static int send_reply(struct msg_t *msg)
{
printBuf((char *)msg, msg->len + sizeof (*msg));
- if (send(manager.host.control_socket,
+ if (send(manager.host.control.socket,
msg, MSG_CMD_HDR_LEN + msg->len, MSG_NOSIGNAL) == -1) {
GETSTRERROR(errno, buf);
LOGE("Cannot send reply : %s\n", buf);
int sendACKToHost(enum HostMessageT resp, enum ErrorCode err_code,
char *payload, int payload_size)
{
+ assert(manager.host.control.status == HCS_RUNNING);
int ret = 1; /* error by default */
struct msg_t *msg = NULL;
uint32_t err = err_code;
payload_size;
char *p;
- if (manager.host.control_socket == -1) {
- LOGE("no connection\n");
- goto exit;
- }
-
msg = malloc(loglen);
if (msg == NULL) {
LOGE("Cannot allocates memory for msg\n");
printBuf((char *)msg, loglen);
/* TODO FIXME What the hell is going around? This shouldn't be this way */
- if (send(manager.host.control_socket, msg,
+ if (send(manager.host.control.socket, msg,
loglen, MSG_NOSIGNAL) == -1) {
GETSTRERROR(errno, buf);
// LOGE("Cannot send reply: %s\n", buf);
manager.connect_timeout_timerfd = -1;
}
/* Receive header */
- recv_len = recv(manager.host.control_socket,
+ recv_len = recv(manager.host.control.socket,
&msg_head, MSG_CMD_HDR_LEN, 0);
/* error or close request from host */
if (msg_head.len > HOST_CTL_MSG_MAX_LEN) {
LOGE("Too long message. MSG_ID = 0x%08X; size = %u\n",
msg_head.id, msg_head.len);
- recv_msg_tail(manager.host.control_socket, msg_head.len);
+ recv_msg_tail(manager.host.control.socket, msg_head.len);
sendACKToHost(msg_head.id, ERR_TO_LONG_MESSAGE, 0, 0);
continue;
}
if (!msg) {
LOGE("Cannot alloc msg. MSG_ID = 0x%08X; size = %u\n",
msg_head.id, msg_head.len);
- recv_msg_tail(manager.host.control_socket, msg_head.len);
+ recv_msg_tail(manager.host.control.socket, msg_head.len);
sendACKToHost(msg_head.id, ERR_WRONG_MESSAGE_FORMAT, 0, 0);
continue;
}
msg->len = msg_head.len;
if (msg->len > 0) {
/* Receive payload (if exists) */
- recv_len = recv(manager.host.control_socket,
+ recv_len = recv(manager.host.control.socket,
msg->payload, msg->len, MSG_WAITALL);
if (recv_len == -1 || recv_len == 0) {
LOGW("error or close request from host. "
free(msg);
}
- /* connection closed */
- LOGI("Connection closed. Termination. (%d)\n",
- manager.host.control_socket);
/* splice will fail without next cmd */
manager.host.data_socket = -1;
stop_all();
evloop_stop(g_loop);
- manager.host.control_socket = -1;
LOGI("Control socket thread finished\n");
return NULL;
}
LOGI("host message from data socket %d\n", recvLen);
}
+static int host_control_thread_create(struct host_control *control, int socket)
+{
+ int ret = 0;
+
+ pthread_mutex_lock(&control->mutex);
+ if (control->status != HCS_READY) {
+ LOGE("Host control thread does not ready starting, status=%d\n",
+ control->status);
+ ret = -1;
+ goto unlock;
+ }
+
+ if (pthread_create(&control->thread,
+ NULL,
+ host_control_sock_thread,
+ NULL) < 0) {
+ LOGE("Failed to create host control thread\n");
+ ret = -1;
+ goto unlock;
+ }
+ control->socket = socket;
+ control->status = HCS_RUNNING;
+
+unlock:
+ pthread_mutex_unlock(&control->mutex);
+ return ret;
+}
+
+static void host_control_thread_destroy(struct host_control *control)
+{
+ int ret = 0;
+ void *retval;
+
+ pthread_mutex_lock(&control->mutex);
+ if (control->status == HCS_READY) {
+ /* do nothing */
+ goto unlock;
+ } else if (control->status == HCS_FINISH) {
+ LOGE("Host control already finished\n");
+ ret = -1;
+ goto unlock;
+ }
+
+ ret = pthread_join(control->thread, &retval);
+ if (ret == 0) {
+ control->status = HCS_FINISH;
+ close(control->socket);
+ } else {
+ LOGE("Cannot join host control thread, err=%d\n", ret);
+ abort();
+ }
+
+unlock:
+ pthread_mutex_unlock(&control->mutex);
+}
+
// return 0 if normal case
// return plus value if non critical error occur
// return minus value if critical error occur
// accept succeed
if (hostserverorder == 0) {
- manager.host.control_socket = csocket;
portfile_reset();
LOGI("host control socket connected = %d\n", csocket);
- if (manager.host_control_sock_thread != -1) {
- LOGI("replay already started\n");
- return -1;
- }
-
- if (pthread_create(&(manager.host_control_sock_thread),
- NULL,
- host_control_sock_thread,
- NULL) < 0)
- {
- LOGE("Failed to create replay thread\n");
+ if (host_control_thread_create(&manager.host.control,
+ csocket)) {
+ close(csocket);
+ LOGE("Cannot create host control thread\n");
return -1;
}
-
} else {
manager.host.data_socket = csocket;
LOGI("host data socket connected = %d\n", csocket);
void daemon_uninit(void)
{
+ host_control_thread_destroy(&manager.host.control);
evloop_destroy(g_loop);
g_loop = NULL;
}