2 * Chan_Misdn -- Channel Driver for Asterisk
6 * Copyright (C) 2004, Christian Richter
8 * Christian Richter <crich@beronet.com>
10 * This program is free software, distributed under the terms of
11 * the GNU General Public License
14 #include "isdn_lib_intern.h"
15 #include <mISDNuser/isdn_debug.h>
17 void misdn_join_conf(struct misdn_bchannel *bc, int conf_id);
18 void misdn_split_conf(struct misdn_bchannel *bc, int conf_id);
20 int queue_cleanup_bc(struct misdn_bchannel *bc) ;
22 int misdn_lib_get_l2_up(struct misdn_stack *stack);
24 struct misdn_stack* get_misdn_stack( void );
27 static int bec_initialized=0;
30 int misdn_lib_port_is_pri(int port)
32 struct misdn_stack *stack=get_misdn_stack();
33 for ( ; stack; stack=stack->next) {
34 if (stack->port == port) {
43 int misdn_lib_port_block(int port)
45 struct misdn_stack *stack=get_misdn_stack();
46 for ( ; stack; stack=stack->next) {
47 if (stack->port == port) {
56 int misdn_lib_port_unblock(int port)
58 struct misdn_stack *stack=get_misdn_stack();
59 for ( ; stack; stack=stack->next) {
60 if (stack->port == port) {
69 int misdn_lib_is_ptp(int port)
71 struct misdn_stack *stack=get_misdn_stack();
72 for ( ; stack; stack=stack->next) {
73 if (stack->port == port) return stack->ptp;
78 int misdn_lib_get_maxchans(int port)
80 struct misdn_stack *stack=get_misdn_stack();
81 for ( ; stack; stack=stack->next) {
82 if (stack->port == port) {
93 struct misdn_stack* get_stack_by_bc(struct misdn_bchannel *bc)
95 struct misdn_stack *stack=get_misdn_stack();
99 for ( ; stack; stack=stack->next) {
101 for (i=0; i <stack->b_num; i++) {
102 if ( bc->port == stack->port) return stack;
110 void get_show_stack_details(int port, char *buf)
112 struct misdn_stack *stack=get_misdn_stack();
114 for ( ; stack; stack=stack->next) {
115 if (stack->port == port) break;
119 sprintf(buf, "* Port %d Type %s Prot. %s L2Link %s L1Link:%s Blocked:%d", stack->port, stack->nt?"NT":"TE", stack->ptp?"PTP":"PMP", stack->l2link?"UP":"DOWN", stack->l1link?"UP":"DOWN",stack->blocked);
128 static int nt_err_cnt =0 ;
135 static enum global_states global_state=MISDN_INITIALIZING;
138 #include <mISDNuser/net_l2.h>
139 #include <mISDNuser/tone.h>
141 #include <semaphore.h>
145 #include "isdn_lib.h"
152 pthread_t event_thread;
153 pthread_t event_handler_thread;
158 msg_queue_t activatequeue;
162 struct misdn_stack *stack_list;
166 #define ECHOCAN_ON 123
167 #define ECHOCAN_OFF 124
170 #define MISDN_DEBUG 0
172 void misdn_tx_jitter(struct misdn_bchannel *bc, int len);
174 struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id);
176 int setup_bc(struct misdn_bchannel *bc);
178 int manager_isdn_handler(iframe_t *frm ,msg_t *msg);
180 int misdn_lib_port_restart(int port);
182 extern struct isdn_msg msgs_g[];
184 #define ISDN_PID_L3_B_USER 0x430000ff
185 #define ISDN_PID_L4_B_USER 0x440000ff
187 /* #define MISDN_IBUF_SIZE 1024 */
188 #define MISDN_IBUF_SIZE 512
190 /* Fine Tuning of Inband Signalling time */
191 #define TONE_ALERT_CNT 41 /* 1 Sec */
192 #define TONE_ALERT_SILENCE_CNT 200 /* 4 Sec */
194 #define TONE_BUSY_CNT 20 /* ? */
195 #define TONE_BUSY_SILENCE_CNT 48 /* ? */
199 static struct misdn_lib *glob_mgr;
201 unsigned char tone_425_flip[TONE_425_SIZE];
202 unsigned char tone_silence_flip[TONE_SILENCE_SIZE];
204 static void misdn_lib_isdn_event_catcher(void *arg);
205 static int handle_event_nt(void *dat, void *arg);
208 void stack_holder_add(struct misdn_stack *stack, struct misdn_bchannel *holder);
209 void stack_holder_remove(struct misdn_stack *stack, struct misdn_bchannel *holder);
210 struct misdn_bchannel *stack_holder_find(struct misdn_stack *stack, unsigned long l3id);
212 /* from isdn_lib.h */
213 int init_bc(struct misdn_stack * stack, struct misdn_bchannel *bc, int midev, int port, int bidx, char *msn, int firsttime);
214 struct misdn_stack* stack_init(int midev, int port, int ptp);
215 void stack_destroy(struct misdn_stack* stack);
217 int te_lib_init( void ) ; /* returns midev */
218 void te_lib_destroy(int midev) ;
219 struct misdn_bchannel *manager_find_bc_by_pid(int pid);
220 struct misdn_bchannel *manager_find_bc_holded(struct misdn_bchannel* bc);
221 void manager_ph_control_block(struct misdn_bchannel *bc, int c1, void *c2, int c2_len);
222 void manager_clean_bc(struct misdn_bchannel *bc );
223 void manager_bchannel_setup (struct misdn_bchannel *bc);
224 void manager_bchannel_cleanup (struct misdn_bchannel *bc);
226 int isdn_msg_get_index(struct isdn_msg msgs[], msg_t *frm, int nt);
227 enum event_e isdn_msg_get_event(struct isdn_msg msgs[], msg_t *frm, int nt);
228 int isdn_msg_parse_event(struct isdn_msg msgs[], msg_t *frm, struct misdn_bchannel *bc, int nt);
229 char * isdn_get_info(struct isdn_msg msgs[], enum event_e event, int nt);
230 msg_t * isdn_msg_build_event(struct isdn_msg msgs[], struct misdn_bchannel *bc, enum event_e event, int nt);
231 void ec_chunk( struct misdn_bchannel *bc, unsigned char *rxchunk, unsigned char *txchunk, int chunk_size);
233 int bchdev_echocancel_activate(struct misdn_bchannel* dev);
234 void bchdev_echocancel_deactivate(struct misdn_bchannel* dev);
238 static char *bearer2str(int cap) {
239 static char *bearers[]={
248 case INFO_CAPABILITY_SPEECH:
251 case INFO_CAPABILITY_AUDIO_3_1K:
254 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
257 case INFO_CAPABILITY_DIGITAL_RESTRICTED:
267 static char flip_table[256];
269 void init_flip_bits(void)
273 for (i = 0 ; i < 256 ; i++) {
274 unsigned char sample = 0 ;
275 for (k = 0; k<8; k++) {
276 if ( i & 1 << k ) sample |= 0x80 >> k;
278 flip_table[i] = sample;
282 unsigned char * flip_buf_bits ( unsigned char * buf , int len)
287 for (i = 0 ; i < len; i++) {
288 buf[i] = flip_table[buf[i]];
297 msg_t *create_l2msg(int prim, int dinfo, int size) /* NT only */
304 dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
309 printf("cannot allocate memory, trying again...\n");
313 printf("cannot allocate memory, system overloaded.\n");
319 msg_t *create_l3msg(int prim, int mt, int dinfo, int size, int ntmode)
327 size = sizeof(Q931_info_t)+2;
331 dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
336 dmsg = alloc_msg(size+256+mISDN_HEADER_LEN+DEFAULT_HEADROOM);
339 memset(msg_put(dmsg,size+mISDN_HEADER_LEN), 0, size+mISDN_HEADER_LEN);
340 frm = (iframe_t *)dmsg->data;
343 qi = (Q931_info_t *)(dmsg->data + mISDN_HEADER_LEN);
349 if (!i) printf("cannot allocate memory, trying again...\n");
353 printf("cannot allocate memory, system overloaded.\n");
358 int send_msg (int midev, struct misdn_bchannel *bc, msg_t *dmsg)
361 frm = (iframe_t *)dmsg->data;
362 struct misdn_stack *stack=get_stack_by_bc(bc);
365 cb_log(0,bc->port,"send_msg: IEK!! no stack\n ");
369 frm->addr = (stack->upper_id | FLG_MSG_DOWN);
372 frm->dinfo = bc->l3_id;
374 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
376 mISDN_write(midev, dmsg->data, dmsg->len, TIMEOUT_1SEC);
387 int misdn_cap_is_speech(int cap)
388 /** Poor mans version **/
390 if ( (cap != INFO_CAPABILITY_DIGITAL_UNRESTRICTED) &&
391 (cap != INFO_CAPABILITY_DIGITAL_RESTRICTED) ) return 1;
395 int misdn_inband_avail(struct misdn_bchannel *bc)
398 /*if ! early_bconnect we have never inband available*/
399 if ( ! bc->early_bconnect ) return 0;
401 switch (bc->progress_indicator) {
402 case INFO_PI_INBAND_AVAILABLE:
403 case INFO_PI_CALL_NOT_E2E_ISDN:
404 case INFO_PI_CALLED_NOT_ISDN:
413 void dump_chan_list(struct misdn_stack *stack)
417 for (i=0; i <stack->b_num; i++) {
418 cb_log(6, stack->port, "Idx:%d stack->cchan:%d Chan:%d\n",i,stack->channels[i], i+1);
425 static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchannel *bc, int channel)
429 cb_log(1,stack->port,"find_free_chan: req_chan:%d\n",channel);
431 if (channel < 0 || channel > MAX_BCHANS) {
432 cb_log(4, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
438 for (i = 0; i < stack->b_num; i++) {
439 if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 Dchannel ;) and work with chan preselection */
440 if (!stack->channels[i]) {
441 cb_log (1, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
442 stack->channels[i] = 1;
444 cb_event(EVENT_NEW_CHANNEL, bc, NULL);
450 cb_log (4, stack->port, " !! NO FREE CHAN IN STACK\n");
451 dump_chan_list(stack);
456 int empty_chan_in_stack(struct misdn_stack *stack, int channel)
459 cb_log(0,stack?stack->port:0, "empty_chan_inst_stack: cannot empty channel %d\n",channel);
463 cb_log (4, stack?stack->port:0, "empty_chan_in_stack: %d\n",channel);
464 stack->channels[channel-1] = 0;
465 dump_chan_list(stack);
469 char *bc_state2str(enum bchannel_state state) {
472 struct bchan_state_s {
474 enum bchannel_state s;
476 {"BCHAN_CLEANED", BCHAN_CLEANED },
477 {"BCHAN_EMPTY", BCHAN_EMPTY},
478 {"BCHAN_SETUP", BCHAN_SETUP},
479 {"BCHAN_SETUPED", BCHAN_SETUPED},
480 {"BCHAN_ACTIVE", BCHAN_ACTIVE},
481 {"BCHAN_ACTIVATED", BCHAN_ACTIVATED},
482 {"BCHAN_BRIDGE", BCHAN_BRIDGE},
483 {"BCHAN_BRIDGED", BCHAN_BRIDGED},
484 {"BCHAN_RELEASE", BCHAN_RELEASE},
485 {"BCHAN_RELEASED", BCHAN_RELEASED},
486 {"BCHAN_CLEAN", BCHAN_CLEAN},
487 {"BCHAN_CLEAN_REQUEST", BCHAN_CLEAN_REQUEST},
488 {"BCHAN_ERROR", BCHAN_ERROR}
491 for (i=0; i< sizeof(states)/sizeof(struct bchan_state_s); i++)
492 if ( states[i].s == state)
498 void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
500 cb_log(5,bc->port,"BC_STATE_CHANGE: from:%s to:%s\n",
501 bc_state2str(bc->bc_state),
502 bc_state2str(state) );
505 case BCHAN_ACTIVATED:
506 if (bc->next_bc_state == BCHAN_BRIDGED) {
507 misdn_join_conf(bc, bc->conf_id);
508 bc->next_bc_state = BCHAN_EMPTY;
517 void bc_next_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
519 cb_log(5,bc->port,"BC_NEXT_STATE_CHANGE: from:%s to:%s\n",
520 bc_state2str(bc->next_bc_state),
521 bc_state2str(state) );
523 bc->next_bc_state=state;
527 void empty_bc(struct misdn_bchannel *bc)
534 bc->sending_complete = 0;
536 bc->restart_channel=0;
540 bc->need_more_infos = 0;
552 bc->curptx=0; bc->curprx=0;
554 bc->crypt_key[0] = 0;
559 bc->dnumplan=NUMPLAN_UNKNOWN;
560 bc->onumplan=NUMPLAN_UNKNOWN;
561 bc->rnumplan=NUMPLAN_UNKNOWN;
562 bc->cpnnumplan=NUMPLAN_UNKNOWN;
567 bc->early_bconnect = 1;
570 bc->ec_deftaps = 128;
571 bc->ec_whenbridged = 0;
579 bc->pres=0 ; /* screened */
581 bc->evq=EVENT_NOTHING;
583 bc->progress_coding=0;
584 bc->progress_location=0;
585 bc->progress_indicator=0;
587 /** Set Default Bearer Caps **/
588 bc->capability=INFO_CAPABILITY_SPEECH;
589 bc->law=INFO_CODEC_ALAW;
600 bc->infos_pending[0] = 0;
607 bc->fac_type=FACILITY_NONE;
609 bc->te_choose_channel = 0;
615 int clean_up_bc(struct misdn_bchannel *bc)
618 unsigned char buff[32];
619 struct misdn_stack * stack;
621 cb_log(3, bc?bc->port:0, "$$$ CLEANUP CALLED pid:%d\n", bc?bc->pid:-1);
624 stack=get_stack_by_bc(bc);
626 if (!stack) return -1;
628 switch (bc->bc_state ) {
630 cb_log(5, stack->port, "$$$ Already cleaned up bc with stid :%x\n", bc->b_stid);
637 cb_log(2, stack->port, "$$$ Cleaning up bc with stid :%x pid:%d\n", bc->b_stid, bc->pid);
639 manager_bchannel_deactivate(bc);
643 beroec_destroy(bc->ec);
647 if ( misdn_cap_is_speech(bc->capability) && bc->ec_enable) {
648 manager_ec_disable(bc);
651 mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_TARGET|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
653 /*mISDN_clear_stack(stack->midev, bc->b_stid);*/
658 bc_state_change(bc, BCHAN_CLEANED);
665 void clear_l3(struct misdn_stack *stack)
669 for (i=0; i<stack->b_num; i++) {
670 if (global_state == MISDN_INITIALIZED) {
671 cb_event(EVENT_CLEANUP, &stack->bc[i], NULL);
672 empty_chan_in_stack(stack,i+1);
673 empty_bc(&stack->bc[i]);
674 clean_up_bc(&stack->bc[i]);
680 int set_chan_in_stack(struct misdn_stack *stack, int channel)
683 cb_log(4,stack->port,"set_chan_in_stack: %d\n",channel);
685 stack->channels[channel-1] = 1;
687 cb_log(0,stack->port,"couldn't set channel %d in\n", channel );
693 int chan_in_stack_free(struct misdn_stack *stack, int channel)
695 if (stack->channels[channel-1])
703 static int newteid=0;
705 #define MAXPROCS 0x100
707 int misdn_lib_get_l1_down(struct misdn_stack *stack)
711 act.prim = PH_DEACTIVATE | REQUEST;
712 act.addr = (stack->upper_id | FLG_MSG_DOWN) ;
718 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
724 int misdn_lib_get_l2_down(struct misdn_stack *stack)
727 if (stack->ptp && (stack->nt) ) {
730 dmsg = create_l2msg(DL_RELEASE| REQUEST, 0, 0);
732 if (stack->nst.manager_l3(&stack->nst, dmsg))
738 act.prim = DL_RELEASE| REQUEST;
739 act.addr = (stack->upper_id |FLG_MSG_DOWN) ;
743 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
750 int misdn_lib_get_l1_up(struct misdn_stack *stack)
754 act.prim = PH_ACTIVATE | REQUEST;
755 act.addr = (stack->upper_id | FLG_MSG_DOWN) ;
761 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
765 int misdn_lib_get_l2_up(struct misdn_stack *stack)
768 if (stack->ptp && (stack->nt) ) {
771 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
773 if (stack->nst.manager_l3(&stack->nst, dmsg))
779 act.prim = DL_ESTABLISH | REQUEST;
780 act.addr = (stack->upper_id |FLG_MSG_DOWN) ;
784 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
790 int misdn_lib_get_l2_te_ptp_up(struct misdn_stack *stack)
794 act.prim = DL_ESTABLISH | REQUEST;
795 act.addr = (stack->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
799 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
803 int misdn_lib_get_l2_status(struct misdn_stack *stack)
807 act.prim = DL_ESTABLISH | REQUEST;
809 act.addr = (stack->upper_id | FLG_MSG_DOWN) ;
813 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
816 int misdn_lib_get_short_status(struct misdn_stack *stack)
821 act.prim = MGR_SHORTSTATUS | REQUEST;
823 act.addr = (stack->upper_id | MSG_BROADCAST) ;
825 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
828 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
833 static int create_process (int midev, struct misdn_bchannel *bc) {
837 struct misdn_stack *stack=get_stack_by_bc(bc);
841 free_chan = find_free_chan_in_stack(stack, bc, bc->channel_preselected?bc->channel:0);
842 if (!free_chan) return -1;
843 /*bc->channel=free_chan;*/
845 cb_log(4,stack->port, " --> found channel: %d\n",free_chan);
847 for (i=0; i <= MAXPROCS; i++)
848 if (stack->procids[i]==0) break;
851 cb_log(0, stack->port, "Couldnt Create New ProcId.\n");
858 ncr.prim = CC_NEW_CR | REQUEST;
860 ncr.addr = (stack->upper_id | FLG_MSG_DOWN) ;
866 cb_log(3, stack->port, " --> new_l3id %x\n",l3_id);
869 if (stack->ptp || bc->te_choose_channel) {
870 /* we know exactly which channels are in use */
871 free_chan = find_free_chan_in_stack(stack, bc, bc->channel_preselected?bc->channel:0);
872 if (!free_chan) return -1;
873 /*bc->channel=free_chan;*/
874 cb_log(2,stack->port, " --> found channel: %d\n",free_chan);
876 /* other phones could have made a call also on this port (ptmp) */
881 /* if we are in te-mode, we need to create a process first */
882 if (newteid++ > 0xffff)
885 l3_id = (entity<<16) | newteid;
886 /* preparing message */
887 ncr.prim = CC_NEW_CR | REQUEST;
889 ncr.addr = (stack->upper_id | FLG_MSG_DOWN) ;
896 cb_log(3, stack->port, "--> new_l3id %x\n",l3_id);
898 mISDN_write(midev, &ncr, mISDN_HEADER_LEN+ncr.len, TIMEOUT_1SEC);
905 void misdn_lib_setup_bc(struct misdn_bchannel *bc)
911 int setup_bc(struct misdn_bchannel *bc)
913 unsigned char buff[1025];
919 struct misdn_stack *stack=get_stack_by_bc(bc);
922 cb_log(0, bc->port, "setup_bc: NO STACK FOUND!!\n");
926 int midev=stack->midev;
927 int channel=bc->channel-1-(bc->channel>16);
928 int b_stid=stack->b_stids[channel>=0?channel:0];
931 switch (bc->bc_state) {
935 cb_log(4, stack->port, "$$$ bc already upsetted stid :%x (state:%s)\n", b_stid, bc_state2str(bc->bc_state) );
939 cb_log(5, stack->port, "$$$ Setting up bc with stid :%x\n", b_stid);
942 cb_log(0, stack->port," -- Stid <=0 at the moment in channel:%d\n",channel);
944 bc_state_change(bc,BCHAN_ERROR);
953 memset(&li, 0, sizeof(li));
958 li.st = bc->b_stid; /* given idx */
965 if ( bc->hdlc || bc->nodsp) {
966 cb_log(4, stack->port,"setup_bc: without dsp\n");
968 int l = sizeof(li.name);
969 strncpy(li.name, "B L3", l);
972 li.pid.layermask = ISDN_LAYER((3));
973 li.pid.protocol[3] = ISDN_PID_L3_B_USER;
977 cb_log(4, stack->port,"setup_bc: with dsp\n");
979 int l = sizeof(li.name);
980 strncpy(li.name, "B L4", l);
983 li.pid.layermask = ISDN_LAYER((4));
984 li.pid.protocol[4] = ISDN_PID_L4_B_USER
990 ret = mISDN_new_layer(midev, &li);
992 cb_log(0, stack->port,"New Layer Err: %d %s\n",ret,strerror(errno));
994 bc_state_change(bc,BCHAN_ERROR);
998 bc->layer_id = li.id;
1001 memset(&pid, 0, sizeof(pid));
1005 cb_log(4, stack->port," --> Channel is %d\n", bc->channel);
1008 cb_log(2, stack->port," --> TRANSPARENT Mode (no DSP, no HDLC)\n");
1009 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
1010 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
1011 pid.protocol[3] = ISDN_PID_L3_B_USER;
1012 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3));
1014 } else if ( bc->hdlc ) {
1015 cb_log(2, stack->port," --> HDLC Mode\n");
1017 bc->ack_hdlc=(sem_t*)malloc(sizeof(sem_t));
1018 if ( sem_init((sem_t*)bc->ack_hdlc, 1, 0)<0 )
1019 sem_init((sem_t*)bc->ack_hdlc, 0, 0);
1022 pid.protocol[1] = ISDN_PID_L1_B_64HDLC ;
1023 pid.protocol[2] = ISDN_PID_L2_B_TRANS ;
1024 pid.protocol[3] = ISDN_PID_L3_B_USER;
1025 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) ;
1027 cb_log(2, stack->port," --> TRANSPARENT Mode\n");
1028 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
1029 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
1030 pid.protocol[3] = ISDN_PID_L3_B_DSP;
1031 pid.protocol[4] = ISDN_PID_L4_B_USER;
1032 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
1036 ret = mISDN_set_stack(midev, bc->b_stid, &pid);
1039 cb_log(0, stack->port,"$$$ Set Stack Err: %d %s\n",ret,strerror(errno));
1041 mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1043 bc_state_change(bc,BCHAN_ERROR);
1048 ret = mISDN_get_setstack_ind(midev, bc->layer_id);
1051 cb_log(0, stack->port,"$$$ Set StackIND Err: %d %s\n",ret,strerror(errno));
1052 mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1054 bc_state_change(bc,BCHAN_ERROR);
1058 ret = mISDN_get_layerid(midev, bc->b_stid, bc->layer) ;
1060 bc->addr = ret>0? ret : 0;
1063 cb_log(0, stack->port,"$$$ Get Layerid Err: %d %s\n",ret,strerror(errno));
1064 mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1066 bc_state_change(bc,BCHAN_ERROR);
1069 manager_bchannel_activate(bc);
1071 bc_state_change(bc,BCHAN_ACTIVATED);
1079 int init_bc(struct misdn_stack *stack, struct misdn_bchannel *bc, int midev, int port, int bidx, char *msn, int firsttime)
1081 unsigned char buff[1025];
1082 iframe_t *frm = (iframe_t *)buff;
1087 cb_log(8, port, "Init.BC %d.\n",bidx);
1089 memset(bc, 0,sizeof(struct misdn_bchannel));
1092 int l = sizeof(bc->msn);
1093 strncpy(bc->msn,msn, l);
1099 bc_state_change(bc, BCHAN_CLEANED);
1101 bc->port=stack->port;
1102 bc->nt=stack->nt?1:0;
1105 ibuffer_t* ibuf= init_ibuffer(MISDN_IBUF_SIZE);
1107 if (!ibuf) return -1;
1109 clear_ibuffer( ibuf);
1111 ibuf->rsem=malloc(sizeof(sem_t));
1115 if (sem_init(ibuf->rsem,1,0)<0)
1116 sem_init(ibuf->rsem,0,0);
1124 stack_info_t *stinf;
1125 ret = mISDN_get_stack_info(midev, stack->port, buff, sizeof(buff));
1127 cb_log(0, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
1131 stinf = (stack_info_t *)&frm->data.p;
1133 cb_log(8, port, " --> Child %x\n",stinf->child[bidx]);
1141 struct misdn_stack* stack_init( int midev, int port, int ptp )
1144 unsigned char buff[1025];
1145 iframe_t *frm = (iframe_t *)buff;
1146 stack_info_t *stinf;
1150 struct misdn_stack *stack = malloc(sizeof(struct misdn_stack));
1151 if (!stack ) return NULL;
1154 cb_log(8, port, "Init. Stack.\n");
1156 memset(stack,0,sizeof(struct misdn_stack));
1158 for (i=0; i<MAX_BCHANS + 1; i++ ) stack->channels[i]=0;
1164 stack->holding=NULL;
1167 msg_queue_init(&stack->downqueue);
1168 msg_queue_init(&stack->upqueue);
1170 /* query port's requirements */
1171 ret = mISDN_get_stack_info(midev, port, buff, sizeof(buff));
1173 cb_log(0, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
1177 stinf = (stack_info_t *)&frm->data.p;
1179 stack->d_stid = stinf->id;
1180 stack->b_num = stinf->childcnt;
1182 for (i=0; i<stinf->childcnt; i++)
1183 stack->b_stids[i] = stinf->child[i];
1185 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK) {
1186 case ISDN_PID_L0_TE_S0:
1189 case ISDN_PID_L0_NT_S0:
1190 cb_log(8, port, "NT Stack\n");
1195 case ISDN_PID_L0_TE_U:
1197 case ISDN_PID_L0_NT_U:
1199 case ISDN_PID_L0_TE_UP2:
1201 case ISDN_PID_L0_NT_UP2:
1203 case ISDN_PID_L0_TE_E1:
1204 cb_log(8, port, "TE S2M Stack\n");
1208 case ISDN_PID_L0_NT_E1:
1209 cb_log(8, port, "TE S2M Stack\n");
1215 cb_log(0, port, "this is a unknown port type 0x%08x\n", stinf->pid.protocol[0]);
1220 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP ) {
1231 cb_log(8, port, "Init. Stack.\n");
1233 memset(&li, 0, sizeof(li));
1235 int l = sizeof(li.name);
1236 strncpy(li.name,nt?"net l2":"user l4", l);
1241 li.pid.protocol[nt?2:4] = nt?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
1242 li.pid.layermask = ISDN_LAYER((nt?2:4));
1243 li.st = stack->d_stid;
1246 ret = mISDN_new_layer(midev, &li);
1248 cb_log(0, port, "%s: Cannot add layer %d to this port.\n", __FUNCTION__, nt?2:4);
1253 stack->upper_id = li.id;
1254 ret = mISDN_register_layer(midev, stack->d_stid, stack->upper_id);
1257 cb_log(0,port,"Cannot register layer %d of this port.\n", nt?2:4);
1261 stack->lower_id = mISDN_get_layerid(midev, stack->d_stid, nt?1:3);
1262 if (stack->lower_id < 0) {
1263 cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, nt?1:3);
1267 stack->upper_id = mISDN_get_layerid(midev, stack->d_stid, nt?2:4);
1268 if (stack->upper_id < 0) {
1269 cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, 2);
1273 cb_log(8, port, "NT Stacks upper_id %x\n",stack->upper_id);
1276 /* create nst (nt-mode only) */
1279 memset(&stack->nst, 0, sizeof(net_stack_t));
1280 memset(&stack->mgr, 0, sizeof(manager_t));
1282 stack->mgr.nst = &stack->nst;
1283 stack->nst.manager = &stack->mgr;
1285 stack->nst.l3_manager = handle_event_nt;
1286 stack->nst.device = midev;
1287 stack->nst.cardnr = port;
1288 stack->nst.d_stid = stack->d_stid;
1290 stack->nst.feature = FEATURE_NET_HOLD;
1292 stack->nst.feature |= FEATURE_NET_PTP;
1294 stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
1296 stack->nst.l1_id = stack->lower_id;
1297 stack->nst.l2_id = stack->upper_id;
1299 msg_queue_init(&stack->nst.down_queue);
1301 Isdnl2Init(&stack->nst);
1302 Isdnl3Init(&stack->nst);
1307 /*assume L1 is up, we'll get DEACTIVATES soon, for non
1312 misdn_lib_get_short_status(stack);
1313 misdn_lib_get_l1_up(stack);
1314 misdn_lib_get_l2_up(stack);
1318 cb_log(8,0,"stack_init: port:%d lowerId:%x upperId:%x\n",stack->port,stack->lower_id, stack->upper_id);
1324 void stack_destroy(struct misdn_stack* stack)
1330 cleanup_Isdnl2(&stack->nst);
1331 cleanup_Isdnl3(&stack->nst);
1334 if (stack->lower_id)
1335 mISDN_write_frame(stack->midev, buf, stack->lower_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1337 if (stack->upper_id)
1338 mISDN_write_frame(stack->midev, buf, stack->upper_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1342 struct misdn_stack * find_stack_by_addr(int addr)
1344 struct misdn_stack *stack;
1346 for (stack=glob_mgr->stack_list;
1348 stack=stack->next) {
1349 if ( (stack->upper_id&STACK_ID_MASK) == (addr&STACK_ID_MASK)) return stack;
1357 struct misdn_stack * find_stack_by_port(int port)
1359 struct misdn_stack *stack;
1361 for (stack=glob_mgr->stack_list;
1364 if (stack->port == port) return stack;
1369 struct misdn_stack * find_stack_by_mgr(manager_t* mgr_nt)
1371 struct misdn_stack *stack;
1373 for (stack=glob_mgr->stack_list;
1376 if ( &stack->mgr == mgr_nt) return stack;
1381 struct misdn_bchannel *find_bc_by_masked_l3id(struct misdn_stack *stack, unsigned long l3id, unsigned long mask)
1384 for (i=0; i<stack->b_num; i++) {
1385 if ( (stack->bc[i].l3_id & mask) == (l3id & mask)) return &stack->bc[i] ;
1387 return stack_holder_find(stack,l3id);
1391 struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id)
1394 for (i=0; i<stack->b_num; i++) {
1395 if (stack->bc[i].l3_id == l3id) return &stack->bc[i] ;
1397 return stack_holder_find(stack,l3id);
1400 struct misdn_bchannel *find_bc_holded(struct misdn_stack *stack)
1403 for (i=0; i<stack->b_num; i++) {
1404 if (stack->bc[i].holded ) return &stack->bc[i] ;
1410 struct misdn_bchannel *find_bc_by_addr(unsigned long addr)
1412 struct misdn_stack* stack;
1416 for (stack=glob_mgr->stack_list;
1418 stack=stack->next) {
1420 for (i=0; i< stack->b_num; i++) {
1422 if ( (stack->bc[i].addr&STACK_ID_MASK)==(addr&STACK_ID_MASK) || stack->bc[i].layer_id== addr ) {
1423 return &stack->bc[i];
1434 struct misdn_bchannel *find_bc_by_channel(int port, int channel)
1436 struct misdn_stack* stack=find_stack_by_port(port);
1439 if (!stack) return NULL;
1441 for (i=0; i< stack->b_num; i++) {
1442 if ( stack->bc[i].channel== channel ) {
1443 return &stack->bc[i];
1454 int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_t *frm)
1456 struct misdn_stack *stack=get_stack_by_bc(bc);
1462 case EVENT_CONNECT_ACKNOWLEDGE:
1464 if ( !misdn_cap_is_speech(bc->capability)) {
1465 int ret=setup_bc(bc);
1466 if (ret == -EINVAL){
1467 cb_log(0,bc->port,"send_event: setup_bc failed\n");
1474 if ( *bc->crypt_key ) {
1475 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);
1476 manager_ph_control_block(bc, BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
1478 case EVENT_ALERTING:
1479 case EVENT_PROGRESS:
1480 case EVENT_PROCEEDING:
1481 case EVENT_SETUP_ACKNOWLEDGE:
1488 if (bc->channel == 0xff) {
1489 bc->channel=find_free_chan_in_stack(stack, bc, 0);
1491 cb_log(0, stack->port, "Any Channel Requested, but we have no more!!\n");
1496 if (bc->channel >0 && bc->channel<255) {
1497 set_chan_in_stack(stack ,bc->channel);
1501 int ret=setup_bc(bc);
1502 if (ret == -EINVAL){
1503 cb_log(0,bc->port,"handle_event: setup_bc failed\n");
1504 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
1510 case EVENT_RELEASE_COMPLETE:
1513 empty_chan_in_stack(stack,bc->channel);
1514 int tmpcause=bc->cause;
1522 } else { /** NT MODE **/
1528 int handle_new_process(struct misdn_stack *stack, iframe_t *frm)
1531 struct misdn_bchannel* bc=misdn_lib_get_free_bc(stack->port, 0);
1535 cb_log(0, stack->port, " --> !! lib: No free channel!\n");
1539 cb_log(7, stack->port, " --> new_process: New L3Id: %x\n",frm->dinfo);
1540 bc->l3_id=frm->dinfo;
1544 int handle_cr ( struct misdn_stack *stack, iframe_t *frm)
1546 if (!stack) return -1;
1548 switch (frm->prim) {
1549 case CC_NEW_CR|INDICATION:
1550 cb_log(7, stack->port, " --> lib: NEW_CR Ind with l3id:%x on this port.\n",frm->dinfo);
1551 if (handle_new_process(stack, frm) <0)
1554 case CC_NEW_CR|CONFIRM:
1556 case CC_NEW_CR|REQUEST:
1558 case CC_RELEASE_CR|REQUEST:
1560 case CC_RELEASE_CR|CONFIRM:
1562 case CC_RELEASE_CR|INDICATION:
1563 cb_log(4, stack->port, " --> lib: RELEASE_CR Ind with l3id:%x\n",frm->dinfo);
1565 struct misdn_bchannel *bc=find_bc_by_l3id(stack, frm->dinfo);
1566 struct misdn_bchannel dummybc;
1569 cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
1570 memset (&dummybc,0,sizeof(dummybc));
1571 dummybc.port=stack->port;
1572 dummybc.l3_id=frm->dinfo;
1577 cb_log(4, stack->port, " --> lib: CLEANING UP l3id: %x\n",frm->dinfo);
1579 empty_chan_in_stack(stack,bc->channel);
1584 dump_chan_list(stack);
1586 bc->need_disconnect=0;
1588 bc->need_release_complete=0;
1590 cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data);
1591 if (bc->stack_holder) {
1592 cb_log(4,stack->port, "REMOVEING Holder\n");
1593 stack_holder_remove( stack, bc);
1599 cb_log(4, stack->port, "BC with dinfo: %x not found.. (prim was %x and addr %x)\n",frm->dinfo, frm->prim, frm->addr);
1611 /*Emptys bc if it's reserved (no SETUP out yet)*/
1612 void misdn_lib_release(struct misdn_bchannel *bc)
1614 struct misdn_stack *stack=get_stack_by_bc(bc);
1617 cb_log(1,0,"misdn_release: No Stack found\n");
1621 if (bc->channel>0) {
1622 empty_chan_in_stack(stack,bc->channel);
1631 int misdn_lib_get_port_up (int port)
1633 struct misdn_stack *stack;
1635 for (stack=glob_mgr->stack_list;
1637 stack=stack->next) {
1639 if (stack->port == port) {
1642 misdn_lib_get_l1_up(stack);
1644 misdn_lib_get_l2_up(stack);
1653 int misdn_lib_get_port_down (int port)
1654 { /* Pull Down L1 */
1655 struct misdn_stack *stack;
1656 for (stack=glob_mgr->stack_list;
1658 stack=stack->next) {
1659 if (stack->port == port) {
1661 misdn_lib_get_l2_down(stack);
1662 misdn_lib_get_l1_down(stack);
1669 int misdn_lib_send_facility(struct misdn_bchannel *bc, enum facility_type fac, void *data)
1672 case FACILITY_CALLDEFLECT:
1673 strcpy(bc->out_fac.calldeflect_nr,(char*)data);
1676 cb_log(1,bc?bc->port:0,"We don't handle this facility yet: %d\n",fac);
1680 bc->out_fac_type=fac;
1682 misdn_lib_send_event(bc,EVENT_FACILITY);
1687 int misdn_lib_port_up(int port, int check)
1689 struct misdn_stack *stack;
1692 for (stack=glob_mgr->stack_list;
1694 stack=stack->next) {
1696 if ( !stack->ptp && !check) return 1;
1698 if (stack->port == port) {
1700 if (stack->blocked) {
1701 cb_log(0,port, "Port Blocked:%d L2:%d L1:%d\n", stack->blocked, stack->l2link, stack->l1link);
1707 if (stack->l1link && stack->l2link) {
1710 cb_log(0,port, "Port Down L2:%d L1:%d\n",
1711 stack->l2link, stack->l1link);
1718 cb_log(0,port, "Port down PMP\n");
1730 handle_event_nt(void *dat, void *arg)
1732 manager_t *mgr = (manager_t *)dat;
1733 msg_t *msg = (msg_t *)arg;
1734 mISDNuser_head_t *hh;
1737 struct misdn_stack *stack=find_stack_by_mgr(mgr);
1743 hh=(mISDNuser_head_t*)msg->data;
1746 cb_log(5, stack->port, " --> lib: prim %x dinfo %x\n",hh->prim, hh->dinfo);
1749 case CC_RETRIEVE|INDICATION:
1751 iframe_t frm; /* fake te frm to add callref to global callreflist */
1752 frm.dinfo = hh->dinfo;
1754 frm.addr=stack->upper_id | FLG_MSG_DOWN;
1756 frm.prim = CC_NEW_CR|INDICATION;
1758 if (handle_cr( stack, &frm)< 0) {
1760 cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
1761 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1762 stack->nst.manager_l3(&stack->nst, dmsg);
1767 struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1768 struct misdn_bchannel *hold_bc=stack_holder_find(stack,bc->l3_id);
1771 cb_event(EVENT_NEW_BC, hold_bc, bc);
1772 cb_log(4, stack->port, "REMOVEING Holder\n");
1773 stack_holder_remove(stack, hold_bc);
1781 case CC_SETUP|CONFIRM:
1783 struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1784 int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE));
1785 cb_log(4, stack->port, " --> lib: Event_ind:SETUP CONFIRM [NT] : new L3ID is %x\n",l3id );
1787 if (!bc) { cb_log(4, stack->port, "Bc Not found (after SETUP CONFIRM)\n"); return 0; }
1788 cb_log (2,bc->port,"I IND :CC_SETUP|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
1790 cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
1795 case CC_SETUP|INDICATION:
1797 iframe_t frm; /* fake te frm to add callref to global callreflist */
1798 frm.dinfo = hh->dinfo;
1799 frm.addr=stack->upper_id;
1800 frm.prim = CC_NEW_CR|INDICATION;
1802 if (handle_cr(stack, &frm)< 0) {
1804 cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
1805 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1806 stack->nst.manager_l3(&stack->nst, dmsg);
1813 case CC_CONNECT_ACKNOWLEDGE|INDICATION:
1816 struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1818 if ( !misdn_cap_is_speech(bc->capability)) {
1819 int ret=setup_bc(bc);
1820 if (ret == -EINVAL){
1821 cb_log(0,bc->port,"send_event: setup_bc failed\n");
1830 case CC_ALERTING|INDICATION:
1831 case CC_PROCEEDING|INDICATION:
1832 case CC_SETUP_ACKNOWLEDGE|INDICATION:
1833 if(!stack->ptp) break;
1834 case CC_CONNECT|INDICATION:
1837 struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1841 cb_log(0, stack->port,"!!!! We didn't found our bc, dinfo:%x on this port.\n",hh->dinfo);
1843 cb_log(0, stack->port, "Releaseing call %x (No free Chan for you..)\n", hh->dinfo);
1844 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1845 stack->nst.manager_l3(&stack->nst, dmsg);
1850 int ret=setup_bc(bc);
1851 if (ret == -EINVAL){
1852 cb_log(0,bc->port,"handle_event_nt: setup_bc failed\n");
1853 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
1858 case CC_DISCONNECT|INDICATION:
1860 struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1862 bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
1864 int myprocid=bc->l3_id&0x0000ffff;
1865 hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
1866 cb_log(3,stack->port,"Reject dinfo: %x cause:%d\n",hh->dinfo,bc->cause);
1873 case CC_FACILITY|INDICATION:
1875 struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1877 bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
1879 int myprocid=bc->l3_id&0x0000ffff;
1880 hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
1881 cb_log(4,bc->port,"Repaired reject Bug, new dinfo: %x\n",hh->dinfo);
1887 case CC_RELEASE_COMPLETE|INDICATION:
1890 case CC_SUSPEND|INDICATION:
1893 cb_log(4, stack->port, " --> Got Suspend, sending Reject for now\n");
1894 dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST,MT_SUSPEND_REJECT, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
1895 stack->nst.manager_l3(&stack->nst, dmsg);
1900 case CC_RESUME|INDICATION:
1903 case CC_RELEASE|CONFIRM:
1906 case CC_RELEASE|INDICATION:
1909 case CC_RELEASE_CR|INDICATION:
1911 struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1912 struct misdn_bchannel dummybc;
1913 iframe_t frm; /* fake te frm to remove callref from global callreflist */
1914 frm.dinfo = hh->dinfo;
1916 frm.addr=stack->upper_id | FLG_MSG_DOWN;
1918 frm.prim = CC_RELEASE_CR|INDICATION;
1919 cb_log(4, stack->port, " --> Faking Realease_cr for %x\n",frm.addr);
1920 /** removing procid **/
1922 cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x) on this port.\n", hh->dinfo);
1923 memset (&dummybc,0,sizeof(dummybc));
1924 dummybc.port=stack->port;
1925 dummybc.l3_id=hh->dinfo;
1930 if ( (bc->l3_id & 0xff00) == 0xff00) {
1931 cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", bc->l3_id&0xff);
1932 stack->procids[bc->l3_id&0xff] = 0 ;
1935 else cb_log(0, stack->port, "Couldnt find BC so I couldnt remove the Process!!!! this is a bad port.\n");
1937 if (handle_cr(stack, &frm)<0) {
1945 case CC_NEW_CR|INDICATION:
1946 /* Got New CR for bchan, for now I handle this one in */
1947 /* connect_ack, Need to be changed */
1949 struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1950 int l3id = *((int *)(((u_char *)msg->data)+ mISDNUSER_HEAD_SIZE));
1951 if (!bc) { cb_log(0, stack->port, " --> In NEW_CR: didn't found bc ??\n"); return -1;};
1952 if (((l3id&0xff00)!=0xff00) && ((bc->l3_id&0xff00)==0xff00)) {
1953 cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", 0xff&bc->l3_id);
1954 stack->procids[bc->l3_id&0xff] = 0 ;
1956 cb_log(4, stack->port, "lib: Event_ind:CC_NEW_CR : very new L3ID is %x\n",l3id );
1959 cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
1965 case DL_ESTABLISH | INDICATION:
1966 case DL_ESTABLISH | CONFIRM:
1968 cb_log(3, stack->port, "%% GOT L2 Activate Info.\n");
1970 if (stack->ptp && stack->l2link) {
1971 cb_log(0, stack->port, "%% GOT L2 Activate Info. but we're activated already.. this l2 is faulty, blocking port\n");
1972 cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data);
1984 case DL_RELEASE | INDICATION:
1985 case DL_RELEASE | CONFIRM:
1988 cb_log(3 , stack->port, "%% GOT L2 DeActivate Info.\n");
1990 if (stack->l2upcnt>3) {
1991 cb_log(0 , stack->port, "!!! Could not Get the L2 up after 3 Attemps!!!\n");
1994 if (stack->nt) misdn_lib_reinit_nt_stack(stack->port);
1996 if (stack->l1link) {
1997 misdn_lib_get_l2_up(stack);
2003 cb_log(3, stack->port, "%% GOT L2 DeActivate Info.\n");
2014 /* Parse Events and fire_up to App. */
2015 struct misdn_bchannel *bc;
2016 struct misdn_bchannel dummybc;
2018 enum event_e event = isdn_msg_get_event(msgs_g, msg, 1);
2020 bc=find_bc_by_l3id(stack, hh->dinfo);
2024 cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x).\n", hh->dinfo);
2025 memset (&dummybc,0,sizeof(dummybc));
2026 dummybc.port=stack->port;
2027 dummybc.l3_id=hh->dinfo;
2031 isdn_msg_parse_event(msgs_g,msg,bc, 1);
2035 if (bc->channel>0 && bc->channel<255) {
2038 set_chan_in_stack(stack, bc->channel);
2040 cb_log(0,stack->port," --> PTMP but channel requested\n");
2044 bc->channel = find_free_chan_in_stack(stack, bc, 0);
2046 cb_log(0, stack->port, " No free channel at the moment\n");
2050 cb_log(0, stack->port, "Releaseing call %x (No free Chan for you..)\n", hh->dinfo);
2051 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST,MT_RELEASE_COMPLETE, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
2052 stack->nst.manager_l3(&stack->nst, dmsg);
2064 case EVENT_RELEASE_COMPLETE:
2066 empty_chan_in_stack(stack, bc->channel);
2067 int tmpcause=bc->cause;
2077 if(!isdn_get_info(msgs_g,event,1)) {
2078 cb_log(4, stack->port, "Unknown Event Ind: prim %x dinfo %x\n",hh->prim, hh->dinfo);
2083 cb_log(1, stack->port, "Siemens Busy reject..\n");
2090 cb_event(event, bc, glob_mgr->user_data);
2094 cb_log(4, stack->port, "No BC found with l3id: prim %x dinfo %x\n",hh->prim, hh->dinfo);
2105 int handle_timers(msg_t* msg)
2107 iframe_t *frm= (iframe_t*)msg->data;
2108 struct misdn_stack *stack;
2111 switch (frm->prim) {
2112 case MGR_INITTIMER | CONFIRM:
2113 case MGR_ADDTIMER | CONFIRM:
2114 case MGR_DELTIMER | CONFIRM:
2115 case MGR_REMOVETIMER | CONFIRM:
2122 if (frm->prim==(MGR_TIMER | INDICATION) ) {
2123 for (stack = glob_mgr->stack_list;
2125 stack = stack->next) {
2128 if (!stack->nt) continue;
2130 it = stack->nst.tlist;
2132 for(it=stack->nst.tlist;
2135 if (it->id == (int)frm->addr)
2140 ret = mISDN_write_frame(stack->midev, msg->data, frm->addr,
2141 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2142 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2143 ret = it->function(it->data);
2149 cb_log(0, 0, "Timer Msg without Timer ??\n");
2159 void misdn_lib_tone_generator_start(struct misdn_bchannel *bc)
2161 bc->generate_tone=1;
2164 void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
2166 bc->generate_tone=0;
2170 static int do_tone(struct misdn_bchannel *bc, int len)
2174 if (bc->generate_tone) {
2175 cb_event(EVENT_TONE_GENERATE, bc, glob_mgr->user_data);
2177 if ( !bc->nojitter ) {
2178 misdn_tx_jitter(bc,len);
2189 void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
2191 char buf[4096 + mISDN_HEADER_LEN];
2192 char *data=&buf[mISDN_HEADER_LEN];
2193 iframe_t *txfrm= (iframe_t*)buf;
2196 jlen=cb_jb_empty(bc,data,len);
2199 flip_buf_bits( data, jlen);
2202 cb_log(7,bc->port,"Jitterbuffer Underrun.\n");
2206 flip_buf_bits(data,len);
2207 beroec_cancel_alaw_chunk(bc->ec, data, bc->bframe, len);
2208 flip_buf_bits(data,len);
2213 txfrm->prim = DL_DATA|REQUEST;
2217 txfrm->addr = bc->addr|FLG_MSG_DOWN; /* | IF_DOWN; */
2220 cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
2222 r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
2224 #define MISDN_GEN_SILENCE
2225 #ifdef MISDN_GEN_SILENCE
2226 int cnt=len/TONE_SILENCE_SIZE;
2227 int rest=len%TONE_SILENCE_SIZE;
2230 for (i=0; i<cnt; i++) {
2231 memcpy(data, tone_silence_flip, TONE_SILENCE_SIZE );
2232 data +=TONE_SILENCE_SIZE;
2236 memcpy(data, tone_silence_flip, rest);
2239 txfrm->prim = DL_DATA|REQUEST;
2243 txfrm->addr = bc->addr|FLG_MSG_DOWN; /* | IF_DOWN; */
2246 cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
2248 r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
2254 int handle_bchan(msg_t *msg)
2256 iframe_t *frm= (iframe_t*)msg->data;
2259 struct misdn_bchannel *bc=find_bc_by_addr(frm->addr);
2262 cb_log(1,0,"handle_bchan: BC not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo);
2266 struct misdn_stack *stack=get_stack_by_bc(bc);
2269 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);
2273 switch (frm->prim) {
2275 case MGR_SETSTACK| CONFIRM:
2276 cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|CONFIRM pid:%d\n",bc->pid);
2279 case MGR_SETSTACK| INDICATION:
2280 cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|IND pid:%d\n",bc->pid);
2284 bc->addr = mISDN_get_layerid(stack->midev, bc->b_stid, bc->layer);
2287 if (errno == EAGAIN) {
2292 cb_log(0,stack->port,"$$$ Get Layer (%d) Id Error: %s\n",bc->layer,strerror(errno));
2294 /* we kill the channel later, when we received some
2296 bc->addr= frm->addr;
2297 } else if ( bc->addr < 0) {
2298 cb_log(0, stack->port,"$$$ bc->addr <0 Error:%s\n",strerror(errno));
2302 cb_log(4, stack->port," --> Got Adr %x\n", bc->addr);
2307 switch(bc->bc_state) {
2309 bc_state_change(bc,BCHAN_SETUPED);
2312 case BCHAN_CLEAN_REQUEST:
2314 cb_log(0, stack->port," --> STATE WASN'T SETUP (but %s) in SETSTACK|IND pid:%d\n",bc_state2str(bc->bc_state), bc->pid);
2320 case MGR_DELLAYER| INDICATION:
2321 cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|IND pid:%d\n",bc->pid);
2324 case MGR_DELLAYER| CONFIRM:
2325 cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|CNF pid:%d\n",bc->pid);
2333 case PH_ACTIVATE | INDICATION:
2334 case DL_ESTABLISH | INDICATION:
2335 cb_log(3, stack->port, "BCHAN: ACT Ind pid:%d\n", bc->pid);
2340 case PH_ACTIVATE | CONFIRM:
2341 case DL_ESTABLISH | CONFIRM:
2343 cb_log(3, stack->port, "BCHAN: bchan ACT Confirm pid:%d\n",bc->pid);
2348 case DL_ESTABLISH | REQUEST:
2351 mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN, DL_ESTABLISH | CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
2356 case DL_RELEASE|REQUEST:
2359 mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN, DL_RELEASE| CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
2364 case PH_DEACTIVATE | INDICATION:
2365 case DL_RELEASE | INDICATION:
2366 cb_log (3, stack->port, "BCHAN: DeACT Ind pid:%d\n",bc->pid);
2371 case PH_DEACTIVATE | CONFIRM:
2372 case DL_RELEASE | CONFIRM:
2373 cb_log(3, stack->port, "BCHAN: DeACT Conf pid:%d\n",bc->pid);
2378 case PH_CONTROL|INDICATION:
2380 unsigned int cont = *((unsigned int *)&frm->data.p);
2382 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);
2384 if ((cont&~DTMF_TONE_MASK) == DTMF_TONE_VAL) {
2385 int dtmf = cont & DTMF_TONE_MASK;
2386 cb_log(4, stack->port, " --> DTMF TONE: %c\n",dtmf);
2388 cb_event(EVENT_DTMF_TONE, bc, glob_mgr->user_data);
2393 if (cont == BF_REJECT) {
2394 cb_log(4, stack->port, " --> BF REJECT\n");
2398 if (cont == BF_ACCEPT) {
2399 cb_log(4, stack->port, " --> BF ACCEPT\n");
2406 case PH_DATA|REQUEST:
2407 case DL_DATA|REQUEST:
2408 cb_log(0, stack->port, "DL_DATA REQUEST \n");
2415 case PH_DATA|INDICATION:
2416 case DL_DATA|INDICATION:
2418 bc->bframe = (void*)&frm->data.i;
2419 bc->bframe_len = frm->len;
2421 /** Anyway flip the bufbits **/
2422 if ( misdn_cap_is_speech(bc->capability) )
2423 flip_buf_bits(bc->bframe, bc->bframe_len);
2426 if (!bc->bframe_len) {
2427 cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
2432 if ( (bc->addr&STACK_ID_MASK) != (frm->addr&STACK_ID_MASK) ) {
2433 cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
2439 cb_log(0, stack->port, "DL_DATA INDICATION Len %d\n", frm->len);
2443 if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) {
2446 #ifdef MISDN_B_DEBUG
2447 cb_log(0,bc->port,"do_tone START\n");
2449 t=do_tone(bc,frm->len);
2451 #ifdef MISDN_B_DEBUG
2452 cb_log(0,bc->port,"do_tone STOP (%d)\n",t);
2456 if ( misdn_cap_is_speech(bc->capability)) {
2457 if ( !bc->nojitter ) {
2458 #ifdef MISDN_B_DEBUG
2459 cb_log(0,bc->port,"tx_jitter START\n");
2461 misdn_tx_jitter(bc,frm->len);
2462 #ifdef MISDN_B_DEBUG
2463 cb_log(0,bc->port,"tx_jitter STOP\n");
2468 #ifdef MISDN_B_DEBUG
2469 cb_log(0,bc->port,"EVENT_B_DATA START\n");
2472 int i=cb_event( EVENT_BCHAN_DATA, bc, glob_mgr->user_data);
2473 #ifdef MISDN_B_DEBUG
2474 cb_log(0,bc->port,"EVENT_B_DATA STOP\n");
2478 cb_log(10,stack->port,"cb_event returned <0\n");
2479 /*clean_up_bc(bc);*/
2488 case PH_CONTROL | CONFIRM:
2489 cb_log(4, stack->port, "PH_CONTROL|CNF bc->addr:%x\n", frm->addr);
2493 case PH_DATA | CONFIRM:
2494 case DL_DATA|CONFIRM:
2497 cb_log(0, stack->port, "Data confirmed\n");
2503 case DL_DATA|RESPONSE:
2505 cb_log(0, stack->port, "Data response\n");
2516 int handle_frm_nt(msg_t *msg)
2518 iframe_t *frm= (iframe_t*)msg->data;
2519 struct misdn_stack *stack;
2522 stack=find_stack_by_addr( frm->addr );
2526 if (!stack || !stack->nt) {
2531 if ((err=stack->nst.l1_l2(&stack->nst,msg))) {
2533 if (nt_err_cnt > 0 ) {
2534 if (nt_err_cnt < 100) {
2536 cb_log(0, stack->port, "NT Stack sends us error: %d \n", err);
2537 } else if (nt_err_cnt < 105){
2538 cb_log(0, stack->port, "NT Stack sends us error: %d over 100 times, so I'll stop this message\n", err);
2551 int handle_frm(msg_t *msg)
2553 iframe_t *frm = (iframe_t*) msg->data;
2555 struct misdn_stack *stack=find_stack_by_addr(frm->addr);
2558 cb_log(4,stack?stack->port:0,"handle_frm: frm->addr:%x frm->prim:%x\n",frm->addr,frm->prim);
2561 if (!stack || stack->nt) {
2566 struct misdn_bchannel *bc;
2567 int ret=handle_cr(stack, frm);
2570 cb_log(3,stack?stack->port:0,"handle_frm: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr);
2578 bc=find_bc_by_l3id(stack, frm->dinfo);
2581 enum event_e event = isdn_msg_get_event(msgs_g, msg, 0);
2582 enum event_response_e response=RESPONSE_OK;
2584 isdn_msg_parse_event(msgs_g,msg,bc, 0);
2586 /** Preprocess some Events **/
2587 handle_event(bc, event, frm);
2588 /* shoot up event to App: */
2589 cb_log(5, stack->port, "lib Got Prim: Addr %x prim %x dinfo %x\n",frm->addr, frm->prim, frm->dinfo);
2591 if(!isdn_get_info(msgs_g,event,0))
2592 cb_log(0, stack->port, "Unknown Event Ind: Addr:%x prim %x dinfo %x\n",frm->addr, frm->prim, frm->dinfo);
2594 response=cb_event(event, bc, glob_mgr->user_data);
2596 if (event == EVENT_SETUP) {
2598 case RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE:
2600 cb_log(0, stack->port, "TOTALY IGNORING SETUP \n");
2603 case RESPONSE_IGNORE_SETUP:
2604 /* I think we should send CC_RELEASE_CR, but am not sure*/
2607 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
2609 empty_chan_in_stack(stack, bc->channel);
2611 bc_state_change(bc,BCHAN_CLEANED);
2613 cb_log(0, stack->port, "GOT IGNORE SETUP\n");
2618 cb_log(4, stack->port, "GOT SETUP OK\n");
2627 cb_log(5, stack->port, "Freeing Msg on prim:%x \n",frm->prim);
2635 cb_log(0, stack->port, "NO BC FOR STACK\n");
2639 cb_log(4, stack->port, "TE_FRM_HANDLER: Returning 0 on prim:%x \n",frm->prim);
2644 int handle_l1(msg_t *msg)
2646 iframe_t *frm = (iframe_t*) msg->data;
2647 struct misdn_stack *stack = find_stack_by_addr(frm->addr);
2650 if (!stack) return 0 ;
2652 switch (frm->prim) {
2653 case PH_ACTIVATE | CONFIRM:
2654 case PH_ACTIVATE | INDICATION:
2655 cb_log (3, stack->port, "L1: PH L1Link Up!\n");
2660 if (stack->nst.l1_l2(&stack->nst, msg))
2664 misdn_lib_get_l2_up(stack);
2669 for (i=0;i<stack->b_num; i++) {
2670 if (stack->bc[i].evq != EVENT_NOTHING) {
2671 cb_log(4, stack->port, "Fireing Queued Event %s because L1 got up\n", isdn_get_info(msgs_g, stack->bc[i].evq, 0));
2672 misdn_lib_send_event(&stack->bc[i],stack->bc[i].evq);
2673 stack->bc[i].evq=EVENT_NOTHING;
2679 case PH_ACTIVATE | REQUEST:
2681 cb_log(3,stack->port,"L1: PH_ACTIVATE|REQUEST \n");
2684 case PH_DEACTIVATE | REQUEST:
2686 cb_log(3,stack->port,"L1: PH_DEACTIVATE|REQUEST \n");
2689 case PH_DEACTIVATE | CONFIRM:
2690 case PH_DEACTIVATE | INDICATION:
2691 cb_log (3, stack->port, "L1: PH L1Link Down! \n");
2693 for (i=0; i<stack->b_num; i++) {
2694 if (global_state == MISDN_INITIALIZED) {
2695 cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data);
2700 if (stack->nst.l1_l2(&stack->nst, msg))
2714 int handle_l2(msg_t *msg)
2716 iframe_t *frm = (iframe_t*) msg->data;
2718 struct misdn_stack *stack = find_stack_by_addr(frm->addr);
2726 case DL_ESTABLISH | REQUEST:
2727 cb_log(1,stack->port,"DL_ESTABLISH|REQUEST \n");
2729 case DL_RELEASE | REQUEST:
2730 cb_log(1,stack->port,"DL_RELEASE|REQUEST \n");
2733 case DL_ESTABLISH | INDICATION:
2734 case DL_ESTABLISH | CONFIRM:
2736 cb_log (3, stack->port, "L2: L2Link Up! \n");
2737 if (stack->ptp && stack->l2link) {
2738 cb_log (-1, stack->port, "L2: L2Link Up! but it's already UP.. must be faulty, blocking port\n");
2739 cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data);
2747 case DL_RELEASE | INDICATION:
2748 case DL_RELEASE | CONFIRM:
2750 cb_log (3, stack->port, "L2: L2Link Down! \n");
2761 int handle_mgmt(msg_t *msg)
2763 iframe_t *frm = (iframe_t*) msg->data;
2765 if ( (frm->addr == 0) && (frm->prim == (MGR_DELLAYER|CONFIRM)) ) {
2766 cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: 0 !\n") ;
2771 struct misdn_stack * stack=find_stack_by_addr(frm->addr);
2774 if (frm->prim == (MGR_DELLAYER|CONFIRM)) {
2775 cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: %x !\n",
2785 case MGR_SHORTSTATUS | INDICATION:
2786 case MGR_SHORTSTATUS | CONFIRM:
2787 cb_log(5, 0, "MGMT: Short status dinfo %x\n",frm->dinfo);
2789 switch (frm->dinfo) {
2790 case SSTATUS_L1_ACTIVATED:
2791 cb_log(3, 0, "MGMT: SSTATUS: L1_ACTIVATED \n");
2795 case SSTATUS_L1_DEACTIVATED:
2796 cb_log(3, 0, "MGMT: SSTATUS: L1_DEACTIVATED \n");
2802 case SSTATUS_L2_ESTABLISHED:
2803 cb_log(3, stack->port, "MGMT: SSTATUS: L2_ESTABLISH \n");
2807 case SSTATUS_L2_RELEASED:
2808 cb_log(3, stack->port, "MGMT: SSTATUS: L2_RELEASED \n");
2816 case MGR_SETSTACK | INDICATION:
2817 cb_log(4, stack->port, "MGMT: SETSTACK|IND dinfo %x\n",frm->dinfo);
2820 case MGR_DELLAYER | CONFIRM:
2821 cb_log(4, stack->port, "MGMT: DELLAYER|CNF dinfo %x\n",frm->dinfo) ;
2828 if ( (frm->prim & 0x0f0000) == 0x0f0000) {
2829 cb_log(5, 0, "$$$ MGMT FRAME: prim %x addr %x dinfo %x\n",frm->prim, frm->addr, frm->dinfo) ;
2838 msg_t *fetch_msg(int midev)
2840 msg_t *msg=alloc_msg(MAX_MSG_SIZE);
2845 cb_log(0, 0, "fetch_msg: alloc msg failed !!");
2851 FD_SET(midev,&rdfs);
2853 mISDN_select(FD_SETSIZE, &rdfs, NULL, NULL, NULL);
2854 //select(FD_SETSIZE, &rdfs, NULL, NULL, NULL);
2856 if (FD_ISSET(midev, &rdfs)) {
2860 r=mISDN_read(midev,msg->data,MAX_MSG_SIZE, TIMEOUT_10SEC);
2864 free_msg(msg); /* danger, cauz usualy freeing in main_loop */
2865 cb_log(6,0,"Got empty Msg..\n");
2870 if (errno == EAGAIN) {
2871 /*we wait for mISDN here*/
2872 cb_log(4,0,"mISDN_read wants us to wait\n");
2877 cb_log(0,0,"mISDN_read returned :%d error:%s (%d)\n",r,strerror(errno),errno);
2884 printf ("Select timeout\n");
2891 void misdn_lib_isdn_l1watcher(int port)
2893 struct misdn_stack *stack;
2895 for (stack = glob_mgr->stack_list; stack && (stack->port != port); stack = stack->next)
2899 cb_log(4, port, "Checking L1 State\n");
2900 if (!stack->l1link) {
2901 cb_log(4, port, "L1 State Down, trying to get it up again\n");
2902 misdn_lib_get_short_status(stack);
2903 misdn_lib_get_l1_up(stack);
2904 misdn_lib_get_l2_up(stack);
2909 static void misdn_lib_isdn_event_catcher(void *arg)
2911 struct misdn_lib *mgr = arg;
2912 int zero_frm=0 , fff_frm=0 ;
2913 int midev= mgr->midev;
2917 msg_t *msg = fetch_msg(midev);
2923 frm = (iframe_t*) msg->data;
2925 /** When we make a call from NT2Ast we get this frames **/
2926 if (frm->len == 0 && frm->addr == 0 && frm->dinfo == 0 && frm->prim == 0 ) {
2932 cb_log(0, port, "*** Alert: %d zero_frms caught\n", zero_frm);
2937 /** I get this sometimes after setup_bc **/
2938 if (frm->len == 0 && frm->dinfo == 0 && frm->prim == 0xffffffff ) {
2944 cb_log(0, port, "*** Alert: %d fff_frms caught\n", fff_frm);
2949 manager_isdn_handler(frm, msg);
2955 /** App Interface **/
2959 iframe_t *frm=(iframe_t*)buff;
2960 int midev=mISDN_open();
2963 memset(buff,0,1025);
2965 if (midev<=0) return midev;
2967 /* create entity for layer 3 TE-mode */
2968 mISDN_write_frame(midev, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2969 ret = mISDN_read_frame(midev, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
2971 if (ret < mISDN_HEADER_LEN) {
2973 fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN: %s\n",strerror(errno));
2977 entity = frm->dinfo & 0xffff ;
2986 void te_lib_destroy(int midev)
2989 mISDN_write_frame(midev, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
2991 cb_log(4, 0, "Entetity deleted\n");
2993 cb_log(4, 0, "midev closed\n");
2998 void misdn_lib_transfer(struct misdn_bchannel* holded_bc)
3000 holded_bc->holded=0;
3003 struct misdn_bchannel *manager_find_bc_by_pid(int pid)
3005 struct misdn_stack *stack;
3008 for (stack=glob_mgr->stack_list;
3010 stack=stack->next) {
3011 for (i=0; i<stack->b_num; i++)
3012 if (stack->bc[i].pid == pid) return &stack->bc[i];
3018 struct misdn_bchannel *manager_find_bc_holded(struct misdn_bchannel* bc)
3020 struct misdn_stack *stack=get_stack_by_bc(bc);
3021 return find_bc_holded(stack);
3026 void prepare_bc(struct misdn_bchannel*bc, int channel)
3028 bc->channel = channel;
3029 bc->channel_preselected = channel?1:0;
3031 bc->need_disconnect=1;
3033 bc->need_release_complete=1;
3036 if (++mypid>5000) mypid=1;
3050 struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel)
3052 struct misdn_stack *stack;
3055 if (channel < 0 || channel > MAX_BCHANS) {
3056 cb_log(0,port,"Requested channel out of bounds (%d)\n",channel);
3060 for (stack=glob_mgr->stack_list; stack; stack=stack->next) {
3062 if (stack->port == port) {
3063 if (stack->blocked) {
3064 cb_log(0,port,"Port is blocked\n");
3069 if (channel <= stack->b_num) {
3070 for (i = 0; i < stack->b_num; i++) {
3071 if (stack->bc[i].in_use && stack->bc[i].channel == channel) {
3072 cb_log(0,port,"Requested channel:%d on port:%d is already in use\n",channel, port);
3077 cb_log(0,port,"Requested channel:%d is out of bounds on port:%d\n",channel, port);
3081 for (i = 0; i < stack->b_num; i++) {
3082 if (!stack->bc[i].in_use) {
3083 prepare_bc(&stack->bc[i], channel);
3084 return &stack->bc[i];
3088 cb_log(1,port,"There is no free channel on port (%d)\n",port);
3093 cb_log(0,port,"Port is not configured (%d)\n",port);
3098 char *fac2str (enum facility_type type) {
3100 enum facility_type p;
3103 { FACILITY_NONE, "FAC_NONE" },
3104 { FACILITY_CALLDEFLECT, "FAC_CALLDEFLECT"},
3105 { FACILITY_CENTREX, "FAC_CENTREX"}
3110 for (i=0; i < sizeof(arr)/sizeof( struct arr_el) ; i ++)
3111 if ( arr[i].p==type) return arr[i].s;
3113 return "FAC_UNKNOWN";
3116 void misdn_lib_log_ies(struct misdn_bchannel *bc)
3120 struct misdn_stack *stack=get_stack_by_bc(bc);
3124 cb_log(2, stack->port, " --> channel:%d mode:%s cause:%d ocause:%d rad:%s cad:%s\n", bc->channel, stack->nt?"NT":"TE", bc->cause, bc->out_cause, bc->rad, bc->cad);
3126 cb_log(2, stack->port,
3127 " --> info_dad:%s onumplan:%c dnumplan:%c rnumplan:%c cpnnumplan:%c\n",
3129 bc->onumplan>=0?'0'+bc->onumplan:' ',
3130 bc->dnumplan>=0?'0'+bc->dnumplan:' ',