Javier Velasco / Mbed 2 deprecated BLE_iBeacon

Dependencies:   BLE_API mbed nRF51822

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include <string.h>
00019 #include <stddef.h>
00020 #include <Serial.h>
00021 #include "ble/services/iBeacon.h"
00022 #include "ble/services/UARTService.h"
00023 #include "ble/services/DFUService.h"
00024 #include "nrf.h"
00025 #include "nrf_sdm.h"
00026 
00027 
00028 extern "C" {
00029     #include "pstorage.h"
00030 }
00031 #include "nrf_error.h"
00032 
00033 #define _DEBUG 
00034 
00035 BLE ble;
00036 UARTService *uarts;
00037 DFUService *dfus;
00038 iBeacon *ibeacon;
00039 pstorage_handle_t pstorageHandle;
00040 #ifdef _DEBUG
00041 Serial pc(USBTX, USBRX);
00042 #endif
00043 Ticker ticker;
00044 
00045 // Struct to hold persistent data across power cycles
00046 typedef struct PersistentData_t {
00047     char name[32];
00048     uint16_t majorNumber;
00049     uint16_t minorNumber;
00050     uint16_t txPower;
00051 } __attribute__ ((aligned (4)));
00052 PersistentData_t  persistentData;
00053 static const int PERSISTENT_DATA_ALIGNED_SIZE = sizeof(PersistentData_t); 
00054 
00055 /* Dummy callback handler needed by Nordic's pstorage module. */
00056 void pstorageNotificationCallback(
00057             pstorage_handle_t *p_handle,
00058             uint8_t            op_code,
00059             uint32_t           result,
00060             uint8_t *          p_data,
00061             uint32_t           data_len){
00062             /* APP_ERROR_CHECK(result); */
00063 }
00064  
00065 void pstorageLoad(){
00066     if (pstorage_init()!=NRF_SUCCESS) {
00067     }
00068     
00069     pstorage_module_param_t pstorageParams = {
00070         .cb          = pstorageNotificationCallback,
00071         .block_size  = PERSISTENT_DATA_ALIGNED_SIZE,
00072         .block_count = 1
00073     };
00074     pstorage_register(&pstorageParams, &pstorageHandle);
00075     if (pstorage_load(
00076             reinterpret_cast<uint8_t *>(&persistentData),
00077             &pstorageHandle, PERSISTENT_DATA_ALIGNED_SIZE, 0
00078     ) != NRF_SUCCESS) {
00079         // On failure zero out and let the service reset to defaults
00080         sprintf(persistentData.name,"INTELLIGENTLUMEN");
00081         persistentData.majorNumber=1234;
00082         persistentData.minorNumber=5678;
00083         persistentData.txPower=54;       
00084     }
00085 }
00086 
00087 
00088 
00089 void pstorageSave() {
00090     pstorage_store(
00091             &pstorageHandle,
00092             reinterpret_cast<uint8_t *>(&persistentData),
00093             sizeof(PersistentData_t),
00094             0 /* offset */
00095     );
00096     wait(2);
00097 }
00098 
00099 
00100 
00101 /* BLE UART data received callback */
00102 void onDataWritten(const GattWriteCallbackParams *params)
00103 {
00104     char *bp = (char*)params->data;
00105     bp[params->len]=0; //Fix string end with zero.
00106     #ifdef _DEBUG
00107     pc.printf("%s\r\n",bp);
00108     #endif
00109     char *token;
00110     token = strtok(bp," ,");
00111     if (token!=NULL) {
00112         #ifdef _DEBUG
00113         pc.printf("Recv: %s\r\n",token);
00114         #endif
00115         if (strcmp(token,"name")==0) {
00116             token = strtok(NULL," ,");
00117             if (token==NULL) {
00118                 #ifdef _DEBUG
00119                 pc.printf("Cfg error: invalid name \r\n");
00120                 #endif
00121                 return;
00122             }
00123             sprintf((char *)persistentData.name,"%s",token);
00124         } else if (strcmp(token,"major")==0) {
00125             token = strtok(NULL," ,");
00126             if (token==NULL) {
00127                 #ifdef _DEBUG
00128                 pc.printf("Cfg error: invalid majorNumber \r\n");
00129                 #endif
00130                 return;
00131             }
00132             persistentData.majorNumber=atoi(token);
00133         } else if (strcmp(token,"minor")==0) {
00134             token = strtok(NULL," ,");
00135             if (token==NULL) {
00136                 #ifdef _DEBUG
00137                 pc.printf("Cfg error: invalid minorNumber \r\n");
00138                 #endif
00139                 return;
00140             }
00141             persistentData.minorNumber=atoi(token);
00142         } else if (strcmp(token,"rssi")==0) {
00143             token = strtok(NULL," ,");
00144             if (token==NULL) {
00145                 #ifdef _DEBUG
00146                 pc.printf("Cfg error: invalid txPower \r\n");
00147                 #endif
00148                 return;
00149             }
00150             persistentData.txPower=atoi(token);
00151             #ifdef _DEBUG
00152             pc.printf("Cfg txPower:%i\r\n",persistentData.txPower);
00153             #endif
00154         } else if (strcmp(token,"save")==0) {
00155             pstorageSave();
00156             #ifdef _DEBUG
00157             pc.printf("Config name:%s major:%i minor:%i tx:%i\r\n",persistentData.name,persistentData.majorNumber,persistentData.minorNumber,persistentData.txPower);
00158             #endif
00159             NVIC_SystemReset();
00160         } else if (strcmp(token,"dfu")==0) {
00161             sd_power_gpregret_set(BOOTLOADER_DFU_START);
00162             sd_softdevice_disable();
00163             sd_softdevice_vector_table_base_set(NRF_UICR->BOOTLOADERADDR);
00164             NVIC_SystemReset();
00165         }
00166     }
00167 }
00168  
00169  
00170 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
00171 {
00172     #ifdef _DEBUG
00173     pc.printf("Connected!\n");
00174     #endif
00175 }
00176  
00177 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *cbParams)
00178 {
00179     #ifdef _DEBUG
00180     pc.printf("Disconnected!\n");
00181     pc.printf("Restarting the advertising process\n");
00182     #endif
00183     ble.startAdvertising();
00184 }
00185 
00186  
00187 
00188 int main(void)
00189 {
00190     const uint8_t uuid[] = {0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4,
00191                             0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61};
00192     #ifdef _DEBUG
00193     pc.baud(9600);
00194     pc.printf("INTELLIGENT LUMEN BEACON DFU v1.1\r\n");
00195     #endif
00196     
00197     /* Load mayor minor and txpower from storage */
00198     pstorageLoad();
00199     #ifdef _DEBUG
00200     pc.printf("Storage size:%i\r\n",PERSISTENT_DATA_ALIGNED_SIZE);
00201     pc.printf("Config name:%s mayor:%i minor:%i tx:%i\r\n",persistentData.name,persistentData.majorNumber,persistentData.minorNumber,persistentData.txPower);
00202     #endif
00203     
00204     ble.init();
00205     while (!ble.hasInitialized()) { wait(0.5);/* wait for BLE initialization */ }
00206     
00207     ble.gap().onDisconnection(disconnectionCallback);
00208     ble.gap().onConnection(connectionCallback);
00209     ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
00210                                      (const uint8_t*)persistentData.name, strlen((const char*)persistentData.name));
00211 
00212     UARTService uartService(ble);
00213     uarts = &uartService;
00214     DFUService dfu(ble);
00215     dfus = &dfu;
00216     ibeacon = new iBeacon(ble, uuid, persistentData.majorNumber, persistentData.minorNumber, persistentData.txPower);  
00217 
00218     ble.onDataWritten(onDataWritten);
00219 
00220     /* setup advertising */
00221     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
00222     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00223     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
00224                                      (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
00225     ble.setAdvertisingInterval(100); /* 100ms; in multiples of 0.625ms. */
00226     ble.gap().startAdvertising();
00227         
00228     
00229     while (true) {
00230         ble.waitForEvent(); // allows or low power operation
00231     }
00232 }