
this is using the mbed os version 5-13-1
Diff: source/main-https.cpp
- Revision:
- 74:f26e846adfe9
- Parent:
- 73:6f5021cbe752
- Child:
- 75:08eff6258e1b
--- a/source/main-https.cpp Thu Feb 28 18:13:48 2019 +0000 +++ b/source/main-https.cpp Sun Mar 10 09:46:06 2019 +0000 @@ -9,31 +9,24 @@ #include <mbed.h> #include "ble/BLE.h" //#include "BLE.h" -#include "mbed_trace.h" -#include "https_request.h" -#include "http_request.h" -#include "network-helper.h" #include "ATCmdParser.h" //#include "BLEDevice.h" #include "LEDService.h" #include "ble/services/UARTService.h" - +#include "common_config.h" +#include "ATCmdManager.h" UARTService *uart; DigitalOut alivenessLED(LED1, 0); DigitalOut actuatedLED(LED2, 0); -#define DEFAULT_BAUD_RATE 115200 -RawSerial *device; // tx, rx -UARTSerial *_serial; // tx, rx -ATCmdParser *_parser; +static RawSerial *device; // tx, rx +static UARTSerial *_serial; // tx, rx +static ATCmdParser *_parser; const static char DEVICE_NAME[] = "BLE-UART"; static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID}; -#define BUFFER_LEN 256 -#define TX_BUFFER_LEN 4*256 -#define RX_BUFFER_LEN 4*256 char buffer[BUFFER_LEN]; uint8_t TxBuffer[TX_BUFFER_LEN]; uint8_t RxBuffer[RX_BUFFER_LEN]; @@ -42,7 +35,30 @@ LEDService *ledServicePtr; + +/* allocate statically stacks for the three threads */ +//unsigned char rt_stk[1024]; +//unsigned char hp_stk[1024]; +//unsigned char lp_stk[1024]; +unsigned char btle_stk[1024]; +unsigned char wifi_stk[1024]; +unsigned char atcmd_stk[1024]; +static bool bleInitializationCompleted = false; + +/* creates three tread objects with different priorities */ +//Thread real_time_thread(osPriorityRealtime, 1024, &rt_stk[0]); +//Thread high_prio_thread(osPriorityHigh, 1024, &hp_stk[0]); +//Thread low_prio_thread(osPriorityNormal, 1024, &lp_stk[0]); +Thread btle_thread(BTLE_THREAD_PRIORITY, 1024, &btle_stk[0]); +Thread wifi_thread(WIFI_THREAD_PRIORITY, 1024, &wifi_stk[0]); +Thread atcmd_thread(ATCMD_THREAD_PRIORITY, 1024, &atcmd_stk[0]); + + +/* create a semaphore to synchronize the threads */ +Semaphore sync_sema; + Thread t; +#include "network-helper.h" /* List of trusted root CA certificates * currently two: GlobalSign, the CA for os.mbed.com and Let's Encrypt, the CA for httpbin.org @@ -51,8 +67,29 @@ */ #include "https_certificates.h" +// wifi demo +#include "wifi_demo.h" +// check free memory + +void performFreeMemoryCheck() +{ + // perform free memory check + int blockSize = 16; + int i = 1; + printf("Checking memory with blocksize %d char ...\n", blockSize); + while (true) { + char *p = (char *) malloc(i * blockSize); + if (p == NULL) + break; + free(p); + ++i; + } + printf("Ok for %d char\n", (i - 1) * blockSize); + +} + void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { (void) params; @@ -115,13 +152,31 @@ /* Initialization error handling should go here */ } + +/* handle BLE timouts */ +static int bleTimoutCount = 0; + +void printBleTimeoutMsg() +{ + bleTimoutCount++; + device->printf("\n --- BLE Times out!! bleTimoutCount = %d --- \n", bleTimoutCount); +} + +//void timeoutCallback(Gap::TimeoutEventCallback_t* context) { +void timeoutCallback(Gap::TimeoutSource_t timeoutSource) { + BLE &ble = BLE::Instance(); + eventQueue.call(printBleTimeoutMsg); +} + + + void printMacAddress() { /* Print out device MAC address to the console*/ Gap::AddressType_t addr_type; Gap::Address_t address; BLE::Instance().gap().getAddress(&addr_type, address); - printf("DEVICE MAC ADDRESS: "); + printf("\nDEVICE MAC ADDRESS: "); for (int i = 5; i >= 1; i--){ printf("%02x:", address[i]); } @@ -149,6 +204,7 @@ ble.gap().onDisconnection(disconnectionCallback); ble.gattServer().onDataWritten(onDataWrittenCallback); + ble.gap().onTimeout(timeoutCallback); bool initialValueForLEDCharacteristic = false; ledServicePtr = new LEDService(ble, initialValueForLEDCharacteristic); @@ -163,9 +219,11 @@ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ + ble.gap().setAdvertisingTimeout(300); /* 16 * 1000ms. */ ble.gap().startAdvertising(); printMacAddress(); + bleInitializationCompleted = true; } void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { @@ -184,6 +242,25 @@ } +void restartBleAdvertising() +{ + BLE &ble = BLE::Instance(); + + //ble.init(bleInitComplete); + // clear advertising payload + ble.gap().clearAdvertisingPayload(); + /* setup advertising */ + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + /* set up the services that can be discovered */ + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ + ble.gap().startAdvertising(); + eventQueue.dispatch(1000); // Dispatch time - 1000msec +} + static int uartExpectedRcvCount = 0; static int uartCharRcvCount = 0; static bool UartBusy = false; @@ -303,230 +380,74 @@ //RawSerial device(MBED_CONF_APP_UART1_TX, MBED_CONF_APP_UART1_RX); // tx, rx -int chunkNum; -void dump_response(HttpResponse* res) { - device->printf("Status: %d - %s\n", res->get_status_code(), res->get_status_message().c_str()); - - device->printf("Headers:\n"); - for (size_t ix = 0; ix < res->get_headers_length(); ix++) { - device->printf("\t%s: %s\n", res->get_headers_fields()[ix]->c_str(), res->get_headers_values()[ix]->c_str()); - } - device->printf("\nBody (%lu bytes):\n\n%s\n", res->get_body_length(), res->get_body_as_string().c_str()); -} - -void completed(){ - } -void dump_chunked_response(const char *at, uint32_t length) { - device->printf("\n Chunked response: Chunk %d : Total Bytes = %d\n", chunkNum , length); - //device->printf("\n Try Print Header as string:\n\n "); - //device->printf("recv %d [%.*s]\n", length, strstr((char *)at, "\r\n")-(char *)at, (char *)at); - //if(false) - if(chunkNum < 2) - for(int i=0; i < length; i++){ - - while(device->writeable()) - { - device->putc((uint8_t)at[i]); - } - //int resp = write( (const uint8_t *)at, (int) length, &completed, SERIAL_EVENT_TX_COMPLETE); - } - if(false) - for (size_t ix = 0; ix < length; ix++) { - device->printf("%02X: ", at[ix]); - if((ix % 32) == 0 and ix) - device->printf("\n"); - } - device->printf("\n\n"); - chunkNum++; - //device->printf("\nBody (%lu bytes):\n\n%s\n", res->get_body_length(), res->get_body_as_string().c_str()); -} // Wifi-demo void wifi_demo(NetworkInterface* network){ - if (!network) { - device->printf("Cannot connect to the network, see serial output\n"); - return 1; - } - - mbed_trace_init(); - - // GET request to os.mbed.com + int n = wifi_demo_func(network); + if(n > 0)// error { - chunkNum = 0; - device->printf("\n----- HTTPS GET request -----\n"); - - HttpsRequest* get_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_GET, "https://os.mbed.com/media/uploads/mbed_official/hello.txt", &dump_chunked_response); - - HttpResponse* get_res = get_req->send(); - if (!get_res) { - device->printf("HttpRequest failed (error code %d)\n", get_req->get_error()); - return 1; - } - device->printf("\n----- HTTPS GET response -----\n"); - dump_response(get_res); - delete get_req; + device->printf("\n --- Error running wifi demo --- \n"); } - - - - // Do a GET request to httpbin.org - { - chunkNum = 0; - device->printf("\n----- HTTP GET request to httpbin.org -----\n"); - - // By default the body is automatically parsed and stored in a buffer, this is memory heavy. - // To receive chunked response, pass in a callback as last parameter to the constructor. - HttpRequest* get_req = new HttpRequest(network, HTTP_GET, "http://httpbin.org/status/418"); +} - HttpResponse* get_res = get_req->send(); - if (!get_res) { - device->printf("HttpRequest failed (error code %d)\n", get_req->get_error()); - return 1; - } - - device->printf("\n----- HTTP GET response from httpbin.org -----\n"); - dump_response(get_res); - - delete get_req; - } - - - // Do a GET request to ovh.net - if(false) +// Wifi-demo2 +void wifi_demo2(){ + //int n = wifi_demo_func(network); + int n =5; + if(n > 0)// error { - chunkNum = 0; - device->printf("\n----- HTTP GET request to ovh.net -----\n"); - Timer t; - // By default the body is automatically parsed and stored in a buffer, this is memory heavy. - // To receive chunked response, pass in a callback as last parameter to the constructor. - t.start(); - HttpRequest* get_req = new HttpRequest(network, HTTP_GET, "http://www.ovh.net/files/1Mio.dat", &dump_chunked_response); - - HttpResponse* get_res = get_req->send(); - if (!get_res) { - device->printf("HttpRequest failed (error code %d)\n", get_req->get_error()); - return 1; - } - - device->printf("\n----- HTTP GET response from ovh.net -----\n"); - dump_response(get_res); - t.stop(); - device->printf("The time taken was %f seconds\n", t.read()); - - - delete get_req; + device->printf("\n --- Error running wifi demo --- \n"); } - - { - device->printf("\n----- HTTPS GET request (large file!) -----\n"); - - HttpsRequest* get_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_GET, "https://os.mbed.com/media/uploads/mbed_official/hello.txt"); +} - HttpResponse* get_res = get_req->send(); - if (!get_res) { - device->printf("HttpRequest failed (error code %d)\n", get_req->get_error()); - return 1; - } - /* - while (0 < (response = socket.recv(p, remaining))) { - p += response; - rcount += response; - remaining -= response; - } - */ - device->printf("\n----- HTTPS GET response -----\n"); - dump_response(get_res); - - - - delete get_req; - } - - // POST request to httpbin.org - { - device->printf("\n----- HTTPS POST request -----\n"); - - HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, "https://httpbin.org/post"); - post_req->set_header("Content-Type", "application/json"); - - const char body[] = "{\"hello\":\"world\"}"; - - HttpResponse* post_res = post_req->send(body, strlen(body)); - if (!post_res) { - device->printf("HttpRequest failed (error code %d)\n", post_req->get_error()); - return 1; - } - - device->printf("\n----- HTTPS POST response -----\n"); - dump_response(post_res); - - delete post_req; - } - - - // POST request to ws.dnanudge.io:80 - { - device->printf("\n----- HTTP POST request (http://ws.dnanudge.io/nudgebox/v1) -----\n"); +void reportGapState() +{ + BLE &ble = BLE::Instance(); + Gap::GapState_t gapState = ble.gap().getState(); + char connStr[20] = " Not Connected "; + char advStr[20] = " Not Advertising "; + char devName[20] = ""; + if(gapState.advertising){ + strncpy(advStr, " Advertising ", 20); + } + if(gapState.connected){ + strncpy(connStr, " Connected ", 20); + } + device->printf("\n Advertising Status = %s\n Connection Status = %s\n", advStr, connStr); + unsigned nLen; + ble_error_t error; + error = ble.gap().getDeviceName((uint8_t *) devName, &nLen); + if(error != BLE_ERROR_NONE) + { + device->printf("\n Error Reading BLE device Name \n"); + return; + } + devName[nLen] = NULL; + device->printf("\n BLE Device name = %s : Name Len %d\n", devName, nLen); + for(int i=0;i<8;i++) + device->putc(devName[i]); + +} - HttpRequest* post_req = new HttpRequest(network, HTTP_POST, "http://ws.dnanudge.io/nudgebox/v1"); - post_req->set_header("Host", "ws.dnanudge.io"); - post_req->set_header("Accept", "*/*"); - post_req->set_header("Content-Type", "application/octet-stream"); - post_req->set_header("Content-Length", "20"); - // 00 08 6a 48 f8 2d 8e 82 01 68 - const uint8_t body[] = {0x00, 0x08, 0x6a, 0x48, 0xf8, 0x2d, 0x8e, 0x82, 0x01, 0x68, - // 65 6c 6c 6f 00 00 67 c3 19 f8 - 0x65, 0x6c, 0x6c, 0x6f, 0x00, 0x00, 0x67, 0xc3, 0x19, 0xf8}; - - HttpResponse* post_res = post_req->send(body, 20); - if (!post_res) { - device->printf("HttpRequest failed (error code %d)\n", post_req->get_error()); - return 1; - } - - device->printf("\n----- HTTPS POST response -----\n"); - dump_response(post_res); - - delete post_req; +void printWait(int numSecs) +{ + printf("Waiting for %d seconds...\n", numSecs); + for(int i=0;i<numSecs;i++){ + printf("%d", i); + wait(0.5); + eventQueue.dispatch(500); // Dispatch time - 500msec } - +} - // POST request to httpbin.org - if(false) - { - device->printf("\n----- HTTPS POST request to AWS -----\n"); - - HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, "https://q6bc0dxw7f.execute-api.eu-west-2.amazonaws.com/test/samples/v1"); - post_req->set_header("Content-Type", "application/json"); - - const char body[] = - "{" - "\"firstName\": \"Maria\", " - "\"lastName\": \"Huntera\", " - "\"dob\": \"1970-12-03\", " - "\"mobile\": \"07841887580\", " - "\"cartridgeId\": \"DN00000000RMPOE\", " - "\"labSampleId\": \"DYYAK\"" - "}"; - HttpResponse* post_res = post_req->send(body, strlen(body)); - if (!post_res) { - device->printf("HttpRequest failed (error code %d)\n", post_req->get_error()); - return 1; - } - - device->printf("\n----- HTTPS POST response from AWS -----\n"); - dump_response(post_res); - - delete post_req; - } - } +static int reset_counter = 0; int main() { + reset_counter++; //RawSerial *device(USBTX, USBRX); // tx, rx device = new RawSerial(USBTX, USBRX, DEFAULT_BAUD_RATE); - device->printf("\n --- Running UART-BLE-UartService --- \n"); + device->printf("\n --- Running UART-BLE-UartService --- (rst_cnt = %d)\n", reset_counter); // Start the event queue //t.start(callback(&eventQueue, &EventQueue::dispatch_forever)); @@ -537,26 +458,125 @@ //////////////////////////////////////////////////////////////////////////////// // BLE Initialization ///////////////////////////////////////////////////////// device->printf("\n --- about to instantiate BLE instance --- \n"); - device->getc(); //cbMAIN_driverLock(); BLE &ble = BLE::Instance(); device->printf("\n --- BLE Instance Instantiated --- \n"); //ble.onEventsToProcess(scheduleBleEventsProcessing); //device->printf("\n --- BLE scheduleBleEventsProcessing setup --- \n"); //ble.init(bleInitComplete); - bleInitialization(); + btle_thread.start(callback(bleInitialization)); //cbMAIN_driverUnlock(); + + device->printf("\n --- Waiting for BLE Initialization to be completed --- \n"); + int i = 0; + while(!ble.hasInitialized() && i < 20){ + // dispatch function + eventQueue.dispatch(1000); // Dispatch time - 1000msec + // 400 msec - Only 2 set of events will be dispatched as period is 200 msec + + device->putc('0'+(i++ % 10)); + } + btle_thread.join(); + if(i < 20) device->printf("\n --- BLE Initialization completed --- \n"); - device->printf("\n Press any key to start Wifi demo: "); + else + device->printf("\n --- BLE Initialization failed --- \n"); + wait(1); // wait for advertising interval so advertising has started + //reportGapState(); + //device->printf("\n Press any key to stop BLE advertising: "); + //ble.gap().stopAdvertising(); + //ble.shutdown(); + //reportGapState(); + //device->getc(); + //device->printf("\n Press any key to restart BLE advertising: "); + //device->getc(); + //restartBleAdvertising(); + //reportGapState(); + //device->printf("\n Press any key to stop BLE advertising: "); + //device->getc(); + //device->baud(115200); + //ble.gap().stopAdvertising(); + //ble.shutdown(); + reportGapState(); + //////////////////////////////////////////////////////////////////////////////// + // BLE Initialization ///////////////////////////////////////////////////////// +#ifdef false + device->printf("\n --- about to shutdown BLE instance --- \n"); + device->printf("\n Press any key: "); device->getc(); + //ble.gap().clearAdvertisingPayload(); + ble.gap().stopAdvertising(); + ble.gap().reset(); + //ble.shutdown(); + //delete ble; //////////////////////////////////////////////////////////////////////////////////// - - //device->baud(115200); +#endif + btle_thread.start(callback(&eventQueue, &EventQueue::dispatch_forever)); + printWait(30); + //device->printf("\n Press any key to start Wifi demo: "); + //device->getc(); + int start = Kernel::get_ms_count(); NetworkInterface* network = connect_to_default_network_interface(); + int stop = Kernel::get_ms_count(); + device->printf("\n The Wifi Network scan took %d ms or %4.1f seconds\n", (stop - start), (float)((stop - start)/1000.0)); // run on separate thread; - t.start(wifi_demo(network)); - network->disconnect(); + t.start(callback(wifi_demo, network)); + //t.start(wifi_demo2()); t.join(); + //network->disconnect(); + //delete network; + printMacAddress(); + reportGapState(); + //device->printf("\n Press any key to restart BLE : "); + //device->getc(); + + + + //////////////////////////////////////////////////////////////////////////////// + // BLE Initialization ///////////////////////////////////////////////////////// + //device->printf("\n --- about to shutdown BLE instance --- \n"); + //ble.shutdown(); + //ble.gap().clearAdvertisingPayload(); + //delete ble; + //device->printf("\n --- about to instantiate new BLE instance --- \n"); + //cbMAIN_driverLock(); + //BLE &ble = BLE::Instance(); + //device->printf("\n --- BLE Instance Instantiated --- \n"); + //ble.onEventsToProcess(scheduleBleEventsProcessing); + //device->printf("\n --- BLE scheduleBleEventsProcessing setup --- \n"); + //ble.init(bleInitComplete); +#ifdef false + device->printf("\n --- Restarting BLE Initialization --- \n"); + ble.gap().reset(); + + btle_thread.start(callback(bleInitialization)); + btle_thread.join(); + + //ble.init(bleInitComplete); + //cbMAIN_driverUnlock(); + + device->printf("\n --- Waiting for BLE Initialization to be completed --- \n"); + i = 0; + while(!ble.hasInitialized() && i < 20){ + // dispatch function + eventQueue.dispatch(1000); // Dispatch time - 1000msec + // 400 msec - Only 2 set of events will be dispatched as period is 200 msec + + device->putc('0'+(i++ % 10)); + } + if(i < 20) + device->printf("\n --- BLE Initialization completed --- \n"); + else + device->printf("\n --- BLE Initialization failed --- \n"); +#endif + wait(1); // wait for advertising interval so advertising has started + reportGapState(); + + + //reportGapState(); + //restartBleAdvertising(); + //printMacAddress(); + //reportGapState(); for(int i=0;i<255;i++) { @@ -564,11 +584,12 @@ } int n; //ReadUartBytes(RxBuffer, RX_BUFFER_LEN, 4); + reportGapState(); device->printf("\n\n\nEnter # of expected bytes: "); n = ReadUartBytes(RxBuffer, RX_BUFFER_LEN, 4, true); - int rxLen = (int) 100*(RxBuffer[0]-'0') + 10*(RxBuffer[1]-'0') + (RxBuffer[2]-'0'); + uint8_t rxLen = (uint8_t) (100*(RxBuffer[0]-'0') + 10*(RxBuffer[1]-'0') + (RxBuffer[2]-'0')) %256; device->printf("\n\nExpected # of Received Bytes = %d\n", rxLen); - BackGndUartRead(RxBuffer, RX_BUFFER_LEN, rxLen); + BackGndUartRead(RxBuffer, RX_BUFFER_LEN, (int) rxLen); //device->printf("--- Writing back received data --- \n\n"); //n = WriteUartBytes(RxBuffer, TX_BUFFER_LEN, rxLen); //write("\n\ntesting Serial Write\n", 40); //, checkUartReceive, SERIAL_EVENT_TX_COMPLETE); @@ -576,14 +597,23 @@ device->printf("\nATCmdParser with ESP8266 example"); device->printf("\n Waiting for 2 minutes "); - wait(120); - eventQueue.dispatch_forever(); - return 0; + wait(2); + device->printf("\n Waiting finished!!!\n\n "); + reportGapState(); + //eventQueue.dispatch_forever(); + + + + //btle_thread.start(callback(&eventQueue, &EventQueue::dispatch_forever)); device->printf("\n About to delete RawSerial device instance "); delete device; + ATCmdManager *aTCmdManager = new ATCmdManager(USBTX, USBRX, true); +#ifdef false _serial = new UARTSerial(USBTX, USBRX, DEFAULT_BAUD_RATE); + _parser = new ATCmdParser(_serial); + _parser->printf("\n _serial printf being used for this \n\n"); + device->printf("\n device printf being used now \n\n"); printf("\n ATCmdParser printf being used now \n\n"); - _parser = new ATCmdParser(_serial); _parser->debug_on( 1 ); _parser->set_delimiter( "\r\n" ); @@ -598,9 +628,11 @@ printf("\nATCmdParser: Retrieving FW version failed"); return -1; } - + //parser.recv("+CIPDATA:%d,", &len); + //parser.read(buffer, len); printf("\nDone\n"); - +#endif + performFreeMemoryCheck(); //eventQueue.dispatch_forever(); //t.start(callback(&eventQueue, &EventQueue::dispatch_forever));