ie.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414
  1. /*
  2. * Chan_Misdn -- Channel Driver for Asterisk
  3. *
  4. * Interface to mISDN
  5. *
  6. * Copyright (C) 2005, Christian Richter
  7. *
  8. * Christian Richter <crich@beronet.com>
  9. *
  10. * heaviliy patched from jollys ie.cpp, jolly gave me ALL
  11. * rights for this code, i can even have my own copyright on it.
  12. *
  13. * This program is free software, distributed under the terms of
  14. * the GNU General Public License
  15. */
  16. /*! \file
  17. * \brief Interface to mISDN
  18. * \author Christian Richter <crich@beronet.com>
  19. */
  20. /*
  21. the pointer of enc_ie_* always points to the IE itself
  22. if qi is not NULL (TE-mode), offset is set
  23. */
  24. /*** MODULEINFO
  25. <support_level>extended</support_level>
  26. ***/
  27. #include "asterisk.h"
  28. #include <string.h>
  29. #include <mISDNuser/mISDNlib.h>
  30. #include <mISDNuser/isdn_net.h>
  31. #include <mISDNuser/l3dss1.h>
  32. #include <mISDNuser/net_l3.h>
  33. #include "asterisk/localtime.h"
  34. #define MISDN_IE_DEBG 0
  35. /* support stuff */
  36. static void strnncpy(char *dest, const char *src, size_t len, size_t dst_len)
  37. {
  38. if (len > dst_len-1)
  39. len = dst_len-1;
  40. strncpy(dest, src, len);
  41. dest[len] = '\0';
  42. }
  43. /* IE_COMPLETE */
  44. static void enc_ie_complete(unsigned char **ntmode, msg_t *msg, int complete, int nt, struct misdn_bchannel *bc)
  45. {
  46. unsigned char *p;
  47. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  48. if (complete<0 || complete>1)
  49. {
  50. printf("%s: ERROR: complete(%d) is out of range.\n", __FUNCTION__, complete);
  51. return;
  52. }
  53. if (complete)
  54. if (MISDN_IE_DEBG) printf(" complete=%d\n", complete);
  55. if (complete)
  56. {
  57. p = msg_put(msg, 1);
  58. if (nt)
  59. {
  60. *ntmode = p;
  61. } else
  62. qi->QI_ELEMENT(sending_complete) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  63. p[0] = IE_COMPLETE;
  64. }
  65. }
  66. static void dec_ie_complete(unsigned char *p, Q931_info_t *qi, int *complete, int nt, struct misdn_bchannel *bc)
  67. {
  68. *complete = 0;
  69. if (!nt)
  70. {
  71. if (qi->QI_ELEMENT(sending_complete))
  72. *complete = 1;
  73. } else
  74. if (p)
  75. *complete = 1;
  76. if (*complete)
  77. if (MISDN_IE_DEBG) printf(" complete=%d\n", *complete);
  78. }
  79. /* IE_BEARER */
  80. static void enc_ie_bearer(unsigned char **ntmode, msg_t *msg, int coding, int capability, int mode, int rate, int multi, int user, int nt, struct misdn_bchannel *bc)
  81. {
  82. unsigned char *p;
  83. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  84. int l;
  85. if (coding<0 || coding>3)
  86. {
  87. printf("%s: ERROR: coding(%d) is out of range.\n", __FUNCTION__, coding);
  88. return;
  89. }
  90. if (capability<0 || capability>31)
  91. {
  92. printf("%s: ERROR: capability(%d) is out of range.\n", __FUNCTION__, capability);
  93. return;
  94. }
  95. if (mode<0 || mode>3)
  96. {
  97. printf("%s: ERROR: mode(%d) is out of range.\n", __FUNCTION__, mode);
  98. return;
  99. }
  100. if (rate<0 || rate>31)
  101. {
  102. printf("%s: ERROR: rate(%d) is out of range.\n", __FUNCTION__, rate);
  103. return;
  104. }
  105. if (multi>127)
  106. {
  107. printf("%s: ERROR: multi(%d) is out of range.\n", __FUNCTION__, multi);
  108. return;
  109. }
  110. if (user>31)
  111. {
  112. printf("%s: ERROR: user L1(%d) is out of range.\n", __FUNCTION__, rate);
  113. return;
  114. }
  115. if (rate!=24 && multi>=0)
  116. {
  117. printf("%s: WARNING: multi(%d) is only possible if rate(%d) would be 24.\n", __FUNCTION__, multi, rate);
  118. multi = -1;
  119. }
  120. if (MISDN_IE_DEBG) printf(" coding=%d capability=%d mode=%d rate=%d multi=%d user=%d\n", coding, capability, mode, rate, multi, user);
  121. l = 2 + (multi>=0) + (user>=0);
  122. p = msg_put(msg, l+2);
  123. if (nt)
  124. *ntmode = p+1;
  125. else
  126. qi->QI_ELEMENT(bearer_capability) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  127. p[0] = IE_BEARER;
  128. p[1] = l;
  129. p[2] = 0x80 + (coding<<5) + capability;
  130. p[3] = 0x80 + (mode<<5) + rate;
  131. if (multi >= 0)
  132. p[4] = 0x80 + multi;
  133. if (user >= 0)
  134. p[4+(multi>=0)] = 0xa0 + user;
  135. }
  136. static void dec_ie_bearer(unsigned char *p, Q931_info_t *qi, int *coding, int *capability, int *mode, int *rate, int *multi, int *user,
  137. int *async, int *urate, int *stopbits, int *dbits, int *parity, int nt, struct misdn_bchannel *bc)
  138. {
  139. int octet;
  140. *coding = -1;
  141. *capability = -1;
  142. *mode = -1;
  143. *rate = -1;
  144. *multi = -1;
  145. *user = -1;
  146. *async = -1;
  147. *urate = -1;
  148. *stopbits = -1;
  149. *dbits = -1;
  150. *parity = -1;
  151. if (!nt)
  152. {
  153. p = NULL;
  154. #ifdef LLC_SUPPORT
  155. if (qi->QI_ELEMENT(llc)) {
  156. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(llc) + 1;
  157. }
  158. #endif
  159. if (qi->QI_ELEMENT(bearer_capability))
  160. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(bearer_capability) + 1;
  161. }
  162. if (!p)
  163. return;
  164. if (p[0] < 2)
  165. {
  166. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  167. return;
  168. }
  169. *coding = (p[1]&0x60) >> 5;
  170. *capability = p[1] & 0x1f;
  171. octet = 2;
  172. if (!(p[1] & 0x80))
  173. octet++;
  174. if (p[0] < octet)
  175. goto done;
  176. *mode = (p[octet]&0x60) >> 5;
  177. *rate = p[octet] & 0x1f;
  178. octet++;
  179. if (p[0] < octet)
  180. goto done;
  181. if (*rate == 0x18) {
  182. /* Rate multiplier only present if 64Kb/s base rate */
  183. *multi = p[octet++] & 0x7f;
  184. }
  185. if (p[0] < octet)
  186. goto done;
  187. /* Start L1 info */
  188. if ((p[octet] & 0x60) == 0x20) {
  189. *user = p[octet] & 0x1f;
  190. if (p[0] <= octet)
  191. goto done;
  192. if (p[octet++] & 0x80)
  193. goto l2;
  194. *async = !!(p[octet] & 0x40);
  195. /* 0x20 is inband negotiation */
  196. *urate = p[octet] & 0x1f;
  197. if (p[0] <= octet)
  198. goto done;
  199. if (p[octet++] & 0x80)
  200. goto l2;
  201. /* Ignore next byte for now: Intermediate rate, NIC, flow control */
  202. if (p[0] <= octet)
  203. goto done;
  204. if (p[octet++] & 0x80)
  205. goto l2;
  206. /* And the next one. Header, multiframe, mode, assignor/ee, negotiation */
  207. if (p[0] <= octet)
  208. goto done;
  209. if (~p[octet++] & 0x80)
  210. goto l2;
  211. /* Wheee. V.110 speed information */
  212. *stopbits = (p[octet] & 0x60) >> 5;
  213. *dbits = (p[octet] & 0x18) >> 3;
  214. *parity = p[octet] & 7;
  215. octet++;
  216. }
  217. l2: /* Nobody seems to want the rest so we don't bother (yet) */
  218. done:
  219. if (MISDN_IE_DEBG) printf(" coding=%d capability=%d mode=%d rate=%d multi=%d user=%d async=%d urate=%d stopbits=%d dbits=%d parity=%d\n", *coding, *capability, *mode, *rate, *multi, *user, *async, *urate, *stopbits, *dbits, *parity);
  220. }
  221. /* IE_CALL_ID */
  222. #if 0
  223. static void enc_ie_call_id(unsigned char **ntmode, msg_t *msg, char *callid, int callid_len, int nt, struct misdn_bchannel *bc)
  224. {
  225. unsigned char *p;
  226. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  227. int l;
  228. char debug[25];
  229. int i;
  230. if (!callid || callid_len<=0)
  231. {
  232. return;
  233. }
  234. if (callid_len>8)
  235. {
  236. printf("%s: ERROR: callid_len(%d) is out of range.\n", __FUNCTION__, callid_len);
  237. return;
  238. }
  239. i = 0;
  240. while(i < callid_len)
  241. {
  242. if (MISDN_IE_DEBG) printf(debug+(i*3), " %02hhx", (unsigned char)callid[i]);
  243. i++;
  244. }
  245. if (MISDN_IE_DEBG) printf(" callid%s\n", debug);
  246. l = callid_len;
  247. p = msg_put(msg, l+2);
  248. if (nt)
  249. *ntmode = p+1;
  250. else
  251. qi->QI_ELEMENT(call_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  252. p[0] = IE_CALL_ID;
  253. p[1] = l;
  254. memcpy(p+2, callid, callid_len);
  255. }
  256. #endif
  257. #if 0
  258. static void dec_ie_call_id(unsigned char *p, Q931_info_t *qi, char *callid, int *callid_len, int nt, struct misdn_bchannel *bc)
  259. {
  260. char debug[25];
  261. int i;
  262. *callid_len = -1;
  263. if (!nt)
  264. {
  265. p = NULL;
  266. if (qi->QI_ELEMENT(call_id))
  267. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(call_id) + 1;
  268. }
  269. if (!p)
  270. return;
  271. if (p[0] > 8)
  272. {
  273. printf("%s: ERROR: IE too long (%d).\n", __FUNCTION__, p[0]);
  274. return;
  275. }
  276. *callid_len = p[0];
  277. memcpy(callid, p+1, *callid_len);
  278. i = 0;
  279. while(i < *callid_len)
  280. {
  281. if (MISDN_IE_DEBG) printf(debug+(i*3), " %02hhx", (unsigned char)callid[i]);
  282. i++;
  283. }
  284. if (MISDN_IE_DEBG) printf(" callid%s\n", debug);
  285. }
  286. #endif
  287. /* IE_CALLED_PN */
  288. static void enc_ie_called_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, char *number, int nt, struct misdn_bchannel *bc)
  289. {
  290. unsigned char *p;
  291. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  292. int l;
  293. if (type<0 || type>7)
  294. {
  295. printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
  296. return;
  297. }
  298. if (plan<0 || plan>15)
  299. {
  300. printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
  301. return;
  302. }
  303. if (!number[0])
  304. {
  305. printf("%s: ERROR: number is not given.\n", __FUNCTION__);
  306. return;
  307. }
  308. if (MISDN_IE_DEBG) printf(" type=%d plan=%d number='%s'\n", type, plan, number);
  309. l = 1+strlen((char *)number);
  310. p = msg_put(msg, l+2);
  311. if (nt)
  312. *ntmode = p+1;
  313. else
  314. qi->QI_ELEMENT(called_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  315. p[0] = IE_CALLED_PN;
  316. p[1] = l;
  317. p[2] = 0x80 + (type<<4) + plan;
  318. strncpy((char *)p+3, (char *)number, strlen((char *)number));
  319. }
  320. static void dec_ie_called_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
  321. {
  322. *type = -1;
  323. *plan = -1;
  324. *number = '\0';
  325. if (!nt)
  326. {
  327. p = NULL;
  328. if (qi->QI_ELEMENT(called_nr))
  329. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(called_nr) + 1;
  330. }
  331. if (!p)
  332. return;
  333. if (p[0] < 2)
  334. {
  335. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  336. return;
  337. }
  338. *type = (p[1]&0x70) >> 4;
  339. *plan = p[1] & 0xf;
  340. strnncpy(number, (char *)p+2, p[0]-1, number_len);
  341. if (MISDN_IE_DEBG) printf(" type=%d plan=%d number='%s'\n", *type, *plan, number);
  342. }
  343. /* IE_CALLING_PN */
  344. static void enc_ie_calling_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, char *number, int nt, struct misdn_bchannel *bc)
  345. {
  346. unsigned char *p;
  347. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  348. int l;
  349. if (type<0 || type>7)
  350. {
  351. printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
  352. return;
  353. }
  354. if (plan<0 || plan>15)
  355. {
  356. printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
  357. return;
  358. }
  359. if (present>3)
  360. {
  361. printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
  362. return;
  363. }
  364. if (present >= 0) if (screen<0 || screen>3)
  365. {
  366. printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
  367. return;
  368. }
  369. if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
  370. l = 1;
  371. if (number) if (number[0])
  372. l += strlen((char *)number);
  373. if (present >= 0)
  374. l += 1;
  375. p = msg_put(msg, l+2);
  376. if (nt)
  377. *ntmode = p+1;
  378. else
  379. qi->QI_ELEMENT(calling_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  380. p[0] = IE_CALLING_PN;
  381. p[1] = l;
  382. if (present >= 0)
  383. {
  384. p[2] = 0x00 + (type<<4) + plan;
  385. p[3] = 0x80 + (present<<5) + screen;
  386. if (number) if (number[0])
  387. strncpy((char *)p+4, (char *)number, strlen((char *)number));
  388. } else
  389. {
  390. p[2] = 0x80 + (type<<4) + plan;
  391. if (number) if (number[0])
  392. strncpy((char *)p+3, (char *)number, strlen((char *)number));
  393. }
  394. }
  395. static void dec_ie_calling_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
  396. {
  397. *type = -1;
  398. *plan = -1;
  399. *present = -1;
  400. *screen = -1;
  401. *number = '\0';
  402. if (!nt)
  403. {
  404. p = NULL;
  405. if (qi->QI_ELEMENT(calling_nr))
  406. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(calling_nr) + 1;
  407. }
  408. if (!p)
  409. return;
  410. if (p[0] < 1)
  411. {
  412. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  413. return;
  414. }
  415. *type = (p[1]&0x70) >> 4;
  416. *plan = p[1] & 0xf;
  417. if (!(p[1] & 0x80))
  418. {
  419. if (p[0] < 2)
  420. {
  421. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  422. return;
  423. }
  424. *present = (p[2]&0x60) >> 5;
  425. *screen = p[2] & 0x3;
  426. strnncpy(number, (char *)p+3, p[0]-2, number_len);
  427. } else
  428. {
  429. strnncpy(number, (char *)p+2, p[0]-1, number_len);
  430. /* SPECIAL workarround for IBT software bug */
  431. /* if (number[0]==0x80) */
  432. /* strcpy((char *)number, (char *)number+1); */
  433. }
  434. if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
  435. }
  436. /* IE_CONNECTED_PN */
  437. static void enc_ie_connected_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, char *number, int nt, struct misdn_bchannel *bc)
  438. {
  439. unsigned char *p;
  440. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  441. int l;
  442. if (type<0 || type>7)
  443. {
  444. printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
  445. return;
  446. }
  447. if (plan<0 || plan>15)
  448. {
  449. printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
  450. return;
  451. }
  452. if (present>3)
  453. {
  454. printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
  455. return;
  456. }
  457. if (present >= 0) if (screen<0 || screen>3)
  458. {
  459. printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
  460. return;
  461. }
  462. if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
  463. l = 1;
  464. if (number) if (number[0])
  465. l += strlen((char *)number);
  466. if (present >= 0)
  467. l += 1;
  468. p = msg_put(msg, l+2);
  469. if (nt)
  470. *ntmode = p+1;
  471. else
  472. qi->QI_ELEMENT(connected_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  473. p[0] = IE_CONNECT_PN;
  474. p[1] = l;
  475. if (present >= 0)
  476. {
  477. p[2] = 0x00 + (type<<4) + plan;
  478. p[3] = 0x80 + (present<<5) + screen;
  479. if (number) if (number[0])
  480. strncpy((char *)p+4, (char *)number, strlen((char *)number));
  481. } else
  482. {
  483. p[2] = 0x80 + (type<<4) + plan;
  484. if (number) if (number[0])
  485. strncpy((char *)p+3, (char *)number, strlen((char *)number));
  486. }
  487. }
  488. static void dec_ie_connected_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
  489. {
  490. *type = -1;
  491. *plan = -1;
  492. *present = -1;
  493. *screen = -1;
  494. *number = '\0';
  495. if (!nt)
  496. {
  497. p = NULL;
  498. if (qi->QI_ELEMENT(connected_nr))
  499. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(connected_nr) + 1;
  500. }
  501. if (!p)
  502. return;
  503. if (p[0] < 1)
  504. {
  505. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  506. return;
  507. }
  508. *type = (p[1]&0x70) >> 4;
  509. *plan = p[1] & 0xf;
  510. if (!(p[1] & 0x80))
  511. {
  512. if (p[0] < 2)
  513. {
  514. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  515. return;
  516. }
  517. *present = (p[2]&0x60) >> 5;
  518. *screen = p[2] & 0x3;
  519. strnncpy(number, (char *)p+3, p[0]-2, number_len);
  520. } else
  521. {
  522. strnncpy(number, (char *)p+2, p[0]-1, number_len);
  523. }
  524. if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
  525. }
  526. /* IE_CAUSE */
  527. static void enc_ie_cause(unsigned char **ntmode, msg_t *msg, int location, int cause, int nt, struct misdn_bchannel *bc)
  528. {
  529. unsigned char *p;
  530. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  531. int l;
  532. if (location<0 || location>7)
  533. {
  534. printf("%s: ERROR: location(%d) is out of range.\n", __FUNCTION__, location);
  535. return;
  536. }
  537. if (cause<0 || cause>127)
  538. {
  539. printf("%s: ERROR: cause(%d) is out of range.\n", __FUNCTION__, cause);
  540. return;
  541. }
  542. if (MISDN_IE_DEBG) printf(" location=%d cause=%d\n", location, cause);
  543. l = 2;
  544. p = msg_put(msg, l+2);
  545. if (nt)
  546. *ntmode = p+1;
  547. else
  548. qi->QI_ELEMENT(cause) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  549. p[0] = IE_CAUSE;
  550. p[1] = l;
  551. p[2] = 0x80 + location;
  552. p[3] = 0x80 + cause;
  553. }
  554. #if 0
  555. static void enc_ie_cause_standalone(unsigned char **ntmode, msg_t *msg, int location, int cause, int nt, struct misdn_bchannel *bc)
  556. {
  557. unsigned char *p = msg_put(msg, 4);
  558. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  559. if (ntmode)
  560. *ntmode = p+1;
  561. else
  562. qi->QI_ELEMENT(cause) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  563. p[0] = IE_CAUSE;
  564. p[1] = 2;
  565. p[2] = 0x80 + location;
  566. p[3] = 0x80 + cause;
  567. }
  568. #endif
  569. static void dec_ie_cause(unsigned char *p, Q931_info_t *qi, int *location, int *cause, int nt, struct misdn_bchannel *bc)
  570. {
  571. *location = -1;
  572. *cause = -1;
  573. if (!nt)
  574. {
  575. p = NULL;
  576. if (qi->QI_ELEMENT(cause))
  577. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(cause) + 1;
  578. }
  579. if (!p)
  580. return;
  581. if (p[0] < 2)
  582. {
  583. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  584. return;
  585. }
  586. *location = p[1] & 0x0f;
  587. *cause = p[2] & 0x7f;
  588. if (MISDN_IE_DEBG) printf(" location=%d cause=%d\n", *location, *cause);
  589. }
  590. /* IE_CHANNEL_ID */
  591. static void enc_ie_channel_id(unsigned char **ntmode, msg_t *msg, int exclusive, int channel, int nt, struct misdn_bchannel *bc)
  592. {
  593. unsigned char *p;
  594. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  595. int l;
  596. struct misdn_stack *stack=get_stack_by_bc(bc);
  597. int pri = stack->pri;
  598. if (exclusive<0 || exclusive>1)
  599. {
  600. printf("%s: ERROR: exclusive(%d) is out of range.\n", __FUNCTION__, exclusive);
  601. return;
  602. }
  603. if ((channel<0 || channel>0xff)
  604. || (!pri && (channel>2 && channel<0xff))
  605. || (pri && (channel>31 && channel<0xff))
  606. || (pri && channel==16))
  607. {
  608. printf("%s: ERROR: channel(%d) is out of range.\n", __FUNCTION__, channel);
  609. return;
  610. }
  611. /* if (MISDN_IE_DEBG) printf(" exclusive=%d channel=%d\n", exclusive, channel); */
  612. if (!pri)
  613. {
  614. /* BRI */
  615. l = 1;
  616. p = msg_put(msg, l+2);
  617. if (nt)
  618. *ntmode = p+1;
  619. else
  620. qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  621. p[0] = IE_CHANNEL_ID;
  622. p[1] = l;
  623. if (channel == 0xff)
  624. channel = 3;
  625. p[2] = 0x80 + (exclusive<<3) + channel;
  626. /* printf(" exclusive=%d channel=%d\n", exclusive, channel); */
  627. } else
  628. {
  629. /* PRI */
  630. if (channel == 0) /* no channel */
  631. return; /* IE not present */
  632. /* if (MISDN_IE_DEBG) printf("channel = %d\n", channel); */
  633. if (channel == 0xff) /* any channel */
  634. {
  635. l = 1;
  636. p = msg_put(msg, l+2);
  637. if (nt)
  638. *ntmode = p+1;
  639. else
  640. qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  641. p[0] = IE_CHANNEL_ID;
  642. p[1] = l;
  643. p[2] = 0x80 + 0x20 + 0x03;
  644. /* if (MISDN_IE_DEBG) printf("%02hhx\n", p[2]); */
  645. return; /* end */
  646. }
  647. l = 3;
  648. p = msg_put(msg, l+2);
  649. if (nt)
  650. *ntmode = p+1;
  651. else
  652. qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  653. p[0] = IE_CHANNEL_ID;
  654. p[1] = l;
  655. p[2] = 0x80 + 0x20 + (exclusive<<3) + 0x01;
  656. p[3] = 0x80 + 3; /* CCITT, Number, B-type */
  657. p[4] = 0x80 + channel;
  658. /* if (MISDN_IE_DEBG) printf("%02hhx %02hhx %02hhx\n", p[2], p[3], p[4]); */
  659. }
  660. }
  661. static void dec_ie_channel_id(unsigned char *p, Q931_info_t *qi, int *exclusive, int *channel, int nt, struct misdn_bchannel *bc)
  662. {
  663. struct misdn_stack *stack=get_stack_by_bc(bc);
  664. int pri =stack->pri;
  665. *exclusive = -1;
  666. *channel = -1;
  667. if (!nt)
  668. {
  669. p = NULL;
  670. if (qi->QI_ELEMENT(channel_id))
  671. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(channel_id) + 1;
  672. }
  673. if (!p)
  674. return;
  675. if (p[0] < 1)
  676. {
  677. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  678. return;
  679. }
  680. if (p[1] & 0x40)
  681. {
  682. printf("%s: ERROR: refering to channels of other interfaces is not supported.\n", __FUNCTION__);
  683. return;
  684. }
  685. if (p[1] & 0x04)
  686. {
  687. printf("%s: ERROR: using d-channel is not supported.\n", __FUNCTION__);
  688. return;
  689. }
  690. *exclusive = (p[1]&0x08) >> 3;
  691. if (!pri)
  692. {
  693. /* BRI */
  694. if (p[1] & 0x20)
  695. {
  696. printf("%s: ERROR: extended channel ID with non PRI interface.\n", __FUNCTION__);
  697. return;
  698. }
  699. *channel = p[1] & 0x03;
  700. if (*channel == 3)
  701. *channel = 0xff;
  702. } else
  703. {
  704. /* PRI */
  705. if (p[0] < 1)
  706. {
  707. printf("%s: ERROR: IE too short for PRI (%d).\n", __FUNCTION__, p[0]);
  708. return;
  709. }
  710. if (!(p[1] & 0x20))
  711. {
  712. printf("%s: ERROR: basic channel ID with PRI interface.\n", __FUNCTION__);
  713. return;
  714. }
  715. if ((p[1]&0x03) == 0x00)
  716. {
  717. /* no channel */
  718. *channel = 0;
  719. return;
  720. }
  721. if ((p[1]&0x03) == 0x03)
  722. {
  723. /* any channel */
  724. *channel = 0xff;
  725. return;
  726. }
  727. if (p[0] < 3)
  728. {
  729. printf("%s: ERROR: IE too short for PRI with channel(%d).\n", __FUNCTION__, p[0]);
  730. return;
  731. }
  732. if (p[2] & 0x10)
  733. {
  734. printf("%s: ERROR: channel map not supported.\n", __FUNCTION__);
  735. return;
  736. }
  737. *channel = p[3] & 0x7f;
  738. if ( (*channel<1) | (*channel==16) | (*channel>31))
  739. {
  740. printf("%s: ERROR: PRI interface channel out of range (%d).\n", __FUNCTION__, *channel);
  741. return;
  742. }
  743. /* if (MISDN_IE_DEBG) printf("%02hhx %02hhx %02hhx\n", p[1], p[2], p[3]); */
  744. }
  745. if (MISDN_IE_DEBG) printf(" exclusive=%d channel=%d\n", *exclusive, *channel);
  746. }
  747. /* IE_DATE */
  748. static void enc_ie_date(unsigned char **ntmode, msg_t *msg, time_t ti, int nt, struct misdn_bchannel *bc)
  749. {
  750. unsigned char *p;
  751. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  752. int l;
  753. struct timeval tv = { ti, 0 };
  754. struct ast_tm tm;
  755. ast_localtime(&tv, &tm, NULL);
  756. if (MISDN_IE_DEBG) printf(" year=%d month=%d day=%d hour=%d minute=%d\n", tm.tm_year%100, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min);
  757. l = 5;
  758. p = msg_put(msg, l+2);
  759. if (nt)
  760. *ntmode = p+1;
  761. else
  762. qi->QI_ELEMENT(date) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  763. p[0] = IE_DATE;
  764. p[1] = l;
  765. p[2] = tm.tm_year % 100;
  766. p[3] = tm.tm_mon + 1;
  767. p[4] = tm.tm_mday;
  768. p[5] = tm.tm_hour;
  769. p[6] = tm.tm_min;
  770. }
  771. /* IE_DISPLAY */
  772. static void enc_ie_display(unsigned char **ntmode, msg_t *msg, char *display, int nt, struct misdn_bchannel *bc)
  773. {
  774. unsigned char *p;
  775. Q931_info_t *qi = (Q931_info_t *) (msg->data + mISDN_HEADER_LEN);
  776. int l;
  777. if (!display[0])
  778. {
  779. printf("%s: ERROR: display text not given.\n", __FUNCTION__);
  780. return;
  781. }
  782. l = strlen(display);
  783. if (80 < l)
  784. {
  785. l = 80;
  786. printf("%s: WARNING: display text too long (max %d chars), cutting.\n", __FUNCTION__, l);
  787. display[l] = '\0';
  788. }
  789. /* if (MISDN_IE_DEBG) printf(" display='%s' (len=%d)\n", display, l); */
  790. p = msg_put(msg, l + 2);
  791. if (nt)
  792. *ntmode = p + 1;
  793. else
  794. qi->QI_ELEMENT(display) = p - (unsigned char *) qi - sizeof(Q931_info_t);
  795. p[0] = IE_DISPLAY;
  796. p[1] = l;
  797. strncpy((char *) p + 2, display, l);
  798. }
  799. #if 0
  800. static void dec_ie_display(unsigned char *p, Q931_info_t *qi, char *display, size_t display_len, int nt, struct misdn_bchannel *bc)
  801. {
  802. *display = '\0';
  803. if (!nt)
  804. {
  805. p = NULL;
  806. if (qi->QI_ELEMENT(display))
  807. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(display) + 1;
  808. }
  809. if (!p)
  810. return;
  811. if (p[0] < 1)
  812. {
  813. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  814. return;
  815. }
  816. strnncpy(display, (char *)p+1, p[0], display_len);
  817. if (MISDN_IE_DEBG) printf(" display='%s'\n", display);
  818. }
  819. #endif
  820. /* IE_KEYPAD */
  821. #if 1
  822. static void enc_ie_keypad(unsigned char **ntmode, msg_t *msg, char *keypad, int nt, struct misdn_bchannel *bc)
  823. {
  824. unsigned char *p;
  825. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  826. int l;
  827. if (!keypad[0])
  828. {
  829. printf("%s: ERROR: keypad info not given.\n", __FUNCTION__);
  830. return;
  831. }
  832. if (MISDN_IE_DEBG) printf(" keypad='%s'\n", keypad);
  833. l = strlen(keypad);
  834. p = msg_put(msg, l+2);
  835. if (nt)
  836. *ntmode = p+1;
  837. else
  838. qi->QI_ELEMENT(keypad) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  839. p[0] = IE_KEYPAD;
  840. p[1] = l;
  841. strncpy((char *)p+2, keypad, strlen(keypad));
  842. }
  843. #endif
  844. static void dec_ie_keypad(unsigned char *p, Q931_info_t *qi, char *keypad, size_t keypad_len, int nt, struct misdn_bchannel *bc)
  845. {
  846. *keypad = '\0';
  847. if (!nt)
  848. {
  849. p = NULL;
  850. if (qi->QI_ELEMENT(keypad))
  851. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(keypad) + 1;
  852. }
  853. if (!p)
  854. return;
  855. if (p[0] < 1)
  856. {
  857. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  858. return;
  859. }
  860. strnncpy(keypad, (char *)p+1, p[0], keypad_len);
  861. if (MISDN_IE_DEBG) printf(" keypad='%s'\n", keypad);
  862. }
  863. /* IE_NOTIFY */
  864. static void enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify, int nt, struct misdn_bchannel *bc)
  865. {
  866. unsigned char *p;
  867. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  868. int l;
  869. if (notify<0 || notify>0x7f)
  870. {
  871. printf("%s: ERROR: notify(%d) is out of range.\n", __FUNCTION__, notify);
  872. return;
  873. }
  874. if (MISDN_IE_DEBG) printf(" notify=%d\n", notify);
  875. l = 1;
  876. p = msg_put(msg, l+2);
  877. if (nt)
  878. *ntmode = p+1;
  879. else
  880. qi->QI_ELEMENT(notify) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  881. p[0] = IE_NOTIFY;
  882. p[1] = l;
  883. p[2] = 0x80 + notify;
  884. }
  885. static void dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify, int nt, struct misdn_bchannel *bc)
  886. {
  887. *notify = -1;
  888. if (!nt)
  889. {
  890. p = NULL;
  891. if (qi->QI_ELEMENT(notify))
  892. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(notify) + 1;
  893. }
  894. if (!p)
  895. return;
  896. if (p[0] < 1)
  897. {
  898. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  899. return;
  900. }
  901. *notify = p[1] & 0x7f;
  902. if (MISDN_IE_DEBG) printf(" notify=%d\n", *notify);
  903. }
  904. /* IE_PROGRESS */
  905. static void enc_ie_progress(unsigned char **ntmode, msg_t *msg, int coding, int location, int progress, int nt, struct misdn_bchannel *bc)
  906. {
  907. unsigned char *p;
  908. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  909. int l;
  910. if (coding<0 || coding>0x03)
  911. {
  912. printf("%s: ERROR: coding(%d) is out of range.\n", __FUNCTION__, coding);
  913. return;
  914. }
  915. if (location<0 || location>0x0f)
  916. {
  917. printf("%s: ERROR: location(%d) is out of range.\n", __FUNCTION__, location);
  918. return;
  919. }
  920. if (progress<0 || progress>0x7f)
  921. {
  922. printf("%s: ERROR: progress(%d) is out of range.\n", __FUNCTION__, progress);
  923. return;
  924. }
  925. if (MISDN_IE_DEBG) printf(" coding=%d location=%d progress=%d\n", coding, location, progress);
  926. l = 2;
  927. p = msg_put(msg, l+2);
  928. if (nt)
  929. *ntmode = p+1;
  930. else
  931. qi->QI_ELEMENT(progress) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  932. p[0] = IE_PROGRESS;
  933. p[1] = l;
  934. p[2] = 0x80 + (coding<<5) + location;
  935. p[3] = 0x80 + progress;
  936. }
  937. static void dec_ie_progress(unsigned char *p, Q931_info_t *qi, int *coding, int *location, int *progress, int nt, struct misdn_bchannel *bc)
  938. {
  939. *coding = -1;
  940. *location = -1;
  941. //*progress = -1;
  942. *progress = 0;
  943. if (!nt)
  944. {
  945. p = NULL;
  946. if (qi->QI_ELEMENT(progress))
  947. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(progress) + 1;
  948. }
  949. if (!p)
  950. return;
  951. if (p[0] < 1)
  952. {
  953. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  954. return;
  955. }
  956. *coding = (p[1]&0x60) >> 5;
  957. *location = p[1] & 0x0f;
  958. *progress = p[2] & 0x7f;
  959. if (MISDN_IE_DEBG) printf(" coding=%d location=%d progress=%d\n", *coding, *location, *progress);
  960. }
  961. /* IE_REDIR_NR (redirecting = during MT_SETUP) */
  962. static void enc_ie_redir_nr(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, int reason, char *number, int nt, struct misdn_bchannel *bc)
  963. {
  964. unsigned char *p;
  965. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  966. int l;
  967. if (type<0 || type>7)
  968. {
  969. printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
  970. return;
  971. }
  972. if (plan<0 || plan>15)
  973. {
  974. printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
  975. return;
  976. }
  977. if (present > 3)
  978. {
  979. printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
  980. return;
  981. }
  982. if (present >= 0) if (screen<0 || screen>3)
  983. {
  984. printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
  985. return;
  986. }
  987. if (reason > 0x0f)
  988. {
  989. printf("%s: ERROR: reason(%d) is out of range.\n", __FUNCTION__, reason);
  990. return;
  991. }
  992. if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d readon=%d number='%s'\n", type, plan, present, screen, reason, number);
  993. l = 1;
  994. if (number)
  995. l += strlen((char *)number);
  996. if (present >= 0)
  997. {
  998. l += 1;
  999. if (reason >= 0)
  1000. l += 1;
  1001. }
  1002. p = msg_put(msg, l+2);
  1003. if (nt)
  1004. *ntmode = p+1;
  1005. else
  1006. qi->QI_ELEMENT(redirect_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  1007. p[0] = IE_REDIR_NR;
  1008. p[1] = l;
  1009. if (present >= 0)
  1010. {
  1011. if (reason >= 0)
  1012. {
  1013. p[2] = 0x00 + (type<<4) + plan;
  1014. p[3] = 0x00 + (present<<5) + screen;
  1015. p[4] = 0x80 + reason;
  1016. if (number)
  1017. strncpy((char *)p+5, (char *)number, strlen((char *)number));
  1018. } else
  1019. {
  1020. p[2] = 0x00 + (type<<4) + plan;
  1021. p[3] = 0x80 + (present<<5) + screen;
  1022. if (number)
  1023. strncpy((char *)p+4, (char *)number, strlen((char *)number));
  1024. }
  1025. } else
  1026. {
  1027. p[2] = 0x80 + (type<<4) + plan;
  1028. if (number) if (number[0])
  1029. strncpy((char *)p+3, (char *)number, strlen((char *)number));
  1030. }
  1031. }
  1032. static void dec_ie_redir_nr(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, int *reason, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
  1033. {
  1034. *type = -1;
  1035. *plan = -1;
  1036. *present = -1;
  1037. *screen = -1;
  1038. *reason = -1;
  1039. *number = '\0';
  1040. if (!nt)
  1041. {
  1042. p = NULL;
  1043. if (qi->QI_ELEMENT(redirect_nr))
  1044. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redirect_nr) + 1;
  1045. }
  1046. if (!p)
  1047. return;
  1048. if (p[0] < 1)
  1049. {
  1050. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  1051. return;
  1052. }
  1053. *type = (p[1]&0x70) >> 4;
  1054. *plan = p[1] & 0xf;
  1055. if (!(p[1] & 0x80))
  1056. {
  1057. *present = (p[2]&0x60) >> 5;
  1058. *screen = p[2] & 0x3;
  1059. if (!(p[2] & 0x80))
  1060. {
  1061. *reason = p[3] & 0x0f;
  1062. strnncpy(number, (char *)p+4, p[0]-3, number_len);
  1063. } else
  1064. {
  1065. strnncpy(number, (char *)p+3, p[0]-2, number_len);
  1066. }
  1067. } else
  1068. {
  1069. strnncpy(number, (char *)p+2, p[0]-1, number_len);
  1070. }
  1071. if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d reason=%d number='%s'\n", *type, *plan, *present, *screen, *reason, number);
  1072. }
  1073. /* IE_REDIR_DN (redirection = during MT_NOTIFY) */
  1074. static void enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, char *number, int nt, struct misdn_bchannel *bc)
  1075. {
  1076. unsigned char *p;
  1077. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  1078. int l;
  1079. if (type<0 || type>7)
  1080. {
  1081. printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
  1082. return;
  1083. }
  1084. if (plan<0 || plan>15)
  1085. {
  1086. printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
  1087. return;
  1088. }
  1089. if (present > 3)
  1090. {
  1091. printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
  1092. return;
  1093. }
  1094. if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d number='%s'\n", type, plan, present, number);
  1095. l = 1;
  1096. if (number)
  1097. l += strlen((char *)number);
  1098. if (present >= 0)
  1099. l += 1;
  1100. p = msg_put(msg, l+2);
  1101. if (nt)
  1102. *ntmode = p+1;
  1103. else {
  1104. qi->QI_ELEMENT(redirect_dn) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  1105. }
  1106. p[0] = IE_REDIR_DN;
  1107. p[1] = l;
  1108. if (present >= 0)
  1109. {
  1110. p[2] = 0x00 + (type<<4) + plan;
  1111. p[3] = 0x80 + (present<<5);
  1112. if (number)
  1113. strncpy((char *)p+4, (char *)number, strlen((char *)number));
  1114. } else
  1115. {
  1116. p[2] = 0x80 + (type<<4) + plan;
  1117. if (number)
  1118. strncpy((char *)p+3, (char *)number, strlen((char *)number));
  1119. }
  1120. }
  1121. static void dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
  1122. {
  1123. *type = -1;
  1124. *plan = -1;
  1125. *present = -1;
  1126. *number = '\0';
  1127. if (!nt)
  1128. {
  1129. p = NULL;
  1130. if (qi->QI_ELEMENT(redirect_dn))
  1131. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redirect_dn) + 1;
  1132. }
  1133. if (!p)
  1134. return;
  1135. if (p[0] < 1)
  1136. {
  1137. printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
  1138. return;
  1139. }
  1140. *type = (p[1]&0x70) >> 4;
  1141. *plan = p[1] & 0xf;
  1142. if (!(p[1] & 0x80))
  1143. {
  1144. *present = (p[2]&0x60) >> 5;
  1145. strnncpy(number, (char *)p+3, p[0]-2, number_len);
  1146. } else
  1147. {
  1148. strnncpy(number, (char *)p+2, p[0]-1, number_len);
  1149. }
  1150. if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d number='%s'\n", *type, *plan, *present, number);
  1151. }
  1152. /* IE_USERUSER */
  1153. #if 1
  1154. static void enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, char *user, int user_len, int nt, struct misdn_bchannel *bc)
  1155. {
  1156. unsigned char *p;
  1157. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  1158. int l;
  1159. if (protocol<0 || protocol>127)
  1160. {
  1161. printf("%s: ERROR: protocol(%d) is out of range.\n", __FUNCTION__, protocol);
  1162. return;
  1163. }
  1164. if (!user || user_len<=0)
  1165. {
  1166. return;
  1167. }
  1168. if (MISDN_IE_DEBG) {
  1169. size_t i;
  1170. char debug[768];
  1171. for (i = 0; i < user_len; ++i) {
  1172. sprintf(debug + (i * 3), " %02hhx", (unsigned char)user[i]);
  1173. }
  1174. debug[i * 3] = 0;
  1175. printf(" protocol=%d user-user%s\n", protocol, debug);
  1176. }
  1177. l = user_len+1;
  1178. p = msg_put(msg, l+3);
  1179. if (nt)
  1180. *ntmode = p+1;
  1181. else
  1182. qi->QI_ELEMENT(useruser) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  1183. p[0] = IE_USER_USER;
  1184. p[1] = l;
  1185. p[2] = protocol;
  1186. memcpy(p+3, user, user_len);
  1187. }
  1188. #endif
  1189. #if 1
  1190. static void dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, char *user, int *user_len, int nt, struct misdn_bchannel *bc)
  1191. {
  1192. *user_len = 0;
  1193. *protocol = -1;
  1194. if (!nt)
  1195. {
  1196. p = NULL;
  1197. if (qi->QI_ELEMENT(useruser))
  1198. p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(useruser) + 1;
  1199. }
  1200. if (!p)
  1201. return;
  1202. *user_len = p[0]-1;
  1203. if (p[0] < 1)
  1204. return;
  1205. *protocol = p[1];
  1206. memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
  1207. if (MISDN_IE_DEBG) {
  1208. int i;
  1209. char debug[768];
  1210. for (i = 0; i < *user_len; ++i) {
  1211. sprintf(debug + (i * 3), " %02hhx", (unsigned char)user[i]);
  1212. }
  1213. debug[i * 3] = 0;
  1214. printf(" protocol=%d user-user%s\n", *protocol, debug);
  1215. }
  1216. }
  1217. #endif
  1218. /* IE_DISPLAY */
  1219. static void enc_ie_restart_ind(unsigned char **ntmode, msg_t *msg, unsigned char rind, int nt, struct misdn_bchannel *bc)
  1220. {
  1221. unsigned char *p;
  1222. Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
  1223. /* if (MISDN_IE_DEBG) printf(" display='%s' (len=%d)\n", display, strlen((char *)display)); */
  1224. p = msg_put(msg, 3);
  1225. if (nt)
  1226. *ntmode = p+1;
  1227. else
  1228. qi->QI_ELEMENT(restart_ind) = p - (unsigned char *)qi - sizeof(Q931_info_t);
  1229. p[0] = IE_RESTART_IND;
  1230. p[1] = 1;
  1231. p[2] = rind;
  1232. }