static void l3_1tr6_t305(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb; u_char tmp[16]; u_char *p = tmp; int l; u_char cause = 0x90; u_char clen = 1; L3DelTimer(&pc->timer); if (pc->para.cause != NO_CAUSE) cause = pc->para.cause; /* Map DSS1 causes */ switch (cause & 0x7f) { case 0x10: clen = 0; break; case 0x15: cause = CAUSE_CallRejected; break; } MsgHead(p, pc->callref, MT_N1_REL, PROTO_DIS_N1); *p++ = WE0_cause; *p++ = clen; /* Laenge */ if (clen) *p++ = cause; newl3state(pc, 19); l = p - tmp; if (!(skb = l3_alloc_skb(l))) return; memcpy(skb_put(skb, l), tmp, l); l3_msg(pc->st, DL_DATA | REQUEST, skb); L3AddTimer(&pc->timer, T308, CC_T308_1); }
static void l3_1tr6_setup_rsp(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb; u_char tmp[24]; u_char *p = tmp; int l; MsgHead(p, pc->callref, MT_N1_CONN, PROTO_DIS_N1); if (pc->para.spv) { /* SPV ? */ /* NSF SPV */ *p++ = WE0_netSpecFac; *p++ = 4; /* Laenge */ *p++ = 0; *p++ = FAC_SPV; /* SPV */ *p++ = pc->para.setup.si1; *p++ = pc->para.setup.si2; *p++ = WE0_netSpecFac; *p++ = 4; /* Laenge */ *p++ = 0; *p++ = FAC_Activate; /* aktiviere SPV */ *p++ = pc->para.setup.si1; *p++ = pc->para.setup.si2; } newl3state(pc, 8); l = p - tmp; if (!(skb = l3_alloc_skb(l))) return; memcpy(skb_put(skb, l), tmp, l); l3_msg(pc->st, DL_DATA | REQUEST, skb); L3DelTimer(&pc->timer); L3AddTimer(&pc->timer, T313, CC_T313); }
static void l3_1TR6_message(struct l3_process *pc, u_char mt, u_char pd) { struct sk_buff *skb; u_char *p; if (!(skb = l3_alloc_skb(4))) return; p = skb_put(skb, 4); MsgHead(p, pc->callref, mt, pd); l3_msg(pc->st, DL_DATA | REQUEST, skb); }
static void down1tr6(struct PStack *st, int pr, void *arg) { int i, cr; struct l3_process *proc; struct Channel *chan; char tmp[80]; if ((DL_ESTABLISH | REQUEST)== pr) { l3_msg(st, pr, NULL); return; } else if ((CC_SETUP | REQUEST) == pr) { chan = arg; cr = newcallref(); cr |= 0x80; if (!(proc = new_l3_process(st, cr))) { return; } else { proc->chan = chan; chan->proc = proc; memcpy(&proc->para.setup, &chan->setup, sizeof(setup_parm)); proc->callref = cr; } } else { proc = arg; } for (i = 0; i < DOWNSTL_LEN; i++) if ((pr == downstl[i].primitive) && ((1 << proc->state) & downstl[i].state)) break; if (i == DOWNSTL_LEN) { if (st->l3.debug & L3_DEB_STATE) { sprintf(tmp, "down1tr6 state %d prim %d unhandled", proc->state, pr); l3_debug(st, tmp); } } else { if (st->l3.debug & L3_DEB_STATE) { sprintf(tmp, "down1tr6 state %d prim %d", proc->state, pr); l3_debug(st, tmp); } downstl[i].rout(proc, pr, arg); } }
static void l3_1tr6_disconnect_req(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb; u_char tmp[16]; u_char *p = tmp; int l; u_char cause = 0x10; u_char clen = 1; if (pc->para.cause > 0) cause = pc->para.cause; /* Map DSS1 causes */ switch (cause & 0x7f) { case 0x10: clen = 0; break; case 0x11: cause = CAUSE_UserBusy; break; case 0x15: cause = CAUSE_CallRejected; break; } StopAllL3Timer(pc); MsgHead(p, pc->callref, MT_N1_DISC, PROTO_DIS_N1); *p++ = WE0_cause; *p++ = clen; /* Laenge */ if (clen) *p++ = cause | 0x80; newl3state(pc, 11); l = p - tmp; if (!(skb = l3_alloc_skb(l))) return; memcpy(skb_put(skb, l), tmp, l); l3_msg(pc->st, DL_DATA | REQUEST, skb); L3AddTimer(&pc->timer, T305, CC_T305); }
static void up1tr6(struct PStack *st, int pr, void *arg) { int i, mt, cr; struct l3_process *proc; struct sk_buff *skb = arg; char tmp[80]; switch (pr) { case (DL_DATA | INDICATION): case (DL_UNIT_DATA | INDICATION): break; case (DL_ESTABLISH | CONFIRM): case (DL_ESTABLISH | INDICATION): case (DL_RELEASE | INDICATION): case (DL_RELEASE | CONFIRM): l3_msg(st, pr, arg); return; break; } if (skb->len < 4) { if (st->l3.debug & L3_DEB_PROTERR) { sprintf(tmp, "up1tr6 len only %d", skb->len); l3_debug(st, tmp); } dev_kfree_skb(skb); return; } if ((skb->data[0] & 0xfe) != PROTO_DIS_N0) { if (st->l3.debug & L3_DEB_PROTERR) { sprintf(tmp, "up1tr6%sunexpected discriminator %x message len %d", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", skb->data[0], skb->len); l3_debug(st, tmp); } dev_kfree_skb(skb); return; } if (skb->data[1] != 1) { if (st->l3.debug & L3_DEB_PROTERR) { sprintf(tmp, "up1tr6 CR len not 1"); l3_debug(st, tmp); } dev_kfree_skb(skb); return; } cr = skb->data[2]; mt = skb->data[3]; if (skb->data[0] == PROTO_DIS_N0) { dev_kfree_skb(skb); if (st->l3.debug & L3_DEB_STATE) { sprintf(tmp, "up1tr6%s N0 mt %x unhandled", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", mt); l3_debug(st, tmp); } } else if (skb->data[0] == PROTO_DIS_N1) { if (!(proc = getl3proc(st, cr))) { if (mt == MT_N1_SETUP) { if (cr < 128) { if (!(proc = new_l3_process(st, cr))) { if (st->l3.debug & L3_DEB_PROTERR) { sprintf(tmp, "up1tr6 no roc mem"); l3_debug(st, tmp); } dev_kfree_skb(skb); return; } } else { dev_kfree_skb(skb); return; } } else if ((mt == MT_N1_REL) || (mt == MT_N1_REL_ACK) || (mt == MT_N1_CANC_ACK) || (mt == MT_N1_CANC_REJ) || (mt == MT_N1_REG_ACK) || (mt == MT_N1_REG_REJ) || (mt == MT_N1_SUSP_ACK) || (mt == MT_N1_RES_REJ) || (mt == MT_N1_INFO)) { dev_kfree_skb(skb); return; } else { if (!(proc = new_l3_process(st, cr))) { if (st->l3.debug & L3_DEB_PROTERR) { sprintf(tmp, "up1tr6 no roc mem"); l3_debug(st, tmp); } dev_kfree_skb(skb); return; } mt = MT_N1_INVALID; } } for (i = 0; i < DATASTLN1_LEN; i++) if ((mt == datastln1[i].primitive) && ((1 << proc->state) & datastln1[i].state)) break; if (i == DATASTLN1_LEN) { dev_kfree_skb(skb); if (st->l3.debug & L3_DEB_STATE) { sprintf(tmp, "up1tr6%sstate %d mt %x unhandled", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", proc->state, mt); l3_debug(st, tmp); } return; } else { if (st->l3.debug & L3_DEB_STATE) { sprintf(tmp, "up1tr6%sstate %d mt %x", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", proc->state, mt); l3_debug(st, tmp); } datastln1[i].rout(proc, pr, skb); } } }
static void l3_1tr6_setup_req(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb; u_char tmp[128]; u_char *p = tmp; u_char *teln; u_char *eaz; u_char channel = 0; int l; MsgHead(p, pc->callref, MT_N1_SETUP, PROTO_DIS_N1); teln = pc->para.setup.phone; pc->para.spv = 0; if (!isdigit(*teln)) { switch (0x5f & *teln) { case 'S': pc->para.spv = 1; break; case 'C': channel = 0x08; case 'P': channel |= 0x80; teln++; if (*teln == '1') channel |= 0x01; else channel |= 0x02; break; default: if (pc->st->l3.debug & L3_DEB_WARN) l3_debug(pc->st, "Wrong MSN Code"); break; } teln++; } if (channel) { *p++ = 0x18; /* channel indicator */ *p++ = 1; *p++ = channel; } if (pc->para.spv) { /* SPV ? */ /* NSF SPV */ *p++ = WE0_netSpecFac; *p++ = 4; /* Laenge */ *p++ = 0; *p++ = FAC_SPV; /* SPV */ *p++ = pc->para.setup.si1; /* 0 for all Services */ *p++ = pc->para.setup.si2; /* 0 for all Services */ *p++ = WE0_netSpecFac; *p++ = 4; /* Laenge */ *p++ = 0; *p++ = FAC_Activate; /* aktiviere SPV (default) */ *p++ = pc->para.setup.si1; /* 0 for all Services */ *p++ = pc->para.setup.si2; /* 0 for all Services */ } eaz = pc->para.setup.eazmsn; if (*eaz) { *p++ = WE0_origAddr; *p++ = strlen(eaz) + 1; /* Classify as AnyPref. */ *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */ while (*eaz) *p++ = *eaz++ & 0x7f; } *p++ = WE0_destAddr; *p++ = strlen(teln) + 1; /* Classify as AnyPref. */ *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */ while (*teln) *p++ = *teln++ & 0x7f; *p++ = WE_Shift_F6; /* Codesatz 6 fuer Service */ *p++ = WE6_serviceInd; *p++ = 2; /* len=2 info,info2 */ *p++ = pc->para.setup.si1; *p++ = pc->para.setup.si2; l = p - tmp; if (!(skb = l3_alloc_skb(l))) return; memcpy(skb_put(skb, l), tmp, l); L3DelTimer(&pc->timer); L3AddTimer(&pc->timer, T303, CC_T303); newl3state(pc, 1); l3_msg(pc->st, DL_DATA | REQUEST, skb); }
static void l3_1tr6_setup_req(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb; u_char tmp[128]; u_char *p = tmp; u_char *teln; u_char *eaz; u_char channel = 0; int l; MsgHead(p, pc->callref, MT_N1_SETUP, PROTO_DIS_N1); teln = pc->para.setup.phone; pc->para.spv = 0; if (!isdigit(*teln)) { switch (0x5f & *teln) { case 'S': pc->para.spv = 1; break; case 'C': channel = 0x08; case 'P': channel |= 0x80; teln++; if (*teln == '1') channel |= 0x01; else channel |= 0x02; break; default: if (pc->st->l3.debug & L3_DEB_WARN) l3_debug(pc->st, "Wrong MSN Code"); break; } teln++; } if (channel) { *p++ = 0x18; *p++ = 1; *p++ = channel; } if (pc->para.spv) { *p++ = WE0_netSpecFac; *p++ = 4; *p++ = 0; *p++ = FAC_SPV; *p++ = pc->para.setup.si1; *p++ = pc->para.setup.si2; *p++ = WE0_netSpecFac; *p++ = 4; *p++ = 0; *p++ = FAC_Activate; *p++ = pc->para.setup.si1; *p++ = pc->para.setup.si2; } eaz = pc->para.setup.eazmsn; if (*eaz) { *p++ = WE0_origAddr; *p++ = strlen(eaz) + 1; *p++ = 0x81; while (*eaz) *p++ = *eaz++ & 0x7f; } *p++ = WE0_destAddr; *p++ = strlen(teln) + 1; *p++ = 0x81; while (*teln) *p++ = *teln++ & 0x7f; *p++ = WE_Shift_F6; *p++ = WE6_serviceInd; *p++ = 2; *p++ = pc->para.setup.si1; *p++ = pc->para.setup.si2; l = p - tmp; if (!(skb = l3_alloc_skb(l))) return; memcpy(skb_put(skb, l), tmp, l); L3DelTimer(&pc->timer); L3AddTimer(&pc->timer, T303, CC_T303); newl3state(pc, 1); l3_msg(pc->st, DL_DATA | REQUEST, skb); }