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