yate/modules/sig/camel_map.cpp

9176 lines
386 KiB
C++

/**
* camel_map.cpp
* This file is part of the YATE Project http://YATE.null.ro
*
* MAP/CAMEL TCAP <-> XML translators
*
* Yet Another Telephony Engine - a fully featured software PBX and IVR
* Copyright (C) 2011-2014 Null Team
*
* This software is distributed under multiple licenses;
* see the COPYING file in the main directory for licensing
* information for this specific distribution.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <yatephone.h>
#include <yatesig.h>
#include <string.h>
#include <yatexml.h>
#include <yateasn.h>
using namespace TelEngine;
namespace {
class TcapXUser;
class TcapXModule;
class XMLConnListener;
class XMLConnection;
class TcapXApplication;
class TcapToXml;
class XmlToTcap;
class StringList;
struct MapCamelType;
struct Parameter;
struct Operation;
struct XMLMap {
Regexp name;
const char* map;
const char* tag;
int type;
};
struct TCAPMap {
const char* path;
bool isPrefix; // for this path, XML children are expected to exist
const String name;
};
struct OpTable {
const Operation* mainTable;
const OpTable* fallbackTable;
};
struct AppCtxt {
const char* name;
const char* oid;
const ObjList& ops;
const OpTable* opTable;
};
struct Capability {
const char* name;
const ObjList& ops;
};
class StringList
{
public:
StringList(const char* list, char sep = ',');
virtual ~StringList();
inline operator const ObjList&() const
{ return *m_list; }
private:
ObjList* m_list;
};
class MyDomParser : public XmlDomParser
{
public:
MyDomParser(TcapXApplication* app, const char* name = "MyDomParser", bool fragment = false);
virtual ~MyDomParser();
protected:
virtual void gotElement(const NamedList& element, bool empty);
virtual void endElement(const String& name);
void verifyRoot();
private:
TcapXApplication* m_app;
};
class XMLConnection : public Thread
{
public:
XMLConnection(Socket* skt, TcapXApplication* app);
~XMLConnection();
// inherited from thread
void start();
void run();
void cleanup();
bool writeData(XmlFragment* frag);
private:
Socket* m_socket;
String m_address;
TcapXApplication* m_app;
MyDomParser m_parser;
};
class XMLConnListener : public Thread
{
public:
XMLConnListener(TcapXUser* user, const NamedList& sect);
~XMLConnListener();
virtual bool init();
virtual void run();
void cleanup();
bool createConn(Socket* skt, String& addr);
protected:
// the socket on which we accept connections
TcapXUser* m_user;
Socket m_socket;
String m_host;
int m_port;
};
class Transaction : public NamedString
{
public:
inline Transaction(const char* tcapID, const char* appID, const AppCtxt* ctxt = 0)
: NamedString(tcapID,appID), m_ctxt(ctxt)
{}
inline ~Transaction()
{}
inline const AppCtxt* context()
{ return m_ctxt; }
inline void setContext(AppCtxt* ctxt)
{ m_ctxt = ctxt; }
private:
const AppCtxt* m_ctxt;
};
class IDMap : public ObjList
{
public:
inline IDMap()
{}
inline ~IDMap()
{}
void appendID(const char* tcapID, const char* appID, const AppCtxt* ctxt = 0);
const String& findTcapID(const char* appID);
const String& findAppID(const char* tcapID);
Transaction* findByAppID(const char* appID);
Transaction* findByTcapID(const char* tcapID);
};
class XmlToTcap : public GenObject, public Mutex
{
public:
enum MsgType {
Unknown,
Capability,
Tcap,
};
XmlToTcap(TcapXApplication* app);
~XmlToTcap();
inline bool hasDeclaration()
{ return m_decl != 0; }
inline XmlElement* message()
{ return m_elem; }
inline MsgType type()
{ return m_type; }
bool validDeclaration();
bool valid(XmlDocument* doc);
bool checkXmlns();
bool parse(NamedList& tcapParams);
bool parse(NamedList& tcapParams, XmlElement* elem, String prefix, const AppCtxt* ctxt);
bool handleComponent(NamedList& tcapParams, XmlElement* elem, const AppCtxt* ctxt);
bool handleMAPDialog(NamedList& tcapParams, XmlElement* elem, String prefix);
void reset();
static const TCAPMap s_tcapMap[];
const TCAPMap* findMap(String& path);
bool encodeComponent(DataBlock& payload, XmlElement* elem, bool searchArgs, int& err, Operation* op);
void encodeOperation(Operation* op, XmlElement* elem, DataBlock& payload, int& err, bool searchArgs);
private:
TcapXApplication* m_app;
XmlDeclaration* m_decl;
XmlElement* m_elem;
MsgType m_type;
};
class TcapToXml : public GenObject, public Mutex
{
public:
enum MsgType {
Unknown,
State,
Tcap,
};
enum XmlType {
None,
Element,
NewElement,
Attribute,
Value,
End,
};
TcapToXml(TcapXApplication* app);
~TcapToXml();
inline MsgType type()
{ return m_type; }
bool buildXMLMessage(NamedList& msg, XmlFragment* frag, MsgType type, const AppCtxt* ctxt = 0);
static const XMLMap s_xmlMap[];
void reset();
void handleMAPDialog(XmlElement* root, NamedList& params);
bool decodeDialogPDU(XmlElement* el, const AppCtxt* ctxt, DataBlock& data);
XmlElement* addToXml(XmlElement* root, const XMLMap* map, NamedString* val);
void addComponentsToXml(XmlElement* root, NamedList& params, const AppCtxt* ctxt);
const XMLMap* findMap(String& elem);
void addParametersToXml(XmlElement* elem, String& payloadHex, Operation* op, bool searchArgs = true);
void decodeTcapToXml(TelEngine::XmlElement*, TelEngine::DataBlock&, Operation* op, unsigned int index = 0, bool seachArgs = true);
bool decodeOperation(Operation* op, XmlElement* elem, DataBlock& data, bool searchArgs = true);
private:
TcapXApplication* m_app;
MsgType m_type;
};
class TcapXUser : public TCAPUser, public Mutex
{
public:
enum UserType {
MAP,
CAMEL,
};
TcapXUser(const char* name);
~TcapXUser();
virtual bool tcapIndication(NamedList& params);
virtual bool managementNotify(SCCP::Type type, NamedList& params);
bool findTCAP(const char* name);
int managementState();
void notifyManagementState(bool forced = false);
bool initialize(NamedList& sect);
bool createApplication(Socket* skt, String& addr);
void setListener(XMLConnListener* list);
void removeApp(TcapXApplication* app);
SS7TCAPError applicationRequest(TcapXApplication* app, NamedList& params, int reqType);
bool sendToApp(NamedList& params, TcapXApplication* app = 0, bool saveID = true);
TcapXApplication* findApplication(NamedList& params);
void reorderApps(TcapXApplication* app);
inline UserType type()
{ return m_type; }
inline bool printMessages()
{ return m_printMsg; }
inline bool addEncoding()
{ return m_addEnc; }
inline unsigned int applicationCount()
{
Lock l(m_appsMtx);
return m_apps.count();
}
void statusString(String& str);
protected:
ObjList m_apps;
Mutex m_appsMtx;
XMLConnListener* m_listener;
ObjList m_trIDs;
UserType m_type;
bool m_printMsg;
bool m_addEnc;
SCCPManagement::LocalBroadcast m_mngtStatus;
};
class TcapXApplication : public RefObject, public Mutex
{
public:
enum State {
Waiting,
Active,
ShutDown,
Inactive,
};
enum ParamType {
Unknown,
Null,
Bool,
Integer,
OID,
HexString,
BitString,
TBCD,
AddressString,
AppString,
Enumerated,
Choice,
Sequence,
SequenceOf,
SetOf,
GSMString,
Flags,
CellIdFixedLength,
LAIFixedLength,
CalledPartyNumber,
CallingPartyNumber,
LocationNumber,
OriginalCalledNumber,
RedirectingNumber,
GenericNumber,
ChargeNumber,
HiLayerCompat,
UserServiceInfo,
RedirectionInformation,
None,
};
enum EncType {
BoolEnc,
IntEnc,
OIDEnc,
StringEnc,
NullEnc,
HexEnc,
TelephonyEnc,
NoEnc,
};
enum Error {
NoError,
DataMissing,
UnexpectedDataValue,
};
TcapXApplication(const char* name, Socket* skt, TcapXUser* user);
~TcapXApplication();
bool hasCapability(const char* oper);
bool handleXML();
void receivedXML(XmlDocument* frag);
const String& toString() const
{ return m_name; }
void setIO(XMLConnection* io);
void reportState(State state, const char* error = 0);
void closeConnection();
bool supportCapability(const String& capab);
void sendStateResponse(const char* error = 0);
bool handleCapability(NamedList& params);
bool handleTcap(NamedList& params);
bool handleIndication(NamedList& params);
void reportError(const char* err);
bool sendTcapMsg(NamedList& params, const AppCtxt* ctxt = 0);
bool canHandle(NamedList& params);
void status(NamedList& status);
const AppCtxt* findCtxt(const String& appID, const String& remoteID);
inline State state()
{ return m_state; }
inline unsigned int trCount()
{ Lock l(this); return m_ids.count() + m_pending.count(); }
inline TcapXUser::UserType type()
{ return m_type; }
inline bool addEncoding()
{ return (m_user ? m_user->addEncoding() : false); }
private:
IDMap m_ids;
IDMap m_pending;
ObjList m_capab;
XMLConnection* m_io;
String m_name;
TcapXUser* m_user;
unsigned int m_sentXml;
unsigned int m_receivedXml;
unsigned int m_sentTcap;
unsigned int m_receivedTcap;
State m_state;
TcapToXml m_tcap2Xml;
XmlToTcap m_xml2Tcap;
TcapXUser::UserType m_type;
};
class TcapXModule : public Module
{
public:
TcapXModule();
virtual ~TcapXModule();
//inherited methods
virtual void initialize();
// uninstall relays and message handlers
bool unload();
inline bool showMissing()
{ return m_showMissing; }
protected:
// inherited methods
virtual bool received(Message& msg, int id);
virtual void statusModule(String& str);
void initUsers(Configuration& cfg);
virtual void statusParams(String& str);
virtual void statusDetail(String& str);
unsigned int applicationCount();
private:
Mutex m_usersMtx;
ObjList m_users;
bool m_showMissing;
};
INIT_PLUGIN(TcapXModule);
UNLOAD_PLUGIN(unloadNow)
{
if (unloadNow && !__plugin.unload())
return false;
return true;
}
void printMissing(const char* missing, const char* parent, bool atEncoding = true)
{
if (__plugin.showMissing())
Debug(&__plugin,DebugMild,
(atEncoding ?
"Missing mandatory child '%s' in XML parent '%s'" :
"Missing mandatory parameter '%s' in payload for '%s'"),
missing,parent);
}
const String s_namespace = "http://yate.null.ro/xml/tcap/v1";
static const String s_msgTag = "m";
static const String s_capabTag = "c";
static const String s_component = "component";
static const String s_typeStr = "type";
static const String s_tagAttr = "tag";
static const String s_encAttr = "enc";
static const String s_qualifierAttr = "qualifier";
static const String s_planAttr = "plan";
static const String s_natureAttr = "nature";
static const String s_innAttr = "inn";
static const String s_completeAttr = "complete";
static const String s_restrictAttr = "restrict";
static const String s_screenedtAttr = "screened";
static const String s_userInformation = "userInformation";
static const String s_encodingContentsTag = "encoding-contents";
static const String s_directReferenceTag = "direct-reference";
static const String s_appContext = "application";
static const String s_localTID = "localTID";
static const String s_remoteTID = "remoteTID";
static const String s_tcapUser = "tcap.user";
static const String s_tcapRequestError = "tcap.request.error";
static const String s_tcapLocalTID = "tcap.transaction.localTID";
static const String s_tcapRemoteTID = "tcap.transaction.remoteTID";
static const String s_tcapEndNow = "tcap.transaction.endNow";
static const String s_tcapAppCtxt = "tcap.dialogPDU.application-context-name";
static const String s_tcapDirectReference = "tcap.dialogPDU.userInformation.direct-reference";
static const String s_tcapEncodingContent = "tcap.dialogPDU.userInformation.encoding-contents";
static const String s_tcapEncodingType = "tcap.dialogPDU.userInformation.encoding-type";
static const String s_tcapReqType = "tcap.request.type";
static const String s_tcapCompCount = "tcap.component.count";
static const String s_tcapCompPrefix = "tcap.component";
static const String s_tcapCompPrefixSep = "tcap.component.";
static const String s_tcapAbortCause = "tcap.transaction.abort.cause";
static const String s_tcapAbortInfo = "tcap.transaction.abort.information";
static const String s_tcapCompType = "componentType";
static const String s_tcapOpCodeType = "operationCodeType";
static const String s_tcapOpCode = "operationCode";
static const String s_tcapOpClass = "operationClass";
static const String s_tcapErrCodeType = "errorCodeType";
static const String s_tcapErrCode = "errorCode";
static const String s_tcapProblemCode = "problemCode";
static NamedString s_encodingPath(s_tcapEncodingContent,"");
static const TokenDict s_tagTypes[] = {
{"universal", AsnTag::Universal},
{"application", AsnTag::Application},
{"context", AsnTag::Context},
{"private", AsnTag::Private},
{"", -1},
};
struct Parameter {
const String name;
const AsnTag& tag;
bool isOptional;
TcapXApplication::ParamType type;
const void* content;
};
struct Operation {
const String name;
bool local;
int code;
int opClass;
const AsnTag& argTag;
const Parameter* args;
const AsnTag& retTag;
const Parameter* res;
};
static const TokenDict s_dict_numNature[] = {
{ "unknown", 0x00 },
{ "international", 0x10 },
{ "national", 0x20 },
{ "network-specific", 0x30 },
{ "subscriber", 0x40 },
{ "reserved", 0x50 },
{ "abbreviated", 0x60 },
{ "extension-reserved", 0x70 },
{ 0, 0 },
};
// Numbering Plan Indicator
static const TokenDict s_dict_numPlan[] = {
{ "unknown", 0 },
{ "isdn", 1 },
{ "data", 3 },
{ "telex", 4 },
{ "land-mobile", 6 },
{ "isdn-mobile", 7 },
{ "national", 8 },
{ "private", 9 },
{ "extension-reserved", 15 },
{ 0, 0 },
};
struct MapCamelType {
TcapXApplication::ParamType type;
TcapXApplication::EncType encoding;
bool (*decode)(const Parameter*, MapCamelType*, AsnTag& tag, DataBlock&, XmlElement*, bool, int& err);
bool (*encode)(const Parameter*, MapCamelType*, DataBlock&, XmlElement*, int& err);
};
static const MapCamelType* findType(TcapXApplication::ParamType type);
static AsnTag s_sequenceTag(AsnTag::Universal,AsnTag::Constructor,16);
static AsnTag s_intTag(AsnTag::Universal, AsnTag::Primitive, 2);
static AsnTag s_bitsTag(AsnTag::Universal, AsnTag::Primitive, 3);
static AsnTag s_nullTag(AsnTag::Universal, AsnTag::Primitive, 5);
static AsnTag s_oidTag(AsnTag::Universal, AsnTag::Primitive, 6);
static AsnTag s_hexTag(AsnTag::Universal, AsnTag::Primitive, 4);
static AsnTag s_numStrTag(AsnTag::Universal, AsnTag::Primitive, 18);
static AsnTag s_noTag(AsnTag::Universal, AsnTag::Primitive, 0);
static AsnTag s_enumTag(AsnTag::Universal, AsnTag::Primitive, 10);
static AsnTag s_boolTag(AsnTag::Universal, AsnTag::Primitive, 1);
static const Parameter* findParam(const Parameter* param, const String& tag)
{
if (!param)
return 0;
XDebug(DebugAll,"findParam(param=%s,tag=%s)",param->name.c_str(),tag.c_str());
if (param->type == TcapXApplication::Choice && param->content) {
const Parameter* p = static_cast<const Parameter*>(param->content);
if (p)
return findParam(p,tag);
}
while (param && !TelEngine::null(param->name)) {
if (tag == param->name)
return param;
param++;
}
return 0;
}
static bool encodeParam(const Parameter* param, DataBlock& data, XmlElement* elem, int& err);
static bool encodeRaw(const Parameter* param, DataBlock& payload, XmlElement* elem, int& err)
{
if (!elem)
return true;
XDebug(&__plugin,DebugAll,"encodeRaw(param=[%p],elem=%s[%p])",param,elem->getTag().c_str(),elem);
bool hasChildren = false;
bool status = true;
while (XmlElement* child = elem->pop()) {
hasChildren = true;
DataBlock db;
Parameter* p = (Parameter*)findParam(param,elem->getTag());
if (p)
status = encodeParam(p,db,child,err);
else
status = encodeRaw(p,db,child,err);
payload.append(db);
TelEngine::destruct(child);
if (!status)
break;
}
AsnTag tag;
const String* clas = elem->getAttribute(s_typeStr);
bool checkParam = (param && !TelEngine::null(param->name));
if (TelEngine::null(clas)) {
if (checkParam)
tag.classType(param->tag.classType());
else {
Debug(DebugMild,"In <%s> missing %s=\"...\" attribute!",elem->getTag().c_str(),s_typeStr.c_str());
return false;
}
}
else
tag.classType((AsnTag::Class)lookup(*clas,s_tagTypes,AsnTag::Universal));
clas = elem->getAttribute(s_tagAttr);
if (TelEngine::null(clas)) {
if (checkParam)
tag.code(param->tag.code());
else {
Debug(DebugMild,"In <%s> missing %s=\"...\" attribute!",elem->getTag().c_str(),s_tagAttr.c_str());
return false;
}
}
else
tag.code(clas->toInteger());
const String& text = elem->getText();
if (!hasChildren) {
clas = elem->getAttribute(s_encAttr);
if (TelEngine::null(clas)) {
if (text) {
Debug(DebugMild,"In <%s> missing %s=\"...\" attribute!",elem->getTag().c_str(),s_encAttr.c_str());
return false;
}
payload.clear();
tag.type(param ? param->tag.type() : AsnTag::Primitive);
clas = &String::empty();
}
else
tag.type(AsnTag::Primitive);
if (*clas == "hex")
payload.unHexify(text.c_str(),text.length(),' ');
else if (*clas == "int")
payload.insert(ASNLib::encodeInteger(text.toInteger(),false));
else if (*clas == "str")
payload.insert(ASNLib::encodeUtf8(text,false));
else if (*clas == "null")
payload.clear();
else if (*clas == "oid") {
ASNObjId obj = text;
payload.insert(ASNLib::encodeOID(obj,false));
}
else if (*clas == "bool")
payload.insert(ASNLib::encodeBoolean(text.toBoolean(),false));
payload.insert(ASNLib::buildLength(payload));
AsnTag::encode(tag.classType(),tag.type(),tag.code(),payload);
}
else {
tag.type(AsnTag::Constructor);
payload.insert(ASNLib::buildLength(payload));
AsnTag::encode(tag.classType(),tag.type(),tag.code(),payload);
}
return true;
}
static bool encodeParam(const Parameter* param, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeParam(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
MapCamelType* type = const_cast<MapCamelType*>(findType(param->type));
bool ok = true;
if (!type)
ok = encodeRaw(param,data,elem,err);
else {
XmlElement* child = (elem->getTag() == s_component || elem->getTag() == s_encodingContentsTag ? elem->findFirstChild(&param->name) : elem);
if (!child) {
if (!param->isOptional)
return false;
return true;
}
if (child->getAttribute(s_tagAttr) || child->getAttribute(s_encAttr))
ok = encodeRaw(param,data,child,err);
else {
if (param->tag.type() == AsnTag::Constructor &&
!(param->type == TcapXApplication::HexString || param->type == TcapXApplication::SequenceOf
|| param->type == TcapXApplication::Sequence || param->type == TcapXApplication::Choice
|| param->type == TcapXApplication::SetOf))
Debug(&__plugin,DebugCrit,"Encoding definition conflict for param='%s', tag is defined as contructor"
" while its type is primitive",param->name.c_str());
ok = type->encode(param,type,data,child,err);
}
elem->removeChild(child);
}
#ifdef XDEBUG
String str;
str.hexify(data.data(),data.length(),' ');
Debug(&__plugin,DebugAll,"encodeParam(param=%s[%p],elem=%s[%p] has %ssucceeded, encodedData=%s)",param->name.c_str(),param,
elem->getTag().c_str(),elem,(ok ? "" : "not "),str.c_str());
#endif
return ok;
}
static bool decodeRaw(XmlElement* elem, DataBlock& data, bool singleParam = false)
{
if (!(elem && data.length()))
return false;
DDebug(&__plugin,DebugAll,"decodeRaw(elem=%s[%p])",elem->getTag().c_str(),elem);
while (data.length()) {
AsnTag tag;
AsnTag::decode(tag,data);
data.cut(-(int)tag.coding().length());
XmlElement* child = new XmlElement("u");
elem->addChild(child);
child->setAttributeValid(s_typeStr,lookup(tag.classType(),s_tagTypes,""));
child->setAttributeValid(s_tagAttr,String((unsigned int)tag.code()));
if (tag.type() == AsnTag::Primitive) {
String enc;
String value;
int len = 0;
u_int8_t fullTag = tag.classType() | tag.type() | tag.code();
switch (fullTag) {
case ASNLib::BOOLEAN: {
bool val;
if (ASNLib::decodeBoolean(data,&val,false) < 0)
return false;
value = String::boolText(val);
enc = "bool";
}
break;
case ASNLib::INTEGER: {
u_int64_t val;
if (ASNLib::decodeInteger(data,val,sizeof(val),false) < 0)
return false;
// to do fix conversion from u_int64_t
value = String((int)val);
enc = "int";
}
break;
case ASNLib::OBJECT_ID: {
ASNObjId val;
if (ASNLib::decodeOID(data,&val,false) < 0)
return false;
value = val.toString();
enc = "oid";
}
break;
case ASNLib::UTF8_STR: {
if (ASNLib::decodeUtf8(data,&enc,false) < 0)
return false;
value = enc;
enc = "str";
}
break;
case ASNLib::NULL_ID:
if (ASNLib::decodeNull(data,false) < 0)
return false;
enc = "null";
break;
case ASNLib::NUMERIC_STR:
case ASNLib::PRINTABLE_STR:
case ASNLib::IA5_STR:
case ASNLib::VISIBLE_STR: {
int type;
if (ASNLib::decodeString(data,&enc,&type,false) < 0)
return false;
value = enc;
enc = "str";
}
break;
default:
len = ASNLib::decodeLength(data);
if (len < 0) {
DDebug(&__plugin,DebugWarn,"decodeRaw() - invalid length=%d while decoding, stopping",len);
return false;
}
value.hexify(data.data(),(len > (int)data.length() ? data.length() : len),' ');
data.cut(-len);
enc = "hex";
break;
}
child->setAttributeValid(s_encAttr,enc);
child->addText(value);
}
else {
int len = ASNLib::decodeLength(data);
DataBlock payload(data.data(),len);
data.cut(-len);
decodeRaw(child,payload);
}
if (singleParam)
break;
}
return true;
}
static bool decodeParam(const Parameter* param, AsnTag& tag, DataBlock& data, XmlElement* elem, bool addEnc, int& err)
{
if (!(param && elem && data.length()))
return false;
String str;
str.hexify(data.data(),data.length(),' ');
XDebug(&__plugin,DebugAll,"decodeParam(param=%s[%p],elem=%s[%p]) - data = %s",param->name.c_str(),param,elem->getTag().c_str(),
elem,str.c_str());
MapCamelType* type = (MapCamelType*)findType(param->type);
bool ok = true;
if (!type)
ok = decodeRaw(elem,data,true);
else
ok = type->decode(param,type,tag,data,elem,addEnc,err);
XDebug(&__plugin,DebugAll,"decodeParam(param=%s[%p],elem=%s[%p]) %s",param->name.c_str(),param,elem->getTag().c_str(),
elem, (ok ? "OK" : "FAILED"));
return ok;
}
static unsigned int decodeBCD(unsigned int length, String& digits, unsigned char* buff)
{
if (!(buff && length))
return 0;
static const char s_digits[] = "0123456789*#ABC";
unsigned int index = 0;
while (index < length) {
digits += s_digits[(buff[index] & 0x0f)];
u_int8_t odd = (buff[index] >> 4);
if ((odd & 0x0f) != 0x0f)
digits += s_digits[(buff[index] >> 4)];
index++;
}
XDebug(&__plugin,DebugAll,"Decoded BCD digits=%s",digits.c_str());
return index;
}
void encodeBCD(const String& digits, DataBlock& data)
{
XDebug(&__plugin,DebugAll,"encodeBCD(digit=%s)",digits.c_str());
unsigned int len = digits.length() / 2 + (digits.length() % 2 ? 1 : 0);
unsigned char buf[32];
unsigned int i = 0;
unsigned int j = 0;
bool odd = false;
while((i < digits.length()) && (j < len)) {
char c = digits[i++];
unsigned char d = 0;
if (('0' <= c) && (c <= '9'))
d = c - '0';
else if ('*' == c)
d = 10;
else if ('#' == c)
d = 11;
else if ('a' == c || 'A' == c)
d = 12;
else if ('b' == c || 'B' == c)
d = 13;
else if ('c' == c || 'C' == c)
d = 14;
// else if ('.' == c)
// d = 15;
else
continue;
odd = !odd;
if (odd)
buf[j] = d;
else
buf[j++] |= (d << 4);
}
if (odd)
buf[j++] |= 0xf0;
data.append(&buf,j);
}
static bool decodeTBCD(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeTBCD(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,parent->getTag().c_str(),parent);
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
if (addEnc)
child->setAttribute(s_encAttr,"str");
int len = ASNLib::decodeLength(data);
String digits;
len = decodeBCD(len,digits,data.data(0,len));
data.cut(-len);
child->addText(digits);
return true;
}
static bool encodeTBCD(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeTBCD(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
const String& text = elem->getText();
encodeBCD(text,data);
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
return true;
}
static bool decodeTel(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeTel(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
int len = ASNLib::decodeLength(data);
if (len < 1)
return false;
u_int8_t attr = data[0];
child->setAttribute(s_natureAttr,lookup((attr & 0x70),s_dict_numNature,"unknown"));
child->setAttribute(s_planAttr,lookup((attr & 0x0f),s_dict_numPlan,"unknown"));
if ((attr & 0x0f) == 1)
child->setAttribute(s_encAttr,"e164");
else if ((attr & 0x0f) == 6)
child->setAttribute(s_encAttr,"e212");
String digits;
decodeBCD(len - 1,digits,data.data(1,len - 1 ));
data.cut(-len);
child->addText(digits);
return true;
}
static bool encodeTel(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeTel(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,elem->getTag().c_str(),
elem,data.length());
u_int8_t first = 0x80; // noExtension bit set
first |= lookup(elem->attribute(s_natureAttr),s_dict_numNature,0);
first |= lookup(elem->attribute(s_planAttr),s_dict_numPlan,0);
data.append(&first,sizeof(first));
const String& digits = elem->getText();
encodeBCD(digits,data);
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
return true;
}
static bool decodeHex(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeHex(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
if (addEnc)
child->setAttribute(s_encAttr,"hex");
int len = ASNLib::decodeLength(data);
bool checkEoC = (len == ASNLib::IndefiniteForm && tag.type() == AsnTag::Constructor);
if (!checkEoC && len < 0)
return false;
String octets;
if (checkEoC) {
DataBlock d(data.data(),data.length());
int l = ASNLib::parseUntilEoC(d);
octets.hexify(data.data(),l,' ');
data.cut(-l);
ASNLib::matchEOC(data);
}
else {
octets.hexify(data.data(),(len > (int)data.length() ? data.length() : len),' ');
data.cut(-len);
}
child->addText(octets);
return true;
}
static bool encodeHex(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeHexparam=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
const String& text = elem->getText();
if (!data.unHexify(text.c_str(),text.length(),' ')) {
Debug(&__plugin,DebugWarn,"Failed to parse hexified string '%s'",text.c_str());
return false;
}
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());;
return true;
}
static bool decodeOID(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeOID(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
if (addEnc)
child->setAttribute(s_encAttr,"oid");
ASNObjId obj;
ASNLib::decodeOID(data,&obj,false);
child->addText(obj.toString());
return true;
}
static bool encodeOID(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeOID(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
ASNObjId oid = elem->getText();
data.append(ASNLib::encodeOID(oid,false));
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
return true;
}
static bool decodeNull(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeNull(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
if (addEnc)
child->setAttribute(s_encAttr,"null");
int len = ASNLib::decodeNull(data,false);
data.cut(-len);
return true;
}
static bool encodeNull(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeNull(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
ASNObjId oid = elem->getText();
data.append(ASNLib::encodeNull(false));
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
return true;
}
static bool decodeInt(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeInt(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
if (addEnc)
child->setAttribute(s_encAttr,"int");
u_int64_t val;
ASNLib::decodeInteger(data,val,sizeof(val),false);
child->addText(String((int)val));
return true;
}
static bool encodeInt(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeInt(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
u_int64_t val = elem->getText().toInteger();
data.append(ASNLib::encodeInteger(val,false));
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
return true;
}
static bool decodeSeq(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeSeq(param=%s[%p],elem=%s[%p],datalen=%d,first=0x%x)",param->name.c_str(),param,
parent->getTag().c_str(),parent,data.length(),data[0]);
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
int len = ASNLib::decodeLength(data);
bool checkEoC = (len == ASNLib::IndefiniteForm);
len = (checkEoC ? data.length() : len);
if (!checkEoC && len < 0)
return false;
int initLen = data.length();
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
if (param->content) {
const Parameter* params= static_cast<const Parameter*>(param->content);
while (params && params->name) {
if ((initLen - (int)data.length() >= len) || (checkEoC && ASNLib::matchEOC(data) > 0))
break;
AsnTag childTag;
AsnTag::decode(childTag,data);
if (!decodeParam(params,childTag,data,child,addEnc,err)) {
if (!params->isOptional) {
if (err != TcapXApplication::DataMissing)
printMissing(params->name.c_str(),param->name.c_str(),false);
err = TcapXApplication::DataMissing;
return false;
}
else {
params++;
continue;
}
}
params++;
}
}
return true;
}
static bool encodeSeq(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeSeq(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
if (param->content) {
const Parameter* params= static_cast<const Parameter*>(param->content);
while (params && params->name) {
const String& name = params->name;
XmlElement* child = elem->findFirstChild(&name);
if (!child) {
if (!params->isOptional) {
printMissing(params->name.c_str(),param->name.c_str());
err = TcapXApplication::DataMissing;
return false;
}
else {
params++;
continue;
}
}
DataBlock db;
if (!encodeParam(params,db,child,err))
return false;
data.append(db);
elem->removeChild(child);
params++;
}
}
if (param->tag != s_noTag) {
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
}
return true;
}
static bool decodeSeqOf(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc,
int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeSeqOf(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
int len = ASNLib::decodeLength(data);
bool checkEoC = (len == ASNLib::IndefiniteForm);
if (!checkEoC && len < 0)
return false;
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
int initLength = data.length();
int payloadLen = (checkEoC ? data.length() : len);
if (param->content) {
const Parameter* params= static_cast<const Parameter*>(param->content);
while (params && !TelEngine::null(params->name) && payloadLen) {
if (checkEoC && ASNLib::matchEOC(data) > 0)
break;
AsnTag childTag;
AsnTag::decode(childTag,data);
if (!decodeParam(params,childTag,data,child,addEnc,err)) {
if (!param->isOptional) {
if (err != TcapXApplication::DataMissing)
printMissing(params->name.c_str(),param->name.c_str(),false);
err = TcapXApplication::DataMissing;
return false;
}
else
break;
}
payloadLen = data.length() - (initLength - len);
}
}
return true;
}
static bool encodeSeqOf(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeSeqOf(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
if (param->content) {
const Parameter* params = static_cast<const Parameter*>(param->content);
XmlElement* child = elem->pop();
bool atLeastOne = false;
while (params && params->name && child) {
if (!(child->getTag() == params->name)) {
Debug(&__plugin,DebugAll,"Skipping over unknown parameter '%s' for parent '%s', expecting '%s'",
child->tag(),elem->tag(),params->name.c_str());
TelEngine::destruct(child);
child = elem->pop();
continue;
}
DataBlock db;
if (!encodeParam(params,db,child,err)) {
TelEngine::destruct(child);
if (err != TcapXApplication::DataMissing) {
printMissing(params->name.c_str(),param->name.c_str());
err = TcapXApplication::DataMissing;
}
if (!param->isOptional && !(elem->findFirstChild()) && !atLeastOne)
return false;
else {
child = elem->pop();
continue;
}
}
else
atLeastOne = true;
data.append(db);
TelEngine::destruct(child);
child = elem->pop();
}
}
if (param->tag != s_noTag) {
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
}
return true;
}
static bool decodeChoice(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeChoice(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length());
bool checkEoC = false;
if (param->tag != s_noTag) {
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
int len = ASNLib::decodeLength(data);
checkEoC = (len == ASNLib::IndefiniteForm);
if (!checkEoC && len < 0)
return false;
}
XmlElement* child = new XmlElement(param->name);
bool showDebug = !(param->tag == s_noTag && param->isOptional);
if (param->content) {
const Parameter* params= static_cast<const Parameter*>(param->content);
while (params && !TelEngine::null(params->name)) {
AsnTag childTag;
AsnTag::decode(childTag,data);
if (!decodeParam(params,childTag,data,child,addEnc,err)) {
params++;
continue;
}
if (checkEoC)
ASNLib::matchEOC(data);
parent->addChild(child);
return true;
}
if (err != TcapXApplication::DataMissing && showDebug) {
if (__plugin.showMissing())
Debug(&__plugin,DebugNote,"No valid choice in payload for '%s'",child->tag());
err = TcapXApplication::DataMissing;
}
}
TelEngine::destruct(child);
return false;
}
static bool encodeChoice(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeChoice(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
if (param->content) {
const Parameter* params = static_cast<const Parameter*>(param->content);
XmlElement* child = elem->pop();
while (child && params && !TelEngine::null(params->name)) {
if (child->getTag() == params->name) {
DataBlock db;
if (!encodeParam(params,db,child,err)) {
TelEngine::destruct(child);
return false;
}
data.append(db);
if (param->tag != s_noTag) {
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
}
TelEngine::destruct(child);
return true;
}
params++;
}
TelEngine::destruct(child);
}
if (err != TcapXApplication::DataMissing) {
if (__plugin.showMissing())
Debug(&__plugin,DebugNote,"No valid choice was given for parent '%s'",elem->tag());
err = TcapXApplication::DataMissing;
}
return false;
}
static bool decodeEnumerated(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeEnumerated(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
int len = ASNLib::decodeLength(data);
if (len < 0)
return false;
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
u_int8_t val = data[0];
data.cut(-1);
if (param->content) {
const TokenDict* dict = static_cast<const TokenDict*>(param->content);
if (!dict)
return false;
child->addText(lookup(val,dict,""));
if (addEnc)
child->setAttribute(s_encAttr,"str");
}
else {
child->addText(String(val));
if (addEnc)
child->setAttribute(s_encAttr,"int");
}
return true;
}
static bool encodeEnumerated(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeEnumerated(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
if (param->content) {
const TokenDict* dict = static_cast<const TokenDict*>(param->content);
if (!dict)
return false;
const String& text = elem->getText();
int val = lookup(text,dict,-1);
if (val < 0 || val > 255) {
err = TcapXApplication::UnexpectedDataValue;
return false;
}
u_int8_t enumVal = val & 0xff;
data.append(&enumVal,sizeof(enumVal));
}
if (param->tag != s_noTag) {
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
}
return true;
}
static bool decodeBitString(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeBitString(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
if (addEnc)
child->setAttribute(s_encAttr,"str");
String val, str;
int value = 0;
ASNLib::decodeBitString(data,&val,false);
for (unsigned int i = 0; i < val.length(); i++) {
char c = val[i];
if (c == '1') {
int mask = 1 << i;
value |= mask;
}
}
if (param->content) {
const TokenDict* dict = static_cast<const TokenDict*>(param->content);
if (!dict)
return true;
while (dict->token){
if ((dict->value & value) == dict->value)
str.append(dict->token,",");
dict++;
}
}
child->addText(str);
return true;
}
static bool encodeBitString(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeBitString(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
if (param->content) {
const TokenDict* dict = static_cast<const TokenDict*>(param->content);
String val;
int value = 0;
if (dict) {
const String& text = elem->getText();
ObjList* list = text.split(',',false);
while(dict->token){
if (list->find(dict->token))
value |= dict->value;
dict++;
}
TelEngine::destruct(list);
}
int size = sizeof(value) * 8;
bool start = false;
while (size > 0) {
size--;
u_int8_t b = (value >> size) & 0x01;
if (b == 1 && !start)
start = true;
if (start)
val = (b == 1? "1" : "0") + val;
}
data.append(ASNLib::encodeBitString(val,false));
}
if (param->tag != s_noTag) {
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
}
return true;
}
// These tables contain embedded UTF-8 characters
static const char* const s_gsm7base[128] = {
"@", "£", "$", "¥", "è", "é", "ù", "ì", "ò", "Ç", "\n", "Ø", "ø", "\r", "Å", "å",
"Δ", "_", "Φ", "Γ", "Λ", "Ω", "Π", "Ψ", "Σ", "Θ", "Ξ", "", "Æ", "æ", "ß", "É",
" ", "!", "\"", "#", "¤", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
"¡", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Ä", "Ö", "Ñ", "Ü", "§",
"¿", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "ä", "ö", "ñ", "ü", "à"
};
static const char* const s_gsm7esc[128] = {
"", "", "", "", "", "", "", "", "", "", "\f", "", "", "", "", "",
"", "", "", "", "^", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "{", "}", "", "", "", "", "", "\\",
"", "", "", "", "", "", "", "", "", "", "", "", "[", "~", "]", "",
"|", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
};
static void decodeGSM7Bit(DataBlock& data, int& len, String& decoded)
{
u_int8_t bits = 0;
u_int16_t buf = 0;
bool esc = false;
for (int i = 0; i < len; i++) {
buf |= ((u_int16_t)data[i]) << bits;
bits += 8;
while (bits >= 7) {
if (esc) {
decoded << s_gsm7esc[buf & 0x7f];
esc = false;
}
else if ((buf & 0x7f) == 0x1b)
esc = true;
else
decoded << s_gsm7base[buf & 0x7f];
buf >>= 7;
bits -= 7;
}
}
data.cut(-len);
if ((bits == 0) && decoded.endsWith("\r"))
decoded.assign(decoded,decoded.length()-1);
}
static bool decodeGSMString(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeGSMString(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
int len = ASNLib::decodeLength(data);
if (len < 0)
return false;
// TODO - should check Encoding Scheme at some point as also translation tables
XmlElement* enc = new XmlElement(param->name);
parent->addChild(enc);
if (addEnc)
enc->setAttribute(s_encAttr,"str");
String str;
decodeGSM7Bit(data,len,str);
enc->addText(str);
return true;
}
static void encodeGSM7Bit(const String& str, DataBlock& db)
{
if (str.null())
return;
u_int8_t bits = 0;
u_int32_t buf = 0;
String tmp = str;
while (tmp) {
bool notFound = true;
for (int i = 0; i < 128; i++) {
if (tmp.startSkip(s_gsm7base[i],false)) {
buf |= (i << bits);
bits += 7;
notFound = false;
break;
}
}
if (notFound) {
for (int i = 0; i < 128; i++) {
if (tmp.startSkip(s_gsm7esc[i],false)) {
buf |= ((i << 7) | 0x1b) << bits;
bits += 14;
notFound = false;
break;
}
}
if (notFound) {
// TODO: skip one UTF-8 instead of one C char
tmp = tmp.c_str() + 1;
continue;
}
}
while (bits >= 8) {
u_int8_t byte = buf & 0xff;
db.append(&byte,sizeof(byte));
buf >>= 8;
bits -= 8;
}
}
if (bits) {
u_int8_t byte = buf & 0xff;
// if just 1 bit use a shifted \r as filler
if (bits == 1)
byte |= 0x1a;
db.append(&byte,sizeof(byte));
}
}
static bool encodeGSMString(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeGSMString(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
if (elem->getTag() != param->name)
return false;
const String& str = elem->getText();
encodeGSM7Bit(str,data);
if (param->tag != s_noTag) {
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
}
return true;
}
static bool decodeFlags(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeFlags(param=%s[%p],elem=%s[%p],datalen=%d, data[0]=%d)",param->name.c_str(),param,
parent->getTag().c_str(),parent,data.length(),data[0]);
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
int len = ASNLib::decodeLength(data);
if (len <= 0)
return false;
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
if (addEnc)
child->setAttribute(s_encAttr,"str");
u_int8_t flags = data[0];
String str;
if (param->content) {
const SignallingFlags* list = static_cast<const SignallingFlags*>(param->content);
if (!list)
return false;
for (; list->mask; list++) {
if ((flags & list->mask) == list->value)
str.append(list->name,",");
}
}
data.cut(-len);
child->addText(str);
return true;
}
static bool encodeFlags(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeFlags(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
u_int8_t byte = 0;
if (param->content) {
const SignallingFlags* flags = static_cast<const SignallingFlags*>(param->content);
if (!flags)
return false;
const String& text = elem->getText();
ObjList* list = text.split(',',false);
for (ObjList* o = list->skipNull(); o; o = o->skipNext()) {
String* s = static_cast<String*>(o->get());
const SignallingFlags* flag = flags;
for (; flag->mask && *s != flag->name; flag++);
if (!flag->name) {
DDebug(&__plugin,DebugAll,"encodeFlags '%s' not found",s->c_str());
continue;
}
byte |= flag->value;
}
TelEngine::destruct(list);
}
data.append(&byte,sizeof(byte));
if (param->tag != s_noTag) {
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
}
return true;
}
static bool decodeString(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeString(param=%s[%p],elem=%s[%p],datalen=%d, data[0]=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length(),data[0]);
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
String value;
int t = 0;
int len = ASNLib::decodeString(data,&value,&t,false);
if (len <= 0)
return false;
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
child->addText(value);
if (addEnc)
child->setAttribute(s_encAttr,"str");
return true;
}
static bool encodeString(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeString(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
const String& text = elem->getText();
data.append(ASNLib::encodeString(text,ASNLib::PRINTABLE_STR,false));
if (param->tag != s_noTag) {
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
}
return true;
}
static bool decodeBool(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeBool(param=%s[%p],elem=%s[%p],datalen=%d, data[0]=%d)",param->name.c_str(),param,parent->getTag().c_str(),
parent,data.length(),data[0]);
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
bool value = false;
int len = ASNLib::decodeBoolean(data,&value,false);
if (len <= 0)
return false;
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
child->addText(String::boolText(value));
if (addEnc)
child->setAttribute(s_encAttr,"bool");
return true;
}
static bool encodeBool(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeBool(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
bool val = elem->getText().toBoolean();
data.append(ASNLib::encodeBoolean(val,false));
if (param->tag != s_noTag) {
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
}
return true;
}
// Nature of Address Indicator
static const TokenDict s_dict_nai[] = {
{ "subscriber", 1 },
{ "unknown", 2 },
{ "national", 3 },
{ "international", 4 },
{ "network-specific", 5 },
{ "national-routing", 6 },
{ "specific-routing", 7 },
{ "routing-with-cdn", 8 },
{ 0, 0 }
};
// Numbering Plan Indicator
static const TokenDict s_dict_numPlanIsup[] = {
{ "unknown", 0 },
{ "isdn", 1 },
{ "data", 3 },
{ "telex", 4 },
{ "private", 5 },
{ "national", 6 },
{ 0, 0 }
};
// Address Presentation
static const TokenDict s_dict_presentation[] = {
{ "allowed", 0 },
{ "restricted", 1 },
{ "unavailable", 2 },
// aliases for restrict=...
{ "no", 0 },
{ "false", 0 },
{ "yes", 1 },
{ "true", 1 },
{ 0, 0 }
};
// Screening Indicator
static const TokenDict s_dict_screening[] = {
{ "user-provided", 0 },
{ "user-provided-passed", 1 },
{ "user-provided-failed", 2 },
{ "network-provided", 3 },
// aliases for screened=...
{ "no", 0 },
{ "false", 0 },
{ "yes", 1 },
{ "true", 1 },
{ 0, 0 }
};
// Generic number qualifier
static const TokenDict s_dict_qual[] = {
{ "dialed-digits", 0 },
{ "called-additional", 1 },
{ "caller-failed", 2 },
{ "caller-not-screened", 3 },
{ "terminating", 4 },
{ "connected-additional", 5 },
{ "caller-additional", 6 },
{ "called-original", 7 },
{ "redirecting", 8 },
{ "redirection", 9 },
{ 0, 0 }
};
// Utility function - extract just ISUP digits from a parameter
static void getDigits(String& num, bool odd, const unsigned char* buf, unsigned int len)
{
static const char digits[] = "0123456789ABCDE.";
for (unsigned int i = 0; i < len; i++) {
num += digits[buf[i] & 0x0f];
if (odd && ((i+1) == len))
break;
num += digits[buf[i] >> 4];
}
}
// Utility function - write digit sequences
static void setDigits(DataBlock& data, const char* val, unsigned char nai, int b2 = -1, int b0 = -1)
{
unsigned char buf[32];
unsigned int len = 0;
if (b0 >= 0)
buf[len++] = b0 & 0xff;
unsigned int naiPos = len++;
buf[naiPos] = nai & 0x7f;
if (b2 >= 0)
buf[len++] = b2 & 0xff;
bool odd = false;
while (val && (len < sizeof(buf))) {
char c = *val++;
if (!c)
break;
unsigned char n = 0;
if (('0' <= c) && (c <= '9'))
n = c - '0';
else if ('.' == c)
n = 15;
else if ('A' == c)
n = 10;
else if ('B' == c)
n = 11;
else if ('C' == c)
n = 12;
else if ('D' == c)
n = 13;
else
continue;
odd = !odd;
if (odd)
buf[len] = n;
else
buf[len++] |= (n << 4);
}
if (odd) {
buf[naiPos] |= 0x80;
len++;
}
XDebug(&__plugin,DebugAll,"setDigits encoding %u octets (%s)",len,odd ? "odd" : "even");
data.append(buf,len);
}
static bool decodeCallNumber(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data,
XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeCallNumber(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
parent->getTag().c_str(),parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
int len = ASNLib::decodeLength(data);
if (len < 2)
return false;
unsigned int index = 0;
unsigned char qualifier = 0;
if (type->type == TcapXApplication::GenericNumber) {
if (len < 3)
return false;
qualifier = data[index];
index++;
}
bool odd = (data[index] & 0x80) != 0;
unsigned char nai = data[index] & 0x7f;
index++;
unsigned char plan = (data[index] >> 4) & 7;
unsigned char pres = (data[index] >> 2) & 3;
unsigned char scrn = data[index] & 3;
if (type->type == TcapXApplication::GenericNumber)
child->setAttribute(s_qualifierAttr,lookup(qualifier,s_dict_qual,"unknown"));
child->setAttribute(s_natureAttr,lookup(nai,s_dict_nai,"unknown"));
child->setAttribute(s_planAttr,lookup(plan,s_dict_numPlanIsup,"unknown"));
if (plan == 1)
child->setAttribute(s_encAttr,"e164");
String tmp;
switch (type->type) {
case TcapXApplication::CalledPartyNumber:
case TcapXApplication::LocationNumber:
tmp = ((data[index] & 0x80) == 0);
child->setAttribute(s_innAttr,tmp);
break;
case TcapXApplication::CallingPartyNumber:
case TcapXApplication::GenericNumber:
tmp = ((data[index] & 0x80) == 0);
child->setAttribute(s_completeAttr,tmp);
break;
default:
break;
}
switch (type->type) {
case TcapXApplication::CallingPartyNumber:
case TcapXApplication::RedirectingNumber:
case TcapXApplication::OriginalCalledNumber:
case TcapXApplication::LocationNumber:
case TcapXApplication::GenericNumber:
child->setAttribute(s_restrictAttr,lookup(pres,s_dict_presentation));
default:
break;
}
switch (type->type) {
case TcapXApplication::CallingPartyNumber:
case TcapXApplication::LocationNumber:
case TcapXApplication::GenericNumber:
child->setAttribute(s_screenedtAttr,lookup(scrn,s_dict_screening));
default:
break;
}
index++;
String digits;
getDigits(digits,odd,data.data(index,len - index),len - index);
data.cut(-len);
child->addText(digits);
return true;
}
static bool encodeCallNumber(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeCallNumber(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
elem->getTag().c_str(),elem,data.length());
unsigned char nai = lookup(elem->attribute(s_natureAttr),s_dict_nai,2) & 0x7f;
unsigned char plan = lookup(elem->attribute(s_planAttr),s_dict_numPlanIsup,1);
int b0 = -1;
if (type->type == TcapXApplication::GenericNumber) {
b0 = 0;
b0 = 0xff & (lookup(elem->attribute(s_qualifierAttr),s_dict_presentation));
}
// Numbering plan
unsigned char b2 = (plan & 7) << 4;
switch (type->type) {
case TcapXApplication::CalledPartyNumber:
case TcapXApplication::LocationNumber:
if (!TelEngine::null(elem->getAttribute(s_innAttr)) && !elem->getAttribute(s_innAttr)->toBoolean(true))
b2 |= 0x80;
break;
case TcapXApplication::CallingPartyNumber:
case TcapXApplication::GenericNumber:
if (!TelEngine::null(elem->getAttribute(s_completeAttr)) && !elem->getAttribute(s_completeAttr)->toBoolean(true))
b2 |= 0x80;
break;
default:
break;
}
switch (type->type) {
case TcapXApplication::CallingPartyNumber:
case TcapXApplication::RedirectingNumber:
case TcapXApplication::OriginalCalledNumber:
case TcapXApplication::LocationNumber:
case TcapXApplication::GenericNumber:
b2 |= (lookup(elem->attribute(s_restrictAttr),s_dict_presentation) & 3) << 2;
default:
break;
}
switch (param->type) {
case TcapXApplication::CallingPartyNumber:
case TcapXApplication::LocationNumber:
case TcapXApplication::GenericNumber:
b2 |= (lookup(elem->attribute(s_screenedtAttr),s_dict_screening) & 3);
default:
break;
}
const String& digits = elem->getText();
setDigits(data,digits,nai,b2,b0);
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
return true;
}
// Redirection Information (Q,763 3.45) bits CBA
static const TokenDict s_dict_redir_main[] = {
{ "none", 0 },
{ "rerouted", 1 },
{ "rerouted-restrict-all", 2 },
{ "diverted", 3 },
{ "diverted-restrict-all", 4 },
{ "rerouted-restrict-number", 5 },
{ "diverted-restrict-number", 6 },
{ 0, 0 }
};
// Redirection Information (Q,763 3.45) bits HGFE or PONM
static const TokenDict s_dict_redir_reason[] = {
{ "busy", 1 },
{ "noanswer", 2 },
{ "always", 3 },
{ "deflected", 4 },
{ "diverted", 5 },
{ "offline", 6 },
{ 0, 0 }
};
static const String s_reasonOrigAttr = "reason_original";
static const String s_counterAttr = "counter";
static const String s_reasonAttr = "reason";
static bool decodeRedir(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data,
XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeRedir(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
parent->getTag().c_str(),parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
int len = ASNLib::decodeLength(data);
if (len < 1)
return false;
// Redirecting indicator
unsigned char reason = data[0] & 0x07;
child->addText(lookup(reason,s_dict_redir_main,""));
// Original reason
reason = data[0] >> 4;
child->setAttribute(s_reasonOrigAttr,lookup(reason,s_dict_redir_reason));
if (len > 1) {
// Counter
int count = data[1] & 0x07;
if (count)
child->setAttribute(s_counterAttr,String(count));
// Reason
reason = data[1] >> 4;
if (reason)
child->setAttribute(s_reasonAttr,lookup(reason,s_dict_redir_reason));
}
if (addEnc)
child->setAttribute(s_encAttr,"str");
data.cut(-len);
return true;
}
static bool encodeRedir(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodeRedir(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
elem->getTag().c_str(),elem,data.length());
unsigned char b0 = lookup(elem->getText(),s_dict_redir_main,0) & 0x07;
b0 |= (lookup(elem->attribute(s_reasonOrigAttr),s_dict_redir_reason,0) & 0x0f) << 4;
data.append(&b0,sizeof(b0));
unsigned char b1 = String(elem->attribute(s_counterAttr)).toInteger() & 0x07;
b1 |= (lookup(elem->attribute(s_reasonAttr),s_dict_redir_reason,0) & 0x0f) << 4;
data.append(&b1,sizeof(b1));
data.insert(ASNLib::buildLength(data));
data.insert(param->tag.coding());
return true;
}
// Coding standard as defined in Q.931/Q.850
static const TokenDict s_dict_codingStandard[] = {
{"CCITT", 0x00},
{"ISO/IEC", 0x20},
{"national", 0x40},
{"network specific", 0x60},
{0,0}
};
// Q.931 4.5.5. Information transfer capability: Bits 0-4
// Defined for CCITT coding standard
static const TokenDict s_dict_transferCapCCITT[] = {
{"speech", 0x00}, // Speech
{"udi", 0x08}, // Unrestricted digital information
{"rdi", 0x09}, // Restricted digital information
{"3.1khz-audio", 0x10}, // 3.1 khz audio
{"udi-ta", 0x11}, // Unrestricted digital information with tone/announcements
{"video", 0x18}, // Video
{0,0}
};
// Q.931 4.5.5. Transfer mode: Bits 5,6
// Defined for CCITT coding standard
static const TokenDict s_dict_transferModeCCITT[] = {
{"circuit", 0x00}, // Circuit switch mode
{"packet", 0x40}, // Packet mode
{0,0}
};
// Q.931 4.5.5. Transfer rate: Bits 0-4
// Defined for CCITT coding standard
static const TokenDict s_dict_transferRateCCITT[] = {
{"packet", 0x00}, // Packet mode only
{"64kbit", 0x10}, // 64 kbit/s
{"2x64kbit", 0x11}, // 2x64 kbit/s
{"384kbit", 0x13}, // 384 kbit/s
{"1536kbit", 0x15}, // 1536 kbit/s
{"1920kbit", 0x17}, // 1920 kbit/s
{"multirate", 0x18}, // Multirate (64 kbit/s base rate)
{0,0}
};
// Q.931 4.5.5. User information Layer 1 protocol: Bits 0-4
// Defined for CCITT coding standard
static const TokenDict s_dict_formatCCITT[] = {
{"v110", 0x01}, // Recomendation V.110 and X.30
{"mulaw", 0x02}, // Recomendation G.711 mu-law
{"alaw", 0x03}, // Recomendation G.711 A-law
{"g721", 0x04}, // Recomendation G.721 32kbit/s ADPCM and I.460
{"h221", 0x05}, // Recomendation H.221 and H.242
{"non-CCITT", 0x07}, // Non CCITT standardized rate adaption
{"v120", 0x08}, // Recomendation V.120
{"x31", 0x09}, // Recomendation X.31 HDLC flag stuffing
{0,0}
};
static const String s_codingAttr = "coding";
static const String s_transferCapAttr = "transfercap";
static const String s_transferModeAttr = "transfermode";
static const String s_transferRateAttr = "transferrate";
static const String s_multiplierAttr = "multiplier";
static bool decodeUSI(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data,
XmlElement* parent, bool addEnc, int& err)
{
if (!(param && type && data.length() && parent))
return false;
XDebug(&__plugin,DebugAll,"decodeUSI(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
parent->getTag().c_str(),parent,data.length());
if (param->tag != tag)
return false;
data.cut(-(int)tag.coding().length());
XmlElement* child = new XmlElement(param->name);
parent->addChild(child);
int len = ASNLib::decodeLength(data);
if (len < 2)
return false;
// Byte 0: Coding standard (bit 5,6), Information transfer capability (bit 0-4)
// Byte 1: Transfer mode (bit 5,6), Transfer rate (bit 0-4)
unsigned char coding = data[0] & 0x60;
child->setAttribute(s_codingAttr,lookup(coding,s_dict_codingStandard));
coding = data[0] & 0x1f;
child->setAttribute(s_transferCapAttr,lookup(coding,s_dict_transferCapCCITT));
coding = data[1] & 0x60;
child->setAttribute(s_transferModeAttr,lookup(coding,s_dict_transferModeCCITT));
u_int8_t rate = data[1] & 0x1f;
child->setAttribute(s_transferRateAttr,lookup(rate,s_dict_transferRateCCITT));
// Figure 4.11 Note 1: Next byte is the rate multiplier if the transfer rate is 'multirate' (0x18)
u_int8_t crt = 2;
if (rate == 0x18) {
if (len < 3) {
Debug(&__plugin,DebugMild,"decodeUSI(). Invalid length %u. No rate multiplier",len);
return false;
}
child->setAttribute(s_multiplierAttr,String(data[2] & 0x7f));
crt = 3;
}
if (len <= crt) {
data.cut(-len);
return true;
}
u_int8_t ident = (data[crt] & 0x60) >> 5;
if (ident != 1) {
Debug(&__plugin,DebugNote,"decodeUSI(). Invalid layer 1 ident %u",ident);
return true;
}
child->addText(lookup(data[crt] & 0x1f,s_dict_formatCCITT));
data.cut(-len);
return true;
}
static bool encodeUSI(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
{
if (!(param && elem))
return false;
XDebug(&__plugin,DebugAll,"encodUSI(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
elem->getTag().c_str(),elem,data.length());
u_int8_t buff[5] = {2,0x00,0x80,0x80,0x80};
unsigned char coding = lookup(elem->attribute(s_codingAttr),s_dict_codingStandard,0);
unsigned char cap = lookup(elem->attribute(s_transferCapAttr),s_dict_transferCapCCITT,0);
unsigned char mode = lookup(elem->attribute(s_transferModeAttr),s_dict_transferModeCCITT,0);
unsigned char rate = lookup(elem->attribute(s_transferRateAttr),s_dict_transferRateCCITT,0x10);
buff[1] = (coding & 0x60) | (cap & 0x1f);
buff[2] |= (mode & 0x60) | (rate & 0x1f);
if (rate == 0x18) {
buff[0] = 3;
rate = String(elem->attribute(s_multiplierAttr)).toInteger();
buff[3] |= rate & 0x7f;
}
// User information layer data
// Bit 7 = 1, Bits 5,6 = layer (1), Bits 0-4: the value
int format = lookup(elem->getText(),s_dict_formatCCITT,-1);
if (format != -1) {
buff[buff[0] + 1] |= 0x20 | (((unsigned char)format) & 0x1f);
buff[0]++;
}
data.assign(buff,buff[0] + 1);
data.insert(param->tag.coding());
return true;
}
static const StringList s_locationManagementCapabOps("updateLocation,cancelLocation,purgeMS,updateGprsLocation,anyTimeInterrogation");
static const StringList s_authenticationCapabOps("sendAuthenticationInfo,authenticationFailureReport");
static const StringList s_subscriberDataCapabOps("insertSubscriberData,deleteSubscriberData,restoreData");
static const StringList s_routingCapabOps("sendRoutingInfoForGprs,sendRoutingInfoForLCS,statusReport");
static const StringList s_vlrRoutingCapabOps("provideRoamingNumber,provideSubscriberInfo");
static const StringList s_traceSubscriberCapabOps("activateTraceMode,deactivateTraceMode");
static const StringList s_servicesCapabOps("registerSS,eraseSS,activateSS,deactivateSS,interrogateSS,registerPassword,getPassword,"
"processUnstructuredSS-Request,unstructuredSS-Request,unstructuredSS-Notify");
static const StringList s_miscellaneousCapabOps("sendIMSI,readyForSM,setReportingState");
static const StringList s_errorRecoveryCapabOps("reset,forwardCheckSS-Indication,failureReport");
static const StringList s_smscCapabOps("informServiceCentre,alertServiceCentre,sendRoutingInfoForSM,mo-forwardSM,mt-forwardSM,forwardSM");
static const StringList s_noOps("");
static const Capability s_mapCapab[] = {
{"LocationManagement", s_locationManagementCapabOps},
{"Authentication", s_authenticationCapabOps},
{"SubscriberData", s_subscriberDataCapabOps},
{"Routing", s_routingCapabOps},
{"VLR-Routing", s_vlrRoutingCapabOps},
{"TraceSubscriber", s_traceSubscriberCapabOps},
{"Services", s_servicesCapabOps},
{"Miscellaneous", s_miscellaneousCapabOps},
{"ErrorRecovery", s_errorRecoveryCapabOps},
{"Charging", s_noOps},
{"SMSC", s_smscCapabOps},
{"None", s_noOps},
{0, s_noOps},
};
static const StringList s_smscCapabOIDs("shortMsgMO-RelayContext-v3,shortMsgMO-RelayContext-v2,shortMsgMO-RelayContext-v1,"
"shortMsgMT-RelayContext-v3,shortMsgMT-RelayContext-v2");
static const Capability s_mapCapabOID[] = {
{"SMSC", s_smscCapabOIDs},
{"None", s_noOps},
{0, s_noOps},
};
static const Capability s_camelCapabOID[] = {
{"None", s_noOps},
{0, s_noOps},
};
static const MapCamelType s_types[] = {
{TcapXApplication::Null, TcapXApplication::NullEnc, decodeNull, encodeNull},
{TcapXApplication::Integer, TcapXApplication::IntEnc, decodeInt, encodeInt},
{TcapXApplication::OID, TcapXApplication::OIDEnc, decodeOID, encodeOID},
{TcapXApplication::TBCD, TcapXApplication::StringEnc, decodeTBCD, encodeTBCD},
{TcapXApplication::AddressString, TcapXApplication::TelephonyEnc, decodeTel, encodeTel},
{TcapXApplication::HexString, TcapXApplication::HexEnc, decodeHex, encodeHex},
{TcapXApplication::Sequence, TcapXApplication::NoEnc, decodeSeq, encodeSeq},
{TcapXApplication::SequenceOf, TcapXApplication::NoEnc, decodeSeqOf, encodeSeqOf},
// for now, use the same encoder/decoder as SequenceOf, TODO - if needed,replace it
{TcapXApplication::SetOf, TcapXApplication::NoEnc, decodeSeqOf, encodeSeqOf},
{TcapXApplication::Choice, TcapXApplication::NoEnc, decodeChoice, encodeChoice},
{TcapXApplication::Enumerated, TcapXApplication::NoEnc, decodeEnumerated, encodeEnumerated},
{TcapXApplication::GSMString, TcapXApplication::StringEnc, decodeGSMString, encodeGSMString},
{TcapXApplication::BitString, TcapXApplication::HexEnc, decodeBitString, encodeBitString},
{TcapXApplication::Flags, TcapXApplication::StringEnc, decodeFlags, encodeFlags},
{TcapXApplication::AppString, TcapXApplication::StringEnc, decodeString, encodeString},
{TcapXApplication::Bool, TcapXApplication::BoolEnc, decodeBool, encodeBool},
{TcapXApplication::CellIdFixedLength, TcapXApplication::StringEnc, decodeTBCD, encodeTBCD},
{TcapXApplication::LAIFixedLength, TcapXApplication::StringEnc, decodeTBCD, encodeTBCD},
{TcapXApplication::CalledPartyNumber, TcapXApplication::TelephonyEnc, decodeCallNumber, encodeCallNumber},
{TcapXApplication::CallingPartyNumber, TcapXApplication::TelephonyEnc, decodeCallNumber, encodeCallNumber},
{TcapXApplication::LocationNumber, TcapXApplication::TelephonyEnc, decodeCallNumber, encodeCallNumber},
{TcapXApplication::OriginalCalledNumber, TcapXApplication::TelephonyEnc, decodeCallNumber, encodeCallNumber},
{TcapXApplication::RedirectingNumber, TcapXApplication::TelephonyEnc, decodeCallNumber, encodeCallNumber},
{TcapXApplication::GenericNumber, TcapXApplication::TelephonyEnc, decodeCallNumber, encodeCallNumber},
{TcapXApplication::ChargeNumber, TcapXApplication::TelephonyEnc, decodeCallNumber, encodeCallNumber},
{TcapXApplication::RedirectionInformation, TcapXApplication::StringEnc, decodeRedir, encodeRedir},
{TcapXApplication::UserServiceInfo, TcapXApplication::NoEnc, decodeUSI, encodeUSI},
// TODO High Layer Compatibility encode/decode implementation - see User teleservice information (Q.763 3.59)
{TcapXApplication::HiLayerCompat, TcapXApplication::NoEnc, decodeHex, encodeHex},
{TcapXApplication::None, TcapXApplication::NoEnc, 0, 0},
};
static const MapCamelType* findType(TcapXApplication::ParamType type)
{
const MapCamelType* t = s_types;
while (t->type != TcapXApplication::None) {
if (t->type == type)
return t;
t++;
}
return 0;
}
static const AsnTag s_ctxtPrim_0_Tag(AsnTag::Context, AsnTag::Primitive, 0);
static const AsnTag s_ctxtPrim_1_Tag(AsnTag::Context, AsnTag::Primitive, 1);
static const AsnTag s_ctxtPrim_2_Tag(AsnTag::Context, AsnTag::Primitive, 2);
static const AsnTag s_ctxtPrim_3_Tag(AsnTag::Context, AsnTag::Primitive, 3);
static const AsnTag s_ctxtPrim_4_Tag(AsnTag::Context, AsnTag::Primitive, 4);
static const AsnTag s_ctxtPrim_5_Tag(AsnTag::Context, AsnTag::Primitive, 5);
static const AsnTag s_ctxtPrim_6_Tag(AsnTag::Context, AsnTag::Primitive, 6);
static const AsnTag s_ctxtPrim_7_Tag(AsnTag::Context, AsnTag::Primitive, 7);
static const AsnTag s_ctxtPrim_8_Tag(AsnTag::Context, AsnTag::Primitive, 8);
static const AsnTag s_ctxtPrim_9_Tag(AsnTag::Context, AsnTag::Primitive, 9);
static const AsnTag s_ctxtPrim_10_Tag(AsnTag::Context, AsnTag::Primitive, 10);
static const AsnTag s_ctxtPrim_11_Tag(AsnTag::Context, AsnTag::Primitive, 11);
static const AsnTag s_ctxtPrim_12_Tag(AsnTag::Context, AsnTag::Primitive, 12);
static const AsnTag s_ctxtPrim_13_Tag(AsnTag::Context, AsnTag::Primitive, 13);
static const AsnTag s_ctxtPrim_14_Tag(AsnTag::Context, AsnTag::Primitive, 14);
static const AsnTag s_ctxtPrim_15_Tag(AsnTag::Context, AsnTag::Primitive, 15);
static const AsnTag s_ctxtPrim_16_Tag(AsnTag::Context, AsnTag::Primitive, 16);
static const AsnTag s_ctxtPrim_17_Tag(AsnTag::Context, AsnTag::Primitive, 17);
static const AsnTag s_ctxtPrim_18_Tag(AsnTag::Context, AsnTag::Primitive, 18);
static const AsnTag s_ctxtPrim_19_Tag(AsnTag::Context, AsnTag::Primitive, 19);
static const AsnTag s_ctxtPrim_20_Tag(AsnTag::Context, AsnTag::Primitive, 20);
static const AsnTag s_ctxtPrim_21_Tag(AsnTag::Context, AsnTag::Primitive, 21);
static const AsnTag s_ctxtPrim_22_Tag(AsnTag::Context, AsnTag::Primitive, 22);
static const AsnTag s_ctxtPrim_23_Tag(AsnTag::Context, AsnTag::Primitive, 23);
static const AsnTag s_ctxtPrim_24_Tag(AsnTag::Context, AsnTag::Primitive, 24);
static const AsnTag s_ctxtPrim_25_Tag(AsnTag::Context, AsnTag::Primitive, 25);
static const AsnTag s_ctxtPrim_26_Tag(AsnTag::Context, AsnTag::Primitive, 26);
static const AsnTag s_ctxtPrim_27_Tag(AsnTag::Context, AsnTag::Primitive, 27);
static const AsnTag s_ctxtPrim_28_Tag(AsnTag::Context, AsnTag::Primitive, 28);
static const AsnTag s_ctxtPrim_29_Tag(AsnTag::Context, AsnTag::Primitive, 29);
static const AsnTag s_ctxtPrim_30_Tag(AsnTag::Context, AsnTag::Primitive, 30);
static const AsnTag s_ctxtPrim_33_Tag(AsnTag::Context, AsnTag::Primitive, 33);
static const AsnTag s_ctxtPrim_34_Tag(AsnTag::Context, AsnTag::Primitive, 34);
static const AsnTag s_ctxtPrim_35_Tag(AsnTag::Context, AsnTag::Primitive, 35);
static const AsnTag s_ctxtPrim_50_Tag(AsnTag::Context, AsnTag::Primitive, 50);
static const AsnTag s_ctxtPrim_53_Tag(AsnTag::Context, AsnTag::Primitive, 53);
static const AsnTag s_ctxtPrim_54_Tag(AsnTag::Context, AsnTag::Primitive, 54);
static const AsnTag s_ctxtPrim_55_Tag(AsnTag::Context, AsnTag::Primitive, 55);
static const AsnTag s_ctxtPrim_56_Tag(AsnTag::Context, AsnTag::Primitive, 56);
static const AsnTag s_ctxtPrim_57_Tag(AsnTag::Context, AsnTag::Primitive, 57);
static const AsnTag s_ctxtPrim_58_Tag(AsnTag::Context, AsnTag::Primitive, 58);
static const AsnTag s_ctxtCstr_0_Tag(AsnTag::Context, AsnTag::Constructor, 0);
static const AsnTag s_ctxtCstr_1_Tag(AsnTag::Context, AsnTag::Constructor, 1);
static const AsnTag s_ctxtCstr_2_Tag(AsnTag::Context, AsnTag::Constructor, 2);
static const AsnTag s_ctxtCstr_3_Tag(AsnTag::Context, AsnTag::Constructor, 3);
static const AsnTag s_ctxtCstr_4_Tag(AsnTag::Context, AsnTag::Constructor, 4);
static const AsnTag s_ctxtCstr_5_Tag(AsnTag::Context, AsnTag::Constructor, 5);
static const AsnTag s_ctxtCstr_6_Tag(AsnTag::Context, AsnTag::Constructor, 6);
static const AsnTag s_ctxtCstr_7_Tag(AsnTag::Context, AsnTag::Constructor, 7);
static const AsnTag s_ctxtCstr_8_Tag(AsnTag::Context, AsnTag::Constructor, 8);
static const AsnTag s_ctxtCstr_9_Tag(AsnTag::Context, AsnTag::Constructor, 9);
static const AsnTag s_ctxtCstr_10_Tag(AsnTag::Context, AsnTag::Constructor, 10);
static const AsnTag s_ctxtCstr_11_Tag(AsnTag::Context, AsnTag::Constructor, 11);
static const AsnTag s_ctxtCstr_12_Tag(AsnTag::Context, AsnTag::Constructor, 12);
static const AsnTag s_ctxtCstr_13_Tag(AsnTag::Context, AsnTag::Constructor, 13);
static const AsnTag s_ctxtCstr_14_Tag(AsnTag::Context, AsnTag::Constructor, 14);
static const AsnTag s_ctxtCstr_15_Tag(AsnTag::Context, AsnTag::Constructor, 15);
static const AsnTag s_ctxtCstr_16_Tag(AsnTag::Context, AsnTag::Constructor, 16);
static const AsnTag s_ctxtCstr_17_Tag(AsnTag::Context, AsnTag::Constructor, 17);
static const AsnTag s_ctxtCstr_18_Tag(AsnTag::Context, AsnTag::Constructor, 18);
static const AsnTag s_ctxtCstr_21_Tag(AsnTag::Context, AsnTag::Constructor, 21);
static const AsnTag s_ctxtCstr_22_Tag(AsnTag::Context, AsnTag::Constructor, 22);
static const AsnTag s_ctxtCstr_23_Tag(AsnTag::Context, AsnTag::Constructor, 23);
static const AsnTag s_ctxtCstr_24_Tag(AsnTag::Context, AsnTag::Constructor, 24);
static const AsnTag s_ctxtCstr_25_Tag(AsnTag::Context, AsnTag::Constructor, 25);
static const AsnTag s_ctxtCstr_27_Tag(AsnTag::Context, AsnTag::Constructor, 27);
static const AsnTag s_ctxtCstr_28_Tag(AsnTag::Context, AsnTag::Constructor, 28);
static const AsnTag s_ctxtCstr_29_Tag(AsnTag::Context, AsnTag::Constructor, 29);
static const AsnTag s_ctxtCstr_30_Tag(AsnTag::Context, AsnTag::Constructor, 30);
static const AsnTag s_ctxtCstr_31_Tag(AsnTag::Context, AsnTag::Constructor, 31);
static const AsnTag s_ctxtCstr_32_Tag(AsnTag::Context, AsnTag::Constructor, 32);
static const AsnTag s_ctxtCstr_50_Tag(AsnTag::Context, AsnTag::Constructor, 50);
static const AsnTag s_ctxtCstr_51_Tag(AsnTag::Context, AsnTag::Constructor, 51);
static const AsnTag s_ctxtCstr_52_Tag(AsnTag::Context, AsnTag::Constructor, 52);
static const AsnTag s_ctxtCstr_53_Tag(AsnTag::Context, AsnTag::Constructor, 53);
static const AsnTag s_ctxtCstr_57_Tag(AsnTag::Context, AsnTag::Constructor, 57);
static const AsnTag s_ctxtCstr_59_Tag(AsnTag::Context, AsnTag::Constructor, 59);
static const TokenDict s_camelPhases[] = {
{"phase1", 1},
{"phase2", 2},
{"phase3", 4},
{"phase4", 8},
{0,0},
};
static const TokenDict s_ISTSupportIndicator[] = {
{"basicISTSupported", 0},
{"istCommandSupported", 1},
{0, 0},
};
static const Parameter s_superChargerInfo[] = {
{"sendSubscriberData", s_ctxtPrim_0_Tag, false, TcapXApplication::Null, 0},
{"subscriberDataStored", s_ctxtPrim_1_Tag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_supportedLCSCapabilitySets[] = {
{"lcsCapabilitySet1", 0x01},
{"lcsCapabilitySet2", 0x02},
{"lcsCapabilitySet3", 0x04},
{"lcsCapabilitySet4", 0x08},
{"lcsCapabilitySet5", 0x10},
{0, 0},
};
static const TokenDict s_offeredCamel4CSIs[] = {
{"o-csi", 0x01},
{"d-csi", 0x02},
{"vt-csi", 0x04},
{"t-csi", 0x08},
{"mt-sms-csi", 0x10},
{"mg-csi", 0x20},
{"psi-enhancements", 0x40},
{0, 0},
};
static const TokenDict s_supportedRATTypes[] = {
{"utran", 0x01},
{"geran", 0x02},
{"gan", 0x04},
{"i-hspa-evolution", 0x08},
{"e-utran", 0x10},
{0, 0},
};
static const Parameter s_vlrCapability[] = {
{"supportedCamelPhases", s_ctxtPrim_0_Tag, true, TcapXApplication::BitString, s_camelPhases},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"solsaSupportIndicator", s_ctxtPrim_2_Tag, true, TcapXApplication::Null, 0},
{"istSupportIndicator", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_ISTSupportIndicator},
{"superChargerSupportedInServingNetworkEntity", s_ctxtCstr_3_Tag, true, TcapXApplication::Choice, s_superChargerInfo},
{"longFTN-Supported", s_ctxtPrim_4_Tag, true, TcapXApplication::Null, 0},
{"supportedLCS-CapabilitySets", s_ctxtPrim_5_Tag, true, TcapXApplication::BitString, s_supportedLCSCapabilitySets},
{"offeredCamel4CSIs", s_ctxtPrim_6_Tag, true, TcapXApplication::BitString, s_offeredCamel4CSIs},
{"supportedRAT-TypesIndicator", s_ctxtPrim_7_Tag, true, TcapXApplication::BitString, s_supportedRATTypes},
{"longGroupID-Supported", s_ctxtPrim_8_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_addInfoSeq[] = {
{"imeisv", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"skipSubscriberDataUpdate", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_locationArea[] = {
{"laiFixedLength", s_ctxtPrim_0_Tag, false, TcapXApplication::LAIFixedLength, 0},
{"lac", s_ctxtPrim_1_Tag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_locationAreaChoice[] = {
{"locationArea", s_noTag, false, TcapXApplication::Choice, s_locationArea},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_imsiWithLmsi[] = {
{"imsi", s_hexTag, false, TcapXApplication::TBCD, 0},
{"lmsi", s_hexTag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_mapIdentity[] = {
{"imsi", s_hexTag, false, TcapXApplication::TBCD, 0},
{"imsi-WithLMSI", s_sequenceTag, false, TcapXApplication::Sequence, s_imsiWithLmsi},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_cancellationType[] = {
{"updateProcedure", 0x00},
{"subscriptionWithdraw", 0x01},
{"initialAttachProcedure", 0x02},
{0,0},
};
static const TokenDict s_typeOfUpdate[] = {
{"sgsn-change", 0x00},
{"mme-change", 0x01},
{0,0},
};
static const TokenDict s_protocolId[] = {
{"gsm-0408", 0x01},
{"gsm-0806", 0x02},
{"gsm-BSSMAP", 0x03},
{"ets-300102-1",0x04},
{0,0},
};
static const Parameter s_externalSignalInfo[] = {
{"protocolId", s_enumTag, false, TcapXApplication::Enumerated, s_protocolId},
{"signalInfo", s_hexTag, false, TcapXApplication::HexString, 0},
{"extensionContainer",s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_alertPattern[] = {
{"alertingLevel-0", 0x00},
{"alertingLevel-1", 0x01},// AlertingPattern ::= '00000001'B
{"alertingLevel-2", 0x02},// AlertingPattern ::= '00000010'B
{"alertingCategory-1", 0x04},// AlertingPattern ::= '00000100'B
{"alertingCategory-2", 0x05},// AlertingPattern ::= '00000101'B
{"alertingCategory-3", 0x06},// AlertingPattern ::= '00000110'B
{"alertingCategory-4", 0x07},// AlertingPattern ::= '00000111'B
{"alertingCategory-5", 0x08},// AlertingPattern ::= '00001000'B
{0,0},
};
static const TokenDict s_extProtocolId[] = {
{"ets-300356", 0x01},
{0,0},
};
static const Parameter s_extExtenalSignalInfo[] = {
{"ext-protocolId", s_enumTag, false, TcapXApplication::Enumerated, s_extProtocolId},
{"signalInfo", s_hexTag, false, TcapXApplication::HexString, 0},
{"extensionContainer",s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_category[] = {
{ "unknown", 0x00 }, // calling party's category is unknown
{ "operator-FR", 0x01 }, // operator, language French
{ "operator-EN", 0x02 }, // operator, language English
{ "operator-DE", 0x03 }, // operator, language German
{ "operator-RU", 0x04 }, // operator, language Russian
{ "operator-ES", 0x05 }, // operator, language Spanish
{ "ordinary", 0x0a }, // ordinary calling subscriber
{ "priority", 0x0b }, // calling subscriber with priority
{ "data", 0x0c }, // data call (voice band data)
{ "test", 0x0d }, // test call
{ "payphone", 0x0f }, // payphone
{ 0, 0 },
};
static const TokenDict s_subscriberStatus[] = {
{"serviceGranted", 0x00},
{"operatorDeterminedBarring", 0x01},
{0,0},
};
static const TokenDict s_SSCode[] = {
// TS 100 974 v7.15.0 page 321
{"allSS", 0x00}, // SS-Code ::= '00000000'B -- all SS
{"allLineIdentificationSS", 0x10}, // SS-Code ::= '00010000'B -- all line identification SS
{"clip", 0x11}, // SS-Code ::= '00010001'B -- calling line identification presentation
{"clir", 0x12}, // SS-Code ::= '00010010'B -- calling line identification restriction
{"colp", 0x13}, // SS-Code ::= '00010011'B -- connected line identification presentation
{"colr", 0x14}, // SS-Code ::= '00010100'B -- connected line identification restriction
{"mci", 0x15}, // SS-Code ::= '00010101'B -- malicious call identification
{"allNameIdentificationSS", 0x18}, // SS-Code ::= '00011000'B -- all name identification SS
{"cnap", 0x19}, // SS-Code ::= '00011001'B -- calling name presentation
{"allForwardingSS", 0x20}, // SS-Code ::= '00100000'B -- all forwarding SS
{"cfu", 0x21}, // SS-Code ::= '00100001'B -- call forwarding unconditional
{"allCondForwardingSS", 0x28}, // SS-Code ::= '00101000'B -- all conditional forwarding SS
{"cfb", 0x29}, // SS-Code ::= '00101001'B -- call forwarding on mobile subscriber busy
{"cfnry", 0x2a}, // SS-Code ::= '00101010'B -- call forwarding on no reply
{"cfnrc", 0x2b}, // SS-Code ::= '00101011'B -- call forwarding on mobile subscriber not reachable
{"cd", 0x24}, // SS-Code ::= '00100100'B -- call deflection
{"allCallOfferingSS", 0x30}, // SS-Code ::= '00110000'B -- all call offering SS includes also all forwarding SS
{"ect", 0x31}, // SS-Code ::= '00110001'B -- explicit call transfer
{"mah", 0x32}, // SS-Code ::= '00110010'B -- mobile access hunting
{"allCallCompletionSS", 0x40}, // SS-Code ::= '01000000'B -- all Call completion SS
{"cw", 0x41}, // SS-Code ::= '01000001'B -- call waiting
{"hold", 0x42}, // SS-Code ::= '01000010'B -- call hold
{"ccbs-A", 0x43}, // SS-Code ::= '01000011'B -- completion of call to busy subscribers, originating side
{"ccbs-B", 0x44}, // SS-Code ::= '01000100'B -- completion of call to busy subscribers, destination side
{"allMultiPartySS", 0x50}, // SS-Code ::= '01010000'B -- all multiparty SS
{"multiPTY", 0x51}, // SS-Code ::= '01010001'B -- multiparty
{"allCommunityOfInterest-SS", 0x60}, // SS-Code ::= '01100000'B -- all community of interest SS
{"cug", 0x61}, // SS-Code ::= '01100001'B -- closed user group
{"allChargingSS", 0x70}, // SS-Code ::= '01110000'B -- all charging SS
{"aoci", 0x71}, // SS-Code ::= '01110001'B -- advice of charge information
{"aocc", 0x72}, // SS-Code ::= '01110010'B -- advice of charge charging
{"allAdditionalInfoTransferSS",0x80}, // SS-Code ::= '10000000'B -- all additional information transfer SS
{"uus1", 0x81}, // SS-Code ::= '10000001'B -- UUS1 user-to-user signalling
{"uus2", 0x82}, // SS-Code ::= '10000010'B -- UUS2 user-to-user signalling
{"uus3", 0x83}, // SS-Code ::= '10000011'B -- UUS3 user-to-user signalling
{"allBarringSS", 0x90}, // SS-Code ::= '10010000'B -- all barring SS
{"barringOfOutgoingCalls", 0x91}, // SS-Code ::= '10010001'B -- barring of outgoing calls
{"baoc", 0x92}, // SS-Code ::= '10010010'B -- barring of all outgoing calls
{"boic", 0x93}, // SS-Code ::= '10010011'B -- barring of outgoing international calls
{"boicExHC", 0x94}, // SS-Code ::= '10010100'B -- barring of outgoing international calls except those directed to the home PLMN
{"barringOfIncomingCalls", 0x99}, // SS-Code ::= '10011001'B -- barring of incoming calls
{"baic", 0x9a}, // SS-Code ::= '10011010'B -- barring of all incoming calls
{"bicRoam", 0x9b}, // SS-Code ::= '10011011'B -- barring of incoming calls when roaming outside home PLMN Country
{"allPLMN-specificSS", 0xf0}, // SS-Code ::= '11110000'B
{"plmn-specificSS-1", 0xf1}, // SS-Code ::= '11110001'B
{"plmn-specificSS-2", 0xf2}, // SS-Code ::= '11110010'B
{"plmn-specificSS-3", 0xf3}, // SS-Code ::= '11110011'B
{"plmn-specificSS-4", 0xf4}, // SS-Code ::= '11110100'B
{"plmn-specificSS-5", 0xf5}, // SS-Code ::= '11110101'B
{"plmn-specificSS-6", 0xf6}, // SS-Code ::= '11110110'B
{"plmn-specificSS-7", 0xf7}, // SS-Code ::= '11110111'B
{"plmn-specificSS-8", 0xf8}, // SS-Code ::= '11111000'B
{"plmn-specificSS-9", 0xf9}, // SS-Code ::= '11111001'B
{"plmn-specificSS-A", 0xfa}, // SS-Code ::= '11111010'B
{"plmn-specificSS-B", 0xfb}, // SS-Code ::= '11111011'B
{"plmn-specificSS-C", 0xfc}, // SS-Code ::= '11111100'B
{"plmn-specificSS-D", 0xfd}, // SS-Code ::= '11111101'B
{"plmn-specificSS-E", 0xfe}, // SS-Code ::= '11111110'B
{"plmn-specificSS-F", 0xff}, // SS-Code ::= '11111111'B
{"allCallPrioritySS", 0xa0}, // SS-Code ::= '10100000'B -- all call priority SS
{"emlpp", 0xa1}, // SS-Code ::= '10100001'B -- enhanced Multilevel Precedence Pre-emption (EMLPP) service
{"allLCSPrivacyException", 0xb0}, // SS-Code ::= '10110000'B -- all LCS Privacy Exception Classes
{"universal", 0xb1}, // SS-Code ::= '10110001'B -- allow location by any LCS client
{"callrelated", 0xb2}, // SS-Code ::= '10110010'B -- allow location by any value added LCS client to which a call
// -- is established from the target MS
{"callunrelated", 0xb3}, // SS-Code ::= '10110011'B -- allow location by designated external value added LCS clients
{"plmnoperator", 0xb4}, // SS-Code ::= '10110100'B -- allow location by designated PLMN operator LCS clients
{"allMOLR-SS", 0xc0}, // SS-Code ::= '11000000'B -- all Mobile Originating Location Request Classes
{"basicSelfLocation", 0xc1}, // SS-Code ::= '11000001'B -- allow an MS to request its own location
{"autonomousSelfLocation", 0xc2}, // SS-Code ::= '11000010'B -- allow an MS to perform self location without interaction
// -- with the PLMN for a predetermined period of time
{"transferToThirdParty", 0xc3}, // SS-Code ::= '11000011'B -- allow an MS to request transfer of its location to another LCS client
{0,0},
};
static const TokenDict s_bearerServiceCode[] = {
{"allBearerServices", 0x00}, // BearerServiceCode ::= '00000000'B
{"allDataCDA-Services", 0x10}, // BearerServiceCode ::= '00010000'B
{"dataCDA-300bps", 0x11}, // BearerServiceCode ::= '00010001'B
{"dataCDA-1200bps", 0x12}, // BearerServiceCode ::= '00010010'B
{"dataCDA-1200-75bps", 0x13}, // BearerServiceCode ::= '00010011'B
{"dataCDA-2400bps", 0x14}, // BearerServiceCode ::= '00010100'B
{"dataCDA-4800bps", 0x15}, // BearerServiceCode ::= '00010101'B
{"dataCDA-9600bps", 0x16}, // BearerServiceCode ::= '00010110'B
{"general-dataCDA", 0x17}, // BearerServiceCode ::= '00010111'B
{"allDataCDS-Services", 0x18}, // BearerServiceCode ::= '00011000'B
{"dataCDS-1200bps", 0x1a}, // BearerServiceCode ::= '00011010'B
{"dataCDS-2400bps", 0x1c}, // BearerServiceCode ::= '00011100'B
{"dataCDS-4800bps", 0x1d}, // BearerServiceCode ::= '00011101'B
{"dataCDS-9600bps", 0x1e}, // BearerServiceCode ::= '00011110'B
{"general-dataCDS", 0x1f}, // BearerServiceCode ::= '00011111'B
{"allPadAccessCA-Services",0x20}, // BearerServiceCode ::= '00100000'B
{"padAccessCA-300bps", 0x21}, // BearerServiceCode ::= '00100001'B
{"padAccessCA-1200bps", 0x22}, // BearerServiceCode ::= '00100010'B
{"padAccessCA-1200-75bps", 0x23}, // BearerServiceCode ::= '00100011'B
{"padAccessCA-2400bps", 0x24}, // BearerServiceCode ::= '00100100'B
{"padAccessCA-4800bps", 0x25}, // BearerServiceCode ::= '00100101'B
{"padAccessCA-9600bps", 0x26}, // BearerServiceCode ::= '00100110'B
{"general-padAccessCA", 0x27}, // BearerServiceCode ::= '00100111'B
{"allDataPDS-Services", 0x28}, // BearerServiceCode ::= '00101000'B
{"dataPDS-2400bps", 0x2c}, // BearerServiceCode ::= '00101100'B
{"dataPDS-4800bps", 0x2d}, // BearerServiceCode ::= '00101101'B
{"dataPDS-9600bps", 0x2e}, // BearerServiceCode ::= '00101110'B
{"general-dataPDS", 0x2f}, // BearerServiceCode ::= '00101111'B
{"allAlternateSpeech-DataCDA", 0x30}, // BearerServiceCode ::= '00110000'B
{"allAlternateSpeech-DataCDS", 0x38}, // BearerServiceCode ::= '00111000'B
{"allSpeechFollowedByDataCDA", 0x40}, // BearerServiceCode ::= '01000000'B
{"allSpeechFollowedByDataCDS", 0x48}, // BearerServiceCode ::= '01001000'B
{"allDataCircuitAsynchronous", 0x50}, // BearerServiceCode ::= '01010000'B
{"allAsynchronousServices", 0x60}, // BearerServiceCode ::= '01100000'B
{"allDataCircuitSynchronous", 0x58}, // BearerServiceCode ::= '01011000'B
{"allSynchronousServices", 0x68}, // BearerServiceCode ::= '01101000'B
{"allPLMN-specificBS", 0xd0}, // BearerServiceCode ::= '11010000'B
{"plmn-specificBS-1", 0xd1}, // BearerServiceCode ::= '11010001'B
{"plmn-specificBS-2", 0xd2}, // BearerServiceCode ::= '11010010'B
{"plmn-specificBS-3", 0xd3}, // BearerServiceCode ::= '11010011'B
{"plmn-specificBS-4", 0xd4}, // BearerServiceCode ::= '11010100'B
{"plmn-specificBS-5", 0xd5}, // BearerServiceCode ::= '11010101'B
{"plmn-specificBS-6", 0xd6}, // BearerServiceCode ::= '11010110'B
{"plmn-specificBS-7", 0xd7}, // BearerServiceCode ::= '11010111'B
{"plmn-specificBS-8", 0xd8}, // BearerServiceCode ::= '11011000'B
{"plmn-specificBS-9", 0xd9}, // BearerServiceCode ::= '11011001'B
{"plmn-specificBS-A", 0xda}, // BearerServiceCode ::= '11011010'B
{"plmn-specificBS-B", 0xdb}, // BearerServiceCode ::= '11011011'B
{"plmn-specificBS-C", 0xdc}, // BearerServiceCode ::= '11011100'B
{"plmn-specificBS-D", 0xdd}, // BearerServiceCode ::= '11011101'B
{"plmn-specificBS-E", 0xde}, // BearerServiceCode ::= '11011110'B
{"plmn-specificBS-F", 0xdf}, // BearerServiceCode ::= '11011111'B
{0,0},
};
static const TokenDict s_teleserviceCode[] = {
{"allTeleservices", 0x00}, // TeleserviceCode ::= '00000000'B
{"allSpeechTransmissionServices", 0x10}, // TeleserviceCode ::= '00010000'B
{"telephony", 0x11}, // TeleserviceCode ::= '00010001'B
{"emergencyCalls", 0x12}, // TeleserviceCode ::= '00010010'B
{"allShortMessageServices", 0x20}, // TeleserviceCode ::= '00100000'B
{"shortMessageMT-PP", 0x21}, // TeleserviceCode ::= '00100001'B
{"shortMessageMO-PP", 0x22}, // TeleserviceCode ::= '00100010'B
{"allFacsimileTransmissionServices", 0x60}, // TeleserviceCode ::= '01100000'B
{"facsimileGroup3AndAlterSpeech", 0x61}, // TeleserviceCode ::= '01100001'B
{"automaticFacsimileGroup3", 0x62}, // TeleserviceCode ::= '01100010'B
{"facsimileGroup4", 0x63}, // TeleserviceCode ::= '01100011'B
{"allDataTeleservices", 0x70}, // TeleserviceCode ::= '01110000'B
{"allTeleservices-ExeptSMS", 0x80}, // TeleserviceCode ::= '10000000'B
{"allVoiceGroupCallServices", 0x90}, // TeleserviceCode ::= '10010000'B
{"voiceGroupCall", 0x91}, // TeleserviceCode ::= '10010001'B
{"voiceBroadcastCall", 0x92}, // TeleserviceCode ::= '10010010'B
{"allPLMN-specificTS", 0xd0}, // TeleserviceCode ::= '11010000'B
{"plmn-specificTS-1", 0xd1}, // TeleserviceCode ::= '11010001'B
{"plmn-specificTS-2", 0xd2}, // TeleserviceCode ::= '11010010'B
{"plmn-specificTS-3", 0xd3}, // TeleserviceCode ::= '11010011'B
{"plmn-specificTS-4", 0xd4}, // TeleserviceCode ::= '11010100'B
{"plmn-specificTS-5", 0xd5}, // TeleserviceCode ::= '11010101'B
{"plmn-specificTS-6", 0xd6}, // TeleserviceCode ::= '11010110'B
{"plmn-specificTS-7", 0xd7}, // TeleserviceCode ::= '11010111'B
{"plmn-specificTS-8", 0xd8}, // TeleserviceCode ::= '11011000'B
{"plmn-specificTS-9", 0xd9}, // TeleserviceCode ::= '11011001'B
{"plmn-specificTS-A", 0xda}, // TeleserviceCode ::= '11011010'B
{"plmn-specificTS-B", 0xdb}, // TeleserviceCode ::= '11011011'B
{"plmn-specificTS-C", 0xdc}, // TeleserviceCode ::= '11011100'B
{"plmn-specificTS-D", 0xdd}, // TeleserviceCode ::= '11011101'B
{"plmn-specificTS-E", 0xde}, // TeleserviceCode ::= '11011110'B
{"plmn-specificTS-F", 0xdf}, // TeleserviceCode ::= '11011111'B
{0,0},
};
static const Parameter s_extBearerServiceCode[] = {
{"ext-BearerServiceCode", s_hexTag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_extTeleserviceCode[] = {
{"ext-TeleserviceCode", s_hexTag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_bearerService[] = {
{"bearerService", s_hexTag, false, TcapXApplication::Enumerated, s_bearerServiceCode},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_teleservice[] = {
{"teleservice", s_hexTag, false, TcapXApplication::Enumerated, s_teleserviceCode},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_basicServiceCode[] = {
{"bearerService", s_ctxtPrim_2_Tag, false, TcapXApplication::Enumerated, s_bearerServiceCode},
{"teleservice", s_ctxtPrim_3_Tag, false, TcapXApplication::Enumerated, s_teleserviceCode},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_extBasicServiceCode[] = {
{"ext-BearerService", s_ctxtPrim_2_Tag, false, TcapXApplication::HexString, 0},
{"ext-Teleservice", s_ctxtPrim_3_Tag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const SignallingFlags s_forwardOptions[] = {
{ 0x80, 0x80, "notify-called" },
{ 0x40, 0x40, "presentation" },
{ 0x20, 0x20, "notify-caller" },
{ 0x0c, 0x00, "offline" },
{ 0x0c, 0x04, "busy" },
{ 0x0c, 0x08, "noanswer" },
{ 0x0c, 0x0c, "always" },
{ 0, 0, 0 },
};
static const SignallingFlags s_ssStatus[] = {
{ 0x01, 0x01, "active" },
{ 0x02, 0x02, "registered" },
{ 0x04, 0x04, "provisioned" },
{ 0x08, 0x08, "quiescent" },
{ 0, 0, 0 },
};
static const Parameter s_forwFeatureSeq[] = {
{"basicService", s_noTag, true, TcapXApplication::Choice, s_basicServiceCode},
{"ss-Status", s_ctxtPrim_4_Tag, false, TcapXApplication::Flags, s_ssStatus},
{"forwardedToNumber", s_ctxtPrim_5_Tag, true, TcapXApplication::AddressString, 0},
{"forwardedToSubaddress", s_ctxtPrim_8_Tag, true, TcapXApplication::HexString, 0},
{"forwardingOptions", s_ctxtPrim_6_Tag, true, TcapXApplication::Flags, s_forwardOptions},
{"noReplyConditionTime", s_ctxtPrim_7_Tag, true, TcapXApplication::Integer, 0},
{"extensionContainer", s_ctxtCstr_9_Tag, true, TcapXApplication::HexString, 0},
{"longForwardedToNumber", s_ctxtPrim_10_Tag, true, TcapXApplication::AddressString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_forwFeature[] = {
{"forwardingFeature", s_sequenceTag, true, TcapXApplication::Sequence, s_forwFeatureSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_extForwInfo[] = {
{"ss-Code", s_hexTag, false, TcapXApplication::Enumerated, s_SSCode},
{"forwardingFeatureList", s_sequenceTag, false, TcapXApplication::SequenceOf, s_forwFeature},
{"extensionContainer", s_ctxtCstr_0_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_extCallBarFeatureSeq[] = {
{"basicService", s_noTag, true, TcapXApplication::Choice, s_basicServiceCode},
{"ss-Status", s_ctxtPrim_4_Tag, false, TcapXApplication::Flags, s_ssStatus},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_extCallBarFeature[] = {
{"ext-CallBarFeature", s_sequenceTag, true, TcapXApplication::Sequence, s_extCallBarFeatureSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_extCallBarInfo[] = {
{"ss-Code", s_hexTag, false, TcapXApplication::Enumerated, s_SSCode},
{"callBarringFeatureList",s_sequenceTag, false, TcapXApplication::SequenceOf, s_extCallBarFeature},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_intraCUGOptions[] = {
{"noCUG-Restrictions", 0},
{"cugIC-CallBarred", 1},
{"cugOG-CallBarred", 2},
{0,0},
};
static const Parameter s_basicServiceCodeType[] = {
{"basicService", s_noTag, true, TcapXApplication::Choice, s_basicServiceCode},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_CUGSubscriptionSeq[] = {
{"cug-Index", s_intTag, false, TcapXApplication::Integer, 0},
{"cug-Interlock", s_hexTag, false, TcapXApplication::HexString, 0},
{"intraCUG-Options", s_enumTag, false, TcapXApplication::Enumerated, s_intraCUGOptions},
{"basicServiceGroupList", s_sequenceTag, true, TcapXApplication::SequenceOf, s_basicServiceCodeType},
{"extensionContainer", s_ctxtCstr_0_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_CUGSubscription[] = {
{"cug-Subscription", s_sequenceTag, false, TcapXApplication::Sequence, s_CUGSubscriptionSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_interCUGRestrinctions[] = {
{"CUG-only", 0x00},
{"CUG-outgoing-access", 0x01},
{"CUG-incoming-access", 0x02},
{"CUG-both", 0x03},
{0,0},
};
static const Parameter s_CUGFeatureSeq[] = {
{"basicService", s_noTag, true, TcapXApplication::Choice, s_basicServiceCode},
{"preferentialCUG-Indicator", s_intTag, true, TcapXApplication::Integer, 0},
{"interCUG-Restrictions", s_hexTag, false, TcapXApplication::Enumerated, s_interCUGRestrinctions},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_CUGFeature[] = {
{"cug-Feature", s_sequenceTag, false, TcapXApplication::Sequence, s_CUGFeatureSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_cugInfo[] = {
{"cug-SubscriptionList", s_sequenceTag, false, TcapXApplication::SequenceOf, s_CUGSubscription},
{"cug-FeatureList", s_sequenceTag, true, TcapXApplication::SequenceOf, s_CUGFeature},
{"extensionContainer", s_ctxtCstr_0_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_cliRestrictionOption[] = {
{"permanent", 0},
{"temporaryDefaultRestricted", 1},
{"temporaryDefaultAllowed", 2},
{0,0},
};
static const TokenDict s_overrideCategory[] = {
{"overrideEnabled", 0},
{"overrideDisabled", 1},
{0,0},
};
static const Parameter s_ssSubscriptionOption[] = {
{"cliRestrictionOption", s_ctxtPrim_2_Tag, false, TcapXApplication::Enumerated, s_cliRestrictionOption},
{"overrideCategory", s_ctxtPrim_1_Tag, false, TcapXApplication::Enumerated, s_overrideCategory},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_extSSData[] = {
{"ss-Code", s_hexTag, false, TcapXApplication::Enumerated, s_SSCode},
{"ss-Status", s_ctxtPrim_4_Tag, false, TcapXApplication::Flags, s_ssStatus},
{"ss-SubscriptionOption", s_noTag, true, TcapXApplication::Choice, s_ssSubscriptionOption},
{"basicServiceGroupList", s_sequenceTag, true, TcapXApplication::SequenceOf, s_basicServiceCodeType},
{"extensionContainer", s_ctxtCstr_5_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_EMLPPPriority[] = {
{"priorityLevel0", 0},
{"priorityLevel1", 1},
{"priorityLevel2", 2},
{"priorityLevel3", 3},
{"priorityLevel4", 4},
{"priorityLevelB", 5},
{"priorityLevelA", 6},
{0,0},
};
static const Parameter s_EMLPPInfo[] = {
{"maximumentitledPriority", s_intTag, false, TcapXApplication::Enumerated, s_EMLPPPriority},
{"defaultPriority", s_intTag, false, TcapXApplication::Enumerated, s_EMLPPPriority},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_extSSInfoChoice[] = {
{"forwardingInfo", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_extForwInfo},
{"callBarringInfo", s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_extCallBarInfo},
{"cug-Info", s_ctxtCstr_2_Tag, false, TcapXApplication::Sequence, s_cugInfo},
{"ss-Data", s_ctxtCstr_3_Tag, false, TcapXApplication::Sequence, s_extSSData},
{"emlpp-Info", s_ctxtCstr_4_Tag, false, TcapXApplication::Sequence, s_EMLPPInfo},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_extSSInfo[] = {
{"SS-Info", s_noTag, false, TcapXApplication::Choice, s_extSSInfoChoice},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_odbGeneralData[] = {
{"allOG-CallsBarred", 0x00000001},
{"internationalOGCallsBarred", 0x00000002},
{"internationalOGCallsNotToHPLMN-CountryBarred", 0x00000004},
{"interzonalOGCallsBarred", 0x00000040},
{"interzonalOGCallsNotToHPLMN-CountryBarred", 0x00000080},
{"interzonalOGCallsAndInternationalOGCallsNotToHPLMN-CountryBarred", 0x00000100},
{"premiumRateInformationOGCallsBarred", 0x00000008},
{"premiumRateEntertainementOGCallsBarred", 0x00000010},
{"ss-AccessBarred", 0x00000020},
{"allECT-Barred", 0x00000200},
{"chargeableECT-Barred", 0x00000400},
{"internationalECT-Barred", 0x00000800},
{"interzonalECT-Barred", 0x00001000},
{"doublyChargeableECT-Barred", 0x00002000},
{"multipleECT-Barred", 0x00004000},
{"allPacketOrientedServicesBarred", 0x00008000},
{"roamerAccessToHPLMN-AP-Barred", 0x00010000},
{"roamerAccessToVPLMN-AP-Barred", 0x00020000},
{"roamingOutsidePLMNOG-CallsBarred", 0x00040000},
{"allIC-CallsBarred", 0x00080000},
{"roamingOutsidePLMNIC-CallsBarred", 0x00100000},
{"roamingOutsidePLMNICountryIC-CallsBarred", 0x00200000},
{"roamingOutsidePLMN-Barred", 0x00400000},
{"roamingOutsidePLMN-CountryBarred", 0x00800000},
{"registrationAllCF-Barred", 0x01000000},
{"registrationCFNotToHPLMN-Barred", 0x02000000},
{"registrationInterzonalCF-Barred", 0x04000000},
{"registrationInterzonalCFNotToHPLMN-Barred", 0x08000000},
{"registrationInternationalCF-Barred", 0x10000000},
{0,0},
};
static const TokenDict s_odbHPLMNData[] = {
{"plmn-SpecificBarringType1", 0x01},
{"plmn-SpecificBarringType2", 0x02},
{"plmn-SpecificBarringType3", 0x04},
{"plmn-SpecificBarringType4", 0x08},
{0,0},
};
static const Parameter s_odbData[] = {
{"odb-GeneralData", s_bitsTag, false, TcapXApplication::BitString, s_odbGeneralData},
{"odb-HPLMN-Data", s_bitsTag, true, TcapXApplication::BitString, s_odbHPLMNData},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_zoneCode[] = {
{"zoneCode", s_hexTag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_voiceBroadcastDataSeq[] = {
{"groupid", s_hexTag, false, TcapXApplication::TBCD, 0},
{"broadcastInitEntitlement", s_nullTag, true, TcapXApplication::Null, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"longGroupId", s_ctxtPrim_0_Tag, true, TcapXApplication::TBCD, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_voiceBroadcastData[] = {
{"voiceBroadcastData", s_sequenceTag, false, TcapXApplication::Sequence, s_voiceBroadcastDataSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_additionalSubscriptions[] = {
{"privilegedUplinkRequest", 0x01},
{"emergencyUplinkRequest", 0x02},
{"emergencyReset", 0x04},
{0,0},
};
static const Parameter s_voiceGroupCallDataSeq[] = {
{"groupid", s_hexTag, false, TcapXApplication::TBCD, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"additionalSubscriptions", s_bitsTag, true, TcapXApplication::BitString, s_additionalSubscriptions},
// additionalInfo is BitString, but no definition was found in 3GPP TS 43.068, leaved as hex string
{"additionalInfo", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"longGroupId", s_ctxtPrim_1_Tag, true, TcapXApplication::TBCD, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_voiceGroupCallData[] = {
{"voiceGroupCallData", s_sequenceTag, false, TcapXApplication::Sequence, s_voiceGroupCallDataSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_OBcsmTriggerDetectionPoint[] = {
{"collectedInfo", 2},
{"routeSelectFailure", 4},
{0,0},
};
static const TokenDict s_defaultCallHandling[] = {
{"continueCall", 0},
{"releaseCall", 1},
{0,0},
};
static const Parameter s_OBcsmCamelTDPDataSeq[] = {
{"o-BcsmTriggerDetectionPoint", s_enumTag, false, TcapXApplication::Enumerated, s_OBcsmTriggerDetectionPoint},
{"serviceKey", s_intTag, false, TcapXApplication::Integer, 0},
{"gsmSCF-Address", s_ctxtPrim_0_Tag, false, TcapXApplication::AddressString, 0},
{"defaultCallHandling", s_ctxtPrim_1_Tag, false, TcapXApplication::Enumerated, s_defaultCallHandling},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_OBcsmCamelTDPData[] = {
{"o-BcsmCamelTDPData", s_sequenceTag, false, TcapXApplication::Sequence, s_OBcsmCamelTDPDataSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_camelCapabilityHandling[] = {
{"phase1", 1},
{"phase2", 2},
{"phase3", 3},
{"phase4", 4},
{0,0},
};
static const Parameter s_OCSI[] = {
{"o-BcsmCamelTDPDataList", s_sequenceTag, false, TcapXApplication::SequenceOf, s_OBcsmCamelTDPData},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"camelCapabilityHandling", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_camelCapabilityHandling},
{"notificationToCSE", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"csiActive", s_ctxtPrim_2_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_ssCode[] = {
{"ss-Code", s_hexTag, false, TcapXApplication::Enumerated, s_SSCode},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_SSCamelData[] = {
{"ss-EventList", s_sequenceTag, false, TcapXApplication::SequenceOf, s_ssCode},
{"gsmSCF-Address", s_hexTag, false, TcapXApplication::AddressString, 0},
{"extensionContainer", s_ctxtCstr_0_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_SSCSI[] = {
{"ss-CamelData", s_sequenceTag, false, TcapXApplication::Sequence, s_SSCamelData},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"notificationToCSE", s_ctxtPrim_0_Tag, true, TcapXApplication::Null, 0},
{"csiActive", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_matchType[] = {
{"inhibiting", 0x00},
{"enabling", 0x01},
{0,0xff},
};
static const Parameter s_destinationNumber[] = {
{"destinationNumber", s_hexTag, false, TcapXApplication::AddressString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_destinationNumberLength[] = {
{"destinationNumberLength", s_intTag, false, TcapXApplication::Integer, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_destinationNumberCriteria[] = {
// TS 100 974 v7.15.0 page 306
{"matchType", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_matchType},
{"destinationNumberList", s_ctxtCstr_1_Tag, true, TcapXApplication::SequenceOf, s_destinationNumber},
{"destinationNumberLengthList", s_ctxtCstr_2_Tag, true, TcapXApplication::SequenceOf, s_destinationNumberLength},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_callTypeCriteria[] = {
// TS 100 974 v7.15.0 page 307
{"forwarded", 0x00},
{"notForwarded", 0x01},
{0,0xff},
};
static const Parameter s_causeValue[]={
{"causeValue", s_hexTag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_OBcsmCamelTDPCriteriaSeq[] = {
{"o-BcsmTriggerDetectionPoint", s_enumTag, false, TcapXApplication::Enumerated, s_OBcsmTriggerDetectionPoint},
{"destinationNumberCriteria", s_ctxtCstr_0_Tag, true, TcapXApplication::Sequence, s_destinationNumberCriteria},
{"basicServiceCriteria", s_ctxtCstr_1_Tag, true, TcapXApplication::SequenceOf, s_basicServiceCodeType},
{"callTypeCriteria", s_ctxtPrim_2_Tag, true, TcapXApplication::Enumerated, s_callTypeCriteria},
{"o-CauseValueCriteria", s_ctxtCstr_3_Tag, true, TcapXApplication::SequenceOf, s_causeValue},
{"extensionContainer", s_ctxtCstr_4_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_OBcsmCamelTDPCriteria[] = {
{"o-BcsmCamelTDP-Criteria", s_sequenceTag, false, TcapXApplication::Sequence, s_OBcsmCamelTDPCriteriaSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_MMCodeValues[] = {
{"Location-update-in-same-VLR", 0x00}, // MM-Code ::= '00000000'B
{"Location-update-to-other-VLR", 0x01}, // MM-Code ::= '00000001'B
{"IMSI-Attach", 0x02}, // MM-Code ::= '00000010'B
{"MS-initiated-IMSI-Detach", 0x03}, // MM-Code ::= '00000011'B
{"Network-initiated-IMSI-Detach", 0x04}, // MM-Code ::= '00000100'B
{"Routeing-Area-update-in-same-SGSN", 0x80}, // MM-Code ::= '10000000'B
{"Routeing-Area-update-to-other-SGSN-update-from-new-SGSN", 0x81}, // MM-Code ::= '10000001'B
{"Routeing-Area-update-to-other-SGSN-disconnect-by-detach", 0x82}, // MM-Code ::= '10000010'B
{"GPRS-Attach", 0x83}, // MM-Code ::= '10000011'B
{"MS-initiated-GPRS-Detach", 0x84}, // MM-Code ::= '10000100'B
{"Network-initiated-GPRS-Detach", 0x85}, // MM-Code ::= '10000101'B
{"Network-initiated-transfer-to-MS-not-reachable-for-paging", 0x86}, // MM-Code ::= '10000110'B
{0,0},
};
static const Parameter s_MMCode[] = {
{"MM-Code", s_hexTag, false, TcapXApplication::Enumerated, s_MMCodeValues},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_M_CSI[] = {
{"mobilityTriggers", s_sequenceTag, false, TcapXApplication::SequenceOf, s_MMCode},
{"serviceKey", s_intTag, false, TcapXApplication::Integer, 0},
{"gsmSCF-Address", s_ctxtPrim_0_Tag, false, TcapXApplication::AddressString, 0},
{"extensionContainer", s_ctxtCstr_1_Tag, true, TcapXApplication::HexString, 0},
{"notificationToCSE", s_ctxtPrim_2_Tag, true, TcapXApplication::Null, 0},
{"csiActive", s_ctxtPrim_3_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_SMSTriggerDetectionPoint[] = {
{"sms-CollectedInfo", 1},
{"sms-DeliveryRequest", 2},
{0, 0},
};
static const TokenDict s_defaultSMSHandling[] = {
{"continueTransaction", 0},
{"releaseTransaction", 1},
{0, 0},
};
static const Parameter s_SMS_CAMEL_TDPDataSeq[] = {
{"sms-TriggerDetectionPoint", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_SMSTriggerDetectionPoint},
{"serviceKey", s_ctxtPrim_1_Tag, false, TcapXApplication::Integer, 0},
{"gsmSCF-Address", s_ctxtPrim_2_Tag, false, TcapXApplication::AddressString, 0},
{"defaultSMS-Handling", s_ctxtPrim_3_Tag, false, TcapXApplication::Enumerated, s_defaultSMSHandling},
{"extensionContainer", s_ctxtCstr_4_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_SMS_CAMEL_TDPData[] = {
{"sms-CAMEL-TDP-Data", s_sequenceTag, false, TcapXApplication::Sequence, s_SMS_CAMEL_TDPDataSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_SMS_CSI[] = {
{"sms-CAMEL-TDP-DataList", s_ctxtCstr_0_Tag, true, TcapXApplication::SequenceOf, s_SMS_CAMEL_TDPData},
{"camelCapabilityHandling", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_camelCapabilityHandling},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"notificationToCSE", s_ctxtPrim_3_Tag, true, TcapXApplication::Null, 0},
{"csiActive", s_ctxtPrim_4_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_TBcsmTriggerDetectionPoint[] = {
{"termAttemptAuthorized", 12},
{"tBusy", 13},
{"tNoAnswer", 14},
{0, 0},
};
static const Parameter s_TBcsmCamelTDPDataSeq[] = {
{"t-BcsmTriggerDetectionPoint", s_enumTag, false, TcapXApplication::Enumerated, s_TBcsmTriggerDetectionPoint},
{"serviceKey", s_intTag, false, TcapXApplication::Integer, 0},
{"gsmSCF-Address", s_ctxtPrim_0_Tag, false, TcapXApplication::AddressString, 0},
{"defaultCallHandling", s_ctxtPrim_1_Tag, false, TcapXApplication::Enumerated, s_defaultCallHandling},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_TBcsmCamelTDPData[] = {
{"t-BcsmCamelTDPData", s_sequenceTag, true, TcapXApplication::Sequence, s_TBcsmCamelTDPDataSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_T_CSI[] = {
{"t-BcsmCamelTDPDataList", s_sequenceTag, false, TcapXApplication::SequenceOf, s_TBcsmCamelTDPData},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"camelCapabilityHandling", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_camelCapabilityHandling},
{"notificationToCSE", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"csiActive", s_ctxtPrim_2_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_T_BCSM_CAMEL_TDPCriteriaSeq[] = {
{"t-BCSM-TriggerDetectionPoint", s_enumTag, false, TcapXApplication::Enumerated, s_TBcsmTriggerDetectionPoint},
{"basicServiceCriteria", s_ctxtCstr_0_Tag, true, TcapXApplication::SequenceOf, s_basicServiceCodeType},
{"t-CauseValueCriteria", s_ctxtCstr_1_Tag, true, TcapXApplication::SequenceOf, s_causeValue},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_T_BCSM_CAMEL_TDPCriteria[] = {
{"t-BCSM-CAMEL-TDP-Criteria", s_sequenceTag, false, TcapXApplication::SequenceOf, s_T_BCSM_CAMEL_TDPCriteriaSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_DP_AnalysedInfoCriteriumSeq[] = {
{"dialledNumber", s_hexTag, false, TcapXApplication::HexString, 0},
{"serviceKey", s_intTag, false, TcapXApplication::Integer, 0},
{"gsmSCF-Address", s_hexTag, false, TcapXApplication::AddressString, 0},
{"defaultCallHandling", s_enumTag, false, TcapXApplication::Enumerated, s_defaultCallHandling},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_DP_AnalysedInfoCriterium[] = {
{"DP-AnalysedInfoCriterium", s_sequenceTag, false, TcapXApplication::SequenceOf, s_DP_AnalysedInfoCriteriumSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_D_CSI[] = {
{"dp-AnalysedInfoCriteriaList", s_ctxtCstr_0_Tag, true, TcapXApplication::SequenceOf, s_DP_AnalysedInfoCriterium},
{"camelCapabilityHandling", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_camelCapabilityHandling},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"notificationToCSE", s_ctxtPrim_3_Tag, true, TcapXApplication::Null, 0},
{"csiActive", s_ctxtPrim_4_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_MT_SMS_TPDUTypeEnum[] = {
{"sms-DELIVER", 0},
{"sms-SUBMIT-REPORT", 1},
{"sms-STATUS-REPORT", 2},
{0, 0},
};
static const Parameter s_MT_SMS_TPDUType[] = {
{"MT-SMS-TPDU-Type", s_enumTag, false, TcapXApplication::Enumerated, s_MT_SMS_TPDUTypeEnum},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_MT_smsCAMELTDP_CriteriaSeq[] = {
{"sms-TriggerDetectionPoint", s_enumTag, false, TcapXApplication::Enumerated, s_SMSTriggerDetectionPoint},
{"tpdu-TypeCriterion", s_ctxtCstr_0_Tag, true, TcapXApplication::SequenceOf, s_MT_SMS_TPDUType},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_MT_smsCAMELTDP_Criteria[] = {
{"MT-smsCAMELTDP-Criteria", s_sequenceTag, false, TcapXApplication::Sequence, s_MT_smsCAMELTDP_CriteriaSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_VlrCamelSubscriptionInfo[] = {
{"o-CSI", s_ctxtCstr_0_Tag, true, TcapXApplication::Sequence, s_OCSI},
{"extensionContainer", s_ctxtCstr_1_Tag, true, TcapXApplication::HexString, 0},
{"ss-CSI", s_ctxtCstr_2_Tag, true, TcapXApplication::Sequence, s_SSCSI},
{"o-BcsmCamelTDP-CriteriaList", s_ctxtCstr_4_Tag, true, TcapXApplication::SequenceOf, s_OBcsmCamelTDPCriteria},
{"tif-CSI", s_ctxtPrim_3_Tag, true, TcapXApplication::Null, 0},
{"m-CSI", s_ctxtCstr_5_Tag, true, TcapXApplication::Sequence, s_M_CSI},
{"mo-sms-CSI", s_ctxtCstr_6_Tag, true, TcapXApplication::Sequence, s_SMS_CSI},
{"vt-CSI", s_ctxtCstr_7_Tag, true, TcapXApplication::Sequence, s_T_CSI},
{"t-BCSM-CAMEL-TDP-CriteriaList",s_ctxtCstr_8_Tag, true, TcapXApplication::SequenceOf, s_T_BCSM_CAMEL_TDPCriteria},
{"d-CSI", s_ctxtCstr_9_Tag, true, TcapXApplication::Sequence, s_D_CSI},
{"mt-sms-CSI", s_ctxtCstr_10_Tag, true, TcapXApplication::Sequence, s_SMS_CSI},
{"mt-smsCAMELTDP-CriteriaList", s_ctxtCstr_11_Tag, true, TcapXApplication::SequenceOf, s_MT_smsCAMELTDP_Criteria},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_naeaPreferredCI[] = {
// NAEAPreferredICI
{"naea-PreferredCIC", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"extensionContainer", s_ctxtCstr_1_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_PDPContextSeq[] = {
{"pdp-ContextId", s_intTag, false, TcapXApplication::Integer, 0},
{"pdp-Type", s_ctxtPrim_16_Tag, false, TcapXApplication::HexString, 0},
{"pdp-Address", s_ctxtPrim_17_Tag, true, TcapXApplication::HexString, 0},
{"qos-Subscribed", s_ctxtPrim_18_Tag, false, TcapXApplication::HexString, 0},
{"vplmnAddressAllowed", s_ctxtPrim_19_Tag, true, TcapXApplication::Null, 0},
{"apn", s_ctxtPrim_20_Tag, false, TcapXApplication::HexString, 0},
{"extensionContainer", s_ctxtCstr_21_Tag, true, TcapXApplication::HexString, 0},
{"ext-QoS-Subscribed", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"pdp-ChargingCharacteristics", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"ext2-QoS-Subscribed", s_ctxtPrim_2_Tag, true, TcapXApplication::HexString, 0},
{"ext3-QoS-Subscribed", s_ctxtPrim_3_Tag, true, TcapXApplication::HexString, 0},
{"ext4-QoS-Subscribed", s_ctxtPrim_4_Tag, true, TcapXApplication::HexString, 0},
{"apn-oi-Replacement", s_ctxtPrim_5_Tag, true, TcapXApplication::HexString, 0},
{"ext-pdp-Type", s_ctxtPrim_6_Tag, true, TcapXApplication::HexString, 0},
{"ext-pdp-Address", s_ctxtPrim_7_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_PDPContext[] = {
{"pdp-Context", s_sequenceTag, false, TcapXApplication::Sequence, s_PDPContextSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_GPRSSubscriptionData[] = {
{"completeDataListIncluded", s_nullTag, true, TcapXApplication::Null, 0},
{"gprsDataList", s_ctxtCstr_1_Tag, false, TcapXApplication::SequenceOf, s_PDPContext},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"apn-oi-Replacement", s_ctxtPrim_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_networkAccessMode[] = {
{"bothMSCAndSGSN", 0x00},
{"onlyMSC", 0x01},
{"onlySGSN", 0x02},
{0,0xff},
};
static const TokenDict s_lsaOnlyAccessIndicator[] = {
{"accessOutsideLSAsAllowed", 0x00},
{"accessOutsideLSAsRestricted", 0x01},
{0,0xff},
};
static const Parameter s_LSADataSeq[] = {
{"lsaIdentity", s_ctxtPrim_0_Tag, false, TcapXApplication::HexString, 0},
{"lsaAttributes", s_ctxtPrim_1_Tag, false, TcapXApplication::HexString, 0},
{"lsaActiveModeIndicator", s_ctxtPrim_2_Tag, true, TcapXApplication::Null, 0},
{"extensionContainer", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_LSAData[] = {
{"lsaData", s_sequenceTag, false, TcapXApplication::Sequence, s_LSADataSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_LSAInformation[] = {
{"completeDataListIncluded", s_nullTag, true, TcapXApplication::Null, 0},
{"lsaOnlyAccessIndicator", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_lsaOnlyAccessIndicator},
{"lsaDataList", s_ctxtCstr_2_Tag, true, TcapXApplication::SequenceOf, s_LSAData},
{"extensionContainer", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_GMLC[] = {
{"gmlc", s_hexTag, false, TcapXApplication::AddressString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_notificationToMSUser[] = {
{"notifyLocationAllowed", 0x00},
{"notifyAndVerify-LocationAllowedIfNoResponse", 0x01},
{"notifyAndVerify-LocationNotAllowedIfNoResponse", 0x02},
{"locationNotAllowed", 0x03},
{0,0},
};
static const TokenDict s_GMLCRestriction[] = {
{"gmlc-List", 0x00},
{"home-Country", 0x01},
{0,0xff},
};
static const Parameter s_LCSClientExternalIDSeq[] = {
{"externalAddress", s_ctxtPrim_0_Tag, true, TcapXApplication::AddressString, 0},
{"extensionContainer", s_ctxtCstr_1_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_externalClientSeq[] = {
{"clientIdentity", s_sequenceTag, false, TcapXApplication::Sequence, s_LCSClientExternalIDSeq},
{"gmlc-Restriction", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_GMLCRestriction},
{"notificationToMSUser", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_notificationToMSUser},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_externalClient[] = {
{"externalClient", s_sequenceTag, false, TcapXApplication::Sequence, s_externalClientSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_LCSClientInternalIDEnum[] = {
{"broadcastService", 0x00},
{"o-andM-HPLMN", 0x01},
{"o-andM-VPLMN", 0x02},
{"anonymousLocation", 0x03},
{"targetMSsubscribedService", 0x04},
{0,0xff},
};
static const Parameter s_LCSClientInternalID[] = {
{"lcsClientInternalID", s_enumTag, false, TcapXApplication::Enumerated, s_LCSClientInternalIDEnum},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_serviceTypeSeq[] = {
{"serviceTypeIdentity", s_intTag, false,TcapXApplication::Integer, 0},
{"gmlc-Restriction", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_GMLCRestriction},
{"notificationToMSUser", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_notificationToMSUser},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_serviceType[] = {
{"serviceType", s_sequenceTag, false, TcapXApplication::Sequence, s_serviceTypeSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_LCSPrivacyClassSeq[] = {
{"ss-Code", s_hexTag, false,TcapXApplication::Enumerated, s_SSCode},
{"ss-Status", s_hexTag, false,TcapXApplication::Flags, s_ssStatus},
{"notificationToMSUser", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_notificationToMSUser},
{"externalClientList", s_ctxtCstr_1_Tag, true, TcapXApplication::SequenceOf, s_externalClient},
{"plmnClientList", s_ctxtCstr_2_Tag, true, TcapXApplication::SequenceOf, s_LCSClientInternalID},
{"extensionContainer", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"ext-externalClientList", s_ctxtCstr_4_Tag, true, TcapXApplication::SequenceOf, s_externalClient},
{"serviceTypeList", s_ctxtCstr_5_Tag, true, TcapXApplication::SequenceOf, s_serviceType},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_LCSPrivacyException[] = {
{"lcsPrivacyClass", s_sequenceTag, false, TcapXApplication::Sequence, s_LCSPrivacyClassSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_MOLRClassSeq[] = {
{"ss-Code", s_hexTag, false,TcapXApplication::Enumerated, s_SSCode},
{"ss-Status", s_hexTag, false,TcapXApplication::Flags, s_ssStatus},
{"extensionContainer", s_ctxtCstr_0_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_MOLRClass[] = {
{"mOLRClass", s_sequenceTag, false, TcapXApplication::Sequence, s_MOLRClassSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_LCSInformation[] = {
{"gmlc-List", s_ctxtCstr_0_Tag, true, TcapXApplication::SequenceOf, s_GMLC},
{"lcs-PrivacyExceptionList", s_ctxtCstr_1_Tag, true, TcapXApplication::SequenceOf, s_LCSPrivacyException},
{"molr-List", s_ctxtCstr_2_Tag, true, TcapXApplication::SequenceOf, s_MOLRClass},
{"add-lcs-PrivacyExceptionList", s_ctxtCstr_3_Tag, true, TcapXApplication::SequenceOf, s_LCSPrivacyException},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_MC_SSInfo[] = {
{"ss-Code", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_SSCode},
{"ss-Status", s_ctxtPrim_1_Tag, false, TcapXApplication::Flags, s_ssStatus},
{"nbrSB", s_ctxtPrim_2_Tag, false, TcapXApplication::Integer, 0},
{"nbrUser", s_ctxtPrim_3_Tag, false, TcapXApplication::Integer, 0},
{"extensionContainer", s_ctxtCstr_4_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_GPRSTriggerDetectionPoint[] = {
{"attach", 1},
{"attachChangeOfPosition", 2},
{"pdp-ContextEstablishment", 11},
{"pdp-ContextEstablishmentAcknowledgement", 12},
{"pdp-ContextChangeOfPosition", 14},
{0,0},
};
static const TokenDict s_defaultGPRSHandling[] = {
{"continueTransaction", 0},
{"releaseTransaction", 1},
{0,0},
};
static const Parameter s_GPRSCamelTDPDataSeq[] = {
{"gprs-TriggerDetectionPoint", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_GPRSTriggerDetectionPoint},
{"serviceKey", s_ctxtPrim_1_Tag, false, TcapXApplication::Integer, 0},
{"gsmSCF-Address", s_ctxtPrim_2_Tag, false, TcapXApplication::AddressString, 0},
{"defaultSessionHandling", s_ctxtPrim_3_Tag, false, TcapXApplication::Enumerated, s_defaultGPRSHandling},
{"extensionContainer", s_ctxtCstr_4_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_GPRSCamelTDPData[] = {
{"gprs-CamelTDPData", s_sequenceTag, false, TcapXApplication::Sequence, s_GPRSCamelTDPDataSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_GPRS_CSISeq[] = {
{"gprs-CamelTDPDataList", s_ctxtCstr_0_Tag, true, TcapXApplication::SequenceOf, s_GPRSCamelTDPData},
{"camelCapabilityHandling", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_camelCapabilityHandling},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"notificationToCSE", s_ctxtPrim_3_Tag, true, TcapXApplication::Null, 0},
{"csiActive", s_ctxtPrim_4_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_SGSN_CAMELSubscriptionInfoSeq[] = {
{"gprs-CSI", s_ctxtCstr_0_Tag, true, TcapXApplication::Sequence, s_GPRS_CSISeq},
{"mo-sms-CSI", s_ctxtCstr_1_Tag, true, TcapXApplication::Sequence, s_SMS_CSI},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"mt-sms-CSI", s_ctxtCstr_3_Tag, true, TcapXApplication::Sequence, s_SMS_CSI},
{"mt-smsCAMELTDP-CriteriaList", s_ctxtCstr_4_Tag, true, TcapXApplication::SequenceOf, s_MT_smsCAMELTDP_Criteria},
{"mg-csi", s_ctxtCstr_5_Tag, true, TcapXApplication::Sequence, s_M_CSI},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_accessRestrictionData[] = {
{"utranNotAllowed", 0x01},
{"geranNotAllowed", 0x02},
{"ganNotAllowed", 0x03},
{"i-hspa-evolutionNotAllowed", 0x04},
{"e-utranNotAllowed", 0x05},
{"ho-toNon3GPP-AccessNotAllowed", 0x06},
{0,0},
};
static const Parameter s_AMBRSeq[] = {
{"max-RequestedBandwidth-UL", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"max-RequestedBandwidth-DL", s_ctxtPrim_1_Tag, false, TcapXApplication::Integer, 0},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_AllocationRetentionPrioritySeq[] = {
{"priority-level", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"pre-emption-capability", s_ctxtPrim_1_Tag, true, TcapXApplication::Bool, 0},
{"pre-emption-vulnerability", s_ctxtPrim_1_Tag, true, TcapXApplication::Bool, 0},
{"extensionContainer", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_EPS_QoS_SubscribedSeq[] = {
{"qos-Class-Identifier", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"allocation-Retention-Priority", s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_AllocationRetentionPrioritySeq},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_PDN_GW_Identity[] = {
{"pdn-gw-ipv4-Address", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"pdn-gw-ipv6-Address", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"pdn-gw-name", s_ctxtPrim_2_Tag, true, TcapXApplication::HexString, 0},
{"extensionContainer", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_PDN_GW_AllocationType[] = {
{"static", 0},
{"dynamic", 1},
{0,0},
};
static const Parameter s_SpecificAPNInfoSeq[] = {
{"apn", s_ctxtPrim_0_Tag, false, TcapXApplication::HexString, 0},
{"pdn-gw-Identity", s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_PDN_GW_Identity},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_SpecificAPNInfo[] = {
{"specificAPNInfo", s_sequenceTag, false, TcapXApplication::Sequence, s_SpecificAPNInfoSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_APNConfigurationSeq[] = {
{"contextId", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"pdn-Type", s_ctxtPrim_1_Tag, false, TcapXApplication::HexString, 0},
{"servedPartyIP-IPv4-Address", s_ctxtPrim_2_Tag, true, TcapXApplication::HexString, 0},
{"apn", s_ctxtPrim_3_Tag, false, TcapXApplication::HexString, 0},
{"eps-qos-Subscribed", s_ctxtCstr_4_Tag, false, TcapXApplication::Sequence, s_EPS_QoS_SubscribedSeq},
{"pdn-gw-Identity", s_ctxtCstr_5_Tag, true, TcapXApplication::Sequence, s_PDN_GW_Identity},
{"pdn-gw-AllocationType", s_ctxtPrim_6_Tag, true, TcapXApplication::Enumerated, s_PDN_GW_AllocationType},
{"vplmnAddressAllowed", s_ctxtPrim_7_Tag, true, TcapXApplication::Null, 0},
{"chargingCharacteristics", s_ctxtPrim_8_Tag, true, TcapXApplication::HexString, 0},
{"ambr", s_ctxtCstr_9_Tag, true, TcapXApplication::Sequence, s_AMBRSeq},
{"specificAPNInfoList", s_ctxtCstr_10_Tag, true, TcapXApplication::SequenceOf, s_SpecificAPNInfo},
{"extensionContainer", s_ctxtCstr_11_Tag, true, TcapXApplication::HexString, 0},
{"servedPartyIP-IPv6-Address", s_ctxtPrim_12_Tag, true, TcapXApplication::HexString, 0},
{"apn-oi-Replacement", s_ctxtPrim_13_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_APNConfiguration[] = {
{"APN-Configuration", s_sequenceTag, false, TcapXApplication::Sequence, s_APNConfigurationSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_APN_ConfigurationProfileSeq[] = {
{"defaultContext", s_intTag, false, TcapXApplication::Integer, 0},
{"completeDataListIncluded", s_nullTag, true, TcapXApplication::Null, 0},
{"epsDataList", s_ctxtCstr_1_Tag, false, TcapXApplication::SequenceOf, s_APNConfiguration},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_EPS_SubscriptionData[] = {
{"apn-oi-Replacement", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"rfsp-id", s_ctxtPrim_2_Tag, true, TcapXApplication::Integer, 0},
{"ambr", s_ctxtCstr_3_Tag, true, TcapXApplication::Sequence, s_AMBRSeq},
{"apn-ConfigurationProfile",s_ctxtCstr_4_Tag, true, TcapXApplication::Sequence, s_APN_ConfigurationProfileSeq},
{"stn-sr", s_ctxtPrim_6_Tag, true, TcapXApplication::AddressString, 0},
{"extensionContainer", s_ctxtCstr_5_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_CSG_SubscriptionDataSeq[] = {
// should find encoding for csg-ID
{"csg-Id", s_bitsTag, false, TcapXApplication::HexString, 0},
{"expirationDate", s_hexTag, true, TcapXApplication::HexString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_CSG_SubscriptionData[] = {
{"CSG-SubscriptionData", s_sequenceTag, false, TcapXApplication::Sequence, s_CSG_SubscriptionDataSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_contextId[] = {
// TS 100 974 v7.15.0 page 305
{"contextId", s_intTag, false, TcapXApplication::Integer, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_GPRSSubscriptionDataWithdraw[] = {
// TS 100 974 v7.15.0 page 305
{"allGPRSData", s_nullTag, false, TcapXApplication::Null, 0},
{"contextIdList", s_sequenceTag, false, TcapXApplication::SequenceOf, s_contextId},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_LSAIdentity[] = {
// TS 100 974 v7.15.0 page 300
{"lsaIdentity", s_hexTag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_LSAInformationWithdraw[] = {
// TS 100 974 v7.15.0 page 305
{"allLSAData", s_nullTag, false, TcapXApplication::Null, 0},
{"lsaIdentityList", s_sequenceTag, false, TcapXApplication::SequenceOf, s_LSAIdentity},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_specificCSI_Withdraw[] = {
{"o-csi", 0x0001},
{"ss-csi", 0x0002},
{"tif-csi", 0x0004},
{"d-csi", 0x0008},
{"vt-csi", 0x0010},
{"mo-sms-csi", 0x0020},
{"m-csi", 0x0040},
{"gprs-csi", 0x0080},
{"t-csi", 0x0100},
{"mt-sms-csi", 0x0200},
{"mg-csi", 0x0400},
{"o-IM-CSI", 0x0800},
{"d-IM-CSI", 0x1000},
{"vt-IM-CSI", 0x2000},
{0,0},
};
static const Parameter s_EPS_SubscriptionDataWithdraw[] = {
{"allEPS-Data", s_nullTag, false, TcapXApplication::Null, 0},
{"contextIdList", s_sequenceTag, false, TcapXApplication::SequenceOf, s_contextId},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_regionalSubscriptionResponse[] = {
// TS 100 974 v7.15.0 page 305
{"networkNode-AreaRestricted", 0},
{"tooManyZoneCodes", 1},
{"zoneCodesConflict", 2},
{"regionalSubscNotSupported", 3},
{0,0},
};
static const TokenDict s_supportedFeatures[] = {
{"odb-all-apn", 0x00000001},
{"odb-HPLMN-APN", 0x00000002},
{"odb-VPLMN-APN", 0x00000004},
{"odb-all-og", 0x00000008},
{"odb-all-international-og", 0x00000010},
{"odb-all-int-og-not-to-HPLMN-country", 0x00000020},
{"odb-all-interzonal-og", 0x00000040},
{"odb-all-interzonal-og-not-to-HPLMN-country", 0x00000080},
{"odb-all-interzonal-og-and-internat-og-not-to-HPLMN-country", 0x00000100},
{"regSub", 0x00000200},
{"trace", 0x00000400},
{"lcs-all-PrivExcep", 0x00000800},
{"lcs-universal", 0x00001000},
{"lcs-CallSessionRelated", 0x00002000},
{"lcs-CallSessionUnrelated", 0x00004000},
{"lcs-PLMN-operator", 0x00008000},
{"lcs-ServiceType", 0x00010000},
{"lcs-all-MOLR-SS", 0x00020000},
{"lcs-basicSelfLocation", 0x00040000},
{"lcs-autonomousSelfLocation", 0x00080000},
{"lcs-transferToThirdParty", 0x00100000},
{"sm-mo-pp", 0x00200000},
{"barring-OutgoingCalls", 0x00400000},
{"baoc", 0x00800000},
{"boic", 0x01000000},
{"boicExHC", 0x02000000},
{0, 0},
};
static const Parameter s_SSForBSCode[] = {
// TS 100 974 v7.15.0 page 319
{"ss-Code", s_hexTag, false, TcapXApplication::Enumerated, s_SSCode},
{"basicService", s_noTag, true, TcapXApplication::Choice, s_basicServiceCode},
{"longFTN-Supported", s_ctxtPrim_4_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_ccbsFeature[] = {
// TS 100 974 v7.15.0 page 319
{"ccbs-Index", s_ctxtPrim_0_Tag, true, TcapXApplication::Integer, 0},
{"b-subscriberNumber", s_ctxtPrim_1_Tag, true, TcapXApplication::AddressString, 0},
{"b-subscriberSubaddress", s_ctxtPrim_2_Tag, true, TcapXApplication::HexString , 0},
{"basicServiceGroup", s_ctxtCstr_3_Tag, true, TcapXApplication::Choice, s_extBasicServiceCode},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_CCBSFeature[] = {
// TS 100 974 v7.15.0 page 319
{"CCBS-Feature", s_sequenceTag, false, TcapXApplication::Sequence, s_ccbsFeature},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_genericServiceInfo[] = {
// TS 100 974 v7.15.0 page 319
{"ss-Status", s_hexTag, false, TcapXApplication::Flags, s_ssStatus},
{"cliRestrictionOption", s_enumTag, true, TcapXApplication::Enumerated, s_cliRestrictionOption},
{"maximumentitledPriority", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_EMLPPPriority},
{"defaultPriority", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_EMLPPPriority},
{"ccbs-FeatureList", s_ctxtCstr_2_Tag, true, TcapXApplication::SequenceOf, s_CCBSFeature},
{"nbrSB", s_ctxtPrim_3_Tag, true, TcapXApplication::Integer, 0},
{"nbrUser", s_ctxtPrim_4_Tag, true, TcapXApplication::Integer, 0},
{"nbrSN", s_ctxtPrim_5_Tag, true, TcapXApplication::Integer, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_InterrogateSSRes[] = {
// TS 100 974 v7.15.0 page 319
{"ss-Status", s_ctxtPrim_0_Tag, false, TcapXApplication::Flags, s_ssStatus},
{"basicServiceGroupList", s_ctxtCstr_2_Tag, false, TcapXApplication::SequenceOf, s_basicServiceCodeType},
{"forwardingFeatureList", s_ctxtCstr_3_Tag, false, TcapXApplication::SequenceOf, s_forwFeature},
{"genericServiceInfo", s_ctxtCstr_4_Tag, false, TcapXApplication::Sequence, s_genericServiceInfo},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_failureCauseEnum[] = {
// TS 129 002 v9.3.0 page 353
{"wrongUserResponse", 0x00},
{"wrongNetworkSignature", 0x01},
{0, 0x00},
};
static const TokenDict s_accessTypeEnum[] = {
// TS 129 002 v9.3.0 page 353
{"call", 0x00},
{"emergencyCall", 0x01},
{"locationUpdating", 0x02},
{"supplementaryService", 0x03},
{"shortMessage", 0x04},
{"gprsAttach", 0x05},
{"routingAreaUpdating", 0x06},
{"serviceRequest", 0x07},
{"pdpContextActivation", 0x08},
{"pdpContextDeactivation",0x09},
{"gprsDetach", 0x0a},
{0, 0x00},
};
static const TokenDict s_guidanceInfo[] = {
{"enterPW", 0 },
{"enterNewPW", 1 },
{"enterNewPW-Again", 2 },
{0, 0},
};
static const Parameter s_SGSN_CapabilitySeq[] = {
{"solsaSupportIndicator", s_nullTag, true, TcapXApplication::Null, 0},
{"extensionContainer", s_ctxtCstr_1_Tag, true, TcapXApplication::HexString, 0},
{"superChargerSupportedInServingNetworkEntity",s_ctxtCstr_2_Tag, true, TcapXApplication::Choice, s_superChargerInfo},
{"gprsEnhancementsSupportIndicator", s_ctxtPrim_3_Tag, true, TcapXApplication::Null, 0},
{"supportedCamelPhases", s_ctxtPrim_4_Tag, true, TcapXApplication::BitString, s_camelPhases},
{"supportedLCS-CapabilitySets", s_ctxtPrim_5_Tag, true, TcapXApplication::BitString, s_supportedLCSCapabilitySets},
{"offeredCamel4CSIs", s_ctxtPrim_6_Tag, true, TcapXApplication::BitString, s_offeredCamel4CSIs},
{"smsCallBarringSupportIndicator", s_ctxtPrim_7_Tag, true, TcapXApplication::Null, 0},
{"supportedRAT-TypesIndicator", s_ctxtPrim_8_Tag, true, TcapXApplication::BitString, s_supportedRATTypes},
{"supportedFeatures", s_ctxtPrim_9_Tag, true, TcapXApplication::BitString, s_supportedFeatures},
{"t-adsDataRetrieval", s_ctxtPrim_10_Tag, true, TcapXApplication::Null, 0},
{"homogeneousSupportOfIMSVoiceOverPSSessions", s_ctxtPrim_11_Tag, true, TcapXApplication::Bool, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_PDN_GW_UpdateSeq[] = {
{"apn", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"pdn-gw-Identity", s_ctxtCstr_1_Tag, true, TcapXApplication::Sequence, s_PDN_GW_Identity},
{"contextId", s_ctxtPrim_2_Tag, true, TcapXApplication::Integer, 0},
{"extensionContainer",s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const TokenDict s_ISR_Information[] = {
{"updateMME", 0x01},
{"cancelSGSN", 0x02},
{"initialAttachIndicator", 0x04},
{0, 0},
};
static const Parameter s_EPS_InfoChoice[] = {
{"pdn-gw-update", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_PDN_GW_UpdateSeq},
{"isr-Information", s_ctxtPrim_1_Tag, false, TcapXApplication::BitString, s_ISR_Information},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_used_RAT_Type[] = {
{"utran", 0},
{"geran", 1},
{"gan", 2},
{"i-hspa-evolution", 3},
{"e-utran", 4},
{0, 0},
};
static const Parameter s_hlrId[] = {
{"HLR-Id", s_hexTag, false, TcapXApplication::TBCD, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_additionalNumber[] = {
{"msc-Number", s_ctxtPrim_0_Tag, false, TcapXApplication::AddressString, 0},
{"sgsn-Number", s_ctxtPrim_1_Tag, false, TcapXApplication::AddressString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_SM_DeliveryNotIntended[] = {
{"onlyIMSI-requested", 0},
{"onlyMCC-MNC-requested", 1},
{0, 0},
};
static const Parameter s_locationInfoWithLMSI[] = {
// TS 100 974 v7.15.0 page 324
{"networkNode-Number", s_ctxtPrim_1_Tag, false, TcapXApplication::AddressString, 0},
{"lmsi", s_hexTag, true, TcapXApplication::HexString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"gprsNodeIndicator", s_ctxtPrim_5_Tag, true, TcapXApplication::Null, 0},
{"additional-Number", s_ctxtCstr_6_Tag, true, TcapXApplication::Choice, s_additionalNumber},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_traceDepth[] = {
{"minimum", 0},
{"medium", 1},
{"maximum", 2},
{0, 0},
};
static const Parameter s_traceDepthListSeq[] = {
{"msc-s-TraceDepth", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_traceDepth},
{"mgw-TraceDepth", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_traceDepth},
{"sgsn-TraceDepth", s_ctxtPrim_2_Tag, true, TcapXApplication::Enumerated, s_traceDepth},
{"ggsn-TraceDepth", s_ctxtPrim_3_Tag, true, TcapXApplication::Enumerated, s_traceDepth},
{"rnc-TraceDepth", s_ctxtPrim_4_Tag, true, TcapXApplication::Enumerated, s_traceDepth},
{"bmsc-TraceDepth", s_ctxtPrim_5_Tag, true, TcapXApplication::Enumerated, s_traceDepth},
{"mme-TraceDepth", s_ctxtPrim_6_Tag, true, TcapXApplication::Enumerated, s_traceDepth},
{"sgw-TraceDepth", s_ctxtPrim_7_Tag, true, TcapXApplication::Enumerated, s_traceDepth},
{"pgw-TraceDepth", s_ctxtPrim_8_Tag, true, TcapXApplication::Enumerated, s_traceDepth},
{"eNB-TraceDepth", s_ctxtPrim_9_Tag, true, TcapXApplication::Enumerated, s_traceDepth},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_traceNETypeList[] = {
{"msc-s",0x0001},
{"mgw", 0x0002},
{"sgsn", 0x0004},
{"ggsn", 0x0008},
{"rnc", 0x0010},
{"bm-sc",0x0020},
{"mme", 0x0040},
{"sgw", 0x0080},
{"pgw", 0x0100},
{"eNB", 0x0200},
{0, 0},
};
static const TokenDict s_MSC_S_InterfaceList[] = {
{"a", 0x0001},
{"iu", 0x0002},
{"mc", 0x0004},
{"map-g", 0x0008},
{"map-b", 0x0010},
{"map-e", 0x0020},
{"map-f", 0x0040},
{"cap", 0x0080},
{"map-d", 0x0100},
{"map-c", 0x0200},
{0, 0},
};
static const TokenDict s_MGW_InterfaceList[] = {
{"mc", 0x01},
{"nb-up", 0x02},
{"iu-up", 0x04},
{0, 0},
};
static const TokenDict s_SGSN_InterfaceList[] = {
{"gb", 0x0001},
{"iu", 0x0002},
{"gn", 0x0004},
{"map-gr", 0x0008},
{"map-gd", 0x0010},
{"map-gf", 0x0020},
{"gs", 0x0040},
{"ge", 0x0080},
{"s3", 0x0100},
{"s4", 0x0200},
{"s6d", 0x0400},
{0, 0},
};
static const TokenDict s_GGSN_InterfaceList[] = {
{"gn", 0x01},
{"gi", 0x02},
{"gmb", 0x04},
{0, 0},
};
static const TokenDict s_RNC_InterfaceList[] = {
{"iu", 0x01},
{"iur", 0x02},
{"iub", 0x04},
{"uu", 0x08},
{0, 0},
};
static const TokenDict s_BMSC_InterfaceList[] = {
{"gmb", 0x01},
{0, 0},
};
static const TokenDict s_MME_InterfaceList[] = {
{"s1-mme", 0x01},
{"s3", 0x02},
{"s6a", 0x04},
{"s10", 0x08},
{"s11", 0x10},
{0, 0},
};
static const TokenDict s_SGW_InterfaceList[] = {
{"s4", 0x01},
{"s5", 0x02},
{"s8b", 0x04},
{"s11", 0x08},
{"gxc", 0x10},
{0, 0},
};
static const TokenDict s_PGW_InterfaceList[] = {
{"s2a", 0x01},
{"s2b", 0x02},
{"s2c", 0x04},
{"s5", 0x08},
{"s6b", 0x10},
{"gx", 0x20},
{"s8b", 0x40},
{"sgi", 0x80},
{0, 0},
};
static const TokenDict s_ENB_InterfaceList[] = {
{"s1-mme", 0x01},
{"x2", 0x02},
{"uu", 0x04},
{0, 0},
};
static const Parameter s_traceInterfaceListSeq[] = {
{"msc-s-List", s_ctxtPrim_0_Tag, true, TcapXApplication::BitString, s_MSC_S_InterfaceList},
{"mgw-List", s_ctxtPrim_1_Tag, true, TcapXApplication::BitString, s_MGW_InterfaceList},
{"sgsn-List", s_ctxtPrim_2_Tag, true, TcapXApplication::BitString, s_SGSN_InterfaceList},
{"ggsn-List", s_ctxtPrim_3_Tag, true, TcapXApplication::BitString, s_GGSN_InterfaceList},
{"rnc-List", s_ctxtPrim_4_Tag, true, TcapXApplication::BitString, s_RNC_InterfaceList},
{"bmsc-List", s_ctxtPrim_5_Tag, true, TcapXApplication::BitString, s_BMSC_InterfaceList},
{"mme-List", s_ctxtPrim_6_Tag, true, TcapXApplication::BitString, s_MME_InterfaceList},
{"sgw-List", s_ctxtPrim_7_Tag, true, TcapXApplication::BitString, s_SGW_InterfaceList},
{"pgw-List", s_ctxtPrim_8_Tag, true, TcapXApplication::BitString, s_PGW_InterfaceList},
{"eNB-List", s_ctxtPrim_9_Tag, true, TcapXApplication::BitString, s_ENB_InterfaceList},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_MSC_S_EventList[] = {
{"mo-mtCall", 0x01},
{"mo-mt-sms", 0x02},
{"lu-imsiAttach-imsiDetach", 0x04},
{"handovers", 0x08},
{"ss", 0x10},
{0, 0},
};
static const TokenDict s_MGW_EventList[] = {
{"context", 0x01},
{0, 0},
};
static const TokenDict s_SGSN_EventList[] = {
{"pdpContext", 0x01},
{"mo-mt-sms", 0x02},
{"rau-gprsAttach-gprsDetach", 0x04},
{"mbmsContext", 0x08},
{0, 0},
};
static const TokenDict s_GGSN_EventList[] = {
{"pdpContext", 0x01},
{"mbmsContext", 0x02},
{0, 0},
};
static const TokenDict s_BMSC_EventList[] = {
{"mbmsMulticastServiceActivation", 0x01},
{0, 0},
};
static const TokenDict s_MME_EventList[] = {
{"ue-initiatedPDNconectivityRequest", 0x01},
{"serviceRequestts", 0x02},
{"initialAttachTrackingAreaUpdateDetach", 0x04},
{"ue-initiatedPDNdisconnection", 0x08},
{"bearerActivationModificationDeletion", 0x10},
{"handover", 0x20},
{0, 0},
};
static const TokenDict s_SPGW_EventList[] = {
{"pdn-connectionCreation", 0x01},
{"pdn-connectionTermination", 0x02},
{"bearerActivationModificationDeletion", 0x04},
{0, 0},
};
static const Parameter s_traceEventListSeq[] = {
{"msc-s-List", s_ctxtPrim_0_Tag, true, TcapXApplication::BitString, s_MSC_S_EventList},
{"mgw-List", s_ctxtPrim_1_Tag, true, TcapXApplication::BitString, s_MGW_EventList},
{"sgsn-List", s_ctxtPrim_2_Tag, true, TcapXApplication::BitString, s_SGSN_EventList},
{"ggsn-List", s_ctxtPrim_3_Tag, true, TcapXApplication::BitString, s_GGSN_EventList},
{"bmsc-List", s_ctxtPrim_4_Tag, true, TcapXApplication::BitString, s_BMSC_EventList},
{"mme-List", s_ctxtPrim_5_Tag, true, TcapXApplication::BitString, s_MME_EventList},
{"sgw-List", s_ctxtPrim_6_Tag, true, TcapXApplication::BitString, s_SPGW_EventList},
{"pgw-List", s_ctxtPrim_7_Tag, true, TcapXApplication::BitString, s_SPGW_EventList},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_authenticationSetSeq[] = {
// TS 100 974 v7.15.0 page 298
{"rand", s_hexTag, false, TcapXApplication::HexString, 0},
{"sres", s_hexTag, false, TcapXApplication::HexString, 0},
{"kc", s_hexTag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_authenticationSet[] = {
{"set", s_sequenceTag, false, TcapXApplication::Sequence, s_authenticationSetSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_authenticationTriplet[] = {
{"triplet", s_sequenceTag, false, TcapXApplication::Sequence, s_authenticationSetSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_authenticationQuintupletSeq[] = {
{"rand", s_hexTag, false, TcapXApplication::HexString, 0},
{"xres", s_hexTag, false, TcapXApplication::HexString, 0},
{"ck", s_hexTag, false, TcapXApplication::HexString, 0},
{"ik", s_hexTag, false, TcapXApplication::HexString, 0},
{"autn", s_hexTag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_authenticationQuintuplet[] = {
{"quintuplet", s_sequenceTag, false, TcapXApplication::Sequence, s_authenticationQuintupletSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_authChoice[] = {
{"tripletList", s_ctxtCstr_0_Tag, false, TcapXApplication::SequenceOf, s_authenticationTriplet},
{"quintupletList", s_ctxtCstr_1_Tag, false, TcapXApplication::SequenceOf, s_authenticationQuintuplet},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_epcAvSeq[] = {
{"rand", s_hexTag, false, TcapXApplication::HexString, 0},
{"xres", s_hexTag, false, TcapXApplication::HexString, 0},
{"autn", s_hexTag, false, TcapXApplication::HexString, 0},
{"kasme", s_hexTag, false, TcapXApplication::HexString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_EPCAV[] = {
// TS 129 002 V9.3.0 page 359
{"EPC-AV", s_sequenceTag, false, TcapXApplication::Sequence, s_epcAvSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_authenticationRes[] = {
// TS 129 002 V9.3.0 page 352
{"authenticationSetList", s_noTag, true, TcapXApplication::Choice, s_authChoice},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"eps-AuthenticationSetList", s_ctxtCstr_2_Tag, true, TcapXApplication::SequenceOf, s_EPCAV},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_alertReason[] = {
// TS 100 974 v7.15.0 page 326
{"ms-Present", 0},
{"memoryAvailable", 1},
{0,0},
};
static const Parameter s_subscriberIdentity[] = {
// TS 100 974 v7.15.0 page 335
{"imsi", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"msisdn", s_ctxtPrim_1_Tag, false, TcapXApplication::AddressString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_domainType[] = {
{"cs-Domain", 0},
{"ps-Domain", 1},
{0,0},
};
static const TokenDict s_requestedNodes[] = {
{"mme", 0x01},
{"sgsn", 0x02},
{0,0},
};
static const Parameter s_requestedInfo[] = {
// TS 100 974 v7.15.0 page 309
{"locationInformation", s_ctxtPrim_0_Tag, true, TcapXApplication::Null, 0},
{"subscriberState", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"currentLocation", s_ctxtPrim_3_Tag, true, TcapXApplication::Null, 0},
{"requestedDomain", s_ctxtPrim_4_Tag, true, TcapXApplication::Enumerated, s_domainType},
{"imei", s_ctxtPrim_6_Tag, true, TcapXApplication::Null, 0},
{"ms-classmark", s_ctxtPrim_5_Tag, true, TcapXApplication::Null, 0},
{"mnpRequestedInfo", s_ctxtPrim_7_Tag, true, TcapXApplication::Null, 0},
{"t-adsData", s_ctxtPrim_8_Tag, true, TcapXApplication::Null, 0},
{"requestedNodes", s_ctxtPrim_9_Tag, true, TcapXApplication::BitString, s_requestedNodes},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_cellIdOrLAI[] = {
// TS 100 974 v7.15.0 page 335
{"cellIdFixedLength", s_ctxtPrim_0_Tag, false, TcapXApplication::CellIdFixedLength, 0},
{"laiFixedLength", s_ctxtPrim_1_Tag, false, TcapXApplication::LAIFixedLength, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_locationInformationEPSSeq[] = {
{"e-utranCellGlobalIdentity", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"trackingAreaIdentity", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"geographicalInformation", s_ctxtPrim_3_Tag, true, TcapXApplication::HexString, 0},
{"geodeticInformation", s_ctxtPrim_4_Tag, true, TcapXApplication::HexString, 0},
{"currentLocationRetrieved", s_ctxtPrim_5_Tag, true, TcapXApplication::Null, 0},
{"ageOfLocationInformation", s_ctxtPrim_6_Tag, true, TcapXApplication::Integer, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_userCSGInformationSeq[] = {
{"csg-Id", s_ctxtPrim_0_Tag, false, TcapXApplication::HexString, 0},
{"extensionContainer", s_ctxtCstr_1_Tag, true, TcapXApplication::HexString, 0},
{"accessMode", s_ctxtPrim_2_Tag, true, TcapXApplication::HexString, 0},
{"cmi", s_ctxtPrim_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_locationInformation[] = {
// TS 100 974 v7.15.0 page 309
{"ageOfLocationInformation", s_intTag, true, TcapXApplication::Integer, 0},
{"geographicalInformation", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"vlr-Number", s_ctxtPrim_1_Tag, true, TcapXApplication::AddressString, 0},
{"locationNumber", s_ctxtPrim_2_Tag, true, TcapXApplication::HexString, 0},
{"cellIdOrLAI", s_ctxtCstr_3_Tag, true, TcapXApplication::Choice, s_cellIdOrLAI},
{"extensionContainer", s_ctxtCstr_4_Tag, true, TcapXApplication::HexString, 0},
{"selectedLSA-Id", s_ctxtPrim_5_Tag, true, TcapXApplication::HexString, 0},
{"msc-Number", s_ctxtPrim_6_Tag, true, TcapXApplication::AddressString, 0},
{"geodeticInformation", s_ctxtPrim_7_Tag, true, TcapXApplication::HexString, 0},
{"currentLocationRetrieved", s_ctxtPrim_8_Tag, true, TcapXApplication::Null, 0},
{"sai-Present", s_ctxtPrim_9_Tag, true, TcapXApplication::Null, 0},
{"locationInformationEPS", s_ctxtCstr_10_Tag,true, TcapXApplication::Sequence, s_locationInformationEPSSeq},
{"userCSGInformation", s_ctxtCstr_11_Tag,true, TcapXApplication::Sequence, s_userCSGInformationSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_notReachableReason[] = {
{"msPurged", 0},
{"imsiDetached", 1},
{"restrictedArea", 2},
{"notRegistered", 3},
{0,0},
};
static const Parameter s_subscriberState[] = {
// TS 100 974 v7.15.0 page 309
{"assumedIdle", s_ctxtPrim_0_Tag, false, TcapXApplication::Null, 0},
{"camelBusy", s_ctxtPrim_1_Tag, false, TcapXApplication::Null, 0},
{"netDetNotReachable", s_enumTag, false, TcapXApplication::Enumerated, s_notReachableReason},
{"notProvidedFromVLR", s_ctxtPrim_2_Tag, false, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_cellGlobalIdOrServiceAreaIdOrLAI[] = {
{"cellGlobalIdOrServiceAreaIdFixedLength", s_ctxtPrim_0_Tag, false, TcapXApplication::HexString, 0},
{"laiFixedLength", s_ctxtPrim_1_Tag, false, TcapXApplication::LAIFixedLength, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_locationInformationGPRSSeq[] = {
{"cellGlobalIdOrServiceAreaIdOrLAI", s_ctxtCstr_0_Tag, true, TcapXApplication::Choice, s_cellGlobalIdOrServiceAreaIdOrLAI},
{"routeingAreaIdentity", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"geographicalInformation", s_ctxtPrim_2_Tag, true, TcapXApplication::HexString, 0},
{"sgsn-Number", s_ctxtPrim_3_Tag, true, TcapXApplication::AddressString, 0},
{"selectedLSAIdentity", s_ctxtPrim_4_Tag, true, TcapXApplication::HexString, 0},
{"extensionContainer", s_ctxtCstr_5_Tag, true, TcapXApplication::HexString, 0},
{"sai-Present", s_ctxtPrim_6_Tag, true, TcapXApplication::Null, 0},
{"geodeticInformation", s_ctxtPrim_7_Tag, true, TcapXApplication::HexString, 0},
{"currentLocationRetrieved", s_ctxtPrim_8_Tag, true, TcapXApplication::Null, 0},
{"ageOfLocationInformation", s_ctxtPrim_9_Tag, true, TcapXApplication::Integer, 0},
{"userCSGInformation", s_ctxtCstr_10_Tag, true, TcapXApplication::Sequence, s_userCSGInformationSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_PDP_ContextInfoSeq[] = {
{"pdp-ContextIdentifier", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"pdp-ContextActive", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"pdp-Type", s_ctxtPrim_2_Tag, false, TcapXApplication::HexString, 0},
{"pdp-Address", s_ctxtPrim_3_Tag, true, TcapXApplication::HexString, 0},
{"apn-Subscribed", s_ctxtPrim_4_Tag, true, TcapXApplication::HexString, 0},
{"apn-InUse", s_ctxtPrim_5_Tag, true, TcapXApplication::HexString, 0},
{"nsapi", s_ctxtPrim_6_Tag, true, TcapXApplication::Integer, 0},
{"transactionId", s_ctxtPrim_7_Tag, true, TcapXApplication::HexString, 0},
{"teid-ForGnAndGp", s_ctxtPrim_8_Tag, true, TcapXApplication::HexString, 0},
{"teid-ForIu", s_ctxtPrim_9_Tag, true, TcapXApplication::HexString, 0},
{"ggsn-Address", s_ctxtPrim_10_Tag, true, TcapXApplication::HexString, 0},
{"qos-Subscribed", s_ctxtPrim_11_Tag, true, TcapXApplication::HexString, 0},
{"qos-Requested", s_ctxtPrim_12_Tag, true, TcapXApplication::HexString, 0},
{"qos-Negotiated", s_ctxtPrim_13_Tag, true, TcapXApplication::HexString, 0},
{"chargingId", s_ctxtPrim_14_Tag, true, TcapXApplication::HexString, 0},
{"chargingCharacteristics", s_ctxtPrim_15_Tag, true, TcapXApplication::HexString, 0},
{"rnc-Address", s_ctxtPrim_16_Tag, true, TcapXApplication::HexString, 0},
{"extensionContainer", s_ctxtCstr_17_Tag, true, TcapXApplication::HexString, 0},
{"qos2-Subscribed", s_ctxtPrim_18_Tag, true, TcapXApplication::HexString, 0},
{"qos2-Requested", s_ctxtPrim_19_Tag, true, TcapXApplication::HexString, 0},
{"qos2-Negotiated", s_ctxtPrim_20_Tag, true, TcapXApplication::HexString, 0},
{"qos3-Subscribed", s_ctxtPrim_21_Tag, true, TcapXApplication::HexString, 0},
{"qos3-Requested", s_ctxtPrim_22_Tag, true, TcapXApplication::HexString, 0},
{"qos3-Negotiated", s_ctxtPrim_23_Tag, true, TcapXApplication::HexString, 0},
{"qos4-Subscribed", s_ctxtPrim_25_Tag, true, TcapXApplication::HexString, 0},
{"qos4-Requested", s_ctxtPrim_26_Tag, true, TcapXApplication::HexString, 0},
{"ext-pdp-Type", s_ctxtPrim_28_Tag, true, TcapXApplication::HexString, 0},
{"ext-pdp-Address", s_ctxtPrim_29_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_PDP_ContextInfo[] = {
{"PDP-ContextInfo", s_sequenceTag, false, TcapXApplication::Sequence, s_PDP_ContextInfoSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_PS_SubscriberStateChoice[] = {
{"notProvidedFromSGSNorMME", s_ctxtPrim_0_Tag, false, TcapXApplication::Null, 0},
{"ps-Detached", s_ctxtPrim_1_Tag, false, TcapXApplication::Null, 0},
{"ps-AttachedNotReachableForPaging", s_ctxtPrim_2_Tag, false, TcapXApplication::Null, 0},
{"ps-AttachedReachableForPaging", s_ctxtPrim_3_Tag, false, TcapXApplication::Null, 0},
{"ps-PDP-ActiveNotReachableForPaging",s_ctxtCstr_4_Tag, false, TcapXApplication::SequenceOf, s_PDP_ContextInfo},
{"ps-PDP-ActiveReachableForPaging", s_ctxtCstr_5_Tag, false, TcapXApplication::SequenceOf, s_PDP_ContextInfo},
{"netDetNotReachable", s_enumTag, false, TcapXApplication::Enumerated, s_notReachableReason},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_GPRSMSClassSeq[] = {
{"mSNetworkCapability", s_ctxtPrim_0_Tag, false, TcapXApplication::HexString, 0},
{"mSRadioAccessCapability", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_numberPortabilityStatus[] = {
{"notKnownToBePorted", 0},
{"ownNumberPortedOut", 1},
{"foreignNumberPortedToForeignNetwork", 2},
{"ownNumberNotPortedOut", 4},
{"foreignNumberPortedIn", 5},
{0,0}
};
static const Parameter s_MNPInfoResSeq[] = {
{"routeingNumber", s_ctxtPrim_0_Tag, true, TcapXApplication::TBCD, 0},
{"imsi", s_ctxtPrim_1_Tag, true, TcapXApplication::TBCD, 0},
{"msisdn", s_ctxtPrim_2_Tag, true, TcapXApplication::AddressString, 0},
{"numberPortabilityStatus", s_ctxtPrim_3_Tag, true, TcapXApplication::Enumerated, s_numberPortabilityStatus},
{"extensionContainer", s_ctxtCstr_4_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_IMS_VoiceOverPS_SessionsInd[] = {
{"imsVoiceOverPS-SessionsNotSupported", 0},
{"imsVoiceOverPS-SessionsSupported", 1},
{0,0}
};
static const Parameter s_subscriberInfo[] = {
// TS 100 974 v7.15.0 page 309
{"locationInformation", s_ctxtCstr_0_Tag, true, TcapXApplication::Sequence, s_locationInformation},
{"subscriberState", s_ctxtCstr_1_Tag, true, TcapXApplication::Choice, s_subscriberState},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"locationInformationGPRS", s_ctxtCstr_3_Tag, true, TcapXApplication::Sequence, s_locationInformationGPRSSeq},
{"ps-SubscriberState", s_ctxtCstr_4_Tag, true, TcapXApplication::Choice, s_PS_SubscriberStateChoice},
{"imei", s_ctxtPrim_5_Tag, true, TcapXApplication::TBCD, 0},
{"ms-Classmark2", s_ctxtPrim_6_Tag, true, TcapXApplication::HexString, 0},
{"gprs-MS-Class", s_ctxtCstr_7_Tag, true, TcapXApplication::Sequence, s_GPRSMSClassSeq},
{"mnpInfoRes", s_ctxtCstr_8_Tag, true, TcapXApplication::Sequence, s_MNPInfoResSeq},
{"imsVoiceOverPS-SessionsIndication", s_ctxtPrim_9_Tag, true, TcapXApplication::Enumerated,s_IMS_VoiceOverPS_SessionsInd},
{"lastUE-ActivityTime", s_ctxtPrim_10_Tag,true, TcapXApplication::HexString, 0},
{"lastRAT-Type", s_ctxtPrim_11_Tag,true, TcapXApplication::Enumerated,s_used_RAT_Type},
{"eps-SubscriberState", s_ctxtCstr_12_Tag,true, TcapXApplication::Choice, s_PS_SubscriberStateChoice},
{"locationInformationEPS", s_ctxtCstr_13_Tag,true, TcapXApplication::Sequence, s_locationInformationEPSSeq},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const TokenDict s_reportingState[] = {
{"stopMonitoring", 0},
{"startMonitoring", 1},
{0,0}
};
static const TokenDict s_CCBSSubscriberStatus[] = {
{"ccbsNotIdle", 0},
{"ccbsIdle", 1},
{"ccbsNotReachable", 2},
{0,0}
};
static const Parameter s_eventReportData[] = {
// TS 100 974 v7.15.0 page 315
{"ccbs-SubscriberStatus", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_CCBSSubscriberStatus},
{"extensionContainer", s_ctxtCstr_1_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_monitoringMode[] = {
// TS 100 974 v7.15.0 page 315
{"a-side", 0},
{"b-side", 1},
{0,0}
};
static const TokenDict s_callOutcome[] = {
// TS 100 974 v7.15.0 page 316
{"success", 0},
{"failure", 1},
{"busy", 2},
{0,0}
};
static const Parameter s_callReportData[] = {
// TS 100 974 v7.15.0 page 315
{"monitoringMode", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_monitoringMode},
{"callOutcome", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_callOutcome},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_updateLocationArgs[] = {
// update location args
{"imsi", s_hexTag, false, TcapXApplication::TBCD, 0},
{"msc-Number", s_ctxtPrim_1_Tag, false, TcapXApplication::AddressString, 0},
{"vlr-Number", s_hexTag, false, TcapXApplication::AddressString, 0},
{"lmsi", s_ctxtPrim_10_Tag, true, TcapXApplication::HexString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"vlr-Capability", s_ctxtCstr_6_Tag, true, TcapXApplication::Sequence, s_vlrCapability},
{"informPreviousNetworkEntity", s_ctxtPrim_11_Tag, true, TcapXApplication::Null, 0},
{"cs-LCS-NotSupportedByUE", s_ctxtPrim_12_Tag, true, TcapXApplication::Null, 0},
{"v-gmlc-Address", s_ctxtPrim_2_Tag, true, TcapXApplication::HexString, 0},
{"add-info", s_ctxtCstr_13_Tag, true, TcapXApplication::Sequence, s_addInfoSeq},
{"pagingArea", s_ctxtCstr_14_Tag, true, TcapXApplication::SequenceOf, s_locationAreaChoice},
{"skipSubscriberDataUpdate", s_ctxtPrim_15_Tag, true, TcapXApplication::Null, 0},
{"restorationIndicator", s_ctxtPrim_16_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_updateLocationRes[] = {
{"hlr-Number", s_hexTag, false, TcapXApplication::AddressString,0},
{"extensionContainer",s_sequenceTag, true, TcapXApplication::HexString, 0},
{"add-Capability", s_nullTag, true, TcapXApplication::Null, 0},
{"pagingArea-Capability",s_ctxtPrim_0_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_cancelLocationArgs[] = {
{"identity", s_noTag, false, TcapXApplication::Choice, s_mapIdentity},
{"cancellationType", s_enumTag, true, TcapXApplication::Enumerated, s_cancellationType},
{"extensionContainer",s_sequenceTag, true, TcapXApplication::HexString, 0},
{"typeOfUpdate", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_typeOfUpdate},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_extensionContainerRes[] = {
{"extensionContainer",s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_provideRoamingNumberArgs[] = {
{"imsi", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"msc-Number", s_ctxtPrim_1_Tag, false, TcapXApplication::AddressString, 0},
{"msisdn", s_ctxtPrim_2_Tag, true, TcapXApplication::AddressString, 0},
{"lmsi", s_ctxtPrim_4_Tag, true, TcapXApplication::HexString, 0},
{"gsm-BearerCapability", s_ctxtCstr_5_Tag, true, TcapXApplication::Sequence, s_externalSignalInfo},
{"networkSignalInfo", s_ctxtCstr_6_Tag, true, TcapXApplication::Sequence, s_externalSignalInfo},
{"suppressionOfAnnouncement", s_ctxtPrim_7_Tag, true, TcapXApplication::Null, 0},
{"gmsc-Address", s_ctxtPrim_8_Tag, true, TcapXApplication::AddressString, 0},
{"callReferenceNumber", s_ctxtPrim_9_Tag, true, TcapXApplication::HexString, 0},
{"or-Interrogation", s_ctxtPrim_10_Tag, true, TcapXApplication::Null, 0},
{"extensionContainer", s_ctxtCstr_11_Tag, true, TcapXApplication::HexString, 0},
{"alertingPattern", s_ctxtPrim_12_Tag, true, TcapXApplication::Enumerated, s_alertPattern},
{"ccbs-Call", s_ctxtPrim_13_Tag, true, TcapXApplication::Null, 0},
{"supportedCamelPhasesInGMSC",s_ctxtPrim_15_Tag, true, TcapXApplication::BitString, s_camelPhases},
{"additionalSignalInfo", s_ctxtCstr_14_Tag, true, TcapXApplication::Sequence, s_extExtenalSignalInfo},
{"orNotSupportedInGMSC", s_ctxtPrim_16_Tag, true, TcapXApplication::Null, 0},
{"pre-pagingSupported", s_ctxtPrim_17_Tag, true, TcapXApplication::Null, 0},
{"longFTN-Supported", s_ctxtPrim_18_Tag, true, TcapXApplication::Null, 0},
{"suppress-VT-CSI", s_ctxtPrim_19_Tag, true, TcapXApplication::Null, 0},
{"offeredCamel4CSIsInInterrogatingNode", s_ctxtPrim_20_Tag, true, TcapXApplication::BitString, s_offeredCamel4CSIs},
{"mtRoamingRetrySupported", s_ctxtPrim_21_Tag, true, TcapXApplication::Null, 0},
{"pagingArea", s_ctxtCstr_22_Tag, true, TcapXApplication::SequenceOf, s_locationAreaChoice},
{"callPriority", s_ctxtPrim_23_Tag, true, TcapXApplication::Enumerated, s_EMLPPPriority},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_provideRoamingNumberRes[] = {
{"roamingNumber", s_hexTag, false,TcapXApplication::AddressString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"releaseResourcesSupported", s_nullTag, true, TcapXApplication::Null, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_insertSubscriberDataArgs[] = {
{"imsi", s_ctxtPrim_0_Tag, true, TcapXApplication::TBCD, 0},
{"msisdn", s_ctxtPrim_1_Tag, true, TcapXApplication::AddressString,0},
{"category", s_ctxtPrim_2_Tag, true, TcapXApplication::Enumerated, s_category},
{"subscriberStatus", s_ctxtPrim_3_Tag, true, TcapXApplication::Enumerated, s_subscriberStatus},
{"bearerServiceList", s_ctxtCstr_4_Tag, true, TcapXApplication::SequenceOf, s_bearerService},
{"teleserviceList", s_ctxtCstr_6_Tag, true, TcapXApplication::SequenceOf, s_teleservice},
{"provisionedSS", s_ctxtCstr_7_Tag, true, TcapXApplication::SequenceOf, s_extSSInfo},
{"odb-Data", s_ctxtCstr_8_Tag, true, TcapXApplication::Sequence, s_odbData},
{"roamingRestrictionDueToUnsupportedFeature", s_ctxtPrim_9_Tag, true, TcapXApplication::Null, 0},
{"regionalSubscriptionData", s_ctxtCstr_10_Tag, true, TcapXApplication::SequenceOf, s_zoneCode},
{"vbsSubscriptionData", s_ctxtCstr_11_Tag, true, TcapXApplication::SequenceOf, s_voiceBroadcastData},
{"vgcsSubscriptionData", s_ctxtCstr_12_Tag, true, TcapXApplication::SequenceOf, s_voiceGroupCallData},
{"vlrCamelSubscriptionInfo", s_ctxtCstr_13_Tag, true, TcapXApplication::Sequence, s_VlrCamelSubscriptionInfo},
{"extensionContainer", s_ctxtCstr_14_Tag, true, TcapXApplication::HexString, 0},
{"naea-PreferredCI", s_ctxtCstr_15_Tag, true, TcapXApplication::Sequence, s_naeaPreferredCI},
{"gprsSubscriptionData", s_ctxtCstr_16_Tag, true, TcapXApplication::Sequence, s_GPRSSubscriptionData},
{"roamingRestrictedInSgsnDueToUnsupportedFeature", s_ctxtPrim_23_Tag, true, TcapXApplication::Null, 0},
{"networkAccessMode", s_ctxtPrim_24_Tag, true, TcapXApplication::Enumerated, s_networkAccessMode},
{"lsaInformation", s_ctxtCstr_25_Tag, true, TcapXApplication::Sequence, s_LSAInformation},
{"lmu-Indicator", s_ctxtPrim_21_Tag, true, TcapXApplication::Null, 0},
{"lcsInformation", s_ctxtCstr_22_Tag, true, TcapXApplication::Sequence, s_LCSInformation},
{"istAlertTimer", s_ctxtPrim_26_Tag, true, TcapXApplication::Integer, 0},
{"superChargerSupportedInHLR", s_ctxtPrim_27_Tag, true, TcapXApplication::HexString, 0},
{"mc-SS-Info", s_ctxtCstr_28_Tag, true, TcapXApplication::Sequence, s_MC_SSInfo},
{"cs-AllocationRetentionPriority", s_ctxtPrim_29_Tag, true, TcapXApplication::HexString, 0},
{"sgsn-CAMEL-SubscriptionInfo", s_ctxtCstr_17_Tag, true, TcapXApplication::Sequence, s_SGSN_CAMELSubscriptionInfoSeq},
{"chargingCharacteristics", s_ctxtPrim_18_Tag, true, TcapXApplication::HexString, 0},
{"accessRestrictionData", s_ctxtPrim_19_Tag, true, TcapXApplication::BitString, s_accessRestrictionData},
{"ics-Indicator", s_ctxtPrim_20_Tag, true, TcapXApplication::Bool, 0},
{"eps-SubscriptionData", s_ctxtCstr_31_Tag, true, TcapXApplication::Sequence, s_EPS_SubscriptionData},
{"csg-SubscriptionDataList", s_ctxtCstr_32_Tag, true, TcapXApplication::SequenceOf, s_CSG_SubscriptionData},
{"ue-ReachabilityRequestIndicator", s_ctxtPrim_33_Tag, true, TcapXApplication::Null, 0},
{"sgsn-Number", s_ctxtPrim_34_Tag, true, TcapXApplication::AddressString,0},
{"mme-Name", s_ctxtPrim_35_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_insertSubscriberDataRes[] = {
{"teleserviceList", s_ctxtCstr_1_Tag, true, TcapXApplication::SequenceOf, s_teleservice},
{"bearerServiceList", s_ctxtCstr_2_Tag, true, TcapXApplication::SequenceOf, s_bearerService},
{"ss-List", s_ctxtCstr_3_Tag, true, TcapXApplication::SequenceOf, s_ssCode},
{"odb-GeneralData", s_ctxtPrim_4_Tag, true, TcapXApplication::BitString, s_odbGeneralData},
{"regionalSubscriptionResponse",s_ctxtPrim_5_Tag, true, TcapXApplication::Enumerated, s_regionalSubscriptionResponse},
{"supportedCamelPhases", s_ctxtPrim_6_Tag, true, TcapXApplication::BitString, s_camelPhases},
{"extensionContainer", s_ctxtCstr_7_Tag, true, TcapXApplication::HexString, 0},
{"offeredCamel4CSIs", s_ctxtPrim_8_Tag, true, TcapXApplication::BitString, s_offeredCamel4CSIs},
{"supportedFeatures", s_ctxtPrim_9_Tag, true, TcapXApplication::BitString, s_supportedFeatures},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_deleteSubscriberDataArgs[] = {
{"imsi", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"basicServiceList", s_ctxtCstr_1_Tag, true, TcapXApplication::SequenceOf, s_basicServiceCodeType},
{"ss-List", s_ctxtCstr_2_Tag, true, TcapXApplication::SequenceOf, s_ssCode},
{"roamingRestrictionDueToUnsupportedFeature", s_ctxtPrim_4_Tag, true, TcapXApplication::Null, 0},
{"regionalSubscriptionIdentifier", s_ctxtPrim_5_Tag, true, TcapXApplication::HexString, 0},
{"vbsGroupIndication", s_ctxtPrim_7_Tag, true, TcapXApplication::Null, 0},
{"vgcsGroupIndication", s_ctxtPrim_8_Tag, true, TcapXApplication::Null, 0},
{"camelSubscriptionInfoWithdraw", s_ctxtPrim_9_Tag, true, TcapXApplication::Null, 0},
{"extensionContainer", s_ctxtCstr_6_Tag, true, TcapXApplication::HexString, 0},
{"gprsSubscriptionDataWithdraw", s_ctxtCstr_10_Tag,true, TcapXApplication::Choice, s_GPRSSubscriptionDataWithdraw},
{"roamingRestrictedInSgsnDueToUnsuppportedFeature", s_ctxtPrim_11_Tag,true, TcapXApplication::Null, 0},
{"lsaInformationWithdraw", s_ctxtCstr_12_Tag,true, TcapXApplication::Choice, s_LSAInformationWithdraw},
{"gmlc-ListWithdraw", s_ctxtPrim_13_Tag,true, TcapXApplication::Null, 0},
{"istInformationWithdraw", s_ctxtPrim_14_Tag,true, TcapXApplication::Null, 0},
{"specificCSI-Withdraw", s_ctxtPrim_15_Tag,true, TcapXApplication::BitString, s_specificCSI_Withdraw},
{"chargingCharacteristicsWithdraw", s_ctxtPrim_16_Tag,true, TcapXApplication::Null, 0},
{"stn-srWithdraw", s_ctxtPrim_17_Tag,true, TcapXApplication::Null, 0},
{"epsSubscriptionDataWithdraw", s_ctxtCstr_18_Tag,true, TcapXApplication::Choice, s_EPS_SubscriptionDataWithdraw},
{"apn-oi-replacementWithdraw", s_ctxtPrim_19_Tag,true, TcapXApplication::Null, 0},
{"csg-SubscriptionDeleted", s_ctxtPrim_20_Tag,true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_deleteSubscriberDataRes[] = {
{"regionalSubscriptionResponse", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_regionalSubscriptionResponse},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
// GSM 09.02 v5.3.0 page 721
static const Parameter s_subscriberId[] = {
{"imsi", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"tmsi", s_ctxtPrim_1_Tag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
// GSM 09.02 v5.3.0 page 721
static const TokenDict s_requestParamEnum[] = {
{"requestIMSI", 0},
{"requestAuthenticationSet", 1},
{"requestSubscriberData", 2},
{"requestKi", 4},
{0,0}
};
// GSM 09.02 v5.3.0 page 721
static const Parameter s_requestParameter[] = {
{"requestParameter", s_enumTag, true, TcapXApplication::Enumerated, s_requestParamEnum},
{"", s_noTag, false, TcapXApplication::None, 0},
};
// GSM 09.02 v5.3.0 pp 721-723
static const Parameter s_sentParameterChoice[] = {
{"imsi", s_ctxtPrim_0_Tag, true, TcapXApplication::TBCD, 0},
{"authenticationSet", s_ctxtCstr_1_Tag, true, TcapXApplication::Sequence, s_authenticationSetSeq},
{"subscriberData", s_ctxtCstr_2_Tag, true, TcapXApplication::Sequence, s_insertSubscriberDataArgs},
{"ki", s_ctxtPrim_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
// GSM 09.02 v5.3.0 pp 721-723
static const Parameter s_sentParameterList[] = {
{"sentParameter", s_noTag, false, TcapXApplication::Choice, s_sentParameterChoice},
{"", s_noTag, false, TcapXApplication::None, 0},
};
// GSM 09.02 v5.3.0 page 721
static const Parameter s_sendParametersDataArgs[] = {
{"subscriberId", s_noTag, false, TcapXApplication::Choice, s_subscriberId},
{"requestParameterList", s_sequenceTag, false, TcapXApplication::SequenceOf, s_requestParameter},
{"", s_noTag, false, TcapXApplication::None, 0},
};
// GSM 09.02 v5.3.0 pp. 721
static const Parameter s_sendParametersDataRes[] = {
{"sentParameterList", s_sequenceTag, false, TcapXApplication::SequenceOf, s_sentParameterList},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_registerSSArgs[] = {
{"ss-Code", s_hexTag, false, TcapXApplication::Enumerated, s_SSCode},
{"basicService", s_noTag, true, TcapXApplication::Choice, s_basicServiceCode},
{"forwardedToNumber", s_ctxtPrim_4_Tag, true, TcapXApplication::AddressString, 0},
{"forwardedToSubaddress", s_ctxtPrim_6_Tag, true, TcapXApplication::HexString, 0},
{"noReplyConditionTime", s_ctxtPrim_5_Tag, true, TcapXApplication::Integer, 0},
{"defaultPriority", s_ctxtPrim_7_Tag, true, TcapXApplication::Enumerated, s_EMLPPPriority},
{"nbrUser", s_ctxtPrim_8_Tag, true, TcapXApplication::Integer, 0},
{"longFTN-Supported", s_ctxtPrim_9_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_ssInfoRes[] = {
{"ss-Info", s_noTag, false, TcapXApplication::Choice, s_extSSInfoChoice},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_ssCodeArgs[] = {
{"ss-Code", s_hexTag, false, TcapXApplication::Enumerated, s_SSCode},
{"basicService", s_noTag, true, TcapXApplication::Choice, s_basicServiceCode},
{"longFTN-Supported", s_ctxtPrim_4_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_authFailureArgs[] = {
{"imsi", s_hexTag, false, TcapXApplication::TBCD, 0},
{"failureCause", s_enumTag, false, TcapXApplication::Enumerated, s_failureCauseEnum},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"re-attempt", s_boolTag, true, TcapXApplication::Bool, 0},
{"accessType", s_enumTag, true, TcapXApplication::Enumerated, s_accessTypeEnum},
{"rand", s_hexTag, true, TcapXApplication::HexString, 0},
{"vlr-Number", s_ctxtPrim_0_Tag, true, TcapXApplication::AddressString, 0},
{"sgsn-Number", s_ctxtPrim_1_Tag, true, TcapXApplication::AddressString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_registerPasswordArgs[] = {
{"ss-Code", s_hexTag, false, TcapXApplication::Enumerated, s_SSCode},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_registerPasswordRes[] = {
{"newPassword", s_numStrTag, false, TcapXApplication::AppString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_getPasswordArgs[] = {
{"guidanceInfo", s_enumTag, false, TcapXApplication::Enumerated, s_guidanceInfo},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_getPasswordRes[] = {
{"currentPassword", s_numStrTag, false, TcapXApplication::AppString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_updateGprsLocationArgs[] = {
{"imsi", s_hexTag, false, TcapXApplication::TBCD, 0},
{"sgsn-Number", s_hexTag, false, TcapXApplication::AddressString, 0},
{"sgsn-Address", s_hexTag, false, TcapXApplication::HexString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"sgsn-Capability", s_ctxtCstr_0_Tag, true, TcapXApplication::Sequence, s_SGSN_CapabilitySeq},
{"informPreviousNetworkEntity", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"ps-LCS-NotSupportedByUE", s_ctxtPrim_2_Tag, true, TcapXApplication::Null, 0},
{"v-gmlc-Address", s_ctxtPrim_3_Tag, true, TcapXApplication::HexString, 0},
{"add-info", s_ctxtCstr_4_Tag, true, TcapXApplication::Sequence, s_addInfoSeq},
{"eps-info", s_ctxtCstr_5_Tag, true, TcapXApplication::Choice, s_EPS_InfoChoice},
{"servingNodeTypeIndicator", s_ctxtPrim_6_Tag, true, TcapXApplication::Null, 0},
{"skipSubscriberDataUpdate", s_ctxtPrim_7_Tag, true, TcapXApplication::Null, 0},
{"usedRAT-Type", s_ctxtPrim_8_Tag, true, TcapXApplication::Enumerated, s_used_RAT_Type},
{"gprsSubscriptionDataNotNeeded", s_ctxtPrim_9_Tag, true, TcapXApplication::Null, 0},
{"nodeTypeIndicator", s_ctxtPrim_10_Tag, true, TcapXApplication::Null, 0},
{"areaRestricted", s_ctxtPrim_11_Tag, true, TcapXApplication::Null, 0},
{"ue-reachableIndicator", s_ctxtPrim_12_Tag, true, TcapXApplication::Null, 0},
{"epsSubscriptionDataNotNeeded", s_ctxtPrim_13_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_updateGprsLocationRes[] = {
{"hlr-Number", s_hexTag, false, TcapXApplication::AddressString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"add-Capability", s_nullTag, true, TcapXApplication::Null, 0},
{"sgsn-mmeSeparationSupported", s_ctxtPrim_0_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false , TcapXApplication::None, 0},
};
static const Parameter s_sendRoutingInfoForGprsArgs[] = {
{"imsi", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"ggsn-Address", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"ggsn-Number", s_ctxtPrim_2_Tag, false, TcapXApplication::AddressString, 0},
{"extensionContainer",s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_sendRoutingInfoForGprsRes[] = {
{"sgsn-Address", s_ctxtPrim_0_Tag, false, TcapXApplication::HexString, 0},
{"ggsn-Address", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"mobileNotReachableReason", s_ctxtPrim_2_Tag, true, TcapXApplication::Integer, 0},
{"extensionContainer", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_failureReportArgs[] = {
{"imsi", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"ggsn-Number", s_ctxtPrim_1_Tag, false, TcapXApplication::AddressString, 0},
{"ggsn-Address", s_ctxtPrim_2_Tag, true, TcapXApplication::HexString, 0},
{"extensionContainer",s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_failureReportRes[] = {
{"ggsn-Address", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"extensionContainer",s_ctxtCstr_1_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_resetArgs[] = {
{"hlr-Number", s_hexTag, false, TcapXApplication::AddressString, 0},
{"hlr-List", s_sequenceTag, true, TcapXApplication::SequenceOf, s_hlrId},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_sendRoutingInfoForSMArgs[] = {
{"msisdn", s_ctxtPrim_0_Tag, false, TcapXApplication::AddressString, 0},
{"sm-RP-PRI", s_ctxtPrim_1_Tag, false, TcapXApplication::Bool, 0},
{"serviceCentreAddress", s_ctxtPrim_2_Tag, false, TcapXApplication::AddressString, 0},
{"extensionContainer", s_ctxtCstr_6_Tag, true, TcapXApplication::HexString, 0},
{"gprsSupportIndicator", s_ctxtPrim_7_Tag, true, TcapXApplication::Null, 0},
{"sm-RP-MTI", s_ctxtPrim_8_Tag, true, TcapXApplication::Integer, 0},
{"sm-RP-SMEA", s_ctxtPrim_9_Tag, true, TcapXApplication::HexString, 0},
{"sm-deliveryNotIntended", s_ctxtPrim_10_Tag, true, TcapXApplication::Enumerated, s_SM_DeliveryNotIntended},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_sendRoutingInfoForSMRes[] = {
{"imsi", s_hexTag, false, TcapXApplication::TBCD, 0},
{"locationInfoWithLMSI", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_locationInfoWithLMSI},
{"extensionContainer", s_ctxtCstr_4_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_smRpDa[] = {
{"imsi", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"lmsi", s_ctxtPrim_1_Tag, false, TcapXApplication::HexString, 0},
{"serviceCentreAddressDA", s_ctxtPrim_4_Tag, false, TcapXApplication::AddressString, 0},
{"noSM-RP-DA", s_ctxtPrim_5_Tag, false, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_smRpOa[] = {
{"msisdn", s_ctxtPrim_2_Tag, false, TcapXApplication::AddressString, 0},
{"serviceCentreAddressOA", s_ctxtPrim_4_Tag, false, TcapXApplication::AddressString, 0},
{"noSM-RP-OA", s_ctxtPrim_5_Tag, false, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_mtForwardSMArgs[] = {
{"sm-RP-DA", s_noTag, false, TcapXApplication::Choice, s_smRpDa},
{"sm-RP-OA", s_noTag, false, TcapXApplication::Choice, s_smRpOa},
{"sm-RP-UI", s_hexTag, false, TcapXApplication::HexString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_moForwardSMArgs[] = {
{"sm-RP-DA", s_noTag, false, TcapXApplication::Choice, s_smRpDa},
{"sm-RP-OA", s_noTag, false, TcapXApplication::Choice, s_smRpOa},
{"sm-RP-UI", s_hexTag, false, TcapXApplication::HexString, 0},
{"moreMessagesToSend", s_nullTag, true, TcapXApplication::Null, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"imsi", s_hexTag, true, TcapXApplication::TBCD, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_forwardSMRes[] = {
{"sm-RP-UI", s_hexTag, true, TcapXApplication::HexString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_forwardSMArgs[] = {
{"sm-RP-DA", s_noTag, false, TcapXApplication::Choice, s_smRpDa},
{"sm-RP-OA", s_noTag, false, TcapXApplication::Choice, s_smRpOa},
{"sm-RP-UI", s_hexTag, false, TcapXApplication::HexString, 0},
{"moreMessagesToSend", s_nullTag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_SMDeliveryOutcomeEnum[] = {
{"memoryCapacityExceeded", 0},
{"absentSubscriber", 1},
{"successfulTransfer", 2},
{0,0}
};
static const Parameter s_reportSMDeliveryArgs[] = {
{"msisdn", s_hexTag, false, TcapXApplication::AddressString, 0},
{"serviceCentreAddress", s_hexTag, false, TcapXApplication::AddressString, 0},
{"sm-DeliveryOutcome", s_enumTag, false, TcapXApplication::Enumerated, s_SMDeliveryOutcomeEnum},
{"absentSubscriberDiagnosticSM", s_ctxtPrim_0_Tag, true, TcapXApplication::Integer, 0},
{"extensionContainer", s_ctxtCstr_1_Tag, true, TcapXApplication::HexString, 0},
{"gprsSupportIndicator", s_ctxtPrim_2_Tag, true, TcapXApplication::Null, 0},
{"deliveryOutcomeIndicator", s_ctxtPrim_3_Tag, true, TcapXApplication::Null, 0},
{"additionalSM-DeliveryOutcome", s_ctxtPrim_4_Tag, true, TcapXApplication::Enumerated, s_SMDeliveryOutcomeEnum},
{"additionalAbsentSubscriberDiagnosticSM", s_ctxtPrim_5_Tag, true, TcapXApplication::Integer, 0},
{"ip-sm-gw-Indicator", s_ctxtPrim_6_Tag, true, TcapXApplication::Null, 0},
{"ip-sm-gw-sm-deliveryOutcome", s_ctxtPrim_7_Tag, true, TcapXApplication::Enumerated, s_SMDeliveryOutcomeEnum},
{"ip-sm-gw-absentSubscriberDiagnosticSM", s_ctxtPrim_8_Tag, true, TcapXApplication::Integer, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_reportSMDeliveryRes[] = {
{ "storedMSISDN", s_hexTag, true, TcapXApplication::AddressString, 0},
{ "extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_activateTraceModeArgs[] = {
{"imsi", s_ctxtPrim_0_Tag, true, TcapXApplication::TBCD, 0},
{"traceReference", s_ctxtPrim_1_Tag, false, TcapXApplication::HexString, 0},
{"traceType", s_ctxtPrim_2_Tag, false, TcapXApplication::Integer, 0},
{"omc-Id", s_ctxtPrim_3_Tag, true, TcapXApplication::AddressString, 0},
{"extensionContainer", s_ctxtCstr_4_Tag, true, TcapXApplication::HexString, 0},
{"traceReference2", s_ctxtPrim_5_Tag, true, TcapXApplication::HexString, 0},
{"traceDepthList", s_ctxtCstr_6_Tag, true, TcapXApplication::Sequence, s_traceDepthListSeq},
{"traceNE-TypeList", s_ctxtPrim_7_Tag, true, TcapXApplication::BitString, s_traceNETypeList},
{"traceInterfaceList", s_ctxtCstr_8_Tag, true, TcapXApplication::Sequence, s_traceInterfaceListSeq},
{"traceEventList", s_ctxtCstr_9_Tag, true, TcapXApplication::Sequence, s_traceEventListSeq},
{"traceCollectionEntity", s_ctxtPrim_10_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_traceModeRes[] = {
{"extensionContainer", s_ctxtCstr_0_Tag, true, TcapXApplication::HexString, 0},
{"traceSupportIndicator", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_deactivateTraceModeArgs[] = {
{"imsi", s_ctxtPrim_0_Tag, true, TcapXApplication::TBCD, 0},
{"traceReference", s_ctxtPrim_1_Tag, false, TcapXApplication::HexString, 0},
{"extensionContainer",s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"traceReference2", s_ctxtPrim_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_lcsLocationInfo[] = {
{"msc-Number", s_hexTag, false, TcapXApplication::AddressString, 0},
{"lmsi", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"extensionContainer", s_ctxtCstr_1_Tag, true, TcapXApplication::HexString, 0},
{"gprsNodeIndicator", s_ctxtPrim_2_Tag, true, TcapXApplication::Null, 0},
{"additional-Number", s_ctxtCstr_3_Tag, true, TcapXApplication::Choice, s_additionalNumber},
{"supportedLCS-CapabilitySets", s_ctxtPrim_4_Tag, true, TcapXApplication::BitString, s_supportedLCSCapabilitySets},
{"additional-LCS-CapabilitySets", s_ctxtPrim_5_Tag, true, TcapXApplication::BitString, s_supportedLCSCapabilitySets},
{"mme-Name", s_ctxtPrim_6_Tag, true, TcapXApplication::HexString, 0},
{"aaa-Server-Name", s_ctxtPrim_8_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_sendRoutingInfoForLCSArgs[] = {
{"mlcNumber", s_ctxtPrim_0_Tag, false, TcapXApplication::AddressString, 0},
{"targetMS", s_ctxtCstr_1_Tag, false, TcapXApplication::Choice, s_subscriberIdentity},
{"extensionContainer",s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_sendRoutingInfoForLCSRes[] = {
{"targetMS", s_ctxtCstr_0_Tag, false, TcapXApplication::Choice, s_subscriberIdentity},
{"lcsLocationInfo", s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_lcsLocationInfo},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"v-gmlc-Address", s_ctxtPrim_3_Tag, true, TcapXApplication::HexString, 0},
{"h-gmlc-Address", s_ctxtPrim_4_Tag, true, TcapXApplication::HexString, 0},
{"ppr-Address", s_ctxtPrim_5_Tag, true, TcapXApplication::HexString, 0},
{"additional-v-gmlc-Address", s_ctxtPrim_6_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_resynchronisationInfo[] = {
{"rand", s_hexTag, false, TcapXApplication::HexString, 0},
{"auts", s_hexTag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_requestingNodeType[] = {
{"vlr", 0},
{"sgsn", 1},
{"s-cscf", 2},
{"bsf", 3},
{"gan-aaa-server", 4},
{"wlan-aaa-server", 5},
{"mme", 16},
{"mme-sgsn", 17},
{0, 0},
};
static const Parameter s_sendAuthInfoSeq[] = {
{"imsi", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"numberOfRequestedVectors", s_intTag, false, TcapXApplication::Integer, 0},
{"segmentationProhibited", s_nullTag, true, TcapXApplication::Null, 0},
{"immediateResponsePreferred", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"re-synchronisationInfo", s_sequenceTag, true, TcapXApplication::Sequence, s_resynchronisationInfo},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"requestingNodeType", s_ctxtPrim_3_Tag, true, TcapXApplication::Enumerated, s_requestingNodeType},
{"requestingPLMN-Id", s_ctxtPrim_4_Tag, true, TcapXApplication::TBCD, 0},
{"numberOfRequestedAdditional-Vectors", s_ctxtPrim_5_Tag, true, TcapXApplication::Integer, 0},
{"additionalVectorsAreForEPS", s_ctxtPrim_6_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_sendAuthenticationInfoArgs[] = {
{"imsi", s_hexTag, false, TcapXApplication::TBCD, 0},
{"sendAuthenticationInfoArgs", s_sequenceTag, false, TcapXApplication::Sequence, s_sendAuthInfoSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_sendAuthenticationInfoRes[] = {
{"sendAuthenticationInfoRes-v2", s_sequenceTag, false, TcapXApplication::SequenceOf, s_authenticationSet},
{"sendAuthenticationInfoRes-v3", s_ctxtCstr_3_Tag, false, TcapXApplication::Sequence, s_authenticationRes},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_restoreDataArgs[] = {
{"imsi", s_hexTag, false, TcapXApplication::TBCD, 0},
{"lmsi", s_hexTag, true, TcapXApplication::HexString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"vlr-Capability", s_ctxtCstr_6_Tag, true, TcapXApplication::Sequence, s_vlrCapability},
{"restorationIndicator", s_ctxtPrim_7_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_restoreDataRes[] = {
{"hlr-Number", s_hexTag, false, TcapXApplication::AddressString, 0},
{"msNotReachable", s_nullTag, true, TcapXApplication::Null, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_sendIMSIArgs[] = {
{"msisdn", s_hexTag, false, TcapXApplication::AddressString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_sendIMSIRes[] = {
{"imsi", s_hexTag, false, TcapXApplication::TBCD, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_unstructuredSSArgs[] = {
{"ussd-DataCodingScheme", s_hexTag, false, TcapXApplication::HexString, 0},
{"ussd-String", s_hexTag, false, TcapXApplication::GSMString, 0},
{"alertingPattern", s_hexTag, true, TcapXApplication::Enumerated, s_alertPattern},
{"msisdn", s_ctxtPrim_0_Tag, true, TcapXApplication::AddressString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_unstructuredSSRes[] = {
{"ussd-DataCodingScheme", s_hexTag, false, TcapXApplication::HexString, 0},
{"ussd-String", s_hexTag, false, TcapXApplication::GSMString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_mwStatus[] = {
{ "sc-AddressNotIncluded", 0x01 },
{ "mnrf-Set", 0x02 },
{ "mcef-Set", 0x04 },
{ "mnrg-Set", 0x08 },
{ 0, 0 }
};
static const Parameter s_informServiceCentreArgs[] = {
{ "storedMSISDN", s_hexTag, true, TcapXApplication::AddressString, 0 },
{ "mw-Status", s_bitsTag, true, TcapXApplication::BitString, s_mwStatus },
{ "extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0 },
{ "absentSubscriberDiagnosticSM", s_intTag, true, TcapXApplication::Integer, 0 },
{ "additionalAbsentSubscriberDiagnosticSM", s_ctxtPrim_0_Tag, true, TcapXApplication::Integer, 0 },
{ "", s_noTag, false, TcapXApplication::None, 0 },
};
static const Parameter s_alertServiceCentreArgs[] = {
{"msisdn", s_hexTag, false, TcapXApplication::AddressString, 0},
{"serviceCentreAddress", s_hexTag, false, TcapXApplication::AddressString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_readyForSMArgs[] = {
{"imsi", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"alertReason", s_enumTag, false, TcapXApplication::Enumerated, s_alertReason},
{"alertReasonIndicator", s_nullTag, true, TcapXApplication::Null, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"additionalAlertReasonIndicator", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_purgeMSArgs[] = {
{"imsi", s_hexTag, false, TcapXApplication::TBCD, 0},
{"vlr-Number", s_ctxtPrim_0_Tag, true, TcapXApplication::AddressString, 0},
{"sgsn-Number", s_ctxtPrim_1_Tag, true, TcapXApplication::AddressString, 0},
{"extensionContainer",s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_purgeMSRes[] = {
{"freezeTMSI", s_ctxtPrim_0_Tag, true, TcapXApplication::Null, 0},
{"freezeP-TMSI", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"extensionContainer",s_sequenceTag, true, TcapXApplication::HexString, 0},
{"freezeM-TMSI", s_ctxtPrim_2_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_provideSubscriberInfoArgs[] = {
{"imsi", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"lmsi", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"requestedInfo", s_ctxtCstr_2_Tag, false, TcapXApplication::Sequence, s_requestedInfo},
{"extensionContainer",s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_provideSubscriberInfoRes[] = {
{"subscriberInfo", s_sequenceTag, false, TcapXApplication::Sequence, s_subscriberInfo},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_anyTimeInterrogationArgs[] = {
{"subscriberIdentity", s_ctxtCstr_0_Tag, false, TcapXApplication::Choice, s_subscriberIdentity},
{"requestedInfo", s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_requestedInfo},
{"gsmSCF-Address", s_ctxtPrim_3_Tag, false, TcapXApplication::AddressString, 0},
{"extensionContainer", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_anyTimeInterrogationRes[] = {
{"subscriberInfo", s_sequenceTag, false, TcapXApplication::Sequence, s_subscriberInfo},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_setReportingStateArgs[] = {
{"imsi", s_ctxtPrim_0_Tag, true, TcapXApplication::TBCD, 0},
{"lmsi", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"ccbs-Monitoring", s_ctxtPrim_2_Tag, true, TcapXApplication::Enumerated, s_reportingState},
{"extensionContainer", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_setReportingStateRes[] = {
{"ccbs-SubscriberStatus", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_CCBSSubscriberStatus},
{"extensionContainer", s_ctxtCstr_1_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_statusReportArgs[] = {
{"imsi", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
{"eventReportData", s_ctxtCstr_1_Tag, true, TcapXApplication::Sequence, s_eventReportData},
{"callReportdata", s_ctxtCstr_2_Tag, true, TcapXApplication::Sequence, s_callReportData},
{"extensionContainer", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_statusReportRes[] = {
{"extensionContainer", s_ctxtCstr_0_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Operation s_mapOps[] = {
{"updateLocation", true, 2, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_updateLocationArgs,
s_sequenceTag, s_updateLocationRes
},
{"cancelLocation", true, 3, SS7TCAP::SuccessOrFailureReport,
s_ctxtCstr_3_Tag, s_cancelLocationArgs,
s_sequenceTag, s_extensionContainerRes
},
{"provideRoamingNumber", true, 4, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_provideRoamingNumberArgs,
s_sequenceTag, s_provideRoamingNumberRes
},
{"insertSubscriberData", true, 7, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_insertSubscriberDataArgs,
s_sequenceTag, s_insertSubscriberDataRes
},
{"deleteSubscriberData", true, 8, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_deleteSubscriberDataArgs,
s_sequenceTag, s_deleteSubscriberDataRes
},
{"sendParameters", true, 9, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_sendParametersDataArgs,
s_noTag, s_sendParametersDataRes
},
{"registerSS", true, 10, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_registerSSArgs,
s_noTag, s_extSSInfoChoice
},
{"eraseSS", true, 11, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_ssCodeArgs,
s_noTag, s_extSSInfoChoice
},
{"activateSS", true, 12, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_ssCodeArgs,
s_noTag, s_extSSInfoChoice
},
{"deactivateSS", true, 13, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_ssCodeArgs,
s_noTag, s_extSSInfoChoice
},
{"interrogateSS", true, 14, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_ssCodeArgs,
s_noTag, s_InterrogateSSRes
},
{"authenticationFailureReport", true, 15, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_authFailureArgs,
s_sequenceTag, s_extensionContainerRes,
},
{"registerPassword", true, 17, SS7TCAP::SuccessOrFailureReport,
s_noTag, s_registerPasswordArgs,
s_noTag, s_registerPasswordRes
},
{"getPassword", true, 18, SS7TCAP::SuccessOnlyReport,
s_noTag, s_getPasswordArgs,
s_noTag, s_getPasswordRes
},
{"updateGprsLocation", true, 23, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_updateGprsLocationArgs,
s_sequenceTag, s_updateGprsLocationRes
},
{"sendRoutingInfoForGprs", true, 24, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_sendRoutingInfoForGprsArgs,
s_sequenceTag, s_sendRoutingInfoForGprsRes
},
{"failureReport", true, 25, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_failureReportArgs,
s_sequenceTag, s_failureReportRes
},
{"reset", true, 37, SS7TCAP::NoReport,
s_sequenceTag, s_resetArgs,
s_noTag, 0
},
{"forwardCheckSS-Indication", true, 38, SS7TCAP::NoReport,
s_noTag, 0,
s_noTag, 0
},
{"mt-forwardSM", true, 44, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_mtForwardSMArgs,
s_sequenceTag, s_forwardSMRes
},
{"sendRoutingInfoForSM", true, 45, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_sendRoutingInfoForSMArgs,
s_sequenceTag, s_sendRoutingInfoForSMRes
},
{"mo-forwardSM", true, 46, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_moForwardSMArgs,
s_sequenceTag, s_forwardSMRes
},
{"forwardSM", true, 46, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_forwardSMArgs,
s_noTag, 0
},
{"reportSM-DeliveryStatus", true, 47, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_reportSMDeliveryArgs,
s_sequenceTag, s_reportSMDeliveryRes,
},
{"activateTraceMode", true, 50, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_activateTraceModeArgs,
s_sequenceTag, s_traceModeRes
},
{"deactivateTraceMode", true, 51, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_deactivateTraceModeArgs,
s_sequenceTag, s_traceModeRes
},
{"sendAuthenticationInfo", true, 56, SS7TCAP::SuccessOrFailureReport,
s_noTag, s_sendAuthenticationInfoArgs,
s_noTag, s_sendAuthenticationInfoRes
},
{"restoreData", true, 57, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_restoreDataArgs,
s_sequenceTag, s_restoreDataRes
},
{"sendIMSI", true, 58, SS7TCAP::SuccessOrFailureReport,
s_noTag, s_sendIMSIArgs,
s_noTag, s_sendIMSIRes
},
{"processUnstructuredSS-Request", true, 59, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_unstructuredSSArgs,
s_sequenceTag, s_unstructuredSSRes
},
{"unstructuredSS-Request", true, 60, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_unstructuredSSArgs,
s_sequenceTag, s_unstructuredSSRes
},
{"unstructuredSS-Notify", true, 61, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_unstructuredSSArgs,
s_noTag, 0
},
{"informServiceCentre", true, 63, SS7TCAP::NoReport,
s_sequenceTag, s_informServiceCentreArgs,
s_noTag, 0
},
{"alertServiceCentre", true, 64, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_alertServiceCentreArgs,
s_noTag, 0
},
{"readyForSM", true, 66, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_readyForSMArgs,
s_sequenceTag, s_extensionContainerRes
},
{"purgeMS", true, 67, SS7TCAP::SuccessOrFailureReport,
s_ctxtCstr_3_Tag, s_purgeMSArgs,
s_sequenceTag, s_purgeMSRes
},
{"provideSubscriberInfo", true, 70, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_provideSubscriberInfoArgs,
s_sequenceTag, s_provideSubscriberInfoRes
},
{"anyTimeInterrogation", true, 71, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_anyTimeInterrogationArgs,
s_sequenceTag, s_anyTimeInterrogationRes
},
{"setReportingState", true, 73, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_setReportingStateArgs,
s_sequenceTag, s_setReportingStateRes
},
{"statusReport", true, 74, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_statusReportArgs,
s_sequenceTag, s_statusReportRes
},
{"sendRoutingInfoForLCS", true, 85, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_sendRoutingInfoForLCSArgs,
s_sequenceTag, s_sendRoutingInfoForLCSRes
},
{"", false, 0, -1,
s_noTag, 0,
s_noTag, 0
},
};
static const StringList s_camelCapabOps("initialDP,assistRequestInstructions,establishTemporaryConnection,disconnectForwardConnection,"
"connectToResource,connect,releaseCall,requestReportBCSMEvent,eventReportBCSM,continue,resetTimer,"
"furnishChargingInformation,applyCharging,applyChargingReport,callInformationReport,callInformationRequest,"
"sendChargingInformation,playAnnouncement,promptAndCollectUserInformation,specializedResourceReport,"
"cancel,activityTest,initiateCallAttempt,disconnectLeg,moveLeg,splitLeg,entityReleased,"
"continueWithArgument,disconnectForwardConnectionWithArgument,playTone,callGap");
static const Capability s_camelCapab[] = {
{"Camel", s_camelCapabOps},
{0, s_noOps},
};
static TokenDict s_eventTypeBCSM[] = {
{"collectedInfo", 2},
{"routeSelectFailure", 4},
{"oCalledPartyBusy", 5},
{"oNoAnswer", 6},
{"oAnswer", 7},
{"oDisconnect", 9},
{"oAbandon", 10},
{"termAttemptAuthorized", 12},
{"tBusy", 13},
{"tNoAnswer", 14},
{"tAnswer", 15},
{"tDisconnect", 17},
{"tAbandon", 18},
{"", 0}
};
static TokenDict s_naCICSelectionType[] = {
{"not-indicated", 0x00},
{"subscribed-not-dialed", 0x01},
{"subscribed-and-dialed", 0x02},
{"subscribed-dialing-undeterminded", 0x03},
{"dialed-CIC-not-subscribed", 0x04},
{"", 0}
};
static const Parameter s_naCarrierInformationSeq[] = {
{"naCarrierId", s_ctxtPrim_0_Tag, true, TcapXApplication::TBCD, 0}, //Carrier digits
{"naCICSelectionType", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_naCICSelectionType},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_initialDPArgExtension[] = {
{"naCarrierInformation", s_ctxtCstr_0_Tag, true, TcapXApplication::Sequence, s_naCarrierInformationSeq},
{"gmscAddress", s_ctxtPrim_1_Tag, true, TcapXApplication::AddressString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static Parameter s_bearerCap[] = {
{"bearerCap", s_ctxtPrim_0_Tag, false, TcapXApplication::UserServiceInfo, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_initialDPArgs[] = {
{"serviceKey", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"calledPartyNumber", s_ctxtPrim_2_Tag, true, TcapXApplication::CalledPartyNumber, 0},
{"callingPartyNumber", s_ctxtPrim_3_Tag, true, TcapXApplication::CallingPartyNumber, 0},
{"callingPartysCategory", s_ctxtPrim_5_Tag, true, TcapXApplication::Enumerated, s_category},
// TODO decode iPSSPCapabilities according to ETSI TS 101 046 V7.1.0 (2000-07) page 42
{"iPSSPCapabilities", s_ctxtPrim_8_Tag, true, TcapXApplication::HexString, 0}, // might need further decoding
{"locationNumber", s_ctxtPrim_10_Tag, true, TcapXApplication::LocationNumber, 0},
{"originalCalledPartyID", s_ctxtPrim_12_Tag, true, TcapXApplication::OriginalCalledNumber, 0},
{"extensions", s_ctxtCstr_15_Tag, true, TcapXApplication::HexString, 0},
{"highLayerCompatibility", s_ctxtPrim_23_Tag, true, TcapXApplication::HiLayerCompat, 0}, // might need further decoding
{"additionalCallingPartyNumber", s_ctxtPrim_25_Tag, true, TcapXApplication::TBCD, 0}, // not sure about this either
{"bearerCapability", s_ctxtCstr_27_Tag, true, TcapXApplication::Choice, s_bearerCap},
{"eventTypeBCSM", s_ctxtPrim_28_Tag, true, TcapXApplication::Enumerated, s_eventTypeBCSM},
{"redirectingPartyID", s_ctxtPrim_29_Tag, true, TcapXApplication::RedirectingNumber, 0},
{"redirectionInformation", s_ctxtPrim_30_Tag, true, TcapXApplication::RedirectionInformation, 0},
{"imsi", s_ctxtPrim_50_Tag, true, TcapXApplication::TBCD, 0},
{"subscriberState", s_ctxtCstr_51_Tag, true, TcapXApplication::Choice, s_subscriberState},
{"locationInformation", s_ctxtCstr_52_Tag, true, TcapXApplication::Sequence, s_locationInformation},
{"ext-basicServiceCode", s_ctxtCstr_53_Tag, true, TcapXApplication::Choice, s_basicServiceCode},
{"callReferenceNumber", s_ctxtPrim_54_Tag, true, TcapXApplication::HexString, 0},
{"mscAddress", s_ctxtPrim_55_Tag, true, TcapXApplication::AddressString, 0},
{"calledPartyBCDNumber", s_ctxtPrim_56_Tag, true, TcapXApplication::AddressString, 0}, //should be checked
{"timeAndTimezone", s_ctxtPrim_57_Tag, true, TcapXApplication::TBCD, 0},//might need special decoding
{"gsm-ForwardingPending", s_ctxtPrim_58_Tag, true, TcapXApplication::Null, 0},
{"initialDPArgExtension", s_ctxtCstr_59_Tag, true, TcapXApplication::Sequence, s_initialDPArgExtension},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_monitorMode[] = {
{"interrupted", 0x00},
{"notifyAndContinue", 0x01},
{"transparent", 0x02},
{"", 0},
};
static const TokenDict s_legType[] = {
{"leg1", 0x01},
{"leg2", 0x02},
{"", 0},
};
static const Parameter s_legID[] = {
{"sendingSideID", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_legType},
{"receivingSideID", s_ctxtPrim_1_Tag, false, TcapXApplication::Enumerated, s_legType},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_DPSpecificCriteria[] = {
{"applicationTimer",s_ctxtPrim_1_Tag, false, TcapXApplication::Integer, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_bcsmEventSeq[] = {
{"eventTypeBCSM", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_eventTypeBCSM},
{"monitorMode", s_ctxtPrim_1_Tag, false, TcapXApplication::Enumerated, s_monitorMode},
{"legID", s_ctxtCstr_2_Tag, true, TcapXApplication::Choice, s_legID},
{"dPSpecificCriteria", s_ctxtCstr_30_Tag,true, TcapXApplication::Choice, s_DPSpecificCriteria},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_bcsmEvent[] = {
{"bcsmEvent", s_sequenceTag, false, TcapXApplication::Sequence, s_bcsmEventSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_requestReportBCSMEventArgs[] = {
{"bcsmEvents", s_ctxtCstr_0_Tag, false, TcapXApplication::SequenceOf, s_bcsmEvent},
{"extensions", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_receivingSideID[] = {
{"receivingSideID", s_ctxtPrim_1_Tag, false, TcapXApplication::Enumerated, s_legType},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_failureCause[] = {
// failureCause := Cause (should find encoding, for now treated as hex string)
{"failureCause", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_busyCause[] = {
// busyCause := Cause (should find encoding, for now treated as hex string)
{"busyCause", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_releaseCause[] = {
// releaseCause := Cause (should find encoding, for now treated as hex string)
{"releaseCause", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_tNoAsnwerInfo[] = {
{"callForwarded", s_ctxtPrim_50_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_tBusyInfo[] = {
// busyCause := Cause (should find encoding, for now treated as hex string)
{"busyCause", s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
{"callForwarded", s_ctxtPrim_50_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_eventSpecificInformationBCSM[] = {
{"routeSelectFailureSpecificInfo", s_ctxtCstr_2_Tag, false, TcapXApplication::Sequence, s_failureCause},
{"oCalledPartyBusySpecificInfo", s_ctxtCstr_3_Tag, false, TcapXApplication::Sequence, s_busyCause},
{"oNoAnswerSpecificInfo", s_ctxtCstr_4_Tag, false, TcapXApplication::Sequence, 0},
{"oAnswerSpecificInfo", s_ctxtCstr_5_Tag, false, TcapXApplication::Sequence, 0},
{"oDisconnectSpecificInfo", s_ctxtCstr_7_Tag, false, TcapXApplication::Sequence, s_releaseCause},
{"tBusySpecificInfo", s_ctxtCstr_8_Tag, false, TcapXApplication::Sequence, s_tBusyInfo},
{"tNoAnswerSpecificInfo", s_ctxtCstr_9_Tag, false, TcapXApplication::Sequence, s_tNoAsnwerInfo},
{"tAnswerSpecificInfo", s_ctxtCstr_10_Tag, false, TcapXApplication::Sequence, 0},
{"tDisconnectSpecificInfo", s_ctxtCstr_12_Tag, false, TcapXApplication::Sequence, s_releaseCause},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_messageType[] = {
{"request", 0x00},
{"notification", 0x01},
{"", 0},
};
static const Parameter s_miscCallInfoSeq[] = {
{"messageType", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_messageType},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_eventReportBCSMArgs[] = {
{"eventTypeBCSM", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_eventTypeBCSM},
{"eventSpecificInformationBCSM", s_ctxtCstr_2_Tag, true, TcapXApplication::Choice, s_eventSpecificInformationBCSM},
{"legID", s_ctxtCstr_3_Tag, true, TcapXApplication::Choice, s_receivingSideID},
{"miscCallInfo", s_ctxtCstr_4_Tag, false, TcapXApplication::Sequence, s_miscCallInfoSeq},
{"extensions", s_ctxtCstr_5_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_calledPartyNumber[] = {
{"calledPartyNumber", s_hexTag, false, TcapXApplication::CalledPartyNumber, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_genericNumber[] = {
{"genericNumber", s_hexTag, false, TcapXApplication::GenericNumber, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_naInfoSeq[] = {
{"naCarrierInformation", s_ctxtCstr_0_Tag, true, TcapXApplication::Sequence, s_naCarrierInformationSeq},
// NA Oli information takes the same value as defined in ANSI ISUP T1.113
{"naOliInfo", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"naChargeNumber", s_ctxtPrim_2_Tag, true, TcapXApplication::ChargeNumber, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_connectArgs[] = {
{"destinationRoutingAddress", s_ctxtCstr_0_Tag, false, TcapXApplication::SequenceOf, s_calledPartyNumber},
//alertingPattern decoded as hex string, encoding in GSM 09.02 (ref. 14)
{"alertingPattern", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"originalCalledPartyID", s_ctxtPrim_6_Tag, true, TcapXApplication::OriginalCalledNumber, 0},
{"extensions", s_ctxtCstr_10_Tag, true, TcapXApplication::HexString, 0},
{"callingPartysCategory", s_ctxtPrim_28_Tag, true, TcapXApplication::Enumerated, s_category},
{"redirectingPartyID", s_ctxtPrim_29_Tag, true, TcapXApplication::RedirectingNumber, 0},
{"redirectionInformation", s_ctxtPrim_30_Tag, true, TcapXApplication::RedirectionInformation, 0},
{"genericNumbers", s_ctxtCstr_14_Tag, true, TcapXApplication::SetOf, s_genericNumber},
{"suppressionOfAnnouncement", s_ctxtPrim_55_Tag, true, TcapXApplication::Null, 0},
{"oCSIApplicable", s_ctxtPrim_56_Tag, true, TcapXApplication::Null, 0},
{"na-Info", s_ctxtCstr_57_Tag, true, TcapXApplication::Sequence, s_naInfoSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_releaseCallArgs[] = {
// TODO - decode Cause (ETS 300 356-1 [3] Cause and Location values refer to Q.850).
{"cause", s_hexTag, false, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_assistRequestInstructionsArgs[] = {
// Defined as Digits - see for encoding ETS 300 356-1 [3] Generic Number
{"correlationID", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
// ETSI TS 101 046 - GSM CAP specification (CAMEL) page 42 for further decoding
{"iPSSPCapabilities", s_ctxtPrim_2_Tag, false, TcapXApplication::HexString, 0},
{"extensions", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_bothwayThroughConnectionInd[] = {
{"bothwayPathRequired", 0x00},
{"bothwayPathNotRequired", 0x01},
{"", 0},
};
static const Parameter s_serviceInteractionIndicatorsTwo[] = {
// FROM CS2-datatypes { ccitt(0) identified-organization(4) etsi(0) inDomain(1)
// in-network(1) CS2(20) modules(0) in-cs2-datatypes (0) version1(0)}
{"bothwayThroughConnectionInd", s_ctxtPrim_2_Tag, true, TcapXApplication::Enumerated, s_bothwayThroughConnectionInd},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_establishTemporaryConnectionArgs[] = {
//Digits - see for encoding ETS 300 356-1 [3] , definde ETSI TS 101 046 - GSM CAP specification (CAMEL) page 42
{"assistingSSPIPRoutingAddress", s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
// Defined as Digits - see for encoding ETS 300 356-1 [3] Generic Number
{"correlationID", s_ctxtPrim_1_Tag, true, TcapXApplication::TBCD, 0},
{"scfID", s_ctxtPrim_3_Tag, true, TcapXApplication::HexString, 0},
{"extensions", s_ctxtCstr_4_Tag, true, TcapXApplication::HexString, 0},
{"serviceInteractionIndicatorsTwo",s_ctxtCstr_7_Tag, true, TcapXApplication::Sequence, s_serviceInteractionIndicatorsTwo},
{"na-Info", s_ctxtCstr_50_Tag,true, TcapXApplication::Sequence, s_naInfoSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_resourceAddress[] = {
{"ipRoutingAddress", s_ctxtPrim_0_Tag, false, TcapXApplication::CalledPartyNumber, 0},
{"none", s_ctxtPrim_3_Tag, false, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_connectToResourceArgs[] = {
{"resourceAddress", s_noTag, false, TcapXApplication::Choice, s_resourceAddress},
{"extensions", s_ctxtCstr_4_Tag, true, TcapXApplication::HexString, 0},
{"serviceInteractionIndicatorsTwo",s_ctxtCstr_7_Tag, true, TcapXApplication::Sequence, s_serviceInteractionIndicatorsTwo},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_timerID[] = {
{"tssf", 0x00},
{"", 0x01},
};
static const Parameter s_resetTimerArgs[] = {
{"timerID", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_timerID},
{"timervalue", s_ctxtPrim_1_Tag, false, TcapXApplication::Integer, 0},
{"extensions", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_sendingSideID[] = {
{"sendingSideID", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_legType},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_fCIBCCCAMELsequenceSeq[] = {
{"freeFormatData", s_ctxtPrim_0_Tag, false, TcapXApplication::HexString, 0},
{"partyToCharge", s_ctxtCstr_1_Tag, false, TcapXApplication::Choice, s_sendingSideID},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_fCIBillingChargingCharacteristicsChoice[] = {
{"fCIBCCCAMELsequence1", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_fCIBCCCAMELsequenceSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_FCIBillingChargingCharacteristics[] = {
{"fCIBillingChargingCharacteristics", s_hexTag, false, TcapXApplication::Choice, s_fCIBillingChargingCharacteristicsChoice},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_releaseIfdurationExceeded[] = {
{"tone", s_boolTag, false, TcapXApplication::Bool, 0},
{"extensions", s_ctxtCstr_10_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_timeDuratinChargingSeq[] = {
{"maxCallPeriodDuration", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"releaseIfdurationExceeded", s_ctxtCstr_1_Tag, true, TcapXApplication::Sequence, s_releaseIfdurationExceeded},
{"tariffSwitchInterval", s_ctxtPrim_2_Tag, true, TcapXApplication::Integer, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_aChBillingChargingCharacteristics[] = {
{"timeDurationCharging", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_timeDuratinChargingSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_applyChargingArgs[] = {
{"aChBillingChargingCharacteristics", s_ctxtPrim_0_Tag, false, TcapXApplication::Choice, s_aChBillingChargingCharacteristics},
{"partyToCharge", s_ctxtCstr_2_Tag, false, TcapXApplication::Choice, s_sendingSideID},
{"extensions", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString,0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_timeIfTariffSwitchSeq[] = {
{"timeSinceTariffSwitch", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"tariffSwitchInterval", s_ctxtPrim_1_Tag, true, TcapXApplication::Integer, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_timeInformation[] = {
{"timeIfNoTariffSwitch", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"timeIfTariffSwitch", s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_timeIfTariffSwitchSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_timeDurationChargingResSeq[] = {
{"partyToCharge", s_ctxtCstr_0_Tag, false, TcapXApplication::Choice, s_receivingSideID},
{"timeInformation", s_ctxtCstr_1_Tag, false, TcapXApplication::Choice, s_timeInformation},
{"callActive", s_ctxtPrim_2_Tag, false, TcapXApplication::Bool, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_callResultChoice[] = {
{"timeDurationChargingResult", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_timeDurationChargingResSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_callResult[] = {
{"callResult", s_hexTag, false, TcapXApplication::Choice, s_callResultChoice},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_requestedInformationType[] = {
{"callAttemptElapsedTime", 0x00},
{"callStopTime", 0x01},
{"callConnectedElapsedTime", 0x02},
{"releaseCause", 0x1e},
{"", 0xff},
};
static const Parameter s_requestedInformationValue[] = {
{"callAttemptElapsedTimeValue", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"callStopTimeValue", s_ctxtPrim_1_Tag, false, TcapXApplication::TBCD, 0},
{"callConnectedElapsedTimeValue",s_ctxtPrim_2_Tag, false, TcapXApplication::Integer, 0},
{"releaseCauseValue", s_ctxtPrim_30_Tag,false, TcapXApplication::HexString,0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_requestedInformationSeq[] = {
{"requestedInformationType", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_requestedInformationType},
{"requestedInformationValue", s_ctxtCstr_1_Tag, false, TcapXApplication::Choice, s_requestedInformationValue},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_requestedInformation[] = {
{"requestedInformation", s_sequenceTag, false, TcapXApplication::Sequence, s_requestedInformationSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_callInformationArgs[] = {
{"requestedInformationList", s_ctxtCstr_0_Tag, false,TcapXApplication::SequenceOf, s_requestedInformation},
{"extensions", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"legID", s_ctxtCstr_3_Tag, true, TcapXApplication::Choice, s_receivingSideID},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_requestedInfoType[] = {
{"requestedInformationType", s_enumTag, false, TcapXApplication::Enumerated, s_requestedInformationType},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_callInformationRequestArgs[] = {
{"requestedInformationTypeList", s_ctxtCstr_0_Tag, false,TcapXApplication::SequenceOf, s_requestedInfoType},
{"extensions", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"legID", s_ctxtCstr_3_Tag, true, TcapXApplication::Choice, s_sendingSideID},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_CAIGSM0224Seq[] = {
{"e1", s_ctxtPrim_0_Tag, true, TcapXApplication::Integer, 0},
{"e2", s_ctxtPrim_1_Tag, true, TcapXApplication::Integer, 0},
{"e3", s_ctxtPrim_2_Tag, true, TcapXApplication::Integer, 0},
{"e4", s_ctxtPrim_3_Tag, true, TcapXApplication::Integer, 0},
{"e5", s_ctxtPrim_4_Tag, true, TcapXApplication::Integer, 0},
{"e6", s_ctxtPrim_5_Tag, true, TcapXApplication::Integer, 0},
{"e7", s_ctxtPrim_6_Tag, true, TcapXApplication::Integer, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_AOCSubsequentSeq[] = {
{"cAI-GSM0224", s_ctxtCstr_0_Tag, false,TcapXApplication::Sequence, s_CAIGSM0224Seq},
{"tariffSwitchInterval", s_ctxtPrim_1_Tag, true, TcapXApplication::Integer, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_AOCBeforeAnswerSeq[] = {
{"aOCInitial", s_ctxtCstr_0_Tag, false,TcapXApplication::Sequence, s_CAIGSM0224Seq},
{"aOCSubsequent", s_ctxtCstr_1_Tag, true, TcapXApplication::Sequence, s_AOCSubsequentSeq},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_sCIBillingChargingCharacteristics[] = {
{"aOCBeforeAnswer", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_AOCBeforeAnswerSeq},
{"aOCAfterAnswer", s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_AOCSubsequentSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_sendChargingInformationArgs[] = {
{"sCIBillingChargingCharacteristics", s_ctxtPrim_0_Tag, false, TcapXApplication::Choice, s_sCIBillingChargingCharacteristics},
{"partyToCharge", s_ctxtCstr_1_Tag, false, TcapXApplication::Choice, s_sendingSideID},
{"extensions", s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_textSeq[] = {
{"messageContent", s_ctxtPrim_0_Tag, false, TcapXApplication::AppString, 0},
{"attributes", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_elementaryMessageID[] = {
{"elementaryMessageID", s_intTag, false, TcapXApplication::Integer, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_variablePartChoice[] = {
{"integer", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"number", s_ctxtPrim_1_Tag, false, TcapXApplication::TBCD, 0},
{"time", s_ctxtPrim_2_Tag, false, TcapXApplication::TBCD, 0},
{"date", s_ctxtPrim_3_Tag, false, TcapXApplication::TBCD, 0},
{"price", s_ctxtPrim_4_Tag, false, TcapXApplication::TBCD, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_variablePart[] = {
{"variablePart", s_noTag, false, TcapXApplication::Choice, s_variablePartChoice},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_variableMessageSeq[] = {
{"elementaryMessageID", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"variableParts", s_ctxtCstr_1_Tag, false, TcapXApplication::SequenceOf, s_variablePart},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_messageID[] = {
{"elementaryMessageID", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"text", s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_textSeq},
{"elementaryMessageIDs",s_ctxtCstr_29_Tag,false, TcapXApplication::SequenceOf, s_elementaryMessageID},
{"variableMessage", s_ctxtCstr_30_Tag,false, TcapXApplication::Sequence, s_variableMessageSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_inbandInfoSeq[] = {
{"messageID", s_ctxtCstr_0_Tag, false,TcapXApplication::Choice, s_messageID},
{"numberOfRepetitions", s_ctxtPrim_1_Tag, true, TcapXApplication::Integer, 0},
{"duration", s_ctxtPrim_2_Tag, true, TcapXApplication::Integer, 0},
{"interval", s_ctxtPrim_3_Tag, true, TcapXApplication::Integer, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const Parameter s_toneSeq[] = {
{"toneID", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"duration", s_ctxtPrim_1_Tag, true, TcapXApplication::Integer, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_informationToSend[] = {
{"inbandInfo", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_inbandInfoSeq},
{"tone", s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_toneSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_playAnnouncementArgs[] = {
{"informationToSend", s_ctxtCstr_0_Tag, false, TcapXApplication::Choice, s_informationToSend},
{"disconnectFromIPForbidden", s_ctxtPrim_1_Tag, false, TcapXApplication::Bool, 0},
{"requestAnnouncementComplete", s_ctxtPrim_2_Tag, false, TcapXApplication::Bool, 0},
{"extensions", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString,0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_errorTreatment[] = {
{"stdErrorAndInfo", 0x00},
{"help", 0x01},
{"repeatPrompt", 0x02},
{"", 0xff},
};
static const Parameter s_collectedInfoSeq[] = {
{"minimumNbOfDigits", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"maximumNbOfDigits", s_ctxtPrim_1_Tag, false, TcapXApplication::Integer, 0},
{"endOfReplyDigit", s_ctxtPrim_2_Tag, true, TcapXApplication::HexString, 0},
{"cancelDigit", s_ctxtPrim_3_Tag, true, TcapXApplication::HexString, 0},
{"startDigit", s_ctxtPrim_4_Tag, true, TcapXApplication::HexString, 0},
{"firstDigitTimeOut", s_ctxtPrim_5_Tag, false, TcapXApplication::Integer, 0},
{"interDigitTimeOut", s_ctxtPrim_6_Tag, false, TcapXApplication::Integer, 0},
{"errorTreatment", s_ctxtPrim_7_Tag, false, TcapXApplication::Enumerated,s_errorTreatment},
{"interruptableAnnInd", s_ctxtPrim_8_Tag, false, TcapXApplication::Bool, 0},
{"voiceInformation", s_ctxtPrim_9_Tag, false, TcapXApplication::Bool, 0},
{"voiceBack", s_ctxtPrim_10_Tag, false, TcapXApplication::Bool, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_collectedInfo[] = {
{"collectedDigits", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_collectedInfoSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_promptAndCollectUserInformationArgs[] = {
{"collectedInfo", s_ctxtCstr_0_Tag, false, TcapXApplication::Choice, s_collectedInfo},
{"disconnectFromIPForbidden", s_ctxtPrim_1_Tag, false, TcapXApplication::Bool, 0},
{"informationToSend", s_ctxtCstr_2_Tag, true, TcapXApplication::Choice, s_informationToSend},
{"extensions", s_ctxtCstr_3_Tag, true, TcapXApplication::HexString,0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_specializedResourceReportArgs[] = {
{"specializedResourceReportArgs", s_nullTag, false, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_cancelChoice[] = {
{"invokeID", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
{"allRequests", s_ctxtPrim_1_Tag, false, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_cancelArgs[] = {
{"cancelArg", s_noTag, false, TcapXApplication::Choice, s_cancelChoice},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Operation s_camelOps[] = {
{"initialDP", true, 0, SS7TCAP::FailureOnlyReport,
s_sequenceTag, s_initialDPArgs,
s_noTag, 0
},
{"assistRequestInstructions", true, 16, SS7TCAP::FailureOnlyReport,
s_sequenceTag, s_assistRequestInstructionsArgs,
s_noTag, 0
},
{"establishTemporaryConnection", true, 17, SS7TCAP::FailureOnlyReport,
s_sequenceTag, s_establishTemporaryConnectionArgs,
s_noTag, 0
},
{"disconnectForwardConnection", true, 18, SS7TCAP::FailureOnlyReport,
s_noTag, 0,
s_noTag, 0
},
{"connectToResource", true, 19, SS7TCAP::FailureOnlyReport,
s_sequenceTag, s_connectToResourceArgs,
s_noTag, 0
},
{"connect", true, 20, SS7TCAP::FailureOnlyReport,
s_sequenceTag, s_connectArgs,
s_noTag, 0
},
{"releaseCall", true, 22, SS7TCAP::NoReport,
s_noTag, s_releaseCallArgs,
s_noTag, 0
},
{"requestReportBCSMEvent", true, 23, SS7TCAP::FailureOnlyReport,
s_sequenceTag, s_requestReportBCSMEventArgs,
s_noTag, 0
},
{"eventReportBCSM", true, 24, SS7TCAP::NoReport,
s_sequenceTag, s_eventReportBCSMArgs,
s_noTag, 0
},
{"continue", true, 31, SS7TCAP::NoReport,
s_noTag, 0,
s_noTag, 0
},
{"resetTimer", true, 33, SS7TCAP::FailureOnlyReport,
s_sequenceTag, s_resetTimerArgs,
s_noTag, 0
},
{"furnishChargingInformation", true, 34, SS7TCAP::FailureOnlyReport,
s_noTag, s_FCIBillingChargingCharacteristics,
s_noTag, 0
},
{"applyCharging", true, 35, SS7TCAP::FailureOnlyReport,
s_sequenceTag, s_applyChargingArgs,
s_noTag, 0
},
{"applyChargingReport", true, 36, SS7TCAP::FailureOnlyReport,
s_noTag, s_callResult,
s_noTag, 0
},
{"callInformationReport", true, 44, SS7TCAP::NoReport,
s_sequenceTag, s_callInformationArgs,
s_noTag, 0
},
{"callInformationRequest", true, 45, SS7TCAP::FailureOnlyReport,
s_sequenceTag, s_callInformationRequestArgs,
s_noTag, 0
},
{"sendChargingInformation", true, 46, SS7TCAP::FailureOnlyReport,
s_sequenceTag, s_sendChargingInformationArgs,
s_noTag, 0
},
{"playAnnouncement", true, 47, SS7TCAP::FailureOnlyReport,
s_sequenceTag, s_playAnnouncementArgs,
s_noTag, 0
},
{"promptAndCollectUserInformation", true, 48, SS7TCAP::SuccessOrFailureReport,
s_sequenceTag, s_promptAndCollectUserInformationArgs,
s_noTag, 0
},
{"specializedResourceReport", true, 49, SS7TCAP::NoReport,
s_noTag, 0,
s_noTag, 0
},
{"cancel", true, 53, SS7TCAP::FailureOnlyReport,
s_noTag, s_cancelChoice,
s_noTag, 0
},
{"activityTest", true, 55, SS7TCAP::SuccessOnlyReport,
s_noTag, 0,
s_noTag, 0
},
{"", false, 0, -1,
s_noTag, 0,
s_noTag, 0
},
};
static const TokenDict s_unknownSubscriberDiagnostic[] = {
{"imsiUnknown", 0},
{"gprsSubscriptionUnknown", 1},
{"npdbMismatch", 2},
{0, 0},
};
static const TokenDict s_roamingNotAllowedCause[] = {
{"plmnRoamingNotAllowed", 0},
{"operatorDeterminedBarring", 3},
{0, 0},
};
static const TokenDict s_additionalRoamingNotAllowedCause[] = {
{"supportedRAT-TypesNotAllowed", 0},
{0, 0},
};
static const TokenDict s_absentSubscriberReason[] = {
{"imsiDetach", 0 },
{"restrictedArea", 1 },
{"noPageResponse", 2 },
{"purgedMS", 3 },
{"mtRoamingRetry", 4 },
{0, 0},
};
static const TokenDict s_smDeliveryFailureCause[] = {
{"memoryCapacityExceeded", 0 },
{"equipmentProtocolError", 1 },
{"equipmentNotSM-Equipped", 2 },
{"unknownServiceCentre", 3 },
{"sc-Congestion", 4 },
{"invalidSME-Address", 5 },
{"subscriberNotSC-Subscriber", 6 },
{0, 0},
};
static const TokenDict s_networkResource[] = {
{"plmn", 0 },
{"hlr", 1 },
{"vlr", 2 },
{"pvlr", 3 },
{"controllingMSC", 4 },
{"vmsc", 5 },
{"eir", 6 },
{"rss", 7 },
{0, 0},
};
static const TokenDict s_additionalNetworkResource[] = {
{"sgsn", 0},
{"ggsn", 1},
{"gmlc", 2},
{"gsmSCF", 3},
{"nplr", 4},
{"auc", 5},
{"ue", 6},
{"mme", 7},
{0, 0},
};
static const TokenDict s_failureCauseParam[] = {
{"limitReachedOnNumberOfConcurrentLocationRequests", 0},
{0, 0},
};
static const TokenDict s_unauthorizedLcscDiag[] = {
{"noAdditionalInformation", 0},
{"clientNotInMSPrivacyExceptionList", 1},
{"callToClientNotSetup", 2},
{"privacyOverrideNotApplicable", 3},
{"disallowedByLocalRegulatoryRequirements", 4},
{"unauthorizedPrivacyClass", 5},
{"unauthorizedCallSessionUnrelatedExternalClient", 6},
{"unauthorizedCallSessionRelatedExternalClient", 7},
{0, 0},
};
static const TokenDict s_positionMethodFailureDiag[] = {
{"congestion", 0},
{"insufficientResources", 1},
{"insufficientMeasurementData", 2},
{"inconsistentMeasurementData", 3},
{"locationProcedureNotCompleted", 4},
{"locationProcedureNotSupportedByTargetMS", 5},
{"qoSNotAttainable", 6},
{"positionMethodNotAvailableInNetwork", 7},
{"positionMethodNotAvailableInLocationArea", 8},
{0, 0},
};
static const Parameter s_extensibleSystemFailure[] = {
{"networkResource", s_enumTag, true, TcapXApplication::Enumerated, s_networkResource},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"additionalNetworkResource", s_ctxtPrim_0_Tag,true, TcapXApplication::Enumerated, s_additionalNetworkResource},
{"failureCauseParam", s_ctxtPrim_1_Tag,true, TcapXApplication::Enumerated, s_failureCauseParam},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_systemFailure[] = {
{"networkResource", s_enumTag, false, TcapXApplication::Enumerated, s_networkResource},
{"extensibleSystemFailure", s_sequenceTag, false, TcapXApplication::Sequence, s_extensibleSystemFailure},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_pwRegistrationFailureCause[] = {
{"undetermined", 0 },
{"invalidFormat", 1 },
{"newPasswordsMismatch", 2 },
{0, 0},
};
static const TokenDict s_callBarringCause[] = {
{"barringServiceActive", 0 },
{"operatorBarring", 1 },
{0, 0},
};
static const TokenDict s_cugRejectCause[] = {
{"incomingCallsBarredWithinCUG", 0 },
{"subscriberNotMemberOfCUG", 1 },
{"requestedBasicServiceViolatesCUG-Constraints", 5 },
{"calledPartySS-InteractionViolation", 7 },
{0, 0},
};
static const Parameter s_extensibleCallBarredParam[] = {
{"callBarringCause", s_enumTag, true, TcapXApplication::Enumerated, s_callBarringCause},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"unauthorisedMessageOriginator", s_ctxtPrim_1_Tag,true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_cugRejectErr[] = {
{"cug-RejectCause", s_enumTag, true, TcapXApplication::Enumerated, s_cugRejectCause},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_unknownSubscriberErr[] = {
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"unknownSubscriberDiagnostic", s_enumTag, true, TcapXApplication::Enumerated, s_unknownSubscriberDiagnostic},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_absentsubscriberSMErr[] = {
{"absentSubscriberDiagnosticSM", s_intTag, true, TcapXApplication::Integer, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"additionalAbsentSubscriberDiagnosticSM", s_intTag, true, TcapXApplication::Integer, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_roamingNotAllowedErr[] = {
{"roamingNotAllowedCause", s_enumTag, true, TcapXApplication::Enumerated, s_roamingNotAllowedCause},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"additionalRoamingNotAllowedCause", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_additionalRoamingNotAllowedCause},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_callBarredErr[] = {
{"callBarringCause", s_enumTag, false, TcapXApplication::Enumerated, s_callBarringCause},
{"extensibleCallBarredParam", s_sequenceTag, false, TcapXApplication::Sequence, s_extensibleCallBarredParam},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_ssErrorStatusErr[] = {
{"ss-Status", s_hexTag, false, TcapXApplication::Flags, s_ssStatus},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_ssIncompatibilityErr[] = {
{"ss-Code", s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_SSCode},
{"basicService", s_noTag, true, TcapXApplication::Choice, s_basicServiceCode},
{"ss-Status", s_ctxtPrim_4_Tag, true, TcapXApplication::Flags, s_ssStatus},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_facilityNotSupportedErr[] = {
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"shapeOfLocationEstimateNotSupported", s_ctxtPrim_0_Tag, true, TcapXApplication::Null, 0},
{"neededLcsCapabilityNotSupportedInServingNode", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_absentSubscriberErr[] = {
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"absentSubscriberReason", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_absentSubscriberReason},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_subscriberBusyMtSmsErr[] = {
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"gprsConnectionSuspended", s_nullTag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_smDeliveryFailureErr[] = {
{"sm-EnumeratedDeliveryFailureCause", s_enumTag, true, TcapXApplication::Enumerated, s_smDeliveryFailureCause},
{"diagnosticInfo", s_hexTag, true, TcapXApplication::HexString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_pwRegistrationFailureErr[] = {
{"pw-RegistrationFailureCause", s_enumTag, true, TcapXApplication::Enumerated, s_pwRegistrationFailureCause},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_busySubscriberErr[] = {
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"ccbs-Possible", s_ctxtPrim_0_Tag, true, TcapXApplication::Null, 0},
{"ccbs-Busy", s_ctxtPrim_1_Tag, true, TcapXApplication::Null, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_unauthorizedLcscErr[] = {
{"unauthorizedLCSClient-Diagnostic", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_unauthorizedLcscDiag},
{"extensionContainer", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_positionMethodFailureErr[] = {
{"positionMethodFailure-Diagnostic", s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_positionMethodFailureDiag},
{"extensionContainer", s_ctxtPrim_1_Tag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Operation s_mapErrors[] = {
{"unknownSubscriber", true, 1, -1,
s_sequenceTag, s_unknownSubscriberErr,
s_noTag, 0
},
{"unknownMSC", true, 3, -1,
s_noTag, 0,
s_noTag, 0
},
{"unidentifiedSubscriber", true, 5, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"absentsubscriberSM", true, 6, -1,
s_sequenceTag, s_absentsubscriberSMErr,
s_noTag, 0
},
{"unknownEquipment", true, 7, -1,
s_noTag, 0,
s_noTag, 0
},
{"roamingNotAllowed", true, 8, -1,
s_sequenceTag, s_roamingNotAllowedErr,
s_noTag, 0
},
{"illegalSubscriber", true, 9, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"bearerServiceNotProvisioned", true, 10, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"teleserviceNotProvisioned", true, 11, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"illegalEquipment", true, 12, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"callBarred", true, 13, -1,
s_noTag, s_callBarredErr,
s_noTag, 0
},
{"forwardingViolation", true, 14, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"cug-Reject", true, 15, -1,
s_sequenceTag, s_cugRejectErr,
s_noTag, 0
},
{"illegalSS-Operation", true, 16, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"ss-ErrorStatus", true, 17, -1,
s_noTag, s_ssErrorStatusErr,
s_noTag, 0
},
{"ss-NotAvailable", true, 18, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"ss-SubscriptionViolation", true, 19, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"ss-Incompatibility", true, 20, -1,
s_sequenceTag, s_ssIncompatibilityErr,
s_noTag, 0
},
{"facilityNotSupported", true, 21, -1,
s_sequenceTag, s_facilityNotSupportedErr,
s_noTag, 0
},
{"ongoingGroupCall", true, 22, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"noHandoverNumberAvailable", true, 25, -1,
s_noTag, 0,
s_noTag, 0
},
{"subsequentHandoverFailure", true, 26, -1,
s_noTag, 0,
s_noTag, 0
},
{"absentSubscriber", true, 27, -1,
s_sequenceTag, s_absentSubscriberErr,
s_noTag, 0
},
{"incompatibleTerminal", true, 28, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"shortTermDenial", true, 29, -1,
s_sequenceTag, 0,
s_noTag, 0
},
{"longTermDenial", true, 30, -1,
s_sequenceTag, 0,
s_noTag, 0
},
{"subscriberBusyForMT-SMS", true, 31, -1,
s_sequenceTag, s_subscriberBusyMtSmsErr,
s_noTag, 0
},
{"sm-DeliveryFailure", true, 32, -1,
s_sequenceTag, s_smDeliveryFailureErr,
s_noTag, 0
},
{"messageWaitingListFull", true, 33, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"systemFailure", true, 34, -1,
s_noTag, s_systemFailure,
s_noTag, 0
},
{"dataMissing", true, 35, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"unexpectedDataValue", true, 36, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"pw-RegistrationFailure", true, 37, -1,
s_noTag, s_pwRegistrationFailureErr,
s_noTag, 0
},
{"negativePW-Check", true, 38, -1,
s_noTag, 0,
s_noTag, 0
},
{"noRoamingNumberAvailable", true, 39, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"tracingBufferFull", true, 40, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"targetCellOutsideGroupCallArea", true, 42, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"numberOfPW-AttemptsViolation", true, 43, -1,
s_noTag, 0,
s_noTag, 0
},
{"numberChanged", true, 44, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"busySubscriber", true, 45, -1,
s_sequenceTag, s_busySubscriberErr,
s_noTag, 0
},
{"noSubscriberReply", true, 46, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"forwardingFailed", true, 47, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"or-NotAllowed", true, 48, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"ati-NotAllowed", true, 49, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"noGroupCallNumberAvailable", true, 50, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"resourceLimitation", true, 51, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"unauthorizedRequestingNetwork", true, 52, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"unauthorizedLCSClient", true, 53, -1,
s_sequenceTag, s_unauthorizedLcscErr,
s_noTag, 0
},
{"positionMethodFailure", true, 54, -1,
s_sequenceTag, s_positionMethodFailureErr,
s_noTag, 0
},
{"unknownOrUnreachableLCSClient", true, 58, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"mm-EventNotSupported", true, 59, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"atsi-NotAllowed", true, 60, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"atm-NotAllowed", true, 61, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"informationNotAvailable", true, 62, -1,
s_sequenceTag, s_extensionContainerRes,
s_noTag, 0
},
{"unknownAlphabet", true, 71, -1,
s_noTag, 0,
s_noTag, 0
},
{"ussd-Busy", true, 72, -1,
s_noTag, 0,
s_noTag, 0
},
{"", false, 0, -1,
s_noTag, 0,
s_noTag, 0
},
};
static const TokenDict s_problemEnum[] = {
{"unknownOperation", 0x00},
{"tooLate", 0x01},
{"operationNotCancellable", 0x02},
{"", 0xff},
};
static const Parameter s_cancelFailedErr[] = {
{"problem", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_problemEnum},
{"operation", s_ctxtPrim_1_Tag, false, TcapXApplication::Integer, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_requestedInfoEnum[] = {
{"unknownRequestedInfo", 0x01},
{"requestedInfoNotAvailable", 0x02},
{"", 0xff},
};
static const Parameter s_requestedInfoErr[] = {
{"requestedInfoError", s_enumTag, false, TcapXApplication::Enumerated, s_requestedInfoEnum},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_systemFailureEnum[] = {
{"unavailableResources", 0x00},
{"componentFailure", 0x01},
{"basicCallProcessingException", 0x02},
{"resourceStatusFailure", 0x03},
{"endUserFailure", 0x04},
{"", 0xff},
};
static const Parameter s_systemFailureCamelErr[] = {
{"systemFailureError", s_enumTag, false, TcapXApplication::Enumerated, s_systemFailureEnum},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_taskRefusedEnum[] = {
{"generic", 0x00},
{"unobtainable", 0x01},
{"congestion", 0x02},
{"", 0xff},
};
static const Parameter s_taskRefusedErr[] = {
{"taskRefusedError", s_enumTag, false, TcapXApplication::Enumerated, s_taskRefusedEnum},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Operation s_camelErrors[] = {
{"cancelled", true, 0, -1,
s_noTag, 0,
s_noTag, 0
},
{"cancelFailed", true, 1, -1,
s_sequenceTag, s_cancelFailedErr,
s_noTag, 0
},
{"eTCFailed", true, 3, -1,
s_noTag, 0,
s_noTag, 0
},
{"improperCallerResponse", true, 4, -1,
s_noTag, 0,
s_noTag, 0
},
{"missingCustomerRecord", true, 6, -1,
s_noTag, 0,
s_noTag, 0
},
{"missingParameter", true, 7, -1,
s_noTag, 0,
s_noTag, 0
},
{"parameterOutOfRange", true, 8, -1,
s_noTag, 0,
s_noTag, 0
},
{"requestedInfoError", true, 10, -1,
s_noTag, s_requestedInfoErr,
s_noTag, 0
},
{"systemFailure", true, 11, -1,
s_noTag, s_systemFailureCamelErr,
s_noTag, 0
},
{"taskRefused", true, 12, -1,
s_noTag, s_taskRefusedErr,
s_noTag, 0
},
{"unavailableResource", true, 13, -1,
s_noTag, 0,
s_noTag, 0
},
{"unexpectedComponentSequence", true, 14, -1,
s_noTag, 0,
s_noTag, 0
},
{"unexpectedDataValue", true, 15, -1,
s_noTag, 0,
s_noTag, 0
},
{"unexpectedParameter", true, 16, -1,
s_noTag, 0,
s_noTag, 0
},
{"unknownLegID", true, 17, -1,
s_noTag, 0,
s_noTag, 0
},
{"", false, 0, -1,
s_noTag, 0,
s_noTag, 0
},
};
static const StringList s_netLocUpCtxtOps("updateLocation,forwardCheckSS-Indication,restoreData,insertSubscriberData,activateTraceMode");
static const StringList s_locationCancelCtxtOps("cancelLocation");
static const StringList s_roamingNumberEnqCtxtOps("provideRoamingNumber");
static const StringList s_locationInfoRetrieveCtxtOps("sendRoutingInfo");
static const StringList s_reportingCtxtOps("setReportingState,statusReport,remoteUserFree");
static const StringList s_resetCtxtOps("reset");
static const StringList s_infoRetrieveCtxt2Ops("sendAuthenticationInfo");
static const StringList s_infoRetrieveCtxt1Ops("sendParameters");
static const StringList s_subscriberDataCtxtOps("insertSubscriberData,deleteSubscriberData");
static const StringList s_tracingCtxtOps("activateTraceMode,deactivateTraceMode");
static const StringList s_networkFunctionalSsCtxtOps("registerSS,eraseSS,activateSS,deactivateSS,"
"interrogateSS,registerPassword,getPassword");
static const StringList s_networkUnstructuredSsCtxt2Ops("processUnstructuredSS-Request,unstructuredSS-Request,unstructuredSS-Notify");
static const StringList s_networkUnstructuredSsCtxt1Ops("processUnstructuredSS-Data");
static const StringList s_shortMsgGatewayCtxtOps("sendRoutingInfoForSM,informServiceCentre");
static const StringList s_shortMsgMOCtxtOps("mo-forwardSM");
static const StringList s_forwardMsgCtxtOps("forwardSM");
static const StringList s_shortMsgAlertCtxtOps("alertServiceCentre");
static const StringList s_mwdMngtCtxtOps("readyForSM");
static const StringList s_shortMsgMTCtxtOps("mt-forwardSM");
static const StringList s_imsiRetrievalCtxtOps("sendIMSI");
static const StringList s_msPurgingCtxtOps("purgeMS");
static const StringList s_subscriberInfoEnquiryCtxOps("provideSubscriberInfo");
static const StringList s_anyTimeInfoEnquiryCtxOps("anyTimeInterrogation");
static const StringList s_gprsLocationUpdateCtxtOps("updateGprsLocation,insertSubscriberData,activateTraceMode");
static const StringList s_gprsLocationInfoRetrieveCtxtOps("sendRoutingInfoForGprs");
static const StringList s_failureReportCtxtOps("failureReport");
static const StringList s_locationSvcGatewayCtxtOps("sendRoutingInfoForLCS");
static const StringList s_authFailureReportCtxtOps("authenticationFailureReport");
static const OpTable s_defMapOpTable = { s_mapOps, 0};
static const AppCtxt s_mapAppCtxt[]= {
// Network Loc Up context
{"networkLocUpContext-v3", "0.4.0.0.1.0.1.3", s_netLocUpCtxtOps, &s_defMapOpTable},
{"networkLocUpContext-v2", "0.4.0.0.1.0.1.2", s_netLocUpCtxtOps, &s_defMapOpTable},
{"networkLocUpContext-v1", "0.4.0.0.1.0.1.1", s_netLocUpCtxtOps, &s_defMapOpTable},
// Location Cancellation context
{"locationCancelationContext-v3", "0.4.0.0.1.0.2.3", s_locationCancelCtxtOps, &s_defMapOpTable},
{"locationCancelationContext-v2", "0.4.0.0.1.0.2.2", s_locationCancelCtxtOps, &s_defMapOpTable},
{"locationCancelationContext-v1", "0.4.0.0.1.0.2.1", s_locationCancelCtxtOps, &s_defMapOpTable},
// Roaming Number Enquiry Context
{"roamingNumberEnquiryContext-v3", "0.4.0.0.1.0.3.3", s_roamingNumberEnqCtxtOps, &s_defMapOpTable},
{"roamingNumberEnquiryContext-v2", "0.4.0.0.1.0.3.2", s_roamingNumberEnqCtxtOps, &s_defMapOpTable},
{"roamingNumberEnquiryContext-v1", "0.4.0.0.1.0.3.1", s_roamingNumberEnqCtxtOps, &s_defMapOpTable},
// Location Info Retrieval Context
{"locationInfoRetrievalContext-v3", "0.4.0.0.1.0.5.3", s_locationInfoRetrieveCtxtOps, &s_defMapOpTable},
{"locationInfoRetrievalContext-v2", "0.4.0.0.1.0.5.2", s_locationInfoRetrieveCtxtOps, &s_defMapOpTable},
{"locationInfoRetrievalContext-v1", "0.4.0.0.1.0.5.1", s_locationInfoRetrieveCtxtOps, &s_defMapOpTable},
// Reporting Context
{"reportingContext-v3", "0.4.0.0.1.0.7.3", s_reportingCtxtOps, &s_defMapOpTable},
// Reset context
{"resetContext-v2", "0.4.0.0.1.0.10.2", s_resetCtxtOps, &s_defMapOpTable},
{"resetContext-v1", "0.4.0.0.1.0.10.1", s_resetCtxtOps, &s_defMapOpTable},
// Info retrieval context
{"infoRetrievalContext-v3", "0.4.0.0.1.0.14.3", s_infoRetrieveCtxt2Ops, &s_defMapOpTable},
{"infoRetrievalContext-v2", "0.4.0.0.1.0.14.2", s_infoRetrieveCtxt2Ops, &s_defMapOpTable},
{"infoRetrievalContext-v1", "0.4.0.0.1.0.14.1", s_infoRetrieveCtxt1Ops, &s_defMapOpTable},
// Subscriber Data Management Context
{"subscriberDataMngtContext-v3", "0.4.0.0.1.0.16.3", s_subscriberDataCtxtOps, &s_defMapOpTable},
{"subscriberDataMngtContext-v2", "0.4.0.0.1.0.16.2", s_subscriberDataCtxtOps, &s_defMapOpTable},
{"subscriberDataMngtContext-v1", "0.4.0.0.1.0.16.1", s_subscriberDataCtxtOps, &s_defMapOpTable},
// Tracing context
{"tracingContext-v3", "0.4.0.0.1.0.17.3", s_tracingCtxtOps, &s_defMapOpTable},
{"tracingContext-v2", "0.4.0.0.1.0.17.2", s_tracingCtxtOps, &s_defMapOpTable},
{"tracingContext-v1", "0.4.0.0.1.0.17.1", s_tracingCtxtOps, &s_defMapOpTable},
// Network functional SS context
{"networkFunctionalSsContext-v2", "0.4.0.0.1.0.18.2", s_networkFunctionalSsCtxtOps, &s_defMapOpTable},
{"networkFunctionalSsContext-v1", "0.4.0.0.1.0.18.1", s_networkFunctionalSsCtxtOps, &s_defMapOpTable},
// Network unstructured SS context
{"networkUnstructuredSsContext-v2", "0.4.0.0.1.0.19.2", s_networkUnstructuredSsCtxt2Ops, &s_defMapOpTable},
{"networkUnstructuredSsContext-v1", "0.4.0.0.1.0.19.1", s_networkUnstructuredSsCtxt1Ops, &s_defMapOpTable},
// Short message routing
{"shortMsgGatewayContext-v3", "0.4.0.0.1.0.20.3", s_shortMsgGatewayCtxtOps, &s_defMapOpTable},
{"shortMsgGatewayContext-v2", "0.4.0.0.1.0.20.2", s_shortMsgGatewayCtxtOps, &s_defMapOpTable},
{"shortMsgGatewayContext-v1", "0.4.0.0.1.0.20.1", s_shortMsgGatewayCtxtOps, &s_defMapOpTable},
// Mobile Originated short messages
{"shortMsgMO-RelayContext-v3", "0.4.0.0.1.0.21.3", s_shortMsgMOCtxtOps, &s_defMapOpTable},
{"shortMsgMO-RelayContext-v2", "0.4.0.0.1.0.21.2", s_forwardMsgCtxtOps, &s_defMapOpTable},
{"shortMsgMO-RelayContext-v1", "0.4.0.0.1.0.21.1", s_forwardMsgCtxtOps, &s_defMapOpTable},
// Short message alerts
{"shortMsgAlertContext-v2", "0.4.0.0.1.0.23.2", s_shortMsgAlertCtxtOps, &s_defMapOpTable},
{"shortMsgAlertContext-v1", "0.4.0.0.1.0.23.1", s_shortMsgAlertCtxtOps, &s_defMapOpTable},
// readyForSM context
{"mwdMngtContext-v3", "0.4.0.0.1.0.24.3", s_mwdMngtCtxtOps, &s_defMapOpTable},
{"mwdMngtContext-v2", "0.4.0.0.1.0.24.2", s_mwdMngtCtxtOps, &s_defMapOpTable},
{"mwdMngtContext-v1", "0.4.0.0.1.0.24.1", s_mwdMngtCtxtOps, &s_defMapOpTable},
// Mobile Terminated short messages
{"shortMsgMT-RelayContext-v3", "0.4.0.0.1.0.25.3", s_shortMsgMTCtxtOps, &s_defMapOpTable},
{"shortMsgMT-RelayContext-v2", "0.4.0.0.1.0.25.2", s_forwardMsgCtxtOps, &s_defMapOpTable},
// sendIMSI Context
{"imsiRetrievalContext-v2", "0.4.0.0.1.0.26.2", s_imsiRetrievalCtxtOps, &s_defMapOpTable},
// MS Purging Context
{"msPurgingContext-v3", "0.4.0.0.1.0.27.3", s_msPurgingCtxtOps, &s_defMapOpTable},
{"msPurgingContext-v2", "0.4.0.0.1.0.27.2", s_msPurgingCtxtOps, &s_defMapOpTable},
// Subscriber Information Enquiry Context
{"subscriberInfoEnquiryContext-v3", "0.4.0.0.1.0.28.3", s_subscriberInfoEnquiryCtxOps, &s_defMapOpTable},
// Any Time Info Enquiry Context
{"anyTimeInfoEnquiryContext-v3", "0.4.0.0.1.0.29.3", s_anyTimeInfoEnquiryCtxOps, &s_defMapOpTable},
// GPRS Location Update Context
{"gprsLocationUpdateContext-v3", "0.4.0.0.1.0.32.3", s_gprsLocationUpdateCtxtOps, &s_defMapOpTable},
// GPRS Location Info Retrieval Context
{"gprsLocationInfoRetrievalContext-v3" , "0.4.0.0.1.0.33.3", s_gprsLocationInfoRetrieveCtxtOps, &s_defMapOpTable},
// Failure Report Context
{"failureReportContext-v3" , "0.4.0.0.1.0.34.3", s_failureReportCtxtOps, &s_defMapOpTable},
// Location Services Gateway Context
{"locationSvcGatewayContext-v3", "0.4.0.0.1.0.37.3", s_locationSvcGatewayCtxtOps, &s_defMapOpTable},
// Authentication Failure Report Context
{"authenticationFailureReportContext-v3" , "0.4.0.0.1.0.39.3", s_authFailureReportCtxtOps, &s_defMapOpTable},
{0, 0, s_noOps, 0},
};
static const StringList s_cap2gsmSSFgsmSCFCtxtOps("initialDP,establishTemporaryConnection,connectToResource,"
"disconnectForwardConnection,connect,releaseCall,eventReportBCSM,"
"requestReportBCSMEvent,applyChargingReport,applyCharging,continue,"
"resetTimer,furnishChargingInformation,callInformationReport,"
"callInformationRequest,sendChargingInformation,specializedResourceReport,"
"playAnnouncement,promptAndCollectUserInformation,cancel,activityTest");
static const StringList s_cap2AssistgsmSSFgsmSCFCtxtOps("assistRequestInstructions,disconnectForwardConnection,connectToResource,"
"resetTimer,specializedResourceReport,playAnnouncement,"
"promptAndCollectUserInformation,cancel,activityTest");
static const StringList s_cap2gsmSRFgsmSCFCtxtOps("assistRequestInstructions,specializedResourceReport,playAnnouncement,"
"promptAndCollectUserInformation,cancel,activityTest");
static OpTable s_defCamelOpTable = { s_camelOps, 0 };
static const AppCtxt s_camelAppCtxt[] = {
{"CAP-v2-gsmSSF-to-gsmSCF-AC", "0.4.0.0.1.0.50.1", s_cap2gsmSSFgsmSCFCtxtOps, &s_defCamelOpTable},
{"CAP-v2-assist-gsmSSF-to-gsmSCF-AC", "0.4.0.0.1.0.51.1", s_cap2AssistgsmSSFgsmSCFCtxtOps, &s_defCamelOpTable},
{"CAP-v2-gsmSRF-to-gsmSCF-AC", "0.4.0.0.1.0.52.1", s_cap2gsmSRFgsmSCFCtxtOps, &s_defCamelOpTable},
{0, 0, s_noOps, 0}
};
static const StringList s_mapDialogCtxtOps("map-open,map-accept,map-close,map-refuse,map-userAbort,map-providerAbort");
static const AppCtxt s_mapDialogCtxt[] = {
{"map-DialogueAS", "0.4.0.0.1.1.1.1", s_mapDialogCtxtOps, 0},
{0, 0, s_noOps, 0}
};
static const Parameter s_mapOpenSeq[] = {
{"destinationReference", s_ctxtPrim_0_Tag, true, TcapXApplication::AddressString, 0},
{"originationReference", s_ctxtPrim_1_Tag, true, TcapXApplication::AddressString, 0},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false,TcapXApplication::None, 0},
};
static const TokenDict s_mapRefuseReasonEnum[] = {
{"noReasonGiven", 0},
{"invalidDestinationReference", 1},
{"invalidOriginatingReference", 2},
{0,0},
};
static const Parameter s_mapRefuseSeq[] = {
{"reason", s_enumTag, false, TcapXApplication::Enumerated, s_mapRefuseReasonEnum},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"alternativeApplicationContext", s_oidTag, true, TcapXApplication::OID, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_rscUnavailableReason[] = {
{"shortTermResourceLimitation", 0},
{"longTermResourceLimitation", 1},
{0,0},
};
static const TokenDict s_procCancelReason[] = {
{"handoverCancellation", 0},
{"radioChannelRelease", 1},
{"networkPathRelease", 2},
{"callRelease", 3},
{"associatedProcedureFailure", 4},
{"tandemDialogueRelease", 5},
{"remoteOperationsFailure", 6},
{0,0},
};
static const Parameter s_mapUserAbortChoice[] = {
{"userSpecificReason", s_ctxtPrim_0_Tag, false, TcapXApplication::Null, 0},
{"userResourceLimitation", s_ctxtPrim_1_Tag, false, TcapXApplication::Null, 0},
{"resourceUnavailable", s_ctxtPrim_2_Tag, false, TcapXApplication::Enumerated, s_rscUnavailableReason},
{"applicationProcedureCancellation", s_ctxtPrim_3_Tag, false, TcapXApplication::Enumerated, s_procCancelReason},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_mapUserAbortSeq[] = {
{"map-UserAbortChoice", s_noTag, false, TcapXApplication::Choice, s_mapUserAbortChoice},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_providerAbortReason[] = {
{"abnormalDialogue", 0},
{"invalidPDU", 1},
{0,0},
};
static const Parameter s_mapProviderAbortSeq[] = {
{"map-ProviderAbortReason", s_enumTag, false, TcapXApplication::Enumerated, s_providerAbortReason},
{"extensionContainer", s_sequenceTag, true, TcapXApplication::HexString, 0},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const Parameter s_mapDialogChoice[] = {
{"map-open", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_mapOpenSeq},
{"map-accept", s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_extensionContainerRes},
{"map-close", s_ctxtCstr_2_Tag, false, TcapXApplication::Sequence, s_extensionContainerRes},
{"map-refuse", s_ctxtCstr_3_Tag, false, TcapXApplication::Sequence, s_mapRefuseSeq},
{"map-userAbort", s_ctxtCstr_4_Tag, false, TcapXApplication::Sequence, s_mapUserAbortSeq},
{"map-providerAbort", s_ctxtCstr_5_Tag, false, TcapXApplication::Sequence, s_mapProviderAbortSeq},
{"", s_noTag, false, TcapXApplication::None, 0},
};
static const TokenDict s_appStates[] = {
{"waiting", TcapXApplication::Waiting},
{"active", TcapXApplication::Active},
{"shutdown", TcapXApplication::ShutDown},
{"inactive", TcapXApplication::Inactive},
{"", 0},
};
static const TokenDict s_userTypes[] = {
{"MAP", TcapXUser::MAP},
{"CAMEL", TcapXUser::CAMEL},
{"", 0},
};
static void replace(String& str, char what, char with)
{
char* c = (char*)str.c_str();
while (c && *c) {
if(*c == what)
*c = with;
c++;
}
}
static const Operation* findError(TcapXUser::UserType type, int opCode, bool opLocal = true)
{
DDebug(&__plugin,DebugAll,"findError(opCode=%d, local=%s)",opCode,String::boolText(opLocal));
const Operation* ops = (type == TcapXUser::MAP ? s_mapErrors : s_camelErrors);
while (!TelEngine::null(ops->name)) {
if (ops->code == opCode && ops->local == opLocal)
return ops;
ops++;
}
return 0;
}
static const Operation* findError(TcapXUser::UserType type, const String& op)
{
DDebug(&__plugin,DebugAll,"findError(opCode=%s)",op.c_str());
const Operation* ops = (type == TcapXUser::MAP ? s_mapErrors : s_camelErrors);
while (!TelEngine::null(ops->name)) {
if (op == ops->name)
return ops;
ops++;
}
return 0;
}
static bool isAppCtxtOperation(const AppCtxt* ctxt, const Operation* op)
{
DDebug(&__plugin,DebugAll,"isAppCtxtOperation(ctxt=%s[%p],op=%s[%p]]",(ctxt ? ctxt->name : ""),ctxt,(op ? op->name.c_str() : ""),op);
if (!ctxt)
return true;
return (0 != ctxt->ops.find(op->name));
}
static const Operation* findOperation(TcapXUser::UserType type, int opCode, bool opLocal = true, const AppCtxt* ctxt = 0)
{
DDebug(&__plugin,DebugAll,"findOperation(type=%s,opCode=%d,local=%s,ctxt=%p)",lookup(type,s_userTypes),opCode,String::boolText(opLocal),ctxt);
const Operation* ops = 0;
const OpTable* opTable = (ctxt ? ctxt->opTable : 0);
do {
ops = ( opTable ? opTable->mainTable : (type == TcapXUser::MAP ? s_mapOps : s_camelOps));
while (!TelEngine::null(ops->name)) {
if (ops->code == opCode && ops->local == opLocal) {
if (isAppCtxtOperation(ctxt,ops))
return ops;
}
ops++;
}
if (opTable)
opTable = opTable->fallbackTable;
} while (opTable);
return 0;
}
static const Operation* findOperation(TcapXUser::UserType type, const String& op, const AppCtxt* ctxt = 0)
{
DDebug(&__plugin,DebugAll,"findOperation(opCode=%s,ctxt=%p)",op.c_str(),ctxt);
const Operation* ops = 0;
const OpTable* opTable = (ctxt ? ctxt->opTable : 0);
do {
ops = ( opTable ? opTable->mainTable : (type == TcapXUser::MAP ? s_mapOps : s_camelOps));
while (!TelEngine::null(ops->name)) {
if (op == ops->name && isAppCtxtOperation(ctxt,ops))
return ops;
ops++;
}
if (opTable)
opTable = opTable->fallbackTable;
} while (opTable);
return 0;
}
static const Capability* findCapability(TcapXUser::UserType type, const String& opName)
{
DDebug(&__plugin,DebugAll,"findCapability(opName=%s)",opName.c_str());
const Capability* cap = (type == TcapXUser::MAP ? s_mapCapab : s_camelCapab);
while (cap->name) {
if (cap->ops.find(opName))
return cap;
cap++;
}
return 0;
}
static const Capability* findCapabilityOID(TcapXUser::UserType type, const char* oid)
{
if (!oid)
return 0;
DDebug(&__plugin,DebugAll,"findCapabilityOID(oid=%s)",oid);
const Capability* cap = (type == TcapXUser::MAP ? s_mapCapabOID : s_camelCapabOID);
while (cap->name) {
if (cap->ops.find(oid))
return cap;
cap++;
}
return 0;
}
static bool findDefCapability(TcapXUser::UserType type, const String& cap)
{
DDebug(&__plugin,DebugAll,"findDefCapability(opName=%s)",cap.c_str());
const Capability* caps = (type == TcapXUser::MAP ? s_mapCapab : s_camelCapab);
while (caps->name) {
if (cap == caps->name)
return true;
caps++;
}
return false;
}
static const AppCtxt* findCtxtFromOid(const String& oid, const AppCtxt* ctxt)
{
DDebug(&__plugin,DebugAll,"findCtxtFromOid(oid=%s)",oid.c_str());
while (ctxt && ctxt->name) {
if (oid == ctxt->oid)
return ctxt;
ctxt++;
}
return 0;
}
static const AppCtxt* findCtxtFromStr(const String& oid, const AppCtxt* ctxt)
{
DDebug(&__plugin,DebugAll,"findCtxtFromStr(ctxt=%s)",oid.c_str());
while (ctxt && ctxt->name) {
if (oid == ctxt->name)
return ctxt;
ctxt++;
}
return 0;
}
/**
* IDMap
*/
void IDMap::appendID(const char* tcapID, const char* appID, const AppCtxt* ctxt)
{
DDebug(&__plugin,DebugAll,"IDMap::appendID(tcapID=%s,appID=%s)",tcapID,appID);
if (tcapID && appID)
append(new Transaction(appID,tcapID,ctxt));
}
const String& IDMap::findTcapID(const char* appID)
{
DDebug(&__plugin,DebugAll,"IDMap::findTcapID(appID=%s)",appID);
ObjList* obj = find(appID);
if (obj) {
NamedString* ns = static_cast<NamedString*>(obj->get());
if (!TelEngine::null(ns))
return (*ns);
}
return String::empty();
}
const String& IDMap::findAppID(const char* tcapID)
{
DDebug(&__plugin,DebugAll,"IDMap::findAppID(tcapID=%s)",tcapID);
for (ObjList* o = skipNull(); o; o = o->skipNext()) {
NamedString* ns = static_cast<NamedString*>(o->get());
if (!TelEngine::null(ns) && (*ns) == tcapID)
return ns->name();
}
return String::empty();
}
Transaction* IDMap::findByAppID(const char* appID)
{
DDebug(&__plugin,DebugAll,"IDMap::findByAppID(appID=%s)",appID);
ObjList* obj = find(appID);
if (obj) {
Transaction* ns = static_cast<Transaction*>(obj->get());
return ns;
}
return 0;
}
Transaction* IDMap::findByTcapID(const char* tcapID)
{
DDebug(&__plugin,DebugAll,"IDMap::findByTcapID(tcapID=%s)",tcapID);
for (ObjList* o = skipNull(); o; o = o->skipNext()) {
Transaction* ns = static_cast<Transaction*>(o->get());
if (!TelEngine::null(ns) && (*ns) == tcapID)
return ns;
}
return 0;
}
/**
* StringList
*/
StringList::StringList(const char* list, char sep)
{
DDebug(&__plugin,DebugAll,"StringList(list=%s) [%p]",list,this);
String str(list);
m_list = str.split(sep,false);
}
StringList::~StringList()
{
XDebug(&__plugin,DebugAll,"~StringList() [%p]",this);
TelEngine::destruct(m_list);
}
/**
* MyDomParser
*/
MyDomParser::MyDomParser(TcapXApplication* app, const char* name, bool fragment)
: XmlDomParser(name,fragment),
m_app(app)
{
Debug(DebugAll,"MyDomParser created [%p]",this);
}
MyDomParser::~MyDomParser()
{
Debug(DebugAll,"MyDomParser destroyed [%p]",this);
}
void MyDomParser::gotElement(const NamedList& element, bool empty)
{
XmlDomParser::gotElement(element,empty);
if (empty)
verifyRoot();
}
void MyDomParser::endElement(const String& name)
{
XmlDomParser::endElement(name);
verifyRoot();
}
void MyDomParser::verifyRoot()
{
if (m_app && document() && document()->root() && document()->root()->completed()) {
m_app->receivedXML(document());
document()->reset();
}
}
/**
* XMLConnection
*/
XMLConnection::XMLConnection(Socket* skt, TcapXApplication* app)
: Thread("XMLConnection"),
m_socket(skt), m_app(app),
m_parser(app,"MyDomParser",false)
{
Debug(&__plugin,DebugAll,"XMLConnection created with socket=[%p] for application=%s[%p] [%p]",skt,app->toString().c_str(),app,this);
m_app->ref();
start();
}
XMLConnection::~XMLConnection()
{
Debug(&__plugin,DebugAll,"XMLConnection destroyed [%p]",this);
if (m_socket){
delete m_socket;
m_socket = 0;
}
TelEngine::destruct(m_app);
}
void XMLConnection::start()
{
Debug(&__plugin,DebugAll,"XMLConnection start [%p]",this);
m_socket->setBlocking(false);
}
void XMLConnection::run()
{
if (!m_socket)
return;
char buffer[2048];
for (;;) {
if (!(m_socket && m_socket->valid()))
break;
Thread::check();
bool readOk = false, error = false;
if (!m_socket->select(&readOk,0,&error,idleUsec()))
continue;
if (!readOk || error) {
if (error) {
if (m_socket->error())
Debug(&__plugin,DebugInfo,"XMLConnection[%p] : Reading data error: %s (%d)",this,strerror(m_socket->error()),
m_socket->error());
return;
}
continue;
}
int readSize = m_socket->readData(buffer,sizeof(buffer));
if (!readSize) {
if (m_socket->canRetry()) {
idle(true);
continue;
}
return;
}
else if (readSize < 0) {
if (m_socket->canRetry()) {
idle(true);
continue;
}
cancel();
Debug(&__plugin,DebugWarn,"Read error %s(%d) on socket %p in XMLConnection[%p]",strerror(m_socket->error()),
m_socket->error(),m_socket,this);
break;
}
buffer[readSize] = 0;
XDebug(&__plugin,DebugAll,"READ %d : %s",readSize,buffer);
if (!m_parser.parse(buffer)) {
if (m_parser.error() != XmlSaxParser::Incomplete) {
Debug(&__plugin,DebugWarn,"Parser error %s in read data [%p] unparsed type %d, buffer = %s, pushed = %s",
m_parser.getError(),this,m_parser.unparsed(),m_parser.getBuffer().c_str(),buffer);
break;
}
}
}
}
void XMLConnection::cleanup()
{
DDebug(&__plugin,DebugAll,"XMLConnection::cleanup() [%p]",this);
m_app->setIO(0);
}
bool XMLConnection::writeData(XmlFragment* elem)
{
if (!elem)
return false;
String xml;
elem->toString(xml,true);
XDebug(&__plugin,DebugAll,"WRITE : %s",xml.c_str());
int len = xml.length();
const char* buffer = xml.c_str();
while (m_socket && (len > 0)) {
bool writeOk = false,error = false;
if (!m_socket->select(0,&writeOk,&error,idleUsec()) || error) {
if (!m_socket->canRetry())
return false;
continue;
}
if (!writeOk )
continue;
int w = m_socket->writeData(buffer,len);
if (w < 0) {
if (!m_socket->canRetry()) {
Debug(&__plugin,DebugWarn,"XMLConnection::writeData(xml=[%p]) [%p] on socket [%p] could not write error : %s",
elem,this,m_socket,strerror(m_socket->error()));
cancel();
return false;
}
}
else {
buffer += w;
len -= w;
}
}
return true;
}
/**
* XMLConnListener
*/
XMLConnListener::XMLConnListener(TcapXUser* user, const NamedList& sect)
: Thread("XMLConnListener"),
m_user(user)
{
Debug(&__plugin,DebugAll,"XMLConnListener [%p] created",this);
m_host = sect.getValue(YSTRING("host"),"127.0.0.1");
m_port = sect.getIntValue(YSTRING("port"),5555);
}
XMLConnListener::~XMLConnListener()
{
Debug(&__plugin,DebugAll,"XMLConnListener [%p] destroyed",this);
m_user = 0;
}
bool XMLConnListener::init()
{
SocketAddr addr;
if (!addr.assign(AF_INET) || !addr.host(m_host) || !addr.port(m_port)) {
Debug(m_user,DebugWarn,"Could not assign address=%s:%d for user listener=%s [%p]",m_host.c_str(),m_port,
m_user->toString().c_str(),this);
return false;
}
if (!m_socket.create(addr.family(),SOCK_STREAM)) {
Debug(m_user,DebugWarn, "Could not create socket for user listener=%s [%p] error %d: %s",
m_user->toString().c_str(),this,m_socket.error(),strerror(m_socket.error()));
return false;
}
m_socket.setReuse();
if (!m_socket.bind(addr)) {
Debug(m_user,DebugWarn,"Could not bind user listener=%s [%p] error %d: %s",
m_user->toString().c_str(),this,m_socket.error(),strerror(m_socket.error()));
return false;
}
if (!m_socket.setBlocking(false) || !m_socket.listen())
return false;
return startup();
}
void XMLConnListener::run()
{
for (;;) {
Thread::check();
idle();
SocketAddr address;
Socket* newSocket = m_socket.accept(address);
if (!newSocket) {
if (m_socket.canRetry())
continue;
Debug(m_user,DebugWarn,"Accept error: %s",strerror(m_socket.error()));
break;
}
else {
String addr(address.host());
addr << ":" << address.port();
if (!createConn(newSocket,addr))
Debug(m_user,DebugInfo,"Connection from %s rejected",addr.c_str());
}
}
}
bool XMLConnListener::createConn(Socket* skt, String& addr)
{
if (!skt->valid()) {
delete skt;
return false;
}
if (!skt->setBlocking(false)) {
Debug(m_user,DebugCrit, "Failed to set TCP socket to nonblocking mode: %s",
strerror(skt->error()));
delete skt;
return false;
}
if (m_user && !m_user->createApplication(skt,addr)) {
delete skt;
return false;
}
return true;
}
void XMLConnListener::cleanup()
{
DDebug(m_user,DebugAll,"XMLConnListener::cleanup() [%p]",this);
m_user->setListener(0);
}
/**
* TcapToXml
*/
const XMLMap TcapToXml::s_xmlMap[] = {
{Regexp("^state$"), "state", "", TcapToXml::Value},
{Regexp("^error$"), "error", "", TcapToXml::Value},
{Regexp("^LocalPC$"), "transport.mtp", "", TcapToXml::Element},
{Regexp("^RemotePC$"), "transport.mtp", "", TcapToXml::Element},
{Regexp("^sls$"), "transport.mtp", "", TcapToXml::Element},
{Regexp("^ReturnCause$"), "transport.sccp", "ReturnCause", TcapToXml::Element},
{Regexp("^HopCounter$"), "transport.sccp", "HopCounter", TcapToXml::Element},
{Regexp("^CallingPartyAddress\\.gt\\.encoding$"), "transport.sccp.CallingPartyAddress.gt", "encoding", TcapToXml::Attribute},
{Regexp("^CallingPartyAddress\\.gt\\.plan$"), "transport.sccp.CallingPartyAddress.gt", "plan", TcapToXml::Attribute},
{Regexp("^CallingPartyAddress\\.gt\\.nature$"), "transport.sccp.CallingPartyAddress.gt", "nature", TcapToXml::Attribute},
{Regexp("^CallingPartyAddress\\.gt\\.translation$"), "transport.sccp.CallingPartyAddress.gt", "translation", TcapToXml::Attribute},
{Regexp("^CallingPartyAddress\\.gt$"), "transport.sccp.CallingPartyAddress", "gt", TcapToXml::Element},
{Regexp("^CallingPartyAddress\\.ssn$"), "transport.sccp.CallingPartyAddress", "ssn", TcapToXml::Element},
{Regexp("^CallingPartyAddress\\.route$"), "transport.sccp.CallingPartyAddress", "route", TcapToXml::Element},
{Regexp("^CallingPartyAddress\\.pointcode$"), "transport.sccp.CallingPartyAddress", "pointcode", TcapToXml::Element},
{Regexp("^CallingPartyAddress\\..\\+$"), "transport.sccp.CallingPartyAddress", "", TcapToXml::Element},
{Regexp("^CalledPartyAddress\\.gt\\.encoding$"), "transport.sccp.CalledPartyAddress.gt", "encoding", TcapToXml::Attribute},
{Regexp("^CalledPartyAddress\\.gt\\.plan$"), "transport.sccp.CalledPartyAddress.gt", "plan", TcapToXml::Attribute},
{Regexp("^CalledPartyAddress\\.gt\\.nature$"), "transport.sccp.CalledPartyAddress.gt", "nature", TcapToXml::Attribute},
{Regexp("^CalledPartyAddress\\.gt\\.translation$"), "transport.sccp.CalledPartyAddress.gt", "translation", TcapToXml::Attribute},
{Regexp("^CalledPartyAddress\\.gt$"), "transport.sccp.CalledPartyAddress", "gt", TcapToXml::Element},
{Regexp("^CalledPartyAddress\\.ssn$"), "transport.sccp.CalledPartyAddress", "ssn", TcapToXml::Element},
{Regexp("^CalledPartyAddress\\.route$"), "transport.sccp.CalledPartyAddress", "route", TcapToXml::Element},
{Regexp("^CalledPartyAddress\\.pointcode$"), "transport.sccp.CalledPartyAddress", "pointcode", TcapToXml::Element},
{Regexp("^CalledPartyAddress\\..\\+$"), "transport.sccp.CalledPartyAddress", "", TcapToXml::Element},
{Regexp("^tcap\\.request\\.type$"), "transport.tcap", "request-type", TcapToXml::Element},
{Regexp("^tcap\\.transaction\\.localTID$"), "transport.tcap", "localTID", TcapToXml::Element},
{Regexp("^tcap\\.transaction\\.remoteTID$"), "transport.tcap", "remoteTID", TcapToXml::Element},
{Regexp("^tcap\\.transaction\\.abort\\.cause$"), "transport.tcap", "abort-cause", TcapToXml::Element},
{Regexp("^tcap\\.transaction\\.abort\\.information$"), "transport.tcap", "abort-information", TcapToXml::Element},
{Regexp("^tcap\\.transaction\\..\\+$"), "transport.tcap", "", TcapToXml::Element},
{Regexp("^tcap\\.dialogPDU\\.application-context-name$"), "application", "", TcapToXml::Value},
{Regexp("^tcap\\.dialogPDU\\.dialog-pdu-type$"), "transport.tcap.dialog", "type", TcapToXml::Attribute},
{Regexp("^tcap\\.dialogPDU\\.protocol-version$"), "transport.tcap.dialog", "version", TcapToXml::Attribute},
{Regexp("^tcap\\.dialogPDU\\.abort-source$"), "transport.tcap.dialog", "abort-source", TcapToXml::Element},
{Regexp("^tcap\\.dialogPDU\\.result$"), "transport.tcap.dialog", "result", TcapToXml::Element},
{Regexp("^tcap\\.dialogPDU\\.result-source-diagnostic$"), "transport.tcap.dialog", "result-source-diagnostic", TcapToXml::Element},
{Regexp("^tcap\\.dialogPDU\\.userInformation\\.direct-reference$"), "transport.tcap.dialog.userInformation", "direct-reference", TcapToXml::Element},
{Regexp("^tcap\\.dialogPDU\\.userInformation\\.encoding-contents$"),"transport.tcap.dialog.userInformation", "encoding-contents",TcapToXml::Element},
{Regexp("^tcap\\.dialogPDU\\.userInformation\\.encoding-type$"), "transport.tcap.dialog.userInformation", "encoding-type", TcapToXml::Element},
{Regexp("^tcap\\.dialogPDU\\.userInformation\\..\\+$"), "transport.tcap.dialog.userInformation", "", TcapToXml::Element},
{Regexp("^tcap\\.component\\.count$"), "", "", TcapToXml::None},
{Regexp("^tcap\\.component\\..\\+\\.localCID$"), "component", "", TcapToXml::Attribute},
{Regexp("^tcap\\.component\\..\\+\\.remoteCID$"), "component", "", TcapToXml::Attribute},
{Regexp("^tcap\\.component\\..\\+\\.componentType$"), "component", "type", TcapToXml::Attribute},
{Regexp("^tcap\\.component\\..\\+\\.operationCode$"), "component", "", TcapToXml::Attribute},
{Regexp("^tcap\\.component\\..\\+\\.operationCodeType$"), "", "", TcapToXml::None},
{Regexp("^tcap\\.component\\..\\+\\.errorCode$"), "component", "", TcapToXml::Attribute},
{Regexp("^tcap\\.component\\..\\+\\.errorCodeType$"), "", "", TcapToXml::None},
{Regexp("^tcap\\.component\\..\\+\\.problemCode$"), "component", "", TcapToXml::Attribute},
{Regexp("^tcap\\.component\\..\\+\\.operationClass$"), "component", "", TcapToXml::Attribute},
{Regexp("^tcap\\.component\\..\\+\\..\\+"), "component", "", TcapToXml::NewElement},
{Regexp(""), "", "", TcapToXml::End},
};
TcapToXml::TcapToXml(TcapXApplication* app)
: Mutex(false,"TcapToXml"),
m_app(app), m_type(Unknown)
{
DDebug(&__plugin,DebugAll,"TcapToXml created for application=%s[%p] [%p]",m_app->toString().c_str(),m_app,this);
}
TcapToXml::~TcapToXml()
{
DDebug(&__plugin,DebugAll,"TcapToXml destroyed [%p]",this);
reset();
}
void TcapToXml::reset()
{
m_type = Unknown;
}
const XMLMap* TcapToXml::findMap(String& what)
{
XDebug(&__plugin,DebugAll,"TcapToXml::findMap(%s) [%p]",what.c_str(),this);
const XMLMap* map = s_xmlMap;
while (map->type != End) {
if (what.matches(map->name))
return map;
map++;
}
return 0;
}
bool TcapToXml::buildXMLMessage(NamedList& params, XmlFragment* msg, MsgType type, const AppCtxt* ctxt)
{
DDebug(&__plugin,DebugAll,"TcapToXML::buildXMLMessage() [%p]",this);
if (!msg)
return false;
XmlDeclaration* decl = new XmlDeclaration();
msg->addChild(decl);
XmlElement* el = new XmlElement(s_msgTag);
el->setXmlns("",true,s_namespace);
msg->addChild(el);
AppCtxt* appCtxt = 0;
NamedString* ctxtStr = params.getParam(s_tcapAppCtxt);
if (!TelEngine::null(ctxtStr)) {
const AppCtxt* contexts = (m_app->type() == TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt);
appCtxt = (AppCtxt*)findCtxtFromOid(*ctxtStr,contexts);
}
if (appCtxt)
params.setParam(s_tcapAppCtxt,appCtxt->name);
// translate P-Abort causes
NamedString* param = params.getParam(s_tcapAbortCause);
if (!TelEngine::null(param) && (*param) == "pAbort") {
int code = params.getIntValue(s_tcapAbortInfo);
params.setParam(s_tcapAbortInfo,lookup(code,SS7TCAPError::s_errorTypes,*param));
}
if (m_app->type() == TcapXUser::MAP && !TelEngine::null(params.getParam(s_tcapDirectReference)))
handleMAPDialog(el,params);
for (unsigned int i = 0; i < params.count(); i++) {
NamedString* ns = params.getParam(i);
if (TelEngine::null(ns))
continue;
if (ns->name().startsWith(s_tcapCompPrefixSep))
continue;
const XMLMap* map = findMap((String&)ns->name());
if (!map)
continue;
addToXml(el,map,ns);
}
addComponentsToXml(el,params,ctxt);
return true;
}
void TcapToXml::handleMAPDialog(XmlElement* root, NamedList& params)
{
if (!root)
return;
XDebug(&__plugin,DebugAll,"TcapToXml::handleMAPDialog(root=%p) [%p]",root,this);
NamedString* param = params.getParam(s_tcapDirectReference);
if (TelEngine::null(param))
return;
const AppCtxt* mapCtxt = findCtxtFromOid(*param,s_mapDialogCtxt);
// we don't know the context, leave it alone
if (!mapCtxt)
return;
if (mapCtxt)
params.setParam(s_tcapDirectReference,mapCtxt->name);
param = params.getParam(s_tcapEncodingContent);
if (TelEngine::null(param))
return;
const XMLMap* map = findMap((String&)s_tcapEncodingContent);
if (!map)
return;
XmlElement* parent = addToXml(root,map,&s_encodingPath);
if (!parent)
return;
DataBlock db;
db.unHexify(param->c_str(),param->length(),' ');
if (decodeDialogPDU(parent,mapCtxt,db)) {
params.clearParam(s_tcapEncodingContent);
}
}
bool TcapToXml::decodeDialogPDU(XmlElement* el, const AppCtxt* ctxt, DataBlock& data)
{
if (!(el && ctxt))
return false;
XDebug(&__plugin,DebugAll,"TcapToXml::decodeDialogPDU(el=%p) [%p]",el,this);
const Parameter* param = s_mapDialogChoice;
int err = TcapXApplication::NoError;
while (param && param->name) {
AsnTag tag;
AsnTag::decode(tag,data);
if (decodeParam(param,tag,data,el,m_app->addEncoding(),err)) {
bool ok = (0 != ctxt->ops.find(param->name));
if (!ok)
el->clearChildren();
return ok;
}
param++;
}
if (data.length())
decodeRaw(el,data);
return true;
}
XmlElement* TcapToXml::addToXml(XmlElement* root, const XMLMap* map, NamedString* val)
{
if (!(root && map && val))
return 0;
if (map->type == None)
return 0;
XDebug(&__plugin,DebugAll,"TcapToXml::addToXml(frag=%p, map=%s[%p], val=%s[%p]) [%p]",root,map->map,map,val->name().c_str(),val,this);
String mapStr = map->map;
ObjList* path = mapStr.split('.',false);
XmlElement* parent = root;
for (ObjList* o = path->skipNull(); o; o = o->skipNext()) {
String* elem = static_cast<String*>(o->get());
if (TelEngine::null(elem))
continue;
XmlElement* child = parent->findFirstChild(elem);
if (!child) {
child = new XmlElement(*elem);
parent->addChild(child);
}
parent = child;
}
if (parent) {
// add to parent child element if map is elem, or attr if map si attribute
XmlElement* child = 0;
String tag;
if (TelEngine::null(map->tag)) {
tag = val->name();
if (tag.find('.') > -1 && tag.startsWith(map->name))
tag.startSkip(map->name,false);
replace(tag,'.','-');
}
else
tag = map->tag;
switch (map->type) {
case Element:
child = parent->findFirstChild(&tag);
if (child) {
child->addText(*val);
parent = child;
break;
}
// fall through and create new child if not found
case NewElement:
child = new XmlElement(tag);
child->addText(*val);
parent->addChild(child);
parent = child;
break;
case Value:
parent->addText(*val);
break;
case Attribute:
parent->setAttributeValid(tag,*val);
break;
case None:
default:
break;
}
}
TelEngine::destruct(path);
return parent;
}
void TcapToXml::addComponentsToXml(XmlElement* el, NamedList& params, const AppCtxt* ctxt)
{
if (!el)
return;
DDebug(&__plugin,DebugAll,"TcapToXml::addComponentsToXml(el=%p, params=%p) [%p]",el,&params,this);
int count = params.getIntValue(s_tcapCompCount);
for (int i = 1; i <= count; i++) {
XmlElement* comp = new XmlElement(s_component);
el->addChild(comp);
String root;
root << s_tcapCompPrefix << "." << String(i);
NamedList compParams("");
compParams.copyParam(params,root,'.');
NamedString* opCode = params.getParam(root + "." + s_tcapOpCode);
NamedString* opType = params.getParam(root + "." + s_tcapOpCodeType);
Operation* op = 0;
if (!TelEngine::null(opCode) && !TelEngine::null(opType))
op = (Operation*)findOperation(m_app->type(),opCode->toInteger(),(*opType == "local"),ctxt);
if (op) {
compParams.setParam(root + "." + s_tcapOpCode,op->name);
if (op->opClass > -1)
compParams.setParam(root + "." + s_tcapOpClass,lookup(op->opClass,SS7TCAP::s_compOperClasses,"reportAll"));
}
int compType = SS7TCAP::lookupComponent(params.getValue(root + "." + s_tcapCompType));
bool searchArgs = true;
switch (compType) {
case SS7TCAP::TC_Invoke:
case SS7TCAP::TC_ResultLast:
case SS7TCAP::TC_ResultNotLast:
searchArgs = (compType == SS7TCAP::TC_Invoke);
break;
case SS7TCAP::TC_U_Error:
opCode = params.getParam(root + "." + s_tcapErrCode);
opType = params.getParam(root + "." + s_tcapErrCodeType);
if (!TelEngine::null(opCode) && !TelEngine::null(opType))
op = (Operation*)findError(m_app->type(),opCode->toInteger(),(*opType == "local"));
if (op)
compParams.setParam(root + "." + s_tcapErrCode,op->name);
break;
case SS7TCAP::TC_R_Reject:
case SS7TCAP::TC_U_Reject:
case SS7TCAP::TC_L_Reject:
compParams.setParam(root + "." + s_tcapProblemCode,
lookup(params.getIntValue(root + "." + s_tcapProblemCode),SS7TCAPError::s_errorTypes));
break;
default:
break;
}
for (unsigned int j = 0; j < compParams.count(); j++) {
NamedString* ns = compParams.getParam(j);
if (TelEngine::null(ns))
continue;
const XMLMap* map = findMap((String&)ns->name());
if (!map)
continue;
XmlElement* child;
int pos = ns->name().rfind('.');
String tag = ns->name().substr(pos + 1);
tag = (TelEngine::null(map->tag) ? tag : (String)map->tag);
switch (map->type) {
case Element:
child = new XmlElement(tag);
child->addText(*ns);
comp->addChild(child);
break;
case Value:
comp->addText(*ns);
break;
case Attribute:
comp->setAttributeValid(tag,*ns);
break;
case None:
default:
break;
}
}
NamedString* payloadHex = params.getParam(root);
if (TelEngine::null(payloadHex))
continue;
addParametersToXml(comp,*payloadHex,op,searchArgs);
}
}
void TcapToXml::addParametersToXml(XmlElement* elem, String& payloadHex, Operation* op, bool searchArgs)
{
if (!elem)
return;
DDebug(&__plugin,DebugAll,"TcapToXml::addParametersToXml(elem=%s[%p], payload=%s, op=%s[%p], searchArgs=%s) [%p]",
elem->getTag().c_str(),elem,payloadHex.c_str(),(op ? op->name.c_str() : ""),op,String::boolText(searchArgs),this);
DataBlock data;
if (!data.unHexify(payloadHex.c_str(),payloadHex.length(),' ')) {
DDebug(&__plugin,DebugAll,"TcapToXml::addParamtersToXml() invalid hexified payload=%s [%p]",payloadHex.c_str(),this);
return;
}
if (elem->getTag() == s_component) {
AsnTag tag = (op ? (searchArgs ? op->argTag : op->retTag) : s_noTag);
AsnTag decTag;
AsnTag::decode(decTag,data);
if (op && tag != decTag) {
if (tag != s_noTag)
op = 0;
}
if (decTag.type() == AsnTag::Constructor && tag == decTag) { // initial constructor
data.cut(-(int)decTag.coding().length());
int len = ASNLib::decodeLength(data);
if (len != (int)data.length())
return;
}
}
decodeTcapToXml(elem,data,op,0,searchArgs);
}
void TcapToXml::decodeTcapToXml(XmlElement* elem, DataBlock& data, Operation* op, unsigned int index, bool searchArgs)
{
DDebug(&__plugin,DebugAll,"TcapToXml::decodeTcapToXml(elem=%s[%p],op=%s[%p], searchArgs=%s) [%p]",
elem->getTag().c_str(),elem,(op ? op->name.c_str() : ""),op,String::boolText(searchArgs),this);
if (!data.length() || !elem)
return;
if (op)
decodeOperation(op,elem,data,searchArgs);
else
decodeRaw(elem,data);
}
bool TcapToXml::decodeOperation(Operation* op, XmlElement* elem, DataBlock& data, bool searchArgs)
{
if (!(op && elem && m_app))
return false;
const Parameter* param = (searchArgs ? op->args : op->res);
AsnTag opTag = (searchArgs ? op->argTag : op->retTag);
int err = TcapXApplication::NoError;
while (param && !TelEngine::null(param->name)) {
AsnTag tag;
AsnTag::decode(tag,data);
if (!decodeParam(param,tag,data,elem,m_app->addEncoding(),err)) {
if (!param->isOptional && (err != TcapXApplication::DataMissing)) {
if (opTag == s_noTag) {
const Parameter* tmp = param;
if ((++tmp) && TelEngine::null(tmp->name))
printMissing(param->name.c_str(),elem->tag(),false);
}
else
printMissing(param->name.c_str(),elem->tag(),false);
}
}
else if (opTag == s_noTag) // should be only one child
break;
param++;
}
if (data.length())
decodeRaw(elem,data);
return true;
}
/**
* XmlToTcap
*/
const TCAPMap XmlToTcap::s_tcapMap[] = {
{"c", false, ""},
{"transport.mtp.", true, ""},
{"transport.sccp.CallingPartyAddress.gt.", true, "CallingPartyAddress.gt"},
{"transport.sccp.CallingPartyAddress.", true, "CallingPartyAddress"},
{"transport.sccp.CalledPartyAddress.gt.", true, "CalledPartyAddress.gt"},
{"transport.sccp.CalledPartyAddress.", true, "CalledPartyAddress"},
{"transport.sccp.", true, ""},
{"transport.tcap.request-type", false, "tcap.request.type"},
{"transport.tcap.abort-cause", false, "tcap.transaction.abort.cause"},
{"transport.tcap.abort-information", false, "tcap.transaction.abort.information"},
{"transport.tcap.dialog.type", false, "tcap.dialogPDU.dialog-pdu-type"},
{"transport.tcap.dialog.version", false, "tcap.dialogPDU.protocol-version"},
{"transport.tcap.dialog.userInformation", true, "tcap.dialogPDU.userInformation"},
{"transport.tcap.dialog.", true, "tcap.dialogPDU"},
{"transport.tcap.", true, "tcap.transaction"},
{"application", false, "tcap.dialogPDU.application-context-name"},
{0, ""},
};
XmlToTcap::XmlToTcap(TcapXApplication* app)
: Mutex(false,"XmlToTcap"),
m_app(app), m_decl(0), m_elem(0)
{
DDebug(&__plugin,DebugAll,"XmlToTcap created for application=%s[%p] [%p]",m_app->toString().c_str(),m_app,this);
}
XmlToTcap::~XmlToTcap()
{
DDebug(&__plugin,DebugAll,"XmlToTcap destroyed [%p]",this);
reset();
}
void XmlToTcap::reset()
{
m_elem = 0;
m_decl = 0;
m_type = Unknown;
}
const TCAPMap* XmlToTcap::findMap(String& path)
{
XDebug(&__plugin,DebugAll,"XmlToTcap::findMap(%s) [%p]",path.c_str(),this);
const TCAPMap* map = s_tcapMap;
while (map && map->path) {
if (path == map->path || path.startsWith(map->path))
return map;
map++;
}
return 0;
}
bool XmlToTcap::validDeclaration()
{
Lock l(this);
if (!m_decl)
return false;
DDebug(&__plugin,DebugAll,"XmlToTcap::validDeclaration() [%p]",this);
const NamedList& decl = m_decl->getDec();
NamedString* vers = decl.getParam(YSTRING("version"));
NamedString* enc = decl.getParam(YSTRING("encoding"));
if ((!TelEngine::null(vers) && (*vers != "1.0")) || (!TelEngine::null(enc) && (*enc |= "UTF-8")))
return false;
return true;
}
bool XmlToTcap::checkXmlns()
{
Lock l(this);
if (!m_elem)
return false;
String* xmlns = m_elem->xmlns();
if (TelEngine::null(xmlns)) {
if (m_app->state() == TcapXApplication::Waiting)
return false;
}
else {
if (s_namespace != *xmlns)
return false;
}
return true;
}
bool XmlToTcap::valid(XmlDocument* doc)
{
Lock l(this);
if (!doc)
return false;
DDebug(&__plugin,DebugAll,"XmlToTcap::valid() [%p]",this);
reset();
m_decl = doc->declaration();
m_elem = doc->root();
if (!(m_elem && m_elem->getTag() == s_msgTag))
return false;
return true;
}
void XmlToTcap::encodeOperation(Operation* op, XmlElement* elem, DataBlock& payload, int& err, bool searchArgs)
{
if (!(op && elem))
return;
const Parameter* param = (searchArgs ? op->args : op->res);
AsnTag opTag = (searchArgs ? op->argTag : op->retTag);
while (param && !TelEngine::null(param->name)) {
DataBlock db;
err = TcapXApplication::NoError;
if (!encodeParam(param,db,elem,err)) {
if (!param->isOptional && (err != TcapXApplication::DataMissing)) {
if (opTag == s_noTag) {
const Parameter* tmp = param;
if ((++tmp) && TelEngine::null(tmp->name))
printMissing(param->name.c_str(),elem->tag());
}
else
printMissing(param->name.c_str(),elem->tag());
}
}
else {
payload.append(db);
if (opTag == s_noTag)
break;
}
param++;
}
XmlElement* child = elem->pop();
while (child) {
DataBlock db;
encodeRaw(param,db,child,err);
payload.append(db);
TelEngine::destruct(child);
child = elem->pop();
}
return;
}
bool XmlToTcap::encodeComponent(DataBlock& payload, XmlElement* elem, bool searchArgs, int& err, Operation* op)
{
DDebug(&__plugin,DebugAll,"XmlToTcap::encodeComponent(elem=%p op=%p) [%p]",elem,op,this);
if (!elem)
return false;
if (op)
encodeOperation(op,elem,payload,err,searchArgs);
else if (elem->hasChildren())
encodeRaw(0,payload,elem,err);
if (elem->getTag() == s_component) {
AsnTag tag = ( op ? (searchArgs ? op->argTag : op->retTag) : s_noTag);
if (tag != s_noTag) {
payload.insert(ASNLib::buildLength(payload));
payload.insert(tag.coding());
}
}
return true;
}
bool XmlToTcap::handleComponent(NamedList& tcapParams, XmlElement* elem, const AppCtxt* appCtxt)
{
DDebug(&__plugin,DebugAll,"XMLToTcap::handleComponent(params=%p, elem=%p) [%p]",&tcapParams,elem,this);
if (!elem && elem->getTag() == s_component)
return false;
unsigned int index = tcapParams.getIntValue(s_tcapCompCount) + 1;
String prefix = s_tcapCompPrefix;
prefix << "." << index;
int type = 0;
const NamedList& comp = elem->attributes();
NamedString* opName = 0;
NamedString* errName = 0;
for (unsigned int i = 0; i < comp.length(); i++) {
NamedString* ns = comp.getParam(i);
if (TelEngine::null(ns))
continue;
if (ns->name() == s_typeStr) {
tcapParams.setParam(prefix + "." + s_tcapCompType,*ns);
type = SS7TCAP::lookupComponent(*ns);
}
else if (ns->name() == s_tcapOpCode)
opName = ns;
else if (ns->name() == s_tcapErrCode)
errName = ns;
else if (ns->name() == s_tcapProblemCode)
tcapParams.setParam(prefix + "." + s_tcapProblemCode,String(lookup(*ns,SS7TCAPError::s_errorTypes)));
else
tcapParams.setParam(prefix + "." + ns->name(),*ns);
}
tcapParams.setParam(s_tcapCompCount,String(index));
Operation* op = 0;
if (!type) {
Debug(&__plugin,DebugWarn,"Trying to encode component with index='%u' without component type",index);
return true;
}
if (type == SS7TCAP::TC_Invoke || type == SS7TCAP::TC_ResultLast || type == SS7TCAP::TC_ResultNotLast) {
if (opName) {
op = (Operation*)findOperation(m_app->type(),*opName,appCtxt);
if (!op)
Debug(&__plugin,DebugMild,"Cannot find operation='%s' in ctxt='%s' [%p]",opName->c_str(),(appCtxt ? appCtxt->name : ""),this);
else {
tcapParams.setParam(prefix + "." + s_tcapOpCode,String(op->code));
tcapParams.setParam(prefix + "." + s_tcapOpCodeType,(op->local ? "local" : "global"));
}
}
else {
if (type == SS7TCAP::TC_Invoke) {
Debug(&__plugin,DebugWarn,"Trying to encode Invoke component with index='%u' without operationCode",index);
return true;
}
}
}
else if (type == SS7TCAP::TC_U_Error) {
if (!errName) {
Debug(&__plugin,DebugWarn,"Trying to encode U_Error component with index='%u' without errorCode",index);
return true;
}
op = (Operation*)findError(m_app->type(),*errName);
if (!op)
Debug(&__plugin,DebugMild,"Cannot find error='%s' [%p]",errName->c_str(),this);
else {
tcapParams.setParam(prefix + "." + s_tcapErrCode,String(op->code));
tcapParams.setParam(prefix + "." + s_tcapErrCodeType,(op->local ? "local" : "global"));
}
}
DataBlock payload;
bool searchArgs = (type == SS7TCAP::TC_Invoke || type == SS7TCAP::TC_U_Error ? true : false);
int err = TcapXApplication::NoError;
if (!encodeComponent(payload,elem,searchArgs,err,op))
return false;
String str;
str.hexify(payload.data(),payload.length(),' ');
tcapParams.setParam(prefix,str);
return true;
}
bool XmlToTcap::handleMAPDialog(NamedList& tcapParams, XmlElement* elem, String prefix)
{
DDebug(&__plugin,DebugAll,"XMLToTcap::handleMAPDialog(params=%p, elem=%p, prefix=%s) [%p]",&tcapParams,elem,prefix.c_str(),this);
if (!elem && elem->getTag() != s_userInformation)
return false;
XmlElement* content = elem->findFirstChild(&s_encodingContentsTag);
if (!(content && content->findFirstChild()))
return parse(tcapParams,elem,prefix,0);
DataBlock payload;
const Parameter* param = s_mapDialogChoice;
int err = TcapXApplication::NoError;
while (param && param->name) {
DataBlock db;
if (encodeParam(param,db,content,err)) {
payload.append(db);
break;
}
param++;
}
XmlElement* child = content->pop();
while (child) {
DataBlock db;
encodeRaw(param,db,child,err);
payload.append(db);
TelEngine::destruct(child);
child = content->pop();
}
// set encoding contents and encoding contents type
String hexString;
hexString.hexify(payload.data(),payload.length(),' ');
tcapParams.setParam(s_tcapEncodingContent,hexString);
tcapParams.setParam(s_tcapEncodingType,YSTRING("single-ASN1-type-contructor"));
// set direct reference
XmlElement* reference = elem->findFirstChild(&s_directReferenceTag);
if (reference) {
const AppCtxt* appCtxt = findCtxtFromStr(reference->getText(),s_mapDialogCtxt);
if (!appCtxt)
tcapParams.setParam(s_tcapDirectReference,reference->getText());
else
tcapParams.setParam(s_tcapDirectReference,appCtxt->oid);
}
else {
// find reference for decoded param
const AppCtxt* ctxt = s_mapDialogCtxt;
while (ctxt && ctxt->name) {
bool ok = (param && ctxt->ops.find(param->name));
if (ok) {
tcapParams.setParam(s_tcapDirectReference,ctxt->oid);
break;
}
}
}
return true;
}
bool XmlToTcap::parse(NamedList& tcapParams)
{
Lock l(this);
XDebug(&__plugin,DebugAll,"XmlToTcap::parse()");
tcapParams.setParam(s_tcapCompCount,String(0));
XmlElement* ctxtElem = (m_elem ? m_elem->findFirstChild(&s_appContext) : 0);
XmlElement* ltidElem = (m_elem ? m_elem->findFirstChild(&s_localTID) : 0);
XmlElement* rtidElem = (m_elem ? m_elem->findFirstChild(&s_remoteTID) : 0);
const AppCtxt* appCtxt = 0;
// try to find the associated context for the given ids
if (ltidElem || rtidElem) {
appCtxt = m_app->findCtxt((ltidElem ? ltidElem->getText() : String::empty()),(rtidElem ? rtidElem->getText() : String::empty()));
}
//if we didn't find a saved context for the current transaction, search context in the XML info
if (!appCtxt && ctxtElem)
appCtxt = (AppCtxt*)findCtxtFromStr(ctxtElem->getText(),(m_app->type() == TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt));
bool ok = parse(tcapParams,m_elem,"",appCtxt);
NamedString* c = tcapParams.getParam(s_capabTag);
if (!c) {
c = tcapParams.getParam(s_tcapReqType);
if (c) {
m_type = Tcap;
// retrieve application context
NamedString* ctxt = tcapParams.getParam(s_tcapAppCtxt);
if (!TelEngine::null(ctxt)) {
const AppCtxt* search = (m_app->type() == TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt);
AppCtxt* appCtxt = (AppCtxt*)findCtxtFromStr(*ctxt,search);
if (appCtxt)
tcapParams.setParam(s_tcapAppCtxt,appCtxt->oid);
}
// retrieve MAP dialog context
ctxt = tcapParams.getParam(s_tcapDirectReference);
if (!TelEngine::null(ctxt)) {
const AppCtxt* search = (m_app->type() == TcapXUser::MAP ? s_mapDialogCtxt : 0);
AppCtxt* appCtxt = (AppCtxt*)findCtxtFromStr(*ctxt,search);
if (appCtxt)
tcapParams.setParam(s_tcapDirectReference,appCtxt->oid);
}
// we shoudn't receive P_Abort from application, but make sure anyway
ctxt = tcapParams.getParam(s_tcapAbortCause);
if (!TelEngine::null(ctxt) && (*ctxt) == "pAbort") {
ctxt = tcapParams.getParam(s_tcapAbortInfo);
int code = lookup(*ctxt,SS7TCAPError::s_errorTypes);
*ctxt = String(code);
}
}
}
else
m_type = Capability;
return ok;
}
bool XmlToTcap::parse(NamedList& tcapParams, XmlElement* elem, String prefix, const AppCtxt* appCtxt)
{
XDebug(&__plugin,DebugAll,"XmlToTcap::parse(elem=%p, prefix=%s) [%p]",elem,prefix.c_str(),this);
if (!elem)
return true;
bool status = true;
bool hasChildren = false;
while (XmlElement* child = elem->pop()) {
hasChildren = true;
if (child->getTag() == s_component)
status = handleComponent(tcapParams,child,appCtxt);
else if (child->getTag() == s_userInformation && m_app->type() == TcapXUser::MAP)
status = handleMAPDialog(tcapParams,child,(!TelEngine::null(prefix) ? prefix + "." + child->getTag() : child->getTag()));
else
status = parse(tcapParams,child, (!TelEngine::null(prefix) ? prefix + "." + child->getTag() : child->getTag()),appCtxt);
TelEngine::destruct(child);
if (!status)
break;
}
const NamedList& attrs = elem->attributes();
for (unsigned int i = 0; i < attrs.count(); i++) {
NamedString* ns = attrs.getParam(i);
if (TelEngine::null(ns))
continue;
String find = (!TelEngine::null(prefix) ? prefix + "." + ns->name() : ns->name());
const TCAPMap* map = findMap(find);
if (map) {
if (TelEngine::null(map->name))
tcapParams.addParam(find,*ns);
else {
if (map->isPrefix)
tcapParams.addParam(map->name + "." + ns->name(),*ns);
else
tcapParams.addParam(map->name,*ns);
}
}
}
if (!hasChildren) {
const TCAPMap* map = findMap(prefix);
if (map) {
if (map->isPrefix) {
if (!TelEngine::null(map->name))
tcapParams.addParam(map->name + "." + elem->getTag(),elem->getText());
else
tcapParams.addParam(elem->getTag(),elem->getText());
}
else {
if (!TelEngine::null(map->name))
tcapParams.addParam(map->name,elem->getText());
else
tcapParams.addParam(elem->getTag(),elem->getText());
}
}
}
return status;
}
/**
* TcapXApplication
*/
TcapXApplication::TcapXApplication(const char* name, Socket* skt, TcapXUser* user)
: Mutex(true,name),
m_io(0), m_name(name), m_user(user),
m_sentXml(0), m_receivedXml(0),
m_sentTcap(0), m_receivedTcap(0),
m_state(Waiting),
m_tcap2Xml(this),
m_xml2Tcap(this)
{
if (skt) {
m_io = new XMLConnection(skt,this);
if (!m_io->startup()) {
delete m_io;
m_io = 0;
}
}
m_type = user->type();
Debug(&__plugin,DebugAll,"TcapXApplication created with name=%s and connection=%p [%p]",m_name.c_str(),m_io,this);
}
TcapXApplication::~TcapXApplication()
{
Debug(&__plugin,DebugAll,"TcapXApplication with name=%s destroyed [%p]",m_name.c_str(),this);
closeConnection();
while (m_io)
Thread::idle();
m_user = 0;
}
bool TcapXApplication::hasCapability(const char* cap)
{
if (!cap)
return false;
DDebug(&__plugin,DebugAll,"TcapXApplication::hasCapability(cap=%s) [%p]",cap,this);
Lock l(this);
ObjList* o = m_capab.find(cap);
if (!o)
return false;
String* str = static_cast<String*>(o->get());
if (!(str && (*str == cap)))
return false;
return true;
}
bool TcapXApplication::canHandle(NamedList& params)
{
DDebug(&__plugin,DebugAll,"TcapXApplication::canHandle(params=%p) [%p]",&params,this);
if (m_state != Active)
return false;
int compCount = params.getIntValue(s_tcapCompCount,0);
// try matching on application context
const AppCtxt* appCtxt = 0;
while (true) {
NamedString* appOID = params.getParam(s_tcapAppCtxt);
if (TelEngine::null(appOID))
break;
appCtxt = findCtxtFromOid(*appOID,(m_type== TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt));
if (!appCtxt)
break;
const Capability* cap = findCapabilityOID(m_type,appCtxt->name);
if (!cap) {
if (!compCount)
return false;
break;
}
if (!hasCapability(cap->name) && !compCount) {
Debug(&__plugin,DebugAll,"TcapXApplication '%s' cannot handle oid='%s' [%p]",m_name.c_str(),appCtxt->name,this);
return false;
}
break;
}
if (!compCount && !appCtxt)
return false;
for (int i = 1; i <= compCount; i++) {
NamedString* opCode = params.getParam(s_tcapCompPrefixSep + String(i) + "." + s_tcapOpCode);
NamedString* opType = params.getParam(s_tcapCompPrefixSep + String(i) + "." + s_tcapOpCodeType);
if (TelEngine::null(opCode) || TelEngine::null(opType))
continue;
const Operation* op = findOperation(m_type,opCode->toInteger(),(*opType == "local"),appCtxt);
if (!op)
return false;
const Capability* cap = findCapability(m_type,op->name);
if (!cap)
return false;
if (!hasCapability(cap->name)) {
Debug(&__plugin,DebugAll,"TcapXApplication '%s' cannot handle operation='%s' [%p]",m_name.c_str(),op->name.c_str(),this);
return false;
}
}
return true;
}
void TcapXApplication::closeConnection()
{
DDebug(&__plugin,DebugAll,"TcapXApplication::closeConnection() - app=%s closing [%p]",m_name.c_str(),this);
Lock l(this);
if (m_io)
m_io->cancel();
l.drop();
}
void TcapXApplication::setIO(XMLConnection* io)
{
DDebug(&__plugin,DebugAll,"TcapXApplication::setIO(io=%p) - app=%s[%p]",io,m_name.c_str(),this);
Lock l(this);
if (!m_io)
return;
m_io = io;
l.drop();
if (!io && m_user)
m_user->removeApp(this);
}
bool TcapXApplication::supportCapability(const String& capab)
{
if (!findDefCapability(m_type,capab))
return false;
return true;
}
bool TcapXApplication::handleXML()
{
Debug(&__plugin,DebugAll,"TcapXApplication::handleXML() - %s[%p]",m_name.c_str(),this);
if (!m_xml2Tcap.checkXmlns()) {
Debug(&__plugin,DebugInfo,"TcapXApplication=%s - XMLNS mismatch, closing the connection [%p]",m_name.c_str(),this);
closeConnection();
return false;
}
NamedList params("xml");
if (!m_xml2Tcap.parse(params)) {
Debug(&__plugin,DebugInfo,"TcapXApplication=%s - parse error, closing the connection [%p]",m_name.c_str(),this);
closeConnection();
return false;
};
if (m_user->printMessages()) {
String tmp;
params.dump(tmp,"\r\n ",'\'',true);
Debug(&__plugin,DebugAll,"App=%s[%p] parsed params %s from xml",m_name.c_str(),this,tmp.c_str());
}
switch (m_xml2Tcap.type()) {
case XmlToTcap::Capability:
return handleCapability(params);
case XmlToTcap::Tcap:
return handleTcap(params);
case XmlToTcap::Unknown:
default:
Debug(&__plugin,DebugInfo,"TcapXApplication=%s - unknown XML message [%p]",m_name.c_str(),this);
closeConnection();
return false;
}
return true;
}
bool TcapXApplication::sendTcapMsg(NamedList& params, const AppCtxt* ctxt)
{
DDebug(&__plugin,DebugAll,"TcapXApplication::sentTcapMsg(params=%p) [%p]",&params,this);
XmlFragment* msg = new XmlFragment();
bool ok = m_tcap2Xml.buildXMLMessage(params,msg,TcapToXml::Tcap,ctxt);
if (m_user->printMessages()) {
String tmp;
msg->toString(tmp,false,"\r\n"," ",false);
Debug(&__plugin,DebugInfo,"App=%s[%p] is sending XML\r\n%s",m_name.c_str(),this,tmp.c_str());
}
if (ok && m_io) {
m_io->writeData(msg);
m_sentXml++;
}
delete msg;
return ok;
}
bool TcapXApplication::handleCapability(NamedList& params)
{
DDebug(&__plugin,DebugAll,"TcapXApplication::handleCapability() - app=%s [%p]",m_name.c_str(),this);
Lock l(this);
bool firstCap = true;
for (unsigned int i = 0; i < params.count(); i++) {
NamedString* ns = params.getParam(i);
if (!ns)
continue;
if (ns->name() == s_capabTag) {
if (TelEngine::null(ns)) {
m_capab.clear();
reportState(ShutDown);
return true;
}
else {
if (!supportCapability(*ns)) {
reportState(Inactive,String("Unsupported: ") + *ns);
return false;
}
if (firstCap && m_state == Active) {
m_capab.clear();
firstCap = false;
}
m_capab.append(new String(*ns));
}
}
}
if (m_state == Waiting)
reportState(Active);
return true;
}
bool TcapXApplication::handleIndication(NamedList& tcap)
{
DDebug(&__plugin,DebugAll,"TcapXApplication::handleIndication() - app=%s state=%s [%p]",m_name.c_str(),lookup(m_state,s_appStates),this);
if (m_user->printMessages()) {
String tmp;
tcap.dump(tmp,"\r\n ",'\'',true);
Debug(&__plugin,DebugInfo,"App=%s[%p] received TCAP indication %s",m_name.c_str(),this,tmp.c_str());
}
int dialog = SS7TCAP::lookupTransaction(tcap.getValue(s_tcapReqType));
String ltid = tcap.getValue(s_tcapLocalTID);
NamedString* rtid = tcap.getParam(s_tcapRemoteTID);
bool saveID = false, removeID = false;
String appID;
switch (dialog) {
case SS7TCAP::TC_Unidirectional:
if (state() != Active)
return false;
tcap.setParam(s_tcapLocalTID,"");
break;
case SS7TCAP::TC_Begin:
case SS7TCAP::TC_QueryWithPerm:
case SS7TCAP::TC_QueryWithoutPerm:
if (state() != Active || TelEngine::null(rtid))
return false;
tcap.setParam(s_tcapLocalTID,"");
saveID = true;
break;
case SS7TCAP::TC_Continue:
case SS7TCAP::TC_ConversationWithPerm:
case SS7TCAP::TC_ConversationWithoutPerm:
case SS7TCAP::TC_Notice:
case SS7TCAP::TC_Unknown:
if (TelEngine::null(ltid))
return false;
lock();
appID = m_ids.findAppID(ltid);
if (TelEngine::null(appID)) {
if (TelEngine::null(rtid)){
unlock();
reportError("Unknown request ID");
return false;
}
appID = m_pending.findTcapID(*rtid);
if (TelEngine::null(appID)) {
unlock();
reportError("Unknown request ID");
return false;
}
m_pending.remove(*rtid);
}
unlock();
break;
case SS7TCAP::TC_End:
case SS7TCAP::TC_Response:
case SS7TCAP::TC_U_Abort:
case SS7TCAP::TC_P_Abort:
if (TelEngine::null(ltid))
return false;
lock();
appID = m_ids.findAppID(ltid);
if (TelEngine::null(appID)) {
appID = m_pending.findAppID(ltid);
if (TelEngine::null(appID)) {
unlock();
reportError("Unknown request ID");
return false;
}
m_pending.remove(appID);
}
unlock();
removeID = true;
break;
default:
return false;
}
tcap.setParam(s_tcapLocalTID,appID);
const AppCtxt* ctxt = 0;
if (saveID) {
NamedString* oid = tcap.getParam(s_tcapAppCtxt);
if (!TelEngine::null(oid))
ctxt = findCtxtFromOid(*oid, m_type == TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt);
}
else
ctxt = findCtxt(appID,(TelEngine::null(rtid) ? String::empty() : *rtid));
bool ok = sendTcapMsg(tcap,ctxt);
Lock l(this);
if (saveID)
m_pending.appendID(ltid,*rtid,ctxt);
if (removeID) {
m_ids.remove(appID);
if (m_state == ShutDown && !trCount())
reportState(Inactive);
}
m_receivedTcap++;
return ok;
}
bool TcapXApplication::handleTcap(NamedList& tcap)
{
DDebug(&__plugin,DebugAll,"TcapXApplication::handleTcap() - app=%s state=%s [%p]",m_name.c_str(),lookup(m_state,s_appStates),this);
int dialog = SS7TCAP::lookupTransaction(tcap.getValue(s_tcapReqType));
String ltid = tcap.getValue(s_tcapLocalTID);
String rtid = tcap.getValue(s_tcapRemoteTID);
bool endNow = tcap.getBoolValue(s_tcapEndNow,false);
bool saveID = false;
bool removeID = false;
lock();
String tcapID = m_ids.findTcapID(ltid);
unlock();
switch (dialog) {
case SS7TCAP::TC_Unknown:
case SS7TCAP::TC_Unidirectional:
break;
case SS7TCAP::TC_Begin:
case SS7TCAP::TC_QueryWithPerm:
case SS7TCAP::TC_QueryWithoutPerm:
if (TelEngine::null(ltid)) {
reportError("Missing request ID");
return false;
}
if (!TelEngine::null(tcapID)) {
reportError("Duplicate request ID");
return false;
}
saveID = true;
break;
case SS7TCAP::TC_Continue:
case SS7TCAP::TC_ConversationWithPerm:
case SS7TCAP::TC_ConversationWithoutPerm:
if (TelEngine::null(ltid)) {
reportError("Missing request ID");
return false;
}
if (TelEngine::null(tcapID)) {
if (!TelEngine::null(rtid)) {
lock();
tcapID = m_pending.findTcapID(rtid);
unlock();
if (TelEngine::null(tcapID)) {
reportError("Unknown request ID");
return false;
}
lock();
m_pending.remove(rtid);
unlock();
saveID = true;
}
else {
reportError("Unknown request ID");
return false;
}
}
break;
case SS7TCAP::TC_End:
case SS7TCAP::TC_Response:
case SS7TCAP::TC_U_Abort:
if (TelEngine::null(ltid)) {
reportError("Missing request ID");
return false;
}
if (TelEngine::null(tcapID)) {
if (!TelEngine::null(rtid)) {
lock();
tcapID = m_pending.findTcapID(rtid);
unlock();
if (TelEngine::null(tcapID)) {
reportError("Unknown request ID");
return false;
}
lock();
m_pending.remove(rtid);
unlock();
}
else {
reportError("Unknown request ID");
return false;
}
}
removeID = true;
break;
case SS7TCAP::TC_P_Abort:
case SS7TCAP::TC_Notice:
default:
reportError("Invalid request");
return false;
}
if (!m_user)
return false;
tcap.setParam(s_tcapLocalTID,tcapID);
const AppCtxt* ctxt = 0;
if (saveID && !endNow) {
NamedString* ctxtStr = tcap.getParam(s_tcapAppCtxt);
if (!TelEngine::null(ctxtStr))
ctxt = findCtxtFromOid(*ctxtStr,(m_type == TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt));
}
if (m_user->printMessages()) {
String tmp;
tcap.dump(tmp,"\r\n ",'\'',true);
Debug(&__plugin,DebugInfo,"App=%s[%p] is sending TCAP request %s",m_name.c_str(),this,tmp.c_str());
}
SS7TCAPError error = m_user->applicationRequest(this,tcap,dialog);
if (error.error() != SS7TCAPError::NoError) {
NamedString* err = tcap.getParam(s_tcapRequestError);
reportError(TelEngine::null(err) ? error.errorName() : *err);
return false;
}
Lock l(this);
if (removeID || endNow) {
m_ids.remove(ltid);
if (m_state == ShutDown && !trCount())
reportState(Inactive);
}
if (saveID && !endNow)
m_ids.appendID(tcap.getValue(s_tcapLocalTID),ltid,ctxt);
m_sentTcap++;
return true;
}
void TcapXApplication::receivedXML(XmlDocument* doc)
{
Debug(&__plugin,DebugAll,"TcapXApplication::receivedXML(frag=%p) - %s[%p]",doc,m_name.c_str(),this);
if (!doc)
return;
if (m_user->printMessages()) {
String tmp;
doc->toString(tmp,false,"\r\n"," ");
Debug(&__plugin,DebugInfo,"App=%s[%p] received XML\r\n%s",m_name.c_str(),this,tmp.c_str());
}
if (!m_xml2Tcap.valid(doc)) {
Debug(&__plugin,DebugInfo,"TcapXApplication=%s - invalid message, closing the connection [%p]",m_name.c_str(),this);
closeConnection();
return;
}
if (m_state == Waiting && !m_xml2Tcap.hasDeclaration()) {
Debug(&__plugin,DebugInfo,"TcapXApplication=%s - initial XML declaration missing, closing the connection [%p]",m_name.c_str(),this);
closeConnection();
return;
}
if (m_xml2Tcap.hasDeclaration() && !m_xml2Tcap.validDeclaration()) {
Debug(&__plugin,DebugInfo,"TcapXApplication=%s - XML declaration mismatch, closing the connection [%p]",m_name.c_str(),this);
closeConnection();
return;
}
if (handleXML())
m_receivedXml++;
}
void TcapXApplication::reportState(State state, const char* error)
{
DDebug(&__plugin,DebugAll,"TcapXApplication::reportState(state=%s, error=%s) [%p]",lookup(state,s_appStates),error,this);
m_state = state;
switch (m_state) {
case Waiting:
break;
case Active:
sendStateResponse();
m_user->notifyManagementState();
break;
case ShutDown:
Debug(&__plugin,DebugInfo,"Requested shutdown, %d transactions pending [%p]",trCount(),this);
if (trCount())
break;
m_state = Inactive;
case Inactive:
sendStateResponse(error);
closeConnection();
default:
break;
}
}
void TcapXApplication::sendStateResponse(const char* error)
{
DDebug(&__plugin,DebugAll,"TcapXApplication::sendStateResponse(error=%s) [%p]",error,this);
NamedList params("xml");
params.setParam("state",lookup(m_state,s_appStates));
if (error)
params.setParam("error",error);
XmlFragment* msg = new XmlFragment();
bool ok = m_tcap2Xml.buildXMLMessage(params,msg,TcapToXml::State);
if (m_user->printMessages()) {
String tmp;
msg->toString(tmp,false,"\r\n"," ",false);
Debug(&__plugin,DebugInfo,"App=%s[%p] is sending XML\r\n%s",m_name.c_str(),this,tmp.c_str());
}
if (ok && m_io) {
m_io->writeData(msg);
m_sentXml++;
}
delete msg;
}
void TcapXApplication::reportError(const char* err)
{
if (!err)
return;
Debug(&__plugin,DebugInfo,"TcapXApplication::reportError(error=%s) - app=%s [%p]",err,m_name.c_str(),this);
}
void TcapXApplication::status(NamedList& status)
{
DDebug(&__plugin,DebugInfo,"TcapXApplication::status() [%p]",this);
Lock l(this);
status.setParam("receivedXML",String(m_receivedXml));
status.setParam("sentXML",String(m_sentXml));
status.setParam("receivedTcap",String(m_receivedTcap));
status.setParam("sentTcap",String(m_sentTcap));
}
const AppCtxt* TcapXApplication::findCtxt(const String& appID, const String& remoteID)
{
DDebug(DebugAll,"TcapXApplication::findCtxt('%s','%s') [%p]",appID.c_str(),remoteID.c_str(),this);
Lock l(this);
if (!appID.null()) {
Transaction* t = m_ids.findByAppID(appID);
if (t)
return t->context();
}
if (!remoteID.null()) {
Transaction* t = m_pending.findByAppID(remoteID);
if (t)
return t->context();
}
return 0;
}
/**
* TcapXUser
*/
TcapXUser::TcapXUser(const char* name)
: TCAPUser(name),
Mutex(true,name),
m_appsMtx(true,"TCAPXApps"),
m_listener(0), m_type(MAP),
m_printMsg(false), m_addEnc(false),
m_mngtStatus(SCCPManagement::UserOutOfService)
{
Debug(&__plugin,DebugAll,"TcapXUser '%s' created [%p]",toString().c_str(),this);
}
TcapXUser::~TcapXUser()
{
Debug(&__plugin,DebugAll,"TcapXUser '%s' destroyed [%p]",toString().c_str(),this);
lock();
if (m_listener)
m_listener->cancel();
if (tcap())
attach(0);
unlock();
m_appsMtx.lock();
for (ObjList* o = m_apps.skipNull(); o; o = o->skipNext()) {
TcapXApplication* app = static_cast<TcapXApplication*>(o->get());
if (app)
app->closeConnection();
}
m_appsMtx.unlock();
while (m_listener)
Thread::idle();
while (true) {
Thread::idle();
m_appsMtx.lock();
ObjList* o = m_apps.skipNull();
m_appsMtx.unlock();
if (!o)
break;
}
}
bool TcapXUser::initialize(NamedList& sect)
{
Debug(this,DebugAll,"TcapXUser::initialize() [%p]",this);
Lock l(this);
if (!m_listener) {
m_listener = new XMLConnListener(this,sect);
if (!m_listener->init()) {
delete m_listener;
m_listener = 0;
return false;
}
}
m_type = (UserType)lookup(sect.getValue(s_typeStr,"MAP"),s_userTypes,m_type);
m_printMsg = sect.getBoolValue(YSTRING("print-messages"),false);
m_addEnc = sect.getBoolValue(YSTRING("add-encoding"),false);
if (!tcap() && !findTCAP(sect.getValue("tcap",0)))
return false;
notifyManagementState(true);
return true;
}
void TcapXUser::removeApp(TcapXApplication* app)
{
Debug(this,DebugAll,"Removing application=%s[%p] [%p]",(app ? app->toString().c_str() : ""),app,this);
Lock l(m_appsMtx);
m_apps.remove(app);
l.drop();
notifyManagementState();
}
bool TcapXUser::tcapIndication(NamedList& params)
{
DDebug(this,DebugAll,"TcapXUser::tcapIndication() [%p]",this);
NamedString* ltid = params.getParam(s_tcapLocalTID);
if (TelEngine::null(ltid)) {
DDebug(this,DebugAll,"Received transaction without local transaction id, rejecting it");
return false;
}
int dialog = SS7TCAP::lookupTransaction(params.getValue(s_tcapReqType));
ObjList* o = m_trIDs.find(*ltid);
NamedString* tcapID = 0;
if (o)
tcapID = static_cast<NamedString*>(o->get());
bool searchApp = false, removeID = false;
switch (dialog) {
case SS7TCAP::TC_Unidirectional:
return sendToApp(params);
case SS7TCAP::TC_Begin:
case SS7TCAP::TC_QueryWithPerm:
case SS7TCAP::TC_QueryWithoutPerm:
if (TelEngine::null(ltid) || !TelEngine::null(tcapID)) {
DDebug(this,DebugAll,"Received a new transaction with an id that we already have, rejecting it");
return false;
}
return sendToApp(params);
case SS7TCAP::TC_Continue:
case SS7TCAP::TC_ConversationWithPerm:
case SS7TCAP::TC_ConversationWithoutPerm:
case SS7TCAP::TC_Notice:
case SS7TCAP::TC_Unknown:
if (TelEngine::null(ltid) || TelEngine::null(tcapID)) {
DDebug(this,DebugAll,"Received a dialog continue TCAP message for a dialog that doesn't exist, rejecting it");
return false;
}
searchApp = true;
break;
case SS7TCAP::TC_End:
case SS7TCAP::TC_Response:
case SS7TCAP::TC_U_Abort:
case SS7TCAP::TC_P_Abort:
if (TelEngine::null(ltid) || TelEngine::null(tcapID)) {
DDebug(this,DebugAll,"Received a end dialogue TCAP message for a dialog that doesn't exist, rejecting it");
return false;
}
searchApp = true;
removeID = true;
break;
default:
DDebug(this,DebugAll,"Received a TCAP message without type of dialog message, rejecting it");
return false;
}
Lock la(m_appsMtx);
o = m_apps.find(*tcapID);
if (!o && searchApp) {
Debug(this,DebugMild,"Cannot find application that was handling transaction with id='%s'",ltid->c_str());
return false;
}
TcapXApplication* app = static_cast<TcapXApplication*>(o->get());
if (searchApp && !app)
return false;
if (removeID) {
reorderApps(app);
m_trIDs.remove(tcapID);
}
la.drop();
return sendToApp(params,app,false);
}
bool TcapXUser::sendToApp(NamedList& params, TcapXApplication* app, bool saveID)
{
DDebug(this,DebugAll,"TcapXUser::sendToApp(params=%p,app=%s[%p]) [%p]",&params,(app ? app->toString().c_str() : ""),app,this);
Lock l(m_appsMtx);
if (!app)
app = findApplication(params);
if (!app) {
NamedString* opCode = params.getParam(YSTRING("tcap.component.1.operationCode"));
NamedString* opType = params.getParam(YSTRING("tcap.component.1.operationCodeType"));
NamedString* appCtxt = params.getParam(s_tcapAppCtxt);
if (!(TelEngine::null(opCode) || TelEngine::null(opType))) {
const Operation* op = findOperation(m_type,opCode->toInteger(),(*opType == "local"),0);
Debug(this,DebugInfo,"TcapXUser::sendToApp() - cannot find application to handle operation='%s' [%p]",(op ? op->name.c_str() : "no operation"),this);
}
else {
if (!TelEngine::null(appCtxt))
Debug(this,DebugInfo,"TcapXUser::sendToApp() - cannot find application to handle application OID='%s' [%p]",appCtxt->c_str(),this);
else
Debug(this,DebugInfo,"TcapXUser::sendToApp() - cannot find application to handle transaction with no given operation or app OID [%p]",this);
}
return false;
}
if (saveID)
m_trIDs.append(new NamedString(params.getValue(s_tcapLocalTID),app->toString()));
return (app && app->handleIndication(params));
}
TcapXApplication* TcapXUser::findApplication(NamedList& params)
{
DDebug(this,DebugAll,"TcapXUser::findApplication() [%p]",this);
for (ObjList* o = m_apps.skipNull(); o; o = o->skipNext()) {
TcapXApplication* app = static_cast<TcapXApplication*>(o->get());
if (app->canHandle(params)) {
// reorder list
reorderApps(app);
return app;
}
}
return 0;
}
void TcapXUser::reorderApps(TcapXApplication* app)
{
if (!app)
return;
ObjList* appObj = m_apps.find(app);
if (!appObj)
return;
ObjList* next = appObj->next();
// it's already at the bottom of the list
if (!next)
return;
unsigned int count = app->trCount() + 1;
while (next) {
TcapXApplication* nextApp = static_cast<TcapXApplication*>(next->get());
if (nextApp) {
if (count < nextApp->trCount())
break;
next = next->next();
}
else
break;
}
if (next) {
if (next != appObj->next()) {
m_apps.remove(app,false);
next->insert(app);
return;
}
}
else {
m_apps.remove(app,false);
m_apps.append(app);
}
}
void TcapXUser::statusString(String& str)
{
DDebug(this,DebugAll,"TcapXUser::statusString() [%p]",this);
Lock l(m_appsMtx);
NamedList params("");
for (ObjList* o = m_apps.skipNull(); o; o = o->skipNext()) {
TcapXApplication* app = static_cast<TcapXApplication*>(o->get());
if (!app)
continue;
str.append(app->toString(),",") << "=" << toString() << "|" << lookup(m_type,s_userTypes);
app->status(params);
str << "|" << params.getIntValue(YSTRING("receivedXML"));
str << "|" << params.getIntValue(YSTRING("sentXML"));
str << "|" << params.getIntValue(YSTRING("receivedTcap"));
str << "|" << params.getIntValue(YSTRING("sentTcap"));
}
}
bool TcapXUser::managementNotify(SCCP::Type type, NamedList& params)
{
// TODO
// check docs if they say anything about management
return true;
}
bool TcapXUser::findTCAP(const char* name)
{
if (!name)
return false;
SignallingComponent* tcap = 0;
SignallingEngine* engine = SignallingEngine::self(true);
if (engine)
tcap = engine->find(name,"SS7TCAPITU",tcap);
if (tcap) {
Debug(this,DebugAll,"TcapXUser '%s' attaching to TCAP=%s [%p]",toString().c_str(),name,this);
attach(YOBJECT(SS7TCAPITU,tcap));
}
return (tcap != 0);
}
bool TcapXUser::createApplication(Socket* skt, String& addr)
{
if (!skt)
return false;
String appName = toString() + ":" + addr;
Lock l(m_appsMtx);
// it's new, put it at the top of the list
m_apps.insert(new TcapXApplication(appName,skt,this));
return true;
}
int TcapXUser::managementState()
{
DDebug(this,DebugAll,"TcapXUser::managementState() - user=%s[%p]",toString().c_str(),this);
Lock l(m_appsMtx);
for (ObjList* o = m_apps.skipNull(); o; o = o->skipNext()) {
TcapXApplication* app = static_cast<TcapXApplication*>(o->get());
if (!app)
continue;
if (app->state() == TcapXApplication::Active)
return SCCPManagement::UserInService;
}
return SCCPManagement::UserOutOfService;
}
void TcapXUser::notifyManagementState(bool forced)
{
DDebug(this,DebugAll,"TcapXUser::notifyManagementState(forced=%s) [%p]",String::boolText(forced),this);
SCCPManagement::LocalBroadcast state = (SCCPManagement::LocalBroadcast)managementState();
Lock l(this);
if (forced || state != m_mngtStatus) {
Debug(this,DebugInfo,"Changing management state from '%s' to '%s' [%p]",
lookup(m_mngtStatus,SCCPManagement::broadcastType(),""),lookup(state,SCCPManagement::broadcastType(),""),this);
m_mngtStatus = state;
l.drop();
if (tcap()) {
NamedList p("");
tcap()->updateUserStatus(this,state,p);
}
}
}
void TcapXUser::setListener(XMLConnListener* list)
{
Lock l(this);
m_listener = list;
}
SS7TCAPError TcapXUser::applicationRequest(TcapXApplication* app, NamedList& params, int reqType)
{
DDebug(this,DebugAll,"TcapXUser::applicationRequest() - user=%s, request from app=%s[%p] [%p]",
toString().c_str(),(app ? app->toString().c_str() : ""),app,this);
SS7TCAPError error((tcap() ? tcap()->tcapType() : SS7TCAP::ITUTCAP));
if (!app)
return error;
if (tcap()) {
params.setParam(s_tcapUser,toString());
error = tcap()->userRequest(params);
}
else {
params.setParam(s_tcapRequestError,"No TCAP attached");
error.setError(SS7TCAPError::Transact_UnassignedTransactionID);
return error;
}
bool saveID = false;
bool removeID = false;
switch (reqType) {
case SS7TCAP::TC_Begin:
case SS7TCAP::TC_QueryWithPerm:
case SS7TCAP::TC_QueryWithoutPerm:
saveID = true;
break;
case SS7TCAP::TC_End:
case SS7TCAP::TC_Response:
case SS7TCAP::TC_U_Abort:
removeID = true;
break;
case SS7TCAP::TC_P_Abort:
case SS7TCAP::TC_Notice:
case SS7TCAP::TC_Unknown:
case SS7TCAP::TC_Unidirectional:
case SS7TCAP::TC_Continue:
case SS7TCAP::TC_ConversationWithPerm:
case SS7TCAP::TC_ConversationWithoutPerm:
default:
break;
}
Lock la(m_appsMtx);
NamedString* ltid = params.getParam(s_tcapLocalTID);
if (saveID) {
reorderApps(app);
if (TelEngine::null(ltid)) {
params.setParam(s_tcapRequestError,"TCAP error");
error.setError(SS7TCAPError::Transact_UnassignedTransactionID);
}
else
m_trIDs.append(new NamedString(*ltid,app->toString()));
}
if (removeID) {
reorderApps(app);
if (TelEngine::null(ltid) ||!m_trIDs.find(*ltid))
error.setError(SS7TCAPError::Transact_UnassignedTransactionID);
else
m_trIDs.remove(*ltid);
}
return error;
}
/**
* TcapXModule
*/
TcapXModule::TcapXModule()
: Module("camel_map","misc"),
m_usersMtx(true,"TCAPXUsers")
{
Output("Loaded TCAPXML module");
}
TcapXModule::~TcapXModule()
{
Output("Unloaded module TCAPXML");
}
void TcapXModule::initialize()
{
Output("Initializing module TCAPXML");
Module::initialize();
Configuration cfg(Engine::configFile(name()));
installRelay(Halt);
cfg.load();
m_showMissing = cfg.getBoolValue(YSTRING("general"),YSTRING("show-missing"),true);
initUsers(cfg);
}
bool TcapXModule::unload()
{
if (!lock(500000))
return false;
uninstallRelays();
m_users.clear();
unlock();
return true;
}
void TcapXModule::initUsers(Configuration& cfg)
{
DDebug(&__plugin,DebugAll,"TcapXModule::initUsers() [%p]",this);
int n = cfg.sections();
Lock l(m_usersMtx);
for (int i = 0; i < n; i++) {
NamedList* sect = cfg.getSection(i);
if (!sect)
continue;
String name(*sect);
if (name.startSkip("tcap") && name) {
if (!sect->getBoolValue("enable",true)) {
m_users.remove(name);
continue;
}
ObjList* o = m_users.find(name);
TcapXUser* usr = (o ? static_cast<TcapXUser*>(o->get()) : 0);
if (!usr) {
usr = new TcapXUser(name);
usr->debugChain(&__plugin);
m_users.append(usr);
}
if (!usr->initialize(*sect)) {
Debug(&__plugin,DebugInfo,"TcapXModule::initUsers() - user '%s' failed to initialize [%p]",name.c_str(),this);
m_users.remove(name);
}
}
}
}
bool TcapXModule::received(Message& msg, int id)
{
if (id == Halt)
unload();
return Module::received(msg,id);
}
unsigned int TcapXModule::applicationCount()
{
Lock l(m_usersMtx);
unsigned int count = 0;
for (ObjList* o = m_users.skipNull(); o; o = o->skipNext()) {
TcapXUser* user = static_cast<TcapXUser*>(o->get());
count += user->applicationCount();
}
return count;
}
void TcapXModule::statusModule(String& str)
{
Module::statusModule(str);
str.append("format=User|Type|ReceivedXML|SentXML|ReceivedTCAP|SentTcap",",");
}
void TcapXModule::statusParams(String& str)
{
str.append("count=",",") << applicationCount();
}
void TcapXModule::statusDetail(String& str)
{
Lock l(m_usersMtx);
for (ObjList* o = m_users.skipNull(); o; o = o->skipNext()) {
TcapXUser* user = static_cast<TcapXUser*>(o->get());
if (!user)
continue;
user->statusString(str);
}
}
}; // anonymous namespace
/* vi: set ts=8 sw=4 sts=4 noet enc=utf-8: */