From 9b6cc17cf97261a3b3443676d277584ebbbd1a0b Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Thu, 13 Jun 2013 11:23:12 -0400 Subject: [PATCH] mod_rayo: updates for 0.2 of spec --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 58 +++++++++++-------- src/mod/event_handlers/mod_rayo/mod_rayo.h | 5 ++ .../event_handlers/mod_rayo/rayo_components.c | 5 +- .../event_handlers/mod_rayo/rayo_elements.h | 16 +++-- .../mod_rayo/rayo_input_component.c | 35 +++++++---- .../mod_rayo/rayo_output_component.c | 2 +- 6 files changed, 78 insertions(+), 43 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index b914f60dcf..ad4e988105 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -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; diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.h b/src/mod/event_handlers/mod_rayo/mod_rayo.h index 84c3a993a2..05b5f23771 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.h +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.h @@ -39,6 +39,11 @@ #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; diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.c b/src/mod/event_handlers/mod_rayo/rayo_components.c index 7537edbece..44dc3803a9 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_components.c @@ -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)); } diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.h b/src/mod/event_handlers/mod_rayo/rayo_elements.h index f4e8fba325..50ce284d50 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.h +++ b/src/mod/event_handlers/mod_rayo/rayo_elements.h @@ -35,14 +35,17 @@ * 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 /** * 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 diff --git a/src/mod/event_handlers/mod_rayo/rayo_input_component.c b/src/mod/event_handlers/mod_rayo/rayo_input_component.c index 37f3531c2c..8b59029e36 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_input_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_input_component.c @@ -33,11 +33,9 @@ #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 ... */ + 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; } diff --git a/src/mod/event_handlers/mod_rayo/rayo_output_component.c b/src/mod/event_handlers/mod_rayo/rayo_output_component.c index c208214b39..64bf843714 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_output_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_output_component.c @@ -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;