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