PageRenderTime 50ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/freebsd4/sys/i4b/layer3/i4b_q932fac.c

https://github.com/kame/kame
C | 573 lines | 381 code | 81 blank | 111 comment | 55 complexity | 71a2510a6942e59e9eb3ff613e278aee MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
  1. /*
  2. * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  14. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  17. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  19. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  23. * SUCH DAMAGE.
  24. *
  25. *---------------------------------------------------------------------------
  26. *
  27. * i4b_q932fac.c - Q932 facility handling
  28. * --------------------------------------
  29. *
  30. * $Id: i4b_q932fac.c,v 1.8 1999/12/13 21:25:27 hm Exp $
  31. *
  32. * $FreeBSD: src/sys/i4b/layer3/i4b_q932fac.c,v 1.6 1999/12/14 20:48:32 hm Exp $
  33. *
  34. * last edit-date: [Mon Dec 13 22:05:51 1999]
  35. *
  36. *---------------------------------------------------------------------------*/
  37. #ifdef __FreeBSD__
  38. #include "i4bq931.h"
  39. #else
  40. #define NI4BQ931 1
  41. #endif
  42. #if NI4BQ931 > 0
  43. #include <sys/param.h>
  44. #if defined(__FreeBSD__)
  45. #include <sys/ioccom.h>
  46. #else
  47. #include <sys/ioctl.h>
  48. #endif
  49. #include <sys/kernel.h>
  50. #include <sys/systm.h>
  51. #include <sys/mbuf.h>
  52. #include <sys/socket.h>
  53. #include <net/if.h>
  54. #ifdef __FreeBSD__
  55. #include <machine/i4b_debug.h>
  56. #include <machine/i4b_ioctl.h>
  57. #else
  58. #include <i4b/i4b_debug.h>
  59. #include <i4b/i4b_ioctl.h>
  60. #endif
  61. #include <i4b/include/i4b_isdnq931.h>
  62. #include <i4b/include/i4b_l2l3.h>
  63. #include <i4b/include/i4b_l3l4.h>
  64. #include <i4b/include/i4b_mbuf.h>
  65. #include <i4b/layer3/i4b_l3.h>
  66. #include <i4b/layer3/i4b_l3fsm.h>
  67. #include <i4b/layer3/i4b_q931.h>
  68. #include <i4b/layer3/i4b_q932fac.h>
  69. #include <i4b/layer4/i4b_l4.h>
  70. static int do_component(int length);
  71. static void next_state(int class, int form, int code, int val);
  72. static int byte_len;
  73. static unsigned char *byte_buf;
  74. static int state;
  75. static int units;
  76. static int operation_value;
  77. /*---------------------------------------------------------------------------*
  78. * decode Q.931/Q.932 facility info element
  79. *---------------------------------------------------------------------------*/
  80. int
  81. i4b_aoc(unsigned char *buf, call_desc_t *cd)
  82. {
  83. int len;
  84. cd->units_type = CHARGE_INVALID;
  85. cd->units = -1;
  86. buf++; /* length */
  87. len = *buf;
  88. buf++; /* protocol profile */
  89. switch(*buf & 0x1f)
  90. {
  91. case FAC_PROTO_ROP:
  92. break;
  93. case FAC_PROTO_CMIP:
  94. DBGL3(L3_A_MSG, "i4b_facility", ("CMIP Protocol (Q.941), UNSUPPORTED\n"));
  95. return(-1);
  96. break;
  97. case FAC_PROTO_ACSE:
  98. DBGL3(L3_A_MSG, "i4b_facility", ("ACSE Protocol (X.217/X.227), UNSUPPORTED!\n"));
  99. return(-1);
  100. break;
  101. default:
  102. DBGL3(L3_A_ERR, "i4b_facility", ("Unknown Protocol, UNSUPPORTED!\n"));
  103. return(-1);
  104. break;
  105. }
  106. DBGL3(L3_A_MSG, "i4b_facility", ("Remote Operations Protocol\n"));
  107. /* next byte */
  108. buf++;
  109. len--;
  110. /* initialize variables for do_component */
  111. byte_len = 0;
  112. byte_buf = buf;
  113. state = ST_EXP_COMP_TYP;
  114. /* decode facility */
  115. do_component(len);
  116. switch(operation_value)
  117. {
  118. case FAC_OPVAL_AOC_D_CUR:
  119. cd->units_type = CHARGE_AOCD;
  120. cd->units = 0;
  121. return(0);
  122. break;
  123. case FAC_OPVAL_AOC_D_UNIT:
  124. cd->units_type = CHARGE_AOCD;
  125. cd->units = units;
  126. return(0);
  127. break;
  128. case FAC_OPVAL_AOC_E_CUR:
  129. cd->units_type = CHARGE_AOCE;
  130. cd->units = 0;
  131. return(0);
  132. break;
  133. case FAC_OPVAL_AOC_E_UNIT:
  134. cd->units_type = CHARGE_AOCE;
  135. cd->units = units;
  136. return(0);
  137. break;
  138. default:
  139. cd->units_type = CHARGE_INVALID;
  140. cd->units = -1;
  141. return(-1);
  142. break;
  143. }
  144. return(-1);
  145. }
  146. /*---------------------------------------------------------------------------*
  147. * handle a component recursively
  148. *---------------------------------------------------------------------------*/
  149. static int
  150. do_component(int length)
  151. {
  152. int comp_tag_class; /* component tag class */
  153. int comp_tag_form; /* component form: constructor or primitive */
  154. int comp_tag_code; /* component code depending on class */
  155. int comp_length = 0; /* component length */
  156. again:
  157. /*----------------------------------------*/
  158. /* first component element: component tag */
  159. /*----------------------------------------*/
  160. /* tag class bits */
  161. comp_tag_class = (*byte_buf & 0xc0) >> 6;
  162. switch(comp_tag_class)
  163. {
  164. case FAC_TAGCLASS_UNI:
  165. break;
  166. case FAC_TAGCLASS_APW:
  167. break;
  168. case FAC_TAGCLASS_COS:
  169. break;
  170. case FAC_TAGCLASS_PRU:
  171. break;
  172. }
  173. /* tag form bit */
  174. comp_tag_form = (*byte_buf & 0x20) > 5;
  175. /* tag code bits */
  176. comp_tag_code = *byte_buf & 0x1f;
  177. if(comp_tag_code == 0x1f)
  178. {
  179. comp_tag_code = 0;
  180. byte_buf++;
  181. byte_len++;
  182. while(*byte_buf & 0x80)
  183. {
  184. comp_tag_code += (*byte_buf & 0x7f);
  185. byte_buf++;
  186. byte_len++;
  187. }
  188. comp_tag_code += (*byte_buf & 0x7f);
  189. }
  190. else
  191. {
  192. comp_tag_code = (*byte_buf & 0x1f);
  193. }
  194. byte_buf++;
  195. byte_len++;
  196. /*--------------------------------------------*/
  197. /* second component element: component length */
  198. /*--------------------------------------------*/
  199. comp_length = 0;
  200. if(*byte_buf & 0x80)
  201. {
  202. int i = *byte_buf & 0x7f;
  203. byte_len += i;
  204. for(;i > 0;i++)
  205. {
  206. byte_buf++;
  207. comp_length += (*byte_buf * (i*256));
  208. }
  209. }
  210. else
  211. {
  212. comp_length = *byte_buf & 0x7f;
  213. }
  214. next_state(comp_tag_class, comp_tag_form, comp_tag_code, -1);
  215. byte_len++;
  216. byte_buf++;
  217. /*---------------------------------------------*/
  218. /* third component element: component contents */
  219. /*---------------------------------------------*/
  220. if(comp_tag_form) /* == constructor */
  221. {
  222. do_component(comp_length);
  223. }
  224. else
  225. {
  226. int val = 0;
  227. if(comp_tag_class == FAC_TAGCLASS_UNI)
  228. {
  229. switch(comp_tag_code)
  230. {
  231. case FAC_CODEUNI_INT:
  232. case FAC_CODEUNI_ENUM:
  233. case FAC_CODEUNI_BOOL:
  234. if(comp_length)
  235. {
  236. int i;
  237. for(i = comp_length-1; i >= 0; i--)
  238. {
  239. val += (*byte_buf + (i*255));
  240. byte_buf++;
  241. byte_len++;
  242. }
  243. }
  244. break;
  245. default:
  246. if(comp_length)
  247. {
  248. int i;
  249. for(i = comp_length-1; i >= 0; i--)
  250. {
  251. byte_buf++;
  252. byte_len++;
  253. }
  254. }
  255. break;
  256. }
  257. }
  258. else /* comp_tag_class != FAC_TAGCLASS_UNI */
  259. {
  260. if(comp_length)
  261. {
  262. int i;
  263. for(i = comp_length-1; i >= 0; i--)
  264. {
  265. val += (*byte_buf + (i*255));
  266. byte_buf++;
  267. byte_len++;
  268. }
  269. }
  270. }
  271. next_state(comp_tag_class, comp_tag_form, comp_tag_code, val);
  272. }
  273. if(byte_len < length)
  274. goto again;
  275. return(byte_len);
  276. }
  277. /*---------------------------------------------------------------------------*
  278. * invoke component
  279. *---------------------------------------------------------------------------*/
  280. static void
  281. F_1_1(int val)
  282. {
  283. if(val == -1)
  284. {
  285. state = ST_EXP_INV_ID;
  286. }
  287. }
  288. /*---------------------------------------------------------------------------*
  289. * return result
  290. *---------------------------------------------------------------------------*/
  291. static void
  292. F_1_2(int val)
  293. {
  294. if(val == -1)
  295. state = ST_EXP_NIX;
  296. }
  297. /*---------------------------------------------------------------------------*
  298. * return error
  299. *---------------------------------------------------------------------------*/
  300. static void
  301. F_1_3(int val)
  302. {
  303. if(val == -1)
  304. state = ST_EXP_NIX;
  305. }
  306. /*---------------------------------------------------------------------------*
  307. * reject
  308. *---------------------------------------------------------------------------*/
  309. static void
  310. F_1_4(int val)
  311. {
  312. if(val == -1)
  313. state = ST_EXP_NIX;
  314. }
  315. /*---------------------------------------------------------------------------*
  316. * invoke id
  317. *---------------------------------------------------------------------------*/
  318. static void
  319. F_2(int val)
  320. {
  321. if(val != -1)
  322. {
  323. DBGL3(L3_A_MSG, "i4b_facility", ("Invoke ID = %d\n", val));
  324. state = ST_EXP_OP_VAL;
  325. }
  326. }
  327. /*---------------------------------------------------------------------------*
  328. * operation value
  329. *---------------------------------------------------------------------------*/
  330. static void
  331. F_3(int val)
  332. {
  333. if(val != -1)
  334. {
  335. DBGL3(L3_A_MSG, "i4b_facility", ("Operation Value = %d\n", val));
  336. operation_value = val;
  337. if((val == FAC_OPVAL_AOC_D_UNIT) || (val == FAC_OPVAL_AOC_E_UNIT))
  338. {
  339. units = 0;
  340. state = ST_EXP_INFO;
  341. }
  342. else
  343. {
  344. state = ST_EXP_NIX;
  345. }
  346. }
  347. }
  348. /*---------------------------------------------------------------------------*
  349. * specific charging units
  350. *---------------------------------------------------------------------------*/
  351. static void
  352. F_4(int val)
  353. {
  354. if(val == -1)
  355. state = ST_EXP_RUL;
  356. }
  357. /*---------------------------------------------------------------------------*
  358. * free of charge
  359. *---------------------------------------------------------------------------*/
  360. static void
  361. F_4_1(int val)
  362. {
  363. if(val == -1)
  364. {
  365. DBGL3(L3_A_MSG, "i4b_facility", ("Free of Charge\n"));
  366. /* units = 0; XXXX */
  367. state = ST_EXP_NIX;
  368. }
  369. }
  370. /*---------------------------------------------------------------------------*
  371. * charge not available
  372. *---------------------------------------------------------------------------*/
  373. static void
  374. F_4_2(int val)
  375. {
  376. if(val == -1)
  377. {
  378. DBGL3(L3_A_MSG, "i4b_facility", ("Charge not available\n"));
  379. /* units = -1; XXXXXX ??? */
  380. state = ST_EXP_NIX;
  381. }
  382. }
  383. /*---------------------------------------------------------------------------*
  384. * recorded units list
  385. *---------------------------------------------------------------------------*/
  386. static void
  387. F_5(int val)
  388. {
  389. if(val == -1)
  390. state = ST_EXP_RU;
  391. }
  392. /*---------------------------------------------------------------------------*
  393. * recorded units
  394. *---------------------------------------------------------------------------*/
  395. static void
  396. F_6(int val)
  397. {
  398. if(val == -1)
  399. state = ST_EXP_RNOU;
  400. }
  401. /*---------------------------------------------------------------------------*
  402. * number of units
  403. *---------------------------------------------------------------------------*/
  404. static void
  405. F_7(int val)
  406. {
  407. if(val != -1)
  408. {
  409. DBGL3(L3_A_MSG, "i4b_facility", ("Number of Units = %d\n", val));
  410. units = val;
  411. state = ST_EXP_TOCI;
  412. }
  413. }
  414. /*---------------------------------------------------------------------------*
  415. * subtotal/total
  416. *---------------------------------------------------------------------------*/
  417. static void
  418. F_8(int val)
  419. {
  420. if(val != -1)
  421. {
  422. DBGL3(L3_A_MSG, "i4b_facility", ("Subtotal/Total = %d\n", val));
  423. /* type_of_charge = val; */
  424. state = ST_EXP_DBID;
  425. }
  426. }
  427. /*---------------------------------------------------------------------------*
  428. * billing_id
  429. *---------------------------------------------------------------------------*/
  430. static void
  431. F_9(int val)
  432. {
  433. if(val != -1)
  434. {
  435. DBGL3(L3_A_MSG, "i4b_facility", ("Billing ID = %d\n", val));
  436. /* billing_id = val; */
  437. state = ST_EXP_NIX;
  438. }
  439. }
  440. /*---------------------------------------------------------------------------*
  441. *
  442. *---------------------------------------------------------------------------*/
  443. static struct statetab {
  444. int currstate; /* input: current state we are in */
  445. int form; /* input: current tag form */
  446. int class; /* input: current tag class */
  447. int code; /* input: current tag code */
  448. void (*func)(int); /* output: func to exec */
  449. } statetab[] = {
  450. /* current state tag form tag class tag code function */
  451. /* --------------------- ---------------------- ---------------------- ---------------------- ----------------*/
  452. {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_1_1 },
  453. {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 2, F_1_2 },
  454. {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 3, F_1_3 },
  455. {ST_EXP_COMP_TYP, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 4, F_1_4 },
  456. {ST_EXP_INV_ID, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_2 },
  457. {ST_EXP_OP_VAL, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_3 },
  458. {ST_EXP_INFO, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_4 },
  459. {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_NULL, F_4_1 },
  460. {ST_EXP_INFO, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 1, F_4_2 },
  461. {ST_EXP_RUL, FAC_TAGFORM_CON, FAC_TAGCLASS_COS, 1, F_5 },
  462. {ST_EXP_RU, FAC_TAGFORM_CON, FAC_TAGCLASS_UNI, FAC_CODEUNI_SEQ, F_6 },
  463. {ST_EXP_RNOU, FAC_TAGFORM_PRI, FAC_TAGCLASS_UNI, FAC_CODEUNI_INT, F_7 },
  464. {ST_EXP_TOCI, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 2, F_8 },
  465. {ST_EXP_DBID, FAC_TAGFORM_PRI, FAC_TAGCLASS_COS, 3, F_9 },
  466. {-1, -1, -1, -1, NULL }
  467. };
  468. /*---------------------------------------------------------------------------*
  469. * state decode for do_component
  470. *---------------------------------------------------------------------------*/
  471. static void
  472. next_state(int class, int form, int code, int val)
  473. {
  474. int i;
  475. for(i=0; ; i++)
  476. {
  477. if((statetab[i].currstate > state) ||
  478. (statetab[i].currstate == -1))
  479. {
  480. break;
  481. }
  482. if((statetab[i].currstate == state) &&
  483. (statetab[i].form == form) &&
  484. (statetab[i].class == class) &&
  485. (statetab[i].code == code))
  486. {
  487. (*statetab[i].func)(val);
  488. break;
  489. }
  490. }
  491. }
  492. #endif /* NI4BQ931 > 0 */