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
15 * \brief Interface to mISDN
16 * \author Christian Richter <crich@beronet.com>
23 #include <mISDNuser/isdn_debug.h>
25 #include "isdn_lib_intern.h"
28 enum event_response_e (*cb_event)(enum event_e event, struct misdn_bchannel *bc, void *user_data);
30 void (*cb_log)(int level, int port, char *tmpl, ...)
31 __attribute__ ((format (printf, 3, 4)));
33 int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len);
37 * Define ARRAY_LEN() because I cannot
38 * #include "asterisk/utils.h"
40 #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
42 #include "asterisk/causes.h"
44 void misdn_join_conf(struct misdn_bchannel *bc, int conf_id);
45 void misdn_split_conf(struct misdn_bchannel *bc, int conf_id);
47 int queue_cleanup_bc(struct misdn_bchannel *bc) ;
49 int misdn_lib_get_l2_up(struct misdn_stack *stack);
51 struct misdn_stack *get_misdn_stack(void);
53 int misdn_lib_port_is_pri(int port)
55 struct misdn_stack *stack=get_misdn_stack();
56 for ( ; stack; stack=stack->next) {
57 if (stack->port == port) {
65 int misdn_lib_port_is_nt(int port)
67 struct misdn_stack *stack=get_misdn_stack();
68 for ( ; stack; stack=stack->next) {
69 if (stack->port == port) {
77 void misdn_make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel)
79 memset (dummybc,0,sizeof(struct misdn_bchannel));
82 dummybc->l3_id = MISDN_ID_DUMMY;
88 dummybc->channel=channel;
91 int misdn_lib_port_block(int port)
93 struct misdn_stack *stack=get_misdn_stack();
94 for ( ; stack; stack=stack->next) {
95 if (stack->port == port) {
104 int misdn_lib_port_unblock(int port)
106 struct misdn_stack *stack=get_misdn_stack();
107 for ( ; stack; stack=stack->next) {
108 if (stack->port == port) {
117 int misdn_lib_is_port_blocked(int port)
119 struct misdn_stack *stack=get_misdn_stack();
120 for ( ; stack; stack=stack->next) {
121 if (stack->port == port) {
122 return stack->blocked;
128 int misdn_lib_is_ptp(int port)
130 struct misdn_stack *stack=get_misdn_stack();
131 for ( ; stack; stack=stack->next) {
132 if (stack->port == port) return stack->ptp;
137 int misdn_lib_get_maxchans(int port)
139 struct misdn_stack *stack=get_misdn_stack();
140 for ( ; stack; stack=stack->next) {
141 if (stack->port == port) {
152 struct misdn_stack *get_stack_by_bc(struct misdn_bchannel *bc)
154 struct misdn_stack *stack = get_misdn_stack();
159 for ( ; stack; stack = stack->next) {
160 if (bc->port == stack->port)
168 void get_show_stack_details(int port, char *buf)
170 struct misdn_stack *stack = get_misdn_stack();
172 for (; stack; stack = stack->next) {
173 if (stack->port == port) {
179 sprintf(buf, "* Port %2d Type %s Prot. %s L2Link %s L1Link:%s Blocked:%d",
181 stack->nt ? "NT" : "TE",
182 stack->ptp ? "PTP" : "PMP",
183 stack->l2link ? "UP " : "DOWN",
184 stack->l1link ? "UP " : "DOWN",
192 static int nt_err_cnt =0 ;
199 static enum global_states global_state=MISDN_INITIALIZING;
202 #include <mISDNuser/net_l2.h>
203 #include <mISDNuser/tone.h>
205 #include <semaphore.h>
209 #include "isdn_lib.h"
213 /*! \brief mISDN device handle returned by mISDN_open() */
215 int midev_nt; /* Not used */
217 pthread_t event_thread;
218 pthread_t event_handler_thread;
223 msg_queue_t activatequeue;
227 struct misdn_stack *stack_list;
231 #define ECHOCAN_ON 123
232 #define ECHOCAN_OFF 124
235 #define MISDN_DEBUG 0
237 void misdn_tx_jitter(struct misdn_bchannel *bc, int len);
239 struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id);
241 int setup_bc(struct misdn_bchannel *bc);
243 int manager_isdn_handler(iframe_t *frm ,msg_t *msg);
245 int misdn_lib_port_restart(int port);
246 int misdn_lib_pid_restart(int pid);
248 extern struct isdn_msg msgs_g[];
250 #define ISDN_PID_L3_B_USER 0x430000ff
251 #define ISDN_PID_L4_B_USER 0x440000ff
253 /* #define MISDN_IBUF_SIZE 1024 */
254 #define MISDN_IBUF_SIZE 512
256 /* Fine Tuning of Inband Signalling time */
257 #define TONE_ALERT_CNT 41 /* 1 Sec */
258 #define TONE_ALERT_SILENCE_CNT 200 /* 4 Sec */
260 #define TONE_BUSY_CNT 20 /* ? */
261 #define TONE_BUSY_SILENCE_CNT 48 /* ? */
265 static struct misdn_lib *glob_mgr;
267 static char tone_425_flip[TONE_425_SIZE];
268 static char tone_silence_flip[TONE_SILENCE_SIZE];
270 static void misdn_lib_isdn_event_catcher(void *arg);
271 static int handle_event_nt(void *dat, void *arg);
274 void stack_holder_add(struct misdn_stack *stack, struct misdn_bchannel *holder);
275 void stack_holder_remove(struct misdn_stack *stack, struct misdn_bchannel *holder);
276 struct misdn_bchannel *stack_holder_find(struct misdn_stack *stack, unsigned long l3id);
278 /* from isdn_lib.h */
280 void te_lib_destroy(int midev) ;
281 struct misdn_bchannel *manager_find_bc_by_pid(int pid);
282 void manager_ph_control_block(struct misdn_bchannel *bc, int c1, void *c2, int c2_len);
283 void manager_clean_bc(struct misdn_bchannel *bc );
284 void manager_bchannel_setup (struct misdn_bchannel *bc);
285 void manager_bchannel_cleanup (struct misdn_bchannel *bc);
287 void ec_chunk( struct misdn_bchannel *bc, unsigned char *rxchunk, unsigned char *txchunk, int chunk_size);
289 int bchdev_echocancel_activate(struct misdn_bchannel* dev);
290 void bchdev_echocancel_deactivate(struct misdn_bchannel* dev);
294 static char *bearer2str(int cap) {
295 static char *bearers[]={
304 case INFO_CAPABILITY_SPEECH:
307 case INFO_CAPABILITY_AUDIO_3_1K:
310 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
313 case INFO_CAPABILITY_DIGITAL_RESTRICTED:
323 static char flip_table[256];
325 static void init_flip_bits(void)
329 for (i = 0 ; i < 256 ; i++) {
330 unsigned char sample = 0 ;
331 for (k = 0; k<8; k++) {
332 if ( i & 1 << k ) sample |= 0x80 >> k;
334 flip_table[i] = sample;
338 static char * flip_buf_bits ( char * buf , int len)
343 for (i = 0 ; i < len; i++) {
344 buf[i] = flip_table[(unsigned char)buf[i]];
353 static msg_t *create_l2msg(int prim, int dinfo, int size) /* NT only */
360 dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
365 printf("cannot allocate memory, trying again...\n");
369 printf("cannot allocate memory, system overloaded.\n");
375 msg_t *create_l3msg(int prim, int mt, int dinfo, int size, int ntmode)
383 size = sizeof(Q931_info_t)+2;
387 dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
392 dmsg = alloc_msg(size+256+mISDN_HEADER_LEN+DEFAULT_HEADROOM);
395 memset(msg_put(dmsg,size+mISDN_HEADER_LEN), 0, size+mISDN_HEADER_LEN);
396 frm = (iframe_t *)dmsg->data;
399 qi = (Q931_info_t *)(dmsg->data + mISDN_HEADER_LEN);
405 if (!i) printf("cannot allocate memory, trying again...\n");
409 printf("cannot allocate memory, system overloaded.\n");
414 static int send_msg (int midev, struct misdn_bchannel *bc, msg_t *dmsg)
416 iframe_t *frm = (iframe_t *)dmsg->data;
417 struct misdn_stack *stack=get_stack_by_bc(bc);
420 cb_log(0,bc->port,"send_msg: IEK!! no stack\n ");
424 frm->addr = (stack->upper_id | FLG_MSG_DOWN);
425 frm->dinfo = bc->l3_id;
426 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
428 cb_log(4,stack->port,"Sending msg, prim:%x addr:%x dinfo:%x\n",frm->prim,frm->addr,frm->dinfo);
430 mISDN_write(midev, dmsg->data, dmsg->len, TIMEOUT_1SEC);
440 int misdn_cap_is_speech(int cap)
441 /** Poor mans version **/
443 if ( (cap != INFO_CAPABILITY_DIGITAL_UNRESTRICTED) &&
444 (cap != INFO_CAPABILITY_DIGITAL_RESTRICTED) ) return 1;
448 int misdn_inband_avail(struct misdn_bchannel *bc)
451 if (!bc->early_bconnect) {
452 /* We have opted to never receive any available inband recorded messages */
456 switch (bc->progress_indicator) {
457 case INFO_PI_INBAND_AVAILABLE:
458 case INFO_PI_CALL_NOT_E2E_ISDN:
459 case INFO_PI_CALLED_NOT_ISDN:
468 static void dump_chan_list(struct misdn_stack *stack)
472 for (i = 0; i <= stack->b_num; ++i) {
473 cb_log(6, stack->port, "Idx:%d stack->cchan:%d in_use:%d Chan:%d\n",
474 i, stack->channels[i], stack->bc[i].in_use, i + 1);
476 #if defined(AST_MISDN_ENHANCEMENTS)
477 for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
478 if (stack->bc[i].in_use) {
479 cb_log(6, stack->port, "Idx:%d stack->cchan:%d REGISTER Chan:%d in_use\n",
480 i, stack->channels[i], i + 1);
483 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
487 void misdn_dump_chanlist(void)
489 struct misdn_stack *stack=get_misdn_stack();
490 for ( ; stack; stack=stack->next) {
491 dump_chan_list(stack);
496 static int set_chan_in_stack(struct misdn_stack *stack, int channel)
498 cb_log(4,stack->port,"set_chan_in_stack: %d\n",channel);
499 dump_chan_list(stack);
500 if (1 <= channel && channel <= ARRAY_LEN(stack->channels)) {
501 if (!stack->channels[channel-1])
502 stack->channels[channel-1] = 1;
504 cb_log(4,stack->port,"channel already in use:%d\n", channel );
508 cb_log(0,stack->port,"couldn't set channel %d in\n", channel );
517 static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchannel *bc, int channel, int dec)
523 if (bc->channel_found) {
527 bc->channel_found = 1;
529 #if defined(AST_MISDN_ENHANCEMENTS)
530 if (bc->is_register_pool) {
531 pthread_mutex_lock(&stack->st_lock);
532 for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->channels); ++i) {
533 if (!stack->channels[i]) {
535 cb_log(3, stack->port, " --> found REGISTER chan: %d\n", chan);
540 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
542 cb_log(5, stack->port, "find_free_chan: req_chan:%d\n", channel);
544 if (channel < 0 || channel > MAX_BCHANS) {
545 cb_log(0, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
551 pthread_mutex_lock(&stack->st_lock);
552 bnums = stack->pri ? stack->b_num : stack->b_num - 1;
554 for (i = bnums; i >= 0; --i) {
555 if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 D channel ;) and work with chan preselection */
556 if (!stack->channels[i]) {
558 cb_log(3, stack->port, " --> found chan%s: %d\n", channel >= 0 ? " (preselected)" : "", chan);
564 for (i = 0; i <= bnums; ++i) {
565 if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 D channel ;) and work with chan preselection */
566 if (!stack->channels[i]) {
568 cb_log(3, stack->port, " --> found chan%s: %d\n", channel >= 0 ? " (preselected)" : "", chan);
577 pthread_mutex_unlock(&stack->st_lock);
578 cb_log(1, stack->port, " !! NO FREE CHAN IN STACK\n");
579 dump_chan_list(stack);
580 bc->out_cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
584 if (set_chan_in_stack(stack, chan) < 0) {
585 pthread_mutex_unlock(&stack->st_lock);
586 cb_log(0, stack->port, "Channel Already in use:%d\n", chan);
587 bc->out_cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
590 pthread_mutex_unlock(&stack->st_lock);
598 * \brief Release a B channel to the allocation pool.
600 * \param stack Which port stack B channel belongs.
601 * \param channel B channel to release. (Range 1-MAX_BCHANS representing B1-Bn)
606 * Must be called after clean_up_bc() to make sure that the media stream is
607 * no longer connected.
609 static void empty_chan_in_stack(struct misdn_stack *stack, int channel)
611 if (channel < 1 || ARRAY_LEN(stack->channels) < channel) {
612 cb_log(0, stack->port, "empty_chan_in_stack: cannot empty channel %d\n", channel);
616 cb_log(4, stack->port, "empty_chan_in_stack: %d\n", channel);
617 stack->channels[channel - 1] = 0;
618 dump_chan_list(stack);
621 char *bc_state2str(enum bchannel_state state) {
624 struct bchan_state_s {
626 enum bchannel_state s;
628 {"BCHAN_CLEANED", BCHAN_CLEANED },
629 {"BCHAN_EMPTY", BCHAN_EMPTY},
630 {"BCHAN_SETUP", BCHAN_SETUP},
631 {"BCHAN_SETUPED", BCHAN_SETUPED},
632 {"BCHAN_ACTIVE", BCHAN_ACTIVE},
633 {"BCHAN_ACTIVATED", BCHAN_ACTIVATED},
634 {"BCHAN_BRIDGE", BCHAN_BRIDGE},
635 {"BCHAN_BRIDGED", BCHAN_BRIDGED},
636 {"BCHAN_RELEASE", BCHAN_RELEASE},
637 {"BCHAN_RELEASED", BCHAN_RELEASED},
638 {"BCHAN_CLEAN", BCHAN_CLEAN},
639 {"BCHAN_CLEAN_REQUEST", BCHAN_CLEAN_REQUEST},
640 {"BCHAN_ERROR", BCHAN_ERROR}
643 for (i=0; i< sizeof(states)/sizeof(struct bchan_state_s); i++)
644 if ( states[i].s == state)
650 void bc_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
652 cb_log(5,bc->port,"BC_STATE_CHANGE: l3id:%x from:%s to:%s\n",
654 bc_state2str(bc->bc_state),
655 bc_state2str(state) );
658 case BCHAN_ACTIVATED:
659 if (bc->next_bc_state == BCHAN_BRIDGED) {
660 misdn_join_conf(bc, bc->conf_id);
661 bc->next_bc_state = BCHAN_EMPTY;
670 static void bc_next_state_change(struct misdn_bchannel *bc, enum bchannel_state state)
672 cb_log(5,bc->port,"BC_NEXT_STATE_CHANGE: from:%s to:%s\n",
673 bc_state2str(bc->next_bc_state),
674 bc_state2str(state) );
676 bc->next_bc_state=state;
681 * \brief Empty the B channel record of most call data.
683 * \param bc B channel record to empty of most call data.
688 * Sets the last_used time and must be called before clearing bc->in_use.
690 static void empty_bc(struct misdn_bchannel *bc)
692 bc->caller.presentation = 0; /* allowed */
693 bc->caller.number_plan = NUMPLAN_ISDN;
694 bc->caller.number_type = NUMTYPE_UNKNOWN;
695 bc->caller.name[0] = 0;
696 bc->caller.number[0] = 0;
697 bc->caller.subaddress[0] = 0;
699 bc->connected.presentation = 0; /* allowed */
700 bc->connected.number_plan = NUMPLAN_ISDN;
701 bc->connected.number_type = NUMTYPE_UNKNOWN;
702 bc->connected.name[0] = 0;
703 bc->connected.number[0] = 0;
704 bc->connected.subaddress[0] = 0;
706 bc->redirecting.from.presentation = 0; /* allowed */
707 bc->redirecting.from.number_plan = NUMPLAN_ISDN;
708 bc->redirecting.from.number_type = NUMTYPE_UNKNOWN;
709 bc->redirecting.from.name[0] = 0;
710 bc->redirecting.from.number[0] = 0;
711 bc->redirecting.from.subaddress[0] = 0;
713 bc->redirecting.to.presentation = 0; /* allowed */
714 bc->redirecting.to.number_plan = NUMPLAN_ISDN;
715 bc->redirecting.to.number_type = NUMTYPE_UNKNOWN;
716 bc->redirecting.to.name[0] = 0;
717 bc->redirecting.to.number[0] = 0;
718 bc->redirecting.to.subaddress[0] = 0;
720 bc->redirecting.reason = mISDN_REDIRECTING_REASON_UNKNOWN;
721 bc->redirecting.count = 0;
722 bc->redirecting.to_changed = 0;
733 bc->sending_complete = 0;
735 bc->restart_channel=0;
739 bc->need_more_infos = 0;
751 bc->curptx=0; bc->curprx=0;
753 bc->crypt_key[0] = 0;
760 bc->early_bconnect = 1;
766 bc->ec_deftaps = 128;
769 bc->AOCD_need_export = 0;
773 bc->cause = AST_CAUSE_NORMAL_CLEARING;
774 bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
776 bc->display_connected = 0; /* none */
777 bc->display_setup = 0; /* none */
779 bc->outgoing_colp = 0;/* pass */
781 bc->presentation = 0; /* allowed */
782 bc->set_presentation = 0;
784 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
786 bc->evq=EVENT_NOTHING;
788 bc->progress_coding=0;
789 bc->progress_location=0;
790 bc->progress_indicator=0;
792 #if defined(AST_MISDN_ENHANCEMENTS)
793 bc->div_leg_3_rx_wanted = 0;
794 bc->div_leg_3_tx_pending = 0;
795 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
797 /** Set Default Bearer Caps **/
798 bc->capability=INFO_CAPABILITY_SPEECH;
799 bc->law=INFO_CODEC_ALAW;
807 bc->dialed.number_plan = NUMPLAN_ISDN;
808 bc->dialed.number_type = NUMTYPE_UNKNOWN;
809 bc->dialed.number[0] = 0;
810 bc->dialed.subaddress[0] = 0;
814 bc->infos_pending[0] = 0;
818 bc->fac_in.Function = Fac_None;
819 bc->fac_out.Function = Fac_None;
821 bc->te_choose_channel = 0;
822 bc->channel_found= 0;
824 gettimeofday(&bc->last_used, NULL);
828 static int clean_up_bc(struct misdn_bchannel *bc)
831 unsigned char buff[32];
832 struct misdn_stack * stack;
834 cb_log(3, bc?bc->port:0, "$$$ CLEANUP CALLED pid:%d\n", bc?bc->pid:-1);
837 stack=get_stack_by_bc(bc);
839 if (!stack) return -1;
841 switch (bc->bc_state ) {
843 cb_log(5, stack->port, "$$$ Already cleaned up bc with stid :%x\n", bc->b_stid);
850 cb_log(2, stack->port, "$$$ Cleaning up bc with stid :%x pid:%d\n", bc->b_stid, bc->pid);
852 manager_ec_disable(bc);
854 manager_bchannel_deactivate(bc);
856 mISDN_write_frame(stack->midev, buff, bc->layer_id|FLG_MSG_TARGET|FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
859 bc_state_change(bc, BCHAN_CLEANED);
866 static void clear_l3(struct misdn_stack *stack)
870 if (global_state == MISDN_INITIALIZED) {
871 for (i = 0; i <= stack->b_num; ++i) {
872 cb_event(EVENT_CLEANUP, &stack->bc[i], NULL);
873 empty_bc(&stack->bc[i]);
874 clean_up_bc(&stack->bc[i]);
875 empty_chan_in_stack(stack, i + 1);
876 stack->bc[i].in_use = 0;
878 #if defined(AST_MISDN_ENHANCEMENTS)
879 for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
880 empty_bc(&stack->bc[i]);
881 empty_chan_in_stack(stack, i + 1);
882 stack->bc[i].in_use = 0;
884 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
888 static int new_te_id = 0;
890 static int misdn_lib_get_l1_down(struct misdn_stack *stack)
894 act.prim = PH_DEACTIVATE | REQUEST;
895 act.addr = stack->lower_id|FLG_MSG_DOWN;
899 cb_log(1, stack->port, "SENDING PH_DEACTIVATE | REQ\n");
900 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
904 static int misdn_lib_get_l2_down(struct misdn_stack *stack)
907 if (stack->ptp && (stack->nt) ) {
910 dmsg = create_l2msg(DL_RELEASE| REQUEST, 0, 0);
912 pthread_mutex_lock(&stack->nstlock);
913 if (stack->nst.manager_l3(&stack->nst, dmsg))
915 pthread_mutex_unlock(&stack->nstlock);
919 act.prim = DL_RELEASE| REQUEST;
920 act.addr = (stack->upper_id |FLG_MSG_DOWN) ;
924 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
931 static int misdn_lib_get_l1_up(struct misdn_stack *stack)
935 act.prim = PH_ACTIVATE | REQUEST;
936 act.addr = (stack->upper_id | FLG_MSG_DOWN) ;
942 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
946 int misdn_lib_get_l2_up(struct misdn_stack *stack)
949 if (stack->ptp && (stack->nt) ) {
952 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
954 pthread_mutex_lock(&stack->nstlock);
955 if (stack->nst.manager_l3(&stack->nst, dmsg))
957 pthread_mutex_unlock(&stack->nstlock);
961 act.prim = DL_ESTABLISH | REQUEST;
962 act.addr = (stack->upper_id |FLG_MSG_DOWN) ;
966 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
973 static int misdn_lib_get_l2_te_ptp_up(struct misdn_stack *stack)
977 act.prim = DL_ESTABLISH | REQUEST;
978 act.addr = (stack->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
982 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
987 static int misdn_lib_get_short_status(struct misdn_stack *stack)
992 act.prim = MGR_SHORTSTATUS | REQUEST;
994 act.addr = (stack->upper_id | MSG_BROADCAST) ;
996 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
999 return mISDN_write(stack->midev, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1004 static int create_process(int midev, struct misdn_bchannel *bc)
1009 struct misdn_stack *stack;
1011 stack = get_stack_by_bc(bc);
1013 if (find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0, 0) < 0) {
1016 cb_log(4, stack->port, " --> found channel: %d\n", bc->channel);
1018 for (proc_id = 0; proc_id < MAXPROCS; ++proc_id) {
1019 if (stack->procids[proc_id] == 0) {
1023 if (proc_id == MAXPROCS) {
1024 cb_log(0, stack->port, "Couldn't Create New ProcId.\n");
1028 stack->procids[proc_id] = 1;
1030 l3_id = 0xff00 | proc_id;
1032 cb_log(3, stack->port, " --> new_l3id %x\n", l3_id);
1034 if ((stack->pri && stack->ptp) || bc->te_choose_channel) {
1035 /* we know exactly which channels are in use */
1036 if (find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0, bc->dec) < 0) {
1039 cb_log(2, stack->port, " --> found channel: %d\n", bc->channel);
1041 /* other phones could have made a call also on this port (ptmp) */
1045 /* if we are in te-mode, we need to create a process first */
1046 if (++new_te_id > 0xffff) {
1050 l3_id = (entity << 16) | new_te_id;
1052 cb_log(3, stack->port, "--> new_l3id %x\n", l3_id);
1055 ncr.prim = CC_NEW_CR | REQUEST;
1056 ncr.addr = (stack->upper_id | FLG_MSG_DOWN);
1059 mISDN_write(midev, &ncr, mISDN_HEADER_LEN + ncr.len, TIMEOUT_1SEC);
1066 void misdn_lib_setup_bc(struct misdn_bchannel *bc)
1073 int setup_bc(struct misdn_bchannel *bc)
1075 unsigned char buff[1025];
1083 struct misdn_stack *stack=get_stack_by_bc(bc);
1086 cb_log(0, bc->port, "setup_bc: NO STACK FOUND!!\n");
1090 midev = stack->midev;
1091 channel = bc->channel - 1 - (bc->channel > 16);
1092 b_stid = stack->b_stids[channel >= 0 ? channel : 0];
1094 switch (bc->bc_state) {
1098 cb_log(4, stack->port, "$$$ bc already setup stid :%x (state:%s)\n", b_stid, bc_state2str(bc->bc_state) );
1102 cb_log(5, stack->port, "$$$ Setting up bc with stid :%x\n", b_stid);
1104 /*check if the b_stid is already initialized*/
1105 for (i=0; i <= stack->b_num; i++) {
1106 if (stack->bc[i].b_stid == b_stid) {
1107 cb_log(0, bc->port, "setup_bc: b_stid:%x already in use !!!\n", b_stid);
1113 cb_log(0, stack->port," -- Stid <=0 at the moment in channel:%d\n",channel);
1115 bc_state_change(bc,BCHAN_ERROR);
1119 bc->b_stid = b_stid;
1123 memset(&li, 0, sizeof(li));
1128 li.st = bc->b_stid; /* given idx */
1135 if ( bc->hdlc || bc->nodsp) {
1136 cb_log(4, stack->port,"setup_bc: without dsp\n");
1138 int l = sizeof(li.name);
1139 strncpy(li.name, "B L3", l);
1142 li.pid.layermask = ISDN_LAYER((3));
1143 li.pid.protocol[3] = ISDN_PID_L3_B_USER;
1147 cb_log(4, stack->port,"setup_bc: with dsp\n");
1149 int l = sizeof(li.name);
1150 strncpy(li.name, "B L4", l);
1153 li.pid.layermask = ISDN_LAYER((4));
1154 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
1159 ret = mISDN_new_layer(midev, &li);
1161 cb_log(0, stack->port,"New Layer Err: %d %s\n",ret,strerror(errno));
1163 bc_state_change(bc,BCHAN_ERROR);
1167 bc->layer_id = li.id;
1170 memset(&pid, 0, sizeof(pid));
1174 cb_log(4, stack->port," --> Channel is %d\n", bc->channel);
1176 if (bc->nodsp && !bc->hdlc) {
1177 cb_log(2, stack->port," --> TRANSPARENT Mode (no DSP, no HDLC)\n");
1178 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
1179 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
1180 pid.protocol[3] = ISDN_PID_L3_B_USER;
1181 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3));
1183 } else if ( bc->hdlc ) {
1184 cb_log(2, stack->port," --> HDLC Mode\n");
1185 pid.protocol[1] = ISDN_PID_L1_B_64HDLC ;
1186 pid.protocol[2] = ISDN_PID_L2_B_TRANS ;
1187 pid.protocol[3] = ISDN_PID_L3_B_USER;
1188 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) ;
1190 cb_log(2, stack->port," --> TRANSPARENT Mode\n");
1191 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
1192 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
1193 pid.protocol[3] = ISDN_PID_L3_B_DSP;
1194 pid.protocol[4] = ISDN_PID_L4_B_USER;
1195 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
1199 ret = mISDN_set_stack(midev, bc->b_stid, &pid);
1202 cb_log(0, stack->port,"$$$ Set Stack Err: %d %s\n",ret,strerror(errno));
1204 mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1206 bc_state_change(bc,BCHAN_ERROR);
1207 cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
1211 ret = mISDN_get_setstack_ind(midev, bc->layer_id);
1214 cb_log(0, stack->port,"$$$ Set StackIND Err: %d %s\n",ret,strerror(errno));
1215 mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1217 bc_state_change(bc,BCHAN_ERROR);
1218 cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
1222 ret = mISDN_get_layerid(midev, bc->b_stid, bc->layer) ;
1224 bc->addr = ret>0? ret : 0;
1227 cb_log(0, stack->port,"$$$ Get Layerid Err: %d %s\n",ret,strerror(errno));
1228 mISDN_write_frame(midev, buff, bc->layer_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1230 bc_state_change(bc,BCHAN_ERROR);
1231 cb_event(EVENT_BCHAN_ERROR, bc, glob_mgr->user_data);
1235 manager_bchannel_activate(bc);
1237 bc_state_change(bc,BCHAN_ACTIVATED);
1245 static int init_bc(struct misdn_stack *stack, struct misdn_bchannel *bc, int midev, int port, int bidx)
1251 cb_log(8, port, "Init.BC %d.\n",bidx);
1253 bc->send_lock=malloc(sizeof(struct send_lock));
1254 if (!bc->send_lock) {
1257 pthread_mutex_init(&bc->send_lock->lock, NULL);
1260 bc_state_change(bc, BCHAN_CLEANED);
1262 bc->port=stack->port;
1263 bc->nt=stack->nt?1:0;
1267 ibuffer_t* ibuf= init_ibuffer(MISDN_IBUF_SIZE);
1269 if (!ibuf) return -1;
1271 clear_ibuffer( ibuf);
1273 ibuf->rsem=malloc(sizeof(sem_t));
1280 if (sem_init(ibuf->rsem,1,0)<0)
1281 sem_init(ibuf->rsem,0,0);
1285 #if 0 /* This code does not seem to do anything useful */
1286 if (bidx <= stack->b_num) {
1287 unsigned char buff[1025];
1288 iframe_t *frm = (iframe_t *) buff;
1289 stack_info_t *stinf;
1292 ret = mISDN_get_stack_info(midev, stack->port, buff, sizeof(buff));
1294 cb_log(0, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
1298 stinf = (stack_info_t *)&frm->data.p;
1300 cb_log(8, port, " --> Child %x\n",stinf->child[bidx]);
1309 static struct misdn_stack *stack_init(int midev, int port, int ptp)
1312 unsigned char buff[1025];
1313 iframe_t *frm = (iframe_t *)buff;
1314 stack_info_t *stinf;
1315 struct misdn_stack *stack;
1319 stack = calloc(1, sizeof(struct misdn_stack));
1324 cb_log(8, port, "Init. Stack.\n");
1330 stack->holding=NULL;
1333 msg_queue_init(&stack->downqueue);
1334 msg_queue_init(&stack->upqueue);
1336 pthread_mutex_init(&stack->st_lock, NULL);
1338 /* query port's requirements */
1339 ret = mISDN_get_stack_info(midev, port, buff, sizeof(buff));
1341 cb_log(0, port, "%s: Cannot get stack info for this port. (ret=%d)\n", __FUNCTION__, ret);
1345 stinf = (stack_info_t *)&frm->data.p;
1347 stack->d_stid = stinf->id;
1348 stack->b_num = stinf->childcnt;
1350 for (i=0; i<=stinf->childcnt; i++)
1351 stack->b_stids[i] = stinf->child[i];
1353 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK) {
1354 case ISDN_PID_L0_TE_S0:
1357 case ISDN_PID_L0_NT_S0:
1358 cb_log(8, port, "NT Stack\n");
1362 case ISDN_PID_L0_TE_E1:
1363 cb_log(8, port, "TE S2M Stack\n");
1367 case ISDN_PID_L0_NT_E1:
1368 cb_log(8, port, "TE S2M Stack\n");
1374 cb_log(0, port, "this is a unknown port type 0x%08x\n", stinf->pid.protocol[0]);
1379 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP ) {
1390 cb_log(8, port, "Init. Stack.\n");
1392 memset(&li, 0, sizeof(li));
1394 int l = sizeof(li.name);
1395 strncpy(li.name,nt?"net l2":"user l4", l);
1400 li.pid.protocol[nt?2:4] = nt?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
1401 li.pid.layermask = ISDN_LAYER((nt?2:4));
1402 li.st = stack->d_stid;
1405 ret = mISDN_new_layer(midev, &li);
1407 cb_log(0, port, "%s: Cannot add layer %d to this port.\n", __FUNCTION__, nt?2:4);
1412 stack->upper_id = li.id;
1413 ret = mISDN_register_layer(midev, stack->d_stid, stack->upper_id);
1416 cb_log(0,port,"Cannot register layer %d of this port.\n", nt?2:4);
1420 stack->lower_id = mISDN_get_layerid(midev, stack->d_stid, nt?1:3);
1421 if (stack->lower_id < 0) {
1422 cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, nt?1:3);
1426 stack->upper_id = mISDN_get_layerid(midev, stack->d_stid, nt?2:4);
1427 if (stack->upper_id < 0) {
1428 cb_log(0, port, "%s: Cannot get layer(%d) id of this port.\n", __FUNCTION__, 2);
1432 cb_log(8, port, "NT Stacks upper_id %x\n",stack->upper_id);
1435 /* create nst (nt-mode only) */
1438 memset(&stack->nst, 0, sizeof(net_stack_t));
1439 memset(&stack->mgr, 0, sizeof(manager_t));
1441 stack->mgr.nst = &stack->nst;
1442 stack->nst.manager = &stack->mgr;
1444 stack->nst.l3_manager = handle_event_nt;
1445 stack->nst.device = midev;
1446 stack->nst.cardnr = port;
1447 stack->nst.d_stid = stack->d_stid;
1449 stack->nst.feature = FEATURE_NET_HOLD;
1451 stack->nst.feature |= FEATURE_NET_PTP;
1453 stack->nst.feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
1455 stack->nst.l1_id = stack->lower_id;
1456 stack->nst.l2_id = stack->upper_id;
1458 msg_queue_init(&stack->nst.down_queue);
1459 pthread_mutex_init(&stack->nstlock, NULL);
1461 Isdnl2Init(&stack->nst);
1462 Isdnl3Init(&stack->nst);
1470 misdn_lib_get_short_status(stack);
1472 misdn_lib_get_l1_up(stack);
1473 if (!stack->ptp) misdn_lib_get_l1_up(stack);
1474 misdn_lib_get_l2_up(stack);
1478 misdn_lib_get_short_status(stack);
1479 misdn_lib_get_l1_up(stack);
1480 misdn_lib_get_l2_up(stack);
1484 cb_log(8,0,"stack_init: port:%d lowerId:%x upperId:%x\n",stack->port,stack->lower_id, stack->upper_id);
1490 static void stack_destroy(struct misdn_stack *stack)
1496 pthread_mutex_destroy(&stack->nstlock);
1497 cleanup_Isdnl2(&stack->nst);
1498 cleanup_Isdnl3(&stack->nst);
1501 if (stack->lower_id)
1502 mISDN_write_frame(stack->midev, buf, stack->lower_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1504 if (stack->upper_id)
1505 mISDN_write_frame(stack->midev, buf, stack->upper_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1507 pthread_mutex_destroy(&stack->st_lock);
1511 static struct misdn_stack * find_stack_by_addr(int addr)
1513 struct misdn_stack *stack;
1515 for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
1516 if ((stack->upper_id & STACK_ID_MASK) == (addr & STACK_ID_MASK)) {
1517 /* Found the stack */
1526 static struct misdn_stack *find_stack_by_port(int port)
1528 struct misdn_stack *stack;
1530 for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
1531 if (stack->port == port) {
1532 /* Found the stack */
1540 static struct misdn_stack *find_stack_by_mgr(manager_t *mgr_nt)
1542 struct misdn_stack *stack;
1544 for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
1545 if (&stack->mgr == mgr_nt) {
1546 /* Found the stack */
1554 static struct misdn_bchannel *find_bc_by_masked_l3id(struct misdn_stack *stack, unsigned long l3id, unsigned long mask)
1558 for (i = 0; i <= stack->b_num; ++i) {
1559 if (stack->bc[i].in_use && (stack->bc[i].l3_id & mask) == (l3id & mask)) {
1560 return &stack->bc[i];
1563 #if defined(AST_MISDN_ENHANCEMENTS)
1564 /* Search the B channel records for a REGISTER signaling link. */
1565 for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
1566 if (stack->bc[i].in_use && (stack->bc[i].l3_id & mask) == (l3id & mask)) {
1567 return &stack->bc[i];
1570 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
1571 return stack_holder_find(stack, l3id);
1575 struct misdn_bchannel *find_bc_by_l3id(struct misdn_stack *stack, unsigned long l3id)
1579 for (i = 0; i <= stack->b_num; ++i) {
1580 if (stack->bc[i].in_use && stack->bc[i].l3_id == l3id) {
1581 return &stack->bc[i];
1584 #if defined(AST_MISDN_ENHANCEMENTS)
1585 /* Search the B channel records for a REGISTER signaling link. */
1586 for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
1587 if (stack->bc[i].in_use && stack->bc[i].l3_id == l3id) {
1588 return &stack->bc[i];
1591 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
1592 return stack_holder_find(stack, l3id);
1595 static struct misdn_bchannel *find_bc_by_addr(unsigned long addr)
1597 struct misdn_stack *stack;
1600 for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
1601 for (i = 0; i <= stack->b_num; i++) {
1602 if (stack->bc[i].in_use
1603 && ((stack->bc[i].addr & STACK_ID_MASK) == (addr & STACK_ID_MASK)
1604 || stack->bc[i].layer_id == addr)) {
1605 return &stack->bc[i];
1613 static struct misdn_bchannel *find_bc_by_confid(unsigned long confid)
1615 struct misdn_stack *stack;
1618 for (stack = glob_mgr->stack_list; stack; stack = stack->next) {
1619 for (i = 0; i <= stack->b_num; i++) {
1620 if (stack->bc[i].in_use && stack->bc[i].conf_id == confid) {
1621 return &stack->bc[i];
1629 static struct misdn_bchannel *find_bc_by_channel(int port, int channel)
1631 struct misdn_stack *stack = find_stack_by_port(port);
1638 for (i = 0; i <= stack->b_num; i++) {
1639 if (stack->bc[i].in_use && stack->bc[i].channel == channel) {
1640 return &stack->bc[i];
1651 static int handle_event ( struct misdn_bchannel *bc, enum event_e event, iframe_t *frm)
1653 struct misdn_stack *stack=get_stack_by_bc(bc);
1659 case EVENT_CONNECT_ACKNOWLEDGE:
1662 if ( *bc->crypt_key ) {
1663 cb_log(4, stack->port,
1664 "ENABLING BLOWFISH channel:%d caller%d:\"%s\" <%s> dialed%d:%s\n",
1666 bc->caller.number_type,
1669 bc->dialed.number_type,
1671 manager_ph_control_block(bc, BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
1674 if (misdn_cap_is_speech(bc->capability)) {
1675 if ( !bc->nodsp) manager_ph_control(bc, DTMF_TONE_START, 0);
1676 manager_ec_enable(bc);
1678 if ( bc->txgain != 0 ) {
1679 cb_log(4, stack->port, "--> Changing txgain to %d\n", bc->txgain);
1680 manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
1682 if ( bc->rxgain != 0 ) {
1683 cb_log(4, stack->port, "--> Changing rxgain to %d\n", bc->rxgain);
1684 manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
1691 if ( *bc->crypt_key ) {
1692 cb_log(4, stack->port,
1693 "ENABLING BLOWFISH channel:%d caller%d:\"%s\" <%s> dialed%d:%s\n",
1695 bc->caller.number_type,
1698 bc->dialed.number_type,
1700 manager_ph_control_block(bc, BF_ENABLE_KEY, bc->crypt_key, strlen(bc->crypt_key) );
1702 case EVENT_ALERTING:
1703 case EVENT_PROGRESS:
1704 case EVENT_PROCEEDING:
1705 case EVENT_SETUP_ACKNOWLEDGE:
1708 if (bc->channel == 0xff || bc->channel<=0)
1711 if (find_free_chan_in_stack(stack, bc, bc->channel, 0)<0){
1712 if (!stack->pri && !stack->ptp) {
1718 cb_log(0, stack->port, "Any Channel Requested, but we have no more!!\n");
1720 cb_log(0, stack->port,
1721 "Requested Channel Already in Use releasing this call with cause %d!!!!\n",
1725 /* when the channel is already in use, we can't
1726 * simply clear it, we need to make sure that
1727 * it will still be marked as in_use in the
1728 * available channels list.*/
1731 misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
1739 case EVENT_RELEASE_COMPLETE:
1745 } else { /** NT MODE **/
1751 static int handle_cr ( struct misdn_stack *stack, iframe_t *frm)
1753 struct misdn_bchannel dummybc;
1754 struct misdn_bchannel *bc;
1757 if (!stack) return -1;
1759 switch (frm->prim) {
1760 case CC_NEW_CR|INDICATION:
1761 cb_log(7, stack->port, " --> lib: NEW_CR Ind with l3id:%x on this port.\n",frm->dinfo);
1763 bc = misdn_lib_get_free_bc(stack->port, 0, 1, 0);
1765 cb_log(0, stack->port, " --> !! lib: No free channel!\n");
1769 cb_log(7, stack->port, " --> new_process: New L3Id: %x\n",frm->dinfo);
1770 bc->l3_id=frm->dinfo;
1772 case CC_NEW_CR|CONFIRM:
1774 case CC_NEW_CR|REQUEST:
1776 case CC_RELEASE_CR|REQUEST:
1778 case CC_RELEASE_CR|CONFIRM:
1780 case CC_RELEASE_CR|INDICATION:
1781 cb_log(4, stack->port, " --> lib: RELEASE_CR Ind with l3id:%x\n", frm->dinfo);
1782 bc = find_bc_by_l3id(stack, frm->dinfo);
1784 cb_log(4, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
1785 misdn_make_dummy(&dummybc, stack->port, frm->dinfo, stack->nt, 0);
1789 channel = bc->channel;
1790 cb_log(4, stack->port, " --> lib: CLEANING UP l3id: %x\n", frm->dinfo);
1793 bc->need_disconnect = 0;
1794 bc->need_release = 0;
1795 bc->need_release_complete = 0;
1797 cb_event(EVENT_CLEANUP, bc, glob_mgr->user_data);
1803 empty_chan_in_stack(stack, channel);
1806 dump_chan_list(stack);
1808 if (bc->stack_holder) {
1809 cb_log(4, stack->port, "REMOVING Holder\n");
1810 stack_holder_remove(stack, bc);
1823 /* Empties bc if it's reserved (no SETUP out yet) */
1824 void misdn_lib_release(struct misdn_bchannel *bc)
1827 struct misdn_stack *stack=get_stack_by_bc(bc);
1830 cb_log(1,0,"misdn_release: No Stack found\n");
1834 channel = bc->channel;
1838 empty_chan_in_stack(stack, channel);
1846 int misdn_lib_get_port_up (int port)
1848 struct misdn_stack *stack;
1850 for (stack=glob_mgr->stack_list;
1852 stack=stack->next) {
1854 if (stack->port == port) {
1857 misdn_lib_get_l1_up(stack);
1859 misdn_lib_get_l2_up(stack);
1868 int misdn_lib_get_port_down (int port)
1869 { /* Pull Down L1 */
1870 struct misdn_stack *stack;
1871 for (stack=glob_mgr->stack_list;
1873 stack=stack->next) {
1874 if (stack->port == port) {
1876 misdn_lib_get_l2_down(stack);
1877 misdn_lib_get_l1_down(stack);
1884 int misdn_lib_port_up(int port, int check)
1886 struct misdn_stack *stack;
1889 for (stack=glob_mgr->stack_list;
1891 stack=stack->next) {
1893 if (stack->port == port) {
1895 if (stack->blocked) {
1896 cb_log(0,port, "Port Blocked:%d L2:%d L1:%d\n", stack->blocked, stack->l2link, stack->l1link);
1902 if (stack->l1link && stack->l2link) {
1905 cb_log(1,port, "Port Down L2:%d L1:%d\n",
1906 stack->l2link, stack->l1link);
1910 if ( !check || stack->l1link )
1913 cb_log(1,port, "Port down PMP\n");
1924 static int release_cr(struct misdn_stack *stack, mISDNuser_head_t *hh)
1926 struct misdn_bchannel *bc=find_bc_by_l3id(stack, hh->dinfo);
1927 struct misdn_bchannel dummybc;
1928 iframe_t frm; /* fake te frm to remove callref from global callreflist */
1930 frm.dinfo = hh->dinfo;
1931 frm.addr=stack->upper_id | FLG_MSG_DOWN;
1932 frm.prim = CC_RELEASE_CR|INDICATION;
1933 cb_log(4, stack->port, " --> CC_RELEASE_CR: Faking Release_cr for %x l3id:%x\n",frm.addr, frm.dinfo);
1935 /** removing procid **/
1937 cb_log(4, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x) on this port.\n", hh->dinfo);
1938 misdn_make_dummy(&dummybc, stack->port, hh->dinfo, stack->nt, 0);
1942 if ((bc->l3_id & 0xff00) == 0xff00) {
1943 cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", bc->l3_id & 0xff);
1944 stack->procids[bc->l3_id & 0xff] = 0;
1947 if (handle_cr(stack, &frm)<0) {
1953 static int handle_event_nt(void *dat, void *arg)
1955 struct misdn_bchannel dummybc;
1956 struct misdn_bchannel *bc;
1957 manager_t *mgr = (manager_t *)dat;
1958 msg_t *msg = (msg_t *)arg;
1960 mISDNuser_head_t *hh;
1961 struct misdn_stack *stack;
1971 stack = find_stack_by_mgr(mgr);
1972 hh=(mISDNuser_head_t*)msg->data;
1975 * When we are called from the mISDNuser lib, the nstlock is held and it
1976 * must be held when we return. We unlock here because the lib may be
1977 * entered again recursively.
1979 pthread_mutex_unlock(&stack->nstlock);
1981 cb_log(5, stack->port, " --> lib: prim %x dinfo %x\n",hh->prim, hh->dinfo);
1983 case CC_RETRIEVE|INDICATION:
1985 struct misdn_bchannel *hold_bc;
1986 iframe_t frm; /* fake te frm to add callref to global callreflist */
1988 frm.dinfo = hh->dinfo;
1989 frm.addr=stack->upper_id | FLG_MSG_DOWN;
1990 frm.prim = CC_NEW_CR|INDICATION;
1991 if (handle_cr( stack, &frm)< 0) {
1992 goto ERR_NO_CHANNEL;
1995 bc = find_bc_by_l3id(stack, hh->dinfo);
1996 hold_bc = stack_holder_find(stack, bc->l3_id);
1997 cb_log(4, stack->port, "bc_l3id:%x holded_bc_l3id:%x\n",bc->l3_id, hold_bc->l3_id);
2000 cb_log(4, stack->port, "REMOVING Holder\n");
2002 /* swap the backup to our new channel back */
2003 stack_holder_remove(stack, hold_bc);
2004 memcpy(bc, hold_bc, sizeof(*bc));
2013 case CC_SETUP | CONFIRM:
2014 l3id = *((int *) (msg->data + mISDNUSER_HEAD_SIZE));
2016 cb_log(4, stack->port, " --> lib: Event_ind:SETUP CONFIRM [NT] : new L3ID is %x\n", l3id);
2018 bc = find_bc_by_l3id(stack, hh->dinfo);
2020 cb_log (2, bc->port, "I IND :CC_SETUP|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
2022 cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
2024 cb_log(4, stack->port, "Bc Not found (after SETUP CONFIRM)\n");
2027 pthread_mutex_lock(&stack->nstlock);
2030 case CC_SETUP | INDICATION:
2031 bc = misdn_lib_get_free_bc(stack->port, 0, 1, 0);
2033 goto ERR_NO_CHANNEL;
2036 cb_log(4, stack->port, " --> new_process: New L3Id: %x\n",hh->dinfo);
2037 bc->l3_id=hh->dinfo;
2040 #if defined(AST_MISDN_ENHANCEMENTS)
2041 case CC_REGISTER | CONFIRM:
2042 l3id = *((int *) (msg->data + mISDNUSER_HEAD_SIZE));
2044 cb_log(4, stack->port, " --> lib: Event_ind:REGISTER CONFIRM [NT] : new L3ID is %x\n", l3id);
2046 bc = find_bc_by_l3id(stack, hh->dinfo);
2048 cb_log (2, bc->port, "I IND :CC_REGISTER|CONFIRM: old l3id:%x new l3id:%x\n", bc->l3_id, l3id);
2051 cb_log(4, stack->port, "Bc Not found (after REGISTER CONFIRM)\n");
2054 pthread_mutex_lock(&stack->nstlock);
2056 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
2058 #if defined(AST_MISDN_ENHANCEMENTS)
2059 case CC_REGISTER | INDICATION:
2060 bc = misdn_lib_get_register_bc(stack->port);
2062 goto ERR_NO_CHANNEL;
2065 cb_log(4, stack->port, " --> new_process: New L3Id: %x\n",hh->dinfo);
2066 bc->l3_id=hh->dinfo;
2068 #endif /* defined(AST_MISDN_ENHANCEMENTS) */
2070 case CC_CONNECT_ACKNOWLEDGE|INDICATION:
2073 case CC_ALERTING|INDICATION:
2074 case CC_PROCEEDING|INDICATION:
2075 case CC_SETUP_ACKNOWLEDGE|INDICATION:
2076 case CC_CONNECT|INDICATION:
2078 case CC_DISCONNECT|INDICATION:
2079 bc = find_bc_by_l3id(stack, hh->dinfo);
2081 bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
2083 int myprocid=bc->l3_id&0x0000ffff;
2085 hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
2086 cb_log(3,stack->port,"Reject dinfo: %x cause:%d\n",hh->dinfo,bc->cause);
2092 case CC_FACILITY|INDICATION:
2093 bc = find_bc_by_l3id(stack, hh->dinfo);
2095 bc=find_bc_by_masked_l3id(stack, hh->dinfo, 0xffff0000);
2097 int myprocid=bc->l3_id&0x0000ffff;
2099 hh->dinfo=(hh->dinfo&0xffff0000)|myprocid;
2100 cb_log(4,bc->port,"Repaired reject Bug, new dinfo: %x\n",hh->dinfo);
2105 case CC_RELEASE_COMPLETE|INDICATION:
2108 case CC_SUSPEND|INDICATION:
2109 cb_log(4, stack->port, " --> Got Suspend, sending Reject for now\n");
2110 dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST,MT_SUSPEND_REJECT, hh->dinfo,sizeof(RELEASE_COMPLETE_t), 1);
2111 pthread_mutex_lock(&stack->nstlock);
2112 stack->nst.manager_l3(&stack->nst, dmsg);
2116 case CC_RESUME|INDICATION:
2119 case CC_RELEASE|CONFIRM:
2120 bc = find_bc_by_l3id(stack, hh->dinfo);
2122 cb_log(1, stack->port, "CC_RELEASE|CONFIRM (l3id:%x), sending RELEASE_COMPLETE\n", hh->dinfo);
2123 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
2127 case CC_RELEASE|INDICATION:
2130 case CC_RELEASE_CR|INDICATION:
2131 release_cr(stack, hh);
2133 pthread_mutex_lock(&stack->nstlock);
2136 case CC_NEW_CR|INDICATION:
2137 /* Got New CR for bchan, for now I handle this one in */
2138 /* connect_ack, Need to be changed */
2139 l3id = *((int *) (msg->data + mISDNUSER_HEAD_SIZE));
2141 bc = find_bc_by_l3id(stack, hh->dinfo);
2143 cb_log(0, stack->port, " --> In NEW_CR: didn't found bc ??\n");
2144 pthread_mutex_lock(&stack->nstlock);
2147 if (((l3id&0xff00)!=0xff00) && ((bc->l3_id&0xff00)==0xff00)) {
2148 cb_log(4, stack->port, " --> Removing Process Id:%x on this port.\n", 0xff&bc->l3_id);
2149 stack->procids[bc->l3_id&0xff] = 0 ;
2151 cb_log(4, stack->port, "lib: Event_ind:CC_NEW_CR : very new L3ID is %x\n",l3id );
2154 if (!bc->is_register_pool) {
2155 cb_event(EVENT_NEW_L3ID, bc, glob_mgr->user_data);
2159 pthread_mutex_lock(&stack->nstlock);
2162 case DL_ESTABLISH | INDICATION:
2163 case DL_ESTABLISH | CONFIRM:
2164 cb_log(3, stack->port, "%% GOT L2 Activate Info.\n");
2166 if (stack->ptp && stack->l2link) {
2167 cb_log(0, stack->port, "%% GOT L2 Activate Info. but we're activated already.. this l2 is faulty, blocking port\n");
2168 cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data);
2171 if (stack->ptp && !stack->restart_sent) {
2172 /* make sure we restart the interface of the
2174 stack->restart_sent=1;
2175 misdn_lib_send_restart(stack->port, -1);
2179 /* when we get the L2 UP, the L1 is UP definitely too*/
2184 pthread_mutex_lock(&stack->nstlock);
2187 case DL_RELEASE | INDICATION:
2188 case DL_RELEASE | CONFIRM:
2190 cb_log(3 , stack->port, "%% GOT L2 DeActivate Info.\n");
2192 if (stack->l2upcnt>3) {
2193 cb_log(0 , stack->port, "!!! Could not Get the L2 up after 3 Attempts!!!\n");
2197 misdn_lib_reinit_nt_stack(stack->port);
2199 if (stack->l1link) {
2200 misdn_lib_get_l2_up(stack);
2206 cb_log(3, stack->port, "%% GOT L2 DeActivate Info.\n");
2210 pthread_mutex_lock(&stack->nstlock);
2217 /* Parse Events and fire_up to App. */
2218 event = isdn_msg_get_event(msgs_g, msg, 1);
2220 bc = find_bc_by_l3id(stack, hh->dinfo);
2222 cb_log(4, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x).\n", hh->dinfo);
2223 misdn_make_dummy(&dummybc, stack->port, hh->dinfo, stack->nt, 0);
2227 isdn_msg_parse_event(msgs_g, msg, bc, 1);
2231 if (bc->channel <= 0 || bc->channel == 0xff) {
2235 if (find_free_chan_in_stack(stack, bc, bc->channel, 0) < 0) {
2236 goto ERR_NO_CHANNEL;
2240 case EVENT_RELEASE_COMPLETE:
2241 channel = bc->channel;
2242 tmpcause = bc->cause;
2245 bc->cause = tmpcause;
2249 empty_chan_in_stack(stack, channel);
2256 if(!isdn_get_info(msgs_g, event, 1)) {
2257 cb_log(4, stack->port, "Unknown Event Ind: prim %x dinfo %x\n", hh->prim, hh->dinfo);
2261 case AST_CAUSE_USER_BUSY:
2262 cb_log(1, stack->port, "Siemens Busy reject..\n");
2268 cb_event(event, bc, glob_mgr->user_data);
2272 pthread_mutex_lock(&stack->nstlock);
2276 cb_log(4, stack->port, "Patch from MEIDANIS:Sending RELEASE_COMPLETE %x (No free Chan for you..)\n", hh->dinfo);
2277 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, hh->dinfo, sizeof(RELEASE_COMPLETE_t), 1);
2278 pthread_mutex_lock(&stack->nstlock);
2279 stack->nst.manager_l3(&stack->nst, dmsg);
2285 static int handle_timers(msg_t* msg)
2287 iframe_t *frm= (iframe_t*)msg->data;
2288 struct misdn_stack *stack;
2291 switch (frm->prim) {
2292 case MGR_INITTIMER | CONFIRM:
2293 case MGR_ADDTIMER | CONFIRM:
2294 case MGR_DELTIMER | CONFIRM:
2295 case MGR_REMOVETIMER | CONFIRM:
2302 if (frm->prim==(MGR_TIMER | INDICATION) ) {
2303 for (stack = glob_mgr->stack_list;
2305 stack = stack->next) {
2308 if (!stack->nt) continue;
2310 it = stack->nst.tlist;
2312 for(it=stack->nst.tlist;
2315 if (it->id == (int)frm->addr)
2320 ret = mISDN_write_frame(stack->midev, msg->data, frm->addr,
2321 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2322 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2323 pthread_mutex_lock(&stack->nstlock);
2324 ret = it->function(it->data);
2325 pthread_mutex_unlock(&stack->nstlock);
2331 cb_log(0, 0, "Timer Msg without Timer ??\n");
2341 void misdn_lib_tone_generator_start(struct misdn_bchannel *bc)
2343 bc->generate_tone=1;
2346 void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
2348 bc->generate_tone=0;
2352 static int do_tone(struct misdn_bchannel *bc, int len)
2356 if (bc->generate_tone) {
2357 cb_event(EVENT_TONE_GENERATE, bc, glob_mgr->user_data);
2359 if ( !bc->nojitter ) {
2360 misdn_tx_jitter(bc,len);
2370 #ifdef MISDN_SAVE_DATA
2371 static void misdn_save_data(int id, char *p1, int l1, char *p2, int l2)
2376 sprintf(n1,"/tmp/misdn-rx-%d.raw",id);
2377 sprintf(n2,"/tmp/misdn-tx-%d.raw",id);
2379 rx = fopen(n1,"a+");
2380 tx = fopen(n2,"a+");
2383 cb_log(0,0,"Couldn't open files: %s\n",strerror(errno));
2400 void misdn_tx_jitter(struct misdn_bchannel *bc, int len)
2402 char buf[4096 + mISDN_HEADER_LEN];
2403 char *data=&buf[mISDN_HEADER_LEN];
2404 iframe_t *txfrm= (iframe_t*)buf;
2407 jlen=cb_jb_empty(bc,data,len);
2410 #ifdef MISDN_SAVE_DATA
2411 misdn_save_data((bc->port*100+bc->channel), data, jlen, bc->bframe, bc->bframe_len);
2413 flip_buf_bits( data, jlen);
2416 cb_log(1, bc->port, "Jitterbuffer Underrun. Got %d of expected %d\n", jlen, len);
2419 txfrm->prim = DL_DATA|REQUEST;
2423 txfrm->addr = bc->addr|FLG_MSG_DOWN; /* | IF_DOWN; */
2426 cb_log(9, bc->port, "Transmitting %d samples 2 misdn\n", txfrm->len);
2428 r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
2430 #define MISDN_GEN_SILENCE
2431 #ifdef MISDN_GEN_SILENCE
2432 int cnt=len/TONE_SILENCE_SIZE;
2433 int rest=len%TONE_SILENCE_SIZE;
2436 for (i=0; i<cnt; i++) {
2437 memcpy(data, tone_silence_flip, TONE_SILENCE_SIZE );
2438 data +=TONE_SILENCE_SIZE;
2442 memcpy(data, tone_silence_flip, rest);
2445 txfrm->prim = DL_DATA|REQUEST;
2449 txfrm->addr = bc->addr|FLG_MSG_DOWN; /* | IF_DOWN; */
2452 cb_log(5, bc->port, "Transmitting %d samples of silence to misdn\n", len);
2454 r=mISDN_write( glob_mgr->midev, buf, txfrm->len + mISDN_HEADER_LEN, 8000 );
2461 cb_log(1, bc->port, "Error in mISDN_write (%s)\n", strerror(errno));
2465 static int handle_bchan(msg_t *msg)
2467 iframe_t *frm= (iframe_t*)msg->data;
2468 struct misdn_bchannel *bc=find_bc_by_addr(frm->addr);
2469 struct misdn_stack *stack;
2472 cb_log(1,0,"handle_bchan: BC not found for prim:%x with addr:%x dinfo:%x\n", frm->prim, frm->addr, frm->dinfo);
2476 stack = get_stack_by_bc(bc);
2479 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);
2483 switch (frm->prim) {
2485 case MGR_SETSTACK| CONFIRM:
2486 cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|CONFIRM pid:%d\n",bc->pid);
2489 case MGR_SETSTACK| INDICATION:
2490 cb_log(3, stack->port, "BCHAN: MGR_SETSTACK|IND pid:%d\n",bc->pid);
2494 bc->addr = mISDN_get_layerid(stack->midev, bc->b_stid, bc->layer);
2497 if (errno == EAGAIN) {
2502 cb_log(0,stack->port,"$$$ Get Layer (%d) Id Error: %s\n",bc->layer,strerror(errno));
2504 /* we kill the channel later, when we received some
2506 bc->addr= frm->addr;
2507 } else if ( bc->addr < 0) {
2508 cb_log(0, stack->port,"$$$ bc->addr <0 Error:%s\n",strerror(errno));
2512 cb_log(4, stack->port," --> Got Adr %x\n", bc->addr);
2517 switch(bc->bc_state) {
2519 bc_state_change(bc,BCHAN_SETUPED);
2522 case BCHAN_CLEAN_REQUEST:
2524 cb_log(0, stack->port," --> STATE WASN'T SETUP (but %s) in SETSTACK|IND pid:%d\n",bc_state2str(bc->bc_state), bc->pid);
2530 case MGR_DELLAYER| INDICATION:
2531 cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|IND pid:%d\n",bc->pid);
2534 case MGR_DELLAYER| CONFIRM:
2535 cb_log(3, stack->port, "BCHAN: MGR_DELLAYER|CNF pid:%d\n",bc->pid);
2543 case PH_ACTIVATE | INDICATION:
2544 case DL_ESTABLISH | INDICATION:
2545 cb_log(3, stack->port, "BCHAN: ACT Ind pid:%d\n", bc->pid);
2550 case PH_ACTIVATE | CONFIRM:
2551 case DL_ESTABLISH | CONFIRM:
2553 cb_log(3, stack->port, "BCHAN: bchan ACT Confirm pid:%d\n",bc->pid);
2558 case DL_ESTABLISH | REQUEST:
2561 mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN, DL_ESTABLISH | CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
2566 case DL_RELEASE|REQUEST:
2569 mISDN_write_frame(stack->midev, buf, bc->addr | FLG_MSG_TARGET | FLG_MSG_DOWN, DL_RELEASE| CONFIRM, 0,0, NULL, TIMEOUT_1SEC);
2574 case PH_DEACTIVATE | INDICATION:
2575 case DL_RELEASE | INDICATION:
2576 cb_log (3, stack->port, "BCHAN: DeACT Ind pid:%d\n",bc->pid);
2581 case PH_DEACTIVATE | CONFIRM:
2582 case DL_RELEASE | CONFIRM:
2583 cb_log(3, stack->port, "BCHAN: DeACT Conf pid:%d\n",bc->pid);
2588 case PH_CONTROL|INDICATION:
2590 unsigned int *cont = (unsigned int *) &frm->data.p;
2592 cb_log(4, stack->port,
2593 "PH_CONTROL: channel:%d caller%d:\"%s\" <%s> dialed%d:%s \n",
2595 bc->caller.number_type,
2598 bc->dialed.number_type,
2601 if ((*cont & ~DTMF_TONE_MASK) == DTMF_TONE_VAL) {
2602 int dtmf = *cont & DTMF_TONE_MASK;
2603 cb_log(4, stack->port, " --> DTMF TONE: %c\n",dtmf);
2605 cb_event(EVENT_DTMF_TONE, bc, glob_mgr->user_data);
2610 if (*cont == BF_REJECT) {
2611 cb_log(4, stack->port, " --> BF REJECT\n");
2615 if (*cont == BF_ACCEPT) {
2616 cb_log(4, stack->port, " --> BF ACCEPT\n");
2623 case PH_DATA|REQUEST:
2624 case DL_DATA|REQUEST:
2625 cb_log(0, stack->port, "DL_DATA REQUEST \n");
2632 case PH_DATA|INDICATION:
2633 case DL_DATA|INDICATION:
2635 bc->bframe = (void*)&frm->data.i;
2636 bc->bframe_len = frm->len;
2638 /** Anyway flip the bufbits **/
2639 if ( misdn_cap_is_speech(bc->capability) )
2640 flip_buf_bits(bc->bframe, bc->bframe_len);
2643 if (!bc->bframe_len) {
2644 cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
2649 if ( (bc->addr&STACK_ID_MASK) != (frm->addr&STACK_ID_MASK) ) {
2650 cb_log(2, stack->port, "DL_DATA INDICATION bc->addr:%x frm->addr:%x\n", bc->addr, frm->addr);
2656 cb_log(0, stack->port, "DL_DATA INDICATION Len %d\n", frm->len);
2660 if ( (bc->bc_state == BCHAN_ACTIVATED) && frm->len > 0) {
2663 #ifdef MISDN_B_DEBUG
2664 cb_log(0,bc->port,"do_tone START\n");
2666 t=do_tone(bc,frm->len);
2668 #ifdef MISDN_B_DEBUG
2669 cb_log(0,bc->port,"do_tone STOP (%d)\n",t);
2674 if ( misdn_cap_is_speech(bc->capability)) {
2675 if ( !bc->nojitter ) {
2676 #ifdef MISDN_B_DEBUG
2677 cb_log(0,bc->port,"tx_jitter START\n");
2679 misdn_tx_jitter(bc,frm->len);
2680 #ifdef MISDN_B_DEBUG
2681 cb_log(0,bc->port,"tx_jitter STOP\n");
2686 #ifdef MISDN_B_DEBUG
2687 cb_log(0,bc->port,"EVENT_B_DATA START\n");
2690 i = cb_event(EVENT_BCHAN_DATA, bc, glob_mgr->user_data);
2691 #ifdef MISDN_B_DEBUG
2692 cb_log(0,bc->port,"EVENT_B_DATA STOP\n");
2696 cb_log(10,stack->port,"cb_event returned <0\n");
2697 /*clean_up_bc(bc);*/
2706 case PH_CONTROL | CONFIRM:
2707 cb_log(4, stack->port, "PH_CONTROL|CNF bc->addr:%x\n", frm->addr);
2711 case PH_DATA | CONFIRM:
2712 case DL_DATA|CONFIRM:
2715 cb_log(0, stack->port, "Data confirmed\n");
2720 case DL_DATA|RESPONSE:
2722 cb_log(0, stack->port, "Data response\n");
2733 static int handle_frm_nt(msg_t *msg)
2735 iframe_t *frm= (iframe_t*)msg->data;
2736 struct misdn_stack *stack;
2739 stack=find_stack_by_addr( frm->addr );
2743 if (!stack || !stack->nt) {
2748 pthread_mutex_lock(&stack->nstlock);
2749 if ((err=stack->nst.l1_l2(&stack->nst,msg))) {
2750 pthread_mutex_unlock(&stack->nstlock);
2751 if (nt_err_cnt > 0 ) {
2752 if (nt_err_cnt < 100) {
2754 cb_log(0, stack->port, "NT Stack sends us error: %d \n", err);
2755 } else if (nt_err_cnt < 105){
2756 cb_log(0, stack->port, "NT Stack sends us error: %d over 100 times, so I'll stop this message\n", err);
2763 pthread_mutex_unlock(&stack->nstlock);
2768 static int handle_frm(msg_t *msg)
2770 struct misdn_bchannel dummybc;
2771 struct misdn_bchannel *bc;
2773 struct misdn_stack *stack;
2775 enum event_response_e response;
2781 frm = (iframe_t*) msg->data;
2782 stack = find_stack_by_addr(frm->addr);
2783 if (!stack || stack->nt) {
2787 cb_log(4, stack ? stack->port : 0, "handle_frm: frm->addr:%x frm->prim:%x\n", frm->addr, frm->prim);
2789 ret = handle_cr(stack, frm);
2791 cb_log(3, stack ? stack->port : 0, "handle_frm: handle_cr <0 prim:%x addr:%x\n", frm->prim, frm->addr);
2798 bc = find_bc_by_l3id(stack, frm->dinfo);
2800 misdn_make_dummy(&dummybc, stack->port, 0, stack->nt, 0);
2801 switch (frm->prim) {
2802 case CC_RESTART | CONFIRM:
2803 dummybc.l3_id = MISDN_ID_GLOBAL;
2806 case CC_SETUP | INDICATION:
2807 dummybc.l3_id = frm->dinfo;
2810 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
2815 if (frm->prim == (CC_FACILITY | INDICATION)) {
2816 cb_log(5, stack->port, " --> Using Dummy BC for FACILITY\n");
2818 cb_log(0, stack->port, " --> Didn't find BC so temporarily creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
2819 dummybc.l3_id = frm->dinfo;
2826 event = isdn_msg_get_event(msgs_g, msg, 0);
2827 isdn_msg_parse_event(msgs_g, msg, bc, 0);
2829 /* Preprocess some Events */
2830 ret = handle_event(bc, event, frm);
2832 cb_log(0, stack->port, "couldn't handle event\n");
2837 /* shoot up event to App: */
2838 cb_log(5, stack->port, "lib Got Prim: Addr %x prim %x dinfo %x\n", frm->addr, frm->prim, frm->dinfo);
2840 if (!isdn_get_info(msgs_g, event, 0)) {
2841 cb_log(0, stack->port, "Unknown Event Ind: Addr:%x prim %x dinfo %x\n", frm->addr, frm->prim, frm->dinfo);
2842 response = RESPONSE_OK;
2844 response = cb_event(event, bc, glob_mgr->user_data);
2850 case RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE:
2851 cb_log(0, stack->port, "TOTALLY IGNORING SETUP\n");
2853 case RESPONSE_IGNORE_SETUP:
2854 /* I think we should send CC_RELEASE_CR, but am not sure*/
2855 bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
2857 case RESPONSE_RELEASE_SETUP:
2858 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
2859 if (bc->channel > 0) {
2860 empty_chan_in_stack(stack, bc->channel);
2863 bc_state_change(bc, BCHAN_CLEANED);
2866 cb_log(0, stack->port, "GOT IGNORE SETUP\n");
2869 cb_log(4, stack->port, "GOT SETUP OK\n");
2875 case EVENT_RELEASE_COMPLETE:
2876 /* release bchannel only after we've announced the RELEASE_COMPLETE */
2877 channel = bc->channel;
2878 tmpcause = bc->cause;
2879 tmp_out_cause = bc->out_cause;
2882 bc->cause = tmpcause;
2883 bc->out_cause = tmp_out_cause;
2887 if (tmpcause == AST_CAUSE_REQUESTED_CHAN_UNAVAIL) {
2888 cb_log(0, stack->port, "**** Received CAUSE:%d, restarting channel %d\n", AST_CAUSE_REQUESTED_CHAN_UNAVAIL, channel);
2889 misdn_lib_send_restart(stack->port, channel);
2892 empty_chan_in_stack(stack, channel);
2896 cb_log(0, stack->port, "**** Received RESTART channel:%d\n", bc->restart_channel);
2897 empty_chan_in_stack(stack, bc->restart_channel);
2903 cb_log(5, stack->port, "Freeing Msg on prim:%x \n", frm->prim);
2909 static int handle_l1(msg_t *msg)
2911 iframe_t *frm = (iframe_t*) msg->data;
2912 struct misdn_stack *stack = find_stack_by_addr(frm->addr);
2915 if (!stack) return 0 ;
2917 switch (frm->prim) {
2918 case PH_ACTIVATE | CONFIRM:
2919 case PH_ACTIVATE | INDICATION:
2920 cb_log (3, stack->port, "L1: PH L1Link Up!\n");
2925 pthread_mutex_lock(&stack->nstlock);
2926 if (stack->nst.l1_l2(&stack->nst, msg))
2928 pthread_mutex_unlock(&stack->nstlock);
2931 misdn_lib_get_l2_up(stack);
2936 for (i=0;i<=stack->b_num; i++) {
2937 if (stack->bc[i].evq != EVENT_NOTHING) {
2938 cb_log(4, stack->port, "Firing Queued Event %s because L1 got up\n", isdn_get_info(msgs_g, stack->bc[i].evq, 0));
2939 misdn_lib_send_event(&stack->bc[i],stack->bc[i].evq);
2940 stack->bc[i].evq=EVENT_NOTHING;
2946 case PH_ACTIVATE | REQUEST:
2948 cb_log(3,stack->port,"L1: PH_ACTIVATE|REQUEST \n");
2951 case PH_DEACTIVATE | REQUEST:
2953 cb_log(3,stack->port,"L1: PH_DEACTIVATE|REQUEST \n");
2956 case PH_DEACTIVATE | CONFIRM:
2957 case PH_DEACTIVATE | INDICATION:
2958 cb_log (3, stack->port, "L1: PH L1Link Down! \n");
2961 for (i=0; i<=stack->b_num; i++) {
2962 if (global_state == MISDN_INITIALIZED) {
2963 cb_event(EVENT_CLEANUP, &stack->bc[i], glob_mgr->user_data);
2969 pthread_mutex_lock(&stack->nstlock);
2970 if (stack->nst.l1_l2(&stack->nst, msg))
2972 pthread_mutex_unlock(&stack->nstlock);
2985 static int handle_l2(msg_t *msg)
2987 iframe_t *frm = (iframe_t*) msg->data;
2989 struct misdn_stack *stack = find_stack_by_addr(frm->addr);
2997 case DL_ESTABLISH | REQUEST:
2998 cb_log(1,stack->port,"DL_ESTABLISH|REQUEST \n");
3001 case DL_RELEASE | REQUEST:
3002 cb_log(1,stack->port,"DL_RELEASE|REQUEST \n");
3006 case DL_ESTABLISH | INDICATION:
3007 case DL_ESTABLISH | CONFIRM:
3009 cb_log (3, stack->port, "L2: L2Link Up! \n");
3010 if (stack->ptp && stack->l2link) {
3011 cb_log (-1, stack->port, "L2: L2Link Up! but it's already UP.. must be faulty, blocking port\n");
3012 cb_event(EVENT_PORT_ALARM, &stack->bc[0], glob_mgr->user_data);
3020 case DL_RELEASE | INDICATION:
3021 case DL_RELEASE | CONFIRM:
3023 cb_log (3, stack->port, "L2: L2Link Down! \n");
3034 static int handle_mgmt(msg_t *msg)
3036 iframe_t *frm = (iframe_t*) msg->data;
3037 struct misdn_stack *stack;
3039 if ( (frm->addr == 0) && (frm->prim == (MGR_DELLAYER|CONFIRM)) ) {
3040 cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: 0 !\n") ;
3045 stack = find_stack_by_addr(frm->addr);
3048 if (frm->prim == (MGR_DELLAYER|CONFIRM)) {
3049 cb_log(2, 0, "MGMT: DELLAYER|CONFIRM Addr: %x !\n",
3059 case MGR_SHORTSTATUS | INDICATION:
3060 case MGR_SHORTSTATUS | CONFIRM:
3061 cb_log(5, stack->port, "MGMT: Short status dinfo %x\n",frm->dinfo);
3063 switch (frm->dinfo) {
3064 case SSTATUS_L1_ACTIVATED:
3065 cb_log(3, stack->port, "MGMT: SSTATUS: L1_ACTIVATED \n");
3069 case SSTATUS_L1_DEACTIVATED:
3070 cb_log(3, stack->port, "MGMT: SSTATUS: L1_DEACTIVATED \n");
3077 case SSTATUS_L2_ESTABLISHED:
3078 cb_log(3, stack->port, "MGMT: SSTATUS: L2_ESTABLISH \n");
3082 case SSTATUS_L2_RELEASED:
3083 cb_log(3, stack->port, "MGMT: SSTATUS: L2_RELEASED \n");
3091 case MGR_SETSTACK | INDICATION:
3092 cb_log(4, stack->port, "MGMT: SETSTACK|IND dinfo %x\n",frm->dinfo);
3095 case MGR_DELLAYER | CONFIRM:
3096 cb_log(4, stack->port, "MGMT: DELLAYER|CNF dinfo %x\n",frm->dinfo) ;
3103 if ( (frm->prim & 0x0f0000) == 0x0f0000) {
3104 cb_log(5, 0, "$$$ MGMT FRAME: prim %x addr %x dinfo %x\n",frm->prim, frm->addr, frm->dinfo) ;
3113 static msg_t *fetch_msg(int midev)
3115 msg_t *msg=alloc_msg(MAX_MSG_SIZE);
3119 cb_log(0, 0, "fetch_msg: alloc msg failed !!");
3124 r=mISDN_read(midev,msg->data,MAX_MSG_SIZE, TIMEOUT_10SEC);
3128 free_msg(msg); /* danger, cause usually freeing in main_loop */
3129 cb_log(6,0,"Got empty Msg..\n");
3134 if (errno == EAGAIN) {
3135 /*we wait for mISDN here*/
3136 cb_log(4,0,"mISDN_read wants us to wait\n");
3141 cb_log(0,0,"mISDN_read returned :%d error:%s (%d)\n",r,strerror(errno),errno);
3145 if (!(frm->prim == (DL_DATA|INDICATION) )|| (frm->prim == (PH_DATA|INDICATION)))
3146 cb_log(0,0,"prim: %x dinfo:%x addr:%x msglen:%d frm->len:%d\n",frm->prim, frm->dinfo, frm->addr, msg->len,frm->len );
3151 void misdn_lib_isdn_l1watcher(int port)
3153 struct misdn_stack *stack;
3155 for (stack = glob_mgr->stack_list; stack && (stack->port != port); stack = stack->next)
3159 cb_log(4, port, "Checking L1 State\n");
3160 if (!stack->l1link) {
3161 cb_log(4, port, "L1 State Down, trying to get it up again\n");
3162 misdn_lib_get_short_status(stack);
3163 misdn_lib_get_l1_up(stack);
3164 misdn_lib_get_l2_up(stack);
3169 /* This is a thread */
3170 static void misdn_lib_isdn_event_catcher(void *arg)
3172 struct misdn_lib *mgr = arg;
3173 int zero_frm=0 , fff_frm=0 ;
3174 int midev= mgr->midev;
3178 msg_t *msg = fetch_msg(midev);
3184 frm = (iframe_t*) msg->data;
3186 /** When we make a call from NT2Ast we get these frames **/
3187 if (frm->len == 0 && frm->addr == 0 && frm->dinfo == 0 && frm->prim == 0 ) {
3193 cb_log(0, port, "*** Alert: %d zero_frms caught\n", zero_frm);
3198 /** I get this sometimes after setup_bc **/
3199 if (frm->len == 0 && frm->dinfo == 0 && frm->prim == 0xffffffff ) {
3205 cb_log(0, port, "*** Alert: %d fff_frms caught\n", fff_frm);
3210 manager_isdn_handler(frm, msg);
3216 /** App Interface **/
3218 static int te_lib_init(void)
3220 char buff[1025] = "";
3221 iframe_t *frm = (iframe_t *) buff;