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