This CLI (Command Line Interface) is based mbed-os. Both NNN50 and NQ620 are supported.

Fork of NNN40_CLI by Delta

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ble_cli.cpp Source File

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 };