this is using the mbed os version 5-13-1
source/main-https.cpp
- Committer:
- ocomeni
- Date:
- 2019-03-14
- Revision:
- 75:08eff6258e1b
- Parent:
- 74:f26e846adfe9
- Child:
- 76:6afda865fbf8
File content as of revision 75:08eff6258e1b:
#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 "ATCmdParser.h"
//#include "BLEDevice.h"
#include "LEDService.h"
#include "ble/services/UARTService.h"
#include "common_config.h"
#include "ATCmdManager.h"
#include "BleManager.h"
UARTService *uart;
DigitalOut alivenessLED(LED1, 0);
DigitalOut actuatedLED(LED2, 0);
static RawSerial *device; // tx, rx
static UARTSerial *_serial; // tx, rx
static ATCmdParser *_parser;
const static char DEVICE_NAME_MAIN[] = "BLE-UART";
static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID};
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;
/* 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
*
* To add more root certificates, just concatenate them.
*/
#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;
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 */
}
/* 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("\nDEVICE 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);
ble.gap().onTimeout(timeoutCallback);
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_MAIN, sizeof(DEVICE_NAME_MAIN));
/* 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().setAdvertisingTimeout(300); /* 16 * 1000ms. */
ble.gap().startAdvertising();
printMacAddress();
bleInitializationCompleted = true;
}
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);
}
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_MAIN, sizeof(DEVICE_NAME_MAIN));
/* 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;
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);
}
}
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 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]);
}
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
}
}
static int reset_counter = 0;
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
while(1) {
{
printf("\r\n PERIPHERAL \r\n\r\n");
SMDevicePeripheral peripheral(ble, queue, peer_address);
peripheral.run();
}
{
printf("\r\n CENTRAL \r\n\r\n");
SMDeviceCentral central(ble, queue, peer_address);
central.run();
}
}
return 0;
}
int main() {
reset_counter++;
//RawSerial *device(USBTX, USBRX); // tx, rx
device = new RawSerial(USBTX, USBRX, DEFAULT_BAUD_RATE);
ble_security_main();
device->printf("\n --- Running UART-BLE-UartService --- (rst_cnt = %d)\n", reset_counter);
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");
BLE &ble = BLE::Instance();
device->printf("\n --- BLE Instance Instantiated --- \n");
btle_thread.start(callback(bleInitialization));
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");
}
else {
device->printf("\n --- BLE Initialization failed --- \n");
}
wait(1); // wait for advertising interval so advertising has started
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;
////////////////////////////////////////////////////////////////////////////////////
#endif
btle_thread.start(callback(&eventQueue, &EventQueue::dispatch_forever));
printWait(5);
//device->printf("\n Press any key to start Wifi demo: ");
//device->getc();
#ifdef false // comment out wifi part
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(callback(wifi_demo, network));
t.join();
#endif
//network->disconnect();
//delete network;
printMacAddress();
reportGapState();
//device->printf("\n Press any key to restart BLE : ");
//device->getc();
wait(1); // wait for advertising interval so advertising has started
reportGapState();
for(int i=0;i<255;i++)
{
device->putc(i);
}
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);
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("--- 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 5 seconds ");
printWait(5);
device->printf("\n Waiting finished!!!\n\n ");
reportGapState();
while(UartBusy){
wait(0.1);
}
ATCmdManager *aTCmdManager = new ATCmdManager(USBTX, USBRX, true);
//ATCmdManager *aTCmdManager = new ATCmdManager(D1, D0, true);
aTCmdManager->runMain();
#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->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;
}
//parser.recv("+CIPDATA:%d,", &len);
//parser.read(buffer, len);
printf("\nDone\n");
#endif
//performFreeMemoryCheck();
//eventQueue.dispatch_forever();
//t.start(callback(&eventQueue, &EventQueue::dispatch_forever));
//eventQueue2.dispatch_forever();
return 0;
//wait(osWaitForever);
}
#endif