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