this is using the mbed os version 5-13-1

Dependencies:   mbed-http

source/main-https.cpp

Committer:
ocomeni
Date:
2019-04-22
Revision:
99:05398b3184f8
Parent:
98:65c2333a38b6
Child:
103:7b566b522427

File content as of revision 99:05398b3184f8:

#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 "fault_handlers.h"
//#include "BLE.h"
#include "ATCmdParser.h"
//#include "BLEDevice.h"

#include "LEDService.h"
#include "ble/services/UARTService.h"
#include "common_config.h"
#include "common_types.h"
#include "ATCmdManager.h"
#include "BleManager.h"
#include "WiFiManager.h"
#include "mbed_memory_status.h"
UARTService *uart;

DigitalOut alivenessLED(LED1, 0);
DigitalOut actuatedLED(LED2, 0);


static RawSerial *device; // tx, rx

// wifi configuration
static wifi_config_t wifi_config;
// wifi interface pointer
static WiFiInterface *network;
// wifi manager pointer
static WiFiManager *wiFiManager;

// BLE configuration
static ble_config_t ble_config;
const uint8_t pairingPassword[6] = "1101";
// BLE interface pointer 
//BLE &_ble;
// BLE peripheral pointer
static SMDevicePeripheral *peripheral;

const static char     DEVICE_NAME_MAIN[] = "UBLOX-BLE";
static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID};
char buffer[BUFFER_LEN];
#ifdef ENABLE_UART_BACKGRND_DEMO
uint8_t TxBuffer[TX_BUFFER_LEN];
uint8_t RxBuffer[RX_BUFFER_LEN];
#endif
static EventQueue eventQueue(/* event count */ 20 * EVENTS_EVENT_SIZE);
//static EventQueue eventQueue2(/* event count */ 10 * EVENTS_EVENT_SIZE);

LEDService *ledServicePtr;

/*  Queue and memory pool for AT to Wifi commands */
static MemoryPool<wifi_cmd_message_t, 16> aT2WiFimPool;
static Queue<wifi_cmd_message_t, 16> aT2WiFiCmdQueue;

/*  Queue and memory pool for WiFi to AT commands */
static MemoryPool<at_resp_message_t, 16> wiFi2ATmPool;
static Queue<at_resp_message_t, 16> wiFi2ATCmdQueue;

/*  Queue and memory pool for AT to WiFi data */
static MemoryPool<wifi_data_msg_t, PQDSZ> aT2WiFiDatamPool;
static Queue<wifi_data_msg_t, PQDSZ> aT2WiFiDataQueue;


/*  Queue and memory pool for WiFi to AT data */
static MemoryPool<at_data_msg_t, PQDSZ> wiFi2ATDatamPool;
static Queue<at_data_msg_t, PQDSZ> wiFi2ATDataQueue;




/* allocate statically stacks for the three threads */
//unsigned char rt_stk[1024];
//unsigned char hp_stk[1024];
//unsigned char lp_stk[1024];

/* 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]);

#ifdef USE_MAIN_THREAD_STACK
// using main thread stack
unsigned char btle_stk[1024];
unsigned char wifi_stk[8*1024];
unsigned char atcmd_stk[4*1024];
Thread btle_thread(BTLE_THREAD_PRIORITY, 1024, &btle_stk[0]);
Thread wifi_thread(WIFI_THREAD_PRIORITY, 8*1024, &wifi_stk[0]);
Thread atcmd_thread(ATCMD_THREAD_PRIORITY, 4*1024, &atcmd_stk[0]);
#else
// using global heap
Thread btle_thread(BTLE_THREAD_PRIORITY, 1024);
Thread wifi_thread(WIFI_THREAD_PRIORITY, 6*1024);
Thread atcmd_thread(ATCMD_THREAD_PRIORITY, 4*1024);
#endif

/* create a semaphore to synchronize the threads */
Semaphore sync_sema;

Thread evt_thread;
#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
 *
 * To add more root certificates, just concatenate them.
 */
#include "https_certificates.h"

// wifi demo
#include "wifi_demo.h"

Mutex _smutex; // Protect memory access
// check free memory

