]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
mod_rayo: updates for 0.2 of spec
authorChris Rienzo <chris.rienzo@grasshopper.com>
Thu, 13 Jun 2013 15:23:12 +0000 (11:23 -0400)
committerChris Rienzo <chris.rienzo@grasshopper.com>
Thu, 13 Jun 2013 15:23:12 +0000 (11:23 -0400)
src/mod/event_handlers/mod_rayo/mod_rayo.c
src/mod/event_handlers/mod_rayo/mod_rayo.h
src/mod/event_handlers/mod_rayo/rayo_components.c
src/mod/event_handlers/mod_rayo/rayo_elements.h
src/mod/event_handlers/mod_rayo/rayo_input_component.c
src/mod/event_handlers/mod_rayo/rayo_output_component.c

index b914f60dcf67718940cea96e176ffac18757c4fc..ad4e988105d777f996a63503e224c42071799eef 100644 (file)
@@ -43,11 +43,12 @@ SWITCH_MODULE_DEFINITION(mod_rayo, mod_rayo_load, mod_rayo_shutdown, NULL);
 #define RAYO_CAUSE_BUSY SWITCH_CAUSE_USER_BUSY
 #define RAYO_CAUSE_ERROR SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE
 
-#define RAYO_END_REASON_HANGUP "hangup"
-#define RAYO_END_REASON_ERROR "error"
-#define RAYO_END_REASON_BUSY "busy"
-#define RAYO_END_REASON_REJECT "reject"
+#define RAYO_END_REASON_HANGUP "hungup"
+#define RAYO_END_REASON_HANGUP_LOCAL "hangup-command"
 #define RAYO_END_REASON_TIMEOUT "timeout"
+#define RAYO_END_REASON_BUSY "busy"
+#define RAYO_END_REASON_REJECT "rejected"
+#define RAYO_END_REASON_ERROR "error"
 
 #define RAYO_SIP_REQUEST_HEADER "sip_r_"
 #define RAYO_SIP_RESPONSE_HEADER "sip_rh_"
@@ -779,8 +780,6 @@ static void rayo_call_cleanup(struct rayo_actor *actor)
 {
        struct rayo_call *call = RAYO_CALL(actor);
        switch_event_t *event = call->end_event;
-       char *cause_str;
-       switch_call_cause_t cause = SWITCH_CAUSE_NONE;
        int no_offered_clients = 1;
        switch_hash_index_t *hi = NULL;
        iks *revent;
@@ -791,17 +790,23 @@ static void rayo_call_cleanup(struct rayo_actor *actor)
                return;
        }
 
-       cause_str = switch_event_get_header(event, "variable_hangup_cause");
        revent = iks_new_presence("end", RAYO_NS,
                RAYO_JID(call),
                rayo_call_get_dcp_jid(call));
        iks_insert_attrib(revent, "type", "unavailable");
        end = iks_find(revent, "end");
 
