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

Dependencies:   mbed-http

source/main-https.cpp

Committer:
ocomeni
Date:
2019-07-19
Branch:
PassingRegression
Revision:
129:590bdc2dcf5b
Parent:
126:9bc33f8b57d5

File content as of revision 129:590bdc2dcf5b:

#define MBED_CONF_MBED_TRACE_ENABLE 1

#include "select-demo.h"
#include "debug.h"

#if DEMO == DEMO_HTTPS

#include <events/mbed_events.h>
#include <mbed.h>
#include "nvstore.h"
#include "ble/BLE.h"
#include "fault_handlers.h"
#include "ATCmdParser.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 led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);

#define FILE_CODE       "main"

// NVStore is a sigleton, get its instance
NVStore &nvstore = NVStore::get_instance();

main_states_t mainLoop;
static RawSerial *device; // tx, rx

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

// BLE instance
//BLE& _ble;
BLE& _ble = BLE::Instance();

// BLE configuration
//static ble_config_t ble_config;

// internet/cloud configuration
//internet_config_t internet_config;

const uint8_t pairingPassword[6] = "1101";
// BLE peripheral pointer
static SMDevicePeripheral *peripheral;

const static char     DEVICE_NAME_MAIN[] = "UBLOX-BLE";
//char buffer[BUFFER_LEN];
static EventQueue eventQueue_atcmd(/* event count */ 32 * EVENTS_EVENT_SIZE);
static EventQueue eventQueue_wifi(/* event count */ 64 * EVENTS_EVENT_SIZE);
static EventQueue eventQueue_ble(/* event count */ 32 * EVENTS_EVENT_SIZE);

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


/*  Queue and memory pool for AT to BLE data */
static MemoryPool<at_ble_msg_t, PQDSZ_BLE> aT2BleDatamPool;
static Queue<at_ble_msg_t, PQDSZ_BLE> aT2BleDataQueue;


/*  Queue and memory pool for BLE to AT data */
static MemoryPool<ble_at_msg_t, PQDSZ_BLE> ble2ATDatamPool;
static Queue<ble_at_msg_t, PQDSZ_BLE> ble2ATDataQueue;




