Routine infrastructure
This commit is contained in:
parent
979b906f4f
commit
17b3f0a89f
11 changed files with 527 additions and 30 deletions
195
core/ble.c
195
core/ble.c
|
|
@ -9,7 +9,8 @@
|
|||
#include <zephyr/sys/util_macro.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include "ble.h"
|
||||
#include "core/ble.h"
|
||||
#include "core/routine.h"
|
||||
|
||||
/**
|
||||
* @brief Begin BLE advertising with the default parameters
|
||||
|
|
@ -35,7 +36,7 @@ static struct bt_conn_cb connection_callbacks = {
|
|||
|
||||
/** Advertising data **/
|
||||
/** Our name to advertise */
|
||||
#define BLE_NAME_DEFAULT ("FM25 Kit 1")
|
||||
#define BLE_NAME_DEFAULT ("FM25 Kit x")
|
||||
|
||||
/** Advertising/Scanning parameters */
|
||||
static struct bt_le_adv_param advertise_params = {
|
||||
|
|
@ -107,6 +108,11 @@ static struct bt_uuid_16 characteristic_description_uuid = {
|
|||
.val = BT_UUID_GATT_CUD_VAL,
|
||||
};
|
||||
|
||||
static struct bt_uuid_16 characteristic_format_uuid = {
|
||||
.uuid = { .type = BT_UUID_TYPE_16 },
|
||||
.val = BT_UUID_GATT_CPF_VAL,
|
||||
};
|
||||
|
||||
static struct bt_uuid_128 service_uuid = {
|
||||
.uuid = { .type = BT_UUID_TYPE_128 },
|
||||
.val = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
|
||||
|
|
@ -122,7 +128,25 @@ static struct bt_uuid_128 telemetry_characteristic_uuid = {
|
|||
.val = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
|
||||
};
|
||||
|
||||
static struct bt_uuid_128 routine_list_characteristic_uuid = {
|
||||
.uuid = { .type = BT_UUID_TYPE_128 },
|
||||
.val = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
|
||||
};
|
||||
|
||||
static struct bt_uuid_128 current_routine_characteristic_uuid = {
|
||||
.uuid = { .type = BT_UUID_TYPE_128 },
|
||||
.val = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
|
||||
};
|
||||
|
||||
/*** Characteristic Data ***/
|
||||
static struct bt_gatt_cpf string_format = {
|
||||
.format = 0x19, /* UTF8 string */
|
||||
.exponent = 0,
|
||||
.unit = 0,
|
||||
.name_space = 0x01, /* Bluetooth SIG */
|
||||
.description = 0,
|
||||
};
|
||||
|
||||
typedef struct ble_attribute_userdata_struct {
|
||||
/** Buffer allocated for this attribute's data */
|
||||
void *buffer;
|
||||
|
|
@ -155,7 +179,7 @@ char input_characteristic_description[] = "Input Data";
|
|||
|
||||
/**** Telemetry Characteristic ****/
|
||||
struct bt_gatt_chrc telemetry_characteristic = {
|
||||
.uuid = (void *)&telemetry_characteristic_uuid,
|
||||
.uuid = (struct bt_uuid *)&telemetry_characteristic_uuid,
|
||||
.properties = BT_GATT_CHRC_READ,
|
||||
};
|
||||
/** Buffer for the contents of the Telemetry characteristic */
|
||||
|
|
@ -171,6 +195,45 @@ ble_attribute_userdata_t telemetry_characteristic_userdata = {
|
|||
char telemetry_characteristic_description[] = "Telemetry Data";
|
||||
|
||||
|
||||
/**** Routine List Characteristic ****/
|
||||
extern const routine_listing_t *routine_list;
|
||||
struct bt_gatt_chrc routine_list_characteristic = {
|
||||
.uuid = (struct bt_uuid *)&routine_list_characteristic_uuid,
|
||||
.properties = BT_GATT_CHRC_READ,
|
||||
};
|
||||
char routine_list_characteristic_buffer[512];
|
||||
ble_attribute_userdata_t routine_list_characterist_userdata = {
|
||||
.buffer = routine_list_characteristic_buffer,
|
||||
.buffer_size = sizeof(routine_list_characteristic_buffer),
|
||||
.value_size = 0,
|
||||
};
|
||||
char routine_list_characteristic_description[] = "Routine List";
|
||||
|
||||
|
||||
|
||||
/**** Current Routine Characteristic ****/
|
||||
struct bt_gatt_chrc current_routine_characteristic = {
|
||||
.uuid = (struct bt_uuid *)¤t_routine_characteristic_uuid,
|
||||
.properties = BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
|
||||
};
|
||||
static ssize_t _read_current_routine(
|
||||
struct bt_conn *connection,
|
||||
const struct bt_gatt_attr *attribute,
|
||||
void *buffer,
|
||||
uint16_t buffer_len,
|
||||
uint16_t offset
|
||||
);
|
||||
static ssize_t _write_current_routine(
|
||||
struct bt_conn *connection,
|
||||
const struct bt_gatt_attr *attribute,
|
||||
const void *buffer,
|
||||
uint16_t buffer_len,
|
||||
uint16_t offset,
|
||||
uint8_t flags
|
||||
);
|
||||
char current_routine_characteristic_description[] = "Current Routine";
|
||||
|
||||
|
||||
/*** Service Layout ***/
|
||||
static struct bt_gatt_attr primary_service_attributes[] = {
|
||||
/* Service declaration */
|
||||
|
|
@ -200,6 +263,12 @@ static struct bt_gatt_attr primary_service_attributes[] = {
|
|||
.user_data = (void *)input_characteristic_description,
|
||||
.perm = BT_GATT_PERM_READ,
|
||||
},
|
||||
{
|
||||
.uuid = (struct bt_uuid *)&characteristic_format_uuid,
|
||||
.read = bt_gatt_attr_read_cpf,
|
||||
.user_data = (void *)&string_format,
|
||||
.perm = BT_GATT_PERM_READ,
|
||||
},
|
||||
/** Telemetry Data Characteristic **/
|
||||
{
|
||||
.uuid = (struct bt_uuid *)&characteristic_declaration_uuid,
|
||||
|
|
@ -218,7 +287,57 @@ static struct bt_gatt_attr primary_service_attributes[] = {
|
|||
.read = bt_gatt_attr_read_cud,
|
||||
.user_data = (void *)telemetry_characteristic_description,
|
||||
.perm = BT_GATT_PERM_READ,
|
||||
}
|
||||
},
|
||||
{
|
||||
.uuid = (struct bt_uuid *)&characteristic_format_uuid,
|
||||
.read = bt_gatt_attr_read_cpf,
|
||||
.user_data = (void *)&string_format,
|
||||
.perm = BT_GATT_PERM_READ,
|
||||
},
|
||||
/** Routine List Characteristic **/
|
||||
{
|
||||
.uuid = (struct bt_uuid *)&characteristic_declaration_uuid,
|
||||
.read = bt_gatt_attr_read_chrc,
|
||||
.user_data = (void *)&routine_list_characteristic,
|
||||
.perm = BT_GATT_PERM_READ,
|
||||
},
|
||||
{
|
||||
.uuid = (struct bt_uuid *)&routine_list_characteristic_uuid,
|
||||
.read = _generic_attribute_read,
|
||||
.user_data = (void *)&routine_list_characterist_userdata,
|
||||
.perm = BT_GATT_PERM_READ,
|
||||
},
|
||||
{
|
||||
.uuid = (struct bt_uuid *)&characteristic_description_uuid,
|
||||
.read = bt_gatt_attr_read_cud,
|
||||
.user_data = (void *)routine_list_characteristic_description,
|
||||
.perm = BT_GATT_PERM_READ,
|
||||
},
|
||||
{
|
||||
.uuid = (struct bt_uuid *)&characteristic_format_uuid,
|
||||
.read = bt_gatt_attr_read_cpf,
|
||||
.user_data = (void *)&string_format,
|
||||
.perm = BT_GATT_PERM_READ,
|
||||
},
|
||||
/** Current Routine Characteristic */
|
||||
{
|
||||
.uuid = (struct bt_uuid *)&characteristic_declaration_uuid,
|
||||
.read = bt_gatt_attr_read_chrc,
|
||||
.user_data = (void *)¤t_routine_characteristic,
|
||||
.perm = BT_GATT_PERM_READ,
|
||||
},
|
||||
{
|
||||
.uuid = (struct bt_uuid *)¤t_routine_characteristic_uuid,
|
||||
.read = _read_current_routine,
|
||||
.write = _write_current_routine,
|
||||
.perm = BT_GATT_PERM_READ | BT_GATT_PERM_WRITE
|
||||
},
|
||||
{
|
||||
.uuid = (struct bt_uuid *)&characteristic_description_uuid,
|
||||
.read = bt_gatt_attr_read_cud,
|
||||
.user_data = (void *)current_routine_characteristic_description,
|
||||
.perm = BT_GATT_PERM_READ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct bt_gatt_service primary_service = {
|
||||
|
|
@ -231,6 +350,8 @@ static struct bt_gatt_service primary_service = {
|
|||
typedef struct ble_state_struct {
|
||||
/** Current callback for a complete input write */
|
||||
void (*oninput_callback)(const void *buffer, uint16_t buffer_len);
|
||||
#define BLE_FLAG_DISCONNECTED (0x01)
|
||||
uint32_t flags;
|
||||
/** Lock for data in the BLE state */
|
||||
struct k_mutex lock;
|
||||
} ble_state_t;
|
||||
|
|
@ -257,6 +378,8 @@ ble_init()
|
|||
/* Initialize the service data */
|
||||
k_mutex_init(&input_characteristic_userdata.lock);
|
||||
k_mutex_init(&telemetry_characteristic_userdata.lock);
|
||||
routine_get_listing(routine_list_characteristic_buffer, sizeof(routine_list_characteristic_buffer));
|
||||
routine_list_characterist_userdata.value_size = strlen(routine_list_characteristic_buffer);
|
||||
|
||||
ret = bt_gatt_service_register(&primary_service);
|
||||
if (ret) {
|
||||
|
|
@ -268,6 +391,17 @@ ble_init()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ble_tick()
|
||||
{
|
||||
k_mutex_lock(&ble.lock, K_FOREVER);
|
||||
if (ble.flags & BLE_FLAG_DISCONNECTED) {
|
||||
_start_advertising();
|
||||
ble.flags &= ~BLE_FLAG_DISCONNECTED;
|
||||
}
|
||||
k_mutex_unlock(&ble.lock);
|
||||
}
|
||||
|
||||
void
|
||||
ble_register_oninput_callback(void (*callback)(const void *buffer, uint16_t buffer_len))
|
||||
{
|
||||
|
|
@ -276,6 +410,14 @@ ble_register_oninput_callback(void (*callback)(const void *buffer, uint16_t buff
|
|||
k_mutex_unlock(&ble.lock);
|
||||
}
|
||||
|
||||
void
|
||||
ble_clear_oninput_callback()
|
||||
{
|
||||
k_mutex_lock(&ble.lock, K_FOREVER);
|
||||
ble.oninput_callback = NULL;
|
||||
k_mutex_unlock(&ble.lock);
|
||||
}
|
||||
|
||||
void
|
||||
ble_set_telemetry_data(const void *buffer, uint16_t buffer_len)
|
||||
{
|
||||
|
|
@ -314,7 +456,9 @@ static void
|
|||
_disconnected_callback(struct bt_conn *connection, uint8_t reason)
|
||||
{
|
||||
/* Resume advertising so we can be found again */
|
||||
_start_advertising();
|
||||
k_mutex_lock(&ble.lock, K_FOREVER);
|
||||
ble.flags |= BLE_FLAG_DISCONNECTED;
|
||||
k_mutex_unlock(&ble.lock);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
|
|
@ -346,7 +490,7 @@ _generic_attribute_read(
|
|||
return read_len;
|
||||
}
|
||||
|
||||
static int _generic_attribute_write(
|
||||
static ssize_t _generic_attribute_write(
|
||||
struct bt_conn *connection,
|
||||
const struct bt_gatt_attr *attribute,
|
||||
const void *buffer,
|
||||
|
|
@ -381,3 +525,42 @@ static int _generic_attribute_write(
|
|||
|
||||
return write_len;
|
||||
}
|
||||
|
||||
static ssize_t _read_current_routine(
|
||||
struct bt_conn *connection,
|
||||
const struct bt_gatt_attr *attribute,
|
||||
void *buffer,
|
||||
uint16_t buffer_len,
|
||||
uint16_t offset
|
||||
) {
|
||||
if ((offset != 0) || (buffer_len < sizeof(int8_t))) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
((int8_t *)buffer)[0] = routine_get_current();
|
||||
|
||||
return (sizeof(int8_t));
|
||||
}
|
||||
|
||||
static ssize_t _write_current_routine(
|
||||
struct bt_conn *connection,
|
||||
const struct bt_gatt_attr *attribute,
|
||||
const void *buffer,
|
||||
uint16_t buffer_len,
|
||||
uint16_t offset,
|
||||
uint8_t flags
|
||||
) {
|
||||
uint8_t index;
|
||||
|
||||
if ((offset != 0) || (buffer_len < sizeof(uint8_t))) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
index = ((uint8_t *)buffer)[0];
|
||||
|
||||
if (routine_select(index)) {
|
||||
return (0);
|
||||
} else {
|
||||
return (sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue