Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MQTT target_st_bluenrg
Fork of ble-star-mbed by
main.cpp
00001 #include <events/mbed_events.h> 00002 #include <mbed.h> 00003 #include "ble/BLE.h" 00004 #include "ble/DiscoveredCharacteristic.h" 00005 #include "ble/DiscoveredService.h" 00006 #include <UUID.h> 00007 #include <BleMasterService.h> 00008 #include <BleSlaveService.h> 00009 #include <string.h> 00010 #include "easy-connect.h" 00011 #include "MQTTClient.h" 00012 #include "MQTTmbed.h" 00013 #include "MQTTNetwork.h" 00014 00015 /*----------------------------------------------------------------------------*/ 00016 00017 /* Enable/Disable WiFi (1 = WiFi Enabled, 0 = WiFi Disabled) */ 00018 #define ENABLE_WIFI 1 00019 00020 /**** System configuration define ****/ 00021 #define ORG_QUICKSTART // comment to connect to play.internetofthings.ibmcloud.com 00022 #ifndef ORG_QUICKSTART 00023 //#define TLS_EN // uncomment to add TLS to NON quickstart connections 00024 #endif 00025 00026 #ifdef TLS_EN // Digicert Root Certificate in PEM format (from IBM website) 00027 const char SSL_CA_PEM[] ="-----BEGIN CERTIFICATE-----\n" 00028 "MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n" 00029 "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" 00030 "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n" 00031 "QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n" 00032 "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n" 00033 "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n" 00034 "9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n" 00035 "CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n" 00036 "nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n" 00037 "43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n" 00038 "T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n" 00039 "gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n" 00040 "BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n" 00041 "TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n" 00042 "DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n" 00043 "hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n" 00044 "06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n" 00045 "PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n" 00046 "YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n" 00047 "CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n" 00048 "-----END CERTIFICATE-----\n"; 00049 #endif 00050 00051 00052 00053 static bool quickstartMode = true; // set to false to connect with authentication tocken 00054 00055 #define MQTT_MAX_PACKET_SIZE 400 00056 #define MQTT_MAX_PAYLOAD_SIZE 300 00057 00058 00059 00060 // Configuration values needed to connect to IBM IoT Cloud 00061 #ifdef ORG_QUICKSTART 00062 #define ORG "quickstart" // connect to quickstart.internetofthings.ibmcloud.com/ For a registered connection, replace with your org 00063 #define ID "" 00064 #define AUTH_TOKEN "" 00065 #define DEFAULT_TYPE_NAME "sensor" 00066 #define DEFAULT_PORT MQTT_PORT 00067 00068 #else // not def ORG_QUICKSTART 00069 #define ORG MQTT_ORG_ID // connect to ORG.internetofthings.ibmcloud.com/ For a registered connection, replace with your org 00070 #define ID MQTT_DEVICE_ID // For a registered connection is your device id 00071 #define AUTH_TOKEN MQTT_DEVICE_PASSWORD // For a registered connection is a device auth-token 00072 #define DEFAULT_TYPE_NAME MQTT_DEVICE_TYPE // For a registered connection is device type 00073 00074 #ifdef TLS_EN 00075 #define DEFAULT_PORT MQTT_TLS_PORT 00076 #else 00077 #define DEFAULT_PORT MQTT_PORT 00078 00079 #endif 00080 #endif 00081 00082 00083 00084 #define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type 00085 #define IBM_IOT_PORT DEFAULT_PORT 00086 00087 #define MAXLEN_MBED_CONF_APP_WIFI_SSID 32 // same as WIFI_SSID_MAX_LEN in easy_connect 00088 #define MAXLEN_MBED_CONF_APP_WIFI_PASSWORD 64 // same as WIFI_PASSWORD_MAX_LEN 00089 00090 static char id[30] = ID; // mac without colons 00091 static char org[12] = ORG; 00092 static int connack_rc = 0; // MQTT connack return code 00093 static char type[30] = TYPE; 00094 static char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode 00095 static bool netConnecting = false; 00096 static bool mqttConnecting = false; 00097 static bool netConnected = false; 00098 static bool connected = false; 00099 static int retryAttempt = 0; 00100 static char subscription_url[MQTT_MAX_PAYLOAD_SIZE]; 00101 static char ssid[MAXLEN_MBED_CONF_APP_WIFI_SSID]; // Network must be visible otherwise it can't connect 00102 static char seckey[MAXLEN_MBED_CONF_APP_WIFI_PASSWORD]; 00103 00104 MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> *pClient; 00105 00106 const char NAME_BLESTAR1[] = "BleStar1"; 00107 00108 uint8_t wifi_status; 00109 00110 uint8_t wifi_data[256]; 00111 uint8_t new_data = 0; 00112 uint8_t *data; 00113 uint8_t wifi_present; 00114 uint8_t start_bnrg; 00115 extern PeripheralDevices_t perDevs; 00116 uint8_t json_buffer[512]; 00117 00118 /*----------------------------------------------------------------------------*/ 00119 00120 00121 00122 /* Prepare JSON packet with sensors data */ 00123 void prepare_json_pkt (uint8_t * buffer){ 00124 char tempbuff[256]; 00125 00126 strcpy((char *)buffer,"{\"d\":{\"ST\":\"BLEStar\""); 00127 sprintf(tempbuff, ",%s", data); 00128 strcat((char *)buffer,tempbuff); 00129 strcat((char *)buffer,"}}"); 00130 00131 return; 00132 } 00133 /*----------------------------------------------------------------------------*/ 00134 00135 00136 00137 /* Connect the broker - return the CONNACK*/ 00138 int connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> * client, MQTTNetwork *mqttNetwork, NetworkInterface* network) 00139 { 00140 const char* iot_ibm = MQTT_BROKER_URL; 00141 char hostname[strlen(org) + strlen(iot_ibm) + 1]; 00142 00143 sprintf(hostname, "%s%s", org, iot_ibm); 00144 // Construct clientId - d:org:type:id 00145 char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; 00146 sprintf(clientId, "d:%s:%s:%s", org, type, id); 00147 sprintf(subscription_url, "%s.%s/#/device/%s/%s/", org, "internetofthings.ibmcloud.com", id, TYPE); 00148 00149 // Network debug statements 00150 printf("\r\n====================================="); 00151 printf("\r\nNucleo IP ADDRESS: %s\n", network->get_ip_address()); 00152 printf("\r\nNucleo MAC ADDRESS: %s\n", network->get_mac_address()); 00153 printf("\r\nServer Hostname: %s port: %d\n", hostname, IBM_IOT_PORT); 00154 printf("\r\nClient ID: %s\n", clientId); 00155 printf("\r\nTopic: %s\n",MQTT_TOPIC); 00156 printf("\r\nSubscription URL: %s", subscription_url); 00157 printf("\r\n=====================================\r\n"); 00158 netConnecting = true; 00159 00160 00161 00162 #ifdef ORG_QUICKSTART 00163 int tls = TLS_OFF; 00164 const char * cert = NULL; 00165 unsigned int sizeof_cert = 0; 00166 00167 #else // if !QUICKSTART possible to connect with TLS or not 00168 #ifdef TLS_EN 00169 int tls = TLS_ON; 00170 const char * cert = SSL_CA_PEM; 00171 unsigned int sizeof_cert = sizeof(SSL_CA_PEM); 00172 00173 #else 00174 int tls = TLS_OFF; 00175 const char * cert = 0; 00176 unsigned int sizeof_cert = 0; 00177 00178 #endif 00179 #endif 00180 00181 00182 //Return code 00183 int rc = mqttNetwork->connect(hostname, IBM_IOT_PORT, tls, cert, sizeof_cert); 00184 if (rc != 0) 00185 { 00186 printf("\r\nrc from TCP connect is %d\n", rc); 00187 return rc; 00188 } 00189 netConnected = true; 00190 netConnecting = false; 00191 00192 00193 // MQTT Connect 00194 mqttConnecting = true; 00195 MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 00196 data.MQTTVersion = 4; 00197 data.struct_version=0; 00198 data.clientID.cstring = clientId; 00199 data.keepAliveInterval = 0; //MQTT_KEEPALIVE; // in Sec 00200 if (!quickstartMode){ 00201 data.username.cstring = "use-token-auth"; 00202 data.password.cstring = auth_token; 00203 printf ("\r\nAutToken: %s\n", auth_token); 00204 } 00205 if ((rc = client->connect(data)) != MQTT::SUCCESS) { 00206 printf("\r\nrc from MQTT connect is %d\n", rc); 00207 connack_rc = rc; 00208 return rc; 00209 } 00210 connected = true; 00211 printf ("\r\n--->MQTT Connected\n"); 00212 00213 mqttConnecting = false; 00214 connack_rc = rc; 00215 return rc; 00216 } 00217 /*----------------------------------------------------------------------------*/ 00218 00219 00220 00221 int getConnTimeout(int attemptNumber) 00222 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute 00223 // after 20 attempts, retry every 10 minutes 00224 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; 00225 } 00226 /*----------------------------------------------------------------------------*/ 00227 00228 00229 00230 void attemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) 00231 { 00232 connected = false; 00233 00234 while (connect(client, mqttNetwork, network) != MQTT_CONNECTION_ACCEPTED) 00235 { 00236 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) { 00237 printf ("\r\nError MQTT_BAD_USERNAME_OR_PASSWORDFile: %s, Line: %d Error: %d \n",__FILE__,__LINE__, connack_rc); 00238 return; // don't reattempt to connect if credentials are wrong 00239 } 00240 int timeout = getConnTimeout(++retryAttempt); 00241 WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); 00242 00243 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed 00244 // or maybe just add the proper members to do this disconnect and call attemptConnect(...) 00245 // this works - reset the system when the retry count gets to a threshold 00246 if (retryAttempt == 5) 00247 NVIC_SystemReset(); 00248 else 00249 wait(timeout); 00250 } 00251 } 00252 /*----------------------------------------------------------------------------*/ 00253 00254 00255 /* Method to publish data to client (sending data to broker) */ 00256 int publish(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client){ 00257 //printf("\r\npublish");//DEBUG 00258 00259 MQTT::Message message; 00260 const char* pubTopic = MQTT_TOPIC; 00261 00262 00263 if (!client->isConnected()){ 00264 printf ("\r\npublish failed: MQTT disconnected\n"); 00265 return MQTT::FAILURE; 00266 } 00267 00268 00269 message.qos = MQTT::QOS0; // quality of service 0 default 00270 message.retained = false; // (false) new clients will not receive past data 00271 message.dup = false; // (false) no duplicated message 00272 message.payload = (void*)json_buffer; // DATA to be sent 00273 message.payloadlen = strlen((const char *)(json_buffer)); 00274 00275 00276 return client->publish(pubTopic, message); 00277 } 00278 /*----------------------------------------------------------------------------*/ 00279 00280 00281 00282 /* scheduleBleEventsProcessing */ 00283 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { 00284 BLE &ble = BLE::Instance(); 00285 eventQ.call(Callback<void()>(&ble, &BLE::processEvents)); 00286 } 00287 /*----------------------------------------------------------------------------*/ 00288 00289 00290 00291 00292 /* Complete the initialization of ble module */ 00293 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){ 00294 00295 00296 initProcess(); 00297 ble_error_t a0, a1, a2, a3; 00298 00299 BLE& ble = params->ble; 00300 ble_error_t error = params->error; 00301 00302 if (error != BLE_ERROR_NONE) { 00303 /* In case of error, forward the error handling to onBleInitError */ 00304 onBleInitError(ble, error); 00305 return; 00306 } 00307 00308 00309 00310 /* Ensure that it is the default instance of BLE */ 00311 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { 00312 return; 00313 } 00314 00315 00316 /* notification + attr writing */ 00317 ble.gattServer().onDataWritten(AttributeModified_CB); 00318 /* data read */ 00319 ble.gattClient().onDataRead(readCharacteristicCallback); 00320 /* when a peripheral node characteristics change */ 00321 ble.gattClient().onHVX(onNotificationCallback); 00322 /* when a peripheral descriptor is written */ 00323 ble.gattClient().onDataWritten(perDescriptorWrittenCallback); 00324 00325 00326 /* disconnection */ 00327 ble.gap().onDisconnection(disconnectionCallback); 00328 /* connection */ 00329 ble.gap().onConnection(connectionCallback); 00330 ble.gap().setScanParams(200, 200); //(scanInterval,scanWindow)ms 00331 ble.gap().setScanTimeout(0x0004); //stop scanning after N sec 00332 ble.gap().onTimeout(onStopScan); //callback when scan stops 00333 00334 00335 00336 00337 /* Setup adv */ 00338 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00339 a0 = ble.gap().accumulateScanResponse(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, manuf_data, sizeof(manuf_data)); 00340 a1 = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::UNKNOWN); 00341 a2 = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)NAME_BLESTAR1, sizeof(NAME_BLESTAR1)); 00342 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); //Advertising_Event_Type 00343 ble.gap().setAdvertisingInterval(1000); //Adv_Interval 00344 a3 = ble.gap().setAdvertisingPolicyMode(Gap::ADV_POLICY_IGNORE_WHITELIST); //Adv_Filter_Policy 00345 if ((a0 != BLE_ERROR_NONE) || (a1 != BLE_ERROR_NONE) || (a2 != BLE_ERROR_NONE) || (a3 != BLE_ERROR_NONE)){ 00346 printf("\r\nError setup ADV\n"); 00347 } 00348 00349 00350 addAllServices(); 00351 printMacAddress(); 00352 00353 } 00354 /*----------------------------------------------------------------------------*/ 00355 00356 00357 00358 void onBleInitError(BLE &ble, ble_error_t error){} 00359 /*----------------------------------------------------------------------------*/ 00360 00361 00362 00363 void mainFunc(void){ 00364 00365 if ((wifi_present) && (perDevs.status != NOTIFICATIONS_DATA_READ)){ 00366 00367 if((new_data)){ 00368 prepare_json_pkt(json_buffer); 00369 }//if-new_data 00370 start_bnrg = 1; 00371 00372 }else{ 00373 start_bnrg = 1; 00374 if (perDevs.status != NOTIFICATIONS_DATA_READ) { 00375 HAL_Delay(1000); 00376 } 00377 }//if-else 00378 00379 00380 if (start_bnrg){ 00381 eventQ.call(connectionProcess); 00382 } 00383 } 00384 /*----------------------------------------------------------------------------*/ 00385 00386 00387 void MQTTpublish(){ 00388 00389 if((new_data)){ 00390 /* publish every 5 seconds */ 00391 publish(pClient); 00392 }//if-new_data 00393 } 00394 /*----------------------------------------------------------------------------*/ 00395 00396 00397 00398 int main() 00399 { 00400 printf("\r\n\n/*******************************************************\n"); 00401 printf("\r* *\n"); 00402 printf("\r* BLESTAR1 MBED Expansion Software *\n"); 00403 printf("\r* *\n"); 00404 printf("\r*******************************************************/\n\n\n"); 00405 00406 00407 #if ENABLE_WIFI 00408 wifi_present = ENABLE_WIFI; 00409 printf("\r\nWi-Fi Enabled!\n"); 00410 printf("\rTo edit SSID and/or Password please refer to mbed_app.json file\n"); 00411 00412 /* QUICK START MODE */ 00413 quickstartMode=false; 00414 if (strcmp(org, "quickstart") == 0){ 00415 quickstartMode = true; 00416 } 00417 00418 /* Connect network */ 00419 printf("\r\nConnecting to Access Point...\n\n"); 00420 NetworkInterface * network = easy_connect(true); // SSID and pw in .jason 00421 if (!network){ 00422 printf("\r\nError easy_connect\n"); 00423 } 00424 00425 /* MQTT CONFIG*/ 00426 printf("\r\nConfiguring MQTT network...\n"); 00427 MQTTNetwork mqttNetwork(network); 00428 MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> client(mqttNetwork); 00429 pClient = &client; 00430 00431 00432 if (quickstartMode){ 00433 char mac[50]; // remove all : from mac 00434 char *digit=NULL; 00435 sprintf (id,"%s", ""); 00436 sprintf (mac,"%s",network->get_mac_address()); 00437 digit = strtok (mac,":"); 00438 while (digit != NULL) 00439 { 00440 strcat (id, digit); 00441 digit = strtok (NULL, ":"); 00442 } 00443 }//if-quickstart 00444 00445 /* Connect MQTT broker */ 00446 printf("\r\nConnecting MQTT broker...\n"); 00447 attemptConnect(&client, &mqttNetwork, network); 00448 00449 #else 00450 printf("\r\nWi-Fi Disabled!\n"); 00451 00452 #endif 00453 00454 printf("\r\n\nStarting the BLE module...\n"); 00455 00456 /* Create the ble instance */ 00457 BLE &ble = BLE::Instance(); 00458 00459 ble.onEventsToProcess(scheduleBleEventsProcessing); 00460 00461 /* Uncomment to debug the status*/ 00462 //eventQ.call_every(20000, checkStatus); 00463 00464 ble.init(bleInitComplete); 00465 00466 /* Start main method */ 00467 eventQ.call_every(100, mainFunc); 00468 eventQ.call_every(1000, MQTTpublish); 00469 00470 //dispatch events 00471 eventQ.dispatch_forever(); 00472 00473 return 0; 00474 } 00475 /*----------------------------------------------------------------------------*/ 00476 00477 00478 00479 00480
Generated on Wed Jul 27 2022 08:13:19 by
1.7.2
