2 * tel-plugin-socket-communicator
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ja-young Gu <jygu@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
26 #include <sys/types.h>
27 #include <sys/socket.h>
30 #include "sipc_common.h"
33 struct _sipc_channel_key {
38 static gboolean _check_key_info(struct _sipc_channel_key *k)
43 SIPC_CHECK_DATA_NULL( k, FALSE);
45 memset(&buf, '\0', sizeof(struct stat));
48 ret = fstat(k->fd, &buf);
50 // debug msg using strerror( errno );
54 if ((buf.st_mode & S_IFMT) != S_IFSOCK) {
55 // debug msg : it's not socket fd
59 if (k->id == (unsigned int) buf.st_ino)
65 static gboolean _check_channel_type(struct _sipc_channel *ch, sipc_channel_type_e t)
67 SIPC_CHECK_DATA_NULL( ch, FALSE);
68 SIPC_CHECK_DATA_RANGE( t, SIPC_CHANNEL_TYPE_TX, SIPC_CHANNEL_TYPE_RX, FALSE);
76 static gboolean _check_channel_rx_type(struct _sipc_channel *ch)
78 SIPC_CHECK_DATA_NULL( ch, FALSE);
80 if (!_check_channel_type(ch, SIPC_CHANNEL_TYPE_RX))
86 static gboolean _check_channel_info(struct _sipc_channel *ch)
88 SIPC_CHECK_DATA_NULL( ch, FALSE);
90 if (!ch->id || !ch->fd || !ch->type) {
97 static struct _sipc_header* _create_header(struct _sipc_channel *ch, sipc_command_e c, int data_type, int data_len)
99 struct _sipc_header *h;
101 SIPC_CHECK_DATA_NULL( ch, 0);
102 SIPC_CHECK_DATA_RANGE( c, SIPC_SEND_DATA_SYNC, SIPC_DEREGISTER_CHANNEL, 0);
104 h = g_new0( struct _sipc_header, 1 );
106 h->ch_type = ch->type;
108 h->en_type = data_type;
109 h->data_len = data_len;
114 static int _channel_send(int fd, struct _sipc_header *h, void* in_d, void** out_d)
120 SIPC_CHECK_DATA_NULL( (fd && h), -1);
121 // 1 will be wrong input
123 p_len = sizeof(struct _sipc_header) + h->data_len;
124 p = g_new0( char, p_len );
126 memcpy(p, h, sizeof(struct _sipc_header));
128 if (in_d && h->data_len)
129 memcpy(p + sizeof(struct _sipc_header), (char*) in_d, h->data_len);
131 ret = send(fd, p, p_len, MSG_NOSIGNAL);
132 dbg("send data (%d) to server", ret);
139 memset(h, 0, sizeof(struct _sipc_header));
140 ret = recv(fd, h, sizeof(struct _sipc_header), MSG_NOSIGNAL);
142 dbg("fail to read ack data from server");
148 if (h->cmd != SIPC_ACK_SUCCESS) {
149 dbg("fail to request");
155 if (h->data_len > 0) {
156 *out_d = g_new0( char, (h->data_len)+1 );
157 ret = recv(fd, *out_d, h->data_len, MSG_NOSIGNAL);
158 //dbg("server returns data\n (%s)\n", *out_d);
166 static int _channel_deliver_data(struct _sipc_header *h, void *data, sipc_callback_t *cb)
170 SIPC_CHECK_DATA_NULL( (h && cb), -1);
172 ret = cb->func(h->ch_id, data, h->data_len, NULL, cb->data);
177 static gboolean _channel_recv(GIOChannel *ch, GIOCondition con, gpointer data)
182 struct _sipc_header h_rsp = { 0, };
186 fd = g_io_channel_unix_get_fd(ch);
187 memset(&h_rsp, 0, sizeof(struct _sipc_header));
189 ret = recv(fd, &h_rsp, sizeof(struct _sipc_header), MSG_NOSIGNAL);
191 dbg("recv() fail. ret = %d", ret);
195 if (h_rsp.data_len > 0) {
196 in_d = g_new0( char, (h_rsp.data_len)+1 );
197 ret = recv(fd, in_d, h_rsp.data_len, MSG_NOSIGNAL);
199 dbg("error to get header in socket");
203 dbg("recv data (%d)", ret);
206 cb = (sipc_callback_t*) data;
207 ack = _channel_deliver_data(&h_rsp, (void*) in_d, cb);
218 struct _sipc_channel_key* sipc_channel_key_create()
220 struct _sipc_channel_key *k;
224 k = g_new0( struct _sipc_channel_key, 1 );
226 k->fd = socket(AF_UNIX, SOCK_STREAM, 0);
230 memset(&buf, '\0', sizeof(struct stat));
233 ret = fstat(k->fd, &buf);
235 // debug msg using strerror( errno );
240 if ((buf.st_mode & S_IFMT) != S_IFSOCK) {
241 // debug msg : it's not socket fd
246 k->id = (unsigned int) buf.st_ino;
251 struct _sipc_channel* sipc_channel_open(struct _sipc_channel_key *k)
254 struct _sipc_channel *ch = 0;
256 SIPC_CHECK_DATA_NULL( k, 0);
258 if (!_check_key_info(k))
261 fd = socket(AF_UNIX, SOCK_STREAM, 0);
266 ch = g_new0( struct _sipc_channel, 1 );
273 gboolean sipc_channel_set_type(struct _sipc_channel *ch, sipc_channel_type_e t)
275 SIPC_CHECK_DATA_NULL( ch, FALSE);
276 SIPC_CHECK_DATA_RANGE( t, SIPC_CHANNEL_TYPE_TX, SIPC_CHANNEL_TYPE_RX, FALSE);
283 gboolean sipc_channel_connect(struct _sipc_channel *ch, char *path)
285 struct sockaddr_un server_addr;
287 struct _sipc_header *h = 0;
289 if (!_check_channel_info(ch))
292 memset(&server_addr, 0, sizeof(server_addr));
294 server_addr.sun_family = AF_UNIX;
295 strcpy((char*) server_addr.sun_path, path);
297 ret = connect(ch->fd, (struct sockaddr*) &server_addr, sizeof(server_addr));
301 h = _create_header(ch, SIPC_REGISTER_CHANNEL, 0, 0);
303 ret = send(ch->fd, h, sizeof(struct _sipc_header), MSG_NOSIGNAL);
304 dbg("send register data(%d) ch->fd(%d), ch->type(%d)", ret, ch->fd, ch->type);
310 memset(h, 0, sizeof(struct _sipc_header));
311 ret = recv(ch->fd, h, sizeof(struct _sipc_header), MSG_NOSIGNAL);
312 dbg("recv register data(%d) ch->fd(%d), h->command(%d)", ret, ch->fd, h->cmd);
318 if (h->cmd != SIPC_ACK_SUCCESS) {
327 gboolean sipc_channel_register_rx_callback(struct _sipc_channel *ch, sipc_callback_t *cb)
332 if (!_check_channel_info(ch))
335 if (!_check_channel_rx_type(ch))
338 SIPC_CHECK_DATA_NULL( cb, FALSE);
340 dbg("g_io_channel_unix_new(fd = %d)", ch->fd);
341 c = g_io_channel_unix_new(ch->fd);
344 dbg("g_io_channel_unix_new failed.");
348 tag = g_io_add_watch(c, (G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL), (GIOFunc) _channel_recv, cb);
351 dbg("g_io_add_watch failed.");
360 int sipc_channel_send(struct _sipc_channel *ch, void *in_d, unsigned int in_data_len, void **out_d, sipc_data_type_e t)
362 struct _sipc_header *h = 0;
364 if (!_check_channel_info(ch))
367 SIPC_CHECK_DATA_RANGE(t, SIPC_DATA_TYPE_SYNC, SIPC_DATA_TYPE_ASYNC, -1);
369 h = _create_header(ch, (sipc_command_e) t, 0, in_data_len);
371 return _channel_send(ch->fd, h, in_d, out_d);
374 gboolean sipc_channel_close(struct _sipc_channel *ch, struct _sipc_channel_key *k)
376 if (!_check_key_info(k))
379 if (!_check_channel_info(ch))
382 sipc_channel_send(ch, 0, 0, NULL, SIPC_DEREGISTER_CHANNEL);
389 gboolean sipc_channel_key_destroy(struct _sipc_channel_key *k)
391 if (!_check_key_info(k))
399 unsigned int sipc_channel_get_channel_id(struct _sipc_channel *ch)
401 SIPC_CHECK_DATA_NULL( ch, -1);