edrosten / libblepp

Modern clean C++ Bluetooth Low Energy on Linux without the Bluez DBUS API
Other
241 stars 63 forks source link

Texas Instruments Sensor Tag #43

Open westsuhanic opened 5 years ago

westsuhanic commented 5 years ago

Hello:

Thank you for your work.

I would like to use your library to control a TI Sensor Tag. However it is not clear to me how I would do the following:

1)turning on the sensor tag by writing 0x01 to the characteristic f000aa02-0451-4000-b000-000000000000 2)Then reading the data by a read request on f000aa01-0451-4000-b000-000000000000

I have modified your temperature.cc code however whenever I try to turn on the sensor tag by writing 0x01-(using characteristic.write_request(uint8_t(1)); ) the program exits with a logic error.

Any help is appreciated.

west suhanic

edrosten commented 5 years ago

Could you post a complete, minimal example?

westsuhanic commented 5 years ago

Hello:

Here is my verson of temperature.cc. Please note that I have a version running based on the github project tinyb. The modifications I made to your stock code is to find the config handle, then once I have the config handle turn the sensor on. Next find the read handle, once I have that register the callback. I know the uuid for the config and read handles are correct as these are used in the tinyb code.

I am motivated to make this work.

===================================================================== int main(int argc, char **argv) { if(argc != 2) { cerr << "Please supply address.\n"; cerr << "Usage:\n"; cerr << "prog "; exit(1); }

    log_level = Error;

    //This class does all of the GATT interactions for you.
    BLEGATTStateMachine gatt;
    std::function<void(const PDUNotificationOrIndication&)> notify_cb = [&](const PDUNotificationOrIndication& n)
    {
            auto ms_since_epoch = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
            float temp = bluetooth_float_to_IEEE754(n.value().first+1);

            cout << setprecision(15) << ms_since_epoch.count()/1000. << " " << setprecision(5) << temp << endl;
            std::cerr << "Herex." << std::endl;
    };

    std::function<void()> found_services_and_characteristics_cb = [&gatt, &notify_cb](){
            //Find config handle then try to turn the temp sensor on.
            for(auto& service: gatt.primary_services)
            {
            char *ytmp = (char *)calloc(300,sizeof(char));
            bt_uuid_to_string( (const bt_uuid_t *)&service.uuid, ytmp, 300 );
            std::cerr << "Y->" << ytmp << std::endl;
            //Find temperature service.
            if( service.uuid == UUID("f000aa00-0451-4000-b000-000000000000") )
            {
                    //for(Characteristic& characteristic: service.characteristics)
                    for(auto& characteristic: service.characteristics)
                    {
                    char *xtmp = (char *)calloc(300,sizeof(char));
                    bt_uuid_to_string( (const bt_uuid_t *)&characteristic.uuid, xtmp, 300 );
                    std::cerr << "X->" << xtmp << std::endl;
                            if(characteristic.uuid == UUID("f000aa02-0451-4000-b000-000000000000"))
                            {
                                    //characteristic.write_request(uint8_t(1));
                                    //characteristic.cb_notify_or_indicate = notify_cb;
                                    //characteristic.set_notify_and_indicate(true, false);
                                    std::cerr << "Found config handle." << std::endl;
                                    //Turn the temp sensor on.
                                    characteristic.write_request(uint8_t(0x01));
                            }
                            else if(characteristic.uuid == UUID("f000aa01-0451-4000-b000-000000000000"))
                            {
                                    std::cerr << "Found read handle." << std::endl;
                                    //Read values of off temp sensor.
                                    //characteristic.cb_notify_or_indicate = notify_cb;
                                    //characteristic.set_notify_and_indicate(true, false);
                            }
                    free( xtmp );
                    }
            }
            free( ytmp );
            }

            //Find the read handle after turning the sensor on and read the
            //temperature sensor.
            for(auto& service: gatt.primary_services)
            {
            char *ytmp = (char *)calloc(300,sizeof(char));
            bt_uuid_to_string( (const bt_uuid_t *)&service.uuid, ytmp, 300 );
            std::cerr << "Y->" << ytmp << std::endl;
            //Find temperature service.
            if( service.uuid == UUID("f000aa00-0451-4000-b000-000000000000") )
            {
                    //for(Characteristic& characteristic: service.characteristics)
                    for(auto& characteristic: service.characteristics)
                    {
                    char *xtmp = (char *)calloc(300,sizeof(char));
                    bt_uuid_to_string( (const bt_uuid_t *)&characteristic.uuid, xtmp, 300 );
                    std::cerr << "X->" << xtmp << std::endl;
                            if(characteristic.uuid == UUID("f000aa02-0451-4000-b000-000000000000"))
                            {
                                    //characteristic.write_request(uint8_t(1));
                                    //characteristic.cb_notify_or_indicate = notify_cb;
                                    //characteristic.set_notify_and_indicate(true, false);
                                    std::cerr << "Found config handle." << std::endl;
                                    //Turn the temp sensor on.
                                    //characteristic.write_request(uint8_t(1));
                            }
                            else if(characteristic.uuid == UUID("f000aa01-0451-4000-b000-000000000000"))
                            {
                                    std::cerr << "Found read handle." << std::endl;
                                    unsigned int microseconds = 10000000;
                                    usleep(microseconds);
                                    //Read values of off temp sensor.
                                    characteristic.cb_notify_or_indicate = notify_cb;
                                    characteristic.set_notify_and_indicate(true, false);
                            }
                    free( xtmp );
                    }
            }
            free( ytmp );
            }
    };

    //I think this one is reasonably clear?
    gatt.cb_disconnected = [](BLEGATTStateMachine::Disconnect d)
    {
            cerr << "Disconnect for reason " << BLEGATTStateMachine::get_disconnect_string(d) << endl;
            exit(1);
    };

    //This is how to use the blocking interface. It is very simple. You provide the main 
    //loop and just hammer on the state machine struct. 
    gatt.connect_blocking(argv[1]);
    for(;;)
            gatt.read_and_process_next();

}

I run the program via the following command:

sudo ./temperature 54:6C:0E:52:F9:1F

The ouptut is: Y->1800 Y->1801 Y->180a Y->180f Y->f000aa00-0451-4000-b000-000000000000 X->f000aa01-0451-4000-b000-000000000000 Found read handle. X->f000aa02-0451-4000-b000-000000000000 Found config handle. X->f000aa03-0451-4000-b000-000000000000 Y->f000aa20-0451-4000-b000-000000000000 Y->f000aa40-0451-4000-b000-000000000000 Y->f000aa80-0451-4000-b000-000000000000 Y->f000aa70-0451-4000-b000-000000000000 Y->ffe0 Y->f000aa64-0451-4000-b000-000000000000 Y->f000ac00-0451-4000-b000-000000000000 Y->f000ccc0-0451-4000-b000-000000000000 Y->f000ffc0-0451-4000-b000-000000000000 Y->1800 Y->1801 Y->180a Y->180f Y->f000aa00-0451-4000-b000-000000000000 X->f000aa01-0451-4000-b000-000000000000 Found read handle. terminate called after throwing an instance of 'std::logic_error' what(): Error trying to issue command mid state Aborted

thank you for your time.

west suhanic