sdp.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. /*
  2. * Service Discover Protocol server for QEMU L2CAP devices
  3. *
  4. * Copyright (C) 2008 Andrzej Zaborowski <balrog@zabor.org>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of
  9. * the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "qemu/osdep.h"
  20. #include "qemu/error-report.h"
  21. #include "qemu/host-utils.h"
  22. #include "hw/bt.h"
  23. struct bt_l2cap_sdp_state_s {
  24. struct bt_l2cap_conn_params_s *channel;
  25. struct sdp_service_record_s {
  26. int match;
  27. int *uuid;
  28. int uuids;
  29. struct sdp_service_attribute_s {
  30. int match;
  31. int attribute_id;
  32. int len;
  33. void *pair;
  34. } *attribute_list;
  35. int attributes;
  36. } *service_list;
  37. int services;
  38. };
  39. static ssize_t sdp_datalen(const uint8_t **element, ssize_t *left)
  40. {
  41. uint32_t len = *(*element) ++ & SDP_DSIZE_MASK;
  42. if (!*left)
  43. return -1;
  44. (*left) --;
  45. if (len < SDP_DSIZE_NEXT1)
  46. return 1 << len;
  47. else if (len == SDP_DSIZE_NEXT1) {
  48. if (*left < 1)
  49. return -1;
  50. (*left) --;
  51. return *(*element) ++;
  52. } else if (len == SDP_DSIZE_NEXT2) {
  53. if (*left < 2)
  54. return -1;
  55. (*left) -= 2;
  56. len = (*(*element) ++) << 8;
  57. return len | (*(*element) ++);
  58. } else {
  59. if (*left < 4)
  60. return -1;
  61. (*left) -= 4;
  62. len = (*(*element) ++) << 24;
  63. len |= (*(*element) ++) << 16;
  64. len |= (*(*element) ++) << 8;
  65. return len | (*(*element) ++);
  66. }
  67. }
  68. static const uint8_t bt_base_uuid[12] = {
  69. 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb,
  70. };
  71. static int sdp_uuid_match(struct sdp_service_record_s *record,
  72. const uint8_t *uuid, ssize_t datalen)
  73. {
  74. int *lo, hi, val;
  75. if (datalen == 16 || datalen == 4) {
  76. if (datalen == 16 && memcmp(uuid + 4, bt_base_uuid, 12))
  77. return 0;
  78. if (uuid[0] | uuid[1])
  79. return 0;
  80. uuid += 2;
  81. }
  82. val = (uuid[0] << 8) | uuid[1];
  83. lo = record->uuid;
  84. hi = record->uuids;
  85. while (hi >>= 1)
  86. if (lo[hi] <= val)
  87. lo += hi;
  88. return *lo == val;
  89. }
  90. #define CONTINUATION_PARAM_SIZE (1 + sizeof(int))
  91. #define MAX_PDU_OUT_SIZE 96 /* Arbitrary */
  92. #define PDU_HEADER_SIZE 5
  93. #define MAX_RSP_PARAM_SIZE (MAX_PDU_OUT_SIZE - PDU_HEADER_SIZE - \
  94. CONTINUATION_PARAM_SIZE)
  95. static int sdp_svc_match(struct bt_l2cap_sdp_state_s *sdp,
  96. const uint8_t **req, ssize_t *len)
  97. {
  98. size_t datalen;
  99. int i;
  100. if ((**req & ~SDP_DSIZE_MASK) != SDP_DTYPE_UUID)
  101. return 1;
  102. datalen = sdp_datalen(req, len);
  103. if (datalen != 2 && datalen != 4 && datalen != 16)
  104. return 1;
  105. for (i = 0; i < sdp->services; i ++)
  106. if (sdp_uuid_match(&sdp->service_list[i], *req, datalen))
  107. sdp->service_list[i].match = 1;
  108. (*req) += datalen;
  109. (*len) -= datalen;
  110. return 0;
  111. }
  112. static ssize_t sdp_svc_search(struct bt_l2cap_sdp_state_s *sdp,
  113. uint8_t *rsp, const uint8_t *req, ssize_t len)
  114. {
  115. ssize_t seqlen;
  116. int i, count, start, end, max;
  117. int32_t handle;
  118. /* Perform the search */
  119. for (i = 0; i < sdp->services; i ++)
  120. sdp->service_list[i].match = 0;
  121. if (len < 1)
  122. return -SDP_INVALID_SYNTAX;
  123. if ((*req & ~SDP_DSIZE_MASK) == SDP_DTYPE_SEQ) {
  124. seqlen = sdp_datalen(&req, &len);
  125. if (seqlen < 3 || len < seqlen)
  126. return -SDP_INVALID_SYNTAX;
  127. len -= seqlen;
  128. while (seqlen)
  129. if (sdp_svc_match(sdp, &req, &seqlen))
  130. return -SDP_INVALID_SYNTAX;
  131. } else {
  132. if (sdp_svc_match(sdp, &req, &len)) {
  133. return -SDP_INVALID_SYNTAX;
  134. }
  135. }
  136. if (len < 3)
  137. return -SDP_INVALID_SYNTAX;
  138. max = (req[0] << 8) | req[1];
  139. req += 2;
  140. len -= 2;
  141. if (*req) {
  142. if (len <= sizeof(int))
  143. return -SDP_INVALID_SYNTAX;
  144. len -= sizeof(int);
  145. memcpy(&start, req + 1, sizeof(int));
  146. } else
  147. start = 0;
  148. if (len > 1)
  149. return -SDP_INVALID_SYNTAX;
  150. /* Output the results */
  151. len = 4;
  152. count = 0;
  153. end = start;
  154. for (i = 0; i < sdp->services; i ++)
  155. if (sdp->service_list[i].match) {
  156. if (count >= start && count < max && len + 4 < MAX_RSP_PARAM_SIZE) {
  157. handle = i;
  158. memcpy(rsp + len, &handle, 4);
  159. len += 4;
  160. end = count + 1;
  161. }
  162. count ++;
  163. }
  164. rsp[0] = count >> 8;
  165. rsp[1] = count & 0xff;
  166. rsp[2] = (end - start) >> 8;
  167. rsp[3] = (end - start) & 0xff;
  168. if (end < count) {
  169. rsp[len ++] = sizeof(int);
  170. memcpy(rsp + len, &end, sizeof(int));
  171. len += 4;
  172. } else
  173. rsp[len ++] = 0;
  174. return len;
  175. }
  176. static int sdp_attr_match(struct sdp_service_record_s *record,
  177. const uint8_t **req, ssize_t *len)
  178. {
  179. int i, start, end;
  180. if (**req == (SDP_DTYPE_UINT | SDP_DSIZE_2)) {
  181. (*req) ++;
  182. if (*len < 3)
  183. return 1;
  184. start = (*(*req) ++) << 8;
  185. start |= *(*req) ++;
  186. end = start;
  187. *len -= 3;
  188. } else if (**req == (SDP_DTYPE_UINT | SDP_DSIZE_4)) {
  189. (*req) ++;
  190. if (*len < 5)
  191. return 1;
  192. start = (*(*req) ++) << 8;
  193. start |= *(*req) ++;
  194. end = (*(*req) ++) << 8;
  195. end |= *(*req) ++;
  196. *len -= 5;
  197. } else
  198. return 1;
  199. for (i = 0; i < record->attributes; i ++)
  200. if (record->attribute_list[i].attribute_id >= start &&
  201. record->attribute_list[i].attribute_id <= end)
  202. record->attribute_list[i].match = 1;
  203. return 0;
  204. }
  205. static ssize_t sdp_attr_get(struct bt_l2cap_sdp_state_s *sdp,
  206. uint8_t *rsp, const uint8_t *req, ssize_t len)
  207. {
  208. ssize_t seqlen;
  209. int i, start, end, max;
  210. int32_t handle;
  211. struct sdp_service_record_s *record;
  212. uint8_t *lst;
  213. /* Perform the search */
  214. if (len < 7)
  215. return -SDP_INVALID_SYNTAX;
  216. memcpy(&handle, req, 4);
  217. req += 4;
  218. len -= 4;
  219. if (handle < 0 || handle > sdp->services)
  220. return -SDP_INVALID_RECORD_HANDLE;
  221. record = &sdp->service_list[handle];
  222. for (i = 0; i < record->attributes; i ++)
  223. record->attribute_list[i].match = 0;
  224. max = (req[0] << 8) | req[1];
  225. req += 2;
  226. len -= 2;
  227. if (max < 0x0007)
  228. return -SDP_INVALID_SYNTAX;
  229. if ((*req & ~SDP_DSIZE_MASK) == SDP_DTYPE_SEQ) {
  230. seqlen = sdp_datalen(&req, &len);
  231. if (seqlen < 3 || len < seqlen)
  232. return -SDP_INVALID_SYNTAX;
  233. len -= seqlen;
  234. while (seqlen)
  235. if (sdp_attr_match(record, &req, &seqlen))
  236. return -SDP_INVALID_SYNTAX;
  237. } else {
  238. if (sdp_attr_match(record, &req, &len)) {
  239. return -SDP_INVALID_SYNTAX;
  240. }
  241. }
  242. if (len < 1)
  243. return -SDP_INVALID_SYNTAX;
  244. if (*req) {
  245. if (len <= sizeof(int))
  246. return -SDP_INVALID_SYNTAX;
  247. len -= sizeof(int);
  248. memcpy(&start, req + 1, sizeof(int));
  249. } else
  250. start = 0;
  251. if (len > 1)
  252. return -SDP_INVALID_SYNTAX;
  253. /* Output the results */
  254. lst = rsp + 2;
  255. max = MIN(max, MAX_RSP_PARAM_SIZE);
  256. len = 3 - start;
  257. end = 0;
  258. for (i = 0; i < record->attributes; i ++)
  259. if (record->attribute_list[i].match) {
  260. if (len >= 0 && len + record->attribute_list[i].len < max) {
  261. memcpy(lst + len, record->attribute_list[i].pair,
  262. record->attribute_list[i].len);
  263. end = len + record->attribute_list[i].len;
  264. }
  265. len += record->attribute_list[i].len;
  266. }
  267. if (0 >= start) {
  268. lst[0] = SDP_DTYPE_SEQ | SDP_DSIZE_NEXT2;
  269. lst[1] = (len + start - 3) >> 8;
  270. lst[2] = (len + start - 3) & 0xff;
  271. }
  272. rsp[0] = end >> 8;
  273. rsp[1] = end & 0xff;
  274. if (end < len) {
  275. len = end + start;
  276. lst[end ++] = sizeof(int);
  277. memcpy(lst + end, &len, sizeof(int));
  278. end += sizeof(int);
  279. } else
  280. lst[end ++] = 0;
  281. return end + 2;
  282. }
  283. static int sdp_svc_attr_match(struct bt_l2cap_sdp_state_s *sdp,
  284. const uint8_t **req, ssize_t *len)
  285. {
  286. int i, j, start, end;
  287. struct sdp_service_record_s *record;
  288. if (**req == (SDP_DTYPE_UINT | SDP_DSIZE_2)) {
  289. (*req) ++;
  290. if (*len < 3)
  291. return 1;
  292. start = (*(*req) ++) << 8;
  293. start |= *(*req) ++;
  294. end = start;
  295. *len -= 3;
  296. } else if (**req == (SDP_DTYPE_UINT | SDP_DSIZE_4)) {
  297. (*req) ++;
  298. if (*len < 5)
  299. return 1;
  300. start = (*(*req) ++) << 8;
  301. start |= *(*req) ++;
  302. end = (*(*req) ++) << 8;
  303. end |= *(*req) ++;
  304. *len -= 5;
  305. } else
  306. return 1;
  307. for (i = 0; i < sdp->services; i ++)
  308. if ((record = &sdp->service_list[i])->match)
  309. for (j = 0; j < record->attributes; j ++)
  310. if (record->attribute_list[j].attribute_id >= start &&
  311. record->attribute_list[j].attribute_id <= end)
  312. record->attribute_list[j].match = 1;
  313. return 0;
  314. }
  315. static ssize_t sdp_svc_search_attr_get(struct bt_l2cap_sdp_state_s *sdp,
  316. uint8_t *rsp, const uint8_t *req, ssize_t len)
  317. {
  318. ssize_t seqlen;
  319. int i, j, start, end, max;
  320. struct sdp_service_record_s *record;
  321. uint8_t *lst;
  322. /* Perform the search */
  323. for (i = 0; i < sdp->services; i ++) {
  324. sdp->service_list[i].match = 0;
  325. for (j = 0; j < sdp->service_list[i].attributes; j ++)
  326. sdp->service_list[i].attribute_list[j].match = 0;
  327. }
  328. if (len < 1)
  329. return -SDP_INVALID_SYNTAX;
  330. if ((*req & ~SDP_DSIZE_MASK) == SDP_DTYPE_SEQ) {
  331. seqlen = sdp_datalen(&req, &len);
  332. if (seqlen < 3 || len < seqlen)
  333. return -SDP_INVALID_SYNTAX;
  334. len -= seqlen;
  335. while (seqlen)
  336. if (sdp_svc_match(sdp, &req, &seqlen))
  337. return -SDP_INVALID_SYNTAX;
  338. } else {
  339. if (sdp_svc_match(sdp, &req, &len)) {
  340. return -SDP_INVALID_SYNTAX;
  341. }
  342. }
  343. if (len < 3)
  344. return -SDP_INVALID_SYNTAX;
  345. max = (req[0] << 8) | req[1];
  346. req += 2;
  347. len -= 2;
  348. if (max < 0x0007)
  349. return -SDP_INVALID_SYNTAX;
  350. if ((*req & ~SDP_DSIZE_MASK) == SDP_DTYPE_SEQ) {
  351. seqlen = sdp_datalen(&req, &len);
  352. if (seqlen < 3 || len < seqlen)
  353. return -SDP_INVALID_SYNTAX;
  354. len -= seqlen;
  355. while (seqlen)
  356. if (sdp_svc_attr_match(sdp, &req, &seqlen))
  357. return -SDP_INVALID_SYNTAX;
  358. } else {
  359. if (sdp_svc_attr_match(sdp, &req, &len)) {
  360. return -SDP_INVALID_SYNTAX;
  361. }
  362. }
  363. if (len < 1)
  364. return -SDP_INVALID_SYNTAX;
  365. if (*req) {
  366. if (len <= sizeof(int))
  367. return -SDP_INVALID_SYNTAX;
  368. len -= sizeof(int);
  369. memcpy(&start, req + 1, sizeof(int));
  370. } else
  371. start = 0;
  372. if (len > 1)
  373. return -SDP_INVALID_SYNTAX;
  374. /* Output the results */
  375. /* This assumes empty attribute lists are never to be returned even
  376. * for matching Service Records. In practice this shouldn't happen
  377. * as the requestor will usually include the always present
  378. * ServiceRecordHandle AttributeID in AttributeIDList. */
  379. lst = rsp + 2;
  380. max = MIN(max, MAX_RSP_PARAM_SIZE);
  381. len = 3 - start;
  382. end = 0;
  383. for (i = 0; i < sdp->services; i ++)
  384. if ((record = &sdp->service_list[i])->match) {
  385. len += 3;
  386. seqlen = len;
  387. for (j = 0; j < record->attributes; j ++)
  388. if (record->attribute_list[j].match) {
  389. if (len >= 0)
  390. if (len + record->attribute_list[j].len < max) {
  391. memcpy(lst + len, record->attribute_list[j].pair,
  392. record->attribute_list[j].len);
  393. end = len + record->attribute_list[j].len;
  394. }
  395. len += record->attribute_list[j].len;
  396. }
  397. if (seqlen == len)
  398. len -= 3;
  399. else if (seqlen >= 3 && seqlen < max) {
  400. lst[seqlen - 3] = SDP_DTYPE_SEQ | SDP_DSIZE_NEXT2;
  401. lst[seqlen - 2] = (len - seqlen) >> 8;
  402. lst[seqlen - 1] = (len - seqlen) & 0xff;
  403. }
  404. }
  405. if (len == 3 - start)
  406. len -= 3;
  407. else if (0 >= start) {
  408. lst[0] = SDP_DTYPE_SEQ | SDP_DSIZE_NEXT2;
  409. lst[1] = (len + start - 3) >> 8;
  410. lst[2] = (len + start - 3) & 0xff;
  411. }
  412. rsp[0] = end >> 8;
  413. rsp[1] = end & 0xff;
  414. if (end < len) {
  415. len = end + start;
  416. lst[end ++] = sizeof(int);
  417. memcpy(lst + end, &len, sizeof(int));
  418. end += sizeof(int);
  419. } else
  420. lst[end ++] = 0;
  421. return end + 2;
  422. }
  423. static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, int len)
  424. {
  425. struct bt_l2cap_sdp_state_s *sdp = opaque;
  426. enum bt_sdp_cmd pdu_id;
  427. uint8_t rsp[MAX_PDU_OUT_SIZE - PDU_HEADER_SIZE], *sdu_out;
  428. int transaction_id, plen;
  429. int err = 0;
  430. int rsp_len = 0;
  431. if (len < 5) {
  432. error_report("%s: short SDP PDU (%iB).", __func__, len);
  433. return;
  434. }
  435. pdu_id = *data ++;
  436. transaction_id = (data[0] << 8) | data[1];
  437. plen = (data[2] << 8) | data[3];
  438. data += 4;
  439. len -= 5;
  440. if (len != plen) {
  441. error_report("%s: wrong SDP PDU length (%iB != %iB).",
  442. __func__, plen, len);
  443. err = SDP_INVALID_PDU_SIZE;
  444. goto respond;
  445. }
  446. switch (pdu_id) {
  447. case SDP_SVC_SEARCH_REQ:
  448. rsp_len = sdp_svc_search(sdp, rsp, data, len);
  449. pdu_id = SDP_SVC_SEARCH_RSP;
  450. break;
  451. case SDP_SVC_ATTR_REQ:
  452. rsp_len = sdp_attr_get(sdp, rsp, data, len);
  453. pdu_id = SDP_SVC_ATTR_RSP;
  454. break;
  455. case SDP_SVC_SEARCH_ATTR_REQ:
  456. rsp_len = sdp_svc_search_attr_get(sdp, rsp, data, len);
  457. pdu_id = SDP_SVC_SEARCH_ATTR_RSP;
  458. break;
  459. case SDP_ERROR_RSP:
  460. case SDP_SVC_ATTR_RSP:
  461. case SDP_SVC_SEARCH_RSP:
  462. case SDP_SVC_SEARCH_ATTR_RSP:
  463. default:
  464. error_report("%s: unexpected SDP PDU ID %02x.",
  465. __func__, pdu_id);
  466. err = SDP_INVALID_SYNTAX;
  467. break;
  468. }
  469. if (rsp_len < 0) {
  470. err = -rsp_len;
  471. rsp_len = 0;
  472. }
  473. respond:
  474. if (err) {
  475. pdu_id = SDP_ERROR_RSP;
  476. rsp[rsp_len ++] = err >> 8;
  477. rsp[rsp_len ++] = err & 0xff;
  478. }
  479. sdu_out = sdp->channel->sdu_out(sdp->channel, rsp_len + PDU_HEADER_SIZE);
  480. sdu_out[0] = pdu_id;
  481. sdu_out[1] = transaction_id >> 8;
  482. sdu_out[2] = transaction_id & 0xff;
  483. sdu_out[3] = rsp_len >> 8;
  484. sdu_out[4] = rsp_len & 0xff;
  485. memcpy(sdu_out + PDU_HEADER_SIZE, rsp, rsp_len);
  486. sdp->channel->sdu_submit(sdp->channel);
  487. }
  488. static void bt_l2cap_sdp_close_ch(void *opaque)
  489. {
  490. struct bt_l2cap_sdp_state_s *sdp = opaque;
  491. int i;
  492. for (i = 0; i < sdp->services; i ++) {
  493. g_free(sdp->service_list[i].attribute_list[0].pair);
  494. g_free(sdp->service_list[i].attribute_list);
  495. g_free(sdp->service_list[i].uuid);
  496. }
  497. g_free(sdp->service_list);
  498. g_free(sdp);
  499. }
  500. struct sdp_def_service_s {
  501. uint16_t class_uuid;
  502. struct sdp_def_attribute_s {
  503. uint16_t id;
  504. struct sdp_def_data_element_s {
  505. uint8_t type;
  506. union {
  507. uint32_t uint;
  508. const char *str;
  509. struct sdp_def_data_element_s *list;
  510. } value;
  511. } data;
  512. } attributes[];
  513. };
  514. /* Calculate a safe byte count to allocate that will store the given
  515. * element, at the same time count elements of a UUID type. */
  516. static int sdp_attr_max_size(struct sdp_def_data_element_s *element,
  517. int *uuids)
  518. {
  519. int type = element->type & ~SDP_DSIZE_MASK;
  520. int len;
  521. if (type == SDP_DTYPE_UINT || type == SDP_DTYPE_UUID ||
  522. type == SDP_DTYPE_BOOL) {
  523. if (type == SDP_DTYPE_UUID)
  524. (*uuids) ++;
  525. return 1 + (1 << (element->type & SDP_DSIZE_MASK));
  526. }
  527. if (type == SDP_DTYPE_STRING || type == SDP_DTYPE_URL) {
  528. if (element->type & SDP_DSIZE_MASK) {
  529. for (len = 0; element->value.str[len] |
  530. element->value.str[len + 1]; len ++);
  531. return len;
  532. } else
  533. return 2 + strlen(element->value.str);
  534. }
  535. if (type != SDP_DTYPE_SEQ)
  536. exit(-1);
  537. len = 2;
  538. element = element->value.list;
  539. while (element->type)
  540. len += sdp_attr_max_size(element ++, uuids);
  541. if (len > 255)
  542. exit (-1);
  543. return len;
  544. }
  545. static int sdp_attr_write(uint8_t *data,
  546. struct sdp_def_data_element_s *element, int **uuid)
  547. {
  548. int type = element->type & ~SDP_DSIZE_MASK;
  549. int len = 0;
  550. if (type == SDP_DTYPE_UINT || type == SDP_DTYPE_BOOL) {
  551. data[len ++] = element->type;
  552. if ((element->type & SDP_DSIZE_MASK) == SDP_DSIZE_1)
  553. data[len ++] = (element->value.uint >> 0) & 0xff;
  554. else if ((element->type & SDP_DSIZE_MASK) == SDP_DSIZE_2) {
  555. data[len ++] = (element->value.uint >> 8) & 0xff;
  556. data[len ++] = (element->value.uint >> 0) & 0xff;
  557. } else if ((element->type & SDP_DSIZE_MASK) == SDP_DSIZE_4) {
  558. data[len ++] = (element->value.uint >> 24) & 0xff;
  559. data[len ++] = (element->value.uint >> 16) & 0xff;
  560. data[len ++] = (element->value.uint >> 8) & 0xff;
  561. data[len ++] = (element->value.uint >> 0) & 0xff;
  562. }
  563. return len;
  564. }
  565. if (type == SDP_DTYPE_UUID) {
  566. *(*uuid) ++ = element->value.uint;
  567. data[len ++] = element->type;
  568. data[len ++] = (element->value.uint >> 24) & 0xff;
  569. data[len ++] = (element->value.uint >> 16) & 0xff;
  570. data[len ++] = (element->value.uint >> 8) & 0xff;
  571. data[len ++] = (element->value.uint >> 0) & 0xff;
  572. memcpy(data + len, bt_base_uuid, 12);
  573. return len + 12;
  574. }
  575. data[0] = type | SDP_DSIZE_NEXT1;
  576. if (type == SDP_DTYPE_STRING || type == SDP_DTYPE_URL) {
  577. if (element->type & SDP_DSIZE_MASK)
  578. for (len = 0; element->value.str[len] |
  579. element->value.str[len + 1]; len ++);
  580. else
  581. len = strlen(element->value.str);
  582. memcpy(data + 2, element->value.str, data[1] = len);
  583. return len + 2;
  584. }
  585. len = 2;
  586. element = element->value.list;
  587. while (element->type)
  588. len += sdp_attr_write(data + len, element ++, uuid);
  589. data[1] = len - 2;
  590. return len;
  591. }
  592. static int sdp_attributeid_compare(const struct sdp_service_attribute_s *a,
  593. const struct sdp_service_attribute_s *b)
  594. {
  595. return (int) b->attribute_id - a->attribute_id;
  596. }
  597. static int sdp_uuid_compare(const int *a, const int *b)
  598. {
  599. return *a - *b;
  600. }
  601. static void sdp_service_record_build(struct sdp_service_record_s *record,
  602. struct sdp_def_service_s *def, int handle)
  603. {
  604. int len = 0;
  605. uint8_t *data;
  606. int *uuid;
  607. record->uuids = 0;
  608. while (def->attributes[record->attributes].data.type) {
  609. len += 3;
  610. len += sdp_attr_max_size(&def->attributes[record->attributes ++].data,
  611. &record->uuids);
  612. }
  613. assert(len > 0);
  614. record->uuids = pow2ceil(record->uuids);
  615. record->attribute_list =
  616. g_malloc0(record->attributes * sizeof(*record->attribute_list));
  617. record->uuid =
  618. g_malloc0(record->uuids * sizeof(*record->uuid));
  619. data = g_malloc(len);
  620. record->attributes = 0;
  621. uuid = record->uuid;
  622. while (def->attributes[record->attributes].data.type) {
  623. int attribute_id = def->attributes[record->attributes].id;
  624. record->attribute_list[record->attributes].pair = data;
  625. record->attribute_list[record->attributes].attribute_id = attribute_id;
  626. len = 0;
  627. data[len ++] = SDP_DTYPE_UINT | SDP_DSIZE_2;
  628. data[len ++] = attribute_id >> 8;
  629. data[len ++] = attribute_id & 0xff;
  630. len += sdp_attr_write(data + len,
  631. &def->attributes[record->attributes].data, &uuid);
  632. /* Special case: assign a ServiceRecordHandle in sequence */
  633. if (def->attributes[record->attributes].id == SDP_ATTR_RECORD_HANDLE)
  634. def->attributes[record->attributes].data.value.uint = handle;
  635. /* Note: we could also assign a ServiceDescription based on
  636. * sdp->device.device->lmp_name. */
  637. record->attribute_list[record->attributes ++].len = len;
  638. data += len;
  639. }
  640. /* Sort the attribute list by the AttributeID. The first must be
  641. * SDP_ATTR_RECORD_HANDLE so that bt_l2cap_sdp_close_ch can free
  642. * the buffer.
  643. */
  644. qsort(record->attribute_list, record->attributes,
  645. sizeof(*record->attribute_list),
  646. (void *) sdp_attributeid_compare);
  647. assert(record->attribute_list[0].pair == data);
  648. /* Sort the searchable UUIDs list for bisection */
  649. qsort(record->uuid, record->uuids,
  650. sizeof(*record->uuid),
  651. (void *) sdp_uuid_compare);
  652. }
  653. static void sdp_service_db_build(struct bt_l2cap_sdp_state_s *sdp,
  654. struct sdp_def_service_s **service)
  655. {
  656. sdp->services = 0;
  657. while (service[sdp->services])
  658. sdp->services ++;
  659. sdp->service_list =
  660. g_malloc0(sdp->services * sizeof(*sdp->service_list));
  661. sdp->services = 0;
  662. while (*service) {
  663. sdp_service_record_build(&sdp->service_list[sdp->services],
  664. *service, sdp->services);
  665. service ++;
  666. sdp->services ++;
  667. }
  668. }
  669. #define LAST { .type = 0 }
  670. #define SERVICE(name, attrs) \
  671. static struct sdp_def_service_s glue(glue(sdp_service_, name), _s) = { \
  672. .attributes = { attrs { .data = LAST } }, \
  673. };
  674. #define ATTRIBUTE(attrid, val) { .id = glue(SDP_ATTR_, attrid), .data = val },
  675. #define UINT8(val) { \
  676. .type = SDP_DTYPE_UINT | SDP_DSIZE_1, \
  677. .value.uint = val, \
  678. },
  679. #define UINT16(val) { \
  680. .type = SDP_DTYPE_UINT | SDP_DSIZE_2, \
  681. .value.uint = val, \
  682. },
  683. #define UINT32(val) { \
  684. .type = SDP_DTYPE_UINT | SDP_DSIZE_4, \
  685. .value.uint = val, \
  686. },
  687. #define UUID128(val) { \
  688. .type = SDP_DTYPE_UUID | SDP_DSIZE_16, \
  689. .value.uint = val, \
  690. },
  691. #define SDP_TRUE { \
  692. .type = SDP_DTYPE_BOOL | SDP_DSIZE_1, \
  693. .value.uint = 1, \
  694. },
  695. #define SDP_FALSE { \
  696. .type = SDP_DTYPE_BOOL | SDP_DSIZE_1, \
  697. .value.uint = 0, \
  698. },
  699. #define STRING(val) { \
  700. .type = SDP_DTYPE_STRING, \
  701. .value.str = val, \
  702. },
  703. #define ARRAY(...) { \
  704. .type = SDP_DTYPE_STRING | SDP_DSIZE_2, \
  705. .value.str = (char []) { __VA_ARGS__, 0, 0 }, \
  706. },
  707. #define URL(val) { \
  708. .type = SDP_DTYPE_URL, \
  709. .value.str = val, \
  710. },
  711. #if 1
  712. #define LIST(val) { \
  713. .type = SDP_DTYPE_SEQ, \
  714. .value.list = (struct sdp_def_data_element_s []) { val LAST }, \
  715. },
  716. #endif
  717. /* Try to keep each single attribute below MAX_PDU_OUT_SIZE bytes
  718. * in resulting SDP data representation size. */
  719. SERVICE(hid,
  720. ATTRIBUTE(RECORD_HANDLE, UINT32(0)) /* Filled in later */
  721. ATTRIBUTE(SVCLASS_ID_LIST, LIST(UUID128(HID_SVCLASS_ID)))
  722. ATTRIBUTE(RECORD_STATE, UINT32(1))
  723. ATTRIBUTE(PROTO_DESC_LIST, LIST(
  724. LIST(UUID128(L2CAP_UUID) UINT16(BT_PSM_HID_CTRL))
  725. LIST(UUID128(HIDP_UUID))
  726. ))
  727. ATTRIBUTE(BROWSE_GRP_LIST, LIST(UUID128(0x1002)))
  728. ATTRIBUTE(LANG_BASE_ATTR_ID_LIST, LIST(
  729. UINT16(0x656e) UINT16(0x006a) UINT16(0x0100)
  730. ))
  731. ATTRIBUTE(PFILE_DESC_LIST, LIST(
  732. LIST(UUID128(HID_PROFILE_ID) UINT16(0x0100))
  733. ))
  734. ATTRIBUTE(DOC_URL, URL("http://bellard.org/qemu/user-doc.html"))
  735. ATTRIBUTE(SVCNAME_PRIMARY, STRING("QEMU Bluetooth HID"))
  736. ATTRIBUTE(SVCDESC_PRIMARY, STRING("QEMU Keyboard/Mouse"))
  737. ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU"))
  738. /* Profile specific */
  739. ATTRIBUTE(DEVICE_RELEASE_NUMBER, UINT16(0x0091)) /* Deprecated, remove */
  740. ATTRIBUTE(PARSER_VERSION, UINT16(0x0111))
  741. /* TODO: extract from l2cap_device->device.class[0] */
  742. ATTRIBUTE(DEVICE_SUBCLASS, UINT8(0x40))
  743. ATTRIBUTE(COUNTRY_CODE, UINT8(0x15))
  744. ATTRIBUTE(VIRTUAL_CABLE, SDP_TRUE)
  745. ATTRIBUTE(RECONNECT_INITIATE, SDP_FALSE)
  746. /* TODO: extract from hid->usbdev->report_desc */
  747. ATTRIBUTE(DESCRIPTOR_LIST, LIST(
  748. LIST(UINT8(0x22) ARRAY(
  749. 0x05, 0x01, /* Usage Page (Generic Desktop) */
  750. 0x09, 0x06, /* Usage (Keyboard) */
  751. 0xa1, 0x01, /* Collection (Application) */
  752. 0x75, 0x01, /* Report Size (1) */
  753. 0x95, 0x08, /* Report Count (8) */
  754. 0x05, 0x07, /* Usage Page (Key Codes) */
  755. 0x19, 0xe0, /* Usage Minimum (224) */
  756. 0x29, 0xe7, /* Usage Maximum (231) */
  757. 0x15, 0x00, /* Logical Minimum (0) */
  758. 0x25, 0x01, /* Logical Maximum (1) */
  759. 0x81, 0x02, /* Input (Data, Variable, Absolute) */
  760. 0x95, 0x01, /* Report Count (1) */
  761. 0x75, 0x08, /* Report Size (8) */
  762. 0x81, 0x01, /* Input (Constant) */
  763. 0x95, 0x05, /* Report Count (5) */
  764. 0x75, 0x01, /* Report Size (1) */
  765. 0x05, 0x08, /* Usage Page (LEDs) */
  766. 0x19, 0x01, /* Usage Minimum (1) */
  767. 0x29, 0x05, /* Usage Maximum (5) */
  768. 0x91, 0x02, /* Output (Data, Variable, Absolute) */
  769. 0x95, 0x01, /* Report Count (1) */
  770. 0x75, 0x03, /* Report Size (3) */
  771. 0x91, 0x01, /* Output (Constant) */
  772. 0x95, 0x06, /* Report Count (6) */
  773. 0x75, 0x08, /* Report Size (8) */
  774. 0x15, 0x00, /* Logical Minimum (0) */
  775. 0x25, 0xff, /* Logical Maximum (255) */
  776. 0x05, 0x07, /* Usage Page (Key Codes) */
  777. 0x19, 0x00, /* Usage Minimum (0) */
  778. 0x29, 0xff, /* Usage Maximum (255) */
  779. 0x81, 0x00, /* Input (Data, Array) */
  780. 0xc0 /* End Collection */
  781. ))))
  782. ATTRIBUTE(LANG_ID_BASE_LIST, LIST(
  783. LIST(UINT16(0x0409) UINT16(0x0100))
  784. ))
  785. ATTRIBUTE(SDP_DISABLE, SDP_FALSE)
  786. ATTRIBUTE(BATTERY_POWER, SDP_TRUE)
  787. ATTRIBUTE(REMOTE_WAKEUP, SDP_TRUE)
  788. ATTRIBUTE(BOOT_DEVICE, SDP_TRUE) /* XXX: untested */
  789. ATTRIBUTE(SUPERVISION_TIMEOUT, UINT16(0x0c80))
  790. ATTRIBUTE(NORMALLY_CONNECTABLE, SDP_TRUE)
  791. ATTRIBUTE(PROFILE_VERSION, UINT16(0x0100))
  792. )
  793. SERVICE(sdp,
  794. ATTRIBUTE(RECORD_HANDLE, UINT32(0)) /* Filled in later */
  795. ATTRIBUTE(SVCLASS_ID_LIST, LIST(UUID128(SDP_SERVER_SVCLASS_ID)))
  796. ATTRIBUTE(RECORD_STATE, UINT32(1))
  797. ATTRIBUTE(PROTO_DESC_LIST, LIST(
  798. LIST(UUID128(L2CAP_UUID) UINT16(BT_PSM_SDP))
  799. LIST(UUID128(SDP_UUID))
  800. ))
  801. ATTRIBUTE(BROWSE_GRP_LIST, LIST(UUID128(0x1002)))
  802. ATTRIBUTE(LANG_BASE_ATTR_ID_LIST, LIST(
  803. UINT16(0x656e) UINT16(0x006a) UINT16(0x0100)
  804. ))
  805. ATTRIBUTE(PFILE_DESC_LIST, LIST(
  806. LIST(UUID128(SDP_SERVER_PROFILE_ID) UINT16(0x0100))
  807. ))
  808. ATTRIBUTE(DOC_URL, URL("http://bellard.org/qemu/user-doc.html"))
  809. ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU"))
  810. /* Profile specific */
  811. ATTRIBUTE(VERSION_NUM_LIST, LIST(UINT16(0x0100)))
  812. ATTRIBUTE(SVCDB_STATE , UINT32(1))
  813. )
  814. SERVICE(pnp,
  815. ATTRIBUTE(RECORD_HANDLE, UINT32(0)) /* Filled in later */
  816. ATTRIBUTE(SVCLASS_ID_LIST, LIST(UUID128(PNP_INFO_SVCLASS_ID)))
  817. ATTRIBUTE(RECORD_STATE, UINT32(1))
  818. ATTRIBUTE(PROTO_DESC_LIST, LIST(
  819. LIST(UUID128(L2CAP_UUID) UINT16(BT_PSM_SDP))
  820. LIST(UUID128(SDP_UUID))
  821. ))
  822. ATTRIBUTE(BROWSE_GRP_LIST, LIST(UUID128(0x1002)))
  823. ATTRIBUTE(LANG_BASE_ATTR_ID_LIST, LIST(
  824. UINT16(0x656e) UINT16(0x006a) UINT16(0x0100)
  825. ))
  826. ATTRIBUTE(PFILE_DESC_LIST, LIST(
  827. LIST(UUID128(PNP_INFO_PROFILE_ID) UINT16(0x0100))
  828. ))
  829. ATTRIBUTE(DOC_URL, URL("http://bellard.org/qemu/user-doc.html"))
  830. ATTRIBUTE(SVCPROV_PRIMARY, STRING("QEMU"))
  831. /* Profile specific */
  832. ATTRIBUTE(SPECIFICATION_ID, UINT16(0x0100))
  833. ATTRIBUTE(VERSION, UINT16(0x0100))
  834. ATTRIBUTE(PRIMARY_RECORD, SDP_TRUE)
  835. )
  836. static int bt_l2cap_sdp_new_ch(struct bt_l2cap_device_s *dev,
  837. struct bt_l2cap_conn_params_s *params)
  838. {
  839. struct bt_l2cap_sdp_state_s *sdp = g_malloc0(sizeof(*sdp));
  840. struct sdp_def_service_s *services[] = {
  841. &sdp_service_sdp_s,
  842. &sdp_service_hid_s,
  843. &sdp_service_pnp_s,
  844. NULL,
  845. };
  846. sdp->channel = params;
  847. sdp->channel->opaque = sdp;
  848. sdp->channel->close = bt_l2cap_sdp_close_ch;
  849. sdp->channel->sdu_in = bt_l2cap_sdp_sdu_in;
  850. sdp_service_db_build(sdp, services);
  851. return 0;
  852. }
  853. void bt_l2cap_sdp_init(struct bt_l2cap_device_s *dev)
  854. {
  855. bt_l2cap_psm_register(dev, BT_PSM_SDP,
  856. MAX_PDU_OUT_SIZE, bt_l2cap_sdp_new_ch);
  857. }