void performFreeMemoryCheck()
{
    _smutex.lock();
       // 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);
    _smutex.unlock();

}
#ifdef ENABLE_UART_BACKGRND_DEMO
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 printUartRxResult()
{
    
    if(uartCharRcvCount == 0)
    {
        device->printf("\nFirst Call to UART attach callback!!\n");
    }
    else if(uartCharRcvCount >= uartExpectedRcvCount)
    {
        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 UartRxcallback_ex() {
    if(uartCharRcvCount >= uartExpectedRcvCount)
    {
        int x = device->getc();
        return;
    }
    if(uartCharRcvCount == 0)
    {
        eventQueue.call(printUartRxResult);
    }
    // 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. */
        eventQueue.call(printUartRxResult);
    }
}
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->printf("\nattaching to device UART\n\n");
    device->attach(&UartRxcallback_ex);
    device->printf("\nBackground UART read setup completed\n\n");
}

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

}
#endif

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




// Wifi-demo
void wifi_demo(NetworkInterface* network){
    int n = wifi_demo_func(network);
    if(n > 0)// error
    {
        device->printf("\n --- Error running wifi demo --- \n");
    }
}

// Wifi-demo2
void wifi_demo2(){
    //int n = wifi_demo_func(network);
    int n =5;
    if(n > 0)// error
    {
        device->printf("\n --- Error running wifi demo --- \n");
    }
}

void printWait(int numSecs)
{
    printf("Waiting for %d seconds...\n", numSecs);
    for(int i=0;i<numSecs;i++){
        printf("%d", i);
        printf("\n");
        wait(0.5);
        eventQueue.dispatch(500);        // Dispatch time - 500msec
    }
}

void printWaitAbortKeyPress(int numSecs)
{
    printf("Waiting for %d seconds... [press key to abort]\n", numSecs);
    char fmtstr[20];
    for(int i=0;i<numSecs;i++){
        printf("%d", i);
        printf("\n");
        sprintf(fmtstr, "BLE: loop # %d\n", i);
        peripheral->sendBLEUartData(fmtstr);
        wait(0.5);
        eventQueue.dispatch(500);        // Dispatch time - 500msec
        if(device->readable()){
            printf("keypress detected aborting....\n");
            device->getc();
            break;
        }
    }
}



void setupDefaultBleConfig()
{
    strcpy(ble_config.deviceName, DEVICE_NAME_MAIN);// set BLE device name
    ble_config.advInterval = 1000;             // set advertising interval to 1 second default
    ble_config.advTimeout = 0;                 // set advertising timeout to disabled by default
    // This works in C and C++
    memcpy(ble_config.pairingKey, pairingPassword, 6); // 

    //ble_config.pairingKey = pairingPassword;
}

void setupDefaultWiFiConfig()
{
    strcpy(wifi_config.ssid, MBED_CONF_APP_WIFI_SSID);
    strcpy(wifi_config.pass, MBED_CONF_APP_WIFI_PASSWORD);
    wifi_config.security = NSAPI_SECURITY_WPA_WPA2;
}

static int reset_counter = 0;




#define MAX_LOOP_COUNT 3
int ble_security_main()
{
    BLE& _ble = BLE::Instance();
    events::EventQueue queue;

#if MBED_CONF_APP_FILESYSTEM_SUPPORT
    /* if filesystem creation fails or there is no filesystem the security manager
     * will fallback to storing the security database in memory */
    if (!create_filesystem()) {
        printf("Filesystem creation failed, will use memory storage\r\n");
    }
#endif
    int loopCount = 0; 
    while(1) {
        {
            printf("\r\n PERIPHERAL \r\n\r\n");
            SMDevicePeripheral peripheral(_ble, queue, peer_address, ble_config);
            peripheral.run();
            return 0;
        }
        if(loopCount >= MAX_LOOP_COUNT)
        {
            return 0;
        }

        {
            printf("\r\n CENTRAL \r\n\r\n");
            SMDeviceCentral central(_ble, queue, peer_address, ble_config);
            central.run();
        }
        loopCount++;
        printf("loop Cycle #%d\r\n", loopCount);
    }

    return 0;
}

