Skip to content

Commit

Permalink
GATTS API improvements
Browse files Browse the repository at this point in the history
 * Added ability to register custom descriptors in the service
   definition. Set is_desc to true for these.
 * Added ability to specify binary UUID when registering services.
   Set is_uuid_bin and initialize uuid_bin.
 * Added `mgos_bt_gatts_read_{1,2,4}()` - a handler for read-only
   attributes that responds with 1, 2 or 4 bytes from the handler arg value.
 * Added `mgos_bt_gatts_unregister_service()` to unregister a previously registered service.
 * Library now automatically handles long reads - if user sends more
   data than MTU allows, library buffers it and automatically responds
   to subsequent ling reads of the same characteristic.
 * Added mgos_bt_uuid_eq() to compare UUIDs.
  • Loading branch information
rojer committed Jul 10, 2021
1 parent 8aff5d2 commit cd6043c
Show file tree
Hide file tree
Showing 8 changed files with 520 additions and 296 deletions.
8 changes: 3 additions & 5 deletions include/esp32/esp32_bt.h
Expand Up @@ -36,13 +36,11 @@ extern "C" {
#define MGOS_BT_ADDR_LEN 6

const char *esp32_bt_addr_to_str(const esp_bd_addr_t addr, char *out);
bool esp32_bt_addr_from_str(const struct mg_str addr_str, esp_bd_addr_t addr);
int esp32_bt_addr_cmp(const esp_bd_addr_t a, const esp_bd_addr_t b);
bool esp32_bt_addr_is_null(const esp_bd_addr_t addr);

const char *esp32_bt_uuid_to_str(const esp_bt_uuid_t *uuid, char *out);
bool esp32_bt_uuid_from_str(const struct mg_str uuid_str, esp_bt_uuid_t *uuid);
int esp32_bt_uuid_cmp(const esp_bt_uuid_t *a, const esp_bt_uuid_t *b);

void mgos_bt_uuid_to_esp32(const struct mgos_bt_uuid *in, esp_bt_uuid_t *out);
void esp32_bt_uuid_to_mgos(const esp_bt_uuid_t *in, struct mgos_bt_uuid *out);

#ifdef __cplusplus
}
Expand Down
2 changes: 2 additions & 0 deletions include/mgos_bt.h
Expand Up @@ -69,6 +69,8 @@ bool mgos_bt_addr_is_null(const struct mgos_bt_addr *addr);

