q931.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514
  1. /* $Id: q931.c,v 1.12.2.3 2004/01/13 14:31:26 keil Exp $
  2. *
  3. * code to decode ITU Q.931 call control messages
  4. *
  5. * Author Jan den Ouden
  6. * Copyright by Jan den Ouden
  7. *
  8. * This software may be used and distributed according to the terms
  9. * of the GNU General Public License, incorporated herein by reference.
  10. *
  11. * Changelog:
  12. *
  13. * Pauline Middelink general improvements
  14. * Beat Doebeli cause texts, display information element
  15. * Karsten Keil cause texts, display information element for 1TR6
  16. *
  17. */
  18. #include "hisax.h"
  19. #include "l3_1tr6.h"
  20. void
  21. iecpy(u_char *dest, u_char *iestart, int ieoffset)
  22. {
  23. u_char *p;
  24. int l;
  25. p = iestart + ieoffset + 2;
  26. l = iestart[1] - ieoffset;
  27. while (l--)
  28. *dest++ = *p++;
  29. *dest++ = '\0';
  30. }
  31. /*
  32. * According to Table 4-2/Q.931
  33. */
  34. static
  35. struct MessageType {
  36. u_char nr;
  37. char *descr;
  38. } mtlist[] = {
  39. {
  40. 0x1, "ALERTING"
  41. },
  42. {
  43. 0x2, "CALL PROCEEDING"
  44. },
  45. {
  46. 0x7, "CONNECT"
  47. },
  48. {
  49. 0xf, "CONNECT ACKNOWLEDGE"
  50. },
  51. {
  52. 0x3, "PROGRESS"
  53. },
  54. {
  55. 0x5, "SETUP"
  56. },
  57. {
  58. 0xd, "SETUP ACKNOWLEDGE"
  59. },
  60. {
  61. 0x24, "HOLD"
  62. },
  63. {
  64. 0x28, "HOLD ACKNOWLEDGE"
  65. },
  66. {
  67. 0x30, "HOLD REJECT"
  68. },
  69. {
  70. 0x31, "RETRIEVE"
  71. },
  72. {
  73. 0x33, "RETRIEVE ACKNOWLEDGE"
  74. },
  75. {
  76. 0x37, "RETRIEVE REJECT"
  77. },
  78. {
  79. 0x26, "RESUME"
  80. },
  81. {
  82. 0x2e, "RESUME ACKNOWLEDGE"
  83. },
  84. {
  85. 0x22, "RESUME REJECT"
  86. },
  87. {
  88. 0x25, "SUSPEND"
  89. },
  90. {
  91. 0x2d, "SUSPEND ACKNOWLEDGE"
  92. },
  93. {
  94. 0x21, "SUSPEND REJECT"
  95. },
  96. {
  97. 0x20, "USER INFORMATION"
  98. },
  99. {
  100. 0x45, "DISCONNECT"
  101. },
  102. {
  103. 0x4d, "RELEASE"
  104. },
  105. {
  106. 0x5a, "RELEASE COMPLETE"
  107. },
  108. {
  109. 0x46, "RESTART"
  110. },
  111. {
  112. 0x4e, "RESTART ACKNOWLEDGE"
  113. },
  114. {
  115. 0x60, "SEGMENT"
  116. },
  117. {
  118. 0x79, "CONGESTION CONTROL"
  119. },
  120. {
  121. 0x7b, "INFORMATION"
  122. },
  123. {
  124. 0x62, "FACILITY"
  125. },
  126. {
  127. 0x6e, "NOTIFY"
  128. },
  129. {
  130. 0x7d, "STATUS"
  131. },
  132. {
  133. 0x75, "STATUS ENQUIRY"
  134. }
  135. };
  136. #define MTSIZE ARRAY_SIZE(mtlist)
  137. static
  138. struct MessageType mt_n0[] =
  139. {
  140. {MT_N0_REG_IND, "REGister INDication"},
  141. {MT_N0_CANC_IND, "CANCel INDication"},
  142. {MT_N0_FAC_STA, "FACility STAtus"},
  143. {MT_N0_STA_ACK, "STAtus ACKnowledge"},
  144. {MT_N0_STA_REJ, "STAtus REJect"},
  145. {MT_N0_FAC_INF, "FACility INFormation"},
  146. {MT_N0_INF_ACK, "INFormation ACKnowledge"},
  147. {MT_N0_INF_REJ, "INFormation REJect"},
  148. {MT_N0_CLOSE, "CLOSE"},
  149. {MT_N0_CLO_ACK, "CLOse ACKnowledge"}
  150. };
  151. #define MT_N0_LEN ARRAY_SIZE(mt_n0)
  152. static
  153. struct MessageType mt_n1[] =
  154. {
  155. {MT_N1_ESC, "ESCape"},
  156. {MT_N1_ALERT, "ALERT"},
  157. {MT_N1_CALL_SENT, "CALL SENT"},
  158. {MT_N1_CONN, "CONNect"},
  159. {MT_N1_CONN_ACK, "CONNect ACKnowledge"},
  160. {MT_N1_SETUP, "SETUP"},
  161. {MT_N1_SETUP_ACK, "SETUP ACKnowledge"},
  162. {MT_N1_RES, "RESume"},
  163. {MT_N1_RES_ACK, "RESume ACKnowledge"},
  164. {MT_N1_RES_REJ, "RESume REJect"},
  165. {MT_N1_SUSP, "SUSPend"},
  166. {MT_N1_SUSP_ACK, "SUSPend ACKnowledge"},
  167. {MT_N1_SUSP_REJ, "SUSPend REJect"},
  168. {MT_N1_USER_INFO, "USER INFO"},
  169. {MT_N1_DET, "DETach"},
  170. {MT_N1_DISC, "DISConnect"},
  171. {MT_N1_REL, "RELease"},
  172. {MT_N1_REL_ACK, "RELease ACKnowledge"},
  173. {MT_N1_CANC_ACK, "CANCel ACKnowledge"},
  174. {MT_N1_CANC_REJ, "CANCel REJect"},
  175. {MT_N1_CON_CON, "CONgestion CONtrol"},
  176. {MT_N1_FAC, "FACility"},
  177. {MT_N1_FAC_ACK, "FACility ACKnowledge"},
  178. {MT_N1_FAC_CAN, "FACility CANcel"},
  179. {MT_N1_FAC_REG, "FACility REGister"},
  180. {MT_N1_FAC_REJ, "FACility REJect"},
  181. {MT_N1_INFO, "INFOrmation"},
  182. {MT_N1_REG_ACK, "REGister ACKnowledge"},
  183. {MT_N1_REG_REJ, "REGister REJect"},
  184. {MT_N1_STAT, "STATus"}
  185. };
  186. #define MT_N1_LEN ARRAY_SIZE(mt_n1)
  187. static int
  188. prbits(char *dest, u_char b, int start, int len)
  189. {
  190. char *dp = dest;
  191. b = b << (8 - start);
  192. while (len--) {
  193. if (b & 0x80)
  194. *dp++ = '1';
  195. else
  196. *dp++ = '0';
  197. b = b << 1;
  198. }
  199. return (dp - dest);
  200. }
  201. static
  202. u_char *
  203. skipext(u_char *p)
  204. {
  205. while (!(*p++ & 0x80));
  206. return (p);
  207. }
  208. /*
  209. * Cause Values According to Q.850
  210. * edescr: English description
  211. * ddescr: German description used by Swissnet II (Swiss Telecom
  212. * not yet written...
  213. */
  214. static
  215. struct CauseValue {
  216. u_char nr;
  217. char *edescr;
  218. char *ddescr;
  219. } cvlist[] = {
  220. {
  221. 0x01, "Unallocated (unassigned) number", "Nummer nicht zugeteilt"
  222. },
  223. {
  224. 0x02, "No route to specified transit network", ""
  225. },
  226. {
  227. 0x03, "No route to destination", ""
  228. },
  229. {
  230. 0x04, "Send special information tone", ""
  231. },
  232. {
  233. 0x05, "Misdialled trunk prefix", ""
  234. },
  235. {
  236. 0x06, "Channel unacceptable", "Kanal nicht akzeptierbar"
  237. },
  238. {
  239. 0x07, "Channel awarded and being delivered in an established channel", ""
  240. },
  241. {
  242. 0x08, "Preemption", ""
  243. },
  244. {
  245. 0x09, "Preemption - circuit reserved for reuse", ""
  246. },
  247. {
  248. 0x10, "Normal call clearing", "Normale Ausloesung"
  249. },
  250. {
  251. 0x11, "User busy", "TNB besetzt"
  252. },
  253. {
  254. 0x12, "No user responding", ""
  255. },
  256. {
  257. 0x13, "No answer from user (user alerted)", ""
  258. },
  259. {
  260. 0x14, "Subscriber absent", ""
  261. },
  262. {
  263. 0x15, "Call rejected", ""
  264. },
  265. {
  266. 0x16, "Number changed", ""
  267. },
  268. {
  269. 0x1a, "non-selected user clearing", ""
  270. },
  271. {
  272. 0x1b, "Destination out of order", ""
  273. },
  274. {
  275. 0x1c, "Invalid number format (address incomplete)", ""
  276. },
  277. {
  278. 0x1d, "Facility rejected", ""
  279. },
  280. {
  281. 0x1e, "Response to Status enquiry", ""
  282. },
  283. {
  284. 0x1f, "Normal, unspecified", ""
  285. },
  286. {
  287. 0x22, "No circuit/channel available", ""
  288. },
  289. {
  290. 0x26, "Network out of order", ""
  291. },
  292. {
  293. 0x27, "Permanent frame mode connection out-of-service", ""
  294. },
  295. {
  296. 0x28, "Permanent frame mode connection operational", ""
  297. },
  298. {
  299. 0x29, "Temporary failure", ""
  300. },
  301. {
  302. 0x2a, "Switching equipment congestion", ""
  303. },
  304. {
  305. 0x2b, "Access information discarded", ""
  306. },
  307. {
  308. 0x2c, "Requested circuit/channel not available", ""
  309. },
  310. {
  311. 0x2e, "Precedence call blocked", ""
  312. },
  313. {
  314. 0x2f, "Resource unavailable, unspecified", ""
  315. },
  316. {
  317. 0x31, "Quality of service unavailable", ""
  318. },
  319. {
  320. 0x32, "Requested facility not subscribed", ""
  321. },
  322. {
  323. 0x35, "Outgoing calls barred within CUG", ""
  324. },
  325. {
  326. 0x37, "Incoming calls barred within CUG", ""
  327. },
  328. {
  329. 0x39, "Bearer capability not authorized", ""
  330. },
  331. {
  332. 0x3a, "Bearer capability not presently available", ""
  333. },
  334. {
  335. 0x3e, "Inconsistency in designated outgoing access information and subscriber class ", " "
  336. },
  337. {
  338. 0x3f, "Service or option not available, unspecified", ""
  339. },
  340. {
  341. 0x41, "Bearer capability not implemented", ""
  342. },
  343. {
  344. 0x42, "Channel type not implemented", ""
  345. },
  346. {
  347. 0x43, "Requested facility not implemented", ""
  348. },
  349. {
  350. 0x44, "Only restricted digital information bearer capability is available", ""
  351. },
  352. {
  353. 0x4f, "Service or option not implemented", ""
  354. },
  355. {
  356. 0x51, "Invalid call reference value", ""
  357. },
  358. {
  359. 0x52, "Identified channel does not exist", ""
  360. },
  361. {
  362. 0x53, "A suspended call exists, but this call identity does not", ""
  363. },
  364. {
  365. 0x54, "Call identity in use", ""
  366. },
  367. {
  368. 0x55, "No call suspended", ""
  369. },
  370. {
  371. 0x56, "Call having the requested call identity has been cleared", ""
  372. },
  373. {
  374. 0x57, "User not member of CUG", ""
  375. },
  376. {
  377. 0x58, "Incompatible destination", ""
  378. },
  379. {
  380. 0x5a, "Non-existent CUG", ""
  381. },
  382. {
  383. 0x5b, "Invalid transit network selection", ""
  384. },
  385. {
  386. 0x5f, "Invalid message, unspecified", ""
  387. },
  388. {
  389. 0x60, "Mandatory information element is missing", ""
  390. },
  391. {
  392. 0x61, "Message type non-existent or not implemented", ""
  393. },
  394. {
  395. 0x62, "Message not compatible with call state or message type non-existent or not implemented ", " "
  396. },
  397. {
  398. 0x63, "Information element/parameter non-existent or not implemented", ""
  399. },
  400. {
  401. 0x64, "Invalid information element contents", ""
  402. },
  403. {
  404. 0x65, "Message not compatible with call state", ""
  405. },
  406. {
  407. 0x66, "Recovery on timer expiry", ""
  408. },
  409. {
  410. 0x67, "Parameter non-existent or not implemented - passed on", ""
  411. },
  412. {
  413. 0x6e, "Message with unrecognized parameter discarded", ""
  414. },
  415. {
  416. 0x6f, "Protocol error, unspecified", ""
  417. },
  418. {
  419. 0x7f, "Interworking, unspecified", ""
  420. },
  421. };
  422. #define CVSIZE ARRAY_SIZE(cvlist)
  423. static
  424. int
  425. prcause(char *dest, u_char *p)
  426. {
  427. u_char *end;
  428. char *dp = dest;
  429. int i, cause;
  430. end = p + p[1] + 1;
  431. p += 2;
  432. dp += sprintf(dp, " coding ");
  433. dp += prbits(dp, *p, 7, 2);
  434. dp += sprintf(dp, " location ");
  435. dp += prbits(dp, *p, 4, 4);
  436. *dp++ = '\n';
  437. p = skipext(p);
  438. cause = 0x7f & *p++;
  439. /* locate cause value */
  440. for (i = 0; i < CVSIZE; i++)
  441. if (cvlist[i].nr == cause)
  442. break;
  443. /* display cause value if it exists */
  444. if (i == CVSIZE)
  445. dp += sprintf(dp, "Unknown cause type %x!\n", cause);
  446. else
  447. dp += sprintf(dp, " cause value %x : %s \n", cause, cvlist[i].edescr);
  448. while (!0) {
  449. if (p > end)
  450. break;
  451. dp += sprintf(dp, " diag attribute %d ", *p++ & 0x7f);
  452. dp += sprintf(dp, " rej %d ", *p & 0x7f);
  453. if (*p & 0x80) {
  454. *dp++ = '\n';
  455. break;
  456. } else
  457. dp += sprintf(dp, " av %d\n", (*++p) & 0x7f);
  458. }
  459. return (dp - dest);
  460. }
  461. static
  462. struct MessageType cause_1tr6[] =
  463. {
  464. {CAUSE_InvCRef, "Invalid Call Reference"},
  465. {CAUSE_BearerNotImpl, "Bearer Service Not Implemented"},
  466. {CAUSE_CIDunknown, "Caller Identity unknown"},
  467. {CAUSE_CIDinUse, "Caller Identity in Use"},
  468. {CAUSE_NoChans, "No Channels available"},
  469. {CAUSE_FacNotImpl, "Facility Not Implemented"},
  470. {CAUSE_FacNotSubscr, "Facility Not Subscribed"},
  471. {CAUSE_OutgoingBarred, "Outgoing calls barred"},
  472. {CAUSE_UserAccessBusy, "User Access Busy"},
  473. {CAUSE_NegativeGBG, "Negative GBG"},
  474. {CAUSE_UnknownGBG, "Unknown GBG"},
  475. {CAUSE_NoSPVknown, "No SPV known"},
  476. {CAUSE_DestNotObtain, "Destination not obtainable"},
  477. {CAUSE_NumberChanged, "Number changed"},
  478. {CAUSE_OutOfOrder, "Out Of Order"},
  479. {CAUSE_NoUserResponse, "No User Response"},
  480. {CAUSE_UserBusy, "User Busy"},
  481. {CAUSE_IncomingBarred, "Incoming Barred"},
  482. {CAUSE_CallRejected, "Call Rejected"},
  483. {CAUSE_NetworkCongestion, "Network Congestion"},
  484. {CAUSE_RemoteUser, "Remote User initiated"},
  485. {CAUSE_LocalProcErr, "Local Procedure Error"},
  486. {CAUSE_RemoteProcErr, "Remote Procedure Error"},
  487. {CAUSE_RemoteUserSuspend, "Remote User Suspend"},
  488. {CAUSE_RemoteUserResumed, "Remote User Resumed"},
  489. {CAUSE_UserInfoDiscarded, "User Info Discarded"}
  490. };
  491. static int cause_1tr6_len = ARRAY_SIZE(cause_1tr6);
  492. static int
  493. prcause_1tr6(char *dest, u_char *p)
  494. {
  495. char *dp = dest;
  496. int i, cause;
  497. p++;
  498. if (0 == *p) {
  499. dp += sprintf(dp, " OK (cause length=0)\n");
  500. return (dp - dest);
  501. } else if (*p > 1) {
  502. dp += sprintf(dp, " coding ");
  503. dp += prbits(dp, p[2], 7, 2);
  504. dp += sprintf(dp, " location ");
  505. dp += prbits(dp, p[2], 4, 4);
  506. *dp++ = '\n';
  507. }
  508. p++;
  509. cause = 0x7f & *p;
  510. /* locate cause value */
  511. for (i = 0; i < cause_1tr6_len; i++)
  512. if (cause_1tr6[i].nr == cause)
  513. break;
  514. /* display cause value if it exists */
  515. if (i == cause_1tr6_len)
  516. dp += sprintf(dp, "Unknown cause type %x!\n", cause);
  517. else
  518. dp += sprintf(dp, " cause value %x : %s \n", cause, cause_1tr6[i].descr);
  519. return (dp - dest);
  520. }
  521. static int
  522. prchident(char *dest, u_char *p)
  523. {
  524. char *dp = dest;
  525. p += 2;
  526. dp += sprintf(dp, " octet 3 ");
  527. dp += prbits(dp, *p, 8, 8);
  528. *dp++ = '\n';
  529. return (dp - dest);
  530. }
  531. static int
  532. prcalled(char *dest, u_char *p)
  533. {
  534. int l;
  535. char *dp = dest;
  536. p++;
  537. l = *p++ - 1;
  538. dp += sprintf(dp, " octet 3 ");
  539. dp += prbits(dp, *p++, 8, 8);
  540. *dp++ = '\n';
  541. dp += sprintf(dp, " number digits ");
  542. while (l--)
  543. *dp++ = *p++;
  544. *dp++ = '\n';
  545. return (dp - dest);
  546. }
  547. static int
  548. prcalling(char *dest, u_char *p)
  549. {
  550. int l;
  551. char *dp = dest;
  552. p++;
  553. l = *p++ - 1;
  554. dp += sprintf(dp, " octet 3 ");
  555. dp += prbits(dp, *p, 8, 8);
  556. *dp++ = '\n';
  557. if (!(*p & 0x80)) {
  558. dp += sprintf(dp, " octet 3a ");
  559. dp += prbits(dp, *++p, 8, 8);
  560. *dp++ = '\n';
  561. l--;
  562. };
  563. p++;
  564. dp += sprintf(dp, " number digits ");
  565. while (l--)
  566. *dp++ = *p++;
  567. *dp++ = '\n';
  568. return (dp - dest);
  569. }
  570. static
  571. int
  572. prbearer(char *dest, u_char *p)
  573. {
  574. char *dp = dest, ch;
  575. p += 2;
  576. dp += sprintf(dp, " octet 3 ");
  577. dp += prbits(dp, *p++, 8, 8);
  578. *dp++ = '\n';
  579. dp += sprintf(dp, " octet 4 ");
  580. dp += prbits(dp, *p, 8, 8);
  581. *dp++ = '\n';
  582. if ((*p++ & 0x1f) == 0x18) {
  583. dp += sprintf(dp, " octet 4.1 ");
  584. dp += prbits(dp, *p++, 8, 8);
  585. *dp++ = '\n';
  586. }
  587. /* check for user information layer 1 */
  588. if ((*p & 0x60) == 0x20) {
  589. ch = ' ';
  590. do {
  591. dp += sprintf(dp, " octet 5%c ", ch);
  592. dp += prbits(dp, *p, 8, 8);
  593. *dp++ = '\n';
  594. if (ch == ' ')
  595. ch = 'a';
  596. else
  597. ch++;
  598. }
  599. while (!(*p++ & 0x80));
  600. }
  601. /* check for user information layer 2 */
  602. if ((*p & 0x60) == 0x40) {
  603. dp += sprintf(dp, " octet 6 ");
  604. dp += prbits(dp, *p++, 8, 8);
  605. *dp++ = '\n';
  606. }
  607. /* check for user information layer 3 */
  608. if ((*p & 0x60) == 0x60) {
  609. dp += sprintf(dp, " octet 7 ");
  610. dp += prbits(dp, *p++, 8, 8);
  611. *dp++ = '\n';
  612. }
  613. return (dp - dest);
  614. }
  615. static
  616. int
  617. prbearer_ni1(char *dest, u_char *p)
  618. {
  619. char *dp = dest;
  620. u_char len;
  621. p++;
  622. len = *p++;
  623. dp += sprintf(dp, " octet 3 ");
  624. dp += prbits(dp, *p, 8, 8);
  625. switch (*p++) {
  626. case 0x80:
  627. dp += sprintf(dp, " Speech");
  628. break;
  629. case 0x88:
  630. dp += sprintf(dp, " Unrestricted digital information");
  631. break;
  632. case 0x90:
  633. dp += sprintf(dp, " 3.1 kHz audio");
  634. break;
  635. default:
  636. dp += sprintf(dp, " Unknown information-transfer capability");
  637. }
  638. *dp++ = '\n';
  639. dp += sprintf(dp, " octet 4 ");
  640. dp += prbits(dp, *p, 8, 8);
  641. switch (*p++) {
  642. case 0x90:
  643. dp += sprintf(dp, " 64 kbps, circuit mode");
  644. break;
  645. case 0xc0:
  646. dp += sprintf(dp, " Packet mode");
  647. break;
  648. default:
  649. dp += sprintf(dp, " Unknown transfer mode");
  650. }
  651. *dp++ = '\n';
  652. if (len > 2) {
  653. dp += sprintf(dp, " octet 5 ");
  654. dp += prbits(dp, *p, 8, 8);
  655. switch (*p++) {
  656. case 0x21:
  657. dp += sprintf(dp, " Rate adaption\n");
  658. dp += sprintf(dp, " octet 5a ");
  659. dp += prbits(dp, *p, 8, 8);
  660. break;
  661. case 0xa2:
  662. dp += sprintf(dp, " u-law");
  663. break;
  664. default:
  665. dp += sprintf(dp, " Unknown UI layer 1 protocol");
  666. }
  667. *dp++ = '\n';
  668. }
  669. return (dp - dest);
  670. }
  671. static int
  672. general(char *dest, u_char *p)
  673. {
  674. char *dp = dest;
  675. char ch = ' ';
  676. int l, octet = 3;
  677. p++;
  678. l = *p++;
  679. /* Iterate over all octets in the information element */
  680. while (l--) {
  681. dp += sprintf(dp, " octet %d%c ", octet, ch);
  682. dp += prbits(dp, *p++, 8, 8);
  683. *dp++ = '\n';
  684. /* last octet in group? */
  685. if (*p & 0x80) {
  686. octet++;
  687. ch = ' ';
  688. } else if (ch == ' ')
  689. ch = 'a';
  690. else
  691. ch++;
  692. }
  693. return (dp - dest);
  694. }
  695. static int
  696. general_ni1(char *dest, u_char *p)
  697. {
  698. char *dp = dest;
  699. char ch = ' ';
  700. int l, octet = 3;
  701. p++;
  702. l = *p++;
  703. /* Iterate over all octets in the information element */
  704. while (l--) {
  705. dp += sprintf(dp, " octet %d%c ", octet, ch);
  706. dp += prbits(dp, *p, 8, 8);
  707. *dp++ = '\n';
  708. /* last octet in group? */
  709. if (*p++ & 0x80) {
  710. octet++;
  711. ch = ' ';
  712. } else if (ch == ' ')
  713. ch = 'a';
  714. else
  715. ch++;
  716. }
  717. return (dp - dest);
  718. }
  719. static int
  720. prcharge(char *dest, u_char *p)
  721. {
  722. char *dp = dest;
  723. int l;
  724. p++;
  725. l = *p++ - 1;
  726. dp += sprintf(dp, " GEA ");
  727. dp += prbits(dp, *p++, 8, 8);
  728. dp += sprintf(dp, " Anzahl: ");
  729. /* Iterate over all octets in the * information element */
  730. while (l--)
  731. *dp++ = *p++;
  732. *dp++ = '\n';
  733. return (dp - dest);
  734. }
  735. static int
  736. prtext(char *dest, u_char *p)
  737. {
  738. char *dp = dest;
  739. int l;
  740. p++;
  741. l = *p++;
  742. dp += sprintf(dp, " ");
  743. /* Iterate over all octets in the * information element */
  744. while (l--)
  745. *dp++ = *p++;
  746. *dp++ = '\n';
  747. return (dp - dest);
  748. }
  749. static int
  750. prfeatureind(char *dest, u_char *p)
  751. {
  752. char *dp = dest;
  753. p += 2; /* skip id, len */
  754. dp += sprintf(dp, " octet 3 ");
  755. dp += prbits(dp, *p, 8, 8);
  756. *dp++ = '\n';
  757. if (!(*p++ & 0x80)) {
  758. dp += sprintf(dp, " octet 4 ");
  759. dp += prbits(dp, *p++, 8, 8);
  760. *dp++ = '\n';
  761. }
  762. dp += sprintf(dp, " Status: ");
  763. switch (*p) {
  764. case 0:
  765. dp += sprintf(dp, "Idle");
  766. break;
  767. case 1:
  768. dp += sprintf(dp, "Active");
  769. break;
  770. case 2:
  771. dp += sprintf(dp, "Prompt");
  772. break;
  773. case 3:
  774. dp += sprintf(dp, "Pending");
  775. break;
  776. default:
  777. dp += sprintf(dp, "(Reserved)");
  778. break;
  779. }
  780. *dp++ = '\n';
  781. return (dp - dest);
  782. }
  783. static
  784. struct DTag { /* Display tags */
  785. u_char nr;
  786. char *descr;
  787. } dtaglist[] = {
  788. { 0x82, "Continuation" },
  789. { 0x83, "Called address" },
  790. { 0x84, "Cause" },
  791. { 0x85, "Progress indicator" },
  792. { 0x86, "Notification indicator" },
  793. { 0x87, "Prompt" },
  794. { 0x88, "Accumlated digits" },
  795. { 0x89, "Status" },
  796. { 0x8a, "Inband" },
  797. { 0x8b, "Calling address" },
  798. { 0x8c, "Reason" },
  799. { 0x8d, "Calling party name" },
  800. { 0x8e, "Called party name" },
  801. { 0x8f, "Orignal called name" },
  802. { 0x90, "Redirecting name" },
  803. { 0x91, "Connected name" },
  804. { 0x92, "Originating restrictions" },
  805. { 0x93, "Date & time of day" },
  806. { 0x94, "Call Appearance ID" },
  807. { 0x95, "Feature address" },
  808. { 0x96, "Redirection name" },
  809. { 0x9e, "Text" },
  810. };
  811. #define DTAGSIZE ARRAY_SIZE(dtaglist)
  812. static int
  813. disptext_ni1(char *dest, u_char *p)
  814. {
  815. char *dp = dest;
  816. int l, tag, len, i;
  817. p++;
  818. l = *p++ - 1;
  819. if (*p++ != 0x80) {
  820. dp += sprintf(dp, " Unknown display type\n");
  821. return (dp - dest);
  822. }
  823. /* Iterate over all tag,length,text fields */
  824. while (l > 0) {
  825. tag = *p++;
  826. len = *p++;
  827. l -= len + 2;
  828. /* Don't space or skip */
  829. if ((tag == 0x80) || (tag == 0x81)) p++;
  830. else {
  831. for (i = 0; i < DTAGSIZE; i++)
  832. if (tag == dtaglist[i].nr)
  833. break;
  834. /* When not found, give appropriate msg */
  835. if (i != DTAGSIZE) {
  836. dp += sprintf(dp, " %s: ", dtaglist[i].descr);
  837. while (len--)
  838. *dp++ = *p++;
  839. } else {
  840. dp += sprintf(dp, " (unknown display tag %2x): ", tag);
  841. while (len--)
  842. *dp++ = *p++;
  843. }
  844. dp += sprintf(dp, "\n");
  845. }
  846. }
  847. return (dp - dest);
  848. }
  849. static int
  850. display(char *dest, u_char *p)
  851. {
  852. char *dp = dest;
  853. char ch = ' ';
  854. int l, octet = 3;
  855. p++;
  856. l = *p++;
  857. /* Iterate over all octets in the * display-information element */
  858. dp += sprintf(dp, " \"");
  859. while (l--) {
  860. dp += sprintf(dp, "%c", *p++);
  861. /* last octet in group? */
  862. if (*p & 0x80) {
  863. octet++;
  864. ch = ' ';
  865. } else if (ch == ' ')
  866. ch = 'a';
  867. else
  868. ch++;
  869. }
  870. *dp++ = '\"';
  871. *dp++ = '\n';
  872. return (dp - dest);
  873. }
  874. static int
  875. prfacility(char *dest, u_char *p)
  876. {
  877. char *dp = dest;
  878. int l, l2;
  879. p++;
  880. l = *p++;
  881. dp += sprintf(dp, " octet 3 ");
  882. dp += prbits(dp, *p++, 8, 8);
  883. dp += sprintf(dp, "\n");
  884. l -= 1;
  885. while (l > 0) {
  886. dp += sprintf(dp, " octet 4 ");
  887. dp += prbits(dp, *p++, 8, 8);
  888. dp += sprintf(dp, "\n");
  889. dp += sprintf(dp, " octet 5 %d\n", l2 = *p++ & 0x7f);
  890. l -= 2;
  891. dp += sprintf(dp, " contents ");
  892. while (l2--) {
  893. dp += sprintf(dp, "%2x ", *p++);
  894. l--;
  895. }
  896. dp += sprintf(dp, "\n");
  897. }
  898. return (dp - dest);
  899. }
  900. static
  901. struct InformationElement {
  902. u_char nr;
  903. char *descr;
  904. int (*f) (char *, u_char *);
  905. } ielist[] = {
  906. {
  907. 0x00, "Segmented message", general
  908. },
  909. {
  910. 0x04, "Bearer capability", prbearer
  911. },
  912. {
  913. 0x08, "Cause", prcause
  914. },
  915. {
  916. 0x10, "Call identity", general
  917. },
  918. {
  919. 0x14, "Call state", general
  920. },
  921. {
  922. 0x18, "Channel identification", prchident
  923. },
  924. {
  925. 0x1c, "Facility", prfacility
  926. },
  927. {
  928. 0x1e, "Progress indicator", general
  929. },
  930. {
  931. 0x20, "Network-specific facilities", general
  932. },
  933. {
  934. 0x27, "Notification indicator", general
  935. },
  936. {
  937. 0x28, "Display", display
  938. },
  939. {
  940. 0x29, "Date/Time", general
  941. },
  942. {
  943. 0x2c, "Keypad facility", general
  944. },
  945. {
  946. 0x34, "Signal", general
  947. },
  948. {
  949. 0x40, "Information rate", general
  950. },
  951. {
  952. 0x42, "End-to-end delay", general
  953. },
  954. {
  955. 0x43, "Transit delay selection and indication", general
  956. },
  957. {
  958. 0x44, "Packet layer binary parameters", general
  959. },
  960. {
  961. 0x45, "Packet layer window size", general
  962. },
  963. {
  964. 0x46, "Packet size", general
  965. },
  966. {
  967. 0x47, "Closed user group", general
  968. },
  969. {
  970. 0x4a, "Reverse charge indication", general
  971. },
  972. {
  973. 0x6c, "Calling party number", prcalling
  974. },
  975. {
  976. 0x6d, "Calling party subaddress", general
  977. },
  978. {
  979. 0x70, "Called party number", prcalled
  980. },
  981. {
  982. 0x71, "Called party subaddress", general
  983. },
  984. {
  985. 0x74, "Redirecting number", general
  986. },
  987. {
  988. 0x78, "Transit network selection", general
  989. },
  990. {
  991. 0x79, "Restart indicator", general
  992. },
  993. {
  994. 0x7c, "Low layer compatibility", general
  995. },
  996. {
  997. 0x7d, "High layer compatibility", general
  998. },
  999. {
  1000. 0x7e, "User-user", general
  1001. },
  1002. {
  1003. 0x7f, "Escape for extension", general
  1004. },
  1005. };
  1006. #define IESIZE ARRAY_SIZE(ielist)
  1007. static
  1008. struct InformationElement ielist_ni1[] = {
  1009. { 0x04, "Bearer Capability", prbearer_ni1 },
  1010. { 0x08, "Cause", prcause },
  1011. { 0x14, "Call State", general_ni1 },
  1012. { 0x18, "Channel Identification", prchident },
  1013. { 0x1e, "Progress Indicator", general_ni1 },
  1014. { 0x27, "Notification Indicator", general_ni1 },
  1015. { 0x2c, "Keypad Facility", prtext },
  1016. { 0x32, "Information Request", general_ni1 },
  1017. { 0x34, "Signal", general_ni1 },
  1018. { 0x38, "Feature Activation", general_ni1 },
  1019. { 0x39, "Feature Indication", prfeatureind },
  1020. { 0x3a, "Service Profile Identification (SPID)", prtext },
  1021. { 0x3b, "Endpoint Identifier", general_ni1 },
  1022. { 0x6c, "Calling Party Number", prcalling },
  1023. { 0x6d, "Calling Party Subaddress", general_ni1 },
  1024. { 0x70, "Called Party Number", prcalled },
  1025. { 0x71, "Called Party Subaddress", general_ni1 },
  1026. { 0x74, "Redirecting Number", general_ni1 },
  1027. { 0x78, "Transit Network Selection", general_ni1 },
  1028. { 0x7c, "Low Layer Compatibility", general_ni1 },
  1029. { 0x7d, "High Layer Compatibility", general_ni1 },
  1030. };
  1031. #define IESIZE_NI1 ARRAY_SIZE(ielist_ni1)
  1032. static
  1033. struct InformationElement ielist_ni1_cs5[] = {
  1034. { 0x1d, "Operator system access", general_ni1 },
  1035. { 0x2a, "Display text", disptext_ni1 },
  1036. };
  1037. #define IESIZE_NI1_CS5 ARRAY_SIZE(ielist_ni1_cs5)
  1038. static
  1039. struct InformationElement ielist_ni1_cs6[] = {
  1040. { 0x7b, "Call appearance", general_ni1 },
  1041. };
  1042. #define IESIZE_NI1_CS6 ARRAY_SIZE(ielist_ni1_cs6)
  1043. static struct InformationElement we_0[] =
  1044. {
  1045. {WE0_cause, "Cause", prcause_1tr6},
  1046. {WE0_connAddr, "Connecting Address", prcalled},
  1047. {WE0_callID, "Call IDentity", general},
  1048. {WE0_chanID, "Channel IDentity", general},
  1049. {WE0_netSpecFac, "Network Specific Facility", general},
  1050. {WE0_display, "Display", general},
  1051. {WE0_keypad, "Keypad", general},
  1052. {WE0_origAddr, "Origination Address", prcalled},
  1053. {WE0_destAddr, "Destination Address", prcalled},
  1054. {WE0_userInfo, "User Info", general}
  1055. };
  1056. #define WE_0_LEN ARRAY_SIZE(we_0)
  1057. static struct InformationElement we_6[] =
  1058. {
  1059. {WE6_serviceInd, "Service Indicator", general},
  1060. {WE6_chargingInfo, "Charging Information", prcharge},
  1061. {WE6_date, "Date", prtext},
  1062. {WE6_facSelect, "Facility Select", general},
  1063. {WE6_facStatus, "Facility Status", general},
  1064. {WE6_statusCalled, "Status Called", general},
  1065. {WE6_addTransAttr, "Additional Transmission Attributes", general}
  1066. };
  1067. #define WE_6_LEN ARRAY_SIZE(we_6)
  1068. int
  1069. QuickHex(char *txt, u_char *p, int cnt)
  1070. {
  1071. register int i;
  1072. register char *t = txt;
  1073. for (i = 0; i < cnt; i++) {
  1074. *t++ = ' ';
  1075. *t++ = hex_asc_hi(p[i]);
  1076. *t++ = hex_asc_lo(p[i]);
  1077. }
  1078. *t++ = 0;
  1079. return (t - txt);
  1080. }
  1081. void
  1082. LogFrame(struct IsdnCardState *cs, u_char *buf, int size)
  1083. {
  1084. char *dp;
  1085. if (size < 1)
  1086. return;
  1087. dp = cs->dlog;
  1088. if (size < MAX_DLOG_SPACE / 3 - 10) {
  1089. *dp++ = 'H';
  1090. *dp++ = 'E';
  1091. *dp++ = 'X';
  1092. *dp++ = ':';
  1093. dp += QuickHex(dp, buf, size);
  1094. dp--;
  1095. *dp++ = '\n';
  1096. *dp = 0;
  1097. HiSax_putstatus(cs, NULL, cs->dlog);
  1098. } else
  1099. HiSax_putstatus(cs, "LogFrame: ", "warning Frame too big (%d)", size);
  1100. }
  1101. void
  1102. dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
  1103. {
  1104. u_char *bend, *buf;
  1105. char *dp;
  1106. unsigned char pd, cr_l, cr, mt;
  1107. unsigned char sapi, tei, ftyp;
  1108. int i, cset = 0, cs_old = 0, cs_fest = 0;
  1109. int size, finish = 0;
  1110. if (skb->len < 3)
  1111. return;
  1112. /* display header */
  1113. dp = cs->dlog;
  1114. dp += jiftime(dp, jiffies);
  1115. *dp++ = ' ';
  1116. sapi = skb->data[0] >> 2;
  1117. tei = skb->data[1] >> 1;
  1118. ftyp = skb->data[2];
  1119. buf = skb->data;
  1120. dp += sprintf(dp, "frame %s ", dir ? "network->user" : "user->network");
  1121. size = skb->len;
  1122. if (tei == GROUP_TEI) {
  1123. if (sapi == CTRL_SAPI) { /* sapi 0 */
  1124. if (ftyp == 3) {
  1125. dp += sprintf(dp, "broadcast\n");
  1126. buf += 3;
  1127. size -= 3;
  1128. } else {
  1129. dp += sprintf(dp, "no UI broadcast\n");
  1130. finish = 1;
  1131. }
  1132. } else if (sapi == TEI_SAPI) {
  1133. dp += sprintf(dp, "tei management\n");
  1134. finish = 1;
  1135. } else {
  1136. dp += sprintf(dp, "unknown sapi %d broadcast\n", sapi);
  1137. finish = 1;
  1138. }
  1139. } else {
  1140. if (sapi == CTRL_SAPI) {
  1141. if (!(ftyp & 1)) { /* IFrame */
  1142. dp += sprintf(dp, "with tei %d\n", tei);
  1143. buf += 4;
  1144. size -= 4;
  1145. } else {
  1146. dp += sprintf(dp, "SFrame with tei %d\n", tei);
  1147. finish = 1;
  1148. }
  1149. } else {
  1150. dp += sprintf(dp, "unknown sapi %d tei %d\n", sapi, tei);
  1151. finish = 1;
  1152. }
  1153. }
  1154. bend = skb->data + skb->len;
  1155. if (buf >= bend) {
  1156. dp += sprintf(dp, "frame too short\n");
  1157. finish = 1;
  1158. }
  1159. if (finish) {
  1160. *dp = 0;
  1161. HiSax_putstatus(cs, NULL, cs->dlog);
  1162. return;
  1163. }
  1164. if ((0xfe & buf[0]) == PROTO_DIS_N0) { /* 1TR6 */
  1165. /* locate message type */
  1166. pd = *buf++;
  1167. cr_l = *buf++;
  1168. if (cr_l)
  1169. cr = *buf++;
  1170. else
  1171. cr = 0;
  1172. mt = *buf++;
  1173. if (pd == PROTO_DIS_N0) { /* N0 */
  1174. for (i = 0; i < MT_N0_LEN; i++)
  1175. if (mt_n0[i].nr == mt)
  1176. break;
  1177. /* display message type if it exists */
  1178. if (i == MT_N0_LEN)
  1179. dp += sprintf(dp, "callref %d %s size %d unknown message type N0 %x!\n",
  1180. cr & 0x7f, (cr & 0x80) ? "called" : "caller",
  1181. size, mt);
  1182. else
  1183. dp += sprintf(dp, "callref %d %s size %d message type %s\n",
  1184. cr & 0x7f, (cr & 0x80) ? "called" : "caller",
  1185. size, mt_n0[i].descr);
  1186. } else { /* N1 */
  1187. for (i = 0; i < MT_N1_LEN; i++)
  1188. if (mt_n1[i].nr == mt)
  1189. break;
  1190. /* display message type if it exists */
  1191. if (i == MT_N1_LEN)
  1192. dp += sprintf(dp, "callref %d %s size %d unknown message type N1 %x!\n",
  1193. cr & 0x7f, (cr & 0x80) ? "called" : "caller",
  1194. size, mt);
  1195. else
  1196. dp += sprintf(dp, "callref %d %s size %d message type %s\n",
  1197. cr & 0x7f, (cr & 0x80) ? "called" : "caller",
  1198. size, mt_n1[i].descr);
  1199. }
  1200. /* display each information element */
  1201. while (buf < bend) {
  1202. /* Is it a single octet information element? */
  1203. if (*buf & 0x80) {
  1204. switch ((*buf >> 4) & 7) {
  1205. case 1:
  1206. dp += sprintf(dp, " Shift %x\n", *buf & 0xf);
  1207. cs_old = cset;
  1208. cset = *buf & 7;
  1209. cs_fest = *buf & 8;
  1210. break;
  1211. case 3:
  1212. dp += sprintf(dp, " Congestion level %x\n", *buf & 0xf);
  1213. break;
  1214. case 2:
  1215. if (*buf == 0xa0) {
  1216. dp += sprintf(dp, " More data\n");
  1217. break;
  1218. }
  1219. if (*buf == 0xa1) {
  1220. dp += sprintf(dp, " Sending complete\n");
  1221. }
  1222. break;
  1223. /* fall through */
  1224. default:
  1225. dp += sprintf(dp, " Reserved %x\n", *buf);
  1226. break;
  1227. }
  1228. buf++;
  1229. continue;
  1230. }
  1231. /* No, locate it in the table */
  1232. if (cset == 0) {
  1233. for (i = 0; i < WE_0_LEN; i++)
  1234. if (*buf == we_0[i].nr)
  1235. break;
  1236. /* When found, give appropriate msg */
  1237. if (i != WE_0_LEN) {
  1238. dp += sprintf(dp, " %s\n", we_0[i].descr);
  1239. dp += we_0[i].f(dp, buf);
  1240. } else
  1241. dp += sprintf(dp, " Codeset %d attribute %x attribute size %d\n", cset, *buf, buf[1]);
  1242. } else if (cset == 6) {
  1243. for (i = 0; i < WE_6_LEN; i++)
  1244. if (*buf == we_6[i].nr)
  1245. break;
  1246. /* When found, give appropriate msg */
  1247. if (i != WE_6_LEN) {
  1248. dp += sprintf(dp, " %s\n", we_6[i].descr);
  1249. dp += we_6[i].f(dp, buf);
  1250. } else
  1251. dp += sprintf(dp, " Codeset %d attribute %x attribute size %d\n", cset, *buf, buf[1]);
  1252. } else
  1253. dp += sprintf(dp, " Unknown Codeset %d attribute %x attribute size %d\n", cset, *buf, buf[1]);
  1254. /* Skip to next element */
  1255. if (cs_fest == 8) {
  1256. cset = cs_old;
  1257. cs_old = 0;
  1258. cs_fest = 0;
  1259. }
  1260. buf += buf[1] + 2;
  1261. }
  1262. } else if ((buf[0] == 8) && (cs->protocol == ISDN_PTYPE_NI1)) { /* NI-1 */
  1263. /* locate message type */
  1264. buf++;
  1265. cr_l = *buf++;
  1266. if (cr_l)
  1267. cr = *buf++;
  1268. else
  1269. cr = 0;
  1270. mt = *buf++;
  1271. for (i = 0; i < MTSIZE; i++)
  1272. if (mtlist[i].nr == mt)
  1273. break;
  1274. /* display message type if it exists */
  1275. if (i == MTSIZE)
  1276. dp += sprintf(dp, "callref %d %s size %d unknown message type %x!\n",
  1277. cr & 0x7f, (cr & 0x80) ? "called" : "caller",
  1278. size, mt);
  1279. else
  1280. dp += sprintf(dp, "callref %d %s size %d message type %s\n",
  1281. cr & 0x7f, (cr & 0x80) ? "called" : "caller",
  1282. size, mtlist[i].descr);
  1283. /* display each information element */
  1284. while (buf < bend) {
  1285. /* Is it a single octet information element? */
  1286. if (*buf & 0x80) {
  1287. switch ((*buf >> 4) & 7) {
  1288. case 1:
  1289. dp += sprintf(dp, " Shift %x\n", *buf & 0xf);
  1290. cs_old = cset;
  1291. cset = *buf & 7;
  1292. cs_fest = *buf & 8;
  1293. break;
  1294. default:
  1295. dp += sprintf(dp, " Unknown single-octet IE %x\n", *buf);
  1296. break;
  1297. }
  1298. buf++;
  1299. continue;
  1300. }
  1301. /* No, locate it in the table */
  1302. if (cset == 0) {
  1303. for (i = 0; i < IESIZE_NI1; i++)
  1304. if (*buf == ielist_ni1[i].nr)
  1305. break;
  1306. /* When not found, give appropriate msg */
  1307. if (i != IESIZE_NI1) {
  1308. dp += sprintf(dp, " %s\n", ielist_ni1[i].descr);
  1309. dp += ielist_ni1[i].f(dp, buf);
  1310. } else
  1311. dp += sprintf(dp, " attribute %x attribute size %d\n", *buf, buf[1]);
  1312. } else if (cset == 5) {
  1313. for (i = 0; i < IESIZE_NI1_CS5; i++)
  1314. if (*buf == ielist_ni1_cs5[i].nr)
  1315. break;
  1316. /* When not found, give appropriate msg */
  1317. if (i != IESIZE_NI1_CS5) {
  1318. dp += sprintf(dp, " %s\n", ielist_ni1_cs5[i].descr);
  1319. dp += ielist_ni1_cs5[i].f(dp, buf);
  1320. } else
  1321. dp += sprintf(dp, " attribute %x attribute size %d\n", *buf, buf[1]);
  1322. } else if (cset == 6) {
  1323. for (i = 0; i < IESIZE_NI1_CS6; i++)
  1324. if (*buf == ielist_ni1_cs6[i].nr)
  1325. break;
  1326. /* When not found, give appropriate msg */
  1327. if (i != IESIZE_NI1_CS6) {
  1328. dp += sprintf(dp, " %s\n", ielist_ni1_cs6[i].descr);
  1329. dp += ielist_ni1_cs6[i].f(dp, buf);
  1330. } else
  1331. dp += sprintf(dp, " attribute %x attribute size %d\n", *buf, buf[1]);
  1332. } else
  1333. dp += sprintf(dp, " Unknown Codeset %d attribute %x attribute size %d\n", cset, *buf, buf[1]);
  1334. /* Skip to next element */
  1335. if (cs_fest == 8) {
  1336. cset = cs_old;
  1337. cs_old = 0;
  1338. cs_fest = 0;
  1339. }
  1340. buf += buf[1] + 2;
  1341. }
  1342. } else if ((buf[0] == 8) && (cs->protocol == ISDN_PTYPE_EURO)) { /* EURO */
  1343. /* locate message type */
  1344. buf++;
  1345. cr_l = *buf++;
  1346. if (cr_l)
  1347. cr = *buf++;
  1348. else
  1349. cr = 0;
  1350. mt = *buf++;
  1351. for (i = 0; i < MTSIZE; i++)
  1352. if (mtlist[i].nr == mt)
  1353. break;
  1354. /* display message type if it exists */
  1355. if (i == MTSIZE)
  1356. dp += sprintf(dp, "callref %d %s size %d unknown message type %x!\n",
  1357. cr & 0x7f, (cr & 0x80) ? "called" : "caller",
  1358. size, mt);
  1359. else
  1360. dp += sprintf(dp, "callref %d %s size %d message type %s\n",
  1361. cr & 0x7f, (cr & 0x80) ? "called" : "caller",
  1362. size, mtlist[i].descr);
  1363. /* display each information element */
  1364. while (buf < bend) {
  1365. /* Is it a single octet information element? */
  1366. if (*buf & 0x80) {
  1367. switch ((*buf >> 4) & 7) {
  1368. case 1:
  1369. dp += sprintf(dp, " Shift %x\n", *buf & 0xf);
  1370. break;
  1371. case 3:
  1372. dp += sprintf(dp, " Congestion level %x\n", *buf & 0xf);
  1373. break;
  1374. case 5:
  1375. dp += sprintf(dp, " Repeat indicator %x\n", *buf & 0xf);
  1376. break;
  1377. case 2:
  1378. if (*buf == 0xa0) {
  1379. dp += sprintf(dp, " More data\n");
  1380. break;
  1381. }
  1382. if (*buf == 0xa1) {
  1383. dp += sprintf(dp, " Sending complete\n");
  1384. }
  1385. break;
  1386. /* fall through */
  1387. default:
  1388. dp += sprintf(dp, " Reserved %x\n", *buf);
  1389. break;
  1390. }
  1391. buf++;
  1392. continue;
  1393. }
  1394. /* No, locate it in the table */
  1395. for (i = 0; i < IESIZE; i++)
  1396. if (*buf == ielist[i].nr)
  1397. break;
  1398. /* When not found, give appropriate msg */
  1399. if (i != IESIZE) {
  1400. dp += sprintf(dp, " %s\n", ielist[i].descr);
  1401. dp += ielist[i].f(dp, buf);
  1402. } else
  1403. dp += sprintf(dp, " attribute %x attribute size %d\n", *buf, buf[1]);
  1404. /* Skip to next element */
  1405. buf += buf[1] + 2;
  1406. }
  1407. } else {
  1408. dp += sprintf(dp, "Unknown protocol %x!", buf[0]);
  1409. }
  1410. *dp = 0;
  1411. HiSax_putstatus(cs, NULL, cs->dlog);
  1412. }