diff --git a/src/btstack_defines.h b/src/btstack_defines.h index 3412c72a7..dcdf4fc67 100644 --- a/src/btstack_defines.h +++ b/src/btstack_defines.h @@ -2992,4 +2992,14 @@ typedef uint8_t sm_key_t[16]; * @param model_identifier */ #define MESH_SUBEVENT_CONFIGURATION_MODEL_PUBLICATION 0x41 + +/** + * @format 12124 + * @param subevent_code + * @param dest + * @param foundation_status + * @param address + * @param model_identifier + */ +#define MESH_SUBEVENT_CONFIGURATION_MODEL_SUBSCRIPTION 0x42 #endif diff --git a/src/btstack_event.h b/src/btstack_event.h index dbc4f9f10..e439ed2c5 100644 --- a/src/btstack_event.h +++ b/src/btstack_event.h @@ -8230,6 +8230,43 @@ static inline uint32_t mesh_subevent_configuration_model_publication_get_model_i return little_endian_read_32(event, 15); } +/** + * @brief Get field dest from event MESH_SUBEVENT_CONFIGURATION_MODEL_SUBSCRIPTION + * @param event packet + * @return dest + * @note: btstack_type 2 + */ +static inline uint16_t mesh_subevent_configuration_model_subscription_get_dest(const uint8_t * event){ + return little_endian_read_16(event, 3); +} +/** + * @brief Get field foundation_status from event MESH_SUBEVENT_CONFIGURATION_MODEL_SUBSCRIPTION + * @param event packet + * @return foundation_status + * @note: btstack_type 1 + */ +static inline uint8_t mesh_subevent_configuration_model_subscription_get_foundation_status(const uint8_t * event){ + return event[5]; +} +/** + * @brief Get field address from event MESH_SUBEVENT_CONFIGURATION_MODEL_SUBSCRIPTION + * @param event packet + * @return address + * @note: btstack_type 2 + */ +static inline uint16_t mesh_subevent_configuration_model_subscription_get_address(const uint8_t * event){ + return little_endian_read_16(event, 6); +} +/** + * @brief Get field model_identifier from event MESH_SUBEVENT_CONFIGURATION_MODEL_SUBSCRIPTION + * @param event packet + * @return model_identifier + * @note: btstack_type 4 + */ +static inline uint32_t mesh_subevent_configuration_model_subscription_get_model_identifier(const uint8_t * event){ + return little_endian_read_32(event, 8); +} + /* API_END */ diff --git a/src/mesh/mesh_configuration_client.c b/src/mesh/mesh_configuration_client.c index 99fed1a8a..3dd31d1ea 100644 --- a/src/mesh/mesh_configuration_client.c +++ b/src/mesh/mesh_configuration_client.c @@ -187,16 +187,40 @@ static const mesh_access_message_t mesh_configuration_client_relay_set = { MESH_FOUNDATION_OPERATION_RELAY_SET, "11" }; -static const mesh_access_message_t mesh_configuration_client_publication_get = { +static const mesh_access_message_t mesh_configuration_client_model_publication_get = { MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_GET, "2m" }; -static const mesh_access_message_t mesh_configuration_client_publication_set = { +static const mesh_access_message_t mesh_configuration_client_model_publication_set = { MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_SET, "222111m" }; -static const mesh_access_message_t mesh_configuration_client_publication_virtual_address_set = { +static const mesh_access_message_t mesh_configuration_client_model_publication_virtual_address_set = { MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_VIRTUAL_ADDRESS_SET, "2P2111m" }; + +static const mesh_access_message_t mesh_configuration_client_model_subscription_add = { + MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_ADD, "22m" +}; +static const mesh_access_message_t mesh_configuration_client_model_subscription_virtual_address_add = { + MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_ADD, "2Pm" +}; +static const mesh_access_message_t mesh_configuration_client_model_subscription_delete = { + MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_DELETE, "22m" +}; +static const mesh_access_message_t mesh_configuration_client_model_subscription_virtual_address_delete = { + MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_DELETE, "2Pm" +}; +static const mesh_access_message_t mesh_configuration_client_model_subscription_overwrite = { + MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_OVERWRITE, "22m" +}; +static const mesh_access_message_t mesh_configuration_client_model_subscription_virtual_address_overwrite = { + MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_OVERWRITE, "2Pm" +}; +static const mesh_access_message_t mesh_configuration_client_model_subscription_delete_all = { + MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_DELETE_ALL, "22m" +}; + + static void mesh_configuration_client_send_acknowledged(uint16_t src, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, mesh_pdu_t *pdu, uint32_t ack_opcode){ uint8_t ttl = mesh_foundation_default_ttl_get(); mesh_upper_transport_setup_access_pdu_header(pdu, netkey_index, appkey_index, ttl, src, dest, 0); @@ -326,25 +350,32 @@ uint8_t mesh_configuration_client_send_model_publication_get(mesh_model_t * mesh 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_publication_get, dest, model_id); + mesh_network_pdu_t * network_pdu = mesh_access_setup_unsegmented_message(&mesh_configuration_client_model_publication_get, dest, model_id); 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); + 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_MODEL_PUBLICATION_GET); + return ERROR_CODE_SUCCESS; +} + +static uint8_t mesh_validate_publication_model_config_parameters(mesh_publication_model_config_t * publication_config, bool use_unicast_address){ + if (publication_config->appkey_index > 0xFFF) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; + if (publication_config->credential_flag > 1) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; + if (publication_config->publish_retransmit_count > 0x07) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; + if (publication_config->publish_retransmit_interval_steps > 0x1F) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; + if (use_unicast_address && mesh_network_address_virtual(publication_config->publish_address_unicast)) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; return ERROR_CODE_SUCCESS; } uint8_t mesh_configuration_client_send_model_publication_set(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint32_t model_id, mesh_publication_model_config_t * publication_config){ uint8_t status = mesh_access_validate_envelop_params(mesh_model, dest, netkey_index, appkey_index); if (status != ERROR_CODE_SUCCESS) return status; - if (mesh_network_address_virtual(publication_config->publish_address_unicast)) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; - if (!mesh_network_address_unicast(dest)) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; - if (publication_config->appkey_index > 0xFFF) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; - if (publication_config->credential_flag > 1) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; - if (publication_config->publish_retransmit_count > 0x07) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; - if (publication_config->publish_retransmit_interval_steps > 0x1F) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; - - mesh_network_pdu_t * network_pdu = mesh_access_setup_unsegmented_message(&mesh_configuration_client_publication_set, + if (!mesh_network_address_unicast(dest) || + mesh_validate_publication_model_config_parameters(publication_config, true) != ERROR_CODE_SUCCESS){ + return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; + } + + mesh_network_pdu_t * network_pdu = mesh_access_setup_unsegmented_message(&mesh_configuration_client_model_publication_set, dest, publication_config->publish_address_unicast, (publication_config->credential_flag << 12) | publication_config->appkey_index, @@ -354,7 +385,7 @@ uint8_t mesh_configuration_client_send_model_publication_set(mesh_model_t * mesh model_id); 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_RELAY_SET); + 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_MODEL_PUBLICATION_SET); return ERROR_CODE_SUCCESS; } @@ -363,13 +394,12 @@ uint8_t mesh_configuration_client_send_model_publication_virtual_address_set(mes uint8_t status = mesh_access_validate_envelop_params(mesh_model, dest, netkey_index, appkey_index); if (status != ERROR_CODE_SUCCESS) return status; - if (!mesh_network_address_unicast(dest)) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; - if (publication_config->appkey_index > 0xFFF) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; - if (publication_config->credential_flag > 1) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; - if (publication_config->publish_retransmit_count > 0x07) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; - if (publication_config->publish_retransmit_interval_steps > 0x1F) return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; + if (!mesh_network_address_unicast(dest) || + mesh_validate_publication_model_config_parameters(publication_config, false) != ERROR_CODE_SUCCESS){ + return ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE; + } - mesh_transport_pdu_t * network_pdu = mesh_access_setup_segmented_message(&mesh_configuration_client_publication_virtual_address_set, + mesh_transport_pdu_t * transport_pdu = mesh_access_setup_segmented_message(&mesh_configuration_client_model_publication_virtual_address_set, dest, publication_config->publish_address_virtual, (publication_config->credential_flag << 12) | publication_config->appkey_index, @@ -377,14 +407,89 @@ uint8_t mesh_configuration_client_send_model_publication_virtual_address_set(mes publication_config->publish_period, (publication_config->publish_retransmit_interval_steps << 3) | publication_config->publish_retransmit_count, model_id); - if (!network_pdu) return BTSTACK_MEMORY_ALLOC_FAILED; + if (!transport_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_RELAY_SET); + mesh_configuration_client_send_acknowledged(mesh_access_get_element_address(mesh_model), dest, netkey_index, appkey_index, (mesh_pdu_t *) transport_pdu, MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_VIRTUAL_ADDRESS_SET); return ERROR_CODE_SUCCESS; } +uint8_t mesh_configuration_client_send_model_subscription_add(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint16_t address, uint32_t model_id){ + 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_model_subscription_add, dest, address, model_id); + 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_MODEL_SUBSCRIPTION_ADD); + return ERROR_CODE_SUCCESS; +} + +uint8_t mesh_configuration_client_send_model_subscription_virtual_address_add(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint8_t * address, uint32_t model_id){ + uint8_t status = mesh_access_validate_envelop_params(mesh_model, dest, netkey_index, appkey_index); + if (status != ERROR_CODE_SUCCESS) return status; + + mesh_transport_pdu_t * transport_pdu = mesh_access_setup_segmented_message(&mesh_configuration_client_model_subscription_virtual_address_add, dest, address, model_id); + if (!transport_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 *) transport_pdu, MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_ADD); + return ERROR_CODE_SUCCESS; +} + +uint8_t mesh_configuration_client_send_model_subscription_delete(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint16_t address, uint32_t model_id){ + 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_model_subscription_delete, dest, address, model_id); + 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_MODEL_SUBSCRIPTION_DELETE); + return ERROR_CODE_SUCCESS; +} + +uint8_t mesh_configuration_client_send_model_subscription_virtual_address_delete(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint8_t * address, uint32_t model_id){ + uint8_t status = mesh_access_validate_envelop_params(mesh_model, dest, netkey_index, appkey_index); + if (status != ERROR_CODE_SUCCESS) return status; + + mesh_transport_pdu_t * transport_pdu = mesh_access_setup_segmented_message(&mesh_configuration_client_model_subscription_virtual_address_delete, dest, address, model_id); + if (!transport_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 *) transport_pdu, MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_DELETE); + return ERROR_CODE_SUCCESS; +} + +uint8_t mesh_configuration_client_send_model_subscription_overwrite(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint16_t address, uint32_t model_id){ + 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_model_subscription_overwrite, dest, address, model_id); + 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_MODEL_SUBSCRIPTION_OVERWRITE); + return ERROR_CODE_SUCCESS; +} + +uint8_t mesh_configuration_client_send_model_subscription_virtual_address_overwrite(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint8_t * address, uint32_t model_id){ + uint8_t status = mesh_access_validate_envelop_params(mesh_model, dest, netkey_index, appkey_index); + if (status != ERROR_CODE_SUCCESS) return status; + + mesh_transport_pdu_t * transport_pdu = mesh_access_setup_segmented_message(&mesh_configuration_client_model_subscription_virtual_address_overwrite, dest, address, model_id); + if (!transport_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 *) transport_pdu, MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_VIRTUAL_ADDRESS_OVERWRITE); + return ERROR_CODE_SUCCESS; +} + +uint8_t mesh_configuration_client_send_model_subscription_delete_all(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint16_t address, uint32_t model_id){ + 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_model_subscription_delete_all, dest, address, model_id); + 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_MODEL_SUBSCRIPTION_DELETE_ALL); + return ERROR_CODE_SUCCESS; +} // Model Operations static void mesh_configuration_client_composition_data_status_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){ // Composition Data has variable of element descriptions, with two lists of model lists @@ -539,14 +644,41 @@ static void mesh_configuration_client_model_publication_handler(mesh_model_t *me mesh_access_message_processed(pdu); } +static void mesh_configuration_client_model_subscription_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 status = mesh_access_parser_get_u8(&parser); + uint16_t address = mesh_access_parser_get_u16(&parser); + uint32_t model_identifier = mesh_access_parser_get_model_identifier(&parser); + + uint8_t event[12]; + int pos = 0; + event[pos++] = HCI_EVENT_MESH_META; + event[pos++] = sizeof(event) - 2; + event[pos++] = MESH_SUBEVENT_CONFIGURATION_MODEL_SUBSCRIPTION; + // dest + little_endian_store_16(event, pos, mesh_pdu_src(pdu)); + pos += 2; + event[pos++] = status; + + little_endian_store_16(event, pos, address); + pos += 2; + + little_endian_store_32(event, pos, model_identifier); + pos += 4; + + (*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, 1, mesh_configuration_client_beacon_status_handler }, - { MESH_FOUNDATION_OPERATION_COMPOSITION_DATA_STATUS, 10, mesh_configuration_client_composition_data_status_handler }, - { MESH_FOUNDATION_OPERATION_DEFAULT_TTL_STATUS, 1, mesh_configuration_client_default_ttl_handler }, - { MESH_FOUNDATION_OPERATION_GATT_PROXY_STATUS, 1, mesh_configuration_client_gatt_proxy_handler }, - { MESH_FOUNDATION_OPERATION_RELAY_STATUS, 2, mesh_configuration_client_relay_handler }, - { MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_STATUS, 12, mesh_configuration_client_model_publication_handler }, - + { MESH_FOUNDATION_OPERATION_BEACON_STATUS, 1, mesh_configuration_client_beacon_status_handler }, + { MESH_FOUNDATION_OPERATION_COMPOSITION_DATA_STATUS, 10, mesh_configuration_client_composition_data_status_handler }, + { MESH_FOUNDATION_OPERATION_DEFAULT_TTL_STATUS, 1, mesh_configuration_client_default_ttl_handler }, + { MESH_FOUNDATION_OPERATION_GATT_PROXY_STATUS, 1, mesh_configuration_client_gatt_proxy_handler }, + { MESH_FOUNDATION_OPERATION_RELAY_STATUS, 2, mesh_configuration_client_relay_handler }, + { MESH_FOUNDATION_OPERATION_MODEL_PUBLICATION_STATUS, 12, mesh_configuration_client_model_publication_handler }, + { MESH_FOUNDATION_OPERATION_MODEL_SUBSCRIPTION_STATUS, 7, mesh_configuration_client_model_subscription_handler }, { 0, 0, NULL } }; diff --git a/src/mesh/mesh_configuration_client.h b/src/mesh/mesh_configuration_client.h index b667aff3e..9a4b17b7d 100644 --- a/src/mesh/mesh_configuration_client.h +++ b/src/mesh/mesh_configuration_client.h @@ -343,6 +343,57 @@ uint8_t mesh_configuration_client_send_model_publication_set(mesh_model_t * mesh */ uint8_t mesh_configuration_client_send_model_publication_virtual_address_set(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint32_t model_id, mesh_publication_model_config_t * publication_config); +/** + * @brief Add an address to a Subscription List of a model + * @param mesh_model + * @param dest element_address + * @param netkey_index + * @param appkey_index + * @param address + * @param model_id + * @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_model_subscription_add(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint16_t address, uint32_t model_id); +uint8_t mesh_configuration_client_send_model_subscription_virtual_address_add(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint8_t * address, uint32_t model_id); + +/** + * @brief Delete an address from a Subscription List of a model + * @param mesh_model + * @param dest element_address + * @param netkey_index + * @param appkey_index + * @param address + * @param model_id + * @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_model_subscription_delete(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint16_t address, uint32_t model_id); +uint8_t mesh_configuration_client_send_model_subscription_virtual_address_delete(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint8_t * address, uint32_t model_id); + +/** + * @brief Discard the Subscription List and add an address to the cleared Subscription List of a model + * @param mesh_model + * @param dest element_address + * @param netkey_index + * @param appkey_index + * @param address + * @param model_id + * @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_model_subscription_overwrite(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint16_t address, uint32_t model_id); +uint8_t mesh_configuration_client_send_model_subscription_virtual_address_overwrite(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint8_t * address, uint32_t model_id); + +/** + * @brief Discard the Subscription List of a model + * @param mesh_model + * @param dest element_address + * @param netkey_index + * @param appkey_index + * @param address + * @param model_id + * @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_model_subscription_delete_all(mesh_model_t * mesh_model, uint16_t dest, uint16_t netkey_index, uint16_t appkey_index, uint16_t address, uint32_t model_id); + #ifdef __cplusplus } /* end of extern "C" */ #endif