const char *mgos_bt_uuid_to_str(const struct mgos_bt_uuid *uuid, char *out);
bool mgos_bt_uuid_from_str(const struct mg_str str, struct mgos_bt_uuid *uuid);
bool mgos_bt_uuid_eq(const struct mgos_bt_uuid *a,
const struct mgos_bt_uuid *b);
int mgos_bt_uuid_cmp(const struct mgos_bt_uuid *a,
const struct mgos_bt_uuid *b);
void mgos_bt_uuid128_from_bytes(const uint8_t *bytes, bool reverse,
Expand Down
1 change: 1 addition & 0 deletions include/mgos_bt_gatt.h
Expand Up @@ -33,6 +33,7 @@ struct mgos_bt_gatt_conn {
#define MGOS_BT_GATT_PROP_WRITE (1 << 1)
#define MGOS_BT_GATT_PROP_NOTIFY (1 << 2)
#define MGOS_BT_GATT_PROP_INDICATE (1 << 3)
#define MGOS_BT_GATT_PROP_WRITE_NR (1 << 4)

#define MGOS_BT_GATT_PROP_RWNI(r, w, n, i) \
(((r) ? MGOS_BT_GATT_PROP_READ : 0) | ((w) ? MGOS_BT_GATT_PROP_WRITE : 0) | \
Expand Down
45 changes: 37 additions & 8 deletions include/mgos_bt_gatts.h
Expand Up @@ -40,20 +40,22 @@ enum mgos_bt_gatts_ev {
};

struct mgos_bt_gatts_conn {
const struct mgos_bt_gatt_conn gc;
struct mgos_bt_uuid svc_uuid;
struct mgos_bt_gatt_conn gc;
void *user_data; /* Opaque pointer for user. */
};

struct mgos_bt_gatts_read_arg {
struct mgos_bt_uuid uuid;
struct mgos_bt_uuid svc_uuid;
struct mgos_bt_uuid char_uuid;
uint16_t handle;
uint32_t trans_id;
uint16_t offset;
uint16_t len;
};

struct mgos_bt_gatts_write_arg {
struct mgos_bt_uuid uuid;
struct mgos_bt_uuid svc_uuid;
struct mgos_bt_uuid char_uuid;
uint16_t handle;
uint32_t trans_id;
uint16_t offset;
Expand All @@ -62,7 +64,8 @@ struct mgos_bt_gatts_write_arg {
};

struct mgos_bt_gatts_notify_mode_arg {
struct mgos_bt_uuid uuid;
struct mgos_bt_uuid svc_uuid;
struct mgos_bt_uuid char_uuid;
uint16_t handle;
enum mgos_bt_gatt_notify_mode mode;
};
Expand All @@ -80,16 +83,21 @@ typedef enum mgos_bt_gatt_status (*mgos_bt_gatts_ev_handler_t)(
void *handler_arg);

struct mgos_bt_gatts_char_def {
const char *uuid;
uint8_t prop;
union {
const char *uuid;
struct mgos_bt_uuid uuid_bin;
};
uint32_t prop : 5;
uint32_t is_desc : 1;
uint32_t is_uuid_bin : 1;
/* Separate event handler for the characteristic.
* If not provided, connection handler will be used. */
mgos_bt_gatts_ev_handler_t handler;
void *handler_arg;
};

/*
* Register a GATTS service.
* Registers and starts a GATTS service.
* `uuid` specifies the service UUID (in string form, "1234" for 16 bit UUIDs,
* "12345678-90ab-cdef-0123-456789abcdef" for 128-bit).
* `sec_level` specifies the minimum required security level of the connection.
Expand All @@ -105,6 +113,11 @@ bool mgos_bt_gatts_register_service(const char *uuid,
mgos_bt_gatts_ev_handler_t handler,
void *handler_arg);

/*
* Stops and unregisters a previously registered service.
*/
bool mgos_bt_gatts_unregister_service(const char *uuid);

/* Note: sending mtu - 1 bytes will usually trigger "long reads" by the client:
* the client will ask for more data (with offset). */
void mgos_bt_gatts_send_resp_data(struct mgos_bt_gatts_conn *gsc,
Expand All @@ -115,8 +128,24 @@ void mgos_bt_gatts_notify(struct mgos_bt_gatts_conn *gsc,
enum mgos_bt_gatt_notify_mode mode, uint16_t handle,
struct mg_str data);

void mgos_bt_gatts_notify_uuid(struct mgos_bt_gatts_conn *gsc,
const struct mgos_bt_uuid *char_uuid,
enum mgos_bt_gatt_notify_mode mode,
struct mg_str data);

bool mgos_bt_gatts_disconnect(struct mgos_bt_gatts_conn *gsc);

/* Handlers that respond to reads with 1/2/4 bytes from the arg's value. */
enum mgos_bt_gatt_status mgos_bt_gatts_read_1(struct mgos_bt_gatts_conn *c,
enum mgos_bt_gatts_ev ev,
void *ev_arg, void *handler_arg);
enum mgos_bt_gatt_status mgos_bt_gatts_read_2(struct mgos_bt_gatts_conn *c,
enum mgos_bt_gatts_ev ev,
void *ev_arg, void *handler_arg);
enum mgos_bt_gatt_status mgos_bt_gatts_read_4(struct mgos_bt_gatts_conn *c,
enum mgos_bt_gatts_ev ev,
void *ev_arg, void *handler_arg);

#ifdef __cplusplus
}
#endif
18 changes: 6 additions & 12 deletions src/esp32/esp32_bt.c
Expand Up @@ -39,19 +39,11 @@ const char *esp32_bt_addr_to_str(const esp_bd_addr_t addr, char *out) {
return mgos_bt_addr_to_str((const struct mgos_bt_addr *) &addr[0], 0, out);
}

bool esp32_bt_addr_from_str(const struct mg_str addr_str, esp_bd_addr_t addr) {
return mgos_bt_addr_from_str(addr_str, (struct mgos_bt_addr *) &addr[0]);
}

int esp32_bt_addr_cmp(const esp_bd_addr_t a, const esp_bd_addr_t b) {
return mgos_bt_addr_cmp((const struct mgos_bt_addr *) &a[0],
(const struct mgos_bt_addr *) &b[0]);
}

bool esp32_bt_addr_is_null(const esp_bd_addr_t addr) {
return mgos_bt_addr_is_null((const struct mgos_bt_addr *) &addr[0]);
}

const char *bt_uuid128_to_str(const uint8_t *u, char *out) {
sprintf(out,
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
Expand All @@ -65,12 +57,14 @@ const char *esp32_bt_uuid_to_str(const esp_bt_uuid_t *uuid, char *out) {
return mgos_bt_uuid_to_str((struct mgos_bt_uuid *) uuid, out);
}

bool esp32_bt_uuid_from_str(const struct mg_str uuid_str, esp_bt_uuid_t *uuid) {
return mgos_bt_uuid_from_str(uuid_str, (struct mgos_bt_uuid *) uuid);
void mgos_bt_uuid_to_esp32(const struct mgos_bt_uuid *in, esp_bt_uuid_t *out) {
out->len = in->len;
memcpy(out->uuid.uuid128, in->uuid.uuid128, 16);
}

int esp32_bt_uuid_cmp(const esp_bt_uuid_t *a, const esp_bt_uuid_t *b) {
return mgos_bt_uuid_cmp((struct mgos_bt_uuid *) a, (struct mgos_bt_uuid *) b);
void esp32_bt_uuid_to_mgos(const esp_bt_uuid_t *in, struct mgos_bt_uuid *out) {
out->len = in->len;
memcpy(out->uuid.uuid128, in->uuid.uuid128, 16);
}

enum cs_log_level ll_from_status(esp_bt_status_t status) {
Expand Down

0 comments on commit cd6043c

Please sign in to comment.