2 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include <dbus/dbus.h>
24 #include <dbus/dbus-glib.h>
25 #include <dbus/dbus-glib-lowlevel.h>
26 #include <dbus/dbus-glib-bindings.h>
29 #include <sys/socket.h>
34 #include "serial_private.h"
39 #define LOG_TAG "CAPI_NETWORK_SERIAL"
41 #define DBG(fmt, args...) SLOGD(fmt, ##args)
42 #define ERR(fmt, args...) SLOGE(fmt, ##args)
44 #define SERIAL_SOCKET_PATH "/tmp/.dr_common_stream"
45 #define SERIAL_BUF_SIZE 65536
46 #define SERIAL_INTERFACE "User.Data.Router.Introspectable"
48 DBusConnection *dbus_connection = NULL;
54 static gboolean __g_io_client_handler(GIOChannel *io, GIOCondition cond, void *data)
57 serial_s *pHandle = (serial_s *)data;
61 if (pHandle->data_handler.callback) {
62 char buffer[SERIAL_BUF_SIZE] = { 0 };
64 fd = g_io_channel_unix_get_fd(io);
65 len = recv(fd, buffer, SERIAL_BUF_SIZE, 0);
67 ERR("Error occured or the peer is shutdownd. [%d]\n", len);
68 ((serial_state_changed_cb)pHandle->state_handler.callback)
71 pHandle->state_handler.user_data);
75 ((serial_data_received_cb)pHandle->data_handler.callback)
76 (buffer, len, pHandle->data_handler.user_data);
81 static void __init_client_giochannel(void *data)
84 serial_s *pHandle = (serial_s *)data;
88 io = g_io_channel_unix_new(pHandle->client_socket);
89 g_io_channel_set_close_on_unref(io, TRUE);
90 pHandle->g_watch_id = g_io_add_watch(io,
91 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
92 __g_io_client_handler, pHandle);
93 g_io_channel_unref(io);
97 static int __connect_to_serial_server(void *data)
99 int client_socket = -1;
100 struct sockaddr_un server_addr;
101 serial_s *pHandle = (serial_s *)data;
105 client_socket = socket(AF_UNIX, SOCK_STREAM, 0);
106 if (client_socket < 0) {
107 ERR("Create socket failed\n");
111 memset(&server_addr, 0, sizeof(server_addr));
112 server_addr.sun_family = AF_UNIX;
113 g_strlcpy(server_addr.sun_path, SERIAL_SOCKET_PATH, sizeof(server_addr.sun_path));
115 if (connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
116 ERR("Connect failed\n");
117 close(client_socket);
120 pHandle->client_socket = client_socket;
122 __init_client_giochannel(pHandle);
124 return client_socket;
128 static DBusHandlerResult __dbus_event_filter(DBusConnection *sys_conn,
129 DBusMessage *msg, void *data)
131 static int socket = -1;
132 const char *path = dbus_message_get_path(msg);
134 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
135 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
137 if (path == NULL || strcmp(path, "/") == 0)
138 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
140 if (dbus_message_is_signal(msg, SERIAL_INTERFACE, "serial_status")) {
142 dbus_message_get_args(msg, NULL,
143 DBUS_TYPE_INT32, &res,
146 serial_s *pHandle = (serial_s *)data;
147 if (res == SERIAL_OPENED) {
148 socket = __connect_to_serial_server(pHandle);
150 ((serial_state_changed_cb)pHandle->state_handler.callback)
151 (SERIAL_ERROR_OPERATION_FAILED,
153 pHandle->state_handler.user_data);
154 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
157 ((serial_state_changed_cb)pHandle->state_handler.callback)
160 pHandle->state_handler.user_data);
161 } else if (res == SERIAL_CLOSED) {
163 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
165 ((serial_state_changed_cb)pHandle->state_handler.callback)
168 pHandle->state_handler.user_data);
171 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
174 return DBUS_HANDLER_RESULT_HANDLED;
177 int __send_serial_ready_done_signal(void)
179 DBusMessage *msg = NULL;
180 const char *res = "OK";
182 if(dbus_connection == NULL)
183 return SERIAL_ERROR_INVALID_OPERATION;
185 msg = dbus_message_new_signal("/Network/Serial",
186 "Capi.Network.Serial",
189 ERR("Unable to allocate D-Bus signal\n");
190 return SERIAL_ERROR_OPERATION_FAILED;
193 if (!dbus_message_append_args(msg,
194 DBUS_TYPE_STRING, &res,
195 DBUS_TYPE_INVALID)) {
196 ERR("Event sending failed\n");
197 dbus_message_unref(msg);
198 return SERIAL_ERROR_OPERATION_FAILED;
201 dbus_connection_send(dbus_connection, msg, NULL);
202 dbus_message_unref(msg);
203 return SERIAL_ERROR_NONE;
207 static int __serial_set_state_changed_cb(serial_h serial, void *callback, void *user_data)
210 ERR("Invalid parameter\n");
211 return SERIAL_ERROR_INVALID_PARAMETER;
214 serial_s *pHandle = (serial_s *)serial;
217 pHandle->state_handler.callback = callback;
218 pHandle->state_handler.user_data = user_data;
220 pHandle->state_handler.callback = NULL;
221 pHandle->state_handler.user_data = NULL;
224 return SERIAL_ERROR_NONE;
227 static int __serial_set_data_received_cb(serial_h serial, void *callback, void *user_data)
230 ERR("Invalid parameter\n");
231 return SERIAL_ERROR_INVALID_PARAMETER;
234 serial_s *pHandle = (serial_s *)serial;
237 pHandle->data_handler.callback = callback;
238 pHandle->data_handler.user_data = user_data;
240 pHandle->data_handler.callback = NULL;
241 pHandle->data_handler.user_data = NULL;
244 return SERIAL_ERROR_NONE;
253 int serial_create(serial_h *serial)
255 DBG("%s\n", __FUNCTION__);
257 GError *error = NULL;
258 DBusError dbus_error;
259 serial_s *pHandle = NULL;
262 return SERIAL_ERROR_INVALID_PARAMETER;
264 pHandle = (serial_s *)g_try_malloc0(sizeof(serial_s));
266 return SERIAL_ERROR_OUT_OF_MEMORY;
270 pHandle->client_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
272 ERR("Couldn't connect to the System bus[%s]",
276 return SERIAL_ERROR_OPERATION_FAILED;
278 dbus_connection = dbus_g_connection_get_connection(pHandle->client_bus);
280 /* Add the filter for network client functions */
281 dbus_error_init(&dbus_error);
282 dbus_connection_add_filter(dbus_connection, __dbus_event_filter, pHandle, NULL);
283 dbus_bus_add_match(dbus_connection,
284 "type=signal,interface=" SERIAL_INTERFACE
285 ",member=serial_status", &dbus_error);
286 if (dbus_error_is_set(&dbus_error)) {
287 ERR("Fail to add dbus filter signal\n");
288 dbus_error_free(&dbus_error);
290 return SERIAL_ERROR_OPERATION_FAILED;
293 *serial = (serial_h)pHandle;
295 return SERIAL_ERROR_NONE;
299 int serial_open(serial_h serial)
301 DBG("%s\n", __FUNCTION__);
304 ERR("Invalid parameter\n");
305 return SERIAL_ERROR_INVALID_PARAMETER;
308 return __send_serial_ready_done_signal();
311 int serial_close(serial_h serial)
313 DBG("%s\n", __FUNCTION__);
316 ERR("Invalid parameter\n");
317 return SERIAL_ERROR_INVALID_PARAMETER;
320 serial_s *pHandle = (serial_s *)serial;
322 if (pHandle->client_socket > 0) {
323 if (close(pHandle->client_socket) < 0)
324 return SERIAL_ERROR_OPERATION_FAILED;
326 pHandle->client_socket = -1;
328 return SERIAL_ERROR_NONE;
330 return SERIAL_ERROR_INVALID_OPERATION;
334 int serial_destroy(serial_h serial)
336 DBG("%s\n", __FUNCTION__);
339 ERR("Invalid parameter\n");
340 return SERIAL_ERROR_INVALID_PARAMETER;
343 serial_s *pHandle = (serial_s *)serial;
345 if (dbus_connection != NULL) {
346 dbus_connection_remove_filter(dbus_connection, __dbus_event_filter, pHandle);
347 dbus_connection = NULL;
350 if (pHandle->client_bus != NULL) {
351 dbus_g_connection_unref(pHandle->client_bus);
352 pHandle->client_bus = NULL;
355 if (pHandle->g_watch_id > 0) {
356 g_source_remove(pHandle->g_watch_id);
357 pHandle->g_watch_id = -1;
360 if (pHandle->client_socket > 0) {
361 close(pHandle->client_socket);
362 pHandle->client_socket = -1;
368 return SERIAL_ERROR_NONE;
371 int serial_write(serial_h serial, const char *data, int data_length)
374 ERR("Invalid parameter\n");
375 return SERIAL_ERROR_INVALID_PARAMETER;
378 serial_s *pHandle = (serial_s *)serial;
380 ret = send(pHandle->client_socket, data, data_length, MSG_EOR);
382 ERR("Send failed. ");
383 return SERIAL_ERROR_OPERATION_FAILED;
389 int serial_set_state_changed_cb(serial_h serial, serial_state_changed_cb callback, void *user_data)
391 DBG("%s\n", __FUNCTION__);
393 if (!serial || !callback) {
394 ERR("Invalid parameter\n");
395 return SERIAL_ERROR_INVALID_PARAMETER;
398 return (__serial_set_state_changed_cb(serial, callback, user_data));
401 int serial_unset_state_changed_cb(serial_h serial)
403 DBG("%s\n", __FUNCTION__);
406 ERR("Invalid parameter\n");
407 return SERIAL_ERROR_INVALID_PARAMETER;
410 return (__serial_set_state_changed_cb(serial, NULL, NULL));
413 int serial_set_data_received_cb(serial_h serial, serial_data_received_cb callback, void *user_data)
415 DBG("%s\n", __FUNCTION__);
417 if (!serial || !callback) {
418 ERR("Invalid parameter\n");
419 return SERIAL_ERROR_INVALID_PARAMETER;
422 return (__serial_set_data_received_cb(serial, callback, user_data));
425 int serial_unset_data_received_cb(serial_h serial)
427 DBG("%s\n", __FUNCTION__);
430 ERR("Invalid parameter\n");
431 return SERIAL_ERROR_INVALID_PARAMETER;
434 return (__serial_set_data_received_cb(serial, NULL, NULL));