Health Thermometer Profile patches
Next set of patches enhances support for health thermometer thermomter profile. They include fixes suggested other set.
[PATCH 1/9] Get thermometer service range to load the driver. [PATCH 2/9] Register Health Thermometer Interface [PATCH 3/9] Unregister Health Thermometer Interface [PATCH 4/9] Add functions to manage attio callbacks [PATCH 5/9] Add handler function to manage GATT indications [PATCH 6/9] Get all characteristics in thermometer service [PATCH 7/9] Read temperature type characteristic [PATCH 8/9] Read measurement interval characteristic [PATCH 9/9] Set Intermediate property if intermediate temp.
PATCH 1/9 Get thermometer service range to load the driver.
--- thermometer/manager.c | 13 ++++++++++++- thermometer/thermometer.c | 5 ++++- thermometer/thermometer.h | 3 ++- 3 files changed, 18 insertions(+), 3 deletions(-)
thermometer/manager.c +12 -1
@@ -21,9 +21,11 @@*/ #include <gdbus.h> +#include <bluetooth/uuid.h> #include "adapter.h" #include "device.h" +#include "att.h" #include "thermometer.h" #include "manager.h"
@@ -33,7 +35,16 @@ static DBusConnection *connection = NULL;static int thermometer_driver_probe (struct btd_device *device,GSList *uuids) { -return thermometer_register (connection, device); +struct att_primary *tattr; +GSList *list; + + list =device_services_from_record (device, uuids); +if (!list) +return -1 ; + + tattr = list->data; + +return thermometer_register (connection, device, tattr); }static void thermometer_driver_remove (struct btd_device *device)
thermometer/thermometer.c +4 -1
@@ -21,12 +21,15 @@*/ #include <gdbus.h> +#include <bluetooth/uuid.h> #include "adapter.h" #include "device.h" +#include "att.h" #include "thermometer.h" -int thermometer_register (DBusConnection *connection,struct btd_device *device) +int thermometer_register (DBusConnection *connection,struct btd_device *device, +struct att_primary *tattr) {/* TODO: Register Health Thermometer Interface */ return 0 ;
thermometer/thermometer.h +2 -1
@@ -20,5 +20,6 @@* */ -int thermometer_register (DBusConnection *connection,struct btd_device *device); +int thermometer_register (DBusConnection *connection,struct btd_device *device, +struct att_primary *tattr);void thermometer_unregister (struct btd_device *device);
Signature · 1 line
1.7.6.1
PATCH 2/9 Register Health Thermometer Interface
--- thermometer/thermometer.c | 108 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 107 insertions(+), 1 deletions(-)
thermometer/thermometer.c +107 -1
@@ -25,13 +25,119 @@#include "adapter.h" #include "device.h" +#include "error.h" +#include "log.h" +#include "gattrib.h" #include "att.h" #include "thermometer.h" +#define THERMOMETER_INTERFACE "org.bluez.Thermometer" + +struct thermometer { +DBusConnection *conn;/* The connection to the bus */ +struct btd_device *dev;/* Device reference */ +struct att_range *svc_range;/* Thermometer range */ +}; + +static GSList *thermometers =NULL ; + +static void destroy_thermometer (gpointer user_data) +{ +struct thermometer *t = user_data; + +dbus_connection_unref (t->conn); +btd_device_unref (t->dev); +g_free (t->svc_range); +g_free (t); +} + +static DBusMessage *get_properties (DBusConnection *conn,DBusMessage *msg, +void *data) +{ +/* TODO: */ +return g_dbus_create_error (msg,ERROR_INTERFACE ".ThermometerError" , +"Function not implemented." ); +} + +static DBusMessage *set_property (DBusConnection *conn,DBusMessage *msg, +void *data) +{ +/* TODO: */ +return g_dbus_create_error (msg,ERROR_INTERFACE ".ThermometerError" , +"Function not implemented." ); +} + +static DBusMessage *register_watcher (DBusConnection *conn,DBusMessage *msg, +void *data) +{ +/* TODO: */ +return g_dbus_create_error (msg,ERROR_INTERFACE ".ThermometerError" , +"Function not implemented." ); +} + +static DBusMessage *unregister_watcher (DBusConnection *conn,DBusMessage *msg, +void *data) +{ +/* TODO: */ +return g_dbus_create_error (msg,ERROR_INTERFACE ".ThermometerError" , +"Function not implemented." ); +} + +static DBusMessage *enable_intermediate (DBusConnection *conn,DBusMessage *msg, +void *data) +{ +/* TODO: */ +return g_dbus_create_error (msg,ERROR_INTERFACE ".ThermometerError" , +"Function not implemented." ); +} + +static DBusMessage *disable_intermediate (DBusConnection *conn,DBusMessage *msg, +void *data) +{ +/* TODO: */ +return g_dbus_create_error (msg,ERROR_INTERFACE ".ThermometerError" , +"Function not implemented." ); +} + +static GDBusMethodTable thermometer_methods[] = { + {"GetProperties" ,"" ,"a{sv}" , get_properties }, + {"SetProperty" ,"sv" ,"" , set_property, +G_DBUS_METHOD_FLAG_ASYNC }, + {"RegisterWatcher" ,"o" ,"" , register_watcher }, + {"UnregisterWatcher" ,"o" ,"" , unregister_watcher }, + {"EnableIntermediateMeasurement" ,"o" ,"" , enable_intermediate }, + {"DisableIntermediateMeasurement" ,"o" ,"" , disable_intermediate }, + { } +}; + +static GDBusSignalTable thermometer_signals[] = { + {"PropertyChanged" ,"sv" }, + { } +}; +int thermometer_register (DBusConnection *connection,struct btd_device *device,struct att_primary *tattr) { -/* TODO: Register Health Thermometer Interface */ +const gchar *path =device_get_path (device); +struct thermometer *t; + + t = g_new0(struct thermometer, 1); + t->conn =dbus_connection_ref (connection); + t->dev =btd_device_ref (device); + t->svc_range = g_new0(struct att_range, 1); + t->svc_range->start = tattr->start; + t->svc_range->end = tattr->end; + +if (!g_dbus_register_interface (t->conn, path,THERMOMETER_INTERFACE , + thermometer_methods, thermometer_signals, +NULL , t, destroy_thermometer)) { +error ("D-Bus failed to register %s interface" , +THERMOMETER_INTERFACE ); +destroy_thermometer (t); +return -1 ; + } + + thermometers =g_slist_prepend (thermometers, t);return 0 ; }
Signature · 1 line
1.7.6.1
PATCH 3/9 Unregister Health Thermometer Interface
--- thermometer/thermometer.c | 23 ++++++++++++++++++++++- 1 files changed, 22 insertions(+), 1 deletions(-)
thermometer/thermometer.c +22 -1
@@ -51,6 +51,17 @@ static void destroy_thermometer(gpointer user_data)g_free (t); } +static gint cmp_device (gconstpointer a,gconstpointer b) +{ +const struct thermometer *t = a; +const struct btd_device *dev = b; + +if (dev == t->dev) +return 0 ; + +return -1 ; +} +static DBusMessage *get_properties (DBusConnection *conn,DBusMessage *msg,void *data) {
@@ -143,5 +154,15 @@ int thermometer_register(DBusConnection *connection, struct btd_device *device,void thermometer_unregister (struct btd_device *device) { -/* TODO: Unregister Health Thermometer Interface */ +struct thermometer *t; +GSList *l; + + l =g_slist_find_custom (thermometers, device, cmp_device); +if (!l) +return ; + + t = l->data; + thermometers =g_slist_remove (thermometers, t); +g_dbus_unregister_interface (t->conn,device_get_path (t->dev), +THERMOMETER_INTERFACE ); }
Signature · 1 line
1.7.6.1
PATCH 4/9 Add functions to manage attio callbacks
--- thermometer/thermometer.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)
thermometer/thermometer.c +29 -0
@@ -28,6 +28,7 @@#include "error.h" #include "log.h" #include "gattrib.h" +#include "attio.h" #include "att.h" #include "thermometer.h"
@@ -36,7 +37,9 @@struct thermometer {DBusConnection *conn;/* The connection to the bus */ struct btd_device *dev;/* Device reference */ +GAttrib *attrib;/* GATT connection */ struct att_range *svc_range;/* Thermometer range */ +gint attioid;/* Att watcher id */ };static GSList *thermometers =NULL ;
@@ -45,6 +48,12 @@ static void destroy_thermometer(gpointer user_data) {struct thermometer *t = user_data; +if (t->attioid) +btd_device_remove_attio_callback (t->dev, t->attioid); + +if (t->attrib) +g_attrib_unref (t->attrib); +dbus_connection_unref (t->conn);btd_device_unref (t->dev);g_free (t->svc_range);
@@ -126,6 +135,23 @@ static GDBusSignalTable thermometer_signals[] = { { } }; +static void attio_connected_cb (GAttrib *attrib,gpointer user_data) +{ +struct thermometer *t = user_data; + + t->attrib =g_attrib_ref (attrib); +} + +static void attio_disconnected_cb (gpointer user_data) +{ +struct thermometer *t = user_data; + +DBG ("GATT Disconnected" ); + +g_attrib_unref (t->attrib); + t->attrib =NULL ; +} +int thermometer_register (DBusConnection *connection,struct btd_device *device,struct att_primary *tattr) {
@@ -149,6 +175,9 @@ int thermometer_register(DBusConnection *connection, struct btd_device *device, } thermometers =g_slist_prepend (thermometers, t); + + t->attioid =btd_device_add_attio_callback (device, attio_connected_cb, + attio_disconnected_cb, t);return 0 ; }
Signature · 1 line
1.7.6.1
PATCH 5/9 Add handler function to manage GATT indications
--- thermometer/thermometer.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-)
thermometer/thermometer.c +17 -0
@@ -40,6 +40,7 @@ struct thermometer {GAttrib *attrib;/* GATT connection */ struct att_range *svc_range;/* Thermometer range */ gint attioid;/* Att watcher id */ +gint attindid;/* Att incications id */ };static GSList *thermometers =NULL ;
@@ -51,6 +52,9 @@ static void destroy_thermometer(gpointer user_data)if (t->attioid)btd_device_remove_attio_callback (t->dev, t->attioid); +if (t->attindid) +g_attrib_unregister (t->attrib, t->attindid); +if (t->attrib)g_attrib_unref (t->attrib);
@@ -135,11 +139,19 @@ static GDBusSignalTable thermometer_signals[] = { { } }; +static void ind_handler (const uint8_t *pdu,uint16_t len,gpointer user_data) +{ +/* TODO: Process indication */ +} +static void attio_connected_cb (GAttrib *attrib,gpointer user_data) {struct thermometer *t = user_data; t->attrib =g_attrib_ref (attrib); + + t->attindid =g_attrib_register (t->attrib,ATT_OP_HANDLE_IND , + ind_handler, t,NULL ); }static void attio_disconnected_cb (gpointer user_data)
@@ -148,6 +160,11 @@ static void attio_disconnected_cb(gpointer user_data)DBG ("GATT Disconnected" ); +if (t->attindid) { +g_attrib_unregister (t->attrib, t->attindid); + t->attindid =0 ; + } +g_attrib_unref (t->attrib); t->attrib =NULL ; }
Signature · 1 line
1.7.6.1
PATCH 6/9 Get all characteristics in thermometer service
--- thermometer/thermometer.c | 110 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 110 insertions(+), 0 deletions(-)
thermometer/thermometer.c +110 -0
@@ -30,10 +30,15 @@#include "gattrib.h" #include "attio.h" #include "att.h" +#include "gatt.h" #include "thermometer.h" #define THERMOMETER_INTERFACE "org.bluez.Thermometer" +#define TEMPERATURE_TYPE_UUID "00002a1d-0000-1000-8000-00805f9b34fb" +#define INTERMEDIATE_TEMPERATURE_UUID "00002a1e-0000-1000-8000-00805f9b34fb" +#define MEASUREMENT_INTERVAL_UUID "00002a21-0000-1000-8000-00805f9b34fb" +struct thermometer {DBusConnection *conn;/* The connection to the bus */ struct btd_device *dev;/* Device reference */
@@ -41,10 +46,31 @@ struct thermometer {struct att_range *svc_range;/* Thermometer range */ gint attioid;/* Att watcher id */ gint attindid;/* Att incications id */ +GSList *chars;/* Characteristics */ +}; + +struct characteristic { +struct att_char attr;/* Characteristic */ +GSList *desc;/* Descriptors */ +struct thermometer *t;/* Thermometer where the char belongs */ +}; + +struct descriptor { +struct characteristic *ch; +uint16_t handle; +bt_uuid_t uuid; };static GSList *thermometers =NULL ; +static void destroy_char (gpointer user_data) +{ +struct characteristic *c = user_data; + +g_slist_free_full (c->desc, g_free); +g_free (c); +} +static void destroy_thermometer (gpointer user_data) {struct thermometer *t = user_data;
@@ -58,6 +84,9 @@ static void destroy_thermometer(gpointer user_data)if (t->attrib)g_attrib_unref (t->attrib); +if (t->chars) +g_slist_free_full (t->chars, destroy_char); +dbus_connection_unref (t->conn);btd_device_unref (t->dev);g_free (t->svc_range);
@@ -75,6 +104,85 @@ static gint cmp_device(gconstpointer a, gconstpointer b)return -1 ; } +static void discover_desc_cb (guint8 status,const guint8 *pdu,guint16 len, +gpointer user_data) +{ +/* TODO */ +} + +static void read_temp_type_cb (guint8 status,const guint8 *pdu,guint16 len, +gpointer user_data) +{ +/* TODO */ +} + +static void read_interval_cb (guint8 status,const guint8 *pdu,guint16 len, +gpointer user_data) +{ +/* TODO */ +} + +static void process_thermometer_char (struct characteristic *ch) +{ +GAttribResultFunc func; + +if (g_strcmp0 (ch->attr.uuid,INTERMEDIATE_TEMPERATURE_UUID ) ==0 ) { +/* TODO: Change intermediate property and emit signal */ +return ; + }else if (g_strcmp0 (ch->attr.uuid,TEMPERATURE_TYPE_UUID ) ==0 ) + func = read_temp_type_cb; +else if (g_strcmp0 (ch->attr.uuid,MEASUREMENT_INTERVAL_UUID ) ==0 ) + func = read_interval_cb; +else +return ; + +gatt_read_char (ch->t->attrib, ch->attr.value_handle,0 , func, ch); +} + +static void configure_thermometer_cb (GSList *characteristics,guint8 status, +gpointer user_data) +{ +struct thermometer *t = user_data; +GSList *l; + +if (status) { +error ("Discover thermometer characteristics: %s" , +att_ecode2str (status)); +return ; + } + +for (l = characteristics; l; l = l->next) { +struct att_char *c = l->data; +struct characteristic *ch; +uint16_t start, end; + + ch = g_new0(struct characteristic, 1); + ch->attr.handle = c->handle; + ch->attr.properties = c->properties; + ch->attr.value_handle = c->value_handle; +memcpy (ch->attr.uuid, c->uuid,MAX_LEN_UUID_STR +1 ); + ch->t = t; + + t->chars =g_slist_append (t->chars, ch); + +process_thermometer_char (ch); + + start = c->value_handle +1 ; + +if (l->next) { +struct att_char *c = l->next->data; +if (start == c->handle) +continue ; + end = c->handle -1 ; + }else if (c->value_handle != t->svc_range->end) + end = t->svc_range->end; +else +continue ; + +gatt_find_info (t->attrib, start, end, discover_desc_cb, ch); + } +} +static DBusMessage *get_properties (DBusConnection *conn,DBusMessage *msg,void *data) {
@@ -152,6 +260,8 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data) t->attindid =g_attrib_register (t->attrib,ATT_OP_HANDLE_IND , ind_handler, t,NULL ); +gatt_discover_char (t->attrib, t->svc_range->start, t->svc_range->end, +NULL , configure_thermometer_cb, t); }static void attio_disconnected_cb (gpointer user_data)
Signature · 1 line
1.7.6.1
PATCH 7/9 Read temperature type characteristic
--- thermometer/thermometer.c | 47 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 46 insertions(+), 1 deletions(-)
thermometer/thermometer.c +46 -1
@@ -47,6 +47,13 @@ struct thermometer {gint attioid;/* Att watcher id */ gint attindid;/* Att incications id */ GSList *chars;/* Characteristics */ +gboolean intermediate; +guint8 type; +guint16 interval; +guint16 max; +guint16 min; +gboolean has_type; +gboolean has_interval; };struct characteristic {
@@ -63,6 +70,24 @@ struct descriptor {static GSList *thermometers =NULL ; +static gchar *temptype2str (uint8_t value) +{ +switch (value) { +case 1 :return "Armpit" ; +case 2 :return "Body" ; +case 3 :return "Ear" ; +case 4 :return "Finger" ; +case 5 :return "Intestines" ; +case 6 :return "Mouth" ; +case 7 :return "Rectum" ; +case 8 :return "Toe" ; +case 9 :return "Tympanum" ; +default : +error ("Temperature type %d reserved for future use" , value); +return NULL ; + }; +} +static void destroy_char (gpointer user_data) {struct characteristic *c = user_data;
@@ -113,7 +138,27 @@ static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,static void read_temp_type_cb (guint8 status,const guint8 *pdu,guint16 len,gpointer user_data) { -/* TODO */ +struct characteristic *ch = user_data; +struct thermometer *t = ch->t; +uint8_t value; +int vlen; + +if (status !=0 ) { +DBG ("Temperature Type value read failed: %s" , +att_ecode2str (status)); +return ; + } + +if (!dec_read_resp (pdu, len, &value, &vlen)) { +DBG ("Protocol error" ); +return ; + } + +DBG ("TEMPERATURE TYPE: %s" ,temptype2str (value)); +if (!t->has_interval) + t->has_interval = TRUE; + + t->type = value; } static void read_interval_cb(guint8 status, const guint8 *pdu, guint16 len,
Signature · 1 line
1.7.6.1
PATCH 8/9 Read measurement interval characteristic
--- thermometer/thermometer.c | 72 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 71 insertions(+), 1 deletions(-)
thermometer/thermometer.c +71 -1
@@ -23,6 +23,7 @@#include <gdbus.h> #include <bluetooth/uuid.h> +#include "dbus-common.h" #include "adapter.h" #include "device.h" #include "error.h"
@@ -129,6 +130,51 @@ static gint cmp_device(gconstpointer a, gconstpointer b)return -1 ; } +static void change_property (struct thermometer *t,const gchar *name, +gpointer value) { +if (g_strcmp0 (name,"Intermediate" ) ==0 ) { +gboolean *intermediate = value; +if (t->intermediate == *intermediate) +return ; + + t->intermediate = *intermediate; +emit_property_changed (t->conn,device_get_path (t->dev), +THERMOMETER_INTERFACE , name, +DBUS_TYPE_BOOLEAN , &t->intermediate); + }else if (g_strcmp0 (name,"Interval" ) ==0 ) { +uint16_t *interval = value; +if (t->has_interval && t->interval == *interval) +return ; + +if (!t->has_interval) + t->has_interval = TRUE; + + t->interval = *interval; +emit_property_changed (t->conn,device_get_path (t->dev), +THERMOMETER_INTERFACE , name, +DBUS_TYPE_UINT16 , &t->interval); + }else if (g_strcmp0 (name,"Maximum" ) ==0 ) { +uint16_t *max = value; +if (t->max == *max) +return ; + + t->max = *max; +emit_property_changed (t->conn,device_get_path (t->dev), +THERMOMETER_INTERFACE , name, +DBUS_TYPE_UINT16 , &t->max); + }else if (g_strcmp0 (name,"Minimum" ) ==0 ) { +uint16_t *min = value; +if (t->min == *min) +return ; + + t->min = *min; +emit_property_changed (t->conn,device_get_path (t->dev), +THERMOMETER_INTERFACE , name, +DBUS_TYPE_UINT16 , &t->min); + }else +DBG ("%s is not a thermometer property" , name); +} +static void discover_desc_cb (guint8 status,const guint8 *pdu,guint16 len,gpointer user_data) {
@@ -164,7 +210,31 @@ static void read_temp_type_cb(guint8 status, const guint8 *pdu, guint16 len,static void read_interval_cb (guint8 status,const guint8 *pdu,guint16 len,gpointer user_data) { -/* TODO */ +struct characteristic *ch = user_data; +uint8_t value[ATT_MAX_MTU ]; +uint16_t *p, interval; +int vlen; + +if (status !=0 ) { +DBG ("Measurement Interval value read failed: %s" , +att_ecode2str (status)); +return ; + } + +if (!dec_read_resp (pdu, len, value, &vlen)) { +DBG ("Protocol error\n" ); +return ; + } + +if (vlen <2 ) { +DBG ("Invalid Interval received" ); +return ; + } + + p = (uint16_t *) value; + interval =btohs (*p); + +change_property (ch->t,"Interval" , &interval); }static void process_thermometer_char (struct characteristic *ch)
Signature · 1 line
1.7.6.1
PATCH 9/9 Set Intermediate property if intermediate temp. characteristic is supported
--- thermometer/thermometer.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
thermometer/thermometer.c +2 -1
@@ -242,7 +242,8 @@ static void process_thermometer_char(struct characteristic *ch)GAttribResultFunc func;if (g_strcmp0 (ch->attr.uuid,INTERMEDIATE_TEMPERATURE_UUID ) ==0 ) { -/* TODO: Change intermediate property and emit signal */ +gboolean intermediate = TRUE; +change_property (ch->t,"Intermediate" , &intermediate);return ; }else if (g_strcmp0 (ch->attr.uuid,TEMPERATURE_TYPE_UUID ) ==0 ) func = read_temp_type_cb;
Signature · 1 line
1.7.6.1
Re: [PATCH 7/9] Read temperature type characteristic
In reply to Santiago Carot-NemesioHi Santiago,
Quoted 1 line · Santiago Carot-Nemesio
+static gchar*
temptype2str(uint8_t value)
Small conding style issue here: gchar* -> gchar *
Quoted 27 lines
thermometer/thermometer.c +17
-0+{ + switch (value) { + case 1: return "Armpit"; + case 2: return "Body"; + case 3: return "Ear"; + case 4: return "Finger"; + case 5: return "Intestines"; + case 6: return "Mouth"; + case 7: return "Rectum"; + case 8: return "Toe"; + case 9: return "Tympanum"; + default: + error("Temperature type %d reserved for future use", value); + return NULL; + }; +} +static void
destroy_char(gpointer user_data)
{
struct characteristic *c =user_data;thermometer/thermometer.c +2
-1@@ -113,7 +138,27 @@ static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len, static void read_temp_type_cb(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { - /* TODO */ + struct characteristic *ch = user_data; + struct thermometer *t = ch->t;
thermometer/thermometer.c static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len, · line 152
Quoted 10 lines
thermometer/thermometer.c +10
-0+ uint8_t value; + int vlen; + + if (status != 0) { + DBG("Temperature Type value read failed: %s", + att_ecode2str(status)); + return; + } + + if (!dec_read_resp(pdu, len, &value, &vlen)) {
Your code is assuming that the read response PDU will always have a one-byte value. This will cause memory corruption if the peer sends an error response with size greater than 2 (first byte is the opcode).
Either put a check like "if (len == sizeof(uint8_t) + 1 && read_read_resp(...))", or use:
uint8_t value[ATT_MAX_MTU];
and cast the first byte.
(just noticed that Proximity monitor code has the same bug...)
thermometer/thermometer.c static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len, · line 157
Quoted 5 lines
thermometer/thermometer.c +5
-0+ DBG("Protocol error"); + return; + } + + DBG("TEMPERATURE TYPE: %s", temptype2str(value));
Can you avoid using all-caps on the DBG() message above?
thermometer/thermometer.c static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len, · line 159
Quoted 2 lines
thermometer/thermometer.c +2
-0+ if (!t->has_interval) + t->has_interval = TRUE;
Why the if() check? You could just do "t->has_interval = TRUE;" always.
thermometer/thermometer.c static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len, · line 162
Quoted 3 lines
thermometer/thermometer.c +2
-0+ + t->type = value; }
Regards,
Signature · 3 lines
Anderson Lizardo Instituto Nokia de Tecnologia - INdT Manaus - Brazil
Re: [PATCH 7/9] Read temperature type characteristic
Hi Anderson
2011/9/28 Anderson Lizardo <[email protected]>:
Quoted 50 lines
Hi Santiago,
Quoted 1 line · Santiago Carot-Nemesio
+static gchar*
temptype2str(uint8_t value)Small conding style issue here: gchar* -> gchar *
Quoted 27 lines
thermometer/thermometer.c +17
-0+{ + switch (value) { + case 1: return "Armpit"; + case 2: return "Body"; + case 3: return "Ear"; + case 4: return "Finger"; + case 5: return "Intestines"; + case 6: return "Mouth"; + case 7: return "Rectum"; + case 8: return "Toe"; + case 9: return "Tympanum"; + default: + error("Temperature type %d reserved for future use", value); + return NULL; + }; +} +static void
destroy_char(gpointer user_data)
{
struct characteristic *c =user_data;thermometer/thermometer.c +2
-1@@ -113,7 +138,27 @@ static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len, static void read_temp_type_cb(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { - /* TODO */ + struct characteristic *ch = user_data; + struct thermometer *t = ch->t;thermometer/thermometer.c static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len, · line 152
Quoted 10 lines
thermometer/thermometer.c +10
-0+ uint8_t value; + int vlen; + + if (status != 0) { + DBG("Temperature Type value read failed: %s", + att_ecode2str(status)); + return; + } + + if (!dec_read_resp(pdu, len, &value, &vlen)) {Your code is assuming that the read response PDU will always have a one-byte value. This will cause memory corruption if the peer sends an error response with size greater than 2 (first byte is the opcode).
Quoted 7 lines
Either put a check like "if (len ==
sizeof(uint8_t)+ 1 &&read_read_resp(...))", or use:
uint8_tvalue[ATT_MAX_MTU];and cast the first byte.
You're right. I'm fixing it. Gatt API is quite confusing.
Quoted 8 lines
(just noticed that Proximity monitor code has the same bug...)
thermometer/thermometer.c static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len, · line 157
Quoted 5 lines
thermometer/thermometer.c +5
-0+ DBG("Protocol error"); + return; + } + + DBG("TEMPERATURE TYPE: %s", temptype2str(value));
Quoted 7 lines
Can you avoid using all-caps on the
DBG()message above?thermometer/thermometer.c static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len, · line 159
Quoted 2 lines
thermometer/thermometer.c +2
-0+ if (!t->has_interval) + t->has_interval = TRUE;Why the
if()check? You could just do "t->has_interval= TRUE;" always.
Ok.
I'm going to send a new set of patches fixing this issues.
Regards.