[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;




    if (!acs) {

        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Internal

        goto cleanup;


    if (!acs->listener || !switch_test_flag(acs->listener, LFLAG_RUNNING) ||

        !acs->listener->rwlock ||
switch_thread_rwlock_tryrdlock(acs->listener->rwlock) !=

        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error!
cannot get read lock.\n");

        acs->ack = -1;

        goto done;


    acs->ack = 1;


    if (acs->console_execute) {

        if ((status = switch_console_execute(acs->api_cmd, 0, &stream)) !=

            stream.write_function(&stream, "-ERR %s Command not found!\n",


    } 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",

        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_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);



    } 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);




    if (acs->listener->rwlock) {



Thanks, as ever, for your help,

-------------- 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