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