diff --git a/src/btstack_defines.h b/src/btstack_defines.h index 89e651f96..f7ca220f5 100644 --- a/src/btstack_defines.h +++ b/src/btstack_defines.h @@ -2938,4 +2938,27 @@ typedef uint8_t sm_key_t[16]; */ #define MESH_SUBEVENT_FOUNDATION_BEACON_STATUS 0x36 +/** + * @format 121122222 + * @param subevent_code + * @param dest + * @param foundation_status + * @param page + * @param cid company identifier assigned by the Bluetooth SIG + * @param pid vendor-assigned product identifier + * @param vid vendor-assigned product version identifier + * @param crpl the minimum number of replay protection list entries in a device + * @param features device features + */ +#define MESH_SUBEVENT_FOUNDATION_COMPOSITION_DATA_STATUS 0x37 + +/** + * @format 1211 + * @param subevent_code + * @param dest + * @param foundation_status + * @param default_ttl + */ +#define MESH_SUBEVENT_FOUNDATION_DEFAULT_TTL_STATUS 0x38 + #endif diff --git a/src/btstack_event.h b/src/btstack_event.h index 518af3189..413e7a3ab 100644 --- a/src/btstack_event.h +++ b/src/btstack_event.h @@ -8036,6 +8036,107 @@ static inline uint8_t mesh_subevent_foundation_beacon_status_get_secure_network_ return event[6]; } +/** + * @brief Get field dest from event MESH_SUBEVENT_FOUNDATION_COMPOSITION_DATA_STATUS + * @param event packet + * @return dest + * @note: btstack_type 2 + */ +static inline uint16_t mesh_subevent_foundation_composition_data_status_get_dest(const uint8_t * event){ + return little_endian_read_16(event, 3); +} +/** + * @brief Get field foundation_status from event MESH_SUBEVENT_FOUNDATION_COMPOSITION_DATA_STATUS + * @param event packet + * @return foundation_status + * @note: btstack_type 1 + */ +static inline uint8_t mesh_subevent_foundation_composition_data_status_get_foundation_status(const uint8_t * event){ + return event[5]; +} +/** + * @brief Get field page from event MESH_SUBEVENT_FOUNDATION_COMPOSITION_DATA_STATUS + * @param event packet + * @return page + * @note: btstack_type 1 + */ +static inline uint8_t mesh_subevent_foundation_composition_data_status_get_page(const uint8_t * event){ + return event[6]; +} +/** + * @brief Get field cid from event MESH_SUBEVENT_FOUNDATION_COMPOSITION_DATA_STATUS + * @param event packet + * @return cid + * @note: btstack_type 2 + */ +static inline uint16_t mesh_subevent_foundation_composition_data_status_get_cid(const uint8_t * event){ + return little_endian_read_16(event, 7); +} +/** + * @brief Get field pid from event MESH_SUBEVENT_FOUNDATION_COMPOSITION_DATA_STATUS + * @param event packet + * @return pid + * @note: btstack_type 2 + */ +static inline uint16_t mesh_subevent_foundation_composition_data_status_get_pid(const uint8_t * event){ + return little_endian_read_16(event, 9); +} +/** + * @brief Get field vid from event MESH_SUBEVENT_FOUNDATION_COMPOSITION_DATA_STATUS + * @param event packet + * @return vid + * @note: btstack_type 2 + */ +static inline uint16_t mesh_subevent_foundation_composition_data_status_get_vid(const uint8_t * event){ + return little_endian_read_16(event, 11); +} +/** + * @brief Get field crpl from event MESH_SUBEVENT_FOUNDATION_COMPOSITION_DATA_STATUS + * @param event packet + * @return crpl + * @note: btstack_type 2 + */ +static inline uint16_t mesh_subevent_foundation_composition_data_status_get_crpl(const uint8_t * event){ + return little_endian_read_16(event, 13); +} +/** + * @brief Get field features from event MESH_SUBEVENT_FOUNDATION_COMPOSITION_DATA_STATUS + * @param event packet + * @return features + * @note: btstack_type 2 + */ +static inline uint16_t mesh_subevent_foundation_composition_data_status_get_features(const uint8_t * event){ + return little_endian_read_16(event, 15); +} + +/** + * @brief Get field dest from event MESH_SUBEVENT_FOUNDATION_BEACON_STATUS + * @param event packet + * @return dest + * @note: btstack_type 2 + */ +static inline uint16_t mesh_subevent_foundation_beacon_status_get_dest(const uint8_t * event){ + return little_endian_read_16(event, 3); +} +/** + * @brief Get field foundation_status from event MESH_SUBEVENT_FOUNDATION_BEACON_STATUS + * @param event packet + * @return foundation_status + * @note: btstack_type 1 + */ +static inline uint8_t mesh_subevent_foundation_beacon_status_get_foundation_status(const uint8_t * event){ + return event[5]; +} +/** + * @brief Get field default_ttl from event MESH_SUBEVENT_FOUNDATION_BEACON_STATUS + * @param event packet + * @return default_ttl + * @note: btstack_type 1 + */ +static inline uint8_t mesh_subevent_foundation_beacon_status_get_default_ttl(const uint8_t * event){ + return event[6]; +} + /* API_END */ diff --git a/src/mesh/mesh_configuration_client.c b/src/mesh/mesh_configuration_client.c index c95bdec89..2d99fb482 100644 --- a/src/mesh/mesh_configuration_client.c +++ b/src/mesh/mesh_configuration_client.c @@ -86,7 +86,6 @@ static const mesh_access_message_t mesh_configuration_client_composition_data_ge }; -#if 0 static const mesh_access_message_t mesh_configuration_client_default_ttl_get = { MESH_FOUNDATION_OPERATION_DEFAULT_TTL_GET, "" }; @@ -94,6 +93,7 @@ static const mesh_access_message_t mesh_configuration_client_default_ttl_set = { MESH_FOUNDATION_OPERATION_DEFAULT_TTL_SET, "1" }; +#if 0 static const mesh_access_message_t mesh_configuration_client_gatt_proxy_get = { MESH_FOUNDATION_OPERATION_GATT_PROXY_GET, "" }; @@ -156,13 +156,37 @@ uint8_t mesh_configuration_client_send_composition_data_get(mesh_model_t * mesh_ return ERROR_CODE_SUCCESS; } +uint8_t mesh_configuration_client_send_default_ttl_get(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index){ + uint8_t status = mesh_access_validate_envelop_params(mesh_model, dest, netkey_index, appkey_index); + if (status != ERROR_CODE_SUCCESS) return status; + + mesh_network_pdu_t * network_pdu = mesh_access_setup_unsegmented_message(&mesh_configuration_client_default_ttl_get); + if (!network_pdu) return BTSTACK_MEMORY_ALLOC_FAILED; + + mesh_configuration_client_send_acknowledged(mesh_access_get_element_address(mesh_model), dest, netkey_index, appkey_index, (mesh_pdu_t *) network_pdu, MESH_FOUNDATION_OPERATION_DEFAULT_TTL_GET); + return ERROR_CODE_SUCCESS; +} + +uint8_t mesh_configuration_client_send_default_ttl_set(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint8_t ttl){ + uint8_t status = mesh_access_validate_envelop_params(mesh_model, dest, netkey_index, appkey_index); + if (status != ERROR_CODE_SUCCESS) return status; + + if (ttl == 0x01 || ttl >= 0x80) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; + + mesh_network_pdu_t * network_pdu = mesh_access_setup_unsegmented_message(&mesh_configuration_client_default_ttl_set, ttl); + if (!network_pdu) return BTSTACK_MEMORY_ALLOC_FAILED; + + mesh_configuration_client_send_acknowledged(mesh_access_get_element_address(mesh_model), dest, netkey_index, appkey_index, (mesh_pdu_t *) network_pdu, MESH_FOUNDATION_OPERATION_DEFAULT_TTL_SET); + return ERROR_CODE_SUCCESS; +} + // Model Operations -static void mesh_configuration_client_status_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){ +static void mesh_configuration_client_beacon_status_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){ mesh_access_parser_state_t parser; mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu); uint8_t beacon_status = mesh_access_parser_get_u8(&parser); - + uint8_t event[7] = {HCI_EVENT_MESH_META, 5, MESH_SUBEVENT_FOUNDATION_BEACON_STATUS}; int pos = 3; // dest @@ -175,8 +199,64 @@ static void mesh_configuration_client_status_handler(mesh_model_t *mesh_model, m mesh_access_message_processed(pdu); } +static void mesh_configuration_client_composition_data_status_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){ + mesh_access_parser_state_t parser; + mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu); + + uint8_t page = mesh_access_parser_get_u8(&parser); + uint16_t cid = mesh_access_parser_get_u16(&parser); + uint16_t pid = mesh_access_parser_get_u16(&parser); + uint16_t vid = mesh_access_parser_get_u16(&parser); + uint16_t crpl = mesh_access_parser_get_u16(&parser); + uint16_t features = mesh_access_parser_get_u16(&parser); + + // TODO: list of element descriptions, see Table 4.4 + + uint8_t event[17] = {HCI_EVENT_MESH_META, 5, MESH_SUBEVENT_FOUNDATION_COMPOSITION_DATA_STATUS}; + int pos = 3; + // dest + little_endian_store_16(event, pos, mesh_pdu_src(pdu)); + pos += 2; + event[pos++] = ERROR_CODE_SUCCESS; + event[pos++] = page; + + little_endian_store_16(event, pos, cid); + pos += 2; + little_endian_store_16(event, pos, pid); + pos += 2; + little_endian_store_16(event, pos, vid); + pos += 2; + little_endian_store_16(event, pos, crpl); + pos += 2; + little_endian_store_16(event, pos, features); + pos += 2; + + (*mesh_model->model_packet_handler)(HCI_EVENT_PACKET, 0, event, pos); + mesh_access_message_processed(pdu); +} + +static void mesh_configuration_client_default_ttl_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){ + mesh_access_parser_state_t parser; + mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu); + + uint8_t default_ttl = mesh_access_parser_get_u8(&parser); + + uint8_t event[7] = {HCI_EVENT_MESH_META, 5, MESH_SUBEVENT_FOUNDATION_DEFAULT_TTL_STATUS}; + int pos = 3; + // dest + little_endian_store_16(event, pos, mesh_pdu_src(pdu)); + pos += 2; + event[pos++] = ERROR_CODE_SUCCESS; + event[pos++] = default_ttl; + + (*mesh_model->model_packet_handler)(HCI_EVENT_PACKET, 0, event, pos); + mesh_access_message_processed(pdu); +} + const static mesh_operation_t mesh_configuration_client_model_operations[] = { - { MESH_FOUNDATION_OPERATION_BEACON_STATUS, 0, mesh_configuration_client_status_handler }, + { MESH_FOUNDATION_OPERATION_BEACON_STATUS, 1, mesh_configuration_client_beacon_status_handler }, + { MESH_FOUNDATION_OPERATION_COMPOSITION_DATA_STATUS, 1, mesh_configuration_client_composition_data_status_handler }, + { MESH_FOUNDATION_OPERATION_DEFAULT_TTL_STATUS, 1, mesh_configuration_client_default_ttl_handler }, { 0, 0, NULL } }; diff --git a/src/mesh/mesh_configuration_client.h b/src/mesh/mesh_configuration_client.h index c95152818..ae7d80a47 100644 --- a/src/mesh/mesh_configuration_client.h +++ b/src/mesh/mesh_configuration_client.h @@ -86,6 +86,27 @@ uint8_t mesh_configuration_client_send_beacon_set(mesh_model_t * mesh_model, uin */ uint8_t mesh_configuration_client_send_composition_data_get(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint8_t page); +/** + * @brief Get the current Default TTL state of a node + * @param mesh_model + * @param dest + * @param netkey_index + * @param appkey_index + * @return status ERROR_CODE_SUCCESS if successful, otherwise BTSTACK_MEMORY_ALLOC_FAILED or ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE + */ +uint8_t mesh_configuration_client_send_default_ttl_get(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index); + +/** + * @brief Set Default TTL state of a node + * @param mesh_model + * @param dest + * @param netkey_index + * @param appkey_index + * @param ttl allowed values: 0x00, 0x02–0x7F + * @return status ERROR_CODE_SUCCESS if successful, otherwise BTSTACK_MEMORY_ALLOC_FAILED or ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE + */ +uint8_t mesh_configuration_client_send_default_ttl_set(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint8_t ttl); + #ifdef __cplusplus } /* end of extern "C" */ #endif