This software setup a central node of a star topology network
Dependencies: MQTT target_st_bluenrg
Fork of ble-star-mbed by
Revision 4:4af40af2530e, committed 2018-03-31
- Comitter:
- lorevee
- Date:
- Sat Mar 31 15:10:54 2018 +0000
- Parent:
- 3:3f35e80ed848
- Child:
- 5:5cfb069b2587
- Commit message:
- first release of ble-star-mbed with cloud support
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MQTT.lib Sat Mar 31 15:10:54 2018 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mapellil/code/MQTT/#688f195846f1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MQTTNetwork.h Sat Mar 31 15:10:54 2018 +0000
@@ -0,0 +1,349 @@
+#ifndef _MQTTNETWORK_H_
+#define _MQTTNETWORK_H_
+
+#include "NetworkInterface.h"
+#include "mbedtls/platform.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/error.h"
+
+/* Change to a number between 1 and 4 to debug the TLS connection */
+#define DEBUG_LEVEL 0
+
+#if DEBUG_LEVEL > 0
+#include "mbedtls/debug.h"
+#endif
+
+#define TLS_OFF 0
+#define TLS_ON 1
+
+/* personalization string for the drbg */
+const char *DRBG_PERS = "mbed TLS Publisher for IBM Watson IoT";
+
+/* List of trusted root CA certificates
+ * currently only GlobalSign, the CA for os.mbed.com
+ *
+ * To add more than one root, just concatenate them.
+ */
+ mbedtls_entropy_context _entropy;
+ mbedtls_ctr_drbg_context _ctr_drbg;
+ mbedtls_x509_crt _cacert;
+ mbedtls_ssl_context _ssl;
+ mbedtls_ssl_config _ssl_conf;
+
+class MQTTNetwork {
+public:
+ MQTTNetwork(NetworkInterface *net_iface) : _network(net_iface) {
+ _tcpsocket = new TCPSocket();
+ _tcpsocket->set_blocking(false);
+ _is_tcpsocket_connected = 0;
+ }
+
+ ~MQTTNetwork() {
+ if (_is_tcpsocket_connected && _tls) {
+ mbedtls_ssl_session_reset( &_ssl );
+ mbedtls_entropy_free(&_entropy);
+ mbedtls_ctr_drbg_free(&_ctr_drbg);
+ mbedtls_x509_crt_free(&_cacert);
+ mbedtls_ssl_free(&_ssl);
+ mbedtls_ssl_config_free(&_ssl_conf);
+ }
+ _tcpsocket->close();
+ delete _tcpsocket;
+ }
+
+ int read(unsigned char* buffer, int len, int timeout) {
+ size_t _bpos = 0; int offset = 0; int ret = 0;
+ if (_tls) {
+//_tcpsocket->set_timeout(timeout);
+ /* Read data out of the socket */
+ offset = 0;
+ Countdown timer;
+ timer.countdown_ms(timeout);
+
+ do {
+ ret = mbedtls_ssl_read(&_ssl, buffer + offset,
+ len - offset );
+ if (ret > 0) offset += ret;
+ if (offset == len) return offset;
+ if (timer.expired()) return 0;
+ } while (ret == MBEDTLS_ERR_SSL_WANT_READ ||
+ ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == 0 );
+ if (ret == MBEDTLS_ERR_SSL_CLIENT_RECONNECT) {
+ print_mbedtls_error("MBEDTLS_ERR_SSL_CLIENT_RECONNECT\n\r", ret);
+ // int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl );
+ _tcpsocket->close();
+ _is_tcpsocket_connected = 0;
+ return ret;
+ }
+
+ if (ret < 0) {
+ print_mbedtls_error("mbedtls_ssl_read", ret);
+ _tcpsocket->close();
+ _is_tcpsocket_connected = 0;
+ return ret;
+ }
+ return ret;
+ } else {
+ _tcpsocket->set_blocking(true);
+ _tcpsocket->set_timeout(timeout);
+ return _tcpsocket->recv(buffer, len);
+ }
+ }
+
+
+ int write(unsigned char* buffer, int len, int timeout) {
+
+ size_t _bpos = len;
+ int offset = 0; int ret = 0;
+ if (_tls) {
+ do {
+ ret = mbedtls_ssl_write(&_ssl,
+ (const unsigned char *) buffer + offset,
+ _bpos - offset);
+ if (ret > 0)
+ offset += ret;
+ } while (offset < _bpos && (ret > 0 || ret == MBEDTLS_ERR_SSL_WANT_READ ||
+ ret == MBEDTLS_ERR_SSL_WANT_WRITE));
+ if (ret < 0) {
+ print_mbedtls_error("mbedtls_ssl_write", ret);
+ _tcpsocket->close();
+ _is_tcpsocket_connected = 0;
+ return ret;
+ }
+ return ret;
+ } else {
+ _tcpsocket->set_blocking(true);
+ _tcpsocket->set_timeout(timeout);
+ return _tcpsocket->send(buffer, len);
+ }
+ }
+
+ int connect(const char* hostname, int port, unsigned int tls=TLS_OFF, const char * cert=NULL, unsigned int sizeof_cert=0) {
+ _tls = tls;
+ if (tls == TLS_ON) { printf ("--->TLS is ON\n\r");};
+ if (tls == TLS_ON) {
+ mbedtls_entropy_init(&_entropy);
+ mbedtls_ctr_drbg_init(&_ctr_drbg);
+ mbedtls_x509_crt_init(&_cacert);
+ mbedtls_ssl_init(&_ssl);
+ mbedtls_ssl_config_init(&_ssl_conf);
+ /*
+ * Initialize TLS-related stuf.
+ */
+ int ret = 0;
+ if ((ret = mbedtls_ctr_drbg_seed(&_ctr_drbg, mbedtls_entropy_func, &_entropy,
+ (const unsigned char *) DRBG_PERS,
+ sizeof (DRBG_PERS))) != 0) {
+ print_mbedtls_error("mbedtls_crt_drbg_init", ret);
+ return ret;
+ }
+ if ((ret = mbedtls_x509_crt_parse(&_cacert, (const unsigned char *) cert,
+ sizeof_cert)) != 0) {
+ print_mbedtls_error("mbedtls_x509_crt_parse", ret);
+ return ret;
+ }
+ if ((ret = mbedtls_ssl_config_defaults(&_ssl_conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM,
+ MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
+ print_mbedtls_error("mbedtls_ssl_config_defaults", ret);
+ return ret;
+ }
+ mbedtls_ssl_conf_ca_chain(&_ssl_conf, &_cacert, NULL);
+ mbedtls_ssl_conf_rng(&_ssl_conf, mbedtls_ctr_drbg_random, &_ctr_drbg);
+ /* It is possible to disable authentication by passing
+ * MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode()
+ */
+ mbedtls_ssl_conf_authmode(&_ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
+#if DEBUG_LEVEL > 0
+ mbedtls_ssl_conf_verify(&_ssl_conf, my_verify, NULL);
+ mbedtls_ssl_conf_dbg(&_ssl_conf, my_debug, NULL);
+ mbedtls_debug_set_threshold(DEBUG_LEVEL);
+#endif
+ if ((ret = mbedtls_ssl_setup(&_ssl, &_ssl_conf)) != 0) {
+ print_mbedtls_error("mbedtls_ssl_setup", ret);
+ return ret;
+ }
+ mbedtls_ssl_set_hostname(&_ssl, hostname);
+
+ mbedtls_ssl_set_bio(&_ssl, static_cast<void *>(_tcpsocket), ssl_send, ssl_recv, NULL );
+ /* Connect to the server */
+ _tcpsocket->open(_network);
+ mbedtls_printf("Connecting with %s port: %d\n", hostname, port);
+ ret = _tcpsocket->connect(hostname, port);
+ if (ret != NSAPI_ERROR_OK) {
+ mbedtls_printf("Failed to connect\n");
+ printf("MBED: Socket Error: %d\n", ret);
+ _tcpsocket->close();
+ return ret;
+ }
+ printf ("--->TCP Connected\n\r");
+ _is_tcpsocket_connected = 1;
+
+ /* Start the handshake, the rest will be done in onReceive() */
+ mbedtls_printf("Starting the TLS handshake...\n");
+ do {
+ ret = mbedtls_ssl_handshake(&_ssl);
+ } while (ret != 0 && (ret == MBEDTLS_ERR_SSL_WANT_READ ||
+ ret == MBEDTLS_ERR_SSL_WANT_WRITE));
+ if (ret < 0) {
+ print_mbedtls_error("mbedtls_ssl_handshake", ret);
+ _tcpsocket->close();
+ return ret;
+ }
+/* const uint32_t buf_size = 1024;
+ char *buf = new char[buf_size];
+ mbedtls_x509_crt_info(buf, buf_size, "\r ",
+ mbedtls_ssl_get_peer_cert(&_ssl));
+ mbedtls_printf("Server certificate:\n%s", buf);
+
+ uint32_t flags = mbedtls_ssl_get_verify_result(&_ssl);
+ if( flags != 0 )
+ {
+ mbedtls_x509_crt_verify_info(buf, buf_size, "\r ! ", flags);
+ printf("Certificate verification failed:\n%s\n", buf);
+ }
+ else
+ printf("Certificate verification passed\n\n");
+*/
+ _is_tcpsocket_connected = 1;
+ return ret;
+
+ } else { // tls off
+ printf ("\r\n--->TLS is OFF\n");
+ _tcpsocket->open(_network);
+ int ret = _tcpsocket->connect(hostname, port);
+ if (ret != NSAPI_ERROR_OK) {
+ mbedtls_printf("\r\nFailed to connect\n");
+ printf("\r\nMBED: Socket Error: %d\n", ret);
+ _tcpsocket->close();
+ return ret;
+ }
+ printf ("\r\n--->TCP Connected\n");
+ _is_tcpsocket_connected = 1;
+ return ret;
+ }
+ }
+
+ int disconnect() {
+ if (_is_tcpsocket_connected && _tls == TLS_ON) {
+ mbedtls_ssl_session_reset( &_ssl );
+ mbedtls_entropy_free(&_entropy);
+ mbedtls_ctr_drbg_free(&_ctr_drbg);
+ mbedtls_x509_crt_free(&_cacert);
+ mbedtls_ssl_free(&_ssl);
+ mbedtls_ssl_config_free(&_ssl_conf);
+ }
+ _is_tcpsocket_connected = 0;
+ return _tcpsocket->close();
+ }
+
+ bool isConnected () { return _is_tcpsocket_connected; }
+
+private:
+ NetworkInterface* _network;
+ unsigned int _is_tcpsocket_connected;
+
+protected:
+ /**
+ * Helper for pretty-printing mbed TLS error codes
+ */
+ static void print_mbedtls_error(const char *name, int err) {
+ char buf[128];
+ mbedtls_strerror(err, buf, sizeof (buf));
+ mbedtls_printf("%s() failed: -0x%04x (%d): %s\n", name, -err, err, buf);
+ }
+
+#if DEBUG_LEVEL > 0
+ /**
+ * Debug callback for Mbed TLS
+ * Just prints on the USB serial port
+ */
+ static void my_debug(void *ctx, int level, const char *file, int line,
+ const char *str)
+ {
+ const char *p, *basename;
+ (void) ctx;
+
+ /* Extract basename from file */
+ for(p = basename = file; *p != '\0'; p++) {
+ if(*p == '/' || *p == '\\') {
+ basename = p + 1;
+ }
+ }
+
+ mbedtls_printf("%s:%04d: |%d| %s", basename, line, level, str);
+ }
+
+ /**
+ * Certificate verification callback for Mbed TLS
+ * Here we only use it to display information on each cert in the chain
+ */
+ static int my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
+ {
+ const uint32_t buf_size = 1024;
+ char *buf = new char[buf_size];
+ (void) data;
+
+ mbedtls_printf("\nVerifying certificate at depth %d:\n", depth);
+ mbedtls_x509_crt_info(buf, buf_size - 1, " ", crt);
+ mbedtls_printf("%s", buf);
+
+ if (*flags == 0)
+ mbedtls_printf("No verification issue for this certificate\n");
+ else
+ {
+ mbedtls_x509_crt_verify_info(buf, buf_size, " ! ", *flags);
+ mbedtls_printf("%s\n", buf);
+ }
+
+ delete[] buf;
+ return 0;
+ }
+#endif
+
+ /**
+ * Receive callback for Mbed TLS
+ */
+ static int ssl_recv(void *ctx, unsigned char *buf, size_t len) {
+ int recv = -1;
+ TCPSocket *socket = static_cast<TCPSocket *>(ctx);
+ recv = socket->recv(buf, len);
+
+ if(NSAPI_ERROR_WOULD_BLOCK == recv){
+ return MBEDTLS_ERR_SSL_WANT_READ;
+ }else if(recv < 0){
+ mbedtls_printf("Socket recv error %d\n", recv);
+ return -1;
+ }else{
+ return recv;
+ }
+ }
+
+ /**
+ * Send callback for Mbed TLS
+ */
+ static int ssl_send(void *ctx, const unsigned char *buf, size_t len) {
+ int size = -1;
+ TCPSocket *socket = static_cast<TCPSocket *>(ctx);
+ size = socket->send(buf, len);
+
+ if(NSAPI_ERROR_WOULD_BLOCK == size){
+ return MBEDTLS_ERR_SSL_WANT_WRITE;
+ }else if(size < 0){
+ mbedtls_printf("Socket send error %d\n", size);
+ return -1;
+ }else{
+ return size;
+ }
+ }
+
+ TCPSocket* _tcpsocket;
+ volatile bool _disconnected;
+ unsigned int _tls;
+};
+
+
+#endif // _MQTTNETWORK_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/easy-connect.lib Sat Mar 31 15:10:54 2018 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/easy-connect/#a05bde9c9d7ceaeacd471afa9989826a282b891d
--- a/inc/BleMasterService.h Tue Mar 13 16:31:07 2018 +0000 +++ b/inc/BleMasterService.h Sat Mar 31 15:10:54 2018 +0000 @@ -188,9 +188,9 @@ - /* Supported peripheral nodes name */ -const char NODE_MOTENV[] = "ME1V310"; +//const char NODE_MOTENV[] = "ME1V310"; +const char NODE_MOTENV[] = "ME1V320"; const char NODE_FLIGHT[] = "FL1V310"; const char NODE_ALLMEMS[] = "AM1V320";
--- a/mbed_app.json Tue Mar 13 16:31:07 2018 +0000
+++ b/mbed_app.json Sat Mar 31 15:10:54 2018 +0000
@@ -1,5 +1,44 @@
{
+ "config": {
+ "network-interface":{
+ "help": "options are ETHERNET, WIFI_ESP8266, WIFI_IDW0XX1, WIFI_ODIN, WIFI_RTW, MESH_LOWPAN_ND, MESH_THREAD, CELLULAR_ONBOARD",
+ "value": "WIFI_IDW0XX1"
+ },
+ "wifi-ssid": {
+ "value": "\"TP-LINK_2.4GHz\""
+ },
+ "wifi-password": {
+ "value": "\"giogerd.62\""
+ },
+ "wifi-tx": {
+ "help": "TX pin for serial connection to external device",
+ "value": "PA_11"
+ },
+ "wifi-rx": {
+ "help": "RX pin for serial connection to external device",
+ "value": "PA_12"
+ }
+ },
+ "macros": [ "MQTT_BROKER_URL=\".messaging.internetofthings.ibmcloud.com\"",
+ "MQTT_CLIENT_ID=\"d:<your ORG_ID>:<your DEVICE_ID_TYPE>:<your DEVICE_ID>\"",
+ "MQTT_ORG_ID=\"lbtsvf\"",
+ "MQTT_USERNAME=\"use-token-auth\"",
+ "MQTT_DEVICE_PASSWORD=\"STM32Nucleo_password\"",
+ "MQTT_TOPIC=\"iot-2/evt/status/fmt/json\"",
+ "MQTT_DEVICE_ID=\"licio\"",
+ "MQTT_DEVICE_TYPE=\"STM32Nucleo_device\"",
+ "MQTT_KEEPALIVE 10",
+ "MQTT_PORT 1883",
+ "MQTT_TLS_PORT 8883",
+ "MBED_CONF_APP_MAIN_STACK_SIZE=6120",
+ "MBEDTLS_USER_CONFIG_FILE=\"mbedtls_entropy_config.h\""
+ ],
"target_overrides": {
+ "*": {
+ "target.features_add": ["NANOSTACK", "LOWPAN_ROUTER", "COMMON_PAL"],
+ "mbed-mesh-api.6lowpan-nd-channel-page": 0,
+ "mbed-mesh-api.6lowpan-nd-channel": 12
+ },
"K64F": {
"target.features_add": ["BLE"],
"target.extra_labels_add": ["ST_BLUENRG"]
@@ -11,6 +50,10 @@
"DISCO_L475VG_IOT01A": {
"target.features_add": ["BLE"],
"target.extra_labels_add": ["ST_BLUENRG"]
+ },
+ "NUCLEO_L476RG": {
+ "target.features_add": ["BLE"],
+ "target.extra_labels_add": ["ST_BLUENRG"]
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbedtls_entropy_config.h Sat Mar 31 15:10:54 2018 +0000 @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006-2016, Arm Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT) && \ + !defined(MBEDTLS_ENTROPY_NV_SEED) && !defined(MBEDTLS_TEST_NULL_ENTROPY) +//#error "This hardware does not have an entropy source." +#endif /* !MBEDTLS_ENTROPY_HARDWARE_ALT && !MBEDTLS_ENTROPY_NV_SEED && + * !MBEDTLS_TEST_NULL_ENTROPY */ + +#if !defined(MBEDTLS_SHA1_C) +#define MBEDTLS_SHA1_C +#endif /* !MBEDTLS_SHA1_C */ + +/* + * This value is sufficient for handling 2048 bit RSA keys. + * + * Set this value higher to enable handling larger keys, but be aware that this + * will increase the stack usage. + */ +#define MBEDTLS_MPI_MAX_SIZE 256 + +#define MBEDTLS_MPI_WINDOW_SIZE 1 + +#if defined(TARGET_STM32F439xI) && defined(MBEDTLS_CONFIG_HW_SUPPORT) +#undef MBEDTLS_AES_ALT +#endif /* TARGET_STM32F439xI && MBEDTLS_CONFIG_HW_SUPPORT */
--- a/source/BleMasterService.cpp Tue Mar 13 16:31:07 2018 +0000
+++ b/source/BleMasterService.cpp Sat Mar 31 15:10:54 2018 +0000
@@ -7,6 +7,10 @@
EventQueue eventQ(/* event count */ 128 * EVENTS_EVENT_SIZE);
+/* 1 to disable reading after master disconnection */
+uint8_t discFlag = 0;
+
+
/* This var defines the central role
* 0 if master
* 1 if slave */
@@ -21,7 +25,6 @@
-
/* Flag to indicate if the device discovery is completed successful
* 1 successful
* 0 or anything else failed */
@@ -54,6 +57,16 @@
+/* Connection Parameters struct */
+Gap::ConnectionParams_t connection_parameters = {
+ 0x0032, // min connection interval
+ 0x0087, // max connection interval
+ 0, // slave latency
+ 0x0C80 // connection supervision timeout
+};
+
+
+
/* Header pointer of the DiscoveredCharacteristic list */
DiscoveredCharacteristicNode * headCharacteristic[MAX_NUM_OF_NODES];
DiscoveredCharacteristicNode * tmp[MAX_NUM_OF_NODES];
@@ -79,16 +92,12 @@
UUID::LongUUIDBytes_t LUX_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x01,0x00,0x00,0x00,0x00,0x01};
UUID::LongUUIDBytes_t CONFIG_CHAR_UUID = {0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x36,0xac,0xe1,0x11,0x0F,0x00,0x02,0x00,0x00,0x00};
-/*----- -----*/
-uint8_t wifi_data[256];
-uint8_t new_data = 0;
-uint8_t *data;
-uint8_t wifi_present;
+extern uint8_t wifi_data[256];
+extern uint8_t new_data;
+extern uint8_t *data;
+extern uint8_t wifi_present;
char print_msg_buff[512];
-//UART_HandleTypeDef UartMsgHandle;
-
-//uint16_t connection_handle = 0;
uint8_t attribute_value[20];
uint8_t star_attr_value[256];
@@ -180,7 +189,7 @@
if ((perDevs.status != 10) && (perDevs.status != 11) && (perDevs.status != 12) && (perDevs.status != 13) && (perDevs.status != 14)
&& (perDevs.status != 15) && (perDevs.status != 16) && (perDevs.status != 17) && (perDevs.status != 18)
&& (perDevs.status != 19) && (perDevs.status != 20) && (perDevs.status != 21)){
- printf("\r\nCurrent Status (status: %d) (read: %s) (write: %s)\n", perDevs.status, (readCompleted == 1 ? "completed" : "pending"),(writeDescriptorCompleted == 1 ? "completed" : "pending"));
+ printf("\r\nCurrent Status (stat: %d) (read: %s) (write: %s)\n", perDevs.status, (readCompleted == 1 ? "completed" : "pending"),(writeDescriptorCompleted == 1 ? "completed" : "pending"));
}
}
/*----------------------------------------------------------------------------*/
@@ -203,7 +212,7 @@
void connectionProcess(void){
- //printf("\r\nconnectionProcess(%d)\n", perDevs.status);//DEBUG
+
@@ -212,7 +221,8 @@
if ( (perDevs.connDevices < MAX_NUM_OF_NODES) && (perDevs.discovery_enabled) ) {
/* Start discovery of new peripheral nodes and connect them */
//startDiscovery();
- eventQ.call(startDiscovery);
+ if (notificationPending == 0)
+ eventQ.call(startDiscovery);
}
else {
perDevs.status = DEVICE_CONNECTED;
@@ -229,7 +239,8 @@
if ( perDevs.device_found == true ) {
/* Establishing connection with a peripheral device */
perDevs.status = START_DEVICE_CONNECTION;
- connectPeripheral();
+ eventQ.call(connectPeripheral);
+ //connectPeripheral();
}else {
perDevs.status = DEVICE_NOT_FOUND;
}
@@ -332,13 +343,13 @@
/* Function called to connect a peripheral */
void connectPeripheral(void){
- ble_error_t e0, e1;
+ ble_error_t e1;
BLE& ble = BLE::Instance();
/* if 1 to enable */
-#if 1
- e0 = ble.gap().stopScan();
+#if 0
+ ble_error_t e0 = ble.gap().stopScan();
if (e0 != BLE_ERROR_NONE){
printf("\r\nError while stopping scan\n");
}
@@ -354,14 +365,20 @@
role = 0;
- e1 = ble.gap().connect(perDevs.devInfo[index].bdaddr, BLEProtocol::AddressType::RANDOM_STATIC, NULL, NULL);
-
-
+ e1 = ble.gap().connect(perDevs.devInfo[index].bdaddr, BLEProtocol::AddressType::RANDOM_STATIC, &connection_parameters, NULL);
+
if (e1 != BLE_ERROR_NONE){
- printf("Error while starting connection with peripheral %d (%02x%02x).\n",
- index+1, perDevs.devInfo[index].bdaddr[NODE_ID_B2], perDevs.devInfo[index].bdaddr[NODE_ID_B1]);
+ printf("\r\nError (%d) while connecting per %d (%02x%02x) (stat: %d) (read: %s) (write: %s)\n", e1, index+1,
+ perDevs.devInfo[index].bdaddr[NODE_ID_B2], perDevs.devInfo[index].bdaddr[NODE_ID_B1], perDevs.status,
+ (readCompleted == 1 ? "completed" : "pending"),(writeDescriptorCompleted == 1 ? "completed" : "pending"));
+
+
perDevs.is_unconnectable[index] = true;
- }
+ //perDevs.is_unconnectable[index] = false;
+
+ perDevs.device_found = false;
+ perDevs.status = DEVICE_NOT_FOUND;
+ }//if-error
}
/*----------------------------------------------------------------------------*/
@@ -436,7 +453,11 @@
/* SLAVE ROLE */
if (handle == slaveDev.conn_handle) {
printf("\r\nMaster disconnected (adv: %d - status %d)\n", ble.gap().getState().advertising, perDevs.status);//DEBUG
-
+
+ /* Disable reading after master disconnection */
+ //discFlag = 1;
+
+
slaveDev.is_discoverable = true;
slaveDev.is_connected = false;
@@ -607,9 +628,8 @@
discoveryCompleted = 0;
- /* if 1 to enable
- * if 0 default because of the adv timer setup */
-
+/* if 1 to enable
+ * if 0 default because of the adv timer setup */
#if 0
if ((slaveDev.is_connected == false) && (slaveDev.is_discoverable == true)){
//printf("\r\nslaveDev.is_discoverable == true\n");//DEBUG
@@ -664,7 +684,6 @@
/* Function called as response of advertising */
void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { //defined in Gap.h
- //printf("\r----> advertisementCallback\n");//DEBUG
static const size_t ADDR_LEN = 6;
//the current address
@@ -676,117 +695,14 @@
uint8_t alreadyIn = 1;
- uint8_t index;
- //uint8_t i;
+ uint8_t index, i;
uint8_t found_zero_pos = 0;
BLEProtocol::AddressBytes_t zeroAddr;
memset(zeroAddr, 0, 6);
-
-if (perDevs.status != DEVICE_FOUND) {
-
-
- for (uint8_t i = 0; i < params->advertisingDataLen; ++i) {
-
- const uint8_t record_length = params->advertisingData[i];
- if (record_length == 0) {
- continue;
- }
- const uint8_t type = params->advertisingData[i + 1];
- const uint8_t* value = params->advertisingData + i + 2;
- const uint8_t value_length = record_length - 1;
-
-
-
-
-
-
-
- /* Switch because per NAMES */
- if(type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
-
-
-
- /* Switch the peripheral nodes */
-
- // M O T E N V
- if (((value_length == sizeof(NODE_MOTENV)-1) && (memcmp(value, NODE_MOTENV, value_length) == 0))) {
-
-
- //initial per data
- uint8_t peripheral_v;
- uint8_t wup_event = 0;
- uint8_t mic_event = 0;
- uint8_t prx_event = 0;
- uint8_t agm_event = 0;
- uint8_t sfusion_event = 0;
-
- uint8_t peripheral_name_len = params->advertisingData[3];
- const uint8_t * manuf_data = params->advertisingData+4+peripheral_name_len;
- uint32_t features = 0;
-
-
- features = (manuf_data[4]<<24) | (manuf_data[5]<<16) | (manuf_data[6]<<8) | manuf_data[7];
- wup_event = (features & FEATURE_MASK_WAKEUP_EVENTS) >> WUP_POS;
- mic_event = (features & FEATURE_MASK_MIC) >> MIC_POS;
- prx_event = (features & FEATURE_MASK_PROX) >> PRX_POS;
- agm_event = (features & FEATURE_MASK_ACC) >> ACC_POS;
- sfusion_event = (features & FEATURE_MASK_SENSORFUSION) >> SFUS_POS;
- peripheral_v = NODE_ME1;//MOTENV
-
-
- for (i=0; i<MAX_NUM_OF_NODES; i++) {
- if (perDevs.is_disconnected[i]) {
- if (memcmp(zeroAddr, perDevs.devInfo[i].bdaddr, 6)==0) {
- if (!found_zero_pos) {
- index = i;
- perDevs.connDeviceIdx = i;
- found_zero_pos = 1;
- alreadyIn = 0;
- }
- }
- else if (memcmp(tempAddr, perDevs.devInfo[i].bdaddr, 6)==0) {
- index = i;
- perDevs.connDeviceIdx = i;
- alreadyIn = 0;
- perDevs.discDevices--;
- break;
- }
- else {
- if (!found_zero_pos) {
- index = i;
- perDevs.connDeviceIdx = i;
- alreadyIn = 0;
- }
- }
- }
- }//for
-
-
- if ((!alreadyIn) && (perDevs.connDevices < MAX_NUM_OF_NODES)) {
-
-
- /* Save the found peripheral device in the struct containing all the found peripheral devices */
- saveDeviceFound(params->type, tempAddr, params->advertisingDataLen, params->advertisingData, index,
- peripheral_v, wup_event, mic_event, prx_event, agm_event, sfusion_event);
-
- perDevs.status = DEVICE_FOUND;
-
- printf("\r\nPeripheral (MOTENV) %d inserted [%02x %02x %02x %02x %02x %02x] \n", perDevs.connDevices+1,
- tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]);
-
- }//if-alreadyIn
-
-
- }//IF-MOTENV
-
-
-
-
- // F L I G H T
- if ((value_length == sizeof(NODE_FLIGHT)-1) && (memcmp(value, NODE_FLIGHT, value_length) == 0)) {
-
+ if (perDevs.status != DEVICE_FOUND) {
+
//initial per data
uint8_t peripheral_v;
uint8_t wup_event = 0;
@@ -798,148 +714,85 @@
uint8_t peripheral_name_len = params->advertisingData[3];
const uint8_t * manuf_data = params->advertisingData+4+peripheral_name_len;
uint32_t features = 0;
-
-
- features = (manuf_data[4]<<24) | (manuf_data[5]<<16) | (manuf_data[6]<<8) | manuf_data[7];
- wup_event = (features & FEATURE_MASK_WAKEUP_EVENTS) >> WUP_POS;
- mic_event = (features & FEATURE_MASK_MIC) >> MIC_POS;
- prx_event = (features & FEATURE_MASK_PROX) >> PRX_POS;
- agm_event = (features & FEATURE_MASK_ACC) >> ACC_POS;
- sfusion_event = (features & FEATURE_MASK_SENSORFUSION) >> SFUS_POS;
- peripheral_v = NODE_FL1;//FLIGHT
-
-
-
- for (i=0; i<MAX_NUM_OF_NODES; i++) {
- if (perDevs.is_disconnected[i]) {
- if (memcmp(zeroAddr, perDevs.devInfo[i].bdaddr, 6)==0) {
- if (!found_zero_pos) {
- index = i;
- perDevs.connDeviceIdx = i;
- found_zero_pos = 1;
- alreadyIn = 0;
- }
- }
- else if (memcmp(tempAddr, perDevs.devInfo[i].bdaddr, 6)==0) {
- index = i;
- perDevs.connDeviceIdx = i;
- alreadyIn = 0;
- perDevs.discDevices--;
- break;
- }
- else {
- if (!found_zero_pos) {
- index = i;
- perDevs.connDeviceIdx = i;
- alreadyIn = 0;
- }
- }
+
+ if ((manuf_data[1] == MANUF_SPECIFIC_TYPE) && ((manuf_data[3] == STM32_NUCLEO)
+ || (manuf_data[3] == SENSOR_TILE) || (manuf_data[3] == BLUE_COIN)) && (peripheral_name_len == 8)) {
+
+ features = (manuf_data[4]<<24) | (manuf_data[5]<<16) | (manuf_data[6]<<8) | manuf_data[7];
+ wup_event = (features & FEATURE_MASK_WAKEUP_EVENTS) >> WUP_POS;
+ mic_event = (features & FEATURE_MASK_MIC) >> MIC_POS;
+ prx_event = (features & FEATURE_MASK_PROX) >> PRX_POS;
+ agm_event = (features & FEATURE_MASK_ACC) >> ACC_POS;
+ sfusion_event = (features & FEATURE_MASK_SENSORFUSION) >> SFUS_POS;
+
+
+ /* Switch the kind of node */
+ if (mic_event) {
+ peripheral_v = NODE_AM1;
+
+ }else if (prx_event) {
+ peripheral_v = NODE_FL1;
+
+ }else {
+ peripheral_v = NODE_ME1;
}
- }//for
-
-
- if ((!alreadyIn) && (perDevs.connDevices < MAX_NUM_OF_NODES)) {
-
-
- /* Save the found peripheral device in the struct containing all the found peripheral devices */
- saveDeviceFound(params->type, tempAddr, params->advertisingDataLen, params->advertisingData, index,
- peripheral_v, wup_event, mic_event, prx_event, agm_event, sfusion_event);
-
- perDevs.status = DEVICE_FOUND;
-
- printf("\r\nPeripheral (FLIGHT) %d inserted [%02x %02x %02x %02x %02x %02x] \n", perDevs.connDevices+1,
- tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]);
- }//if-alreadyIn
-
- }//IF-FLIGHT
-
-
-
-
-
-
-
- // A L L M E M S
- if ((value_length == sizeof(NODE_ALLMEMS)-1) && (memcmp(value, NODE_ALLMEMS, value_length) == 0)){
-
-
- //initial per data
- uint8_t peripheral_v;
- uint8_t wup_event = 0;
- uint8_t mic_event = 0;
- uint8_t prx_event = 0;
- uint8_t agm_event = 0;
- uint8_t sfusion_event = 0;
-
- uint8_t peripheral_name_len = params->advertisingData[3];
- const uint8_t * manuf_data = params->advertisingData+4+peripheral_name_len;
- uint32_t features = 0;
-
-
- features = (manuf_data[4]<<24) | (manuf_data[5]<<16) | (manuf_data[6]<<8) | manuf_data[7];
- wup_event = (features & FEATURE_MASK_WAKEUP_EVENTS) >> WUP_POS;
- mic_event = (features & FEATURE_MASK_MIC) >> MIC_POS;
- prx_event = (features & FEATURE_MASK_PROX) >> PRX_POS;
- agm_event = (features & FEATURE_MASK_ACC) >> ACC_POS;
- sfusion_event = (features & FEATURE_MASK_SENSORFUSION) >> SFUS_POS;
- peripheral_v = NODE_AM1;//ALLMEMS
-
-
- for (i=0; i<MAX_NUM_OF_NODES; i++) {
- if (perDevs.is_disconnected[i]) {
- if (memcmp(zeroAddr, perDevs.devInfo[i].bdaddr, 6)==0) {
- if (!found_zero_pos) {
- index = i;
- perDevs.connDeviceIdx = i;
- found_zero_pos = 1;
- alreadyIn = 0;
+
+
+ for (i=0; i<MAX_NUM_OF_NODES; i++) {
+ if (perDevs.is_disconnected[i]) {
+ if (memcmp(zeroAddr, perDevs.devInfo[i].bdaddr, 6)==0) {
+ if (!found_zero_pos) {
+ index = i;
+ perDevs.connDeviceIdx = i;
+ found_zero_pos = 1;
+ alreadyIn = 0;
+ }
+
+ }else if (memcmp(tempAddr, perDevs.devInfo[i].bdaddr, 6)==0) {
+ index = i;
+ perDevs.connDeviceIdx = i;
+ alreadyIn = 0;
+ perDevs.discDevices--;
+ break;
+
+ }else {
+ if (!found_zero_pos) {
+ index = i;
+ perDevs.connDeviceIdx = i;
+ alreadyIn = 0;
+ }
+ }
+ }//perDevs.is_disconnected[i]
+ }//for
+
+ if ((!alreadyIn) && (perDevs.connDevices < MAX_NUM_OF_NODES)) {
+
+ /* Save the found peripheral device in the struct containing all the found peripheral devices */
+ saveDeviceFound(params->type, tempAddr, params->advertisingDataLen, params->advertisingData, index,
+ peripheral_v, wup_event, mic_event, prx_event, agm_event, sfusion_event);
+
+ perDevs.status = DEVICE_FOUND;
+
+ switch(peripheral_v){
+ case 0x01: /* MOTENV1 */
+ printf("\r\nPeripheral (MOTENV) %d inserted [%02x %02x %02x %02x %02x %02x] \n", perDevs.connDevices+1,
+ tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]);
+ break;
+
+ case 0x02: /* FLIGHT1 */
+ printf("\r\nPeripheral (FLIGHT) %d inserted [%02x %02x %02x %02x %02x %02x] \n", perDevs.connDevices+1,
+ tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]);
+ break;
+
+ case 0x03: /* ALLMEMS1 */
+ printf("\r\nPeripheral (ALLMEMS) %d inserted [%02x %02x %02x %02x %02x %02x] \n", perDevs.connDevices+1,
+ tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]);
+ break;
}
- }
- else if (memcmp(tempAddr, perDevs.devInfo[i].bdaddr, 6)==0) {
- index = i;
- perDevs.connDeviceIdx = i;
- alreadyIn = 0;
- perDevs.discDevices--;
- break;
- }
- else {
- if (!found_zero_pos) {
- index = i;
- perDevs.connDeviceIdx = i;
- alreadyIn = 0;
- }
- }
- }
- }//for
-
-
- if ((!alreadyIn) && (perDevs.connDevices < MAX_NUM_OF_NODES)) {
-
-
- /* Save the found peripheral device in the struct containing all the found peripheral devices */
- saveDeviceFound(params->type, tempAddr, params->advertisingDataLen, params->advertisingData, index,
- peripheral_v, wup_event, mic_event, prx_event, agm_event, sfusion_event);
-
- perDevs.status = DEVICE_FOUND;
-
-
- printf("\r\nPeripheral (ALLMEMS) %d inserted [%02x %02x %02x %02x %02x %02x] \n", perDevs.connDevices+1,
- tempAddr[5], tempAddr[4], tempAddr[3], tempAddr[2], tempAddr[1], tempAddr[0]);
-
- }//if-alreadyIn
-
-
- }//IF-ALLMEMS
-
-
- }//IF-typeCOMPLETE_LOCAL_NAME
-
-
- i += record_length;
- }//for-MAIN
-
-}//if status != DEVICE_FOUND
-
+
+ }//IF-alreadyIn
+ }//IF-ST-hw
+ }//IF-!DEVICE_FOUND
}
/*----------------------------------------------------------------------------*/
@@ -2338,6 +2191,7 @@
}
+ /* Enable notification here because a reading operation was pending */
if (notificationPending == 1){
readCompleted = 1;
Change_Notification_Status(notifyP->att_data, notifyP->attr_value, notifyP->conn_handle, notifyP->i, notifyP->feature_mask, notifyP->frequency);
@@ -2353,7 +2207,6 @@
/* This function retrieves the peripheral device index and address
* from the connection handle */
void getDeviceFromConnHandle(uint16_t handle, uint8_t *index, tBDAddr devAddr){
-
//printf("\r\ngetDeviceFromConnHandle\n\n");//DEBUG
uint8_t i;
@@ -2376,7 +2229,8 @@
pointer->connHandle = connection_handle;
pointer->len = 0;
- pointer->data = NULL;
+ //pointer->data = NULL;
+ pointer->data = 0;
return pointer;
@@ -2416,43 +2270,9 @@
/* start to read sensors data from environmental */
if ((perDevs.mic_event_enabled) || (perDevs.prx_event_enabled) || (perDevs.agm_event_enabled)
- || (perDevs.sfusion_event_enabled)){
+ || (perDevs.sfusion_event_enabled) || (discFlag)){
//printf("\r\nNotification event enabled, skip reading\n");//DEBUG
- if (stackBusy == 1){
- uint8_t j;
- uint16_t attr_handle;
- uint8_t value_len;
- uint8_t attr_value[2];
- char* feat = NULL;
-
- for (j=0; j<(perDevs.connDevices+perDevs.discDevices); j++) {
-
- if ((perDevs.prx_event[j]) && (perDevs.prx_event_enabled)) {
- feat = "PRX";
- perDevs.prx_event_enabled = 0;
- perDevs.prx_on[j] = 0;
- attr_handle = perDevs.prx_char_handle[j] + 2;
-
- } else {
- continue;
- }
-
- value_len = 2;
- attr_value[0] = DISABLE;
-
- writeDescriptorCompleted=0;
- ble_error_t disableErr = writeCharacDescriptorWithError(perDevs.connection_handle[j], attr_handle, value_len, attr_value);
- printf("\r\nSet OFF the %s notifications on node %d\n", feat, j);
-
- if (disableErr != BLE_ERROR_NONE){
- printf("\r\n(readingProcess) Write charac descriptor failed (err: %d, stat: %d)\n", disableErr, perDevs.status);
- writeDescriptorCompleted=1;
-
- }//if-error
- }//for
- }//if-stackBusy
-
} else {
perDevs.status = READING_ENVIRONMENTAL;
}
@@ -2647,23 +2467,20 @@
if ((perDevs.status == ALL_DATA_READ) && (readCompleted == 1) && (writeDescriptorCompleted ==1)) {
if (i>0) {
perDevs.readDeviceIdx--;
- }
+ }//i>0
+
perDevs.status = READ_INIT;
+ if ((slaveDev.is_connected == false) && (slaveDev.is_discoverable == true)) {
+#if ENABLE_MEMS
+ disableAllNotifications(); /* Called here to disable the SFUSION notifications */
+#endif
+ setSlaveDiscoverable();
+ }
// All peripherals are read!
if (i==0) {
-
- if ((slaveDev.is_connected == false) && (slaveDev.is_discoverable == true)) {
-#if ENABLE_MEMS
- disableAllNotifications(); /* Called here to disable the SFUSION notifications */
-#endif
- setSlaveDiscoverable();
-
- } else {
- perDevs.status = CONN_INIT;
- }//if-else-adv
-
- }//if-i=0
+ perDevs.status = CONN_INIT;
+ }//i=0
}//if-ALL_DATA_READ
@@ -2686,7 +2503,7 @@
/* Start connection process */
- eventQ.call(connectionProcess);
+ //eventQ.call(connectionProcess);
}
/*----------------------------------------------------------------------------*/
@@ -2699,29 +2516,19 @@
ble_error_t error;
-
-
-
- if (!perDevs.is_disconnected[index] && characteristic.getDeclHandle()){
-// printf("\r\n\nReading sensor data from periph %d (0x%04x - 0x%04x) - status=%d\n", index+1,
-// connection_handle, characteristic.getDeclHandle(), perDevs.status);//DEBUG
-
- error = characteristic.read();
-
- if (error != BLE_ERROR_NONE){
- printf("\r\nUnable to read data from periph %d (err %d, cHndl 0x%04x - dHdl 0x%04x)\n", index+1,
- error, connection_handle, characteristic.getDeclHandle());
-
- eventQ.call(setNewStatus);
- readCompleted = 1;
- }//if-failed
-
-
- } else {
+ if (!perDevs.is_disconnected[index] && characteristic.getDeclHandle()){
+ error = characteristic.read();
+
+ if (error != BLE_ERROR_NONE){
+ printf("\r\nUnable to read data from periph %d (err %d, cHndl 0x%04x - dHdl 0x%04x)\n", index+1,
+ error, connection_handle, characteristic.getDeclHandle());
eventQ.call(setNewStatus);
-
- }//if-else-isConnected
-
+ readCompleted = 1;
+ }//if-failed
+
+ } else {
+ eventQ.call(setNewStatus);
+ }//if-else
}
/*----------------------------------------------------------------------------*/
--- a/source/BleSlaveService.cpp Tue Mar 13 16:31:07 2018 +0000
+++ b/source/BleSlaveService.cpp Sat Mar 31 15:10:54 2018 +0000
@@ -84,9 +84,8 @@
//Restart loop ops
- perDevs.status = CONN_INIT;
- perDevs.discovery_enabled = true;
- //printf("\rstatus = CONN_INIT (%d)\n", perDevs.status);//DEBUG
+ //perDevs.status = CONN_INIT;
+ //perDevs.discovery_enabled = true;
}
/*----------------------------------------------------------------------------*/
@@ -143,7 +142,7 @@
/* The gatt write function above is w/out response, so we just wait for a short time before going on */
writeCharacValueWithoutResp(conn_handle, attr_handle, value_len, attr_value);
- HAL_Delay(2000);//N ms
+ HAL_Delay(1000);//N ms
}
/*----------------------------------------------------------------------------*/
@@ -155,8 +154,8 @@
//printf("\r\nnotifyMaster\n");//DEBUG
ble_error_t notifyError;
-
- notifyError = BLE::Instance().gattServer().write(attribute_handle+1, attribute_value, data_length, false);
+ if (slaveDev.is_connected !=0)
+ notifyError = BLE::Instance().gattServer().write(attribute_handle+1, attribute_value, data_length, false);
if (notifyError != BLE_ERROR_NONE){
printf("\r\n(notifyMaster) Error (%d) while updating characteristic\n", notifyError);//BLE_STACK_BUSY
@@ -277,16 +276,16 @@
switch (enabled) {
case 0x01:
perDevs.discovery_enabled = true;
- //printf("\r\nScanning enabled (%d)\n", enabled);
+// printf("\r\nScanning enabled (%d)\n", enabled);
break;
case 0x02:
perDevs.discovery_enabled = false;
- //printf("\r\nScanning disabled (%d)\n", enabled);
+// printf("\r\nScanning disabled (%d)\n", enabled);
break;
default:
- //printf("\r\nScanning set to unrecognized value (%d)\n", enabled);
+// printf("\r\nScanning set to unrecognized value (%d)\n", enabled);
break;
}
@@ -297,8 +296,8 @@
/* Notify master for scanning */
/* Check the scan enable/disable */
-// notifyMaster(slaveDev.star_config_value_len, slaveDev.star_config_value,
-// slaveDev.star_config_char_handle);
+ notifyMaster(slaveDev.star_config_value_len, slaveDev.star_config_value,
+ slaveDev.star_config_char_handle);
}
/*----------------------------------------------------------------------------*/
@@ -405,8 +404,7 @@
/* This function is called when a local attribute gets modified */
void AttributeModified_CB(const GattWriteCallbackParams* param){
-// printf("\r\nAttributeModified_CB (%d)\n", perDevs.status);//DEBUG
-
+ //printf("\r\nAttributeModified_CB\n");//DEBUG
/* Assign prototype vars */
uint16_t handle = param->handle;
@@ -640,7 +638,6 @@
/* Then, call the Change_Notification_Status from the readCallback with these params */
}else if (readCompleted == 1) {
- //notificationPending = 0;
Change_Notification_Status(att_data, attr_value, conn_handle, i, FEATURE_MASK_SENSORFUSION, SENDING_INTERVAL_100MS_MULTIPLE);
}
@@ -766,8 +763,7 @@
attr_value[0] = 0x01;
setNotificationProperty(perDevs.connection_handle[j], j, FEATURE_MASK_WAKEUP_EVENTS, WAKEUP_NOTIFICATION_CMD, 1);
-
-// if (discoveryCompleted == 1){
+
writeDescriptorCompleted=0;
ble_error_t wupErrOn = writeCharacDescriptorWithError(perDevs.connection_handle[j], attr_handle, value_len, attr_value);
@@ -775,14 +771,12 @@
perDevs.wup_event_enabled = 1;
perDevs.wup_event[j] = 1;
printf("\r\nWUP notification on node [%d] ON\n", j);
-
+
} else {
printf("\r\nWrite WUP char descriptor failed! (%d)\n", wupErrOn);
writeDescriptorCompleted=1;
}//if-else
-
-// }//if-else-discovery-completed
}//if
}//for
@@ -799,7 +793,6 @@
attr_value[0] = 0x00;
-// if (discoveryCompleted == 1){
writeDescriptorCompleted=0;
ble_error_t wupErrOff = writeCharacDescriptorWithError(perDevs.connection_handle[j], attr_handle, value_len, attr_value);
@@ -813,25 +806,25 @@
writeDescriptorCompleted=1;
}
-
-// }//if-discovery-completed
}//if
}//for
+ if (perDevs.wup_event_enabled == 0)
+ //printf("\r\nAll WUP notifications turned OFF\n");//DEBUG
perDevs.status = NOTIFICATIONS_DATA_READ;
}//if-else-wup
+
+
attr_value[0] = att_data[3];
perDevs.readDeviceIdx = i;
-
+
+ /* No notification is pending anymore */
notificationPending = 0;
//Return to connectionProcess
- perDevs.status = CONN_INIT;
-
+ //perDevs.status = CONN_INIT;
-
-
}
/*----------------------------------------------------------------------------*/
--- a/source/main.cpp Tue Mar 13 16:31:07 2018 +0000
+++ b/source/main.cpp Sat Mar 31 15:10:54 2018 +0000
@@ -1,19 +1,3 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2006-2015 ARM Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
#include <events/mbed_events.h>
#include <mbed.h>
#include "ble/BLE.h"
@@ -22,13 +6,278 @@
#include <UUID.h>
#include <BleMasterService.h>
#include <BleSlaveService.h>
+#include <string.h>
+#include "easy-connect.h"
+#include "MQTTClient.h"
+#include "MQTTmbed.h"
+#include "MQTTNetwork.h"
+
+/*----------------------------------------------------------------------------*/
+
+/* Enable/Disable WiFi (1 = WiFi Enabled, 0 = WiFi Disabled) */
+#define ENABLE_WIFI 1
+
+/**** System configuration define ****/
+#define ORG_QUICKSTART // comment to connect to play.internetofthings.ibmcloud.com
+#ifndef ORG_QUICKSTART
+//#define TLS_EN // uncomment to add TLS to NON quickstart connections
+#endif
+
+#ifdef TLS_EN // Digicert Root Certificate in PEM format (from IBM website)
+const char SSL_CA_PEM[] ="-----BEGIN CERTIFICATE-----\n"
+"MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n"
+"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
+"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n"
+"QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n"
+"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n"
+"b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n"
+"9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n"
+"CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n"
+"nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n"
+"43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n"
+"T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n"
+"gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n"
+"BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n"
+"TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n"
+"DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n"
+"hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n"
+"06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n"
+"PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n"
+"YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n"
+"CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n"
+"-----END CERTIFICATE-----\n";
+#endif
+
+
+
+static bool quickstartMode = true; // set to false to connect with authentication tocken
+
+#define MQTT_MAX_PACKET_SIZE 400
+#define MQTT_MAX_PAYLOAD_SIZE 300
+
+
+
+// Configuration values needed to connect to IBM IoT Cloud
+#ifdef ORG_QUICKSTART
+#define ORG "quickstart" // connect to quickstart.internetofthings.ibmcloud.com/ For a registered connection, replace with your org
+#define ID ""
+#define AUTH_TOKEN ""
+#define DEFAULT_TYPE_NAME "sensor"
+#define DEFAULT_PORT MQTT_PORT
+
+#else // not def ORG_QUICKSTART
+#define ORG MQTT_ORG_ID // connect to ORG.internetofthings.ibmcloud.com/ For a registered connection, replace with your org
+#define ID MQTT_DEVICE_ID // For a registered connection is your device id
+#define AUTH_TOKEN MQTT_DEVICE_PASSWORD // For a registered connection is a device auth-token
+#define DEFAULT_TYPE_NAME MQTT_DEVICE_TYPE // For a registered connection is device type
+
+#ifdef TLS_EN
+#define DEFAULT_PORT MQTT_TLS_PORT
+#else
+#define DEFAULT_PORT MQTT_PORT
+
+#endif
+#endif
+
+
+
+#define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type
+#define IBM_IOT_PORT DEFAULT_PORT
+
+#define MAXLEN_MBED_CONF_APP_WIFI_SSID 32 // same as WIFI_SSID_MAX_LEN in easy_connect
+#define MAXLEN_MBED_CONF_APP_WIFI_PASSWORD 64 // same as WIFI_PASSWORD_MAX_LEN
+
+static char id[30] = ID; // mac without colons
+static char org[12] = ORG;
+static int connack_rc = 0; // MQTT connack return code
+static char type[30] = TYPE;
+static char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
+static bool netConnecting = false;
+static bool mqttConnecting = false;
+static bool netConnected = false;
+static bool connected = false;
+static int retryAttempt = 0;
+static char subscription_url[MQTT_MAX_PAYLOAD_SIZE];
+static char ssid[MAXLEN_MBED_CONF_APP_WIFI_SSID]; // Network must be visible otherwise it can't connect
+static char seckey[MAXLEN_MBED_CONF_APP_WIFI_PASSWORD];
+
+MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> *pClient;
const char NAME_BLESTAR1[] = "BleStar1";
+uint8_t wifi_status;
+
+uint8_t wifi_data[256];
+uint8_t new_data = 0;
+uint8_t *data;
+uint8_t wifi_present;
+uint8_t start_bnrg;
+extern PeripheralDevices_t perDevs;
+uint8_t json_buffer[512];
+
+/*----------------------------------------------------------------------------*/
+
+
+
+/* Prepare JSON packet with sensors data */
+void prepare_json_pkt (uint8_t * buffer){
+ char tempbuff[256];
+
+ strcpy((char *)buffer,"{\"d\":{\"ST\":\"BLEStar\"");
+ sprintf(tempbuff, ",%s", data);
+ strcat((char *)buffer,tempbuff);
+ strcat((char *)buffer,"}}");
+
+ return;
+}
/*----------------------------------------------------------------------------*/
+/* Connect the broker - return the CONNACK*/
+int connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> * client, MQTTNetwork *mqttNetwork, NetworkInterface* network)
+{
+ const char* iot_ibm = MQTT_BROKER_URL;
+ char hostname[strlen(org) + strlen(iot_ibm) + 1];
+
+ sprintf(hostname, "%s%s", org, iot_ibm);
+ // Construct clientId - d:org:type:id
+ char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
+ sprintf(clientId, "d:%s:%s:%s", org, type, id);
+ sprintf(subscription_url, "%s.%s/#/device/%s/%s/", org, "internetofthings.ibmcloud.com", id, TYPE);
+
+ // Network debug statements
+ printf("\r\n=====================================");
+ printf("\r\nNucleo IP ADDRESS: %s\n", network->get_ip_address());
+ printf("\r\nNucleo MAC ADDRESS: %s\n", network->get_mac_address());
+ printf("\r\nServer Hostname: %s port: %d\n", hostname, IBM_IOT_PORT);
+ printf("\r\nClient ID: %s\n", clientId);
+ printf("\r\nTopic: %s\n",MQTT_TOPIC);
+ printf("\r\nSubscription URL: %s", subscription_url);
+ printf("\r\n=====================================\r\n");
+ netConnecting = true;
+
+
+
+#ifdef ORG_QUICKSTART
+ int tls = TLS_OFF;
+ const char * cert = NULL;
+ unsigned int sizeof_cert = 0;
+
+#else // if !QUICKSTART possible to connect with TLS or not
+#ifdef TLS_EN
+ int tls = TLS_ON;
+ const char * cert = SSL_CA_PEM;
+ unsigned int sizeof_cert = sizeof(SSL_CA_PEM);
+
+#else
+ int tls = TLS_OFF;
+ const char * cert = 0;
+ unsigned int sizeof_cert = 0;
+
+#endif
+#endif
+
+
+ //Return code
+ int rc = mqttNetwork->connect(hostname, IBM_IOT_PORT, tls, cert, sizeof_cert);
+ if (rc != 0)
+ {
+ printf("\r\nrc from TCP connect is %d\n", rc);
+ return rc;
+ }
+ netConnected = true;
+ netConnecting = false;
+
+
+ // MQTT Connect
+ mqttConnecting = true;
+ MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
+ data.MQTTVersion = 4;
+ data.struct_version=0;
+ data.clientID.cstring = clientId;
+ data.keepAliveInterval = 0; //MQTT_KEEPALIVE; // in Sec
+ if (!quickstartMode){
+ data.username.cstring = "use-token-auth";
+ data.password.cstring = auth_token;
+ printf ("\r\nAutToken: %s\n", auth_token);
+ }
+ if ((rc = client->connect(data)) != MQTT::SUCCESS) {
+ printf("\r\nrc from MQTT connect is %d\n", rc);
+ connack_rc = rc;
+ return rc;
+ }
+ connected = true;
+ printf ("\r\n--->MQTT Connected\n");
+
+ mqttConnecting = false;
+ connack_rc = rc;
+ return rc;
+}
+/*----------------------------------------------------------------------------*/
+
+
+
+int getConnTimeout(int attemptNumber)
+{ // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
+ // after 20 attempts, retry every 10 minutes
+ return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
+}
+/*----------------------------------------------------------------------------*/
+
+
+
+void attemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network)
+{
+ connected = false;
+
+ while (connect(client, mqttNetwork, network) != MQTT_CONNECTION_ACCEPTED)
+ {
+ if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) {
+ printf ("\r\nError MQTT_BAD_USERNAME_OR_PASSWORDFile: %s, Line: %d Error: %d \n",__FILE__,__LINE__, connack_rc);
+ return; // don't reattempt to connect if credentials are wrong
+ }
+ int timeout = getConnTimeout(++retryAttempt);
+ WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout);
+
+ // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
+ // or maybe just add the proper members to do this disconnect and call attemptConnect(...)
+ // this works - reset the system when the retry count gets to a threshold
+ if (retryAttempt == 5)
+ NVIC_SystemReset();
+ else
+ wait(timeout);
+ }
+}
+/*----------------------------------------------------------------------------*/
+
+
+/* Method to publish data to client (sending data to broker) */
+int publish(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client){
+ //printf("\r\npublish");//DEBUG
+
+ MQTT::Message message;
+ const char* pubTopic = MQTT_TOPIC;
+
+
+ if (!client->isConnected()){
+ printf ("\r\npublish failed: MQTT disconnected\n");
+ return MQTT::FAILURE;
+ }
+
+
+ message.qos = MQTT::QOS0; // quality of service 0 default
+ message.retained = false; // (false) new clients will not receive past data
+ message.dup = false; // (false) no duplicated message
+ message.payload = (void*)json_buffer; // DATA to be sent
+ message.payloadlen = strlen((const char *)(json_buffer));
+
+
+ return client->publish(pubTopic, message);
+}
+/*----------------------------------------------------------------------------*/
+
+
/* scheduleBleEventsProcessing */
void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
@@ -36,6 +285,10 @@
eventQ.call(Callback<void()>(&ble, &BLE::processEvents));
}
/*----------------------------------------------------------------------------*/
+
+
+
+
/* Complete the initialization of ble module */
void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){
@@ -59,12 +312,6 @@
return;
}
- printf("\r\nBLE Init Completed\n");
-
-
- /* notification */
- //ble.gattServer().onUpdatesEnabled(onUpdatesEnabledCallback);
- //ble.gattServer().onUpdatesDisabled(onUpdatesDisabledCallback);
/* notification + attr writing */
ble.gattServer().onDataWritten(AttributeModified_CB);
@@ -80,7 +327,7 @@
ble.gap().onDisconnection(disconnectionCallback);
/* connection */
ble.gap().onConnection(connectionCallback);
- ble.gap().setScanParams(400, 200); //(scanInterval,scanWindow)ms
+ ble.gap().setScanParams(200, 200); //(scanInterval,scanWindow)ms
ble.gap().setScanTimeout(0x0004); //stop scanning after N sec
ble.gap().onTimeout(onStopScan); //callback when scan stops
@@ -102,20 +349,48 @@
addAllServices();
printMacAddress();
-
-
- /* Start connection, service/chars discovery and enable notification */
- connectionProcess();
-
- /* Start advertising from this point */
- //setSlaveDiscoverable();//DEBUG_ONLY
}
/*----------------------------------------------------------------------------*/
-void onBleInitError(BLE &ble, ble_error_t error) {}
+void onBleInitError(BLE &ble, ble_error_t error){}
+/*----------------------------------------------------------------------------*/
+
+
+
+void mainFunc(void){
+
+ if ((wifi_present) && (perDevs.status != NOTIFICATIONS_DATA_READ)){
+
+ if((new_data)){
+ prepare_json_pkt(json_buffer);
+ }//if-new_data
+ start_bnrg = 1;
+
+ }else{
+ start_bnrg = 1;
+ if (perDevs.status != NOTIFICATIONS_DATA_READ) {
+ HAL_Delay(1000);
+ }
+ }//if-else
+
+
+ if (start_bnrg){
+ eventQ.call(connectionProcess);
+ }
+}
+/*----------------------------------------------------------------------------*/
+
+
+void MQTTpublish(){
+
+ if((new_data)){
+ /* publish every 5 seconds */
+ publish(pClient);
+ }//if-new_data
+}
/*----------------------------------------------------------------------------*/
@@ -124,20 +399,73 @@
{
printf("\r\n\n/*******************************************************\n");
printf("\r* *\n");
- printf("\r* FP-NET-BLESTAR1 (MBED) Expansion Software *\n");
+ printf("\r* BLESTAR1 MBED Expansion Software *\n");
printf("\r* *\n");
printf("\r*******************************************************/\n\n\n");
+
+#if ENABLE_WIFI
+ wifi_present = ENABLE_WIFI;
+ printf("\r\nWi-Fi Enabled!\n");
+ printf("\rTo edit SSID and/or Password please refer to mbed_app.json file\n");
+
+ /* QUICK START MODE */
+ quickstartMode=false;
+ if (strcmp(org, "quickstart") == 0){
+ quickstartMode = true;
+ }
+
+ /* Connect network */
+ printf("\r\nConnecting to Access Point...\n\n");
+ NetworkInterface * network = easy_connect(true); // SSID and pw in .jason
+ if (!network){
+ printf("\r\nError easy_connect\n");
+ }
+
+ /* MQTT CONFIG*/
+ printf("\r\nConfiguring MQTT network...\n");
+ MQTTNetwork mqttNetwork(network);
+ MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> client(mqttNetwork);
+ pClient = &client;
+
+
+ if (quickstartMode){
+ char mac[50]; // remove all : from mac
+ char *digit=NULL;
+ sprintf (id,"%s", "");
+ sprintf (mac,"%s",network->get_mac_address());
+ digit = strtok (mac,":");
+ while (digit != NULL)
+ {
+ strcat (id, digit);
+ digit = strtok (NULL, ":");
+ }
+ }//if-quickstart
+
+ /* Connect MQTT broker */
+ printf("\r\nConnecting MQTT broker...\n");
+ attemptConnect(&client, &mqttNetwork, network);
+
+#else
+ printf("\r\nWi-Fi Disabled!\n");
+
+#endif
+
+ printf("\r\n\nStarting the BLE module...\n");
+
/* Create the ble instance */
BLE &ble = BLE::Instance();
ble.onEventsToProcess(scheduleBleEventsProcessing);
- /* Uncommenting to debug the status*/
+ /* Uncomment to debug the status*/
//eventQ.call_every(20000, checkStatus);
ble.init(bleInitComplete);
+ /* Start main method */
+ eventQ.call_every(100, mainFunc);
+ eventQ.call_every(1000, MQTTpublish);
//dispatch events
eventQ.dispatch_forever();
Lorenzo Invidia
