this is using the mbed os version 5-13-1
Diff: source/main-https.cpp
- Revision:
- 73:6f5021cbe752
- Child:
- 74:f26e846adfe9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/main-https.cpp Thu Feb 28 18:13:48 2019 +0000
@@ -0,0 +1,617 @@
+#define MBED_CONF_MBED_TRACE_ENABLE 1
+
+#include "select-demo.h"
+
+#if DEMO == DEMO_HTTPS
+
+//#include "mbed.h"
+#include <events/mbed_events.h>
+#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"
+
+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;
+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];
+static EventQueue eventQueue(/* event count */ 20 * EVENTS_EVENT_SIZE);
+//static EventQueue eventQueue2(/* event count */ 10 * EVENTS_EVENT_SIZE);
+
+LEDService *ledServicePtr;
+
+Thread t;
+
+/* List of trusted root CA certificates
+ * currently two: GlobalSign, the CA for os.mbed.com and Let's Encrypt, the CA for httpbin.org
+ *
+ * To add more root certificates, just concatenate them.
+ */
+#include "https_certificates.h"
+
+
+
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
+{
+ (void) params;
+ BLE::Instance().gap().startAdvertising();
+}
+
+void blinkCallback(void)
+{
+ alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */
+}
+
+void EchoBleUartReceived()
+{
+ uart->writeString(buffer);
+ uart->writeString("\n"); //flushes uart output buffer and sends data
+}
+
+/**
+ * This callback allows the LEDService to receive updates to the ledState Characteristic.
+ *
+ * @param[in] params
+ * Information about the characterisitc being updated.
+ */
+void onDataWrittenCallback(const GattWriteCallbackParams *params) {
+ if ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) {
+ actuatedLED = *(params->data);
+ }
+ else if ((uart != NULL) && (params->handle == uart->getTXCharacteristicHandle())) {
+ uint16_t bytesRead = params->len;
+
+ printf("received %u bytes\n\r ", bytesRead);
+
+ if(bytesRead >= 255){
+ printf("Overflow command %u n\r ", bytesRead);
+ bytesRead = 255;
+ }
+
+ unsigned index = 0;
+ for (; index < bytesRead; index++) {
+ buffer[index] = params->data[index];
+ }
+
+ buffer[index++] = 0;
+
+ printf("Data : %s ",buffer);
+ printf("\r\n");
+ eventQueue.call(EchoBleUartReceived);
+
+ }
+}
+
+
+/**
+ * This function is called when the ble initialization process has failled
+ */
+void onBleInitError(BLE &ble, ble_error_t error)
+{
+ printf("\n BLE Initialization failed!! \n");
+
+ /* Initialization error handling should go here */
+}
+
+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: ");
+ for (int i = 5; i >= 1; i--){
+ printf("%02x:", address[i]);
+ }
+ printf("%02x\r\n", address[0]);
+}
+
+/**
+ * Callback triggered when the ble initialization process has finished
+ */
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
+{
+ BLE& ble = params->ble;
+ ble_error_t error = params->error;
+
+ if (error != BLE_ERROR_NONE) {
+ /* In case of error, forward the error handling to onBleInitError */
+ onBleInitError(ble, error);
+ return;
+ }
+
+ /* Ensure that it is the default instance of BLE */
+ if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
+ return;
+ }
+
+ ble.gap().onDisconnection(disconnectionCallback);
+ ble.gattServer().onDataWritten(onDataWrittenCallback);
+
+ bool initialValueForLEDCharacteristic = false;
+ ledServicePtr = new LEDService(ble, initialValueForLEDCharacteristic);
+ /* Setup primary service */
+ uart = new UARTService(ble);
+
+ /* 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();
+
+ printMacAddress();
+}
+
+void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
+ BLE &ble = BLE::Instance();
+ eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
+}
+
+
+void bleInitialization()
+{
+ BLE &ble = BLE::Instance();
+ device->printf("\n --- BLE Instance Instantiated --- \n");
+ ble.onEventsToProcess(scheduleBleEventsProcessing);
+ device->printf("\n --- BLE scheduleBleEventsProcessing setup --- \n");
+ ble.init(bleInitComplete);
+}
+
+
+static int uartExpectedRcvCount = 0;
+static int uartCharRcvCount = 0;
+static bool UartBusy = false;
+int WriteUartBytes(const uint8_t * txBuffer, size_t bufSize, int txLen)
+{
+ if(txLen > bufSize)
+ {
+ txLen = bufSize;
+ }
+ //int goodTxLen;
+ //goodTxLen = _parser.write((const char *) txBuffer, txLen);
+ for(int i=0;i<txLen;i++)
+ {
+ device->putc(txBuffer[i]);
+ }
+ // return number of bytes written to UART
+ return (int) txLen;
+}
+
+void UartRxcallback_ex() {
+ if(uartCharRcvCount >= uartExpectedRcvCount)
+ {
+ int x = device->getc();
+ return;
+ }
+ if(uartCharRcvCount == 0)
+ {
+ device->printf("\nFirst Call to UART attach callback!!\n");
+ }
+ // Note: you need to actually read from the serial to clear the RX interrupt
+ RxBuffer[uartCharRcvCount] = (uint8_t) device->getc();
+ uartCharRcvCount++;
+ if(uartCharRcvCount >= uartExpectedRcvCount)
+ {
+ alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */
+ device->printf("\nNumber of Received Bytes = %d\n\n", uartCharRcvCount);
+ device->printf("--- Writing back received bytes --- \n");
+ int n;
+ n = WriteUartBytes(RxBuffer, TX_BUFFER_LEN, uartCharRcvCount);
+ UartBusy = false;
+ }
+}
+
+void BackGndUartRead(uint8_t * rxBuffer, size_t bufSize, int rxLen)
+{
+ UartBusy = true;
+ device->printf("Setting up background UART read - rxLen = %d\n", rxLen);
+ uartCharRcvCount = 0;
+ if(rxLen > bufSize)
+ {
+ rxLen = bufSize;
+ }
+ uartExpectedRcvCount = rxLen;
+ device->attach(&UartRxcallback_ex);
+ device->printf("\nBackground UART read setup completed\n\n");
+ //for(int i=0;i<rxLen;i++)
+ //{
+ // rxBuffer[i] = (uint8_t) getc();
+ //}
+ // return number of bytes written to UART
+ //return rxLen;
+}
+
+int ReadUartBytes(uint8_t * rxBuffer, size_t bufSize, int rxLen, bool echo)
+{
+ UartBusy = true;
+ if(rxLen > bufSize)
+ {
+ rxLen = bufSize;
+ }
+ for(int i=0;i<rxLen;i++)
+ {
+ rxBuffer[i] = (uint8_t) device->getc();
+ if(echo)device->putc(rxBuffer[i]);
+ }
+ UartBusy = false;
+ //return number of bytes written to UART
+ return rxLen;
+}
+
+
+void checkUartReceive()
+{
+ //device->printf("Hello World!\n\r");
+ char cbuf[100];
+ int rxCnt=0;
+ while(device->readable()) {
+ //device->printf("uartCharRcvCount = %d\n\r", uartCharRcvCount++);
+ cbuf[rxCnt++] = device->getc();
+ //putc(getc() + 1); // echo input back to terminal
+ }
+ cbuf[rxCnt] = NULL;
+ if(rxCnt > 0)
+ {
+ device->printf("received %d chars\n", rxCnt);
+ device->printf("%s\n", cbuf);
+ }
+
+}
+uint64_t lastTime = 0;
+uint64_t now = 0;
+uint32_t callCount = 0;
+void HelloUart()
+{
+ //if(UartBusy)return;
+ // 64-bit time doesn't wrap for half a billion years, at least
+ lastTime = now;
+ now = Kernel::get_ms_count();
+ callCount++;
+ device->printf("\nHello : %d secs elapsed : CallCount = %d \n", uint32_t(now - lastTime), callCount);
+}
+
+
+
+
+//Serial device(USBTX, USBRX); // tx, rx
+//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
+ {
+ 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;
+ }
+
+
+
+ // 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)
+ {
+ 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----- 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");
+
+ 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;
+ }
+
+
+ // 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;
+ }
+ }
+
+int main() {
+ //RawSerial *device(USBTX, USBRX); // tx, rx
+ device = new RawSerial(USBTX, USBRX, DEFAULT_BAUD_RATE);
+
+ device->printf("\n --- Running UART-BLE-UartService --- \n");
+ // Start the event queue
+ //t.start(callback(&eventQueue, &EventQueue::dispatch_forever));
+
+ eventQueue.call_every(500, blinkCallback);
+ eventQueue.call_every(60000, HelloUart);
+ //eventQueue.call_every(1000, checkUartReceive);
+ device->printf("\n --- EventQueues setup --- \n");
+ ////////////////////////////////////////////////////////////////////////////////
+ // 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();
+ //cbMAIN_driverUnlock();
+ device->printf("\n --- BLE Initialization completed --- \n");
+ device->printf("\n Press any key to start Wifi demo: ");
+ device->getc();
+ ////////////////////////////////////////////////////////////////////////////////////
+
+ //device->baud(115200);
+ NetworkInterface* network = connect_to_default_network_interface();
+ // run on separate thread;
+ t.start(wifi_demo(network));
+ network->disconnect();
+ t.join();
+
+ for(int i=0;i<255;i++)
+ {
+ device->putc(i);
+ }
+ int n;
+ //ReadUartBytes(RxBuffer, RX_BUFFER_LEN, 4);
+ 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');
+ device->printf("\n\nExpected # of Received Bytes = %d\n", rxLen);
+ BackGndUartRead(RxBuffer, RX_BUFFER_LEN, 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);
+
+
+ device->printf("\nATCmdParser with ESP8266 example");
+ device->printf("\n Waiting for 2 minutes ");
+ wait(120);
+ eventQueue.dispatch_forever();
+ return 0;
+ device->printf("\n About to delete RawSerial device instance ");
+ delete device;
+ _serial = new UARTSerial(USBTX, USBRX, DEFAULT_BAUD_RATE);
+ printf("\n ATCmdParser printf being used now \n\n");
+ _parser = new ATCmdParser(_serial);
+ _parser->debug_on( 1 );
+ _parser->set_delimiter( "\r\n" );
+
+ //Now get the FW version number of ESP8266 by sending an AT command
+ printf("\nATCmdParser: Retrieving FW version");
+ _parser->send("AT+GMR");
+ int version;
+ if(_parser->recv("SDK version:%d", &version) && _parser->recv("OK")) {
+ printf("\nATCmdParser: FW version: %d", version);
+ printf("\nATCmdParser: Retrieving FW version success");
+ } else {
+ printf("\nATCmdParser: Retrieving FW version failed");
+ return -1;
+ }
+
+ printf("\nDone\n");
+
+
+ //eventQueue.dispatch_forever();
+ //t.start(callback(&eventQueue, &EventQueue::dispatch_forever));
+ //eventQueue2.dispatch_forever();
+
+ return 0;
+
+
+
+
+ //wait(osWaitForever);
+}
+
+#endif