upload tizen1.0 source
[profile/ivi/obexd.git] / client / map.c
1 /*
2  *
3  *  OBEX Client
4  *
5  *  Copyright (C) 2011  Bartosz Szatkowski <bulislaw@linux.com> for Comarch
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
31 #include "log.h"
32
33 #include "map.h"
34 #include "transfer.h"
35 #include "session.h"
36 #include "driver.h"
37
38 #define OBEX_MAS_UUID \
39         "\xBB\x58\x2B\x40\x42\x0C\x11\xDB\xB0\xDE\x08\x00\x20\x0C\x9A\x66"
40 #define OBEX_MAS_UUID_LEN 16
41
42 #define MAP_INTERFACE  "org.openobex.MessageAccess"
43 #define MAS_UUID "00001132-0000-1000-8000-00805f9b34fb"
44
45 struct map_data {
46         struct obc_session *session;
47         DBusMessage *msg;
48 };
49
50 static DBusConnection *conn = NULL;
51
52 static void simple_cb(GObex *obex, GError *err, GObexPacket *rsp,
53                                                         gpointer user_data)
54 {
55         DBusMessage *reply;
56         struct map_data *map = user_data;
57         guint8 err_code = g_obex_packet_get_operation(rsp, NULL);
58
59         if (err != NULL)
60                 reply = g_dbus_create_error(map->msg,
61                                                 "org.openobex.Error.Failed",
62                                                 "%s", err->message);
63         else if (err_code != G_OBEX_RSP_SUCCESS)
64                 reply = g_dbus_create_error(map->msg,
65                                                 "org.openobex.Error.Failed",
66                                                 "%s (0x%02x)",
67                                                 g_obex_strerror(err_code),
68                                                 err_code);
69         else
70                 reply = dbus_message_new_method_return(map->msg);
71
72         g_dbus_send_message(conn, reply);
73         dbus_message_unref(map->msg);
74 }
75
76 static DBusMessage *map_setpath(DBusConnection *connection,
77                                         DBusMessage *message, void *user_data)
78 {
79         struct map_data *map = user_data;
80         const char *folder;
81         GObex *obex;
82         GError *err = NULL;
83
84         if (dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &folder,
85                                                 DBUS_TYPE_INVALID) == FALSE)
86                 return g_dbus_create_error(message,
87                                         "org.openobex.Error.InvalidArguments",
88                                         NULL);
89
90         obex = obc_session_get_obex(map->session);
91
92         g_obex_setpath(obex, folder, simple_cb, map, &err);
93         if (err != NULL) {
94                 DBusMessage *reply;
95                 reply =  g_dbus_create_error(message,
96                                                 "org.openobex.Error.Failed",
97                                                 "%s", err->message);
98                 g_error_free(err);
99                 return reply;
100         }
101
102         map->msg = dbus_message_ref(message);
103
104         return NULL;
105 }
106
107 static void buffer_cb(struct obc_session *session, GError *err,
108                                                         void *user_data)
109 {
110         struct obc_transfer *transfer = obc_session_get_transfer(session);
111         struct map_data *map = user_data;
112         DBusMessage *reply;
113         const char *buf;
114         int size;
115
116         if (err != NULL) {
117                 reply = g_dbus_create_error(map->msg,
118                                                 "org.openobex.Error.Failed",
119                                                 "%s", err->message);
120                 goto done;
121         }
122
123         buf = obc_transfer_get_buffer(transfer, &size);
124         if (size == 0)
125                 buf = "";
126
127         reply = g_dbus_create_reply(map->msg, DBUS_TYPE_STRING, &buf,
128                                                         DBUS_TYPE_INVALID);
129
130         obc_transfer_clear_buffer(transfer);
131
132 done:
133         g_dbus_send_message(conn, reply);
134         dbus_message_unref(map->msg);
135         obc_transfer_unregister(transfer);
136 }
137
138 static DBusMessage *map_get_folder_listing(DBusConnection *connection,
139                                         DBusMessage *message, void *user_data)
140 {
141         struct map_data *map = user_data;
142         int err;
143
144         err = obc_session_get(map->session, "x-obex/folder-listing",
145                                                         NULL, NULL, NULL, 0,
146                                                         buffer_cb, map);
147         if (err < 0)
148                 return g_dbus_create_error(message, "org.openobex.Error.Failed",
149                                                                         NULL);
150
151         map->msg = dbus_message_ref(message);
152
153         return NULL;
154 }
155
156 static DBusMessage *map_get_message_listing(DBusConnection *connection,
157                                         DBusMessage *message, void *user_data)
158 {
159         struct map_data *map = user_data;
160         int err;
161         const char *folder;
162         DBusMessageIter msg_iter;
163
164         dbus_message_iter_init(message, &msg_iter);
165
166         if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_STRING)
167                 return g_dbus_create_error(message,
168                                 "org.openobex.Error.InvalidArguments", NULL);
169
170         dbus_message_iter_get_basic(&msg_iter, &folder);
171
172         err = obc_session_get(map->session, "x-bt/MAP-msg-listing", folder,
173                                                         NULL, NULL, 0,
174                                                         buffer_cb, map);
175         if (err < 0)
176                 return g_dbus_create_error(message, "org.openobex.Error.Failed",
177                                                                         NULL);
178
179         map->msg = dbus_message_ref(message);
180
181         return NULL;
182 }
183
184 static GDBusMethodTable map_methods[] = {
185         { "SetFolder",          "s", "",        map_setpath,
186                                                 G_DBUS_METHOD_FLAG_ASYNC },
187         { "GetFolderListing",   "a{ss}", "s",   map_get_folder_listing,
188                                                 G_DBUS_METHOD_FLAG_ASYNC },
189         { "GetMessageListing",  "sa{ss}", "s",  map_get_message_listing,
190                                                 G_DBUS_METHOD_FLAG_ASYNC },
191         { }
192 };
193
194 static void map_free(void *data)
195 {
196         struct map_data *map = data;
197
198         obc_session_unref(map->session);
199         g_free(map);
200 }
201
202 static int map_probe(struct obc_session *session)
203 {
204         struct map_data *map;
205         const char *path;
206
207         path = obc_session_get_path(session);
208
209         DBG("%s", path);
210
211         map = g_try_new0(struct map_data, 1);
212         if (!map)
213                 return -ENOMEM;
214
215         map->session = obc_session_ref(session);
216
217         if (!g_dbus_register_interface(conn, path, MAP_INTERFACE, map_methods,
218                                         NULL, NULL, map, map_free)) {
219                 map_free(map);
220
221                 return -ENOMEM;
222         }
223
224         return 0;
225 }
226
227 static void map_remove(struct obc_session *session)
228 {
229         const char *path = obc_session_get_path(session);
230
231         DBG("%s", path);
232
233         g_dbus_unregister_interface(conn, path, MAP_INTERFACE);
234 }
235
236 static struct obc_driver map = {
237         .service = "MAP",
238         .uuid = MAS_UUID,
239         .target = OBEX_MAS_UUID,
240         .target_len = OBEX_MAS_UUID_LEN,
241         .probe = map_probe,
242         .remove = map_remove
243 };
244
245 int map_init(void)
246 {
247         int err;
248
249         DBG("");
250
251         conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
252         if (!conn)
253                 return -EIO;
254
255         err = obc_driver_register(&map);
256         if (err < 0) {
257                 dbus_connection_unref(conn);
258                 conn = NULL;
259                 return err;
260         }
261
262         return 0;
263 }
264
265 void map_exit(void)
266 {
267         DBG("");
268
269         dbus_connection_unref(conn);
270         conn = NULL;
271
272         obc_driver_unregister(&map);
273 }