Change subscriber profile on location update

From YateBTS
Jump to: navigation, search


Description

This feature allows custom profile set/reset on subscriber location update.
The decision can be made based on subscriber location, update type (CS/PS/EPS), protocol ...
When subscriber's profile is set/deleted using this feature this will be used by YateHSS until next location update.

This feature may be used to change subscriber's profile when roaming into specific network(s).

Each profile may be:

  • Changed: a new profile name is returned. A profile may be returned even if subscriber don't have one (e.g. a ps profile may be set for subscribers not having one)
  • Reset: delete the profile set for the subscriber

The feature is implemented using the following mechanism:

  • YateHSS sends an internal message (named 'prof.change'). This must be enabled (see the section describing it)
  • A custom script must be added to handle specific logic used to change profile(s)

NOTES:

  • When changing subscriber's a profile the new profile must exist in database: it must be already added
  • Profile change feature is triggered before visited check hook

Enable feature

MMI

Go to 'Edit equipment' -> 'YateHSS' (Press 'Control node' -> 'Edit').
In page 'Extra params' add a new custom parameter named 'sub_profile_change', data type: bool.
Make sure the 'Value' is checked (enable).
Press 'Finish' and push changes to equipment (reload is enough).

Manual

Edit /etc/yate/hss/yatehss.conf

[hss]
sub_profile_change=yes

Pushing scripts or regexroute rules using MMI

Go to 'Edit equipment' -> 'YateHSS' (Press 'Control node' -> 'Edit').

  • Javascript scripts: See page 'Scripts'.
    If not available you should update MMI.
    If not working you should update YateHSS.
    If still not working you should check for syntax errors
  • Regexroute: See page 'Routing'.

Available parameters

  • imsi: Subscriber's IMSI
  • imsi_info: Information associated with multi IMSI if applicable (the IMSI is an additional SIM identity) and available
  • operator: Operator name
  • protocol: MAP or DIAMETER
  • operation: Protocol operation (DIAMETER: UpdateLocationRequest, MAP: updateLocation, updateGprsLocation)
  • cs_profile, ps_profile, eps_profile: Corresponding profile names set for subscriber. May be missing if not set

MAP specific:

  • vlr, msc: VLR/MSC number (Global Title), updateLocation only
  • sgsn_num: SGSN number (Global Title), updateGprsLocation only
  • sgsn_addr: SGSN IP, updateGprsLocation only
  • node: Node type, updateGprsLocation only: sgsn, mme, sgsn-mme, mme-sgsn
  • tech: RAT type (updateGprsLocation only): e-utran, utran, geran ...
  • caller_gt: SCCP Calling Party Address GT (if available)
  • caller_ssn: SCCP Calling Party Address SSN (if available)
  • called_gt: SCCP Called Party Address GT (if available)
  • called_ssn: SCCP Called Party Address SSN (if available)
  • remote_pc: MTP origin PC
  • local_pc: MTP destination PC
  • network: The name of the linkset (network) receiving the request

DIAMETER specific:

  • plmn: Visited PLMN ID (MCC + MNC)
  • node: Node type: sgsn, mme, mme-sgsn
  • origin_realm, origin_host: Request originator's identity
  • destination_realm, destination_host: Request destination's identity
  • remote_realm, remote_host: Identity of peer we received the request from
  • local_realm, local_host: Receiving node's identity (local node)
  • tech: RAT type: e-utran, utran, geran ...
  • sgsn_num: SGSN number (Global Title)

Return:
cs_profile, ps_profile and eps_profile parameters are checked if message is handled.
Missing or empty value indicates profile reset.

Examples

In the following examples we have 3 sets of profile changes:

  • profs_1 and profs_2: alter (set) different CS/PS/EPS profile(s)
  • profs_reset_cs: Reset CS profile, leave PS/EPS profiles untouched

We are using the following rules to change profiles:

GT prefix:

  • 882800001, 8838000: return 'profs_1'
  • 88380: return 'profs_2'
  • 88480: return 'profs_reset_cs'

Diameter:

  • For MCCs (country code) 001 and 002: return 'profs_1'
  • For MCC=003 and MNC (operator code) 1 and 2: return 'profs_2'

Javascript

