add ble_ota.c
This commit is contained in:
parent
58e9d61623
commit
0c101b7042
5 changed files with 74 additions and 658 deletions
|
|
@ -6,25 +6,25 @@
|
|||
#include "config.h"
|
||||
#include "OSAL.h"
|
||||
#include "sbp_profile.h"
|
||||
#include "flash.h"
|
||||
#include "ble_ota.h"
|
||||
|
||||
struct {
|
||||
u8 err_flag;
|
||||
u8 version;
|
||||
u8 start_flag;
|
||||
u8 reboot_flag;
|
||||
u32 program_offset;
|
||||
u16 pkt_index;
|
||||
u16 pkt_total;
|
||||
u32 fw_value;
|
||||
u32 crc32;
|
||||
u32 erase_offset;
|
||||
uint8_t err_flag;
|
||||
uint8_t version;
|
||||
uint8_t start_flag;
|
||||
uint8_t reboot_flag;
|
||||
uint32_t program_offset;
|
||||
uint16_t pkt_index;
|
||||
uint16_t pkt_total;
|
||||
uint32_t fw_value;
|
||||
uint32_t crc32;
|
||||
uint32_t erase_addr;
|
||||
} ota;
|
||||
|
||||
#define blt_ota_timeout_us 30000; // default 30 second
|
||||
#define ota_timeout_us 30000; // default 30 second
|
||||
|
||||
unsigned short crc16(unsigned char *pD, int len) {
|
||||
|
||||
static unsigned short poly[2] = { 0, 0xa001 }; //0x8005 <==> 0xa001
|
||||
unsigned short crc = 0xffff;
|
||||
int i, j;
|
||||
|
|
@ -36,7 +36,6 @@ unsigned short crc16(unsigned char *pD, int len) {
|
|||
ds = ds >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
|
|
@ -57,9 +56,9 @@ unsigned int crc32_half_cal(unsigned int crc, unsigned char *input,
|
|||
return crc;
|
||||
}
|
||||
|
||||
u32 get_crc32_16bytes(unsigned int crc_init, unsigned char *data) {
|
||||
// split 16 bytes OTA data into 32 half bytes to caculate CRC.
|
||||
u8 ota_dat[32];
|
||||
uint32_t get_crc32_16bytes(unsigned int crc_init, unsigned char *data) {
|
||||
// split 16 bytes OTA data into 32 half bytes to calculate CRC.
|
||||
uint8_t ota_dat[32];
|
||||
for (int i = 0; i < 16; i++) {
|
||||
ota_dat[i * 2] = data[i] & 0x0f;
|
||||
ota_dat[i * 2 + 1] = data[i] >> 4;
|
||||
|
|
@ -69,39 +68,39 @@ u32 get_crc32_16bytes(unsigned int crc_init, unsigned char *data) {
|
|||
}
|
||||
|
||||
|
||||
void ota_reload_imer(void) {
|
||||
void ota_reload_timer(void) {
|
||||
|
||||
}
|
||||
|
||||
int otaWrite(unsigned char imsg, unsigned char isize) {
|
||||
u32 tmp;
|
||||
u16 crc;
|
||||
u16 ota_adr = imsg[0] | (imsg[1] << 8);
|
||||
u8 flash_check[16];
|
||||
u8 err_flg = OTA_SUCCESS;
|
||||
if(isize > 2) {
|
||||
int ota_parse(unsigned char *pmsg, unsigned int msg_size) {
|
||||
uint32_t tmp;
|
||||
uint16_t crc;
|
||||
uint16_t ota_adr = pmsg[0] | (pmsg[1] << 8);
|
||||
uint8_t flash_check[16];
|
||||
uint8_t err_flg = OTA_SUCCESS;
|
||||
if(msg_size > 2) {
|
||||
// ota_reload_imer();
|
||||
if (ota_adr >= CMD_OTA_START) {
|
||||
if (ota_adr == CMD_OTA_START) {
|
||||
ota.erase_offset = FADD_APP_SEC;
|
||||
ota.erase_addr = FADDR_START_ADDR;
|
||||
ota.fw_value = START_UP_FLAG;
|
||||
ota.start_flag = 0;
|
||||
ota.err_flag = OTA_SUCCESS;
|
||||
} else if (ota_adr == CMD_OTA_SET) {
|
||||
if(ota.start_flag) {
|
||||
err_flg = OTA_NO_START;
|
||||
} else if(isize >= 2 + 10) {
|
||||
ota.program_offset = ((imsg[2] & 0xf0)
|
||||
| (imsg[3] << 8)
|
||||
| (imsg[4] << 16)
|
||||
| (imsg[5] << 24));
|
||||
ota.fw_value = (imsg[6]
|
||||
| (imsg[7] << 8)
|
||||
| (imsg[8] << 16)
|
||||
| (imsg[9] << 24));
|
||||
ota.pkt_total = (imsg[10]
|
||||
| (imsg[11] << 8));
|
||||
if(ota.program_offset >= FADD_APP_SEC
|
||||
} else if(msg_size >= 2 + 10) {
|
||||
ota.program_offset = ((pmsg[2] & 0xf0)
|
||||
| (pmsg[3] << 8)
|
||||
| (pmsg[4] << 16)
|
||||
| (pmsg[5] << 24));
|
||||
ota.fw_value = (pmsg[6]
|
||||
| (pmsg[7] << 8)
|
||||
| (pmsg[8] << 16)
|
||||
| (pmsg[9] << 24));
|
||||
ota.pkt_total = (pmsg[10]
|
||||
| (pmsg[11] << 8));
|
||||
if(ota.program_offset >= FADDR_APP_SEC
|
||||
&& ota.program_offset + (ota.pkt_total << 4) <= FLASH_MAX_SIZE) {
|
||||
ota.pkt_index = -1;
|
||||
ota.start_flag = 1; //set flag
|
||||
|
|
@ -110,28 +109,31 @@ int otaWrite(unsigned char imsg, unsigned char isize) {
|
|||
} else
|
||||
err_flg = OTA_PKT_SIZE_ERR; // size error
|
||||
} else if (ota_adr == CMD_OTA_END) {
|
||||
//@TODO go to reboot or start app
|
||||
//terminateConnection(0x13);
|
||||
//timer(reboot)
|
||||
} else
|
||||
err_flg = OTA_UNKNOWN_CMD; // unknown commad
|
||||
} else if(ota.err_flag) {
|
||||
// stop - old error
|
||||
} else if(ota.start_flag) {
|
||||
if (ota.pkt_index + 1 == ota_adr) { // correct OTA data index
|
||||
if(isize < 2+16+2) {
|
||||
crc = (imsg[19] << 8) | imsg[18];
|
||||
if (crc == crc16(imsg, 18)) {
|
||||
if(msg_size < 2+16+2) {
|
||||
crc = (pmsg[19] << 8) | pmsg[18];
|
||||
if (crc == crc16(pmsg, 18)) {
|
||||
if (ota_adr == 0) {
|
||||
ota.crc32 = 0xFFFFFFFF; // crc init set to 0xFFFFFFFF
|
||||
tmp = ((imsg[2])
|
||||
| (imsg[3] << 8)
|
||||
| (imsg[4] << 16)
|
||||
| (imsg[5] << 24));
|
||||
tmp = ((pmsg[2])
|
||||
| (pmsg[3] << 8)
|
||||
| (pmsg[4] << 16)
|
||||
| (pmsg[5] << 24));
|
||||
if (tmp != ota.fw_value) // id != ?
|
||||
err_flg = OTA_FW_CHECK_ERR;
|
||||
} else if (ota_adr == ota.pkt_total - 1) {
|
||||
tmp = ((imsg[2])
|
||||
| (imsg[3] << 8)
|
||||
| (imsg[4] << 16)
|
||||
| (imsg[5] << 24));
|
||||
tmp = ((pmsg[2])
|
||||
| (pmsg[3] << 8)
|
||||
| (pmsg[4] << 16)
|
||||
| (pmsg[5] << 24));
|
||||
if (ota.crc32 != tmp) // crc32 != ?
|
||||
err_flg = OTA_FW_CRC32_ERR;
|
||||
else {
|
||||
|
|
@ -146,19 +148,23 @@ int otaWrite(unsigned char imsg, unsigned char isize) {
|
|||
}
|
||||
}
|
||||
if (((ota_adr == 0) || ota_adr < ota.pkt_total - 1))
|
||||
ota.crc32 = get_crc32_16bytes(ota.crc32, imsg + 2);
|
||||
ota.crc32 = get_crc32_16bytes(ota.crc32, pmsg + 2);
|
||||
if (ota_adr < ota.pkt_total) {
|
||||
if (ota_adr == 0) {
|
||||
imsg[2] = 0xff;
|
||||
imsg[3] = 0xff;
|
||||
imsg[4] = 0xff;
|
||||
imsg[5] = 0xff;
|
||||
tmp = (ota.program_offset + (ota_adr << 4))
|
||||
& (~(FLASH_SECTOR_SIZE-1));
|
||||
if (tmp > ota.erase_addr) {
|
||||
ota.erase_addr = tmp;
|
||||
hal_flash_erase_sector(tmp);
|
||||
}
|
||||
hal_flash_write(ota.program_offset + (ota_adr << 4),
|
||||
imsg + 2, 16);
|
||||
if (ota_adr == 0)
|
||||
hal_flash_write(ota.program_offset + (ota_adr << 4) + 4,
|
||||
pmsg + 6, 12);
|
||||
else
|
||||
hal_flash_write(ota.program_offset + (ota_adr << 4),
|
||||
pmsg + 2, 16);
|
||||
hal_flash_read(ota.program_offset + (ota_adr << 4),
|
||||
flash_check, 16);
|
||||
if (!memcmp(flash_check, imsg + 2, 16)) { // OK
|
||||
if (!osal_memcmp(flash_check, pmsg + 2, 16)) { // OK
|
||||
ota.pkt_index = ota_adr;
|
||||
} else
|
||||
err_flg = OTA_WRITE_FLASH_ERR; // flash write err
|
||||
|
|
@ -178,7 +184,7 @@ int otaWrite(unsigned char imsg, unsigned char isize) {
|
|||
err_flg = OTA_PKT_SIZE_ERR; // size error
|
||||
if (err_flg) {
|
||||
ota.err_flag = err_flg;
|
||||
blt_ota_finished_flag_set(err_flg);
|
||||
//@TODO send/Notify?
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@
|
|||
#define FLASH_SIZE 0x80000 // 512k (512*1024)
|
||||
#define FLASH_MAX_SIZE 0x200000 // 2M (2048*1024)
|
||||
#define FLASH_SECTOR_SIZE 0x01000 // 4k (4*1024)
|
||||
#define FADD_START_ADDR 0x11000000
|
||||
#define FADD_BOOT_ROM_INFO (FADD_START_ADDR + 0x02000) // 4k
|
||||
#define FADD_BOOT_OTA (FADD_START_ADDR + 0x03000) // 4k
|
||||
#define FADD_APP_INFO (FADD_START_ADDR + 0x04000) // 4k
|
||||
#define FADD_OTA_SEC (FADD_START_ADDR + 0x05000) // 44k
|
||||
#define FADD_APP_SEC (FADD_START_ADDR + 0x10000) // 236k (2x118k)
|
||||
#define FADD_DATA_SEC (FADD_START_ADDR + 0x40000) // 248k
|
||||
#define FADD_EEP_SEC (FADD_START_ADDR + (FLASH_SIZE - 2*FLASH_SECTOR_SIZE))
|
||||
#define FADDR_START_ADDR 0x11000000
|
||||
#define FADDR_BOOT_ROM_INFO (FADDR_START_ADDR + 0x02000) // 4k
|
||||
#define FADDR_BOOT_OTA (FADDR_START_ADDR + 0x03000) // 4k
|
||||
#define FADDR_APP_INFO (FADDR_START_ADDR + 0x04000) // 4k
|
||||
#define FADDR_OTA_SEC (FADDR_START_ADDR + 0x05000) // 44k
|
||||
#define FADDR_APP_SEC (FADDR_START_ADDR + 0x10000) // 236k (2x118k)
|
||||
#define FADDR_DATA_SEC (FADDR_START_ADDR + 0x40000) // 248k
|
||||
#define FADDR_EEP_SEC (FADDR_START_ADDR + (FLASH_SIZE - 2*FLASH_SECTOR_SIZE))
|
||||
|
||||
#define START_UP_FLAG 0x12345678
|
||||
|
||||
|
|
@ -45,7 +45,6 @@ enum {
|
|||
OTA_END = 0xff
|
||||
};
|
||||
|
||||
extern int otaWrite(void *p);
|
||||
extern int otaRead(void *p);
|
||||
int ota_parse(unsigned char *pmsg, unsigned int msg_size);
|
||||
|
||||
#endif /* BLE_OTA_H_ */
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#define DEVICE_TH05 21
|
||||
|
||||
#ifndef DEVICE
|
||||
#define DEVICE DEVICE_THB2
|
||||
#define DEVICE DEVICE_BTH01
|
||||
#endif
|
||||
|
||||
#define DEF_SOFTWARE_REVISION {'V', '0'+ (APP_VERSION >> 4), '.' , '0'+ (APP_VERSION & 0x0F), 0}
|
||||
|
|
|
|||
|
|
@ -1,460 +0,0 @@
|
|||
/**************************************************************************************************
|
||||
Filename: sbpProfile_ota.c
|
||||
Revised:
|
||||
Revision:
|
||||
Description: This file contains the Simple GATT profile sample GATT service
|
||||
profile for use with the BLE sample application.
|
||||
**************************************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
INCLUDES
|
||||
*/
|
||||
#include "bcomdef.h"
|
||||
#include "OSAL.h"
|
||||
#include "linkdb.h"
|
||||
#include "att.h"
|
||||
#include "gatt.h"
|
||||
#include "gatt_uuid.h"
|
||||
#include "gattservapp.h"
|
||||
#include "gapbondmgr.h"
|
||||
//#include "log.h"
|
||||
#include "sbp_profile_ota.h"
|
||||
#include "bleperipheral.h"
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
#define SERVAPP_NUM_ATTR_SUPPORTED 8
|
||||
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* GLOBAL VARIABLES
|
||||
*/
|
||||
// Simple GATT Profile Service UUID: 0xFFF0
|
||||
CONST uint8 simpleProfileServUUID[ATT_BT_UUID_SIZE] =
|
||||
{
|
||||
LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)
|
||||
};
|
||||
|
||||
// Characteristic 1 UUID: 0xFFF3
|
||||
CONST uint8 simpleProfilechar1UUID[ATT_BT_UUID_SIZE] =
|
||||
{
|
||||
LO_UINT16(SIMPLEPROFILE_CHAR1_UUID), HI_UINT16(SIMPLEPROFILE_CHAR1_UUID)
|
||||
};
|
||||
|
||||
// Characteristic 2 UUID: 0xFFF4
|
||||
CONST uint8 simpleProfilechar2UUID[ATT_BT_UUID_SIZE] =
|
||||
{
|
||||
LO_UINT16(SIMPLEPROFILE_CHAR2_UUID), HI_UINT16(SIMPLEPROFILE_CHAR2_UUID)
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL VARIABLES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNAL FUNCTIONS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL VARIABLES
|
||||
*/
|
||||
|
||||
static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
|
||||
//static uint8 ReadNotify_Len = 0;
|
||||
|
||||
/*********************************************************************
|
||||
* Profile Attributes - variables
|
||||
*/
|
||||
|
||||
// Simple Profile Service attribute 0xFFF0
|
||||
static CONST gattAttrType_t simpleProfileService = { ATT_BT_UUID_SIZE, simpleProfileServUUID };
|
||||
|
||||
|
||||
// Simple Profile Characteristic 1 Properties
|
||||
static CONST uint8 simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE | GATT_PROP_WRITE_NO_RSP;
|
||||
static CONST uint8 simpleProfileChar1UserDesp[] = "OTA\0"; // Simple Profile Characteristic 1 User Description
|
||||
|
||||
static uint8 simpleProfileChar1[20]= {0,}; // Characteristic 1 Value
|
||||
|
||||
|
||||
// Simple Profile Characteristic 2 Properties
|
||||
static CONST uint8 simpleProfileChar2Props = GATT_PROP_READ | GATT_PROP_NOTIFY;
|
||||
static CONST uint8 simpleProfileChar2UserDesp[] = "CMD\0"; // Simple Profile Characteristic 2 User Description
|
||||
static gattCharCfg_t simpleProfileChar2Config[GATT_MAX_NUM_CONN]; //
|
||||
|
||||
static uint8 simpleProfileChar2[20]= {0,}; // Characteristic 2 Value
|
||||
|
||||
/*********************************************************************
|
||||
* Profile Attributes - Table
|
||||
*/
|
||||
|
||||
static CONST gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
|
||||
{
|
||||
/* type */ /* permissions */ /* handle */ /* pValue */
|
||||
// Simple Profile Service
|
||||
{{ ATT_BT_UUID_SIZE, primaryServiceUUID }, GATT_PERMIT_READ, 0, (uint8 *)&simpleProfileService},
|
||||
|
||||
// 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[0]},
|
||||
// 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 | GATT_PERMIT_WRITE, 0, &simpleProfileChar2[0]},
|
||||
// Characteristic 2 configuration
|
||||
{{ ATT_BT_UUID_SIZE, clientCharCfgUUID }, GATT_PERMIT_READ | GATT_PERMIT_WRITE, 0, (uint8 *)simpleProfileChar2Config},
|
||||
// Characteristic 2 User Description
|
||||
{{ ATT_BT_UUID_SIZE, charUserDescUUID }, GATT_PERMIT_READ, 0, simpleProfileChar2UserDesp},
|
||||
};
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
*/
|
||||
static bStatus_t simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,uint8 *pValue, uint16 *pLen, uint16 offset, uint8 maxLen );
|
||||
static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,uint8 *pValue, uint16 len, uint16 offset );
|
||||
static void simpleProfile_HandleConnStatusCB( uint16 connHandle, uint8 changeType );
|
||||
/*********************************************************************
|
||||
* PROFILE CALLBACKS
|
||||
*/
|
||||
// Simple Profile Service Callbacks
|
||||
CONST 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 services )
|
||||
{
|
||||
uint8 status = SUCCESS;
|
||||
|
||||
// Initialize Client Characteristic Configuration attributes
|
||||
GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar2Config );
|
||||
|
||||
// Register with Link DB to receive link status change callback
|
||||
VOID 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 ),
|
||||
&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 will be cast to
|
||||
* uint16 pointer).
|
||||
*
|
||||
* @return bStatus_t
|
||||
*/
|
||||
bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
|
||||
{
|
||||
bStatus_t ret = SUCCESS;
|
||||
switch ( param )
|
||||
{
|
||||
case SIMPLEPROFILE_CHAR1:
|
||||
if ( len <= sizeof(simpleProfileChar1) )
|
||||
len = sizeof(simpleProfileChar1);
|
||||
osal_memcpy(simpleProfileChar1, value, len);
|
||||
break;
|
||||
case SIMPLEPROFILE_CHAR2:
|
||||
if ( len <= sizeof(simpleProfileChar2) )
|
||||
len = sizeof(simpleProfileChar2);
|
||||
osal_memcpy(simpleProfileChar2, value, len);
|
||||
break;
|
||||
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 will be cast to
|
||||
* uint16 pointer).
|
||||
*
|
||||
* @return bStatus_t
|
||||
*/
|
||||
bStatus_t SimpleProfile_GetParameter( uint8 param, void *value )
|
||||
{
|
||||
bStatus_t ret = SUCCESS;
|
||||
switch ( param )
|
||||
{
|
||||
case SIMPLEPROFILE_CHAR1:
|
||||
osal_memcpy( value, simpleProfileChar1, sizeof(simpleProfileChar1));
|
||||
break;
|
||||
case SIMPLEPROFILE_CHAR2:
|
||||
osal_memcpy( value, simpleProfileChar2, sizeof(simpleProfileChar2));
|
||||
break;
|
||||
default:
|
||||
ret = INVALIDPARAMETER;
|
||||
break;
|
||||
}
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @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 connHandle, gattAttribute_t *pAttr,
|
||||
uint8 *pValue, uint16 *pLen, uint16 offset, uint8 maxLen )
|
||||
{
|
||||
(void)connHandle;
|
||||
(void)maxLen;
|
||||
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 ( pAttr->type.len == ATT_BT_UUID_SIZE )
|
||||
{
|
||||
// 16-bit UUID
|
||||
uint16 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
|
||||
case SIMPLEPROFILE_CHAR1_UUID:
|
||||
*pLen = sizeof(simpleProfileChar1);
|
||||
VOID osal_memcpy( pValue, pAttr->pValue, *pLen );
|
||||
LOG("Read_UUID1:\n");
|
||||
break;
|
||||
case SIMPLEPROFILE_CHAR2_UUID:
|
||||
*pLen = sizeof(simpleProfileChar2);
|
||||
VOID osal_memcpy( pValue, pAttr->pValue, *pLen );
|
||||
LOG("Read_UUID2:\n");
|
||||
break;
|
||||
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
|
||||
*/
|
||||
// TODO: test this function
|
||||
static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
|
||||
uint8 *pValue, uint16 len, uint16 offset )
|
||||
{
|
||||
bStatus_t status = SUCCESS;
|
||||
uint8 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 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 > BLE_ATT_CMD_LED){
|
||||
status = ATT_ERR_INVALID_VALUE_SIZE;
|
||||
}
|
||||
} else {
|
||||
status = ATT_ERR_ATTR_NOT_LONG;
|
||||
}
|
||||
// Write the value
|
||||
if ( status == SUCCESS ){
|
||||
uint8 *pCurValue = (uint8 *)pAttr->pValue;
|
||||
VOID osal_memcpy(pCurValue, pValue, len );
|
||||
LOG("receive data = 0x ");
|
||||
LOG_DUMP_BYTE(pCurValue, len);
|
||||
// DO NOT deal data in call back!!!Copy data and start an event.
|
||||
osal_set_event(simpleBLEPeripheral_TaskID, SBP_DEALDATA);
|
||||
notifyApp = SIMPLEPROFILE_CHAR1;
|
||||
}
|
||||
break;
|
||||
|
||||
case GATT_CLIENT_CHAR_CFG_UUID:
|
||||
LOG("Enable/Disable Notity\n");
|
||||
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 );
|
||||
}
|
||||
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 connHandle, uint8 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, simpleProfileChar2Config );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bStatus_t simpleProfile_Notify( uint8 param, uint8 len, void *value )
|
||||
{
|
||||
bStatus_t ret = SUCCESS;
|
||||
uint16 notfEnable;
|
||||
|
||||
switch ( param )
|
||||
{
|
||||
case SIMPLEPROFILE_CHAR2:
|
||||
notfEnable = GATTServApp_ReadCharCfg( 0, simpleProfileChar2Config );
|
||||
|
||||
// If notifications enabled
|
||||
if ( notfEnable & GATT_CLIENT_CFG_NOTIFY ){
|
||||
VOID osal_memcpy( simpleProfileChar2, value, len );
|
||||
// ReadNotify_Len = len;
|
||||
/*
|
||||
ret = GATTServApp_ProcessCharCfg( simpleProfileChar2Config, simpleProfileChar2, FALSE,
|
||||
simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
|
||||
INVALID_TASK_ID );
|
||||
*/
|
||||
}else{
|
||||
ret = bleNotReady;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = INVALIDPARAMETER;
|
||||
break;
|
||||
}
|
||||
return ( ret );
|
||||
}
|
||||
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
/**************************************************************************************************
|
||||
Filename: sbpProfile_ota.h
|
||||
Revised:
|
||||
Revision:
|
||||
Description: This file contains the Simple GATT profile definitions and
|
||||
prototypes.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef SBPPROFILE_OTA_H
|
||||
#define SBPPROFILE_OTA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
// Profile Parameters
|
||||
#define SIMPLEPROFILE_CHAR1 0 // RW uint8 - Profile Characteristic 1 value
|
||||
#define SIMPLEPROFILE_CHAR2 1 // RW uint8 - Profile Characteristic 2 value
|
||||
//#define SIMPLEPROFILE_CHAR3 2 // RW uint8 - Profile Characteristic 3 value
|
||||
//#define SIMPLEPROFILE_CHAR4 3 // RW uint8 - Profile Characteristic 4 value
|
||||
//#define SIMPLEPROFILE_CHAR5 4 // RW uint8 - Profile Characteristic 4 value
|
||||
//#define SIMPLEPROFILE_CHAR6 5 // RW uint8 - Profile Characteristic 4 value
|
||||
//#define SIMPLEPROFILE_CHAR7 6 // RW uint8 - Profile Characteristic 4 value
|
||||
|
||||
// Simple Profile Service UUID
|
||||
#define SIMPLEPROFILE_SERV_UUID 0xFFF0
|
||||
|
||||
// Key Pressed UUID
|
||||
#define SIMPLEPROFILE_CHAR1_UUID 0xFFF3
|
||||
#define SIMPLEPROFILE_CHAR2_UUID 0xFFF4
|
||||
//#define SIMPLEPROFILE_CHAR3_UUID 0xFFF3
|
||||
//#define SIMPLEPROFILE_CHAR4_UUID 0xFFF4
|
||||
//#define SIMPLEPROFILE_CHAR5_UUID 0xFFF5
|
||||
//#define SIMPLEPROFILE_CHAR6_UUID 0xFFF6
|
||||
//#define SIMPLEPROFILE_CHAR7_UUID 0xFFF7
|
||||
|
||||
// Simple Keys Profile Services bit fields
|
||||
#define SIMPLEPROFILE_SERVICE 0x00000001
|
||||
|
||||
// Length of Characteristic 5 in bytes
|
||||
#define LC_RGBLIGHT_READTIME_LEN 9
|
||||
#define BLE_ATT_CMD_LED 20
|
||||
#define IBEACON_ATT_LONG_PKT 251 //230//160
|
||||
/*********************************************************************
|
||||
* TYPEDEFS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
* Profile Callbacks
|
||||
*/
|
||||
|
||||
// Callback when a characteristic value has changed
|
||||
typedef void (*simpleProfileChange_t)( uint8 paramID );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
simpleProfileChange_t pfnSimpleProfileChange; // Called when characteristic value changes
|
||||
} simpleProfileCBs_t;
|
||||
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* API FUNCTIONS
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* SimpleProfile_AddService- Initializes the Simple GATT 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.
|
||||
*/
|
||||
|
||||
extern bStatus_t SimpleProfile_AddService( uint32 services );
|
||||
|
||||
/*
|
||||
* SimpleProfile_RegisterAppCBs - Registers the application callback function.
|
||||
* Only call this function once.
|
||||
*
|
||||
* appCallbacks - pointer to application callbacks.
|
||||
*/
|
||||
extern bStatus_t SimpleProfile_RegisterAppCBs( simpleProfileCBs_t *appCallbacks );
|
||||
|
||||
/*
|
||||
* SimpleProfile_SetParameter - Set a Simple GATT Profile parameter.
|
||||
*
|
||||
* param - Profile parameter ID
|
||||
* len - length of data to right
|
||||
* 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 will be cast to
|
||||
* uint16 pointer).
|
||||
*/
|
||||
extern bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value );
|
||||
|
||||
/*
|
||||
* SimpleProfile_GetParameter - Get a Simple GATT Profile parameter.
|
||||
*
|
||||
* param - Profile parameter ID
|
||||
* 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 will be cast to
|
||||
* uint16 pointer).
|
||||
*/
|
||||
extern bStatus_t SimpleProfile_GetParameter( uint8 param, void *value );
|
||||
|
||||
extern bStatus_t simpleProfile_Notify( uint8 param, uint8 len, void *value );
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SIMPLEGATTPROFILE_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue