ie.c 32 KB

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