Implement basic Support for Global Call Reference.
* Add GCR to mncc struct and therefore bump mncc version. * Add the GCR as a SIP Header and retrieve any such header from incoming SIP calls, passing the GCR on to MNCC Depends: osmo-msc I705c860e51637b4537cad65a330ecbaaca96dd5b Change-Id: Id40d7e0fed9356f801b3627c118150055e7232b1
This commit is contained in:
parent
1c76aadeed
commit
42304d9139
|
@ -31,6 +31,7 @@ struct call {
|
||||||
|
|
||||||
const char *source;
|
const char *source;
|
||||||
const char *dest;
|
const char *dest;
|
||||||
|
struct osmo_gcr_parsed gcr;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -543,6 +543,7 @@ static void check_setup(struct mncc_connection *conn, const char *buf, int rc)
|
||||||
leg->conn = conn;
|
leg->conn = conn;
|
||||||
leg->state = MNCC_CC_INITIAL;
|
leg->state = MNCC_CC_INITIAL;
|
||||||
leg->dir = MNCC_DIR_MO;
|
leg->dir = MNCC_DIR_MO;
|
||||||
|
leg->base.call->gcr = data->gcr;
|
||||||
memcpy(&leg->called, called, sizeof(leg->called));
|
memcpy(&leg->called, called, sizeof(leg->called));
|
||||||
memcpy(&leg->calling, &data->calling, sizeof(leg->calling));
|
memcpy(&leg->calling, &data->calling, sizeof(leg->calling));
|
||||||
memcpy(&leg->imsi, data->imsi, sizeof(leg->imsi));
|
memcpy(&leg->imsi, data->imsi, sizeof(leg->imsi));
|
||||||
|
@ -898,6 +899,7 @@ int mncc_create_remote_leg(struct mncc_connection *conn, struct call *call)
|
||||||
|
|
||||||
mncc.fields |= MNCC_F_CALLING;
|
mncc.fields |= MNCC_F_CALLING;
|
||||||
mncc.calling.plan = GSM48_NPI_ISDN_E164;
|
mncc.calling.plan = GSM48_NPI_ISDN_E164;
|
||||||
|
mncc.gcr = call->gcr;
|
||||||
|
|
||||||
if (call->source && call->source[0] == '+') {
|
if (call->source && call->source[0] == '+') {
|
||||||
mncc.calling.type = GSM48_TON_INTERNATIONAL;
|
mncc.calling.type = GSM48_TON_INTERNATIONAL;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <osmocom/core/linuxlist.h>
|
#include <osmocom/core/linuxlist.h>
|
||||||
#include <osmocom/gsm/mncc.h>
|
#include <osmocom/gsm/mncc.h>
|
||||||
|
#include <osmocom/gsm/gsm29205.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
@ -159,6 +160,7 @@ struct gsm_mncc {
|
||||||
|
|
||||||
unsigned char lchan_type;
|
unsigned char lchan_type;
|
||||||
unsigned char lchan_mode;
|
unsigned char lchan_mode;
|
||||||
|
struct osmo_gcr_parsed gcr;
|
||||||
|
|
||||||
/* A buffer to contain SDP ('\0' terminated) */
|
/* A buffer to contain SDP ('\0' terminated) */
|
||||||
char sdp[1024];
|
char sdp[1024];
|
||||||
|
@ -170,7 +172,7 @@ struct gsm_data_frame {
|
||||||
unsigned char data[0];
|
unsigned char data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MNCC_SOCK_VERSION 7
|
#define MNCC_SOCK_VERSION 8
|
||||||
struct gsm_mncc_hello {
|
struct gsm_mncc_hello {
|
||||||
uint32_t msg_type;
|
uint32_t msg_type;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
|
25
src/sip.c
25
src/sip.c
|
@ -113,9 +113,22 @@ static void new_call(struct sip_agent *agent, nua_handle_t *nh,
|
||||||
struct sip_call_leg *leg;
|
struct sip_call_leg *leg;
|
||||||
const char *from = NULL, *to = NULL;
|
const char *from = NULL, *to = NULL;
|
||||||
char ip_addr[INET6_ADDRSTRLEN];
|
char ip_addr[INET6_ADDRSTRLEN];
|
||||||
|
char gcr_hex[sizeof(call->gcr)*2] = {0};
|
||||||
|
uint8_t gcr_back[28] = {0};
|
||||||
|
|
||||||
|
|
||||||
LOGP(DSIP, LOGL_INFO, "Incoming call(%s) handle(%p)\n", sip->sip_call_id->i_id, nh);
|
LOGP(DSIP, LOGL_INFO, "Incoming call(%s) handle(%p)\n", sip->sip_call_id->i_id, nh);
|
||||||
|
|
||||||
|
sip_unknown_t *unknown_header = sip->sip_unknown;
|
||||||
|
while (unknown_header != NULL) {
|
||||||
|
if (!strcmp("X-Global-Call-Ref", unknown_header->un_name)) {
|
||||||
|
memcpy(gcr_hex, unknown_header->un_value, sizeof(gcr_hex));
|
||||||
|
osmo_hexparse(gcr_hex, gcr_back, sizeof(gcr_back));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
unknown_header = unknown_header->un_next;
|
||||||
|
}
|
||||||
|
|
||||||
if (!sdp_screen_sdp(sip)) {
|
if (!sdp_screen_sdp(sip)) {
|
||||||
LOGP(DSIP, LOGL_ERROR, "No supported codec.\n");
|
LOGP(DSIP, LOGL_ERROR, "No supported codec.\n");
|
||||||
nua_respond(nh, SIP_406_NOT_ACCEPTABLE, TAG_END());
|
nua_respond(nh, SIP_406_NOT_ACCEPTABLE, TAG_END());
|
||||||
|
@ -131,6 +144,8 @@ static void new_call(struct sip_agent *agent, nua_handle_t *nh,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osmo_dec_gcr(&call->gcr, gcr_back, sizeof(gcr_back));
|
||||||
|
|
||||||
if (sip->sip_to)
|
if (sip->sip_to)
|
||||||
to = sip->sip_to->a_url->url_user;
|
to = sip->sip_to->a_url->url_user;
|
||||||
if (sip->sip_from)
|
if (sip->sip_from)
|
||||||
|
@ -594,6 +609,13 @@ static int send_invite(struct sip_agent *agent, struct sip_call_leg *leg,
|
||||||
const char *calling_num, const char *called_num)
|
const char *calling_num, const char *called_num)
|
||||||
{
|
{
|
||||||
struct call_leg *other = leg->base.call->initial;
|
struct call_leg *other = leg->base.call->initial;
|
||||||
|
char gcr_hex[sizeof(leg->base.call->gcr)*2] = { NULL };
|
||||||
|
|
||||||
|
struct msgb *msg = msgb_alloc(128, "gcr-header");
|
||||||
|
uint8_t len = osmo_enc_gcr(msg, &leg->base.call->gcr);
|
||||||
|
osmo_strlcpy(gcr_hex, osmo_hexdump_nospc(msg->data, len*2+2), len*2+2);
|
||||||
|
msgb_free(msg);
|
||||||
|
|
||||||
|
|
||||||
char *from = talloc_asprintf(leg, "sip:%s@%s:%d",
|
char *from = talloc_asprintf(leg, "sip:%s@%s:%d",
|
||||||
calling_num,
|
calling_num,
|
||||||
|
@ -605,6 +627,8 @@ static int send_invite(struct sip_agent *agent, struct sip_call_leg *leg,
|
||||||
agent->app->sip.remote_port);
|
agent->app->sip.remote_port);
|
||||||
char *sdp = sdp_create_file(leg, other, sdp_sendrecv);
|
char *sdp = sdp_create_file(leg, other, sdp_sendrecv);
|
||||||
|
|
||||||
|
char *x_gcr = talloc_asprintf(leg, "X-Global-Call-Ref: %s", gcr_hex);
|
||||||
|
|
||||||
leg->state = SIP_CC_INITIAL;
|
leg->state = SIP_CC_INITIAL;
|
||||||
leg->dir = SIP_DIR_MT;
|
leg->dir = SIP_DIR_MT;
|
||||||
nua_invite(leg->nua_handle,
|
nua_invite(leg->nua_handle,
|
||||||
|
@ -612,6 +636,7 @@ static int send_invite(struct sip_agent *agent, struct sip_call_leg *leg,
|
||||||
SIPTAG_TO_STR(to),
|
SIPTAG_TO_STR(to),
|
||||||
NUTAG_MEDIA_ENABLE(0),
|
NUTAG_MEDIA_ENABLE(0),
|
||||||
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
|
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
|
||||||
|
SIPTAG_HEADER_STR(x_gcr),
|
||||||
SIPTAG_PAYLOAD_STR(sdp),
|
SIPTAG_PAYLOAD_STR(sdp),
|
||||||
TAG_END());
|
TAG_END());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue