-
Notifications
You must be signed in to change notification settings - Fork 808
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/aeg-1990' into 'master'
feat(ble_services): Support Weight Scale Service Closes AEG-1990 See merge request ae_group/esp-iot-solution!1177
- Loading branch information
Showing
33 changed files
with
614 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Weight Scale Service | ||
|
||
menuconfig BLE_WSS | ||
bool "GATT Weight Scale Service" | ||
|
||
if BLE_WSS | ||
|
||
endif # BLE_WSS |
137 changes: 137 additions & 0 deletions
137
components/bluetooth/ble_services/wss/include/esp_wss.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <stdbool.h> | ||
#include <stdint.h> | ||
|
||
#include "esp_err.h" | ||
#include "esp_event_base.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" | ||
{ | ||
#endif | ||
|
||
/* 16 Bit Weight Scale Service UUID */ | ||
#define BLE_WSS_UUID16 0x181D | ||
|
||
/* 16 Bit Weight Scale Characteristics UUID */ | ||
#define BLE_WSS_CHR_UUID16_WEIGHT_FEATURE 0x2A9E | ||
#define BLE_WSS_CHR_UUID16_WEIGHT_MEASUREMENT 0x2A9D | ||
|
||
/* Weight Scale Feature masks */ | ||
#define BLE_WSS_TIMESTAMP_MASK (1 << 0) | ||
#define BLE_WSS_MULTI_USER_MASK (1 << 1) | ||
#define BLE_WSS_BMI_MASK (1 << 2) | ||
|
||
/* Weight resolution offset*/ | ||
#define BLE_WSS_WEIGHT_RESOLUTION_OFSET (3) | ||
|
||
#define BLE_WSS_WEIGHT_RESOLUTION_NONE (0x0) | ||
#define BLE_WSS_WEIGHT_RESOLUTION_0P5_KG (0x1) | ||
#define BLE_WSS_WEIGHT_RESOLUTION_0P2_KG (0x2) | ||
#define BLE_WSS_WEIGHT_RESOLUTION_0P1_KG (0x3) | ||
#define BLE_WSS_WEIGHT_RESOLUTION_0P05_KG (0x4) | ||
#define BLE_WSS_WEIGHT_RESOLUTION_0P02_KG (0x5) | ||
#define BLE_WSS_WEIGHT_RESOLUTION_0P01_KG (0x6) | ||
#define BLE_WSS_WEIGHT_RESOLUTION_0P005_KG (0x7) | ||
|
||
/* Height resolution offset*/ | ||
#define BLE_WSS_HEIGHT_RESOLUTION_OFSET (6) | ||
|
||
#define BLE_WSS_HEIGHT_RESOLUTION_NONE (0x0) | ||
#define BLE_WSS_HEIGHT_RESOLUTION_0P01_M (0x1) | ||
#define BLE_WSS_HEIGHT_RESOLUTION_0P005_M (0x2) | ||
#define BLE_WSS_HEIGHT_RESOLUTION_0P001_M (0x3) | ||
|
||
/* Weight Scale Measurement Flag */ | ||
#define BLE_WSS_MEASUREMENT_UINTS_FLAG (1 << 0) | ||
#define BLE_WSS_TIME_STAMP_FLAG (1 << 1) | ||
#define BLE_WSS_USER_ID_FLAG (1 << 2) | ||
#define BLE_WSS_BMI_FLAG (1 << 3) | ||
|
||
/** | ||
* @brief Weight Scale Feature | ||
*/ | ||
typedef struct { | ||
uint32_t timestamp: 1; /*!< 0: Don't Support, 1: Support */ | ||
uint32_t user_id: 1; /*!< 0: Don't Support, 1: Support */ | ||
uint32_t bmi: 1; /*!< 0: Don't Support, 1: Support */ | ||
uint32_t weight: 1; /*!< 0: Don't Support, 1: Support */ | ||
uint32_t w_resolution: 3; /*!< If weight support, this filed should present */ | ||
uint32_t height: 1; /*!< 0: Don't Support, 1: Support */ | ||
uint32_t h_resolution: 2; /*!< If height support, this filed should present */ | ||
} esp_ble_wss_feature_t; /*!< The structure of the weight scale feature field */ | ||
|
||
/** | ||
* @brief weight Measurement | ||
*/ | ||
typedef struct { | ||
struct { | ||
uint32_t measurement_unit: 1; /*!< 0: Kg & meter, 1: reference to weight and height resolution */ | ||
uint32_t time_present: 1; /*!< 0: Don't contain time information, 1: time stamp present */ | ||
uint32_t user_present: 1; /*!< 0: Don't contain user index, 1: contain user index */ | ||
uint32_t bmi_height_present: 1; /*!< 0: Don't contain BMI and height, 1: contain BMI and height */ | ||
} flag; /*!< Flag */ | ||
|
||
uint16_t weight; /*!< weight */ | ||
|
||
struct { | ||
uint16_t year; /*!< Year as defined by the Gregorian calendar, Valid range 1582 to 9999 */ | ||
uint8_t month; /*!< Month of the year as defined by the Gregorian calendar, Valid range 1 (January) to 12 (December) */ | ||
uint8_t day; /*!< Day of the month as defined by the Gregorian calendar, Valid range 1 to 31 */ | ||
uint8_t hours; /*!< Number of hours past midnight, Valid range 0 to 23 */ | ||
uint8_t minutes; /*!< Number of minutes since the start of the hour. Valid range 0 to 59 */ | ||
uint8_t seconds; /*!< Number of seconds since the start of the minute. Valid range 0 to 59 */ | ||
} __attribute__((packed)) timestamp; /*!< The date and time */ | ||
|
||
uint8_t user_id; /*!< User index */ | ||
uint8_t bmi; /*!< BMI */ | ||
uint16_t height; /*!< Height */ | ||
uint8_t weight_resolution; /*!< Weight resolution */ | ||
uint8_t height_resolution; /*!< Height resolution */ | ||
} __attribute__((packed)) esp_ble_wss_measurement_t; | ||
|
||
/** | ||
* @brief Read the weight measurement characteristic value. | ||
* | ||
* @param[in] out_val The pointer to store the weight measurement value. | ||
* | ||
* @return | ||
* - ESP_OK on successful | ||
* - ESP_ERR_INVALID_ARG on wrong parameter | ||
*/ | ||
esp_err_t esp_ble_wss_get_measurement(esp_ble_wss_measurement_t *out_val); | ||
|
||
/** | ||
* @brief Set the weight measurement characteristic value. | ||
* | ||
* @param[in] in_val The pointer to store the weight measurement. | ||
* | ||
* @param[in] need_send send the weight measurement information to remote client. | ||
* | ||
* @return | ||
* - ESP_OK on successful | ||
* - ESP_ERR_INVALID_ARG on wrong initialization | ||
* - ESP_FAIL on error | ||
*/ | ||
esp_err_t esp_ble_wss_set_measurement(esp_ble_wss_measurement_t *in_val, bool need_send); | ||
|
||
/** | ||
* @brief Initialization Weight Scale Service | ||
* | ||
* @return | ||
* - ESP_OK on successful | ||
* - ESP_ERR_INVALID_ARG on wrong initialization | ||
* - ESP_FAIL on error | ||
*/ | ||
esp_err_t esp_ble_wss_init(void); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/** @file | ||
* @brief Weight Scale Service(WSS) | ||
*/ | ||
|
||
#include <string.h> | ||
|
||
#include "esp_ble_conn_mgr.h" | ||
#include "esp_wss.h" | ||
|
||
#define BLE_WSS_MAX_VAL_LEN 20 | ||
|
||
typedef struct { | ||
uint8_t len; | ||
uint8_t buf[BLE_WSS_MAX_VAL_LEN]; | ||
} indicate_buf_t; | ||
|
||
/* Weight Scale Feature value */ | ||
static esp_ble_wss_feature_t s_wss_feature = { | ||
.timestamp = 1, | ||
.user_id = 1, | ||
.bmi = 1, | ||
.weight = 1, | ||
.w_resolution = 1, | ||
.height = 1, | ||
.h_resolution = 1 | ||
}; | ||
|
||
static esp_ble_wss_measurement_t s_wss_measurement; | ||
|
||
static void build_wss_ind_buf(esp_ble_wss_measurement_t *in_val, indicate_buf_t *out_buf) | ||
{ | ||
uint32_t offset = 0; | ||
|
||
/* Add Flag */ | ||
memcpy(out_buf->buf + offset, &(in_val->flag), sizeof(uint32_t)); | ||
offset += sizeof(uint32_t); | ||
|
||
/* Add weight */ | ||
memcpy(out_buf->buf + offset, &(in_val->weight), sizeof(uint16_t)); | ||
offset += sizeof(uint32_t); | ||
|
||
if (in_val->flag.time_present == 1) { | ||
memcpy(out_buf->buf + offset, &(in_val->timestamp), sizeof(in_val->timestamp)); | ||
offset += sizeof(in_val->timestamp); // timestamp length | ||
} | ||
|
||
if (in_val->flag.user_present == 1) { | ||
memcpy(out_buf->buf + offset, &(in_val->user_id), sizeof(uint8_t)); | ||
offset += sizeof(uint8_t); // user id length | ||
} | ||
|
||
if (in_val->flag.bmi_height_present == 1) { | ||
memcpy(out_buf->buf + offset, &(in_val->bmi), sizeof(uint8_t)); | ||
offset += sizeof(uint8_t); // bmi length | ||
|
||
memcpy(out_buf->buf + offset, &(in_val->height), sizeof(uint16_t)); | ||
offset += sizeof(uint16_t); // height length | ||
} | ||
|
||
out_buf->len = offset; | ||
|
||
return; | ||
} | ||
|
||
esp_err_t esp_ble_wss_get_measurement(esp_ble_wss_measurement_t *out_val) | ||
{ | ||
if (!out_val) { | ||
return ESP_ERR_INVALID_ARG; | ||
} | ||
|
||
memcpy(out_val, &s_wss_measurement, sizeof(esp_ble_wss_measurement_t)); | ||
|
||
return ESP_OK; | ||
} | ||
|
||
esp_err_t esp_ble_wss_set_measurement(esp_ble_wss_measurement_t *in_val, bool need_send) | ||
{ | ||
if (in_val == NULL) { | ||
return ESP_ERR_INVALID_ARG; | ||
} | ||
|
||
memcpy(&s_wss_measurement, in_val, sizeof(esp_ble_wss_measurement_t)); | ||
|
||
/* Set Weight Scale Feature Bit Masks */ | ||
memset(&s_wss_feature, 0x0, sizeof(esp_ble_wss_feature_t)); | ||
s_wss_feature.weight = 1; | ||
|
||
if (in_val->flag.measurement_unit == 0x1) { | ||
s_wss_feature.w_resolution = in_val->weight_resolution; | ||
s_wss_feature.h_resolution = in_val->height_resolution; | ||
} | ||
|
||
if (in_val->flag.time_present == 0x1) { | ||
s_wss_feature.timestamp = 1; | ||
} | ||
|
||
if (in_val->flag.user_present == 0x1) { | ||
s_wss_feature.user_id = 1; | ||
} | ||
|
||
if (in_val->flag.bmi_height_present == 0x1) { | ||
s_wss_feature.bmi = 1; | ||
s_wss_feature.height = 1; | ||
} | ||
|
||
indicate_buf_t out_buf; | ||
|
||
/* Build Body Composition Measurement value */ | ||
build_wss_ind_buf(in_val, &out_buf); | ||
|
||
esp_ble_conn_data_t conn_data = { | ||
.type = BLE_CONN_UUID_TYPE_16, | ||
.uuid = { | ||
.uuid16 = BLE_WSS_CHR_UUID16_WEIGHT_MEASUREMENT, | ||
}, | ||
.data = out_buf.buf, | ||
.data_len = out_buf.len, | ||
}; | ||
|
||
return esp_ble_conn_write(&conn_data); | ||
} | ||
|
||
static esp_err_t wss_feature_cb(const uint8_t *inbuf, uint16_t inlen, | ||
uint8_t **outbuf, uint16_t *outlen, void *priv_data) | ||
{ | ||
uint8_t len = sizeof(s_wss_feature); | ||
|
||
if (inbuf || !outbuf || !outlen) { | ||
return ESP_ERR_INVALID_ARG; | ||
} | ||
|
||
*outbuf = calloc(1, len); | ||
if (!(*outbuf)) { | ||
return ESP_ERR_NO_MEM; | ||
} | ||
|
||
memcpy(*outbuf, &s_wss_feature, len); | ||
*outlen = len; | ||
|
||
return ESP_OK; | ||
} | ||
|
||
static const esp_ble_conn_character_t nu_lookup_table[] = { | ||
{ | ||
"weight feature", BLE_CONN_UUID_TYPE_16, BLE_CONN_GATT_CHR_READ | ||
, { BLE_WSS_CHR_UUID16_WEIGHT_FEATURE }, wss_feature_cb | ||
}, | ||
{ | ||
"weight measurement", BLE_CONN_UUID_TYPE_16, BLE_CONN_GATT_CHR_INDICATE | ||
, { BLE_WSS_CHR_UUID16_WEIGHT_MEASUREMENT }, NULL | ||
}, | ||
}; | ||
|
||
static const esp_ble_conn_svc_t svc = { | ||
.type = BLE_CONN_UUID_TYPE_16, | ||
.uuid = { | ||
.uuid16 = BLE_WSS_UUID16, | ||
}, | ||
.nu_lookup_count = sizeof(nu_lookup_table) / sizeof(nu_lookup_table[0]), | ||
.nu_lookup = (esp_ble_conn_character_t *)nu_lookup_table | ||
}; | ||
|
||
esp_err_t esp_ble_wss_init(void) | ||
{ | ||
return esp_ble_conn_add_svc(&svc); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.