1 /* $Id: tei.c,v 2.20.2.3 2004/01/13 14:31:26 keil Exp $
 
   4  *              based on the teles driver from Jan den Ouden
 
   5  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
 
   7  * This software may be used and distributed according to the terms
 
   8  * of the GNU General Public License, incorporated herein by reference.
 
  10  * For changes and modifications please read
 
  11  * Documentation/isdn/HiSax.cert
 
  13  * Thanks to    Jan den Ouden
 
  20 #include <linux/init.h>
 
  21 #include <linux/random.h>
 
  23 const char *tei_revision = "$Revision: 2.20.2.3 $";
 
  33 #define TEI_ENTITY_ID   0xf
 
  35 static struct Fsm teifsm;
 
  37 void tei_handler(struct PStack *st, u_char pr, struct sk_buff *skb);
 
  45 #define TEI_STATE_COUNT (ST_TEI_IDVERIFY+1)
 
  47 static char *strTeiState[] =
 
  64 #define TEI_EVENT_COUNT (EV_T202+1)
 
  66 static char *strTeiEvent[] =
 
  82         get_random_bytes(&x, sizeof(x));
 
  86 static struct PStack *
 
  87 findtei(struct PStack *st, int tei)
 
  89         struct PStack *ptr = *(st->l1.stlistp);
 
  95                 if (ptr->l2.tei == tei)
 
 103 put_tei_msg(struct PStack *st, u_char m_id, unsigned int ri, u_char tei)
 
 108         if (!(skb = alloc_skb(8, GFP_ATOMIC))) {
 
 109                 printk(KERN_WARNING "HiSax: No skb for TEI manager\n");
 
 112         bp = skb_put(skb, 3);
 
 113         bp[0] = (TEI_SAPI << 2);
 
 114         bp[1] = (GROUP_TEI << 1) | 0x1;
 
 116         bp = skb_put(skb, 5);
 
 117         bp[0] = TEI_ENTITY_ID;
 
 121         bp[4] = (tei << 1) | 1;
 
 122         st->l2.l2l1(st, PH_DATA | REQUEST, skb);
 
 126 tei_id_request(struct FsmInst *fi, int event, void *arg)
 
 128         struct PStack *st = fi->userdata;
 
 130         if (st->l2.tei != -1) {
 
 131                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 132                         "assign request for allready asigned tei %d",
 
 136         st->ma.ri = random_ri();
 
 138                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 139                         "assign request ri %d", st->ma.ri);
 
 140         put_tei_msg(st, ID_REQUEST, st->ma.ri, 127);
 
 141         FsmChangeState(&st->ma.tei_m, ST_TEI_IDREQ);
 
 142         FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 1);
 
 147 tei_id_assign(struct FsmInst *fi, int event, void *arg)
 
 149         struct PStack *ost, *st = fi->userdata;
 
 150         struct sk_buff *skb = arg;
 
 151         struct IsdnCardState *cs;
 
 154         ri = ((unsigned int) skb->data[1] << 8) + skb->data[2];
 
 155         tei = skb->data[4] >> 1;
 
 157                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 158                         "identity assign ri %d tei %d", ri, tei);
 
 159         if ((ost = findtei(st, tei))) { /* same tei is in use */
 
 160                 if (ri != ost->ma.ri) {
 
 161                         st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 162                                 "possible duplicate assignment tei %d", tei);
 
 163                         ost->l2.l2tei(ost, MDL_ERROR | RESPONSE, NULL);
 
 165         } else if (ri == st->ma.ri) {
 
 166                 FsmDelTimer(&st->ma.t202, 1);
 
 167                 FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
 
 168                 st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) tei);
 
 169                 cs = (struct IsdnCardState *) st->l1.hardware;
 
 170                 cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL);
 
 175 tei_id_test_dup(struct FsmInst *fi, int event, void *arg)
 
 177         struct PStack *ost, *st = fi->userdata;
 
 178         struct sk_buff *skb = arg;
 
 181         ri = ((unsigned int) skb->data[1] << 8) + skb->data[2];
 
 182         tei = skb->data[4] >> 1;
 
 184                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 185                         "foreign identity assign ri %d tei %d", ri, tei);
 
 186         if ((ost = findtei(st, tei))) { /* same tei is in use */
 
 187                 if (ri != ost->ma.ri) { /* and it wasn't our request */
 
 188                         st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 189                                 "possible duplicate assignment tei %d", tei);
 
 190                         FsmEvent(&ost->ma.tei_m, EV_VERIFY, NULL);
 
 196 tei_id_denied(struct FsmInst *fi, int event, void *arg)
 
 198         struct PStack *st = fi->userdata;
 
 199         struct sk_buff *skb = arg;
 
 202         ri = ((unsigned int) skb->data[1] << 8) + skb->data[2];
 
 203         tei = skb->data[4] >> 1;
 
 205                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 206                         "identity denied ri %d tei %d", ri, tei);
 
 210 tei_id_chk_req(struct FsmInst *fi, int event, void *arg)
 
 212         struct PStack *st = fi->userdata;
 
 213         struct sk_buff *skb = arg;
 
 216         tei = skb->data[4] >> 1;
 
 218                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 219                         "identity check req tei %d", tei);
 
 220         if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) {
 
 221                 FsmDelTimer(&st->ma.t202, 4);
 
 222                 FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
 
 223                 put_tei_msg(st, ID_CHK_RES, random_ri(), st->l2.tei);
 
 228 tei_id_remove(struct FsmInst *fi, int event, void *arg)
 
 230         struct PStack *st = fi->userdata;
 
 231         struct sk_buff *skb = arg;
 
 232         struct IsdnCardState *cs;
 
 235         tei = skb->data[4] >> 1;
 
 237                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 238                         "identity remove tei %d", tei);
 
 239         if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) {
 
 240                 FsmDelTimer(&st->ma.t202, 5);
 
 241                 FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
 
 242                 st->l3.l3l2(st, MDL_REMOVE | REQUEST, NULL);
 
 243                 cs = (struct IsdnCardState *) st->l1.hardware;
 
 244                 cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
 
 249 tei_id_verify(struct FsmInst *fi, int event, void *arg)
 
 251         struct PStack *st = fi->userdata;
 
 254                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 255                         "id verify request for tei %d", st->l2.tei);
 
 256         put_tei_msg(st, ID_VERIFY, 0, st->l2.tei);
 
 257         FsmChangeState(&st->ma.tei_m, ST_TEI_IDVERIFY);
 
 258         FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 2);
 
 263 tei_id_req_tout(struct FsmInst *fi, int event, void *arg)
 
 265         struct PStack *st = fi->userdata;
 
 266         struct IsdnCardState *cs;
 
 269                 st->ma.ri = random_ri();
 
 271                         st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 272                                 "assign req(%d) ri %d", 4 - st->ma.N202,
 
 274                 put_tei_msg(st, ID_REQUEST, st->ma.ri, 127);
 
 275                 FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 3);
 
 277                 st->ma.tei_m.printdebug(&st->ma.tei_m, "assign req failed");
 
 278                 st->l3.l3l2(st, MDL_ERROR | RESPONSE, NULL);
 
 279                 cs = (struct IsdnCardState *) st->l1.hardware;
 
 280                 cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
 
 281                 FsmChangeState(fi, ST_TEI_NOP);
 
 286 tei_id_ver_tout(struct FsmInst *fi, int event, void *arg)
 
 288         struct PStack *st = fi->userdata;
 
 289         struct IsdnCardState *cs;
 
 293                         st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 294                                 "id verify req(%d) for tei %d",
 
 295                                 3 - st->ma.N202, st->l2.tei);
 
 296                 put_tei_msg(st, ID_VERIFY, 0, st->l2.tei);
 
 297                 FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 4);
 
 299                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 300                         "verify req for tei %d failed", st->l2.tei);
 
 301                 st->l3.l3l2(st, MDL_REMOVE | REQUEST, NULL);
 
 302                 cs = (struct IsdnCardState *) st->l1.hardware;
 
 303                 cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
 
 304                 FsmChangeState(fi, ST_TEI_NOP);
 
 309 tei_l1l2(struct PStack *st, int pr, void *arg)
 
 311         struct sk_buff *skb = arg;
 
 314         if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) {
 
 319         if (pr == (PH_DATA | INDICATION)) {
 
 321                         st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 322                                 "short mgr frame %ld/3", skb->len);
 
 323                 } else if ((skb->data[0] != ((TEI_SAPI << 2) | 2)) ||
 
 324                            (skb->data[1] != ((GROUP_TEI << 1) | 1))) {
 
 325                         st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 326                                 "wrong mgr sapi/tei %x/%x",
 
 327                                 skb->data[0], skb->data[1]);
 
 328                 } else if ((skb->data[2] & 0xef) != UI) {
 
 329                         st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 330                                 "mgr frame is not ui %x", skb->data[2]);
 
 334                                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 335                                         "short mgr frame %ld/5", skb->len);
 
 336                         } else if (skb->data[0] != TEI_ENTITY_ID) {
 
 337                                 /* wrong management entity identifier, ignore */
 
 338                                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 339                                         "tei handler wrong entity id %x",
 
 343                                 if (mt == ID_ASSIGNED)
 
 344                                         FsmEvent(&st->ma.tei_m, EV_ASSIGN, skb);
 
 345                                 else if (mt == ID_DENIED)
 
 346                                         FsmEvent(&st->ma.tei_m, EV_DENIED, skb);
 
 347                                 else if (mt == ID_CHK_REQ)
 
 348                                         FsmEvent(&st->ma.tei_m, EV_CHKREQ, skb);
 
 349                                 else if (mt == ID_REMOVE)
 
 350                                         FsmEvent(&st->ma.tei_m, EV_REMOVE, skb);
 
 352                                         st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 353                                                 "tei handler wrong mt %x\n", mt);
 
 358                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 359                         "tei handler wrong pr %x\n", pr);
 
 365 tei_l2tei(struct PStack *st, int pr, void *arg)
 
 367         struct IsdnCardState *cs;
 
 369         if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) {
 
 370                 if (pr == (MDL_ASSIGN | INDICATION)) {
 
 372                                 st->ma.tei_m.printdebug(&st->ma.tei_m,
 
 373                                         "fixed assign tei %d", st->l2.tei);
 
 374                         st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) st->l2.tei);
 
 375                         cs = (struct IsdnCardState *) st->l1.hardware;
 
 376                         cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL);
 
 381                 case (MDL_ASSIGN | INDICATION):
 
 382                         FsmEvent(&st->ma.tei_m, EV_IDREQ, arg);
 
 384                 case (MDL_ERROR | REQUEST):
 
 385                         FsmEvent(&st->ma.tei_m, EV_VERIFY, arg);
 
 393 tei_debug(struct FsmInst *fi, char *fmt, ...)
 
 396         struct PStack *st = fi->userdata;
 
 399         VHiSax_putstatus(st->l1.hardware, "tei ", fmt, args);
 
 404 setstack_tei(struct PStack *st)
 
 406         st->l2.l2tei = tei_l2tei;
 
 407         st->ma.T202 = 2000;     /* T202  2000 milliseconds */
 
 408         st->l1.l1tei = tei_l1l2;
 
 410         st->ma.tei_m.fsm = &teifsm;
 
 411         st->ma.tei_m.state = ST_TEI_NOP;
 
 412         st->ma.tei_m.debug = 1;
 
 413         st->ma.tei_m.userdata = st;
 
 414         st->ma.tei_m.userint = 0;
 
 415         st->ma.tei_m.printdebug = tei_debug;
 
 416         FsmInitTimer(&st->ma.tei_m, &st->ma.t202);
 
 420 init_tei(struct IsdnCardState *cs, int protocol)
 
 425 release_tei(struct IsdnCardState *cs)
 
 427         struct PStack *st = cs->stlist;
 
 430                 FsmDelTimer(&st->ma.t202, 1);
 
 435 static struct FsmNode TeiFnList[] __initdata =
 
 437         {ST_TEI_NOP, EV_IDREQ, tei_id_request},
 
 438         {ST_TEI_NOP, EV_ASSIGN, tei_id_test_dup},
 
 439         {ST_TEI_NOP, EV_VERIFY, tei_id_verify},
 
 440         {ST_TEI_NOP, EV_REMOVE, tei_id_remove},
 
 441         {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req},
 
 442         {ST_TEI_IDREQ, EV_T202, tei_id_req_tout},
 
 443         {ST_TEI_IDREQ, EV_ASSIGN, tei_id_assign},
 
 444         {ST_TEI_IDREQ, EV_DENIED, tei_id_denied},
 
 445         {ST_TEI_IDVERIFY, EV_T202, tei_id_ver_tout},
 
 446         {ST_TEI_IDVERIFY, EV_REMOVE, tei_id_remove},
 
 447         {ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req},
 
 450 #define TEI_FN_COUNT (sizeof(TeiFnList)/sizeof(struct FsmNode))
 
 455         teifsm.state_count = TEI_STATE_COUNT;
 
 456         teifsm.event_count = TEI_EVENT_COUNT;
 
 457         teifsm.strEvent = strTeiEvent;
 
 458         teifsm.strState = strTeiState;
 
 459         return FsmNew(&teifsm, TeiFnList, TEI_FN_COUNT);