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