tei.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. /* $Id: tei.c,v 2.20.2.3 2004/01/13 14:31:26 keil Exp $
  2. *
  3. * Author Karsten Keil
  4. * based on the teles driver from Jan den Ouden
  5. * Copyright by Karsten Keil <keil@isdn4linux.de>
  6. *
  7. * This software may be used and distributed according to the terms
  8. * of the GNU General Public License, incorporated herein by reference.
  9. *
  10. * For changes and modifications please read
  11. * Documentation/isdn/HiSax.cert
  12. *
  13. * Thanks to Jan den Ouden
  14. * Fritz Elfert
  15. *
  16. */
  17. #include "hisax.h"
  18. #include "isdnl2.h"
  19. #include <linux/gfp.h>
  20. #include <linux/init.h>
  21. #include <linux/random.h>
  22. const char *tei_revision = "$Revision: 2.20.2.3 $";
  23. #define ID_REQUEST 1
  24. #define ID_ASSIGNED 2
  25. #define ID_DENIED 3
  26. #define ID_CHK_REQ 4
  27. #define ID_CHK_RES 5
  28. #define ID_REMOVE 6
  29. #define ID_VERIFY 7
  30. #define TEI_ENTITY_ID 0xf
  31. static struct Fsm teifsm;
  32. void tei_handler(struct PStack *st, u_char pr, struct sk_buff *skb);
  33. enum {
  34. ST_TEI_NOP,
  35. ST_TEI_IDREQ,
  36. ST_TEI_IDVERIFY,
  37. };
  38. #define TEI_STATE_COUNT (ST_TEI_IDVERIFY + 1)
  39. static char *strTeiState[] =
  40. {
  41. "ST_TEI_NOP",
  42. "ST_TEI_IDREQ",
  43. "ST_TEI_IDVERIFY",
  44. };
  45. enum {
  46. EV_IDREQ,
  47. EV_ASSIGN,
  48. EV_DENIED,
  49. EV_CHKREQ,
  50. EV_REMOVE,
  51. EV_VERIFY,
  52. EV_T202,
  53. };
  54. #define TEI_EVENT_COUNT (EV_T202 + 1)
  55. static char *strTeiEvent[] =
  56. {
  57. "EV_IDREQ",
  58. "EV_ASSIGN",
  59. "EV_DENIED",
  60. "EV_CHKREQ",
  61. "EV_REMOVE",
  62. "EV_VERIFY",
  63. "EV_T202",
  64. };
  65. static unsigned int
  66. random_ri(void)
  67. {
  68. unsigned int x;
  69. get_random_bytes(&x, sizeof(x));
  70. return (x & 0xffff);
  71. }
  72. static struct PStack *
  73. findtei(struct PStack *st, int tei)
  74. {
  75. struct PStack *ptr = *(st->l1.stlistp);
  76. if (tei == 127)
  77. return (NULL);
  78. while (ptr)
  79. if (ptr->l2.tei == tei)
  80. return (ptr);
  81. else
  82. ptr = ptr->next;
  83. return (NULL);
  84. }
  85. static void
  86. put_tei_msg(struct PStack *st, u_char m_id, unsigned int ri, u_char tei)
  87. {
  88. struct sk_buff *skb;
  89. u_char *bp;
  90. if (!(skb = alloc_skb(8, GFP_ATOMIC))) {
  91. printk(KERN_WARNING "HiSax: No skb for TEI manager\n");
  92. return;
  93. }
  94. bp = skb_put(skb, 3);
  95. bp[0] = (TEI_SAPI << 2);
  96. bp[1] = (GROUP_TEI << 1) | 0x1;
  97. bp[2] = UI;
  98. bp = skb_put(skb, 5);
  99. bp[0] = TEI_ENTITY_ID;
  100. bp[1] = ri >> 8;
  101. bp[2] = ri & 0xff;
  102. bp[3] = m_id;
  103. bp[4] = (tei << 1) | 1;
  104. st->l2.l2l1(st, PH_DATA | REQUEST, skb);
  105. }
  106. static void
  107. tei_id_request(struct FsmInst *fi, int event, void *arg)
  108. {
  109. struct PStack *st = fi->userdata;
  110. if (st->l2.tei != -1) {
  111. st->ma.tei_m.printdebug(&st->ma.tei_m,
  112. "assign request for already assigned tei %d",
  113. st->l2.tei);
  114. return;
  115. }
  116. st->ma.ri = random_ri();
  117. if (st->ma.debug)
  118. st->ma.tei_m.printdebug(&st->ma.tei_m,
  119. "assign request ri %d", st->ma.ri);
  120. put_tei_msg(st, ID_REQUEST, st->ma.ri, 127);
  121. FsmChangeState(&st->ma.tei_m, ST_TEI_IDREQ);
  122. FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 1);
  123. st->ma.N202 = 3;
  124. }
  125. static void
  126. tei_id_assign(struct FsmInst *fi, int event, void *arg)
  127. {
  128. struct PStack *ost, *st = fi->userdata;
  129. struct sk_buff *skb = arg;
  130. struct IsdnCardState *cs;
  131. int ri, tei;
  132. ri = ((unsigned int) skb->data[1] << 8) + skb->data[2];
  133. tei = skb->data[4] >> 1;
  134. if (st->ma.debug)
  135. st->ma.tei_m.printdebug(&st->ma.tei_m,
  136. "identity assign ri %d tei %d", ri, tei);
  137. if ((ost = findtei(st, tei))) { /* same tei is in use */
  138. if (ri != ost->ma.ri) {
  139. st->ma.tei_m.printdebug(&st->ma.tei_m,
  140. "possible duplicate assignment tei %d", tei);
  141. ost->l2.l2tei(ost, MDL_ERROR | RESPONSE, NULL);
  142. }
  143. } else if (ri == st->ma.ri) {
  144. FsmDelTimer(&st->ma.t202, 1);
  145. FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
  146. st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) tei);
  147. cs = (struct IsdnCardState *) st->l1.hardware;
  148. cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL);
  149. }
  150. }
  151. static void
  152. tei_id_test_dup(struct FsmInst *fi, int event, void *arg)
  153. {
  154. struct PStack *ost, *st = fi->userdata;
  155. struct sk_buff *skb = arg;
  156. int tei, ri;
  157. ri = ((unsigned int) skb->data[1] << 8) + skb->data[2];
  158. tei = skb->data[4] >> 1;
  159. if (st->ma.debug)
  160. st->ma.tei_m.printdebug(&st->ma.tei_m,
  161. "foreign identity assign ri %d tei %d", ri, tei);
  162. if ((ost = findtei(st, tei))) { /* same tei is in use */
  163. if (ri != ost->ma.ri) { /* and it wasn't our request */
  164. st->ma.tei_m.printdebug(&st->ma.tei_m,
  165. "possible duplicate assignment tei %d", tei);
  166. FsmEvent(&ost->ma.tei_m, EV_VERIFY, NULL);
  167. }
  168. }
  169. }
  170. static void
  171. tei_id_denied(struct FsmInst *fi, int event, void *arg)
  172. {
  173. struct PStack *st = fi->userdata;
  174. struct sk_buff *skb = arg;
  175. int ri, tei;
  176. ri = ((unsigned int) skb->data[1] << 8) + skb->data[2];
  177. tei = skb->data[4] >> 1;
  178. if (st->ma.debug)
  179. st->ma.tei_m.printdebug(&st->ma.tei_m,
  180. "identity denied ri %d tei %d", ri, tei);
  181. }
  182. static void
  183. tei_id_chk_req(struct FsmInst *fi, int event, void *arg)
  184. {
  185. struct PStack *st = fi->userdata;
  186. struct sk_buff *skb = arg;
  187. int tei;
  188. tei = skb->data[4] >> 1;
  189. if (st->ma.debug)
  190. st->ma.tei_m.printdebug(&st->ma.tei_m,
  191. "identity check req tei %d", tei);
  192. if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) {
  193. FsmDelTimer(&st->ma.t202, 4);
  194. FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
  195. put_tei_msg(st, ID_CHK_RES, random_ri(), st->l2.tei);
  196. }
  197. }
  198. static void
  199. tei_id_remove(struct FsmInst *fi, int event, void *arg)
  200. {
  201. struct PStack *st = fi->userdata;
  202. struct sk_buff *skb = arg;
  203. struct IsdnCardState *cs;
  204. int tei;
  205. tei = skb->data[4] >> 1;
  206. if (st->ma.debug)
  207. st->ma.tei_m.printdebug(&st->ma.tei_m,
  208. "identity remove tei %d", tei);
  209. if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) {
  210. FsmDelTimer(&st->ma.t202, 5);
  211. FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
  212. st->l3.l3l2(st, MDL_REMOVE | REQUEST, NULL);
  213. cs = (struct IsdnCardState *) st->l1.hardware;
  214. cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
  215. }
  216. }
  217. static void
  218. tei_id_verify(struct FsmInst *fi, int event, void *arg)
  219. {
  220. struct PStack *st = fi->userdata;
  221. if (st->ma.debug)
  222. st->ma.tei_m.printdebug(&st->ma.tei_m,
  223. "id verify request for tei %d", st->l2.tei);
  224. put_tei_msg(st, ID_VERIFY, 0, st->l2.tei);
  225. FsmChangeState(&st->ma.tei_m, ST_TEI_IDVERIFY);
  226. FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 2);
  227. st->ma.N202 = 2;
  228. }
  229. static void
  230. tei_id_req_tout(struct FsmInst *fi, int event, void *arg)
  231. {
  232. struct PStack *st = fi->userdata;
  233. struct IsdnCardState *cs;
  234. if (--st->ma.N202) {
  235. st->ma.ri = random_ri();
  236. if (st->ma.debug)
  237. st->ma.tei_m.printdebug(&st->ma.tei_m,
  238. "assign req(%d) ri %d", 4 - st->ma.N202,
  239. st->ma.ri);
  240. put_tei_msg(st, ID_REQUEST, st->ma.ri, 127);
  241. FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 3);
  242. } else {
  243. st->ma.tei_m.printdebug(&st->ma.tei_m, "assign req failed");
  244. st->l3.l3l2(st, MDL_ERROR | RESPONSE, NULL);
  245. cs = (struct IsdnCardState *) st->l1.hardware;
  246. cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
  247. FsmChangeState(fi, ST_TEI_NOP);
  248. }
  249. }
  250. static void
  251. tei_id_ver_tout(struct FsmInst *fi, int event, void *arg)
  252. {
  253. struct PStack *st = fi->userdata;
  254. struct IsdnCardState *cs;
  255. if (--st->ma.N202) {
  256. if (st->ma.debug)
  257. st->ma.tei_m.printdebug(&st->ma.tei_m,
  258. "id verify req(%d) for tei %d",
  259. 3 - st->ma.N202, st->l2.tei);
  260. put_tei_msg(st, ID_VERIFY, 0, st->l2.tei);
  261. FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 4);
  262. } else {
  263. st->ma.tei_m.printdebug(&st->ma.tei_m,
  264. "verify req for tei %d failed", st->l2.tei);
  265. st->l3.l3l2(st, MDL_REMOVE | REQUEST, NULL);
  266. cs = (struct IsdnCardState *) st->l1.hardware;
  267. cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
  268. FsmChangeState(fi, ST_TEI_NOP);
  269. }
  270. }
  271. static void
  272. tei_l1l2(struct PStack *st, int pr, void *arg)
  273. {
  274. struct sk_buff *skb = arg;
  275. int mt;
  276. if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) {
  277. dev_kfree_skb(skb);
  278. return;
  279. }
  280. if (pr == (PH_DATA | INDICATION)) {
  281. if (skb->len < 3) {
  282. st->ma.tei_m.printdebug(&st->ma.tei_m,
  283. "short mgr frame %ld/3", skb->len);
  284. } else if ((skb->data[0] != ((TEI_SAPI << 2) | 2)) ||
  285. (skb->data[1] != ((GROUP_TEI << 1) | 1))) {
  286. st->ma.tei_m.printdebug(&st->ma.tei_m,
  287. "wrong mgr sapi/tei %x/%x",
  288. skb->data[0], skb->data[1]);
  289. } else if ((skb->data[2] & 0xef) != UI) {
  290. st->ma.tei_m.printdebug(&st->ma.tei_m,
  291. "mgr frame is not ui %x", skb->data[2]);
  292. } else {
  293. skb_pull(skb, 3);
  294. if (skb->len < 5) {
  295. st->ma.tei_m.printdebug(&st->ma.tei_m,
  296. "short mgr frame %ld/5", skb->len);
  297. } else if (skb->data[0] != TEI_ENTITY_ID) {
  298. /* wrong management entity identifier, ignore */
  299. st->ma.tei_m.printdebug(&st->ma.tei_m,
  300. "tei handler wrong entity id %x",
  301. skb->data[0]);
  302. } else {
  303. mt = skb->data[3];
  304. if (mt == ID_ASSIGNED)
  305. FsmEvent(&st->ma.tei_m, EV_ASSIGN, skb);
  306. else if (mt == ID_DENIED)
  307. FsmEvent(&st->ma.tei_m, EV_DENIED, skb);
  308. else if (mt == ID_CHK_REQ)
  309. FsmEvent(&st->ma.tei_m, EV_CHKREQ, skb);
  310. else if (mt == ID_REMOVE)
  311. FsmEvent(&st->ma.tei_m, EV_REMOVE, skb);
  312. else {
  313. st->ma.tei_m.printdebug(&st->ma.tei_m,
  314. "tei handler wrong mt %x\n", mt);
  315. }
  316. }
  317. }
  318. } else {
  319. st->ma.tei_m.printdebug(&st->ma.tei_m,
  320. "tei handler wrong pr %x\n", pr);
  321. }
  322. dev_kfree_skb(skb);
  323. }
  324. static void
  325. tei_l2tei(struct PStack *st, int pr, void *arg)
  326. {
  327. struct IsdnCardState *cs;
  328. if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) {
  329. if (pr == (MDL_ASSIGN | INDICATION)) {
  330. if (st->ma.debug)
  331. st->ma.tei_m.printdebug(&st->ma.tei_m,
  332. "fixed assign tei %d", st->l2.tei);
  333. st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) st->l2.tei);
  334. cs = (struct IsdnCardState *) st->l1.hardware;
  335. cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL);
  336. }
  337. return;
  338. }
  339. switch (pr) {
  340. case (MDL_ASSIGN | INDICATION):
  341. FsmEvent(&st->ma.tei_m, EV_IDREQ, arg);
  342. break;
  343. case (MDL_ERROR | REQUEST):
  344. FsmEvent(&st->ma.tei_m, EV_VERIFY, arg);
  345. break;
  346. default:
  347. break;
  348. }
  349. }
  350. static void
  351. tei_debug(struct FsmInst *fi, char *fmt, ...)
  352. {
  353. va_list args;
  354. struct PStack *st = fi->userdata;
  355. va_start(args, fmt);
  356. VHiSax_putstatus(st->l1.hardware, "tei ", fmt, args);
  357. va_end(args);
  358. }
  359. void
  360. setstack_tei(struct PStack *st)
  361. {
  362. st->l2.l2tei = tei_l2tei;
  363. st->ma.T202 = 2000; /* T202 2000 milliseconds */
  364. st->l1.l1tei = tei_l1l2;
  365. st->ma.debug = 1;
  366. st->ma.tei_m.fsm = &teifsm;
  367. st->ma.tei_m.state = ST_TEI_NOP;
  368. st->ma.tei_m.debug = 1;
  369. st->ma.tei_m.userdata = st;
  370. st->ma.tei_m.userint = 0;
  371. st->ma.tei_m.printdebug = tei_debug;
  372. FsmInitTimer(&st->ma.tei_m, &st->ma.t202);
  373. }
  374. void
  375. init_tei(struct IsdnCardState *cs, int protocol)
  376. {
  377. }
  378. void
  379. release_tei(struct IsdnCardState *cs)
  380. {
  381. struct PStack *st = cs->stlist;
  382. while (st) {
  383. FsmDelTimer(&st->ma.t202, 1);
  384. st = st->next;
  385. }
  386. }
  387. static struct FsmNode TeiFnList[] __initdata =
  388. {
  389. {ST_TEI_NOP, EV_IDREQ, tei_id_request},
  390. {ST_TEI_NOP, EV_ASSIGN, tei_id_test_dup},
  391. {ST_TEI_NOP, EV_VERIFY, tei_id_verify},
  392. {ST_TEI_NOP, EV_REMOVE, tei_id_remove},
  393. {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req},
  394. {ST_TEI_IDREQ, EV_T202, tei_id_req_tout},
  395. {ST_TEI_IDREQ, EV_ASSIGN, tei_id_assign},
  396. {ST_TEI_IDREQ, EV_DENIED, tei_id_denied},
  397. {ST_TEI_IDVERIFY, EV_T202, tei_id_ver_tout},
  398. {ST_TEI_IDVERIFY, EV_REMOVE, tei_id_remove},
  399. {ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req},
  400. };
  401. int __init
  402. TeiNew(void)
  403. {
  404. teifsm.state_count = TEI_STATE_COUNT;
  405. teifsm.event_count = TEI_EVENT_COUNT;
  406. teifsm.strEvent = strTeiEvent;
  407. teifsm.strState = strTeiState;
  408. return FsmNew(&teifsm, TeiFnList, ARRAY_SIZE(TeiFnList));
  409. }
  410. void
  411. TeiFree(void)
  412. {
  413. FsmFree(&teifsm);
  414. }