+message_port_pkt_s *__message_port_recv_raw(int fd)
+{
+ int len;
+ int ret;
+ message_port_pkt_s *pkt = NULL;
+
+ pkt = (message_port_pkt_s *) calloc(sizeof(char) * MAX_MESSAGE_SIZE, 1);
+ if(pkt == NULL) {
+ close(fd);
+ return NULL;
+ }
+
+retry_recv:
+ /* receive single packet from socket */
+ len = recv(fd, pkt, MAX_MESSAGE_SIZE, 0);
+ if (len < 0) {
+ _LOGE("recv error: %d[%s]", errno, strerror(errno));
+ if (errno == EINTR)
+ goto retry_recv;
+ }
+
+ if (len < HEADER_LEN) {
+ _LOGE("recv error %d %d", len, pkt->len);
+ free(pkt);
+ close(fd);
+ return NULL;
+ }
+ while( len < (pkt->len + HEADER_LEN) ) {
+retry_recv1:
+ ret = recv(fd, &pkt->data[len - 8], MAX_MESSAGE_SIZE, 0);
+ if (ret < 0) {
+ SECURE_LOGE("recv error: %d %d %d", errno, len, pkt->len);
+ if (errno == EINTR)
+ goto retry_recv1;
+ free(pkt);
+ close(fd);
+ return NULL;
+ }
+ len += ret;
+ }
+ return pkt;
+}
+
+static gboolean __socket_request_handler(GIOChannel *gio,
+ GIOCondition cond,
+ gpointer data)
+{
+ int fd = 0;
+ message_port_callback_info_s *mi;
+ message_port_pkt_s *pkt;
+ bundle *kb = NULL;
+ bool is_bidirection;
+ GError *error = NULL;
+
+ if (cond == G_IO_HUP) {
+
+ _LOGI("socket G_IO_HUP");
+ g_io_channel_shutdown(gio, FALSE, &error);
+ if (error) {
+ _LOGE("g_io_channel_shutdown error : %s", error->message);
+ g_error_free(error);
+ }
+ g_io_channel_unref(gio);
+ if (data)
+ g_free(data);
+ } else {
+
+ if ((fd = g_io_channel_unix_get_fd(gio)) < 0) {
+ _LOGE("fail to get fd from io channel");
+ return TRUE;
+ }
+
+ //_LOGI("__socket_request_handler fd : %d", fd);
+
+ mi = (message_port_callback_info_s *)data;
+
+ if ((pkt = __message_port_recv_raw(fd)) == NULL) {
+ _LOGE("recv error on SOCKET");
+ close(fd);
+ return FALSE;
+ }
+ kb = bundle_decode(pkt->data, pkt->len);
+ is_bidirection = pkt->is_bidirection;
+
+ if (is_bidirection) {
+ mi->callback(mi->local_id, mi->remote_app_id, mi->remote_port, mi->is_trusted, kb, NULL);
+ } else {
+ mi->callback(mi->local_id, mi->remote_app_id, NULL, mi->is_trusted, kb, NULL);
+ }
+
+ if (pkt)
+ free(pkt);
+ }
+
+ return TRUE;
+}