boting ren / Mbed OS BLEClient_mbedDevConn
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Copyright (c) 2015 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "simpleclient.h"
00018 #include <string>
00019 #include <sstream>
00020 #include <vector>
00021 #include "mbed-trace/mbed_trace.h"
00022 #include "mbedtls/entropy_poll.h"
00023 
00024 #include <events/mbed_events.h>
00025 #include <mbed.h>
00026 #include "ble/BLE.h"
00027 #include "ble/DiscoveredCharacteristic.h"
00028 #include "ble/DiscoveredService.h"
00029 
00030 #include "security.h"
00031 
00032 //#include "mbed.h"
00033 #include "rtos.h"
00034 
00035 #if MBED_CONF_APP_NETWORK_INTERFACE == WIFI
00036 #include "ESP8266Interface.h"
00037 ESP8266Interface esp(MBED_CONF_APP_WIFI_TX, MBED_CONF_APP_WIFI_RX);
00038 #elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
00039 #include "EthernetInterface.h"
00040 EthernetInterface eth;
00041 #elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_LOWPAN_ND
00042 #define MESH
00043 #include "NanostackInterface.h"
00044 LoWPANNDInterface mesh;
00045 #elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_THREAD
00046 #define MESH
00047 #include "NanostackInterface.h"
00048 ThreadInterface mesh;
00049 #endif
00050 
00051 #if defined(MESH)
00052 #if MBED_CONF_APP_MESH_RADIO_TYPE == ATMEL
00053 #include "NanostackRfPhyAtmel.h"
00054 NanostackRfPhyAtmel rf_phy(ATMEL_SPI_MOSI, ATMEL_SPI_MISO, ATMEL_SPI_SCLK, ATMEL_SPI_CS,
00055                            ATMEL_SPI_RST, ATMEL_SPI_SLP, ATMEL_SPI_IRQ, ATMEL_I2C_SDA, ATMEL_I2C_SCL);
00056 #elif MBED_CONF_APP_MESH_RADIO_TYPE == MCR20
00057 #include "NanostackRfPhyMcr20a.h"
00058 NanostackRfPhyMcr20a rf_phy(MCR20A_SPI_MOSI, MCR20A_SPI_MISO, MCR20A_SPI_SCLK, MCR20A_SPI_CS, MCR20A_SPI_RST, MCR20A_SPI_IRQ);
00059 #endif //MBED_CONF_APP_RADIO_TYPE
00060 #endif //MESH
00061 
00062 #ifndef MESH
00063 // This is address to mbed Device Connector
00064 #define MBED_SERVER_ADDRESS "coap://api.connector.mbed.com:5684"
00065 #else
00066 // This is address to mbed Device Connector
00067 #define MBED_SERVER_ADDRESS "coaps://[2607:f0d0:2601:52::20]:5684"
00068 #endif
00069 
00070 Serial output(USBTX, USBRX);
00071 
00072 // Status indication
00073 DigitalOut red_led(LED1);
00074 DigitalOut green_led(LED2);
00075 DigitalOut blue_led(LED3);
00076 Ticker status_ticker;
00077 // Ren, begin
00078 enum charType {
00079     PRESSURE,
00080     TEMPERATURE,
00081     HUMIDITY
00082 };
00083 const char * dbg_CharType[HUMIDITY+1]={"Pressure","Temperature","Humidity"};
00084 const char * objName[HUMIDITY+1]={"3323","3303","3304"};
00085 static bool is_active[HUMIDITY+1];
00086 static float dataprint[HUMIDITY+1]={0,0,0};
00087 /*
00088  * The BME280 sensor contains 3 float properties.
00089  * Those are updated once BLE Gatt client read the values.
00090  */
00091 class BME280Resource {
00092 public:
00093     BME280Resource() {
00094         // create Pressure object '3323'.
00095         for(int m=0; m<HUMIDITY+1; m++) {
00096             M2MObjectInstance* tmp_inst;
00097             bme280[m] = M2MInterfaceFactory::create_object(objName[m]);
00098             tmp_inst = bme280[m] ->create_object_instance();
00099             tmp_res[m] = tmp_inst->create_dynamic_resource("5700", dbg_CharType[m],
00100                     M2MResourceInstance::STRING, true /* observable */);
00101             tmp_res[m]->set_operation(M2MBase::GET_ALLOWED);
00102             tmp_res[m]->set_value((uint8_t*)"0.0", 3);
00103         }
00104     }
00105 
00106     void set_bme280_value(float val, int h){
00107         char tmp_buf[50];
00108         int len;
00109         if (h<PRESSURE || h>HUMIDITY) {
00110             printf("data type h (input) is wrong!!");
00111             return;
00112         }
00113         if (h==HUMIDITY)
00114             len=sprintf(tmp_buf,"%0.2f%%",val);
00115         else if (h==PRESSURE)
00116             len=sprintf(tmp_buf,"%0.1f hPa",val);
00117         else
00118             len=sprintf(tmp_buf,"%0.2f degC",val);
00119 
00120         tmp_res[h]->set_value((uint8_t*)tmp_buf, len);
00121         //printf("set_value(tmp_bug=%s\r\n", tmp_buf);
00122     }
00123 
00124 
00125     M2MObject* get_object(int idx) {
00126         if (idx<PRESSURE || idx>HUMIDITY)    return NULL;
00127         return bme280[idx];
00128     }
00129 private:
00130     M2MObject*  bme280[HUMIDITY+1];
00131 //    M2MObjectInstance* tmp_inst[HUMIDITY+1];
00132     M2MResource* tmp_res[HUMIDITY+1];
00133 };
00134 
00135 static BME280Resource *demo1;
00136 // end of BME280 resource definition
00137 
00138 
00139 /************************************************************BLE Stuff from here *********************************/
00140 BLE &ble = BLE::Instance();
00141 static DiscoveredCharacteristic bme280Characteristic[HUMIDITY+1];
00142 static bool triggerLedCharacteristic;
00143 static const char PEER_NAME[] = "BME280";
00144 
00145 
00146 static EventQueue eventQueue(
00147     /* event count */ 16 * /* event size */ 32
00148 );
00149 
00150 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {
00151     // parse the advertising payload, looking for data type COMPLETE_LOCAL_NAME
00152     // The advertising payload is a collection of key/value records where
00153     // byte 0: length of the record excluding this byte
00154     // byte 1: The key, it is the type of the data
00155     // byte [2..N] The value. N is equal to byte0 - 1
00156 
00157     //printf("Starting advertisementCallback...\r\n");
00158     for (uint8_t i = 0; i < params->advertisingDataLen; ++i) {
00159 
00160         const uint8_t record_length = params->advertisingData[i];
00161         if (record_length == 0) {
00162             continue;
00163         }
00164         const uint8_t type = params->advertisingData[i + 1];
00165         const uint8_t* value = params->advertisingData + i + 2;
00166         const uint8_t value_length = record_length - 1;
00167 
00168         if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
00169             if ((value_length == sizeof(PEER_NAME)) && (memcmp(value, PEER_NAME, value_length) == 0)) {
00170                 printf(
00171                     "adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
00172                     params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2],
00173                     params->peerAddr[1], params->peerAddr[0], params->rssi, params->isScanResponse, params->type
00174                 );
00175                 BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);
00176                 break;
00177             }
00178         }
00179         i += record_length;
00180     }
00181 }
00182 
00183 void serviceDiscoveryCallback(const DiscoveredService *service) {
00184     if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
00185         printf("S type short UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());
00186     } else {
00187         printf("S type long UUID-");
00188         const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
00189         for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
00190             printf("%02x", longUUIDBytes[i]);
00191         }
00192         printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());
00193     }
00194 }
00195 
00196 /***
00197     This function called read() initially, following read() calls
00198     are repeated inside triggerRead function
00199 ***/
00200 void updateLedCharacteristic(void) {
00201     if (!BLE::Instance().gattClient().isServiceDiscoveryActive()) {
00202         //printf("02  updateLedCharacteristic\n");
00203         for(int g=0; g<HUMIDITY+1; g++) {
00204             if (is_active[g])    bme280Characteristic[g].read();
00205         }
00206     }
00207 }
00208 
00209 
00210 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) {
00211     int tmp_uuid;
00212     tmp_uuid=characteristicP->getUUID().getShortUUID();
00213     printf("  C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
00214     if ((tmp_uuid < GattCharacteristic::UUID_PRESSURE_CHAR) ||
00215         (tmp_uuid > GattCharacteristic::UUID_HUMIDITY_CHAR))     return;
00216     triggerLedCharacteristic = true;
00217     if (tmp_uuid == GattCharacteristic::UUID_PRESSURE_CHAR) {
00218         bme280Characteristic[PRESSURE] = *characteristicP;    is_active[PRESSURE] = true;
00219         printf(" is_active[PRESSURE] = true\r\n");
00220     }
00221     else if (tmp_uuid == GattCharacteristic::UUID_TEMPERATURE_CHAR) {
00222         bme280Characteristic[TEMPERATURE] = *characteristicP;    is_active[TEMPERATURE] = true;
00223         printf(" is_active[TEMPERATURE] = true\r\n");
00224    } else {
00225         bme280Characteristic[HUMIDITY] = *characteristicP;    is_active[HUMIDITY] = true;
00226         printf(" is_active[HUMIDITY] = true\r\n");
00227    }
00228 }
00229 
00230 void discoveryTerminationCallback(Gap::Handle_t connectionHandle) {
00231     printf("terminated SD for handle %u\r\n", connectionHandle);
00232     if (triggerLedCharacteristic) {
00233         triggerLedCharacteristic = false;
00234         eventQueue.call(updateLedCharacteristic);
00235     }
00236 }
00237 
00238 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) {
00239     int ret;
00240     printf("Connected to BME280 now...\r\n");
00241     if (params->role == Gap::CENTRAL) {
00242         BLE &ble = BLE::Instance();
00243         ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
00244         // Ren, connect to ENVIRONMENT service
00245         ret=ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, GattService::UUID_ENVIRONMENTAL_SERVICE);
00246         printf("ble.gattClient().launchServiceDiscovery = %d\r\n", ret);
00247     }
00248 }
00249 
00250 //ASHOK's triggerRead function
00251 
00252 void triggerRead(const GattReadCallbackParams *response) {
00253     int k=0;
00254     uint8_t dataforClient[4] = {0,0,0,0};
00255     uint32_t final_dataforClient = 0;
00256     for(int j=0; j<HUMIDITY+1; j++) {
00257         if (is_active[j]) {
00258             if (response->handle == bme280Characteristic[j].getValueHandle()){
00259                 if ( response-> len > 4) {
00260                     printf("response-> len is wrong :%d, %s, skipping read", response-> len, dbg_CharType[j]);
00261                     break;
00262                 }
00263                 for(int i=0; i< response-> len; i++) {
00264                     dataforClient[i] = response -> data[i];
00265                 }
00266                 printf("%d B, ", response->len);
00267                 //BLE packet contains 4 bytes of 8 bit int's each. Combine all of them to form a single 32-bit int.
00268                 final_dataforClient = ((uint32_t)dataforClient[3]<<24) | (dataforClient[2]<<16) | (dataforClient[1] << 8) | (dataforClient[0]);
00269                 //Ren debug
00270                 dataprint[j] = ( j==PRESSURE)?   (float) final_dataforClient/10 : (float) final_dataforClient/100;
00271                 demo1->set_bme280_value(dataprint[j], j);
00272                 if (j==HUMIDITY) {
00273                     k=0;   printf("%s  = %0.2f%%   ", dbg_CharType[j], dataprint[j]);
00274                 } else
00275                 {
00276                     k=j+1;
00277                     if(j==PRESSURE)    printf("%s  = %0.1f hPa   ", dbg_CharType[j], dataprint[j]);
00278                     else   printf("%s  = %0.2f degC   ", dbg_CharType[j], dataprint[j]);
00279                 }
00280                 break;
00281             }
00282         }
00283     }
00284     printf("\r\n");
00285     bme280Characteristic[k].read();
00286 }
00287 
00288 // BLE disconnected
00289 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) {
00290     printf("BLE disconnected\r\n");
00291     /* Start scanning and try to connect again */
00292     BLE::Instance().gap().startScan(advertisementCallback);
00293 }
00294 
00295 void onBleInitError(BLE &ble, ble_error_t error)
00296 {
00297     /* Initialization error handling should go here */
00298     printf("BLE Error = %u\r\n", error);
00299 }
00300 
00301 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
00302 {
00303     printf("I'm inside BLE init Complete\r\n");
00304     BLE&        ble   = params->ble;
00305     ble_error_t error = params->error;
00306 
00307     if (error != BLE_ERROR_NONE) {
00308         /* In case of error, forward the error handling to onBleInitError */
00309         onBleInitError(ble, error);
00310         return;
00311     }
00312 
00313     /* Ensure that it is the default instance of BLE */
00314     if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
00315         printf("Not the default instance\r\n");
00316         return;
00317     }
00318 
00319     // Ren, clear discovered Characteristic at beginning
00320     for(int i=0; i<HUMIDITY+1; i++)   {
00321         dataprint[i]=0.0;     is_active[i]=false;
00322     }
00323 
00324     ble.gap().onDisconnection(disconnectionCallback);
00325     ble.gap().onConnection(connectionCallback);
00326 
00327     // On reading data, call triggerRead function.
00328     ble.gattClient().onDataRead(triggerRead);
00329 
00330     // scan interval: 400ms and scan window: 400ms.
00331     // Every 400ms the device will scan for 400ms
00332     // This means that the device will scan continuously.
00333     ble.gap().setScanParams(400, 400);
00334     error =   ble.gap().startScan(advertisementCallback);
00335     printf("BLE Error startScan = %u\r\n", error);
00336 
00337 }
00338 
00339 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
00340     BLE &ble = BLE::Instance();
00341     eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
00342 }
00343 
00344 /************************************************************BLE Stuff to here *********************************/
00345 
00346 void blinky() {
00347     green_led = !green_led;
00348 }
00349 
00350 // These are example resource values for the Device Object
00351 struct MbedClientDevice device = {
00352     "Manufacturer_String",      // Manufacturer
00353     "Type_String",              // Type
00354     "ModelNumber_String",       // ModelNumber
00355     "SerialNumber_String"       // SerialNumber
00356 };
00357 
00358 // Instantiate the class which implements LWM2M Client API (from simpleclient.h)
00359 MbedClient mbed_client(device);
00360 
00361 // Network interaction must be performed outside of interrupt context
00362 Semaphore updates(0);
00363 volatile bool registered = false;
00364 volatile bool clicked = false;
00365 osThreadId mainThread;
00366 
00367 
00368 #ifdef TARGET_K64F
00369 // Set up Hardware interrupt button.
00370 InterruptIn obs_button(SW2);
00371 InterruptIn unreg_button(SW3);
00372 #else
00373 //In non K64F boards , set up a timer to simulate updating resource,
00374 // there is no functionality to unregister.
00375 Ticker timer;
00376 #endif
00377 
00378 /*
00379  * The button contains one property (click count).
00380  * When `handle_button_click` is executed, the counter updates.
00381  */
00382 class ButtonResource {
00383 public:
00384     ButtonResource(): counter(0) {
00385         // create ObjectID with metadata tag of 'BTN_SW2', which is 'digital input'
00386         btn_object = M2MInterfaceFactory::create_object("BTN_SW2");
00387         M2MObjectInstance* btn_inst = btn_object->create_object_instance();
00388         // create resource with ID '5501', which is digital input counter
00389         M2MResource* btn_res = btn_inst->create_dynamic_resource("5501", "Button",
00390             M2MResourceInstance::INTEGER, true /* observable */);
00391         // we can read this value
00392         btn_res->set_operation(M2MBase::GET_ALLOWED);
00393         // set initial value (all values in mbed Client are buffers)
00394         // to be able to read this data easily in the Connector console, we'll use a string
00395         btn_res->set_value((uint8_t*)"0", 1);
00396     }
00397 
00398     ~ButtonResource() {
00399     }
00400 
00401     M2MObject* get_object() {
00402         return btn_object;
00403     }
00404 
00405     /*
00406      * When you press the button, we read the current value of the click counter
00407      * from mbed Device Connector, then up the value with one.
00408      */
00409     void handle_button_click() {
00410         M2MObjectInstance* inst = btn_object->object_instance();
00411         M2MResource* res = inst->resource("5501");
00412 
00413         // up counter
00414         counter++;
00415         printf("handle_button_click, new value of counter is %d\r\n", counter);
00416         // serialize the value of counter as a string, and tell connector
00417         char buffer[20];
00418         int size = sprintf(buffer,"%d",counter);
00419         res->set_value((uint8_t*)buffer, size);
00420     }
00421 
00422 private:
00423     M2MObject* btn_object;
00424     uint16_t counter;
00425 };
00426 
00427 
00428 void unregister() {
00429     registered = false;
00430     updates.release();
00431 }
00432 
00433 void button_clicked() {
00434     clicked = true;
00435     updates.release();
00436 }
00437 
00438 // debug printf function
00439 void trace_printer(const char* str) {
00440     printf("%s\r\n", str);
00441 }
00442 
00443 /****************************************************************More BLE Stuff from here****************/
00444 //BLE thread init and further calls to other BLE methods.
00445 void BLE_thread_init(void){
00446     printf("I'm inside BLE thread_init.....\r\n");
00447     eventQueue.call_every(500, blinky);
00448     //Schedule events before starting the thread since there might be some missed events while scanning / pairing.
00449     ble.onEventsToProcess(scheduleBleEventsProcessing);
00450     ble.init(bleInitComplete);
00451     //Loop forever the BLE thread
00452     eventQueue.dispatch_forever();
00453 }
00454 
00455 /****************************************************************More BLE Stuff  to here****************/
00456 
00457 // Entry point to the program
00458 int main() {
00459 
00460     unsigned int seed;
00461     size_t len;
00462 
00463     //Create a new thread for BLE
00464     Thread BLE_thread;
00465 
00466 
00467 #ifdef MBEDTLS_ENTROPY_HARDWARE_ALT
00468     // Used to randomize source port
00469     mbedtls_hardware_poll(NULL, (unsigned char *) &seed, sizeof seed, &len);
00470 
00471 #elif defined MBEDTLS_TEST_NULL_ENTROPY
00472 
00473 #warning "mbedTLS security feature is disabled. Connection will not be secure !! Implement proper hardware entropy for your selected hardware."
00474     // Used to randomize source port
00475     mbedtls_null_entropy_poll( NULL,(unsigned char *) &seed, sizeof seed, &len);
00476 
00477 #else
00478 
00479 #error "This hardware does not have entropy, endpoint will not register to Connector.\
00480 You need to enable NULL ENTROPY for your application, but if this configuration change is made then no security is offered by mbed TLS.\
00481 Add MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES and MBEDTLS_TEST_NULL_ENTROPY in mbed_app.json macros to register your endpoint."
00482 
00483 #endif
00484 
00485     srand(seed);
00486     red_led = 1;
00487     blue_led = 1;
00488     status_ticker.attach_us(blinky, 250000);
00489     // Keep track of the main thread
00490     mainThread = osThreadGetId();
00491 
00492     // Sets the console baud-rate
00493     output.baud(9600);
00494 
00495     output.printf("Starting mbed Client example...\r\n");
00496 
00497     mbed_trace_init();
00498     mbed_trace_print_function_set(trace_printer);
00499     NetworkInterface *network_interface = 0;
00500     int connect_success = -1;
00501 #if MBED_CONF_APP_NETWORK_INTERFACE == WIFI
00502     output.printf("\n\rUsing WiFi \r\n");
00503     output.printf("\n\rConnecting to WiFi..\r\n");
00504     connect_success = esp.connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD);
00505     network_interface = &esp;
00506 #elif MBED_CONF_APP_NETWORK_INTERFACE == ETHERNET
00507     output.printf("Using Ethernet\r\n");
00508     connect_success = eth.connect();
00509     network_interface = &eth;
00510 #endif
00511 #ifdef MESH
00512     output.printf("Using Mesh\r\n");
00513     output.printf("\n\rConnecting to Mesh..\r\n");
00514     mesh.initialize(&rf_phy);
00515     connect_success = mesh.connect();
00516     network_interface = &mesh;
00517 #endif
00518     if(connect_success == 0) {
00519         output.printf("\n\rConnected to Network successfully\r\n");
00520     } else {
00521         output.printf("\n\rConnection to Network Failed %d! Exiting application....\r\n", connect_success);
00522         return 0;
00523     }
00524     const char *ip_addr = network_interface->get_ip_address();
00525     if (ip_addr) {
00526         output.printf("IP address %s\r\n", ip_addr);
00527     } else {
00528         output.printf("No IP address\r\n");
00529     }
00530 
00531     // create our button resources
00532     ButtonResource button_resource;
00533 #ifdef TARGET_K64F
00534     // On press of SW3 button on K64F board, example application
00535     // will call unregister API towards mbed Device Connector
00536     //unreg_button.fall(&mbed_client,&MbedClient::test_unregister);
00537     unreg_button.fall(&unregister);
00538 
00539     // Observation Button (SW2) press will send update of endpoint resource values to connector
00540     obs_button.fall(&button_clicked);
00541 #else
00542     // Send update of endpoint resource values to connector every 5 seconds periodically
00543     timer.attach(&button_clicked, 5.0);
00544 #endif
00545 
00546     // Create endpoint interface to manage register and unregister
00547     mbed_client.create_interface(MBED_SERVER_ADDRESS, network_interface);
00548 
00549     // Create Objects of varying types, see simpleclient.h for more details on implementation.
00550     M2MSecurity* register_object = mbed_client.create_register_object(); // server object specifying connector info
00551     M2MDevice*   device_object   = mbed_client.create_device_object();   // device resources object
00552 
00553     // Create list of Objects to register
00554     M2MObjectList object_list;
00555 
00556     // Add objects to list
00557     object_list.push_back(device_object);
00558     object_list.push_back(button_resource.get_object());
00559     // add bme280 data objects
00560     if (demo1==NULL)   {
00561         //  Create bme280 instance
00562         demo1=new BME280Resource();
00563           printf("created bme280 instance now!!\r\n");
00564     }
00565     object_list.push_back(demo1->get_object(PRESSURE));
00566     object_list.push_back(demo1->get_object(TEMPERATURE));
00567     object_list.push_back(demo1->get_object(HUMIDITY));
00568 
00569     // Set endpoint registration object
00570     mbed_client.set_register_object(register_object);
00571 
00572     // Register with mbed Device Connector
00573     mbed_client.test_register(register_object, object_list);
00574     registered = true;
00575 
00576     //Start BLE thread after connection is established to device connector. Else, there is conflict.
00577       BLE_thread.start(BLE_thread_init);
00578     // waiting for completion of BLE_thread_init
00579     Thread::wait(2000);
00580 
00581     while (true) {
00582 
00583       printf("inside main for client\r\n");
00584         triggerLedCharacteristic = false;
00585 
00586         updates.wait(25000);
00587         if(registered) {
00588             if(!clicked) {
00589                 //printf("Inside registered ... clicked \r\n");
00590                 mbed_client.test_update_register();
00591             }
00592         } else {   // not registered, then stop;
00593             break;
00594         }
00595         if(clicked) {
00596            clicked = false;
00597            button_resource.handle_button_click();
00598         }
00599 
00600     }
00601 
00602     mbed_client.test_unregister();
00603     status_ticker.detach();
00604 }