GPS to Pulga
source/BLE.txt
- Committer:
- brunnobbco
- Date:
- 2020-12-11
- Revision:
- 26:1e1776201716
- Parent:
- 23:7f1c9c1a4c57
File content as of revision 26:1e1776201716:
using mbed::callback; // A My service that demonstrate the GattServer features. class MyService { typedef MyService Self; public: MyService() : _sens00_char("00000000-000a-000a-a000-a0a000aa00aa", 0), _sens01_char("11111111-111b-111b-b111-b1b111bb11bb", 0), _sens02_char("22222222-222c-222c-c222-c2c222cc22cc", 0), _led_char("33333333-333d-333d-d333-d3d333dd33dd", 0), _sensors_char("55555555-555f-555f-f555-f5f555ff55ff", 0), _My_service( /* uuid */ "51311102-030e-485f-b122-f8f381aa84ed", /* characteristics */ _My_characteristics, /* numCharacteristics */ sizeof(_My_characteristics) / sizeof(_My_characteristics[0]) ), _server(NULL), _event_queue(NULL), _actuated_led(P1_14,0) { // update internal pointers (value, descriptors and characteristics array) _My_characteristics[4] = &_sensors_char; _My_characteristics[3] = &_led_char; _My_characteristics[2] = &_sens02_char; _My_characteristics[1] = &_sens01_char; _My_characteristics[0] = &_sens00_char; // setup authorization handlers _sens00_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); _sens01_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); _sens02_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); _led_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); _sensors_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write); } void start(BLE &ble_interface, events::EventQueue &event_queue) { if (_event_queue) { return; } _server = &ble_interface.gattServer(); _event_queue = &event_queue; // register the service printf("Adding arquetipo service\r\n"); ble_error_t err = _server->addService(_My_service); if (err) { printf("Error %u during demo service registration.\r\n", err); return; } // read write handler _server->onDataSent(as_cb(&Self::when_data_sent)); _server->onDataWritten(as_cb(&Self::when_data_written)); _server->onDataRead(as_cb(&Self::when_data_read)); // updates subscribtion handlers _server->onUpdatesEnabled(as_cb(&Self::when_update_enabled)); _server->onUpdatesDisabled(as_cb(&Self::when_update_disabled)); _server->onConfirmationReceived(as_cb(&Self::when_confirmation_received)); // print the handles printf("My service registered\r\n"); printf("service handle: %u\r\n", _My_service.getHandle()); printf("\tsens00 characteristic value handle %u\r\n", _sens00_char.getValueHandle()); printf("\tsens01 characteristic value handle %u\r\n", _sens01_char.getValueHandle()); printf("\tsens02 characteristic value handle %u\r\n", _sens02_char.getValueHandle()); printf("\tled characteristic value handle %u\r\n", _led_char.getValueHandle()); printf("\tsensors characteristic value handle %u\r\n", _sensors_char.getValueHandle()); _event_queue->call_every(503 /* ms */, callback(this, &Self::blink)); // _event_queue->call(Callback<void(bool)>(button1,false), &Self::read_sensors); //button1.fall(Callback<void()>(this, &Self::read_sensors) ); } private: /** * Handler called when a notification or an indication has been sent. */ void when_data_sent(unsigned count) { printf("sent %u updates\r\n", count); } /** * Handler called after an attribute has been written. */ void when_data_written(const GattWriteCallbackParams *e) { printf("data written:\r\n"); printf("\tconnection handle: %u\r\n", e->connHandle); printf("\tattribute handle: %u", e->handle); if (e->handle == _sensors_char.getValueHandle()) { printf(" (sensors characteristic)\r\n"); sensors = *(e->data); read_sensors(sensors); }else if (e->handle == _led_char.getValueHandle()) { printf(" (led characteristic)\r\n"); _actuated_led = *(e->data); } else if (e->handle == _sens00_char.getValueHandle()) { printf(" (sens00 characteristic)\r\n"); } else if (e->handle == _sens01_char.getValueHandle()) { printf(" (sens01 characteristic)\r\n"); } else if (e->handle == _sens02_char.getValueHandle()) { printf(" (sens02 characteristic)\r\n"); } else { printf("\r\n"); } printf("\twrite operation: %u\r\n", e->writeOp); printf("\toffset: %u\r\n", e->offset); printf("\tlength: %u\r\n", e->len); printf("\t data: "); for (size_t i = 0; i < e->len; ++i) { printf("%02X", e->data[i]); } printf("\r\n"); } /** * Handler called after an attribute has been read. */ void when_data_read(const GattReadCallbackParams *e) { printf("data read:\r\n"); printf("\tconnection handle: %u\r\n", e->connHandle); printf("\tattribute handle: %u", e->handle); if (e->handle == _sensors_char.getValueHandle()) { printf(" (sensors characteristic)\r\n"); } else if (e->handle == _led_char.getValueHandle()) { printf(" (led characteristic)\r\n"); } else if (e->handle == _sens00_char.getValueHandle()) { printf(" (sens00 characteristic)\r\n"); } else if (e->handle == _sens01_char.getValueHandle()) { printf(" (sens01 characteristic)\r\n"); } else if (e->handle == _sens02_char.getValueHandle()) { printf(" (sens02 characteristic)\r\n"); } else { printf("\r\n"); } } /** * Handler called after a client has subscribed to notification or indication. * * @param handle Handle of the characteristic value affected by the change. */ void when_update_enabled(GattAttribute::Handle_t handle) { printf("update enabled on handle %d\r\n", handle); } /** * Handler called after a client has cancelled his subscription from * notification or indication. * * @param handle Handle of the characteristic value affected by the change. */ void when_update_disabled(GattAttribute::Handle_t handle) { printf("update disabled on handle %d\r\n", handle); } /** * Handler called when an indication confirmation has been received. * * @param handle Handle of the characteristic value that has emitted the * indication. */ void when_confirmation_received(GattAttribute::Handle_t handle) { printf("confirmation received on handle %d\r\n", handle); } /** * Handler called when a write request is received. * * This handler verify that the value submitted by the client is valid before * authorizing the operation. */ void authorize_client_write(GattWriteAuthCallbackParams *e) { printf("characteristic %u write authorization\r\n", e->handle); if (e->offset != 0) { printf("Error invalid offset\r\n"); e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; return; } if (e->len != 1) { printf("Error invalid len\r\n"); e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; return; } e->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; } /** * Read Sensors */ void read_sensors_0 (void){ Sensor_Read(1); Update_char(0); } void read_sensors_1 (void){ Sensor_Read(1); Update_char(1); } void read_sensors_2 (void){ Sensor_Read(1); Update_char(2); } void read_sensors_3 (void){ Sensor_Read(2); Update_char(0); } void read_sensors_4 (void){ Sensor_Read(3); Update_char(1); } void read_sensors_5 (void){ Sensor_Read(4); Update_char(0); } void read_sensors_6 (void){ Sensor_Read(4); Update_char(1); } void read_sensors_7 (void){ Sensor_Read(4); Update_char(2); } void read_sensors (int sensors) { if(sensors==0){ read_sensors_0(); } if(sensors==1){ read_sensors_1(); } if(sensors==2){ read_sensors_2(); } if(sensors==3){ read_sensors_3(); } if(sensors==4){ read_sensors_4(); } if(sensors==5){ read_sensors_5(); } if(sensors==6){ read_sensors_6(); } if(sensors==7){ read_sensors_7(); } if(sensors==8){ _event_queue->call_every(1741 /* ms */, callback(this, &Self::read_sensors_0)); } if(sensors==9){ _event_queue->call_every(1742 /* ms */, callback(this, &Self::read_sensors_1)); } if(sensors==10){ _event_queue->call_every(1743 /* ms */, callback(this, &Self::read_sensors_2)); } if(sensors==11){ _event_queue->call_every(1744 /* ms */, callback(this, &Self::read_sensors_3)); } if(sensors==12){ _event_queue->call_every(1745 /* ms */, callback(this, &Self::read_sensors_4)); } if(sensors==13){ _event_queue->call_every(1746 /* ms */, callback(this, &Self::read_sensors_5)); } if(sensors==14){ _event_queue->call_every(1747 /* ms */, callback(this, &Self::read_sensors_6)); } if(sensors==15){ _event_queue->call_every(1748 /* ms */, callback(this, &Self::read_sensors_7)); } } void Update_char(int up) { if (up==0){ ble_error_t err = _sens00_char.set(*_server, sens00); printf ("sens00 sensor value: %d\n", sens00); if (err) { printf("write of the sens00 value returned error %u\r\n", err); return; } } if(up==1){ ble_error_t err = _sens01_char.set(*_server, sens01); printf ("sens01 sensor value: %d\n", sens01); if (err) { printf("write of the sens01 value returned error %u\r\n", err); return; } } if (up==2){ ble_error_t err = _sens02_char.set(*_server, sens02); printf ("sens02 sensor value: %d\n", sens02); if (err) { printf("write of the sens02 value returned error %u\r\n", err); return; } } } void blink() { led1 = !led1; } /** * Change led status. */ void change_led(void) { uint8_t led = 0; ble_error_t err = _led_char.get(*_server, led); if (err) { printf("read of the led value returned error %u\r\n", err); return; } } private: /** * Helper that construct an event handler from a member function of this * instance. */ template<typename Arg> FunctionPointerWithContext<Arg> as_cb(void (Self::*member)(Arg)) { return makeFunctionPointer(this, member); } /** * Read, Write, Notify, Indicate Characteristic declaration helper. * * @tparam T type of data held by the characteristic. */ template<typename T> class ReadWriteNotifyIndicateCharacteristic : public GattCharacteristic { public: /** * Construct a characteristic that can be read or written and emit * notification or indication. * * @param[in] uuid The UUID of the characteristic. * @param[in] initial_value Initial value contained by the characteristic. */ ReadWriteNotifyIndicateCharacteristic(const UUID & uuid, const T& initial_value) : GattCharacteristic( /* UUID */ uuid, /* Initial value */ (uint8_t *) &_value, /* Value size */ sizeof(_value), /* Value capacity */ sizeof(_value), /* Properties */ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE, /* Descriptors */ NULL, /* Num descriptors */ 0, /* variable len */ false ), _value(initial_value) { } /** * Get the value of this characteristic. * * @param[in] server GattServer instance that contain the characteristic * value. * @param[in] dst Variable that will receive the characteristic value. * * @return BLE_ERROR_NONE in case of success or an appropriate error code. */ ble_error_t get(GattServer &server, T& dst) const { uint16_t value_length = sizeof(dst); return server.read(getValueHandle(), (uint8_t *) &dst, &value_length); } /** * Assign a new value to this characteristic. * * @param[in] server GattServer instance that will receive the new value. * @param[in] value The new value to set. * @param[in] local_only Flag that determine if the change should be kept * locally or forwarded to subscribed clients. */ ble_error_t set( GattServer &server, const uint8_t &value, bool local_only = false ) const { return server.write(getValueHandle(), (uint8_t *) &value, sizeof(value), local_only); } private: uint32_t _value; }; template<typename T> class ReadWriteCharacteristic : public GattCharacteristic { public: /** * Construct a characteristic that can be read or written and emit * notification or indication. * * @param[in] uuid The UUID of the characteristic. * @param[in] initial_value Initial value contained by the characteristic. */ ReadWriteCharacteristic(const UUID & uuid, const T& initial_value) : GattCharacteristic( /* UUID */ uuid, /* Initial value */ (uint8_t *) &_value, /* Value size */ sizeof(_value), /* Value capacity */ sizeof(_value), /* Properties */ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE , /* Descriptors */ NULL, /* Num descriptors */ 0, /* variable len */ false ), _value(initial_value) { } /** * Get the value of this characteristic. * * @param[in] server GattServer instance that contain the characteristic * value. * @param[in] dst Variable that will receive the characteristic value. * * @return BLE_ERROR_NONE in case of success or an appropriate error code. */ ble_error_t get(GattServer &server, T& dst) const { uint16_t value_length = sizeof(dst); return server.read(getValueHandle(), (uint8_t *) &dst, &value_length); } /** * Assign a new value to this characteristic. * * @param[in] server GattServer instance that will receive the new value. * @param[in] value The new value to set. * @param[in] local_only Flag that determine if the change should be kept * locally or forwarded to subscribed clients. */ ble_error_t set( GattServer &server, const uint8_t &value, bool local_only = false ) const { return server.write(getValueHandle(), (uint8_t *) &value, sizeof(value), local_only); } private: uint8_t _value; }; ReadWriteCharacteristic<uint8_t> _sensors_char; ReadWriteCharacteristic<uint8_t> _led_char; ReadWriteNotifyIndicateCharacteristic<uint32_t> _sens00_char; ReadWriteNotifyIndicateCharacteristic<uint32_t> _sens01_char; ReadWriteNotifyIndicateCharacteristic<uint32_t> _sens02_char; // list of the characteristics of the My service GattCharacteristic* _My_characteristics[5]; // demo service GattService _My_service; GattServer* _server; events::EventQueue *_event_queue; DigitalOut _actuated_led; };