tei.c 11 KB

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