Advertisement
Guest User

Untitled

a guest
Feb 17th, 2020
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.58 KB | None | 0 0
  1. public:
  2.     ClockService() :
  3.         _hour_char("485f4145-52b9-4644-af1f-7a6b9322490f", 0),
  4.         _minute_char("0a924ca7-87cd-4699-a3bd-abdcd9cf126a", 0),
  5.         _second_char("8dd6a1b7-bc75-4741-8a26-264af75807de", 0),
  6.         _clock_service(
  7.             /* uuid */ "51311102-030e-485f-b122-f8f381aa84ed",
  8.             /* characteristics */ _clock_characteristics,
  9.             /* numCharacteristics */ sizeof(_clock_characteristics) /
  10.                                      sizeof(_clock_characteristics[0])
  11.         ),
  12.         _server(NULL),
  13.         _event_queue(NULL)
  14.     {
  15.         // update internal pointers (value, descriptors and characteristics array)
  16.         _clock_characteristics[0] = &_hour_char;
  17.         _clock_characteristics[1] = &_minute_char;
  18.         _clock_characteristics[2] = &_second_char;
  19.  
  20.         // setup authorization handlers
  21.         _hour_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write);
  22.         _minute_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write);
  23.         _second_char.setWriteAuthorizationCallback(this, &Self::authorize_client_write);
  24.     }
  25.  
  26.  
  27.  
  28.     void start(BLE &ble_interface, events::EventQueue &event_queue)
  29.     {
  30.          if (_event_queue) {
  31.             return;
  32.         }
  33.  
  34.         _server = &ble_interface.gattServer();
  35.         _event_queue = &event_queue;
  36.  
  37.         // register the service
  38.         printf("Adding demo service\r\n");
  39.         ble_error_t err = _server->addService(_clock_service);
  40.  
  41.         if (err) {
  42.             printf("Error %u during demo service registration.\r\n", err);
  43.             return;
  44.         }
  45.  
  46.         // read write handler
  47.         _server->onDataSent(as_cb(&Self::when_data_sent));
  48.         _server->onDataWritten(as_cb(&Self::when_data_written));
  49.         _server->onDataRead(as_cb(&Self::when_data_read));
  50.  
  51.         // updates subscribtion handlers
  52.         _server->onUpdatesEnabled(as_cb(&Self::when_update_enabled));
  53.         _server->onUpdatesDisabled(as_cb(&Self::when_update_disabled));
  54.         _server->onConfirmationReceived(as_cb(&Self::when_confirmation_received));
  55.  
  56.         // print the handles
  57.         printf("clock service registered\r\n");
  58.         printf("service handle: %u\r\n", _clock_service.getHandle());
  59.         printf("\thour characteristic value handle %u\r\n", _hour_char.getValueHandle());
  60.         printf("\tminute characteristic value handle %u\r\n", _minute_char.getValueHandle());
  61.         printf("\tsecond characteristic value handle %u\r\n", _second_char.getValueHandle());
  62.  
  63.         _event_queue->call_every(1000 /* ms */, callback(this, &Self::increment_second));
  64.     }
  65.  
  66. private:
  67.  
  68.     /**
  69.      * Handler called when a notification or an indication has been sent.
  70.      */
  71.     void when_data_sent(unsigned count)
  72.     {
  73.         printf("sent %u updates\r\n", count);
  74.     }
  75.  
  76.     /**
  77.      * Handler called after an attribute has been written.
  78.      */
  79.     void when_data_written(const GattWriteCallbackParams *e)
  80.     {
  81.         printf("data written:\r\n");
  82.         printf("\tconnection handle: %u\r\n", e->connHandle);
  83.         printf("\tattribute handle: %u", e->handle);
  84.         if (e->handle == _hour_char.getValueHandle()) {
  85.             printf(" (hour characteristic)\r\n");
  86.         } else if (e->handle == _minute_char.getValueHandle()) {
  87.             printf(" (minute characteristic)\r\n");
  88.         } else if (e->handle == _second_char.getValueHandle()) {
  89.             printf(" (second characteristic)\r\n");
  90.         } else {
  91.             printf("\r\n");
  92.         }
  93.         printf("\twrite operation: %u\r\n", e->writeOp);
  94.         printf("\toffset: %u\r\n", e->offset);
  95.         printf("\tlength: %u\r\n", e->len);
  96.         printf("\t data: ");
  97.  
  98.         for (size_t i = 0; i < e->len; ++i) {
  99.             printf("%02X", e->data[i]);
  100.         }
  101.  
  102.         printf("\r\n");
  103.     }
  104.  
  105.     /**
  106.      * Handler called after an attribute has been read.
  107.      */
  108.     void when_data_read(const GattReadCallbackParams *e)
  109.     {
  110.         printf("data read:\r\n");
  111.         printf("\tconnection handle: %u\r\n", e->connHandle);
  112.         printf("\tattribute handle: %u", e->handle);
  113.         if (e->handle == _hour_char.getValueHandle()) {
  114.             printf(" (hour characteristic)\r\n");
  115.         } else if (e->handle == _minute_char.getValueHandle()) {
  116.             printf(" (minute characteristic)\r\n");
  117.         } else if (e->handle == _second_char.getValueHandle()) {
  118.             printf(" (second characteristic)\r\n");
  119.         } else {
  120.             printf("\r\n");
  121.         }
  122.     }
  123.  
  124.     /**
  125.      * Handler called after a client has subscribed to notification or indication.
  126.      *
  127.      * @param handle Handle of the characteristic value affected by the change.
  128.      */
  129.     void when_update_enabled(GattAttribute::Handle_t handle)
  130.     {
  131.         printf("update enabled on handle %d\r\n", handle);
  132.     }
  133.  
  134.     /**
  135.      * Handler called after a client has cancelled his subscription from
  136.      * notification or indication.
  137.      *
  138.      * @param handle Handle of the characteristic value affected by the change.
  139.      */
  140.     void when_update_disabled(GattAttribute::Handle_t handle)
  141.     {
  142.         printf("update disabled on handle %d\r\n", handle);
  143.     }
  144.  
  145.     /**
  146.      * Handler called when an indication confirmation has been received.
  147.      *
  148.      * @param handle Handle of the characteristic value that has emitted the
  149.      * indication.
  150.      */
  151.     void when_confirmation_received(GattAttribute::Handle_t handle)
  152.     {
  153.         printf("confirmation received on handle %d\r\n", handle);
  154.     }
  155.  
  156.     /**
  157.      * Handler called when a write request is received.
  158.      *
  159.      * This handler verify that the value submitted by the client is valid before
  160.      * authorizing the operation.
  161.      */
  162.     void authorize_client_write(GattWriteAuthCallbackParams *e)
  163.     {
  164.         printf("characteristic %u write authorization\r\n", e->handle);
  165.  
  166.         if (e->offset != 0) {
  167.             printf("Error invalid offset\r\n");
  168.             e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
  169.             return;
  170.         }
  171.  
  172.         if (e->len != 1) {
  173.             printf("Error invalid len\r\n");
  174.             e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
  175.             return;
  176.         }
  177.  
  178.         if ((e->data[0] >= 60) ||
  179.             ((e->data[0] >= 24) && (e->handle == _hour_char.getValueHandle()))) {
  180.             printf("Error invalid data\r\n");
  181.             e->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED;
  182.             return;
  183.         }
  184.  
  185.         e->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
  186.     }
  187.  
  188.     /**
  189.      * Increment the second counter.
  190.      */
  191.     void increment_second(void)
  192.     {
  193.         uint8_t second = 0;
  194.         ble_error_t err = _second_char.get(*_server, second);
  195.         if (err) {
  196.             printf("read of the second value returned error %u\r\n", err);
  197.             return;
  198.         }
  199.  
  200.         second = (second + 1) % 60;
  201.  
  202.         err = _second_char.set(*_server, second);
  203.         if (err) {
  204.             printf("write of the second value returned error %u\r\n", err);
  205.             return;
  206.         }
  207.  
  208.         if (second == 0) {
  209.             increment_minute();
  210.         }
  211.     }
  212.  
  213.     /**
  214.      * Increment the minute counter.
  215.      */
  216.     void increment_minute(void)
  217.     {
  218.         uint8_t minute = 0;
  219.         ble_error_t err = _minute_char.get(*_server, minute);
  220.         if (err) {
  221.             printf("read of the minute value returned error %u\r\n", err);
  222.             return;
  223.         }
  224.  
  225.         minute = (minute + 1) % 60;
  226.  
  227.         err = _minute_char.set(*_server, minute);
  228.         if (err) {
  229.             printf("write of the minute value returned error %u\r\n", err);
  230.             return;
  231.         }
  232.  
  233.         if (minute == 0) {
  234.             increment_hour();
  235.         }
  236.     }
  237.  
  238.     /**
  239.      * Increment the hour counter.
  240.      */
  241.     void increment_hour(void)
  242.     {
  243.         uint8_t hour = 0;
  244.         ble_error_t err = _hour_char.get(*_server, hour);
  245.         if (err) {
  246.             printf("read of the hour value returned error %u\r\n", err);
  247.             return;
  248.         }
  249.  
  250.         hour = (hour + 1) % 24;
  251.  
  252.         err = _hour_char.set(*_server, hour);
  253.         if (err) {
  254.             printf("write of the hour value returned error %u\r\n", err);
  255.             return;
  256.         }
  257.     }
  258.  
  259. private:
  260.     /**
  261.      * Helper that construct an event handler from a member function of this
  262.      * instance.
  263.      */
  264.     template<typename Arg>
  265.     FunctionPointerWithContext<Arg> as_cb(void (Self::*member)(Arg))
  266.     {
  267.         return makeFunctionPointer(this, member);
  268.     }
  269.  
  270.     /**
  271.      * Read, Write, Notify, Indicate  Characteristic declaration helper.
  272.      *
  273.      * @tparam T type of data held by the characteristic.
  274.      */
  275.     template<typename T>
  276.     class ReadWriteNotifyIndicateCharacteristic : public GattCharacteristic {
  277.     public:
  278.         /**
  279.          * Construct a characteristic that can be read or written and emit
  280.          * notification or indication.
  281.          *
  282.          * @param[in] uuid The UUID of the characteristic.
  283.          * @param[in] initial_value Initial value contained by the characteristic.
  284.          */
  285.         ReadWriteNotifyIndicateCharacteristic(const UUID & uuid, const T& initial_value) :
  286.             GattCharacteristic(
  287.                 /* UUID */ uuid,
  288.                 /* Initial value */ &_value,
  289.                 /* Value size */ sizeof(_value),
  290.                 /* Value capacity */ sizeof(_value),
  291.                 /* Properties */ GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ |
  292.                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE |
  293.                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY |
  294.                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE,
  295.                 /* Descriptors */ NULL,
  296.                 /* Num descriptors */ 0,
  297.                 /* variable len */ false
  298.             ),
  299.             _value(initial_value) {
  300.         }
  301.  
  302.         /**
  303.          * Get the value of this characteristic.
  304.          *
  305.          * @param[in] server GattServer instance that contain the characteristic
  306.          * value.
  307.          * @param[in] dst Variable that will receive the characteristic value.
  308.          *
  309.          * @return BLE_ERROR_NONE in case of success or an appropriate error code.
  310.          */
  311.         ble_error_t get(GattServer &server, T& dst) const
  312.         {
  313.             uint16_t value_length = sizeof(dst);
  314.             return server.read(getValueHandle(), &dst, &value_length);
  315.         }
  316.  
  317.         /**
  318.          * Assign a new value to this characteristic.
  319.          *
  320.          * @param[in] server GattServer instance that will receive the new value.
  321.          * @param[in] value The new value to set.
  322.          * @param[in] local_only Flag that determine if the change should be kept
  323.          * locally or forwarded to subscribed clients.
  324.          */
  325.         ble_error_t set(
  326.             GattServer &server, const uint8_t &value, bool local_only = false
  327.         ) const {
  328.             return server.write(getValueHandle(), &value, sizeof(value), local_only);
  329.         }
  330.  
  331.     private:
  332.         uint8_t _value;
  333.     };
  334.  
  335.     ReadWriteNotifyIndicateCharacteristic<uint8_t> _hour_char;
  336.     ReadWriteNotifyIndicateCharacteristic<uint8_t> _minute_char;
  337.     ReadWriteNotifyIndicateCharacteristic<uint8_t> _second_char;
  338.  
  339.     // list of the characteristics of the clock service
  340.     GattCharacteristic* _clock_characteristics[3];
  341.  
  342.     // demo service
  343.     GattService _clock_service;
  344.  
  345.     GattServer* _server;
  346.     events::EventQueue *_event_queue;
  347. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement