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