This CLI (Command Line Interface) is based mbed-os. Both NNN50 and NQ620 are supported.
Fork of NNN40_CLI by
ble_cli.cpp
00001 /** 00002 * File: ble-cli.c 00003 * Description: BLE CLI commands used by all applications BLE of profile. 00004 * 00005 * Copyright 2014 by CYNTEC Corporation. All rights reserved. 00006 */ 00007 00008 #include "ble_cli.h" // All #include define in ble_cli.h 00009 00010 // Genral configuration parameters 00011 #define BLE_DEBUG 0 00012 #define MAX_DEVNAME_LEN 32 00013 #define CLI_FWVERION "DELTA_CLI_V1.18" 00014 00015 //0920 Silvia modify 00016 #if defined(TARGET_DELTA_DFBM_NQ620) 00017 #define MODULE_NAME "DFBM-NQ620" 00018 #else if defined(TARGET_DELTA_DFCM_NNN50) 00019 #define MODULE_NAME "DFCM-NNN50" 00020 #endif 00021 //0920 Silvia modify 00022 00023 // Advertising configuration parameters 00024 #define APP_ADV_INTERVAL 40 /**< The advertising interval (in units of ms). */ 00025 #define APP_ADV_TIMEOUT_IN_SECONDS 180 /**< The advertising timeout (in units of seconds). */ 00026 #define APP_ADV_INTERVAL_MAX 10240 // correspond to 10.24s 00027 #define APP_ADV_INTERVAL_MIN 20 // correspond to 20ms 00028 #define APP_ADV_TIMEOUT_LIMITED_MAX 16383 //1102 Silvia add 00029 #define APP_ADV_TIMEOUT_LIMITED_MIN 1 //1102 Silvia add 00030 #define APP_ADV_DATA_OFFSET 2 // Offset for Advertising Data. 00031 //#define ADVERTISING_LED_PIN_NO LED1 00032 00033 //1102 Silvia add 00034 //Scanning configuration parameters 00035 #define BLE_SCAN_INTERVAL_LIMITED_MAX 10240 00036 #define BLE_SCAN_INTERVAL_LIMITED_MIN 3 00037 #define BLE_SCAN_WINDOW_LIMITED_MAX 10240 00038 #define BLE_SCAN_WINDOW_LIMITED_MIN 3 00039 #define BLE_SCAN_TIMEOUT_LIMITED_MAX 16383 00040 #define BLE_SCAN_TIMEOUT_LIMITED_MIN 1 00041 00042 // Peripheral mode operation parameters 00043 #define CLI_SERVICE_MAX_NUM 10 00044 #define CLI_CHAR_MAX_NUM 10 00045 #define MAX_VALUE_LENGTH 20 00046 // Central mode operation parameters 00047 #define DEFAULT_SCAN_INTERVAL 500 00048 #define DEFAULT_SCAN_WINDOW 400 00049 #define DEFAULT_SCAN_TIMEOUT 0x0005 00050 #define BLE_MAX_ADDRESS_NUMBER 10 00051 #define TARGET_DEVNAME_LEN 30 00052 00053 typedef struct bufferGattChar { 00054 uint8_t props; 00055 UUID char_uuid; 00056 uint8_t value[MAX_VALUE_LENGTH]; 00057 uint16_t char_value_handle; 00058 uint16_t valueLength; 00059 } bufferGattChar_t; 00060 00061 typedef struct bufferGattService { 00062 UUID ser_uuid; 00063 bufferGattChar_t bufferGattChar[CLI_CHAR_MAX_NUM]; 00064 //uint16_t service_handle; 00065 } bufferGattService_t; 00066 00067 // gill 20150916 for scan 00068 typedef struct { 00069 const uint8_t * p_data; /**< Pointer to data. */ 00070 uint8_t data_len; /**< Length of data. */ 00071 } data_t; 00072 00073 /*************** General parameters**********************************/ 00074 bufferGattService_t bufferService[CLI_SERVICE_MAX_NUM]; /* save entry services */ 00075 static GattCharacteristic *charAry[CLI_SERVICE_MAX_NUM][CLI_CHAR_MAX_NUM]; 00076 DiscoveredService discoverServiceArr[CLI_SERVICE_MAX_NUM]; //Silvia add 00077 DiscoveredCharacteristic discoverCharArr[CLI_SERVICE_MAX_NUM][CLI_CHAR_MAX_NUM]; //Silvia add 00078 extern Serial console; 00079 BLE deltaBLE; //gill 0904 00080 extern const char* cyntecCommandErrorNames[]; 00081 00082 /*************** GATT Configuration parameters************************/ 00083 static bool connState = false; // gill 0904, define currently connecting state 00084 static uint8_t service_count=0; 00085 static uint8_t char_count=0; 00086 static uint8_t discoverService_count=0; //Silvia add 00087 static uint8_t discoverChar_count=0; //Silvia add 00088 static uint16_t test_conn_handle; //Connection handle, assign after trigger onConnectionCallback 00089 //extern bool advState; // currently no use 00090 static Gap::Address_t saveAddr[BLE_MAX_ADDRESS_NUMBER]; // check in advertisementCallback 00091 static uint8_t bleDevInd; 00092 //static const unsigned ADDR_LEN = BLEProtocol::ADDR_LEN; //Silvia add, Length (in octets) of the BLE MAC address 00093 static BLEProtocol::AddressBytes_t targetAddr; //Silvia add, For connect target device 00094 static char targetDevName[TARGET_DEVNAME_LEN]; // For connect target device 00095 //static char DEVICE_NAME[] = "nRF5x"; // default device name, same as defined in Gap.h 00096 static bool conn_action = false; // Gill add 20151015 00097 static ble_gap_addr_t m_peer_addr; 00098 //DigitalOut led1(p7); 00099 //DigitalOut led2(p13); 00100 DigitalOut BLEWriteInt(p13); // used in OnDataWritten() 00101 00102 /****************************************************** 00103 * Function Definitions 00104 ******************************************************/ 00105 00106 //DiscoveredCharacteristic ledCharacteristic; 00107 00108 void serviceDiscoveryCallback(const DiscoveredService *service) 00109 { 00110 console.printf("serviceDiscoveryCallback\r\n"); 00111 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 00112 console.printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); 00113 } else { 00114 console.printf("S UUID-"); 00115 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); 00116 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { 00117 console.printf("%02x", longUUIDBytes[i]); 00118 } 00119 console.printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); 00120 } 00121 00122 discoverServiceArr[discoverService_count] = *service; 00123 discoverService_count++; 00124 discoverChar_count = 0; 00125 } 00126 00127 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) 00128 { 00129 //Silvia modify 00130 if (characteristicP->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 00131 console.printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); 00132 } 00133 else { 00134 console.printf(" C UUID-"); 00135 const uint8_t *longUUIDBytes = characteristicP->getUUID().getBaseUUID(); 00136 for (unsigned i = (UUID::LENGTH_OF_LONG_UUID) - 1; i < UUID::LENGTH_OF_LONG_UUID; i--) { 00137 console.printf("%02x ", longUUIDBytes[i]); 00138 } 00139 console.printf(" valueAttr[%u] props[%x]\r\n", characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); 00140 // uvCharacteristic = *characteristicP; 00141 } 00142 00143 discoverCharArr[discoverService_count - 1][discoverChar_count] = *characteristicP; 00144 discoverChar_count++; 00145 } 00146 void discoveryTerminationCallback(Gap::Handle_t connectionHandle) 00147 { 00148 console.printf("terminated SD for handle %u\r\n", connectionHandle); 00149 } 00150 00151 void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params) 00152 { 00153 test_conn_handle = params->handle; 00154 connState = true; 00155 #if BLE_DEBUG 00156 console.printf("Connect: connState write to %d\r\n",connState); 00157 #endif 00158 //Silvia modify 00159 if (params->role == Gap::CENTRAL) { 00160 deltaBLE.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); 00161 deltaBLE.gattClient().launchServiceDiscovery(test_conn_handle, serviceDiscoveryCallback, characteristicDiscoveryCallback); 00162 } 00163 //Silvia modify 00164 } 00165 00166 void onTimeoutCallback(Gap::TimeoutSource_t source) 00167 { 00168 //led1 = !led1; 00169 00170 //Silvia add 00171 switch (source) { 00172 case Gap::TIMEOUT_SRC_ADVERTISING: 00173 console.printf("Advertising timeout\r\n"); 00174 break; 00175 case Gap::TIMEOUT_SRC_SECURITY_REQUEST: 00176 console.printf("Security request timeout\r\n"); 00177 break; 00178 case Gap::TIMEOUT_SRC_SCAN: 00179 console.printf("Scanning timeout\r\n"); 00180 break; 00181 case Gap::TIMEOUT_SRC_CONN: 00182 console.printf("Connection timeout\r\n"); 00183 break; 00184 } 00185 //Silvia add 00186 } 00187 00188 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) 00189 { 00190 console.printf("Disconnected\r\n"); //Silvia add 00191 //console.printf("connState:%d\r\n",connState); 00192 //Gap::GapState_t->connected = 0; 00193 connState = false; 00194 } 00195 00196 void onDataWrittenCallback(const GattWriteCallbackParams *params) 00197 { 00198 #if BLE_DEBUG 00199 console.printf("onDataWritten\r\n"); 00200 #endif 00201 // trigger Host GPIO interrupt 00202 BLEWriteInt = !BLEWriteInt; 00203 BLEWriteInt = !BLEWriteInt; 00204 #if BLE_DEBUG 00205 console.printf("handle:%04X\r\n",params->handle); 00206 console.printf("conn_handle:%04X,writeOp:%d,offset:%04X\r\n",params->connHandle,params->writeOp,params->offset); 00207 #endif 00208 console.printf("w%d,",params->writeOp); 00209 const uint8_t* cpSerBaseUUID; 00210 const uint8_t* cpCharBaseUUID; 00211 00212 // Find specific handle Characteristic 00213 for ( int i = 0 ; i < service_count ; i++ ) { 00214 for (int j = 0 ; j < CLI_CHAR_MAX_NUM ; j++ ) { 00215 GattAttribute& tempValueAttr = charAry[i][j]->getValueAttribute(); 00216 if (tempValueAttr.getHandle()==params->handle) { 00217 #if BLE_DEBUG 00218 console.printf("ser_count,char_count:%d,%d\r\n",i,j); 00219 #endif 00220 if (bufferService[i].ser_uuid.shortOrLong()==0) 00221 console.printf("%04X",bufferService[i].ser_uuid.getShortUUID()); 00222 else { 00223 cpSerBaseUUID = bufferService[i].ser_uuid.getBaseUUID(); 00224 for (int i=15; i>=0; i--) { 00225 console.printf("%02X",cpSerBaseUUID[i]); 00226 } 00227 } 00228 console.printf(","); 00229 //console.printf("char_uuid:"); 00230 if (bufferService[i].bufferGattChar[j].char_uuid.shortOrLong()==0) // Short UUID 00231 console.printf("%04X",bufferService[i].bufferGattChar[j].char_uuid.getShortUUID()); 00232 else { // Long UUID 00233 cpCharBaseUUID = bufferService[i].bufferGattChar[j].char_uuid.getBaseUUID(); 00234 for (int i=15; i>=0; i--) { 00235 console.printf("%02X",cpCharBaseUUID[i]); 00236 } 00237 } 00238 console.printf(","); 00239 // update char value length 00240 bufferService[i].bufferGattChar[j].valueLength = params->len; 00241 break; 00242 } 00243 } 00244 } 00245 console.printf("%d,",params->len); 00246 for(int i=0; i<params->len; i++) { 00247 console.printf("%02X",params->data[i]); 00248 } 00249 console.printf(";\r\n"); 00250 } 00251 00252 static void cyntecPrintOk(void) 00253 { 00254 console.printf("\r\nOK\r\n\r\n"); 00255 } 00256 00257 static void cyntecPrintError(uint8_t errIdx) 00258 { 00259 console.printf("\r\nERROR;"); 00260 console.printf(cyntecCommandErrorNames[errIdx]); 00261 console.printf("\r\n\r\n"); 00262 } 00263 00264 static void cynAdvertiseStartCommand(void) 00265 { 00266 uint8_t argLen = 0; 00267 uint8_t *arg; 00268 uint16_t advInterval; 00269 uint16_t advTimeout; 00270 00271 switch (cyntecGetCommandTokenCnt()) { 00272 case 2: 00273 advInterval = APP_ADV_INTERVAL; 00274 advTimeout = APP_ADV_TIMEOUT_IN_SECONDS; 00275 break; 00276 case 3: 00277 /* arg1 is adv interval parameter */ 00278 arg = cyntecGetCommandArgument(0,&argLen); 00279 advInterval = cyntecAtoiUint16( arg, argLen ); 00280 advTimeout = APP_ADV_TIMEOUT_IN_SECONDS; 00281 break; 00282 case 4: 00283 arg = cyntecGetCommandArgument(0,&argLen); 00284 advInterval = cyntecAtoiUint16( arg, argLen ); 00285 arg = cyntecGetCommandArgument(1,&argLen); 00286 advTimeout = cyntecAtoiUint16( arg, argLen ); 00287 break; 00288 default: 00289 advInterval = APP_ADV_INTERVAL; 00290 advTimeout = APP_ADV_TIMEOUT_IN_SECONDS; 00291 break; 00292 } 00293 00294 if ( advInterval< APP_ADV_INTERVAL_MIN | advInterval> APP_ADV_INTERVAL_MAX | advTimeout < APP_ADV_TIMEOUT_LIMITED_MIN | advTimeout > APP_ADV_TIMEOUT_LIMITED_MAX ) { 00295 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE); 00296 return; 00297 } 00298 #if BLE_DEBUG 00299 console.printf("advInterval:%d,advTimeout:%d",advInterval,advTimeout); 00300 #endif 00301 uint8_t bleName[BLE_GAP_DEVNAME_MAX_LEN] = {"\0"}; 00302 uint16_t bleLen = BLE_GAP_DEVNAME_MAX_LEN - APP_ADV_DATA_OFFSET; 00303 uint32_t err_code; 00304 00305 err_code = sd_ble_gap_device_name_get(&bleName[APP_ADV_DATA_OFFSET], &bleLen); 00306 #if BLE_DEBUG 00307 console.printf("%08X,%s\r\n",err_code,bleName+APP_ADV_DATA_OFFSET); 00308 #endif 00309 deltaBLE.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00310 //deltaBLE.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); 00311 deltaBLE.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, bleName+APP_ADV_DATA_OFFSET, bleLen); 00312 deltaBLE.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00313 deltaBLE.gap().setAdvertisingInterval(advInterval); /* minisecond. */ 00314 deltaBLE.gap().setAdvertisingTimeout(advTimeout); /* second. */ 00315 deltaBLE.gap().startAdvertising(); 00316 cyntecPrintOk(); 00317 //nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); 00318 } 00319 00320 /**@brief Function for stop advertising. 00321 */ 00322 static void cynAdvertiseStopCommand(void) 00323 { 00324 deltaBLE.gap().stopAdvertising(); 00325 cyntecPrintOk(); 00326 //nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); 00327 } 00328 00329 //Silvia modify 00330 static void cynBLENameCommand(void) 00331 { 00332 uint8_t nameLen = 0; // Name char number, max is TARGET_DEVNAME_LEN 00333 uint8_t nameLenCharNum = 0; // Name length number is 1 or 2 00334 uint8_t *nameLeng = cyntecGetCommandArgument(0,&nameLenCharNum); 00335 nameLen = cyntecAtoi(nameLeng,nameLenCharNum); 00336 #ifdef BLE_DEUG 00337 console.printf("nameLenCharNum:%i\r\nOK;",nameLenCharNum); 00338 console.printf("nameLen:%i\r\nOK;",nameLen); 00339 #endif 00340 uint8_t bleName[BLE_GAP_DEVNAME_MAX_LEN] = {"\0"}; 00341 uint16_t bleLen = BLE_GAP_DEVNAME_MAX_LEN - APP_ADV_DATA_OFFSET; 00342 ble_gap_conn_sec_mode_t sec_mode; 00343 uint32_t err_code; 00344 uint8_t * argName2 = cyntecGetCommandTotalBuffer(); 00345 00346 // Get name string 00347 if (cyntecGetCommandTokenCnt() == 2) { 00348 err_code = sd_ble_gap_device_name_get(&bleName[APP_ADV_DATA_OFFSET], &bleLen); 00349 console.printf("\r\nOK;"); 00350 console.printf("%s",bleName+APP_ADV_DATA_OFFSET); 00351 console.printf(";\r\n"); 00352 } 00353 // Set name 00354 if (cyntecGetCommandTokenCnt() >= 3) { 00355 if (nameLen>TARGET_DEVNAME_LEN || nameLen <=0) 00356 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE); 00357 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); 00358 err_code = sd_ble_gap_device_name_set(&sec_mode, 00359 (const uint8_t *) &argName2[11+nameLenCharNum], 00360 (uint16_t) nameLen);//(uint16_t) (cyntecGetTotalIndex()-11-nameLenCharNum)); 00361 if (err_code == NRF_SUCCESS) 00362 cyntecPrintOk(); 00363 else 00364 cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL); 00365 #ifdef BLE_DEUG 00366 console.printf("LengNum:%i,string:%s,index:%i\r\n",nameLenCharNum,(const uint8_t *) &argName2[11+nameLenCharNum],cyntecGetTotalIndex()); 00367 #endif 00368 } 00369 } 00370 00371 static void cynBLEInfoCommand(void) 00372 { 00373 console.printf("\r\nOK;%s;%s\r\n\r\n", CLI_FWVERION, MODULE_NAME); 00374 } 00375 //Silvia modify 00376 00377 /**@brief Set the radio's transmit power. 00378 * 00379 * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm). 00380 * 00381 * @note -40 dBm will not actually give -40 dBm, but will instead be remapped to -30 dBm. 00382 */ 00383 static void cynBLESetTxPowerCommand (void) 00384 { 00385 if (cyntecGetCommandTokenCnt() != 3) { 00386 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 00387 return; 00388 } 00389 uint32_t err_code; 00390 uint8_t txLen=0; 00391 uint8_t *arg = cyntecGetCommandArgument(0,&txLen); 00392 00393 bool inputSwitch = false; // if find matched case in TxPow, assign true 00394 00395 #if defined(TARGET_DELTA_DFBM_NQ620) 00396 const uint8_t NUM_TXPOW = 7; 00397 int8_t validTxPow[NUM_TXPOW] = {-20, -16, -12, -8, -4, 0, 4}; 00398 #else if defined(TARGET_DELTA_DFCM_NNN50) 00399 const uint8_t NUM_TXPOW = 9; 00400 int8_t validTxPow[NUM_TXPOW] = {-40, -30, -20, -16, -12, -8, -4, 0, 4}; 00401 #endif 00402 uint8_t i; 00403 int8_t setValue; 00404 00405 if ( arg != NULL ) { 00406 #if defined(TARGET_DELTA_DFBM_NQ620) 00407 setValue = atoi((const char *)arg); 00408 #else if defined(TARGET_DELTA_DFCM_NNN50) 00409 setValue = cyntecAtoInt(arg);//work around for NNN50 since somehow atoi doesn't work properly 00410 #endif 00411 for (i = 0; i < NUM_TXPOW; i++) { 00412 if (setValue == validTxPow[i]) { 00413 err_code = sd_ble_gap_tx_power_set(setValue); 00414 //APP_ERROR_CHECK(err_code); 00415 inputSwitch = true; 00416 break; 00417 } 00418 } 00419 00420 if ( inputSwitch ) 00421 cyntecPrintOk(); 00422 else 00423 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE); 00424 00425 } 00426 clearBuffer(); // clear the commandState.buffer 00427 return; 00428 } 00429 00430 static void cynBLEAddressCommand(void) 00431 { 00432 if (cyntecGetCommandTokenCnt() == 3) { 00433 uint8_t argLen = 0; 00434 uint8_t *arg = cyntecGetCommandArgument(0, &argLen); 00435 uint32_t err_code; 00436 uint8_t addr,i; 00437 00438 /* should with "0x" + 12 len addr */ 00439 if (argLen == 14) { 00440 if (arg[0] != '0' || arg[1] != 'x') { 00441 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); 00442 return; 00443 } 00444 00445 m_peer_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; 00446 00447 for ( i = 1 ; i < 7 ; i++) { 00448 addr = cyntecArgToUint8(arg+2*i, 2); 00449 /* 5 - (i-1) */ 00450 m_peer_addr.addr[6-i] = addr; 00451 } 00452 00453 err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &m_peer_addr); 00454 //APP_ERROR_CHECK(err_code); 00455 00456 } else { //argLen != 14 00457 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); 00458 return; 00459 } 00460 00461 //#if BLE_DEBUG 00462 // uint8_t buf2[20]; 00463 // console.printf("\r\nSet BLE Address: "); 00464 // sprintf((char *)&buf2[0],(const char *)"[%02X %02X %02X %02X %02X %02X]", 00465 // m_peer_addr.addr[0], m_peer_addr.addr[1], m_peer_addr.addr[2], 00466 // m_peer_addr.addr[3], m_peer_addr.addr[4], m_peer_addr.addr[5]); 00467 // console.printf(buf2); 00468 //#endif 00469 00470 cyntecPrintOk(); 00471 } else if (cyntecGetCommandTokenCnt() == 2) { 00472 00473 uint32_t err_code; 00474 err_code = sd_ble_gap_address_get(&m_peer_addr); 00475 //APP_ERROR_CHECK(err_code); 00476 00477 // cyntecPrintOk(); 00478 00479 console.printf("OK;[%02X %02X %02X %02X %02X %02X];\r\n", 00480 m_peer_addr.addr[5], m_peer_addr.addr[4], m_peer_addr.addr[3], 00481 m_peer_addr.addr[2], m_peer_addr.addr[1], m_peer_addr.addr[0]); 00482 } else { //cyntecGetCommandTokenCnt() not equal to 2 or 3 00483 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 00484 } 00485 return; 00486 } 00487 00488 static uint32_t adv_report_parse(uint8_t type, data_t * p_advdata, data_t * p_typedata) 00489 { 00490 uint32_t index = 0; 00491 const uint8_t * p_data; 00492 00493 p_data = p_advdata->p_data; 00494 00495 while (index < p_advdata->data_len) { 00496 uint8_t field_length = p_data[index]; 00497 uint8_t field_type = p_data[index+1]; 00498 00499 if (field_type == type) { 00500 p_typedata->p_data = &p_data[index+2]; 00501 p_typedata->data_len = field_length-1; 00502 return NRF_SUCCESS; 00503 } 00504 index += field_length+1; 00505 } 00506 return NRF_ERROR_NOT_FOUND; 00507 } 00508 00509 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) 00510 { 00511 //Silvia modify 00512 Gap::Address_t newAddr[6]; 00513 memcpy(newAddr,params->peerAddr,6); 00514 00515 if (conn_action == true) { 00516 conn_action = false; 00517 00518 if (memcmp(targetAddr,newAddr,6)==0) { 00519 deltaBLE.gap().connect(params->peerAddr, Gap::ADDR_TYPE_PUBLIC, NULL, NULL); //0920 Silvia change address type 00520 return; 00521 } 00522 } else { 00523 bool flagRepeat=false; 00524 00525 for(int i=0; i<BLE_MAX_ADDRESS_NUMBER; i++) { 00526 if (memcmp(newAddr,saveAddr[i],6)==0) { 00527 #if BLE_DEBUG 00528 console.printf("Repeated\r\n"); 00529 #endif 00530 flagRepeat = true; 00531 //return; 00532 } 00533 } 00534 00535 #if BLE_DEBUG 00536 console.printf("addr cmp result :%i\r\n",memcmp(newAddr,params->peerAddr,6)); 00537 console.printf("ADV data:%X,%i\r\n",&(params->advertisingData),params->advertisingDataLen); 00538 #endif 00539 data_t adv_data; 00540 data_t type_data; 00541 //Initialize advertisement report for parsing. 00542 adv_data.p_data = params->advertisingData; 00543 adv_data.data_len = params->advertisingDataLen; 00544 // Parsing Device Name 00545 uint32_t err_code = adv_report_parse(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, 00546 &adv_data, 00547 &type_data); 00548 #if BLE_DEBUG 00549 console.printf("error code:%X\r\n",err_code); 00550 console.printf("type_data.data_len:%i\r\n",type_data.data_len); 00551 #endif 00552 if (flagRepeat == false) { 00553 if (err_code == 0) { 00554 for (int i=0; i<type_data.data_len; i++) { 00555 console.printf("%c",type_data.p_data[i]); 00556 } 00557 //console.printf("\r\n"); 00558 } 00559 console.printf(",ADV,[%02X %02X %02X %02X %02X %02X],%d,%u\r\n",params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], 00560 params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],params->rssi,params->type); 00561 memcpy(saveAddr[bleDevInd],params->peerAddr,6); 00562 bleDevInd++; 00563 } 00564 } 00565 00566 /* 00567 Check short name, not implemented 00568 */ 00569 //else 00570 // { 00571 // uint32_t err_code_2 = adv_report_parse(BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME, 00572 // &adv_data, 00573 // &type_data); 00574 // console.printf("error code:%X\r\n",err_code_2); 00575 // console.printf("%i\r\n",type_data.data_len); 00576 // console.printf("%s\r\n",type_data.p_data); 00577 // 00578 // } 00579 } 00580 00581 00582 /**@brief Function to start scanning. 00583 */ 00584 static void scan_start(void) 00585 { 00586 memset(saveAddr,0,sizeof(saveAddr)); //Silvia add, Clear saving address set 00587 deltaBLE.gap().startScan(advertisementCallback); 00588 //APP_ERROR_CHECK(err_code); 00589 } 00590 00591 static void scan_stop(void) 00592 { 00593 deltaBLE.stopScan(); 00594 //APP_ERROR_CHECK(err_code); 00595 } 00596 00597 // gill 20150916 modify 00598 static void cynBLEScanCommand(void) 00599 { 00600 uint16_t setInterval = DEFAULT_SCAN_INTERVAL; 00601 uint16_t setWindow = DEFAULT_SCAN_WINDOW; 00602 uint16_t setTimeout = DEFAULT_SCAN_TIMEOUT; 00603 if (cyntecGetCommandTokenCnt()!= 2 & cyntecGetCommandTokenCnt()!= 5) { 00604 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 00605 return; 00606 } 00607 // If user input scan parameters, overwrite the default value 00608 if (cyntecGetCommandTokenCnt()== 5) { 00609 uint8_t argLen = 0; 00610 uint8_t *arg = cyntecGetCommandArgument(0,&argLen); 00611 setInterval = cyntecAtoiUint16( arg, argLen ); 00612 arg = cyntecGetCommandArgument(1,&argLen); 00613 setWindow = cyntecAtoiUint16( arg, argLen ); 00614 arg = cyntecGetCommandArgument(2,&argLen); 00615 setTimeout = cyntecAtoiUint16( arg, argLen ); 00616 } 00617 00618 //1102 Silvia modify 00619 if ( setInterval < BLE_SCAN_INTERVAL_LIMITED_MIN | setInterval > BLE_SCAN_INTERVAL_LIMITED_MAX | setWindow < BLE_SCAN_WINDOW_LIMITED_MIN | setWindow > BLE_SCAN_WINDOW_LIMITED_MAX | setTimeout > BLE_SCAN_TIMEOUT_LIMITED_MAX | (setTimeout < BLE_SCAN_TIMEOUT_LIMITED_MIN && setTimeout != 0 ) | (setInterval < setWindow)) { 00620 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE); 00621 return; 00622 } 00623 00624 #if BLE_DEBUG 00625 console.printf("Interval:%d,Window:%d,timeout:%d\r\n",setInterval,setWindow,setTimeout); 00626 #endif 00627 // memset(saveAddr,0,sizeof(saveAddr)); // Clear saving address set 00628 //deltaBLE.gap().setScanParams(setInterval,setWindow,setTimeout,false); 00629 deltaBLE.gap().setScanInterval(setInterval); 00630 deltaBLE.gap().setScanWindow(setWindow); 00631 deltaBLE.gap().setScanTimeout(setTimeout); 00632 console.printf("Start Scan\r\n"); 00633 scan_start(); 00634 00635 } 00636 00637 static void cynBLEScanStopCommand(void) 00638 { 00639 console.printf("\r\nStop Scanning\r\n"); 00640 scan_stop(); 00641 } 00642 00643 static void cynBLEConnectCommand(void) 00644 { 00645 //Silvia modify for specific address 00646 if (cyntecGetCommandTokenCnt() != 3) { 00647 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 00648 return; 00649 } 00650 uint8_t argLen = 0; 00651 uint8_t *arg = cyntecGetCommandArgument(0, &argLen); 00652 ble_error_t err_code; 00653 uint8_t addr,i; 00654 00655 /* should with "0x" + 12 len addr */ 00656 if (argLen == 14) { 00657 if (arg[0] != '0' || arg[1] != 'x') { 00658 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); 00659 return; 00660 } 00661 memset(targetAddr,0,sizeof(targetAddr)); 00662 00663 for ( i = 1 ; i < 7 ; i++) { 00664 addr = cyntecArgToUint8(arg+2*i, 2); 00665 /* 5 - (i-1) */ 00666 targetAddr[6-i] = addr; 00667 } 00668 00669 for(int i=0; i<BLE_MAX_ADDRESS_NUMBER; i++) { 00670 if (memcmp(targetAddr,saveAddr[i],6)==0) { 00671 err_code = deltaBLE.gap().connect(targetAddr, Gap::ADDR_TYPE_PUBLIC, NULL, NULL); //0920 Silvia change address type 00672 00673 if (err_code != 0) { 00674 console.printf("Error:%d\r\n",err_code); 00675 } else { 00676 cyntecPrintOk(); 00677 } 00678 00679 return; 00680 } 00681 } 00682 00683 conn_action = true; 00684 scan_start(); 00685 } else { //argLen != 14 00686 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); 00687 return; 00688 } 00689 00690 //if (cyntecGetCommandTokenCnt() != 3) { 00691 // cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 00692 // return; 00693 // } 00694 // 00695 // uint8_t devNameLen = 0; 00696 // uint8_t *argDevName = cyntecGetCommandArgument(0, &devNameLen); 00697 // 00698 // //if ( argDevName != NULL ) { 00699 //// uint8_t i; 00700 //// for (i = 0; i < devNameLen; i++) { 00701 //// targetDevName[i] = argDevName[i]; 00702 //// } 00703 //// if (i < devNameLen) 00704 //// targetDevName[i] = '\0'; 00705 //// } 00706 // 00707 // memset( targetDevName , 0, TARGET_DEVNAME_LEN); 00708 // memcpy( targetDevName, argDevName, devNameLen); 00709 //#if BLE_DEBUG 00710 // console.printf("Search for device name:%s\r\n",argDevName); 00711 // console.printf("Target:%s\r\n",targetDevName); 00712 //#endif 00713 // conn_action = true; 00714 // scan_start(); 00715 00716 } 00717 00718 00719 static void cynBLEDisconnectCommand(void) 00720 { 00721 ble_error_t err_code; 00722 err_code = deltaBLE.gap().disconnect(Gap::REMOTE_USER_TERMINATED_CONNECTION); 00723 //err_code = sd_ble_gap_disconnect(test_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); 00724 //err_code = sd_ble_gap_connect_cancel(); // No function defined currently 00725 #if BLE_DEBUG 00726 console.printf("Error:%d\r\n",err_code); 00727 #endif 00728 cyntecPrintOk(); 00729 } 00730 00731 static void cynBLESystemOffCommand(void) 00732 { 00733 if (cyntecGetCommandTokenCnt() == 3) { 00734 uint8_t argLen = 0; 00735 uint8_t *arg = cyntecGetCommandArgument(0,&argLen); 00736 uint8_t gpioNum = cyntecAtoi( arg, argLen ); 00737 00738 if (gpioNum < 1 || gpioNum > 4) { 00739 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE); 00740 return; 00741 } 00742 if (gpioNum == 1) 00743 nrf_gpio_cfg_sense_input(BUTTON1, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); 00744 #if defined(TARGET_DELTA_DFBM_NQ620)//Tsungta, temp use only, will be fix in NNN50 00745 else if (gpioNum == 2) 00746 nrf_gpio_cfg_sense_input(BUTTON2, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); 00747 else if (gpioNum == 3) 00748 nrf_gpio_cfg_sense_input(BUTTON3, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); 00749 else if (gpioNum == 4) 00750 nrf_gpio_cfg_sense_input(BUTTON4, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); 00751 #endif 00752 else { 00753 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE); 00754 return; 00755 } 00756 cyntecPrintOk(); 00757 } else if (cyntecGetCommandTokenCnt() == 2) { 00758 /* default wake up pin is uart Rx pin */ 00759 nrf_gpio_cfg_sense_input(RX_PIN_NUMBER, 00760 NRF_GPIO_PIN_PULLUP, 00761 NRF_GPIO_PIN_SENSE_LOW); 00762 cyntecPrintOk(); 00763 } else { 00764 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 00765 return; 00766 } 00767 sd_power_system_off(); 00768 } 00769 00770 static void cynBLEGPIOCommand(void) 00771 { 00772 00773 if (cyntecGetCommandTokenCnt() == 4) { 00774 uint8_t argLen = 0; 00775 uint8_t *arg = cyntecGetCommandArgument(0,&argLen); 00776 uint8_t gpioNum = cyntecAtoi( arg, argLen ); 00777 00778 if (gpioNum < 1 || gpioNum > 4) { 00779 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE); 00780 return; 00781 } 00782 00783 /* arg2 is set or clear */ 00784 uint8_t *action = cyntecGetCommandArgument(1,&argLen); 00785 00786 if ( cyntecStrCmp(action,(unsigned char *)"set",argLen) == 1 ) { 00787 if (gpioNum == 1) { DigitalOut CLI_LED(LED1); CLI_LED = 1; } 00788 else if (gpioNum == 2) { DigitalOut CLI_LED(LED2); CLI_LED = 1; } 00789 else if (gpioNum == 3) { DigitalOut CLI_LED(LED3); CLI_LED = 1; } 00790 else if (gpioNum == 4) { DigitalOut CLI_LED(LED4); CLI_LED = 1; } 00791 cyntecPrintOk(); 00792 } else if ( cyntecStrCmp(action,(unsigned char *)"clear",argLen) == 1 ) { 00793 if (gpioNum == 1) { DigitalOut CLI_LED(LED1); CLI_LED = 0; } 00794 else if (gpioNum == 2) { DigitalOut CLI_LED(LED2); CLI_LED = 0; } 00795 else if (gpioNum == 3) { DigitalOut CLI_LED(LED3); CLI_LED = 0; } 00796 else if (gpioNum == 4) { DigitalOut CLI_LED(LED4); CLI_LED = 0; } 00797 cyntecPrintOk(); 00798 } else { 00799 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); 00800 } 00801 } else { 00802 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 00803 } 00804 } 00805 00806 static void cynResetCommand(void) 00807 { 00808 cyntecPrintOk(); 00809 // On assert, the system can only recover with a reset. 00810 NVIC_SystemReset(); 00811 } 00812 00813 void triggerRead(const GattReadCallbackParams *response) 00814 { 00815 //if (response->handle == ledCharacteristic.getValueHandle()) { 00816 #if DUMP_READ_DATA 00817 printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len); 00818 for (unsigned index = 0; index < response->len; index++) { 00819 printf("%c[%02x]", response->data[index], response->data[index]); 00820 } 00821 printf("\r\n"); 00822 #endif 00823 // 00824 // uint8_t toggledValue = response->data[0] ^ 0x1; 00825 // ledCharacteristic.write(1, &toggledValue); 00826 // } 00827 } 00828 00829 //Silvia modify 00830 void centralReadCallback(const GattReadCallbackParams *response) { 00831 // printf("centralReadCallback Handle: %d\r\n", response->handle); 00832 00833 for (unsigned index = 0; index < response->len; index++) { 00834 console.printf("[%02x]", response->data[index]); 00835 } 00836 console.printf("\r\n"); 00837 } 00838 00839 void centralWriteCallback(const GattWriteCallbackParams *response) { 00840 // printf("centralWriteCallback: %d\r\n", response->len); 00841 00842 for (unsigned index = 0; index < response->len; index++) { 00843 console.printf("[%02x]", response->data[index]); 00844 } 00845 console.printf("\r\n"); 00846 } 00847 00848 void centralHvxCallback(const GattHVXCallbackParams *response) { 00849 // printf("centralHvxCallback handle %u, type %02x, len %u\r\n", response->handle, response->type, response->len); 00850 for (unsigned index = 0; index < response->len; index++) { 00851 console.printf("[%02x]", response->data[index]); 00852 } 00853 console.printf("\r\n"); 00854 } 00855 //Silvia modify 00856 00857 static void cynBLEUpdateDataCommand(void) 00858 { 00859 if (cyntecGetCommandTokenCnt() != 6) { 00860 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 00861 return; 00862 } 00863 UUID buf_ser_uuid ; 00864 uint8_t bufferUuidVs[16]; 00865 UUID buf_char_uuid; 00866 uint8_t bufVal[MAX_VALUE_LENGTH] = {0}; 00867 uint16_t valueLen = 0; 00868 bool readmatchFlag = false; 00869 uint8_t argLen = 0; 00870 uint8_t *arg = cyntecGetCommandArgument(0,&argLen); 00871 00872 // Handle input parameter - Service UUID 00873 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 00874 buf_ser_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 00875 } 00876 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 00877 for (uint8_t i=0; i<16; i++) { 00878 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 00879 } 00880 buf_ser_uuid.setupLong(bufferUuidVs); 00881 } 00882 00883 // Handle input parameter - Characteristic UUID 00884 argLen = 0; 00885 arg = cyntecGetCommandArgument(1,&argLen); 00886 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 00887 buf_char_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 00888 } 00889 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 00890 for (uint8_t i=0; i<16; i++) { 00891 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 00892 } 00893 buf_char_uuid.setupLong(bufferUuidVs); 00894 } 00895 // Input Value Type 00896 arg = cyntecGetCommandArgument(2,&argLen); 00897 uint8_t type = *arg; 00898 //type = cyntecArgToUint8(arg,2); 00899 //printf("type:%d\r\n",type); 00900 if(type != '0' && type != '1') // Original Data 00901 { 00902 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE); 00903 } 00904 00905 // Input value 00906 arg = cyntecGetCommandArgument(3,&argLen); 00907 if(type == '0') // Original Data 00908 { 00909 valueLen = argLen; 00910 memcpy(bufVal,arg,argLen); 00911 } 00912 if(type == '1') // Char Data 00913 { 00914 valueLen = (argLen-2)/2; // uint8_t to uint16_t transform 00915 for (int i=0 ; i < valueLen; i++) { 00916 bufVal[i] = cyntecArgToUint8(arg+2+2*i,2); 00917 } 00918 } 00919 #if BLE_DEBUG 00920 printf("type:%i,bufVal:",type); 00921 printf("valueLength:%i\r\n",valueLen); 00922 for (int i=0 ; i < valueLen; i++) { 00923 printf("%02X ",bufVal[i]); 00924 } 00925 printf("\r\n"); 00926 #endif 00927 00928 for ( int i = 0 ; i < service_count ; i++ ) { 00929 if ( (bufferService[i].ser_uuid == buf_ser_uuid) & (readmatchFlag == false)) { 00930 for (int j = 0 ; j < CLI_CHAR_MAX_NUM ; j++ ) { 00931 if (( bufferService[i].bufferGattChar[j].char_uuid == buf_char_uuid)& (readmatchFlag == false)) { 00932 GattAttribute& valueAttr = charAry[i][j]->getValueAttribute(); 00933 ble_error_t err; 00934 if (!connState) 00935 err = deltaBLE.gattServer().write(valueAttr.getHandle(),bufVal,valueLen,true); 00936 else 00937 err = deltaBLE.gattServer().write(test_conn_handle,valueAttr.getHandle(),bufVal,valueLen,false); 00938 00939 // update valueLength 00940 bufferService[i].bufferGattChar[j].valueLength = valueLen; 00941 00942 #if BLE_DEBUG 00943 console.printf("Write ERR:%i\r\n",err); 00944 printf("valueLen:%i\r\n",valueLen); 00945 #endif 00946 console.printf("\r\nOK;"); 00947 for (uint16_t n=0; n<valueLen; n++) { 00948 console.printf("%02X",bufVal[n]); 00949 } 00950 console.printf("\r\n"); 00951 readmatchFlag = true; 00952 return; 00953 } 00954 } 00955 } 00956 } 00957 // no matched case, can not read 00958 if (readmatchFlag == false) { 00959 cyntecPrintError(CYNTEC_CMD_ERR_NO_MATCHED_ARGUMENT); 00960 } 00961 } 00962 00963 static void cynBLEReadDataCommand(void) 00964 { 00965 //#if BLE_DEBUG 00966 // printf("Saved Char:\r\n"); 00967 // for (int i=0; i<service_count; i++) { 00968 // console.printf("ser_uuid:%04X",bufferService[service_count-1].ser_uuid.getShortUUID()); 00969 // for (int j=0; j<CLI_CHAR_MAX_NUM; j++) { 00970 // printf(" %i,char_uuid%04X,",j,bufferService[service_count-1].bufferGattChar[char_count-1].char_uuid.getShortUUID()); 00971 // printf("len%d,",bufferService[service_count-1].bufferGattChar[char_count-1].valueLength); 00972 // printf("val%02X;",bufferService[service_count-1].bufferGattChar[char_count-1].value[0]); 00973 // } 00974 // } 00975 // printf("\r\n"); 00976 //#endif 00977 if (cyntecGetCommandTokenCnt() != 4) { 00978 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 00979 return; 00980 } 00981 UUID buf_ser_uuid ; 00982 uint8_t bufferUuidVs[16]; 00983 UUID buf_char_uuid; 00984 uint8_t bufVal[MAX_VALUE_LENGTH] = {0}; 00985 uint16_t valueLen=0; 00986 //uint16_t * valueLenPtr; 00987 bool readmatchFlag = false; 00988 uint8_t argLen = 0; 00989 uint8_t *arg = cyntecGetCommandArgument(0,&argLen); 00990 00991 // Handle input parameter - Service UUID 00992 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 00993 buf_ser_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 00994 } 00995 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 00996 for (uint8_t i=0; i<16; i++) { 00997 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 00998 } 00999 buf_ser_uuid.setupLong(bufferUuidVs); 01000 } 01001 01002 // Handle input parameter - Characteristic UUID 01003 argLen = 0; 01004 arg = cyntecGetCommandArgument(1,&argLen); 01005 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 01006 buf_char_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01007 } 01008 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 01009 for (uint8_t i=0; i<16; i++) { 01010 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 01011 } 01012 buf_char_uuid.setupLong(bufferUuidVs); 01013 } 01014 01015 for ( int i = 0 ; i < service_count ; i++ ) { 01016 if ( (bufferService[i].ser_uuid == buf_ser_uuid) & (readmatchFlag == false)) { 01017 for (int j = 0 ; j < CLI_CHAR_MAX_NUM ; j++ ) { 01018 if (( bufferService[i].bufferGattChar[j].char_uuid == buf_char_uuid)& (readmatchFlag == false)) { 01019 GattAttribute& valueAttr = charAry[i][j]->getValueAttribute(); 01020 // valueLenPtr = valueAttr.getLengthPtr(); 01021 valueLen = bufferService[i].bufferGattChar[j].valueLength; 01022 uint16_t * valueLenPtr = &bufferService[i].bufferGattChar[j].valueLength; 01023 ble_error_t err = deltaBLE.gattServer().read(valueAttr.getHandle(),bufVal,valueLenPtr); 01024 #if BLE_DEBUG 01025 console.printf("Read ERR:%i\r\n",err); 01026 printf("valueLen:%i\r\n",valueLen); 01027 #endif 01028 console.printf("\r\nOK;"); 01029 console.printf("0x"); 01030 for (uint16_t n=0; n<valueLen; n++) { 01031 console.printf("%02X",bufVal[n]); 01032 } 01033 console.printf("\r\n"); 01034 readmatchFlag = true; 01035 return; 01036 } 01037 } 01038 } 01039 01040 } 01041 // no matched case, can not read 01042 if (readmatchFlag == false) { 01043 cyntecPrintError(CYNTEC_CMD_ERR_NO_MATCHED_ARGUMENT); 01044 } 01045 } 01046 01047 static void cynGattCharCommand(void) 01048 { 01049 uint8_t i; 01050 uint8_t valueLengthBuffer; 01051 01052 if (cyntecGetCommandTokenCnt() != 5) { 01053 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 01054 return; 01055 } 01056 01057 //Silvia add 01058 if (service_count == 0) { 01059 cyntecPrintError(CYNTEC_CMD_ERR_INVALID_STATE_TO_PERFORM_OPERATION); 01060 return; 01061 } 01062 //Silvia add 01063 01064 if (char_count >= CLI_CHAR_MAX_NUM) { 01065 cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL); 01066 #if BLE_DEBUG 01067 console.printf("Error: char_count>CLI_CHAR_MAX_NUM\r\n"); 01068 #endif 01069 return; 01070 } 01071 01072 /* handle parameter - UUID */ 01073 /* Only support 16-bit or 128-bit UUID type */ 01074 uint8_t argLen = 0; 01075 uint8_t *arg = cyntecGetCommandArgument(0,&argLen); 01076 if (arg[0] != '0' || arg[1] != 'x' || (argLen != 6 && argLen != 34)) { 01077 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); 01078 return; 01079 } 01080 /* len: 6 => 0xXXXX */ 01081 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 01082 UUID::ShortUUIDBytes_t buffer_uuid_short; 01083 buffer_uuid_short = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01084 UUID uuid_short(buffer_uuid_short); 01085 bufferService[service_count-1].bufferGattChar[char_count].char_uuid = uuid_short; 01086 } 01087 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 01088 // Initialize LongUUIDBytes_t, then use default constructor to setupLong(longUUID) 01089 UUID::LongUUIDBytes_t buffer_uuid_vs; 01090 for (uint8_t i=0; i<16; i++) { 01091 buffer_uuid_vs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 01092 } 01093 bufferService[service_count-1].bufferGattChar[char_count].char_uuid.setupLong(buffer_uuid_vs); 01094 } 01095 01096 /* handle 3rd parameter - attribute mode */ 01097 argLen = 0; 01098 arg = cyntecGetCommandArgument(1,&argLen); 01099 if (arg[0] != '0' || arg[1] != 'x' ) { 01100 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); 01101 return; 01102 } 01103 uint8_t prop = cyntecArgToUint8(arg+2,2); 01104 01105 /* handle 4th parameter - attribute value */ 01106 argLen = 0; 01107 arg = cyntecGetCommandArgument(2,&argLen); 01108 if (arg[0] != '0' || arg[1] != 'x' | argLen%2 != 0) { 01109 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_SYNTAX_ERROR); 01110 return; 01111 } 01112 valueLengthBuffer = (argLen-2)/2; 01113 memset(bufferService[service_count-1].bufferGattChar[char_count].value,0,MAX_VALUE_LENGTH); 01114 for (i=0 ; i < (argLen-2)/2; i++) { 01115 bufferService[service_count-1].bufferGattChar[char_count].value[i] = cyntecArgToUint8(arg+2*(i+1), 2); 01116 //console.printf("%02X ",bufferService[service_count-1].bufferGattChar[char_count].value[i]); 01117 } 01118 #if BLE_DEBUG 01119 printf("prop:%02X\r\n",prop); 01120 console.printf("valueLengthBuffer:%d\r\n",valueLengthBuffer); 01121 console.printf("value:"); 01122 for (i=0 ; i < valueLengthBuffer; i++) { 01123 console.printf("%02X",bufferService[service_count-1].bufferGattChar[char_count].value[i]); 01124 } 01125 #endif 01126 bufferService[service_count-1].bufferGattChar[char_count].valueLength = valueLengthBuffer; 01127 bufferService[service_count-1].bufferGattChar[char_count].props = prop; 01128 //bufferService[service_count-1].bufferGattChar[char_count].char_value_handle = testHandle; 01129 01130 cyntecPrintOk(); 01131 char_count++; 01132 } 01133 01134 static void cynRegServiceCommand(void) 01135 { 01136 //GattCharacteristic *charAry[char_count]; 01137 //GattCharacteristic **charAry; 01138 //charAry = new GattCharacteristic *[char_count]; 01139 #if BLE_DEBUG 01140 console.printf("Current char_count:%d\r\n",char_count); 01141 console.printf("Current service_count:%d\r\n",service_count); 01142 #endif 01143 for (uint8_t i=0; i<char_count; i++) { 01144 charAry[service_count-1][i] = new GattCharacteristic ( 01145 bufferService[service_count-1].bufferGattChar[i].char_uuid, 01146 bufferService[service_count-1].bufferGattChar[i].value, 01147 bufferService[service_count-1].bufferGattChar[i].valueLength, 01148 MAX_VALUE_LENGTH, 01149 bufferService[service_count-1].bufferGattChar[i].props 01150 ); 01151 } 01152 GattService newService(bufferService[service_count-1].ser_uuid, charAry[service_count-1], char_count ); 01153 ble_error_t err_code; 01154 err_code = deltaBLE.addService(newService); 01155 if (err_code != 0) { 01156 #if BLE_DEBUG 01157 console.printf("addService error:%d\r\n",err_code); 01158 #endif 01159 cyntecPrintError(CYNTEC_CMD_ERR_CALL_FAIL); 01160 } else 01161 cyntecPrintOk(); 01162 //char_count = 0; // already did in gattService 01163 } 01164 01165 static void cynGattServiceCommand(void) 01166 { 01167 if (cyntecGetCommandTokenCnt() != 3) { 01168 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 01169 return; 01170 } 01171 /* handle first parameter - Service UUID */ 01172 uint8_t argLen = 0; 01173 uint8_t *arg = cyntecGetCommandArgument(0,&argLen); 01174 01175 /* Service uuid is 16 bits */ 01176 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 01177 UUID::ShortUUIDBytes_t buffer_uuid_short; 01178 buffer_uuid_short = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01179 #if BLE_DEBUG 01180 console.printf("%4X",buffer_uuid_short); 01181 #endif 01182 UUID uuid_short(buffer_uuid_short); 01183 bufferService[service_count].ser_uuid = uuid_short; 01184 //buffer_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01185 } 01186 01187 /* Service uuid is 128 bits */ 01188 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 01189 // Initialize LongUUIDBytes_t, then use default constructor to setupLong(longUUID) 01190 UUID::LongUUIDBytes_t buffer_uuid_vs; 01191 for (uint8_t i=0; i<16; i++) { 01192 buffer_uuid_vs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 01193 #if BLE_DEBUG 01194 console.printf("%2X ",buffer_uuid_vs[i]); 01195 #endif 01196 } 01197 UUID uuid_long(buffer_uuid_vs); 01198 bufferService[service_count].ser_uuid = uuid_long; 01199 } 01200 cyntecPrintOk(); 01201 service_count++; 01202 char_count = 0; 01203 } 01204 01205 /*Tsungta, @0913 modify to compatiable with mbed os 5.0*/ 01206 //#include <mbed-events/events.h> 01207 void onBleInitError(BLE &ble, ble_error_t error) 01208 { 01209 (void)ble; 01210 (void)error; 01211 /* Initialization error handling should go here */ 01212 } 01213 01214 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 01215 { 01216 01217 } 01218 01219 static EventQueue eventQueue( 01220 /* event count */ 16 * /* event size */ 32 01221 ); 01222 01223 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { 01224 BLE &deltaBLE = BLE::Instance(); 01225 eventQueue.call(Callback<void()>(&deltaBLE, &BLE::processEvents)); 01226 } 01227 01228 void cynBLEInitCommand(void) 01229 { 01230 BLE &deltaBLE = BLE::Instance(); 01231 01232 deltaBLE.onEventsToProcess(scheduleBleEventsProcessing); 01233 deltaBLE.init(bleInitComplete); 01234 deltaBLE.onDisconnection(disconnectionCallback); 01235 deltaBLE.onConnection(onConnectionCallback); 01236 deltaBLE.onTimeout(onTimeoutCallback); 01237 deltaBLE.gattServer().onDataRead(triggerRead); 01238 01239 console.printf("\r\nOK;%s;%s\r\n\r\n", CLI_FWVERION, MODULE_NAME); //0920 Silvia add 01240 while (true) { 01241 eventQueue.dispatch(); 01242 } 01243 } 01244 /*Tsungta, end of @0913 modification*/ 01245 01246 //Silvia modify 01247 static void cynBLECenInitCommand(void) 01248 { 01249 deltaBLE.init(); 01250 deltaBLE.onDisconnection(disconnectionCallback); 01251 deltaBLE.onConnection(onConnectionCallback); 01252 deltaBLE.onTimeout(onTimeoutCallback); 01253 deltaBLE.gattClient().onDataRead(centralReadCallback); 01254 deltaBLE.gattClient().onDataWrite(centralWriteCallback); 01255 deltaBLE.gattClient().onHVX(centralHvxCallback); 01256 01257 cyntecPrintOk(); 01258 } 01259 01260 static void cynBLECenReadDataCommand(void) 01261 { 01262 if (cyntecGetCommandTokenCnt() != 4) { 01263 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 01264 return; 01265 } 01266 UUID buf_ser_uuid ; 01267 uint8_t bufferUuidVs[16]; 01268 UUID buf_char_uuid; 01269 bool readmatchFlag = false; 01270 uint8_t argLen = 0; 01271 uint8_t *arg = cyntecGetCommandArgument(0,&argLen); 01272 01273 // Handle input parameter - Service UUID 01274 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 01275 buf_ser_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01276 } 01277 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 01278 for (uint8_t i=0; i<16; i++) { 01279 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 01280 } 01281 buf_ser_uuid.setupLong(bufferUuidVs); 01282 } 01283 01284 // Handle input parameter - Characteristic UUID 01285 argLen = 0; 01286 arg = cyntecGetCommandArgument(1,&argLen); 01287 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 01288 buf_char_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01289 } 01290 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 01291 for (uint8_t i=0; i<16; i++) { 01292 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 01293 } 01294 buf_char_uuid.setupLong(bufferUuidVs); 01295 } 01296 01297 for ( int i = 0 ; i < discoverService_count ; i++ ) { 01298 UUID sUUID, cUUID; 01299 if (discoverServiceArr[i].getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 01300 sUUID = UUID(discoverServiceArr[i].getUUID().getShortUUID()); 01301 } else { 01302 const uint8_t *longUUIDBytes = discoverServiceArr[i].getUUID().getBaseUUID(); 01303 sUUID = UUID(longUUIDBytes); 01304 } 01305 if ((sUUID == buf_ser_uuid) & (readmatchFlag == false)) { 01306 for (int j = 0 ; j < CLI_CHAR_MAX_NUM ; j++ ) { 01307 if (discoverCharArr[i][j].getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 01308 cUUID = UUID(discoverCharArr[i][j].getUUID().getShortUUID()); 01309 } else { 01310 const uint8_t *longUUIDBytes = discoverCharArr[i][j].getUUID().getBaseUUID(); 01311 cUUID = UUID(longUUIDBytes); 01312 } 01313 if ((cUUID == buf_char_uuid) & (readmatchFlag == false)) { 01314 cyntecPrintOk(); 01315 discoverCharArr[i][j].read(); 01316 01317 readmatchFlag = true; 01318 return; 01319 } 01320 } 01321 } 01322 } 01323 01324 // no matched case, can not read 01325 if (readmatchFlag == false) { 01326 cyntecPrintError(CYNTEC_CMD_ERR_NO_MATCHED_ARGUMENT); 01327 } 01328 } 01329 01330 static void cynBLECenWriteDataCommand(void) { 01331 if (cyntecGetCommandTokenCnt() != 6) { 01332 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 01333 return; 01334 } 01335 UUID buf_ser_uuid ; 01336 uint8_t bufferUuidVs[16]; 01337 UUID buf_char_uuid; 01338 bool readmatchFlag = false; 01339 uint16_t valueLen = 0; 01340 uint8_t argLen = 0; 01341 uint8_t *arg = cyntecGetCommandArgument(0,&argLen); 01342 uint8_t bufVal[MAX_VALUE_LENGTH] = {0}; 01343 01344 // Handle input parameter - Service UUID 01345 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 01346 buf_ser_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01347 } 01348 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 01349 for (uint8_t i=0; i<16; i++) { 01350 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 01351 } 01352 buf_ser_uuid.setupLong(bufferUuidVs); 01353 } 01354 01355 // Handle input parameter - Characteristic UUID 01356 argLen = 0; 01357 arg = cyntecGetCommandArgument(1,&argLen); 01358 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 01359 buf_char_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01360 } 01361 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 01362 for (uint8_t i=0; i<16; i++) { 01363 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 01364 } 01365 buf_char_uuid.setupLong(bufferUuidVs); 01366 } 01367 01368 //// Input Value Type 01369 arg = cyntecGetCommandArgument(2,&argLen); 01370 uint8_t type = *arg; 01371 //type = cyntecArgToUint8(arg,2); 01372 // printf("type:%d\r\n",type); 01373 if(type != '0' && type != '1') { 01374 cyntecPrintError(CYNTEC_CMD_ERR_ARGUMENT_OUT_OF_RANGE); 01375 } 01376 01377 // Input value 01378 arg = cyntecGetCommandArgument(3,&argLen); 01379 if(type == '0') { 01380 valueLen = argLen; 01381 memcpy(bufVal,arg,argLen); 01382 } 01383 if(type == '1') { 01384 valueLen = (argLen-2)/2; // uint8_t to uint16_t transform 01385 for (int i=0 ; i < valueLen; i++) { 01386 bufVal[i] = cyntecArgToUint8(arg+2+2*i,2); 01387 } 01388 } 01389 #if BLE_DEBUG 01390 printf("type:%i,bufVal:",type); 01391 printf("valueLength:%i\r\n",valueLen); 01392 for (int i=0 ; i < valueLen; i++) { 01393 printf("%02X ",bufVal[i]); 01394 } 01395 printf("\r\n"); 01396 #endif 01397 01398 for ( int i = 0 ; i < discoverService_count ; i++ ) { 01399 UUID sUUID, cUUID; 01400 if (discoverServiceArr[i].getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 01401 sUUID = UUID(discoverServiceArr[i].getUUID().getShortUUID()); 01402 } else { 01403 const uint8_t *longUUIDBytes = discoverServiceArr[i].getUUID().getBaseUUID(); 01404 sUUID = UUID(longUUIDBytes); 01405 } 01406 if ((sUUID == buf_ser_uuid) & (readmatchFlag == false)) { 01407 for (int j = 0 ; j < CLI_CHAR_MAX_NUM ; j++ ) { 01408 if (discoverCharArr[i][j].getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 01409 cUUID = UUID(discoverCharArr[i][j].getUUID().getShortUUID()); 01410 } else { 01411 const uint8_t *longUUIDBytes = discoverCharArr[i][j].getUUID().getBaseUUID(); 01412 cUUID = UUID(longUUIDBytes); 01413 } 01414 if ((cUUID == buf_char_uuid) & (readmatchFlag == false)) { 01415 console.printf("OK;"); 01416 for (int i=0 ; i < valueLen; i++) { 01417 console.printf("%02X",bufVal[i]); 01418 } 01419 console.printf("\r\n"); 01420 deltaBLE.gattClient().write(GattClient::GATT_OP_WRITE_REQ, discoverCharArr[i][j].getConnectionHandle(), discoverCharArr[i][j].getValueHandle(), valueLen, bufVal); 01421 readmatchFlag = true; 01422 return; 01423 } 01424 } 01425 } 01426 } 01427 01428 // no matched case, can not read 01429 if (readmatchFlag == false) { 01430 cyntecPrintError(CYNTEC_CMD_ERR_NO_MATCHED_ARGUMENT); 01431 } 01432 } 01433 01434 static void cynBLECenEnNotifyCommand(void) 01435 { 01436 if (cyntecGetCommandTokenCnt() != 4) { 01437 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 01438 return; 01439 } 01440 UUID buf_ser_uuid ; 01441 uint8_t bufferUuidVs[16]; 01442 UUID buf_char_uuid; 01443 bool readmatchFlag = false; 01444 uint8_t argLen = 0; 01445 uint8_t *arg = cyntecGetCommandArgument(0,&argLen); 01446 01447 // Handle input parameter - Service UUID 01448 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 01449 buf_ser_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01450 } 01451 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 01452 for (uint8_t i=0; i<16; i++) { 01453 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 01454 } 01455 buf_ser_uuid.setupLong(bufferUuidVs); 01456 } 01457 01458 // Handle input parameter - Characteristic UUID 01459 argLen = 0; 01460 arg = cyntecGetCommandArgument(1,&argLen); 01461 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 01462 buf_char_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01463 } 01464 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 01465 for (uint8_t i=0; i<16; i++) { 01466 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 01467 } 01468 buf_char_uuid.setupLong(bufferUuidVs); 01469 } 01470 01471 for ( int i = 0 ; i < discoverService_count ; i++ ) { 01472 UUID sUUID, cUUID; 01473 if (discoverServiceArr[i].getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 01474 sUUID = UUID(discoverServiceArr[i].getUUID().getShortUUID()); 01475 } else { 01476 const uint8_t *longUUIDBytes = discoverServiceArr[i].getUUID().getBaseUUID(); 01477 sUUID = UUID(longUUIDBytes); 01478 } 01479 if ((sUUID == buf_ser_uuid) & (readmatchFlag == false)) { 01480 for (int j = 0 ; j < CLI_CHAR_MAX_NUM ; j++ ) { 01481 if (discoverCharArr[i][j].getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 01482 cUUID = UUID(discoverCharArr[i][j].getUUID().getShortUUID()); 01483 } else { 01484 const uint8_t *longUUIDBytes = discoverCharArr[i][j].getUUID().getBaseUUID(); 01485 cUUID = UUID(longUUIDBytes); 01486 } 01487 if ((cUUID == buf_char_uuid) & (readmatchFlag == false)) { 01488 cyntecPrintOk(); 01489 uint16_t value = BLE_HVX_NOTIFICATION; 01490 deltaBLE.gattClient().write(GattClient::GATT_OP_WRITE_REQ, discoverCharArr[i][j].getConnectionHandle(), discoverCharArr[i][j].getValueHandle() + 1, 2, (uint8_t *)&value); 01491 readmatchFlag = true; 01492 return; 01493 } 01494 } 01495 } 01496 } 01497 01498 // no matched case, can not read 01499 if (readmatchFlag == false) { 01500 cyntecPrintError(CYNTEC_CMD_ERR_NO_MATCHED_ARGUMENT); 01501 } 01502 } 01503 01504 static void cynBLECenDisNotifyCommand(void) { 01505 if (cyntecGetCommandTokenCnt() != 4) { 01506 cyntecPrintError(CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS); 01507 return; 01508 } 01509 UUID buf_ser_uuid ; 01510 uint8_t bufferUuidVs[16]; 01511 UUID buf_char_uuid; 01512 bool readmatchFlag = false; 01513 uint8_t argLen = 0; 01514 uint8_t *arg = cyntecGetCommandArgument(0,&argLen); 01515 01516 // Handle input parameter - Service UUID 01517 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 01518 buf_ser_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01519 } 01520 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 01521 for (uint8_t i=0; i<16; i++) { 01522 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 01523 } 01524 buf_ser_uuid.setupLong(bufferUuidVs); 01525 } 01526 01527 // Handle input parameter - Characteristic UUID 01528 argLen = 0; 01529 arg = cyntecGetCommandArgument(1,&argLen); 01530 if ( argLen == 6 && arg[0] == '0' && arg[1] == 'x') { 01531 buf_char_uuid = cyntecArgToUint16( (arg + 2), (argLen - 2)); 01532 } 01533 if ( argLen == 34 && arg[0] == '0' && arg[1] == 'x' ) { 01534 for (uint8_t i=0; i<16; i++) { 01535 bufferUuidVs[i] = cyntecArgToUint8( (arg + 2+2*i), 2); 01536 } 01537 buf_char_uuid.setupLong(bufferUuidVs); 01538 } 01539 01540 for ( int i = 0 ; i < discoverService_count ; i++ ) { 01541 UUID sUUID, cUUID; 01542 if (discoverServiceArr[i].getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 01543 sUUID = UUID(discoverServiceArr[i].getUUID().getShortUUID()); 01544 } else { 01545 const uint8_t *longUUIDBytes = discoverServiceArr[i].getUUID().getBaseUUID(); 01546 sUUID = UUID(longUUIDBytes); 01547 } 01548 if ((sUUID == buf_ser_uuid) & (readmatchFlag == false)) { 01549 for (int j = 0 ; j < CLI_CHAR_MAX_NUM ; j++ ) { 01550 if (discoverCharArr[i][j].getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { 01551 cUUID = UUID(discoverCharArr[i][j].getUUID().getShortUUID()); 01552 } else { 01553 const uint8_t *longUUIDBytes = discoverCharArr[i][j].getUUID().getBaseUUID(); 01554 cUUID = UUID(longUUIDBytes); 01555 } 01556 if ((cUUID == buf_char_uuid) & (readmatchFlag == false)) { 01557 cyntecPrintOk(); 01558 uint16_t value = 0x00; 01559 deltaBLE.gattClient().write(GattClient::GATT_OP_WRITE_REQ, discoverCharArr[i][j].getConnectionHandle(), discoverCharArr[i][j].getValueHandle() + 1, 2, (uint8_t *)&value); 01560 readmatchFlag = true; 01561 return; 01562 } 01563 } 01564 } 01565 } 01566 01567 // no matched case, can not read 01568 if (readmatchFlag == false) { 01569 cyntecPrintError(CYNTEC_CMD_ERR_NO_MATCHED_ARGUMENT); 01570 } 01571 } 01572 //Silvia modify 01573 01574 static void cynBLEDataIntCommand(void) 01575 { 01576 cyntecPrintOk(); 01577 deltaBLE.gattServer().onDataWritten().add(onDataWrittenCallback); 01578 } 01579 static void cynBLEDisDataIntCommand(void) 01580 { 01581 cyntecPrintOk(); 01582 deltaBLE.gattServer().onDataWritten().detach(onDataWrittenCallback); 01583 } 01584 01585 #if BLE_DEBUG 01586 static void cynBLETestCommand(void) 01587 { 01588 // gill test 1021 01589 uint8_t bufVal[20] = {0}; 01590 //uint8_t valWrite[2] = {0x22,0x33}; 01591 //uint16_t bufhandle = 0x0001; 01592 //uint8_t valRead[2] = {0,0}; 01593 01594 // uint16_t handle = charAry[0][0]->getValueHandle(); // No used? 01595 GattAttribute& valueAttr = charAry[0][0]->getValueAttribute(); 01596 //valueAttr.setHandle(bufhandle); 01597 console.printf("Handle:%04X ",valueAttr.getHandle()); 01598 console.printf("UUID:%04X ",valueAttr.getUUID().getShortUUID()); 01599 01600 uint16_t* valueLenPtr = valueAttr.getLengthPtr(); 01601 deltaBLE.gattServer().read(valueAttr.getHandle(),bufVal,valueLenPtr); 01602 console.printf("gatt val[0][1]:%02X %02X\r\n",bufVal[0],bufVal[1]); 01603 } 01604 #endif 01605 01606 CyntecCommandEntry bleCommandSets[] = { 01607 // General 01608 #if BLE_DEBUG 01609 {"TEST", cynBLETestCommand, NULL, "test"}, 01610 #endif 01611 // 01612 #if SIMPLE_CMD_NAME 01613 //{"INT", cynBLEInitCommand, NULL, "Init BLE stack"},//Tsungta, INT is called in main.cpp 01614 {"GIO", cynBLEGPIOCommand, NULL, "Config gpio, Usage: <GPIO NO> <set|clear>"}, 01615 {"SLP", cynBLESystemOffCommand, NULL, "System off mode, Usage: <GPIO NO>"}, 01616 {"RST", cynResetCommand, NULL, "Soft reset"}, 01617 {"INF", cynBLEInfoCommand, NULL, "Get module information"}, 01618 {"POW", cynBLESetTxPowerCommand, NULL, "Set BLE tx power, Usage: <TX POWER>"}, 01619 {"NAM", cynBLENameCommand, NULL, "Set/Get friendly for BLE module, Usage: <LENGTH> <NAME>"}, 01620 // GATT 01621 {"GRS", cynRegServiceCommand, NULL, "Register standby service"}, 01622 {"GAC", cynGattCharCommand, NULL, "Set SIG defined characteristic or Create your own,Usage: <CHAR UUID> <PROPS> <VALUE>"}, 01623 {"GAS", cynGattServiceCommand, NULL, "Set SIG defined service or Create your own,Usage: <SERVICE UUID>"}, 01624 {"ADS", cynAdvertiseStartCommand, NULL, "Start broadcast advertise packet,Usage: <INTERVAL> <WINDOW>"}, 01625 {"ADP", cynAdvertiseStopCommand, NULL, "Stop broadcast advertise packet"}, 01626 {"SCS", cynBLEScanCommand, NULL, "Start to scan BLE device, Usage: <INTERVAL> <WINDOW> <TIMEOUT>"}, 01627 {"SCP", cynBLEScanStopCommand, NULL, "Stop to scan BLE device"}, 01628 {"CON", cynBLEConnectCommand, NULL, "Connect to specific BLE device by Device Address, Usage: <ADDR>"}, 01629 {"DCN", cynBLEDisconnectCommand, NULL, "Disconnection"}, 01630 {"ADR", cynBLEAddressCommand, NULL, "Set/Get Bluetooth address, Usage: <ADDR>"}, 01631 {"WRT", cynBLEUpdateDataCommand, NULL, "Update value of specific characteristics, Usage: <SERVICE UUID> <CHAR UUID> <TYPE> <VALUE>"}, 01632 {"RED", cynBLEReadDataCommand, NULL, "Read value of specific characteristics, Usage: <SERVICE UUID> <CHAR UUID>"}, 01633 {"EDI", cynBLEDataIntCommand, NULL, "Trigger remote write detection, give interrupt to Host."}, 01634 {"DDI", cynBLEDisDataIntCommand, NULL, "Disable remote write detection."}, 01635 //Silvia add BLE central commands 01636 {"CIN", cynBLECenInitCommand, NULL, "Init BLE Central stack"}, 01637 {"CRD", cynBLECenReadDataCommand, NULL, "BLE Central read value of specific characteristics, Usage: <SERVICE UUID> <CHAR UUID>"}, 01638 {"CWD", cynBLECenWriteDataCommand, NULL, "BLE Central write value to specific characteristics, Usage: <SERVICE UUID> <CHAR UUID> <TYPE> <VALUE>"}, 01639 {"CEN", cynBLECenEnNotifyCommand, NULL, "BLE Central enable notification of specific characteristics, Usage: <SERVICE UUID> <CHAR UUID>"}, 01640 {"CDN", cynBLECenDisNotifyCommand, NULL, "BLE Central disable notification of specific characteristics, Usage: <SERVICE UUID> <CHAR UUID>"}, 01641 {NULL, NULL, NULL, NULL}, 01642 #else 01643 //{"init", cynBLEInitCommand, NULL, "Init BLE stack"},//Tsungta, init is called in main.cpp 01644 {"gpio", cynBLEGPIOCommand, NULL, "Config gpio, Usage: <GPIO NO> <set|clear>"}, 01645 {"sleep", cynBLESystemOffCommand, NULL, "System off mode, Usage: <GPIO NO>"}, 01646 {"reset", cynResetCommand, NULL, "Soft reset"}, 01647 {"info", cynBLEInfoCommand, NULL, "Get module information"}, 01648 {"txPow", cynBLESetTxPowerCommand, NULL, "Set BLE tx power, Usage: <TX POWER>"}, 01649 {"name", cynBLENameCommand, NULL, "Set/Get friendly for BLE module, Usage: <LENGTH> <NAME>"}, 01650 // GATT 01651 {"regService", cynRegServiceCommand, NULL, "Register standby service"}, 01652 {"gattChar", cynGattCharCommand, NULL, "Set SIG defined characteristic or Create your own,Usage: <CHAR UUID> <PROPS> <VALUE>"}, 01653 {"gattService", cynGattServiceCommand, NULL, "Set SIG defined service or Create your own,Usage: <SERVICE UUID>"}, 01654 {"advStart", cynAdvertiseStartCommand, NULL, "Start broadcast advertise packet,Usage: <INTERVAL> <WINDOW>"}, 01655 {"advStop", cynAdvertiseStopCommand, NULL, "Stop broadcast advertise packet"}, 01656 {"scanStart", cynBLEScanCommand, NULL, "Start to scan BLE device, Usage: <INTERVAL> <WINDOW> <TIMEOUT>"}, //BLE central 01657 {"scanStop", cynBLEScanStopCommand, NULL, "Stop to scan BLE device"}, //BLE central 01658 {"connect", cynBLEConnectCommand, NULL, "Connect to specific BLE device by Device Address, Usage: <ADDR>"}, //Silvia modify, BLE central 01659 {"disconn", cynBLEDisconnectCommand, NULL, "Disconnection, Usage: cynb disconn"}, 01660 {"bleAddr", cynBLEAddressCommand, NULL, "Set/Get Bluetooth address, Usage: <ADDR>"}, 01661 {"update", cynBLEUpdateDataCommand, NULL, "Update value of specific characteristics, Usage: <SERVICE UUID> <CHAR UUID> <TYPE> <VALUE>"}, 01662 {"readData", cynBLEReadDataCommand, NULL, "Read value of specific characteristics, Usage: <SERVICE UUID> <CHAR UUID>"}, 01663 {"enInt", cynBLEDataIntCommand, NULL, "Trigger remote write detection, give interrupt to Host."}, 01664 {"disInt", cynBLEDisDataIntCommand, NULL, "Disable remote write detection."}, 01665 //Silvia add BLE central commands 01666 {"initBleCen", cynBLECenInitCommand, NULL, "Init BLE Central stack"}, 01667 {"cenReadData", cynBLECenReadDataCommand, NULL, "BLE Central read value of specific characteristics, Usage: <SERVICE UUID> <CHAR UUID>"}, 01668 {"cenWriteData", cynBLECenWriteDataCommand, NULL, "BLE Central write value to specific characteristics, Usage: <SERVICE UUID> <CHAR UUID> <TYPE> <VALUE>"}, 01669 {"cenEnNotify", cynBLECenEnNotifyCommand, NULL, "BLE Central enable notification of specific characteristics, Usage: <SERVICE UUID> <CHAR UUID>"}, 01670 {"cenDisNotify", cynBLECenDisNotifyCommand, NULL, "BLE Central disable notification of specific characteristics, Usage: <SERVICE UUID> <CHAR UUID>"}, 01671 {NULL, NULL, NULL, NULL}, 01672 #endif 01673 };
Generated on Tue Jul 12 2022 21:48:15 by 1.7.2