#include <errno.h>
#include <glib.h>
#include <gdbus.h>
+#include <string.h>
#include "log.h"
#include "transfer.h"
#include "session.h"
#include "driver.h"
+#include "map_ap.h"
#include "mns.h"
#define OBEX_MNS_UUID \
#define OBEX_MNS_UUID_LEN 16
#define MNS_INTERFACE "org.openobex.MessageNotification"
+#define ERROR_INF MNS_INTERFACE ".Error"
#define MNS_UUID "00001133-0000-1000-8000-00805f9b34fb"
+enum msg_event_type {
+ EVENT_TYPE_NEW_MESSAGE,
+ EVENT_TYPE_DELIVERY_SUCCESS,
+ EVENT_TYPE_SENDING_SUCCESS,
+ EVENT_TYPE_DELIVERY_FAILURE,
+ EVENT_TYPE_SENDING_FAILURE,
+ EVENT_TYPE_MEMORY_FULL,
+ EVENT_TYPE_MEMORY_AVAILABLE,
+ EVENT_TYPE_MESSAGE_DELETED,
+ EVENT_TYPE_MESSAGE_SHIFT,
+ EVENT_TYPE_UNKNOWN,
+};
+
+struct sendevent_apparam {
+ uint8_t masinstanceid_tag;
+ uint8_t masinstanceid_len;
+ uint8_t masinstanceid;
+} __attribute__ ((packed));
+
struct mns_data {
struct obc_session *session;
DBusMessage *msg;
static DBusConnection *conn = NULL;
+static int get_event_type(gchar *event_type)
+{
+ DBG("event_type = %s\n", event_type);
+
+ if (!g_strcmp0(event_type, "NewMessage"))
+ return EVENT_TYPE_NEW_MESSAGE;
+ else if (!g_strcmp0(event_type, "DeliverySuccess"))
+ return EVENT_TYPE_DELIVERY_SUCCESS;
+ else if (!g_strcmp0(event_type, "SendingSuccess"))
+ return EVENT_TYPE_SENDING_SUCCESS;
+ else if (!g_strcmp0(event_type, "DeliveryFailure"))
+ return EVENT_TYPE_DELIVERY_FAILURE;
+ else if (!g_strcmp0(event_type, "SendingFailure"))
+ return EVENT_TYPE_SENDING_FAILURE;
+ else if (!g_strcmp0(event_type, "MemoryFull"))
+ return EVENT_TYPE_MEMORY_FULL;
+ else if (!g_strcmp0(event_type, "MemoryAvailable"))
+ return EVENT_TYPE_MEMORY_AVAILABLE;
+ else if (!g_strcmp0(event_type, "MessageDeleted"))
+ return EVENT_TYPE_MESSAGE_DELETED;
+ else if (!g_strcmp0(event_type, "MessageShift"))
+ return EVENT_TYPE_MESSAGE_SHIFT;
+ else
+ return EVENT_TYPE_UNKNOWN;
+
+}
+
+static gchar *generate_event_report(gchar *event_type,
+ gchar *handle, gchar *folder,
+ gchar *old_folder, gchar *msg_type)
+{
+ GString *buf;
+ int event;
+
+ event = get_event_type(event_type);
+ if (event == EVENT_TYPE_UNKNOWN)
+ return NULL;
+
+ buf = g_string_new("<MAP-event-report version=\"1.0\">\n");
+ g_string_append_printf(buf, "<event type=\"%s\" ", event_type);
+
+ if (event == EVENT_TYPE_MEMORY_FULL ||
+ event == EVENT_TYPE_MEMORY_AVAILABLE)
+ goto done;
+
+ g_string_append_printf(buf, "handle=\"%s\" ", handle);
+ g_string_append_printf(buf, "folder=\"%s\" ", folder);
+
+ if (event == EVENT_TYPE_MESSAGE_SHIFT)
+ g_string_append_printf(buf, " old_folder=\"%s\" ", old_folder);
+
+ g_string_append_printf(buf, "msg_type=\"%s\" ", msg_type);
+
+done:
+ g_string_append(buf, "/>\n</MAP-event-report>\n");
+
+ return g_string_free(buf, FALSE);
+}
+
static DBusMessage *send_event(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- return NULL;
+ struct mns_data *mns = user_data;
+ struct obc_transfer *transfer;
+ struct sendevent_apparam apparam;
+ gchar *event_type;
+ gchar *handle;
+ gchar *folder;
+ gchar *old_folder;
+ gchar *msg_type;
+ gchar *buf;
+ GError *err;
+ DBusMessage *reply;
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &event_type,
+ DBUS_TYPE_STRING, &handle,
+ DBUS_TYPE_STRING, &folder,
+ DBUS_TYPE_STRING, &old_folder,
+ DBUS_TYPE_STRING, &msg_type,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments",
+ NULL);
+
+ buf = generate_event_report(event_type, handle, folder,
+ old_folder, msg_type);
+ if (!buf)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments", NULL);
+
+ transfer = obc_transfer_put("x-bt/MAP-event-report", NULL, NULL,
+ buf, strlen(buf), &err);
+
+ g_free(buf);
+
+ if (transfer == NULL)
+ goto fail;
+
+ apparam.masinstanceid_tag = MAP_AP_MASINSTANCEID;
+ apparam.masinstanceid_len = 1;
+ /* Obexd currently supports single SDP for MAS */
+ apparam.masinstanceid = 0;
+
+ obc_transfer_set_params(transfer, &apparam, sizeof(apparam));
+
+ if (obc_session_queue(mns->session, transfer, NULL, NULL, &err))
+ return dbus_message_new_method_return(message);
+
+fail:
+ reply = g_dbus_create_error(message, ERROR_INF ".Failed", "%s",
+ err->message);
+ g_error_free(err);
+ return reply;
}
static GDBusMethodTable mns_methods[] = {
- { "SendEvent", "s", "", send_event,
+ { "SendEvent", "sssss", "", send_event,
G_DBUS_METHOD_FLAG_ASYNC },
{ }
};
map_ap_t *inparams;
map_ap_t *outparams;
gboolean ap_sent;
+#ifdef TIZEN_PATCH
+ int notification_status;
+ char *remote_addr;
+#endif
};
static const uint8_t MAS_TARGET[TARGET_SIZE] = {
static void mas_clean(struct mas_session *mas)
{
reset_request(mas);
+#ifdef TIZEN_PATCH
+ g_free(mas->remote_addr);
+#endif
g_free(mas);
}
static void *mas_connect(struct obex_session *os, int *err)
{
struct mas_session *mas;
+#ifdef TIZEN_PATCH
+ char *address;
+#endif
DBG("");
manager_register_session(os);
+#ifdef TIZEN_PATCH
+ if (obex_getpeername(os, &address) == 0) {
+ mas->remote_addr = address;
+ DBG("mas->remote_addr = %s \n", mas->remote_addr);
+ }
+#endif
+
return mas;
failed:
else
return mas;
}
+
+static void *notification_registration_open(const char *name, int oflag,
+ mode_t mode, void *driver_data, size_t *size, int *err)
+{
+ struct mas_session *mas = driver_data;
+ uint8_t status;
+
+ if (oflag == O_RDONLY) {
+ *err = -EBADR;
+ return NULL;
+ }
+
+ if (!map_ap_get_u8(mas->inparams, MAP_AP_NOTIFICATIONSTATUS, &status)) {
+ *err = -EBADR;
+ return NULL;
+ }
+
+ DBG("status: %d", status);
+
+ mas->notification_status = status;
+ *err = 0;
+ mas->finished = TRUE;
+ return mas;
+}
+
+static int notification_registration_close(void *obj)
+{
+ struct mas_session *mas = obj;
+
+ DBG("");
+
+ messages_notification_registration(mas->backend_data,
+ mas->remote_addr, mas->notification_status,
+ NULL, mas);
+
+ reset_request(mas);
+
+ return 0;
+}
#endif
static ssize_t any_get_next_header(void *object, void *buf, size_t mtu,
.target = MAS_TARGET,
.target_size = TARGET_SIZE,
.mimetype = "x-bt/MAP-NotificationRegistration",
+#ifdef TIZEN_PATCH
+ .open = notification_registration_open,
+ .close = notification_registration_close,
+#else
.open = any_open,
.close = any_close,
+#endif
.read = any_read,
.write = any_write,
};
#define QUERY_GET_MESSAGE "GetMessage"
#define QUERY_UPDATE_MESSAGE "UpdateMessage"
#define QUERY_MESSAGE_STATUS "MessageStatus"
+#define QUERY_NOTI_REGISTRATION "NotiRegistration"
#define BT_MAP_SERVICE_OBJECT_PATH "/org/bluez/map_agent"
#define BT_MAP_SERVICE_NAME "org.bluez.map_agent"
static DBusConnection *g_conn = NULL;
+struct mns_reg_data {
+ int notification_status;
+ char *remote_addr;
+};
+
struct message_folder {
char *name;
GSList *subfolders;
return 1;
}
+static gboolean notification_registration(gpointer user_data)
+{
+ DBG("+\n");
+ DBusMessage *message = NULL;
+ gboolean reg;
+ struct mns_reg_data *data = (struct mns_reg_data *)user_data;
+
+ message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
+ BT_MAP_SERVICE_OBJECT_PATH,
+ BT_MAP_SERVICE_INTERFACE,
+ QUERY_NOTI_REGISTRATION);
+ if (!message) {
+ error("Can't allocate new message");
+ goto done;
+ }
+
+ DBG("data->notification_status = %d\n", data->notification_status);
+
+ if (data->notification_status == 1)
+ reg = TRUE;
+ else
+ reg = FALSE;
+
+ dbus_message_append_args(message, DBUS_TYPE_STRING, &data->remote_addr,
+ DBUS_TYPE_BOOLEAN, ®,
+ DBUS_TYPE_INVALID);
+
+ if (dbus_connection_send(g_conn, message, NULL) == FALSE)
+ error("Could not send dbus message");
+
+done:
+ if (message)
+ dbus_message_unref(message);
+
+ g_free(data->remote_addr);
+ g_free(data);
+
+ DBG("-\n");
+ return FALSE;
+}
+
+int messages_notification_registration(void *session,
+ char *address, int status,
+ messages_notification_registration_cb callback,
+ void *user_data)
+{
+ DBG("+\n");
+ struct mns_reg_data *data = g_new0(struct mns_reg_data, 1);
+ data->notification_status = status;
+ data->remote_addr = g_strdup(address);
+
+ DBG("status = %d\n", status);
+
+ g_idle_add(notification_registration, data);
+ DBG("-\n");
+ return 1;
+}
+
void messages_abort(void *session)
{
}