GPS to Pulga

Dependencies:   Si1133 BME280

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;
};