when we get a disconnect, we should stop the tones on te side..
[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                                 
1499                                 bc_state_change(bc, BCHAN_EMPTY);
1500
1501                                 clean_up_bc(bc);
1502                                 dump_chan_list(stack);
1503                                 bc->pid = 0;
1504                                 cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data);
1505                                 if (bc->stack_holder) {
1506                                         cb_log(4,stack->port, "REMOVEING Holder\n");
1507                                         stack_holder_remove( stack, bc);
1508                                         free(bc);
1509                                 }
1510                         }
1511                         else {
1512                                 if (stack->nt) 
1513                                         cb_log(4, stack->port, "BC with dinfo: %x  not found.. (prim was %x and addr %x)\n",frm->dinfo, frm->prim, frm->addr);
1514                         }
1515       
1516                         return 1;
1517                 }
1518                 break;
1519         }
1520   
1521         return 0;
1522 }
1523
1524
1525 /*Emptys bc if it's reserved (no SETUP out yet)*/
1526 void misdn_lib_release(struct misdn_bchannel *bc)
1527 {
1528         struct misdn_stack *stack=get_stack_by_bc(bc);
1529
1530         if (!stack) {
1531                 cb_log(1,0,"misdn_release: No Stack found\n");
1532                 return;
1533         }
1534         
1535         if (bc->channel>=0) {
1536                 empty_chan_in_stack(stack,bc->channel);
1537                 empty_bc(bc);
1538         }
1539         clean_up_bc(bc);
1540 }
1541
1542
1543
1544
1545 int misdn_lib_get_port_up (int port) 
1546 { /* Pull Up L1 */ 
1547         struct misdn_stack *stack;
1548         
1549         for (stack=glob_mgr->stack_list;
1550              stack;
1551              stack=stack->next) {
1552                 
1553                 if (stack->port == port) {
1554
1555                         if (!stack->l1link)
1556                                 misdn_lib_get_l1_up(stack);
1557                         if (!stack->l2link)
1558                                 misdn_lib_get_l2_up(stack);
1559                         
1560                         return 0;
1561                 }
1562         }
1563         return 0;
1564 }
1565
1566
1567 int misdn_lib_get_port_down (int port) 
1568 { /* Pull Down L1 */ 
1569         struct misdn_stack *stack;
1570         for (stack=glob_mgr->stack_list;
1571              stack;
1572              stack=stack->next) {
1573                 if (stack->port == port) {
1574                                 if (stack->l2link)
1575                                         misdn_lib_get_l2_down(stack);
1576                                 misdn_lib_get_l1_down(stack);
1577                         return 0;
1578                 }
1579         }
1580         return 0;
1581 }
1582
1583 int misdn_lib_send_facility(struct misdn_bchannel *bc, enum facility_type fac, void *data)
1584 {
1585         switch (fac) {
1586         case FACILITY_CALLDEFLECT:
1587                 strcpy(bc->out_fac.calldeflect_nr,(char*)data);
1588                 break;
1589         default:
1590                 cb_log(1,bc?bc->port:0,"We don't handle this facility yet: %d\n",fac);
1591                 return 0;
1592         }
1593         
1594         bc->out_fac_type=fac;
1595         
1596         misdn_lib_send_event(bc,EVENT_FACILITY);
1597         return 0;
1598 }
1599
1600
1601 int misdn_lib_port_up(int port, int check)
1602 {
1603         struct misdn_stack *stack;
1604
1605
1606         for (stack=glob_mgr->stack_list;
1607              stack;
1608              stack=stack->next) {
1609                 
1610                 if ( !stack->ptp && !check) return 1;
1611                 
1612                 if (stack->port == port) {
1613                         if (stack->l1link)
1614                                 return 1;
1615                         else {
1616                                 cb_log(-1,port, "Port down [%s]\n",
1617                                        stack->ptp?"PP":"PMP");
1618                                 return 0;
1619                         }
1620                 }
1621         }
1622   
1623         return -1;
1624 }
1625
1626
1627 int
1628 handle_event_nt(void *dat, void *arg)
1629 {
1630         manager_t *mgr = (manager_t *)dat;
1631         msg_t *msg = (msg_t *)arg;
1632         mISDNuser_head_t *hh;
1633         int reject=0;
1634
1635         struct misdn_stack *stack=find_stack_by_mgr(mgr);
1636         int port;
1637
1638         if (!msg || !mgr)
1639                 return(-EINVAL);
1640
1641         hh=(mISDNuser_head_t*)msg->data;
1642         port=stack->port;
1643         
1644         cb_log(4, stack->port, " --> lib: prim %x dinfo %x\n",hh->prim, hh->dinfo);
1645         {
1646                 switch(hh->prim){
1647                 case CC_RETRIEVE|INDICATION:
1648                 {
1649                         iframe_t frm; /* fake te frm to add callref to global callreflist */
1650                         frm.dinfo = hh->dinfo;
1651
1652                         frm.addr=stack->upper_id | FLG_MSG_DOWN;
1653
1654                         frm.prim = CC_NEW_CR|INDICATION;
1655                         
1656                         if (handle_cr( stack, &frm)< 0) {
1657                                 msg_t *dmsg;
1658                                 cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
1659                                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1660                                 stack->nst.manager_l3(&stack->nst, dmsg);
1661                                 free_msg(msg);
1662                                 return 0;
1663                         }
1664                         
1665                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1666                         cb_event(EVENT_NEW_BC, bc, glob_mgr->user_data);
1667                         struct misdn_bchannel *hold_bc=stack_holder_find(stack,bc->l3_id);
1668                         if (hold_bc) {
1669                                 cb_log(4, stack->port, "REMOVEING Holder\n");
1670                                 stack_holder_remove(stack, hold_bc);
1671                                 free(hold_bc);
1672                         }
1673                         
1674                 }
1675                         
1676                         break;
1677                         
1678                 case CC_SETUP|CONFIRM:
1679                 {
1680                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1681                         int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE));
1682                         cb_log(4, stack->port, " --> lib: Event_ind:SETUP CONFIRM [NT] : new L3ID  is %x\n",l3id );
1683         
1684                         if (!bc) { cb_log(4, stack->port, "Bc Not found (after SETUP CONFIRM)\n"); return 0; }
1685                         cb_log (2,bc->port,"I IND :CC_SETUP|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
1686                         bc->l3_id=l3id;
1687                         cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
1688                 }
1689                 free_msg(msg);
1690                 return 0;
1691       
1692                 case CC_SETUP|INDICATION:
1693                 {
1694                         iframe_t frm; /* fake te frm to add callref to global callreflist */
1695                         frm.dinfo = hh->dinfo;
1696                         frm.addr=stack->upper_id;
1697                         frm.prim = CC_NEW_CR|INDICATION;
1698                         
1699                         if (handle_cr(stack, &frm)< 0) {
1700                                 msg_t *dmsg;
1701                                 cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
1702                                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1703                                 stack->nst.manager_l3(&stack->nst, dmsg);
1704                                 free_msg(msg);
1705                                 return 0;
1706                         }
1707                 }
1708                 break;
1709
1710                 case CC_CONNECT_ACKNOWLEDGE|INDICATION:
1711 #if 0
1712                 {
1713                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1714                         if (bc) {
1715                                 if ( !misdn_cap_is_speech(bc->capability)) {
1716                                         int ret=setup_bc(bc);
1717                                         if (ret == -EINVAL){
1718                                                 cb_log(-1,bc->port,"send_event: setup_bc failed\n");
1719                                                 
1720                                         }
1721                                 }
1722                                 
1723                                 manager_bchannel_activate(bc);
1724                         }
1725                 }
1726 #endif
1727                 break;
1728                 
1729                 case CC_ALERTING|INDICATION:
1730                 case CC_PROCEEDING|INDICATION:
1731                 case CC_SETUP_ACKNOWLEDGE|INDICATION:
1732                         if(!stack->ptp) break;  
1733                 case CC_CONNECT|INDICATION:
1734                 {
1735                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1736                         
1737                         if (!bc) {
1738                                 msg_t *dmsg;
1739                                 cb_log(-1, stack->port,"!!!! We didn't found our bc, dinfo:%x on this port.\n",hh->dinfo);
1740                                 
1741                                 cb_log(-1, stack->port, "Releaseing call %x (No free Chan for you..)\n", hh->dinfo);
1742                                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1743                                 stack->nst.manager_l3(&stack->nst, dmsg);
1744                                 free_msg(msg);
1745                                 return 0;
1746                                 
1747                         }
1748                         int ret=setup_bc(bc);
1749                         if (ret == -EINVAL){
1750                                 cb_log(-1,bc->port,"handle_event_nt: setup_bc failed\n");
1751                                 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
1752                         }
1753                 }
1754                 break;
1755                 case CC_DISCONNECT|INDICATION:
1756                 {
1757                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1758                         if (!bc) {
1759                                 bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
1760                                 if (bc) { 
1761                                         int myprocid=bc->l3_id&0x0000ffff;
1762                                         hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
1763                                         cb_log(3,stack->port,"Reject dinfo: %x cause:%d\n",hh->dinfo,bc->cause);
1764                                         reject=1;               
1765                                 }
1766                         }
1767                 }
1768                 break;
1769                 
1770                 case CC_FACILITY|INDICATION:
1771                 {
1772                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1773                         if (!bc) {
1774                                 bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
1775                                 if (bc) { 
1776                                         int myprocid=bc->l3_id&0x0000ffff;
1777                                         hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
1778                                         cb_log(4,bc->port,"Repaired reject Bug, new dinfo: %x\n",hh->dinfo);
1779                                 }
1780                         }
1781                 }
1782                 break;
1783                 
1784                 case CC_RELEASE_COMPLETE|INDICATION:
1785                         break;
1786
1787                 case CC_SUSPEND|INDICATION:
1788                 {
1789                         msg_t *dmsg;
1790                         cb_log(4, stack->port, " --> Got Suspend, sending Reject for now\n");
1791                         dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST,MT_SUSPEND_REJECT, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1792                         stack->nst.manager_l3(&stack->nst, dmsg);
1793                         free_msg(msg);
1794                         return 0;
1795                 }
1796                 break;
1797                 case CC_RESUME|INDICATION:
1798                         break;
1799
1800                 case CC_RELEASE|CONFIRM:
1801                         break;
1802                         
1803                 case CC_RELEASE|INDICATION:
1804                         break;
1805
1806                 case CC_RELEASE_CR|INDICATION:
1807                 {
1808                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1809                         struct misdn_bchannel dummybc;
1810                         iframe_t frm; /* fake te frm to remove callref from global callreflist */
1811                         frm.dinfo = hh->dinfo;
1812
1813                         frm.addr=stack->upper_id | FLG_MSG_DOWN;
1814
1815                         frm.prim = CC_RELEASE_CR|INDICATION;
1816                         cb_log(4, stack->port, " --> Faking Realease_cr for %x\n",frm.addr);
1817                         /** removing procid **/
1818                         if (!bc) {
1819                                 cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x) on this port.\n", hh->dinfo);
1820                                 memset (&dummybc,0,sizeof(dummybc));
1821                                 dummybc.port=stack->port;
1822                                 dummybc.l3_id=hh->dinfo;
1823                                 bc=&dummybc; 
1824                         }
1825         
1826                         if (bc) {
1827                                 if ( (bc->l3_id & 0xff00) == 0xff00) {
1828                                         cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", bc->l3_id&0xff);
1829                                         stack->procids[bc->l3_id&0xff] = 0 ;
1830                                 }
1831                         }
1832                         else cb_log(-1, stack->port, "Couldnt find BC so I couldnt remove the Process!!!! this is a bad port.\n");
1833         
1834                         handle_cr(stack, &frm);
1835                         free_msg(msg);
1836                         return 0 ;
1837                 }
1838                 break;
1839       
1840                 case CC_NEW_CR|INDICATION:
1841                         /*  Got New CR for bchan, for now I handle this one in */
1842                         /*  connect_ack, Need to be changed */
1843                 {
1844                         struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1845                         int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE));
1846                         if (!bc) { cb_log(-1, stack->port, " --> In NEW_CR: didn't found bc ??\n"); return -1;};
1847                         if (((l3id&0xff00)!=0xff00) && ((bc->l3_id&0xff00)==0xff00)) {
1848                                 cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", 0xff&bc->l3_id);
1849                                 stack->procids[bc->l3_id&0xff] = 0 ;
1850                         }
1851                         cb_log(4, stack->port, "lib: Event_ind:CC_NEW_CR : very new L3ID  is %x\n",l3id );
1852         
1853                         bc->l3_id =l3id;
1854                         cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
1855         
1856                         free_msg(msg);
1857                         return 0;
1858                 }
1859       
1860                 case DL_ESTABLISH | INDICATION:
1861                 case DL_ESTABLISH | CONFIRM:
1862                 {
1863                         cb_log(4, stack->port, "%% GOT L2 Activate Info.\n");
1864                         stack->l2link = 1;
1865                         
1866                         free_msg(msg);
1867                         return 0;
1868                 }
1869                 break;
1870
1871                 case DL_RELEASE | INDICATION:
1872                 case DL_RELEASE | CONFIRM:
1873                 {
1874                         cb_log(4, stack->port, "%% GOT L2 DeActivate Info.\n");
1875                         stack->l2link = 0;
1876                         
1877                         free_msg(msg);
1878                         return 0;
1879                 }
1880                 break;
1881                 }
1882         }
1883         
1884         {
1885                 /*  Parse Events and fire_up to App. */
1886                 struct misdn_bchannel *bc;
1887                 struct misdn_bchannel dummybc;
1888                 
1889                 enum event_e event = isdn_msg_get_event(msgs_g, msg, 1);
1890     
1891                 bc=find_bc_by_l3id(stack, hh->dinfo);
1892     
1893                 if (!bc) {
1894       
1895                         cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x).\n", hh->dinfo);
1896                         memset (&dummybc,0,sizeof(dummybc));
1897                         dummybc.port=stack->port;
1898                         dummybc.l3_id=hh->dinfo;
1899                         bc=&dummybc; 
1900                 }
1901                 if (bc ) {
1902                         isdn_msg_parse_event(msgs_g,msg,bc, 1);
1903                         
1904                         if(!isdn_get_info(msgs_g,event,1)) {
1905                                 cb_log(4, stack->port, "Unknown Event Ind: prim %x dinfo %x\n",hh->prim, hh->dinfo);
1906                         } else {
1907                                 if (reject) {
1908                                         switch(bc->cause){
1909                                                 case 17:
1910                                                         cb_log(1, stack->port, "Siemens Busy reject..\n");
1911
1912                                                         break;
1913                                                 default:
1914                                                         return 0;
1915                                         }
1916                                 }
1917                                 cb_event(event, bc, glob_mgr->user_data);
1918                         }
1919       
1920                 } else {
1921                         cb_log(4, stack->port, "No BC found with l3id: prim %x dinfo %x\n",hh->prim, hh->dinfo);
1922                 }
1923
1924                 free_msg(msg);
1925         }
1926
1927
1928         return 0;
1929 }
1930
1931
1932 int handle_timers(msg_t* msg)
1933 {
1934         iframe_t *frm= (iframe_t*)msg->data;
1935         struct misdn_stack *stack; 
1936   
1937         /* Timer Stuff */
1938         switch (frm->prim) {
1939         case MGR_INITTIMER | CONFIRM:
1940         case MGR_ADDTIMER | CONFIRM:
1941         case MGR_DELTIMER | CONFIRM:
1942         case MGR_REMOVETIMER | CONFIRM:
1943                 free_msg(msg);
1944                 return(1);
1945         }
1946   
1947   
1948   
1949         if (frm->prim==(MGR_TIMER | INDICATION) ) {
1950                 for (stack = glob_mgr->stack_list;
1951                      stack;
1952                      stack = stack->next) {
1953                         itimer_t *it;
1954       
1955                         if (!stack->nt) continue;
1956       
1957                         it = stack->nst.tlist;
1958                         /* find timer */
1959                         for(it=stack->nst.tlist;
1960                             it;
1961                             it=it->next) {
1962                                 if (it->id == (int)frm->addr)
1963                                         break;
1964                         }
1965                         if (it) {
1966                                 int ret;
1967                                 ret = mISDN_write_frame(stack->midev, msg->data, frm->addr,
1968                                                         MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
1969                                 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
1970                                 ret = it->function(it->data);
1971                                 free_msg(msg);
1972                                 return 1;
1973                         }
1974                 }
1975     
1976                 cb_log(-1, 0, "Timer Msg without Timer ??\n");
1977                 free_msg(msg);
1978                 return 1;
1979         }
1980   
1981         return 0;
1982 }
1983
1984
1985
1986 void misdn_lib_tone_generator_start(struct misdn_bchannel *bc)
1987 {
1988         bc->generate_tone=1;
1989 }
1990
1991 void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
1992 {
1993         bc->generate_tone=0;
1994 }
1995
1996
1997 static int do_tone(struct misdn_bchannel *bc, int len)
1998 {
1999         bc->tone_cnt=len;
2000         
2001         if (bc->generate_tone) {
2002                 cb_event(EVENT_TONE_GENERATE, bc, glob_mgr->user_data);
2003                 
2004                 if ( !bc->nojitter ) {
2005                         misdn_tx_jitter(bc,len);
2006                 }
2007                 
2008                 return 1;
2009         }
2010         
2011         return 0;
2012 }
2013
2014
2015
2016 void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
2017 {
2018         char buf[4096 + mISDN_HEADER_LEN];
2019         char *data=&buf[mISDN_HEADER_LEN];
2020         iframe_t *txfrm= (iframe_t*)buf;
2021         int jlen, r;
2022         
2023         jlen=cb_jb_empty(bc,data,len);
2024         
2025         if (jlen) {
2026                 flip_buf_bits( data, jlen);
2027                 
2028                 if (jlen < len) {
2029                         cb_log(5,bc->port,"Jitterbuffer Underrun.\n");
2030                 }
2031                 
2032                 txfrm->prim = DL_DATA|REQUEST;
2033                 
2034                 txfrm->dinfo = 0;
2035                 
2036                 txfrm->addr = bc->addr|FLG_MSG_DOWN; /*  | IF_DOWN; */
2037                 
2038                 txfrm->len =jlen;
2039                 cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
2040                 
2041                 r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
2042         } else {
2043 #ifdef MISDN_GEN_SILENCE
2044                 int cnt=len/TONE_SILENCE_SIZE;
2045                 int rest=len%TONE_SILENCE_SIZE;
2046                 int i;
2047
2048                 for (i=0; i<cnt; i++) {
2049                         memcpy(data, tone_silence_flip, TONE_SILENCE_SIZE );
2050                         data +=TONE_SILENCE_SIZE;
2051                 }
2052
2053                 if (rest) {
2054                         memcpy(data, tone_silence_flip, rest);
2055                 }
2056
2057                 txfrm->prim = DL_DATA|REQUEST;
2058
2059                 txfrm->dinfo = 0;
2060
2061                 txfrm->addr = bc->addr|FLG_MSG_DOWN; /*  | IF_DOWN; */
2062
2063                 txfrm->len =len;
2064                 cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
2065
2066                 r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
2067 #endif
2068
2069         }
2070 }
2071
2072 int handle_bchan(msg_t *msg)
2073 {
2074         iframe_t *frm= (iframe_t*)msg->data;
2075         struct misdn_bchannel *bc;
2076
2077         bc=find_bc_by_addr(frm->addr);
2078         
2079         if (!bc) {
2080                 cb_log(0,0,"handle_bchan: BC not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo);
2081                 return 0 ;
2082         }
2083         
2084         struct misdn_stack *stack=get_stack_by_bc(bc);
2085         
2086         if (!stack) {
2087                 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);
2088                 return 0;
2089         }
2090         
2091         switch (frm->prim) {
2092
2093         case MGR_SETSTACK| CONFIRM:
2094                 cb_log(2, stack->port, "BCHAN: MGR_SETSTACK|CONFIRM \n");
2095                 break;
2096                 
2097         case MGR_SETSTACK| INDICATION:
2098                 cb_log(2, stack->port, "BCHAN: MGR_SETSTACK|IND \n");
2099                 
2100         AGAIN:
2101                 bc->addr = mISDN_get_layerid(stack->midev, bc->b_stid, bc->layer);
2102                 if (!bc->addr) {
2103
2104                         if (errno == EAGAIN) {
2105                                 usleep(1000);
2106                                 goto AGAIN;
2107                         }
2108                         
2109                         cb_log(0,stack->port,"$$$ Get Layer (%d) Id Error: %s\n",bc->layer,strerror(errno));
2110                         
2111                         /* we kill the channel later, when we received some
2112                            data. */
2113                         bc->addr= frm->addr;
2114                 } else if ( bc->addr < 0) {
2115                         cb_log(-1, stack->port,"$$$ bc->addr <0 Error:%s\n",strerror(errno));
2116                         bc->addr=0;
2117                 }
2118                 
2119                 cb_log(4, stack->port," --> Got Adr %x\n", bc->addr);
2120
2121                 free_msg(msg);
2122         
2123                 
2124                 switch(bc->bc_state) {
2125                 case BCHAN_SETUP:
2126                         bc_state_change(bc,BCHAN_SETUPED);
2127                         manager_bchannel_activate(bc);
2128                 break;
2129
2130                 case BCHAN_CLEAN_REQUEST:
2131                 default:
2132                         cb_log(-1, stack->port," --> STATE WASN'T SETUP (but %s) in SETSTACK|IND\n",bc_state2str(bc->bc_state));
2133                         clean_up_bc(bc);
2134                 }
2135                 return 1;
2136
2137         case MGR_DELLAYER| INDICATION:
2138                 cb_log(2, stack->port, "BCHAN: MGR_DELLAYER|IND\n");
2139                 break;
2140                 
2141         case MGR_DELLAYER| CONFIRM:
2142                 cb_log(2, stack->port, "BCHAN: MGR_DELLAYER|CNF \n");
2143                 
2144                 bc_state_change(bc,BCHAN_CLEANED);
2145                 
2146                 free_msg(msg);
2147                 return 1;
2148                 
2149         case PH_ACTIVATE | INDICATION:
2150         case DL_ESTABLISH | INDICATION:
2151                 cb_log(4, stack->port, "BCHAN: ACT Ind\n");
2152
2153                 bc_state_change(bc,BCHAN_ACTIVATED);
2154                 
2155                 free_msg(msg);
2156                 return 1;    
2157
2158         case PH_ACTIVATE | CONFIRM:
2159         case DL_ESTABLISH | CONFIRM:
2160                 
2161                 bc_state_change(bc,BCHAN_ACTIVATED);
2162                 
2163                 cb_log(4, stack->port, "BCHAN: bchan ACT Confirm\n");
2164                 free_msg(msg);
2165                 
2166                 return 1;    
2167                 
2168         case PH_DEACTIVATE | INDICATION:
2169         case DL_RELEASE | INDICATION:
2170                 cb_log (4, stack->port, "BCHAN: DeACT Ind\n");
2171                 
2172                 bc_state_change(bc,BCHAN_RELEASED);
2173                 free_msg(msg);
2174                 return 1;
2175     
2176         case PH_DEACTIVATE | CONFIRM:
2177         case DL_RELEASE | CONFIRM:
2178                 cb_log(4, stack->port, "BCHAN: DeACT Conf\n");
2179                 
2180                 bc_state_change(bc,BCHAN_RELEASED);
2181                 free_msg(msg);
2182                 return 1;
2183     
2184         case PH_CONTROL|INDICATION:
2185         {
2186                 unsigned int cont = *((unsigned int *)&frm->data.p);
2187                 
2188                 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);
2189
2190                 if ((cont&~DTMF_TONE_MASK) == DTMF_TONE_VAL) {
2191                         int dtmf = cont & DTMF_TONE_MASK;
2192                         cb_log(4, stack->port, " --> DTMF TONE: %c\n",dtmf);
2193                         bc->dtmf=dtmf;
2194                         cb_event(EVENT_DTMF_TONE, bc, glob_mgr->user_data);
2195         
2196                         free_msg(msg);
2197                         return 1;
2198                 }
2199                 if (cont == BF_REJECT) {
2200                         cb_log(4, stack->port, " --> BF REJECT\n");
2201                         free_msg(msg);
2202                         return 1;
2203                 }
2204                 if (cont == BF_ACCEPT) {
2205                         cb_log(4, stack->port, " --> BF ACCEPT\n");
2206                         free_msg(msg);
2207                         return 1;
2208                 }
2209         }
2210         break;
2211
2212         case PH_DATA|REQUEST:
2213         case DL_DATA|REQUEST:
2214                 cb_log(0, stack->port, "DL_DATA REQUEST \n");
2215                 do_tone(bc, 64);
2216                 
2217                 free_msg(msg);
2218                 return 1;
2219                 
2220         case PH_DATA|INDICATION:
2221         case DL_DATA|INDICATION:
2222         {
2223                 bc->bframe = (void*)&frm->data.i;
2224                 bc->bframe_len = frm->len;
2225
2226                 /** Anyway flip the bufbits **/
2227                 if ( misdn_cap_is_speech(bc->capability) ) 
2228                         flip_buf_bits(bc->bframe, bc->bframe_len);
2229         
2230
2231                 if (!bc->bframe_len) {
2232                         cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
2233                         free_msg(msg);
2234                         return 1;
2235                 }
2236
2237                 if ( (bc->addr&STACK_ID_MASK) != (frm->addr&STACK_ID_MASK) ) {
2238                         cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
2239                         free_msg(msg);
2240                         return 1;
2241                 }
2242                 
2243 #if MISDN_DEBUG
2244                 cb_log(-1, stack->port, "DL_DATA INDICATION Len %d\n", frm->len);
2245
2246 #endif
2247                 
2248                 if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) {
2249                         int t;
2250
2251 #ifdef MISDN_B_DEBUG
2252                         cb_log(0,bc->port,"do_tone START\n");
2253 #endif
2254                         t=do_tone(bc,frm->len);
2255
2256 #ifdef MISDN_B_DEBUG
2257                         cb_log(0,bc->port,"do_tone STOP (%d)\n",t);
2258 #endif
2259                         if (  !t ) {
2260                                 
2261                                 if ( misdn_cap_is_speech(bc->capability)) {
2262                                         if ( !bc->nojitter ) {
2263 #ifdef MISDN_B_DEBUG
2264                                                 cb_log(0,bc->port,"tx_jitter START\n");
2265 #endif
2266                                                 misdn_tx_jitter(bc,frm->len);
2267 #ifdef MISDN_B_DEBUG
2268                                                 cb_log(0,bc->port,"tx_jitter STOP\n");
2269 #endif
2270                                         }
2271                                 }
2272
2273 #ifdef MISDN_B_DEBUG    
2274                                 cb_log(0,bc->port,"EVENT_B_DATA START\n");
2275 #endif
2276                                 
2277                                 int i=cb_event( EVENT_BCHAN_DATA, bc, glob_mgr->user_data);
2278 #ifdef MISDN_B_DEBUG    
2279                                 cb_log(0,bc->port,"EVENT_B_DATA STOP\n");
2280 #endif
2281                                 
2282                                 if (i<0) {
2283                                         cb_log(10,stack->port,"cb_event returned <0\n");
2284                                         /*clean_up_bc(bc);*/
2285                                 }
2286                         }
2287                 }
2288                 free_msg(msg);
2289                 return 1;
2290         }
2291
2292
2293         case PH_CONTROL | CONFIRM:
2294                 cb_log(2, stack->port, "PH_CONTROL|CNF bc->addr:%x\n", frm->addr);
2295                 free_msg(msg);
2296                 return 1;
2297
2298         case PH_DATA | CONFIRM:
2299         case DL_DATA|CONFIRM:
2300 #if MISDN_DEBUG
2301
2302                 cb_log(-1, stack->port, "Data confirmed\n");
2303
2304 #endif
2305                 free_msg(msg);
2306                 
2307                 return 1;
2308         case DL_DATA|RESPONSE:
2309 #if MISDN_DEBUG
2310                 cb_log(-1, stack->port, "Data response\n");
2311
2312 #endif
2313                 break;
2314         }
2315   
2316         return 0;
2317 }
2318
2319
2320
2321 int handle_frm_nt(msg_t *msg)
2322 {
2323         iframe_t *frm= (iframe_t*)msg->data;
2324         struct misdn_stack *stack;
2325         int err=0;
2326
2327         stack=find_stack_by_addr( frm->addr );
2328
2329         
2330   
2331         if (!stack || !stack->nt) {
2332                 return 0;
2333         }
2334
2335         
2336         if ((err=stack->nst.l1_l2(&stack->nst,msg))) {
2337     
2338                 if (nt_err_cnt > 0 ) {
2339                         if (nt_err_cnt < 100) {
2340                                 nt_err_cnt++; 
2341                                 cb_log(-1, stack->port, "NT Stack sends us error: %d \n", err);
2342                         } else if (nt_err_cnt < 105){
2343                                 cb_log(-1, stack->port, "NT Stack sends us error: %d over 100 times, so I'll stop this message\n", err);
2344                                 nt_err_cnt = - 1; 
2345                         }
2346                 }
2347                 free_msg(msg);
2348                 return 1;
2349                 
2350         }
2351         
2352         return 1;
2353 }
2354
2355
2356 int handle_frm(msg_t *msg)
2357 {
2358         iframe_t *frm = (iframe_t*) msg->data;
2359         
2360         struct misdn_stack *stack=find_stack_by_addr(frm->addr);
2361
2362         
2363         cb_log(4,stack?stack->port:0,"handle_frm: frm->addr:%x frm->prim:%x\n",frm->addr,frm->prim);
2364         
2365   
2366         if (!stack || stack->nt) {
2367                 return 0;
2368         }
2369
2370         {
2371                 struct misdn_bchannel *bc;
2372                 int ret=handle_cr(stack, frm);
2373
2374                 if (ret<0) {
2375                         cb_log(3,stack?stack->port:0,"handle_frm: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr);
2376                 }
2377
2378                 if(ret) {
2379                         free_msg(msg);
2380                         return 1;
2381                 }
2382     
2383                 bc=find_bc_by_l3id(stack, frm->dinfo);
2384     
2385                 if (bc ) {
2386                         enum event_e event = isdn_msg_get_event(msgs_g, msg, 0);
2387                         enum event_response_e response=RESPONSE_OK;
2388       
2389                         isdn_msg_parse_event(msgs_g,msg,bc, 0);
2390                         
2391                         /** Preprocess some Events **/
2392                         handle_event(bc, event, frm);
2393                         /*  shoot up event to App: */
2394                         cb_log(5, stack->port, "lib Got Prim: Addr %x prim %x dinfo %x\n",frm->addr, frm->prim, frm->dinfo);
2395       
2396                         if(!isdn_get_info(msgs_g,event,0)) 
2397                                 cb_log(-1, stack->port, "Unknown Event Ind: Addr:%x prim %x dinfo %x\n",frm->addr, frm->prim, frm->dinfo);
2398                         else 
2399                                 response=cb_event(event, bc, glob_mgr->user_data);
2400 #if 1
2401                         if (event == EVENT_SETUP) {
2402                                 switch (response) {
2403                                 case RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE:
2404
2405                                         cb_log(-1, stack->port, "TOTALY IGNORING SETUP \n");                                    
2406                                         
2407                                         break;
2408                                 case RESPONSE_IGNORE_SETUP:
2409                                         /* I think we should send CC_RELEASE_CR, but am not sure*/
2410
2411                                         bc->out_cause=16;
2412                                         misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
2413                                         empty_chan_in_stack(stack, bc->channel);
2414                                         empty_bc(bc);
2415                                         bc_state_change(bc,BCHAN_CLEANED);
2416
2417                                         cb_log(-1, stack->port, "GOT IGNORE SETUP\n");
2418
2419                                         
2420                                         break;
2421                                 case RESPONSE_OK:
2422                                         cb_log(4, stack->port, "GOT SETUP OK\n");
2423
2424                                         
2425                                         break;
2426                                 default:
2427                                         break;
2428                                 }
2429                         }
2430
2431                         cb_log(5, stack->port, "Freeing Msg on prim:%x \n",frm->prim);
2432
2433                         
2434                         free_msg(msg);
2435                         return 1;
2436 #endif
2437       
2438                 } else {
2439                         cb_log(-1, stack->port, "NO BC FOR STACK\n");           
2440                 }
2441         }
2442
2443         cb_log(4, stack->port, "TE_FRM_HANDLER: Returning 0 on prim:%x \n",frm->prim);
2444         return 0;
2445 }
2446
2447
2448 int handle_l1(msg_t *msg)
2449 {
2450         iframe_t *frm = (iframe_t*) msg->data;
2451         struct misdn_stack *stack = find_stack_by_addr(frm->addr);
2452         int i ;
2453         
2454         if (!stack) return 0 ;
2455   
2456         switch (frm->prim) {
2457         case PH_ACTIVATE | CONFIRM:
2458         case PH_ACTIVATE | INDICATION:
2459                 cb_log (1, stack->port, "L1: PH L1Link Up!\n");
2460                 stack->l1link=1;
2461                 
2462                 if (stack->nt) {
2463                         
2464                         if (stack->nst.l1_l2(&stack->nst, msg))
2465                                 free_msg(msg);
2466                 } else {
2467                         free_msg(msg);
2468                 }
2469                 
2470                 for (i=0;i<stack->b_num; i++) {
2471                         if (stack->bc[i].evq != EVENT_NOTHING) {
2472                                 cb_log(4, stack->port, "Fireing Queued Event %s because L1 got up\n", isdn_get_info(msgs_g, stack->bc[i].evq, 0));
2473                                 misdn_lib_send_event(&stack->bc[i],stack->bc[i].evq);
2474                                 stack->bc[i].evq=EVENT_NOTHING;
2475                         }
2476                         
2477                 }
2478                 return 1;
2479
2480         case PH_ACTIVATE | REQUEST:
2481                 free_msg(msg);
2482                 cb_log(1,stack->port,"L1: PH_ACTIVATE|REQUEST \n");
2483                 return 1;
2484                 
2485         case PH_DEACTIVATE | REQUEST:
2486                 free_msg(msg);
2487                 cb_log(1,stack->port,"L1: PH_DEACTIVATE|REQUEST \n");
2488                 return 1;
2489                 
2490         case PH_DEACTIVATE | CONFIRM:
2491         case PH_DEACTIVATE | INDICATION:
2492                 cb_log (1, stack->port, "L1: PH L1Link Down! \n");
2493                 
2494                 for (i=0; i<stack->b_num; i++) {
2495                         if (global_state == MISDN_INITIALIZED)  {
2496                                 cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data);
2497                         }
2498                 }
2499                 
2500                 if (stack->nt) {
2501                         if (stack->nst.l1_l2(&stack->nst, msg))
2502                                 free_msg(msg);
2503                 } else {
2504                         free_msg(msg);
2505                 }
2506                 
2507                 stack->l1link=0;
2508                 stack->l2link=0;
2509                 
2510                 return 1;
2511         }
2512   
2513         return 0;
2514 }
2515
2516 int handle_l2(msg_t *msg)
2517 {
2518         iframe_t *frm = (iframe_t*) msg->data;
2519
2520         struct misdn_stack *stack = find_stack_by_addr(frm->addr);
2521         
2522         if (!stack) {
2523                 return 0 ;
2524         }
2525         
2526         switch(frm->prim) {
2527
2528         case DL_ESTABLISH | REQUEST:
2529                 cb_log(1,stack->port,"DL_ESTABLISH|REQUEST \n");
2530                 return 1;
2531         case DL_RELEASE | REQUEST:
2532                 cb_log(1,stack->port,"DL_RELEASE|REQUEST \n");
2533                 return 1;
2534                 
2535         case DL_ESTABLISH | INDICATION:
2536         case DL_ESTABLISH | CONFIRM:
2537         {
2538                 cb_log (3, stack->port, "L2: L2Link Up! \n");
2539                 stack->l2link=1;
2540                 free_msg(msg);
2541                 return 1;
2542         }
2543         break;
2544     
2545         case DL_RELEASE | INDICATION:
2546         case DL_RELEASE | CONFIRM:
2547         {
2548                 cb_log (3, stack->port, "L2: L2Link Down! \n");
2549                 stack->l2link=0;
2550                 
2551                 free_msg(msg);
2552                 return 1;
2553         }
2554         break;
2555         }
2556         return 0;
2557 }
2558
2559 int handle_mgmt(msg_t *msg)
2560 {
2561         iframe_t *frm = (iframe_t*) msg->data;
2562
2563         if ( (frm->addr == 0) && (frm->prim == (MGR_DELLAYER|CONFIRM)) ) {
2564                 cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: 0 !\n") ;
2565                 free_msg(msg);
2566                 return 1;
2567         }
2568         
2569         struct misdn_stack * stack=find_stack_by_addr(frm->addr);
2570         
2571         if (!stack) {
2572                 if (frm->prim == (MGR_DELLAYER|CONFIRM)) {
2573                         cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: %x !\n",
2574                                         frm->addr) ;
2575                         free_msg(msg);
2576                         return 1;
2577                 }
2578                 
2579                 return 0;
2580         }
2581         
2582         switch(frm->prim) {
2583         case MGR_SHORTSTATUS | INDICATION:
2584         case MGR_SHORTSTATUS | CONFIRM:
2585                 cb_log(2, 0, "MGMT: Short status dinfo %x\n",frm->dinfo);
2586                 
2587                 switch (frm->dinfo) {
2588                 case SSTATUS_L1_ACTIVATED:
2589                         cb_log(1, 0, "MGMT: SSTATUS: L1_ACTIVATED \n");
2590                         stack->l1link=1;
2591                 
2592                         break;
2593                 case SSTATUS_L1_DEACTIVATED:
2594                         cb_log(1, 0, "MGMT: SSTATUS: L1_DEACTIVATED \n");
2595                         stack->l1link=0;
2596
2597                         clear_l3(stack);
2598                         break;
2599
2600                 case SSTATUS_L2_ESTABLISHED:
2601                         cb_log(1, stack->port, "MGMT: SSTATUS: L2_ESTABLISH \n");
2602                         stack->l2link=1;
2603                         break;
2604                         
2605                 case SSTATUS_L2_RELEASED:
2606                         cb_log(1, stack->port, "MGMT: SSTATUS: L2_RELEASED \n");
2607                         stack->l2link=0;
2608                         break;
2609                 }
2610                 
2611                 free_msg(msg);
2612                 return 1;
2613                 
2614         case MGR_SETSTACK | INDICATION:
2615                 cb_log(2, stack->port, "MGMT: SETSTACK|IND dinfo %x\n",frm->dinfo);
2616                 free_msg(msg);
2617                 return 1;
2618         case MGR_DELLAYER | CONFIRM:
2619                 cb_log(2, stack->port, "MGMT: DELLAYER|CNF dinfo %x\n",frm->dinfo) ;
2620                 free_msg(msg);
2621                 return 1;
2622                 
2623         }
2624         
2625         /*
2626         if ( (frm->prim & 0x0f0000) ==  0x0f0000) {
2627         cb_log(5, 0, "$$$ MGMT FRAME: prim %x addr %x dinfo %x\n",frm->prim, frm->addr, frm->dinfo) ;
2628         free_msg(msg);
2629         return 1;
2630         } */
2631     
2632         return 0;
2633 }
2634
2635
2636 msg_t *fetch_msg(int midev) 
2637 {
2638         msg_t *msg=alloc_msg(MAX_MSG_SIZE);
2639         int r;
2640         fd_set rdfs;
2641
2642         if (!msg) {
2643                 cb_log(-1, 0, "fetch_msg: alloc msg failed !!");
2644                 return NULL;
2645         }
2646         
2647         FD_ZERO(&rdfs);
2648         FD_SET(midev,&rdfs);
2649   
2650         mISDN_select(FD_SETSIZE, &rdfs, NULL, NULL, NULL);
2651         //select(FD_SETSIZE, &rdfs, NULL, NULL, NULL);
2652   
2653         if (FD_ISSET(midev, &rdfs)) {
2654
2655         AGAIN:
2656                 r=mISDN_read(midev,msg->data,MAX_MSG_SIZE, 5000);
2657                 msg->len=r;
2658     
2659                 if (r==0) {
2660                         free_msg(msg); /* danger, cauz usualy freeing in main_loop */
2661                         printf ("Got empty Msg?\n");
2662                         return NULL;
2663                 }
2664
2665                 if (r<0) {
2666                         if (errno == EAGAIN) {
2667                                 /*we wait for mISDN here*/
2668                                 cb_log(4,0,"mISDN_read wants us to wait\n");
2669                                 usleep(5000);
2670                                 goto AGAIN;
2671                         }
2672                         
2673                         cb_log(-1,0,"mISDN_read returned :%d error:%s (%d)\n",r,strerror(errno),errno); 
2674                 }
2675
2676                 return msg;
2677         } else {
2678                 printf ("Select timeout\n");
2679         }
2680   
2681         return NULL;
2682 }
2683
2684 static void misdn_lib_isdn_l1watcher(void *arg)
2685 {
2686         struct misdn_lib *mgr = arg;
2687         struct misdn_stack *stack;
2688
2689         while (1) {
2690                 sleep(mgr->l1watcher_timeout);
2691                 
2692                 /* look out for l1 which are down
2693                    and try to pull the up.
2694
2695                    We might even try to pull the l2 up in the
2696                    ptp case.
2697                 */
2698                 for (stack = mgr->stack_list;
2699                      stack;
2700                      stack = stack->next) {
2701                         cb_log(4,stack->port,"Checking L1 State\n");    
2702                         if (!stack->l1link) {
2703                                 cb_log(4,stack->port,"L1 State Down, trying to get it up again\n");     
2704                                 misdn_lib_get_short_status(stack);
2705                                 misdn_lib_get_l1_up(stack); 
2706                                 misdn_lib_get_l2_up(stack); 
2707                         }
2708                 }
2709         }
2710 }
2711
2712 static void misdn_lib_isdn_event_catcher(void *arg)
2713 {
2714         struct misdn_lib *mgr = arg;
2715         int zero_frm=0 , fff_frm=0 ;
2716         int midev= mgr->midev;
2717         int port=0;
2718         
2719         while (1) {
2720                 msg_t *msg = fetch_msg(midev); 
2721                 iframe_t *frm;
2722                 
2723                 
2724                 if (!msg) continue;
2725                 
2726                 frm = (iframe_t*) msg->data;
2727                 
2728                 /** When we make a call from NT2Ast we get this frames **/
2729                 if (frm->len == 0 && frm->addr == 0 && frm->dinfo == 0 && frm->prim == 0 ) {
2730                         zero_frm++; 
2731                         free_msg(msg);
2732                         continue;
2733                 } else {
2734                         if (zero_frm) {
2735                                 cb_log(-1, port, "*** Alert: %d zero_frms caught\n", zero_frm);
2736                                 zero_frm = 0 ;
2737                         }
2738                 }
2739                 
2740                 /** I get this sometimes after setup_bc **/
2741                 if (frm->len == 0 &&  frm->dinfo == 0 && frm->prim == 0xffffffff ) {
2742                         fff_frm++; 
2743                         free_msg(msg);
2744                         continue;
2745                 } else {
2746                         if (fff_frm) {
2747                                 cb_log(-1, port, "*** Alert: %d fff_frms caught\n", fff_frm);
2748                                 fff_frm = 0 ;
2749                         }
2750                 }
2751                 
2752                 manager_isdn_handler(frm, msg);
2753         }
2754
2755 }
2756
2757
2758 /** App Interface **/
2759
2760 int te_lib_init() {
2761         char buff[1025];
2762         iframe_t *frm=(iframe_t*)buff;
2763         int midev=mISDN_open();
2764         int ret;
2765
2766         memset(buff,0,1025);
2767   
2768         if  (midev<=0) return midev;
2769   
2770 /* create entity for layer 3 TE-mode */
2771         mISDN_write_frame(midev, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2772         ret = mISDN_read_frame(midev, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
2773   
2774         if (ret < mISDN_HEADER_LEN) {
2775         noentity:
2776                 fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN: %s\n",strerror(errno));
2777                 exit(-1);
2778         }
2779   
2780         entity = frm->dinfo & 0xffff ;
2781   
2782         if (!entity)
2783                 goto noentity;
2784
2785         return midev;
2786   
2787 }
2788
2789 void te_lib_destroy(int midev)
2790 {
2791         char buf[1024];
2792         mISDN_write_frame(midev, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
2793
2794         cb_log(4, 0, "Entetity deleted\n");
2795         mISDN_close(midev);
2796         cb_log(4, 0, "midev closed\n");
2797 }
2798
2799
2800
2801 void misdn_lib_transfer(struct misdn_bchannel* holded_bc)
2802 {
2803         holded_bc->holded=0;
2804 }
2805
2806 struct misdn_bchannel *manager_find_bc_by_pid(int pid)
2807 {
2808         struct misdn_stack *stack;
2809         int i;
2810   
2811         for (stack=glob_mgr->stack_list;
2812              stack;
2813              stack=stack->next) {
2814                 for (i=0; i<stack->b_num; i++)
2815                         if (stack->bc[i].pid == pid) return &stack->bc[i];
2816         }
2817   
2818         return NULL;
2819 }
2820
2821 struct misdn_bchannel *manager_find_bc_holded(struct misdn_bchannel* bc)
2822 {
2823         struct misdn_stack *stack=get_stack_by_bc(bc);
2824         return find_bc_holded(stack);
2825 }
2826
2827
2828
2829 struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel)
2830 {
2831         struct misdn_stack *stack;
2832         int i;
2833         
2834         if (channel < 0 || channel > MAX_BCHANS)
2835                 return NULL;
2836
2837         for (stack=glob_mgr->stack_list; stack; stack=stack->next) {
2838     
2839                 if (stack->port == port) {
2840                         if (channel > 0) {
2841                                 if (channel <= stack->b_num) {
2842                                         for (i = 0; i < stack->b_num; i++) {
2843                                                 if (stack->bc[i].in_use && stack->bc[i].channel == channel) {
2844                                                         return NULL;
2845                                                 }
2846                                         }
2847                                 } else
2848                                         return NULL;
2849                         }
2850                         for (i = 0; i < stack->b_num; i++) {
2851                                 if (!stack->bc[i].in_use) {
2852                                         stack->bc[i].channel = channel;
2853                                         stack->bc[i].channel_preselected = channel?1:0;
2854                                         stack->bc[i].in_use = 1;
2855                                         return &stack->bc[i];
2856                                 }
2857                         }
2858                         return NULL;
2859                 }
2860         }
2861         return NULL;
2862 }
2863
2864
2865 char *fac2str (enum facility_type type) {
2866         struct arr_el { 
2867                 enum facility_type p; 
2868                 char *s ; 
2869         } arr[] = {
2870                 { FACILITY_NONE, "FAC_NONE" },
2871                 { FACILITY_CALLDEFLECT, "FAC_CALLDEFLECT"},
2872                 { FACILITY_CENTREX, "FAC_CENTREX"}
2873         };
2874         
2875         int i;
2876         
2877         for (i=0; i < sizeof(arr)/sizeof( struct arr_el) ; i ++)
2878                 if ( arr[i].p==type) return arr[i].s;
2879         
2880         return "FAC_UNKNOWN";
2881 }
2882
2883 void misdn_lib_log_ies(struct misdn_bchannel *bc)
2884 {
2885         if (!bc) return;
2886
2887         struct misdn_stack *stack=get_stack_by_bc(bc);
2888
2889         if (!stack) return;
2890
2891         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);
2892         
2893         cb_log(3, stack->port, " --> facility:%s out_facility:%s\n",fac2str(bc->fac_type),fac2str(bc->out_fac_type));
2894         
2895         cb_log(2, stack->port,
2896                " --> info_dad:%s onumplan:%c dnumplan:%c rnumplan:%c cpnnumplan:%c\n",
2897                bc->info_dad,
2898                bc->onumplan>=0?'0'+bc->onumplan:' ',
2899                bc->dnumplan>=0?'0'+bc->dnumplan:' ',
2900                bc->rnumplan>=0?'0'+bc->rnumplan:' ',
2901                bc->cpnnumplan>=0?'0'+bc->cpnnumplan:' '
2902                 );
2903         cb_log(3, stack->port, " --> screen:%d --> pres:%d\n",
2904                         bc->screen, bc->pres);
2905         
2906         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);
2907
2908         cb_log(3, stack->port, " --> urate:%d rate:%d mode:%d user1:%d\n", bc->urate, bc->rate, bc->mode,bc->user1);
2909         
2910         cb_log(3, stack->port, " --> pid:%d addr:%x l3id:%x\n", bc->pid, bc->addr, bc->l3_id);
2911         cb_log(3, stack->port, " --> b_stid:%x layer_id:%x\n", bc->b_stid, bc->layer_id);
2912         
2913         cb_log(4, stack->port, " --> bc:%x h:%d sh:%d\n", bc, bc->holded, bc->stack_holder);
2914 }
2915
2916 int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
2917 {
2918         msg_t *msg; 
2919         int err = -1 ;
2920   
2921         if (!bc) goto ERR; 
2922         
2923         struct misdn_stack *stack=get_stack_by_bc(bc);
2924         
2925         if (!stack) {
2926                 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);
2927                 return -1;
2928         }
2929         
2930         cb_log(6,stack->port,"SENDEVENT: stack->nt:%d stack->uperid:%x\n",stack->nt, stack->upper_id);
2931
2932         if ( stack->nt && !stack->l1link) {
2933                 /** Queue Event **/
2934                 bc->evq=event;
2935                 cb_log(1, stack->port, "Queueing Event %s because L1 is down (btw. Activating L1)\n", isdn_get_info(msgs_g, event, 0));
2936                 misdn_lib_get_l1_up(stack);
2937                 return 0;
2938         }
2939         
2940         cb_log(1, stack->port, "I SEND:%s oad:%s dad:%s \n", isdn_get_info(msgs_g, event, 0), bc->oad, bc->dad);
2941         cb_log(1, stack->port, " --> bc_state:%s\n",bc_state2str(bc->bc_state));
2942         misdn_lib_log_ies(bc);
2943         
2944         switch (event) {
2945         case EVENT_SETUP:
2946                 if (create_process(glob_mgr->midev, bc)<0) {
2947                         cb_log(-1,  stack->port, " No free channel at the moment @ send_event\n");
2948
2949                         err=-ENOCHAN;
2950                         goto ERR;
2951                 }
2952                 break;
2953
2954         case EVENT_PROGRESS:
2955         case EVENT_ALERTING:
2956         case EVENT_PROCEEDING:
2957         case EVENT_SETUP_ACKNOWLEDGE:
2958                 if (!bc->nt && !stack->ptp) break;
2959
2960         case EVENT_CONNECT:
2961         case EVENT_RETRIEVE_ACKNOWLEDGE:
2962                 if (stack->nt) {
2963                         if (bc->channel <=0 ) { /*  else we have the channel already */
2964                                 bc->channel = find_free_chan_in_stack(stack, bc, 0);
2965                                 if (!bc->channel) {
2966                                         cb_log(-1, stack->port, " No free channel at the moment\n");
2967                                         
2968                                         err=-ENOCHAN;
2969                                         goto ERR;
2970                                 }
2971                         }
2972                         /* Its that i generate channels */
2973                 }
2974                 
2975                 if ( bc->nt || misdn_cap_is_speech(bc->capability)) {
2976                         int ret=setup_bc(bc);
2977                         if (ret == -EINVAL){
2978                                 cb_log(-1,bc->port,"send_event: setup_bc failed\n");
2979                                 
2980                         }
2981                 } 
2982                 
2983                 if ( (event == EVENT_CONNECT ) && misdn_cap_is_speech(bc->capability) ) {
2984                         if ( *bc->crypt_key ) {
2985                                 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);
2986                                 
2987                                 manager_ph_control_block(bc,  BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
2988                         }
2989                         
2990                         if (!bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
2991                         
2992                         if (bc->ec_enable) manager_ec_enable(bc);
2993                         
2994                         if (bc->txgain != 0) {
2995                                 cb_log(4, stack->port,  "--> Changing txgain to %d\n", bc->txgain);
2996                                 manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
2997                         }
2998                         
2999                         if ( bc->rxgain != 0 ) {
3000                                 cb_log(4, stack->port,  "--> Changing rxgain to %d\n", bc->rxgain);
3001                                 manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
3002                         }
3003                         
3004                 }
3005                 
3006                 if (event == EVENT_RETRIEVE_ACKNOWLEDGE) {
3007                         manager_bchannel_activate(bc);
3008                 }
3009                 break;
3010
3011         case EVENT_HOLD_ACKNOWLEDGE:
3012         {
3013                 struct misdn_bchannel *holded_bc=malloc(sizeof(struct misdn_bchannel));
3014                 memcpy(holded_bc,bc,sizeof(struct misdn_bchannel));
3015                 holded_bc->holded=1;
3016                 stack_holder_add(stack,holded_bc);
3017                 
3018                 if (stack->nt) {
3019                         if (bc->bc_state == BCHAN_BRIDGED) {
3020                                 misdn_split_conf(bc,bc->conf_id);
3021                                 misdn_split_conf(bc->holded_bc,bc->holded_bc->conf_id);
3022                                 /*bc_state_change(bc,BCHAN_SETUPED);
3023                                 manager_bchannel_activate(bc);*/
3024                         }
3025
3026                         empty_chan_in_stack(stack,bc->channel);
3027                         empty_bc(bc);
3028                         clean_up_bc(bc);
3029                 }
3030                 
3031                 /** we set it up later at RETRIEVE_ACK again.**/
3032                 /*holded_bc->upset=0;
3033                   holded_bc->active=0;*/
3034                 bc_state_change(holded_bc,BCHAN_CLEANED);
3035                 
3036                 cb_event( EVENT_NEW_BC, holded_bc, glob_mgr->user_data);
3037         }
3038         break;
3039         
3040         case EVENT_RELEASE:
3041                 break;
3042                 
3043         case EVENT_RELEASE_COMPLETE:
3044                 /*we do the cleanup in EVENT_CLEANUP*/
3045                 break;
3046     
3047         case EVENT_CONNECT_ACKNOWLEDGE:
3048                 
3049                 if (misdn_cap_is_speech(bc->capability)) {
3050                         if (  !bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
3051                         if (bc->ec_enable) manager_ec_enable(bc);
3052                         if ( bc->txgain != 0 ) {
3053                                 cb_log(4, stack->port, "--> Changing txgain to %d\n", bc->txgain);
3054                                 manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
3055                         }
3056                         if ( bc->rxgain != 0 ) {
3057                                 cb_log(4, stack->port, "--> Changing rxgain to %d\n", bc->rxgain);
3058                                 manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
3059                         }
3060                 }
3061                 break;
3062     
3063         default:
3064                 break;
3065         }
3066   
3067         /* Later we should think about sending bchannel data directly to misdn. */
3068         msg = isdn_msg_build_event(msgs_g, bc, event, stack->nt);
3069         msg_queue_tail(&stack->downqueue, msg);
3070         sem_post(&glob_mgr->new_msg);
3071   
3072         return 0;
3073   
3074  ERR:
3075         return -1; 
3076 }
3077
3078
3079 int handle_err(msg_t *msg)
3080 {
3081         iframe_t *frm = (iframe_t*) msg->data;
3082
3083
3084         if (!frm->addr) {
3085                 static int cnt=0;
3086                 if (!cnt)
3087                         cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x\n",frm->prim,frm->dinfo);
3088                 cnt++;
3089                 if (cnt>100) {
3090                         cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x (already more than 100 of them)\n",frm->prim,frm->dinfo);
3091                         cnt=0;
3092                 }
3093                 
3094                 free_msg(msg);
3095                 return 1;
3096                 
3097         }
3098         
3099         switch (frm->prim) {
3100                 case MGR_SETSTACK|INDICATION:
3101                         return handle_bchan(msg);
3102                 break;
3103
3104                 case MGR_SETSTACK|CONFIRM:
3105                 case MGR_CLEARSTACK|CONFIRM:
3106                         free_msg(msg) ; 
3107                         return 1;
3108                 break;
3109
3110                 case DL_DATA|INDICATION:
3111                 {
3112                         int port=(frm->addr&MASTER_ID_MASK) >> 8;
3113                         int channel=(frm->addr&CHILD_ID_MASK) >> 16;
3114
3115                         /*we flush the read buffer here*/
3116                         
3117                         cb_log(9,0,"BCHAN DATA without BC: addr:%x port:%d channel:%d\n",frm->addr, port,channel);
3118                         
3119                         free_msg(msg) ; 
3120                         return 1;
3121                         
3122                         
3123                         struct misdn_bchannel *bc=find_bc_by_channel( port , channel);
3124
3125                         if (!bc) {
3126                                 struct misdn_stack *stack=find_stack_by_port( port );
3127
3128                                 if (!stack) {
3129                                         cb_log(-1,0," --> stack not found\n");