/********************************************************************* * @fn sensor_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 * @param method - type of write message * * @return SUCCESS, blePending or Failure */ static bStatus_t sensor_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; uint16_t uuid; // If attribute permissions require authorization to write, return error if (gattPermitAuthorWrite(pAttr->permissions)) { // Insufficient authorization return (ATT_ERR_INSUFFICIENT_AUTHOR); } if (utilExtractUuid16(pAttr,&uuid) == FAILURE) { // Invalid handle return ATT_ERR_INVALID_HANDLE; } switch (uuid) { case REGISTER_DATA_UUID: // Validate the value // Make sure it's not a blob oper if (offset == 0) { if (len > REGISTER_DATA_LEN ) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if (status == SUCCESS) { memcpy(pAttr->pValue, pValue, len); sensor_writeRegister(); } break; case REGISTER_ADDR_UUID: // Validate the value // Make sure it's not a blob oper if (offset == 0) { if (len > REGISTER_ADDRESS_LEN ) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if (status == SUCCESS) { if (pValue[0] <= REGISTER_DATA_LEN ) { memcpy(pAttr->pValue, pValue, len); // Address changed; read data sensor_readRegister(); if (pAttr->pValue == (uint8_t*)®isterAddress ) { notifyApp = REGISTER_ADDR; } } else { status = ATT_ERR_INVALID_VALUE; } } break; case REGISTER_DEV_UUID: // Validate the value // Make sure it's not a blob oper if (offset == 0) { if (len != REGISTER_DEVICE_LEN ) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if (status == SUCCESS) { if (pValue[0] < REGISTER_INTERFACE_NUM ) { memcpy(pAttr->pValue, pValue, REGISTER_DEVICE_LEN); if (pAttr->pValue == (uint8_t*)®isterDeviceID ) { notifyApp = REGISTER_DEV; // bspI2cReset(); sensor_initRegister(registerDeviceID[0], registerDeviceID[1]); } } else { status = ATT_ERR_INVALID_VALUE; } } break; case GATT_CLIENT_CHAR_CFG_UUID: status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len, offset, GATT_CLIENT_CFG_NOTIFY); break; default: // Should never get here! status = ATT_ERR_ATTR_NOT_FOUND; break; } // If a characteristic value changed then callback function // to notify application of change if ((notifyApp != 0xFF ) && sensor_AppCBs && sensor_AppCBs->pfnSensorChange) { sensor_AppCBs->pfnSensorChange(notifyApp); } return (status); }
/********************************************************************* * @fn sensor_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 sensor_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr, uint8 *pValue, uint8 len, uint16 offset ) { bStatus_t status = SUCCESS; uint8 notifyApp = 0xFF; uint16 uuid; // If attribute permissions require authorization to write, return error if ( gattPermitAuthorWrite( pAttr->permissions ) ) { // Insufficient authorization return ( ATT_ERR_INSUFFICIENT_AUTHOR ); } if (utilExtractUuid16(pAttr,&uuid) == FAILURE) { // Invalid handle return ATT_ERR_INVALID_HANDLE; } switch ( uuid ) { case SENSOR_DATA_UUID: case SENSOR_CALIBR_UUID: // Should not get here break; case SENSOR_CONFIG_UUID: // Validate the value // Make sure it's not a blob oper if ( offset == 0 ) { if ( len != 1 ) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if ( status == SUCCESS ) { uint8 *pCurValue = (uint8 *)pAttr->pValue; *pCurValue = pValue[0]; if( pAttr->pValue == &sensorCfg ) { notifyApp = SENSOR_CONF; } } break; case SENSOR_PERIOD_UUID: // Validate the value // Make sure it's not a blob oper if ( offset == 0 ) { if ( len != 1 ) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if ( status == SUCCESS ) { if (pValue[0]>=(SENSOR_MIN_UPDATE_PERIOD/SENSOR_PERIOD_RESOLUTION)) { uint8 *pCurValue = (uint8 *)pAttr->pValue; *pCurValue = pValue[0]; if( pAttr->pValue == &sensorPeriod ) { notifyApp = SENSOR_PERI; } } else { status = ATT_ERR_INVALID_VALUE; } } break; case GATT_CLIENT_CHAR_CFG_UUID: status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len, offset, GATT_CLIENT_CFG_NOTIFY ); break; default: // Should never get here! status = ATT_ERR_ATTR_NOT_FOUND; break; } // If a charactersitic value changed then callback function to notify application of change if ( (notifyApp != 0xFF ) && sensor_AppCBs && sensor_AppCBs->pfnSensorChange ) { sensor_AppCBs->pfnSensorChange( notifyApp ); } return ( status ); }
/********************************************************************* * @fn sensor_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 uint8 sensor_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr, uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen ) { uint16 uuid; bStatus_t status = SUCCESS; // If attribute permissions require authorization to read, return error if ( gattPermitAuthorRead( pAttr->permissions ) ) { // Insufficient authorization return ( ATT_ERR_INSUFFICIENT_AUTHOR ); } // 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 (utilExtractUuid16(pAttr,&uuid) == FAILURE) { // Invalid handle *pLen = 0; return ATT_ERR_INVALID_HANDLE; } switch ( uuid ) { // No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases; // gattserverapp handles those reads case SENSOR_DATA_UUID: *pLen = SENSOR_DATA_LEN; VOID osal_memcpy( pValue, pAttr->pValue, SENSOR_DATA_LEN ); break; case SENSOR_CONFIG_UUID: case SENSOR_PERIOD_UUID: *pLen = 1; pValue[0] = *pAttr->pValue; break; case SENSOR_DATA1_UUID: *pLen = SENSOR_DATA1_LEN; VOID osal_memcpy( pValue, pAttr->pValue, SENSOR_DATA1_LEN ); break; case SENSOR_DATA2_UUID: *pLen = SENSOR_DATA2_LEN; VOID osal_memcpy( pValue, pAttr->pValue, SENSOR_DATA2_LEN ); break; case SENSOR_CONFIG1_UUID: case SENSOR_PERIOD1_UUID: *pLen = 1; pValue[0] = *pAttr->pValue; break; case SENSOR_DATA3_UUID: *pLen = SENSOR_DATA3_LEN; VOID osal_memcpy( pValue, pAttr->pValue, SENSOR_DATA3_LEN ); break; case SENSOR_CONFIG2_UUID: case SENSOR_PERIOD2_UUID: *pLen = 1; pValue[0] = *pAttr->pValue; break; default: *pLen = 0; status = ATT_ERR_ATTR_NOT_FOUND; break; } return ( status ); }
/********************************************************************* * @fn sensor_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 * @param method - type of write message * * @return SUCCESS, blePending or Failure */ static bStatus_t sensor_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; uint16_t uuid; if (utilExtractUuid16(pAttr,&uuid) == FAILURE) { // Invalid handle return ATT_ERR_INVALID_HANDLE; } switch (uuid) { case SENSOR_DATA_UUID: // Should not get here break; case SENSOR_CONFIG_UUID: // Validate the value // Make sure it's not a blob oper if (offset == 0) { if (len != SENSOR_CONFIG_LEN) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if (status == SUCCESS) { memcpy(pAttr->pValue, pValue, SENSOR_CONFIG_LEN); if (pAttr->pValue == (uint8_t*)&sensorCfg) { notifyApp = SENSOR_CONF; } } break; case SENSOR_PERIOD_UUID: // Validate the value // Make sure it's not a blob oper if (offset == 0) { if (len != 1) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if (status == SUCCESS) { if (pValue[0]>=(SENSOR_MIN_UPDATE_PERIOD/SENSOR_PERIOD_RESOLUTION)) { uint8_t *pCurValue = (uint8_t *)pAttr->pValue; *pCurValue = pValue[0]; if (pAttr->pValue == &sensorPeriod) { notifyApp = SENSOR_PERI; } } else { status = ATT_ERR_INVALID_VALUE; } } break; case GATT_CLIENT_CHAR_CFG_UUID: status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len, offset, GATT_CLIENT_CFG_NOTIFY); break; default: // Should never get here! status = ATT_ERR_ATTR_NOT_FOUND; break; } // If a characteristic value changed then callback function // to notify application of change if ((notifyApp != 0xFF) && sensor_AppCBs && sensor_AppCBs->pfnSensorChange) { sensor_AppCBs->pfnSensorChange(notifyApp); } return (status); }
/********************************************************************* * @fn sensor_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 * @param method - type of write message * * @return SUCCESS, blePending or Failure */ static bStatus_t sensor_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; uint16_t uuid; // If attribute permissions require authorization to write, return error if (gattPermitAuthorWrite(pAttr->permissions)) { // Insufficient authorization return (ATT_ERR_INSUFFICIENT_AUTHOR); } if (utilExtractUuid16(pAttr,&uuid) == FAILURE) { // Invalid handle return ATT_ERR_INVALID_HANDLE; } switch (uuid) { case DISPLAY_DATA_UUID: // Validate the value // Make sure it's not a blob oper if (offset == 0) { if (len > DISPLAY_DATA_LEN ) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if (status == SUCCESS) { memcpy(pAttr->pValue, pValue, len); // Execute the control sequence if (pAttr->pValue == (uint8_t*)&displayData ) { notifyApp = DISPLAY_DATA; } } break; case DISPLAY_CONF_UUID: // Validate the value // Make sure it's not a blob oper if (offset == 0) { if (len > DISPLAY_CONF_LEN ) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if (status == SUCCESS) { memcpy(pAttr->pValue, pValue, len); // Execute the control sequence if (pAttr->pValue == (uint8_t*)&displayControl ) { notifyApp = DISPLAY_CONF; } } break; default: // Should never get here! status = ATT_ERR_ATTR_NOT_FOUND; break; } // If a characteristic value changed then callback function // to notify application of change if ((notifyApp != 0xFF ) && sensor_AppCBs && sensor_AppCBs->pfnSensorChange) { sensor_AppCBs->pfnSensorChange(notifyApp); } return (status); }
/********************************************************************* * @fn test_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 test_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr, uint8 *pValue, uint8 len, uint16 offset, uint8 method ) { bStatus_t status = SUCCESS; uint8 notifyApp = 0xFF; uint16 uuid; // If attribute permissions require authorization to write, return error if ( gattPermitAuthorWrite( pAttr->permissions ) ) { // Insufficient authorization return ( ATT_ERR_INSUFFICIENT_AUTHOR ); } if (utilExtractUuid16(pAttr,&uuid) == FAILURE) { // Invalid handle return ATT_ERR_INVALID_HANDLE; } switch ( uuid ) { case TEST_CONF_UUID: // Validate the value // Make sure it's not a blob oper if ( offset == 0 ) { if ( len != 1 ) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if ( status == SUCCESS ) { uint8 *pCurValue = (uint8 *)pAttr->pValue; *pCurValue = pValue[0]; if( pAttr->pValue == &testConf ) { notifyApp = TEST_CONF_ATTR; } } break; 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; } // If a charactersitic value changed then callback function to notify application of change if ( (notifyApp != 0xFF ) && test_AppCBs && test_AppCBs->pfnTestChange ) { test_AppCBs->pfnTestChange( notifyApp ); } return ( status ); }
/********************************************************************* * @fn ccService_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 * @param method - type of write message * * @return SUCCESS, blePending or Failure */ static bStatus_t ccService_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr, uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method) { uint16_t uuid; 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 (utilExtractUuid16(pAttr,&uuid) == FAILURE) { // Invalid handle return ATT_ERR_INVALID_HANDLE; } switch (uuid) { case CCSERVICE_CHAR2_UUID: // Validate the value // Make sure it's not a blob oper if (offset == 0) { if (len != CCSERVICE_CHAR2_LEN ) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if (status == SUCCESS) { memcpy(ccServiceChar2, pValue, CCSERVICE_CHAR2_LEN); notifyApp = CCSERVICE_CHAR2; } break; case CCSERVICE_CHAR3_UUID: if (offset == 0) { if (len != 1) { status = ATT_ERR_INVALID_VALUE_SIZE; } } else { status = ATT_ERR_ATTR_NOT_LONG; } // Write the value if (status == SUCCESS) { uint8_t *pCurValue = (uint8_t *)pAttr->pValue; *pCurValue = pValue[0]; notifyApp = CCSERVICE_CHAR3; } break; case GATT_CLIENT_CHAR_CFG_UUID: status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len, offset, GATT_CLIENT_CFG_NOTIFY); break; default: status = ATT_ERR_ATTR_NOT_FOUND; break; } // If a characteristic value changed then callback function to notify application of change if ((notifyApp != 0xFF ) && ccService_AppCBs && ccService_AppCBs->pfnCcChange) { ccService_AppCBs->pfnCcChange(notifyApp); } return (status); }