[bluetooth-frwk] Added listFolders implementation with async result 48/102848/2
authorPiotr Kosko <p.kosko@samsung.com>
Fri, 28 Oct 2016 12:57:49 +0000 (14:57 +0200)
committerPyun DoHyun <dh79.pyun@samsung.com>
Thu, 8 Dec 2016 00:19:50 +0000 (16:19 -0800)
[Feature] added implementation for listFolders method

[Verification] function checked with sample C program:
  - listing folder is possible,
  - options work correctly and maxcount works fine.
  - user_data is correctly passed to result callback

Change-Id: If81066103306cd1bc4199d5bf2a1396c4d11af7f
Signed-off-by: Piotr Kosko <p.kosko@samsung.com>
bt-api/bt-common.c
bt-api/bt-event-handler.c
bt-api/bt-map-client.c
bt-api/bt-request-sender.c
bt-service/bt-request-handler.c
bt-service/bt-service-event-sender.c
bt-service/bt-service-map-client.c
bt-service/include/bt-service-map-client.h
include/bluetooth-api.h
include/bt-internal-types.h

index d7a9e49..ce0365e 100644 (file)
@@ -126,6 +126,7 @@ bt_user_info_t *_bt_get_user_data(int type)
 void _bt_common_event_cb(int event, int result, void *param,
                                        void *callback, void *user_data)
 {
+       BT_DBG("bt_common_event_cb, event: %d", event);
        bluetooth_event_param_t bt_event = { 0, };
        bt_event.event = event;
        bt_event.result = result;
index 4d0d21a..a2f3913 100644 (file)
@@ -1983,6 +1983,7 @@ void __bt_map_client_event_filter(GDBusConnection *connection,
                                                 GVariant *parameters,
                                                 gpointer user_data)
 {
+       BT_DBG("Entered __bt_map_client_event_filter");
        bt_event_info_t *event_info;
        int result = BLUETOOTH_ERROR_NONE;
        event_info = (bt_event_info_t *)user_data;
@@ -2024,7 +2025,7 @@ void __bt_map_client_event_filter(GDBusConnection *connection,
                bluetooth_device_address_t dev_address = { {0} };
 
                g_variant_get(parameters, "(i&si)", &result, &address,
-                                                       &request_id);
+                               &request_id);
 
                if (__bt_is_request_id_exist(request_id) == FALSE) {
                        BT_ERR("Different request id!");
@@ -2032,18 +2033,68 @@ void __bt_map_client_event_filter(GDBusConnection *connection,
                }
 
                _bt_convert_addr_string_to_type(dev_address.addr,
-                                               address);
+                               address);
 
                _bt_common_event_cb(BLUETOOTH_EVENT_MAP_DISCONNECTED,
                                result, &dev_address,
                                event_info->cb, event_info->user_data);
 
                __bt_remove_push_request_id(request_id);
-       } else if (strcasecmp(signal_name, BT_MAP_OP_COMPLETE) == 0) {
+       } else if (strcasecmp(signal_name, BT_MAP_LIST_FOLDERS_COMPLETE) == 0) {
+               int request_id = 0;
+               GVariant* folder_list_var = NULL;
+
+               g_variant_get(parameters, "(iiv)", &result, &request_id, &folder_list_var);
+               if (__bt_is_request_id_exist(request_id) == FALSE) {
+                       BT_ERR("Different request id!");
+                       return;
+               }
 
-               /* TODO: MAP, see __bt_opp_client_event_filter above */
+               GVariantIter* iter;
 
+               bt_map_client_folders_s folders_struct = {0,};
+               g_variant_get(folder_list_var, "(aa{sv})", &iter);
+
+               folders_struct.size = g_variant_iter_n_children(iter);
+               folders_struct.names = (char**) malloc(folders_struct.size * sizeof(*(folders_struct.names)));
+               BT_DBG("g_variant_iter_n_children: %d", folders_struct.size);
+               GVariantIter* res = NULL;
+               int i = 0;
+               while (g_variant_iter_loop(iter, "a{sv}", &res)) {
+                       char* key = NULL;
+                       GVariant* value = NULL;
+                       while (g_variant_iter_loop(res, "{sv}", &key, &value)) {
+                               char* string_value = NULL;
+                               g_variant_get(value, "s", &string_value);
+                               BT_DBG("got folder name: %s", string_value);
+                               folders_struct.names[i] = strdup(string_value);
+                       }
+                       ++i;
+               }
+               _bt_common_event_cb(BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE,
+                               result, &folders_struct,
+                               event_info->cb, event_info->user_data);
+
+               __bt_remove_push_request_id(request_id);
+
+               // freeing resources
+               while (--i >= 0) {
+                       free(folders_struct.names[i]);
+                       folders_struct.names[i] = NULL;
+               }
+               free(folders_struct.names);
+
+               g_variant_unref(folder_list_var);
        }
+       // TODO MAP place for you else 1
+       // TODO MAP place for you else 2
+       // TODO MAP place for you else 3
+       // TODO MAP place for you else 4
+       // TODO MAP place for you else 5
+       // TODO MAP place for you else 6
+       // TODO MAP place for you else 7
+       // TODO MAP place for you else 8
+
 }
 
 void __bt_pbap_client_event_filter(GDBusConnection *connection,
index a476881..eb062c9 100644 (file)
@@ -134,15 +134,32 @@ BT_EXPORT_API int bluetooth_map_client_set_folder(
 }
 
 BT_EXPORT_API int bluetooth_map_client_list_folders(
-    bt_map_client_session_info_s *session,
-    GVariant *filter)
+               bt_map_client_session_info_s *session,
+           int offset,
+           int maxcount)
 {
-    BT_DBG("bluetooth_map_client_list_folders");
-    int result = BLUETOOTH_ERROR_INTERNAL;
+       BT_DBG("bluetooth_map_list_folders");
+       int result = 0;
 
-    /* TODO: MAP */
+       BT_CHECK_ENABLED(return);
+       BT_CHECK_PARAMETER(session->session_path, return);
 
-    return result;
+       bt_user_info_t *user_info = _bt_get_user_data(BT_COMMON);
+       retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       BT_INIT_PARAMS();
+       BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       g_array_append_vals(in_param1, session->session_path, strlen(session->session_path)+1);
+       g_array_append_vals(in_param2, &offset, sizeof(offset));
+       g_array_append_vals(in_param3, &maxcount, sizeof(maxcount));
+
+       result = _bt_send_request_async(BT_OBEX_SERVICE, BT_MAP_LIST_FOLDERS,
+                       in_param1, in_param2, in_param3, in_param4, user_info->cb, user_info->user_data);
+
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+       return result;
 }
 
 BT_EXPORT_API int bluetooth_map_client_list_filter_fields(
index be6ab8d..6594580 100644 (file)
@@ -254,6 +254,7 @@ static void __send_request_cb(GDBusProxy *proxy,
                                GAsyncResult *res,
                                gpointer user_data)
 {
+       BT_DBG("Entered __send_request_cb");
        bluetooth_event_param_t bt_event;
        bt_req_info_t *cb_data = user_data;
        int result = BLUETOOTH_ERROR_NONE;
@@ -310,17 +311,25 @@ static void __send_request_cb(GDBusProxy *proxy,
                                &bt_event.event, &event_type,
                                &bt_event.param_data);
 
+               BT_DBG("service_function [%d]", cb_data->service_function);
                if (result == BLUETOOTH_ERROR_NONE && out_param1) {
                        if (cb_data->service_function == BT_OPP_PUSH_FILES) {
                                request_id = g_array_index(out_param1, int, 0);
                                BT_DBG("request_id : %d", request_id);
                                _bt_add_push_request_id(request_id);
+                       } else if (cb_data->service_function == BT_MAP_LIST_FOLDERS) {
+                               request_id = g_array_index(out_param1, int, 0);
+                               BT_DBG("request_id : %d", request_id);
+                               _bt_add_push_request_id(request_id);
                        }
-                       /* TODO: MAP service functions:
-                       else if (cb_data->service_function == BT_MAP_XXX) {
-
-                       }
-                       */
+                       // TODO MAP place for your own if 1
+                       // TODO MAP place for your own if 2
+                       // TODO MAP place for your own if 3
+                       // TODO MAP place for your own if 4
+                       // TODO MAP place for your own if 5
+                       // TODO MAP place for your own if 6
+                       // TODO MAP place for your own if 7
+                       // TODO MAP place for your own if 8
 
                        goto done;
                }
index eb92aa5..401d17e 100644 (file)
@@ -2293,10 +2293,19 @@ int __bt_obexd_request(int function_name,
 
        case BT_MAP_LIST_FOLDERS: {
                BT_DBG("BT_MAP_LIST_FOLDERS");
+               // TODO MAP add filter handling
+               GVariant *filter = g_variant_new("()");
 
-               /* TODO: MAP */
+               char* session_id = (char *)g_variant_get_data(in_param1);
+               int offset = 0;
+               int maxcount = 0;
+               __bt_service_get_parameters(in_param2, &offset, sizeof(int));
+               __bt_service_get_parameters(in_param3, &maxcount, sizeof(int));
 
-               result = BLUETOOTH_ERROR_NOT_SUPPORT;
+               result = _bt_map_client_list_folders(request_id, context, session_id, offset, maxcount);
+               if (result == BLUETOOTH_ERROR_NONE) {
+                       BT_DBG("_bt_map_client_list_folders succeed");
+               }
                break;
        }
 
index de9b216..cc13bb8 100644 (file)
@@ -328,6 +328,18 @@ int _bt_send_event(int event_type, int event, GVariant *param)
                signal = BT_MAP_DISCONNECTED;
                BT_INFO_C("Disconnected [MAP]");
                break;
+       case BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE:
+               signal = BT_MAP_LIST_FOLDERS_COMPLETE;
+               BT_INFO_C("Completed list folders operation[MAP]");
+               break;
+               // TODO MAP place for your own case 1
+               // TODO MAP place for your own case 2
+               // TODO MAP place for your own case 3
+               // TODO MAP place for your own case 4
+               // TODO MAP place for your own case 5
+               // TODO MAP place for your own case 6
+               // TODO MAP place for your own case 7
+               // TODO MAP place for your own case 8
        case BLUETOOTH_EVENT_OBEX_SERVER_TRANSFER_CONNECTED:
                signal = BT_TRANSFER_CONNECTED;
                break;
index 3eac5c5..1ecba34 100644 (file)
@@ -366,15 +366,84 @@ int _bt_map_client_set_folder(const char* session_id, const char* name)
        return BLUETOOTH_ERROR_NONE;
 }
 
-int _bt_map_client_list_folders(const char* session_id, GVariant *filter)
+int _bt_map_client_list_folders(int request_id, GDBusMethodInvocation *context,
+               const char* session_id, int offset, int maxcount)
 {
-       BT_DBG("+");
+       BT_DBG("Entered _bt_map_list_folders with session id: \"%s\"", session_id);
+       BT_DBG("Entered offset: %d maxcount: %d", offset, maxcount);
+       GDBusConnection *g_conn;
+       GDBusProxy *message_access_proxy;
+       GError *error = NULL;
+       int result = BLUETOOTH_ERROR_NONE;
 
-       /* TODO: MAP */
+       retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
+
+       g_conn = _bt_gdbus_get_session_gconn();
+       retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
+                       &request_id, sizeof(int),
+                       TRUE, NULL, NULL);
+       g_dbus_method_invocation_return_value(context,
+                       g_variant_new("(iv)", result, out_param1));
+
+       // create message access proxy
+       g_clear_error(&error);
+       message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
+                       BT_OBEX_SERVICE_NAME, session_id, "org.bluez.obex.MessageAccess1",
+                       NULL, &error);
+       if (error != NULL) {
+               BT_ERR("Could not create message access proxy: %s\n", error->message);
+               result = BLUETOOTH_ERROR_INTERNAL;
+       } else {
+               if (!message_access_proxy) {
+                       BT_ERR("message proxy handle is null\n");
+                       result = BLUETOOTH_ERROR_INTERNAL;
+               } else {
+                       BT_DBG("message proxy set");
+
+                       GVariantBuilder* b = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+
+                       if (offset >= 0) {
+                               g_variant_builder_add(b, "{sv}", "Offset", g_variant_new_uint16(offset));
+                       }
+                       if (maxcount >= 0) {
+                               g_variant_builder_add(b, "{sv}", "MaxCount", g_variant_new_uint16(maxcount));
+                       }
+                       GVariant *args = g_variant_builder_end(b);
+                       GVariant *params = g_variant_new("(@a{sv})", args);
+                       g_variant_builder_unref (b);
+
+                       int* request_id_p = malloc(sizeof(*request_id_p));
+                       *request_id_p = request_id;
+
+                       GVariant *folder_list_var = g_dbus_proxy_call_sync(message_access_proxy,
+                                       "ListFolders", params, G_DBUS_CALL_FLAGS_NONE, -1,
+                                       NULL, &error);
+                       if (error != NULL) {
+                               BT_ERR("Could not ListFolders: %s\n", error->message);
+                               // TODO return correct error
+                               result = BLUETOOTH_ERROR_INTERNAL;
+                       } else {
+                               if (!folder_list_var) {
+                                       BT_ERR("returned ListFolders is null\n");
+                                       result = BLUETOOTH_ERROR_INTERNAL;
+                               } else {
+                                       BT_DBG("ListFolders succeed\n");
+
+                                       GVariant *param = g_variant_new("(iiv)", result, request_id, folder_list_var);
+                                       BT_DBG("RequestID[%d]", request_id);
+                                       result = _bt_send_event(BT_MAP_CLIENT_EVENT,
+                                                                       BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE, param);
+                               }
+                       }
+               }
+       }
 
+       g_object_unref(message_access_proxy);
        BT_DBG("-");
 
-       return BLUETOOTH_ERROR_NONE;
+       return result;
 }
 
 int _bt_map_client_list_filter_fields(const char* session_id)
