| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832 |
- /********************************** (C) COPYRIGHT *******************************
- * File Name : gattprofile.C
- * Author : WCH
- * Version : V1.0
- * Date : 2018/12/10
- * Description : Customize services with five different attributes,
- * including readable, writable, notification,
- * readable and writable, and safe readable
- *********************************************************************************
- * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
- * Attention: This software (modified or not) and binary are used for
- * microcontroller manufactured by Nanjing Qinheng Microelectronics.
- *******************************************************************************/
- /*********************************************************************
- * INCLUDES
- */
- #include <user_config.h>
- #include "gattprofile.h"
- /*********************************************************************
- * MACROS
- */
- /*********************************************************************
- * CONSTANTS
- */
- // Position of simpleProfilechar4 value in attribute array
- #define SIMPLEPROFILE_CHAR4_VALUE_POS 11
- #if(DEBUG == DEBUG_UART_BLE)
- #define SIMPLEPROFILE_CHAR5_VALUE_POS 15
- #endif
- /*********************************************************************
- * TYPEDEFS
- */
- /*********************************************************************
- * GLOBAL VARIABLES
- */
- // Simple GATT Profile Service UUID: 0xFFF0
- const uint8_t simpleProfileServUUID[ATT_BT_UUID_SIZE] = {
- LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)};
- // Characteristic 1 UUID: 0xFFF1
- const uint8_t simpleProfilechar1UUID[ATT_BT_UUID_SIZE] = {
- LO_UINT16(SIMPLEPROFILE_CHAR1_UUID), HI_UINT16(SIMPLEPROFILE_CHAR1_UUID)};
- // Characteristic 2 UUID: 0xFFF2
- const uint8_t simpleProfilechar2UUID[ATT_BT_UUID_SIZE] = {
- LO_UINT16(SIMPLEPROFILE_CHAR2_UUID), HI_UINT16(SIMPLEPROFILE_CHAR2_UUID)};
- // Characteristic 3 UUID: 0xFFF3
- const uint8_t simpleProfilechar3UUID[ATT_BT_UUID_SIZE] = {
- LO_UINT16(SIMPLEPROFILE_CHAR3_UUID), HI_UINT16(SIMPLEPROFILE_CHAR3_UUID)};
- // Characteristic 4 UUID: 0xFFF4
- const uint8_t simpleProfilechar4UUID[ATT_BT_UUID_SIZE] = {
- LO_UINT16(SIMPLEPROFILE_CHAR4_UUID), HI_UINT16(SIMPLEPROFILE_CHAR4_UUID)};
- #if(DEBUG == DEBUG_UART_BLE)
- // Characteristic 5 UUID: 0xFFF5
- const uint8_t simpleProfilechar5UUID[ATT_BT_UUID_SIZE] = {
- LO_UINT16(SIMPLEPROFILE_CHAR5_UUID), HI_UINT16(SIMPLEPROFILE_CHAR5_UUID)};
- #endif
- /*********************************************************************
- * EXTERNAL VARIABLES
- */
- /*********************************************************************
- * EXTERNAL FUNCTIONS
- */
- /*********************************************************************
- * LOCAL VARIABLES
- */
- static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
- /*********************************************************************
- * Profile Attributes - variables
- */
- // Simple Profile Service attribute
- static const gattAttrType_t simpleProfileService = {ATT_BT_UUID_SIZE, simpleProfileServUUID};
- // Simple Profile Characteristic 1 Properties
- static uint8_t simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE | GATT_PROP_WRITE_NO_RSP;
- // Characteristic 1 Value
- static uint8_t simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] = {0};
- // Simple Profile Characteristic 1 User Description
- static uint8_t simpleProfileChar1UserDesp[] = "Characteristic 1\0";
- // Simple Profile Characteristic 2 Properties
- static uint8_t simpleProfileChar2Props = GATT_PROP_READ;
- // Characteristic 2 Value
- static uint8_t simpleProfileChar2[SIMPLEPROFILE_CHAR2_LEN] = {0};
- // Simple Profile Characteristic 2 User Description
- static uint8_t simpleProfileChar2UserDesp[] = "Characteristic 2\0";
- // Simple Profile Characteristic 3 Properties
- static uint8_t simpleProfileChar3Props = GATT_PROP_WRITE_NO_RSP;
- // Characteristic 3 Value
- static uint8_t simpleProfileChar3[SIMPLEPROFILE_CHAR3_LEN] = {0};
- // Simple Profile Characteristic 3 User Description
- static uint8_t simpleProfileChar3UserDesp[] = "Characteristic 3\0";
- // Simple Profile Characteristic 4 Properties
- static uint8_t simpleProfileChar4Props = GATT_PROP_NOTIFY | GATT_PROP_WRITE;
- // Characteristic 4 Value
- static uint8_t simpleProfileChar4[SIMPLEPROFILE_CHAR4_LEN] = {0};
- // Simple Profile Characteristic 4 Configuration Each client has its own
- // instantiation of the Client Characteristic Configuration. Reads of the
- // Client Characteristic Configuration only shows the configuration for
- // that client and writes only affect the configuration of that client.
- static gattCharCfg_t simpleProfileChar4Config[4];
- // Simple Profile Characteristic 4 User Description
- static uint8_t simpleProfileChar4UserDesp[] = "Characteristic 4\0";
- #if(DEBUG == DEBUG_UART_BLE)
- // Simple Profile Characteristic 5 Properties
- static uint8_t simpleProfileChar5Props = GATT_PROP_NOTIFY | GATT_PROP_WRITE;
- // Characteristic 5 Value
- static uint8_t simpleProfileChar5[SIMPLEPROFILE_CHAR5_LEN] = {0};
- // Simple Profile Characteristic 5 Configuration Each client has its own
- // instantiation of the Client Characteristic Configuration. Reads of the
- // Client Characteristic Configuration only shows the configuration for
- // that client and writes only affect the configuration of that client.
- static gattCharCfg_t simpleProfileChar5Config[4];
- // Simple Profile Characteristic 5 User Description
- static uint8_t simpleProfileChar5UserDesp[] = "Characteristic 5\0";
- #endif
- /*********************************************************************
- * Profile Attributes - Table
- */
- static gattAttribute_t simpleProfileAttrTbl[] = {
- // Simple Profile Service
- {
- {ATT_BT_UUID_SIZE, primaryServiceUUID}, /* type */
- GATT_PERMIT_READ, /* permissions */
- 0, /* handle */
- (uint8_t *)&simpleProfileService /* pValue */
- },
- // Characteristic 1 Declaration
- {
- {ATT_BT_UUID_SIZE, characterUUID},
- GATT_PERMIT_READ,
- 0,
- &simpleProfileChar1Props},
- // Characteristic Value 1
- {
- {ATT_BT_UUID_SIZE, simpleProfilechar1UUID},
- GATT_PERMIT_READ | GATT_PERMIT_WRITE,
- 0,
- simpleProfileChar1},
- // Characteristic 1 User Description
- {
- {ATT_BT_UUID_SIZE, charUserDescUUID},
- GATT_PERMIT_READ,
- 0,
- simpleProfileChar1UserDesp},
- // Characteristic 2 Declaration
- {
- {ATT_BT_UUID_SIZE, characterUUID},
- GATT_PERMIT_READ,
- 0,
- &simpleProfileChar2Props},
- // Characteristic Value 2
- {
- {ATT_BT_UUID_SIZE, simpleProfilechar2UUID},
- GATT_PERMIT_READ,
- 0,
- simpleProfileChar2},
- // Characteristic 2 User Description
- {
- {ATT_BT_UUID_SIZE, charUserDescUUID},
- GATT_PERMIT_READ,
- 0,
- simpleProfileChar2UserDesp},
- // Characteristic 3 Declaration
- {
- {ATT_BT_UUID_SIZE, characterUUID},
- GATT_PERMIT_READ,
- 0,
- &simpleProfileChar3Props},
- // Characteristic Value 3
- {
- {ATT_BT_UUID_SIZE, simpleProfilechar3UUID},
- GATT_PERMIT_WRITE,
- 0,
- simpleProfileChar3},
- // Characteristic 3 User Description
- {
- {ATT_BT_UUID_SIZE, charUserDescUUID},
- GATT_PERMIT_READ,
- 0,
- simpleProfileChar3UserDesp},
- // Characteristic 4 Declaration
- {
- {ATT_BT_UUID_SIZE, characterUUID},
- GATT_PERMIT_READ,
- 0,
- &simpleProfileChar4Props},
- // Characteristic Value 4
- {
- {ATT_BT_UUID_SIZE, simpleProfilechar4UUID},
- GATT_PERMIT_WRITE,
- 0,
- simpleProfileChar4},
- // Characteristic 4 configuration
- {
- {ATT_BT_UUID_SIZE, clientCharCfgUUID},
- GATT_PERMIT_READ | GATT_PERMIT_WRITE,
- 0,
- (uint8_t *)simpleProfileChar4Config},
- // Characteristic 4 User Description
- {
- {ATT_BT_UUID_SIZE, charUserDescUUID},
- GATT_PERMIT_READ,
- 0,
- simpleProfileChar4UserDesp},
- #if(DEBUG == DEBUG_UART_BLE)
- // Characteristic 5 Declaration
- {
- {ATT_BT_UUID_SIZE, characterUUID},
- GATT_PERMIT_READ,
- 0,
- &simpleProfileChar5Props},
- // Characteristic Value 5
- {
- {ATT_BT_UUID_SIZE, simpleProfilechar5UUID},
- GATT_PERMIT_WRITE,
- 0,
- simpleProfileChar5},
- // Characteristic 5 configuration
- {
- {ATT_BT_UUID_SIZE, clientCharCfgUUID},
- GATT_PERMIT_READ | GATT_PERMIT_WRITE,
- 0,
- (uint8_t *)simpleProfileChar5Config},
- // Characteristic 5 User Description
- {
- {ATT_BT_UUID_SIZE, charUserDescUUID},
- GATT_PERMIT_READ,
- 0,
- simpleProfileChar5UserDesp},
- #endif
- };
- /*********************************************************************
- * LOCAL FUNCTIONS
- */
- static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
- uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method);
- static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
- uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method);
- static void simpleProfile_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType);
- /*********************************************************************
- * PROFILE CALLBACKS
- */
- // Simple Profile Service Callbacks
- gattServiceCBs_t simpleProfileCBs = {
- simpleProfile_ReadAttrCB, // Read callback function pointer
- simpleProfile_WriteAttrCB, // Write callback function pointer
- NULL // Authorization callback function pointer
- };
- /*********************************************************************
- * PUBLIC FUNCTIONS
- */
- /*********************************************************************
- * @fn SimpleProfile_AddService
- *
- * @brief Initializes the Simple Profile service by registering
- * GATT attributes with the GATT server.
- *
- * @param services - services to add. This is a bit map and can
- * contain more than one service.
- *
- * @return Success or Failure
- */
- bStatus_t SimpleProfile_AddService(uint32_t services)
- {
- uint8_t status = SUCCESS;
- // Initialize Client Characteristic Configuration attributes
- GATTServApp_InitCharCfg(INVALID_CONNHANDLE, simpleProfileChar4Config);
- #if(DEBUG == DEBUG_UART_BLE)
- GATTServApp_InitCharCfg(INVALID_CONNHANDLE, simpleProfileChar5Config);
- #endif
- // Register with Link DB to receive link status change callback
- linkDB_Register(simpleProfile_HandleConnStatusCB);
- if(services & SIMPLEPROFILE_SERVICE)
- {
- // Register GATT attribute list and CBs with GATT Server App
- status = GATTServApp_RegisterService(simpleProfileAttrTbl,
- GATT_NUM_ATTRS(simpleProfileAttrTbl),
- GATT_MAX_ENCRYPT_KEY_SIZE,
- &simpleProfileCBs);
- }
- return (status);
- }
- /*********************************************************************
- * @fn SimpleProfile_RegisterAppCBs
- *
- * @brief Registers the application callback function. Only call
- * this function once.
- *
- * @param callbacks - pointer to application callbacks.
- *
- * @return SUCCESS or bleAlreadyInRequestedMode
- */
- bStatus_t SimpleProfile_RegisterAppCBs(simpleProfileCBs_t *appCallbacks)
- {
- if(appCallbacks)
- {
- simpleProfile_AppCBs = appCallbacks;
- return (SUCCESS);
- }
- else
- {
- return (bleAlreadyInRequestedMode);
- }
- }
- /*********************************************************************
- * @fn SimpleProfile_SetParameter
- *
- * @brief Set a Simple Profile parameter.
- *
- * @param param - Profile parameter ID
- * @param len - length of data to right
- * @param value - pointer to data to write. This is dependent on
- * the parameter ID and WILL be cast to the appropriate
- * data type (example: data type of uint16_t will be cast to
- * uint16_t pointer).
- *
- * @return bStatus_t
- */
- bStatus_t SimpleProfile_SetParameter(uint8_t param, uint16_t len, void *value)
- {
- bStatus_t ret = SUCCESS;
- switch(param)
- {
- case SIMPLEPROFILE_CHAR1:
- if(len == SIMPLEPROFILE_CHAR1_LEN)
- {
- tmos_memcpy(simpleProfileChar1, value, SIMPLEPROFILE_CHAR1_LEN);
- }
- else
- {
- ret = bleInvalidRange;
- }
- break;
- case SIMPLEPROFILE_CHAR2:
- if(len == SIMPLEPROFILE_CHAR2_LEN)
- {
- tmos_memcpy(simpleProfileChar2, value, SIMPLEPROFILE_CHAR2_LEN);
- }
- else
- {
- ret = bleInvalidRange;
- }
- break;
- case SIMPLEPROFILE_CHAR3:
- if(len == SIMPLEPROFILE_CHAR3_LEN)
- {
- tmos_memcpy(simpleProfileChar3, value, SIMPLEPROFILE_CHAR3_LEN);
- }
- else
- {
- ret = bleInvalidRange;
- }
- break;
- case SIMPLEPROFILE_CHAR4:
- if(len == SIMPLEPROFILE_CHAR4_LEN)
- {
- tmos_memcpy(simpleProfileChar4, value, SIMPLEPROFILE_CHAR4_LEN);
- }
- else
- {
- ret = bleInvalidRange;
- }
- break;
- #if(DEBUG == DEBUG_UART_BLE)
- case SIMPLEPROFILE_CHAR5:
- if(len == SIMPLEPROFILE_CHAR5_LEN)
- {
- tmos_memcpy(simpleProfileChar5, value, SIMPLEPROFILE_CHAR5_LEN);
- }
- else
- {
- ret = bleInvalidRange;
- }
- break;
- #endif
- default:
- ret = INVALIDPARAMETER;
- break;
- }
- return (ret);
- }
- /*********************************************************************
- * @fn SimpleProfile_GetParameter
- *
- * @brief Get a Simple Profile parameter.
- *
- * @param param - Profile parameter ID
- * @param value - pointer to data to put. This is dependent on
- * the parameter ID and WILL be cast to the appropriate
- * data type (example: data type of uint16_t will be cast to
- * uint16_t pointer).
- *
- * @return bStatus_t
- */
- bStatus_t SimpleProfile_GetParameter(uint8_t param, void *value)
- {
- bStatus_t ret = SUCCESS;
- switch(param)
- {
- case SIMPLEPROFILE_CHAR1:
- tmos_memcpy(value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN);
- break;
- case SIMPLEPROFILE_CHAR2:
- tmos_memcpy(value, simpleProfileChar2, SIMPLEPROFILE_CHAR2_LEN);
- break;
- case SIMPLEPROFILE_CHAR3:
- tmos_memcpy(value, simpleProfileChar3, SIMPLEPROFILE_CHAR3_LEN);
- break;
- case SIMPLEPROFILE_CHAR4:
- tmos_memcpy(value, simpleProfileChar4, SIMPLEPROFILE_CHAR4_LEN);
- break;
- #if(DEBUG == DEBUG_UART_BLE)
- case SIMPLEPROFILE_CHAR5:
- tmos_memcpy(value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN);
- break;
- #endif
- default:
- ret = INVALIDPARAMETER;
- break;
- }
- return (ret);
- }
- /*********************************************************************
- * @fn simpleProfileChar4_Notify
- *
- * @brief Send a notification containing a heart rate
- * measurement.
- *
- * @param connHandle - connection handle
- * @param pNoti - pointer to notification structure
- *
- * @return Success or Failure
- */
- bStatus_t simpleProfileChar4_Notify(uint16_t connHandle, attHandleValueNoti_t *pNoti)
- {
- uint16_t value = GATTServApp_ReadCharCfg(connHandle, simpleProfileChar4Config);
- // If notifications enabled
- if(value & GATT_CLIENT_CFG_NOTIFY)
- {
- // Set the handle
- pNoti->handle = simpleProfileAttrTbl[SIMPLEPROFILE_CHAR4_VALUE_POS].handle;
- // Send the notification
- return GATT_Notification(connHandle, pNoti, FALSE);
- }
- return bleIncorrectMode;
- }
- #if(DEBUG == DEBUG_UART_BLE)
- /*********************************************************************
- * @fn simpleProfileChar5_Notify
- *
- * @brief Send a notification containing a heart rate
- * measurement.
- *
- * @param connHandle - connection handle
- * @param pNoti - pointer to notification structure
- *
- * @return Success or Failure
- */
- bStatus_t simpleProfileChar5_Notify(uint16_t connHandle, attHandleValueNoti_t *pNoti)
- {
- uint16_t value = GATTServApp_ReadCharCfg(connHandle, simpleProfileChar5Config);
- // If notifications enabled
- if(value & GATT_CLIENT_CFG_NOTIFY)
- {
- // Set the handle
- pNoti->handle = simpleProfileAttrTbl[SIMPLEPROFILE_CHAR5_VALUE_POS].handle;
- // Send the notification
- return GATT_Notification(connHandle, pNoti, FALSE);
- }
- return bleIncorrectMode;
- }
- #endif
- /*********************************************************************
- * @fn simpleProfile_ReadAttrCB
- *
- * @brief Read an attribute.
- *
- * @param connHandle - connection message was received on
- * @param pAttr - pointer to attribute
- * @param pValue - pointer to data to be read
- * @param pLen - length of data to be read
- * @param offset - offset of the first octet to be read
- * @param maxLen - maximum length of data to be read
- *
- * @return Success or Failure
- */
- static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
- uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method)
- {
- bStatus_t status = SUCCESS;
- // Make sure it's not a blob operation (no attributes in the profile are long)
- if(offset > 0)
- {
- return (ATT_ERR_ATTR_NOT_LONG);
- }
- if(pAttr->type.len == ATT_BT_UUID_SIZE)
- {
- // 16-bit UUID
- uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
- switch(uuid)
- {
- // No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
- // gattserverapp handles those reads
- // characteristics 1 and 2 have read permissions
- // characteritisc 3 does not have read permissions; therefore it is not
- // included here
- // characteristic 4 does not have read permissions, but because it
- // can be sent as a notification, it is included here
- case SIMPLEPROFILE_CHAR1_UUID:
- if(maxLen > SIMPLEPROFILE_CHAR1_LEN)
- {
- *pLen = SIMPLEPROFILE_CHAR1_LEN;
- }
- else
- {
- *pLen = maxLen;
- }
- tmos_memcpy(pValue, pAttr->pValue, *pLen);
- break;
- case SIMPLEPROFILE_CHAR2_UUID:
- if(maxLen > SIMPLEPROFILE_CHAR2_LEN)
- {
- *pLen = SIMPLEPROFILE_CHAR2_LEN;
- }
- else
- {
- *pLen = maxLen;
- }
- tmos_memcpy(pValue, pAttr->pValue, *pLen);
- break;
- case SIMPLEPROFILE_CHAR4_UUID:
- if(maxLen > SIMPLEPROFILE_CHAR4_LEN)
- {
- *pLen = SIMPLEPROFILE_CHAR4_LEN;
- }
- else
- {
- *pLen = maxLen;
- }
- tmos_memcpy(pValue, pAttr->pValue, *pLen);
- break;
- #if(DEBUG == DEBUG_UART_BLE)
- case SIMPLEPROFILE_CHAR5_UUID:
- if(maxLen > SIMPLEPROFILE_CHAR5_LEN)
- {
- *pLen = SIMPLEPROFILE_CHAR5_LEN;
- }
- else
- {
- *pLen = maxLen;
- }
- tmos_memcpy(pValue, pAttr->pValue, *pLen);
- break;
- #endif
- default:
- // Should never get here! (characteristics 3 and 4 do not have read permissions)
- *pLen = 0;
- status = ATT_ERR_ATTR_NOT_FOUND;
- break;
- }
- }
- else
- {
- // 128-bit UUID
- *pLen = 0;
- status = ATT_ERR_INVALID_HANDLE;
- }
- return (status);
- }
- /*********************************************************************
- * @fn simpleProfile_WriteAttrCB
- *
- * @brief Validate attribute data prior to a write operation
- *
- * @param connHandle - connection message was received on
- * @param pAttr - pointer to attribute
- * @param pValue - pointer to data to be written
- * @param len - length of data
- * @param offset - offset of the first octet to be written
- *
- * @return Success or Failure
- */
- static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
- uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method)
- {
- bStatus_t status = SUCCESS;
- uint8_t notifyApp = 0xFF;
- // If attribute permissions require authorization to write, return error
- if(gattPermitAuthorWrite(pAttr->permissions))
- {
- // Insufficient authorization
- return (ATT_ERR_INSUFFICIENT_AUTHOR);
- }
- if(pAttr->type.len == ATT_BT_UUID_SIZE)
- {
- // 16-bit UUID
- uint16_t uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
- switch(uuid)
- {
- case SIMPLEPROFILE_CHAR1_UUID:
- //Validate the value
- // Make sure it's not a blob oper
- if(offset == 0)
- {
- if(len > SIMPLEPROFILE_CHAR1_LEN)
- {
- status = ATT_ERR_INVALID_VALUE_SIZE;
- }
- }
- else
- {
- status = ATT_ERR_ATTR_NOT_LONG;
- }
- //Write the value
- if(status == SUCCESS)
- {
- tmos_memcpy(pAttr->pValue, pValue, SIMPLEPROFILE_CHAR1_LEN);
- notifyApp = SIMPLEPROFILE_CHAR1;
- }
- break;
- case SIMPLEPROFILE_CHAR3_UUID:
- //Validate the value
- // Make sure it's not a blob oper
- if(offset == 0)
- {
- if(len > SIMPLEPROFILE_CHAR3_LEN)
- {
- status = ATT_ERR_INVALID_VALUE_SIZE;
- }
- }
- else
- {
- status = ATT_ERR_ATTR_NOT_LONG;
- }
- //Write the value
- if(status == SUCCESS)
- {
- tmos_memcpy(pAttr->pValue, pValue, SIMPLEPROFILE_CHAR3_LEN);
- notifyApp = SIMPLEPROFILE_CHAR3;
- }
- break;
- case SIMPLEPROFILE_CHAR4_UUID:
- //Validate the value
- // Make sure it's not a blob oper
- if(offset == 0)
- {
- if(len > SIMPLEPROFILE_CHAR4_LEN)
- {
- status = ATT_ERR_INVALID_VALUE_SIZE;
- }
- }
- else
- {
- status = ATT_ERR_ATTR_NOT_LONG;
- }
- //Write the value
- if(status == SUCCESS)
- {
- tmos_memcpy(pAttr->pValue, pValue, SIMPLEPROFILE_CHAR4_LEN);
- notifyApp = SIMPLEPROFILE_CHAR4;
- }
- break;
- #if(DEBUG == DEBUG_UART_BLE)
- case SIMPLEPROFILE_CHAR5_UUID:
- //Validate the value
- // Make sure it's not a blob oper
- if(offset == 0)
- {
- if(len > SIMPLEPROFILE_CHAR5_LEN)
- {
- status = ATT_ERR_INVALID_VALUE_SIZE;
- }
- }
- else
- {
- status = ATT_ERR_ATTR_NOT_LONG;
- }
- //Write the value
- if(status == SUCCESS)
- {
- tmos_memcpy(pAttr->pValue, pValue, SIMPLEPROFILE_CHAR5_LEN);
- notifyApp = SIMPLEPROFILE_CHAR5;
- }
- break;
- #endif
- case GATT_CLIENT_CHAR_CFG_UUID:
- status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len,
- offset, GATT_CLIENT_CFG_NOTIFY);
- break;
- default:
- // Should never get here! (characteristics 2 and 4 do not have write permissions)
- status = ATT_ERR_ATTR_NOT_FOUND;
- break;
- }
- }
- else
- {
- // 128-bit UUID
- status = ATT_ERR_INVALID_HANDLE;
- }
- // If a charactersitic value changed then callback function to notify application of change
- if((notifyApp != 0xFF) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange)
- {
- simpleProfile_AppCBs->pfnSimpleProfileChange(notifyApp, pValue, len);
- }
- return (status);
- }
- /*********************************************************************
- * @fn simpleProfile_HandleConnStatusCB
- *
- * @brief Simple Profile link status change handler function.
- *
- * @param connHandle - connection handle
- * @param changeType - type of change
- *
- * @return none
- */
- static void simpleProfile_HandleConnStatusCB(uint16_t connHandle, uint8_t changeType)
- {
- // Make sure this is not loopback connection
- if(connHandle != LOOPBACK_CONNHANDLE)
- {
- // Reset Client Char Config if connection has dropped
- if((changeType == LINKDB_STATUS_UPDATE_REMOVED) ||
- ((changeType == LINKDB_STATUS_UPDATE_STATEFLAGS) &&
- (!linkDB_Up(connHandle))))
- {
- GATTServApp_InitCharCfg(connHandle, simpleProfileChar4Config);
- #if(DEBUG == DEBUG_UART_BLE)
- GATTServApp_InitCharCfg(connHandle, simpleProfileChar5Config);
- #endif
- }
- }
- }
- /*********************************************************************
- *********************************************************************/
|