
fork test
Dependencies: BLE_API WIFI_API_32kRAM mbed nRF51822
Fork of NNN40_CLI by
Diff: CLI_Source/ble_cli.cpp
- Revision:
- 4:b52035367aee
- Parent:
- 3:38ec8ad317f4
- Child:
- 5:ee474e3133eb
--- a/CLI_Source/ble_cli.cpp Fri Oct 02 10:36:29 2015 +0000 +++ b/CLI_Source/ble_cli.cpp Sat Nov 07 09:02:38 2015 +0000 @@ -24,14 +24,16 @@ extern "C" { #include "ble_advdata.h" } - -//#define S110_BLE_PERIPHERAL -//#define S120_BLE_CENTRAL +#include "ble/GattCharacteristic.h" +#include "ble/UUID.h" +#include "ble/DiscoveredCharacteristic.h" +#include "ble/DiscoveredService.h" +//#include <vector> -#define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */ +#define APP_ADV_INTERVAL 40 /**< The advertising interval (in units of ms). */ #define APP_ADV_TIMEOUT_IN_SECONDS 180 /**< The advertising timeout (in units of seconds). */ -#define APP_ADV_INTERVAL_MAX 16384 // correspond to 10.24s -#define APP_ADV_INTERVAL_MIN 32 // correspond to 20ms +#define APP_ADV_INTERVAL_MAX 10240 // correspond to 10.24s +#define APP_ADV_INTERVAL_MIN 20 // correspond to 20ms // Offset for Advertising Data. #define APP_ADV_DATA_OFFSET 2 @@ -40,45 +42,32 @@ #define CLI_CHAR_MAX_NUM 10 #define MAX_VALUE_LENGTH 20 -#define CLI_CHAR_MODE_NONE 0 -#define CLI_CHAR_MODE_READ 1 -#define CLI_CHAR_MODE_WRITE 2 -#define CLI_CHAR_MODE_INDICATE 3 -#define CLI_CHAR_MODE_NOTIFY 4 - #define CLI_FWVERION "DELTA_CLI_V1.6" #define MODULE_NAME "DFCM-NNN40-DT1R" #define ADVERTISING_LED_PIN_NO LED1 -//#define DELTA_DEBUG +//#define BLE_DEBUG //#define LBS_UUID_BASE {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00} #define NEW_VS_SERVICE 0x0001 #define DEFAULT_SCAN_INTERVAL 500 #define DEFAULT_SCAN_WINDOW 400 -#define DEFAULT_SCAN_TIMEOUT 5 +#define DEFAULT_SCAN_TIMEOUT 0x0005 #define BLE_MAX_ADDRESS_NUMBER 10 - -static ble_gap_addr_t m_peer_addr; -extern Serial console; -BLE deltaBLE; //gill 0904 -extern const char* cyntecCommandErrorNames[]; -static bool connState = false; // gill 0904 +#define TARGET_DEVNAME_LEN 30 typedef struct bufferGattChar { // bool flag; - uint8_t mode; - ble_uuid_t char_uuid; - //uint8_t value[MAX_VALUE_LENGTH]; - uint16_t char_value_handle; + uint32_t props; + UUID char_uuid; + uint8_t value[MAX_VALUE_LENGTH]; + //uint16_t char_value_handle; uint8_t valueLength; } bufferGattChar_t; typedef struct bufferGattService { -// uint16_t service_uuid_vs[8]; -// uint16_t service_uuid; // bool flag; - ble_uuid_t service_uuid; + UUID ser_uuid; bufferGattChar_t bufferGattChar[CLI_CHAR_MAX_NUM]; - uint16_t service_handle; + //uint16_t service_handle; } bufferGattService_t; // gill 20150916 for scan @@ -88,18 +77,23 @@ } data_t; /* save entry services */ -bufferGattService_t bufferGattTest; bufferGattService_t bufferService[CLI_SERVICE_MAX_NUM]; - - -//static uint8_t debugMess[20]; // used in print debug -uint8_t service_count=0; -uint8_t char_count=0; +static ble_gap_addr_t m_peer_addr; +extern Serial console; +BLE deltaBLE; //gill 0904 +extern const char* cyntecCommandErrorNames[]; +static bool connState = false; // gill 0904 +static uint8_t service_count=0; +static uint8_t char_count=0; static uint16_t test_conn_handle; //Connection handle, assign after connected extern bool advState; // currently no use static Gap::Address_t saveAddr[BLE_MAX_ADDRESS_NUMBER]; // check in advertisementCallback static uint8_t bleDevInd; -static Gap::GapState_t nowState; +//static Gap::GapState_t nowState; +static char targetDevName[TARGET_DEVNAME_LEN]; +static char DEVICE_NAME[] = "DELTA_CLI"; // default device name +static bool conn_action = false; // Gill add 20151015 +static GattCharacteristic *charAry[CLI_SERVICE_MAX_NUM][CLI_CHAR_MAX_NUM]; DigitalOut led1(p7); DigitalOut led2(p13); @@ -108,20 +102,60 @@ * Function Definitions ******************************************************/ +DiscoveredCharacteristic ledCharacteristic; void onTimeoutCallback(Gap::TimeoutSource_t source) { led1 = !led1; } +void serviceDiscoveryCallback(const DiscoveredService *service) +{ + console.printf("serviceDiscoveryCallback\r\n"); + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); + } else { + printf("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + printf("%02x", longUUIDBytes[i]); + } + printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); + } +} + +void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) +{ + console.printf("characteristicDiscoveryCallback\r\n"); + //printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); + //if (characteristicP->getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */ + if(1) { + ledCharacteristic = *characteristicP; + } +} +void discoveryTerminationCallback(Gap::Handle_t connectionHandle) +{ + printf("terminated SD for handle %u\r\n", connectionHandle); +} + + void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params) { test_conn_handle = params->handle; - //console.printf("connState:%d\r\n",connState); connState = true; - led2 = !led2; +#ifdef BLE_DEBUG + console.printf("Connect: connState write to %d\r\n",connState); +#endif + + //led2 = !led2; + + // gill test + //if (params->role == Gap::CENTRAL) { +// //deltaBLE.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); +// deltaBLE.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0xa000, 0xa001); +// } } -void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { //console.printf("connState:%d\r\n",connState); //Gap::GapState_t->connected = 0; @@ -141,152 +175,10 @@ console.printf("\r\n\r\n"); } - -static uint32_t adv_report_parse(uint8_t type, data_t * p_advdata, data_t * p_typedata) -{ - uint32_t index = 0; - const uint8_t * p_data; - - p_data = p_advdata->p_data; - - while (index < p_advdata->data_len) { - uint8_t field_length = p_data[index]; - uint8_t field_type = p_data[index+1]; - - if (field_type == type) { - p_typedata->p_data = &p_data[index+2]; - p_typedata->data_len = field_length-1; - return NRF_SUCCESS; - } - index += field_length+1; - } - return NRF_ERROR_NOT_FOUND; -} - -void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) -{ - bool flagRepeat=false; - Gap::Address_t newAddr[6]; - memcpy(newAddr,params->peerAddr,6); - - for(int i=0; i<BLE_MAX_ADDRESS_NUMBER; i++) { - if (memcmp(newAddr,saveAddr[i],6)==0) { -#ifdef DELTA_DEBUG - console.printf("Repeated\r\n"); -#endif - flagRepeat = true; - //return; - } - } - -#ifdef DELTA_DEBUG - console.printf("addr cmp result :%i\r\n",memcmp(newAddr,params->peerAddr,6)); - console.printf("ADV data:%X,%i\r\n",&(params->advertisingData),params->advertisingDataLen); -#endif - data_t adv_data; - data_t type_data; - //Initialize advertisement report for parsing. - adv_data.p_data = params->advertisingData; - adv_data.data_len = params->advertisingDataLen; - // Parsing Device Name - uint32_t err_code = adv_report_parse(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, - &adv_data, - &type_data); -#ifdef DELTA_DEBUG - console.printf("error code:%X\r\n",err_code); - console.printf("type_data.data_len:%i\r\n",type_data.data_len); -#endif - if (flagRepeat == false) { - if (err_code == 0) { - for (int i=0; i<type_data.data_len; i++) { - console.printf("%c",type_data.p_data[i]); - } - //console.printf("\r\n"); - } - console.printf(",ADV,[%02X %02X %02X %02X %02X %02X],%d,%u\r\n",params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], - params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],params->rssi,params->type); - memcpy(saveAddr[bleDevInd],params->peerAddr,6); - bleDevInd++; - } - - /* - Check short name, not implemented - */ - //else -// { -// uint32_t err_code_2 = adv_report_parse(BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME, -// &adv_data, -// &type_data); -// console.printf("error code:%X\r\n",err_code_2); -// console.printf("%i\r\n",type_data.data_len); -// console.printf("%s\r\n",type_data.p_data); -// -// } - //ble.gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); -} - - - -/**@brief Function for the Advertising functionality initialization. - * - * @details Encodes the required advertising data and passes it to the stack. - * Also builds a structure to be passed to the stack when starting advertising. - */ -static void advertising_init(void) -{ - uint32_t err_code; - ble_advdata_t advdata; - ble_advdata_t scanrsp; - //uint8_t flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE; - - ble_uuid_t adv_uuids[] = {{bufferService[0].service_uuid.uuid, 0x01}}; - - memset(&advdata, 0, sizeof(advdata)); - advdata.name_type = BLE_ADVDATA_FULL_NAME; - advdata.include_appearance = false; - advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; -// advdata.flags.size = sizeof(flags); -// advdata.flags.p_data = &flags; - - memset(&scanrsp, 0, sizeof(scanrsp)); - scanrsp.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]); - scanrsp.uuids_complete.p_uuids = adv_uuids; - - err_code = ble_advdata_set(&advdata, &scanrsp); - APP_ERROR_CHECK(err_code); -} - - -/**@brief Function for starting advertising. - */ -static uint8_t advertising_start(uint16_t advInterval, uint16_t advTimeout) -{ - uint32_t err_code; - ble_gap_adv_params_t adv_params; - - // Start advertising - memset(&adv_params, 0, sizeof(adv_params)); - - adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; /**< Connectable undirected. */ - adv_params.p_peer_addr = NULL; - adv_params.fp = BLE_GAP_ADV_FP_ANY; /**< Allow scan requests and connect requests from any device. */ - adv_params.interval = advInterval; - adv_params.timeout = advTimeout; - - err_code = sd_ble_gap_adv_start(&adv_params); - //APP_ERROR_CHECK(err_code); - return err_code; -} - - - static void cynAdvertiseStartCommand(void) { - // adv start or adv stop or syntax error uint8_t argLen = 0; uint8_t *arg; - /* arg0 is start or stop advertising */ - uint8_t *action = cyntecGetCommandArgument(0,&argLen); uint16_t advInterval; uint16_t advTimeout; @@ -295,21 +187,18 @@ advInterval = APP_ADV_INTERVAL; advTimeout = APP_ADV_TIMEOUT_IN_SECONDS; break; - case 3: /* arg1 is adv interval parameter */ - arg = cyntecGetCommandArgument(1,&argLen); + arg = cyntecGetCommandArgument(0,&argLen); advInterval = cyntecAtoiUint16( arg, argLen ); advTimeout = APP_ADV_TIMEOUT_IN_SECONDS; break; - case 4: + arg = cyntecGetCommandArgument(0,&argLen); + advInterval = cyntecAtoiUint16( arg, argLen ); arg = cyntecGetCommandArgument(1,&argLen); - advInterval = cyntecAtoiUint16( arg, argLen ); - arg = cyntecGetCommandArgument(2,&argLen); advTimeout = cyntecAtoiUint16( arg, argLen ); break; - default: advInterval = APP_ADV_INTERVAL; advTimeout = APP_ADV_TIMEOUT_IN_SECONDS; @@ -320,40 +209,28 @@ // cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE); // return; // } -//#ifdef DELTA_DEBUG -//sprintf((char *)&debugMess[0],"[%d][%d]", advInterval,advTimeout); -//console.printf(debugMess); -//#endif -// service_Test(); - advertising_init(); - uint8_t error_code = advertising_start(advInterval, advTimeout); - - if (error_code==NRF_SUCCESS) { - cyntecPrintOk(); - nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); - } else if (error_code==NRF_ERROR_INVALID_STATE) { - cyntecPrintError(CYNTEC_CMD_ERR_INVALID_STATE_TO_PERFORM_OPERATION); - return; - } else { - console.printf("ERROR;\r\n"); - } +#ifdef BLE_DEBUG + console.printf("advInterval:%d,advTimeout:%d",advInterval,advTimeout); +#endif + //uint16_t uuid16_list[] = {0x0001}; + deltaBLE.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + //deltaBLE.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + deltaBLE.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + deltaBLE.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + deltaBLE.gap().setAdvertisingInterval(advInterval); /* minisecond. */ + deltaBLE.gap().setAdvertisingTimeout(advTimeout); /* second. */ + deltaBLE.gap().startAdvertising(); + cyntecPrintOk(); + nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); } /**@brief Function for stop advertising. */ static void cynAdvertiseStopCommand(void) { - uint8_t advStopErr = 0; - advStopErr = sd_ble_gap_adv_stop(); - if (advStopErr == NRF_SUCCESS) { - cyntecPrintOk(); - nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); - } else if (advStopErr==NRF_ERROR_INVALID_STATE) { - cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); - return; - } else { - console.printf("ERROR;\r\n"); - } + deltaBLE.gap().stopAdvertising(); + cyntecPrintOk(); + nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); } //gill modify 20150904 for accept blank in name @@ -399,13 +276,7 @@ // { // console.printf("%c",argName[i]); // } - //#endif - //console.printf("\r\nPrint buffer:\r\n"); - //console.printf("%s\r\n",cyntecGetCommandTotalBuffer()); - - /* Re-init application setting */ - //cyntecCLIAppInit(); } else { cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); } @@ -444,48 +315,39 @@ */ static void cynBLESetTxPowerCommand (void) { - if (cyntecGetCommandTokenCnt() == 3) { - uint32_t err_code; - uint8_t txLen=0; - uint8_t *arg = cyntecGetCommandArgument(0,&txLen); - -// uint8_t *arg = cyntecGetMinusArgument(0,&txLen); - -// cyntecGetMinusArgument(); -// const char *value = (const char *)arg; -// sprintf((char *)&debugMess[0],"\r\n[%i]\r\n",*value); -// console.printf(debugMess); - const uint8_t NUM_TXPOW = 9; - bool inputSwitch = false; // if find matched case in TxPow, assign true - - int8_t validTxPow[NUM_TXPOW] = {-40, -30, -20, -16, -12, -8, -4, 0, 4}; - uint8_t i; - int8_t setValue; - - if ( arg != NULL ) { - setValue = atoi((const char *)arg); -// sprintf((char *)&debugMess[0],"\r\n[%i]\r\n",setValue); -// console.printf(debugMess); - for (i = 0; i < NUM_TXPOW; i++) { - if (setValue == validTxPow[i]) { - err_code = sd_ble_gap_tx_power_set(setValue); - APP_ERROR_CHECK(err_code); - inputSwitch = true; - break; - } - } - - if ( inputSwitch ) - cyntecPrintOk(); - else - console.printf("\r\nWrong Input; Accept Tx Pow: -40, -30, -20, -16, -12, -8, -4, 0, 4\r\n"); - } - clearBuffer(); // clear the commandState.buffer - return; - } else { + if (cyntecGetCommandTokenCnt() != 3) { cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); return; } + uint32_t err_code; + uint8_t txLen=0; + uint8_t *arg = cyntecGetCommandArgument(0,&txLen); + const uint8_t NUM_TXPOW = 9; + bool inputSwitch = false; // if find matched case in TxPow, assign true + + int8_t validTxPow[NUM_TXPOW] = {-40, -30, -20, -16, -12, -8, -4, 0, 4}; + uint8_t i; + int8_t setValue; + + if ( arg != NULL ) { + setValue = atoi((const char *)arg); + for (i = 0; i < NUM_TXPOW; i++) { + if (setValue == validTxPow[i]) { + err_code = sd_ble_gap_tx_power_set(setValue); + APP_ERROR_CHECK(err_code); + inputSwitch = true; + break; + } + } + + if ( inputSwitch ) + cyntecPrintOk(); + else + cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE); + + } + clearBuffer(); // clear the commandState.buffer + return; } static void cynBLEAddressCommand(void) @@ -546,6 +408,92 @@ return; } +static uint32_t adv_report_parse(uint8_t type, data_t * p_advdata, data_t * p_typedata) +{ + uint32_t index = 0; + const uint8_t * p_data; + + p_data = p_advdata->p_data; + + while (index < p_advdata->data_len) { + uint8_t field_length = p_data[index]; + uint8_t field_type = p_data[index+1]; + + if (field_type == type) { + p_typedata->p_data = &p_data[index+2]; + p_typedata->data_len = field_length-1; + return NRF_SUCCESS; + } + index += field_length+1; + } + return NRF_ERROR_NOT_FOUND; +} + +void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) +{ + bool flagRepeat=false; + Gap::Address_t newAddr[6]; + memcpy(newAddr,params->peerAddr,6); + + for(int i=0; i<BLE_MAX_ADDRESS_NUMBER; i++) { + if (memcmp(newAddr,saveAddr[i],6)==0) { +#ifdef BLE_DEBUG + console.printf("Repeated\r\n"); +#endif + flagRepeat = true; + //return; + } + } + +#ifdef BLE_DEBUG + console.printf("addr cmp result :%i\r\n",memcmp(newAddr,params->peerAddr,6)); + console.printf("ADV data:%X,%i\r\n",&(params->advertisingData),params->advertisingDataLen); +#endif + data_t adv_data; + data_t type_data; + //Initialize advertisement report for parsing. + adv_data.p_data = params->advertisingData; + adv_data.data_len = params->advertisingDataLen; + // Parsing Device Name + uint32_t err_code = adv_report_parse(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, + &adv_data, + &type_data); +#ifdef BLE_DEBUG + console.printf("error code:%X\r\n",err_code); + console.printf("type_data.data_len:%i\r\n",type_data.data_len); +#endif + if (flagRepeat == false) { + if (err_code == 0) { + for (int i=0; i<type_data.data_len; i++) { + console.printf("%c",type_data.p_data[i]); + } + //console.printf("\r\n"); + } + console.printf(",ADV,[%02X %02X %02X %02X %02X %02X],%d,%u\r\n",params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], + params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],params->rssi,params->type); + memcpy(saveAddr[bleDevInd],params->peerAddr,6); + bleDevInd++; + } + + /* + Check short name, not implemented + */ + //else +// { +// uint32_t err_code_2 = adv_report_parse(BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME, +// &adv_data, +// &type_data); +// console.printf("error code:%X\r\n",err_code_2); +// console.printf("%i\r\n",type_data.data_len); +// console.printf("%s\r\n",type_data.p_data); +// +// } + if (conn_action == true) { + conn_action = false; + deltaBLE.gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); + } +} + /**@brief Function to start scanning. */ @@ -564,41 +512,53 @@ // gill 20150916 modify static void cynBLEScanCommand(void) { - uint8_t argLen = 0; - uint8_t *arg = cyntecGetCommandArgument(0,&argLen); uint16_t setInterval = DEFAULT_SCAN_INTERVAL; uint16_t setWindow = DEFAULT_SCAN_WINDOW; uint16_t setTimeout = DEFAULT_SCAN_TIMEOUT; - setInterval = cyntecAtoiUint16( arg, argLen ); - arg = cyntecGetCommandArgument(1,&argLen); - setWindow = cyntecAtoiUint16( arg, argLen ); - arg = cyntecGetCommandArgument(2,&argLen); - setTimeout = cyntecAtoiUint16( arg, argLen ); -#ifdef DELTA_DEBUG - console.printf("%i\r\n",setTimeout); + if (cyntecGetCommandTokenCnt()!= 2 & cyntecGetCommandTokenCnt()!= 5) { + cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + + if (cyntecGetCommandTokenCnt()== 5) { + uint8_t argLen = 0; + uint8_t *arg = cyntecGetCommandArgument(0,&argLen); + setInterval = cyntecAtoiUint16( arg, argLen ); + arg = cyntecGetCommandArgument(1,&argLen); + setWindow = cyntecAtoiUint16( arg, argLen ); + arg = cyntecGetCommandArgument(2,&argLen); + setTimeout = cyntecAtoiUint16( arg, argLen ); + } +#ifdef BLE_DEBUG + console.printf("Interval:%d,Window:%d,timeout:%d\r\n",setInterval,setWindow,setTimeout); #endif - memset(saveAddr,0,sizeof(saveAddr)); // Clear saving address set - - deltaBLE.gap().setScanParams(setInterval,setWindow,setTimeout,1); - console.printf("Start Scanning\r\n"); + memset(saveAddr,0,sizeof(saveAddr)); // Clear saving address set + //deltaBLE.gap().setScanParams(setInterval,setWindow,setTimeout,false); + deltaBLE.gap().setScanInterval(setInterval); + deltaBLE.gap().setScanWindow(setWindow); + deltaBLE.gap().setScanTimeout(setTimeout); + console.printf("Start Scanning\r\n"); scan_start(); - + } static void cynBLEScanStopCommand(void) { - console.printf("\r\nStop Scanning"); + console.printf("\r\nStop Scanning\r\n"); scan_stop(); } -//static void cynBLEConnectCommand(void) -//{ -// if (cyntecGetCommandTokenCnt() == 3) -// { -// uint8_t devNameLen = 0; -// uint8_t *argDevName = cyntecGetCommandArgument(0, &devNameLen); -// uint8_t *targetDevName[devNameLen]; -// if ( argDevName != NULL ) { +static void cynBLEConnectCommand(void) +{ + if (cyntecGetCommandTokenCnt() != 3) { + cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); + return; + } + + uint8_t devNameLen = 0; + uint8_t *argDevName = cyntecGetCommandArgument(0, &devNameLen); + + //if ( argDevName != NULL ) { // uint8_t i; // for (i = 0; i < devNameLen; i++) { // targetDevName[i] = argDevName[i]; @@ -606,38 +566,29 @@ // if (i < devNameLen) // targetDevName[i] = '\0'; // } -//#ifdef DELTA_DEBUG -// console.printf("\r\nSearch for device name:"); -// console.printf(argDevName); -//#endif -// scan_start(); -// } else { -// console.printf("\r\nUsage: cynb connect <Device Name>"); -// console.printf("\r\n(Ex:cynb connect CYN_DEVICE"); -// } -//} + + memset( targetDevName , 0, TARGET_DEVNAME_LEN); + memcpy( targetDevName, argDevName, devNameLen); +#ifdef BLE_DEBUG + console.printf("Search for device name:%s\r\n",argDevName); + console.printf("Target:%s\r\n",targetDevName); +#endif + conn_action = true; + scan_start(); + +} static void cynBLEDisconnectCommand(void) { - uint32_t err_code; - - //marcus need to modify - err_code = sd_ble_gap_disconnect(test_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); - - - - err_code = sd_ble_gap_connect_cancel(); // No function defined currently - - if (err_code == NRF_SUCCESS) { - - cyntecPrintOk(); -// APP_ERROR_CHECK(err_code); - } else if (err_code ==NRF_ERROR_INVALID_STATE) { - cyntecPrintError(CYNTEC_CMD_ERR_INVALID_STATE_TO_PERFORM_OPERATION); - } else { - console.printf("ERROR;\r\n"); - } + ble_error_t err_code; + err_code = deltaBLE.gap().disconnect(Gap::REMOTE_USER_TERMINATED_CONNECTION); + //err_code = sd_ble_gap_disconnect(test_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + //err_code = sd_ble_gap_connect_cancel(); // No function defined currently +#ifdef BLE_DEBUG + console.printf("Error:%d\r\n",err_code); +#endif + cyntecPrintOk(); } uint8_t isValidGPIO(uint8_t num) @@ -719,581 +670,405 @@ NVIC_SystemReset(); } -// gill modify for update value in non-connect state 20150904 -// Change set value connection handle +void triggerRead(const GattReadCallbackParams *response) +{ + //if (response->handle == ledCharacteristic.getValueHandle()) { +#if DUMP_READ_DATA + printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len); + for (unsigned index = 0; index < response->len; index++) { + printf("%c[%02x]", response->data[index], response->data[index]); + } + printf("\r\n"); +#endif +// +// uint8_t toggledValue = response->data[0] ^ 0x1; +// ledCharacteristic.write(1, &toggledValue); +// } +} static void cynBLEUpdateUUIDCommand(void) { - uint8_t i,j; - uint8_t value[MAX_VALUE_LENGTH]; - memset(value, 0, sizeof(value)); -// uint8_t buf_char_uuid_type; - ble_uuid_t buf_service_uuid; - ble_uuid_t buf_char_uuid; - uint8_t argLen = 0; - uint8_t *arg; - uint8_t valueLengthBuffer = 0; - uint8_t modeType; - bool updatematchFlag = false; // Check matched characteristic found - uint16_t len = MAX_VALUE_LENGTH; - uint32_t err_code; - // check if argument count is right if (cyntecGetCommandTokenCnt() != 5) { cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); return; - } else { - arg = cyntecGetCommandArgument(0,&argLen); - if (arg[0] != '0' | arg[1] != 'x' | argLen%2 != 0) { - cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); - return; - } else { - // Handle input parameter - Service UUID - arg = cyntecGetCommandArgument(0,&argLen); - - if (argLen == 6 && arg[0] == '0' && arg[1] == 'x') { - buf_service_uuid.uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); - buf_service_uuid.type = BLE_UUID_TYPE_BLE; - } - if (argLen == 34 && arg[0] == '0' && arg[1] == 'x') { - buf_service_uuid.uuid = cyntecArgToUint16( (arg + 6), 4); - buf_service_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; - } - - // Handle input parameter - Characteristic UUID - argLen = 0; - arg = cyntecGetCommandArgument(1,&argLen); + } + UUID buf_ser_uuid ; + uint8_t bufferUuidVs[16]; + UUID buf_char_uuid; + uint8_t bufVal[MAX_VALUE_LENGTH] = {0}; + uint16_t valueLen = 0; + bool readmatchFlag = false; + uint8_t argLen = 0; + uint8_t *arg = cyntecGetCommandArgument(0,&argLen); - if (argLen == 6 && arg[0] == '0' && arg[1] == 'x') { - buf_char_uuid.uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); - buf_char_uuid.type = BLE_UUID_TYPE_BLE; - } - if (argLen == 34 && arg[0] == '0' && arg[1] == 'x') { - buf_char_uuid.uuid = cyntecArgToUint16( (arg + 6), 4); - buf_char_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; - } -// sprintf((char *)&debugMess[0],"buf_service_uuid[%d,%4X]\r\n",buf_service_uuid.type,buf_service_uuid.uuid); -// console.printf(debugMess); - - // Handle input parameter - value - arg = cyntecGetCommandArgument(2,&argLen); - valueLengthBuffer = (argLen-2)/2; - for (i=0 ; i < (argLen-2)/2; i++) { - value[i] = cyntecArgToUint8(arg+2*(i+1), 2); - // debug - // sprintf((char *)&buf[0],"[%2X]",value[i]); - // console.printf(buf); - } - + // Handle input parameter - Service UUID + if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { + buf_ser_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); + } + if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { + for (uint8_t i=0; i<16; i++) { + bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); } - // debug message -// sprintf((char *)&buf[0],"value:[%02X]", value); -// console.printf(buf); + buf_ser_uuid.setupLong(bufferUuidVs); + } - for ( i = 0 ; i < CLI_SERVICE_MAX_NUM ; i++ ) { - if ( (bufferService[i].service_uuid.uuid == buf_service_uuid.uuid) &(bufferService[i].service_uuid.type == buf_service_uuid.type)& (updatematchFlag == false)) { - //readmatchFlag = true; - for ( j = 0 ; j < CLI_CHAR_MAX_NUM ; j++ ) { - if ( (bufferService[i].bufferGattChar[j].char_uuid.uuid == buf_char_uuid.uuid) &(bufferService[i].bufferGattChar[j].char_uuid.type == buf_char_uuid.type)& (updatematchFlag == false)) { - modeType = bufferService[i].bufferGattChar[j].mode; - //memset(bufferService[i].bufferGattChar[j].value, 0, sizeof(bufferService[i].bufferGattChar[j].value)); - // Identify characteristic property is notify or indicate - if (((modeType & (1 << CLI_CHAR_MODE_INDICATE)) | (modeType & (1 << CLI_CHAR_MODE_NOTIFY))) ) { - if (bufferService[i].bufferGattChar[j].mode & (1 << CLI_CHAR_MODE_INDICATE)) - modeType = BLE_GATT_HVX_INDICATION ; - if (bufferService[i].bufferGattChar[j].mode & (1 << CLI_CHAR_MODE_NOTIFY)) - modeType = BLE_GATT_HVX_NOTIFICATION; - ble_gatts_hvx_params_t hvx_params; - memset(&hvx_params, 0, sizeof(hvx_params)); - hvx_params.handle = bufferService[i].bufferGattChar[j].char_value_handle; - hvx_params.type = modeType; - hvx_params.offset = 0; - hvx_params.p_len = &len; - hvx_params.p_data = value; - if (connState) { // If connected, send notification/indication - err_code = sd_ble_gatts_hvx(test_conn_handle, &hvx_params); + // Handle input parameter - Characteristic UUID + argLen = 0; + arg = cyntecGetCommandArgument(1,&argLen); + if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { + buf_char_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); + } + if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { + for (uint8_t i=0; i<16; i++) { + bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); + } + buf_char_uuid.setupLong(bufferUuidVs); + } - if (err_code == NRF_SUCCESS) { - //do nothing - } else if ((err_code != NRF_SUCCESS) && - (err_code != NRF_ERROR_INVALID_STATE) && - (err_code != BLE_ERROR_NO_TX_BUFFERS) && - (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) - ) { - console.printf("HVX ERROR;%04X\r\n",err_code); - } - } - - } - - // Update database - bufferService[i].bufferGattChar[j].valueLength = valueLengthBuffer; - ble_gatts_value_t bufGattsValue; - memset(&bufGattsValue, 0, sizeof(bufGattsValue)); - bufGattsValue.len = len; - bufGattsValue.offset = 0; - bufGattsValue.p_value = value; - //err_code = sd_ble_gatts_value_set(bufferService[i].bufferGattChar[j].char_value_handle, -// 0, -// &len, -// value); - err_code = sd_ble_gatts_value_set( - //test_conn_handle, - BLE_CONN_HANDLE_INVALID, // User can update in non-connected state - bufferService[i].bufferGattChar[j].char_value_handle, - &bufGattsValue - ); - - if (err_code == NRF_SUCCESS) { - cyntecPrintOk(); - } else { - console.printf("Set ERROR;%04X\r\n",err_code); - } - updatematchFlag = true; - return; - } + // Input value + arg = cyntecGetCommandArgument(2,&argLen); + valueLen = (argLen-2)/2; // uint8_t to uint16_t transform + for (int i=0 ; i < (argLen-2)/2; i++) { + bufVal[i] = cyntecArgToUint8(arg+2*(i+1), 2); + } + for (uint16_t n=0; n<valueLen; n++) { + console.printf("%02X",bufVal[n]); + } + for ( int i = 0 ; i < service_count ; i++ ) { + if ( (bufferService[i].ser_uuid == buf_ser_uuid) & (readmatchFlag == false)) { + for (int j = 0 ; j < CLI_CHAR_MAX_NUM ; j++ ) { + if (( bufferService[i].bufferGattChar[j].char_uuid == buf_char_uuid)& (readmatchFlag == false)) { + GattAttribute& valueAttr = charAry[i][j]->getValueAttribute(); + ble_error_t err; + if (!connState) + err = deltaBLE.gattServer().write(valueAttr.getHandle(),bufVal,valueLen,true); + else + err = deltaBLE.gattServer().write(test_conn_handle,valueAttr.getHandle(),bufVal,valueLen,false); + //wait(5); //NO USE +#ifdef BLE_DEBUG + console.printf("Write ERR:%i\r\n",err); +#endif + console.printf("\r\n"); + readmatchFlag = true; + return; } } } - if (updatematchFlag == false) { - cyntecPrintError(CYNTEC_CMD_ERR_NO_MATCHED_ARGUMENT); - } + } + // no matched case, can not read + if (readmatchFlag == false) { + cyntecPrintError(CYNTEC_CMD_ERR_NO_MATCHED_ARGUMENT); } } static void cynBLEReadDataCommand(void) { - +#ifdef BLE_DEBUG + printf("Saved Char:\r\n"); + for (int i=0; i<service_count; i++) { + console.printf("ser_uuid:%04X",bufferService[service_count-1].ser_uuid.getShortUUID()); + for (int j=0; j<CLI_CHAR_MAX_NUM; j++) { + printf("%i,U%04X,",j,bufferService[service_count-1].bufferGattChar[char_count-1].char_uuid.getShortUUID()); + printf("L%d,",bufferService[service_count-1].bufferGattChar[char_count-1].valueLength); + printf("V%02X ",bufferService[service_count-1].bufferGattChar[char_count-1].value[0]); + } + } + printf("\r\n"); +#endif if (cyntecGetCommandTokenCnt() != 4) { cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); - } else { - //uint16_t buf_char_uuid ; - uint8_t i,j; - uint8_t value[MAX_VALUE_LENGTH]; - //uint8_t buf[20]; -// uint8_t buf_char_uuid_type; - ble_uuid_t buf_service_uuid; - ble_uuid_t buf_char_uuid; - uint8_t valueLengthBuffer; - bool readmatchFlag = false; - // debug message -// sprintf((char *)&debugMess[0],"buf_char_uuid:[%04X]", buf_char_uuid); -// console.printf(debugMess); - uint8_t argLen = 0; - uint8_t *arg = cyntecGetCommandArgument(0,&argLen); + return; + } + UUID buf_ser_uuid ; + uint8_t bufferUuidVs[16]; + UUID buf_char_uuid; + uint8_t bufVal[MAX_VALUE_LENGTH] = {0}; + uint16_t valueLen=0; + uint16_t * valueLenPtr; + bool readmatchFlag = false; + uint8_t argLen = 0; + uint8_t *arg = cyntecGetCommandArgument(0,&argLen); - // Print out the service & char uuids table -// for ( i = 0 ; i < CLI_SERVICE_MAX_NUM ; i++ ) -// { -// for ( j = 0 ; j < CLI_SERVICE_MAX_NUM ; j++ ) -// { -// sprintf((char *)&debugMess[0],"[%4X,%d][%4X,%d]\r\n",bufferService[i].service_uuid.uuid,bufferService[i].service_uuid.type,bufferService[i].bufferGattChar[j].char_uuid.uuid,bufferService[i].bufferGattChar[j].char_uuid.type); -// console.printf(debugMess); -// } -// } - - // Handle input parameter - Service UUID - if (argLen == 6 && arg[0] == '0' && arg[1] == 'x') { - buf_service_uuid.uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); - buf_service_uuid.type = BLE_UUID_TYPE_BLE; + // Handle input parameter - Service UUID + if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { + buf_ser_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); + } + if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { + for (uint8_t i=0; i<16; i++) { + bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); } - if (argLen == 34 && arg[0] == '0' && arg[1] == 'x') { - buf_service_uuid.uuid = cyntecArgToUint16( (arg + 6), 4); - buf_service_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; - } + buf_ser_uuid.setupLong(bufferUuidVs); + } - // Handle input parameter - Characteristic UUID - argLen = 0; - arg = cyntecGetCommandArgument(1,&argLen); - if (argLen == 6 && arg[0] == '0' && arg[1] == 'x') { - buf_char_uuid.uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); - buf_char_uuid.type = BLE_UUID_TYPE_BLE; - } - if (argLen == 34 && arg[0] == '0' && arg[1] == 'x') { - buf_char_uuid.uuid = cyntecArgToUint16( (arg + 6), 4); - buf_char_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; + // Handle input parameter - Characteristic UUID + argLen = 0; + arg = cyntecGetCommandArgument(1,&argLen); + if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { + buf_char_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); + } + if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { + for (uint8_t i=0; i<16; i++) { + bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); } -// sprintf((char *)&debugMess[0],"buf_service_uuid[%d,%4X]\r\n",buf_service_uuid.type,buf_service_uuid.uuid); -// console.printf(debugMess); - for ( i = 0 ; i < CLI_SERVICE_MAX_NUM ; i++ ) { - if ( (bufferService[i].service_uuid.uuid == buf_service_uuid.uuid) &(bufferService[i].service_uuid.type == buf_service_uuid.type)& (readmatchFlag == false)) { - //readmatchFlag = true; - for ( j = 0 ; j < CLI_CHAR_MAX_NUM ; j++ ) { - if ( (bufferService[i].bufferGattChar[j].char_uuid.uuid == buf_char_uuid.uuid) &(bufferService[i].bufferGattChar[j].char_uuid.type == buf_char_uuid.type)& (readmatchFlag == false)) { - // uint8_t value[] = "88"; - uint16_t len = MAX_VALUE_LENGTH; - ble_gatts_value_t bufGattsValue; - memset(&bufGattsValue, 0, sizeof(bufGattsValue)); - bufGattsValue.len = len; - bufGattsValue.offset = 0; - bufGattsValue.p_value = value; - //sd_ble_gatts_value_get(bufferService[i].bufferGattChar[j].char_value_handle, -// 0, -// &len, -// value); - sd_ble_gatts_value_get( test_conn_handle, - bufferService[i].bufferGattChar[j].char_value_handle, - &bufGattsValue - ); - console.printf("\r\nOK;0x"); - valueLengthBuffer = bufferService[i].bufferGattChar[j].valueLength; - // sprintf((char *)&debugMess[0],"[%i]",valueLengthBuffer); - // console.printf(debugMess); - - for (i=0 ; i < valueLengthBuffer; i++) { - console.printf("%02X",value[i]); - } - console.printf(";\r\n"); - readmatchFlag = true; - return; + buf_char_uuid.setupLong(bufferUuidVs); + } + + for ( int i = 0 ; i < service_count ; i++ ) { + if ( (bufferService[i].ser_uuid == buf_ser_uuid) & (readmatchFlag == false)) { + for (int j = 0 ; j < CLI_CHAR_MAX_NUM ; j++ ) { + if (( bufferService[i].bufferGattChar[j].char_uuid == buf_char_uuid)& (readmatchFlag == false)) { + GattAttribute& valueAttr = charAry[i][j]->getValueAttribute(); + valueLenPtr = valueAttr.getLengthPtr(); + valueLen = valueAttr.getLength(); + ble_error_t err = deltaBLE.gattServer().read(valueAttr.getHandle(),bufVal,valueLenPtr); +#ifdef BLE_DEBUG + console.printf("Read ERR:%i\r\n",err); +#endif + console.printf("0x"); + for (uint16_t n=0; n<valueLen; n++) { + console.printf("%02X",bufVal[n]); } + console.printf("\r\n"); + readmatchFlag = true; + return; } } } - // no matched case, can not read - if (readmatchFlag == false) { - cyntecPrintError(CYNTEC_CMD_ERR_NO_MATCHED_ARGUMENT); - } + } - - -} -/* Set characteristics */ -static void cyntecInsertCharUUID(ble_uuid_t char_UUID, uint16_t charValueHandle,uint8_t valueLengthBuffer,uint8_t mode) -{ - uint8_t j; - j=char_count; -// sprintf((char *)&debugMess[0],"char_uuid:%4X\r\n",char_UUID.uuid); -// console.printf(debugMess); - bufferService[service_count-1].bufferGattChar[j].char_uuid.uuid = char_UUID.uuid; - bufferService[service_count-1].bufferGattChar[j].char_uuid.type = char_UUID.type; - bufferService[service_count-1].bufferGattChar[j].valueLength = valueLengthBuffer; - bufferService[service_count-1].bufferGattChar[j].mode = mode; - bufferService[service_count-1].bufferGattChar[j].char_value_handle = charValueHandle; - return; + // no matched case, can not read + if (readmatchFlag == false) { + cyntecPrintError(CYNTEC_CMD_ERR_NO_MATCHED_ARGUMENT); + } } static void cynGattCharCommand(void) { -// uint16_t service_uuid_ble; -// uint8_t service_uuid_vs[16]; - - uint8_t attrMode=0; - uint8_t attrValue[MAX_VALUE_LENGTH]; - memset(&attrValue, 0, sizeof(attrValue)); - - uint8_t i; -// uint8_t valueBuffer; - uint8_t err_code; - uint16_t buffer_char_uuid; -// uint16_t buffer_char_uuid_ble; - uint16_t buffer_uuid_vs[8]; - ble_uuid_t char_uuid; - ble_uuid128_t char_uuid_vs; - - ble_gatts_char_md_t char_md; - ble_gatts_attr_t attr_char_value; - - ble_gatts_attr_md_t cccd_md; - ble_gatts_attr_md_t attr_md; -// uint8_t init_value_encoded[2] = "77"; -// uint8_t init_value_len; - uint8_t valueLengthBuffer; - extern uint8_t char_count; + uint8_t i; + uint8_t valueLengthBuffer; if (cyntecGetCommandTokenCnt() != 5) { cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); return; - } else { - -//#ifdef DELTA_DEBUG -//sprintf((char *)&debugMess[0],"[%04X]", service_uuid); -//console.printf(debugMess); -//#endif - - /* handle second parameter - UUID */ - uint8_t argLen = 0; - uint8_t *arg = cyntecGetCommandArgument(0,&argLen); - - /* len: 6 => 0xXXXX */ - if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { - buffer_char_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); - BLE_UUID_BLE_ASSIGN(char_uuid, buffer_char_uuid); - char_uuid.type = BLE_UUID_TYPE_BLE; - } - - if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { - for ( i=0; i<8; i++) { - buffer_uuid_vs[7-i] = cyntecArgToUint16( (arg + 2+4*i), 4); - if (i==1) { - char_uuid.uuid = cyntecArgToUint16( (arg + 2+4*i), 4); - } -//#ifdef DELTA_DEBUG -// sprintf((char *)&debugMess[0],"%2X/",buffer_uuid_vs[7-i]); -// console.printf(debugMess); -//#endif - } - memcpy(&char_uuid_vs,buffer_uuid_vs,16); - err_code = sd_ble_uuid_vs_add(&char_uuid_vs, &char_uuid.type); + } + + /* handle parameter - UUID */ + /* Only support 16-bit or 128-bit UUID type */ + uint8_t argLen = 0; + uint8_t *arg = cyntecGetCommandArgument(0,&argLen); + if (arg[0] != '0' || arg[1] != 'x' || (argLen != 6 && argLen != 34)) { + cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); + return; + } + /* len: 6 => 0xXXXX */ + if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { + UUID::ShortUUIDBytes_t buffer_uuid_short; + buffer_uuid_short = cyntecArgToUint16( (arg + 2), (argLen - 2)); + UUID uuid_short(buffer_uuid_short); + bufferService[service_count-1].bufferGattChar[char_count].char_uuid = uuid_short; + } + if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { + // Initialize LongUUIDBytes_t, then use default constructor to setupLong(longUUID) + UUID::LongUUIDBytes_t buffer_uuid_vs; + for (uint8_t i=0; i<16; i++) { + buffer_uuid_vs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); } -//#ifdef DELTA_DEBUG -// sprintf((char *)&debugMess[0],"char_uuid_type:[%d]\r\n",char_uuid.type); -// console.printf(debugMess); -//#endif - - -//#ifdef DELTA_DEBUG -// sprintf((char *)&debugMess[0],"vs_add_Error:%d\r\n",err_code); -// console.printf(debugMess); -//#endif - - /* handle 3rd parameter - attribute mode */ - argLen = 0; - arg = cyntecGetCommandArgument(1,&argLen); - - for ( i = 0 ; i < argLen ; i++ ) { - switch(arg[i]) { - case 'r': - attrMode |= (1 << CLI_CHAR_MODE_READ); - break; - case 'w': - attrMode |= (1 << CLI_CHAR_MODE_WRITE); - break; - case 'i': - attrMode |= (1 << CLI_CHAR_MODE_INDICATE); - break; - case 'n': - attrMode |= (1 << CLI_CHAR_MODE_NOTIFY); - break; - default: - break; - } - } - - /* handle 4th parameter - attribute value */ - argLen = 0; - arg = cyntecGetCommandArgument(2,&argLen); - - if (arg[0] != '0' || arg[1] != 'x' | argLen%2 != 0) { - cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); - return; - } else { - valueLengthBuffer = (argLen-2)/2; - for (i=0 ; i < (argLen-2)/2; i++) { - attrValue[i] = cyntecArgToUint8(arg+2*(i+1), 2); - - } - //cyntecInsertCharUUID(service_uuid, char_uuid, attrMode, attrValue,valueLengthBuffer); - //cyntecPrintOk(); - } + bufferService[service_count-1].bufferGattChar[char_count].char_uuid.setupLong(buffer_uuid_vs); } - - //debug -// sprintf((char *)&debugMess[0],"value:[%02X][%02X]", value[0],value[1]); -// console.printf(debugMess); - - //write read permission - ble_gap_conn_sec_mode_t local_all_perm; - local_all_perm.lv = 1; - local_all_perm.sm = 1; - - memset(&cccd_md, 0, sizeof(cccd_md)); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); - cccd_md.write_perm = local_all_perm; - cccd_md.vloc = BLE_GATTS_VLOC_STACK; - - memset(&char_md, 0, sizeof(char_md)); - - if ( attrMode & (1 << CLI_CHAR_MODE_READ)) - char_md.char_props.read = 1; - if (attrMode & (1 << CLI_CHAR_MODE_WRITE)) - char_md.char_props.write = 1; - if (attrMode & (1 << CLI_CHAR_MODE_NOTIFY)) - char_md.char_props.notify = 1; - if (attrMode & (1 << CLI_CHAR_MODE_INDICATE)) - char_md.char_props.indicate = 1; - - char_md.p_char_user_desc = NULL; - char_md.p_char_pf = NULL; - char_md.p_user_desc_md = NULL; - char_md.p_cccd_md = &cccd_md; - char_md.p_sccd_md = NULL; - - memset(&attr_md, 0, sizeof(attr_md)); + /* handle 3rd parameter - attribute mode */ + argLen = 0; + arg = cyntecGetCommandArgument(1,&argLen); + if (arg[0] != '0' || arg[1] != 'x' ) { + cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); + return; + } + uint32_t prop = cyntecHexToUint32(arg+2,argLen-2); - attr_md.vloc = BLE_GATTS_VLOC_STACK; - attr_md.read_perm = local_all_perm; - attr_md.write_perm = local_all_perm; - attr_md.rd_auth = 0; - attr_md.wr_auth = 0; - attr_md.vlen = 0; - - memset(&attr_char_value, 0, sizeof(attr_char_value)); - -// init_value_len = MAX_VALUE_LENGTH; - - attr_char_value.p_uuid = &char_uuid; - attr_char_value.p_attr_md = &attr_md; - attr_char_value.init_len = MAX_VALUE_LENGTH; - attr_char_value.init_offs = 0; - attr_char_value.max_len = MAX_VALUE_LENGTH; - attr_char_value.p_value = attrValue; - //debug -// sprintf((char *)&debugMess[0],"value:[%s]", attr_char_value.p_value); -// console.printf(debugMess); - ble_gatts_char_handles_t testHandle; - err_code = sd_ble_gatts_characteristic_add(bufferGattTest.service_handle, - &char_md, - &attr_char_value, - &testHandle); -//#ifdef DELTA_DEBUG -// sprintf((char *)&debugMess[0],"char_uuid:%4X\r\n",char_uuid.uuid); -// console.printf(debugMess); -//#endif - if (err_code == NRF_SUCCESS) { - cyntecPrintOk(); - cyntecInsertCharUUID(char_uuid, testHandle.value_handle,valueLengthBuffer,attrMode); -// sprintf((char *)&debugMess[0],"char_count:%d\r\n",char_count); -// console.printf(debugMess); - char_count++; - if (char_count>10) - char_count=0; - } else if (err_code == NRF_ERROR_INVALID_STATE) { - cyntecPrintError(CYNTEC_CMD_ERR_INVALID_STATE_TO_PERFORM_OPERATION); + /* handle 4th parameter - attribute value */ + argLen = 0; + arg = cyntecGetCommandArgument(2,&argLen); + if (arg[0] != '0' || arg[1] != 'x' | argLen%2 != 0) { + cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); return; - } else { - console.printf("ERROR;\r\n"); + } + valueLengthBuffer = (argLen-2)/2; + memset(bufferService[service_count-1].bufferGattChar[char_count].value,0,MAX_VALUE_LENGTH); + for (i=0 ; i < (argLen-2)/2; i++) { + bufferService[service_count-1].bufferGattChar[char_count].value[i] = cyntecArgToUint8(arg+2*(i+1), 2); + //console.printf("%02X ",bufferService[service_count-1].bufferGattChar[char_count].value[i]); } - +#ifdef BLE_DEBUG + console.printf("valueLengthBuffer:%d\r\n",valueLengthBuffer); + console.printf("value:"); + for (i=0 ; i < valueLengthBuffer; i++) { + console.printf("%02X",bufferService[service_count-1].bufferGattChar[char_count].value[i]); + } +#endif + bufferService[service_count-1].bufferGattChar[char_count].valueLength = valueLengthBuffer; + bufferService[service_count-1].bufferGattChar[char_count].props = prop; + //bufferService[service_count-1].bufferGattChar[char_count].char_value_handle = testHandle; + if (char_count>CLI_CHAR_MAX_NUM) { + cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL); + return; + } + cyntecPrintOk(); + char_count++; } -static void cyntecInsertServiceUUID(ble_uuid_t service_UUID) +static void cynRegServiceCommand(void) { - /* find if the service uuid is exist */ - bufferService[service_count].service_uuid.uuid = service_UUID.uuid; - bufferService[service_count].service_uuid.type = service_UUID.type; - return; - + //GattCharacteristic *charAry[char_count]; + //GattCharacteristic **charAry; + //charAry = new GattCharacteristic *[char_count]; +#ifdef BLE_DEBUG + console.printf("Current char_count:%d\r\n",char_count); + console.printf("Current service_count:%d\r\n",service_count); +#endif + for (uint8_t i=0; i<char_count; i++) { + charAry[service_count-1][i] = new GattCharacteristic ( + bufferService[service_count-1].bufferGattChar[i].char_uuid, + bufferService[service_count-1].bufferGattChar[i].value, + bufferService[service_count-1].bufferGattChar[i].valueLength, + MAX_VALUE_LENGTH, + bufferService[service_count-1].bufferGattChar[i].props + ); + } + GattService newService(bufferService[service_count-1].ser_uuid, charAry[service_count-1], char_count ); + ble_error_t err_code; + err_code = deltaBLE.addService(newService); +#ifdef BLE_DEBUG + console.printf("addService error:%d\r\n",err_code); +#endif + cyntecPrintOk(); + //char_count = 0; // already did in gattService } static void cynGattServiceCommand(void) { -// uint16_t service_uuid; -// uint8_t attrValue[MAX_VALUE_LENGTH]; -// memset(&attrValue, 0, sizeof(attrValue)); -// uint8_t i; -// uint8_t valueBuffer; - extern uint8_t service_count; - - uint32_t err_code; - ble_uuid_t ble_uuid; - ble_uuid128_t ble_uuid128; - uint16_t buffer_uuid; - uint16_t buffer_uuid_vs[8]; - int i; - if (cyntecGetCommandTokenCnt() != 3) { cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); return; - } else { - /* handle first parameter - Service UUID */ - uint8_t argLen = 0; - uint8_t *arg = cyntecGetCommandArgument(0,&argLen); - - /* Service uuid is 16 bits */ - if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { - buffer_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); - //ble_uuid.type = BLE_UUID_TYPE_BLE; //type assign in BLE_UUID_BLE_ASSIGN - BLE_UUID_BLE_ASSIGN(ble_uuid, buffer_uuid); - - err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &bufferGattTest.service_handle); - ble_uuid.type = BLE_UUID_TYPE_BLE; + } + /* handle first parameter - Service UUID */ + uint8_t argLen = 0; + uint8_t *arg = cyntecGetCommandArgument(0,&argLen); - } - - /* Service uuid is 128 bits */ - if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { -// uint8_t uuid_type = custom_add_uuid_base(CFG_CUSTOM_UUID_BASE); - //ASSERT(uuid_type > 0, ERROR_NOT_FOUND); - for ( i=0; i<8; i++) { - buffer_uuid_vs[7-i] = cyntecArgToUint16( (arg + 2+4*i), 4); - if (i==1) { - ble_uuid.uuid = cyntecArgToUint16( (arg + 2+4*i), 4); - } -#ifdef DELTA_DEBUG - console.printf("%2X/",buffer_uuid_vs[7-i]); + /* Service uuid is 16 bits */ + if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { + UUID::ShortUUIDBytes_t buffer_uuid_short; + buffer_uuid_short = cyntecArgToUint16( (arg + 2), (argLen - 2)); +#ifdef BLE_DEBUG + console.printf("%4X",buffer_uuid_short); #endif - } - memcpy(&ble_uuid128.uuid128,buffer_uuid_vs,16); -//#ifdef DELTA_DEBUG -// sprintf((char *)&debugMess[0],"%32X\r\n",ble_uuid128.uuid128); -// console.printf(debugMess); -//#endif - err_code = sd_ble_uuid_vs_add(&ble_uuid128, &ble_uuid.type); -//#ifdef DELTA_DEBUG -// sprintf((char *)&debugMess[0],"service_uuid_type:%d\r\n",ble_uuid.type); -// console.printf(debugMess); -//#endif - - err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &bufferGattTest.service_handle); + UUID uuid_short(buffer_uuid_short); + bufferService[service_count].ser_uuid = uuid_short; + //buffer_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); + } - ble_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; - + /* Service uuid is 128 bits */ + if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { + // Initialize LongUUIDBytes_t, then use default constructor to setupLong(longUUID) + UUID::LongUUIDBytes_t buffer_uuid_vs; + for (uint8_t i=0; i<16; i++) { + buffer_uuid_vs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); +#ifdef BLE_DEBUG + console.printf("%2X ",buffer_uuid_vs[i]); +#endif } - if (err_code == NRF_SUCCESS) { - cyntecPrintOk(); - cyntecInsertServiceUUID(ble_uuid); - service_count++; - char_count = 0; -// sprintf((char *)&debugMess[0],"service_count:%d\r\n",service_count); -// console.printf(debugMess); - } else { - console.printf("ERROR;\r\n"); - - } - + UUID uuid_long(buffer_uuid_vs); + bufferService[service_count].ser_uuid = uuid_long; } + cyntecPrintOk(); + service_count++; + char_count = 0; } static void cynBLEInitCommand(void) { - const char DEVICE_NAME[] = "DELTA_CLI"; - deltaBLE.init(); deltaBLE.onDisconnection(disconnectionCallback); deltaBLE.onConnection(onConnectionCallback); deltaBLE.onTimeout(onTimeoutCallback); - - /* Setup advertising. */ - deltaBLE.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); - deltaBLE.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); - deltaBLE.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - deltaBLE.setAdvertisingInterval(1000); - + deltaBLE.gattClient().onDataRead(triggerRead); cyntecPrintOk(); } + +static void cynBLETestCommand(void) +{ + // gill test 1021 + uint8_t bufVal[20] = {0}; + uint8_t valWrite[2] = {0x22,0x33}; + //uint16_t bufhandle = 0x0001; + uint8_t valRead[2] = {0,0}; + +// uint16_t handle = charAry[0][0]->getValueHandle(); +// console.printf("Handle:%04X\r\n",handle); + GattAttribute& valueAttr = charAry[0][0]->getValueAttribute(); + //valueAttr.setHandle(bufhandle); + console.printf("Handle:%04X ",valueAttr.getHandle()); + console.printf("UUID:%04X ",valueAttr.getUUID().getShortUUID()); + + uint16_t* valueLenPtr = valueAttr.getLengthPtr(); + console.printf("gatt val:%02X %02X\r\n",bufVal[0],bufVal[1]); + deltaBLE.gattServer().read(valueAttr.getHandle(),bufVal,valueLenPtr); + console.printf("gatt val:%02X %02X\r\n",bufVal[0],bufVal[1]); + + deltaBLE.gattServer().write(valueAttr.getHandle(),valWrite,2); + deltaBLE.gattServer().read(valueAttr.getHandle(),valRead,valueLenPtr); + console.printf("gatt val:%02X %02X\r\n",valRead[0],valRead[1]); +} + + CyntecCommandEntry bleCommandSets[] = { +// General +#ifdef BLE_DEBUG + {"TEST", cynBLETestCommand, NULL, "test"}, +#endif +// +#if SIMPLE_CMD_NAME + {"INT", cynBLEInitCommand, NULL, "Init BLE stack"}, + {"GIO", cynBLEGPIOCommand, NULL, "Config gpio, Usage: <GPIO NO> <set|clear>"}, + {"SLP", cynBLESystemOffCommand, NULL, "System off mode, Usage: <GPIO NO>"}, + {"RST", cynResetCommand, NULL, "Soft reset"}, + {"INF", cynBLEInfoCommand, NULL, "Module information"}, + {"POW", cynBLESetTxPowerCommand, NULL, "Set BLE tx power, Usage: <POW setting>"}, + {"NAM", cynBLENameCommand, NULL, "Set/Get friendly for BLE module, Usage: <name>"}, +// GATT + {"GRS", cynRegServiceCommand, NULL, "Register standby service"}, + {"GAC", cynGattCharCommand, NULL, "Set SIG defined characteristic or Create your own"}, + {"GAS", cynGattServiceCommand, NULL, "Set SIG defined service or Create your own"}, + {"ADS", cynAdvertiseStartCommand, NULL, "Start broadcast advertise packet"}, + {"ADP", cynAdvertiseStopCommand, NULL, "Stop broadcast advertise packet"}, + {"SCS", cynBLEScanCommand, NULL, "Start to scan BLE device"}, + {"SCP", cynBLEScanStopCommand, NULL, "Stop to scan BLE device"}, + {"CON", cynBLEConnectCommand, NULL, "Connect to specific BLE device by Device Name"}, + {"DCN", cynBLEDisconnectCommand, NULL, "Disconnection, Usage: cynb disconn"}, + {"ADR", cynBLEAddressCommand, NULL, "Set/Get Bluetooth address"}, + {"WRT", cynBLEUpdateUUIDCommand, NULL, "Update value of specific characteristics"}, + {"RED", cynBLEReadDataCommand, NULL, "Read value of specific characteristics"}, + {NULL, NULL, NULL, NULL}, +#else {"init", cynBLEInitCommand, NULL, "Init BLE stack, Usage: cynb init"}, {"gpio", cynBLEGPIOCommand, NULL, "Config gpio, Usage: cynb gpio <GPIO NO> <set|clear>"}, {"sleep", cynBLESystemOffCommand, NULL, "System off mode, Usage: cynb sleep <GPIO NO>"}, - {"disconn", cynBLEDisconnectCommand, NULL, "Disconnection, Usage: cynb disconn"}, {"reset", cynResetCommand, NULL, "Soft reset, Usage: cynb reset"}, {"info", cynBLEInfoCommand, NULL, "Module information, Usage: cynb info"}, -// s110 + {"txPow", cynBLESetTxPowerCommand, NULL, "Set BLE tx power"}, + {"name", cynBLENameCommand, NULL, "Set/Get friendly for BLE module"}, +// GATT + {"regService", cynRegServiceCommand, NULL, "Test"}, {"gattChar", cynGattCharCommand, NULL, "Set SIG defined characteristic or Create your own"}, {"gattService", cynGattServiceCommand, NULL, "Set SIG defined service or Create your own"}, - {"name", cynBLENameCommand, NULL, "Set/Get friendly for BLE module"}, {"advStart", cynAdvertiseStartCommand, NULL, "Start broadcast advertise packet"}, {"advStop", cynAdvertiseStopCommand, NULL, "Stop broadcast advertise packet"}, - -//s120 {"scanStart", cynBLEScanCommand, NULL, "Start to scan BLE device"}, {"scanStop", cynBLEScanStopCommand, NULL, "Stop to scan BLE device"}, -// {"connect", cynBLEConnectCommand, NULL, "Connect to specific BLE device by Device Name"}, - - {"txPow", cynBLESetTxPowerCommand, NULL, "Set BLE tx power"}, + {"connect", cynBLEConnectCommand, NULL, "Connect to specific BLE device by Device Name"}, + {"disconn", cynBLEDisconnectCommand, NULL, "Disconnection, Usage: cynb disconn"}, {"bleAddr", cynBLEAddressCommand, NULL, "Set/Get Bluetooth address"}, {"update", cynBLEUpdateUUIDCommand, NULL, "Update value of specific characteristics"}, {"readData", cynBLEReadDataCommand, NULL, "Read value of specific characteristics"}, {NULL, NULL, NULL, NULL}, +#endif };