int l2_tei(teimgr_t *tm, struct sk_buff *skb) { mISDN_head_t *hh; int ret = -EINVAL; if (!tm || !skb) return(ret); hh = mISDN_HEAD_P(skb); if (tm->debug) printk(KERN_DEBUG "%s: prim(%x)\n", __FUNCTION__, hh->prim); switch(hh->prim) { case (MDL_UNITDATA | INDICATION): return(tei_ph_data_ind(tm, hh->dinfo, skb)); case (MDL_ASSIGN | INDICATION): if (test_bit(FLG_FIXED_TEI, &tm->l2->flag)) { if (tm->debug) tm->tei_m.printdebug(&tm->tei_m, "fixed assign tei %d", tm->l2->tei); skb_trim(skb, 0); mISDN_sethead(MDL_ASSIGN | REQUEST, tm->l2->tei, skb); if (!tei_l2(tm->l2, skb)) return(0); // cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL); } else mISDN_FsmEvent(&tm->tei_m, EV_IDREQ, NULL); break; case (MDL_ERROR | INDICATION): if (!test_bit(FLG_FIXED_TEI, &tm->l2->flag)) mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, NULL); break; } dev_kfree_skb(skb); return(0); }
int l1_event(struct layer1 *l1, u_int event) { int err = 0; if (!l1) return -EINVAL; switch (event) { case HW_RESET_IND: mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL); break; case HW_DEACT_IND: mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL); break; case HW_POWERUP_IND: mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL); break; case HW_DEACT_CNF: mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL); break; case ANYSIGNAL: mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); break; case LOSTFRAMING: mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); break; case INFO2: mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL); break; case INFO4_P8: mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); break; case INFO4_P10: mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); break; case PH_ACTIVATE_REQ: if (test_bit(FLG_L1_ACTIVATED, &l1->Flags)) l1->dcb(l1->dch, PH_ACTIVATE_IND); else { test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags); mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL); } break; case CLOSE_CHANNEL: release_l1(l1); break; default: if (*debug & DEBUG_L1) #ifdef CONFIG_DEBUG_PRINTK printk(KERN_DEBUG "%s %x unhandled\n", __func__, event); #else ; #endif err = -EINVAL; } return err; }
static int tei_ph_data_ind(teimgr_t *tm, int dtyp, struct sk_buff *skb) { u_char *dp; int mt; int ret = -EINVAL; if (!skb) return(ret); if (test_bit(FLG_FIXED_TEI, &tm->l2->flag) && !test_bit(FLG_LAPD_NET, &tm->l2->flag)) return(ret); if (skb->len < 8) { tm->tei_m.printdebug(&tm->tei_m, "short mgr frame %ld/8", skb->len); return(ret); } dp = skb->data + 2; if ((*dp & 0xef) != UI) { tm->tei_m.printdebug(&tm->tei_m, "mgr frame is not ui %x", *dp); return(ret); } dp++; if (*dp++ != TEI_ENTITY_ID) { /* wrong management entity identifier, ignore */ dp--; tm->tei_m.printdebug(&tm->tei_m, "tei handler wrong entity id %x", *dp); return(ret); } else { mt = *(dp+2); if (tm->debug) tm->tei_m.printdebug(&tm->tei_m, "tei handler mt %x", mt); if (mt == ID_ASSIGNED) mISDN_FsmEvent(&tm->tei_m, EV_ASSIGN, dp); else if (mt == ID_DENIED) mISDN_FsmEvent(&tm->tei_m, EV_DENIED, dp); else if (mt == ID_CHK_REQ) mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, dp); else if (mt == ID_REMOVE) mISDN_FsmEvent(&tm->tei_m, EV_REMOVE, dp); else if (mt == ID_REQUEST && test_bit(FLG_LAPD_NET, &tm->l2->flag)) mISDN_FsmEvent(&tm->tei_m, EV_ASSIGN_REQ, dp); else { tm->tei_m.printdebug(&tm->tei_m, "tei handler wrong mt %x", mt); return(ret); } } dev_kfree_skb(skb); return(0); }
static void l2_restart_multi(struct FsmInst *fi, int event, void *arg) { struct layer2 *l2 = fi->userdata; struct sk_buff *skb = arg; int est = 0; send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP); l2mgr(l2, MDL_ERROR_IND, (void *) 'F'); if (l2->vs != l2->va) { skb_queue_purge(&l2->i_queue); est = 1; } clear_exception(l2); l2->vs = 0; l2->va = 0; l2->vr = 0; l2->sow = 0; mISDN_FsmChangeState(fi, ST_L2_7); stop_t200(l2, 3); mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3); if (est) l2up_create(l2, DL_ESTABLISH_IND, 0, NULL); /* mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST, * MGR_SHORTSTATUS | INDICATION, SSTATUS_L2_ESTABLISHED, * 0, NULL, 0); */ if (skb_queue_len(&l2->i_queue) && cansend(l2)) mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL); }
static void invoke_retransmission(struct layer2 *l2, unsigned int nr) { u_int p1; if (l2->vs != nr) { while (l2->vs != nr) { (l2->vs)--; if (test_bit(FLG_MOD128, &l2->flag)) { l2->vs %= 128; p1 = (l2->vs - l2->va) % 128; } else { l2->vs %= 8; p1 = (l2->vs - l2->va) % 8; } p1 = (p1 + l2->sow) % l2->window; if (l2->windowar[p1]) skb_queue_head(&l2->i_queue, l2->windowar[p1]); else printk(KERN_WARNING "%s: windowar[%d] is NULL\n", __func__, p1); l2->windowar[p1] = NULL; } mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL); } }
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 FsmExpireTimer(struct FsmTimer *ft) { #if FSM_TIMER_DEBUG if (ft->fi->debug) ft->fi->printdebug(ft->fi, "FsmExpireTimer %lx", (long) ft); #endif mISDN_FsmEvent(ft->fi, ft->event, ft->arg); }
static void lc_connect(struct FsmInst *fi, int event, void *arg) { layer3_t *l3 = fi->userdata; struct sk_buff *skb; int dequeued = 0; mISDN_FsmChangeState(fi, ST_L3_LC_ESTAB); while ((skb = skb_dequeue(&l3->squeue))) { if (l3down(l3, DL_DATA | REQUEST, l3_newid(l3), skb)) dev_kfree_skb(skb); dequeued++; } if (list_empty(&l3->plist) && dequeued) { if (l3->debug) l3m_debug(fi, "lc_connect: release link"); mISDN_FsmEvent(&l3->l3m, EV_RELEASE_REQ, NULL); } else l3ml3p(l3, DL_ESTABLISH | INDICATION); }
static void listen_req_l_x(struct FsmInst *fi, int event, void *arg, int state) { Application_t *app = fi->userdata; _cmsg *cmsg = arg; mISDN_FsmChangeState(fi, state); app->InfoMask = cmsg->InfoMask; app->CIPmask = cmsg->CIPmask; app->CIPmask2 = cmsg->CIPmask2; listenDebug(app, CAPI_DBG_LISTEN_INFO, "set InfoMask to 0x%x", app->InfoMask); listenDebug(app, CAPI_DBG_LISTEN_INFO, "set CIP to 0x%x,0x%x", app->CIPmask, app->CIPmask2); capi_cmsg_answer(cmsg); cmsg->Info = CAPI_NOERROR; if (mISDN_FsmEvent(&app->listen_m, EV_LISTEN_CONF, cmsg)) cmsg_free(cmsg); }
static int ph_data_confirm(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) { struct sk_buff *nskb = skb; int ret = -EAGAIN; if (test_bit(FLG_L1_NOTREADY, &l2->flag)) { if (hh->id == l2->down_id) { nskb = skb_dequeue(&l2->down_queue); if (nskb) { l2->down_id = mISDN_HEAD_ID(nskb); if (l2down_skb(l2, nskb)) { dev_kfree_skb(nskb); l2->down_id = MISDN_ID_NONE; } } else l2->down_id = MISDN_ID_NONE; if (ret) { dev_kfree_skb(skb); ret = 0; } if (l2->down_id == MISDN_ID_NONE) { test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag); mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL); } } } if (!test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) { nskb = skb_dequeue(&l2->down_queue); if (nskb) { l2->down_id = mISDN_HEAD_ID(nskb); if (l2down_skb(l2, nskb)) { dev_kfree_skb(nskb); l2->down_id = MISDN_ID_NONE; test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag); } } else test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag); } return ret; }
static void tei_id_test_dup(struct FsmInst *fi, int event, void *arg) { teimgr_t *otm, *tm = fi->userdata; u_char *dp = arg; int tei, ri; ri = ((unsigned int) *dp++ << 8); ri += *dp++; dp++; tei = *dp >> 1; if (tm->debug) tm->tei_m.printdebug(fi, "foreign identity assign ri %d tei %d", ri, tei); if ((otm = findtei(tm, tei))) { /* same tei is in use */ if (ri != otm->ri) { /* and it wasn't our request */ tm->tei_m.printdebug(fi, "possible duplicate assignment tei %d", tei); mISDN_FsmEvent(&otm->tei_m, EV_VERIFY, NULL); } } }
__u16 listenSendMessage(Application_t *app, struct sk_buff *skb) { _cmsg *cmsg; cmsg = cmsg_alloc(); if (!cmsg) { int_error(); return (CAPI_MSGOSRESOURCEERR); } capi_message2cmsg(cmsg, skb->data); switch (CMSGCMD(cmsg)) { case CAPI_LISTEN_REQ: if (mISDN_FsmEvent(&app->listen_m, EV_LISTEN_REQ, cmsg)) cmsg_free(cmsg); break; default: int_error(); cmsg_free(cmsg); } dev_kfree_skb(skb); return(CAPI_NOERROR); }
static void l2_connected(struct FsmInst *fi, int event, void *arg) { struct layer2 *l2 = fi->userdata; struct sk_buff *skb = arg; int pr = -1; if (!get_PollFlag(l2, skb)) { l2_mdl_error_ua(fi, event, arg); return; } dev_kfree_skb(skb); if (test_and_clear_bit(FLG_PEND_REL, &l2->flag)) l2_disconnect(fi, event, NULL); if (test_and_clear_bit(FLG_L3_INIT, &l2->flag)) { pr = DL_ESTABLISH_CNF; } else if (l2->vs != l2->va) { skb_queue_purge(&l2->i_queue); pr = DL_ESTABLISH_IND; } stop_t200(l2, 5); l2->vr = 0; l2->vs = 0; l2->va = 0; l2->sow = 0; mISDN_FsmChangeState(fi, ST_L2_7); mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 4); if (pr != -1) l2up_create(l2, pr, 0, NULL); if (skb_queue_len(&l2->i_queue) && cansend(l2)) mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL); if (l2->tm) l2_tei(l2, MDL_STATUS_UP_IND, 0); }
int l3_msg(layer3_t *l3, u_int pr, int dinfo, int len, void *arg) { switch (pr) { case (DL_DATA | REQUEST): if (l3->l3m.state == ST_L3_LC_ESTAB) { return(l3down(l3, pr, l3_newid(l3), arg)); } else { struct sk_buff *skb = arg; // printk(KERN_DEBUG "%s: queue skb %p len(%d)\n", // __FUNCTION__, skb, skb->len); skb_queue_tail(&l3->squeue, skb); mISDN_FsmEvent(&l3->l3m, EV_ESTABLISH_REQ, NULL); } break; case (DL_ESTABLISH | REQUEST): mISDN_FsmEvent(&l3->l3m, EV_ESTABLISH_REQ, NULL); break; case (DL_ESTABLISH | CONFIRM): mISDN_FsmEvent(&l3->l3m, EV_ESTABLISH_CNF, NULL); break; case (DL_ESTABLISH | INDICATION): mISDN_FsmEvent(&l3->l3m, EV_ESTABLISH_IND, NULL); break; case (DL_RELEASE | INDICATION): mISDN_FsmEvent(&l3->l3m, EV_RELEASE_IND, NULL); break; case (DL_RELEASE | CONFIRM): mISDN_FsmEvent(&l3->l3m, EV_RELEASE_CNF, NULL); break; case (DL_RELEASE | REQUEST): mISDN_FsmEvent(&l3->l3m, EV_RELEASE_REQ, NULL); break; } return(0); }
int l1_event(struct layer1 *l1, u_int event) { int err = 0; if (!l1) return -EINVAL; switch (event) { case HW_RESET_IND: mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL); break; case HW_DEACT_IND: mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL); break; case HW_POWERUP_IND: mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL); break; case HW_DEACT_CNF: mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL); break; case ANYSIGNAL: mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); break; case LOSTFRAMING: mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); break; case INFO2: mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL); break; case INFO4_P8: mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); break; case INFO4_P10: mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); break; case PH_ACTIVATE_REQ: if (test_bit(FLG_L1_ACTIVATED, &l1->Flags)) l1->dcb(l1->dch, PH_ACTIVATE_IND); else { test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags); mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL); } break; case CLOSE_CHANNEL: release_l1(l1); break; default: if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) { int val = event & HW_TIMER3_VMASK; if (val < 5) val = 5; if (val > 30) val = 30; l1->t3_value = val; break; } if (*debug & DEBUG_L1) printk(KERN_DEBUG "%s %x unhandled\n", __func__, event); err = -EINVAL; } return err; }