rfcomm.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2001-2002 Wayne Lee <waynelee@qualcomm.com>
  7. * Copyright (C) 2003-2011 Marcel Holtmann <marcel@holtmann.org>
  8. *
  9. *
  10. */
  11. #ifdef HAVE_CONFIG_H
  12. #include <config.h>
  13. #endif
  14. #define _GNU_SOURCE
  15. #include <stdio.h>
  16. #include <errno.h>
  17. #include <unistd.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include "parser.h"
  21. #include "rfcomm.h"
  22. #include "sdp.h"
  23. static char *cr_str[] = {
  24. "RSP",
  25. "CMD"
  26. };
  27. #define CR_STR(mcc_head) cr_str[mcc_head->type.cr]
  28. #define GET_DLCI(addr) ((addr.server_chn << 1) | (addr.d & 1))
  29. static void print_rfcomm_hdr(long_frame_head* head, uint8_t *ptr, int len)
  30. {
  31. address_field addr = head->addr;
  32. uint8_t ctr = head->control;
  33. uint16_t ilen = head->length.bits.len;
  34. uint8_t pf, dlci, fcs;
  35. dlci = GET_DLCI(addr);
  36. pf = GET_PF(ctr);
  37. fcs = *(ptr + len - 1);
  38. printf("cr %d dlci %d pf %d ilen %d fcs 0x%x ", addr.cr, dlci, pf, ilen, fcs);
  39. }
  40. static void print_mcc(mcc_long_frame_head* mcc_head)
  41. {
  42. printf("mcc_len %d\n", mcc_head->length.bits.len);
  43. }
  44. static inline void mcc_test(int level, uint8_t *ptr, int len,
  45. long_frame_head *head, mcc_long_frame_head *mcc_head)
  46. {
  47. printf("TEST %s: ", CR_STR(mcc_head));
  48. print_rfcomm_hdr(head, ptr, len);
  49. print_mcc(mcc_head);
  50. p_indent(level, 0);
  51. printf("%*cTest data: 0x ", level, ' ');
  52. while (len > 1) {
  53. printf("%2.2x ", (uint8_t)*ptr);
  54. len--;
  55. ptr++;
  56. }
  57. printf("\n");
  58. }
  59. static inline void mcc_fcon(int level, uint8_t *ptr, int len,
  60. long_frame_head *head, mcc_long_frame_head *mcc_head)
  61. {
  62. printf("FCON %s: ", CR_STR(mcc_head));
  63. print_rfcomm_hdr(head, ptr, len);
  64. print_mcc(mcc_head);
  65. }
  66. static inline void mcc_fcoff(int level, uint8_t *ptr, int len,
  67. long_frame_head *head, mcc_long_frame_head *mcc_head)
  68. {
  69. printf("FCOFF %s: ", CR_STR(mcc_head));
  70. print_rfcomm_hdr(head, ptr, len);
  71. print_mcc(mcc_head);
  72. }
  73. static inline void mcc_msc(int level, uint8_t *ptr, unsigned int len,
  74. long_frame_head *head, mcc_long_frame_head *mcc_head)
  75. {
  76. msc_msg *msc = (void*) (ptr - STRUCT_END(msc_msg, mcc_s_head));
  77. printf("MSC %s: ", CR_STR(mcc_head));
  78. print_rfcomm_hdr(head, ptr, len);
  79. print_mcc(mcc_head);
  80. p_indent(level, 0);
  81. printf("dlci %d fc %d rtc %d rtr %d ic %d dv %d",
  82. GET_DLCI(msc->dlci), msc->v24_sigs.fc, msc->v24_sigs.rtc,
  83. msc->v24_sigs.rtr, msc->v24_sigs.ic, msc->v24_sigs.dv );
  84. /* Assuming that break_signals field is _not declared_ in struct msc_msg... */
  85. if (len > STRUCT_OFFSET(msc_msg, fcs) - STRUCT_END(msc_msg, v24_sigs)) {
  86. break_signals *brk = (break_signals *)
  87. (ptr + STRUCT_END(msc_msg, v24_sigs));
  88. printf(" b1 %d b2 %d b3 %d len %d\n",
  89. brk->b1, brk->b2, brk->b3, brk->len);
  90. } else
  91. printf("\n");
  92. }
  93. static inline void mcc_rpn(int level, uint8_t *ptr, unsigned int len,
  94. long_frame_head *head, mcc_long_frame_head *mcc_head)
  95. {
  96. rpn_msg *rpn = (void *) (ptr - STRUCT_END(rpn_msg, mcc_s_head));
  97. printf("RPN %s: ", CR_STR(mcc_head));
  98. print_rfcomm_hdr(head, ptr, len);
  99. print_mcc(mcc_head);
  100. p_indent(level, 0);
  101. printf("dlci %d ", GET_DLCI(rpn->dlci));
  102. /* Assuming that rpn_val is _declared_ as a member of rpn_msg... */
  103. if (len <= STRUCT_OFFSET(rpn_msg, rpn_val) - STRUCT_END(rpn_msg, mcc_s_head)) {
  104. printf("\n");
  105. return;
  106. }
  107. printf("br %d db %d sb %d p %d pt %d xi %d xo %d\n",
  108. rpn->rpn_val.bit_rate, rpn->rpn_val.data_bits,
  109. rpn->rpn_val.stop_bit, rpn->rpn_val.parity,
  110. rpn->rpn_val.parity_type, rpn->rpn_val.xon_input,
  111. rpn->rpn_val.xon_output);
  112. p_indent(level, 0);
  113. printf("rtri %d rtro %d rtci %d rtco %d xon %d xoff %d pm 0x%04x\n",
  114. rpn->rpn_val.rtr_input, rpn->rpn_val.rtr_output,
  115. rpn->rpn_val.rtc_input, rpn->rpn_val.rtc_output,
  116. rpn->rpn_val.xon, rpn->rpn_val.xoff, btohs(rpn->rpn_val.pm));
  117. }
  118. static inline void mcc_rls(int level, uint8_t *ptr, int len,
  119. long_frame_head *head, mcc_long_frame_head *mcc_head)
  120. {
  121. rls_msg* rls = (void*) (ptr - STRUCT_END(rls_msg, mcc_s_head));
  122. printf("RLS %s: ", CR_STR(mcc_head));
  123. print_rfcomm_hdr(head, ptr, len);
  124. print_mcc(mcc_head);
  125. printf("dlci %d error: %d", GET_DLCI(rls->dlci), rls->error);
  126. }
  127. static inline void mcc_pn(int level, uint8_t *ptr, int len,
  128. long_frame_head *head, mcc_long_frame_head *mcc_head)
  129. {
  130. pn_msg *pn = (void*) (ptr - STRUCT_END(pn_msg, mcc_s_head));
  131. printf("PN %s: ", CR_STR(mcc_head));
  132. print_rfcomm_hdr(head, ptr, len);
  133. print_mcc(mcc_head);
  134. p_indent(level, 0);
  135. printf("dlci %d frame_type %d credit_flow %d pri %d ack_timer %d\n",
  136. pn->dlci, pn->frame_type, pn->credit_flow, pn->prior, pn->ack_timer);
  137. p_indent(level, 0);
  138. printf("frame_size %d max_retrans %d credits %d\n",
  139. btohs(pn->frame_size), pn->max_nbrof_retrans, pn->credits);
  140. }
  141. static inline void mcc_nsc(int level, uint8_t *ptr, int len,
  142. long_frame_head *head, mcc_long_frame_head *mcc_head)
  143. {
  144. nsc_msg *nsc = (void*) (ptr - STRUCT_END(nsc_msg, mcc_s_head));
  145. printf("NSC %s: ", CR_STR(mcc_head));
  146. print_rfcomm_hdr(head, ptr, len);
  147. print_mcc(mcc_head);
  148. p_indent(level, 0);
  149. printf("cr %d, mcc_cmd_type %x\n",
  150. nsc->command_type.cr, nsc->command_type.type );
  151. }
  152. static inline void mcc_frame(int level, struct frame *frm, long_frame_head *head)
  153. {
  154. mcc_short_frame_head *mcc_short_head_p = frm->ptr;
  155. mcc_long_frame_head mcc_head;
  156. uint8_t hdr_size;
  157. if ( mcc_short_head_p->length.ea == EA ) {
  158. mcc_head.type = mcc_short_head_p->type;
  159. mcc_head.length.bits.len = mcc_short_head_p->length.len;
  160. hdr_size = sizeof(mcc_short_frame_head);
  161. } else {
  162. mcc_head = *(mcc_long_frame_head *)frm->ptr;
  163. mcc_head.length.val = btohs(mcc_head.length.val);
  164. hdr_size = sizeof(mcc_long_frame_head);
  165. }
  166. frm->ptr += hdr_size;
  167. frm->len -= hdr_size;
  168. p_indent(level, frm);
  169. printf("RFCOMM(s): ");
  170. switch (mcc_head.type.type) {
  171. case TEST:
  172. mcc_test(level, frm->ptr, frm->len, head, &mcc_head);
  173. break;
  174. case FCON:
  175. mcc_fcon(level, frm->ptr, frm->len, head, &mcc_head);
  176. break;
  177. case FCOFF:
  178. mcc_fcoff(level, frm->ptr, frm->len, head, &mcc_head);
  179. break;
  180. case MSC:
  181. mcc_msc(level, frm->ptr, frm->len, head, &mcc_head);
  182. break;
  183. case RPN:
  184. mcc_rpn(level, frm->ptr, frm->len, head, &mcc_head);
  185. break;
  186. case RLS:
  187. mcc_rls(level, frm->ptr, frm->len, head, &mcc_head);
  188. break;
  189. case PN:
  190. mcc_pn(level, frm->ptr, frm->len, head, &mcc_head);
  191. break;
  192. case NSC:
  193. mcc_nsc(level, frm->ptr, frm->len, head, &mcc_head);
  194. break;
  195. default:
  196. printf("MCC message type 0x%02x: ", mcc_head.type.type);
  197. print_rfcomm_hdr(head, frm->ptr, frm->len);
  198. printf("\n");
  199. frm->len--;
  200. raw_dump(level, frm);
  201. }
  202. }
  203. static inline void uih_frame(int level, struct frame *frm, long_frame_head *head)
  204. {
  205. uint32_t proto;
  206. if (!head->addr.server_chn) {
  207. mcc_frame(level, frm, head);
  208. } else {
  209. p_indent(level, frm);
  210. printf("RFCOMM(d): UIH: ");
  211. print_rfcomm_hdr(head, frm->ptr, frm->len);
  212. if (GET_PF(head->control)) {
  213. printf("credits %d\n", *(uint8_t *)(frm->ptr));
  214. frm->ptr++;
  215. frm->len--;
  216. } else
  217. printf("\n");
  218. frm->len--;
  219. frm->dlci = GET_DLCI(head->addr);
  220. frm->channel = head->addr.server_chn;
  221. proto = get_proto(frm->handle, RFCOMM_PSM, frm->channel);
  222. if (frm->len > 0) {
  223. switch (proto) {
  224. case SDP_UUID_OBEX:
  225. if (!p_filter(FILT_OBEX))
  226. obex_dump(level + 1, frm);
  227. else
  228. raw_dump(level, frm);
  229. break;
  230. case SDP_UUID_LAN_ACCESS_PPP:
  231. case SDP_UUID_DIALUP_NETWORKING:
  232. if (!p_filter(FILT_PPP))
  233. ppp_dump(level + 1, frm);
  234. else
  235. raw_dump(level, frm);
  236. break;
  237. case SDP_UUID_SIM_ACCESS:
  238. if (!p_filter(FILT_SAP))
  239. sap_dump(level + 1, frm);
  240. else
  241. raw_dump(level, frm);
  242. break;
  243. default:
  244. if (p_filter(FILT_RFCOMM))
  245. break;
  246. raw_dump(level, frm);
  247. break;
  248. }
  249. }
  250. }
  251. }
  252. void rfcomm_dump(int level, struct frame *frm)
  253. {
  254. uint8_t hdr_size, ctr_type;
  255. short_frame_head *short_head_p = (void *) frm->ptr;
  256. long_frame_head head;
  257. if (short_head_p->length.ea == EA) {
  258. head.addr = short_head_p->addr;
  259. head.control = short_head_p->control;
  260. head.length.bits.len = short_head_p->length.len;
  261. hdr_size = sizeof(short_frame_head);
  262. } else {
  263. head = *(long_frame_head *) frm->ptr;
  264. head.length.val = btohs(head.length.val);
  265. hdr_size = sizeof(long_frame_head);
  266. }
  267. frm->ptr += hdr_size;
  268. frm->len -= hdr_size;
  269. ctr_type = CLR_PF(head.control);
  270. if (ctr_type == UIH) {
  271. uih_frame(level, frm, &head);
  272. } else {
  273. p_indent(level, frm);
  274. printf("RFCOMM(s): ");
  275. switch (ctr_type) {
  276. case SABM:
  277. printf("SABM: ");
  278. break;
  279. case UA:
  280. printf("UA: ");
  281. break;
  282. case DM:
  283. printf("DM: ");
  284. break;
  285. case DISC:
  286. printf("DISC: ");
  287. del_frame(frm->handle, GET_DLCI(head.addr));
  288. break;
  289. default:
  290. printf("ERR: ");
  291. }
  292. print_rfcomm_hdr(&head, frm->ptr, frm->len);
  293. printf("\n");
  294. }
  295. }