void print_memory_info() {
    // allocate enough room for every thread's stack statistics
    int cnt = osThreadGetCount();
    mbed_stats_stack_t *stats = (mbed_stats_stack_t*) malloc(cnt * sizeof(mbed_stats_stack_t));
 
    cnt = mbed_stats_stack_get_each(stats, cnt);
    for (int i = 0; i < cnt; i++) {
        printf("Thread: 0x%lX, Stack size: %lu / %lu\r\n", stats[i].thread_id, stats[i].max_size, stats[i].reserved_size);
    }
    free(stats);
 
    // Grab the heap statistics
    mbed_stats_heap_t heap_stats;
    mbed_stats_heap_get(&heap_stats);
    printf("Heap size: %lu / %lu bytes\r\n", heap_stats.current_size, heap_stats.reserved_size);
}

//#define DISABLE_WIFI
#define DISABLE_WIFI_DEMO
#define SKIP_WIFI_SCAN_DEMO
#define BLE_STOP_START_ADV_SCAN_DEMO
#define SKIP_WIFI_CONNECT_DEMO
#define PAUSE_SECONDS   0
#define PAUSE_SECONDS_BLE 2
int main() {
    //print_all_thread_info();
    //print_heap_and_isr_stack_info();
#ifdef MBED_MAJOR_VERSION
    printf("Mbed OS version %d.%d.%d\n\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
#endif
    
    reset_counter++;
    print_memory_info();
    printf("\r\n ++++++ PROGRAM STARTING -- reset count = %d ++++++ \r\n", reset_counter);
    device = new RawSerial(USBTX, USBRX, DEFAULT_BAUD_RATE);
    //device = new RawSerial(PA_9, PA_10, DEFAULT_BAUD_RATE);
    
    printf("*** HELLO MESSAGE *** \n %s", (char *)&hello_msg[6]);
    setupDefaultWiFiConfig();
    setupDefaultBleConfig();
    BLE& _ble = BLE::Instance();
    events::EventQueue queue(/* event count */ 10 * EVENTS_EVENT_SIZE);
#if MBED_CONF_APP_FILESYSTEM_SUPPORT
    /* if filesystem creation fails or there is no filesystem the security manager
     * will fallback to storing the security database in memory */
    if (!create_filesystem()) {
        printf("Filesystem creation failed, will use memory storage\r\n");
    }
#endif
    print_memory_info();
    printf("\r\n PERIPHERAL \r\n\r\n");
    peripheral = new SMDevicePeripheral(_ble, queue, peer_address, ble_config);
    print_memory_info();

    peripheral->run();
    btle_thread.start(callback(&queue, &EventQueue::dispatch_forever));
    print_memory_info();
    printWaitAbortKeyPress(PAUSE_SECONDS_BLE); // give BLE time to settle
    //peripheral->stopAdvertising();

#ifndef DISABLE_WIFI // comment out wifi part
    int start = Kernel::get_ms_count();
#ifdef DISABLE_WIFI_DEMO
    network = WiFiInterface::get_default_instance();
    if (!network) {
        printf("ERROR: No WiFiInterface found.\n");
    }
    wiFiManager = new WiFiManager(wifi_config, network, 
                                  eventQueue,
                                  &aT2WiFimPool, &aT2WiFiCmdQueue,
                                  &wiFi2ATmPool, &wiFi2ATCmdQueue,
                                  &aT2WiFiDatamPool, &aT2WiFiDataQueue,
                                  &wiFi2ATDatamPool, &wiFi2ATDataQueue
                                  );
#else
    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;
    evt_thread.start(callback(wifi_demo, network));
    evt_thread.join(); 
    network->disconnect(); 
    delete network;
    device->printf("\n Wifi-Demo completed - restarting BLE  \n\n");
#endif /// endif DISABLE_WIFI_DEMO

#else
    device->printf("\n Wifi Demo disabled so just waiting it out...  \n\n");
    printWait(2); // lets wait for a minute before turning BLE back on
    device->printf("\n ++++++ restarting BLE ++++++ \n\n");
#endif  /// endif DISABLE_WIFI
    printWaitAbortKeyPress(PAUSE_SECONDS);
    //peripheral->startAdvertising();
#ifdef ENABLE_UART_BACKGRND_DEMO
    for(int i=0;i<255;i++)
    {
        device->putc(i);
    }
    reportGapState();
    device->printf("\n\n\nEnter # of expected bytes: ");
    ReadUartBytes(RxBuffer, RX_BUFFER_LEN, 4, true);
    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, (int) rxLen);

    device->printf("\n Waiting for 5 seconds ");
    printWait(5);
    device->printf("\n Waiting finished!!!\n Now waiting for expected bytes to be received \n\n");
    while(UartBusy){
        wait(0.1);
    }
#endif 

    device->printf("\r\n++++++ Press key for Wifi demo test ++++++ \r\n");
    printWaitAbortKeyPress(PAUSE_SECONDS);
#ifndef SKIP_WIFI_SCAN_DEMO
    device->printf("\r\n++++++ Test WiFi Manager Network Scan ++++++ \r\n");
    int count;
    count = wiFiManager->scanNetworks();
    if (count <= 0) {
        device->printf("scan() failed with return value: %d\n", count);
    }
    else {
        device->printf("\r\n++++++ Test WiFi Scan found %d networks ++++++ \r\n ++++ SUCCESS ++++\r\n", count);
    }
#endif    

#ifndef SKIP_WIFI_CONNECT_DEMO
    device->printf("\r\n++++++ Test WiFi Manager Network connect ++++++ \r\n");
    nsapi_error_t werror;
    werror = wiFiManager->connect();
    if (werror < 0) {
        device->printf("connect() failed with return value: %d\n", werror);
    }
    else {
        device->printf("\r\n++++++ Test WiFi connect SUCCESSFUL ++++++ \r\n");
    }
    if(!werror) // connect successful - test dicsonnection
    {
        device->printf("\r\n++++++ Test WiFi Manager Network disconnect ++++++ \r\n");
        werror = wiFiManager->disconnect();
        if (werror) {
            device->printf("disconnect() failed with return value: %d\n", werror);
        }
        else {
            device->printf("\r\n++++++ Test WiFi disconnect SUCCESSFUL ++++++ \r\n");
        }
    }
#endif    
    //wiFiManager->runMain();
    device->printf("\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \r\n");
    device->printf("\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \r\n");
    device->printf("\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \r\n");
    device->printf("\r\n++++++ Test WiFi Manager Network scan from thread ++++++ \r\n");
    device->printf("\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \r\n");
    device->printf("\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \r\n");
    device->printf("\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \r\n");
    wifi_thread.start(callback(wiFiManager, &WiFiManager::runMain));
    printf("\r\n after starting wifi thread \r\n");
    print_memory_info();
    // dispatch event queue on event thread
    printf("\r\n [MAIN THREAD]  Thread Id = %X\r\n", (uint32_t)ThisThread::get_id());
    printf("\r\n [EVENT THREAD]  Thread Id = %X\r\n", (uint32_t)evt_thread.get_id());
    evt_thread.start(callback(&eventQueue, &EventQueue::dispatch_forever));
    device->printf("\r\n++++++ Starting ATCmdmanager ++++++ \r\n");
    ATCmdManager *aTCmdManager = new ATCmdManager(USBTX, USBRX, peripheral, 
                                                eventQueue, wiFiManager, 
                                                &aT2WiFimPool, &aT2WiFiCmdQueue,
                                                &wiFi2ATmPool, &wiFi2ATCmdQueue,
                                                &aT2WiFiDatamPool, &aT2WiFiDataQueue,
                                                &wiFi2ATDatamPool, &wiFi2ATDataQueue,
                                                false);
    //aTCmdManager->runMain();
    atcmd_thread.start(callback(aTCmdManager, &ATCmdManager::runMain));
    printf("\r\n after starting atcmd thread \r\n");
    print_memory_info();
    //SCB->SHCSR |= 0x00070000;//Enable fault handler.
    //wiFiManager->runMain();
    while(1) wait(0.1);
    //performFreeMemoryCheck();

    //eventQueue.dispatch_forever();
    //t.start(callback(&eventQueue, &EventQueue::dispatch_forever));
    //eventQueue2.dispatch_forever();

    return 0;
}

#endif