^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author Karsten Keil <kkeil@novell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2008 by Karsten Keil <kkeil@novell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "layer2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define ID_REQUEST 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define ID_ASSIGNED 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define ID_DENIED 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define ID_CHK_REQ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define ID_CHK_RES 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define ID_REMOVE 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define ID_VERIFY 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define TEI_ENTITY_ID 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define MGR_PH_ACTIVE 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define MGR_PH_NOTREADY 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define DATIMER_VAL 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static u_int *debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static struct Fsm deactfsm = {NULL, 0, 0, NULL, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static struct Fsm teifsmu = {NULL, 0, 0, NULL, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static struct Fsm teifsmn = {NULL, 0, 0, NULL, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) ST_L1_DEACT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ST_L1_DEACT_PENDING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) ST_L1_ACTIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define DEACT_STATE_COUNT (ST_L1_ACTIV + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static char *strDeactState[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) "ST_L1_DEACT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) "ST_L1_DEACT_PENDING",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) "ST_L1_ACTIV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) EV_ACTIVATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) EV_ACTIVATE_IND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) EV_DEACTIVATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) EV_DEACTIVATE_IND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) EV_UI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) EV_DATIMER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define DEACT_EVENT_COUNT (EV_DATIMER + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static char *strDeactEvent[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) "EV_ACTIVATE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) "EV_ACTIVATE_IND",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) "EV_DEACTIVATE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) "EV_DEACTIVATE_IND",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) "EV_UI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) "EV_DATIMER",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) da_debug(struct FsmInst *fi, char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct manager *mgr = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) va_list va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (!(*debug & DEBUG_L2_TEIFSM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) va_start(va, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) vaf.va = &va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) printk(KERN_DEBUG "mgr(%d): %pV\n", mgr->ch.st->dev->id, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) va_end(va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) da_activate(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct manager *mgr = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (fi->state == ST_L1_DEACT_PENDING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) mISDN_FsmDelTimer(&mgr->datimer, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) mISDN_FsmChangeState(fi, ST_L1_ACTIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) da_deactivate_ind(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mISDN_FsmChangeState(fi, ST_L1_DEACT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) da_deactivate(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct manager *mgr = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) read_lock_irqsave(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) list_for_each_entry(l2, &mgr->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (l2->l2m.state > ST_L2_4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* have still activ TEI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) read_unlock_irqrestore(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) read_unlock_irqrestore(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* All TEI are inactiv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) NULL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) da_ui(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct manager *mgr = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* restart da timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) mISDN_FsmDelTimer(&mgr->datimer, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) NULL, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) da_timer(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct manager *mgr = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* check again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) read_lock_irqsave(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) list_for_each_entry(l2, &mgr->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (l2->l2m.state > ST_L2_4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* have still activ TEI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) read_unlock_irqrestore(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) mISDN_FsmChangeState(fi, ST_L1_ACTIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) read_unlock_irqrestore(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* All TEI are inactiv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) mISDN_FsmChangeState(fi, ST_L1_DEACT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) _queue_data(&mgr->ch, PH_DEACTIVATE_REQ, MISDN_ID_ANY, 0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static struct FsmNode DeactFnList[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {ST_L1_DEACT, EV_ACTIVATE_IND, da_activate},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {ST_L1_ACTIV, EV_DEACTIVATE_IND, da_deactivate_ind},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {ST_L1_ACTIV, EV_DEACTIVATE, da_deactivate},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {ST_L1_DEACT_PENDING, EV_ACTIVATE, da_activate},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {ST_L1_DEACT_PENDING, EV_UI, da_ui},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {ST_L1_DEACT_PENDING, EV_DATIMER, da_timer},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ST_TEI_NOP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ST_TEI_IDREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ST_TEI_IDVERIFY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define TEI_STATE_COUNT (ST_TEI_IDVERIFY + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static char *strTeiState[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) "ST_TEI_NOP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) "ST_TEI_IDREQ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) "ST_TEI_IDVERIFY",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) EV_IDREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) EV_ASSIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) EV_ASSIGN_REQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) EV_DENIED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) EV_CHKREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) EV_CHKRESP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) EV_REMOVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) EV_VERIFY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) EV_TIMER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define TEI_EVENT_COUNT (EV_TIMER + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static char *strTeiEvent[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) "EV_IDREQ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) "EV_ASSIGN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) "EV_ASSIGN_REQ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) "EV_DENIED",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) "EV_CHKREQ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) "EV_CHKRESP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) "EV_REMOVE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) "EV_VERIFY",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) "EV_TIMER",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) tei_debug(struct FsmInst *fi, char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) va_list va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (!(*debug & DEBUG_L2_TEIFSM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) va_start(va, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) vaf.va = &va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) printk(KERN_DEBUG "sapi(%d) tei(%d): %pV\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) tm->l2->sapi, tm->l2->tei, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) va_end(va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) get_free_id(struct manager *mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) DECLARE_BITMAP(ids, 64) = { [0 ... BITS_TO_LONGS(64) - 1] = 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) list_for_each_entry(l2, &mgr->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (l2->ch.nr > 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) "%s: more as 63 layer2 for one device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) __set_bit(l2->ch.nr, ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) i = find_next_zero_bit(ids, 64, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (i < 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) printk(KERN_WARNING "%s: more as 63 layer2 for one device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) get_free_tei(struct manager *mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) DECLARE_BITMAP(ids, 64) = { [0 ... BITS_TO_LONGS(64) - 1] = 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) list_for_each_entry(l2, &mgr->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (l2->ch.nr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if ((l2->ch.addr & 0xff) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) i = l2->ch.addr >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (i < 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) i -= 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) __set_bit(i, ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) i = find_first_zero_bit(ids, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (i < 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return i + 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) printk(KERN_WARNING "%s: more as 63 dynamic tei for one device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) teiup_create(struct manager *mgr, u_int prim, int len, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct mISDNhead *hh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) skb = mI_alloc_skb(len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) hh->prim = prim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) hh->id = (mgr->ch.nr << 16) | mgr->ch.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) skb_put_data(skb, arg, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) err = mgr->up->send(mgr->up, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) printk(KERN_WARNING "%s: err=%d\n", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static u_int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) new_id(struct manager *mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) u_int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) id = mgr->nextid++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (id == 0x7fff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) mgr->nextid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) id <<= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) id |= GROUP_TEI << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) id |= TEI_SAPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) do_send(struct manager *mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!test_bit(MGR_PH_ACTIVE, &mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (!test_and_set_bit(MGR_PH_NOTREADY, &mgr->options)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct sk_buff *skb = skb_dequeue(&mgr->sendq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) mgr->lastid = mISDN_HEAD_ID(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) mISDN_FsmEvent(&mgr->deact, EV_UI, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (mgr->ch.recv(mgr->ch.peer, skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) mgr->lastid = MISDN_ID_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) do_ack(struct manager *mgr, u_int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (test_bit(MGR_PH_NOTREADY, &mgr->options)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (id == mgr->lastid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (test_bit(MGR_PH_ACTIVE, &mgr->options)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) skb = skb_dequeue(&mgr->sendq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) mgr->lastid = mISDN_HEAD_ID(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (!mgr->ch.recv(mgr->ch.peer, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) mgr->lastid = MISDN_ID_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) mgr_send_down(struct manager *mgr, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) skb_queue_tail(&mgr->sendq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (!test_bit(MGR_PH_ACTIVE, &mgr->options)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) _queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) do_send(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) dl_unit_data(struct manager *mgr, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!test_bit(MGR_OPT_NETWORK, &mgr->options)) /* only net send UI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (!test_bit(MGR_PH_ACTIVE, &mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) _queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) skb_push(skb, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) skb->data[0] = 0x02; /* SAPI 0 C/R = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) skb->data[1] = 0xff; /* TEI 127 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) skb->data[2] = UI; /* UI frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) mISDN_HEAD_PRIM(skb) = PH_DATA_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) mISDN_HEAD_ID(skb) = new_id(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) skb_queue_tail(&mgr->sendq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) do_send(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) random_ri(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) u16 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) get_random_bytes(&x, sizeof(x));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static struct layer2 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) findtei(struct manager *mgr, int tei)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) read_lock_irqsave(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) list_for_each_entry(l2, &mgr->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if ((l2->sapi == 0) && (l2->tei > 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) (l2->tei != GROUP_TEI) && (l2->tei == tei))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) l2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) read_unlock_irqrestore(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, int tei)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) u_char bp[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) bp[0] = (TEI_SAPI << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (test_bit(MGR_OPT_NETWORK, &mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) bp[0] |= 2; /* CR:=1 for net command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) bp[1] = (GROUP_TEI << 1) | 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) bp[2] = UI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) bp[3] = TEI_ENTITY_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) bp[4] = ri >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) bp[5] = ri & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) bp[6] = m_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) bp[7] = ((tei << 1) & 0xff) | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), 8, bp, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) printk(KERN_WARNING "%s: no skb for tei msg\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) mgr_send_down(mgr, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) tei_id_request(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (tm->l2->tei != GROUP_TEI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) tm->tei_m.printdebug(&tm->tei_m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) "assign request for already assigned tei %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) tm->ri = random_ri();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) tm->tei_m.printdebug(&tm->tei_m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) "assign request ri %d", tm->ri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) mISDN_FsmChangeState(fi, ST_TEI_IDREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) tm->nval = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) tei_id_assign(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) u_char *dp = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int ri, tei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ri = ((unsigned int) *dp++ << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ri += *dp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) dp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) tei = *dp >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) tm->tei_m.printdebug(fi, "identity assign ri %d tei %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ri, tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) l2 = findtei(tm->mgr, tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (l2) { /* same tei is in use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (ri != l2->tm->ri) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) tm->tei_m.printdebug(fi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) "possible duplicate assignment tei %d", tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) tei_l2(l2, MDL_ERROR_RSP, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) } else if (ri == tm->ri) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) mISDN_FsmDelTimer(&tm->timer, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) mISDN_FsmChangeState(fi, ST_TEI_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) tei_l2(tm->l2, MDL_ASSIGN_REQ, tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) tei_id_test_dup(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) u_char *dp = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) int tei, ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) ri = ((unsigned int) *dp++ << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ri += *dp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) tei = *dp >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) tm->tei_m.printdebug(fi, "foreign identity assign ri %d tei %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ri, tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) l2 = findtei(tm->mgr, tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (l2) { /* same tei is in use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (ri != l2->tm->ri) { /* and it wasn't our request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) tm->tei_m.printdebug(fi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) "possible duplicate assignment tei %d", tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) mISDN_FsmEvent(&l2->tm->tei_m, EV_VERIFY, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) tei_id_denied(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) u_char *dp = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int ri, tei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ri = ((unsigned int) *dp++ << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ri += *dp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) tei = *dp >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) tm->tei_m.printdebug(fi, "identity denied ri %d tei %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ri, tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) tei_id_chk_req(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) u_char *dp = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) int tei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) tei = *(dp + 3) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) tm->tei_m.printdebug(fi, "identity check req tei %d", tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if ((tm->l2->tei != GROUP_TEI) && ((tei == GROUP_TEI) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) (tei == tm->l2->tei))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) mISDN_FsmDelTimer(&tm->timer, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) mISDN_FsmChangeState(&tm->tei_m, ST_TEI_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) put_tei_msg(tm->mgr, ID_CHK_RES, random_ri(), tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) tei_id_remove(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) u_char *dp = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) int tei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) tei = *(dp + 3) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) tm->tei_m.printdebug(fi, "identity remove tei %d", tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if ((tm->l2->tei != GROUP_TEI) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) ((tei == GROUP_TEI) || (tei == tm->l2->tei))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) mISDN_FsmDelTimer(&tm->timer, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) mISDN_FsmChangeState(&tm->tei_m, ST_TEI_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) tei_l2(tm->l2, MDL_REMOVE_REQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) tei_id_verify(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) tm->tei_m.printdebug(fi, "id verify request for tei %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) tm->nval = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) tei_id_req_tout(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (--tm->nval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) tm->ri = random_ri();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) tm->tei_m.printdebug(fi, "assign req(%d) ri %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 4 - tm->nval, tm->ri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) tm->tei_m.printdebug(fi, "assign req failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) tei_l2(tm->l2, MDL_ERROR_RSP, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) mISDN_FsmChangeState(fi, ST_TEI_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) tei_id_ver_tout(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (--tm->nval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) tm->tei_m.printdebug(fi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) "id verify req(%d) for tei %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 3 - tm->nval, tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) tm->tei_m.printdebug(fi, "verify req for tei %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) tei_l2(tm->l2, MDL_REMOVE_REQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) mISDN_FsmChangeState(fi, ST_TEI_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static struct FsmNode TeiFnListUser[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {ST_TEI_NOP, EV_IDREQ, tei_id_request},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {ST_TEI_NOP, EV_ASSIGN, tei_id_test_dup},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {ST_TEI_NOP, EV_VERIFY, tei_id_verify},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {ST_TEI_NOP, EV_REMOVE, tei_id_remove},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {ST_TEI_IDREQ, EV_TIMER, tei_id_req_tout},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {ST_TEI_IDREQ, EV_ASSIGN, tei_id_assign},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {ST_TEI_IDREQ, EV_DENIED, tei_id_denied},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {ST_TEI_IDVERIFY, EV_TIMER, tei_id_ver_tout},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {ST_TEI_IDVERIFY, EV_REMOVE, tei_id_remove},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) tei_l2remove(struct layer2 *l2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) put_tei_msg(l2->tm->mgr, ID_REMOVE, 0, l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) tei_l2(l2, MDL_REMOVE_REQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) list_del(&l2->ch.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) tei_assign_req(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) u_char *dp = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (tm->l2->tei == GROUP_TEI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) tm->tei_m.printdebug(&tm->tei_m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) "net tei assign request without tei");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) tm->ri = ((unsigned int) *dp++ << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) tm->ri += *dp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) tm->tei_m.printdebug(&tm->tei_m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) "net assign request ri %d teim %d", tm->ri, *dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) put_tei_msg(tm->mgr, ID_ASSIGNED, tm->ri, tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) mISDN_FsmChangeState(fi, ST_TEI_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) tei_id_chk_req_net(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) tm->tei_m.printdebug(fi, "id check request for tei %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) tm->rcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) tm->nval = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) tei_id_chk_resp(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) u_char *dp = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) int tei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) tei = dp[3] >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) tm->tei_m.printdebug(fi, "identity check resp tei %d", tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (tei == tm->l2->tei)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) tm->rcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) tei_id_verify_net(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) u_char *dp = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) int tei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) tei = dp[3] >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) tm->tei_m.printdebug(fi, "identity verify req tei %d/%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) tei, tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (tei == tm->l2->tei)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) tei_id_chk_req_net(fi, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) tei_id_ver_tout_net(struct FsmInst *fi, int event, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct teimgr *tm = fi->userdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (tm->rcnt == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) tm->tei_m.printdebug(fi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) "check req for tei %d successful\n", tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) mISDN_FsmChangeState(fi, ST_TEI_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) } else if (tm->rcnt > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* duplicate assignment; remove */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) tei_l2remove(tm->l2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) } else if (--tm->nval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) tm->tei_m.printdebug(fi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) "id check req(%d) for tei %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 3 - tm->nval, tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) tm->tei_m.printdebug(fi, "check req for tei %d failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) tm->l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) mISDN_FsmChangeState(fi, ST_TEI_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) tei_l2remove(tm->l2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static struct FsmNode TeiFnListNet[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {ST_TEI_NOP, EV_ASSIGN_REQ, tei_assign_req},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {ST_TEI_NOP, EV_VERIFY, tei_id_verify_net},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req_net},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {ST_TEI_IDVERIFY, EV_TIMER, tei_id_ver_tout_net},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {ST_TEI_IDVERIFY, EV_CHKRESP, tei_id_chk_resp},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (test_bit(FLG_FIXED_TEI, &tm->l2->flag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) tm->tei_m.printdebug(&tm->tei_m, "tei handler mt %x", mt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (mt == ID_ASSIGNED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) mISDN_FsmEvent(&tm->tei_m, EV_ASSIGN, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) else if (mt == ID_DENIED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) mISDN_FsmEvent(&tm->tei_m, EV_DENIED, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) else if (mt == ID_CHK_REQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) else if (mt == ID_REMOVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) mISDN_FsmEvent(&tm->tei_m, EV_REMOVE, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) else if (mt == ID_VERIFY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) else if (mt == ID_CHK_RES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) mISDN_FsmEvent(&tm->tei_m, EV_CHKRESP, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) static struct layer2 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) create_new_tei(struct manager *mgr, int tei, int sapi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) unsigned long opt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct channel_req rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (!mgr->up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if ((tei >= 0) && (tei < 64))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (mgr->ch.st->dev->Dprotocols & ((1 << ISDN_P_TE_E1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) (1 << ISDN_P_NT_E1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) test_and_set_bit(OPTION_L2_PMX, &opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) rq.protocol = ISDN_P_NT_E1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) rq.protocol = ISDN_P_NT_S0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (!l2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) printk(KERN_WARNING "%s:no memory for layer2\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (!l2->tm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) kfree(l2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) printk(KERN_WARNING "%s:no memory for teimgr\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) l2->tm->mgr = mgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) l2->tm->l2 = l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) l2->tm->tei_m.debug = *debug & DEBUG_L2_TEIFSM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) l2->tm->tei_m.userdata = l2->tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) l2->tm->tei_m.printdebug = tei_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) l2->tm->tei_m.fsm = &teifsmn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) l2->tm->tei_m.state = ST_TEI_NOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) l2->tm->tval = 2000; /* T202 2 sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) write_lock_irqsave(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) id = get_free_id(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) list_add_tail(&l2->list, &mgr->layer2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) write_unlock_irqrestore(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) printk(KERN_WARNING "%s:no free id\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) l2->ch.nr = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) __add_layer2(&l2->ch, mgr->ch.st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) l2->ch.recv = mgr->ch.recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) l2->ch.peer = mgr->ch.peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* We need open here L1 for the manager as well (refcounting) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) rq.adr.dev = mgr->ch.st->dev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) id = mgr->ch.st->own.ctrl(&mgr->ch.st->own, OPEN_CHANNEL, &rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) printk(KERN_WARNING "%s: cannot open L1\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) l2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) new_tei_req(struct manager *mgr, u_char *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) int tei, ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) ri = dp[0] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ri += dp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (!mgr->up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) goto denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (!(dp[3] & 1)) /* Extension bit != 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) goto denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (dp[3] != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) tei = dp[3] >> 1; /* 3GPP TS 08.56 6.1.11.2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) tei = get_free_tei(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (tei < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) printk(KERN_WARNING "%s:No free tei\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) goto denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) l2 = create_new_tei(mgr, tei, CTRL_SAPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (!l2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) goto denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) mISDN_FsmEvent(&l2->tm->tei_m, EV_ASSIGN_REQ, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) denied:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) put_tei_msg(mgr, ID_DENIED, ri, GROUP_TEI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ph_data_ind(struct manager *mgr, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) struct layer2 *l2, *nl2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) u_char mt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (skb->len < 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) printk(KERN_DEBUG "%s: short mgr frame %d/8\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) __func__, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if ((skb->data[0] >> 2) != TEI_SAPI) /* not for us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (skb->data[0] & 1) /* EA0 formal error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (!(skb->data[1] & 1)) /* EA1 formal error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if ((skb->data[1] >> 1) != GROUP_TEI) /* not for us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if ((skb->data[2] & 0xef) != UI) /* not UI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (skb->data[3] != TEI_ENTITY_ID) /* not tei entity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) mt = skb->data[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) switch (mt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) case ID_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) case ID_CHK_RES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) case ID_VERIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (!test_bit(MGR_OPT_NETWORK, &mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) case ID_ASSIGNED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) case ID_DENIED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) case ID_CHK_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) case ID_REMOVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (test_bit(MGR_OPT_NETWORK, &mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (mt == ID_REQUEST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) new_tei_req(mgr, &skb->data[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) l2_tei(struct layer2 *l2, u_int cmd, u_long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) struct teimgr *tm = l2->tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (test_bit(FLG_FIXED_TEI, &l2->flag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) printk(KERN_DEBUG "%s: cmd(%x)\n", __func__, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) case MDL_ASSIGN_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) mISDN_FsmEvent(&tm->tei_m, EV_IDREQ, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) case MDL_ERROR_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, &l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (test_bit(MGR_OPT_USER, &tm->mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) case MDL_STATUS_UP_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) mISDN_FsmEvent(&tm->mgr->deact, EV_ACTIVATE, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) case MDL_STATUS_DOWN_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) mISDN_FsmEvent(&tm->mgr->deact, EV_DEACTIVATE, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) case MDL_STATUS_UI_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) mISDN_FsmEvent(&tm->mgr->deact, EV_UI, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) TEIrelease(struct layer2 *l2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) struct teimgr *tm = l2->tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) mISDN_FsmDelTimer(&tm->timer, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) write_lock_irqsave(&tm->mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) list_del(&l2->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) write_unlock_irqrestore(&tm->mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) l2->tm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) kfree(tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) create_teimgr(struct manager *mgr, struct channel_req *crq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) unsigned long opt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) struct channel_req l1rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (*debug & DEBUG_L2_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) __func__, dev_name(&mgr->ch.st->dev->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) crq->protocol, crq->adr.dev, crq->adr.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) crq->adr.sapi, crq->adr.tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (crq->adr.tei > GROUP_TEI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (crq->adr.tei < 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (crq->adr.tei == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) test_and_set_bit(OPTION_L2_PTP, &opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (crq->protocol == ISDN_P_LAPD_TE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if ((crq->adr.tei != 0) && (crq->adr.tei != 127))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (mgr->up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) "%s: only one network manager is allowed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) } else if (test_bit(MGR_OPT_USER, &mgr->options)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (crq->protocol == ISDN_P_LAPD_NT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if ((crq->adr.tei >= 64) && (crq->adr.tei < GROUP_TEI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return -EINVAL; /* dyn tei */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (crq->protocol == ISDN_P_LAPD_NT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) test_and_set_bit(MGR_OPT_NETWORK, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (crq->protocol == ISDN_P_LAPD_TE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) test_and_set_bit(MGR_OPT_USER, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) l1rq.adr = crq->adr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (mgr->ch.st->dev->Dprotocols
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) test_and_set_bit(OPTION_L2_PMX, &opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if ((crq->protocol == ISDN_P_LAPD_NT) && (crq->adr.tei == 127)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) mgr->up = crq->ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) id = DL_INFO_L2_CONNECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) teiup_create(mgr, DL_INFORMATION_IND, sizeof(id), &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (test_bit(MGR_PH_ACTIVE, &mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) teiup_create(mgr, PH_ACTIVATE_IND, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) crq->ch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (!list_empty(&mgr->layer2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) read_lock_irqsave(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) list_for_each_entry(l2, &mgr->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) l2->up = mgr->up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) read_unlock_irqrestore(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) l2 = create_l2(crq->ch, crq->protocol, opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) crq->adr.tei, crq->adr.sapi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (!l2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (!l2->tm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) kfree(l2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) printk(KERN_ERR "kmalloc teimgr failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) l2->tm->mgr = mgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) l2->tm->l2 = l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) l2->tm->tei_m.debug = *debug & DEBUG_L2_TEIFSM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) l2->tm->tei_m.userdata = l2->tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) l2->tm->tei_m.printdebug = tei_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (crq->protocol == ISDN_P_LAPD_TE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) l2->tm->tei_m.fsm = &teifsmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) l2->tm->tei_m.state = ST_TEI_NOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) l2->tm->tval = 1000; /* T201 1 sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (test_bit(OPTION_L2_PMX, &opt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) l1rq.protocol = ISDN_P_TE_E1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) l1rq.protocol = ISDN_P_TE_S0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) l2->tm->tei_m.fsm = &teifsmn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) l2->tm->tei_m.state = ST_TEI_NOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) l2->tm->tval = 2000; /* T202 2 sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (test_bit(OPTION_L2_PMX, &opt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) l1rq.protocol = ISDN_P_NT_E1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) l1rq.protocol = ISDN_P_NT_S0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) write_lock_irqsave(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) id = get_free_id(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) list_add_tail(&l2->list, &mgr->layer2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) write_unlock_irqrestore(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (id >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) l2->ch.nr = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) l2->up->nr = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) crq->ch = &l2->ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) /* We need open here L1 for the manager as well (refcounting) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) id = mgr->ch.st->own.ctrl(&mgr->ch.st->own, OPEN_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) &l1rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) mgr_send(struct mISDNchannel *ch, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) struct manager *mgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) struct mISDNhead *hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) mgr = container_of(ch, struct manager, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (*debug & DEBUG_L2_RECV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) printk(KERN_DEBUG "%s: prim(%x) id(%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) __func__, hh->prim, hh->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) switch (hh->prim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) case PH_DATA_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) mISDN_FsmEvent(&mgr->deact, EV_UI, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) ret = ph_data_ind(mgr, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) case PH_DATA_CNF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) do_ack(mgr, hh->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) case PH_ACTIVATE_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) test_and_set_bit(MGR_PH_ACTIVE, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (mgr->up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) teiup_create(mgr, PH_ACTIVATE_IND, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) mISDN_FsmEvent(&mgr->deact, EV_ACTIVATE_IND, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) do_send(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) case PH_DEACTIVATE_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) test_and_clear_bit(MGR_PH_ACTIVE, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (mgr->up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) teiup_create(mgr, PH_DEACTIVATE_IND, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) mISDN_FsmEvent(&mgr->deact, EV_DEACTIVATE_IND, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) case DL_UNITDATA_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return dl_unit_data(mgr, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) free_teimanager(struct manager *mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct layer2 *l2, *nl2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /* not locked lock is taken in release tei */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) mgr->up = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (test_bit(OPTION_L2_CLEANUP, &mgr->options)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) put_tei_msg(mgr, ID_REMOVE, 0, l2->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) mutex_lock(&mgr->ch.st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) list_del(&l2->ch.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) mutex_unlock(&mgr->ch.st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) test_and_clear_bit(MGR_OPT_NETWORK, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) l2->up = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (test_bit(MGR_OPT_USER, &mgr->options)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (list_empty(&mgr->layer2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) test_and_clear_bit(MGR_OPT_USER, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) mgr->ch.st->dev->D.ctrl(&mgr->ch.st->dev->D, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) ctrl_teimanager(struct manager *mgr, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) /* currently we only have one option */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) unsigned int *val = (unsigned int *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) switch (val[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) case IMCLEAR_L2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (val[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) case IMHOLD_L1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (val[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) test_and_set_bit(OPTION_L1_HOLD, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) /* This function does create a L2 for fixed TEI in NT Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) check_data(struct manager *mgr, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) struct mISDNhead *hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) int ret, tei, sapi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (*debug & DEBUG_L2_CTRL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) printk(KERN_DEBUG "%s: prim(%x) id(%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) __func__, hh->prim, hh->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (test_bit(MGR_OPT_USER, &mgr->options))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (hh->prim != PH_DATA_IND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (skb->len != 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (skb->data[0] & 3) /* EA0 and CR must be 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) sapi = skb->data[0] >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (!(skb->data[1] & 1)) /* invalid EA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) tei = skb->data[1] >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (tei > 63) /* not a fixed tei */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if ((skb->data[2] & ~0x10) != SABME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) /* We got a SABME for a fixed TEI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (*debug & DEBUG_L2_CTRL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) printk(KERN_DEBUG "%s: SABME sapi(%d) tei(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) __func__, sapi, tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) l2 = create_new_tei(mgr, tei, sapi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (!l2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (*debug & DEBUG_L2_CTRL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) printk(KERN_DEBUG "%s: failed to create new tei\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) ret = l2->ch.send(&l2->ch, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) delete_teimanager(struct mISDNchannel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) struct manager *mgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) struct layer2 *l2, *nl2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) mgr = container_of(ch, struct manager, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) /* not locked lock is taken in release tei */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) mutex_lock(&mgr->ch.st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) list_del(&l2->ch.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) mutex_unlock(&mgr->ch.st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) list_del(&mgr->ch.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) list_del(&mgr->bcast.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) skb_queue_purge(&mgr->sendq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) kfree(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) mgr_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) struct manager *mgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) mgr = container_of(ch, struct manager, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) if (*debug & DEBUG_L2_CTRL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) printk(KERN_DEBUG "%s(%x, %p)\n", __func__, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) case OPEN_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) ret = create_teimgr(mgr, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) case CLOSE_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) ret = free_teimanager(mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) case CONTROL_CHANNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) ret = ctrl_teimanager(mgr, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) case CHECK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) ret = check_data(mgr, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) mgr_bcast(struct mISDNchannel *ch, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) struct manager *mgr = container_of(ch, struct manager, bcast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) struct mISDNhead *hhc, *hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) struct sk_buff *cskb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) struct layer2 *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) u_long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) read_lock_irqsave(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) list_for_each_entry(l2, &mgr->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if ((hh->id & MISDN_ID_SAPI_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) (l2->ch.addr & MISDN_ID_SAPI_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (list_is_last(&l2->list, &mgr->layer2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) cskb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (!cskb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) cskb = skb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (cskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) hhc = mISDN_HEAD_P(cskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) /* save original header behind normal header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) hhc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) *hhc = *hh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) hhc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) hhc->prim = DL_INTERN_MSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) hhc->id = l2->ch.nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) ret = ch->st->own.recv(&ch->st->own, cskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if (*debug & DEBUG_SEND_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) "%s ch%d prim(%x) addr(%x)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) " err %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) __func__, l2->ch.nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) hh->prim, l2->ch.addr, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) cskb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) printk(KERN_WARNING "%s ch%d addr %x no mem\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) __func__, ch->nr, ch->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) read_unlock_irqrestore(&mgr->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) dev_kfree_skb(cskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) mgr_bcast_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) create_teimanager(struct mISDNdevice *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) struct manager *mgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) mgr = kzalloc(sizeof(struct manager), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (!mgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) INIT_LIST_HEAD(&mgr->layer2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) rwlock_init(&mgr->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) skb_queue_head_init(&mgr->sendq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) mgr->nextid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) mgr->lastid = MISDN_ID_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) mgr->ch.send = mgr_send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) mgr->ch.ctrl = mgr_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) mgr->ch.st = dev->D.st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) set_channel_address(&mgr->ch, TEI_SAPI, GROUP_TEI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) add_layer2(&mgr->ch, dev->D.st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) mgr->bcast.send = mgr_bcast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) mgr->bcast.ctrl = mgr_bcast_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) mgr->bcast.st = dev->D.st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) set_channel_address(&mgr->bcast, 0, GROUP_TEI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) add_layer2(&mgr->bcast, dev->D.st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) mgr->deact.debug = *debug & DEBUG_MANAGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) mgr->deact.userdata = mgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) mgr->deact.printdebug = da_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) mgr->deact.fsm = &deactfsm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) mgr->deact.state = ST_L1_DEACT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) mISDN_FsmInitTimer(&mgr->deact, &mgr->datimer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) dev->teimgr = &mgr->ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) int TEIInit(u_int *deb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) debug = deb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) teifsmu.state_count = TEI_STATE_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) teifsmu.event_count = TEI_EVENT_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) teifsmu.strEvent = strTeiEvent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) teifsmu.strState = strTeiState;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) res = mISDN_FsmNew(&teifsmu, TeiFnListUser, ARRAY_SIZE(TeiFnListUser));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) teifsmn.state_count = TEI_STATE_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) teifsmn.event_count = TEI_EVENT_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) teifsmn.strEvent = strTeiEvent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) teifsmn.strState = strTeiState;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) res = mISDN_FsmNew(&teifsmn, TeiFnListNet, ARRAY_SIZE(TeiFnListNet));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) goto error_smn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) deactfsm.state_count = DEACT_STATE_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) deactfsm.event_count = DEACT_EVENT_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) deactfsm.strEvent = strDeactEvent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) deactfsm.strState = strDeactState;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) res = mISDN_FsmNew(&deactfsm, DeactFnList, ARRAY_SIZE(DeactFnList));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) goto error_deact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) error_deact:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) mISDN_FsmFree(&teifsmn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) error_smn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) mISDN_FsmFree(&teifsmu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) void TEIFree(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) mISDN_FsmFree(&teifsmu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) mISDN_FsmFree(&teifsmn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) mISDN_FsmFree(&deactfsm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }