when we don't want the call we need to release_complete it.. ignoring it breaks the...
[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
2393                                         bc->out_cause=16;
2394                                         misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
2395                                         empty_chan_in_stack(stack, bc->channel);
2396                                         empty_bc(bc);
2397                                         bc_state_change(bc,BCHAN_CLEANED);
2398
2399                                         cb_log(-1, stack->port, "GOT IGNORE SETUP\n");
2400
2401                                         
2402                                         break;
2403                                 case RESPONSE_OK:
2404                                         cb_log(4, stack->port, "GOT SETUP OK\n");
2405
2406                                         
2407                                         break;
2408                                 default:
2409                                         break;
2410                                 }
2411                         }
2412
2413                         cb_log(5, stack->port, "Freeing Msg on prim:%x \n",frm->prim);
2414
2415                         
2416                         free_msg(msg);
2417                         return 1;
2418 #endif
2419       
2420                 } else {
2421                         cb_log(-1, stack->port, "NO BC FOR STACK\n");           
2422                 }
2423         }
2424
2425         cb_log(4, stack->port, "TE_FRM_HANDLER: Returning 0 on prim:%x \n",frm->prim);
2426         return 0;
2427 }
2428
2429
2430 int handle_l1(msg_t *msg)
2431 {
2432         iframe_t *frm = (iframe_t*) msg->data;
2433         struct misdn_stack *stack = find_stack_by_addr(frm->addr);
2434         int i ;
2435         
2436         if (!stack) return 0 ;
2437   
2438         switch (frm->prim) {
2439         case PH_ACTIVATE | CONFIRM:
2440         case PH_ACTIVATE | INDICATION:
2441                 cb_log (1, stack->port, "L1: PH L1Link Up!\n");
2442                 stack->l1link=1;
2443                 
2444                 if (stack->nt) {
2445                         
2446                         if (stack->nst.l1_l2(&stack->nst, msg))
2447                                 free_msg(msg);
2448                 } else {
2449                         free_msg(msg);
2450                 }
2451                 
2452                 for (i=0;i<stack->b_num; i++) {
2453                         if (stack->bc[i].evq != EVENT_NOTHING) {
2454                                 cb_log(4, stack->port, "Fireing Queued Event %s because L1 got up\n", isdn_get_info(msgs_g, stack->bc[i].evq, 0));
2455                                 misdn_lib_send_event(&stack->bc[i],stack->bc[i].evq);
2456                                 stack->bc[i].evq=EVENT_NOTHING;
2457                         }
2458                         
2459                 }
2460                 return 1;
2461
2462         case PH_ACTIVATE | REQUEST:
2463                 free_msg(msg);
2464                 cb_log(1,stack->port,"L1: PH_ACTIVATE|REQUEST \n");
2465                 return 1;
2466                 
2467         case PH_DEACTIVATE | REQUEST:
2468                 free_msg(msg);
2469                 cb_log(1,stack->port,"L1: PH_DEACTIVATE|REQUEST \n");
2470                 return 1;
2471                 
2472         case PH_DEACTIVATE | CONFIRM:
2473         case PH_DEACTIVATE | INDICATION:
2474                 cb_log (1, stack->port, "L1: PH L1Link Down! \n");
2475                 
2476                 for (i=0; i<stack->b_num; i++) {
2477                         if (global_state == MISDN_INITIALIZED)  {
2478                                 cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data);
2479                         }
2480                 }
2481                 
2482                 if (stack->nt) {
2483                         if (stack->nst.l1_l2(&stack->nst, msg))
2484                                 free_msg(msg);
2485                 } else {
2486                         free_msg(msg);
2487                 }
2488                 
2489                 stack->l1link=0;
2490                 stack->l2link=0;
2491                 
2492                 return 1;
2493         }
2494   
2495         return 0;
2496 }
2497
2498 int handle_l2(msg_t *msg)
2499 {
2500         iframe_t *frm = (iframe_t*) msg->data;
2501
2502         struct misdn_stack *stack = find_stack_by_addr(frm->addr);
2503         
2504         if (!stack) {
2505                 return 0 ;
2506         }
2507         
2508         switch(frm->prim) {
2509
2510         case DL_ESTABLISH | REQUEST:
2511                 cb_log(1,stack->port,"DL_ESTABLISH|REQUEST \n");
2512                 return 1;
2513         case DL_RELEASE | REQUEST:
2514                 cb_log(1,stack->port,"DL_RELEASE|REQUEST \n");
2515                 return 1;
2516                 
2517         case DL_ESTABLISH | INDICATION:
2518         case DL_ESTABLISH | CONFIRM:
2519         {
2520                 cb_log (3, stack->port, "L2: L2Link Up! \n");
2521                 stack->l2link=1;
2522                 free_msg(msg);
2523                 return 1;
2524         }
2525         break;
2526     
2527         case DL_RELEASE | INDICATION:
2528         case DL_RELEASE | CONFIRM:
2529         {
2530                 cb_log (3, stack->port, "L2: L2Link Down! \n");
2531                 stack->l2link=0;
2532                 
2533                 free_msg(msg);
2534                 return 1;
2535         }
2536         break;
2537         }
2538         return 0;
2539 }
2540
2541 int handle_mgmt(msg_t *msg)
2542 {
2543         iframe_t *frm = (iframe_t*) msg->data;
2544
2545         if ( (frm->addr == 0) && (frm->prim == (MGR_DELLAYER|CONFIRM)) ) {
2546                 cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: 0 !\n") ;
2547                 free_msg(msg);
2548                 return 1;
2549         }
2550         
2551         struct misdn_stack * stack=find_stack_by_addr(frm->addr);
2552         
2553         if (!stack) {
2554                 if (frm->prim == (MGR_DELLAYER|CONFIRM)) {
2555                         cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: %x !\n",
2556                                         frm->addr) ;
2557                         free_msg(msg);
2558                         return 1;
2559                 }
2560                 
2561                 return 0;
2562         }
2563         
2564         switch(frm->prim) {
2565         case MGR_SHORTSTATUS | INDICATION:
2566         case MGR_SHORTSTATUS | CONFIRM:
2567                 cb_log(2, 0, "MGMT: Short status dinfo %x\n",frm->dinfo);
2568                 
2569                 switch (frm->dinfo) {
2570                 case SSTATUS_L1_ACTIVATED:
2571                         cb_log(1, 0, "MGMT: SSTATUS: L1_ACTIVATED \n");
2572                         stack->l1link=1;
2573                 
2574                         break;
2575                 case SSTATUS_L1_DEACTIVATED:
2576                         cb_log(1, 0, "MGMT: SSTATUS: L1_DEACTIVATED \n");
2577                         stack->l1link=0;
2578
2579                         clear_l3(stack);
2580                         break;
2581
2582                 case SSTATUS_L2_ESTABLISHED:
2583                         cb_log(1, stack->port, "MGMT: SSTATUS: L2_ESTABLISH \n");
2584                         stack->l2link=1;
2585                         break;
2586                         
2587                 case SSTATUS_L2_RELEASED:
2588                         cb_log(1, stack->port, "MGMT: SSTATUS: L2_RELEASED \n");
2589                         stack->l2link=0;
2590                         break;
2591                 }
2592                 
2593                 free_msg(msg);
2594                 return 1;
2595                 
2596         case MGR_SETSTACK | INDICATION:
2597                 cb_log(2, stack->port, "MGMT: SETSTACK|IND dinfo %x\n",frm->dinfo);
2598                 free_msg(msg);
2599                 return 1;
2600         case MGR_DELLAYER | CONFIRM:
2601                 cb_log(2, stack->port, "MGMT: DELLAYER|CNF dinfo %x\n",frm->dinfo) ;
2602                 free_msg(msg);
2603                 return 1;
2604                 
2605         }
2606         
2607         /*
2608         if ( (frm->prim & 0x0f0000) ==  0x0f0000) {
2609         cb_log(5, 0, "$$$ MGMT FRAME: prim %x addr %x dinfo %x\n",frm->prim, frm->addr, frm->dinfo) ;
2610         free_msg(msg);
2611         return 1;
2612         } */
2613     
2614         return 0;
2615 }
2616
2617
2618 msg_t *fetch_msg(int midev) 
2619 {
2620         msg_t *msg=alloc_msg(MAX_MSG_SIZE);
2621         int r;
2622         fd_set rdfs;
2623
2624         if (!msg) {
2625                 cb_log(-1, 0, "fetch_msg: alloc msg failed !!");
2626                 return NULL;
2627         }
2628         
2629         FD_ZERO(&rdfs);
2630         FD_SET(midev,&rdfs);
2631   
2632         mISDN_select(FD_SETSIZE, &rdfs, NULL, NULL, NULL);
2633         //select(FD_SETSIZE, &rdfs, NULL, NULL, NULL);
2634   
2635         if (FD_ISSET(midev, &rdfs)) {
2636
2637         AGAIN:
2638                 r=mISDN_read(midev,msg->data,MAX_MSG_SIZE, 5000);
2639                 msg->len=r;
2640     
2641                 if (r==0) {
2642                         free_msg(msg); /* danger, cauz usualy freeing in main_loop */
2643                         printf ("Got empty Msg?\n");
2644                         return NULL;
2645                 }
2646
2647                 if (r<0) {
2648                         if (errno == EAGAIN) {
2649                                 /*we wait for mISDN here*/
2650                                 cb_log(4,0,"mISDN_read wants us to wait\n");
2651                                 usleep(5000);
2652                                 goto AGAIN;
2653                         }
2654                         
2655                         cb_log(-1,0,"mISDN_read returned :%d error:%s (%d)\n",r,strerror(errno),errno); 
2656                 }
2657
2658                 return msg;
2659         } else {
2660                 printf ("Select timeout\n");
2661         }
2662   
2663         return NULL;
2664 }
2665
2666 static void misdn_lib_isdn_l1watcher(void *arg)
2667 {
2668         struct misdn_lib *mgr = arg;
2669         struct misdn_stack *stack;
2670
2671         while (1) {
2672                 sleep(mgr->l1watcher_timeout);
2673                 
2674                 /* look out for l1 which are down
2675                    and try to pull the up.
2676
2677                    We might even try to pull the l2 up in the
2678                    ptp case.
2679                 */
2680                 for (stack = mgr->stack_list;
2681                      stack;
2682                      stack = stack->next) {
2683                         cb_log(4,stack->port,"Checking L1 State\n");    
2684                         if (!stack->l1link) {
2685                                 cb_log(4,stack->port,"L1 State Down, trying to get it up again\n");     
2686                                 misdn_lib_get_short_status(stack);
2687                                 misdn_lib_get_l1_up(stack); 
2688                                 misdn_lib_get_l2_up(stack); 
2689                         }
2690                 }
2691         }
2692 }
2693
2694 static void misdn_lib_isdn_event_catcher(void *arg)
2695 {
2696         struct misdn_lib *mgr = arg;
2697         int zero_frm=0 , fff_frm=0 ;
2698         int midev= mgr->midev;
2699         int port=0;
2700         
2701         while (1) {
2702                 msg_t *msg = fetch_msg(midev); 
2703                 iframe_t *frm;
2704                 
2705                 
2706                 if (!msg) continue;
2707                 
2708                 frm = (iframe_t*) msg->data;
2709                 
2710                 /** When we make a call from NT2Ast we get this frames **/
2711                 if (frm->len == 0 && frm->addr == 0 && frm->dinfo == 0 && frm->prim == 0 ) {
2712                         zero_frm++; 
2713                         free_msg(msg);
2714                         continue;
2715                 } else {
2716                         if (zero_frm) {
2717                                 cb_log(-1, port, "*** Alert: %d zero_frms caught\n", zero_frm);
2718                                 zero_frm = 0 ;
2719                         }
2720                 }
2721                 
2722                 /** I get this sometimes after setup_bc **/
2723                 if (frm->len == 0 &&  frm->dinfo == 0 && frm->prim == 0xffffffff ) {
2724                         fff_frm++; 
2725                         free_msg(msg);
2726                         continue;
2727                 } else {
2728                         if (fff_frm) {
2729                                 cb_log(-1, port, "*** Alert: %d fff_frms caught\n", fff_frm);
2730                                 fff_frm = 0 ;
2731                         }
2732                 }
2733                 
2734                 manager_isdn_handler(frm, msg);
2735         }
2736
2737 }
2738
2739
2740 /** App Interface **/
2741
2742 int te_lib_init() {
2743         char buff[1025];
2744         iframe_t *frm=(iframe_t*)buff;
2745         int midev=mISDN_open();
2746         int ret;
2747
2748         memset(buff,0,1025);
2749   
2750         if  (midev<=0) return midev;
2751   
2752 /* create entity for layer 3 TE-mode */
2753         mISDN_write_frame(midev, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2754         ret = mISDN_read_frame(midev, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
2755   
2756         if (ret < mISDN_HEADER_LEN) {
2757         noentity:
2758                 fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN: %s\n",strerror(errno));
2759                 exit(-1);
2760         }
2761   
2762         entity = frm->dinfo & 0xffff ;
2763   
2764         if (!entity)
2765                 goto noentity;
2766
2767         return midev;
2768   
2769 }
2770
2771 void te_lib_destroy(int midev)
2772 {
2773         char buf[1024];
2774         mISDN_write_frame(midev, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
2775
2776         cb_log(4, 0, "Entetity deleted\n");
2777         mISDN_close(midev);
2778         cb_log(4, 0, "midev closed\n");
2779 }
2780
2781
2782
2783 void misdn_lib_transfer(struct misdn_bchannel* holded_bc)
2784 {
2785         holded_bc->holded=0;
2786 }
2787
2788 struct misdn_bchannel *manager_find_bc_by_pid(int pid)
2789 {
2790         struct misdn_stack *stack;
2791         int i;
2792   
2793         for (stack=glob_mgr->stack_list;
2794              stack;
2795              stack=stack->next) {
2796                 for (i=0; i<stack->b_num; i++)
2797                         if (stack->bc[i].pid == pid) return &stack->bc[i];
2798         }
2799   
2800         return NULL;
2801 }
2802
2803 struct misdn_bchannel *manager_find_bc_holded(struct misdn_bchannel* bc)
2804 {
2805         struct misdn_stack *stack=get_stack_by_bc(bc);
2806         return find_bc_holded(stack);
2807 }
2808
2809
2810
2811 struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel)
2812 {
2813         struct misdn_stack *stack;
2814         int i;
2815         
2816         if (channel < 0 || channel > MAX_BCHANS)
2817                 return NULL;
2818
2819         for (stack=glob_mgr->stack_list; stack; stack=stack->next) {
2820     
2821                 if (stack->port == port) {
2822                         if (channel > 0) {
2823                                 if (channel <= stack->b_num) {
2824                                         for (i = 0; i < stack->b_num; i++) {
2825                                                 if (stack->bc[i].in_use && stack->bc[i].channel == channel) {
2826                                                         return NULL;
2827                                                 }
2828                                         }
2829                                 } else
2830                                         return NULL;
2831                         }
2832                         for (i = 0; i < stack->b_num; i++) {
2833                                 if (!stack->bc[i].in_use) {
2834                                         stack->bc[i].channel = channel;
2835                                         stack->bc[i].channel_preselected = channel?1:0;
2836                                         stack->bc[i].in_use = 1;
2837                                         return &stack->bc[i];
2838                                 }
2839                         }
2840                         return NULL;
2841                 }
2842         }
2843         return NULL;
2844 }
2845
2846
2847 char *fac2str (enum facility_type type) {
2848         struct arr_el { 
2849                 enum facility_type p; 
2850                 char *s ; 
2851         } arr[] = {
2852                 { FACILITY_NONE, "FAC_NONE" },
2853                 { FACILITY_CALLDEFLECT, "FAC_CALLDEFLECT"},
2854                 { FACILITY_CENTREX, "FAC_CENTREX"}
2855         };
2856         
2857         int i;
2858         
2859         for (i=0; i < sizeof(arr)/sizeof( struct arr_el) ; i ++)
2860                 if ( arr[i].p==type) return arr[i].s;
2861         
2862         return "FAC_UNKNOWN";
2863 }
2864
2865 void misdn_lib_log_ies(struct misdn_bchannel *bc)
2866 {
2867         if (!bc) return;
2868
2869         struct misdn_stack *stack=get_stack_by_bc(bc);
2870
2871         if (!stack) return;
2872
2873         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);
2874         
2875         cb_log(3, stack->port, " --> facility:%s out_facility:%s\n",fac2str(bc->fac_type),fac2str(bc->out_fac_type));
2876         
2877         cb_log(2, stack->port,
2878                " --> info_dad:%s onumplan:%c dnumplan:%c rnumplan:%c cpnnumplan:%c\n",
2879                bc->info_dad,
2880                bc->onumplan>=0?'0'+bc->onumplan:' ',
2881                bc->dnumplan>=0?'0'+bc->dnumplan:' ',
2882                bc->rnumplan>=0?'0'+bc->rnumplan:' ',
2883                bc->cpnnumplan>=0?'0'+bc->cpnnumplan:' '
2884                 );
2885         cb_log(3, stack->port, " --> screen:%d --> pres:%d\n",
2886                         bc->screen, bc->pres);
2887         
2888         cb_log(2, stack->port, " --> channel:%d caps:%s pi:%x keypad:%s\n", bc->channel, bearer2str(bc->capability),bc->progress_indicator, bc->keypad);
2889
2890         cb_log(3, stack->port, " --> urate:%d rate:%d mode:%d user1:%d\n", bc->urate, bc->rate, bc->mode,bc->user1);
2891         
2892         cb_log(3, stack->port, " --> pid:%d addr:%x l3id:%x\n", bc->pid, bc->addr, bc->l3_id);
2893         cb_log(3, stack->port, " --> b_stid:%x layer_id:%x\n", bc->b_stid, bc->layer_id);
2894         
2895         cb_log(4, stack->port, " --> bc:%x h:%d sh:%d\n", bc, bc->holded, bc->stack_holder);
2896 }
2897
2898 int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event )
2899 {
2900         msg_t *msg; 
2901         int err = -1 ;
2902   
2903         if (!bc) goto ERR; 
2904         
2905         struct misdn_stack *stack=get_stack_by_bc(bc);
2906         
2907         if (!stack) {
2908                 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);
2909                 return -1;
2910         }
2911         
2912         cb_log(6,stack->port,"SENDEVENT: stack->nt:%d stack->uperid:%x\n",stack->nt, stack->upper_id);
2913
2914         if ( stack->nt && !stack->l1link) {
2915                 /** Queue Event **/
2916                 bc->evq=event;
2917                 cb_log(1, stack->port, "Queueing Event %s because L1 is down (btw. Activating L1)\n", isdn_get_info(msgs_g, event, 0));
2918                 misdn_lib_get_l1_up(stack);
2919                 return 0;
2920         }
2921         
2922         cb_log(1, stack->port, "I SEND:%s oad:%s dad:%s \n", isdn_get_info(msgs_g, event, 0), bc->oad, bc->dad);
2923         cb_log(1, stack->port, " --> bc_state:%s\n",bc_state2str(bc->bc_state));
2924         misdn_lib_log_ies(bc);
2925         
2926         switch (event) {
2927         case EVENT_SETUP:
2928                 if (create_process(glob_mgr->midev, bc)<0) {
2929                         cb_log(-1,  stack->port, " No free channel at the moment @ send_event\n");
2930
2931                         err=-ENOCHAN;
2932                         goto ERR;
2933                 }
2934                 break;
2935
2936         case EVENT_CONNECT:
2937         case EVENT_PROGRESS:
2938         case EVENT_ALERTING:
2939         case EVENT_PROCEEDING:
2940         case EVENT_SETUP_ACKNOWLEDGE:
2941         case EVENT_RETRIEVE_ACKNOWLEDGE:
2942                 if (stack->nt) {
2943                         if (bc->channel <=0 ) { /*  else we have the channel already */
2944                                 bc->channel = find_free_chan_in_stack(stack, bc, 0);
2945                                 if (!bc->channel) {
2946                                         cb_log(-1, stack->port, " No free channel at the moment\n");
2947                                         
2948                                         err=-ENOCHAN;
2949                                         goto ERR;
2950                                 }
2951                         }
2952                         /* Its that i generate channels */
2953                 }
2954                 
2955                 if ( bc->nt || misdn_cap_is_speech(bc->capability)) {
2956                         int ret=setup_bc(bc);
2957                         if (ret == -EINVAL){
2958                                 cb_log(-1,bc->port,"send_event: setup_bc failed\n");
2959                                 
2960                         }
2961                 } 
2962                 
2963                 if ( (event == EVENT_CONNECT ) && misdn_cap_is_speech(bc->capability) ) {
2964                         if ( *bc->crypt_key ) {
2965                                 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);
2966                                 
2967                                 manager_ph_control_block(bc,  BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
2968                         }
2969                         
2970                         if (!bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
2971                         
2972                         if (bc->ec_enable) manager_ec_enable(bc);
2973                         
2974                         if (bc->txgain != 0) {
2975                                 cb_log(4, stack->port,  "--> Changing txgain to %d\n", bc->txgain);
2976                                 manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
2977                         }
2978                         
2979                         if ( bc->rxgain != 0 ) {
2980                                 cb_log(4, stack->port,  "--> Changing rxgain to %d\n", bc->rxgain);
2981                                 manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
2982                         }
2983                         
2984                 }
2985                 
2986                 if (event == EVENT_RETRIEVE_ACKNOWLEDGE) {
2987                         manager_bchannel_activate(bc);
2988                 }
2989                 break;
2990
2991         case EVENT_HOLD_ACKNOWLEDGE:
2992         {
2993                 struct misdn_bchannel *holded_bc=malloc(sizeof(struct misdn_bchannel));
2994                 memcpy(holded_bc,bc,sizeof(struct misdn_bchannel));
2995                 holded_bc->holded=1;
2996                 stack_holder_add(stack,holded_bc);
2997                 
2998                 if (stack->nt) {
2999                         if (bc->bc_state == BCHAN_BRIDGED) {
3000                                 misdn_split_conf(bc,bc->conf_id);
3001                                 misdn_split_conf(bc->holded_bc,bc->holded_bc->conf_id);
3002                                 /*bc_state_change(bc,BCHAN_SETUPED);
3003                                 manager_bchannel_activate(bc);*/
3004                         }
3005
3006                         empty_chan_in_stack(stack,bc->channel);
3007                         empty_bc(bc);
3008                         clean_up_bc(bc);
3009                 }
3010                 
3011                 /** we set it up later at RETRIEVE_ACK again.**/
3012                 /*holded_bc->upset=0;
3013                   holded_bc->active=0;*/
3014                 bc_state_change(holded_bc,BCHAN_CLEANED);
3015                 
3016                 cb_event( EVENT_NEW_BC, holded_bc, glob_mgr->user_data);
3017         }
3018         break;
3019         
3020         case EVENT_RELEASE:
3021                 break;
3022                 
3023         case EVENT_RELEASE_COMPLETE:
3024                 /*we do the cleanup in EVENT_CLEANUP*/
3025                 break;
3026     
3027         case EVENT_CONNECT_ACKNOWLEDGE:
3028                 
3029                 if (misdn_cap_is_speech(bc->capability)) {
3030                         if (  !bc->nodsp) manager_ph_control(bc,  DTMF_TONE_START, 0);
3031                         if (bc->ec_enable) manager_ec_enable(bc);
3032                         if ( bc->txgain != 0 ) {
3033                                 cb_log(4, stack->port, "--> Changing txgain to %d\n", bc->txgain);
3034                                 manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
3035                         }
3036                         if ( bc->rxgain != 0 ) {
3037                                 cb_log(4, stack->port, "--> Changing rxgain to %d\n", bc->rxgain);
3038                                 manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
3039                         }
3040                 }
3041                 break;
3042     
3043         default:
3044                 break;
3045         }
3046   
3047         /* Later we should think about sending bchannel data directly to misdn. */
3048         msg = isdn_msg_build_event(msgs_g, bc, event, stack->nt);
3049         msg_queue_tail(&stack->downqueue, msg);
3050         sem_post(&glob_mgr->new_msg);
3051   
3052         return 0;
3053   
3054  ERR:
3055         return -1; 
3056 }
3057
3058
3059 int handle_err(msg_t *msg)
3060 {
3061         iframe_t *frm = (iframe_t*) msg->data;
3062
3063
3064         if (!frm->addr) {
3065                 static int cnt=0;
3066                 if (!cnt)
3067                         cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x\n",frm->prim,frm->dinfo);
3068                 cnt++;
3069                 if (cnt>100) {
3070                         cb_log(0,0,"mISDN Msg without Address pr:%x dinfo:%x (already more than 100 of them)\n",frm->prim,frm->dinfo);
3071                         cnt=0;
3072                 }
3073                 
3074                 free_msg(msg);
3075                 return 1;
3076                 
3077         }
3078         
3079         switch (frm->prim) {
3080                 case MGR_SETSTACK|INDICATION:
3081                         return handle_bchan(msg);
3082                 break;
3083
3084                 case MGR_SETSTACK|CONFIRM:
3085                 case MGR_CLEARSTACK|CONFIRM:
3086                         free_msg(msg) ; 
3087                         return 1;
3088                 break;
3089
3090                 case DL_DATA|INDICATION:
3091                 {
3092                         int port=(frm->addr&MASTER_ID_MASK) >> 8;
3093                         int channel=(frm->addr&CHILD_ID_MASK) >> 16;
3094
3095                         /*we flush the read buffer here*/
3096                         
3097                         cb_log(9,0,"BCHAN DATA without BC: addr:%x port:%d channel:%d\n",frm->addr, port,channel);
3098                         
3099                         free_msg(msg) ; 
3100                         return 1;
3101                         
3102                         
3103                         struct misdn_bchannel *bc=find_bc_by_channel( port , channel);
3104
3105                         if (!bc) {
3106                                 struct misdn_stack *stack=find_stack_by_port( port );
3107
3108                                 if (!stack) {
3109                                         cb_log(-1,0," --> stack not found\n");
3110                                         free_msg(msg);
3111                                         return 1;
3112                                 }
3113                                 
3114                                 cb_log(-1,0," --> bc not found by channel\n");
3115                                 if (stack->l2link)
3116                                         misdn_lib_get_l2_down(stack);
3117
3118                                 if (stack->l1link)
3119                                         misdn_lib_get_l1_down(stack);
3120
3121                                 free_msg(msg);
3122                                 return 1;
3123                         }
3124                         
3125                         cb_log(3,port," --> BC in state:%s\n", bc_state2str(bc->bc_state));