From 686ce025a22f4a933fee4f3895f3b690ec628979 Mon Sep 17 00:00:00 2001
From: Piotr Dabrowski
Date: Wed, 9 Nov 2016 16:39:46 +0100
Subject: [PATCH] [bluetooth-frwk] listMessages
Change-Id: Ibc633c9c9e930da5cc296917d7821d0f2294971a
---
bt-api/bt-event-handler.c | 143 ++++++++++++++++++++++++++++-
bt-api/bt-map-client.c | 30 +++++-
bt-api/bt-request-sender.c | 5 +-
bt-service/bt-request-handler.c | 12 ++-
bt-service/bt-service-event-sender.c | 5 +-
bt-service/bt-service-map-client.c | 84 ++++++++++++++++-
bt-service/include/bt-service-map-client.h | 2 +
include/bluetooth-api.h | 72 ++++++++++++++-
include/bt-internal-types.h | 2 +-
9 files changed, 340 insertions(+), 15 deletions(-)
diff --git a/bt-api/bt-event-handler.c b/bt-api/bt-event-handler.c
index c6c77b4..c34b91b 100644
--- a/bt-api/bt-event-handler.c
+++ b/bt-api/bt-event-handler.c
@@ -2126,9 +2126,148 @@ void __bt_map_client_event_filter(GDBusConnection *connection,
__bt_remove_push_request_id(request_id);
g_variant_unref(value);
- }
+ } else if (strcasecmp(signal_name, BT_MAP_LIST_MESSAGES_COMPLETE) == 0) {
+ int request_id = 0;
+ GVariant* messages_list_var = NULL;
+ g_variant_get(parameters, "(iiv)", &result, &request_id, &messages_list_var);
+ if (__bt_is_request_id_exist(request_id) == FALSE) {
+ BT_ERR("Different request id!");
+ return;
+ }
+
+ bt_map_client_message_items_s messages_struct = {0,};
- // TODO MAP place for you else 2
+ GVariantIter* iter;
+ g_variant_get(messages_list_var, "(a{oa{sv}})", &iter);
+ messages_struct.size = g_variant_iter_n_children(iter);
+ messages_struct.message_items = (bt_map_client_message_item_t*)
+ malloc(messages_struct.size * sizeof(*(messages_struct.message_items)));
+ BT_DBG("g_variant_iter_n_children: %d", messages_struct.size);
+
+ char *object = NULL;
+ GVariantIter *properites = NULL;
+ int i = 0;
+ while (g_variant_iter_loop(iter, "{oa{sv}}", &object, &properites)) {
+ messages_struct.message_items[i].message_object_name = strdup(object);
+ BT_DBG("Message found: %s", messages_struct.message_items[i].message_object_name);
+ messages_struct.message_items[i].folder = NULL;
+ messages_struct.message_items[i].subject = NULL;
+ messages_struct.message_items[i].timestamp = NULL;
+ messages_struct.message_items[i].sender = NULL;
+ messages_struct.message_items[i].sender_address = NULL;
+ messages_struct.message_items[i].reply_to = NULL;
+ messages_struct.message_items[i].recipient = NULL;
+ messages_struct.message_items[i].recipient_address = NULL;
+ messages_struct.message_items[i].type = NULL;
+ messages_struct.message_items[i].size = -1;
+ messages_struct.message_items[i].is_text = -1;
+ messages_struct.message_items[i].status = NULL;
+ messages_struct.message_items[i].attachment_size = -1;
+ messages_struct.message_items[i].is_priority = -1;
+ messages_struct.message_items[i].is_read = -1;
+ messages_struct.message_items[i].is_sent = -1;
+ messages_struct.message_items[i].is_protected = -1;
+ char *key = NULL;
+ GVariant *value = NULL;
+ while (g_variant_iter_loop(properites, "{sv}", &key, &value)) {
+ char *value_string = NULL;
+ uint64_t value_int = -1;
+ bool value_bool = false;
+ if (strcmp(key, "Folder") == 0) {
+ g_variant_get(value, "s", &value_string);
+ messages_struct.message_items[i].folder = strdup(value_string);
+ BT_DBG(" Folder: %s", value_string);
+ } else if (strcmp(key, "Subject") == 0) {
+ g_variant_get(value, "s", &value_string);
+ messages_struct.message_items[i].subject = strdup(value_string);
+ BT_DBG(" Subject: %s", value_string);
+ } else if (strcmp(key, "Timestamp") == 0) {
+ g_variant_get(value, "s", &value_string);
+ messages_struct.message_items[i].timestamp = strdup(value_string);
+ BT_DBG(" Timestamp: %s", value_string);
+ } else if (strcmp(key, "Sender") == 0) {
+ g_variant_get(value, "s", &value_string);
+ messages_struct.message_items[i].sender = strdup(value_string);
+ BT_DBG(" Sender: %s", value_string);
+ } else if (strcmp(key, "SenderAddress") == 0) {
+ g_variant_get(value, "s", &value_string);
+ messages_struct.message_items[i].sender_address = strdup(value_string);
+ BT_DBG(" SenderAddress: %s", value_string);
+ } else if (strcmp(key, "ReplyTo") == 0) {
+ g_variant_get(value, "s", &value_string);
+ messages_struct.message_items[i].reply_to = strdup(value_string);
+ BT_DBG(" ReplyTo: %s", value_string);
+ } else if (strcmp(key, "Recipient") == 0) {
+ g_variant_get(value, "s", &value_string);
+ messages_struct.message_items[i].recipient = strdup(value_string);
+ BT_DBG(" Recipient: %s", value_string);
+ } else if (strcmp(key, "RecipientAddress") == 0) {
+ g_variant_get(value, "s", &value_string);
+ messages_struct.message_items[i].recipient_address = strdup(value_string);
+ BT_DBG(" RecipientAddress: %s", value_string);
+ } else if (strcmp(key, "Type") == 0) {
+ g_variant_get(value, "s", &value_string);
+ messages_struct.message_items[i].type = strdup(value_string);
+ BT_DBG(" Type: %s", value_string);
+ } else if (strcmp(key, "Size") == 0) {
+ g_variant_get(value, "t", &value_int);
+ messages_struct.message_items[i].size = value_int;
+ BT_DBG(" Size: %d", value_int);
+ } else if (strcmp(key, "Text") == 0) {
+ g_variant_get(value, "b", &value_bool);
+ messages_struct.message_items[i].is_text = value_bool ? 1 : 0;
+ BT_DBG(" Text: %s", value_bool ? "true" : "false");
+ } else if (strcmp(key, "Status") == 0) {
+ g_variant_get(value, "s", &value_string);
+ messages_struct.message_items[i].status = strdup(value_string);
+ BT_DBG(" Status: %s", value_string);
+ } else if (strcmp(key, "AttachmentSize") == 0) {
+ g_variant_get(value, "t", &value_int);
+ messages_struct.message_items[i].attachment_size = value_int;
+ BT_DBG(" AttachmentSize: %d", value_int);
+ } else if (strcmp(key, "Priority") == 0) {
+ g_variant_get(value, "b", &value_bool);
+ messages_struct.message_items[i].is_priority = value_bool ? 1 : 0;
+ BT_DBG(" Priority: %s", value_bool ? "true" : "false");
+ } else if (strcmp(key, "Read") == 0) {
+ g_variant_get(value, "b", &value_bool);
+ messages_struct.message_items[i].is_read = value_bool ? 1 : 0;
+ BT_DBG(" Read: %s", value_bool ? "true" : "false");
+ } else if (strcmp(key, "Sent") == 0) {
+ g_variant_get(value, "b", &value_bool);
+ messages_struct.message_items[i].is_sent = value_bool ? 1 : 0;
+ BT_DBG(" Sent: %s", value_bool ? "true" : "false");
+ } else if (strcmp(key, "Protected") == 0) {
+ g_variant_get(value, "b", &value_bool);
+ messages_struct.message_items[i].is_protected = value_bool ? 1 : 0;
+ BT_DBG(" Protected: %s", value_bool ? "true" : "false");
+ }
+ }
+ ++i;
+ }
+
+ _bt_common_event_cb(BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE,
+ result, &messages_struct,
+ event_info->cb, event_info->user_data);
+
+ __bt_remove_push_request_id(request_id);
+
+ while (--i >= 0) {
+ free(messages_struct.message_items[i].folder);
+ free(messages_struct.message_items[i].subject);
+ free(messages_struct.message_items[i].timestamp);
+ free(messages_struct.message_items[i].sender);
+ free(messages_struct.message_items[i].sender_address);
+ free(messages_struct.message_items[i].reply_to);
+ free(messages_struct.message_items[i].recipient);
+ free(messages_struct.message_items[i].recipient_address);
+ free(messages_struct.message_items[i].type);
+ free(messages_struct.message_items[i].status);
+ }
+ free(messages_struct.message_items);
+
+ g_variant_unref(messages_list_var);
+ }
// TODO MAP place for you else 3
// TODO MAP place for you else 4
// TODO MAP place for you else 5
diff --git a/bt-api/bt-map-client.c b/bt-api/bt-map-client.c
index 8d4610e..78b66e7 100644
--- a/bt-api/bt-map-client.c
+++ b/bt-api/bt-map-client.c
@@ -194,12 +194,34 @@ BT_EXPORT_API int bluetooth_map_client_list_messages(
const char *folder,
GVariant *filter)
{
- BT_DBG("bluetooth_map_client_list_messages");
- int result = BLUETOOTH_ERROR_INTERNAL;
+ BT_DBG("bluetooth_map_client_list_messages");
+ int result = 0;
- /* TODO: MAP */
+ BT_CHECK_ENABLED(return);
+ BT_CHECK_PARAMETER(session->session_path, return);
+ BT_CHECK_PARAMETER(folder, return);
+ BT_CHECK_PARAMETER(filter, 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);
+
+ char *filter_string = g_variant_print(filter, TRUE);
+
+ g_array_append_vals(in_param1, session->session_path, strlen(session->session_path)+1);
+ g_array_append_vals(in_param2, folder, strlen(folder)+1);
+ g_array_append_vals(in_param3, filter_string, strlen(filter_string)+1);
+
+ result = _bt_send_request_async(BT_OBEX_SERVICE, BT_MAP_LIST_MESSAGES,
+ 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);
+
+ free(filter_string);
+
+ return result;
}
BT_EXPORT_API int bluetooth_map_client_update_inbox(
diff --git a/bt-api/bt-request-sender.c b/bt-api/bt-request-sender.c
index 294b8ad..0f2bcf1 100644
--- a/bt-api/bt-request-sender.c
+++ b/bt-api/bt-request-sender.c
@@ -325,8 +325,11 @@ static void __send_request_cb(GDBusProxy *proxy,
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_MESSAGES) {
+ 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 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
diff --git a/bt-service/bt-request-handler.c b/bt-service/bt-request-handler.c
index ba982f6..8565ce8 100644
--- a/bt-service/bt-request-handler.c
+++ b/bt-service/bt-request-handler.c
@@ -2324,9 +2324,17 @@ int __bt_obexd_request(int function_name,
case BT_MAP_LIST_MESSAGES: {
BT_DBG("BT_MAP_LIST_MESSAGES");
- /* TODO: MAP */
+ char* session_id = (char*)g_variant_get_data(in_param1);
+ char* folder = (char*)g_variant_get_data(in_param2);
+ char* filter_string = (char*)g_variant_get_data(in_param3);
+ GVariant *filter = g_variant_parse(NULL, filter_string, NULL, NULL, NULL);
- result = BLUETOOTH_ERROR_NOT_SUPPORT;
+ result = _bt_map_client_list_messages(request_id, context, session_id, folder, filter);
+ if (result == BLUETOOTH_ERROR_NONE) {
+ BT_DBG("_bt_map_client_list_messages succeed");
+ } else {
+ BT_DBG("_bt_map_client_list_messages failed");
+ }
break;
}
diff --git a/bt-service/bt-service-event-sender.c b/bt-service/bt-service-event-sender.c
index ac53303..937df18 100644
--- a/bt-service/bt-service-event-sender.c
+++ b/bt-service/bt-service-event-sender.c
@@ -336,7 +336,10 @@ int _bt_send_event(int event_type, int event, GVariant *param)
signal = BT_MAP_FILTER_FIELDS_COMPLETE;
BT_INFO_C("Completed list filters field operation[MAP]");
break;
- // TODO MAP place for your own case 2
+ case BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE:
+ signal = BT_MAP_LIST_MESSAGES_COMPLETE;
+ BT_INFO_C("Completed list messages operation [MAP]");
+ break;
// TODO MAP place for your own case 3
// TODO MAP place for your own case 4
// TODO MAP place for your own case 5
diff --git a/bt-service/bt-service-map-client.c b/bt-service/bt-service-map-client.c
index d554e3d..f457155 100644
--- a/bt-service/bt-service-map-client.c
+++ b/bt-service/bt-service-map-client.c
@@ -546,18 +546,96 @@ int _bt_map_client_list_filter_fields(int request_id, GDBusMethodInvocation *con
return BLUETOOTH_ERROR_NONE;
}
+static void __bt_list_messages_cb(
+ GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
+{
+ BT_DBG("+");
+
+ GError *error = NULL;
+ GVariant *value, *in_param, *param;
+
+ int result = BLUETOOTH_ERROR_NONE;
+ int request_id;
+ int size = 0;
+
+ in_param = (GVariant*) user_data;
+ g_variant_get(in_param, "(i)", &request_id);
+
+ value = g_dbus_proxy_call_finish(proxy, res, &error);
+
+ if (error) {
+ BT_ERR("%s", error->message);
+ g_clear_error(&error);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ param = g_variant_new("(iiv)", result, request_id, value);
+ BT_DBG("RequestID[%d]", request_id);
+ result = _bt_send_event(BT_MAP_CLIENT_EVENT,
+ BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE, param);
+
+ g_variant_unref(value);
+ g_variant_unref(in_param);
+
+ BT_DBG("-");
+}
+
int _bt_map_client_list_messages(
+ int request_id,
+ GDBusMethodInvocation *context,
const char* session_id,
const char* folder,
GVariant *filter)
{
- BT_DBG("+");
+ BT_DBG("Entered _bt_map_client_list_messages with session id: \"%s\"", session_id);
+ BT_DBG("Entered folder: %s", folder);
+ 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");
+
+ GVariant *params = g_variant_new("(s@a{sv})", folder, filter);
+ GVariant *param = g_variant_new("(i)", request_id);
+
+ g_dbus_proxy_call(message_access_proxy,
+ "ListMessages", params,
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL,
+ (GAsyncReadyCallback)__bt_list_messages_cb,
+ (void*)param);
+ }
+ }
+
+ g_object_unref(message_access_proxy);
BT_DBG("-");
- return BLUETOOTH_ERROR_NONE;
+ return result;
}
int _bt_map_client_update_inbox(const char* session_id)
diff --git a/bt-service/include/bt-service-map-client.h b/bt-service/include/bt-service-map-client.h
index 4d9c772..fdfe63a 100644
--- a/bt-service/include/bt-service-map-client.h
+++ b/bt-service/include/bt-service-map-client.h
@@ -69,6 +69,8 @@ int _bt_map_client_list_folders(int request_id, GDBusMethodInvocation *context,
int _bt_map_client_list_filter_fields(int request_id, GDBusMethodInvocation *context,
const char* session_id);
int _bt_map_client_list_messages(
+ int request_id,
+ GDBusMethodInvocation *context,
const char* session_id,
const char* folder,
GVariant *filter);
diff --git a/include/bluetooth-api.h b/include/bluetooth-api.h
index a386950..74d330c 100644
--- a/include/bluetooth-api.h
+++ b/include/bluetooth-api.h
@@ -1805,10 +1805,80 @@ typedef struct {
} bt_map_client_session_info_s;
typedef struct {
+ int16_t offset;
+ int16_t maxcount;
+} bt_map_client_list_folders_filter_t;
+
+typedef struct {
+ int16_t offset;
+ int16_t max_count;
+ int8_t subject_length;
+ char *fields;
+ char *types;
+ char *period_begin;
+ char *period_end;
+ int is_read;
+ char *recipient;
+ char *sender;
+ int is_priority;
+} bt_map_client_list_messages_filter_t;
+
+typedef struct {
+ char *message_object_name;
+ char *folder;
+ char *subject;
+ char *timestamp;
+ char *sender;
+ char *sender_address;
+ char *reply_to;
+ char *recipient;
+ char *recipient_address;
+ char *type;
+ int64_t size;
+ int is_text;
+ char *status;
+ int64_t attachment_size;
+ int is_priority;
+ int is_read;
+ int is_sent;
+ int is_protected;
+} bt_map_client_message_item_t;
+
+typedef struct {
+ int is_transparent;
+ int is_retry;
+ char *charset;
+} bt_map_client_push_message_args_t;
+
+typedef struct {
+ char *folder;
+ char *subject;
+ char *timestamp;
+ char *sender;
+ char *sender_address;
+ char *reply_to;
+ char *recipient;
+ char *recipient_address;
+ char *type;
+ int64_t size;
+ char *status;
+ int is_priority;
+ int is_read;
+ int is_deleted;
+ int is_sent;
+ int is_protected;
+} bt_map_client_message_t;
+
+typedef struct {
char **names; // holding %size null-terminated folder names
- int size;
+ int64_t size;
} bt_map_client_folders_s;
+typedef struct {
+ bt_map_client_message_item_t *message_items;
+ int64_t size;
+} bt_map_client_message_items_s;
+
/**
* Callback pointer type
diff --git a/include/bt-internal-types.h b/include/bt-internal-types.h
index 6bbc033..551e6a5 100644
--- a/include/bt-internal-types.h
+++ b/include/bt-internal-types.h
@@ -503,7 +503,7 @@ typedef struct {
#define BT_MAP_DISCONNECTED "MapDisconnected"
#define BT_MAP_LIST_FOLDERS_COMPLETE "ListFoldersComplete"
#define BT_MAP_FILTER_FIELDS_COMPLETE "MapListFiltersFieldComplete"
-// TODO MAP place for your define 2
+#define BT_MAP_LIST_MESSAGES_COMPLETE "MapListMessagesComplete"
// TODO MAP place for your define 3
// TODO MAP place for your define 4
// TODO MAP place for your define 5
--
2.7.4