#include <stdio.h>
#include <stdint.h>
#include <string.h>
+#include <stdarg.h>
#include <glib.h>
#include <stdlib.h>
#include <sys/types.h>
#include "phonebook.h"
#include <dbus/dbus.h>
-#define QUERY_GET_PHONEBOOK_SIZE "GetPhonebookSize"
-#define QUERY_GET_PHONEBOOK "GetPhonebook"
-#define QUERY_GET_CALLS "GetCalls"
+#define PHONEBOOK_DESTINATION "org.bluez.pb_agent"
+#define PHONEBOOK_PATH "/org/bluez/pb_agent"
+#define PHONEBOOK_INTERFACE "org.bluez.PbAgent"
+#define QUERY_GET_PHONEBOOK_SIZE "GetPhonebookSize"
+#define QUERY_GET_PHONEBOOK "GetPhonebook"
#define QUERY_GET_PHONEBOOK_LIST "GetPhonebookList"
-#define QUERY_GET_CALLS_LIST "GetCallsList"
-
#define QUERY_GET_PHONEBOOK_ENTRY "GetPhonebookEntry"
-#define QUERY_GET_CALLS_ENTRY "GetCallsEntry"
-
-#define QUERY_CALL_TYPE_INCOMING "incoming"
-#define QUERY_CALL_TYPE_OUTGOING "outgoing"
-#define QUERY_CALL_TYPE_MISSED "missed"
-#define QUERY_CALL_TYPE_COMBINED "combined"
struct phonebook_tizen_data {
phonebook_cb cb;
phonebook_entry_cb entry_cb;
phonebook_cache_ready_cb ready_cb;
- const char *id;
char *req_name;
};
-static void get_phonebook_reply(DBusPendingCall *call, void *user_data);
-static void get_phonebook_size_reply(DBusPendingCall *call, void *user_data);
-static void get_phonebook_list_reply(DBusPendingCall *call, void *user_data);
-static void get_phonebook_entry_reply(DBusPendingCall *call, void *user_data);
-int get_phonebook_data(const char *query, const char *call_type,
- struct phonebook_tizen_data *s_data);
-static gboolean get_sim_phonebook_reply(void *user_data);
-
static gboolean folder_is_valid(const char *folder)
{
if (folder == NULL)
return FALSE;
}
+static gboolean phonebook_request(struct phonebook_tizen_data *data,
+ const gchar *method,
+ DBusPendingCallNotifyFunction function,
+ int first_arg_type,
+ ...)
+{
+ DBusConnection *connection;
+ DBusPendingCall *call;
+ DBusMessage *message;
+
+ va_list args;
+
+ DBG("%s\n", method);
+
+ if (!method) {
+ error("Can't get method name");
+ return FALSE;
+ }
+
+
+ connection = dbus_bus_get(DBUS_BUS_SESSION, NULL);
+ if (!connection) {
+ error("Can't get on session bus");
+ return FALSE;
+ }
+
+ message = dbus_message_new_method_call(PHONEBOOK_DESTINATION,
+ PHONEBOOK_PATH,
+ PHONEBOOK_INTERFACE,
+ method);
+ if(!message) {
+ dbus_connection_unref(connection);
+ error("Can't Allocate new message");
+ return FALSE;
+ }
+
+ va_start(args, first_arg_type);
+ dbus_message_append_args_valist(message, first_arg_type, args);
+ va_end(args);
+
+ if (dbus_connection_send_with_reply(connection, message, &call, -1) == FALSE) {
+ dbus_message_unref(message);
+ dbus_connection_unref(connection);
+ return FALSE;
+ }
+ dbus_pending_call_set_notify(call, function, data, NULL);
+
+ dbus_pending_call_unref(call);
+ dbus_message_unref(message);
+ dbus_connection_unref(connection);
+
+ return TRUE;
+}
+
+static void get_phonebook_size_reply(DBusPendingCall *call, void *user_data)
+{
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ struct phonebook_tizen_data *s_data = user_data;
+ DBusError derr;
+ uint32_t phonebook_size;
+
+ DBG("");
+
+ if (!reply) {
+ DBG("Reply Error\n");
+ return;
+ }
+
+ dbus_error_init(&derr);
+ if (dbus_set_error_from_message(&derr, reply)) {
+ error("Replied with an error: %s, %s", derr.name, derr.message);
+ dbus_error_free(&derr);
+ phonebook_size = 0;
+ } else {
+ dbus_message_get_args(reply, NULL, DBUS_TYPE_UINT32,
+ &phonebook_size, DBUS_TYPE_INVALID);
+ DBG("phonebooksize:%d\n", phonebook_size);
+ }
+
+ s_data->cb(NULL, 0, phonebook_size, 0, TRUE, s_data->user_data);
+
+ dbus_message_unref(reply);
+}
+
+static void get_phonebook_reply(DBusPendingCall *call, void *user_data)
+{
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ struct phonebook_tizen_data *s_data = user_data;
+ DBusError derr;
+ GString *buffer;
+
+ guint new_missed_call = 0;
+
+ uint32_t count = 0;
+
+ DBG("");
+
+ if (!reply) {
+ DBG("Reply Error\n");
+ return;
+ }
+
+ buffer = g_string_new("");
+
+ dbus_error_init(&derr);
+ if (dbus_set_error_from_message(&derr, reply)) {
+ error("Replied with an error: %s, %s", derr.name, derr.message);
+ dbus_error_free(&derr);
+ } else {
+ DBusMessageIter iter;
+
+ dbus_message_iter_init(reply, &iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) {
+ DBusMessageIter recurse_iter;
+
+ dbus_message_iter_recurse(&iter, &recurse_iter);
+ while(dbus_message_iter_get_arg_type(&recurse_iter) == DBUS_TYPE_STRING) {
+ gchar *str;
+
+ dbus_message_iter_get_basic(&recurse_iter, &str);
+ dbus_message_iter_next(&recurse_iter);
+
+ g_string_append(buffer, str);
+
+ DBG("str:\n%s\n", str);
+
+ count++;
+ }
+ dbus_message_iter_next(&iter);
+ }
+
+ if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_UINT16)
+ dbus_message_iter_get_basic(&iter, &new_missed_call);
+
+ DBG("new_missed_call %d\n", new_missed_call);
+ }
+
+ s_data->cb(buffer->str, buffer->len, count, new_missed_call, 1, s_data->user_data);
+
+ g_string_free(buffer, TRUE);
+ dbus_message_unref(reply);
+}
+
+
+static void get_phonebook_list_reply(DBusPendingCall *call, void *user_data)
+{
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ DBusMessageIter iter, iter_struct, entry;
+ struct phonebook_tizen_data *data = user_data;
+ DBusError derr;
+ uint32_t handle = 0;
+ const char *name = NULL;
+ const char *tel = NULL;
+ char id[10];
+
+ if (!reply) {
+ DBG("Reply Error\n");
+ return;
+ }
+
+ dbus_error_init(&derr);
+ if (dbus_set_error_from_message(&derr, reply)) {
+ error("Replied with an error: %s, %s", derr.name, derr.message);
+ dbus_error_free(&derr);
+ } else {
+
+ dbus_message_iter_init(reply, &iter);
+
+ dbus_message_iter_recurse(&iter, &iter_struct);
+
+ while (dbus_message_iter_get_arg_type(&iter_struct) ==
+ DBUS_TYPE_STRUCT) {
+ dbus_message_iter_recurse(&iter_struct, &entry);
+
+ dbus_message_iter_get_basic(&entry, &name);
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &tel);
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_get_basic(&entry, &handle);
+
+ /*
+ DBG("[handle:%d name:%s tel:%s]\n", handle, name, tel);
+ */
+
+ snprintf(id, sizeof(id), "%d.vcf", handle);
+
+ data->entry_cb(id, handle, name, NULL, tel,
+ data->user_data);
+
+ dbus_message_iter_next(&iter_struct);
+ }
+ }
+
+ data->ready_cb(data->user_data);
+
+ dbus_message_unref(reply);
+}
+
+static void get_phonebook_entry_reply(DBusPendingCall *call, void *user_data)
+{
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ struct phonebook_tizen_data *s_data = user_data;
+ DBusError derr;
+ const char *phonebook_entry;
+
+ DBG("");
+
+ if (!reply) {
+ DBG("Reply Error\n");
+ return;
+ }
+
+ dbus_error_init(&derr);
+ if (dbus_set_error_from_message(&derr, reply)) {
+ error("Replied with an error: %s, %s", derr.name, derr.message);
+ dbus_error_free(&derr);
+ } else {
+ dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING,
+ &phonebook_entry, DBUS_TYPE_INVALID);
+ DBG("phonebook_entry:[%s]\n", phonebook_entry);
+ }
+
+ s_data->cb(phonebook_entry, strlen(phonebook_entry), 1, 0, TRUE,
+ s_data->user_data);
+
+ dbus_message_unref(reply);
+}
+
+static gboolean get_sim_phonebook_reply(void *user_data)
+{
+ struct phonebook_tizen_data *s_data = user_data;
+ uint32_t phonebook_size = 0;
+ int lastpart = 1;
+
+ DBG("");
+
+ /* We don't support phonebook of SIM
+ * Send dummy data */
+ s_data->cb(NULL, 0, phonebook_size, 0, lastpart, s_data->user_data);
+
+ return FALSE;
+}
+
int phonebook_init(void)
{
return 0;
int phonebook_pull_read(void *request)
{
- struct phonebook_tizen_data *s_data = request;
- const char *query;
- const char *call_type = NULL;
-
- DBG("name %s", s_data->req_name);
-
- s_data->reply_cb = get_phonebook_reply;
-
- if (g_strcmp0(s_data->req_name, "/telecom/ich.vcf") == 0) {
- call_type = QUERY_CALL_TYPE_INCOMING;
- query = QUERY_GET_CALLS;
- } else if (g_strcmp0(s_data->req_name, "/telecom/och.vcf") == 0) {
- call_type = QUERY_CALL_TYPE_OUTGOING;
- query = QUERY_GET_CALLS;
- } else if (g_strcmp0(s_data->req_name, "/telecom/mch.vcf") == 0) {
- call_type = QUERY_CALL_TYPE_MISSED;
- query = QUERY_GET_CALLS;
- } else if (g_strcmp0(s_data->req_name, "/telecom/cch.vcf") == 0) {
- call_type = QUERY_CALL_TYPE_COMBINED;
- query = QUERY_GET_CALLS;
- } else if (g_strcmp0(s_data->req_name, "/SIM1/telecom/pb.vcf") == 0) {
- g_idle_add(get_sim_phonebook_reply, s_data);
+ struct phonebook_tizen_data *data = request;
+
+ DBG("name %s", data->req_name);
+
+ if (data->params->maxlistcount == 0) {
+ phonebook_request(data,
+ QUERY_GET_PHONEBOOK_SIZE,
+ get_phonebook_size_reply,
+ DBUS_TYPE_STRING, &data->req_name,
+ DBUS_TYPE_INVALID);
+ return 0;
+ }
+
+ if (g_strcmp0(data->req_name, "/SIM1/telecom/pb.vcf") == 0) {
+ g_idle_add(get_sim_phonebook_reply, data);
return 0;
- } else if (s_data->params->maxlistcount == 0) {
- query = QUERY_GET_PHONEBOOK_SIZE;
- s_data->reply_cb = get_phonebook_size_reply;
- } else {
- query = QUERY_GET_PHONEBOOK;
}
- get_phonebook_data(query, call_type, s_data);
+ phonebook_request(data,
+ QUERY_GET_PHONEBOOK,
+ get_phonebook_reply,
+ DBUS_TYPE_STRING, &data->req_name,
+ DBUS_TYPE_UINT64, &data->params->filter,
+ DBUS_TYPE_BYTE, &data->params->format,
+ DBUS_TYPE_UINT16, &data->params->maxlistcount,
+ DBUS_TYPE_UINT16, &data->params->liststartoffset,
+ DBUS_TYPE_INVALID);
return 0;
}
const struct apparam_field *params, phonebook_cb cb,
void *user_data, int *err)
{
- struct phonebook_tizen_data *s_data;
- DBusPendingCallNotifyFunction reply_cb;
- const char *query;
-
- DBG("folder %s id %s", folder, id);
+ struct phonebook_tizen_data *data;
- if (g_strcmp0(folder, "/telecom/pb") == 0) {
- query = QUERY_GET_PHONEBOOK_ENTRY;
- } else {
- query = QUERY_GET_CALLS_ENTRY;
+ if (!g_str_has_suffix(id, ".vcf")) {
+ DBG("invaild request");
+ if (err)
+ *err = -EBADR;
+ return NULL;
}
+ DBG("folder %s id %s", folder, id);
- reply_cb = get_phonebook_entry_reply;
-
- s_data = g_new0(struct phonebook_tizen_data, 1);
- s_data->params = params;
- s_data->user_data = user_data;
- s_data->cb = cb;
- s_data->reply_cb = reply_cb;
- s_data->id = id;
-
- get_phonebook_data(query, NULL, s_data);
+ data = g_new0(struct phonebook_tizen_data, 1);
+ data->params = params;
+ data->user_data = user_data;
+ data->cb = cb;
- if (err)
- *err = 0;
+ phonebook_request(data,
+ QUERY_GET_PHONEBOOK_ENTRY,
+ get_phonebook_entry_reply,
+ DBUS_TYPE_STRING, &folder,
+ DBUS_TYPE_STRING, &id,
+ DBUS_TYPE_UINT64, &data->params->filter,
+ DBUS_TYPE_BYTE, &data->params->format,
+ DBUS_TYPE_INVALID);
return NULL;
}
void *phonebook_create_cache(const char *name, phonebook_entry_cb entry_cb,
phonebook_cache_ready_cb ready_cb, void *user_data, int *err)
{
- struct phonebook_tizen_data *s_data;
- DBusPendingCallNotifyFunction reply_cb;
- const char *query;
- const char *call_type = NULL;
+ struct phonebook_tizen_data *data;
+ gboolean req = FALSE;
DBG("name %s", name);
- if (g_strcmp0(name, "/telecom/pb") == 0) {
- query = QUERY_GET_PHONEBOOK_LIST;
- } else if (g_strcmp0(name, "/telecom/ich") == 0) {
- call_type = QUERY_CALL_TYPE_INCOMING;
- query = QUERY_GET_CALLS_LIST;
- } else if (g_strcmp0(name, "/telecom/och") == 0) {
- call_type = QUERY_CALL_TYPE_OUTGOING;
- query = QUERY_GET_CALLS_LIST;
- } else if (g_strcmp0(name, "/telecom/mch") == 0) {
- call_type = QUERY_CALL_TYPE_MISSED;
- query = QUERY_GET_CALLS_LIST;
- } else if (g_strcmp0(name, "/telecom/cch") == 0) {
- call_type = QUERY_CALL_TYPE_COMBINED;
- query = QUERY_GET_CALLS_LIST;
- } else {
- if (err)
- *err = -ENOENT;
- return NULL;
- }
-
- reply_cb = get_phonebook_list_reply;
-
- s_data = g_new0(struct phonebook_tizen_data, 1);
- s_data->user_data = user_data;
- s_data->entry_cb = entry_cb;
- s_data->ready_cb = ready_cb;
- s_data->reply_cb = reply_cb;
- s_data->params = NULL;
-
- get_phonebook_data(query, call_type, s_data);
-
- if (err)
- *err = 0;
-
- return NULL;
-}
-
-static void get_phonebook_reply(DBusPendingCall *call, void *user_data)
-{
- DBusMessage *reply = dbus_pending_call_steal_reply(call);
- DBusMessageIter iter, element;
- struct phonebook_tizen_data *s_data = user_data;
- DBusError derr;
- uint32_t phonebook_size = 0;
- GString *buffer;
- int lastpart = 1;
-
- DBG("");
-
- buffer = g_string_new("");
-
- dbus_error_init(&derr);
- if (dbus_set_error_from_message(&derr, reply)) {
- error("Replied with an error: %s, %s", derr.name, derr.message);
- dbus_error_free(&derr);
- } else {
- dbus_message_iter_init(reply, &iter);
-
- if (dbus_message_iter_get_arg_type(&iter) ==
- DBUS_TYPE_INT32) {
- dbus_message_iter_get_basic(&iter, &lastpart);
- dbus_message_iter_next(&iter);
- }
-
- dbus_message_iter_recurse(&iter, &element);
-
- while(dbus_message_iter_get_arg_type(&element) !=
- DBUS_TYPE_INVALID) {
- char *arg;
-
- if (dbus_message_iter_get_arg_type(&element) !=
- DBUS_TYPE_STRING) {
- DBG("element is not a string");
- dbus_message_iter_next(&element);
- continue;
- }
-
- dbus_message_iter_get_basic(&element, &arg);
-
- g_string_append(buffer, arg);
-
- dbus_message_iter_next(&element);
-
- phonebook_size++;
- }
-
- DBG("phonebooksize : %d\n", phonebook_size);
- }
-
- s_data->cb(buffer->str, buffer->len, phonebook_size, 0, lastpart,
- s_data->user_data);
-
- g_string_free(buffer, TRUE);
-
- dbus_message_unref(reply);
-}
-
-static void get_phonebook_size_reply(DBusPendingCall *call, void *user_data)
-{
- DBusMessage *reply = dbus_pending_call_steal_reply(call);
- struct phonebook_tizen_data *s_data = user_data;
- DBusError derr;
- uint32_t phonebook_size;
-
- DBG("");
-
- dbus_error_init(&derr);
- if (dbus_set_error_from_message(&derr, reply)) {
- error("Replied with an error: %s, %s", derr.name, derr.message);
- dbus_error_free(&derr);
- phonebook_size = 0;
- } else {
- dbus_message_get_args(reply, NULL, DBUS_TYPE_UINT32,
- &phonebook_size, DBUS_TYPE_INVALID);
- DBG("phonebooksize:%d\n", phonebook_size);
- }
-
- s_data->cb(NULL, 0, phonebook_size, 0, TRUE, s_data->user_data);
-
- dbus_message_unref(reply);
-}
-
-static void get_phonebook_list_reply(DBusPendingCall *call, void *user_data)
-{
- DBusMessage *reply = dbus_pending_call_steal_reply(call);
- DBusMessageIter iter, iter_struct, entry;
- struct phonebook_tizen_data *s_data = user_data;
- DBusError derr;
- uint32_t handle = 0;
- const char *name = NULL;
- const char *tel = NULL;
- char id[10];
-
- DBG("");
-
- dbus_error_init(&derr);
- if (dbus_set_error_from_message(&derr, reply)) {
- error("Replied with an error: %s, %s", derr.name, derr.message);
- dbus_error_free(&derr);
- } else {
-
- dbus_message_iter_init(reply, &iter);
-
- dbus_message_iter_recurse(&iter, &iter_struct);
-
- while (dbus_message_iter_get_arg_type(&iter_struct) ==
- DBUS_TYPE_STRUCT) {
- dbus_message_iter_recurse(&iter_struct, &entry);
-
- dbus_message_iter_get_basic(&entry, &name);
- dbus_message_iter_next(&entry);
- dbus_message_iter_get_basic(&entry, &tel);
- dbus_message_iter_next(&entry);
- dbus_message_iter_get_basic(&entry, &handle);
-
- //DBG("[handle:%d name:%s tel:%s]\n", handle, name, tel);
-
- snprintf(id, sizeof(id), "%d.vcf", handle);
-
- s_data->entry_cb(id, handle, name, NULL, tel,
- s_data->user_data);
-
- dbus_message_iter_next(&iter_struct);
- }
- }
-
- s_data->ready_cb(s_data->user_data);
-
- dbus_message_unref(reply);
-}
-
-static void get_phonebook_entry_reply(DBusPendingCall *call, void *user_data)
-{
- DBusMessage *reply = dbus_pending_call_steal_reply(call);
- struct phonebook_tizen_data *s_data = user_data;
- DBusError derr;
- const char *phonebook_entry;
-
- DBG("");
-
- dbus_error_init(&derr);
- if (dbus_set_error_from_message(&derr, reply)) {
- error("Replied with an error: %s, %s", derr.name, derr.message);
- dbus_error_free(&derr);
- } else {
- dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING,
- &phonebook_entry, DBUS_TYPE_INVALID);
- DBG("phonebook_entry:[%s]\n", phonebook_entry);
- }
-
- s_data->cb(phonebook_entry, strlen(phonebook_entry), 1, 0, TRUE,
- s_data->user_data);
-
- dbus_message_unref(reply);
-}
-
-int get_phonebook_data(const char *query, const char *call_type,
- struct phonebook_tizen_data *s_data)
-{
- DBusConnection *conn;
- DBusPendingCall *call;
- DBusMessage *message;
-
- DBG("call_type:%s", call_type);
-
- conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
- if (!conn) {
- error("Can't get on session bus");
- return -1;
- }
-
- message = dbus_message_new_method_call("org.bluez.pb_agent",
- "/org/bluez/pb_agent",
- "org.bluez.PbAgent",
- query);
- if (!message) {
- error("Can't allocate new message");
- return -1;
- }
-
- if (s_data->id) {
- DBG("phonebook_get_entry");
- dbus_message_append_args(message, DBUS_TYPE_STRING, &s_data->id,
- DBUS_TYPE_INVALID);
- } else if (s_data->params) {
- DBG("phonebook_pull_read");
- if (call_type)
- dbus_message_append_args(message, DBUS_TYPE_UINT16,
- &s_data->params->maxlistcount,
- DBUS_TYPE_UINT16,
- &s_data->params->liststartoffset,
- DBUS_TYPE_STRING, &call_type,
- DBUS_TYPE_INVALID);
+ data = g_new0(struct phonebook_tizen_data, 1);
+ data->user_data = user_data;
+ data->entry_cb = entry_cb;
+ data->ready_cb = ready_cb;
+
+ req = phonebook_request(data,
+ QUERY_GET_PHONEBOOK_LIST,
+ get_phonebook_list_reply,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID);
+
+ if (*err) {
+ if (req)
+ *err = 0;
else
- dbus_message_append_args(message, DBUS_TYPE_UINT16,
- &s_data->params->maxlistcount,
- DBUS_TYPE_UINT16,
- &s_data->params->liststartoffset,
- DBUS_TYPE_INVALID);
-
- } else if (call_type) {
- DBG("phonebook_create_cache");
- dbus_message_append_args(message, DBUS_TYPE_STRING, &call_type,
- DBUS_TYPE_INVALID);
- }
-
- if (dbus_connection_send_with_reply(conn, message, &call,
- -1) == FALSE) {
- error("Could not send dbus message");
- dbus_message_unref(message);
- return -1;
+ *err = -ENOENT;
}
- dbus_pending_call_set_notify(call, s_data->reply_cb, s_data, NULL);
- dbus_message_unref(message);
-
- //dbus_connection_unref(conn);
-
- return 0;
-}
-
-static gboolean get_sim_phonebook_reply(void *user_data)
-{
- struct phonebook_tizen_data *s_data = user_data;
- uint32_t phonebook_size = 0;
- int lastpart = 1;
-
- DBG("");
-
- /* We don't support phonebook of SIM
- * Send dummy data */
- s_data->cb(NULL, 0, phonebook_size, 0, lastpart, s_data->user_data);
-
- return FALSE;
+ return data;
}
-