Hi, I'm looking for a way to change the device's name (GAP Scan Response data) over UART. I have a working UART code and currently, to change the device's name, the user would type SN,<new device name> with <...> as whatever the name the user want to change to.
I'm using the non-volatile flash memory to store newly set name, and when the device is initializing, the name stored would be loaded and its CRC value is compared with the stored CRC value when the user was setting the device name.
Currently, no matter what the value in scanData (allocated at runtime), my tablet (Lollipop) always use the last-known default_scanData so there must be some kind of errors with the newly made scanData. If I change a single character in default_scanData and use that instead, the new name is detected fine. Can I please get some insights into what I'm doing wrong? Thanks.
This the code so far:
0. Local variables and constants...
#define SNV_ID_DEVICE_NAME 0x80
#define SNV_ID_DEVICE_NAME_LENGTH 0x81
#define SNV_ID_DEVICE_NAME_CRC 0x82
uint8 *device_name_crc;
uint8 *device_name;
uint8 *device_name_length;
uint8 *scanData;
// GAP Profile - Name attribute for SCAN RSP data - Name shown up when scanned
static uint8 default_scanData[] =
{
0x15, // length of this data => name's size = 20 bytes
GAP_ADTYPE_LOCAL_NAME_COMPLETE, // AD Type = Complete local name
'H',
'I',
'D',
' ',
'K',
'e',
'y',
'b',
'o',
'a',
'r',
'd',
' ',
'&',
' ',
'M',
'o',
'u',
's',
'e'
};
1. Name changing when user sends over a SN,<new name>
if((rxBuffer[1] == 'N') && (rxBuffer[2] == ',')) {
//TO-DO: SET NAME - May have been coded correctly
printf("Name is being set, reset to set new name\r\n");
uint8 i;
uint8 deviceNewName[20];
uint8 deviceNewNameLength;
uint8 deviceNewNameCRC;
deviceNewNameLength = rxBufferIndex-3;
if(deviceNewNameLength > 20) {
printf("Name exceeds permitted length\r\n");
} else {
for(i = 3; i < rxBufferIndex; i++) {
deviceNewName[i-3] = rxBuffer[i];
}
deviceNewName[deviceNewNameLength] = '\0';
deviceNewNameCRC = getCRC(deviceNewName, deviceNewNameLength);
//printf("%i, %i\r\n", rxBufferIndex, deviceNewNameLength);
//printf("%s\r\n", deviceNewName);
//printf("%x\r\n", deviceNewNameCRC);
osal_snv_write(SNV_ID_DEVICE_NAME, 20, deviceNewName);
osal_snv_write(SNV_ID_DEVICE_NAME_LENGTH, 1, &deviceNewNameLength);
osal_snv_write(SNV_ID_DEVICE_NAME_CRC, 1, &deviceNewNameCRC);
}
2. During initialization, device checks for stored value and use the stored value if it's legit.
osal_snv_read(SNV_ID_DEVICE_NAME_CRC, 1, device_name_crc);
osal_snv_read(SNV_ID_DEVICE_NAME_LENGTH, 1, device_name_length);
osal_snv_read(SNV_ID_DEVICE_NAME, 20, device_name);
if(*device_name_crc != getCRC(device_name, *device_name_length)) {
printf("Using default name\r\n");
GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( default_scanData ), default_scanData );
} else {
printf("Using stored name\r\n"); //this is called just fine
printf("%s\r\n", device_name);
createScanResponseData(device_name, device_name_length, scanData);
//GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( default_scanData ), default_scanData ); //any changes to the default scanData is picked up fine.
GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanData ), scanData ); //not updated regardless of names changed
}
3. Related name changing functions:
//Pololu's CRC functions with minimal changes
uint8 CRCPoly = 0x89; // the value of our CRC-7 polynomial
uint8 CRCTable[256];
void GenerateCRCTable()
{
int i, j;
// generate a table value for all 256 possible byte values
for (i = 0; i < 256; i++)
{
CRCTable[i] = (i & 0x80) ? i ^ CRCPoly : i;
for (j = 1; j < 8; j++)
{
CRCTable[i] <<= 1;
if (CRCTable[i] & 0x80)
CRCTable[i] ^= CRCPoly;
}
}
}
// adds a message byte to the current CRC-7 to get a the new CRC-7
uint8 CRCAdd(uint8 CRC, uint8 message_byte)
{
return CRCTable[(CRC << 1) ^ message_byte];
}
// returns the CRC-7 for a message of "length" bytes
uint8 getCRC(uint8 message[], uint8 length)
{
uint8 i;
uint8 CRC = 0;
for (i = 0; i < length; i++)
CRC = CRCAdd(CRC, message[i]);
return CRC;
}
void createScanResponseData(uint8 *name, uint8 *nameLength, uint8 *responseData) {
uint8 i;
uint8 deviceNameLength = *nameLength;
responseData = osal_mem_alloc(deviceNameLength + 2);
responseData[0] = deviceNameLength + 1;
responseData[1] = GAP_ADTYPE_LOCAL_NAME_COMPLETE;
for(i = 0; i < deviceNameLength; i++) {
responseData[i+2] = name[i];
}
// for(i = 0; i < deviceNameLength+2; i++) {
// printf("%c\r\n", responseData[i]);
// }
}