sdp.c 29 KB

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