devinfoservice.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. /**************************************************************************************************
  2. Phyplus Microelectronics Limited confidential and proprietary.
  3. All rights reserved.
  4. IMPORTANT: All rights of this software belong to Phyplus Microelectronics
  5. Limited ("Phyplus"). Your use of this Software is limited to those
  6. specific rights granted under the terms of the business contract, the
  7. confidential agreement, the non-disclosure agreement and any other forms
  8. of agreements as a customer or a partner of Phyplus. You may not use this
  9. Software unless you agree to abide by the terms of these agreements.
  10. You acknowledge that the Software may not be modified, copied,
  11. distributed or disclosed unless embedded on a Phyplus Bluetooth Low Energy
  12. (BLE) integrated circuit, either as a product or is integrated into your
  13. products. Other than for the aforementioned purposes, you may not use,
  14. reproduce, copy, prepare derivative works of, modify, distribute, perform,
  15. display or sell this Software and/or its documentation for any purposes.
  16. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  17. PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  18. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  19. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  20. PHYPLUS OR ITS SUBSIDIARIES BE LIABLE OR OBLIGATED UNDER CONTRACT,
  21. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  22. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  23. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  24. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  25. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  26. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  27. **************************************************************************************************/
  28. /**************************************************************************************************
  29. Filename: devinfoservice.c
  30. Revised: $Date $
  31. Revision: $Revision $
  32. Description: This file contains the Device Information service.
  33. **************************************************************************************************/
  34. /*********************************************************************
  35. * INCLUDES
  36. */
  37. #include "bcomdef.h"
  38. #include "OSAL.h"
  39. #include "linkdb.h"
  40. #include "att.h"
  41. #include "gatt.h"
  42. #include "gatt_uuid.h"
  43. #include "gatt_profile_uuid.h"
  44. #include "gattservapp.h"
  45. #include "devinfoservice.h"
  46. /*********************************************************************
  47. * MACROS
  48. */
  49. /*********************************************************************
  50. * CONSTANTS
  51. */
  52. /*********************************************************************
  53. * TYPEDEFS
  54. */
  55. /*********************************************************************
  56. * GLOBAL VARIABLES
  57. */
  58. // Device information service
  59. CONST uint8 devInfoServUUID[ATT_BT_UUID_SIZE] =
  60. {
  61. LO_UINT16(DEVINFO_SERV_UUID), HI_UINT16(DEVINFO_SERV_UUID)
  62. };
  63. // System ID
  64. CONST uint8 devInfoSystemIdUUID[ATT_BT_UUID_SIZE] =
  65. {
  66. LO_UINT16(SYSTEM_ID_UUID), HI_UINT16(SYSTEM_ID_UUID)
  67. };
  68. // Model Number String
  69. CONST uint8 devInfoModelNumberUUID[ATT_BT_UUID_SIZE] =
  70. {
  71. LO_UINT16(MODEL_NUMBER_UUID), HI_UINT16(MODEL_NUMBER_UUID)
  72. };
  73. // Serial Number String
  74. CONST uint8 devInfoSerialNumberUUID[ATT_BT_UUID_SIZE] =
  75. {
  76. LO_UINT16(SERIAL_NUMBER_UUID), HI_UINT16(SERIAL_NUMBER_UUID)
  77. };
  78. // Firmware Revision String
  79. CONST uint8 devInfoFirmwareRevUUID[ATT_BT_UUID_SIZE] =
  80. {
  81. LO_UINT16(FIRMWARE_REV_UUID), HI_UINT16(FIRMWARE_REV_UUID)
  82. };
  83. // Hardware Revision String
  84. CONST uint8 devInfoHardwareRevUUID[ATT_BT_UUID_SIZE] =
  85. {
  86. LO_UINT16(HARDWARE_REV_UUID), HI_UINT16(HARDWARE_REV_UUID)
  87. };
  88. // Software Revision String
  89. CONST uint8 devInfoSoftwareRevUUID[ATT_BT_UUID_SIZE] =
  90. {
  91. LO_UINT16(SOFTWARE_REV_UUID), HI_UINT16(SOFTWARE_REV_UUID)
  92. };
  93. // Manufacturer Name String
  94. CONST uint8 devInfoMfrNameUUID[ATT_BT_UUID_SIZE] =
  95. {
  96. LO_UINT16(MANUFACTURER_NAME_UUID), HI_UINT16(MANUFACTURER_NAME_UUID)
  97. };
  98. // IEEE 11073-20601 Regulatory Certification Data List
  99. CONST uint8 devInfo11073CertUUID[ATT_BT_UUID_SIZE] =
  100. {
  101. LO_UINT16(IEEE_11073_CERT_DATA_UUID), HI_UINT16(IEEE_11073_CERT_DATA_UUID)
  102. };
  103. // PnP ID
  104. CONST uint8 devInfoPnpIdUUID[ATT_BT_UUID_SIZE] =
  105. {
  106. LO_UINT16(PNP_ID_UUID), HI_UINT16(PNP_ID_UUID)
  107. };
  108. /*********************************************************************
  109. * EXTERNAL VARIABLES
  110. */
  111. /*********************************************************************
  112. * EXTERNAL FUNCTIONS
  113. */
  114. /*********************************************************************
  115. * LOCAL VARIABLES
  116. */
  117. /*********************************************************************
  118. * Profile Attributes - variables
  119. */
  120. // Device Information Service attribute
  121. static CONST gattAttrType_t devInfoService = { ATT_BT_UUID_SIZE, devInfoServUUID };
  122. // System ID characteristic
  123. static uint8 devInfoSystemIdProps = GATT_PROP_READ;
  124. static uint8 devInfoSystemId[DEVINFO_SYSTEM_ID_LEN] = {0, 0, 0, 0, 0, 0, 0, 0};
  125. // Model Number String characteristic
  126. static uint8 devInfoModelNumberProps = GATT_PROP_READ;
  127. static const uint8 devInfoModelNumber[] = "Model Number";
  128. // Serial Number String characteristic
  129. static uint8 devInfoSerialNumberProps = GATT_PROP_READ;
  130. static const uint8 devInfoSerialNumber[] = "Serial Number";
  131. // Firmware Revision String characteristic
  132. static uint8 devInfoFirmwareRevProps = GATT_PROP_READ;
  133. static const uint8 devInfoFirmwareRev[] = "Firmware Revision";
  134. // Hardware Revision String characteristic
  135. static uint8 devInfoHardwareRevProps = GATT_PROP_READ;
  136. static const uint8 devInfoHardwareRev[] = "Hardware Revision";
  137. // Software Revision String characteristic
  138. static uint8 devInfoSoftwareRevProps = GATT_PROP_READ;
  139. static const uint8 devInfoSoftwareRev[] = "Software Revision";
  140. // Manufacturer Name String characteristic
  141. static uint8 devInfoMfrNameProps = GATT_PROP_READ;
  142. static const uint8 devInfoMfrName[] = "Manufacturer Name";
  143. // IEEE 11073-20601 Regulatory Certification Data List characteristic
  144. static uint8 devInfo11073CertProps = GATT_PROP_READ;
  145. static const uint8 devInfo11073Cert[] =
  146. {
  147. DEVINFO_11073_BODY_EXP, // authoritative body type
  148. 0x00, // authoritative body structure type
  149. // authoritative body data follows below:
  150. 'e', 'x', 'p', 'e', 'r', 'i', 'm', 'e', 'n', 't', 'a', 'l'
  151. };
  152. // System ID characteristic
  153. static uint8 devInfoPnpIdProps = GATT_PROP_READ;
  154. static uint8 devInfoPnpId[DEVINFO_PNP_ID_LEN] =
  155. {
  156. 1, // Vendor ID source (1=Bluetooth SIG)
  157. LO_UINT16(0x0504), HI_UINT16(0x0504), // Vendor ID (Phyplus)
  158. LO_UINT16(0x0000), HI_UINT16(0x0000), // Product ID (vendor-specific)
  159. LO_UINT16(0x0110), HI_UINT16(0x0110) // Product version (JJ.M.N)
  160. };
  161. /*********************************************************************
  162. * Profile Attributes - Table
  163. */
  164. static gattAttribute_t devInfoAttrTbl[] =
  165. {
  166. // Device Information Service
  167. {
  168. { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
  169. GATT_PERMIT_READ, /* permissions */
  170. 0, /* handle */
  171. (uint8 *)&devInfoService /* pValue */
  172. },
  173. // System ID Declaration
  174. {
  175. { ATT_BT_UUID_SIZE, characterUUID },
  176. GATT_PERMIT_READ,
  177. 0,
  178. &devInfoSystemIdProps
  179. },
  180. // System ID Value
  181. {
  182. { ATT_BT_UUID_SIZE, devInfoSystemIdUUID },
  183. GATT_PERMIT_READ,
  184. 0,
  185. (uint8 *) devInfoSystemId
  186. },
  187. // Model Number String Declaration
  188. {
  189. { ATT_BT_UUID_SIZE, characterUUID },
  190. GATT_PERMIT_READ,
  191. 0,
  192. &devInfoModelNumberProps
  193. },
  194. // Model Number Value
  195. {
  196. { ATT_BT_UUID_SIZE, devInfoModelNumberUUID },
  197. GATT_PERMIT_READ,
  198. 0,
  199. (uint8 *) devInfoModelNumber
  200. },
  201. // Serial Number String Declaration
  202. {
  203. { ATT_BT_UUID_SIZE, characterUUID },
  204. GATT_PERMIT_READ,
  205. 0,
  206. &devInfoSerialNumberProps
  207. },
  208. // Serial Number Value
  209. {
  210. { ATT_BT_UUID_SIZE, devInfoSerialNumberUUID },
  211. GATT_PERMIT_READ,
  212. 0,
  213. (uint8 *) devInfoSerialNumber
  214. },
  215. // Firmware Revision String Declaration
  216. {
  217. { ATT_BT_UUID_SIZE, characterUUID },
  218. GATT_PERMIT_READ,
  219. 0,
  220. &devInfoFirmwareRevProps
  221. },
  222. // Firmware Revision Value
  223. {
  224. { ATT_BT_UUID_SIZE, devInfoFirmwareRevUUID },
  225. GATT_PERMIT_READ,
  226. 0,
  227. (uint8 *) devInfoFirmwareRev
  228. },
  229. // Hardware Revision String Declaration
  230. {
  231. { ATT_BT_UUID_SIZE, characterUUID },
  232. GATT_PERMIT_READ,
  233. 0,
  234. &devInfoHardwareRevProps
  235. },
  236. // Hardware Revision Value
  237. {
  238. { ATT_BT_UUID_SIZE, devInfoHardwareRevUUID },
  239. GATT_PERMIT_READ,
  240. 0,
  241. (uint8 *) devInfoHardwareRev
  242. },
  243. // Software Revision String Declaration
  244. {
  245. { ATT_BT_UUID_SIZE, characterUUID },
  246. GATT_PERMIT_READ,
  247. 0,
  248. &devInfoSoftwareRevProps
  249. },
  250. // Software Revision Value
  251. {
  252. { ATT_BT_UUID_SIZE, devInfoSoftwareRevUUID },
  253. GATT_PERMIT_READ,
  254. 0,
  255. (uint8 *) devInfoSoftwareRev
  256. },
  257. // Manufacturer Name String Declaration
  258. {
  259. { ATT_BT_UUID_SIZE, characterUUID },
  260. GATT_PERMIT_READ,
  261. 0,
  262. &devInfoMfrNameProps
  263. },
  264. // Manufacturer Name Value
  265. {
  266. { ATT_BT_UUID_SIZE, devInfoMfrNameUUID },
  267. GATT_PERMIT_READ,
  268. 0,
  269. (uint8 *) devInfoMfrName
  270. },
  271. // IEEE 11073-20601 Regulatory Certification Data List Declaration
  272. {
  273. { ATT_BT_UUID_SIZE, characterUUID },
  274. GATT_PERMIT_READ,
  275. 0,
  276. &devInfo11073CertProps
  277. },
  278. // IEEE 11073-20601 Regulatory Certification Data List Value
  279. {
  280. { ATT_BT_UUID_SIZE, devInfo11073CertUUID },
  281. GATT_PERMIT_READ,
  282. 0,
  283. (uint8 *) devInfo11073Cert
  284. },
  285. // PnP ID Declaration
  286. {
  287. { ATT_BT_UUID_SIZE, characterUUID },
  288. GATT_PERMIT_READ,
  289. 0,
  290. &devInfoPnpIdProps
  291. },
  292. // PnP ID Value
  293. {
  294. { ATT_BT_UUID_SIZE, devInfoPnpIdUUID },
  295. GATT_PERMIT_READ,
  296. 0,
  297. (uint8 *) devInfoPnpId
  298. }
  299. };
  300. /*********************************************************************
  301. * LOCAL FUNCTIONS
  302. */
  303. static uint8 devInfo_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
  304. uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen );
  305. /*********************************************************************
  306. * PROFILE CALLBACKS
  307. */
  308. // Device Info Service Callbacks
  309. CONST gattServiceCBs_t devInfoCBs =
  310. {
  311. devInfo_ReadAttrCB, // Read callback function pointer
  312. NULL, // Write callback function pointer
  313. NULL // Authorization callback function pointer
  314. };
  315. /*********************************************************************
  316. * NETWORK LAYER CALLBACKS
  317. */
  318. /*********************************************************************
  319. * PUBLIC FUNCTIONS
  320. */
  321. /*********************************************************************
  322. * @fn DevInfo_AddService
  323. *
  324. * @brief Initializes the Device Information service by registering
  325. * GATT attributes with the GATT server.
  326. *
  327. * @return Success or Failure
  328. */
  329. bStatus_t DevInfo_AddService( void )
  330. {
  331. // Register GATT attribute list and CBs with GATT Server App
  332. return GATTServApp_RegisterService( devInfoAttrTbl,
  333. GATT_NUM_ATTRS( devInfoAttrTbl ),
  334. &devInfoCBs );
  335. }
  336. /*********************************************************************
  337. * @fn DevInfo_SetParameter
  338. *
  339. * @brief Set a Device Information parameter.
  340. *
  341. * @param param - Profile parameter ID
  342. * @param len - length of data to write
  343. * @param value - pointer to data to write. This is dependent on
  344. * the parameter ID and WILL be cast to the appropriate
  345. * data type (example: data type of uint16 will be cast to
  346. * uint16 pointer).
  347. *
  348. * @return bStatus_t
  349. */
  350. bStatus_t DevInfo_SetParameter( uint8 param, uint8 len, void *value )
  351. {
  352. bStatus_t ret = SUCCESS;
  353. switch ( param )
  354. {
  355. case DEVINFO_SYSTEM_ID:
  356. osal_memcpy(devInfoSystemId, value, len);
  357. break;
  358. default:
  359. ret = INVALIDPARAMETER;
  360. break;
  361. }
  362. return ( ret );
  363. }
  364. /*********************************************************************
  365. * @fn DevInfo_GetParameter
  366. *
  367. * @brief Get a Device Information parameter.
  368. *
  369. * @param param - Profile parameter ID
  370. * @param value - pointer to data to get. This is dependent on
  371. * the parameter ID and WILL be cast to the appropriate
  372. * data type (example: data type of uint16 will be cast to
  373. * uint16 pointer).
  374. *
  375. * @return bStatus_t
  376. */
  377. bStatus_t DevInfo_GetParameter( uint8 param, void *value )
  378. {
  379. bStatus_t ret = SUCCESS;
  380. switch ( param )
  381. {
  382. case DEVINFO_SYSTEM_ID:
  383. osal_memcpy(value, devInfoSystemId, sizeof(devInfoSystemId));
  384. break;
  385. case DEVINFO_MODEL_NUMBER:
  386. osal_memcpy(value, devInfoModelNumber, sizeof(devInfoModelNumber));
  387. break;
  388. case DEVINFO_SERIAL_NUMBER:
  389. osal_memcpy(value, devInfoSerialNumber, sizeof(devInfoSerialNumber));
  390. break;
  391. case DEVINFO_FIRMWARE_REV:
  392. osal_memcpy(value, devInfoFirmwareRev, sizeof(devInfoFirmwareRev));
  393. break;
  394. case DEVINFO_HARDWARE_REV:
  395. osal_memcpy(value, devInfoHardwareRev, sizeof(devInfoHardwareRev));
  396. break;
  397. case DEVINFO_SOFTWARE_REV:
  398. osal_memcpy(value, devInfoSoftwareRev, sizeof(devInfoSoftwareRev));
  399. break;
  400. case DEVINFO_MANUFACTURER_NAME:
  401. osal_memcpy(value, devInfoMfrName, sizeof(devInfoMfrName));
  402. break;
  403. case DEVINFO_11073_CERT_DATA:
  404. osal_memcpy(value, devInfo11073Cert, sizeof(devInfo11073Cert));
  405. break;
  406. case DEVINFO_PNP_ID:
  407. osal_memcpy(value, devInfoPnpId, sizeof(devInfoPnpId));
  408. break;
  409. default:
  410. ret = INVALIDPARAMETER;
  411. break;
  412. }
  413. return ( ret );
  414. }
  415. /*********************************************************************
  416. * @fn devInfo_ReadAttrCB
  417. *
  418. * @brief Read an attribute.
  419. *
  420. * @param connHandle - connection message was received on
  421. * @param pAttr - pointer to attribute
  422. * @param pValue - pointer to data to be read
  423. * @param pLen - length of data to be read
  424. * @param offset - offset of the first octet to be read
  425. * @param maxLen - maximum length of data to be read
  426. *
  427. * @return Success or Failure
  428. */
  429. static uint8 devInfo_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
  430. uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen )
  431. {
  432. bStatus_t status = SUCCESS;
  433. uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
  434. switch (uuid)
  435. {
  436. case SYSTEM_ID_UUID:
  437. // verify offset
  438. if (offset >= sizeof(devInfoSystemId))
  439. {
  440. status = ATT_ERR_INVALID_OFFSET;
  441. }
  442. else
  443. {
  444. // determine read length
  445. *pLen = MIN(maxLen, (sizeof(devInfoSystemId) - offset));
  446. // copy data
  447. osal_memcpy(pValue, &devInfoSystemId[offset], *pLen);
  448. }
  449. break;
  450. case MODEL_NUMBER_UUID:
  451. // verify offset
  452. if (offset >= (sizeof(devInfoModelNumber) - 1))
  453. {
  454. status = ATT_ERR_INVALID_OFFSET;
  455. }
  456. else
  457. {
  458. // determine read length (exclude null terminating character)
  459. *pLen = MIN(maxLen, ((sizeof(devInfoModelNumber) - 1) - offset));
  460. // copy data
  461. osal_memcpy(pValue, &devInfoModelNumber[offset], *pLen);
  462. }
  463. break;
  464. case SERIAL_NUMBER_UUID:
  465. // verify offset
  466. if (offset >= (sizeof(devInfoSerialNumber) - 1))
  467. {
  468. status = ATT_ERR_INVALID_OFFSET;
  469. }
  470. else
  471. {
  472. // determine read length (exclude null terminating character)
  473. *pLen = MIN(maxLen, ((sizeof(devInfoSerialNumber) - 1) - offset));
  474. // copy data
  475. osal_memcpy(pValue, &devInfoSerialNumber[offset], *pLen);
  476. }
  477. break;
  478. case FIRMWARE_REV_UUID:
  479. // verify offset
  480. if (offset >= (sizeof(devInfoFirmwareRev) - 1))
  481. {
  482. status = ATT_ERR_INVALID_OFFSET;
  483. }
  484. else
  485. {
  486. // determine read length (exclude null terminating character)
  487. *pLen = MIN(maxLen, ((sizeof(devInfoFirmwareRev) - 1) - offset));
  488. // copy data
  489. osal_memcpy(pValue, &devInfoFirmwareRev[offset], *pLen);
  490. }
  491. break;
  492. case HARDWARE_REV_UUID:
  493. // verify offset
  494. if (offset >= (sizeof(devInfoHardwareRev) - 1))
  495. {
  496. status = ATT_ERR_INVALID_OFFSET;
  497. }
  498. else
  499. {
  500. // determine read length (exclude null terminating character)
  501. *pLen = MIN(maxLen, ((sizeof(devInfoHardwareRev) - 1) - offset));
  502. // copy data
  503. osal_memcpy(pValue, &devInfoHardwareRev[offset], *pLen);
  504. }
  505. break;
  506. case SOFTWARE_REV_UUID:
  507. // verify offset
  508. if (offset >= (sizeof(devInfoSoftwareRev) - 1))
  509. {
  510. status = ATT_ERR_INVALID_OFFSET;
  511. }
  512. else
  513. {
  514. // determine read length (exclude null terminating character)
  515. *pLen = MIN(maxLen, ((sizeof(devInfoSoftwareRev) - 1) - offset));
  516. // copy data
  517. osal_memcpy(pValue, &devInfoSoftwareRev[offset], *pLen);
  518. }
  519. break;
  520. case MANUFACTURER_NAME_UUID:
  521. // verify offset
  522. if (offset >= (sizeof(devInfoMfrName) - 1))
  523. {
  524. status = ATT_ERR_INVALID_OFFSET;
  525. }
  526. else
  527. {
  528. // determine read length (exclude null terminating character)
  529. *pLen = MIN(maxLen, ((sizeof(devInfoMfrName) - 1) - offset));
  530. // copy data
  531. osal_memcpy(pValue, &devInfoMfrName[offset], *pLen);
  532. }
  533. break;
  534. case IEEE_11073_CERT_DATA_UUID:
  535. // verify offset
  536. if (offset >= sizeof(devInfo11073Cert))
  537. {
  538. status = ATT_ERR_INVALID_OFFSET;
  539. }
  540. else
  541. {
  542. // determine read length
  543. *pLen = MIN(maxLen, (sizeof(devInfo11073Cert) - offset));
  544. // copy data
  545. osal_memcpy(pValue, &devInfo11073Cert[offset], *pLen);
  546. }
  547. break;
  548. case PNP_ID_UUID:
  549. // verify offset
  550. if (offset >= sizeof(devInfoPnpId))
  551. {
  552. status = ATT_ERR_INVALID_OFFSET;
  553. }
  554. else
  555. {
  556. // determine read length
  557. *pLen = MIN(maxLen, (sizeof(devInfoPnpId) - offset));
  558. // copy data
  559. osal_memcpy(pValue, &devInfoPnpId[offset], *pLen);
  560. }
  561. break;
  562. default:
  563. *pLen = 0;
  564. status = ATT_ERR_ATTR_NOT_FOUND;
  565. break;
  566. }
  567. return ( status );
  568. }
  569. /*********************************************************************
  570. *********************************************************************/