Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / obexd / client / mns-tizen.c
1 /*
2  *
3  *  OBEX Client
4  *
5  *  Copyright (C) 2012 Samsung Electronics Co., Ltd.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <errno.h>
28 #include <glib.h>
29 #include <gdbus.h>
30 #include <string.h>
31
32 #include "log.h"
33
34 #include "transfer.h"
35 #include "session.h"
36 #include "driver.h"
37 #include "map_ap.h"
38 #include "mns-tizen.h"
39
40 #define OBEX_MNS_UUID \
41         "\xBB\x58\x2B\x41\x42\x0C\x11\xDB\xB0\xDE\x08\x00\x20\x0C\x9A\x66"
42 #define OBEX_MNS_UUID_LEN 16
43
44 #define MNS_INTERFACE  "org.openobex.MessageNotification"
45 #define ERROR_INF MNS_INTERFACE ".Error"
46 #define MNS_UUID "00001133-0000-1000-8000-00805f9b34fb"
47
48 enum msg_event_type {
49         EVENT_TYPE_NEW_MESSAGE,
50         EVENT_TYPE_DELIVERY_SUCCESS,
51         EVENT_TYPE_SENDING_SUCCESS,
52         EVENT_TYPE_DELIVERY_FAILURE,
53         EVENT_TYPE_SENDING_FAILURE,
54         EVENT_TYPE_MEMORY_FULL,
55         EVENT_TYPE_MEMORY_AVAILABLE,
56         EVENT_TYPE_MESSAGE_DELETED,
57         EVENT_TYPE_MESSAGE_SHIFT,
58         EVENT_TYPE_UNKNOWN,
59 };
60
61 struct sendevent_apparam {
62         uint8_t     masinstanceid_tag;
63         uint8_t     masinstanceid_len;
64         uint8_t     masinstanceid;
65 } __attribute__ ((packed));
66
67 struct mns_data {
68         struct obc_session *session;
69         DBusMessage *msg;
70 };
71
72 static DBusConnection *conn = NULL;
73
74 static int get_event_type(gchar *event_type)
75 {
76         DBG("event_type = %s\n", event_type);
77
78         if (!g_strcmp0(event_type, "NewMessage"))
79                 return EVENT_TYPE_NEW_MESSAGE;
80         else if (!g_strcmp0(event_type, "DeliverySuccess"))
81                 return EVENT_TYPE_DELIVERY_SUCCESS;
82         else if (!g_strcmp0(event_type, "SendingSuccess"))
83                 return EVENT_TYPE_SENDING_SUCCESS;
84         else if (!g_strcmp0(event_type, "DeliveryFailure"))
85                 return EVENT_TYPE_DELIVERY_FAILURE;
86         else if (!g_strcmp0(event_type, "SendingFailure"))
87                 return EVENT_TYPE_SENDING_FAILURE;
88         else if (!g_strcmp0(event_type, "MemoryFull"))
89                 return EVENT_TYPE_MEMORY_FULL;
90         else if (!g_strcmp0(event_type, "MemoryAvailable"))
91                 return EVENT_TYPE_MEMORY_AVAILABLE;
92         else if (!g_strcmp0(event_type, "MessageDeleted"))
93                 return EVENT_TYPE_MESSAGE_DELETED;
94         else if (!g_strcmp0(event_type, "MessageShift"))
95                 return EVENT_TYPE_MESSAGE_SHIFT;
96         else
97                 return EVENT_TYPE_UNKNOWN;
98
99 }
100
101 static gchar *generate_event_report(gchar *event_type,
102                                 guint64 handle, gchar *folder,
103                                 gchar *old_folder, gchar *msg_type)
104 {
105         GString *buf;
106         int event;
107
108         event = get_event_type(event_type);
109         if (event == EVENT_TYPE_UNKNOWN)
110                 return NULL;
111
112         buf = g_string_new("<MAP-event-report version=\"1.0\">");
113         g_string_append_printf(buf, "<event type=\"%s\" ", event_type);
114
115         if (event == EVENT_TYPE_MEMORY_FULL ||
116                         event == EVENT_TYPE_MEMORY_AVAILABLE)
117                 goto done;
118
119         g_string_append_printf(buf, "handle=\"%llx\" ", handle);
120         g_string_append_printf(buf, "folder=\"%s\" ", folder);
121
122         if (event == EVENT_TYPE_MESSAGE_SHIFT)
123                 g_string_append_printf(buf, " old_folder=\"%s\" ", old_folder);
124
125         g_string_append_printf(buf, "msg_type=\"%s\" ", msg_type);
126
127 done:
128         g_string_append(buf, "/></MAP-event-report>");
129
130         return g_string_free(buf, FALSE);
131 }
132
133 static DBusMessage *send_event(DBusConnection *connection,
134                                         DBusMessage *message, void *user_data)
135 {
136         struct mns_data *mns = user_data;
137         struct obc_transfer *transfer;
138         struct sendevent_apparam apparam;
139         gchar *event_type;
140         gchar *folder;
141         gchar *old_folder;
142         gchar *msg_type;
143         gchar *buf;
144         guint64 handle;
145         GError *err;
146         DBusMessage *reply;
147
148         if (dbus_message_get_args(message, NULL,
149                         DBUS_TYPE_STRING, &event_type,
150                         DBUS_TYPE_UINT64, &handle,
151                         DBUS_TYPE_STRING, &folder,
152                         DBUS_TYPE_STRING, &old_folder,
153                         DBUS_TYPE_STRING, &msg_type,
154                         DBUS_TYPE_INVALID) == FALSE)
155                 return g_dbus_create_error(message,
156                                         "org.openobex.Error.InvalidArguments",
157                                         NULL);
158
159         buf = generate_event_report(event_type, handle, folder,
160                                 old_folder, msg_type);
161         if (!buf)
162                 return g_dbus_create_error(message,
163                                 "org.openobex.Error.InvalidArguments", NULL);
164
165         transfer = obc_transfer_put("x-bt/MAP-event-report", NULL, NULL,
166                                 buf, strlen(buf), &err);
167
168         g_free(buf);
169
170         if (transfer == NULL)
171                 goto fail;
172
173         apparam.masinstanceid_tag = MAP_AP_MASINSTANCEID;
174         apparam.masinstanceid_len = 1;
175         /* Obexd currently supports single SDP for MAS */
176         apparam.masinstanceid = 0;
177
178         obc_transfer_set_apparam(transfer, &apparam);
179
180         if (obc_session_queue(mns->session, transfer, NULL, NULL, &err))
181                 return dbus_message_new_method_return(message);
182
183 fail:
184         reply = g_dbus_create_error(message, ERROR_INF ".Failed", "%s",
185                                                                 err->message);
186         g_error_free(err);
187         return reply;
188 }
189
190 static GDBusMethodTable mns_methods[] = {
191         { GDBUS_ASYNC_METHOD("SendEvent",
192                 GDBUS_ARGS({ "event_type", "s" }, { "handle", "t" },
193                                 { "folder", "s" }, { "old_folder", "s" },
194                                 { "msg_type", "s" }),
195                 NULL,
196                 send_event) },
197         { }
198 };
199
200 static void mns_free(void *data)
201 {
202         struct mns_data *mns = data;
203
204         obc_session_unref(mns->session);
205         g_free(mns);
206 }
207
208 static int mns_probe(struct obc_session *session)
209 {
210         struct mns_data *mns;
211         const char *path;
212
213         path = obc_session_get_path(session);
214
215         DBG("%s", path);
216
217         mns = g_try_new0(struct mns_data, 1);
218         if (!mns)
219                 return -ENOMEM;
220
221         mns->session = obc_session_ref(session);
222
223         if (!g_dbus_register_interface(conn, path, MNS_INTERFACE, mns_methods,
224                                         NULL, NULL, mns, mns_free)) {
225                 mns_free(mns);
226                 return -ENOMEM;
227         }
228
229         return 0;
230 }
231
232 static void mns_remove(struct obc_session *session)
233 {
234         const char *path = obc_session_get_path(session);
235
236         DBG("%s", path);
237
238         g_dbus_unregister_interface(conn, path, MNS_INTERFACE);
239 }
240
241 static struct obc_driver mns = {
242         .service = "MNS",
243         .uuid = MNS_UUID,
244         .target = OBEX_MNS_UUID,
245         .target_len = OBEX_MNS_UUID_LEN,
246         .probe = mns_probe,
247         .remove = mns_remove
248 };
249
250 int mns_init(void)
251 {
252         int err;
253
254         DBG("");
255
256         conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
257         if (!conn)
258                 return -EIO;
259
260         err = obc_driver_register(&mns);
261         if (err < 0) {
262                 dbus_connection_unref(conn);
263                 conn = NULL;
264                 return err;
265         }
266
267         return 0;
268 }
269
270 void mns_exit(void)
271 {
272         DBG("");
273
274         dbus_connection_unref(conn);
275         conn = NULL;
276
277         obc_driver_unregister(&mns);
278 }