From d6c64e713b4e6ac84262a71eca197cf2dae0b848 Mon Sep 17 00:00:00 2001 From: Karsten Keil Date: Tue, 17 Feb 2004 20:30:09 +0000 Subject: [PATCH] merge changes from 1.0 branch --- i4lnet/net_l2.c | 29 +-- i4lnet/net_l2.h | 8 +- i4lnet/net_l3.c | 493 +++++++++++++++++++++++++++++++++++++++++++-- i4lnet/net_l3.h | 34 +++- i4lnet/tei.c | 28 +-- include/ibuffer.h | 8 +- include/isdn_msg.h | 18 +- include/isdn_net.h | 12 +- include/l3dss1.h | 24 +++ voip/voip_appl.c | 2 + 10 files changed, 598 insertions(+), 58 deletions(-) diff --git a/i4lnet/net_l2.c b/i4lnet/net_l2.c index cd5b50d..fe88c89 100644 --- a/i4lnet/net_l2.c +++ b/i4lnet/net_l2.c @@ -19,9 +19,6 @@ static void l2m_debug(struct FsmInst *fi, char *fmt, ...); static int debug = 0xff; -static -struct Fsm l2fsm = {NULL, 0, 0, NULL, NULL}; - enum { ST_L2_1, ST_L2_2, @@ -1722,7 +1719,7 @@ ph_data_mux(net_stack_t *nst, iframe_t *frm, msg_t *msg) datap = msg_pull(msg, IFRAME_HEAD_SIZE); if (msg->len <= 2) { - dprint(DBGM_L2, "%s: msg (%d)too shoort\n", __FUNCTION__, + dprint(DBGM_L2, "%s: msg (%d) too short\n", __FUNCTION__, msg->len); msg_push(msg, IFRAME_HEAD_SIZE); return(ret); @@ -2023,7 +2020,7 @@ new_dl2(net_stack_t *nst, int tei) { msg_queue_init(&nl2->i_queue); msg_queue_init(&nl2->ui_queue); InitWin(nl2); - nl2->l2m.fsm = &l2fsm; + nl2->l2m.fsm = nst->l2fsm; nl2->l2m.state = ST_L2_4; nl2->l2m.debug = debug; nl2->l2m.nst = nl2->nst; @@ -2040,13 +2037,18 @@ int Isdnl2Init(net_stack_t *nst) { layer2_t *l2; msg_t *msg; + struct Fsm *l2f; - l2fsm.state_count = L2_STATE_COUNT; - l2fsm.event_count = L2_EVENT_COUNT; - l2fsm.strEvent = strL2Event; - l2fsm.strState = strL2State; - FsmNew(&l2fsm, L2FnList, L2_FN_COUNT); - TEIInit(); + if (!(l2f = malloc(sizeof(struct Fsm)))) + return(-ENOMEM); + nst->l2fsm = l2f; + memset(l2f, 0, sizeof(struct Fsm)); + l2f->state_count = L2_STATE_COUNT; + l2f->event_count = L2_EVENT_COUNT; + l2f->strEvent = strL2Event; + l2f->strState = strL2State; + FsmNew(l2f, L2FnList, L2_FN_COUNT); + TEIInit(nst); nst->l1_l2 = l2muxer; nst->l3_l2 = l2from_up; l2 = new_dl2(nst, 127); @@ -2067,6 +2069,7 @@ void cleanup_Isdnl2(net_stack_t *nst) while(nst->layer2) release_l2(nst->layer2); } - TEIFree(); - FsmFree(&l2fsm); + TEIFree(nst); + FsmFree(nst->l2fsm); + free(nst->l2fsm); } diff --git a/i4lnet/net_l2.h b/i4lnet/net_l2.h index a994347..3c1ac6f 100644 --- a/i4lnet/net_l2.h +++ b/i4lnet/net_l2.h @@ -17,6 +17,8 @@ #include "memdbg.h" #endif +#define DINFO_SKB -1 + #define MAX_WINDOW 8 typedef struct _teimgr { @@ -37,7 +39,7 @@ struct _layer2 { laddr_t addr; int maxlen; teimgr_t *tm; - u_int flag; + u_long flag; u_int vs, va, vr; int rc; u_int window; @@ -70,8 +72,8 @@ extern int tei_mux(net_stack_t *nst, msg_t *msg); extern int l2_tei(teimgr_t *tm, msg_t *msg); extern int create_teimgr(layer2_t *l2); extern void release_tei(teimgr_t *tm); -extern int TEIInit(void); -extern void TEIFree(void); +extern int TEIInit(net_stack_t *nst); +extern void TEIFree(net_stack_t *nst); #define GROUP_TEI 127 #define TEI_SAPI 63 diff --git a/i4lnet/net_l3.c b/i4lnet/net_l3.c index 023fd89..f991fc4 100644 --- a/i4lnet/net_l3.c +++ b/i4lnet/net_l3.c @@ -41,6 +41,7 @@ enum { IMSG_L4_DATA, IMSG_TIMER_EXPIRED, IMSG_MASTER_L2_DATA, + IMSG_PROCEEDING_IND, IMSG_ALERTING_IND, IMSG_CONNECT_IND, IMSG_SEL_PROC, @@ -433,6 +434,8 @@ l3dss1_check_messagetype_validity(layer3_proc_t *pc, int mt, void *arg) case MT_CONGESTION_CONTROL: case MT_STATUS: case MT_STATUS_ENQUIRY: + case MT_HOLD: + case MT_RETRIEVE: case MT_RESUME: /* RESUME only in user->net */ case MT_SUSPEND: /* SUSPEND only in user->net */ if (pc->l3->debug & L3_DEB_CHECK) @@ -670,6 +673,8 @@ l3dss1_setup(layer3_proc_t *pc, int pr, void *arg) find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg); setup->NET_FAC = find_and_copy_ie(msg->data, msg->len, IE_NET_FAC, 0, umsg); + setup->KEYPAD = + find_and_copy_ie(msg->data, msg->len, IE_KEYPAD, 0, umsg); setup->SIGNAL = find_and_copy_ie(msg->data, msg->len, IE_SIGNAL, 0, umsg); setup->CALLED_PN = @@ -688,6 +693,7 @@ l3dss1_setup(layer3_proc_t *pc, int pr, void *arg) find_and_copy_ie(msg->data, msg->len, IE_HLC, 0, umsg); setup->USER_USER = find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg); + setup->ces = pc->ces; newl3state(pc, 1); L3DelTimer(&pc->timer2); L3AddTimer(&pc->timer2, T_CTRL, 0x31f); @@ -871,6 +877,38 @@ l3dss1_release_cmpl_i(layer3_proc_t *pc, int pr, void *arg) send_proc(pc, IMSG_END_PROC_M, NULL); } +static void +l3dss1_proceeding_i(layer3_proc_t *pc, int pr, void *arg) +{ + msg_t *umsg, *msg = arg; + CALL_PROCEEDING_t *proc; + + dprint(DBGM_L3,"%s\n", __FUNCTION__); + if (!pc->master) { + L3DelTimer(&pc->timer1); + newl3state(pc, 9); + return; + } + umsg = prep_l3data_msg(CC_PROCEEDING | INDICATION, pc->master->ces | + (pc->master->callref << 16), sizeof(CALL_PROCEEDING_t), msg->len, NULL); + if (!umsg) + return; + proc = (CALL_PROCEEDING_t *)(umsg->data + mISDN_HEAD_SIZE); + L3DelTimer(&pc->timer1); /* T304 */ + newl3state(pc, 9); + proc->BEARER = + find_and_copy_ie(msg->data, msg->len, IE_BEARER, 0, umsg); + proc->FACILITY = + find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg); + proc->PROGRESS = + find_and_copy_ie(msg->data, msg->len, IE_PROGRESS, 0, umsg); + proc->HLC = + find_and_copy_ie(msg->data, msg->len, IE_HLC, 0, umsg); + if (!mISDN_l3up(pc->master, umsg)) + return; + free_msg(umsg); +} + static void l3dss1_alerting_i(layer3_proc_t *pc, int pr, void *arg) { @@ -999,10 +1037,105 @@ l3dss1_connect_i(layer3_proc_t *pc, int pr, void *arg) find_and_copy_ie(msg->data, msg->len, IE_LLC, 0, umsg); conn->USER_USER = find_and_copy_ie(msg->data, msg->len, IE_USER_USER, 0, umsg); + conn->ces = pc->ces; if (send_proc(pc, IMSG_CONNECT_IND, umsg)) free_msg(umsg); } +static void +l3dss1_hold(layer3_proc_t *pc, int pr, void *arg) +{ + msg_t *umsg, *msg = arg; + HOLD_t *hold; + + dprint(DBGM_L3,"%s\n", __FUNCTION__); +#warning TODO: global mask for supported none mandatory services, like HOLD + if (pc->hold_state == HOLDAUX_HOLD_IND) + return; + if (pc->hold_state != HOLDAUX_IDLE) { + l3dss1_message_cause(pc, MT_HOLD_REJECT, CAUSE_NOTCOMPAT_STATE); + return; + } + pc->hold_state = HOLDAUX_HOLD_IND; + + umsg = prep_l3data_msg(CC_HOLD | INDICATION, pc->ces | + (pc->callref << 16), sizeof(HOLD_t), msg->len, NULL); + if (!umsg) + return; + hold = (HOLD_t *)(umsg->data + mISDN_HEAD_SIZE); + if (mISDN_l3up(pc, umsg)) + free_msg(umsg); +} + +static void +l3dss1_retrieve(layer3_proc_t *pc, int pr, void *arg) +{ + msg_t *umsg, *msg = arg; + RETRIEVE_t *retr; + + dprint(DBGM_L3,"%s\n", __FUNCTION__); + if (pc->hold_state == HOLDAUX_RETR_IND) + return; + if (pc->hold_state != HOLDAUX_HOLD) { + l3dss1_message_cause(pc, MT_RETRIEVE_REJECT, CAUSE_NOTCOMPAT_STATE); + return; + } + pc->hold_state = HOLDAUX_RETR_IND; + + umsg = prep_l3data_msg(CC_RETRIEVE | INDICATION, pc->ces | + (pc->callref << 16), sizeof(RETRIEVE_t), msg->len, NULL); + if (!umsg) + return; + retr = (RETRIEVE_t *)(umsg->data + mISDN_HEAD_SIZE); + retr->CHANNEL_ID = + find_and_copy_ie(msg->data, msg->len, IE_CHANNEL_ID, 0, umsg); + if (mISDN_l3up(pc, umsg)) + free_msg(umsg); +} + +static void +l3dss1_suspend(layer3_proc_t *pc, int pr, void *arg) +{ + msg_t *umsg, *msg = arg; + SUSPEND_t *susp; + + dprint(DBGM_L3,"%s\n", __FUNCTION__); + umsg = prep_l3data_msg(CC_SUSPEND | INDICATION, pc->ces | + (pc->callref << 16), sizeof(SUSPEND_t), msg->len, NULL); + if (!umsg) + return; + susp = (SUSPEND_t *)(umsg->data + mISDN_HEAD_SIZE); + susp->CALL_ID = + find_and_copy_ie(msg->data, msg->len, IE_CALL_ID, 0, umsg); + susp->FACILITY = + find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg); + newl3state(pc, 15); + if (mISDN_l3up(pc, umsg)) + free_msg(umsg); +} + +static void +l3dss1_resume(layer3_proc_t *pc, int pr, void *arg) +{ + msg_t *umsg, *msg = arg; + RESUME_t *res; + + dprint(DBGM_L3,"%s\n", __FUNCTION__); + umsg = prep_l3data_msg(CC_RESUME | INDICATION, pc->ces | + (pc->callref << 16), sizeof(RESUME_t), msg->len, NULL); + if (!umsg) + return; + res = (RESUME_t *)(umsg->data + mISDN_HEAD_SIZE); + res->CALL_ID = + find_and_copy_ie(msg->data, msg->len, IE_CALL_ID, 0, umsg); + res->FACILITY = + find_and_copy_ie(msg->data, msg->len, IE_FACILITY, 0, umsg); + res->ces = pc->ces; + newl3state(pc, 17); + if (mISDN_l3up(pc, umsg)) + free_msg(umsg); +} + static struct stateentry datastatelist[] = { {ALL_STATES, @@ -1013,6 +1146,8 @@ static struct stateentry datastatelist[] = MT_STATUS, l3dss1_release_cmpl}, {SBIT(0), MT_SETUP, l3dss1_setup}, + {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25), + MT_CALL_PROCEEDING, l3dss1_proceeding_i}, {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25), MT_ALERTING, l3dss1_alerting_i}, {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25), @@ -1036,6 +1171,14 @@ static struct stateentry datastatelist[] = MT_USER_INFORMATION, l3dss1_userinfo}, {SBIT(7) | SBIT(8) | SBIT(9) | SBIT(19) | SBIT(25), MT_RELEASE_COMPLETE, l3dss1_release_cmpl_i}, + {SBIT(3) | SBIT(4) | SBIT(10), + MT_HOLD, l3dss1_hold}, + {SBIT(3) | SBIT(4) | SBIT(10) | SBIT(12), + MT_RETRIEVE, l3dss1_retrieve}, + {SBIT(10), + MT_SUSPEND, l3dss1_suspend}, + {SBIT(0), + MT_RESUME, l3dss1_resume}, }; #define DATASLLEN \ @@ -1063,6 +1206,14 @@ create_child_proc(layer3_proc_t *pc, int mt, msg_t *msg, int state) { return(0); } +static void +l3dss1_proceeding_m(layer3_proc_t *pc, int pr, void *arg) +{ + dprint(DBGM_L3,"%s\n", __FUNCTION__); + L3DelTimer(&pc->timer1); + create_child_proc(pc, pr, arg, 9); +} + static void l3dss1_alerting_m(layer3_proc_t *pc, int pr, void *arg) { @@ -1140,9 +1291,8 @@ l3dss1_information_mx(layer3_proc_t *pc, int pr, void *arg) static struct stateentry mdatastatelist[] = { - -// TODO CALL_PROCEEDING - + {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25), + MT_CALL_PROCEEDING, l3dss1_proceeding_m}, {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25), MT_ALERTING, l3dss1_alerting_m}, {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25), @@ -1462,6 +1612,76 @@ l3dss1_userinfo_req(layer3_proc_t *pc, int pr, void *arg) } } +static void +l3dss1_information_req(layer3_proc_t *pc, int pr, void *arg) +{ + INFORMATION_t *info = arg; + + if (info) { + MsgStart(pc, MT_INFORMATION); + if (info->COMPLETE) + *pc->op++ = IE_COMPLETE; + if (info->DISPLAY) + AddvarIE(pc, IE_DISPLAY, info->DISPLAY); + if (info->KEYPAD) + AddvarIE(pc, IE_KEYPAD, info->KEYPAD); + if (info->SIGNAL) + AddvarIE(pc, IE_SIGNAL, info->SIGNAL); + if (info->CALLED_PN) + AddvarIE(pc, IE_CALLED_PN, info->CALLED_PN); + SendMsg(pc, -1); + } +} + +static void +l3dss1_progress_req(layer3_proc_t *pc, int pr, void *arg) +{ + PROGRESS_t *prog = arg; + + if (prog) { + MsgStart(pc, MT_INFORMATION); + if (prog->BEARER) + AddvarIE(pc, IE_BEARER, prog->BEARER); + if (prog->CAUSE) + AddvarIE(pc, IE_CAUSE, prog->CAUSE); + if (prog->FACILITY) + AddvarIE(pc, IE_FACILITY, prog->FACILITY); + if (prog->PROGRESS) + AddvarIE(pc, IE_PROGRESS, prog->PROGRESS); + else + return; + if (prog->DISPLAY) + AddvarIE(pc, IE_DISPLAY, prog->DISPLAY); + if (prog->HLC) + AddvarIE(pc, IE_HLC, prog->HLC); +#warning ETSI 300286-1 only define USER_USER for USER_INFORMATION SETUP ALERTING PROGRESS CONNECT DISCONNECT RELEASE* + if (prog->USER_USER) + AddvarIE(pc, IE_USER_USER, prog->USER_USER); + SendMsg(pc, -1); + } +} + +static void +l3dss1_notify_req(layer3_proc_t *pc, int pr, void *arg) +{ + NOTIFY_t *noti = arg; + + if (noti) { + MsgStart(pc, MT_INFORMATION); + if (noti->BEARER) + AddvarIE(pc, IE_BEARER, noti->BEARER); + if (noti->NOTIFY) + AddvarIE(pc, IE_NOTIFY, noti->NOTIFY); + else + return; + if (noti->DISPLAY) + AddvarIE(pc, IE_DISPLAY, noti->DISPLAY); + if (noti->REDIR_DN) + AddvarIE(pc, IE_REDIR_DN, noti->REDIR_DN); + SendMsg(pc, -1); + } +} + static void l3dss1_disconnect_req_out(layer3_proc_t *pc, int pr, void *arg) { @@ -1542,6 +1762,19 @@ l3dss1_release_cmpl_req(layer3_proc_t *pc, int pr, void *arg) send_proc(pc, IMSG_END_PROC_M, NULL); } +static void +l3dss1_t302(layer3_proc_t *pc, int pr, void *arg) +{ + { + int t = 0x302; + + StopAllL3Timer(pc); + if_link(pc->l3->nst->manager, (ifunc_t)pc->l3->nst->l3_manager, + CC_TIMEOUT | INDICATION,pc->ces | (pc->callref << 16), + sizeof(int), &t, 0); + } +} + static void l3dss1_t303(layer3_proc_t *pc, int pr, void *arg) { @@ -1642,6 +1875,198 @@ l3dss1_t312(layer3_proc_t *pc, int pr, void *arg) } } +static void +l3dss1_holdack_req(layer3_proc_t *pc, int pr, void *arg) +{ + HOLD_ACKNOWLEDGE_t *hack = arg; + + if (pc->hold_state != HOLDAUX_HOLD_IND) + return; + pc->hold_state = HOLDAUX_HOLD; + if (hack) { + MsgStart(pc, MT_HOLD_ACKNOWLEDGE); + if (hack->DISPLAY) + AddvarIE(pc, IE_DISPLAY, hack->DISPLAY); + SendMsg(pc, -1); + } else { + l3dss1_message(pc, MT_HOLD_ACKNOWLEDGE); + } +} + +static void +l3dss1_holdrej_req(layer3_proc_t *pc, int pr, void *arg) +{ + HOLD_REJECT_t *hrej = arg; + + if (pc->hold_state != HOLDAUX_HOLD_IND) + return; + pc->hold_state = HOLDAUX_IDLE; + MsgStart(pc, MT_HOLD_REJECT); + if (hrej) { + if (hrej->CAUSE) + AddvarIE(pc, IE_CAUSE, hrej->CAUSE); + else { + *pc->op++ = IE_CAUSE; + *pc->op++ = 2; + *pc->op++ = 0x80; + *pc->op++ = 0x80 | 0x47; + } + if (hrej->DISPLAY) + AddvarIE(pc, IE_DISPLAY, hrej->DISPLAY); + } else { + *pc->op++ = IE_CAUSE; + *pc->op++ = 2; + *pc->op++ = 0x80; + *pc->op++ = 0x80 | 0x47; + } + SendMsg(pc, -1); +} + +static void +l3dss1_retrack_req(layer3_proc_t *pc, int pr, void *arg) +{ + RETRIEVE_ACKNOWLEDGE_t *rack = arg; + + if (pc->hold_state != HOLDAUX_RETR_IND) + return; + pc->hold_state = HOLDAUX_IDLE; + if (rack) { + MsgStart(pc, MT_RETRIEVE_ACKNOWLEDGE); + if (rack->CHANNEL_ID) + AddvarIE(pc, IE_CHANNEL_ID, rack->CHANNEL_ID); + if (rack->DISPLAY) + AddvarIE(pc, IE_DISPLAY, rack->DISPLAY); + SendMsg(pc, -1); + } else { + l3dss1_message(pc, MT_RETRIEVE_ACKNOWLEDGE); + } +} + +static void +l3dss1_retrrej_req(layer3_proc_t *pc, int pr, void *arg) +{ + RETRIEVE_REJECT_t *rrej = arg; + + if (pc->hold_state != HOLDAUX_RETR_IND) + return; + pc->hold_state = HOLDAUX_HOLD; + MsgStart(pc, MT_RETRIEVE_REJECT); + if (rrej) { + if (rrej->CAUSE) + AddvarIE(pc, IE_CAUSE, rrej->CAUSE); + else { + *pc->op++ = IE_CAUSE; + *pc->op++ = 2; + *pc->op++ = 0x80; + *pc->op++ = 0x80 | 0x47; + } + if (rrej->DISPLAY) + AddvarIE(pc, IE_DISPLAY, rrej->DISPLAY); + } else { + *pc->op++ = IE_CAUSE; + *pc->op++ = 2; + *pc->op++ = 0x80; + *pc->op++ = 0x80 | 0x47; + } + SendMsg(pc, -1); +} + +static void +l3dss1_suspack_req(layer3_proc_t *pc, int pr, void *arg) +{ + SUSPEND_ACKNOWLEDGE_t *sack = arg; + + StopAllL3Timer(pc); + if (sack) { + MsgStart(pc, MT_SUSPEND_ACKNOWLEDGE); + if (sack->FACILITY) + AddvarIE(pc, IE_FACILITY, sack->FACILITY); + if (sack->DISPLAY) + AddvarIE(pc, IE_DISPLAY, sack->DISPLAY); + SendMsg(pc, 0); + } else { + l3dss1_message(pc, MT_SUSPEND_ACKNOWLEDGE); + } + newl3state(pc, 0); + send_proc(pc, IMSG_END_PROC_M, NULL); +} + +static void +l3dss1_susprej_req(layer3_proc_t *pc, int pr, void *arg) +{ + SUSPEND_REJECT_t *srej = arg; + + MsgStart(pc, MT_SUSPEND_REJECT); + if (srej) { + if (srej->CAUSE) + AddvarIE(pc, IE_CAUSE, srej->CAUSE); + else { + *pc->op++ = IE_CAUSE; + *pc->op++ = 2; + *pc->op++ = 0x80; + *pc->op++ = 0x80 | 0x47; + } + if (srej->DISPLAY) + AddvarIE(pc, IE_DISPLAY, srej->DISPLAY); + } else { + *pc->op++ = IE_CAUSE; + *pc->op++ = 2; + *pc->op++ = 0x80; + *pc->op++ = 0x80 | 0x47; + } + SendMsg(pc, -1); + newl3state(pc, 10); +} + +static void +l3dss1_resack_req(layer3_proc_t *pc, int pr, void *arg) +{ + RESUME_ACKNOWLEDGE_t *rack = arg; + + StopAllL3Timer(pc); + if (rack) { + MsgStart(pc, MT_RESUME_ACKNOWLEDGE); + if (rack->CHANNEL_ID) + AddvarIE(pc, IE_CHANNEL_ID, rack->CHANNEL_ID); + if (rack->FACILITY) + AddvarIE(pc, IE_FACILITY, rack->FACILITY); + if (rack->DISPLAY) + AddvarIE(pc, IE_DISPLAY, rack->DISPLAY); + SendMsg(pc, 0); + } else { + l3dss1_message(pc, MT_RESUME_ACKNOWLEDGE); + } + newl3state(pc, 10); +} + +static void +l3dss1_resrej_req(layer3_proc_t *pc, int pr, void *arg) +{ + RESUME_REJECT_t *rrej = arg; + + MsgStart(pc, MT_RESUME_REJECT); + if (rrej) { + if (rrej->CAUSE) + AddvarIE(pc, IE_CAUSE, rrej->CAUSE); + else { + *pc->op++ = IE_CAUSE; + *pc->op++ = 2; + *pc->op++ = 0x80; + *pc->op++ = 0x80 | 0x47; + } + if (rrej->DISPLAY) + AddvarIE(pc, IE_DISPLAY, rrej->DISPLAY); + } else { + *pc->op++ = IE_CAUSE; + *pc->op++ = 2; + *pc->op++ = 0x80; + *pc->op++ = 0x80 | 0x47; + } + SendMsg(pc, -1); + newl3state(pc, 0); + send_proc(pc, IMSG_END_PROC_M, NULL); +} + /* *INDENT-OFF* */ static struct stateentry downstatelist[] = { @@ -1665,9 +2090,9 @@ static struct stateentry downstatelist[] = CC_SETUP_ACKNOWLEDGE | REQUEST, l3dss1_setup_ack_req}, {SBIT(1) | SBIT(2), CC_PROCEEDING | REQUEST, l3dss1_proceed_req}, - {SBIT(1) | SBIT(2) | SBIT(3), + {SBIT(2) | SBIT(3), CC_ALERTING | REQUEST, l3dss1_alert_req}, - {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4), + {SBIT(2) | SBIT(3) | SBIT(4), CC_CONNECT | REQUEST, l3dss1_connect_req}, {SBIT(8), CC_CONNECT | RESPONSE, l3dss1_connect_res}, @@ -1675,19 +2100,56 @@ static struct stateentry downstatelist[] = CC_DISCONNECT | REQUEST, l3dss1_disconnect_req}, {SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(25), CC_DISCONNECT | REQUEST, l3dss1_disconnect_req_out}, -// TODO CC_RELEASE only in SBIT(11) - {SBIT(6) | SBIT(7) | SBIT(11) | SBIT(25), - CC_RELEASE | REQUEST, l3dss1_release_req}, + {SBIT(11) +#warning bitte beachte folgendes: +/* +es ist nur erlaubt, im state 11 einen release zu schicken! +dennoch verwende der stack den release scheinbar, um einen prozess +zu releasen, wie es z.b. in l3dss1_disconnect_req_out geschieht. +der process befindet sich zu diesem zeitpunk noch im state 7, 9 oder 25. +wenn man den (Layer 4) state auf 11 ändern würde, braucht mann die folgende +zeile nicht: (bitte nachdenken, ob dies korrekt ist) +Nein glaube ich nicht. CC_RELEASE |= CC_RELEASE_CR muss aber mal ein paar Tests +machen +*/ + | SBIT(12) | SBIT(7) | SBIT(9) | SBIT(25) + ,CC_RELEASE | REQUEST, l3dss1_release_req}, +#warning noch ein bug: wenn ein CC_DISCONNECT gesendet wird (state 7 = klingeling), dann bekommt man nur einen RELEASE_CR, aber keinen vorherigen RELEASE +/* muss ich auch testen, keine Zeit */ {ALL_STATES, CC_FACILITY | REQUEST, l3dss1_facility_req}, {SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10), CC_USER_INFORMATION | REQUEST, l3dss1_userinfo_req}, + {SBIT(2) | SBIT(3) | SBIT(4) | SBIT(10) | SBIT(11) | SBIT(12), + CC_INFORMATION | REQUEST, l3dss1_information_req}, + {SBIT(2) | SBIT(3) | SBIT(4), + CC_PROGRESS | REQUEST, l3dss1_progress_req}, + {SBIT(10) | SBIT(15), + CC_NOTIFY | REQUEST, l3dss1_notify_req}, + {SBIT(2), + CC_T302, l3dss1_t302}, {SBIT(6), CC_T303, l3dss1_t303}, {SBIT(19), CC_T308, l3dss1_t308}, {ALL_STATES, CC_T312, l3dss1_t312}, + {SBIT(3) | SBIT(4) | SBIT(10) | SBIT(12), + CC_HOLD_ACKNOWLEDGE | REQUEST, l3dss1_holdack_req}, + {SBIT(3) | SBIT(4) | SBIT(10) | SBIT(12), + CC_HOLD_REJECT | REQUEST, l3dss1_holdrej_req}, + {SBIT(3) | SBIT(4) | SBIT(10) | SBIT(12), + CC_RETRIEVE_ACKNOWLEDGE | REQUEST, l3dss1_retrack_req}, + {SBIT(3) | SBIT(4) | SBIT(10) | SBIT(12), + CC_RETRIEVE_REJECT | REQUEST, l3dss1_retrrej_req}, + {SBIT(15), + CC_SUSPEND_ACKNOWLEDGE | REQUEST, l3dss1_suspack_req}, + {SBIT(15), + CC_SUSPEND_REJECT | REQUEST, l3dss1_susprej_req}, + {SBIT(17), + CC_RESUME_ACKNOWLEDGE | REQUEST, l3dss1_resack_req}, + {SBIT(17), + CC_RESUME_REJECT | REQUEST, l3dss1_resrej_req}, }; #define DOWNSLLEN \ @@ -1718,7 +2180,8 @@ imsg_intrelease(layer3_proc_t *master, layer3_proc_t *child) case 25: if (master->child || test_bit(FLG_L3P_TIMER312, &master->Flags)) { - /* TODO: save cause */ +#warning TODO: save cause +#warning bedenke auch, dass vielleicht overlap sending mit information-messages praktisch wäre (später PTP) } else { send_proc(master, IMSG_END_PROC, NULL); } @@ -1964,16 +2427,16 @@ dl_data_mux(layer3_t *l3, mISDN_head_t *hh, msg_t *msg) proc = find_proc(l3->proc, hh->dinfo, cr); dprint(DBGM_L3, "%s: proc(%p)\n", __FUNCTION__, proc); if (!proc) { - if (l3m.mt == MT_SETUP) { - /* Setup creates a new transaction process */ + if (l3m.mt == MT_SETUP || l3m.mt == MT_RESUME) { + /* Setup/Resume creates a new transaction process */ if (msg->data[2] & 0x80) { - /* Setup with wrong CREF flag */ + /* Setup/Resume with wrong CREF flag */ if (l3->debug & L3_DEB_STATE) l3_debug(l3, "dss1 wrong CRef flag"); free_msg(msg); return(0); } - dprint(DBGM_L3, "%s: MT_SETUP\n", __FUNCTION__); + dprint(DBGM_L3, "%s: %s\n", __FUNCTION__, (l3m.mt==MT_SETUP)?"MT_SETUP":"MT_RESUME"); if (!(proc = create_proc(l3, hh->dinfo, cr, NULL))) { /* May be to answer with RELEASE_COMPLETE and * CAUSE 0x2f "Resource unavailable", but this @@ -2046,7 +2509,6 @@ manager_l3(net_stack_t *nst, msg_t *msg) nst->layer3->next_cr = 1; proc = create_proc(nst->layer3, hh->dinfo & 0xffff, nst->layer3->next_cr | 0x80, NULL); - // TODO Errorhandling dprint(DBGM_L3, "%s: proc(%p)\n", __FUNCTION__, proc); APPEND_TO_LIST(proc, nst->layer3->proc); l4id = proc->ces | (proc->callref << 16); @@ -2164,6 +2626,9 @@ l3_msg(layer3_t *l3, u_int pr, int dinfo, void *arg) } break; case (DL_RELEASE | INDICATION): +#warning du musst alle processe releasen CC_RELEASE!!! dies geschieht z.b. wenn man das telefon vom s0-bus abnimmt und der layer-2 dadurch zusammen bricht. +#warning geschieht dies auch im TE-mode? +#warning TODO DL_RELEASE | INDICATION handling; inclusiv special state 10 (T309) if (l3->l2_state == ST_L3_LC_ESTAB) { l3->l2_state = ST_L3_LC_REL; } diff --git a/i4lnet/net_l3.h b/i4lnet/net_l3.h index 2317b9c..2e5cc4e 100644 --- a/i4lnet/net_l3.h +++ b/i4lnet/net_l3.h @@ -30,12 +30,13 @@ struct _layer3_proc { int ces; int selces; int state; - int Flags; + u_long Flags; L3Timer_t timer1; L3Timer_t timer2; int bc; int err; int cause; + int hold_state; u_char obuf[MAX_DFRAME_LEN]; u_char *op; }; @@ -105,6 +106,7 @@ typedef struct _CONNECT { u_char *LLC; u_char *HLC; u_char *USER_USER; + int ces; } CONNECT_t; typedef struct _CONNECT_ACKNOWLEDGE { @@ -134,6 +136,7 @@ typedef struct _NOTIFY { u_char *BEARER; u_char *NOTIFY; u_char *DISPLAY; + u_char *REDIR_DN; } NOTIFY_t; typedef struct _PROGRESS { @@ -165,6 +168,7 @@ typedef struct _RELEASE_COMPLETE { typedef struct _RESUME { u_char *CALL_ID; u_char *FACILITY; + int ces; } RESUME_t; typedef struct _RESUME_ACKNOWLEDGE { @@ -196,6 +200,7 @@ typedef struct _SETUP { u_char *LLC; u_char *HLC; u_char *USER_USER; + int ces; } SETUP_t; typedef struct _SETUP_ACKNOWLEDGE { @@ -253,5 +258,32 @@ typedef struct _FACILITY { u_char *DISPLAY; } FACILITY_t; +typedef struct _HOLD { + u_char *DISPLAY; +} HOLD_t; + +typedef struct _HOLD_ACKNOWLEDGE { + u_char *CHANNEL_ID; + u_char *DISPLAY; +} HOLD_ACKNOWLEDGE_t; + +typedef struct _HOLD_REJECT { + u_char *CAUSE; + u_char *DISPLAY; +} HOLD_REJECT_t; + +typedef struct _RETRIEVE { + u_char *CHANNEL_ID; +} RETRIEVE_t; + +typedef struct _RETRIEVE_ACKNOWLEDGE { + u_char *CHANNEL_ID; + u_char *DISPLAY; +} RETRIEVE_ACKNOWLEDGE_t; + +typedef struct _RETRIEVE_REJECT { + u_char *CAUSE; + u_char *DISPLAY; +} RETRIEVE_REJECT_t; #endif diff --git a/i4lnet/tei.c b/i4lnet/tei.c index 40c75e2..bcd261f 100644 --- a/i4lnet/tei.c +++ b/i4lnet/tei.c @@ -26,10 +26,6 @@ const char *tei_revision = "$Revision$"; #define TEI_ENTITY_ID 0xf -static -struct Fsm teifsm = -{NULL, 0, 0, NULL, NULL}; - enum { ST_TEI_NOP, ST_TEI_REMOVE, @@ -324,7 +320,7 @@ create_teimgr(layer2_t *l2) { ntei->tei_m.debug = l2->debug; ntei->tei_m.userdata = ntei; ntei->tei_m.printdebug = tei_debug; - ntei->tei_m.fsm = &teifsm; + ntei->tei_m.fsm = l2->nst->teifsm; ntei->tei_m.state = ST_TEI_NOP; FsmInitTimer(&ntei->tei_m, &ntei->t201); l2->tm = ntei; @@ -425,17 +421,23 @@ tei_mux(net_stack_t *nst, msg_t *msg) -int TEIInit(void) +int TEIInit(net_stack_t *nst) { - teifsm.state_count = TEI_STATE_COUNT; - teifsm.event_count = TEI_EVENT_COUNT; - teifsm.strEvent = strTeiEvent; - teifsm.strState = strTeiState; - FsmNew(&teifsm, TeiFnList, TEI_FN_COUNT); + struct Fsm *teif; + + if (!(teif = malloc(sizeof(struct Fsm)))) + return(1); + nst->teifsm = teif; + memset(teif, 0, sizeof(struct Fsm)); + teif->state_count = TEI_STATE_COUNT; + teif->event_count = TEI_EVENT_COUNT; + teif->strEvent = strTeiEvent; + teif->strState = strTeiState; + FsmNew(teif, TeiFnList, TEI_FN_COUNT); return(0); } -void TEIFree(void) +void TEIFree(net_stack_t *nst) { - FsmFree(&teifsm); + FsmFree(nst->teifsm); } diff --git a/include/ibuffer.h b/include/ibuffer.h index 6c963f8..ad3f9a4 100644 --- a/include/ibuffer.h +++ b/include/ibuffer.h @@ -32,11 +32,11 @@ init_ibuffer(int size) { ibuffer_t *ib; - ib = malloc(sizeof(ibuffer_t)); + ib = (ibuffer_t *)malloc(sizeof(ibuffer_t)); if (!ib) return(NULL); memset(ib, 0, sizeof(ibuffer_t)); - ib->buffer = malloc(size); + ib->buffer = (unsigned char *)malloc(size); if (!ib->buffer) { free(ib); return(NULL); @@ -80,7 +80,7 @@ ibuf_freecount(ibuffer_t *ib) static inline void ibuf_memcpy_w(ibuffer_t *ib, void *data, int len) { - unsigned char *p = data; + unsigned char *p = (unsigned char *)data; int frag; frag = ib->size - ib->widx; @@ -99,7 +99,7 @@ ibuf_memcpy_w(ibuffer_t *ib, void *data, int len) static inline void ibuf_memcpy_r(void *data, ibuffer_t *ib, int len) { - unsigned char *p = data; + unsigned char *p = (unsigned char *)data; int frag; frag = ib->size - ib->ridx; diff --git a/include/isdn_msg.h b/include/isdn_msg.h index ff6abe0..a8ff0b5 100644 --- a/include/isdn_msg.h +++ b/include/isdn_msg.h @@ -1,6 +1,10 @@ #ifndef ISDN_MSG_H #define ISDN_MSG_H +#ifdef __cplusplus +extern "C" { +#endif + #include #include @@ -145,14 +149,14 @@ static __inline__ unsigned char *msg_push(msg_t *msg, unsigned int len) static __inline__ char *__msg_pull(msg_t *msg, unsigned int len) { msg->len-=len; - return msg->data+=len; + return (char *)msg->data+=len; } static __inline__ unsigned char * msg_pull(msg_t *msg, unsigned int len) -{ - if (len > msg->len) +{ + if (len > (unsigned int)msg->len) return NULL; - return __msg_pull(msg,len); + return (unsigned char *)__msg_pull(msg,len); } static __inline__ int msg_headroom(msg_t *msg) @@ -179,9 +183,13 @@ static __inline__ void __msg_trim(msg_t *msg, unsigned int len) static __inline__ void msg_trim(msg_t *msg, unsigned int len) { - if (msg->len > len) { + if ((unsigned int)msg->len > len) { __msg_trim(msg, len); } } +#ifdef __cplusplus +} +#endif + #endif diff --git a/include/isdn_net.h b/include/isdn_net.h index 7877386..26d4325 100644 --- a/include/isdn_net.h +++ b/include/isdn_net.h @@ -122,8 +122,10 @@ struct _net_stack { int b_stid[2]; int b_addr[2]; int bcid[2]; - int flag; + u_long flag; struct _itimer *tlist; + void *l2fsm; + void *teifsm; }; struct _nr_list { @@ -146,7 +148,7 @@ typedef struct _itimer { net_stack_t *nst; int id; int expires; - int Flags; + u_long Flags; unsigned long data; int (*function)(unsigned long); } itimer_t; @@ -220,7 +222,7 @@ static inline int if_newhead(void *arg, ifunc_t func, u_int prim, int dinfo, if (!msg) return(-ENXIO); mISDN_newhead(prim, dinfo, msg); - return(func(arg, msg)); + return(func((net_stack_t *)arg, msg)); } static inline void mISDN_addhead(u_int prim, int dinfo, msg_t *msg) @@ -238,7 +240,7 @@ static inline int if_addhead(void *arg, ifunc_t func, u_int prim, int dinfo, if (!msg) return(-ENXIO); mISDN_addhead(prim, dinfo, msg); - return(func(arg, msg)); + return(func((net_stack_t *)arg, msg)); } @@ -267,7 +269,7 @@ static inline int if_link(void *farg, ifunc_t func, u_int prim, int dinfo, int l if (!(msg = create_link_msg(prim, dinfo, len, arg, reserve))) return(-ENOMEM); - err = func(farg, msg); + err = func((net_stack_t *)farg, msg); if (err) free_msg(msg); return(err); diff --git a/include/l3dss1.h b/include/l3dss1.h index 7f8db9b..6b4be7e 100644 --- a/include/l3dss1.h +++ b/include/l3dss1.h @@ -70,6 +70,22 @@ #define MT_NOTIFY 0x6e #define MT_STATUS 0x7d #define MT_STATUS_ENQUIRY 0x75 +#define MT_HOLD 0x24 +#define MT_HOLD_ACKNOWLEDGE 0x28 +#define MT_HOLD_REJECT 0x30 +#define MT_RETRIEVE 0x31 +#define MT_RETRIEVE_ACKNOWLEDGE 0x33 +#define MT_RETRIEVE_REJECT 0x37 + +#warning FIXME if mISDN.h is uptodate +#ifndef CC_HOLD +#define CC_HOLD 0x032400 +#define CC_HOLD_ACKNOWLEDGE 0x032800 +#define CC_HOLD_REJECT 0x033000 +#define CC_RETRIEVE 0x033100 +#define CC_RETRIEVE_ACKNOWLEDGE 0x033300 +#define CC_RETRIEVE_REJECT 0x033700 +#endif #define IE_SEGMENT 0x00 #define IE_BEARER 0x04 @@ -100,6 +116,7 @@ #define IE_CALLED_PN 0x70 #define IE_CALLED_SUB 0x71 #define IE_REDIR_NR 0x74 +#define IE_REDIR_DN 0x76 #define IE_TRANS_SEL 0x78 #define IE_RESTART_IND 0x79 #define IE_LLC 0x7c @@ -152,6 +169,13 @@ #define PROGRESS_TONE 8 +#define HOLDAUX_IDLE 0 +#define HOLDAUX_HOLD_REQ 1 +#define HOLDAUX_HOLD 2 +#define HOLDAUX_RETR_REQ 3 +#define HOLDAUX_HOLD_IND 4 +#define HOLDAUX_RETR_IND 5 + #else /* only l3dss1_process */ /* l3dss1 specific data in l3 process */ diff --git a/voip/voip_appl.c b/voip/voip_appl.c index 343f861..0023312 100644 --- a/voip/voip_appl.c +++ b/voip/voip_appl.c @@ -109,10 +109,12 @@ clear_connection(iapplication_t *ia) } if (c->sock) close(c->sock); +#ifdef GSM_COMPRESSION if (c->r_gsm) gsm_destroy(c->r_gsm); if (c->s_gsm) gsm_destroy(c->s_gsm); +#endif free(c); ia->con = NULL; }