/* 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, 4*1024);
Thread wifi_thread(WIFI_THREAD_PRIORITY, 4*1024);
Thread atcmd_thread(ATCMD_THREAD_PRIORITY, 4*1024);
#endif

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

Thread atcmd_evt_thread(osPriorityNormal, 1024);
Thread wifi_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

bool ble_mgr_started;
bool wifi_mgr_started;

uint64_t lastTime = 0;
uint64_t now = 0;
uint32_t callCount = 0;


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

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


void printWaitAbortKeyPress(int numSecs, const char * printStr=NULL)
{
#ifndef DEBUG_ENABLED
    return;
#endif
    dbg_printf(LOG, "%s", printStr);
    dbg_printf(LOG, "Waiting for %d seconds... [press key to abort]\n", numSecs);
    char fmtstr[20];
    int len;
    for(int i=0;i<numSecs;i++){
        dbg_printf(LOG, "%d", i);
        dbg_printf(LOG, "\n");
        sprintf(fmtstr, "BLE: loop # %d\n", i);
        len = strlen(fmtstr)+1;
        peripheral->sendBLEUartData((const uint8_t *)fmtstr, len);
        wait(0.5);
        //eventQueue_atcmd.dispatch(500);        // Dispatch time - 500msec
        if(device->readable()){
            dbg_printf(LOG, "keypress detected aborting....\n");
            device->getc();
            break;
        }
    }
}



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

    //ble_config.pairingKey = pairingPassword;
}

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

// Entry point for the example
void print_app_config()
{
    //dbg_printf(LOG, "Return code is %d ", rc);
}

// Entry point for the example
void print_return_code(int rc, int expected_rc)
{
    dbg_printf(LOG, "Return code is %d ", rc);
    if (rc == expected_rc)
        dbg_printf(LOG, "(as expected).\n");
    else
        dbg_printf(LOG, "(expected %d!).\n", expected_rc);
}
void setupDefaultStartupConfig()
{
    app_config.startup_config.ble_enable = true;
}

void setupDefaultCloudConfig()
{
    strcpy(app_config.internet_config.url, "tcp://https://dev2.dnanudge.io");
    app_config.internet_config.peer_id = 0;
    app_config.internet_config.remote_port = 443; // default HTTPS port
    app_config.internet_config.connectionScheme = ALWAYS_CONNECTED;
}

void setupDefaultUartConfig()
{
    app_config.uart_config.baudrate             = 2*DEFAULT_BAUD_RATE;
    app_config.uart_config.flow_ctrl            = 2;
    app_config.uart_config.data_bits            = 8;
    app_config.uart_config.stop_bits            = 1;
    app_config.uart_config.parity               = 1;
    app_config.uart_config.change_after_confirm = 1;
}

void resetConfiguration()
{
    int rc;
    // Clear NVStore data. Should only be done once at factory configuration
    rc = nvstore.reset();
    dbg_printf(LOG, "Reset NVStore. ");
    print_return_code(rc, NVSTORE_SUCCESS);
}

bool deleteConfiguration(nvstore_key_t configKey)
{
    int rc;
    // Clear NVStore data. Should only be done once at factory configuration
    rc = nvstore.remove(configKey);
    dbg_printf(LOG, "Deleted config key %d from NVStore. ", (int)configKey);
    print_return_code(rc, NVSTORE_SUCCESS);
    return (rc == NVSTORE_SUCCESS);
}

void saveConfiguration(nvstore_key_t configKey)
{
    int rc;
    rc = nvstore.set((uint16_t)configKey, sizeof(app_config), &app_config);
    print_return_code(rc, NVSTORE_SUCCESS);
}

bool loadConfiguration(nvstore_key_t configKey)
{
    int rc;
    // Get the value of this key (should be 3000)
    uint16_t actual_len_bytes;
    rc = nvstore.get((uint16_t)configKey, sizeof(app_config), &app_config, actual_len_bytes);
    print_app_config();
    print_return_code(rc, NVSTORE_SUCCESS);
    return (rc == NVSTORE_SUCCESS && (sizeof(app_config) == actual_len_bytes));
}

static int reset_counter = 0;



//#define ENABLE_MEMORY_CHECKS

void print_memory_info() {
#ifdef ENABLE_MEMORY_CHECKS
    // 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++) {
        dbg_printf(LOG, "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);
    dbg_printf(LOG, "Heap size: %lu / %lu bytes\r\n", heap_stats.current_size, heap_stats.reserved_size);
#endif
}

void blinkLEDs()
{
    static int cnt =0;
    cnt++;
    if(cnt == 3){
        cnt = 0;
    }
    if(cnt==0)
        led1 = !led1;
    //wait(1.0);
    if(cnt==1)
        led2 = !led2;
    //wait(1.0);
    if(cnt==2)
        led3 = !led3;
}

void start_BLE()
{
    //_ble = BLE::Instance();
#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()) {
        dbg_printf(LOG, "Filesystem creation failed, will use memory storage\r\n");
    }
#endif
    dbg_printf(LOG, "\r\n PERIPHERAL \r\n\r\n");
    peripheral = new SMDevicePeripheral(_ble, eventQueue_ble, peer_address, 
                                        &aT2BleDatamPool, &aT2BleDataQueue,
                                        &ble2ATDatamPool, &ble2ATDataQueue,
                                        &app_config.ble_config);

    peripheral->run();
    btle_thread.start(callback(&eventQueue_ble, &EventQueue::dispatch_forever));
    ble_mgr_started = true;
    wait_ms(10);
}

void stop_BLE()
{
    btle_thread.terminate();
    delete peripheral;
    ble_mgr_started = false;
    wait_ms(10);
}

void start_WiFi()
{
    wiFiManager = new WiFiManager(&app_config.wifi_config, network, 
                                  &app_config.internet_config,
                                  eventQueue_wifi,
                                  &aT2WiFimPool, &aT2WiFiCmdQueue,
                                  &wiFi2ATmPool, &wiFi2ATCmdQueue,
                                  &aT2WiFiDatamPool, &aT2WiFiDataQueue,
                                  &wiFi2ATDatamPool, &wiFi2ATDataQueue
                                  );
    dbg_printf(LOG, "\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \r\n");
    dbg_printf(LOG, "\r\n++++++ Test WiFi Manager Network scan from thread ++++++ \r\n");
    dbg_printf(LOG, "\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \r\n");
    wifi_thread.start(callback(wiFiManager, &WiFiManager::runMain));
    dbg_printf(LOG, "\r\n after starting wifi thread \r\n");
    printWaitAbortKeyPress(120, "Wait after WiFi Manager dispatch\r\n");
    // dispatch wifi event queue on event thread
    wifi_evt_thread.start(callback(&eventQueue_wifi, &EventQueue::dispatch_forever));
    wifi_mgr_started = true;
}

void stop_WiFi()
{
    wifi_evt_thread.terminate();
    wifi_thread.terminate();
    delete wiFiManager;
    delete network;
    wifi_mgr_started = false;
}


void trigger_start_BLE()
{
    mainLoop = START_BLE;
}


void trigger_stop_BLE()
{
    mainLoop = STOP_BLE;
}


void trigger_start_WiFi()
{
    mainLoop = START_WIFI;
}


void trigger_stop_WiFi()
{
    mainLoop = STOP_WIFI;
}

//#define USE_DEFAULT_CONFIGURATION
//#define TEST_NVSTORE
//#define STARTUP_DEBUG_ENABLE
//#define AUTO_START_BLE_MANAGER
//#define AUTO_START_WIFI_MANAGER
#define PAUSE_SECONDS   0
#define PAUSE_SECONDS_BLE 0
int main() {
#ifndef USE_DEFAULT_CONFIGURATION
    if(loadConfiguration(APP_CONFIG_0) == false)
    {
        setupDefaultStartupConfig();
        setupDefaultUartConfig();
        setupDefaultWiFiConfig();
        setupDefaultBleConfig();
        setupDefaultCloudConfig();
    }
    if(app_config.startup_config.ble_enable)
    {
        trigger_start_BLE();
    }
#else
    setupDefaultUartConfig();
    setupDefaultWiFiConfig();
    setupDefaultBleConfig();
    setupDefaultCloudConfig();
#endif
    device = new RawSerial(USBTX, USBRX, app_config.uart_config.baudrate);
#if defined (STARTUP_DEBUG_ENABLE) || defined (DEBUG_ENABLED)
    uint8_t debug_level = (LOG | ERR | TXT | DBG);
    initialise_debug(debug_level);
#else
    initialise_debug(NONE);
#endif
#ifdef MBED_MAJOR_VERSION
    dbg_printf(LOG, "Mbed OS version %d.%d.%d\n\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
#endif
#ifdef TEST_NVSTORE
    app_config_t *current_config = new app_config_t;
    memcpy(current_config, &app_config, sizeof(app_config_t));
    saveConfiguration(APP_CONFIG_0);
    memset(&app_config, 0, sizeof(app_config_t));
    loadConfiguration(APP_CONFIG_0);
    int cmp;
    cmp = memcmp(current_config, &app_config, sizeof(app_config_t));
    if(cmp == 0)
    {
        dbg_printf(LOG, " NVSTRORE TEST Passed!!\r\n");
    }
    else
    {
        dbg_printf(LOG, " NVSTRORE TEST Failed!!\r\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
    }
    delete current_config;
#endif
    
    reset_counter++;
    dbg_printf(LOG, "\r\n ++++++ PROGRAM STARTING -- reset count = %d ++++++ \r\n", reset_counter);
#ifdef AUTO_START_BLE_MANAGER
    //btle_thread.start(callback(peripheral, &SMDevicePeripheral::run));
    start_BLE();
    printWaitAbortKeyPress(120, "Wait after BLE dispatch\r\n");
#endif
    //int start = Kernel::get_ms_count();
#ifdef AUTO_START_WIFI_MANAGER
    start_WiFi();
    printWaitAbortKeyPress(120, "Wait after WiFi instantiation\r\n");
#endif
    // dispatch atcmd event queue on event thread
    atcmd_evt_thread.start(callback(&eventQueue_atcmd, &EventQueue::dispatch_forever));
    dbg_printf(LOG, "\r\n++++++ Starting ATCmdmanager ++++++ \r\n");
    ATCmdManager *aTCmdManager = new ATCmdManager(USBTX, USBRX, &app_config.uart_config, 
                                                eventQueue_atcmd, wiFiManager, 
                                                &aT2WiFimPool, &aT2WiFiCmdQueue,
                                                &wiFi2ATmPool, &wiFi2ATCmdQueue,
                                                &aT2WiFiDatamPool, &aT2WiFiDataQueue,
                                                &wiFi2ATDatamPool, &wiFi2ATDataQueue,
                                                &aT2BleDatamPool, &aT2BleDataQueue,
                                                &ble2ATDatamPool, &ble2ATDataQueue,
                                                &app_config.startup_config, false);
    atcmd_thread.start(callback(aTCmdManager, &ATCmdManager::runMain));
    dbg_printf(LOG, "\r\n after starting atcmd thread \r\n");
    print_memory_info();
#ifdef STARTUP_DEBUG_ENABLE
    initialise_debug(NONE);
#endif
    while(1)
    {
        switch(mainLoop)
        {
            case MAIN_IDLE:
                break;
            case START_BLE:
                start_BLE();
                mainLoop = MAIN_IDLE;
                break;
            case START_WIFI:
                if(!ble_mgr_started)
                {
                    start_BLE();
                }
                start_WiFi();
                mainLoop = MAIN_IDLE;
                break;
            case STOP_BLE:
                stop_BLE();
                mainLoop = MAIN_IDLE;
                break;
            case STOP_WIFI:
                stop_WiFi();
                mainLoop = MAIN_IDLE;
                break;
            default:
                mainLoop = MAIN_IDLE;
                break;
        }
        wait(1);
    }
}

#endif