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: BLE_API mbed nRF51822
SimpleBLE.h
00001 /** 00002 * Because BLE_API is too hard 00003 */ 00004 #include <string> 00005 #include <vector> 00006 #include <map> 00007 #include "ble/BLE.h" 00008 00009 using namespace std; 00010 00011 template <class T> 00012 class ReadOnlyCharacteristic { 00013 public: 00014 ReadOnlyCharacteristic(BLE* aBle, const uint16_t aCharUuid, bool enableNotify, T defaultValue) : 00015 ble(aBle) 00016 { 00017 state = new ReadOnlyGattCharacteristic<T>(aCharUuid, new T(defaultValue), enableNotify ? 00018 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY : 00019 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); 00020 } 00021 00022 ~ReadOnlyCharacteristic() { 00023 // @todo clear defaultValue 00024 if (state) { 00025 free(state); 00026 } 00027 } 00028 00029 void update(T newValue) { 00030 ble->gattServer().write(state->getValueHandle(), (uint8_t *)&newValue, sizeof(T)); 00031 } 00032 00033 ReadOnlyGattCharacteristic<T>* getChar(void) { 00034 return state; 00035 } 00036 00037 private: 00038 BLE* ble; 00039 ReadOnlyGattCharacteristic<T>* state; 00040 }; 00041 00042 template <class T> 00043 class ReadWriteCharacteristic { 00044 public: 00045 ReadWriteCharacteristic(BLE* aBle, const uint16_t aCharUuid, bool enableNotify, T defaultValue) : 00046 ble(aBle) 00047 { 00048 state = new ReadWriteGattCharacteristic<T>(aCharUuid, new T(defaultValue), enableNotify ? 00049 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY : 00050 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); 00051 } 00052 00053 ~ReadWriteCharacteristic() { 00054 // @todo clear defaultValue 00055 if (state) { 00056 free(state); 00057 } 00058 } 00059 00060 void update(T newValue) { 00061 ble->gattServer().write(state->getValueHandle(), (uint8_t *)&newValue, sizeof(T)); 00062 } 00063 00064 ReadWriteGattCharacteristic<T>* getChar(void) { 00065 return state; 00066 } 00067 00068 private: 00069 BLE* ble; 00070 ReadWriteGattCharacteristic<T>* state; 00071 }; 00072 00073 class SimpleBLE { 00074 public: 00075 SimpleBLE(const char* aName, uint16_t aInterval = 1000) : name(aName), interval(aInterval) { 00076 ble = &BLE::Instance(); 00077 } 00078 ~SimpleBLE() {} 00079 00080 // Start up the BLE service and just run with it! 00081 void spin() { 00082 ble->init(this, &SimpleBLE::bleInitComplete); 00083 00084 /* SpinWait for initialization to complete. This is necessary because the 00085 * BLE object is used in the main loop below. */ 00086 while (ble->hasInitialized() == false) { /* spin loop */ } 00087 00088 while (true) { 00089 ble->waitForEvent(); 00090 } 00091 } 00092 00093 template <typename T> 00094 ReadOnlyCharacteristic<T>* createReadOnlyChar(uint16_t serviceUuid, 00095 uint16_t charUuid, 00096 bool enableNotify, 00097 T defaultValue) { 00098 ReadOnlyCharacteristic<T>* c = new ReadOnlyCharacteristic<T>(ble, charUuid, enableNotify, defaultValue); 00099 00100 if (services.count(serviceUuid) == 0) { 00101 services[serviceUuid] = new vector<GattCharacteristic*>(); 00102 } 00103 00104 services[serviceUuid]->push_back(c->getChar()); 00105 00106 return c; 00107 } 00108 00109 template <typename T> 00110 ReadWriteCharacteristic<T>* createReadWriteChar(uint16_t serviceUuid, 00111 uint16_t charUuid, 00112 bool enableNotify, 00113 T defaultValue, 00114 void(*callback)(const uint8_t*, size_t)) { 00115 ReadWriteCharacteristic<T>* c = new ReadWriteCharacteristic<T>(ble, charUuid, enableNotify, defaultValue); 00116 00117 if (services.count(serviceUuid) == 0) { 00118 services[serviceUuid] = new vector<GattCharacteristic*>(); 00119 } 00120 00121 services[serviceUuid]->push_back(c->getChar()); 00122 writeCallbacks[c->getChar()] = (void*)callback; 00123 00124 return c; 00125 } 00126 00127 void onDisconnection(Gap::DisconnectionEventCallback_t callback) { 00128 ble->gap().onDisconnection(callback); 00129 } 00130 00131 void onConnection(Gap::ConnectionEventCallback_t callback) { 00132 ble->gap().onConnection(callback); 00133 } 00134 00135 void onDataWrittenCallback(const GattWriteCallbackParams *params) { 00136 // see if we know for which char this message is... 00137 typedef std::map<GattCharacteristic*, void* >::iterator it_type; 00138 for(it_type it = writeCallbacks.begin(); it != writeCallbacks.end(); it++) { 00139 if (it->first->getValueHandle() == params->handle) { 00140 void(*func)(const uint8_t*, size_t) = (void(*)(const uint8_t*, size_t))it->second; 00141 00142 func(params->data, params->len); 00143 } 00144 } 00145 00146 // handle corresponds to the characteristic being written 00147 // then we can read data to get a buffer of the actual data 00148 // if ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) { 00149 // // When writing 1 -> turn LED on, 0 -> turn LED off 00150 // char val = params->data[0]; 00151 // actuatedLED = val == 1 ? LED_ON : LED_OFF; 00152 // } 00153 } 00154 00155 00156 private: 00157 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00158 { 00159 printf("bleInitComplete\r\n"); 00160 00161 BLE& ble = params->ble; 00162 ble_error_t error = params->error; 00163 00164 if (error != BLE_ERROR_NONE) { 00165 printf("BLE Init error %d\r\n", error); 00166 return; 00167 } 00168 00169 /* Ensure that it is the default instance of BLE */ 00170 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { 00171 return; 00172 } 00173 00174 ble.gattServer().onDataWritten(this, &SimpleBLE::onDataWrittenCallback); 00175 00176 // let's add some services yo (why is there no 'auto' in mbed?) 00177 uint16_t uuid16_list[services.size()]; 00178 00179 size_t counter = 0; 00180 typedef std::map<std::uint16_t, vector<GattCharacteristic*>* >::iterator it_type; 00181 for(it_type it = services.begin(); it != services.end(); it++) { 00182 printf("Creating service 0x%x\n", it->first); 00183 00184 uuid16_list[counter++] = it->first; 00185 00186 GattCharacteristic* charTable[it->second->size()]; 00187 for (size_t git = 0; git < it->second->size(); git++) { 00188 charTable[git] = it->second->at(git); 00189 } 00190 GattService service(it->first, charTable, it->second->size()); 00191 ble.gattServer().addService(service); 00192 } 00193 00194 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00195 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); 00196 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)name, strlen(name)); 00197 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00198 ble.gap().setAdvertisingInterval(interval); 00199 ble.gap().startAdvertising(); 00200 00201 printf("Started advertising\n"); 00202 } 00203 00204 BLE* ble; 00205 const char* name; 00206 uint16_t interval; 00207 map<uint16_t, vector<GattCharacteristic*>* > services; 00208 map<GattCharacteristic*, void*> writeCallbacks; 00209 }; 00210
Generated on Tue Jul 19 2022 04:55:26 by
1.7.2