From eb0acd9c8b5cc911a0e5369dfbbe0abf275d7c25 Mon Sep 17 00:00:00 2001 From: Anjali Nijhara Date: Thu, 18 Aug 2022 10:49:47 +0530 Subject: [PATCH] Use Mutex insted of thread scope variables. Change-Id: Ia615d623e42ea0684b38d64bb9317628ff605706 --- packaging/capi-network-nsd.spec | 2 +- src/dns-sd/dns-sd-util.h | 13 ++ src/dns-sd/dns-sd.c | 302 ++++++++++++++++++++++++++++++++-------- src/ssdp/ssdp-util.h | 13 ++ src/ssdp/ssdp.c | 126 +++++++++++++++-- 5 files changed, 384 insertions(+), 72 deletions(-) diff --git a/packaging/capi-network-nsd.spec b/packaging/capi-network-nsd.spec index ac19fdb..bad8279 100644 --- a/packaging/capi-network-nsd.spec +++ b/packaging/capi-network-nsd.spec @@ -1,6 +1,6 @@ Name: capi-network-nsd Summary: A Network Service Discovery libraries in Native API -Version: 0.1.1 +Version: 0.1.2 Release: 2 Group: System/Network License: Apache-2.0 diff --git a/src/dns-sd/dns-sd-util.h b/src/dns-sd/dns-sd-util.h index f65d4dd..4ef9f77 100644 --- a/src/dns-sd/dns-sd-util.h +++ b/src/dns-sd/dns-sd-util.h @@ -46,6 +46,16 @@ #endif /* USE_DLOG */ +#define DNSSD_LOCK \ + do { \ + _dnssd_lock(); \ + } while(0) + +#define DNSSD_UNLOCK \ + do { \ + _dnssd_unlock(); \ + } while(0) + #define NETWORK_SERVICE_DISCOVERY_FEATURE "http://tizen.org/feature/network.service_discovery.dnssd" #define CHECK_FEATURE_SUPPORTED(feature_name)\ @@ -134,4 +144,7 @@ typedef struct _resolve_reply_data { char *service_name; } resolve_reply_data; +void _dnssd_lock(void); +void _dnssd_unlock(void); + #endif /* __TIZEN_NET_DNSSD_UTIL_H__ */ diff --git a/src/dns-sd/dns-sd.c b/src/dns-sd/dns-sd.c index 0d4a959..c455f1a 100644 --- a/src/dns-sd/dns-sd.c +++ b/src/dns-sd/dns-sd.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#define _GNU_SOURCE +#include #include #include #include @@ -42,6 +44,7 @@ do {\ if (__dnssd_is_init() == false) {\ DNSSD_LOGE("Not initialized");\ + DNSSD_UNLOCK;\ __DNSSD_LOG_FUNC_EXIT__;\ return DNSSD_ERROR_NOT_INITIALIZED;\ } \ @@ -51,15 +54,18 @@ do {\ if (__dnssd_check_permission() == false) {\ DNSSD_LOGE("Permission denied");\ + DNSSD_UNLOCK;\ __DNSSD_LOG_FUNC_EXIT__;\ return DNSSD_ERROR_PERMISSION_DENIED;\ } \ } while (0) -static __thread GSList *dnssd_handle_list = NULL; -static __thread GSList *resolve_handle_list = NULL; -static __thread bool g_is_init = false; -static __thread GDBusConnection *netconfig_bus = NULL; +static GSList *dnssd_handle_list = NULL; +static GSList *resolve_handle_list = NULL; +static bool g_is_init = false; +static GDBusConnection *netconfig_bus = NULL; + +static pthread_mutex_t dnssd_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; //LCOV_EXCL_START static const char *dnssd_error_to_string(DNSServiceErrorType dnssd_service_error) @@ -412,9 +418,11 @@ EXPORT_API int dnssd_initialize(void) int res = 0; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; if (__dnssd_is_init() == true) { DNSSD_LOGE("Already initialized"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_OPERATION; } @@ -422,12 +430,14 @@ EXPORT_API int dnssd_initialize(void) res = __connect_netconfig_gdbus(); if (res != DNSSD_ERROR_NONE) { DNSSD_LOGE("Failed to launch mdnsresponder"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return res; } __dnssd_set_initialized(true); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -437,6 +447,7 @@ EXPORT_API int dnssd_deinitialize(void) __DNSSD_LOG_FUNC_ENTER__; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; CHECK_INITIALIZED(); @@ -444,6 +455,7 @@ EXPORT_API int dnssd_deinitialize(void) __disconnect_netconfig_gdbus(); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -457,12 +469,14 @@ EXPORT_API int dnssd_create_local_service(const char *service_type, unsigned int handler; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; CHECK_INITIALIZED(); if (dnssd_service == NULL || service_type == NULL || __dnssd_get_struct_from_handle(*dnssd_service) != NULL) { DNSSD_LOGE("Invalid Parameter"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -470,6 +484,7 @@ EXPORT_API int dnssd_create_local_service(const char *service_type, local_handle = (dnssd_handle_s *)g_try_malloc0(REG_SIZE); if (local_handle == NULL) { DNSSD_LOGE("Failed to Allocate Memory"); //LCOV_EXCL_LINE + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE return DNSSD_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE } @@ -491,6 +506,7 @@ EXPORT_API int dnssd_create_local_service(const char *service_type, dnssd_handle_list = g_slist_prepend(dnssd_handle_list, local_handle); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -499,8 +515,6 @@ static int __get_valid_registered_handle(dnssd_service_h dnssd_service, dnssd_ha { dnssd_handle_s *local_handle; - CHECK_INITIALIZED(); - local_handle = __dnssd_get_struct_from_handle(dnssd_service); if (local_handle == NULL) { DNSSD_LOGD("Service Handler not found"); @@ -526,10 +540,15 @@ EXPORT_API int dnssd_destroy_local_service(dnssd_service_h dnssd_service) int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_registered_handle(dnssd_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } DNSSD_LOGD("Destroy handle: [%p]->[%u]", local_handle, dnssd_service); @@ -541,6 +560,7 @@ EXPORT_API int dnssd_destroy_local_service(dnssd_service_h dnssd_service) local_handle = NULL; DNSSD_LOGD("g_slist length [%d]", g_slist_length(dnssd_handle_list)); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -554,13 +574,19 @@ EXPORT_API int dnssd_service_set_name(dnssd_service_h local_service, int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_registered_handle(local_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } if (service_name == NULL) { DNSSD_LOGD("Service name is NULL"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -571,6 +597,7 @@ EXPORT_API int dnssd_service_set_name(dnssd_service_h local_service, DNSSD_LOGD("Successfully set service name %s", service_name); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -583,13 +610,19 @@ EXPORT_API int dnssd_service_set_port(dnssd_service_h local_service, int port) int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_registered_handle(local_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } if (port < 0 || port > 65535) { DNSSD_LOGD("Invalid port range"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -599,6 +632,7 @@ EXPORT_API int dnssd_service_set_port(dnssd_service_h local_service, int port) DNSSD_LOGD("Successfully set port %d", port); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -612,13 +646,19 @@ EXPORT_API int dnssd_service_set_interface(dnssd_service_h local_service, const int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_registered_handle(local_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } if ((if_index = if_nametoindex(interface)) == 0) { DNSSD_LOGE("Invalid interface name"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -629,6 +669,7 @@ EXPORT_API int dnssd_service_set_interface(dnssd_service_h local_service, const DNSSD_LOGD("Successfully set interface %s with index %u", interface, if_index); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -645,19 +686,26 @@ EXPORT_API int dnssd_service_add_txt_record(dnssd_service_h local_service, int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_registered_handle(local_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } if (key == NULL) { DNSSD_LOGE("key is NULL"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } if (length > 255) { DNSSD_LOGE("Invalid length"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -678,12 +726,14 @@ EXPORT_API int dnssd_service_add_txt_record(dnssd_service_h local_service, if (ret != kDNSServiceErr_NoError) { DNSSD_LOGE("Failed to add value to key, error[%s]", //LCOV_EXCL_LINE dnssd_error_to_string(ret)); //LCOV_EXCL_LINE + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_OPERATION_FAILED; } else { DNSSD_LOGD("Succeeded to add value to key"); } + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -700,13 +750,19 @@ EXPORT_API int dnssd_service_remove_txt_record(dnssd_service_h local_service, int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_registered_handle(local_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } if (key == NULL) { DNSSD_LOGE("key is NULL"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -718,6 +774,7 @@ EXPORT_API int dnssd_service_remove_txt_record(dnssd_service_h local_service, if (ret != kDNSServiceErr_NoError) { DNSSD_LOGE("Failed to remove value from key, error[%s]", dnssd_error_to_string(ret)); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_OPERATION_FAILED; } else { @@ -733,6 +790,7 @@ EXPORT_API int dnssd_service_remove_txt_record(dnssd_service_h local_service, reg->is_txt_ref = 0; } + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -747,10 +805,15 @@ EXPORT_API int dnssd_service_set_record(dnssd_service_h local_service, unsigned int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_registered_handle(local_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } reg = GET_REG_DATA_P(local_handle); DNSSD_LOGD("Record Type %d Record len %d", type, length); @@ -768,12 +831,14 @@ EXPORT_API int dnssd_service_set_record(dnssd_service_h local_service, unsigned if (ret != kDNSServiceErr_NoError) { DNSSD_LOGE("Failed to Add Record for DNS Service, error[%s]", //LCOV_EXCL_LINE dnssd_error_to_string(ret)); //LCOV_EXCL_LINE + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE return DNSSD_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE } DNSSD_LOGD("Successfully added record for DNS Service"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -791,15 +856,21 @@ EXPORT_API int dnssd_service_unset_record(dnssd_service_h local_service, int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_registered_handle(local_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } reg = GET_REG_DATA_P(local_handle); if (reg->record_ref == NULL) { DNSSD_LOGE("Invalid DNS SD Client"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -815,6 +886,7 @@ EXPORT_API int dnssd_service_unset_record(dnssd_service_h local_service, if (ret != kDNSServiceErr_NoError) { DNSSD_LOGE("Failed to Remove Record for DNS Service, error[%s]", //LCOV_EXCL_LINE dnssd_error_to_string(ret)); //LCOV_EXCL_LINE + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE return DNSSD_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE } @@ -823,6 +895,7 @@ EXPORT_API int dnssd_service_unset_record(dnssd_service_h local_service, DNSSD_LOGD("Successfully removed record for DNS Service"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -831,9 +904,11 @@ static void __dnssd_register_reply_cb(DNSServiceRef sd_ref, unsigned int flags, DNSServiceErrorType error_code, const char *service_name, const char *service_type, const char *domain, void *user_data) { + DNSSD_LOCK; dnssd_handle_s *dnssd_handle; dnssd_register_data_s *reg = NULL; GSList *list; + dnssd_registered_cb callback; void *data; @@ -867,6 +942,56 @@ static void __dnssd_register_reply_cb(DNSServiceRef sd_ref, unsigned int flags, break; } } + DNSSD_UNLOCK; +} + +static int __get_valid_handle(dnssd_service_h dnssd_service, dnssd_handle_s **handle) +{ + dnssd_handle_s *local_handle; + + local_handle = __dnssd_get_struct_from_handle(dnssd_service); + if (local_handle == NULL) { + DNSSD_LOGD("Service Handler not found"); + __DNSSD_LOG_FUNC_EXIT__; + return DNSSD_ERROR_SERVICE_NOT_FOUND; + } + + *handle = local_handle; + + return DNSSD_ERROR_NONE; +} + +static int __dnssd_service_get_all_txt_record(dnssd_service_h dnssd_service, + unsigned short *length, void **value) +{ + __DNSSD_LOG_FUNC_ENTER__; + TXTRecordRef *txt_record; + dnssd_handle_s *local_handle = NULL; + int res; + + res = __get_valid_handle(dnssd_service, &local_handle); + if (res != DNSSD_ERROR_NONE) + return res; + + if (local_handle->op_type == DNSSD_TYPE_FOUND) { + + dnssd_found_data_s *found = NULL; + found = GET_FOUND_DATA_P(local_handle); + + *value = g_strndup(found->txt_record, found->txt_len); + *length = found->txt_len; + } else { + + dnssd_register_data_s *reg = NULL; + reg = GET_REG_DATA_P(local_handle); + txt_record = &(reg->txt_ref); + + *length = TXTRecordGetLength(txt_record); + *value = g_strndup(TXTRecordGetBytesPtr(txt_record), *length); + } + + __DNSSD_LOG_FUNC_EXIT__; + return DNSSD_ERROR_NONE; } EXPORT_API int dnssd_register_local_service(dnssd_service_h local_service, @@ -881,15 +1006,21 @@ EXPORT_API int dnssd_register_local_service(dnssd_service_h local_service, int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; CHECK_PERMISSION(); + CHECK_INITIALIZED(); + res = __get_valid_registered_handle(local_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } if (register_cb == NULL) { DNSSD_LOGE("No callback provided"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -905,7 +1036,7 @@ EXPORT_API int dnssd_register_local_service(dnssd_service_h local_service, DNSSD_LOGD("Domain/Interface/Flags : %s/%d/0x%x", local_handle->domain, reg->if_index, local_handle->flags); - dnssd_service_get_all_txt_record(local_service, &length, &data); + __dnssd_service_get_all_txt_record(local_service, &length, &data); ret = DNSServiceRegister(&(local_handle->sd_ref), local_handle->flags, reg->if_index, reg->service_name, @@ -917,6 +1048,7 @@ EXPORT_API int dnssd_register_local_service(dnssd_service_h local_service, if (ret != kDNSServiceErr_NoError) { DNSSD_LOGE("Failed to register for dns service, error[%s]", //LCOV_EXCL_LINE dnssd_error_to_string(ret)); //LCOV_EXCL_LINE + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE return DNSSD_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE } @@ -926,6 +1058,7 @@ EXPORT_API int dnssd_register_local_service(dnssd_service_h local_service, __dnssd_handle_add_event_handler(&(local_handle->watch_id), local_handle); DNSSD_LOGD("Succeeded to register for dns service"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -939,13 +1072,19 @@ EXPORT_API int dnssd_deregister_local_service(dnssd_service_h local_service) int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_registered_handle(local_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } if (local_handle->sd_ref == NULL) { DNSSD_LOGE("Invalid DNS SD Client"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -969,6 +1108,7 @@ EXPORT_API int dnssd_deregister_local_service(dnssd_service_h local_service) DNSServiceRefDeallocate(local_handle->sd_ref); local_handle->sd_ref = NULL; + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -976,6 +1116,7 @@ EXPORT_API int dnssd_deregister_local_service(dnssd_service_h local_service) //LCOV_EXCL_START static gboolean __remove_service_getaddrinfo_socket(gpointer user_data) { + DNSSD_LOCK; DNSSD_LOGD("Remove DNSServiceGetAddrInfo socket"); dnssd_handle_s *local_handle = user_data; if (local_handle->watch_id > 0) @@ -983,6 +1124,7 @@ static gboolean __remove_service_getaddrinfo_socket(gpointer user_data) DNSServiceRefDeallocate(local_handle->sd_ref); local_handle->watch_id = 0; local_handle->sd_ref = NULL; + DNSSD_UNLOCK; return FALSE; } @@ -992,6 +1134,7 @@ static void __dnssd_getaddrinfo_reply_cb(DNSServiceRef sd_ref, const struct sockaddr *address, unsigned int ttl, void *user_data) { + DNSSD_LOCK; dnssd_handle_s *dnssd_handle = NULL; dnssd_handle_s *local_handle = NULL; dnssd_browse_data_s *browse = NULL; @@ -1001,6 +1144,7 @@ static void __dnssd_getaddrinfo_reply_cb(DNSServiceRef sd_ref, if (user_data == NULL) { DNSSD_LOGD("Invalid found handle"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return; } @@ -1017,6 +1161,7 @@ static void __dnssd_getaddrinfo_reply_cb(DNSServiceRef sd_ref, dnssd_handle = __dnssd_get_struct_from_handle(found->browse_handler); if (dnssd_handle == NULL) { DNSSD_LOGD("Invalid browse handle"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return; } @@ -1045,6 +1190,7 @@ static void __dnssd_getaddrinfo_reply_cb(DNSServiceRef sd_ref, if (flags & kDNSServiceFlagsMoreComing) { DNSSD_LOGD("More results are queued, No need to send callback to " "application at this stage"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return; } @@ -1061,6 +1207,7 @@ static void __dnssd_getaddrinfo_reply_cb(DNSServiceRef sd_ref, } g_idle_add_full(G_PRIORITY_HIGH, __remove_service_getaddrinfo_socket, local_handle, NULL); + DNSSD_UNLOCK; } static int __dnssd_getaddrinfo(dnssd_handle_s *dnssd_handle, unsigned int flags, @@ -1149,6 +1296,7 @@ static int __dnssd_getaddrinfo(dnssd_handle_s *dnssd_handle, unsigned int flags, static gboolean __remove_service_resolve_socket(gpointer user_data) { + DNSSD_LOCK; DNSSD_LOGD("Remove DNSServiceResolve socket"); resolve_reply_data *resolve_data = user_data; if (resolve_data->watch_id > 0) @@ -1156,6 +1304,7 @@ static gboolean __remove_service_resolve_socket(gpointer user_data) DNSServiceRefDeallocate(resolve_data->sd_ref); resolve_data->watch_id = 0; resolve_data->sd_ref = NULL; + DNSSD_UNLOCK; return FALSE; } @@ -1165,11 +1314,13 @@ static void __dnssd_resolve_reply_cb(DNSServiceRef sd_ref, unsigned int flags, unsigned short port, unsigned short txt_len, const unsigned char *txt_record, void *user_data) { + DNSSD_LOCK; resolve_reply_data *resolve_data = user_data; DNSSD_LOGD("Received Resolve Reply"); if (flags & kDNSServiceFlagsMoreComing) { DNSSD_LOGD("More results are queued"); + DNSSD_UNLOCK; return; } @@ -1180,6 +1331,7 @@ static void __dnssd_resolve_reply_cb(DNSServiceRef sd_ref, unsigned int flags, g_idle_add_full(G_PRIORITY_HIGH, __remove_service_resolve_socket, resolve_data, NULL); + DNSSD_UNLOCK; } static int __dnssd_resolve_dns_service(dnssd_handle_s *dnssd_handle, @@ -1259,6 +1411,7 @@ static void __dnssd_browse_reply_cb(DNSServiceRef sd_ref, unsigned int flags, const char *domain, void *user_data) { __DNSSD_LOG_FUNC_ENTER__; + DNSSD_LOCK; dnssd_handle_s *dnssd_handle; GSList *list; void *data; @@ -1269,6 +1422,7 @@ static void __dnssd_browse_reply_cb(DNSServiceRef sd_ref, unsigned int flags, DNSSD_LOGE("Failed to browse, error code %s", dnssd_error_to_string(error_code)); __DNSSD_LOG_FUNC_EXIT__; + DNSSD_UNLOCK; return; } @@ -1317,6 +1471,7 @@ static void __dnssd_browse_reply_cb(DNSServiceRef sd_ref, unsigned int flags, DNSSD_LOGD("Finished executing Browse Callback"); } } + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; } @@ -1331,6 +1486,7 @@ EXPORT_API int dnssd_start_browsing_service(const char *service_type, unsigned int handler; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; CHECK_PERMISSION(); @@ -1339,6 +1495,7 @@ EXPORT_API int dnssd_start_browsing_service(const char *service_type, if (found_cb == NULL || dnssd_service == NULL || service_type == NULL || __dnssd_get_struct_from_handle(*dnssd_service) != NULL) { DNSSD_LOGE("Invalid Parameter"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -1346,6 +1503,7 @@ EXPORT_API int dnssd_start_browsing_service(const char *service_type, local_handle = (dnssd_handle_s *)g_try_malloc0(BROWSE_SIZE); if (local_handle == NULL) { DNSSD_LOGE("Failed to Allocate Memory"); //LCOV_EXCL_LINE + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE return DNSSD_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE } @@ -1372,6 +1530,7 @@ EXPORT_API int dnssd_start_browsing_service(const char *service_type, dnssd_error_to_string(ret)); //LCOV_EXCL_LINE g_free(local_handle->service_type); //LCOV_EXCL_LINE g_free(local_handle); //LCOV_EXCL_LINE + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE return DNSSD_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE } @@ -1382,6 +1541,7 @@ EXPORT_API int dnssd_start_browsing_service(const char *service_type, __dnssd_handle_add_event_handler(&(local_handle->watch_id), local_handle); DNSSD_LOGD("Succeeded to browse for dns service"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -1398,6 +1558,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ unsigned int if_index; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; CHECK_PERMISSION(); @@ -1406,6 +1567,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ if (found_cb == NULL || dnssd_service == NULL || service_type == NULL || __dnssd_get_struct_from_handle(*dnssd_service) != NULL) { DNSSD_LOGE("Invalid Parameter"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -1413,6 +1575,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ local_handle = (dnssd_handle_s *)g_try_malloc0(BROWSE_SIZE); if (local_handle == NULL) { DNSSD_LOGE("Failed to Allocate Memory"); //LCOV_EXCL_LINE + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE return DNSSD_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE } @@ -1420,6 +1583,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ if ((if_index = if_nametoindex(interface)) == 0) { DNSSD_LOGE("Invalid interface name"); g_free(local_handle); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -1447,6 +1611,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ dnssd_error_to_string(ret)); //LCOV_EXCL_LINE g_free(local_handle->service_type); //LCOV_EXCL_LINE g_free(local_handle); //LCOV_EXCL_LINE + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE return DNSSD_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE } @@ -1457,6 +1622,7 @@ EXPORT_API int dnssd_start_browsing_service_on_interface(const char *service_typ __dnssd_handle_add_event_handler(&(local_handle->watch_id), local_handle); DNSSD_LOGD("Succeeded to browse for dns service"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -1579,37 +1745,23 @@ EXPORT_API int dnssd_stop_browsing_service(dnssd_browser_h dnssd_service) int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; res = __get_valid_browsing_handle(dnssd_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } __remove_related_handles(local_handle); __destroy_browsing_handle(local_handle); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } //LCOV_EXCL_STOP -static int __get_valid_handle(dnssd_service_h dnssd_service, dnssd_handle_s **handle) -{ - dnssd_handle_s *local_handle; - - CHECK_INITIALIZED(); - - local_handle = __dnssd_get_struct_from_handle(dnssd_service); - if (local_handle == NULL) { - DNSSD_LOGD("Service Handler not found"); - __DNSSD_LOG_FUNC_EXIT__; - return DNSSD_ERROR_SERVICE_NOT_FOUND; - } - - *handle = local_handle; - - return DNSSD_ERROR_NONE; -} - EXPORT_API int dnssd_service_get_type(dnssd_service_h dnssd_service, char **service_type) { __DNSSD_LOG_FUNC_ENTER__; @@ -1617,13 +1769,19 @@ EXPORT_API int dnssd_service_get_type(dnssd_service_h dnssd_service, char **serv int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_handle(dnssd_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } if (service_type == NULL) { DNSSD_LOGE("Invalid Parameter"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -1631,6 +1789,7 @@ EXPORT_API int dnssd_service_get_type(dnssd_service_h dnssd_service, char **serv *service_type = g_strdup(local_handle->service_type); DNSSD_LOGD("Service Type %s", *service_type); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -1642,13 +1801,19 @@ EXPORT_API int dnssd_service_get_name(dnssd_service_h dnssd_service, char **serv int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_handle(dnssd_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } if (service_name == NULL) { DNSSD_LOGE("Invalid Parameter"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -1664,12 +1829,14 @@ EXPORT_API int dnssd_service_get_name(dnssd_service_h dnssd_service, char **serv } else { *service_name = NULL; DNSSD_LOGD("Invalid DNS SD service"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } DNSSD_LOGD("Service Name %s", *service_name); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -1684,19 +1851,26 @@ EXPORT_API int dnssd_service_get_ip(dnssd_service_h dnssd_service, char **ip_v4_ int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; if (ip_v4_address == NULL && ip_v6_address == NULL) { DNSSD_LOGE("Invalid Parameter"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } + CHECK_INITIALIZED(); + res = __get_valid_handle(dnssd_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } if (local_handle->op_type != DNSSD_TYPE_FOUND) { DNSSD_LOGD("Invalid DNS SD Service"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -1722,6 +1896,7 @@ EXPORT_API int dnssd_service_get_ip(dnssd_service_h dnssd_service, char **ip_v4_ addr[14], addr[15]); } + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -1733,13 +1908,19 @@ EXPORT_API int dnssd_service_get_port(dnssd_service_h dnssd_service, int *port) int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; + + CHECK_INITIALIZED(); res = __get_valid_handle(dnssd_service, &local_handle); - if (res != DNSSD_ERROR_NONE) + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; return res; + } if (port == NULL) { DNSSD_LOGE("Invalid Parameter"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } @@ -1755,11 +1936,13 @@ EXPORT_API int dnssd_service_get_port(dnssd_service_h dnssd_service, int *port) } else { *port = 0; DNSSD_LOGD("Invalid DNS SD service"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } DNSSD_LOGD("Port %d", *port); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } @@ -1768,39 +1951,38 @@ EXPORT_API int dnssd_service_get_all_txt_record(dnssd_service_h dnssd_service, unsigned short *length, void **value) { __DNSSD_LOG_FUNC_ENTER__; - TXTRecordRef *txt_record; - dnssd_handle_s *local_handle; int res; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + DNSSD_LOCK; - res = __get_valid_handle(dnssd_service, &local_handle); - if (res != DNSSD_ERROR_NONE) - return res; + CHECK_INITIALIZED(); if (value == NULL || length == NULL) { DNSSD_LOGE("Invalid Parameter"); + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_INVALID_PARAMETER; } - if (local_handle->op_type == DNSSD_TYPE_FOUND) { - - dnssd_found_data_s *found = NULL; - found = GET_FOUND_DATA_P(local_handle); - - *value = g_strndup(found->txt_record, found->txt_len); - *length = found->txt_len; - } else { - - dnssd_register_data_s *reg = NULL; - reg = GET_REG_DATA_P(local_handle); - txt_record = &(reg->txt_ref); - - *length = TXTRecordGetLength(txt_record); - *value = g_strndup(TXTRecordGetBytesPtr(txt_record), *length); + res = __dnssd_service_get_all_txt_record(dnssd_service, length, value); + if (res != DNSSD_ERROR_NONE) { + DNSSD_UNLOCK; + __DNSSD_LOG_FUNC_EXIT__; + return res; } + DNSSD_UNLOCK; __DNSSD_LOG_FUNC_EXIT__; return DNSSD_ERROR_NONE; } + +void _dnssd_lock(void) +{ + pthread_mutex_lock(&dnssd_mutex); +} + +void _dnssd_unlock(void) +{ + pthread_mutex_unlock(&dnssd_mutex); +} diff --git a/src/ssdp/ssdp-util.h b/src/ssdp/ssdp-util.h index 405091b..deccda1 100644 --- a/src/ssdp/ssdp-util.h +++ b/src/ssdp/ssdp-util.h @@ -44,6 +44,16 @@ #endif /* USE_DLOG */ +#define SSDP_LOCK \ + do { \ + _ssdp_lock(); \ + } while(0) + +#define SSDP_UNLOCK \ + do { \ + _ssdp_unlock(); \ + } while(0) + #define NETWORK_SERVICE_DISCOVERY_FEATURE "http://tizen.org/feature/network.service_discovery.ssdp" #define CHECK_FEATURE_SUPPORTED(feature_name)\ @@ -69,4 +79,7 @@ #define GLIST_ITER_END() } +void _ssdp_lock(void); +void _ssdp_unlock(void); + #endif diff --git a/src/ssdp/ssdp.c b/src/ssdp/ssdp.c index 19ad4bb..f6fadc1 100644 --- a/src/ssdp/ssdp.c +++ b/src/ssdp/ssdp.c @@ -17,7 +17,8 @@ /***************************************************************************** * Standard headers *****************************************************************************/ - +#define _GNU_SOURCE +#include #include #include #include @@ -82,11 +83,13 @@ typedef struct { /***************************************************************************** * Global Variables *****************************************************************************/ -static __thread gboolean g_is_gssdp_init; -static __thread GSSDPClient *g_gssdp_client = NULL; +static gboolean g_is_gssdp_init; +static GSSDPClient *g_gssdp_client = NULL; + +static GList *g_ssdp_local_services = NULL; +static GHashTable *g_found_ssdp_services = NULL; -static __thread GList *g_ssdp_local_services = NULL; -static __thread GHashTable *g_found_ssdp_services = NULL; +static pthread_mutex_t ssdp_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; /***************************************************************************** * Local Functions Definition *****************************************************************************/ @@ -316,6 +319,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser, const char *usn, GList *urls, gpointer user_data) { __SSDP_LOG_FUNC_ENTER__; + SSDP_LOCK; ssdp_service_s *browser = NULL; ssdp_service_s *found_service = NULL; char *temp_url = NULL; @@ -326,6 +330,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser, browser = (ssdp_service_s *)user_data; if (browser == NULL) { SSDP_LOGE("Service not found"); + SSDP_UNLOCK; return; } @@ -337,6 +342,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser, temp_url = g_try_malloc0(url_len + 1); if (!temp_url) { SSDP_LOGE("Failed to get memory for url"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return; } @@ -352,6 +358,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser, g_strcmp0(found_service->usn, usn) == 0) { SSDP_LOGD("Duplicated service!"); g_free(temp_url); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return; } @@ -360,6 +367,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser, if (!found_service) { SSDP_LOGE("Failed to get memory for ssdp service structure"); g_free(temp_url); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return; } @@ -383,6 +391,7 @@ __ssdp_res_available_cb(GSSDPResourceBrowser *resource_browser, found_service->service_handler, browser->cb_user_data); } + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return; @@ -395,18 +404,21 @@ __ssdp_res_unavailable_cb(GSSDPResourceBrowser *resource_browser, const char *usn, GList *urls, gpointer user_data) { __SSDP_LOG_FUNC_ENTER__; + SSDP_LOCK; ssdp_service_s *browser = NULL; ssdp_service_s *found_service = NULL; browser = (ssdp_service_s *)user_data; if (browser == NULL) { SSDP_LOGE("Browser not found"); + SSDP_UNLOCK; return; } found_service = g_hash_table_lookup(g_found_ssdp_services, usn); if (found_service == NULL) { SSDP_LOGD("No service matched!"); + SSDP_UNLOCK; return; } @@ -425,6 +437,7 @@ __ssdp_res_unavailable_cb(GSSDPResourceBrowser *resource_browser, SSDP_LOGD("Hash tbl size [%d]", g_hash_table_size(g_found_ssdp_services)); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return; } @@ -436,11 +449,13 @@ EXPORT_API int ssdp_initialize() int status = SSDP_ERROR_NONE; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; GError *gerror = NULL; if (g_is_gssdp_init) { SSDP_LOGE("gssdp already initialized"); + SSDP_UNLOCK; return SSDP_ERROR_NONE; } @@ -449,12 +464,14 @@ EXPORT_API int ssdp_initialize() SSDP_LOGE("Error creating the GSSDP client: %s\n", gerror->message); g_error_free(gerror); //LCOV_EXCL_LINE + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_OPERATION_FAILED; } if (g_gssdp_client == NULL) { SSDP_LOGE("failed to create client\n"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_OPERATION_FAILED; } @@ -462,7 +479,7 @@ EXPORT_API int ssdp_initialize() g_found_ssdp_services = g_hash_table_new(g_str_hash, g_str_equal); g_is_gssdp_init = TRUE; - + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -473,9 +490,11 @@ EXPORT_API int ssdp_deinitialize() int status = SSDP_ERROR_NONE; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (!g_is_gssdp_init) { SSDP_LOGE("gssdp not initialized"); + SSDP_UNLOCK; return SSDP_ERROR_NOT_INITIALIZED; } @@ -491,6 +510,7 @@ EXPORT_API int ssdp_deinitialize() g_gssdp_client = NULL; g_is_gssdp_init = FALSE; + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -502,20 +522,24 @@ EXPORT_API int ssdp_create_local_service(const char *target, ssdp_service_h *ssd ssdp_service_s *service = NULL; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (!g_is_gssdp_init) { SSDP_LOGE("gssdp not initialized"); + SSDP_UNLOCK; return SSDP_ERROR_NOT_INITIALIZED; //LCOV_EXCL_LINE } if (target == NULL) { SSDP_LOGE("target is NULL"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_INVALID_PARAMETER; } if (ssdp_service == NULL) { SSDP_LOGE("ssdp_service is NULL"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_INVALID_PARAMETER; } @@ -523,6 +547,7 @@ EXPORT_API int ssdp_create_local_service(const char *target, ssdp_service_h *ssd service = (ssdp_service_s*)g_try_malloc0(sizeof(ssdp_service_s)); if (!service) { SSDP_LOGE("Failed to get memory for gssdp service structure"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE } @@ -531,6 +556,7 @@ EXPORT_API int ssdp_create_local_service(const char *target, ssdp_service_h *ssd if (!service->target) { SSDP_LOGE("Failed to get memory for gssdp service type"); g_free(service); //LCOV_EXCL_LINE + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE } @@ -541,6 +567,7 @@ EXPORT_API int ssdp_create_local_service(const char *target, ssdp_service_h *ssd service->origin = SSDP_SERVICE_STATE_NOT_REGISTERED; g_ssdp_local_services = g_list_append(g_ssdp_local_services, service); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -552,9 +579,11 @@ EXPORT_API int ssdp_destroy_local_service(ssdp_service_h ssdp_service) ssdp_service_s *service = NULL; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (ssdp_service == 0) { SSDP_LOGE("Invalid parameter"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } @@ -562,12 +591,15 @@ EXPORT_API int ssdp_destroy_local_service(ssdp_service_h ssdp_service) if (!g_is_gssdp_init) { SSDP_LOGE("gssdp not initialized"); + SSDP_UNLOCK; return SSDP_ERROR_NOT_INITIALIZED; //LCOV_EXCL_LINE } service = __ssdp_find_local_service(g_ssdp_local_services, ssdp_service); - if (service == NULL) + if (service == NULL) { + SSDP_UNLOCK; return SSDP_ERROR_SERVICE_NOT_FOUND; + } if (service->resource_group != NULL) service->resource_group = NULL; //LCOV_EXCL_LINE @@ -581,6 +613,7 @@ EXPORT_API int ssdp_destroy_local_service(ssdp_service_h ssdp_service) g_free(service->url); g_free(service); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -592,9 +625,11 @@ EXPORT_API int ssdp_service_set_usn(ssdp_service_h local_service, const char* us ssdp_service_s *service = NULL; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (local_service == 0 || usn == NULL) { SSDP_LOGE("Invalid parameter"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } SSDP_LOGD("SSDP service ID [%u]", local_service); @@ -602,29 +637,33 @@ EXPORT_API int ssdp_service_set_usn(ssdp_service_h local_service, const char* us if (!g_is_gssdp_init) { SSDP_LOGE("gssdp not initialized"); + SSDP_UNLOCK; return SSDP_ERROR_NOT_INITIALIZED; //LCOV_EXCL_LINE } service = __ssdp_find_local_service(g_ssdp_local_services, local_service); if (service == NULL) { SSDP_LOGE("Service not found"); + SSDP_UNLOCK; return SSDP_ERROR_SERVICE_NOT_FOUND; } if (service->origin == SSDP_SERVICE_STATE_REGISTERED) { SSDP_LOGE("Already registered"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } if (__ssdp_find_local_service_with_usn(g_ssdp_local_services, usn) != NULL) { SSDP_LOGE("Duplicate USN"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } g_free(service->usn); service->usn = g_strndup(usn, strlen(usn)); - + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -636,9 +675,11 @@ EXPORT_API int ssdp_service_set_url(ssdp_service_h local_service, const char *ur ssdp_service_s *service = NULL; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (local_service == 0 || url == NULL) { SSDP_LOGE("Invalid parameter"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } SSDP_LOGD("SSDP service ID [%u]", local_service); @@ -646,28 +687,33 @@ EXPORT_API int ssdp_service_set_url(ssdp_service_h local_service, const char *ur if (!g_is_gssdp_init) { SSDP_LOGE("gssdp not initialized"); + SSDP_UNLOCK; return SSDP_ERROR_NOT_INITIALIZED; //LCOV_EXCL_LINE } service = __ssdp_find_local_service(g_ssdp_local_services, local_service); if (service == NULL) { SSDP_LOGE("Service not found"); + SSDP_UNLOCK; return SSDP_ERROR_SERVICE_NOT_FOUND; } if (service->origin == SSDP_SERVICE_STATE_REGISTERED) { SSDP_LOGE("Already registered"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } if (__ssdp_find_local_service_with_url(g_ssdp_local_services, url) != NULL) { SSDP_LOGE("Duplicate URL"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } g_free(service->url); service->url = g_strndup(url, strlen(url)); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -680,36 +726,43 @@ EXPORT_API int ssdp_service_get_target(ssdp_service_h ssdp_service, char **targe char *target_local = NULL; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (ssdp_service == 0 || !target) { SSDP_LOGE("Invalid parameter"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } SSDP_LOGD("SSDP service ID [%u]", ssdp_service); if (!g_is_gssdp_init) { SSDP_LOGE("gssdp not initialized"); + SSDP_UNLOCK; return SSDP_ERROR_NOT_INITIALIZED; //LCOV_EXCL_LINE } service = __ssdp_find_local_service(g_ssdp_local_services, ssdp_service); - if (service == NULL) + if (service == NULL) { service = __ssdp_find_remote_service(g_found_ssdp_services, ssdp_service); + } if (service == NULL || service->target == NULL) { SSDP_LOGE("Service not found"); + SSDP_UNLOCK; return SSDP_ERROR_SERVICE_NOT_FOUND; } target_local = g_strndup(service->target, strlen(service->target)); if (!target_local) { SSDP_LOGE("Failed to get memory for gssdp service type"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE } *target = target_local; + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -722,36 +775,43 @@ EXPORT_API int ssdp_service_get_usn(ssdp_service_h ssdp_service, char **usn) char *usn_local = NULL; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (ssdp_service == 0 || !usn) { SSDP_LOGE("Invalid parameter"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } SSDP_LOGD("SSDP service ID [%u]", ssdp_service); if (!g_is_gssdp_init) { SSDP_LOGE("gssdp not initialized"); + SSDP_UNLOCK; return SSDP_ERROR_NOT_INITIALIZED; //LCOV_EXCL_LINE } service = __ssdp_find_local_service(g_ssdp_local_services, ssdp_service); - if (service == NULL) + if (service == NULL) { service = __ssdp_find_remote_service(g_found_ssdp_services, ssdp_service); + } if (service == NULL || service->usn == NULL) { SSDP_LOGE("Service not found"); + SSDP_UNLOCK; return SSDP_ERROR_SERVICE_NOT_FOUND; } usn_local = g_strndup(service->usn, strlen(service->usn)); if (!usn_local) { SSDP_LOGE("Failed to get memory for gssdp service type"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE } *usn = usn_local; + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -764,36 +824,43 @@ EXPORT_API int ssdp_service_get_url(ssdp_service_h ssdp_service, char **url) char *url_local = NULL; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (ssdp_service == 0 || !url) { SSDP_LOGE("Invalid parameter"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } SSDP_LOGD("SSDP service ID [%u]", ssdp_service); if (!g_is_gssdp_init) { SSDP_LOGE("gssdp not initialized"); + SSDP_UNLOCK; return SSDP_ERROR_NOT_INITIALIZED; //LCOV_EXCL_LINE } service = __ssdp_find_local_service(g_ssdp_local_services, ssdp_service); - if (service == NULL) + if (service == NULL) { service = __ssdp_find_remote_service(g_found_ssdp_services, ssdp_service); + } if (service == NULL || service->url == NULL) { SSDP_LOGE("Service not found"); + SSDP_UNLOCK; return SSDP_ERROR_SERVICE_NOT_FOUND; } url_local = g_strndup(service->url, strlen(service->url)); if (!url_local) { SSDP_LOGE("Failed to get memory for gssdp service type"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE } *url = url_local; + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -806,31 +873,37 @@ EXPORT_API int ssdp_register_local_service(ssdp_service_h local_service, ssdp_service_s *service = NULL; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (__ssdp_check_permission() == false) { SSDP_LOGE("Permission denied"); + SSDP_UNLOCK; return SSDP_ERROR_PERMISSION_DENIED; } if (local_service == 0) { SSDP_LOGE("Invalid parameter"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } SSDP_LOGD("SSDP service ID [%u]", local_service); if (!g_is_gssdp_init) { SSDP_LOGE("gssdp not initialized"); + SSDP_UNLOCK; return SSDP_ERROR_NOT_INITIALIZED; //LCOV_EXCL_LINE } service = __ssdp_find_local_service(g_ssdp_local_services, local_service); if (service == NULL) { SSDP_LOGE("Service not found"); + SSDP_UNLOCK; return SSDP_ERROR_SERVICE_NOT_FOUND; } if (service->origin == SSDP_SERVICE_STATE_REGISTERED) { SSDP_LOGE("Already registered"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } @@ -844,12 +917,14 @@ EXPORT_API int ssdp_register_local_service(ssdp_service_h local_service, if (g_gssdp_client == NULL) { SSDP_LOGE("GSSDPClient is NULL. Init first"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } service->resource_group = gssdp_resource_group_new(g_gssdp_client); if (service->resource_group == NULL) { SSDP_LOGE("Resource group is NULL"); + SSDP_UNLOCK; return SSDP_ERROR_OPERATION_FAILED; } @@ -861,6 +936,7 @@ EXPORT_API int ssdp_register_local_service(ssdp_service_h local_service, if (service->resource_id == 0) { SSDP_LOGE("Failed to add resource"); + SSDP_UNLOCK; return SSDP_ERROR_OPERATION_FAILED; } @@ -873,6 +949,7 @@ EXPORT_API int ssdp_register_local_service(ssdp_service_h local_service, SSDP_LOGD("Resource group id is [%d]\n", service->resource_id); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -885,21 +962,25 @@ EXPORT_API int ssdp_deregister_local_service(ssdp_service_h local_service) ssdp_service_s *service = NULL; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (local_service == 0) { SSDP_LOGE("Invalid parameter"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } SSDP_LOGD("SSDP service ID [%u]", local_service); if (!g_is_gssdp_init) { SSDP_LOGE("gssdp not initialized"); + SSDP_UNLOCK; return SSDP_ERROR_NOT_INITIALIZED; //LCOV_EXCL_LINE } service = __ssdp_find_local_service(g_ssdp_local_services, local_service); if (service == NULL) { SSDP_LOGE("Service not found"); + SSDP_UNLOCK; return SSDP_ERROR_SERVICE_NOT_FOUND; } @@ -917,6 +998,7 @@ EXPORT_API int ssdp_deregister_local_service(ssdp_service_h local_service) service->registered_cb = NULL; service->cb_user_data = NULL; + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -929,26 +1011,31 @@ EXPORT_API int ssdp_start_browsing_service(const char* target, ssdp_browser_h* s ssdp_service_s *browser = NULL; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (__ssdp_check_permission() == false) { SSDP_LOGE("Permission denied"); + SSDP_UNLOCK; return SSDP_ERROR_PERMISSION_DENIED; } if (!g_is_gssdp_init) { SSDP_LOGE("gssdp not initialized"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_NOT_INITIALIZED; //LCOV_EXCL_LINE } if (ssdp_browser == NULL) { SSDP_LOGE("Invalid parameter"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_INVALID_PARAMETER; } if (g_gssdp_client == NULL) { SSDP_LOGE("GSSDPClient is NULL. Init first"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_INVALID_PARAMETER; } @@ -966,6 +1053,7 @@ GLIST_ITER_END() browser = (ssdp_service_s*)g_try_malloc0(sizeof(ssdp_service_s)); if (!browser) { SSDP_LOGE("Failed to get memory for gssdp service structure"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_OUT_OF_MEMORY; } @@ -974,6 +1062,7 @@ GLIST_ITER_END() if (!browser->target) { SSDP_LOGE("Failed to get memory for gssdp service type"); g_free(browser); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_OUT_OF_MEMORY; } @@ -988,6 +1077,7 @@ GLIST_ITER_END() browser->target); if (browser->resource_browser == NULL) { SSDP_LOGE("Failed to create service browser\n"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_OPERATION_FAILED; } @@ -1007,6 +1097,7 @@ GLIST_ITER_END() } else { if (!(gssdp_resource_browser_rescan(browser->resource_browser))) { SSDP_LOGE("Failed to request rescan"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_OPERATION_FAILED; } @@ -1015,6 +1106,7 @@ GLIST_ITER_END() browser->found_cb = found_cb; browser->cb_user_data = user_data; + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } @@ -1026,9 +1118,11 @@ EXPORT_API int ssdp_stop_browsing_service(ssdp_browser_h ssdp_browser) ssdp_service_s *browser = NULL; CHECK_FEATURE_SUPPORTED(NETWORK_SERVICE_DISCOVERY_FEATURE); + SSDP_LOCK; if (ssdp_browser == 0) { SSDP_LOGE("Invalid parameter"); + SSDP_UNLOCK; return SSDP_ERROR_INVALID_PARAMETER; } @@ -1036,6 +1130,7 @@ EXPORT_API int ssdp_stop_browsing_service(ssdp_browser_h ssdp_browser) browser = __ssdp_find_local_service(g_ssdp_local_services, ssdp_browser); if (browser == NULL) { SSDP_LOGE("Service not found"); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return SSDP_ERROR_SERVICE_NOT_FOUND; } @@ -1057,9 +1152,18 @@ EXPORT_API int ssdp_stop_browsing_service(ssdp_browser_h ssdp_browser) g_free(browser->target); g_free(browser); + SSDP_UNLOCK; __SSDP_LOG_FUNC_EXIT__; return status; } +void _ssdp_lock(void) +{ + pthread_mutex_lock(&ssdp_mutex); +} +void _ssdp_unlock(void) +{ + pthread_mutex_unlock(&ssdp_mutex); +} -- 2.7.4