first release Intelligent Lumen iBeacon
Dependencies: BLE_API mbed nRF51822
main.cpp
- Committer:
- javiervelasco
- Date:
- 2016-10-17
- Branch:
- INTELLIGENT_LUMEN_BEACON
- Revision:
- 1:2e474d4e7092
- Parent:
- 0:720b1ee20d33
File content as of revision 1:2e474d4e7092:
/* 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 "mbed.h" #include <string.h> #include <stddef.h> #include <Serial.h> #include "ble/services/iBeacon.h" #include "ble/services/UARTService.h" #include "ble/services/DFUService.h" #include "nrf.h" #include "nrf_sdm.h" extern "C" { #include "pstorage.h" } #include "nrf_error.h" #define _DEBUG BLE ble; UARTService *uarts; DFUService *dfus; iBeacon *ibeacon; pstorage_handle_t pstorageHandle; #ifdef _DEBUG Serial pc(USBTX, USBRX); #endif Ticker ticker; // Struct to hold persistent data across power cycles typedef struct PersistentData_t { char name[32]; uint16_t majorNumber; uint16_t minorNumber; uint16_t txPower; } __attribute__ ((aligned (4))); PersistentData_t persistentData; static const int PERSISTENT_DATA_ALIGNED_SIZE = sizeof(PersistentData_t); /* Dummy callback handler needed by Nordic's pstorage module. */ void pstorageNotificationCallback( pstorage_handle_t *p_handle, uint8_t op_code, uint32_t result, uint8_t * p_data, uint32_t data_len){ /* APP_ERROR_CHECK(result); */ } void pstorageLoad(){ if (pstorage_init()!=NRF_SUCCESS) { } pstorage_module_param_t pstorageParams = { .cb = pstorageNotificationCallback, .block_size = PERSISTENT_DATA_ALIGNED_SIZE, .block_count = 1 }; pstorage_register(&pstorageParams, &pstorageHandle); if (pstorage_load( reinterpret_cast<uint8_t *>(&persistentData), &pstorageHandle, PERSISTENT_DATA_ALIGNED_SIZE, 0 ) != NRF_SUCCESS) { // On failure zero out and let the service reset to defaults sprintf(persistentData.name,"INTELLIGENTLUMEN"); persistentData.majorNumber=1234; persistentData.minorNumber=5678; persistentData.txPower=54; } } void pstorageSave() { pstorage_store( &pstorageHandle, reinterpret_cast<uint8_t *>(&persistentData), sizeof(PersistentData_t), 0 /* offset */ ); wait(2); } /* BLE UART data received callback */ void onDataWritten(const GattWriteCallbackParams *params) { char *bp = (char*)params->data; bp[params->len]=0; //Fix string end with zero. #ifdef _DEBUG pc.printf("%s\r\n",bp); #endif char *token; token = strtok(bp," ,"); if (token!=NULL) { #ifdef _DEBUG pc.printf("Recv: %s\r\n",token); #endif if (strcmp(token,"name")==0) { token = strtok(NULL," ,"); if (token==NULL) { #ifdef _DEBUG pc.printf("Cfg error: invalid name \r\n"); #endif return; } sprintf((char *)persistentData.name,"%s",token); } else if (strcmp(token,"major")==0) { token = strtok(NULL," ,"); if (token==NULL) { #ifdef _DEBUG pc.printf("Cfg error: invalid majorNumber \r\n"); #endif return; } persistentData.majorNumber=atoi(token); } else if (strcmp(token,"minor")==0) { token = strtok(NULL," ,"); if (token==NULL) { #ifdef _DEBUG pc.printf("Cfg error: invalid minorNumber \r\n"); #endif return; } persistentData.minorNumber=atoi(token); } else if (strcmp(token,"rssi")==0) { token = strtok(NULL," ,"); if (token==NULL) { #ifdef _DEBUG pc.printf("Cfg error: invalid txPower \r\n"); #endif return; } persistentData.txPower=atoi(token); #ifdef _DEBUG pc.printf("Cfg txPower:%i\r\n",persistentData.txPower); #endif } else if (strcmp(token,"save")==0) { pstorageSave(); #ifdef _DEBUG pc.printf("Config name:%s major:%i minor:%i tx:%i\r\n",persistentData.name,persistentData.majorNumber,persistentData.minorNumber,persistentData.txPower); #endif NVIC_SystemReset(); } else if (strcmp(token,"dfu")==0) { sd_power_gpregret_set(BOOTLOADER_DFU_START); sd_softdevice_disable(); sd_softdevice_vector_table_base_set(NRF_UICR->BOOTLOADERADDR); NVIC_SystemReset(); } } } void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { #ifdef _DEBUG pc.printf("Connected!\n"); #endif } void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *cbParams) { #ifdef _DEBUG pc.printf("Disconnected!\n"); pc.printf("Restarting the advertising process\n"); #endif ble.startAdvertising(); } int main(void) { const uint8_t uuid[] = {0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4, 0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61}; #ifdef _DEBUG pc.baud(9600); pc.printf("INTELLIGENT LUMEN BEACON DFU v1.1\r\n"); #endif /* Load mayor minor and txpower from storage */ pstorageLoad(); #ifdef _DEBUG pc.printf("Storage size:%i\r\n",PERSISTENT_DATA_ALIGNED_SIZE); pc.printf("Config name:%s mayor:%i minor:%i tx:%i\r\n",persistentData.name,persistentData.majorNumber,persistentData.minorNumber,persistentData.txPower); #endif ble.init(); while (!ble.hasInitialized()) { wait(0.5);/* wait for BLE initialization */ } ble.gap().onDisconnection(disconnectionCallback); ble.gap().onConnection(connectionCallback); ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t*)persistentData.name, strlen((const char*)persistentData.name)); UARTService uartService(ble); uarts = &uartService; DFUService dfu(ble); dfus = &dfu; ibeacon = new iBeacon(ble, uuid, persistentData.majorNumber, persistentData.minorNumber, persistentData.txPower); ble.onDataWritten(onDataWritten); /* setup advertising */ ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); ble.setAdvertisingInterval(100); /* 100ms; in multiples of 0.625ms. */ ble.gap().startAdvertising(); while (true) { ble.waitForEvent(); // allows or low power operation } }