*/
void _thread_onmesh_prefix_free(gpointer data);
+/**
+ * @brief Encode TXT entries as a null-terminated hex-string.
+ * @since_tizen 7.0
+ *
+ * @exception
+ * @pre
+ * @post
+ */
+int _thread_encode_txt_entries(const thread_dns_txt_entry_s *txt_entries,
+ uint8_t num_txt_entries, char *buffer, size_t buffer_size);
+
#ifdef __cplusplus
}
#endif
*/
typedef void *thread_network_h;
+/**
+ * @ingroup CAPI_NETWORK_THREAD_MODULE
+ * @brief Structure which holds single DNS TXT entry.
+ * @since_tizen 7.0
+ *
+ * @note The total length of the TXT entry, which is "key + '=' + value" or
+ * "key" for boolean key, must not exceed 255 bytes.
+ */
+typedef struct {
+ const char *key; /** The TXT record null-terminated key string */
+ const uint8_t *value; /** The TXT record value, or NULL for boolean key */
+ uint8_t value_len; /** The length of the TXT record value */
+} thread_dns_txt_entry_s;
/**
* @ingroup CAPI_NETWORK_THREAD_MODULE
* @pre thread API must be initialized with thread_initialize().
* @see thread_srp_client_start()
* @see thread_srp_client_set_host_address()
+ * @see thread_srp_client_register_service_full()
*/
int thread_srp_client_register_service(thread_instance_h instance,
const char *service_name, const char *service_type, uint64_t port);
/**
* @ingroup CAPI_NETWORK_THREAD_SRP_MODULE
+ * @brief Register Service to SRP server
+ * @since_tizen 7.0
+ *
+ * This is an extended version of thread_srp_client_register_service()
+ * which allows to set priority, weight and TXT entries.
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #THREAD_ERROR_NONE Successful
+ * @retval #THREAD_ERROR_NOT_INITIALIZED Not initialized
+ * @retval #THREAD_ERROR_OPERATION_FAILED Operation failed
+ * @retval #THREAD_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre thread API must be initialized with thread_initialize().
+ * @see thread_srp_client_start()
+ * @see thread_srp_client_set_host_address()
+ * @see thread_srp_client_register_service()
+ */
+int thread_srp_client_register_service_full(thread_instance_h instance,
+ const char *service_name, const char *service_type, uint16_t port, uint16_t priority,
+ uint16_t weight, const thread_dns_txt_entry_s *txt_entries, uint8_t num_txt_entries);
+
+/**
+ * @ingroup CAPI_NETWORK_THREAD_SRP_MODULE
* @brief Remove Service from SRP server
* @since_tizen 7.0
*
return ret;
}
+int thread_srp_client_register_service_full(thread_instance_h instance,
+ const char *service_name, const char *service_type, uint16_t port, uint16_t priority,
+ uint16_t weight, const thread_dns_txt_entry_s *txt_entries, uint8_t num_txt_entries)
+{
+ FUNC_ENTRY;
+ THREAD_CHECK_SUPPORTED_FEATURE(THREAD_FEATURE_COMMON);
+ THREAD_VALIDATE_INPUT_PARAMETER(service_name);
+ THREAD_VALIDATE_INPUT_PARAMETER(txt_entries);
+ THREAD_CHECK_INIT_STATUS();
+ THREAD_VALIDATE_INPUT_PARAMETER(instance);
+ int ret = THREAD_ERROR_NONE;
+
+ /* Register SRP service */
+ const char *msg = THREAD_SRP_CLIENT_REGISTER_SERVICE_CMD;
+
+ char buffer[THREAD_MAX_BUFFER_SIZE] = {0};
+ char txt[THREAD_MAX_BUFFER_SIZE] = "";
+
+ ret = _thread_encode_txt_entries(txt_entries, num_txt_entries, txt, sizeof(txt));
+ if (ret != THREAD_ERROR_NONE) {
+ THREAD_DBG("socket srp_client_register_service_full encode txt entries failed");
+ return ret;
+ }
+
+ int len = snprintf(buffer, sizeof(buffer), "%s %s %s %u %u %u %s", msg,
+ service_name, service_type, (int)port, (int)priority, (int)weight, txt);
+ /* Make sure that the socket command was not truncated. It might
+ * happen if the TXT record is too long. */
+ if (len > sizeof(buffer) - 1) {
+ THREAD_DBG("socket srp_client_register_service_full buffer overflow");
+ return THREAD_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = _thread_socket_client_execute(_thread_get_socket_fd(),
+ buffer, strlen(buffer));
+ if (ret != THREAD_ERROR_NONE && ret != THREAD_ERROR_ALREADY_DONE) {
+ THREAD_DBG("socket srp_client_register_service_full execute failed");
+ return ret;
+ }
+ THREAD_DBG("socket srp_client_register_service_full execute successful");
+
+ FUNC_EXIT;
+ return ret;
+}
+
int thread_srp_client_remove_service(thread_instance_h instance,
const char *service_name, const char *service_type)
{
FUNC_EXIT;
}
+
+int _thread_encode_txt_entries(const thread_dns_txt_entry_s *txt_entries,
+ uint8_t num_txt_entries, char *buffer, size_t buffer_size)
+{
+ FUNC_ENTRY;
+ int ret = THREAD_ERROR_NONE;
+
+ for (size_t i = 0; i < num_txt_entries; i++) {
+
+ /* calculate data length for DNS TXT entry as "key=value" */
+ size_t key_len = strlen(txt_entries[i].key);
+ size_t entry_len = key_len;
+ if (txt_entries[i].value != NULL)
+ entry_len += 1 + txt_entries[i].value_len;
+ if (entry_len > 255) {
+ THREAD_DBG("Invalid DNS TXT entry length: %zu > 255", entry_len);
+ return THREAD_ERROR_INVALID_PARAMETER;
+ }
+
+ /* check if buffer is big enough to hold hex-encoded
+ * entry record and string null-terminator */
+ if (buffer_size < 2 * (entry_len + 1) + 1) {
+ THREAD_DBG("Not enough space in buffer for hex-encoded TXT entries");
+ return THREAD_ERROR_OUT_OF_MEMORY;
+ }
+
+ sprintf(&buffer[0], "%.2x", (int)entry_len);
+ for (size_t n = 0; n < key_len; n++)
+ sprintf(&buffer[2 + 2 * n], "%.2x", txt_entries[i].key[n]);
+
+ buffer += 2 * (1 + key_len);
+ buffer_size -= 2 * (1 + key_len);
+
+ if (txt_entries[i].value != NULL) {
+
+ sprintf(&buffer[0], "%.2x", (int)'=');
+ for (size_t n = 0; n < txt_entries[i].value_len; n++)
+ sprintf(&buffer[2 + 2 * n], "%.2x", txt_entries[i].value[n]);
+
+ buffer += 2 * (1 + txt_entries[i].value_len);
+ buffer_size -= 2 * (1 + txt_entries[i].value_len);
+
+ }
+
+ }
+
+ FUNC_EXIT;
+ return ret;
+}