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