git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16721 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2010-02-22 18:35:21 +00:00
parent a82506de57
commit 4197a25412
2 changed files with 111 additions and 37 deletions

View File

@ -378,8 +378,13 @@ ESL_DECLARE(char *)esl_url_decode(char *s)
return s; return s;
} }
static void sock_setup(esl_handle_t *handle) static int sock_setup(esl_handle_t *handle)
{ {
if (handle->sock == ESL_SOCK_INVALID) {
return ESL_FAIL;
}
#ifdef WIN32 #ifdef WIN32
BOOL bOptVal = TRUE; BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL); int bOptLen = sizeof(BOOL);
@ -388,28 +393,33 @@ static void sock_setup(esl_handle_t *handle)
int x = 1; int x = 1;
setsockopt(handle->sock, IPPROTO_TCP, TCP_NODELAY, &x, sizeof(x)); setsockopt(handle->sock, IPPROTO_TCP, TCP_NODELAY, &x, sizeof(x));
#endif #endif
return ESL_SUCCESS;
} }
ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t socket, struct sockaddr_in *addr) ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t socket, struct sockaddr_in *addr)
{ {
if (!handle || socket == ESL_SOCK_INVALID) {
return ESL_FAIL;
}
handle->sock = socket; handle->sock = socket;
if (addr) { if (addr) {
handle->addr = *addr; handle->addr = *addr;
} }
if (handle->sock == ESL_SOCK_INVALID) { if (sock_setup(handle) != ESL_SUCCESS) {
return ESL_FAIL; return ESL_FAIL;
} }
if (!handle->mutex) { if (!handle->mutex) {
esl_mutex_create(&handle->mutex); esl_mutex_create(&handle->mutex);
} }
handle->connected = 1; handle->connected = 1;
sock_setup(handle);
esl_send_recv(handle, "connect\n\n"); esl_send_recv(handle, "connect\n\n");
@ -439,13 +449,23 @@ ESL_DECLARE(esl_status_t) esl_sendevent(esl_handle_t *handle, esl_event_t *event
snprintf(event_buf, sizeof(event_buf), "sendevent %s\n", esl_event_name(event->event_id)); snprintf(event_buf, sizeof(event_buf), "sendevent %s\n", esl_event_name(event->event_id));
send(handle->sock, event_buf, strlen(event_buf), 0); if (send(handle->sock, event_buf, strlen(event_buf), 0)) goto fail;
send(handle->sock, txt, strlen(txt), 0); if (send(handle->sock, txt, strlen(txt), 0)) goto fail;
send(handle->sock, "\n\n", 2, 0); if (send(handle->sock, "\n\n", 2, 0)) goto fail;
free(txt); free(txt);
return ESL_SUCCESS; return ESL_SUCCESS;
fail:
handle->connected = 0;
free(txt);
return ESL_FAIL;
} }
ESL_DECLARE(esl_status_t) esl_execute(esl_handle_t *handle, const char *app, const char *arg, const char *uuid) ESL_DECLARE(esl_status_t) esl_execute(esl_handle_t *handle, const char *app, const char *arg, const char *uuid)
@ -457,9 +477,9 @@ ESL_DECLARE(esl_status_t) esl_execute(esl_handle_t *handle, const char *app, con
const char *bl_buf = "async: true\n"; const char *bl_buf = "async: true\n";
char send_buf[1292] = ""; char send_buf[1292] = "";
if (!handle->connected) { if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
return ESL_FAIL; return ESL_FAIL;
} }
if (uuid) { if (uuid) {
snprintf(cmd_buf, sizeof(cmd_buf), "sendmsg %s", uuid); snprintf(cmd_buf, sizeof(cmd_buf), "sendmsg %s", uuid);
@ -484,9 +504,9 @@ ESL_DECLARE(esl_status_t) esl_filter(esl_handle_t *handle, const char *header, c
{ {
char send_buf[1024] = ""; char send_buf[1024] = "";
if (!handle->connected) { if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
return ESL_FAIL; return ESL_FAIL;
} }
snprintf(send_buf, sizeof(send_buf), "filter %s %s\n\n", header, value); snprintf(send_buf, sizeof(send_buf), "filter %s %s\n\n", header, value);
@ -499,9 +519,9 @@ ESL_DECLARE(esl_status_t) esl_events(esl_handle_t *handle, esl_event_type_t etyp
char send_buf[1024] = ""; char send_buf[1024] = "";
const char *type = "plain"; const char *type = "plain";
if (!handle->connected) { if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
return ESL_FAIL; return ESL_FAIL;
} }
if (etype == ESL_EVENT_TYPE_XML) { if (etype == ESL_EVENT_TYPE_XML) {
type = "xml"; type = "xml";
@ -677,7 +697,7 @@ ESL_DECLARE(esl_status_t) esl_connect(esl_handle_t *handle, const char *host, es
fail: fail:
esl_disconnect(handle); handle->connected = 0;
return ESL_FAIL; return ESL_FAIL;
} }
@ -687,10 +707,17 @@ ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle)
esl_mutex_t *mutex = handle->mutex; esl_mutex_t *mutex = handle->mutex;
esl_status_t status = ESL_FAIL; esl_status_t status = ESL_FAIL;
if (handle->destroyed) {
return ESL_FAIL;
}
if (mutex) { if (mutex) {
esl_mutex_lock(mutex); esl_mutex_lock(mutex);
} }
handle->destroyed = 1;
handle->connected = 0;
esl_event_safe_destroy(&handle->race_event); esl_event_safe_destroy(&handle->race_event);
esl_event_safe_destroy(&handle->last_event); esl_event_safe_destroy(&handle->last_event);
esl_event_safe_destroy(&handle->last_sr_event); esl_event_safe_destroy(&handle->last_sr_event);
@ -703,14 +730,13 @@ ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle)
status = ESL_SUCCESS; status = ESL_SUCCESS;
} }
handle->connected = 0;
if (mutex) { if (mutex) {
esl_mutex_unlock(mutex);
esl_mutex_lock(mutex);
esl_mutex_unlock(mutex); esl_mutex_unlock(mutex);
esl_mutex_destroy(&mutex); esl_mutex_destroy(&mutex);
} }
return status; return status;
} }
@ -721,6 +747,10 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
int max, activity; int max, activity;
esl_status_t status = ESL_SUCCESS; esl_status_t status = ESL_SUCCESS;
if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
return ESL_FAIL;
}
if (check_q) { if (check_q) {
esl_mutex_lock(handle->mutex); esl_mutex_lock(handle->mutex);
if (handle->race_event) { if (handle->race_event) {
@ -730,10 +760,6 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
esl_mutex_unlock(handle->mutex); esl_mutex_unlock(handle->mutex);
} }
if (!handle || !handle->connected || handle->sock == -1) {
return ESL_FAIL;
}
tv.tv_usec = ms * 1000; tv.tv_usec = ms * 1000;
@ -754,6 +780,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
max = handle->sock + 1; max = handle->sock + 1;
if ((activity = select(max, &rfds, NULL, &efds, &tv)) < 0) { if ((activity = select(max, &rfds, NULL, &efds, &tv)) < 0) {
handle->connected = 0;
return ESL_FAIL; return ESL_FAIL;
} }
@ -761,7 +788,28 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
return ESL_BREAK; return ESL_BREAK;
} }
if (activity && FD_ISSET(handle->sock, &rfds)) { tv.tv_usec = 0;
FD_ZERO(&rfds);
FD_ZERO(&efds);
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4127 )
FD_SET(handle->sock, &rfds);
FD_SET(handle->sock, &efds);
#pragma warning( pop )
#else
FD_SET(handle->sock, &rfds);
FD_SET(handle->sock, &efds);
#endif
activity = select(max, &rfds, NULL, &efds, &tv);
if (activity < 0) {
handle->connected = 0;
status = ESL_FAIL;
} else if (activity > 0 && FD_ISSET(handle->sock, &rfds)) {
if (esl_recv_event(handle, check_q, save_event)) { if (esl_recv_event(handle, check_q, save_event)) {
status = ESL_FAIL; status = ESL_FAIL;
} }
@ -789,11 +837,19 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
esl_ssize_t len; esl_ssize_t len;
int zc = 0; int zc = 0;
if (!handle->connected) {
if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
return ESL_FAIL; return ESL_FAIL;
} }
esl_mutex_lock(handle->mutex); esl_mutex_lock(handle->mutex);
if (!handle->connected || handle->sock == ESL_SOCK_INVALID) {
handle->connected = 0;
esl_mutex_unlock(handle->mutex);
return ESL_FAIL;
}
esl_event_safe_destroy(&handle->last_event); esl_event_safe_destroy(&handle->last_event);
esl_event_safe_destroy(&handle->last_ievent); esl_event_safe_destroy(&handle->last_ievent);
@ -822,7 +878,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
rrval = recv(handle->sock, c, 1, 0); rrval = recv(handle->sock, c, 1, 0);
if (rrval == 0) { if (rrval == 0) {
if (++zc >= 100) { if (++zc >= 100) {
esl_disconnect(handle); handle->connected = 0;
esl_mutex_unlock(handle->mutex); esl_mutex_unlock(handle->mutex);
return ESL_DISCONNECTED; return ESL_DISCONNECTED;
} }
@ -987,7 +1043,8 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_
fail: fail:
esl_disconnect(handle); handle->connected = 0;
return ESL_FAIL; return ESL_FAIL;
} }
@ -996,19 +1053,22 @@ ESL_DECLARE(esl_status_t) esl_send(esl_handle_t *handle, const char *cmd)
{ {
const char *e = cmd + strlen(cmd) -1; const char *e = cmd + strlen(cmd) -1;
if (!handle->connected) {
if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
return ESL_FAIL; return ESL_FAIL;
} }
esl_log(ESL_LOG_DEBUG, "SEND\n%s\n", cmd); esl_log(ESL_LOG_DEBUG, "SEND\n%s\n", cmd);
if (send(handle->sock, cmd, strlen(cmd), 0) != (int)strlen(cmd)) { if (send(handle->sock, cmd, strlen(cmd), 0) != (int)strlen(cmd)) {
handle->connected = 0;
strerror_r(handle->errnum, handle->err, sizeof(handle->err)); strerror_r(handle->errnum, handle->err, sizeof(handle->err));
return ESL_FAIL; return ESL_FAIL;
} }
if (!(*e == '\n' && *(e-1) == '\n')) { if (!(*e == '\n' && *(e-1) == '\n')) {
if (send(handle->sock, "\n\n", 2, 0) != 2) { if (send(handle->sock, "\n\n", 2, 0) != 2) {
handle->connected = 0;
strerror_r(handle->errnum, handle->err, sizeof(handle->err)); strerror_r(handle->errnum, handle->err, sizeof(handle->err));
return ESL_FAIL; return ESL_FAIL;
} }
@ -1024,13 +1084,19 @@ ESL_DECLARE(esl_status_t) esl_send_recv(esl_handle_t *handle, const char *cmd)
const char *hval; const char *hval;
esl_status_t status; esl_status_t status;
if (!handle->connected) { if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
return ESL_FAIL; return ESL_FAIL;
} }
esl_mutex_lock(handle->mutex); esl_mutex_lock(handle->mutex);
if (!handle->connected || handle->sock == ESL_SOCK_INVALID) {
handle->connected = 0;
esl_mutex_unlock(handle->mutex);
return ESL_FAIL;
}
esl_event_safe_destroy(&handle->last_event); esl_event_safe_destroy(&handle->last_event);
esl_event_safe_destroy(&handle->last_sr_event); esl_event_safe_destroy(&handle->last_sr_event);
@ -1063,6 +1129,13 @@ ESL_DECLARE(esl_status_t) esl_send_recv(esl_handle_t *handle, const char *cmd)
esl_mutex_unlock(handle->mutex); esl_mutex_unlock(handle->mutex);
esl_mutex_lock(handle->mutex); esl_mutex_lock(handle->mutex);
if (!handle->connected || handle->sock == ESL_SOCK_INVALID) {
handle->connected = 0;
esl_mutex_unlock(handle->mutex);
return ESL_FAIL;
}
goto recv; goto recv;
} }

View File

@ -290,6 +290,7 @@ typedef struct {
esl_mutex_t *mutex; esl_mutex_t *mutex;
int async_execute; int async_execute;
int event_lock; int event_lock;
int destroyed;
} esl_handle_t; } esl_handle_t;
/*! \brief Used internally for truth test */ /*! \brief Used internally for truth test */