Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