-       if (cause_str) {
-               cause = switch_channel_str2cause(cause_str);
+       if (switch_true(switch_event_get_header(event, "variable_rayo_local_hangup"))) {
+               iks_insert(end, RAYO_END_REASON_HANGUP_LOCAL);
+       } else {
+               /* remote hangup... translate to specific rayo reason */
+               switch_call_cause_t cause = SWITCH_CAUSE_NONE;
+               char *cause_str = switch_event_get_header(event, "variable_hangup_cause");
+               if (cause_str) {
+                       cause = switch_channel_str2cause(cause_str);
+               }
+               iks_insert(end, switch_cause_to_rayo_cause(cause));
        }
-       iks_insert(end, switch_cause_to_rayo_cause(cause));
 
        #if 0
        {
@@ -1598,6 +1603,7 @@ static iks *on_rayo_hangup(struct rayo_actor *client, struct rayo_actor *call, i
 
        /* do hangup */
        if (!response) {
+               switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_local_hangup", "true");
                add_signaling_headers(session, hangup, RAYO_SIP_REQUEST_HEADER);
                add_signaling_headers(session, hangup, RAYO_SIP_RESPONSE_HEADER);
                switch_ivr_kill_uuid(rayo_call_get_uuid(call), hangup_cause);
@@ -1634,7 +1640,7 @@ static iks *join_call(struct rayo_call *call, switch_core_session_t *session, ik
        } else {
                RAYO_UNLOCK(b_call);
 
-               /* bridge this call to call-id */
+               /* bridge this call to call-uri */
                switch_channel_set_variable(switch_core_session_get_channel(session), "bypass_media", bypass);
                if (switch_false(bypass)) {
                        switch_channel_pre_answer(switch_core_session_get_channel(session));
@@ -1689,17 +1695,17 @@ static iks *on_rayo_join(struct rayo_actor *client, struct rayo_actor *call, iks
                goto done;
        }
        mixer_name = iks_find_attrib(join, "mixer-name");
-       call_id = iks_find_attrib(join, "call-id");
+       call_id = iks_find_attrib(join, "call-uri");
 
        /* can't join both mixer and call */
        if (!zstr(mixer_name) && !zstr(call_id)) {
-               response = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "mixer-name and call-id are mutually exclusive");
+               response = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "mixer-name and call-uri are mutually exclusive");
                goto done;
        }
 
        /* need to join *something* */
        if (zstr(mixer_name) && zstr(call_id)) {
-               response = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "mixer-name or call-id is required");
+               response = iks_new_error_detailed(node, STANZA_ERROR_BAD_REQUEST, "mixer-name or call-uri is required");
                goto done;
        }
 
@@ -1799,7 +1805,7 @@ static iks *on_rayo_unjoin(struct rayo_actor *client, struct rayo_actor *call, i
        switch_core_session_t *session = (switch_core_session_t *)session_data;
        iks *response = NULL;
        iks *unjoin = iks_find(node, "unjoin");
-       const char *call_id = iks_find_attrib(unjoin, "call-id");
+       const char *call_id = iks_find_attrib(unjoin, "call-uri");
        const char *mixer_name = iks_find_attrib(unjoin, "mixer-name");
 
        if (!zstr(call_id) && !zstr(mixer_name)) {
@@ -1888,7 +1894,7 @@ static void *SWITCH_THREAD_FUNC rayo_dial_thread(switch_thread_t *thread, void *
 
                if (join) {
                        /* check join args */
-                       const char *call_id = iks_find_attrib(join, "call-id");
+                       const char *call_id = iks_find_attrib(join, "call-uri");
                        const char *mixer_name = iks_find_attrib(join, "mixer-name");
 
                        if (!zstr(call_id) && !zstr(mixer_name)) {
@@ -2258,7 +2264,7 @@ static void on_mixer_delete_member_event(struct rayo_mixer *mixer, switch_event_
        /* broadcast member unjoined event to subscribers */
        delete_member_event = iks_new_presence("unjoined", RAYO_NS, RAYO_JID(mixer), "");
        x = iks_find(delete_member_event, "unjoined");
-       iks_insert_attrib(x, "call-id", uuid);
+       iks_insert_attrib(x, "call-uri", uuid);
        broadcast_mixer_event(mixer, delete_member_event);
        iks_delete(delete_member_event);
 
@@ -2335,7 +2341,7 @@ static void on_mixer_add_member_event(struct rayo_mixer *mixer, switch_event_t *
        /* broadcast member joined event to subscribers */
        add_member_event = iks_new_presence("joined", RAYO_NS, RAYO_JID(mixer), "");
        x = iks_find(add_member_event, "joined");
-       iks_insert_attrib(x, "call-id", uuid);
+       iks_insert_attrib(x, "call-uri", uuid);
        broadcast_mixer_event(mixer, add_member_event);
        iks_delete(add_member_event);
 }
@@ -2397,8 +2403,12 @@ static void on_call_originate_event(struct rayo_client *rclient, switch_event_t
                iks_insert_attrib(response, "type", "result");
                ref = iks_insert(response, "ref");
                iks_insert_attrib(ref, "xmlns", RAYO_NS);
-               iks_insert_attrib(ref, "id", uuid);
-               iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(call));
+
+#ifdef RAYO_UUID_IN_REF_URI
+       iks_insert_attrib(ref, "uri", uuid);
+#else
+       iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(call));
+#endif
                RAYO_SEND(call, rclient, rayo_message_create(response));
                call->dial_id = NULL;
        }
@@ -2480,7 +2490,7 @@ static void on_call_bridge_event(struct rayo_client *rclient, switch_event_t *ev
                        switch_event_get_header(event, "variable_rayo_call_jid"),
                        switch_event_get_header(event, "variable_rayo_dcp_jid"));
                iks *joined = iks_find(revent, "joined");
-               iks_insert_attrib(joined, "call-id", b_uuid);
+               iks_insert_attrib(joined, "call-uri", b_uuid);
 
                call->joined = 1;
 
@@ -2491,7 +2501,7 @@ static void on_call_bridge_event(struct rayo_client *rclient, switch_event_t *ev
                if (b_call) {
                        revent = iks_new_presence("joined", RAYO_NS, RAYO_JID(b_call), rayo_call_get_dcp_jid(b_call));
                        joined = iks_find(revent, "joined");
-                       iks_insert_attrib(joined, "call-id", a_uuid);
+                       iks_insert_attrib(joined, "call-uri", a_uuid);
 
                        b_call->joined = 1;
 
@@ -2520,7 +2530,7 @@ static void on_call_unbridge_event(struct rayo_client *rclient, switch_event_t *
                        switch_event_get_header(event, "variable_rayo_call_jid"),
                        switch_event_get_header(event, "variable_rayo_dcp_jid"));
                iks *joined = iks_find(revent, "unjoined");
-               iks_insert_attrib(joined, "call-id", b_uuid);
+               iks_insert_attrib(joined, "call-uri", b_uuid);
                RAYO_SEND(call, rclient, rayo_message_create(revent));
 
                call->joined = 0;
@@ -2530,7 +2540,7 @@ static void on_call_unbridge_event(struct rayo_client *rclient, switch_event_t *
                if (b_call) {
                        revent = iks_new_presence("unjoined", RAYO_NS, RAYO_JID(b_call), rayo_call_get_dcp_jid(b_call));
                        joined = iks_find(revent, "unjoined");
-                       iks_insert_attrib(joined, "call-id", a_uuid);
+                       iks_insert_attrib(joined, "call-uri", a_uuid);
                        RAYO_SEND_BY_JID(b_call, rayo_call_get_dcp_jid(b_call), rayo_message_create(revent));
 
                        b_call->joined = 0;
index 84c3a993a21001cce310a2ce798c9a506c122582..05b5f23771b97927e609b71e82268ccc3f2aac7d 100644 (file)
 
 #define RAYO_NS RAYO_BASE RAYO_VERSION
 #define RAYO_CLIENT_NS RAYO_BASE "client:" RAYO_VERSION
+#define RAYO_CALL_NS RAYO_BASE "call:" RAYO_VERSION
+#define RAYO_MIXER_NS RAYO_BASE "mixer:" RAYO_VERSION
+
+/* this is to support punchblock.. undefine once punchblock is fixed */
+#define RAYO_UUID_IN_REF_URI
 
 struct rayo_actor;
 struct rayo_call;
index 7537edbecea9138b510f9d229d0586c39b922e87..44dc3803a902c9f50093500190a7729fbc8b7b90 100644 (file)
@@ -58,8 +58,11 @@ void rayo_component_send_start(struct rayo_component *component, iks *iq)
        iks *response = iks_new_iq_result(iq);
        iks *ref = iks_insert(response, "ref");
        iks_insert_attrib(ref, "xmlns", RAYO_NS);
-       iks_insert_attrib(ref, "id", component->ref);
+#ifdef RAYO_UUID_IN_REF_URI
+       iks_insert_attrib(ref, "uri", component->ref);
+#else
        iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(component));
+#endif
        RAYO_SEND_BY_JID(component, iks_find_attrib(response, "to"), rayo_message_create(response));
 }
 
index f4e8fba32555e001c0bec401ccfc2754f8855a54..50ce284d50173b61db6fe0b3733bf4a108d6003e 100644 (file)
  * <input> component validation
  */
 ELEMENT(RAYO_INPUT)
-       STRING_ATTRIB(mode, any, "any,dtmf,speech");
+       STRING_ATTRIB(mode, any, "any,dtmf,voice")
        ATTRIB(terminator,, any)
-       ATTRIB(recognizer, en-US, any)
+       ATTRIB(recognizer,, any)
+       ATTRIB(language, en-US, any)
        ATTRIB(initial-timeout, -1, positive_or_neg_one)
        ATTRIB(inter-digit-timeout, -1, positive_or_neg_one)
        ATTRIB(sensitivity, 0.5, decimal_between_zero_and_one)
        ATTRIB(min-confidence, 0, decimal_between_zero_and_one)
        ATTRIB(max-silence, -1, positive_or_neg_one)
+       /* for now, only NLSML */
+       STRING_ATTRIB(match-content-type, application/nlsml+xml, "application/nlsml+xml")
        /* internal attribs for prompt support */
        ATTRIB(barge-event, false, bool)
        ATTRIB(start-timers, true, bool)
@@ -55,16 +58,17 @@ ELEMENT(RAYO_OUTPUT)
        ATTRIB(start-offset, 0, not_negative)
        ATTRIB(start-paused, false, bool)
        ATTRIB(repeat-interval, 0, not_negative)
-       ATTRIB(repeat-times, 1, positive)
+       ATTRIB(repeat-times, 1, not_negative)
        ATTRIB(max-time, -1, positive_or_neg_one)
        ATTRIB(renderer,, any)
+       ATTRIB(voice,, any)
 ELEMENT_END
 
 /**
  * <output><seek> validation
  */
 ELEMENT(RAYO_OUTPUT_SEEK)
-       STRING_ATTRIB(direction,, "forward,back");
+       STRING_ATTRIB(direction,, "forward,back")
        ATTRIB(amount,-1, positive)
 ELEMENT_END
 
@@ -86,7 +90,7 @@ ELEMENT(RAYO_RECORD)
        ATTRIB(max-duration, -1, positive_or_neg_one)
        ATTRIB(initial-timeout, -1, positive_or_neg_one)
        ATTRIB(final-timeout, -1, positive_or_neg_one)
-       STRING_ATTRIB(direction, duplex, "duplex,send,recv");
+       STRING_ATTRIB(direction, duplex, "duplex,send,recv")
        ATTRIB(mix, false, bool)
 ELEMENT_END
 
@@ -98,7 +102,7 @@ ELEMENT(RAYO_JOIN)
        STRING_ATTRIB(direction, duplex, "send,recv,duplex"); */
        STRING_ATTRIB(direction, duplex, "duplex")
        STRING_ATTRIB(media, bridge, "bridge,direct")
-       ATTRIB(call-id,, any)
+       ATTRIB(call-uri,, any)
        ATTRIB(mixer-name,, any)
 ELEMENT_END
 
index 37f3531c2c4f565a9709e76a775ff0b47b4b9c3d..8b59029e36649625c12cbec5d527cbd448105347 100644 (file)
 
 #define MAX_DTMF 64
 
-#define INPUT_INITIAL_TIMEOUT "initial-timeout", RAYO_INPUT_COMPLETE_NS
-#define INPUT_INTER_DIGIT_TIMEOUT "inter-digit-timeout", RAYO_INPUT_COMPLETE_NS
-#define INPUT_MAX_SILENCE "max-silence", RAYO_INPUT_COMPLETE_NS
-#define INPUT_MIN_CONFIDENCE "min-confidence", RAYO_INPUT_COMPLETE_NS
-#define INPUT_MATCH "match", RAYO_INPUT_COMPLETE_NS
+#define INPUT_MATCH_TAG "match"
+#define INPUT_MATCH INPUT_MATCH_TAG, RAYO_INPUT_COMPLETE_NS
+#define INPUT_NOINPUT "noinput", RAYO_INPUT_COMPLETE_NS
 #define INPUT_NOMATCH "nomatch", RAYO_INPUT_COMPLETE_NS
 
 #define RAYO_INPUT_COMPONENT_PRIVATE_VAR "__rayo_input_component"
@@ -166,6 +164,18 @@ static int digit_mask_set_from_digits(int digit_mask, const char *digits)
        return digit_mask;
 }
 
+/**
+ * Send match event to client
+ */
+static void send_match_event(struct rayo_component *component, iks *result)
+{
+       iks *event = rayo_component_create_complete_event_with_metadata(RAYO_COMPONENT(component), INPUT_MATCH, result, 0);
+       /* add content-type to <match>... */
+       iks *match = iks_find(iks_find(event, "complete"), INPUT_MATCH_TAG);
+       iks_insert_attrib(match, "content-type", "application/nlsml+xml");
+       rayo_component_send_complete_event(component, event);
+}
+
 /**
  * Send barge-in event to client
  */
@@ -242,7 +252,7 @@ static switch_status_t input_component_on_dtmf(switch_core_session_t *session, c
                                handler->component = NULL;
                                switch_core_media_bug_remove(session, &handler->bug);
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MATCH = %s\n", component->digits);
-                               rayo_component_send_complete_with_metadata(RAYO_COMPONENT(component), INPUT_MATCH, result, 0);
+                               send_match_event(RAYO_COMPONENT(component), result);
                                iks_delete(result);
                                break;
                        }
@@ -284,16 +294,16 @@ static switch_bool_t input_component_bug_callback(switch_media_bug_t *bug, void
                                                iks *result = nlsml_create_dtmf_match(component->digits);
                                                /* notify of match */
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MATCH = %s\n", component->digits);
-                                               rayo_component_send_complete_with_metadata(RAYO_COMPONENT(component), INPUT_MATCH, result, 0);
+                                               send_match_event(RAYO_COMPONENT(component), result);
                                                iks_delete(result);
                                        } else {
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "inter-digit-timeout\n");
-                                               rayo_component_send_complete(RAYO_COMPONENT(component), INPUT_INTER_DIGIT_TIMEOUT);
+                                               rayo_component_send_complete(RAYO_COMPONENT(component), INPUT_NOMATCH);
                                        }
                                } else if (!component->num_digits && component->initial_timeout > 0 && elapsed_ms > component->initial_timeout) {
                                        handler->component = NULL;
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "initial-timeout\n");
-                                       rayo_component_send_complete(RAYO_COMPONENT(component), INPUT_INITIAL_TIMEOUT);
+                                       rayo_component_send_complete(RAYO_COMPONENT(component), INPUT_NOINPUT);
                                }
                        }
                        switch_core_media_bug_set_read_replace_frame(bug, rframe);
@@ -387,7 +397,10 @@ static iks *start_call_input(struct input_component *component, switch_core_sess
        component->min_confidence = (int)ceil(iks_find_decimal_attrib(input, "min-confidence") * 100.0);
        component->barge_event = iks_find_bool_attrib(input, "barge-event");
        component->start_timers = iks_find_bool_attrib(input, "start-timers");
+       /* TODO this should just be a single digit terminator? */
        component->term_digit_mask = digit_mask_set_from_digits(0, iks_find_attrib_soft(input, "terminator"));
+       /* TODO recognizer ignored */
+       /* TODO language ignored */
        component->handler = handler;
 
        /* parse the grammar */
@@ -543,11 +556,11 @@ static void on_detected_speech_event(switch_event_t *event)
                                enum nlsml_match_type match_type = nlsml_parse(result, uuid);
                                switch (match_type) {
                                case NMT_NOINPUT:
-                                       rayo_component_send_complete(component, INPUT_INITIAL_TIMEOUT);
+                                       rayo_component_send_complete(component, INPUT_NOINPUT);
                                        break;
                                case NMT_MATCH: {
                                        iks *result_xml = nlsml_normalize(result);
-                                       rayo_component_send_complete_with_metadata(component, INPUT_MATCH, result_xml, 0);
+                                       send_match_event(RAYO_COMPONENT(component), result_xml);
                                        iks_delete(result_xml);
                                        break;
                                }
index c208214b3919a1a8d5b6e8115aa897f6ab95a9f6..64bf84371402e86a01bf0dd027950186b4f6de64 100644 (file)
@@ -352,7 +352,7 @@ static switch_status_t next_file(switch_file_handle_t *handle)
 
        /* done? */
        if (!context->cur_doc) {
-               if (++context->play_count < output->repeat_times) {
+               if (output->repeat_times == 0 || ++context->play_count < output->repeat_times) {
                        /* repeat all document(s) */
                        if (!output->repeat_interval) {
                                goto top;