att.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2010 Nokia Corporation
  7. * Copyright (C) 2010 Marcel Holtmann <marcel@holtmann.org>
  8. *
  9. *
  10. */
  11. #ifdef HAVE_CONFIG_H
  12. #include <config.h>
  13. #endif
  14. #include <errno.h>
  15. #include <stdint.h>
  16. #include <stdlib.h>
  17. #include <glib.h>
  18. #include "lib/bluetooth.h"
  19. #include "lib/uuid.h"
  20. #include "src/shared/util.h"
  21. #include "att.h"
  22. static inline void put_uuid_le(const bt_uuid_t *src, void *dst)
  23. {
  24. if (src->type == BT_UUID16)
  25. put_le16(src->value.u16, dst);
  26. else
  27. /* Convert from 128-bit BE to LE */
  28. bswap_128(&src->value.u128, dst);
  29. }
  30. const char *att_ecode2str(uint8_t status)
  31. {
  32. switch (status) {
  33. case ATT_ECODE_INVALID_HANDLE:
  34. return "Invalid handle";
  35. case ATT_ECODE_READ_NOT_PERM:
  36. return "Attribute can't be read";
  37. case ATT_ECODE_WRITE_NOT_PERM:
  38. return "Attribute can't be written";
  39. case ATT_ECODE_INVALID_PDU:
  40. return "Attribute PDU was invalid";
  41. case ATT_ECODE_AUTHENTICATION:
  42. return "Attribute requires authentication before read/write";
  43. case ATT_ECODE_REQ_NOT_SUPP:
  44. return "Server doesn't support the request received";
  45. case ATT_ECODE_INVALID_OFFSET:
  46. return "Offset past the end of the attribute";
  47. case ATT_ECODE_AUTHORIZATION:
  48. return "Attribute requires authorization before read/write";
  49. case ATT_ECODE_PREP_QUEUE_FULL:
  50. return "Too many prepare writes have been queued";
  51. case ATT_ECODE_ATTR_NOT_FOUND:
  52. return "No attribute found within the given range";
  53. case ATT_ECODE_ATTR_NOT_LONG:
  54. return "Attribute can't be read/written using Read Blob Req";
  55. case ATT_ECODE_INSUFF_ENCR_KEY_SIZE:
  56. return "Encryption Key Size is insufficient";
  57. case ATT_ECODE_INVAL_ATTR_VALUE_LEN:
  58. return "Attribute value length is invalid";
  59. case ATT_ECODE_UNLIKELY:
  60. return "Request attribute has encountered an unlikely error";
  61. case ATT_ECODE_INSUFF_ENC:
  62. return "Encryption required before read/write";
  63. case ATT_ECODE_UNSUPP_GRP_TYPE:
  64. return "Attribute type is not a supported grouping attribute";
  65. case ATT_ECODE_INSUFF_RESOURCES:
  66. return "Insufficient Resources to complete the request";
  67. case ATT_ECODE_IO:
  68. return "Internal application error: I/O";
  69. case ATT_ECODE_TIMEOUT:
  70. return "A timeout occured";
  71. case ATT_ECODE_ABORTED:
  72. return "The operation was aborted";
  73. default:
  74. return "Unexpected error code";
  75. }
  76. }
  77. void att_data_list_free(struct att_data_list *list)
  78. {
  79. if (list == NULL)
  80. return;
  81. if (list->data) {
  82. int i;
  83. for (i = 0; i < list->num; i++)
  84. g_free(list->data[i]);
  85. }
  86. g_free(list->data);
  87. g_free(list);
  88. }
  89. struct att_data_list *att_data_list_alloc(uint16_t num, uint16_t len)
  90. {
  91. struct att_data_list *list;
  92. int i;
  93. if (len > UINT8_MAX)
  94. return NULL;
  95. list = g_new0(struct att_data_list, 1);
  96. list->len = len;
  97. list->num = num;
  98. list->data = g_malloc0(sizeof(uint8_t *) * num);
  99. for (i = 0; i < num; i++)
  100. list->data[i] = g_malloc0(sizeof(uint8_t) * len);
  101. return list;
  102. }
  103. static void get_uuid(uint8_t type, const void *val, bt_uuid_t *uuid)
  104. {
  105. if (type == BT_UUID16)
  106. bt_uuid16_create(uuid, get_le16(val));
  107. else {
  108. uint128_t u128;
  109. /* Convert from 128-bit LE to BE */
  110. bswap_128(val, &u128);
  111. bt_uuid128_create(uuid, u128);
  112. }
  113. }
  114. uint16_t enc_read_by_grp_req(uint16_t start, uint16_t end, bt_uuid_t *uuid,
  115. uint8_t *pdu, size_t len)
  116. {
  117. uint16_t uuid_len;
  118. if (!uuid)
  119. return 0;
  120. if (uuid->type == BT_UUID16)
  121. uuid_len = 2;
  122. else if (uuid->type == BT_UUID128)
  123. uuid_len = 16;
  124. else
  125. return 0;
  126. /* Attribute Opcode (1 octet) */
  127. pdu[0] = ATT_OP_READ_BY_GROUP_REQ;
  128. /* Starting Handle (2 octets) */
  129. put_le16(start, &pdu[1]);
  130. /* Ending Handle (2 octets) */
  131. put_le16(end, &pdu[3]);
  132. /* Attribute Group Type (2 or 16 octet UUID) */
  133. put_uuid_le(uuid, &pdu[5]);
  134. return 5 + uuid_len;
  135. }
  136. uint16_t dec_read_by_grp_req(const uint8_t *pdu, size_t len, uint16_t *start,
  137. uint16_t *end, bt_uuid_t *uuid)
  138. {
  139. const size_t min_len = sizeof(pdu[0]) + sizeof(*start) + sizeof(*end);
  140. uint8_t type;
  141. if (pdu == NULL)
  142. return 0;
  143. if (start == NULL || end == NULL || uuid == NULL)
  144. return 0;
  145. if (pdu[0] != ATT_OP_READ_BY_GROUP_REQ)
  146. return 0;
  147. if (len == (min_len + 2))
  148. type = BT_UUID16;
  149. else if (len == (min_len + 16))
  150. type = BT_UUID128;
  151. else
  152. return 0;
  153. *start = get_le16(&pdu[1]);
  154. *end = get_le16(&pdu[3]);
  155. get_uuid(type, &pdu[5], uuid);
  156. return len;
  157. }
  158. uint16_t enc_read_by_grp_resp(struct att_data_list *list, uint8_t *pdu,
  159. size_t len)
  160. {
  161. int i;
  162. uint16_t w;
  163. uint8_t *ptr;
  164. if (list == NULL)
  165. return 0;
  166. if (len < list->len + sizeof(uint8_t) * 2)
  167. return 0;
  168. pdu[0] = ATT_OP_READ_BY_GROUP_RESP;
  169. pdu[1] = list->len;
  170. ptr = &pdu[2];
  171. for (i = 0, w = 2; i < list->num && w + list->len <= len; i++) {
  172. memcpy(ptr, list->data[i], list->len);
  173. ptr += list->len;
  174. w += list->len;
  175. }
  176. return w;
  177. }
  178. struct att_data_list *dec_read_by_grp_resp(const uint8_t *pdu, size_t len)
  179. {
  180. struct att_data_list *list;
  181. const uint8_t *ptr;
  182. uint16_t elen, num;
  183. int i;
  184. if (pdu[0] != ATT_OP_READ_BY_GROUP_RESP)
  185. return NULL;
  186. /* PDU must contain at least:
  187. * - Attribute Opcode (1 octet)
  188. * - Length (1 octet)
  189. * - Attribute Data List (at least one entry):
  190. * - Attribute Handle (2 octets)
  191. * - End Group Handle (2 octets)
  192. * - Attribute Value (at least 1 octet) */
  193. if (len < 7)
  194. return NULL;
  195. elen = pdu[1];
  196. /* Minimum Attribute Data List size */
  197. if (elen < 5)
  198. return NULL;
  199. /* Reject incomplete Attribute Data List */
  200. if ((len - 2) % elen)
  201. return NULL;
  202. num = (len - 2) / elen;
  203. list = att_data_list_alloc(num, elen);
  204. if (list == NULL)
  205. return NULL;
  206. ptr = &pdu[2];
  207. for (i = 0; i < num; i++) {
  208. memcpy(list->data[i], ptr, list->len);
  209. ptr += list->len;
  210. }
  211. return list;
  212. }
  213. uint16_t enc_find_by_type_req(uint16_t start, uint16_t end, bt_uuid_t *uuid,
  214. const uint8_t *value, size_t vlen,
  215. uint8_t *pdu, size_t len)
  216. {
  217. uint16_t min_len = sizeof(pdu[0]) + sizeof(start) + sizeof(end) +
  218. sizeof(uint16_t);
  219. if (pdu == NULL)
  220. return 0;
  221. if (!uuid)
  222. return 0;
  223. if (uuid->type != BT_UUID16)
  224. return 0;
  225. if (vlen > len - min_len)
  226. vlen = len - min_len;
  227. pdu[0] = ATT_OP_FIND_BY_TYPE_REQ;
  228. put_le16(start, &pdu[1]);
  229. put_le16(end, &pdu[3]);
  230. put_le16(uuid->value.u16, &pdu[5]);
  231. if (vlen > 0) {
  232. memcpy(&pdu[7], value, vlen);
  233. return min_len + vlen;
  234. }
  235. return min_len;
  236. }
  237. uint16_t dec_find_by_type_req(const uint8_t *pdu, size_t len, uint16_t *start,
  238. uint16_t *end, bt_uuid_t *uuid,
  239. uint8_t *value, size_t *vlen)
  240. {
  241. if (pdu == NULL)
  242. return 0;
  243. if (len < 7)
  244. return 0;
  245. /* Attribute Opcode (1 octet) */
  246. if (pdu[0] != ATT_OP_FIND_BY_TYPE_REQ)
  247. return 0;
  248. /* First requested handle number (2 octets) */
  249. *start = get_le16(&pdu[1]);
  250. /* Last requested handle number (2 octets) */
  251. *end = get_le16(&pdu[3]);
  252. /* 16-bit UUID to find (2 octets) */
  253. bt_uuid16_create(uuid, get_le16(&pdu[5]));
  254. /* Attribute value to find */
  255. *vlen = len - 7;
  256. if (*vlen > 0)
  257. memcpy(value, pdu + 7, *vlen);
  258. return len;
  259. }
  260. uint16_t enc_find_by_type_resp(GSList *matches, uint8_t *pdu, size_t len)
  261. {
  262. GSList *l;
  263. uint16_t offset;
  264. if (!pdu)
  265. return 0;
  266. pdu[0] = ATT_OP_FIND_BY_TYPE_RESP;
  267. for (l = matches, offset = 1;
  268. l && len >= (offset + sizeof(uint16_t) * 2);
  269. l = l->next, offset += sizeof(uint16_t) * 2) {
  270. struct att_range *range = l->data;
  271. put_le16(range->start, &pdu[offset]);
  272. put_le16(range->end, &pdu[offset + 2]);
  273. }
  274. return offset;
  275. }
  276. GSList *dec_find_by_type_resp(const uint8_t *pdu, size_t len)
  277. {
  278. struct att_range *range;
  279. GSList *matches;
  280. off_t offset;
  281. /* PDU should contain at least:
  282. * - Attribute Opcode (1 octet)
  283. * - Handles Information List (at least one entry):
  284. * - Found Attribute Handle (2 octets)
  285. * - Group End Handle (2 octets) */
  286. if (pdu == NULL || len < 5)
  287. return NULL;
  288. if (pdu[0] != ATT_OP_FIND_BY_TYPE_RESP)
  289. return NULL;
  290. /* Reject incomplete Handles Information List */
  291. if ((len - 1) % 4)
  292. return NULL;
  293. for (offset = 1, matches = NULL;
  294. len >= (offset + sizeof(uint16_t) * 2);
  295. offset += sizeof(uint16_t) * 2) {
  296. range = g_new0(struct att_range, 1);
  297. range->start = get_le16(&pdu[offset]);
  298. range->end = get_le16(&pdu[offset + 2]);
  299. matches = g_slist_append(matches, range);
  300. }
  301. return matches;
  302. }
  303. uint16_t enc_read_by_type_req(uint16_t start, uint16_t end, bt_uuid_t *uuid,
  304. uint8_t *pdu, size_t len)
  305. {
  306. uint16_t uuid_len;
  307. if (!uuid)
  308. return 0;
  309. if (uuid->type == BT_UUID16)
  310. uuid_len = 2;
  311. else if (uuid->type == BT_UUID128)
  312. uuid_len = 16;
  313. else
  314. return 0;
  315. /* Attribute Opcode (1 octet) */
  316. pdu[0] = ATT_OP_READ_BY_TYPE_REQ;
  317. /* Starting Handle (2 octets) */
  318. put_le16(start, &pdu[1]);
  319. /* Ending Handle (2 octets) */
  320. put_le16(end, &pdu[3]);
  321. /* Attribute Type (2 or 16 octet UUID) */
  322. put_uuid_le(uuid, &pdu[5]);
  323. return 5 + uuid_len;
  324. }
  325. uint16_t dec_read_by_type_req(const uint8_t *pdu, size_t len, uint16_t *start,
  326. uint16_t *end, bt_uuid_t *uuid)
  327. {
  328. const size_t min_len = sizeof(pdu[0]) + sizeof(*start) + sizeof(*end);
  329. uint8_t type;
  330. if (pdu == NULL)
  331. return 0;
  332. if (start == NULL || end == NULL || uuid == NULL)
  333. return 0;
  334. if (len == (min_len + 2))
  335. type = BT_UUID16;
  336. else if (len == (min_len + 16))
  337. type = BT_UUID128;
  338. else
  339. return 0;
  340. if (pdu[0] != ATT_OP_READ_BY_TYPE_REQ)
  341. return 0;
  342. *start = get_le16(&pdu[1]);
  343. *end = get_le16(&pdu[3]);
  344. get_uuid(type, &pdu[5], uuid);
  345. return len;
  346. }
  347. uint16_t enc_read_by_type_resp(struct att_data_list *list, uint8_t *pdu,
  348. size_t len)
  349. {
  350. uint8_t *ptr;
  351. size_t i, w, l;
  352. if (list == NULL)
  353. return 0;
  354. if (pdu == NULL)
  355. return 0;
  356. l = MIN(len - 2, list->len);
  357. pdu[0] = ATT_OP_READ_BY_TYPE_RESP;
  358. pdu[1] = l;
  359. ptr = &pdu[2];
  360. for (i = 0, w = 2; i < list->num && w + l <= len; i++) {
  361. memcpy(ptr, list->data[i], l);
  362. ptr += l;
  363. w += l;
  364. }
  365. return w;
  366. }
  367. struct att_data_list *dec_read_by_type_resp(const uint8_t *pdu, size_t len)
  368. {
  369. struct att_data_list *list;
  370. const uint8_t *ptr;
  371. uint16_t elen, num;
  372. int i;
  373. if (pdu[0] != ATT_OP_READ_BY_TYPE_RESP)
  374. return NULL;
  375. /* PDU must contain at least:
  376. * - Attribute Opcode (1 octet)
  377. * - Length (1 octet)
  378. * - Attribute Data List (at least one entry):
  379. * - Attribute Handle (2 octets)
  380. * - Attribute Value (at least 1 octet) */
  381. if (len < 5)
  382. return NULL;
  383. elen = pdu[1];
  384. /* Minimum Attribute Data List size */
  385. if (elen < 3)
  386. return NULL;
  387. /* Reject incomplete Attribute Data List */
  388. if ((len - 2) % elen)
  389. return NULL;
  390. num = (len - 2) / elen;
  391. list = att_data_list_alloc(num, elen);
  392. if (list == NULL)
  393. return NULL;
  394. ptr = &pdu[2];
  395. for (i = 0; i < num; i++) {
  396. memcpy(list->data[i], ptr, list->len);
  397. ptr += list->len;
  398. }
  399. return list;
  400. }
  401. uint16_t enc_write_cmd(uint16_t handle, const uint8_t *value, size_t vlen,
  402. uint8_t *pdu, size_t len)
  403. {
  404. const uint16_t min_len = sizeof(pdu[0]) + sizeof(handle);
  405. if (pdu == NULL)
  406. return 0;
  407. if (vlen > len - min_len)
  408. vlen = len - min_len;
  409. pdu[0] = ATT_OP_WRITE_CMD;
  410. put_le16(handle, &pdu[1]);
  411. if (vlen > 0) {
  412. memcpy(&pdu[3], value, vlen);
  413. return min_len + vlen;
  414. }
  415. return min_len;
  416. }
  417. uint16_t dec_write_cmd(const uint8_t *pdu, size_t len, uint16_t *handle,
  418. uint8_t *value, size_t *vlen)
  419. {
  420. const uint16_t min_len = sizeof(pdu[0]) + sizeof(*handle);
  421. if (pdu == NULL)
  422. return 0;
  423. if (value == NULL || vlen == NULL || handle == NULL)
  424. return 0;
  425. if (len < min_len)
  426. return 0;
  427. if (pdu[0] != ATT_OP_WRITE_CMD)
  428. return 0;
  429. *handle = get_le16(&pdu[1]);
  430. memcpy(value, pdu + min_len, len - min_len);
  431. *vlen = len - min_len;
  432. return len;
  433. }
  434. uint16_t enc_signed_write_cmd(uint16_t handle, const uint8_t *value,
  435. size_t vlen, struct bt_crypto *crypto,
  436. const uint8_t csrk[16],
  437. uint32_t sign_cnt,
  438. uint8_t *pdu, size_t len)
  439. {
  440. const uint16_t hdr_len = sizeof(pdu[0]) + sizeof(handle);
  441. const uint16_t min_len = hdr_len + ATT_SIGNATURE_LEN;
  442. if (pdu == NULL)
  443. return 0;
  444. if (vlen > len - min_len)
  445. vlen = len - min_len;
  446. pdu[0] = ATT_OP_SIGNED_WRITE_CMD;
  447. put_le16(handle, &pdu[1]);
  448. if (vlen > 0)
  449. memcpy(&pdu[hdr_len], value, vlen);
  450. if (!bt_crypto_sign_att(crypto, csrk, pdu, hdr_len + vlen, sign_cnt,
  451. &pdu[hdr_len + vlen]))
  452. return 0;
  453. return min_len + vlen;
  454. }
  455. uint16_t dec_signed_write_cmd(const uint8_t *pdu, size_t len,
  456. uint16_t *handle,
  457. uint8_t *value, size_t *vlen,
  458. uint8_t signature[12])
  459. {
  460. const uint16_t hdr_len = sizeof(pdu[0]) + sizeof(*handle);
  461. const uint16_t min_len = hdr_len + ATT_SIGNATURE_LEN;
  462. if (pdu == NULL)
  463. return 0;
  464. if (value == NULL || vlen == NULL || handle == NULL)
  465. return 0;
  466. if (len < min_len)
  467. return 0;
  468. if (pdu[0] != ATT_OP_SIGNED_WRITE_CMD)
  469. return 0;
  470. *vlen = len - min_len;
  471. *handle = get_le16(&pdu[1]);
  472. memcpy(value, pdu + hdr_len, *vlen);
  473. memcpy(signature, pdu + hdr_len + *vlen, ATT_SIGNATURE_LEN);
  474. return len;
  475. }
  476. uint16_t enc_write_req(uint16_t handle, const uint8_t *value, size_t vlen,
  477. uint8_t *pdu, size_t len)
  478. {
  479. const uint16_t min_len = sizeof(pdu[0]) + sizeof(handle);
  480. if (pdu == NULL)
  481. return 0;
  482. if (vlen > len - min_len)
  483. vlen = len - min_len;
  484. pdu[0] = ATT_OP_WRITE_REQ;
  485. put_le16(handle, &pdu[1]);
  486. if (vlen > 0) {
  487. memcpy(&pdu[3], value, vlen);
  488. return min_len + vlen;
  489. }
  490. return min_len;
  491. }
  492. uint16_t dec_write_req(const uint8_t *pdu, size_t len, uint16_t *handle,
  493. uint8_t *value, size_t *vlen)
  494. {
  495. const uint16_t min_len = sizeof(pdu[0]) + sizeof(*handle);
  496. if (pdu == NULL)
  497. return 0;
  498. if (value == NULL || vlen == NULL || handle == NULL)
  499. return 0;
  500. if (len < min_len)
  501. return 0;
  502. if (pdu[0] != ATT_OP_WRITE_REQ)
  503. return 0;
  504. *handle = get_le16(&pdu[1]);
  505. *vlen = len - min_len;
  506. if (*vlen > 0)
  507. memcpy(value, pdu + min_len, *vlen);
  508. return len;
  509. }
  510. uint16_t enc_write_resp(uint8_t *pdu)
  511. {
  512. if (pdu == NULL)
  513. return 0;
  514. pdu[0] = ATT_OP_WRITE_RESP;
  515. return sizeof(pdu[0]);
  516. }
  517. uint16_t dec_write_resp(const uint8_t *pdu, size_t len)
  518. {
  519. if (pdu == NULL)
  520. return 0;
  521. if (pdu[0] != ATT_OP_WRITE_RESP)
  522. return 0;
  523. return len;
  524. }
  525. uint16_t enc_read_req(uint16_t handle, uint8_t *pdu, size_t len)
  526. {
  527. if (pdu == NULL)
  528. return 0;
  529. /* Attribute Opcode (1 octet) */
  530. pdu[0] = ATT_OP_READ_REQ;
  531. /* Attribute Handle (2 octets) */
  532. put_le16(handle, &pdu[1]);
  533. return 3;
  534. }
  535. uint16_t enc_read_blob_req(uint16_t handle, uint16_t offset, uint8_t *pdu,
  536. size_t len)
  537. {
  538. if (pdu == NULL)
  539. return 0;
  540. /* Attribute Opcode (1 octet) */
  541. pdu[0] = ATT_OP_READ_BLOB_REQ;
  542. /* Attribute Handle (2 octets) */
  543. put_le16(handle, &pdu[1]);
  544. /* Value Offset (2 octets) */
  545. put_le16(offset, &pdu[3]);
  546. return 5;
  547. }
  548. uint16_t dec_read_req(const uint8_t *pdu, size_t len, uint16_t *handle)
  549. {
  550. const uint16_t min_len = sizeof(pdu[0]) + sizeof(*handle);
  551. if (pdu == NULL)
  552. return 0;
  553. if (handle == NULL)
  554. return 0;
  555. if (len < min_len)
  556. return 0;
  557. if (pdu[0] != ATT_OP_READ_REQ)
  558. return 0;
  559. *handle = get_le16(&pdu[1]);
  560. return min_len;
  561. }
  562. uint16_t dec_read_blob_req(const uint8_t *pdu, size_t len, uint16_t *handle,
  563. uint16_t *offset)
  564. {
  565. const uint16_t min_len = sizeof(pdu[0]) + sizeof(*handle) +
  566. sizeof(*offset);
  567. if (pdu == NULL)
  568. return 0;
  569. if (handle == NULL)
  570. return 0;
  571. if (offset == NULL)
  572. return 0;
  573. if (len < min_len)
  574. return 0;
  575. if (pdu[0] != ATT_OP_READ_BLOB_REQ)
  576. return 0;
  577. *handle = get_le16(&pdu[1]);
  578. *offset = get_le16(&pdu[3]);
  579. return min_len;
  580. }
  581. uint16_t enc_read_resp(uint8_t *value, size_t vlen, uint8_t *pdu, size_t len)
  582. {
  583. if (pdu == NULL)
  584. return 0;
  585. /* If the attribute value length is longer than the allowed PDU size,
  586. * send only the octets that fit on the PDU. The remaining octets can
  587. * be requested using the Read Blob Request. */
  588. if (vlen > len - 1)
  589. vlen = len - 1;
  590. pdu[0] = ATT_OP_READ_RESP;
  591. memcpy(pdu + 1, value, vlen);
  592. return vlen + 1;
  593. }
  594. uint16_t enc_read_blob_resp(uint8_t *value, size_t vlen, uint16_t offset,
  595. uint8_t *pdu, size_t len)
  596. {
  597. if (pdu == NULL)
  598. return 0;
  599. vlen -= offset;
  600. if (vlen > len - 1)
  601. vlen = len - 1;
  602. pdu[0] = ATT_OP_READ_BLOB_RESP;
  603. memcpy(pdu + 1, &value[offset], vlen);
  604. return vlen + 1;
  605. }
  606. ssize_t dec_read_resp(const uint8_t *pdu, size_t len, uint8_t *value,
  607. size_t vlen)
  608. {
  609. if (pdu == NULL)
  610. return -EINVAL;
  611. if (pdu[0] != ATT_OP_READ_RESP)
  612. return -EINVAL;
  613. if (value == NULL)
  614. return len - 1;
  615. if (vlen < (len - 1))
  616. return -ENOBUFS;
  617. memcpy(value, pdu + 1, len - 1);
  618. return len - 1;
  619. }
  620. uint16_t enc_error_resp(uint8_t opcode, uint16_t handle, uint8_t status,
  621. uint8_t *pdu, size_t len)
  622. {
  623. /* Attribute Opcode (1 octet) */
  624. pdu[0] = ATT_OP_ERROR;
  625. /* Request Opcode In Error (1 octet) */
  626. pdu[1] = opcode;
  627. /* Attribute Handle In Error (2 octets) */
  628. put_le16(handle, &pdu[2]);
  629. /* Error Code (1 octet) */
  630. pdu[4] = status;
  631. return 5;
  632. }
  633. uint16_t enc_find_info_req(uint16_t start, uint16_t end, uint8_t *pdu,
  634. size_t len)
  635. {
  636. if (pdu == NULL)
  637. return 0;
  638. /* Attribute Opcode (1 octet) */
  639. pdu[0] = ATT_OP_FIND_INFO_REQ;
  640. /* Starting Handle (2 octets) */
  641. put_le16(start, &pdu[1]);
  642. /* Ending Handle (2 octets) */
  643. put_le16(end, &pdu[3]);
  644. return 5;
  645. }
  646. uint16_t dec_find_info_req(const uint8_t *pdu, size_t len, uint16_t *start,
  647. uint16_t *end)
  648. {
  649. const uint16_t min_len = sizeof(pdu[0]) + sizeof(*start) + sizeof(*end);
  650. if (pdu == NULL)
  651. return 0;
  652. if (len < min_len)
  653. return 0;
  654. if (start == NULL || end == NULL)
  655. return 0;
  656. if (pdu[0] != ATT_OP_FIND_INFO_REQ)
  657. return 0;
  658. *start = get_le16(&pdu[1]);
  659. *end = get_le16(&pdu[3]);
  660. return min_len;
  661. }
  662. uint16_t enc_find_info_resp(uint8_t format, struct att_data_list *list,
  663. uint8_t *pdu, size_t len)
  664. {
  665. uint8_t *ptr;
  666. size_t i, w;
  667. if (pdu == NULL)
  668. return 0;
  669. if (list == NULL)
  670. return 0;
  671. if (len < list->len + sizeof(uint8_t) * 2)
  672. return 0;
  673. pdu[0] = ATT_OP_FIND_INFO_RESP;
  674. pdu[1] = format;
  675. ptr = (void *) &pdu[2];
  676. for (i = 0, w = 2; i < list->num && w + list->len <= len; i++) {
  677. memcpy(ptr, list->data[i], list->len);
  678. ptr += list->len;
  679. w += list->len;
  680. }
  681. return w;
  682. }
  683. struct att_data_list *dec_find_info_resp(const uint8_t *pdu, size_t len,
  684. uint8_t *format)
  685. {
  686. struct att_data_list *list;
  687. uint8_t *ptr;
  688. uint16_t elen, num;
  689. int i;
  690. if (pdu == NULL)
  691. return 0;
  692. if (format == NULL)
  693. return 0;
  694. if (pdu[0] != ATT_OP_FIND_INFO_RESP)
  695. return 0;
  696. *format = pdu[1];
  697. elen = sizeof(pdu[0]) + sizeof(*format);
  698. if (*format == 0x01)
  699. elen += 2;
  700. else if (*format == 0x02)
  701. elen += 16;
  702. num = (len - 2) / elen;
  703. ptr = (void *) &pdu[2];
  704. list = att_data_list_alloc(num, elen);
  705. if (list == NULL)
  706. return NULL;
  707. for (i = 0; i < num; i++) {
  708. memcpy(list->data[i], ptr, list->len);
  709. ptr += list->len;
  710. }
  711. return list;
  712. }
  713. uint16_t enc_notification(uint16_t handle, uint8_t *value, size_t vlen,
  714. uint8_t *pdu, size_t len)
  715. {
  716. const uint16_t min_len = sizeof(pdu[0]) + sizeof(uint16_t);
  717. if (pdu == NULL)
  718. return 0;
  719. if (len < (vlen + min_len))
  720. return 0;
  721. pdu[0] = ATT_OP_HANDLE_NOTIFY;
  722. put_le16(handle, &pdu[1]);
  723. memcpy(&pdu[3], value, vlen);
  724. return vlen + min_len;
  725. }
  726. uint16_t enc_indication(uint16_t handle, uint8_t *value, size_t vlen,
  727. uint8_t *pdu, size_t len)
  728. {
  729. const uint16_t min_len = sizeof(pdu[0]) + sizeof(uint16_t);
  730. if (pdu == NULL)
  731. return 0;
  732. if (len < (vlen + min_len))
  733. return 0;
  734. pdu[0] = ATT_OP_HANDLE_IND;
  735. put_le16(handle, &pdu[1]);
  736. memcpy(&pdu[3], value, vlen);
  737. return vlen + min_len;
  738. }
  739. uint16_t dec_indication(const uint8_t *pdu, size_t len, uint16_t *handle,
  740. uint8_t *value, size_t vlen)
  741. {
  742. const uint16_t min_len = sizeof(pdu[0]) + sizeof(uint16_t);
  743. uint16_t dlen;
  744. if (pdu == NULL)
  745. return 0;
  746. if (pdu[0] != ATT_OP_HANDLE_IND)
  747. return 0;
  748. if (len < min_len)
  749. return 0;
  750. dlen = MIN(len - min_len, vlen);
  751. if (handle)
  752. *handle = get_le16(&pdu[1]);
  753. memcpy(value, &pdu[3], dlen);
  754. return dlen;
  755. }
  756. uint16_t enc_confirmation(uint8_t *pdu, size_t len)
  757. {
  758. if (pdu == NULL)
  759. return 0;
  760. /* Attribute Opcode (1 octet) */
  761. pdu[0] = ATT_OP_HANDLE_CNF;
  762. return 1;
  763. }
  764. uint16_t enc_mtu_req(uint16_t mtu, uint8_t *pdu, size_t len)
  765. {
  766. if (pdu == NULL)
  767. return 0;
  768. /* Attribute Opcode (1 octet) */
  769. pdu[0] = ATT_OP_MTU_REQ;
  770. /* Client Rx MTU (2 octets) */
  771. put_le16(mtu, &pdu[1]);
  772. return 3;
  773. }
  774. uint16_t dec_mtu_req(const uint8_t *pdu, size_t len, uint16_t *mtu)
  775. {
  776. const uint16_t min_len = sizeof(pdu[0]) + sizeof(*mtu);
  777. if (pdu == NULL)
  778. return 0;
  779. if (mtu == NULL)
  780. return 0;
  781. if (len < min_len)
  782. return 0;
  783. if (pdu[0] != ATT_OP_MTU_REQ)
  784. return 0;
  785. *mtu = get_le16(&pdu[1]);
  786. return min_len;
  787. }
  788. uint16_t enc_mtu_resp(uint16_t mtu, uint8_t *pdu, size_t len)
  789. {
  790. if (pdu == NULL)
  791. return 0;
  792. /* Attribute Opcode (1 octet) */
  793. pdu[0] = ATT_OP_MTU_RESP;
  794. /* Server Rx MTU (2 octets) */
  795. put_le16(mtu, &pdu[1]);
  796. return 3;
  797. }
  798. uint16_t dec_mtu_resp(const uint8_t *pdu, size_t len, uint16_t *mtu)
  799. {
  800. const uint16_t min_len = sizeof(pdu[0]) + sizeof(*mtu);
  801. if (pdu == NULL)
  802. return 0;
  803. if (mtu == NULL)
  804. return 0;
  805. if (len < min_len)
  806. return 0;
  807. if (pdu[0] != ATT_OP_MTU_RESP)
  808. return 0;
  809. *mtu = get_le16(&pdu[1]);
  810. return min_len;
  811. }
  812. uint16_t enc_prep_write_req(uint16_t handle, uint16_t offset,
  813. const uint8_t *value, size_t vlen,
  814. uint8_t *pdu, size_t len)
  815. {
  816. const uint16_t min_len = sizeof(pdu[0]) + sizeof(handle) +
  817. sizeof(offset);
  818. if (pdu == NULL)
  819. return 0;
  820. if (vlen > len - min_len)
  821. vlen = len - min_len;
  822. pdu[0] = ATT_OP_PREP_WRITE_REQ;
  823. put_le16(handle, &pdu[1]);
  824. put_le16(offset, &pdu[3]);
  825. if (vlen > 0) {
  826. memcpy(&pdu[5], value, vlen);
  827. return min_len + vlen;
  828. }
  829. return min_len;
  830. }
  831. uint16_t dec_prep_write_req(const uint8_t *pdu, size_t len, uint16_t *handle,
  832. uint16_t *offset, uint8_t *value, size_t *vlen)
  833. {
  834. const uint16_t min_len = sizeof(pdu[0]) + sizeof(*handle) +
  835. sizeof(*offset);
  836. if (pdu == NULL)
  837. return 0;
  838. if (handle == NULL || offset == NULL || value == NULL || vlen == NULL)
  839. return 0;
  840. if (len < min_len)
  841. return 0;
  842. if (pdu[0] != ATT_OP_PREP_WRITE_REQ)
  843. return 0;
  844. *handle = get_le16(&pdu[1]);
  845. *offset = get_le16(&pdu[3]);
  846. *vlen = len - min_len;
  847. if (*vlen > 0)
  848. memcpy(value, pdu + min_len, *vlen);
  849. return len;
  850. }
  851. uint16_t enc_prep_write_resp(uint16_t handle, uint16_t offset,
  852. const uint8_t *value, size_t vlen,
  853. uint8_t *pdu, size_t len)
  854. {
  855. const uint16_t min_len = sizeof(pdu[0]) + sizeof(handle) +
  856. sizeof(offset);
  857. if (pdu == NULL)
  858. return 0;
  859. if (vlen > len - min_len)
  860. vlen = len - min_len;
  861. pdu[0] = ATT_OP_PREP_WRITE_RESP;
  862. put_le16(handle, &pdu[1]);
  863. put_le16(offset, &pdu[3]);
  864. if (vlen > 0) {
  865. memcpy(&pdu[5], value, vlen);
  866. return min_len + vlen;
  867. }
  868. return min_len;
  869. }
  870. uint16_t dec_prep_write_resp(const uint8_t *pdu, size_t len, uint16_t *handle,
  871. uint16_t *offset, uint8_t *value, size_t *vlen)
  872. {
  873. const uint16_t min_len = sizeof(pdu[0]) + sizeof(*handle) +
  874. sizeof(*offset);
  875. if (pdu == NULL)
  876. return 0;
  877. if (handle == NULL || offset == NULL || value == NULL || vlen == NULL)
  878. return 0;
  879. if (len < min_len)
  880. return 0;
  881. if (pdu[0] != ATT_OP_PREP_WRITE_REQ)
  882. return 0;
  883. *handle = get_le16(&pdu[1]);
  884. *offset = get_le16(&pdu[3]);
  885. *vlen = len - min_len;
  886. if (*vlen > 0)
  887. memcpy(value, pdu + min_len, *vlen);
  888. return len;
  889. }
  890. uint16_t enc_exec_write_req(uint8_t flags, uint8_t *pdu, size_t len)
  891. {
  892. if (pdu == NULL)
  893. return 0;
  894. if (flags > 1)
  895. return 0;
  896. /* Attribute Opcode (1 octet) */
  897. pdu[0] = ATT_OP_EXEC_WRITE_REQ;
  898. /* Flags (1 octet) */
  899. pdu[1] = flags;
  900. return 2;
  901. }
  902. uint16_t dec_exec_write_req(const uint8_t *pdu, size_t len, uint8_t *flags)
  903. {
  904. const uint16_t min_len = sizeof(pdu[0]) + sizeof(*flags);
  905. if (pdu == NULL)
  906. return 0;
  907. if (flags == NULL)
  908. return 0;
  909. if (len < min_len)
  910. return 0;
  911. if (pdu[0] != ATT_OP_EXEC_WRITE_REQ)
  912. return 0;
  913. *flags = pdu[1];
  914. return min_len;
  915. }
  916. uint16_t enc_exec_write_resp(uint8_t *pdu)
  917. {
  918. if (pdu == NULL)
  919. return 0;
  920. /* Attribute Opcode (1 octet) */
  921. pdu[0] = ATT_OP_EXEC_WRITE_RESP;
  922. return 1;
  923. }
  924. uint16_t dec_exec_write_resp(const uint8_t *pdu, size_t len)
  925. {
  926. const uint16_t min_len = sizeof(pdu[0]);
  927. if (pdu == NULL)
  928. return 0;
  929. if (len < min_len)
  930. return 0;
  931. if (pdu[0] != ATT_OP_EXEC_WRITE_RESP)
  932. return 0;
  933. return len;
  934. }