index 4f6e133..42eb8d2 100644 (file)
@@ -64,7 +64,8 @@ typedef struct {
 int _bt_create_session_sync(const char* address, char** session_id);
 int _bt_destroy_session_sync(const char* session_id);
 int _bt_map_client_set_folder(const char* session_id, const char* name);
-int _bt_map_client_list_folders(const char* session_id, GVariant *filter);
+int _bt_map_client_list_folders(int request_id, GDBusMethodInvocation *context,
+               const char* session_id, int offset, int maxcount);
 int _bt_map_client_list_filter_fields(const char* session_id);
 int _bt_map_client_list_messages(
                const char* session_id,
index e7a6951..c81f2b5 100644 (file)
@@ -1796,6 +1796,12 @@ typedef struct {
        char* remote_address;
 } bt_map_client_session_info_s;
 
+typedef struct {
+       char **names; // holding %size null-terminated folder names
+       int size;
+} bt_map_client_folders_s;
+
+
 /**
  * Callback pointer type
  */
@@ -4859,7 +4865,8 @@ int bluetooth_map_client_set_folder(
 
 int bluetooth_map_client_list_folders(
     bt_map_client_session_info_s *session,
-    GVariant *filter
+    int offset,
+    int maxcount
 );
 
 int bluetooth_map_client_list_filter_fields(
index d9eb63a..0b69dcc 100644 (file)
@@ -501,6 +501,15 @@ typedef struct {
 #define BT_OPP_DISCONNECTED "OppDisconnected"
 #define BT_MAP_CONNECTED "MapConnected"
 #define BT_MAP_DISCONNECTED "MapDisconnected"
+#define BT_MAP_LIST_FOLDERS_COMPLETE "ListFoldersComplete"
+//  TODO MAP place for your define 1
+//  TODO MAP place for your define 2
+//  TODO MAP place for your define 3
+//  TODO MAP place for your define 4
+//  TODO MAP place for your define 5
+//  TODO MAP place for your define 6
+//  TODO MAP place for your define 7
+//  TODO MAP place for your define 8
 #define BT_MAP_OP_COMPLETE "Complete"
 #define BT_TRANSFER_CONNECTED "TransferConnected"
 #define BT_TRANSFER_DISCONNECTED "TransferDisonnected"