diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c index 1f336b0d85..074f18696e 100644 --- a/libs/libdingaling/src/libdingaling.c +++ b/libs/libdingaling/src/libdingaling.c @@ -125,6 +125,7 @@ struct ldl_session { ldl_candidate_t candidates[LDL_MAX_CANDIDATES]; unsigned int candidate_len; apr_pool_t *pool; + apr_hash_t *variables; apr_time_t created; void *private_data; }; @@ -170,6 +171,16 @@ static unsigned int next_id(void) } +char *ldl_session_get_value(ldl_session_t *session, char *key) +{ + return apr_hash_get(session->variables, key, APR_HASH_KEY_STRING); +} + +void ldl_session_set_value(ldl_session_t *session, char *key, char *val) +{ + apr_hash_set(session->variables, apr_pstrdup(session->pool, key), APR_HASH_KEY_STRING, apr_pstrdup(session->pool, val)); +} + char *ldl_session_get_id(ldl_session_t *session) { return session->id; @@ -223,8 +234,10 @@ ldl_status ldl_session_create(ldl_session_t **session_p, ldl_handle_t *handle, c session->handle = handle; session->created = apr_time_now(); session->state = LDL_STATE_NEW; + session->variables = apr_hash_make(session->pool); *session_p = session; - + + if (globals.debug) { globals.logger(DL_LOG_DEBUG, "Created Session %s\n", id); } @@ -305,7 +318,11 @@ static ldl_status parse_session_code(ldl_handle_t *handle, char *id, char *from, tag = iks_child (xml); while(tag) { - if (!strcasecmp(iks_name(tag), "candidate") && session->candidate_len < LDL_MAX_CANDIDATES) { + if (!strcasecmp(type, "info_element")) { + char *name = iks_find_attrib(tag, "name"); + char *value = iks_find_attrib(tag, "value"); + ldl_session_set_value(session, name, value); + } else if (!strcasecmp(iks_name(tag), "candidate") && session->candidate_len < LDL_MAX_CANDIDATES) { char *key; double pref = 0.0; int index = -1; @@ -812,7 +829,8 @@ static ldl_status new_session_iq(ldl_session_t *session, iks **iqp, iks **sessp, iks *iq, *sess; unsigned int myid; char idbuf[80]; - + apr_hash_index_t *hi; + myid = next_id(); snprintf(idbuf, sizeof(idbuf), "%u", myid); iq = iks_new("iq"); @@ -827,6 +845,19 @@ static ldl_status new_session_iq(ldl_session_t *session, iks **iqp, iks **sessp, iks_insert_attrib(sess, "type", type); iks_insert_attrib(sess, "id", session->id); iks_insert_attrib(sess, "initiator", session->initiator ? session->initiator : session->them); + for (hi = apr_hash_first(session->pool, session->variables); hi; hi = apr_hash_next(hi)) { + void *val = NULL; + const void *key = NULL; + + apr_hash_this(hi, &key, NULL, &val); + if (val) { + iks *var = iks_insert(sess, "info_element"); + iks_insert_attrib(var, "xmlns", "http://www.freeswitch.org/jie"); + iks_insert_attrib(var, "name", (char *) key); + iks_insert_attrib(var, "value", (char *) val); + } + } + *sessp = sess; *iqp = iq; *id = myid; diff --git a/libs/libdingaling/src/libdingaling.h b/libs/libdingaling/src/libdingaling.h index 6ef4b5e3e7..0301456a3e 100644 --- a/libs/libdingaling/src/libdingaling.h +++ b/libs/libdingaling/src/libdingaling.h @@ -191,6 +191,22 @@ typedef void (*ldl_logger_t)(char *file, const char *func, int line, int level, */ ldl_status ldl_session_destroy(ldl_session_t **session_p); +/*! + \brief Get a value from a session + \param session the session + \param key the key to look up + \return the value +*/ +char *ldl_session_get_value(ldl_session_t *session, char *key); + +/*! + \brief Set a value on a session + \param session the session + \param key the key to set + \param val the value of the key +*/ +void ldl_session_set_value(ldl_session_t *session, char *key, char *val); + /*! \brief Create a Jingle Session \param session_p pointer to reference the session diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 7bae9a7c79..290d21ab73 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -143,6 +143,7 @@ struct private_object { switch_time_t next_cand; char *stun_ip; char *recip; + char *dnis; uint16_t stun_port; }; @@ -1065,10 +1066,9 @@ static switch_status_t channel_outgoing_channel(switch_core_session_t *session, char idbuf[1024]; char *full_id; char sess_id[11] = ""; - char workspace[1024]; - - - + char *dnis = NULL; + char workspace[1024] = ""; + switch_copy_string(workspace, outbound_profile->destination_number, sizeof(workspace)); profile_name = workspace; if ((callto = strchr(profile_name, '/'))) { @@ -1079,6 +1079,9 @@ static switch_status_t channel_outgoing_channel(switch_core_session_t *session, return SWITCH_STATUS_GENERR; } + if ((dnis = strchr(profile_name, ':'))) { + *dnis++ = '\0'; + } if ((mdl_profile = switch_core_hash_find(globals.profile_hash, profile_name))) { if (!ldl_handle_ready(mdl_profile->handle)) { @@ -1109,6 +1112,7 @@ static switch_status_t channel_outgoing_channel(switch_core_session_t *session, tech_pvt->codec_index = -1; tech_pvt->local_port = switch_rtp_request_port(); tech_pvt->recip = switch_core_session_strdup(*new_session, full_id); + tech_pvt->dnis = switch_core_session_strdup(*new_session, dnis); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); switch_core_session_destroy(new_session); @@ -1138,6 +1142,9 @@ static switch_status_t channel_outgoing_channel(switch_core_session_t *session, ldl_session_create(&dlsession, mdl_profile->handle, sess_id, full_id, mdl_profile->login); tech_pvt->profile = mdl_profile; ldl_session_set_private(dlsession, *new_session); + ldl_session_set_value(dlsession, "dnis", dnis); + ldl_session_set_value(dlsession, "caller_id_name", outbound_profile->caller_id_name); + ldl_session_set_value(dlsession, "caller_id_number", outbound_profile->caller_id_number); tech_pvt->dlsession = dlsession; get_codecs(tech_pvt); //tech_pvt->desc_id = ldl_session_describe(dlsession, NULL, 0, LDL_DESCRIPTION_INITIATE); @@ -1516,6 +1523,11 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi return LDL_STATUS_FALSE; } if ((session = switch_core_session_request(&channel_endpoint_interface, NULL)) != 0) { + char *exten; + char *context; + char *cid_name; + char *cid_num; + switch_core_session_add_stream(session, NULL); if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object))) != 0) { memset(tech_pvt, 0, sizeof(*tech_pvt)); @@ -1537,17 +1549,33 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating a session for %s\n", ldl_session_get_id(dlsession)); + if (!(exten = ldl_session_get_value(dlsession, "dnis"))) { + exten = profile->exten; + } + + if (!(context = ldl_session_get_value(dlsession, "context"))) { + context = profile->context; + } + + if (!(cid_name = ldl_session_get_value(dlsession, "caller_id_name"))) { + cid_name = tech_pvt->recip; + } + + if (!(cid_num = ldl_session_get_value(dlsession, "caller_id_number"))) { + cid_num = tech_pvt->recip; + } + if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), profile->dialplan, - ldl_session_get_caller(dlsession), - ldl_session_get_caller(dlsession), + cid_name, + cid_num, ldl_session_get_ip(dlsession), - NULL, - NULL, - NULL, + ldl_session_get_value(dlsession, "ani"), + ldl_session_get_value(dlsession, "ani2"), + ldl_session_get_value(dlsession, "rdnis"), (char *)modname, - profile->context, - profile->exten)) != 0) { + context, + exten)) != 0) { char name[128]; snprintf(name, sizeof(name), "DingaLing/%s-%04x", tech_pvt->caller_profile->destination_number, rand() & 0xffff); @@ -1697,11 +1725,12 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi return LDL_STATUS_FALSE; } } - + tech_pvt->remote_ip = switch_core_session_strdup(session, candidates[x].address); ldl_session_set_ip(dlsession, tech_pvt->remote_ip); tech_pvt->remote_port = candidates[x].port; tech_pvt->remote_user = switch_core_session_strdup(session, candidates[x].username); + if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { do_candidates(tech_pvt, 0); }