diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 8785bfa9fb1ba054a0635ed9220cf48ae06979b6..3cbbc3b12d63cb942ddd4c975aad4b56def72d52 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -634,6 +634,7 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s ast_party_id_copy(&ast_channel_caller(chan)->id, &session->id); ast_party_id_copy(&ast_channel_caller(chan)->ani, &session->id); + ast_channel_caller(chan)->ani2 = session->ani2; if (!ast_strlen_zero(exten)) { /* Set provided DNID on the new channel. */ diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h index 54c704fd117bc6fc03d89b57525fc2a596032c98..e2ea64ea5979ed79f9c2c06d23c3ca422fbead7f 100644 --- a/include/asterisk/res_pjsip_session.h +++ b/include/asterisk/res_pjsip_session.h @@ -239,6 +239,8 @@ struct ast_sip_session { unsigned int authentication_challenge_count:4; /*! The direction of the call respective to Asterisk */ enum ast_sip_session_call_direction call_direction; + /*! Originating Line Info (ANI II digits) */ + int ani2; }; typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata); diff --git a/res/res_pjsip_caller_id.c b/res/res_pjsip_caller_id.c index 0b166650ef314adf21e11d9b927e21dd0fcaeae4..3b871cdd6aa39341bb731ca66746a9132cc92a10 100644 --- a/res/res_pjsip_caller_id.c +++ b/res/res_pjsip_caller_id.c @@ -33,6 +33,7 @@ #include "asterisk/channel.h" #include "asterisk/module.h" #include "asterisk/callerid.h" +#include "asterisk/conversions.h" /*! * \internal @@ -119,6 +120,58 @@ static pjsip_fromto_hdr *get_id_header(pjsip_rx_data *rdata, const pj_str_t *hea return parsed_hdr; } +/*! + * \internal + * \brief Set an ANI2 integer based on OLI data in a From header + * + * This uses the contents of a From header in order to set Originating Line information. + * + * \param rdata The incoming message + * \param ani2 The ANI2 field to set + * \retval 0 Successfully parsed OLI + * \retval non-zero Could not parse OLI + */ +static int set_id_from_oli(pjsip_rx_data *rdata, int *ani2) +{ + char fromhdr[AST_CHANNEL_NAME]; + const char *s = NULL; + pjsip_sip_uri *uri; + pjsip_name_addr *id_name_addr; + + pjsip_fromto_hdr *from = pjsip_msg_find_hdr(rdata->msg_info.msg, + PJSIP_H_FROM, rdata->msg_info.msg->hdr.next); + id_name_addr = (pjsip_name_addr *) from->uri; + + if (!from) { + /* This had better not happen */ + return -1; + } + + uri = pjsip_uri_get_uri(id_name_addr); + ast_copy_pj_str(fromhdr, &uri->user, sizeof(fromhdr)); + + /* Look for the possible OLI tags. */ + if ((s = strcasestr(fromhdr, ";isup-oli="))) { + s += 10; + } else if ((s = strcasestr(fromhdr, ";ss7-oli="))) { + s += 9; + } else if ((s = strcasestr(fromhdr, ";oli="))) { + s += 5; + } + + if (ast_strlen_zero(s)) { + /* OLI tag is missing, or present with nothing following the '=' sign */ + return -1; + } + + /* just in case OLI is quoted */ + if (*s == '\"') { + s++; + } + + return ast_str_to_int(s, ani2); +} + /*! * \internal * \brief Set an ast_party_id structure based on data in a P-Asserted-Identity header @@ -371,6 +424,7 @@ static void update_incoming_connected_line(struct ast_sip_session *session, pjsi static int caller_id_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata) { if (!session->channel) { + int ani2; /* * Since we have no channel this must be the initial inbound * INVITE. Set the session ID directly because the channel @@ -387,6 +441,11 @@ static int caller_id_incoming_request(struct ast_sip_session *session, pjsip_rx_ if (!session->endpoint->id.self.number.valid) { set_id_from_from(rdata, &session->id); } + if (!set_id_from_oli(rdata, &ani2)) { + session->ani2 = ani2; + } else { + session->ani2 = 0; + } } else { /* * ReINVITE or UPDATE. Check for changes to the ID and queue