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