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"
37 struct _sipc_channel_key {
42 static gboolean _check_key_info(struct _sipc_channel_key *k)
47 SIPC_CHECK_DATA_NULL( k, FALSE);
49 memset(&buf, '\0', sizeof(struct stat));
52 ret = fstat(k->fd, &buf);
54 // debug msg using strerror( errno );
58 if ((buf.st_mode & S_IFMT) != S_IFSOCK) {
59 // debug msg : it's not socket fd
63 if (k->id == (unsigned int) buf.st_ino)
69 static gboolean _check_channel_type(struct _sipc_channel *ch, sipc_channel_type_e t)
71 SIPC_CHECK_DATA_NULL( ch, FALSE);
72 SIPC_CHECK_DATA_RANGE( t, SIPC_CHANNEL_TYPE_TX, SIPC_CHANNEL_TYPE_RX, FALSE);
80 static gboolean _check_channel_rx_type(struct _sipc_channel *ch)
82 SIPC_CHECK_DATA_NULL( ch, FALSE);
84 if (!_check_channel_type(ch, SIPC_CHANNEL_TYPE_RX))
90 static gboolean _check_channel_info(struct _sipc_channel *ch)
92 SIPC_CHECK_DATA_NULL( ch, FALSE);
94 if (!ch->id || !ch->fd || !ch->type) {
101 static struct _sipc_header* _create_header(struct _sipc_channel *ch, sipc_command_e c, int data_type, int data_len)
103 struct _sipc_header *h;
105 SIPC_CHECK_DATA_NULL( ch, 0);
106 SIPC_CHECK_DATA_RANGE( c, SIPC_SEND_DATA_SYNC, SIPC_DEREGISTER_CHANNEL, 0);
108 h = g_new0( struct _sipc_header, 1 );
110 h->ch_type = ch->type;
112 h->en_type = data_type;
113 h->data_len = data_len;
118 static int _channel_send(int fd, struct _sipc_header *h, void* in_d, void** out_d)
124 SIPC_CHECK_DATA_NULL( (fd && h), -1);
125 // 1 will be wrong input
127 p_len = sizeof(struct _sipc_header) + h->data_len;
128 p = g_new0( char, p_len );
130 memcpy(p, h, sizeof(struct _sipc_header));
132 if (in_d && h->data_len)
133 memcpy(p + sizeof(struct _sipc_header), (char*) in_d, h->data_len);
135 ret = send(fd, p, p_len, MSG_NOSIGNAL);
136 dbg("send data (%d) to server", ret);
143 memset(h, 0, sizeof(struct _sipc_header));
144 ret = recv(fd, h, sizeof(struct _sipc_header), MSG_NOSIGNAL);
146 dbg("fail to read ack data from server");
152 if (h->cmd != SIPC_ACK_SUCCESS) {
153 dbg("fail to request");
159 if (h->data_len > 0) {
160 *out_d = g_new0( char, (h->data_len)+1 );
161 ret = recv(fd, *out_d, h->data_len, MSG_NOSIGNAL);
162 //dbg("server returns data\n (%s)\n", *out_d);
170 static int _channel_deliver_data(struct _sipc_header *h, void *data, sipc_callback_t *cb)
174 SIPC_CHECK_DATA_NULL( (h && cb), -1);
176 ret = cb->func(h->ch_id, data, h->data_len, NULL, cb->data);
181 static gboolean _channel_recv(GIOChannel *ch, GIOCondition con, gpointer data)
186 struct _sipc_header h_rsp = { 0, };
190 fd = g_io_channel_unix_get_fd(ch);
191 memset(&h_rsp, 0, sizeof(struct _sipc_header));
193 ret = recv(fd, &h_rsp, sizeof(struct _sipc_header), MSG_NOSIGNAL);
195 dbg("recv() fail. ret = %d", ret);
199 if (h_rsp.data_len > 0) {
200 in_d = g_new0( char, (h_rsp.data_len)+1 );
201 ret = recv(fd, in_d, h_rsp.data_len, MSG_NOSIGNAL);
203 dbg("error to get header in socket");
207 dbg("recv data (%d)", ret);
210 cb = (sipc_callback_t*) data;
211 ack = _channel_deliver_data(&h_rsp, (void*) in_d, cb);
222 struct _sipc_channel_key* sipc_channel_key_create()
224 struct _sipc_channel_key *k;
228 k = g_new0( struct _sipc_channel_key, 1 );
230 k->fd = socket(AF_UNIX, SOCK_STREAM, 0);
234 memset(&buf, '\0', sizeof(struct stat));
237 ret = fstat(k->fd, &buf);
239 // debug msg using strerror( errno );
244 if ((buf.st_mode & S_IFMT) != S_IFSOCK) {
245 // debug msg : it's not socket fd
250 k->id = (unsigned int) buf.st_ino;
255 struct _sipc_channel* sipc_channel_open(struct _sipc_channel_key *k)
258 struct _sipc_channel *ch = 0;
260 SIPC_CHECK_DATA_NULL( k, 0);
262 if (!_check_key_info(k))
265 fd = socket(AF_UNIX, SOCK_STREAM, 0);
270 ch = g_new0( struct _sipc_channel, 1 );
277 gboolean sipc_channel_set_type(struct _sipc_channel *ch, sipc_channel_type_e t)
279 SIPC_CHECK_DATA_NULL( ch, FALSE);
280 SIPC_CHECK_DATA_RANGE( t, SIPC_CHANNEL_TYPE_TX, SIPC_CHANNEL_TYPE_RX, FALSE);
287 gboolean sipc_channel_connect(struct _sipc_channel *ch, char *path)
289 struct sockaddr_un server_addr;
291 struct _sipc_header *h = 0;
293 if (!_check_channel_info(ch))
296 memset(&server_addr, 0, sizeof(server_addr));
298 server_addr.sun_family = AF_UNIX;
299 strcpy((char*) server_addr.sun_path, path);
301 ret = connect(ch->fd, (struct sockaddr*) &server_addr, sizeof(server_addr));
305 h = _create_header(ch, SIPC_REGISTER_CHANNEL, 0, 0);
307 ret = send(ch->fd, h, sizeof(struct _sipc_header), MSG_NOSIGNAL);
308 dbg("send register data(%d) ch->fd(%d), ch->type(%d)", ret, ch->fd, ch->type);
314 memset(h, 0, sizeof(struct _sipc_header));
315 ret = recv(ch->fd, h, sizeof(struct _sipc_header), MSG_NOSIGNAL);
316 dbg("recv register data(%d) ch->fd(%d), h->command(%d)", ret, ch->fd, h->cmd);
322 if (h->cmd != SIPC_ACK_SUCCESS) {
331 gboolean sipc_channel_register_rx_callback(struct _sipc_channel *ch, sipc_callback_t *cb)
336 if (!_check_channel_info(ch))
339 if (!_check_channel_rx_type(ch))
342 SIPC_CHECK_DATA_NULL( cb, FALSE);
344 dbg("g_io_channel_unix_new(fd = %d)", ch->fd);
345 c = g_io_channel_unix_new(ch->fd);
348 dbg("g_io_channel_unix_new failed.");
352 tag = g_io_add_watch(c, (G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL), (GIOFunc) _channel_recv, cb);
355 dbg("g_io_add_watch failed.");
364 int sipc_channel_send(struct _sipc_channel *ch, void *in_d, unsigned int in_data_len, void **out_d, sipc_data_type_e t)
366 struct _sipc_header *h = 0;
368 if (!_check_channel_info(ch))
371 SIPC_CHECK_DATA_RANGE(t, SIPC_DATA_TYPE_SYNC, SIPC_DATA_TYPE_ASYNC, -1);
373 h = _create_header(ch, (sipc_command_e) t, 0, in_data_len);
375 return _channel_send(ch->fd, h, in_d, out_d);
378 gboolean sipc_channel_close(struct _sipc_channel *ch, struct _sipc_channel_key *k)
380 if (!_check_key_info(k))
383 if (!_check_channel_info(ch))
386 sipc_channel_send(ch, 0, 0, NULL, SIPC_DEREGISTER_CHANNEL);
393 gboolean sipc_channel_key_destroy(struct _sipc_channel_key *k)
395 if (!_check_key_info(k))
403 unsigned int sipc_channel_get_channel_id(struct _sipc_channel *ch)
405 SIPC_CHECK_DATA_NULL( ch, -1);