static void l3_1tr6_rel(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb = arg; u_char *p; p = skb->data; if ((p = findie(p, skb->len, WE0_cause, 0))) { if (p[1] > 0) { pc->para.cause = p[2]; if (p[1] > 1) pc->para.loc = p[3]; else pc->para.loc = 0; } else { pc->para.cause = 0; pc->para.loc = 0; } } else { pc->para.cause = NO_CAUSE; l3_1tr6_error(pc, "missing REL cause", skb); return; } dev_kfree_skb(skb); StopAllL3Timer(pc); newl3state(pc, 0); l3_1TR6_message(pc, MT_N1_REL_ACK, PROTO_DIS_N1); pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc); release_l3_process(pc); }
void release_l3_process(l3_process_t *p) { layer3_t *l3; if (!p) return; l3 = p->l3; mISDN_l3up(p, CC_RELEASE_CR | INDICATION, NULL); list_del(&p->list); StopAllL3Timer(p); kfree(p); if (list_empty(&l3->plist) && !test_bit(FLG_PTP, &l3->Flag)) { if (l3->debug) l3_debug(l3, "release_l3_process: last process"); if (!skb_queue_len(&l3->squeue)) { if (l3->debug) l3_debug(l3, "release_l3_process: release link"); mISDN_FsmEvent(&l3->l3m, EV_RELEASE_REQ, NULL); } else { if (l3->debug) l3_debug(l3, "release_l3_process: not release link"); } } };
static void l3_1tr6_disconnect_req(struct PStack *st, 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 (st->pa->cause > 0) cause = st->pa->cause; /* Map DSS1 causes */ switch (cause & 0x7f) { case 0x10: clen = 0; break; case 0x15: cause = CAUSE_CallRejected; break; } StopAllL3Timer(st); MsgHead(p, st->l3.callref, MT_N1_DISC, PROTO_DIS_N1); *p++ = WE0_cause; *p++ = clen; /* Laenge */ if (clen) *p++ = cause | 0x80; newl3state(st, 11); l = p - tmp; if (!(skb = l3_alloc_skb(l))) return; memcpy(skb_put(skb, l), tmp, l); st->l3.l3l2(st, DL_DATA, skb); L3AddTimer(&st->l3.timer, st->l3.t305, CC_T305); }
static void l3_1tr6_rel(struct PStack *st, u_char pr, void *arg) { struct sk_buff *skb = arg; u_char *p; p = skb->data; if ((p = findie(p, skb->len, WE0_cause, 0))) { if (p[1] > 0) { st->pa->cause = p[2]; if (p[1] > 1) st->pa->loc = p[3]; else st->pa->loc = 0; } else { st->pa->cause = 0; st->pa->loc = 0; } } else st->pa->cause = -1; SET_SKB_FREE(skb); dev_kfree_skb(skb, FREE_READ); StopAllL3Timer(st); newl3state(st, 0); l3_1TR6_message(st, MT_N1_REL_ACK, PROTO_DIS_N1); st->l3.l3l4(st, CC_RELEASE_IND, NULL); }
static void l3_1tr6_release_req(struct l3_process *pc, u_char pr, void *arg) { StopAllL3Timer(pc); newl3state(pc, 19); l3_1TR6_message(pc, MT_N1_REL, PROTO_DIS_N1); L3AddTimer(&pc->timer, T308, CC_T308_1); }
static void l3_1tr6_release_req(struct PStack *st, u_char pr, void *arg) { StopAllL3Timer(st); newl3state(st, 19); l3_1TR6_message(st, MT_N1_REL, PROTO_DIS_N1); L3AddTimer(&st->l3.timer, st->l3.t308, CC_T308_1); }
static void l3_1tr6_disc(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb = arg; u_char *p; int i, tmpcharge = 0; char a_charge[8], tmp[32]; StopAllL3Timer(pc); p = skb->data; if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) { iecpy(a_charge, p, 1); for (i = 0; i < strlen(a_charge); i++) { tmpcharge *= 10; tmpcharge += a_charge[i] & 0xf; } if (tmpcharge > pc->para.chargeinfo) { pc->para.chargeinfo = tmpcharge; pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc); } if (pc->st->l3.debug & L3_DEB_CHARGE) { sprintf(tmp, "charging info %d", pc->para.chargeinfo); l3_debug(pc->st, tmp); } } else if (pc->st->l3.debug & L3_DEB_CHARGE) l3_debug(pc->st, "charging info not found"); p = skb->data; if ((p = findie(p, skb->len, WE0_cause, 0))) { if (p[1] > 0) { pc->para.cause = p[2]; if (p[1] > 1) pc->para.loc = p[3]; else pc->para.loc = 0; } else { pc->para.cause = 0; pc->para.loc = 0; } } else { if (pc->st->l3.debug & L3_DEB_WARN) l3_debug(pc->st, "cause not found"); pc->para.cause = NO_CAUSE; } if (!findie(skb->data, skb->len, WE6_date, 6)) { l3_1tr6_error(pc, "missing connack date", skb); return; } dev_kfree_skb(skb); newl3state(pc, 12); pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc); }
static void l3_1tr6_rel_ack(struct l3_process *pc, u_char pr, void *arg) { struct sk_buff *skb = arg; dev_kfree_skb(skb); StopAllL3Timer(pc); newl3state(pc, 0); pc->para.cause = NO_CAUSE; pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc); release_l3_process(pc); }
void releasestack_isdnl3(struct PStack *st) { while (st->l3.proc) release_l3_process(st->l3.proc); if (st->l3.global) { StopAllL3Timer(st->l3.global); kfree(st->l3.global); st->l3.global = NULL; } discard_queue(&st->l3.squeue); }
static void l3_1tr6_rel_ack(struct PStack *st, u_char pr, void *arg) { struct sk_buff *skb = arg; SET_SKB_FREE(skb); dev_kfree_skb(skb, FREE_READ); StopAllL3Timer(st); newl3state(st, 0); st->pa->cause = -1; st->l3.l3l4(st, CC_RELEASE_CNF, NULL); }
void releasestack_isdnl3(struct PStack *st) { while (st->l3.proc) release_l3_process(st->l3.proc); if (st->l3.global) { StopAllL3Timer(st->l3.global); kfree(st->l3.global); st->l3.global = NULL; } FsmDelTimer(&st->l3.l3m_timer, 54); skb_queue_purge(&st->l3.squeue); }
void release_l3(layer3_t *l3) { l3_process_t *p, *np; if (l3->l3m.debug) printk(KERN_DEBUG "release_l3(%p) plist(%s) global(%p) dummy(%p)\n", l3, list_empty(&l3->plist) ? "no" : "yes", l3->global, l3->dummy); list_for_each_entry_safe(p, np, &l3->plist, list) release_l3_process(p); if (l3->global) { StopAllL3Timer(l3->global); kfree(l3->global); l3->global = NULL; } if (l3->dummy) { StopAllL3Timer(l3->dummy); kfree(l3->dummy); l3->dummy = NULL; } mISDN_FsmDelTimer(&l3->l3m_timer, 54); discard_queue(&l3->squeue); }
static void l3_1tr6_disc(struct PStack *st, u_char pr, void *arg) { struct sk_buff *skb = arg; u_char *p; int i, tmpcharge = 0; char a_charge[8], tmp[32]; StopAllL3Timer(st); p = skb->data; if ((p = findie(p, skb->len, WE6_chargingInfo, 6))) { iecpy(a_charge, p, 1); for (i = 0; i < strlen(a_charge); i++) { tmpcharge *= 10; tmpcharge += a_charge[i] & 0xf; } if (tmpcharge > st->pa->chargeinfo) { st->pa->chargeinfo = tmpcharge; st->l3.l3l4(st, CC_INFO_CHARGE, NULL); } if (st->l3.debug & L3_DEB_CHARGE) { sprintf(tmp, "charging info %d", st->pa->chargeinfo); l3_debug(st, tmp); } } else if (st->l3.debug & L3_DEB_CHARGE) l3_debug(st, "charging info not found"); p = skb->data; if ((p = findie(p, skb->len, WE0_cause, 0))) { if (p[1] > 0) { st->pa->cause = p[2]; if (p[1] > 1) st->pa->loc = p[3]; else st->pa->loc = 0; } else { st->pa->cause = 0; st->pa->loc = 0; } } else { if (st->l3.debug & L3_DEB_WARN) l3_debug(st, "cause not found"); st->pa->cause = -1; } SET_SKB_FREE(skb); dev_kfree_skb(skb, FREE_READ); newl3state(st, 12); st->l3.l3l4(st, CC_DISCONNECT_IND, NULL); }
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); }
void release_l3_process(struct l3_process *p) { struct l3_process *np, *pp = NULL; if (!p) return; np = p->st->l3.proc; while (np) { if (np == p) { StopAllL3Timer(p); if (pp) pp->next = np->next; else if (!(p->st->l3.proc = np->next) && !test_bit(FLG_PTP, &p->st->l2.flag)) { if (p->debug) l3_debug(p->st, "release_l3_process: last process"); if (!skb_queue_len(&p->st->l3.squeue)) { if (p->debug) l3_debug(p->st, "release_l3_process: release link"); if (p->st->protocol != ISDN_PTYPE_NI1) FsmEvent(&p->st->l3.l3m, EV_RELEASE_REQ, NULL); else FsmEvent(&p->st->l3.l3m, EV_RELEASE_IND, NULL); } else { if (p->debug) l3_debug(p->st, "release_l3_process: not release link"); } } kfree(p); return; } pp = np; np = np->next; } printk(KERN_ERR "HiSax internal L3 error CR(%d) not in list\n", p->callref); l3_debug(p->st, "HiSax internal L3 error CR(%d) not in list", p->callref); };
void release_l3_process(struct l3_process *p) { struct l3_process *np, *pp = NULL; if (!p) return; np = p->st->l3.proc; while (np) { if (np == p) { StopAllL3Timer(p); if (pp) pp->next = np->next; else p->st->l3.proc = np->next; kfree(p); return; } pp = np; np = np->next; } printk(KERN_ERR "HiSax internal L3 error CR(%d) not in list\n", p->callref); l3_debug(p->st, "HiSax internal L3 error CR(%d) not in list", p->callref); };