5287363d95eb310dc7e18697d6b9f370b4035f57
[asterisk/asterisk.git] / channels / misdn / isdn_lib.c
1 /*
2  * Chan_Misdn -- Channel Driver for Asterisk
3  *
4  * Interface to mISDN
5  *
6  * Copyright (C) 2004, Christian Richter
7  *
8  * Christian Richter <crich@beronet.com>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include "isdn_lib_intern.h"
15 #include <mISDNuser/isdn_debug.h>
16
17
18 void misdn_join_conf(struct misdn_bchannel *bc, int conf_id);
19 void misdn_split_conf(struct misdn_bchannel *bc, int conf_id);
20
21 int queue_cleanup_bc(struct misdn_bchannel *bc) ;
22
23 int misdn_lib_get_l2_up(struct misdn_stack *stack);
24
25 struct misdn_stack* get_misdn_stack( void );
26
27
28 int misdn_lib_is_ptp(int port)
29 {
30         struct misdn_stack *stack=get_misdn_stack();
31         for ( ; stack; stack=stack->next) {
32                 if (stack->port == port) return stack->ptp;
33         }
34         return -1;
35 }
36
37 int misdn_lib_get_maxchans(int port) 
38 {
39         struct misdn_stack *stack=get_misdn_stack();
40         for ( ; stack; stack=stack->next) {
41                 if (stack->port == port) {
42                         if (stack->pri) 
43                                 return 30;
44                         else
45                                 return 2;
46                 }
47         }
48         return -1;
49 }
50
51
52 struct misdn_stack* get_stack_by_bc(struct misdn_bchannel *bc)
53 {
54         struct misdn_stack *stack=get_misdn_stack();
55
56         if (!bc) return NULL;
57         
58         for ( ; stack; stack=stack->next) {
59                 int i;
60                 for (i=0; i <stack->b_num; i++) {
61                         if ( bc->port == stack->port) return stack;
62                 }
63         }
64
65         return NULL;
66 }
67
68
69 void get_show_stack_details(int port, char *buf)
70 {
71         struct misdn_stack *stack=get_misdn_stack();
72         
73         for ( ; stack; stack=stack->next) {
74                 if (stack->port == port) break;
75         }
76         
77         if (stack) {
78                 sprintf(buf, "* Stack Addr:%x Port %d Type %s Prot. %s L2Link %s L1Link:%s", stack->upper_id, stack->port, stack->nt?"NT":"TE", stack->ptp?"PTP":"PMP", stack->l2link?"UP":"DOWN", stack->l1link?"UP":"DOWN");
79
80         } else {
81                 buf[0]=0;
82         }
83         
84 }
85
86
87 static int nt_err_cnt =0 ;
88
89 enum global_states {
90         MISDN_INITIALIZING,
91         MISDN_INITIALIZED
92 } ;
93
94 static enum global_states  global_state=MISDN_INITIALIZING;
95
96
97 #include <mISDNuser/net_l2.h>
98 #include <mISDNuser/tone.h>
99 #include <unistd.h>
100 #include <semaphore.h>
101 #include <pthread.h>
102 #include <signal.h>
103
104 #include "isdn_lib.h"
105
106
107 struct misdn_lib {
108         int midev;
109         int midev_nt;
110
111         pthread_t l1watcher_thread;
112         pthread_t event_thread;
113         pthread_t event_handler_thread;
114
115         int l1watcher_timeout;
116         
117         void *user_data;
118
119         msg_queue_t upqueue;
120         msg_queue_t activatequeue; 
121   
122         sem_t new_msg;
123   
124         struct misdn_stack *stack_list;
125 } ;
126
127 #ifndef ECHOCAN_ON
128 #define ECHOCAN_ON 123
129 #define ECHOCAN_OFF 124
130 #endif
131
132 #define MISDN_DEBUG 0
133
134 void misdn_tx_jitter(struct misdn_bchannel *bc, int len);
135
136 struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id);
137
138 int setup_bc(struct misdn_bchannel *bc);
139
140 int manager_isdn_handler(iframe_t *frm ,msg_t *msg);
141
142 int misdn_lib_port_restart(int port);
143
144 extern struct isdn_msg msgs_g[]; 
145
146 #define ISDN_PID_L3_B_USER 0x430000ff
147 #define ISDN_PID_L4_B_USER 0x440000ff
148
149 /* #define MISDN_IBUF_SIZE 1024 */
150 #define MISDN_IBUF_SIZE 512
151
152 /*  Fine Tuning of Inband  Signalling time */
153 #define TONE_ALERT_CNT 41 /*  1 Sec  */
154 #define TONE_ALERT_SILENCE_CNT 200 /*  4 Sec */
155
156 #define TONE_BUSY_CNT 20 /*  ? */
157 #define TONE_BUSY_SILENCE_CNT 48 /*  ? */
158
159 static int  entity;
160
161 static struct misdn_lib *glob_mgr;
162
163 unsigned char tone_425_flip[TONE_425_SIZE];
164 unsigned char tone_silence_flip[TONE_SILENCE_SIZE];
165
166 static void misdn_lib_isdn_l1watcher(void *arg);
167 static void misdn_lib_isdn_event_catcher(void *arg);
168 static int handle_event_nt(void *dat, void *arg);
169
170
171 void stack_holder_add(struct misdn_stack *stack, struct misdn_bchannel *holder);
172 void stack_holder_remove(struct misdn_stack *stack, struct misdn_bchannel *holder);
173 struct misdn_bchannel *stack_holder_find(struct misdn_stack *stack, unsigned long l3id);
174
175 /* from isdn_lib.h */
176 int init_bc(struct misdn_stack * stack,  struct misdn_bchannel *bc, int midev, int port, int bidx, char *msn, int firsttime);
177 struct misdn_stack* stack_init(int midev,  int port, int ptp);
178 void stack_destroy(struct misdn_stack* stack);
179         /* user iface */
180 int te_lib_init( void ) ; /* returns midev */
181 void te_lib_destroy(int midev) ;
182 struct misdn_bchannel *manager_find_bc_by_pid(int pid);
183 struct misdn_bchannel *manager_find_bc_holded(struct misdn_bchannel* bc);
184 void manager_ph_control_block(struct misdn_bchannel *bc, int c1, void *c2, int c2_len);
185 void manager_clean_bc(struct misdn_bchannel *bc );
186 void manager_bchannel_setup (struct misdn_bchannel *bc);
187 void manager_bchannel_cleanup (struct misdn_bchannel *bc);
188
189 int isdn_msg_get_index(struct isdn_msg msgs[], msg_t *frm, int nt);
190 enum event_e isdn_msg_get_event(struct isdn_msg msgs[], msg_t *frm, int nt);
191 int isdn_msg_parse_event(struct isdn_msg msgs[], msg_t *frm, struct misdn_bchannel *bc, int nt);
192 char * isdn_get_info(struct isdn_msg msgs[], enum event_e event, int nt);
193 msg_t * isdn_msg_build_event(struct isdn_msg msgs[], struct misdn_bchannel *bc, enum event_e event, int nt);
194 void ec_chunk( struct misdn_bchannel *bc, unsigned char *rxchunk, unsigned char *txchunk, int chunk_size);
195         /* end */
196 int bchdev_echocancel_activate(struct misdn_bchannel* dev);
197 void bchdev_echocancel_deactivate(struct misdn_bchannel* dev);
198 /* end */
199
200
201 static char *bearer2str(int cap) {
202         static char *bearers[]={
203                 "Speech",
204                 "Audio 3.1k",
205                 "Unres Digital",
206                 "Res Digital",
207                 "Unknown Bearer"
208         };
209         
210         switch (cap) {
211         case INFO_CAPABILITY_SPEECH:
212                 return bearers[0];
213                 break;
214         case INFO_CAPABILITY_AUDIO_3_1K:
215                 return bearers[1];
216                 break;
217         case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
218                 return bearers[2];
219                 break;
220         case INFO_CAPABILITY_DIGITAL_RESTRICTED:
221                 return bearers[3];
222                 break;
223         default:
224                 return bearers[4];
225                 break;
226         }
227 }
228
229
230 static char flip_table[256];
231
232 void init_flip_bits(void)
233 {
234         int i,k;
235         
236         for (i = 0 ; i < 256 ; i++) {
237                 unsigned char sample = 0 ;
238                 for (k = 0; k<8; k++) {
239                         if ( i & 1 << k ) sample |= 0x80 >>  k;
240                 }
241                 flip_table[i] = sample;
242         }
243 }
244
245 unsigned char * flip_buf_bits ( unsigned char * buf , int len)
246 {
247         int i;
248         char * start = buf;
249         
250         for (i = 0 ; i < len; i++) {
251                 buf[i] = flip_table[buf[i]];
252         }
253         
254         return start;
255 }
256
257
258
259
260 msg_t *create_l2msg(int prim, int dinfo, int size) /* NT only */
261 {
262         int i = 0;
263         msg_t *dmsg;
264   
265         while(i < 10)
266         {
267                 dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
268                 if (dmsg)
269                         return(dmsg);
270       
271                 if (!i)
272                         printf("cannot allocate memory, trying again...\n");
273                 i++;
274                 usleep(300000);
275         }
276         printf("cannot allocate memory, system overloaded.\n");
277         exit(-1);
278 }
279
280
281
282 msg_t *create_l3msg(int prim, int mt, int dinfo, int size, int ntmode)
283 {
284         int i = 0;
285         msg_t *dmsg;
286         Q931_info_t *qi;
287         iframe_t *frm;
288   
289         if (!ntmode)
290                 size = sizeof(Q931_info_t)+2;
291   
292         while(i < 10) {
293                 if (ntmode) {
294                         dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
295                         if (dmsg) {
296                                 return(dmsg);
297                         }
298                 } else {
299                         dmsg = alloc_msg(size+256+mISDN_HEADER_LEN+DEFAULT_HEADROOM);
300                         if (dmsg)
301                         {
302                                 memset(msg_put(dmsg,size+mISDN_HEADER_LEN), 0, size+mISDN_HEADER_LEN);
303                                 frm = (iframe_t *)dmsg->data;
304                                 frm->prim = prim;
305                                 frm->dinfo = dinfo;
306                                 qi = (Q931_info_t *)(dmsg->data + mISDN_HEADER_LEN);
307                                 qi->type = mt;
308                                 return(dmsg);
309                         }
310                 }
311     
312                 if (!i) printf("cannot allocate memory, trying again...\n");
313                 i++;
314                 usleep(300000);
315         }
316         printf("cannot allocate memory, system overloaded.\n");
317         exit(-1);
318 }
319
320
321 int send_msg (int midev, struct misdn_bchannel *bc, msg_t *dmsg)
322 {
323         iframe_t *frm;
324         frm = (iframe_t *)dmsg->data;
325         struct misdn_stack *stack=get_stack_by_bc(bc);
326
327         if (!stack) {
328                 cb_log(0,bc->port,"send_msg: IEK!! no stack\n ");
329                 return -1;
330         }
331         
332         frm->addr = (stack->upper_id | FLG_MSG_DOWN);
333
334         
335         frm->dinfo = bc->l3_id;
336   
337         frm->len = (dmsg->len) - mISDN_HEADER_LEN;
338         
339         mISDN_write(midev, dmsg->data, dmsg->len, TIMEOUT_1SEC);
340   
341         free_msg(dmsg);
342
343         return 0;
344 }
345
346
347 static int mypid=1;
348
349
350 int misdn_cap_is_speech(int cap)
351 /** Poor mans version **/
352 {
353         if ( (cap != INFO_CAPABILITY_DIGITAL_UNRESTRICTED) &&
354              (cap != INFO_CAPABILITY_DIGITAL_RESTRICTED) ) return 1;
355         return 0;
356 }
357
358 int misdn_inband_avail(struct misdn_bchannel *bc)
359 {
360
361         /*if ! early_bconnect we have never inband available*/
362         if ( ! bc->early_bconnect ) return 0;
363         
364         switch (bc->progress_indicator) {
365         case INFO_PI_INBAND_AVAILABLE:
366         case INFO_PI_CALL_NOT_E2E_ISDN:
367         case INFO_PI_CALLED_NOT_ISDN:
368                 return 1;
369         default:
370                 return 0;
371         }
372         return 0;
373 }
374
375
376 void dump_chan_list(struct misdn_stack *stack)
377 {
378         int i;
379
380         for (i=0; i <stack->b_num; i++) {
381                 cb_log(6, stack->port, "Idx:%d stack->cchan:%d Chan:%d\n",i,stack->channels[i], i+1);
382         }
383 }
384
385
386
387
388 static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchannel *bc, int channel)
389 {
390         int i;
391
392         cb_log(1,stack->port,"find_free_chan: req_chan:%d\n",channel);
393
394         if (channel < 0 || channel > MAX_BCHANS) {
395                 cb_log(4, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
396                 return 0;
397         }
398         
399         channel--;
400   
401         for (i = 0; i < stack->b_num; i++) {
402                 if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 Dchannel ;) and work with chan preselection */
403                         if (!stack->channels[i]) {
404                                 cb_log (1, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
405                                 stack->channels[i] = 1;
406                                 bc->channel=i+1;
407                                 cb_event(EVENT_NEW_CHANNEL, bc, NULL);
408                                 return i+1;
409                         }
410                 }
411         }
412
413         cb_log (4, stack->port, " !! NO FREE CHAN IN STACK\n");
414         dump_chan_list(stack);
415   
416         return 0;
417 }
418
419 int empty_chan_in_stack(struct misdn_stack *stack, int channel)
420 {
421         if (channel<=0) {
422                 cb_log(-1,stack?stack->port:0, "empty_chan_inst_stack: cannot empty channel %d\n",channel);
423                 return -1;
424         }
425         
426         cb_log (1, stack?stack->port:0, "empty_chan_in_stack: %d\n",channel); 
427         stack->channels[channel-1] = 0;
428         dump_chan_list(stack);
429         return 0;
430 }
431
432 char *bc_state2str(enum bchannel_state state) {
433         int i;
434         
435         struct bchan_state_s {
436                 char *n;
437                 enum bchannel_state s;
438         } states[] = {
439                 {"BCHAN_CLEANED", BCHAN_CLEANED },
440                 {"BCHAN_EMPTY", BCHAN_EMPTY},
441                 {"BCHAN_SETUP", BCHAN_SETUP},
442                 {"BCHAN_SETUPED", BCHAN_SETUPED},
443                 {"BCHAN_ACTIVE", BCHAN_ACTIVE},
444                 {"BCHAN_ACTIVATED", BCHAN_ACTIVATED},
445                 {"BCHAN_BRIDGE",  BCHAN_BRIDGE},
446                 {"BCHAN_BRIDGED", BCHAN_BRIDGED},
447                 {"BCHAN_RELEASE", BCHAN_RELEASE},
448                 {"BCHAN_RELEASED", BCHAN_RELEASED},
449                 {"BCHAN_CLEAN", BCHAN_CLEAN},
450                 {"BCHAN_CLEAN_REQUEST", BCHAN_CLEAN_REQUEST},
451                 {"BCHAN_ERROR", BCHAN_ERROR}
452         };
453         
454         for (i=0; i< sizeof(states)/sizeof(struct bchan_state_s); i++)
455                 if ( states[i].s == state)
456                         return states[i].n;
457
458         return "UNKNOWN";
459 }
460
461 void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
462 {
463         cb_log(3,bc->port,"BC_STATE_CHANGE: from:%s to:%s\n",
464                bc_state2str(bc->bc_state),
465                bc_state2str(state) );
466         
467         switch (state) {
468                 case BCHAN_ACTIVATED:
469                         if (bc->next_bc_state ==  BCHAN_BRIDGED) {
470                                 misdn_join_conf(bc, bc->conf_id);
471                                 bc->next_bc_state = BCHAN_EMPTY;
472                                 return;
473                         }
474                 default:
475                         bc->bc_state=state;
476                         break;
477         }
478 }
479
480 void bc_next_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
481 {
482         cb_log(3,bc->port,"BC_NEXT_STATE_CHANGE: from:%s to:%s\n",
483                bc_state2str(bc->next_bc_state),
484                bc_state2str(state) );
485
486         bc->next_bc_state=state;
487 }
488
489
490 void empty_bc(struct misdn_bchannel *bc)
491 {
492         bc->bframe_len=0;
493         
494         bc->channel = 0;
495         bc->in_use = 0;
496
497         bc->sending_complete = 0;
498
499         bc->restart_channel=0;
500         
501         bc->conf_id = 0;
502
503         bc->need_more_infos = 0;
504         
505         bc->send_dtmf=0;
506         bc->nodsp=0;
507         bc->nojitter=0;
508
509         bc->time_usec=0;
510         
511         bc->rxgain=0;
512         bc->txgain=0;
513
514         bc->crypt=0;
515         bc->curptx=0; bc->curprx=0;
516         
517         bc->crypt_key[0] = 0;
518         
519         bc->generate_tone=0;
520         bc->tone_cnt=0;
521   
522         bc->dnumplan=NUMPLAN_UNKNOWN;
523         bc->onumplan=NUMPLAN_UNKNOWN;
524         bc->rnumplan=NUMPLAN_UNKNOWN;
525         bc->cpnnumplan=NUMPLAN_UNKNOWN;
526         
527
528         bc->active = 0;
529
530         bc->early_bconnect = 1;
531         
532         bc->ec_enable = 0;
533         bc->ec_deftaps = 128;
534         bc->ec_whenbridged = 0;
535         bc->ec_training = 1;
536         
537         
538         bc->orig=0;
539   
540         bc->cause=16;
541         bc->out_cause=16;
542         bc->pres=0 ; /* screened */
543         
544         bc->evq=EVENT_NOTHING;
545
546         bc->progress_coding=0;
547         bc->progress_location=0;
548         bc->progress_indicator=0;
549         
550 /** Set Default Bearer Caps **/
551         bc->capability=INFO_CAPABILITY_SPEECH;
552         bc->law=INFO_CODEC_ALAW;
553         bc->mode=0;
554         bc->rate=0x10;
555         bc->user1=0;
556         bc->urate=0;
557         
558         bc->hdlc=0;
559         
560         
561         bc->info_dad[0] = 0;
562         bc->display[0] = 0;
563         bc->infos_pending[0] = 0;
564         bc->cad[0] = 0;
565         bc->oad[0] = 0;
566         bc->dad[0] = 0;
567         bc->rad[0] = 0;
568         bc->orig_dad[0] = 0;
569         
570         bc->fac_type=FACILITY_NONE;
571         
572         bc->te_choose_channel = 0;
573
574         bc->holded_bc=NULL;
575 }
576
577
578 int clean_up_bc(struct misdn_bchannel *bc)
579 {
580         int ret=0;
581         unsigned char buff[32];
582         struct misdn_stack * stack;
583
584         cb_log(3, bc?bc->port:0, "$$$ CLEANUP CALLED pid:%d\n", bc?bc->pid:-1);
585         
586         if (!bc  ) return -1;
587         stack=get_stack_by_bc(bc);
588         
589         if (!stack) return -1;
590         
591         switch (bc->bc_state ) {
592         case BCHAN_CLEANED:
593                 cb_log(5, stack->port, "$$$ Already cleaned up bc with stid :%x\n", bc->b_stid);
594                 return -1;
595                 
596         default:
597                 break;
598         }
599         
600         cb_log(2, stack->port, "$$$ Cleaning up bc with stid :%x pid:%d\n", bc->b_stid, bc->pid);
601         
602         manager_bchannel_deactivate(bc);
603
604         if ( misdn_cap_is_speech(bc->capability) && bc->ec_enable) {
605                 manager_ec_disable(bc);
606         }
607
608         mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_TARGET|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
609         
610         /*mISDN_clear_stack(stack->midev, bc->b_stid);*/
611
612         
613
614         bc->b_stid = 0;
615         bc_state_change(bc, BCHAN_CLEANED);
616         
617         return ret;
618 }
619
620
621
622 void clear_l3(struct misdn_stack *stack)
623 {
624         int i;
625         for (i=0; i<stack->b_num; i++) {
626                 if (global_state == MISDN_INITIALIZED)  {
627                         cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data);
628                         empty_chan_in_stack(stack,i+1);
629                         empty_bc(&stack->bc[i]);
630                         clean_up_bc(&stack->bc[i]);
631                 }
632                 
633         } 
634 }
635
636 int set_chan_in_stack(struct misdn_stack *stack, int channel)
637 {
638
639         cb_log(1,stack->port,"set_chan_in_stack: %d\n",channel);
640         if (channel >=1 ) {
641                 stack->channels[channel-1] = 1;
642         } else {
643                 cb_log(-1,stack->port,"couldn't set channel %d in\n", channel );
644         }
645   
646         return 0;
647 }
648
649 int chan_in_stack_free(struct misdn_stack *stack, int channel)
650 {
651         if (stack->channels[channel-1])
652                 return 0;
653   
654         return 1;
655 }
656
657
658
659 static int newteid=0;
660
661 #define MAXPROCS 0x100
662
663 int misdn_lib_get_l1_down(struct misdn_stack *stack)
664 {
665         /* Pull Up L1 */ 
666         iframe_t act;
667         act.prim = PH_DEACTIVATE | REQUEST; 
668         act.addr = (stack->upper_id | FLG_MSG_DOWN)  ;
669
670         
671         act.dinfo = 0;
672         act.len = 0;
673
674         return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
675
676
677 }
678
679
680 int misdn_lib_get_l2_down(struct misdn_stack *stack)
681 {
682         
683         if (stack->ptp && (stack->nt) ) {
684                 msg_t *dmsg;
685                 /* L2 */
686                 dmsg = create_l2msg(DL_RELEASE| REQUEST, 0, 0);
687                 
688                 if (stack->nst.manager_l3(&stack->nst, dmsg))
689                         free_msg(dmsg);
690                 
691         } else {
692                 iframe_t act;
693                 
694                 act.prim = DL_RELEASE| REQUEST;
695                 act.addr = (stack->upper_id |FLG_MSG_DOWN)  ;
696                 
697                 act.dinfo = 0;
698                 act.len = 0;
699                 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
700         }
701         
702         return 0;
703 }
704
705
706 int misdn_lib_get_l1_up(struct misdn_stack *stack)
707 {
708         /* Pull Up L1 */ 
709         iframe_t act;
710         act.prim = PH_ACTIVATE | REQUEST; 
711         act.addr = (stack->upper_id | FLG_MSG_DOWN)  ;
712
713         
714         act.dinfo = 0;
715         act.len = 0;
716
717         return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
718
719 }
720
721 int misdn_lib_get_l2_up(struct misdn_stack *stack)
722 {
723         
724         if (stack->ptp && (stack->nt) ) {
725                 msg_t *dmsg;
726                 /* L2 */
727                 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
728                 
729                 if (stack->nst.manager_l3(&stack->nst, dmsg))
730                         free_msg(dmsg);
731                 
732         } else {
733                 iframe_t act;
734                 
735                 act.prim = DL_ESTABLISH | REQUEST;
736                 act.addr = (stack->upper_id |FLG_MSG_DOWN)  ;
737                 
738                 act.dinfo = 0;
739                 act.len = 0;
740                 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
741         }
742         
743         return 0;
744 }
745
746 int misdn_lib_get_l2_te_ptp_up(struct misdn_stack *stack)
747 {
748         iframe_t act;
749                 
750         act.prim = DL_ESTABLISH | REQUEST;
751         act.addr = (stack->upper_id  & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
752                 
753         act.dinfo = 0;
754         act.len = 0;
755         return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
756         return 0;
757 }
758
759 int misdn_lib_get_l2_status(struct misdn_stack *stack)
760 {
761         iframe_t act;
762         
763         act.prim = DL_ESTABLISH | REQUEST;
764
765         act.addr = (stack->upper_id | FLG_MSG_DOWN)  ;
766
767         act.dinfo = 0;
768         act.len = 0;
769         return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
770 }
771
772 int misdn_lib_get_short_status(struct misdn_stack *stack)
773 {
774         iframe_t act;
775         
776         
777         act.prim = MGR_SHORTSTATUS | REQUEST; 
778         
779         act.addr = (stack->upper_id | MSG_BROADCAST)  ;
780
781         act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
782         
783         act.len = 0;
784         return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
785 }
786
787
788
789 static int create_process (int midev, struct misdn_bchannel *bc) {
790         iframe_t ncr;
791         int l3_id;
792         int i;
793         struct misdn_stack *stack=get_stack_by_bc(bc);
794         int free_chan;
795   
796         if (stack->nt) {
797                 free_chan = find_free_chan_in_stack(stack, bc, bc->channel_preselected?bc->channel:0);
798                 if (!free_chan) return -1;
799                 /*bc->channel=free_chan;*/
800                 
801                 cb_log(4,stack->port, " -->  found channel: %d\n",free_chan);
802     
803                 for (i=0; i <= MAXPROCS; i++)
804                         if (stack->procids[i]==0) break;
805     
806                 if (i== MAXPROCS) {
807                         cb_log(-1, stack->port, "Couldnt Create New ProcId.\n");
808                         return -1;
809                 }
810                 stack->procids[i]=1;
811
812                 l3_id = 0xff00 | i;
813     
814                 ncr.prim = CC_NEW_CR | REQUEST; 
815
816                 ncr.addr = (stack->upper_id | FLG_MSG_DOWN)  ;
817
818                 ncr.dinfo = l3_id;
819                 ncr.len = 0;
820
821                 bc->l3_id = l3_id;
822                 cb_log(3, stack->port, " --> new_l3id %x\n",l3_id);
823     
824         } else { 
825                 if (stack->ptp || bc->te_choose_channel) {
826                         /* we know exactly which channels are in use */
827                         free_chan = find_free_chan_in_stack(stack, bc, bc->channel_preselected?bc->channel:0);
828                         if (!free_chan) return -1;
829                         /*bc->channel=free_chan;*/
830                         cb_log(2,stack->port, " -->  found channel: %d\n",free_chan);
831                 } else {
832                         /* other phones could have made a call also on this port (ptmp) */
833                         bc->channel=0xff;
834                 }
835     
836     
837                 /* if we are in te-mode, we need to create a process first */
838                 if (newteid++ > 0xffff)
839                         newteid = 0x0001;
840     
841                 l3_id = (entity<<16) | newteid;
842                 /* preparing message */
843                 ncr.prim = CC_NEW_CR | REQUEST; 
844
845                 ncr.addr = (stack->upper_id | FLG_MSG_DOWN)  ;
846
847                 ncr.dinfo =l3_id;
848                 ncr.len = 0;
849                 /* send message */
850
851                 bc->l3_id = l3_id;
852                 cb_log(3, stack->port, "--> new_l3id %x\n",l3_id);
853     
854                 mISDN_write(midev, &ncr, mISDN_HEADER_LEN+ncr.len, TIMEOUT_1SEC);
855         }
856   
857         return l3_id;
858 }
859
860
861 void misdn_lib_setup_bc(struct misdn_bchannel *bc)
862 {
863         setup_bc(bc);
864 }
865
866
867 int setup_bc(struct misdn_bchannel *bc)
868 {
869         unsigned char buff[1025];
870   
871         mISDN_pid_t pid;
872         int ret;
873         
874
875         struct misdn_stack *stack=get_stack_by_bc(bc);
876
877         if (!stack) {
878                 cb_log(-1, bc->port, "setup_bc: NO STACK FOUND!!\n");
879                 return -1;
880         }
881         
882         int midev=stack->midev;
883         int channel=bc->channel-1-(bc->channel>16);
884         int b_stid=stack->b_stids[channel>=0?channel:0];
885
886
887         switch (bc->bc_state) {
888                 case BCHAN_CLEANED:
889                         break;
890                 default:
891                         cb_log(4, stack->port, "$$$ bc already upsetted stid :%x (state:%s)\n", b_stid, bc_state2str(bc->bc_state) );
892                         return -1;
893         }
894         
895         cb_log(5, stack->port, "$$$ Setting up bc with stid :%x\n", b_stid);
896         
897         if (b_stid <= 0) {
898                 cb_log(-1, stack->port," -- Stid <=0 at the moment in channel:%d\n",channel);
899                 
900                 bc_state_change(bc,BCHAN_ERROR);
901                 return 1;
902         }
903         
904         
905         bc->b_stid = b_stid;
906         
907         {
908                 layer_info_t li;
909                 memset(&li, 0, sizeof(li));
910     
911                 li.object_id = -1;
912                 li.extentions = 0;
913                 
914                 li.st = bc->b_stid; /*  given idx */
915
916
917 #define MISDN_DSP
918 #ifndef MISDN_DSP
919                 bc->nodsp=1;
920 #endif
921                 if ( bc->hdlc || bc->nodsp) {
922                         cb_log(4, stack->port,"setup_bc: without dsp\n");
923                         { 
924                                 int l = sizeof(li.name);
925                                 strncpy(li.name, "B L3", l);
926                                 li.name[l-1] = 0;
927                         }
928                         li.pid.layermask = ISDN_LAYER((3));
929                         li.pid.protocol[3] = ISDN_PID_L3_B_USER;
930                         
931                         bc->layer=3;
932                 } else {
933                         cb_log(4, stack->port,"setup_bc: with dsp\n");
934                         { 
935                                 int l = sizeof(li.name);
936                                 strncpy(li.name, "B L4", l);
937                                 li.name[l-1] = 0;
938                         }
939                         li.pid.layermask = ISDN_LAYER((4));
940                         li.pid.protocol[4] = ISDN_PID_L4_B_USER
941 ;
942                         bc->layer=4;
943                         
944                 }  
945                 
946                 ret = mISDN_new_layer(midev, &li);
947                 if (ret ) {
948                         cb_log(-1, stack->port,"New Layer Err: %d %s\n",ret,strerror(errno));
949
950                         bc_state_change(bc,BCHAN_ERROR);
951                         return(-EINVAL);
952                 }
953                 
954                 bc->layer_id = li.id;
955         }
956         
957         memset(&pid, 0, sizeof(pid));
958         
959         
960         
961         cb_log(4, stack->port," --> Channel is %d\n", bc->channel);
962         
963         if (bc->nodsp) {
964                 cb_log(2, stack->port," --> TRANSPARENT Mode (no DSP, no HDLC)\n");
965                 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
966                 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
967                 pid.protocol[3] = ISDN_PID_L3_B_USER;
968                 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3));
969                 
970         } else if ( bc->hdlc ) {
971                 cb_log(2, stack->port," --> HDLC Mode\n");
972 #ifdef ACK_HDLC
973                 bc->ack_hdlc=(sem_t*)malloc(sizeof(sem_t));
974                 if ( sem_init((sem_t*)bc->ack_hdlc, 1, 0)<0 )
975                         sem_init((sem_t*)bc->ack_hdlc, 0, 0);
976 #endif
977                 
978                 pid.protocol[1] = ISDN_PID_L1_B_64HDLC ;
979                 pid.protocol[2] = ISDN_PID_L2_B_TRANS  ;
980                 pid.protocol[3] = ISDN_PID_L3_B_USER;
981                 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) ;
982         } else {
983                 cb_log(2, stack->port," --> TRANSPARENT Mode\n");
984                 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
985                 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
986                 pid.protocol[3] = ISDN_PID_L3_B_DSP;
987                 pid.protocol[4] = ISDN_PID_L4_B_USER;
988                 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
989                 
990         } 
991
992         ret = mISDN_set_stack(midev, bc->b_stid, &pid);
993
994         if (ret){
995                 cb_log(-1, stack->port,"$$$ Set Stack Err: %d %s\n",ret,strerror(errno));
996                 
997                 mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
998                 
999                 bc_state_change(bc,BCHAN_ERROR);
1000                 return(-EINVAL);
1001         }
1002
1003
1004         ret = mISDN_get_setstack_ind(midev, bc->layer_id);
1005
1006         if (ret) {
1007                 cb_log(-1, stack->port,"$$$ Set StackIND Err: %d %s\n",ret,strerror(errno));
1008                 mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1009                 
1010                 bc_state_change(bc,BCHAN_ERROR);
1011                 return(-EINVAL);
1012         }
1013
1014         ret = mISDN_get_layerid(midev, bc->b_stid, bc->layer) ;
1015
1016         bc->addr = ret>0? ret : 0;
1017
1018         if (!bc->addr) {
1019                 cb_log(-1, stack->port,"$$$ Get Layerid Err: %d %s\n",ret,strerror(errno));
1020                 mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1021                 
1022                 bc_state_change(bc,BCHAN_ERROR);
1023         }
1024
1025         manager_bchannel_activate(bc);
1026         
1027         bc_state_change(bc,BCHAN_ACTIVATED);
1028
1029         return 0;
1030 }
1031
1032
1033
1034 /** IFACE **/
1035 int init_bc(struct misdn_stack *stack,  struct misdn_bchannel *bc, int midev, int port, int bidx,  char *msn, int firsttime)
1036 {
1037         unsigned char buff[1025];
1038         iframe_t *frm = (iframe_t *)buff;
1039         int ret;
1040   
1041         if (!bc) return -1;
1042   
1043         cb_log(4, port, "Init.BC %d.\n",bidx);
1044         
1045         memset(bc, 0,sizeof(struct misdn_bchannel));
1046         
1047         if (msn) {
1048                 int l = sizeof(bc->msn);
1049                 strncpy(bc->msn,msn, l);
1050                 bc->msn[l-1] = 0;
1051         }
1052         
1053         
1054         empty_bc(bc);
1055         bc_state_change(bc, BCHAN_CLEANED);
1056         
1057         bc->port=stack->port;
1058         bc->nt=stack->nt?1:0;
1059         
1060         {
1061                 ibuffer_t* ibuf= init_ibuffer(MISDN_IBUF_SIZE);
1062
1063                 if (!ibuf) return -1;
1064                 
1065                 clear_ibuffer( ibuf);
1066                 
1067                 ibuf->rsem=malloc(sizeof(sem_t));
1068                 
1069                 bc->astbuf=ibuf;
1070
1071                 if (sem_init(ibuf->rsem,1,0)<0)
1072                         sem_init(ibuf->rsem,0,0);
1073                 
1074         }
1075         
1076         
1077         
1078         
1079         {
1080                 stack_info_t *stinf;
1081                 ret = mISDN_get_stack_info(midev, stack->port, buff, sizeof(buff));
1082                 if (ret < 0) {
1083                         cb_log(-1, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
1084                         return -1;
1085                 }
1086     
1087                 stinf = (stack_info_t *)&frm->data.p;
1088     
1089                 cb_log(4, port, " --> Child %x\n",stinf->child[bidx]);
1090         }
1091   
1092         return 0;
1093 }
1094
1095
1096
1097 struct misdn_stack* stack_init( int midev, int port, int ptp )
1098 {
1099         int ret;
1100         unsigned char buff[1025];
1101         iframe_t *frm = (iframe_t *)buff;
1102         stack_info_t *stinf;
1103         int i; 
1104         layer_info_t li;
1105
1106         struct misdn_stack *stack = malloc(sizeof(struct misdn_stack));
1107         if (!stack ) return NULL;
1108
1109
1110         cb_log(4, port, "Init. Stack.\n");
1111   
1112         memset(stack,0,sizeof(struct misdn_stack));
1113   
1114         for (i=0; i<MAX_BCHANS + 1; i++ ) stack->channels[i]=0;
1115         
1116         stack->port=port;
1117         stack->midev=midev;
1118         stack->ptp=ptp;
1119   
1120         stack->holding=NULL;
1121         stack->pri=0;
1122   
1123         msg_queue_init(&stack->downqueue);
1124         msg_queue_init(&stack->upqueue);
1125   
1126         /* query port's requirements */
1127         ret = mISDN_get_stack_info(midev, port, buff, sizeof(buff));
1128         if (ret < 0) {
1129                 cb_log(-1, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
1130                 return(NULL);
1131         }
1132   
1133         stinf = (stack_info_t *)&frm->data.p;
1134
1135         stack->d_stid = stinf->id;
1136         stack->b_num = stinf->childcnt;
1137
1138         for (i=0; i<stinf->childcnt; i++)
1139                 stack->b_stids[i] = stinf->child[i];
1140   
1141         switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK) {
1142         case ISDN_PID_L0_TE_S0:
1143                 stack->nt=0;
1144                 break;
1145         case ISDN_PID_L0_NT_S0:
1146                 cb_log(4, port, "NT Stack\n");
1147
1148                 stack->nt=1;
1149                 break;
1150
1151         case ISDN_PID_L0_TE_U:
1152                 break;
1153         case ISDN_PID_L0_NT_U:
1154                 break;
1155         case ISDN_PID_L0_TE_UP2:
1156                 break;
1157         case ISDN_PID_L0_NT_UP2:
1158                 break;
1159         case ISDN_PID_L0_TE_E1:
1160                 cb_log(4, port, "TE S2M Stack\n");
1161                 stack->nt=0;
1162                 stack->pri=1;
1163                 break;
1164         case ISDN_PID_L0_NT_E1:
1165                 cb_log(4, port, "TE S2M Stack\n");
1166                 stack->nt=1;
1167                 stack->pri=1;
1168                 
1169                 break;
1170         default:
1171                 cb_log(-1, port, "this is a unknown port type 0x%08x\n", stinf->pid.protocol[0]);
1172
1173         }
1174
1175         if (!stack->nt) {
1176                 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP ) { 
1177                         stack->ptp = 1;
1178                 } else {
1179                         stack->ptp = 0;
1180                 }
1181         }
1182         
1183         {
1184                 int ret;
1185                 int nt=stack->nt;
1186
1187                 cb_log(4, port, "Init. Stack.\n");
1188                 
1189                 memset(&li, 0, sizeof(li));
1190                 {
1191                         int l = sizeof(li.name);
1192                         strncpy(li.name,nt?"net l2":"user l4", l);
1193                         li.name[l-1] = 0;
1194                 }
1195                 li.object_id = -1;
1196                 li.extentions = 0;
1197                 li.pid.protocol[nt?2:4] = nt?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
1198                 li.pid.layermask = ISDN_LAYER((nt?2:4));
1199                 li.st = stack->d_stid;
1200                 
1201                 
1202                 ret = mISDN_new_layer(midev, &li);
1203                 if (ret) {
1204                         cb_log(-1, port, "%s: Cannot add layer %d to this port.\n", __FUNCTION__, nt?2:4);
1205                         return(NULL);
1206                 }
1207                 
1208                 
1209                 stack->upper_id = li.id;
1210                 ret = mISDN_register_layer(midev, stack->d_stid, stack->upper_id);
1211                 if (ret)
1212                 {
1213                         cb_log(-1,port,"Cannot register layer %d of this port.\n", nt?2:4);
1214                         return(NULL);
1215                 }
1216                 
1217                 stack->lower_id = mISDN_get_layerid(midev, stack->d_stid, nt?1:3); 
1218                 if (stack->lower_id < 0) {
1219                         cb_log(-1, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, nt?1:3);
1220                         return(NULL);
1221                 }
1222                 
1223                 stack->upper_id = mISDN_get_layerid(midev, stack->d_stid, nt?2:4);
1224                 if (stack->upper_id < 0) {
1225                         cb_log(-1, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, 2);
1226                         return(NULL);
1227                 }
1228                 
1229                 cb_log(4, port, "NT Stacks upper_id %x\n",stack->upper_id);
1230                 
1231                 
1232                 /* create nst (nt-mode only) */
1233                 if (nt) {
1234                         
1235                         memset(&stack->nst, 0, sizeof(net_stack_t));
1236                         memset(&stack->mgr, 0, sizeof(manager_t));
1237     
1238                         stack->mgr.nst = &stack->nst;
1239                         stack->nst.manager = &stack->mgr;
1240     
1241                         stack->nst.l3_manager = handle_event_nt;
1242                         stack->nst.device = midev;
1243                         stack->nst.cardnr = port;
1244                         stack->nst.d_stid = stack->d_stid;
1245     
1246                         stack->nst.feature = FEATURE_NET_HOLD;
1247                         if (stack->ptp)
1248                                 stack->nst.feature |= FEATURE_NET_PTP;
1249                         if (stack->pri)
1250                                 stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
1251                         
1252                         stack->nst.l1_id = stack->lower_id;
1253                         stack->nst.l2_id = stack->upper_id;
1254                         
1255                         msg_queue_init(&stack->nst.down_queue);
1256                         
1257                         Isdnl2Init(&stack->nst);
1258                         Isdnl3Init(&stack->nst);
1259                         
1260                 } 
1261                 
1262                 if (!stack->nt) {
1263                         /*assume L1 is up, we'll get DEACTIVATES soon, for non
1264                          * up L1s*/
1265                         stack->l1link=0;
1266                 }
1267
1268                 misdn_lib_get_short_status(stack);
1269                 misdn_lib_get_l1_up(stack);
1270                 misdn_lib_get_l2_up(stack);
1271                 
1272         }
1273
1274         cb_log(1,0,"stack_init: port:%d lowerId:%x  upperId:%x\n",stack->port,stack->lower_id, stack->upper_id);
1275         
1276         return stack;
1277 }
1278
1279
1280 void stack_destroy(struct misdn_stack* stack)
1281 {
1282         char buf[1024];
1283         if (!stack) return;
1284
1285         if (stack->nt) {
1286                 cleanup_Isdnl2(&stack->nst);
1287                 cleanup_Isdnl3(&stack->nst);
1288         }
1289   
1290         if (stack->lower_id) 
1291                 mISDN_write_frame(stack->midev, buf, stack->lower_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1292
1293         if (stack->upper_id) 
1294                 mISDN_write_frame(stack->midev, buf, stack->upper_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1295 }
1296
1297
1298 struct misdn_stack * find_stack_by_addr(int  addr)
1299 {
1300         struct misdn_stack *stack;
1301         
1302         for (stack=glob_mgr->stack_list;
1303              stack;
1304              stack=stack->next) {
1305                 if ( (stack->upper_id&STACK_ID_MASK) == (addr&STACK_ID_MASK)) return stack;
1306
1307         }
1308   
1309         return NULL;
1310 }
1311
1312
1313 struct misdn_stack * find_stack_by_port(int port)
1314 {
1315         struct misdn_stack *stack;
1316   
1317         for (stack=glob_mgr->stack_list;
1318              stack;
1319              stack=stack->next) 
1320                 if (stack->port == port) return stack;
1321   
1322         return NULL;
1323 }
1324
1325 struct misdn_stack * find_stack_by_mgr(manager_t* mgr_nt)
1326 {
1327         struct misdn_stack *stack;
1328   
1329         for (stack=glob_mgr->stack_list;
1330              stack;
1331              stack=stack->next) 
1332                 if ( &stack->mgr == mgr_nt) return stack;
1333   
1334         return NULL;
1335 }
1336
1337 struct misdn_bchannel *find_bc_by_masked_l3id(struct misdn_stack *stack, unsigned long l3id, unsigned long mask)
1338 {
1339         int i;
1340         for (i=0; i<stack->b_num; i++) {
1341                 if ( (stack->bc[i].l3_id & mask)  ==  (l3id & mask)) return &stack->bc[i] ;
1342         }
1343         return stack_holder_find(stack,l3id);
1344 }
1345
1346
1347 struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id)
1348 {
1349         int i;
1350         for (i=0; i<stack->b_num; i++) {
1351                 if (stack->bc[i].l3_id == l3id) return &stack->bc[i] ;
1352         }
1353         return stack_holder_find(stack,l3id);
1354 }
1355
1356 struct misdn_bchannel *find_bc_holded(struct misdn_stack *stack)
1357 {
1358         int i;
1359         for (i=0; i<stack->b_num; i++) {
1360                 if (stack->bc[i].holded ) return &stack->bc[i] ;
1361         }
1362         return NULL;
1363 }
1364
1365
1366 struct misdn_bchannel *find_bc_by_addr(unsigned long addr)
1367 {
1368         struct misdn_stack* stack;
1369         int i;
1370
1371         
1372         for (stack=glob_mgr->stack_list;
1373              stack;
1374              stack=stack->next) {
1375                 
1376                 for (i=0; i< stack->b_num; i++) {
1377
1378                         if ( (stack->bc[i].addr&STACK_ID_MASK)==(addr&STACK_ID_MASK) ||  stack->bc[i].layer_id== addr ) {
1379                                 return &stack->bc[i];
1380                         }
1381                 }
1382                 
1383         }
1384
1385         
1386         return NULL;
1387 }
1388
1389
1390 struct misdn_bchannel *find_bc_by_channel(int port, int channel)
1391 {
1392         struct misdn_stack* stack=find_stack_by_port(port);
1393         int i;
1394
1395         if (!stack) return NULL;        
1396         
1397         for (i=0; i< stack->b_num; i++) {
1398                 if ( stack->bc[i].channel== channel ) {
1399                         return &stack->bc[i];
1400                 }
1401         }
1402                 
1403         return NULL;
1404 }
1405
1406
1407
1408
1409
1410 int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_t *frm)
1411 {
1412         struct misdn_stack *stack=get_stack_by_bc(bc);
1413         
1414         if (!stack->nt) {
1415                 
1416                 switch (event) {
1417
1418                 case EVENT_CONNECT_ACKNOWLEDGE:
1419 #if 0
1420                         if ( !misdn_cap_is_speech(bc->capability)) {
1421                                 int ret=setup_bc(bc);
1422                                 if (ret == -EINVAL){
1423                                         cb_log(-1,bc->port,"send_event: setup_bc failed\n");
1424                                 }
1425                         }
1426 #endif  
1427                         break;
1428                 case EVENT_CONNECT:
1429
1430                         if ( *bc->crypt_key ) {
1431                                 cb_log(4, stack->port, "ENABLING BLOWFISH channel:%d oad%d:%s dad%d:%s\n", bc->channel, bc->onumplan,bc->oad, bc->dnumplan,bc->dad);
1432                                 manager_ph_control_block(bc,  BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
1433                         }
1434                 case EVENT_ALERTING:
1435                 case EVENT_PROGRESS:
1436                 case EVENT_PROCEEDING:
1437                 case EVENT_SETUP_ACKNOWLEDGE:
1438
1439                 setup_bc(bc);
1440                 
1441                 case EVENT_SETUP:
1442                         
1443                 {
1444                         if (bc->channel == 0xff) {
1445                                 bc->channel=find_free_chan_in_stack(stack, bc,  0);
1446                                 if (!bc->channel) {
1447                                         cb_log(-1, stack->port, "Any Channel Requested, but we have no more!!\n");
1448                                         break;
1449                                 }
1450                         }  
1451
1452                         if (bc->channel >0 && bc->channel<255) {
1453                                 set_chan_in_stack(stack ,bc->channel);
1454                         }
1455
1456 #if 0
1457                         int ret=setup_bc(bc);
1458                         if (ret == -EINVAL){
1459                                 cb_log(-1,bc->port,"handle_event: setup_bc failed\n");
1460                                 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
1461                         }
1462 #endif
1463                 }
1464                 break;
1465
1466                 case EVENT_RELEASE_COMPLETE:
1467                 case EVENT_RELEASE:
1468                         if (bc->channel>0)
1469                                 empty_chan_in_stack(stack,bc->channel);
1470                         empty_bc(bc);
1471                         clean_up_bc(bc);
1472                         break;
1473                 default:
1474                         break;
1475                 }
1476         } else {    /** NT MODE **/
1477                 
1478         }
1479         return 0;
1480 }
1481
1482 int handle_new_process(struct misdn_stack *stack, iframe_t *frm)
1483 {
1484   
1485         struct misdn_bchannel* bc=misdn_lib_get_free_bc(stack->port, 0);
1486         
1487         
1488         if (!bc) {
1489                 cb_log(-1, stack->port, " --> !! lib: No free channel!\n");
1490                 return -1;
1491         }
1492   
1493         cb_log(7, stack->port, " --> new_process: New L3Id: %x\n",frm->dinfo);
1494         bc->l3_id=frm->dinfo;
1495         return 0;
1496 }
1497
1498 int handle_cr ( struct misdn_stack *stack, iframe_t *frm)
1499 {
1500         if (!stack) return -1;
1501   
1502         switch (frm->prim) {
1503         case CC_NEW_CR|INDICATION:
1504                 cb_log(7, stack->port, " --> lib: NEW_CR Ind with l3id:%x on this port.\n",frm->dinfo);
1505                 if (handle_new_process(stack, frm) <0) 
1506                         return -1;
1507                 return 1;
1508         case CC_NEW_CR|CONFIRM:
1509                 return 1;
1510         case CC_NEW_CR|REQUEST:
1511                 return 1;
1512         case CC_RELEASE_CR|REQUEST:
1513                 return 1;
1514         case CC_RELEASE_CR|CONFIRM:
1515                 break;
1516         case CC_RELEASE_CR|INDICATION:
1517                 cb_log(4, stack->port, " --> lib: RELEASE_CR Ind with l3id:%x\n",frm->dinfo);
1518                 {
1519                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, frm->dinfo);
1520                         struct misdn_bchannel dummybc;
1521       
1522                         if (!bc) {
1523                                 cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
1524                                 memset (&dummybc,0,sizeof(dummybc));
1525                                 dummybc.port=stack->port;
1526                                 dummybc.l3_id=frm->dinfo;
1527                                 bc=&dummybc; 
1528                         }
1529       
1530                         if (bc) {
1531                                 cb_log(4, stack->port, " --> lib: CLEANING UP l3id: %x\n",frm->dinfo);
1532                                 if (bc->channel>0)
1533                                         empty_chan_in_stack(stack,bc->channel);
1534                                 empty_bc(bc);
1535                                 
1536                                 clean_up_bc(bc);
1537                                 
1538                                 dump_chan_list(stack);
1539                                 /*bc->pid = 0;*/
1540                                 cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data);
1541                                 if (bc->stack_holder) {
1542                                         cb_log(4,stack->port, "REMOVEING Holder\n");
1543                                         stack_holder_remove( stack, bc);
1544                                         free(bc);
1545                                 }
1546                         }
1547                         else {
1548                                 if (stack->nt) 
1549                                         cb_log(4, stack->port, "BC with dinfo: %x  not found.. (prim was %x and addr %x)\n",frm->dinfo, frm->prim, frm->addr);
1550                         }
1551       
1552                         return 1;
1553                 }
1554                 break;
1555         }
1556   
1557         return 0;
1558 }
1559
1560
1561 /*Emptys bc if it's reserved (no SETUP out yet)*/
1562 void misdn_lib_release(struct misdn_bchannel *bc)
1563 {
1564         struct misdn_stack *stack=get_stack_by_bc(bc);
1565
1566         if (!stack) {
1567                 cb_log(1,0,"misdn_release: No Stack found\n");
1568                 return;
1569         }
1570         
1571         if (bc->channel>0) {
1572                 empty_chan_in_stack(stack,bc->channel);
1573         }
1574         empty_bc(bc);
1575         clean_up_bc(bc);
1576 }
1577
1578
1579
1580
1581 int misdn_lib_get_port_up (int port) 
1582 { /* Pull Up L1 */ 
1583         struct misdn_stack *stack;
1584         
1585         for (stack=glob_mgr->stack_list;
1586              stack;
1587              stack=stack->next) {
1588                 
1589                 if (stack->port == port) {
1590
1591                         if (!stack->l1link)
1592                                 misdn_lib_get_l1_up(stack);
1593                         if (!stack->l2link)
1594                                 misdn_lib_get_l2_up(stack);
1595                         
1596                         return 0;
1597                 }
1598         }
1599         return 0;
1600 }
1601
1602
1603 int misdn_lib_get_port_down (int port) 
1604 { /* Pull Down L1 */ 
1605         struct misdn_stack *stack;
1606         for (stack=glob_mgr->stack_list;
1607              stack;
1608              stack=stack->next) {
1609                 if (stack->port == port) {
1610                                 if (stack->l2link)
1611                                         misdn_lib_get_l2_down(stack);
1612                                 misdn_lib_get_l1_down(stack);
1613                         return 0;
1614                 }
1615         }
1616         return 0;
1617 }
1618
1619 int misdn_lib_send_facility(struct misdn_bchannel *bc, enum facility_type fac, void *data)
1620 {
1621         switch (fac) {
1622         case FACILITY_CALLDEFLECT:
1623                 strcpy(bc->out_fac.calldeflect_nr,(char*)data);
1624                 break;
1625         default:
1626                 cb_log(1,bc?bc->port:0,"We don't handle this facility yet: %d\n",fac);
1627                 return 0;
1628         }
1629         
1630         bc->out_fac_type=fac;
1631         
1632         misdn_lib_send_event(bc,EVENT_FACILITY);
1633         return 0;
1634 }
1635
1636
1637 int misdn_lib_port_up(int port, int check)
1638 {
1639         struct misdn_stack *stack;
1640
1641
1642         for (stack=glob_mgr->stack_list;
1643              stack;
1644              stack=stack->next) {
1645                 
1646                 if ( !stack->ptp && !check) return 1;
1647                 
1648                 if (stack->port == port) {
1649                         if (stack->ptp ) {
1650                                 if (stack->l1link) {
1651                                         if (check==2 && !stack->l2link) {
1652                                                 cb_log(-1,port, "Port Down L2 (checked):%d L1:%d\n", stack->l2link, stack->l1link);
1653                                                 return 0;
1654                                         }
1655                                         return 1;
1656                                 } else {
1657                                         cb_log(-1,port, "Port Down L2:%d L1:%d\n",
1658                                                 stack->l2link, stack->l1link);
1659                                         return 0;
1660                                 }
1661                         } else {
1662                                 if ( stack->l1link)
1663                                         return 1;
1664                                 else {
1665                                         cb_log(-1,port, "Port down PMP\n");
1666                                         return 0;
1667                                 }
1668                         }
1669                 }
1670         }
1671   
1672         return -1;
1673 }
1674
1675
1676 int
1677 handle_event_nt(void *dat, void *arg)
1678 {
1679         manager_t *mgr = (manager_t *)dat;
1680         msg_t *msg = (msg_t *)arg;
1681         mISDNuser_head_t *hh;
1682         int reject=0;
1683
1684         struct misdn_stack *stack=find_stack_by_mgr(mgr);
1685         int port;
1686
1687         if (!msg || !mgr)
1688                 return(-EINVAL);
1689
1690         hh=(mISDNuser_head_t*)msg->data;
1691         port=stack->port;
1692         
1693         cb_log(4, stack->port, " --> lib: prim %x dinfo %x\n",hh->prim, hh->dinfo);
1694         {
1695                 switch(hh->prim){
1696                 case CC_RETRIEVE|INDICATION:
1697                 {
1698                         iframe_t frm; /* fake te frm to add callref to global callreflist */
1699                         frm.dinfo = hh->dinfo;
1700
1701                         frm.addr=stack->upper_id | FLG_MSG_DOWN;
1702
1703                         frm.prim = CC_NEW_CR|INDICATION;
1704                         
1705                         if (handle_cr( stack, &frm)< 0) {
1706                                 msg_t *dmsg;
1707                                 cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
1708                                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1709                                 stack->nst.manager_l3(&stack->nst, dmsg);
1710                                 free_msg(msg);
1711                                 return 0;
1712                         }
1713                         
1714                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1715                         cb_event(EVENT_NEW_BC, bc, glob_mgr->user_data);
1716                         struct misdn_bchannel *hold_bc=stack_holder_find(stack,bc->l3_id);
1717                         if (hold_bc) {
1718                                 cb_log(4, stack->port, "REMOVEING Holder\n");
1719                                 stack_holder_remove(stack, hold_bc);
1720                                 free(hold_bc);
1721                         }
1722                         
1723                 }
1724                         
1725                         break;
1726                         
1727                 case CC_SETUP|CONFIRM:
1728                 {
1729                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1730                         int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE));
1731                         cb_log(4, stack->port, " --> lib: Event_ind:SETUP CONFIRM [NT] : new L3ID  is %x\n",l3id );
1732         
1733                         if (!bc) { cb_log(4, stack->port, "Bc Not found (after SETUP CONFIRM)\n"); return 0; }
1734                         cb_log (2,bc->port,"I IND :CC_SETUP|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
1735                         bc->l3_id=l3id;
1736                         cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
1737                 }
1738                 free_msg(msg);
1739                 return 0;
1740       
1741                 case CC_SETUP|INDICATION:
1742                 {
1743                         iframe_t frm; /* fake te frm to add callref to global callreflist */
1744                         frm.dinfo = hh->dinfo;
1745                         frm.addr=stack->upper_id;
1746                         frm.prim = CC_NEW_CR|INDICATION;
1747                         
1748                         if (handle_cr(stack, &frm)< 0) {
1749                                 msg_t *dmsg;
1750                                 cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
1751                                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1752                                 stack->nst.manager_l3(&stack->nst, dmsg);
1753                                 free_msg(msg);
1754                                 return 0;
1755                         }
1756                 }
1757                 break;
1758
1759                 case CC_CONNECT_ACKNOWLEDGE|INDICATION:
1760 #if 0
1761                 {
1762                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1763                         if (bc) {
1764                                 if ( !misdn_cap_is_speech(bc->capability)) {
1765                                         int ret=setup_bc(bc);
1766                                         if (ret == -EINVAL){
1767                                                 cb_log(-1,bc->port,"send_event: setup_bc failed\n");
1768                                                 
1769                                         }
1770                                 }
1771                         }
1772                 }
1773 #endif
1774                 break;
1775                 
1776                 case CC_ALERTING|INDICATION:
1777                 case CC_PROCEEDING|INDICATION:
1778                 case CC_SETUP_ACKNOWLEDGE|INDICATION:
1779                         if(!stack->ptp) break;  
1780                 case CC_CONNECT|INDICATION:
1781                 {
1782 #if 0
1783                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1784                         
1785                         if (!bc) {
1786                                 msg_t *dmsg;
1787                                 cb_log(-1, stack->port,"!!!! We didn't found our bc, dinfo:%x on this port.\n",hh->dinfo);
1788                                 
1789                                 cb_log(-1, stack->port, "Releaseing call %x (No free Chan for you..)\n", hh->dinfo);
1790                                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1791                                 stack->nst.manager_l3(&stack->nst, dmsg);
1792                                 free_msg(msg);
1793                                 return 0;
1794                                 
1795                         }
1796                         int ret=setup_bc(bc);
1797                         if (ret == -EINVAL){
1798                                 cb_log(-1,bc->port,"handle_event_nt: setup_bc failed\n");
1799                                 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
1800                         }
1801 #endif
1802                 }
1803                 break;
1804                 case CC_DISCONNECT|INDICATION:
1805                 {
1806                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1807                         if (!bc) {
1808                                 bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
1809                                 if (bc) { 
1810                                         int myprocid=bc->l3_id&0x0000ffff;
1811                                         hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
1812                                         cb_log(3,stack->port,"Reject dinfo: %x cause:%d\n",hh->dinfo,bc->cause);
1813                                         reject=1;               
1814                                 }
1815                         }
1816                 }
1817                 break;
1818                 
1819                 case CC_FACILITY|INDICATION:
1820                 {
1821                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1822                         if (!bc) {
1823                                 bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
1824                                 if (bc) { 
1825                                         int myprocid=bc->l3_id&0x0000ffff;
1826                                         hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
1827                                         cb_log(4,bc->port,"Repaired reject Bug, new dinfo: %x\n",hh->dinfo);
1828                                 }
1829                         }
1830                 }
1831                 break;
1832                 
1833                 case CC_RELEASE_COMPLETE|INDICATION:
1834                         break;
1835
1836                 case CC_SUSPEND|INDICATION:
1837                 {
1838                         msg_t *dmsg;
1839                         cb_log(4, stack->port, " --> Got Suspend, sending Reject for now\n");
1840                         dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST,MT_SUSPEND_REJECT, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1841                         stack->nst.manager_l3(&stack->nst, dmsg);
1842                         free_msg(msg);
1843                         return 0;
1844                 }
1845                 break;
1846                 case CC_RESUME|INDICATION:
1847                         break;
1848
1849                 case CC_RELEASE|CONFIRM:
1850                         break;
1851                         
1852                 case CC_RELEASE|INDICATION:
1853                         break;
1854
1855                 case CC_RELEASE_CR|INDICATION:
1856                 {
1857                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1858                         struct misdn_bchannel dummybc;
1859                         iframe_t frm; /* fake te frm to remove callref from global callreflist */
1860                         frm.dinfo = hh->dinfo;
1861
1862                         frm.addr=stack->upper_id | FLG_MSG_DOWN;
1863
1864                         frm.prim = CC_RELEASE_CR|INDICATION;
1865                         cb_log(4, stack->port, " --> Faking Realease_cr for %x\n",frm.addr);
1866                         /** removing procid **/
1867                         if (!bc) {
1868                                 cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x) on this port.\n", hh->dinfo);
1869                                 memset (&dummybc,0,sizeof(dummybc));
1870                                 dummybc.port=stack->port;
1871                                 dummybc.l3_id=hh->dinfo;
1872                                 bc=&dummybc; 
1873                         }
1874         
1875                         if (bc) {
1876                                 if ( (bc->l3_id & 0xff00) == 0xff00) {
1877                                         cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", bc->l3_id&0xff);
1878                                         stack->procids[bc->l3_id&0xff] = 0 ;
1879                                 }
1880                         }
1881                         else cb_log(-1, stack->port, "Couldnt find BC so I couldnt remove the Process!!!! this is a bad port.\n");
1882         
1883                         if (handle_cr(stack, &frm)<0) {
1884                         }
1885
1886                         free_msg(msg);
1887                         return 0 ;
1888                 }
1889                 break;
1890       
1891                 case CC_NEW_CR|INDICATION:
1892                         /*  Got New CR for bchan, for now I handle this one in */
1893                         /*  connect_ack, Need to be changed */
1894                 {
1895                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1896                         int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE));
1897                         if (!bc) { cb_log(-1, stack->port, " --> In NEW_CR: didn't found bc ??\n"); return -1;};
1898                         if (((l3id&0xff00)!=0xff00) && ((bc->l3_id&0xff00)==0xff00)) {
1899                                 cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", 0xff&bc->l3_id);
1900                                 stack->procids[bc->l3_id&0xff] = 0 ;
1901                         }
1902                         cb_log(4, stack->port, "lib: Event_ind:CC_NEW_CR : very new L3ID  is %x\n",l3id );
1903         
1904                         bc->l3_id =l3id;
1905                         cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
1906         
1907                         free_msg(msg);
1908                         return 0;
1909                 }
1910       
1911                 case DL_ESTABLISH | INDICATION:
1912                 case DL_ESTABLISH | CONFIRM:
1913                 {
1914                         cb_log(4, stack->port, "%% GOT L2 Activate Info.\n");
1915                         stack->l2link = 1;
1916                         stack->l2upcnt=0;
1917                         
1918                         free_msg(msg);
1919                         return 0;
1920                 }
1921                 break;
1922
1923
1924                 case DL_RELEASE | INDICATION:
1925                 case DL_RELEASE | CONFIRM:
1926                 {
1927                         if (stack->ptp) {
1928                                 cb_log(-1 , stack->port, "%% GOT L2 DeActivate Info.\n");
1929
1930                                 if (stack->l2upcnt>3) {
1931                                         cb_log(-1 , stack->port, "!!! Could not Get the L2 up after 3 Attemps!!!\n");
1932                                 }  else {
1933                                         if (stack->nt) misdn_lib_reinit_nt_stack(stack->port);
1934                                         misdn_lib_get_l2_up(stack);
1935                                         stack->l2upcnt++;
1936                                 }
1937                                 
1938                         } else 
1939                                 cb_log(4, stack->port, "%% GOT L2 DeActivate Info.\n");
1940                         
1941                         stack->l2link = 0;
1942                         free_msg(msg);
1943                         return 0;
1944                 }
1945                 break;
1946                 }
1947         }
1948         
1949         {
1950                 /*  Parse Events and fire_up to App. */
1951                 struct misdn_bchannel *bc;
1952                 struct misdn_bchannel dummybc;
1953                 
1954                 enum event_e event = isdn_msg_get_event(msgs_g, msg, 1);
1955     
1956                 bc=find_bc_by_l3id(stack, hh->dinfo);
1957     
1958                 if (!bc) {
1959       
1960                         cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x).\n", hh->dinfo);
1961                         memset (&dummybc,0,sizeof(dummybc));
1962                         dummybc.port=stack->port;
1963                         dummybc.l3_id=hh->dinfo;
1964                         bc=&dummybc; 
1965                 }
1966                 if (bc ) {
1967                         isdn_msg_parse_event(msgs_g,msg,bc, 1);
1968
1969                         switch (event) {
1970                                 case EVENT_SETUP:
1971                                         if (bc->channel>0 && bc->channel<255) {
1972
1973                                                 if (stack->ptp) 
1974                                                         set_chan_in_stack(stack, bc->channel);
1975                                                 else 
1976                                                         cb_log(-1,stack->port," --> PTMP but channel requested\n");
1977
1978                                         } else {
1979
1980                                                 bc->channel = find_free_chan_in_stack(stack, bc, 0);
1981                                                 if (!bc->channel) {
1982                                                         cb_log(-1, stack->port, " No free channel at the moment\n");
1983                                         
1984                                                         msg_t *dmsg;
1985                                 
1986                                                         cb_log(-1, stack->port, "Releaseing call %x (No free Chan for you..)\n", hh->dinfo);
1987                                                                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1988                                                         stack->nst.manager_l3(&stack->nst, dmsg);
1989                                                         free_msg(msg);
1990                                                         return 0;
1991                                                 }
1992                                                 
1993                                         }
1994 #if 0
1995                                         setup_bc(bc);
1996 #endif
1997
1998                                         break;
1999                                 case EVENT_RELEASE:
2000                                 case EVENT_RELEASE_COMPLETE:
2001                                         if (bc->channel>0)
2002                                                 empty_chan_in_stack(stack, bc->channel);
2003                                         empty_bc(bc);
2004                                         clean_up_bc(bc);
2005                                         break;
2006
2007                                 default:
2008                                 break;
2009                         }
2010                         
2011                         if(!isdn_get_info(msgs_g,event,1)) {
2012                                 cb_log(4, stack->port, "Unknown Event Ind: prim %x dinfo %x\n",hh->prim, hh->dinfo);
2013                         } else {
2014                                 if (reject) {
2015                                         switch(bc->cause){
2016                                                 case 17:
2017                                                         cb_log(1, stack->port, "Siemens Busy reject..\n");
2018
2019                                                         break;
2020                                                 default:
2021                                                         return 0;
2022                                         }
2023                                 }
2024                                 cb_event(event, bc, glob_mgr->user_data);
2025                         }
2026       
2027                 } else {
2028                         cb_log(4, stack->port, "No BC found with l3id: prim %x dinfo %x\n",hh->prim, hh->dinfo);
2029                 }
2030
2031                 free_msg(msg);
2032         }
2033
2034
2035         return 0;
2036 }
2037
2038
2039 int handle_timers(msg_t* msg)
2040 {
2041         iframe_t *frm= (iframe_t*)msg->data;
2042         struct misdn_stack *stack; 
2043   
2044         /* Timer Stuff */
2045         switch (frm->prim) {
2046         case MGR_INITTIMER | CONFIRM:
2047         case MGR_ADDTIMER | CONFIRM:
2048         case MGR_DELTIMER | CONFIRM:
2049         case MGR_REMOVETIMER | CONFIRM:
2050                 free_msg(msg);
2051                 return(1);
2052         }
2053   
2054   
2055   
2056         if (frm->prim==(MGR_TIMER | INDICATION) ) {
2057                 for (stack = glob_mgr->stack_list;
2058                      stack;
2059                      stack = stack->next) {
2060                         itimer_t *it;
2061       
2062                         if (!stack->nt) continue;
2063       
2064                         it = stack->nst.tlist;
2065                         /* find timer */
2066                         for(it=stack->nst.tlist;
2067                             it;
2068                             it=it->next) {
2069                                 if (it->id == (int)frm->addr)
2070                                         break;
2071                         }
2072                         if (it) {
2073                                 int ret;
2074                                 ret = mISDN_write_frame(stack->midev, msg->data, frm->addr,
2075                                                         MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2076                                 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2077                                 ret = it->function(it->data);
2078                                 free_msg(msg);
2079                                 return 1;
2080                         }
2081                 }
2082     
2083                 cb_log(-1, 0, "Timer Msg without Timer ??\n");
2084                 free_msg(msg);
2085                 return 1;
2086         }
2087   
2088         return 0;
2089 }
2090
2091
2092
2093 void misdn_lib_tone_generator_start(struct misdn_bchannel *bc)
2094 {
2095         bc->generate_tone=1;
2096 }
2097
2098 void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
2099 {
2100         bc->generate_tone=0;
2101 }
2102
2103
2104 static int do_tone(struct misdn_bchannel *bc, int len)
2105 {
2106         bc->tone_cnt=len;
2107         
2108         if (bc->generate_tone) {
2109                 cb_event(EVENT_TONE_GENERATE, bc, glob_mgr->user_data);
2110                 
2111                 if ( !bc->nojitter ) {
2112                         misdn_tx_jitter(bc,len);
2113                 }
2114                 
2115                 return 1;
2116         }
2117         
2118         return 0;
2119 }
2120
2121
2122
2123 void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
2124 {
2125         char buf[4096 + mISDN_HEADER_LEN];
2126         char *data=&buf[mISDN_HEADER_LEN];
2127         iframe_t *txfrm= (iframe_t*)buf;
2128         int jlen, r;
2129         
2130         jlen=cb_jb_empty(bc,data,len);
2131         
2132         if (jlen) {
2133                 flip_buf_bits( data, jlen);
2134                 
2135                 if (jlen < len) {
2136                         cb_log(7,bc->port,"Jitterbuffer Underrun.\n");
2137                 }
2138                 
2139                 txfrm->prim = DL_DATA|REQUEST;
2140                 
2141                 txfrm->dinfo = 0;
2142                 
2143                 txfrm->addr = bc->addr|FLG_MSG_DOWN; /*  | IF_DOWN; */
2144                 
2145                 txfrm->len =jlen;
2146                 cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
2147                 
2148                 r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
2149         } else {
2150 #define MISDN_GEN_SILENCE
2151 #ifdef MISDN_GEN_SILENCE
2152                 int cnt=len/TONE_SILENCE_SIZE;
2153                 int rest=len%TONE_SILENCE_SIZE;
2154                 int i;
2155
2156                 for (i=0; i<cnt; i++) {
2157                         memcpy(data, tone_silence_flip, TONE_SILENCE_SIZE );
2158                         data +=TONE_SILENCE_SIZE;
2159                 }
2160
2161                 if (rest) {
2162                         memcpy(data, tone_silence_flip, rest);
2163                 }
2164
2165                 txfrm->prim = DL_DATA|REQUEST;
2166
2167                 txfrm->dinfo = 0;
2168
2169                 txfrm->addr = bc->addr|FLG_MSG_DOWN; /*  | IF_DOWN; */
2170
2171                 txfrm->len =len;
2172                 cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
2173
2174                 r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
2175 #endif
2176
2177         }
2178 }
2179
2180 int handle_bchan(msg_t *msg)
2181 {
2182         iframe_t *frm= (iframe_t*)msg->data;
2183
2184
2185         struct misdn_bchannel *bc=find_bc_by_addr(frm->addr);
2186         
2187         if (!bc) {
2188                 cb_log(1,0,"handle_bchan: BC not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo);
2189                 return 0 ;
2190         }
2191         
2192         struct misdn_stack *stack=get_stack_by_bc(bc);
2193         
2194         if (!stack) {
2195                 cb_log(0, bc->port,"handle_bchan: STACK not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo);
2196                 return 0;
2197         }
2198         
2199         switch (frm->prim) {
2200
2201         case MGR_SETSTACK| CONFIRM:
2202                 cb_log(2, stack->port, "BCHAN: MGR_SETSTACK|CONFIRM pid:%d\n",bc->pid);
2203                 break;
2204                 
2205         case MGR_SETSTACK| INDICATION:
2206                 cb_log(2, stack->port, "BCHAN: MGR_SETSTACK|IND pid:%d\n",bc->pid);
2207         break;
2208 #if 0
2209         AGAIN:
2210                 bc->addr = mISDN_get_layerid(stack->midev, bc->b_stid, bc->layer);
2211                 if (!bc->addr) {
2212
2213                         if (errno == EAGAIN) {
2214                                 usleep(1000);
2215                                 goto AGAIN;
2216                         }
2217                         
2218                         cb_log(0,stack->port,"$$$ Get Layer (%d) Id Error: %s\n",bc->layer,strerror(errno));
2219                         
2220                         /* we kill the channel later, when we received some
2221                            data. */
2222                         bc->addr= frm->addr;
2223                 } else if ( bc->addr < 0) {
2224                         cb_log(-1, stack->port,"$$$ bc->addr <0 Error:%s\n",strerror(errno));
2225                         bc->addr=0;
2226                 }
2227                 
2228                 cb_log(4, stack->port," --> Got Adr %x\n", bc->addr);
2229
2230                 free_msg(msg);
2231         
2232                 
2233                 switch(bc->bc_state) {
2234                 case BCHAN_SETUP:
2235                         bc_state_change(bc,BCHAN_SETUPED);
2236                 break;
2237
2238                 case BCHAN_CLEAN_REQUEST:
2239                 default:
2240                         cb_log(-1, stack->port," --> STATE WASN'T SETUP (but %s) in SETSTACK|IND pid:%d\n",bc_state2str(bc->bc_state), bc->pid);
2241                         clean_up_bc(bc);
2242                 }
2243                 return 1;
2244 #endif
2245
2246         case MGR_DELLAYER| INDICATION:
2247                 cb_log(2, stack->port, "BCHAN: MGR_DELLAYER|IND pid:%d\n",bc->pid);
2248                 break;
2249                 
2250         case MGR_DELLAYER| CONFIRM:
2251                 cb_log(2, stack->port, "BCHAN: MGR_DELLAYER|CNF pid:%d\n",bc->pid);
2252                 
2253                 bc->pid=0;
2254                 bc->addr=0;
2255                 
2256                 free_msg(msg);
2257                 return 1;
2258                 
2259         case PH_ACTIVATE | INDICATION:
2260         case DL_ESTABLISH | INDICATION:
2261                 cb_log(2, stack->port, "BCHAN: ACT Ind pid:%d\n", bc->pid);
2262
2263                 free_msg(msg);
2264                 return 1;    
2265
2266         case PH_ACTIVATE | CONFIRM:
2267         case DL_ESTABLISH | CONFIRM:
2268                 
2269                 cb_log(2, stack->port, "BCHAN: bchan ACT Confirm pid:%d\n",bc->pid);
2270                 free_msg(msg);
2271                 
2272                 return 1;    
2273
2274         case DL_ESTABLISH | REQUEST:
2275                 {
2276                         char buf[128];
2277                         mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN,  DL_ESTABLISH | CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
2278                 }
2279                 free_msg(msg);
2280                 return 1;
2281
2282         case DL_RELEASE|REQUEST:
2283                 {
2284                         char buf[128];
2285                         mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN,  DL_RELEASE| CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
2286                 }
2287                 free_msg(msg);
2288                 return 1;
2289                 
2290         case PH_DEACTIVATE | INDICATION:
2291         case DL_RELEASE | INDICATION:
2292                 cb_log (2, stack->port, "BCHAN: DeACT Ind pid:%d\n",bc->pid);
2293                 
2294                 free_msg(msg);
2295                 return 1;
2296     
2297         case PH_DEACTIVATE | CONFIRM:
2298         case DL_RELEASE | CONFIRM:
2299                 cb_log(4, stack->port, "BCHAN: DeACT Conf pid:%d\n",bc->pid);
2300                 
2301                 free_msg(msg);
2302                 return 1;
2303     
2304         case PH_CONTROL|INDICATION:
2305         {
2306                 unsigned int cont = *((unsigned int *)&frm->data.p);
2307                 
2308                 cb_log(4, stack->port, "PH_CONTROL: channel:%d oad%d:%s dad%d:%s \n", bc->channel, bc->onumplan,bc->oad, bc->dnumplan,bc->dad);
2309
2310                 if ((cont&~DTMF_TONE_MASK) == DTMF_TONE_VAL) {
2311                         int dtmf = cont & DTMF_TONE_MASK;
2312                         cb_log(4, stack->port, " --> DTMF TONE: %c\n",dtmf);
2313                         bc->dtmf=dtmf;
2314                         cb_event(EVENT_DTMF_TONE, bc, glob_mgr->user_data);
2315         
2316                         free_msg(msg);
2317                         return 1;
2318                 }
2319                 if (cont == BF_REJECT) {
2320                         cb_log(4, stack->port, " --> BF REJECT\n");
2321                         free_msg(msg);
2322                         return 1;
2323                 }
2324                 if (cont == BF_ACCEPT) {
2325                         cb_log(4, stack->port, " --> BF ACCEPT\n");
2326                         free_msg(msg);
2327                         return 1;
2328                 }
2329         }
2330         break;
2331
2332         case PH_DATA|REQUEST:
2333         case DL_DATA|REQUEST:
2334                 cb_log(0, stack->port, "DL_DATA REQUEST \n");
2335                 do_tone(bc, 64);
2336                 
2337                 free_msg(msg);
2338                 return 1;
2339         
2340         
2341         case PH_DATA|INDICATION:
2342         case DL_DATA|INDICATION:
2343         {
2344                 bc->bframe = (void*)&frm->data.i;
2345                 bc->bframe_len = frm->len;
2346
2347                 /** Anyway flip the bufbits **/
2348                 if ( misdn_cap_is_speech(bc->capability) ) 
2349                         flip_buf_bits(bc->bframe, bc->bframe_len);
2350         
2351
2352                 if (!bc->bframe_len) {
2353                         cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
2354                         free_msg(msg);
2355                         return 1;
2356                 }
2357
2358                 if ( (bc->addr&STACK_ID_MASK) != (frm->addr&STACK_ID_MASK) ) {
2359                         cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
2360                         free_msg(msg);
2361                         return 1;
2362                 }
2363                 
2364 #if MISDN_DEBUG
2365                 cb_log(-1, stack->port, "DL_DATA INDICATION Len %d\n", frm->len);
2366
2367 #endif
2368                 
2369                 if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) {
2370                         int t;
2371
2372 #ifdef MISDN_B_DEBUG
2373                         cb_log(0,bc->port,"do_tone START\n");
2374 #endif
2375                         t=do_tone(bc,frm->len);
2376
2377 #ifdef MISDN_B_DEBUG
2378                         cb_log(0,bc->port,"do_tone STOP (%d)\n",t);
2379 #endif
2380                         if (  !t ) {
2381                                 
2382                                 if ( misdn_cap_is_speech(bc->capability)) {
2383                                         if ( !bc->nojitter ) {
2384 #ifdef MISDN_B_DEBUG
2385                                                 cb_log(0,bc->port,"tx_jitter START\n");
2386 #endif
2387                                                 misdn_tx_jitter(bc,frm->len);
2388 #ifdef MISDN_B_DEBUG
2389                                                 cb_log(0,bc->port,"tx_jitter STOP\n");
2390 #endif
2391                                         }
2392                                 }
2393
2394 #ifdef MISDN_B_DEBUG    
2395                                 cb_log(0,bc->port,"EVENT_B_DATA START\n");
2396 #endif
2397                                 
2398                                 int i=cb_event( EVENT_BCHAN_DATA, bc, glob_mgr->user_data);
2399 #ifdef MISDN_B_DEBUG    
2400                                 cb_log(0,bc->port,"EVENT_B_DATA STOP\n");
2401 #endif
2402                                 
2403                                 if (i<0) {
2404                                         cb_log(10,stack->port,"cb_event returned <0\n");
2405                                         /*clean_up_bc(bc);*/
2406                                 }
2407                         }
2408                 }
2409                 free_msg(msg);
2410                 return 1;
2411         }
2412
2413
2414         case PH_CONTROL | CONFIRM:
2415                 cb_log(2, stack->port, "PH_CONTROL|CNF bc->addr:%x\n", frm->addr);
2416                 free_msg(msg);
2417                 return 1;
2418
2419         case PH_DATA | CONFIRM:
2420         case DL_DATA|CONFIRM:
2421 #if MISDN_DEBUG
2422
2423                 cb_log(-1, stack->port, "Data confirmed\n");
2424
2425 #endif
2426                 free_msg(msg);
2427                 
2428                 return 1;
2429         case DL_DATA|RESPONSE:
2430 #if MISDN_DEBUG
2431                 cb_log(-1, stack->port, "Data response\n");
2432
2433 #endif
2434                 break;
2435         }
2436   
2437         return 0;
2438 }
2439
2440
2441
2442 int handle_frm_nt(msg_t *msg)
2443 {
2444         iframe_t *frm= (iframe_t*)msg->data;
2445         struct misdn_stack *stack;
2446         int err=0;
2447
2448         stack=find_stack_by_addr( frm->addr );
2449
2450         
2451   
2452         if (!stack || !stack->nt) {
2453                 return 0;
2454         }
2455
2456         
2457         if ((err=stack->nst.l1_l2(&stack->nst,msg))) {
2458     
2459                 if (nt_err_cnt > 0 ) {
2460                         if (nt_err_cnt < 100) {
2461                                 nt_err_cnt++; 
2462                                 cb_log(-1, stack->port, "NT Stack sends us error: %d \n", err);
2463                         } else if (nt_err_cnt < 105){
2464                                 cb_log(-1, stack->port, "NT Stack sends us error: %d over 100 times, so I'll stop this message\n", err);
2465                                 nt_err_cnt = - 1; 
2466                         }
2467                 }
2468                 free_msg(msg);
2469                 return 1;
2470                 
2471         }
2472         
2473         return 1;
2474 }
2475
2476
2477 int handle_frm(msg_t *msg)
2478 {
2479         iframe_t *frm = (iframe_t*) msg->data;
2480         
2481         struct misdn_stack *stack=find_stack_by_addr(frm->addr);
2482
2483         
2484         cb_log(4,stack?stack->port:0,"handle_frm: frm->addr:%x frm->prim:%x\n",frm->addr,frm->prim);
2485         
2486   
2487         if (!stack || stack->nt) {
2488                 return 0;
2489         }
2490
2491         {
2492                 struct misdn_bchannel *bc;
2493                 int ret=handle_cr(stack, frm);
2494
2495                 if (ret<0) {
2496                         cb_log(3,stack?stack->port:0,"handle_frm: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr);
2497                 }
2498
2499                 if(ret) {
2500                         free_msg(msg);
2501                         return 1;
2502                 }
2503     
2504                 bc=find_bc_by_l3id(stack, frm->dinfo);
2505     
2506                 if (bc ) {
2507                         enum event_e event = isdn_msg_get_event(msgs_g, msg, 0);
2508                         enum event_response_e response=RESPONSE_OK;
2509       
2510                         isdn_msg_parse_event(msgs_g,msg,bc, 0);
2511                         
2512                         /** Preprocess some Events **/
2513                         handle_event(bc, event, frm);
2514                         /*  shoot up event to App: */
2515                         cb_log(5, stack->port, "lib Got Prim: Addr %x prim %x dinfo %x\n",frm->addr, frm->prim, frm->dinfo);
2516       
2517                         if(!isdn_get_info(msgs_g,event,0)) 
2518                                 cb_log(-1, stack->port, "Unknown Event Ind: Addr:%x prim %x dinfo %x\n",frm->addr, frm->prim, frm->dinfo);
2519                         else 
2520                                 response=cb_event(event, bc, glob_mgr->user_data);
2521 #if 1
2522                         if (event == EVENT_SETUP) {
2523                                 switch (response) {
2524                                 case RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE:
2525
2526                                         cb_log(-1, stack->port, "TOTALY IGNORING SETUP \n");                                    
2527                                         
2528                                         break;
2529                                 case RESPONSE_IGNORE_SETUP:
2530                                         /* I think we should send CC_RELEASE_CR, but am not sure*/
2531
2532                                         bc->out_cause=16;
2533                                         misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
2534                                         if (bc->channel>0)
2535                                                 empty_chan_in_stack(stack, bc->channel);
2536                                         empty_bc(bc);
2537                                         bc_state_change(bc,BCHAN_CLEANED);
2538
2539                                         cb_log(-1, stack->port, "GOT IGNORE SETUP\n");
2540
2541                                         
2542                                         break;
2543                                 case RESPONSE_OK:
2544                                         cb_log(4, stack->port, "GOT SETUP OK\n");
2545
2546                                         
2547                                         break;
2548                                 default:
2549                                         break;
2550                                 }
2551                         }
2552
2553                         cb_log(5, stack->port, "Freeing Msg on prim:%x \n",frm->prim);
2554
2555                         
2556                         free_msg(msg);
2557                         return 1;
2558 #endif
2559       
2560                 } else {
2561                         cb_log(-1, stack->port, "NO BC FOR STACK\n");           
2562                 }
2563         }
2564
2565         cb_log(4, stack->port, "TE_FRM_HANDLER: Returning 0 on prim:%x \n",frm->prim);
2566         return 0;
2567 }
2568
2569
2570 int handle_l1(msg_t *msg)
2571 {
2572         iframe_t *frm = (iframe_t*) msg->data;
2573         struct misdn_stack *stack = find_stack_by_addr(frm->addr);
2574         int i ;
2575         
2576         if (!stack) return 0 ;
2577   
2578         switch (frm->prim) {
2579         case PH_ACTIVATE | CONFIRM:
2580         case PH_ACTIVATE | INDICATION:
2581                 cb_log (1, stack->port, "L1: PH L1Link Up!\n");
2582                 stack->l1link=1;
2583                 
2584                 if (stack->nt) {
2585                         
2586                         if (stack->nst.l1_l2(&stack->nst, msg))
2587                                 free_msg(msg);
2588                 } else {
2589                         free_msg(msg);
2590                 }
2591                 
2592                 for (i=0;i<stack->b_num; i++) {
2593                         if (stack->bc[i].evq != EVENT_NOTHING) {
2594                                 cb_log(4, stack->port, "Fireing Queued Event %s because L1 got up\n", isdn_get_info(msgs_g, stack->bc[i].evq, 0));
2595                                 misdn_lib_send_event(&stack->bc[i],stack->bc[i].evq);
2596                                 stack->bc[i].evq=EVENT_NOTHING;
2597                         }
2598                         
2599                 }
2600                 return 1;
2601
2602         case PH_ACTIVATE | REQUEST:
2603                 free_msg(msg);
2604                 cb_log(1,stack->port,"L1: PH_ACTIVATE|REQUEST \n");
2605                 return 1;
2606                 
2607         case PH_DEACTIVATE | REQUEST:
2608                 free_msg(msg);
2609                 cb_log(1,stack->port,"L1: PH_DEACTIVATE|REQUEST \n");
2610                 return 1;
2611                 
2612         case PH_DEACTIVATE | CONFIRM:
2613         case PH_DEACTIVATE | INDICATION:
2614                 cb_log (1, stack->port, "L1: PH L1Link Down! \n");
2615                 
2616                 for (i=0; i<stack->b_num; i++) {
2617                         if (global_state == MISDN_INITIALIZED)  {
2618                                 cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data);
2619                         }
2620                 }
2621                 
2622                 if (stack->nt) {
2623                         if (stack->nst.l1_l2(&stack->nst, msg))
2624                                 free_msg(msg);
2625                 } else {
2626                         free_msg(msg);
2627                 }
2628                 
2629                 stack->l1link=0;
2630                 stack->l2link=0;
2631                 
2632                 return 1;
2633         }
2634   
2635         return 0;
2636 }
2637
2638 int handle_l2(msg_t *msg)
2639 {
2640         iframe_t *frm = (iframe_t*) msg->data;
2641
2642         struct misdn_stack *stack = find_stack_by_addr(frm->addr);
2643         
2644         if (!stack) {
2645                 return 0 ;
2646         }
2647         
2648         switch(frm->prim) {
2649
2650         case DL_ESTABLISH | REQUEST:
2651                 cb_log(1,stack->port,"DL_ESTABLISH|REQUEST \n");
2652                 return 1;
2653         case DL_RELEASE | REQUEST:
2654                 cb_log(1,stack->port,"DL_RELEASE|REQUEST \n");
2655                 return 1;
2656                 
2657         case DL_ESTABLISH | INDICATION:
2658         case DL_ESTABLISH | CONFIRM:
2659         {
2660                 cb_log (3, stack->port, "L2: L2Link Up! \n");
2661                 stack->l2link=1;
2662                 free_msg(msg);
2663                 return 1;
2664         }
2665         break;
2666     
2667         case DL_RELEASE | INDICATION:
2668         case DL_RELEASE | CONFIRM:
2669         {
2670                 cb_log (3, stack->port, "L2: L2Link Down! \n");
2671                 stack->l2link=0;
2672                 
2673                 free_msg(msg);
2674                 return 1;
2675         }
2676         break;
2677         }
2678         return 0;
2679 }
2680
2681 int handle_mgmt(msg_t *msg)
2682 {
2683         iframe_t *frm = (iframe_t*) msg->data;
2684
2685         if ( (frm->addr == 0) && (frm->prim == (MGR_DELLAYER|CONFIRM)) ) {
2686                 cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: 0 !\n") ;
2687                 free_msg(msg);
2688                 return 1;
2689         }
2690         
2691         struct misdn_stack * stack=find_stack_by_addr(frm->addr);
2692         
2693         if (!stack) {
2694                 if (frm->prim == (MGR_DELLAYER|CONFIRM)) {
2695                         cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: %x !\n",
2696                                         frm->addr) ;
2697                         free_msg(msg);
2698                         return 1;
2699                 }
2700                 
2701                 return 0;
2702         }
2703         
2704         switch(frm->prim) {
2705         case MGR_SHORTSTATUS | INDICATION:
2706         case MGR_SHORTSTATUS | CONFIRM:
2707                 cb_log(2, 0, "MGMT: Short status dinfo %x\n",frm->dinfo);
2708                 
2709                 switch (frm->dinfo) {
2710                 case SSTATUS_L1_ACTIVATED:
2711                         cb_log(1, 0, "MGMT: SSTATUS: L1_ACTIVATED \n");
2712                         stack->l1link=1;
2713                 
2714                         break;
2715                 case SSTATUS_L1_DEACTIVATED:
2716                         cb_log(1, 0, "MGMT: SSTATUS: L1_DEACTIVATED \n");
2717                         stack->l1link=0;
2718
2719                         clear_l3(stack);
2720                         break;
2721
2722                 case SSTATUS_L2_ESTABLISHED:
2723                         cb_log(1, stack->port, "MGMT: SSTATUS: L2_ESTABLISH \n");
2724                         stack->l2link=1;
2725                         break;
2726                         
2727                 case SSTATUS_L2_RELEASED:
2728                         cb_log(1, stack->port, "MGMT: SSTATUS: L2_RELEASED \n");
2729                         stack->l2link=0;
2730                         break;
2731                 }
2732                 
2733                 free_msg(msg);
2734                 return 1;
2735                 
2736         case MGR_SETSTACK | INDICATION:
2737                 cb_log(2, stack->port, "MGMT: SETSTACK|IND dinfo %x\n",frm->dinfo);
2738                 free_msg(msg);
2739                 return 1;
2740         case MGR_DELLAYER | CONFIRM:
2741                 cb_log(2, stack->port, "MGMT: DELLAYER|CNF dinfo %x\n",frm->dinfo) ;
2742                 free_msg(msg);
2743                 return 1;
2744                 
2745         }
2746         
2747         /*
2748         if ( (frm->prim & 0x0f0000) ==  0x0f0000) {
2749         cb_log(5, 0, "$$$ MGMT FRAME: prim %x addr %x dinfo %x\n",frm->prim, frm->addr, frm->dinfo) ;
2750         free_msg(msg);
2751         return 1;
2752         } */
2753     
2754         return 0;
2755 }
2756
2757
2758 msg_t *fetch_msg(int midev) 
2759 {
2760         msg_t *msg=alloc_msg(MAX_MSG_SIZE);
2761         int r;
2762 /*      fd_set rdfs; */
2763
2764         if (!msg) {
2765                 cb_log(-1, 0, "fetch_msg: alloc msg failed !!");
2766                 return NULL;
2767         }
2768
2769 #if 0
2770         FD_ZERO(&rdfs);
2771         FD_SET(midev,&rdfs);
2772   
2773         mISDN_select(FD_SETSIZE, &rdfs, NULL, NULL, NULL);
2774         //select(FD_SETSIZE, &rdfs, NULL, NULL, NULL);
2775   
2776         if (FD_ISSET(midev, &rdfs)) {
2777 #endif
2778
2779         AGAIN:
2780                 r=mISDN_read(midev,msg->data,MAX_MSG_SIZE, TIMEOUT_10SEC);
2781                 msg->len=r;
2782     
2783                 if (r==0) {
2784                         free_msg(msg); /* danger, cauz usualy freeing in main_loop */
2785                         cb_log(6,0,"Got empty Msg..\n");
2786                         return NULL;
2787                 }
2788
2789                 if (r<0) {
2790                         if (errno == EAGAIN) {
2791                                 /*we wait for mISDN here*/
2792                                 cb_log(4,0,"mISDN_read wants us to wait\n");
2793                                 usleep(5000);
2794                                 goto AGAIN;
2795                         }
2796                         
2797                         cb_log(-1,0,"mISDN_read returned :%d error:%s (%d)\n",r,strerror(errno),errno); 
2798                 }
2799
2800                 return msg;
2801
2802 #if 0
2803         } else {
2804                 printf ("Select timeout\n");
2805         }
2806 #endif
2807   
2808         return NULL;
2809 }
2810
2811 static void misdn_lib_isdn_l1watcher(void *arg)
2812 {
2813         struct misdn_lib *mgr = arg;
2814         struct misdn_stack *stack;
2815
2816         while (1) {
2817                 sleep(mgr->l1watcher_timeout);
2818                 
2819                 /* look out for l1 which are down
2820                    and try to pull the up.
2821
2822                    We might even try to pull the l2 up in the
2823                    ptp case.
2824                 */
2825                 for (stack = mgr->stack_list;
2826                      stack;
2827                      stack = stack->next) {
2828                         cb_log(4,stack->port,"Checking L1 State\n");    
2829                         if (!stack->l1link) {
2830                                 cb_log(4,stack->port,"L1 State Down, trying to get it up again\n");     
2831                                 misdn_lib_get_short_status(stack);
2832                                 misdn_lib_get_l1_up(stack); 
2833                                 misdn_lib_get_l2_up(stack); 
2834                         }
2835                 }
2836         }
2837 }
2838
2839 static void misdn_lib_isdn_event_catcher(void *arg)
2840 {
2841         struct misdn_lib *mgr = arg;
2842         int zero_frm=0 , fff_frm=0 ;
2843         int midev= mgr->midev;
2844         int port=0;
2845         
2846         while (1) {
2847                 msg_t *msg = fetch_msg(midev); 
2848                 iframe_t *frm;
2849                 
2850                 
2851                 if (!msg) continue;
2852                 
2853                 frm = (iframe_t*) msg->data;
2854                 
2855                 /** When we make a call from NT2Ast we get this frames **/
2856                 if (frm->len == 0 && frm->addr == 0 && frm->dinfo == 0 && frm->prim == 0 ) {
2857                         zero_frm++; 
2858                         free_msg(msg);
2859                         continue;
2860                 } else {
2861                         if (zero_frm) {
2862                                 cb_log(-1, port, "*** Alert: %d zero_frms caught\n", zero_frm);
2863                                 zero_frm = 0 ;
2864                         }
2865                 }
2866                 
2867                 /** I get this sometimes after setup_bc **/
2868                 if (frm->len == 0 &&  frm->dinfo == 0 && frm->prim == 0xffffffff ) {
2869                         fff_frm++; 
2870                         free_msg(msg);
2871                         continue;
2872                 } else {
2873                         if (fff_frm) {
2874                                 cb_log(-1, port, "*** Alert: %d fff_frms caught\n", fff_frm);
2875                                 fff_frm = 0 ;
2876                         }
2877                 }
2878                 
2879                 manager_isdn_handler(frm, msg);
2880         }
2881
2882 }
2883
2884
2885 /** App Interface **/
2886
2887 int te_lib_init() {
2888         char buff[1025];
2889         iframe_t *frm=(iframe_t*)buff;
2890         int midev=mISDN_open();
2891         int ret;
2892
2893         memset(buff,0,1025);
2894   
2895         if  (midev<=0) return midev;
2896   
2897 /* create entity for layer 3 TE-mode */
2898         mISDN_write_frame(midev, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2899         ret = mISDN_read_frame(midev, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
2900   
2901         if (ret < mISDN_HEADER_LEN) {
2902         noentity:
2903                 fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN: %s\n",strerror(errno));
2904                 exit(-1);
2905         }
2906   
2907         entity = frm->dinfo & 0xffff ;
2908   
2909         if (!entity)
2910                 goto noentity;
2911
2912         return midev;
2913   
2914 }
2915
2916 void te_lib_destroy(int midev)
2917 {
2918         char buf[1024];
2919         mISDN_write_frame(midev, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
2920
2921         cb_log(4, 0, "Entetity deleted\n");
2922         mISDN_close(midev);
2923         cb_log(4, 0, "midev closed\n");
2924 }
2925
2926
2927
2928 void misdn_lib_transfer(struct misdn_bchannel* holded_bc)
2929 {
2930         holded_bc->holded=0;
2931 }
2932
2933 struct misdn_bchannel *manager_find_bc_by_pid(int pid)
2934 {
2935         struct misdn_stack *stack;
2936         int i;
2937   
2938         for (stack=glob_mgr->stack_list;
2939              stack;
2940              stack=stack->next) {
2941                 for (i=0; i<stack->b_num; i++)
2942                         if (stack->bc[i].pid == pid) return &stack->bc[i];
2943         }
2944   
2945         return NULL;
2946 }
2947
2948 struct misdn_bchannel *manager_find_bc_holded(struct misdn_bchannel* bc)
2949 {
2950         struct misdn_stack *stack=get_stack_by_bc(bc);
2951         return find_bc_holded(stack);
2952 }
2953
2954
2955
2956 void prepare_bc(struct misdn_bchannel*bc, int channel)
2957 {
2958         bc->channel = channel;
2959         bc->channel_preselected = channel?1:0;
2960         bc->in_use = 1;
2961         bc->need_disconnect=1;
2962         bc->need_release=1;
2963         bc->need_release_complete=1;
2964
2965         if (++mypid>5000) mypid=1;
2966         bc->pid=mypid;
2967
2968 #if 0
2969         bc->addr=0;
2970         bc->b_stid=0;
2971         bc->layer_id=0;
2972 #endif
2973 }
2974
2975 struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel)
2976 {
2977         struct misdn_stack *stack;
2978         int i;
2979         
2980         if (channel < 0 || channel > MAX_BCHANS) {
2981                 cb_log(-1,port,"Requested channel out of bounds (%d)\n",channel);
2982                 return NULL;
2983         }
2984
2985         for (stack=glob_mgr->stack_list; stack; stack=stack->next) {
2986     
2987                 if (stack->port == port) {
2988                         if (channel > 0) {
2989                                 if (channel <= stack->b_num) {
2990                                         for (i = 0; i < stack->b_num; i++) {
2991                                                 if (stack->bc[i].in_use && stack->bc[i].channel == channel) {
2992                                                         cb_log(-1,port,"Requested channel:%d on port:%d is already in use\n",channel, port);
2993                                                         return NULL;
2994                                                 }
2995                                         }
2996                                 } else {
2997                                         cb_log(-1,port,"Requested channel:%d is out of bounds on port:%d\n",channel, port);
2998                                         return NULL;
2999                                 }
3000                         }
3001                         for (i = 0; i < stack->b_num; i++) {
3002                                 if (!stack->bc[i].in_use) {
3003                                         prepare_bc(&stack->bc[i], channel);
3004                                         return &stack->bc[i];
3005                                 }
3006                         }
3007
3008                         cb_log(-1,port,"There is no free channel on port (%d)\n",port);
3009                         return NULL;
3010                 }
3011         }
3012
3013         cb_log(-1,port,"Port is not configured (%d)\n",port);
3014         return NULL;
3015 }
3016
3017
3018 char *fac2str (enum facility_type type) {
3019         struct arr_el { 
3020                 enum facility_type p; 
3021                 char *s ; 
3022         } arr[] = {
3023                 { FACILITY_NONE, "FAC_NONE" },
3024                 { FACILITY_CALLDEFLECT, "FAC_CALLDEFLECT"},
3025                 { FACILITY_CENTREX, "FAC_CENTREX"}
3026         };
3027         
3028         int i;
3029         
3030         for (i=0; i < sizeof(arr)/sizeof( struct arr_el) ; i ++)
3031                 if ( arr[i].p==type) return arr[i].s;
3032         
3033         return "FAC_UNKNOWN";
3034 }
3035
3036 void misdn_lib_log_ies(struct misdn_bchannel *bc)
3037 {
3038         if (!bc) return;
3039
3040         struct misdn_stack *stack=get_stack_by_bc(bc);
3041
3042         if (!stack) return;
3043
3044         cb_log(2, stack->port, " --> mode:%s cause:%d ocause:%d rad:%s cad:%s\n", stack->nt?"NT":"TE", bc->cause, bc->out_cause, bc->rad, bc->cad);
3045         
3046         cb_log(3, stack->port, " --> facility:%s out_facility:%s\n",fac2str(bc->fac_type),fac2str(bc->out_fac_type));
3047         
3048         cb_log(2, stack->port,
3049                " --> info_dad:%s onumplan:%c dnumplan:%c rnumplan:%c cpnnumplan:%c\n",
3050                bc->info_dad,
3051                bc->onumplan>=0?'0'+bc->onumplan:' ',
3052                bc->dnumplan>=0?'0'+bc->dnumplan:' ',
3053                bc->rnumplan>=0?'0'+bc->rnumplan:' ',
3054                bc->cpnnumplan>=0?'0'+bc->cpnnumplan:' '
3055                 );
3056         cb_log(3, stack->port, " --> screen:%d --> pres:%d\n",
3057                         bc->screen, bc->pres);
3058         
3059         cb_log(2, stack->port, " --> channel:%d caps:%s pi:%x keypad:%s sending_complete:%d\n", bc->channel, bearer2str(bc->capability),bc->progress_indicator, bc->keypad, bc->sending_complete);
3060
3061         cb_log(3, stack->port, " --> urate:%d rate:%d mode:%d user1:%d\n", bc->urate, bc->rate, bc->mode,bc->user1);
3062         
3063         cb_log(3, stack->port, " --> pid:%d addr:%x l3id:%x\n", bc->pid, bc->addr, bc->l3_id);
3064         cb_log(3, stack->port, " --> b_stid:%x layer_id:%x\n", bc->b_stid, bc->layer_id);
3065         
3066         cb_log(4, stack->port, " --> bc:%x h:%d sh:%d\n", bc, bc->holded, bc->stack_holder);
3067 }
3068
3069 int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
3070 {
3071         msg_t *msg; 
3072         int err = -1 ;
3073         int ret=0;
3074   
3075         if (!bc) goto ERR; 
3076         
3077         struct misdn_stack *stack=get_stack_by_bc(bc);
3078         
3079         if (!stack) {
3080                 cb_log(-1,bc->port,"SENDEVENT: no Stack for event:%s oad:%s dad:%s \n", isdn_get_info(msgs_g, event, 0), bc->oad, bc->dad);
3081                 return -1;
3082         }
3083         
3084         cb_log(6,stack->port,"SENDEVENT: stack->nt:%d stack->uperid:%x\n",stack->nt, stack->upper_id);
3085
3086         if ( stack->nt && !stack->l1link) {
3087                 /** Queue Event **/
3088                 bc->evq=event;
3089                 cb_log(1, stack->port, "Queueing Event %s because L1 is down (btw. Activating L1)\n", isdn_get_info(msgs_g, event, 0));
3090                 misdn_lib_get_l1_up(stack);
3091                 return 0;
3092         }
3093         
3094         cb_log(1, stack->port, "I SEND:%s oad:%s dad:%s pid:%d\n", isdn_get_info(msgs_g, event, 0), bc->oad, bc->dad, bc->pid);
3095         cb_log(1, stack->port, " --> bc_state:%s\n",bc_state2str(bc->bc_state));
3096         misdn_lib_log_ies(bc);
3097         
3098         switch (event) {
3099         case EVENT_SETUP:
3100                 if (create_process(glob_mgr->midev, bc)<0) {
3101                         cb_log(-1,  stack->port, " No free channel at the moment @ send_event\n");
3102
3103                         err=-ENOCHAN;
3104                         goto ERR;
3105                 }
3106 #if 0
3107                 ret=setup_bc(bc);
3108                 if (ret == -EINVAL) {
3109                         cb_log(-1,bc->port,"send_event: setup_bc failed\n");
3110                 }
3111 #endif
3112                 break;
3113
3114         case EVENT_PROGRESS:
3115         case EVENT_ALERTING:
3116         case EVENT_PROCEEDING:
3117         case EVENT_SETUP_ACKNOWLEDGE:
3118                 if (!bc->nt && !stack->ptp) break;
3119
3120         case EVENT_CONNECT:
3121         case EVENT_RETRIEVE_ACKNOWLEDGE:
3122                 if (stack->nt) {
3123                         if (bc->channel <=0 ) { /*  else we have the channel already */
3124                                 bc->channel = find_free_chan_in_stack(stack, bc, 0);
3125                                 if (!bc->channel) {
3126                                         cb_log(-1, stack->port, " No free channel at the moment\n");
3127                                         
3128                                         err=-ENOCHAN;
3129