diff --git a/src/modules/ims_isc/checker.c b/src/modules/ims_isc/checker.c
index f02cf98babc..07381c79abc 100644
--- a/src/modules/ims_isc/checker.c
+++ b/src/modules/ims_isc/checker.c
@@ -393,6 +393,8 @@ static inline isc_match* isc_new_match(ims_filter_criteria *fc, int index) {
fc->application_server.service_info.len);
}
r->index = index;
+ r->include_register_request = fc->application_server.include_register_request;
+ r->include_register_response = fc->application_server.include_register_response;
return r;
}
diff --git a/src/modules/ims_isc/checker.h b/src/modules/ims_isc/checker.h
index f35636ceab3..24a5ec96a75 100644
--- a/src/modules/ims_isc/checker.h
+++ b/src/modules/ims_isc/checker.h
@@ -68,6 +68,8 @@ typedef struct {
char default_handling; /**< handling to apply on failure to contact the AS */
str service_info; /**< additional service information */
int index; /**< index of the matching IFC */
+ int include_register_request; /**< additional flag from the HSS */
+ int include_register_response; /**< additional flag from the HSS */
} isc_match;
diff --git a/src/modules/ims_isc/doc/ims_isc_admin.xml b/src/modules/ims_isc/doc/ims_isc_admin.xml
index 311a25b921f..1c19ab2e979 100644
--- a/src/modules/ims_isc/doc/ims_isc_admin.xml
+++ b/src/modules/ims_isc/doc/ims_isc_admin.xml
@@ -163,6 +163,14 @@ modparam("ims_isc", "add_p_served_user", 1)
A positive return code (1) means that the REGISTER message has
matched to Initial Filter Criteria and is armed for routing.
+ This function handles also the Service Info (if sent by the
+ HSS), the InsertRegisterRequest flag (if sent by the HSS) or the
+ InsertRegisterResponse flag (if sent by the HSS). Either the Service
+ Info OR the original REGISTER request OR the original REGISTER
+ response is added to the body of the REGISTER message, before it is
+ forwarded to the relevant Application Server. Multipart body is not
+ supported in this case.
+
Meaning of the parameters is as follows:
diff --git a/src/modules/ims_isc/third_party_reg.c b/src/modules/ims_isc/third_party_reg.c
index b07773efa89..41877fd5150 100644
--- a/src/modules/ims_isc/third_party_reg.c
+++ b/src/modules/ims_isc/third_party_reg.c
@@ -44,6 +44,7 @@
*/
#include "third_party_reg.h"
+#include "../../core/msg_translator.h"
usrloc_api_t isc_ulb;/*!< Structure containing pointers to usrloc functions*/
@@ -204,7 +205,7 @@ int build_p_associated_uri(ims_subscription* s) {
return 0;
}
-
+static str reg_resp_200OK = {"OK", 2};
/**
* Handle third party registration
@@ -286,7 +287,24 @@ int isc_third_party_reg(struct sip_msg *msg, isc_match *m, isc_mark *mark, udoma
r.pvni = pvni;
r.pani = pani;
r.cv = cv;
- r.service_info = m->service_info;
+ if (m->service_info.s && m->service_info.len) {
+ r.body.content_type = CT_SERVICE_INFO;
+ r.body.content = m->service_info;
+ } else if (m->include_register_request) {
+ r.body.content_type = CT_REGISTER_REQ;
+ r.body.content.s = msg->first_line.u.request.method.s;
+ r.body.content.len = msg->len;
+ } else if (m->include_register_response) {
+ struct bookmark dummy_bm;
+ r.body.content_type = CT_REGISTER_RESP;
+ r.body.content.s = build_res_buf_from_sip_req(200, ®_resp_200OK, 0, msg, (unsigned int*)&r.body.content.len, &dummy_bm);
+ if (!r.body.content.s) {
+ LM_DBG("response building failed for body of third party register request");
+ r.body.content_type = CT_NONE;
+ }
+ } else {
+ r.body.content_type = CT_NONE;
+ }
r.path = path;
if (expires <= 0)
@@ -324,6 +342,13 @@ static str comma = {",", 1};
static str path_mine_s = {"<", 1};
static str path_mine_e = {";lr>", 4};
+static str content_type_s = {"Content-Type: ", 14};
+static str content_type_e = {"\r\n", 2};
+
+static str ct_service_info = {"application/3gpp-ims+xml", 24};
+static str ct_register_req = {"message/sip", 11};
+static str ct_register_resp = {"message/sip", 11};
+
static str body_s = {"", 36};
static str body_e = {"", 26};
@@ -371,6 +396,20 @@ int r_send_third_party_reg(r_third_party_registration *r, int expires) {
h.len += pauri.len;
}
+ if (r->body.content_type == CT_SERVICE_INFO) {
+ h.len += content_type_s.len;
+ h.len += ct_service_info.len;
+ h.len += content_type_e.len;
+ } else if (r->body.content_type == CT_REGISTER_REQ) {
+ h.len += content_type_s.len;
+ h.len += ct_register_req.len;
+ h.len += content_type_e.len;
+ } else if (r->body.content_type == CT_REGISTER_RESP) {
+ h.len += content_type_s.len;
+ h.len += ct_register_resp.len;
+ h.len += content_type_e.len;
+ }
+
h.s = pkg_malloc(h.len);
if (!h.s) {
LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", h.len);
@@ -423,20 +462,53 @@ int r_send_third_party_reg(r_third_party_registration *r, int expires) {
if (p_associated_uri.data_len > 0) {
STR_APPEND(h, pauri);
}
- LM_DBG("SRV INFO:<%.*s>\n", r->service_info.len, r->service_info.s);
- if (r->service_info.len) {
- b.len = body_s.len + r->service_info.len + body_e.len;
- b.s = pkg_malloc(b.len);
- if (!b.s) {
- LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
- b.len = 0;
- return 0;
+ LM_DBG("BODY TYPE(3rd PARTY REGISTER):<%d>\n", r->body.content_type);
+ if (r->body.content_type != CT_NONE) {
+ if (r->body.content_type == CT_SERVICE_INFO) {
+ LM_ERR("BODY (3rd PARTY REGISTER) \"SI\": <%.*s>\n", r->body.content.len, r->body.content.s);
+ b.len = body_s.len + r->body.content.len + body_e.len;
+ b.s = pkg_malloc(b.len);
+ if (!b.s) {
+ LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
+ b.len = 0;
+ goto error;
+ }
+ b.len = 0;
+ STR_APPEND(b, body_s);
+ STR_APPEND(b, r->body.content);
+ STR_APPEND(b, body_e);
+ STR_APPEND(h, content_type_s);
+ STR_APPEND(h, ct_service_info);
+ STR_APPEND(h, content_type_e);
+ } else if (r->body.content_type == CT_REGISTER_REQ) {
+ LM_ERR("BODY (3rd PARTY REGISTER) \"REQ\": <%.*s>\n", r->body.content.len, r->body.content.s);
+ b.len = r->body.content.len;
+ b.s = pkg_malloc(b.len);
+ if (!b.s) {
+ LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
+ b.len = 0;
+ goto error;
+ }
+ b.len = 0;
+ STR_APPEND(b, r->body.content);
+ STR_APPEND(h, content_type_s);
+ STR_APPEND(h, ct_register_req);
+ STR_APPEND(h, content_type_e);
+ } else if (r->body.content_type == CT_REGISTER_RESP) {
+ LM_ERR("BODY (3rd PARTY REGISTER) \"RESP\": <%.*s>\n", r->body.content.len, r->body.content.s);
+ b.len = r->body.content.len;
+ b.s = pkg_malloc(b.len);
+ if (!b.s) {
+ LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len);
+ b.len = 0;
+ goto error;
+ }
+ b.len = 0;
+ STR_APPEND(b, r->body.content);
+ STR_APPEND(h, content_type_s);
+ STR_APPEND(h, ct_register_resp);
+ STR_APPEND(h, content_type_e);
}
-
- b.len = 0;
- STR_APPEND(b, body_s);
- STR_APPEND(b, r->service_info);
- STR_APPEND(b, body_e);
}
set_uac_req(&req, &method, &h, &b, 0,
@@ -450,6 +522,8 @@ int r_send_third_party_reg(r_third_party_registration *r, int expires) {
pkg_free(h.s);
if (b.s)
pkg_free(b.s);
+ if (r->body.content_type == CT_REGISTER_RESP)
+ pkg_free(r->body.content.s);
return 1;
error:
@@ -457,6 +531,8 @@ int r_send_third_party_reg(r_third_party_registration *r, int expires) {
pkg_free(h.s);
if (b.s)
pkg_free(b.s);
+ if (r->body.content_type == CT_REGISTER_RESP)
+ pkg_free(r->body.content.s);
return 0;
}
diff --git a/src/modules/ims_isc/third_party_reg.h b/src/modules/ims_isc/third_party_reg.h
index 66d21ee5bff..d2762c919e2 100644
--- a/src/modules/ims_isc/third_party_reg.h
+++ b/src/modules/ims_isc/third_party_reg.h
@@ -63,6 +63,20 @@ extern int isc_expires_grace; /**< expires value to add to the expires in the
to prevent expiration in AS */
extern struct tm_binds isc_tmb; /**< Structure with pointers to tm funcs */
+
+#define CT_NONE 0
+#define CT_SERVICE_INFO 1
+#define CT_REGISTER_REQ 2
+#define CT_REGISTER_RESP 3
+
+/** one (part of a) body for the reg event notification structure */
+/** Currently we restrict the usage of multipart bodies */
+typedef struct body {
+ char content_type; /* Content-Type header for (one part of the) body*/
+ str content; /* Content of (one part of the) body */
+} body_t;
+
+
/** reg event notification structure */
typedef struct _r_third_party_reg {
str req_uri; /* AS sip uri: */
@@ -71,8 +85,8 @@ typedef struct _r_third_party_reg {
str pvni; /* Visited network id */
str pani; /* Access Network info */
str cv; /* Charging vector */
- str service_info; /* Service info body */
- str path; /* Path header */
+ body_t body; /* The body */
+ str path; /* Path header */
} r_third_party_registration;
int isc_third_party_reg(struct sip_msg *msg, isc_match *m, isc_mark *mark, udomain_t* d);