profs_1 = {
    cs_profile: "cs_1",
    ps_profile: "ps_1",
    eps_profile: "eps_1"
};

profs_2 = {
    cs_profile: "cs_2",
    ps_profile: "ps_2",
    eps_profile: "eps_2"
};

profs_reset_cs = {
    cs_profile: ""
};

profs_by_gt_prefix = {
    "882800001": profs_1,
    "8838000": profs_1,
    "88380": profs_2,
    "88480": profs_reset_cs,
};

function findProfByGt(key)
{
    key = "" + key;
    if (!key)
	return null;
    // Use longest prefix match
    // Assume we set minimum 5 digits prefix
    while (key.length >= 5) {
	var obj = profs_by_gt_prefix[key];
	if (obj)
	    return obj;
	key = key.substr(0,key.length - 1);
    }
    return null;
}

function onProfChange(msg)
{
    var chg = undefined;
    switch (msg.operation) {
	case "updateLocation":
	    // MAP update CS location
	    // Find profile(s) change by VLR GT
	    if (chg = findProfByGt(msg.vlr))
		break;
	    return false;
	case "updateGprsLocation":
	    // MAP update PS/EPS location
	    // Find profile(s) change by SGSN GT
	    if (chg = findProfByGt(msg.sgsn_num))
		break;
	    return false;
	case "UpdateLocationRequest":
	    // Diameter update PS/EPS location
	    // Find profile(s) change by MME/SGSN realm (domain)
	    var realm = "" + msg.origin_realm;
	    switch (realm) {
		case /^epc\.mnc[0-9]{3}\.mcc(001|002)\.3gppnetwork\.org$/:
		    chg = profs_1;
		    break;
		case /^epc\.mnc00(1|2)\.mcc003\.3gppnetwork\.org$/:
		    chg = profs_2;
		    break;
	    }
	    // Alternative matching: no REGEXP used
	    if (realm.endsWith(".mcc001.3gppnetwork.org"))
		chg = profs_1;
	    else if (realm.endsWith(".mcc002.3gppnetwork.org"))
		chg = profs_1;
	    else if ("epc.mnc001.mcc003.3gppnetwork.org" == realm)
		chg = profs_2;
	    else if ("epc.mnc002.mcc003.3gppnetwork.org" == realm)
		chg = profs_2;
	    if (chg)
		break;
	    // Find profile(s) change by SGSN GT (if present)
	    if (chg = findProfByGt(msg.sgsn_num))
		break;
	    return false;
	default:
	    return false;
    }
    // Set changes
    for (var p in chg)
	msg[p] = chg[p];
    return true;
}

Message.trackName("prof_change");
Message.install(onProfChange,"prof.change");

Regexroute

[extra]
prof.change=50

[set_prof_1]
.*=return true;cs_profile=cs_1;ps_profile=ps_1;eps_profile=eps_1

[set_prof_2]
.*=return true;cs_profile=cs_2;ps_profile=ps_2;eps_profile=eps_2

[set_prof_reset_cs]
.*=return true;cs_profile

[prof_check_gt]
;= Find profile(s) change by VLR or SGSN GT
${GT}^882800001=goto set_prof_1
${GT}^8838000=goto set_prof_1
${GT}^88380=goto set_prof_2
${GT}^88480=goto set_prof_reset_cs

[prof.change]
${operation}^updateLocation$={
    ;= MAP update CS location
    ;= Find profile(s) change by VLR GT
    .*=include prof_check_gt;GT=${vlr}
    .*=return
}=
${operation}^updateGprsLocation$={
    ;= MAP update PS/EPS location
    ;= Find profile(s) change by SGSN GT
    .*=include prof_check_gt;GT=${sgsn_num}
    .*=return
}=
${operation}^UpdateLocationRequest$={
    ;= Diameter update PS/EPS location
    ;= Find profile(s) change by MME/SGSN realm (domain)
    ${origin_realm}^epc\.mnc[0-9]\{3\}\.mcc\(001\|002\)\.3gppnetwork\.org$=goto set_prof_1
    ${origin_realm}^epc\.mnc00\(1\|2\)\.mcc003\.3gppnetwork\.org$=goto set_prof_2
    ;= Find profile(s) change by SGSN GT (if present)
    .*=include prof_check_gt;GT=${sgsn_num}
    .*=return
}=