[Freeswitch-users] API question
Chris Mandra
mandra at gmail.com
Fri May 20 16:15:00 MSD 2016
Hi guys - Happy Friday - I have a question:
My main question is how can I generate a custom reply event for an api call
with custom body and headers for an API method defined in a custom module?
- is the only mechanism using this stream object?
or can you directly create the reply event. and if so, how does the caller
receive the reply event and know it corresponds to the API call made?
I want to provide a response to an API command defined in a module via:
#define SWITCH_STANDARD_API(name) static switch_status_t name (_In_opt_z_
const char *cmd, _In_opt_ switch_core_session_t *session, _In_
switch_stream_handle_t *stream)
and my understanding (which may be incorrect) is that the stream object can
be used to provide a response.
When the API is called, an event is automatically generated which uses the
stream object. Is there a way to directly modify the event that is
generated in response to an API call? How can I modify the headers and
body of the event generated from an API call directly?
it looks like the stream data is put in the body of the response as per:
switch_event_add_body(event, "%s", reply);
the relevant code is in api_exec
static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t *thread, void *obj)
{
struct api_command_struct *acs = (struct api_command_struct *) obj;
switch_stream_handle_t stream = { 0 };
char *reply, *freply = NULL;
switch_status_t status;
switch_mutex_lock(globals.listener_mutex);
prefs.threads++;
switch_mutex_unlock(globals.listener_mutex);
if (!acs) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Internal
error.\n");
goto cleanup;
}
if (!acs->listener || !switch_test_flag(acs->listener, LFLAG_RUNNING) ||
!acs->listener->rwlock ||
switch_thread_rwlock_tryrdlock(acs->listener->rwlock) !=
SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!
cannot get read lock.\n");
acs->ack = -1;
goto done;
}
acs->ack = 1;
SWITCH_STANDARD_STREAM(stream);
if (acs->console_execute) {
if ((status = switch_console_execute(acs->api_cmd, 0, &stream)) !=
SWITCH_STATUS_SUCCESS) {
stream.write_function(&stream, "-ERR %s Command not found!\n",
acs->api_cmd);
}
} else {
status = switch_api_execute(acs->api_cmd, acs->arg, NULL, &stream);
}
if (status == SWITCH_STATUS_SUCCESS) {
reply = stream.data;
} else {
freply = switch_mprintf("-ERR %s Command not found!\n",
acs->api_cmd);
reply = freply;
}
if (!reply) {
reply = "Command returned no output!";
}
if (acs->bg) {
switch_event_t *event;
if (switch_event_create(&event, SWITCH_EVENT_BACKGROUND_JOB) ==
SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM,
"Job-UUID", acs->uuid_str);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM,
"Job-Command", acs->api_cmd);
if (acs->arg) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM,
"Job-Command-Arg", acs->arg);
}
switch_event_add_body(event, "%s", reply);
switch_event_fire(&event);
}
} else {
switch_size_t rlen, blen;
char buf[1024] = "";
if (!(rlen = strlen(reply))) {
reply = "-ERR no reply\n";
rlen = strlen(reply);
}
switch_snprintf(buf, sizeof(buf), "Content-Type:
api/response\nContent-Length: %" SWITCH_SSIZE_T_FMT "\n\n", rlen);
blen = strlen(buf);
switch_socket_send(acs->listener->sock, buf, &blen);
switch_socket_send(acs->listener->sock, reply, &rlen);
}
switch_safe_free(stream.data);
switch_safe_free(freply);
if (acs->listener->rwlock) {
switch_thread_rwlock_unlock(acs->listener->rwlock);
}
Thanks, as ever, for your help,
chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.freeswitch.org/pipermail/freeswitch-users/attachments/20160520/7fbeb17f/attachment.html
Join us at ClueCon 2016 Aug 8-12, 2016
More information about the FreeSWITCH-users
mailing list