diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index 1b97dd5f76..7d553fc917 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -228,6 +228,7 @@ SWITCH_DECLARE(char *) switch_channel_get_variable(switch_channel_t *channel, ch * @remark Use switch_hash_next and switch_hash_this with this function to iterate all the channel variables */ SWITCH_DECLARE(switch_hash_index_t *) switch_channel_variable_first(switch_channel_t *channel, switch_memory_pool_t *pool); +SWITCH_DECLARE(void) switch_channel_variable_last(switch_channel_t *channel); /*! \brief Assign a caller extension to a given channel diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 4c6b21cd4a..e81fa65929 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1025,10 +1025,6 @@ static void conference_loop_fn_energy_up(conference_member_t * member, caller_co if (member->energy_level > 3000) { member->energy_level = 3000; } - switch_mutex_unlock(member->flag_mutex); - - snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); - conference_member_say(member, msg, 0); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_channel_t *channel = switch_core_session_get_channel(member->session); @@ -1040,6 +1036,12 @@ static void conference_loop_fn_energy_up(conference_member_t * member, caller_co switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level); switch_event_fire(&event); } + switch_mutex_unlock(member->flag_mutex); + + snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); + conference_member_say(member, msg, 0); + + } } @@ -1051,10 +1053,6 @@ static void conference_loop_fn_energy_equ_conf(conference_member_t * member, cal switch_mutex_lock(member->flag_mutex); member->energy_level = member->conference->energy_level; - switch_mutex_unlock(member->flag_mutex); - - snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); - conference_member_say(member, msg, 0); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_channel_t *channel = switch_core_session_get_channel(member->session); @@ -1066,6 +1064,11 @@ static void conference_loop_fn_energy_equ_conf(conference_member_t * member, cal switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level); switch_event_fire(&event); } + switch_mutex_unlock(member->flag_mutex); + + snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); + conference_member_say(member, msg, 0); + } } @@ -1080,10 +1083,6 @@ static void conference_loop_fn_energy_dn(conference_member_t * member, caller_co if (member->energy_level < 0) { member->energy_level = 0; } - switch_mutex_unlock(member->flag_mutex); - - snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); - conference_member_say(member, msg, 0); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_channel_t *channel = switch_core_session_get_channel(member->session); @@ -1095,6 +1094,13 @@ static void conference_loop_fn_energy_dn(conference_member_t * member, caller_co switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->energy_level); switch_event_fire(&event); } + switch_mutex_unlock(member->flag_mutex); + + snprintf(msg, sizeof(msg), "Energy level %d", member->energy_level); + conference_member_say(member, msg, 0); + + + } } @@ -1107,10 +1113,7 @@ static void conference_loop_fn_volume_talk_up(conference_member_t * member, call switch_mutex_lock(member->flag_mutex); member->volume_out_level++; switch_normalize_volume(member->volume_out_level); - switch_mutex_unlock(member->flag_mutex); - snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); - conference_member_say(member, msg, 0); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_channel_t *channel = switch_core_session_get_channel(member->session); @@ -1122,6 +1125,12 @@ static void conference_loop_fn_volume_talk_up(conference_member_t * member, call switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level); switch_event_fire(&event); } + switch_mutex_unlock(member->flag_mutex); + + + snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); + conference_member_say(member, msg, 0); + } } @@ -1133,10 +1142,7 @@ static void conference_loop_fn_volume_talk_zero(conference_member_t * member, ca switch_mutex_lock(member->flag_mutex); member->volume_out_level = 0; - switch_mutex_unlock(member->flag_mutex); - snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); - conference_member_say(member, msg, 0); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_channel_t *channel = switch_core_session_get_channel(member->session); @@ -1148,6 +1154,13 @@ static void conference_loop_fn_volume_talk_zero(conference_member_t * member, ca switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level); switch_event_fire(&event); } + switch_mutex_unlock(member->flag_mutex); + + + snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); + conference_member_say(member, msg, 0); + + } } @@ -1160,10 +1173,6 @@ static void conference_loop_fn_volume_talk_dn(conference_member_t * member, call switch_mutex_lock(member->flag_mutex); member->volume_out_level--; switch_normalize_volume(member->volume_out_level); - switch_mutex_unlock(member->flag_mutex); - - snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); - conference_member_say(member, msg, 0); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_channel_t *channel = switch_core_session_get_channel(member->session); @@ -1175,6 +1184,12 @@ static void conference_loop_fn_volume_talk_dn(conference_member_t * member, call switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_out_level); switch_event_fire(&event); } + switch_mutex_unlock(member->flag_mutex); + + snprintf(msg, sizeof(msg), "Volume level %d", member->volume_out_level); + conference_member_say(member, msg, 0); + + } } @@ -1187,10 +1202,7 @@ static void conference_loop_fn_volume_listen_up(conference_member_t * member, ca switch_mutex_lock(member->flag_mutex); member->volume_in_level++; switch_normalize_volume(member->volume_in_level); - switch_mutex_unlock(member->flag_mutex); - snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); - conference_member_say(member, msg, 0); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_channel_t *channel = switch_core_session_get_channel(member->session); @@ -1202,6 +1214,14 @@ static void conference_loop_fn_volume_listen_up(conference_member_t * member, ca switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level); switch_event_fire(&event); } + switch_mutex_unlock(member->flag_mutex); + + + snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); + conference_member_say(member, msg, 0); + + + } } @@ -1213,10 +1233,6 @@ static void conference_loop_fn_volume_listen_zero(conference_member_t * member, switch_mutex_lock(member->flag_mutex); member->volume_in_level = 0; - switch_mutex_unlock(member->flag_mutex); - - snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); - conference_member_say(member, msg, 0); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_channel_t *channel = switch_core_session_get_channel(member->session); @@ -1228,6 +1244,13 @@ static void conference_loop_fn_volume_listen_zero(conference_member_t * member, switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level); switch_event_fire(&event); } + switch_mutex_unlock(member->flag_mutex); + + snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); + conference_member_say(member, msg, 0); + + + } } @@ -1240,10 +1263,7 @@ static void conference_loop_fn_volume_listen_dn(conference_member_t * member, ca switch_mutex_lock(member->flag_mutex); member->volume_in_level--; switch_normalize_volume(member->volume_in_level); - switch_mutex_unlock(member->flag_mutex); - snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); - conference_member_say(member, msg, 0); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { switch_channel_t *channel = switch_core_session_get_channel(member->session); @@ -1255,6 +1275,13 @@ static void conference_loop_fn_volume_listen_dn(conference_member_t * member, ca switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->volume_in_level); switch_event_fire(&event); } + switch_mutex_unlock(member->flag_mutex); + + + snprintf(msg, sizeof(msg), "Gain level %d", member->volume_in_level); + conference_member_say(member, msg, 0); + + } } diff --git a/src/mod/applications/mod_enum/mod_enum.c b/src/mod/applications/mod_enum/mod_enum.c index c9d798dc0e..33ddfce394 100644 --- a/src/mod/applications/mod_enum/mod_enum.c +++ b/src/mod/applications/mod_enum/mod_enum.c @@ -591,11 +591,14 @@ static void enum_app_function(switch_core_session_t *session, char *data) void *vval; const void *vvar; - for (hi = switch_channel_variable_first(channel, switch_core_session_get_pool(session)); hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &vval); - if (vvar && !strncmp(vvar, "enum_", 5)) { - switch_channel_set_variable(channel, (char *) vvar, NULL); + if ((hi = switch_channel_variable_first(channel, switch_core_session_get_pool(session)))) { + for (; hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &vval); + if (vvar && !strncmp(vvar, "enum_", 5)) { + switch_channel_set_variable(channel, (char *) vvar, NULL); + } } + switch_channel_variable_last(channel); } for (rtp = globals.route_order; rtp; rtp = rtp->next) { diff --git a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c index aff62974b1..c0b6c4c875 100644 --- a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c +++ b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c @@ -251,28 +251,30 @@ static switch_status_t dialplan_xml_locate(switch_core_session_t *session, switc stream.write_function(&stream, "%s=%s&", prof_names[x], encode_buf); } + if ((hi = switch_channel_variable_first(channel, switch_core_session_get_pool(session)))) { + for (; hi; hi = switch_hash_next(hi)) { + void *val; + const void *var; + switch_hash_this(hi, &var, NULL, &val); + + new_len = (strlen((char *) var) * 3) + 1; + if (encode_len < new_len) { + char *tmp; + + encode_len = new_len; + + if (!(tmp = realloc(encode_buf, encode_len))) { + goto done; + } - for (hi = switch_channel_variable_first(channel, switch_core_session_get_pool(session)); hi; hi = switch_hash_next(hi)) { - void *val; - const void *var; - switch_hash_this(hi, &var, NULL, &val); - - new_len = (strlen((char *) var) * 3) + 1; - if (encode_len < new_len) { - char *tmp; - - encode_len = new_len; - - if (!(tmp = realloc(encode_buf, encode_len))) { - goto done; + encode_buf = tmp; } - encode_buf = tmp; + switch_url_encode((char *) val, encode_buf, encode_len - 1); + stream.write_function(&stream, "%s=%s&", (char *) var, encode_buf); + } - - switch_url_encode((char *) val, encode_buf, encode_len - 1); - stream.write_function(&stream, "%s=%s&", (char *) var, encode_buf); - + switch_channel_variable_last(channel); } e = (char *) stream.data + (strlen((char *) stream.data) - 1); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index b3ac38f463..68a0548c82 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -570,17 +570,20 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) SWITCH_STANDARD_STREAM(stream); - for (hi = switch_channel_variable_first(channel, switch_core_session_get_pool(tech_pvt->session)); hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &vval); - if (vvar && vval) { - const char *name = vvar; - char *value = (char *) vval; - - if (!strncasecmp(name, SOFIA_SIP_HEADER_PREFIX, strlen(SOFIA_SIP_HEADER_PREFIX))) { - const char *hname = name + strlen(SOFIA_SIP_HEADER_PREFIX); - stream.write_function(&stream, "%s: %s\r\n", hname, value); + if ((hi = switch_channel_variable_first(channel, switch_core_session_get_pool(tech_pvt->session)))) { + for (; hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &vval); + if (vvar && vval) { + const char *name = vvar; + char *value = (char *) vval; + + if (!strncasecmp(name, SOFIA_SIP_HEADER_PREFIX, strlen(SOFIA_SIP_HEADER_PREFIX))) { + const char *hname = name + strlen(SOFIA_SIP_HEADER_PREFIX); + stream.write_function(&stream, "%s: %s\r\n", hname, value); + } } } + switch_channel_variable_last(channel); } if (stream.data) { diff --git a/src/switch_channel.c b/src/switch_channel.c index 2797b1cb95..e876af85bf 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -115,6 +115,7 @@ struct switch_channel { switch_hash_t *variables; switch_hash_t *private_hash; switch_call_cause_t hangup_cause; + int vi; }; @@ -306,6 +307,7 @@ SWITCH_DECLARE(char *) switch_channel_get_variable(switch_channel_t *channel, ch char *v = NULL; assert(channel != NULL); + switch_mutex_lock(channel->profile_mutex); if (!(v = switch_core_hash_find(channel->variables, varname))) { if (!channel->caller_profile || !(v = switch_caller_get_field_by_name(channel->caller_profile, varname))) { if (!strcmp(varname, "base_dir")) { @@ -314,27 +316,50 @@ SWITCH_DECLARE(char *) switch_channel_get_variable(switch_channel_t *channel, ch v = switch_core_get_variable(varname); } } + switch_mutex_unlock(channel->profile_mutex); return v; } -SWITCH_DECLARE(switch_hash_index_t *) switch_channel_variable_first(switch_channel_t *channel, switch_memory_pool_t *pool) +SWITCH_DECLARE(void) switch_channel_variable_last(switch_channel_t *channel) { assert(channel != NULL); - return switch_hash_first(pool, channel->variables); + if (channel->vi) { + switch_mutex_unlock(channel->profile_mutex); + } +} + +SWITCH_DECLARE(switch_hash_index_t *) switch_channel_variable_first(switch_channel_t *channel, switch_memory_pool_t *pool) +{ + switch_hash_index_t *hi; + + assert(channel != NULL); + + if ((hi = switch_hash_first(pool, channel->variables))) { + switch_mutex_lock(channel->profile_mutex); + channel->vi = 1; + } + + return hi; } SWITCH_DECLARE(switch_status_t) switch_channel_set_private(switch_channel_t *channel, char *key, void *private_info) { assert(channel != NULL); + switch_mutex_lock(channel->profile_mutex); switch_core_hash_insert_dup(channel->private_hash, switch_core_session_strdup(channel->session, key), private_info); + switch_mutex_unlock(channel->profile_mutex); return SWITCH_STATUS_SUCCESS; } SWITCH_DECLARE(void *) switch_channel_get_private(switch_channel_t *channel, char *key) { assert(channel != NULL); - return switch_core_hash_find(channel->private_hash, key); + void *val; + switch_mutex_lock(channel->profile_mutex); + val = switch_core_hash_find(channel->private_hash, key); + switch_mutex_unlock(channel->profile_mutex); + return val; } SWITCH_DECLARE(switch_status_t) switch_channel_set_name(switch_channel_t *channel, char *name) @@ -361,12 +386,14 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_variable(switch_channel_t *ch assert(channel != NULL); if (varname) { + switch_mutex_lock(channel->profile_mutex); switch_core_hash_delete(channel->variables, varname); if (!switch_strlen_zero(value)) { switch_core_hash_insert_dup(channel->variables, varname, switch_core_session_strdup(channel->session, value)); } else { switch_core_hash_delete(channel->variables, varname); } + switch_mutex_unlock(channel->profile_mutex); return SWITCH_STATUS_SUCCESS; } @@ -378,12 +405,14 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_variable_nodup(switch_channel assert(channel != NULL); if (varname) { + switch_mutex_lock(channel->profile_mutex); switch_core_hash_delete(channel->variables, varname); if (!switch_strlen_zero(value)) { switch_core_hash_insert_dup(channel->variables, varname, value); } else { switch_core_hash_delete(channel->variables, varname); } + switch_mutex_unlock(channel->profile_mutex); return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_ivr.c b/src/switch_ivr.c index bccbc7f540..e6cc981770 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -900,11 +900,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_transfer_variable(switch_core_session void *vval; const void *vvar; - for (hi = switch_channel_variable_first(chana, switch_core_session_get_pool(sessa)); hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &vval); - if (vvar && vval && (!prefix || (var && !strncmp((char *) vvar, var, strlen(var))))) { - switch_channel_set_variable(chanb, (char *) vvar, (char *) vval); + if ((hi = switch_channel_variable_first(chana, switch_core_session_get_pool(sessa)))) { + for (; hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &vval); + if (vvar && vval && (!prefix || (var && !strncmp((char *) vvar, var, strlen(var))))) { + switch_channel_set_variable(chanb, (char *) vvar, (char *) vval); + } } + switch_channel_variable_last(chana); } } @@ -1260,20 +1263,23 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_ } } - for (hi = switch_channel_variable_first(channel, switch_core_session_get_pool(session)); hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &vval); - if (vvar && vval) { - if ((variable = switch_xml_add_child_d(variables, (char *) vvar, v_off++))) { - char *data; - char *value = (char *) vval; - switch_size_t dlen = strlen(value) * 3; - - if ((data = switch_core_session_alloc(session, dlen))) { - switch_url_encode(value, data, dlen); - switch_xml_set_txt_d(variable, data); + if (((hi = switch_channel_variable_first(channel, switch_core_session_get_pool(session))))) { + for (; hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &vval); + if (vvar && vval) { + if ((variable = switch_xml_add_child_d(variables, (char *) vvar, v_off++))) { + char *data; + char *value = (char *) vval; + switch_size_t dlen = strlen(value) * 3; + + if ((data = switch_core_session_alloc(session, dlen))) { + switch_url_encode(value, data, dlen); + switch_xml_set_txt_d(variable, data); + } } } } + switch_channel_variable_last(channel); } caller_profile = switch_channel_get_caller_profile(channel); diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index f24e91e0f3..f60009af5c 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -323,11 +323,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess assert(caller_channel != NULL); /* Copy all the channel variables into the event */ - for (hi = switch_channel_variable_first(caller_channel, switch_core_session_get_pool(session)); hi; hi = switch_hash_next(hi)) { - switch_hash_this(hi, &vvar, NULL, &vval); - if (vvar && vval) { - switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, (void *) vvar, "%s", (char *) vval); + if ((hi = switch_channel_variable_first(caller_channel, switch_core_session_get_pool(session)))) { + for (; hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &vval); + if (vvar && vval) { + switch_event_add_header(var_event, SWITCH_STACK_BOTTOM, (void *) vvar, "%s", (char *) vval); + } } + switch_channel_variable_last(caller_channel); } }