/** * 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) 2004 - 2011 Null Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include using namespace TelEngine; namespace { class TcapXUser; class TcapXModule; class XMLConnListener; class XMLConnection; class TcapXApplication; class TcapToXml; class XmlToTcap; class TcapXNamespace; 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 AppCtxt { const char* name; const char* oid; const String ops; }; struct Capability { const char* name; String ops[30]; }; 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() { 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: bool m_init; 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_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; 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(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); if (TelEngine::null(clas)) { if (param) 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 (param) 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(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(¶m->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,DebugGoOn,"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(); data.unHexify(text.c_str(),text.length(),' '); 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(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(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(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(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(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(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(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(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(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(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(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(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(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[] = "0123456789ABCD?."; 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 Capability s_mapCapab[] = { {"LocationManagement", {"updateLocation", "cancelLocation", "purgeMS", "updateGprsLocation", "anyTimeInterrogation", ""}}, {"Authentication", {"sendAuthenticationInfo", "authenticationFailureReport", ""}}, {"SubscriberData", {"insertSubscriberData", "deleteSubscriberData", "restoreData", ""}}, {"Routing", {"sendRoutingInfoForGprs", "sendRoutingInfoForLCS", "statusReport", ""}}, {"VLR-Routing", {"provideRoamingNumber", ""}}, {"TraceSubscriber", {"activateTraceMode", "deactivateTraceMode", ""}}, {"Services", {"registerSS", "eraseSS", "activateSS", "deactivateSS", "interrogateSS", "registerPassword", "getPassword", "processUnstructuredSS-Request", "unstructuredSS-Request", "unstructuredSS-Notify", ""}}, {"Miscellaneous", {"sendIMSI", "readyForSM", "setReportingState", "sendParameters", ""}}, {"ErrorRecovery", {"reset", "forwardCheckSS-Indication", "failureReport", ""}}, {"Charging", {""}}, {"SMSC", {"informServiceCentre", "alertServiceCentre", "sendRoutingInfoForSM", "mo-forwardSM", "mt-forwardSM", "forwardSM", "reportSM-DeliveryStatus", ""}}, {"None", {""}}, {0, {""}}, }; static const AppCtxt s_mapAppCtxt[]= { // Network Loc Up context {"networkLocUpContext-v3", "0.4.0.0.1.0.1.3", "updateLocation,forwardCheckSS-Indication,restoreData,insertSubscriberData," "activateTraceMode"}, {"networkLocUpContext-v2", "0.4.0.0.1.0.1.2", "updateLocation,forwardCheckSS-Indication,restoreData,insertSubscriberData," "activateTraceMode"}, {"networkLocUpContext-v1", "0.4.0.0.1.0.1.1", "updateLocation,forwardCheckSS-Indication,sendParameters,insertSubscriberData," "activateTraceMode"}, // Location Cancellation context {"locationCancelationContext-v3", "0.4.0.0.1.0.2.3", "cancelLocation"}, {"locationCancelationContext-v2", "0.4.0.0.1.0.2.2", "cancelLocation"}, {"locationCancelationContext-v1", "0.4.0.0.1.0.2.1", "cancelLocation"}, // Roaming Number Enquiry Context {"roamingNumberEnquiryContext-v3", "0.4.0.0.1.0.3.3", "provideRoamingNumber"}, {"roamingNumberEnquiryContext-v2", "0.4.0.0.1.0.3.2", "provideRoamingNumber"}, {"roamingNumberEnquiryContext-v1", "0.4.0.0.1.0.3.1", "provideRoamingNumber"}, // Location Info Retrieval Context {"locationInfoRetrievalContext-v3", "0.4.0.0.1.0.5.3", "sendRoutingInfo"}, {"locationInfoRetrievalContext-v2", "0.4.0.0.1.0.5.2", "sendRoutingInfo"}, {"locationInfoRetrievalContext-v1", "0.4.0.0.1.0.5.1", "sendRoutingInfo"}, // Reporting Context {"reportingContext-v3", "0.4.0.0.1.0.7.3", "setReportingState,statusReport,remoteUserFree"}, // Reset context {"resetContext-v2", "0.4.0.0.1.0.10.2", "reset"}, {"resetContext-v1", "0.4.0.0.1.0.10.1", "reset"}, // Info retrieval context {"infoRetrievalContext-v3", "0.4.0.0.1.0.14.3", "sendAuthenticationInfo"}, {"infoRetrievalContext-v2", "0.4.0.0.1.0.14.2", "sendAuthenticationInfo"}, {"infoRetrievalContext-v1", "0.4.0.0.1.0.14.1", "sendParameters"}, // Subscriber Data Management Context {"subscriberDataMngtContext-v3", "0.4.0.0.1.0.16.3", "insertSubscriberData,deleteSubscriberData"}, {"subscriberDataMngtContext-v2", "0.4.0.0.1.0.16.2", "insertSubscriberData,deleteSubscriberData"}, {"subscriberDataMngtContext-v1", "0.4.0.0.1.0.16.1", "insertSubscriberData,deleteSubscriberData"}, // Tracing context {"tracingContext-v3", "0.4.0.0.1.0.17.3", "activateTraceMode,deactivateTraceMode"}, {"tracingContext-v2", "0.4.0.0.1.0.17.2", "activateTraceMode,deactivateTraceMode"}, {"tracingContext-v1", "0.4.0.0.1.0.17.1", "activateTraceMode,deactivateTraceMode"}, // Network functional SS context {"networkFunctionalSsContext-v2", "0.4.0.0.1.0.18.2", "registerSS,eraseSS,activateSS,deactivateSS," "interrogateSS,registerPassword,getPassword"}, {"networkFunctionalSsContext-v1", "0.4.0.0.1.0.18.1", "registerSS,eraseSS,activateSS,deactivateSS," "interrogateSS,registerPassword,getPassword"}, // Network unstructured SS context {"networkUnstructuredSsContext-v2", "0.4.0.0.1.0.19.2", "processUnstructuredSS-Request,unstructuredSS-Request,unstructuredSS-Notify"}, {"networkUnstructuredSsContext-v1", "0.4.0.0.1.0.19.1", "processUnstructuredSS-Data"}, // Short message routing {"shortMsgGatewayContext-v3", "0.4.0.0.1.0.20.3", "sendRoutingInfoForSM,informServiceCentre,reportSM-DeliveryStatus"}, {"shortMsgGatewayContext-v2", "0.4.0.0.1.0.20.2", "sendRoutingInfoForSM,informServiceCentre,reportSM-DeliveryStatus"}, {"shortMsgGatewayContext-v1", "0.4.0.0.1.0.20.1", "sendRoutingInfoForSM,informServiceCentre,reportSM-DeliveryStatus"}, // Mobile Originated short messages {"shortMsgMO-RelayContext-v3", "0.4.0.0.1.0.21.3", "mo-forwardSM"}, {"shortMsgMO-RelayContext-v2", "0.4.0.0.1.0.21.2", "forwardSM"}, {"shortMsgMO-RelayContext-v1", "0.4.0.0.1.0.21.1", "forwardSM"}, // Short message alerts {"shortMsgAlertContext-v2", "0.4.0.0.1.0.23.2", "alertServiceCentre"}, {"shortMsgAlertContext-v1", "0.4.0.0.1.0.23.1", "alertServiceCentre"}, // readyForSM context {"mwdMngtContext-v3", "0.4.0.0.1.0.24.3", "readyForSM"}, {"mwdMngtContext-v2", "0.4.0.0.1.0.24.2", "readyForSM"}, {"mwdMngtContext-v1", "0.4.0.0.1.0.24.1", "readyForSM"}, // Mobile Terminated short messages {"shortMsgMT-RelayContext-v3", "0.4.0.0.1.0.25.3", "mt-forwardSM"}, {"shortMsgMT-RelayContext-v2", "0.4.0.0.1.0.25.2", "forwardSM"}, // sendIMSI Context {"imsiRetrievalContext-v2", "0.4.0.0.1.0.26.2", "sendIMSI"}, // MS Purging Context {"msPurgingContext-v3", "0.4.0.0.1.0.27.3", "purgeMS"}, {"msPurgingContext-v2", "0.4.0.0.1.0.27.2", "purgeMS"}, // Any Time Info Enquiry Context {"anyTimeInfoEnquiryContext-v3", "0.4.0.0.1.0.29.3", "anyTimeInterrogation"}, // GPRS Location Update Context {"gprsLocationUpdateContext-v3", "0.4.0.0.1.0.32.3", "updateGprsLocation,insertSubscriberData,activateTraceMode"}, // GPRS Location Info Retrieval Context {"gprsLocationInfoRetrievalContext-v3" , "0.4.0.0.1.0.33.3", "sendRoutingInfoForGprs"}, // Failure Report Context {"failureReportContext-v3" , "0.4.0.0.1.0.34.3", "failureReport"}, // Location Services Gateway Context {"locationSvcGatewayContext-v3", "0.4.0.0.1.0.37.3", "sendRoutingInfoForLCS"}, // Authentication Failure Report Context {"authenticationFailureReportContext-v3" , "0.4.0.0.1.0.39.3", "authenticationFailureReport"}, {0, 0, ""}, }; static const AppCtxt s_camelAppCtxt[] = { {"CAP-v2-gsmSSF-to-gsmSCF-AC", "0.4.0.0.1.0.50.1", "initialDP,establishTemporaryConnection,connectToResource," "disconnectForwardConnection,connect,releaseCall,eventReportBCSM," "requestReportBCSMEvent,applyChargingReport,applyCharging,continue," "resetTimer,furnishChargingInformation,callInformationReport," "callInformationRequest,sendChargingInformation,specializedResourceReport," "playAnnouncement,promptAndCollectUserInformation,cancel,activityTest"}, {"CAP-v2-assist-gsmSSF-to-gsmSCF-AC", "0.4.0.0.1.0.51.1", "assistRequestInstructions,disconnectForwardConnection,connectToResource," "resetTimer,specializedResourceReport,playAnnouncement," "promptAndCollectUserInformation,cancel,activityTest"}, {"CAP-v2-gsmSRF-to-gsmSCF-AC", "0.4.0.0.1.0.52.1", "assistRequestInstructions,specializedResourceReport,playAnnouncement," "promptAndCollectUserInformation,cancel,activityTest"}, {0, 0, ""} }; static const Capability s_mapCapabOID[] = { {"SMSC", {"shortMsgMO-RelayContext-v3", "shortMsgMO-RelayContext-v2", "shortMsgMO-RelayContext-v1", "shortMsgMT-RelayContext-v3", "shortMsgMT-RelayContext-v2", ""}}, {"None", {""}}, {0, {""}}, }; static const Capability s_camelCapabOID[] = { {"None", {""}}, {0, {""}}, }; 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}, {"csi-Active", 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}, {"csi-Active", 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}, {"csi-Active", 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}, {"csi-Active", 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}, {"csi-Active", 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, false, 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_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, s_sequenceTag, s_updateLocationArgs, s_sequenceTag, s_updateLocationRes }, {"cancelLocation", true, 3, s_ctxtCstr_3_Tag, s_cancelLocationArgs, s_sequenceTag, s_extensionContainerRes }, {"provideRoamingNumber", true, 4, s_sequenceTag, s_provideRoamingNumberArgs, s_sequenceTag, s_provideRoamingNumberRes }, {"insertSubscriberData", true, 7, s_sequenceTag, s_insertSubscriberDataArgs, s_sequenceTag, s_insertSubscriberDataRes }, {"deleteSubscriberData", true, 8, s_sequenceTag, s_deleteSubscriberDataArgs, s_sequenceTag, s_deleteSubscriberDataRes }, {"sendParameters", true, 9, s_sequenceTag, s_sendParametersDataArgs, s_noTag, s_sendParametersDataRes }, {"registerSS", true, 10, s_sequenceTag, s_registerSSArgs, s_noTag, s_extSSInfoChoice }, {"eraseSS", true, 11, s_sequenceTag, s_ssCodeArgs, s_noTag, s_extSSInfoChoice }, {"activateSS", true, 12, s_sequenceTag, s_ssCodeArgs, s_noTag, s_extSSInfoChoice }, {"deactivateSS", true, 13, s_sequenceTag, s_ssCodeArgs, s_noTag, s_extSSInfoChoice }, {"interrogateSS", true, 14, s_sequenceTag, s_ssCodeArgs, s_noTag, s_InterrogateSSRes }, {"authenticationFailureReport", true, 15, s_sequenceTag, s_authFailureArgs, s_sequenceTag, s_extensionContainerRes, }, {"registerPassword", true, 17, s_noTag, s_registerPasswordArgs, s_noTag, s_registerPasswordRes }, {"getPassword", true, 18, s_noTag, s_getPasswordArgs, s_noTag, s_getPasswordRes }, {"updateGprsLocation", true, 23, s_sequenceTag, s_updateGprsLocationArgs, s_sequenceTag, s_updateGprsLocationRes }, {"sendRoutingInfoForGprs", true, 24, s_sequenceTag, s_sendRoutingInfoForGprsArgs, s_sequenceTag, s_sendRoutingInfoForGprsRes }, {"failureReport", true, 25, s_sequenceTag, s_failureReportArgs, s_sequenceTag, s_failureReportRes }, {"reset", true, 37, s_sequenceTag, s_resetArgs, s_noTag, 0 }, {"forwardCheckSS-Indication", true, 38, s_noTag, 0, s_noTag, 0 }, {"mt-forwardSM", true, 44, s_sequenceTag, s_mtForwardSMArgs, s_sequenceTag, s_forwardSMRes }, {"sendRoutingInfoForSM", true, 45, s_sequenceTag, s_sendRoutingInfoForSMArgs, s_sequenceTag, s_sendRoutingInfoForSMRes }, {"mo-forwardSM", true, 46, s_sequenceTag, s_moForwardSMArgs, s_sequenceTag, s_forwardSMRes }, {"forwardSM", true, 46, s_sequenceTag, s_forwardSMArgs, s_noTag, 0 }, {"reportSM-DeliveryStatus", true, 47, s_sequenceTag, s_reportSMDeliveryArgs, s_sequenceTag, s_reportSMDeliveryRes, }, {"activateTraceMode", true, 50, s_sequenceTag, s_activateTraceModeArgs, s_sequenceTag, s_traceModeRes }, {"deactivateTraceMode", true, 51, s_sequenceTag, s_deactivateTraceModeArgs, s_sequenceTag, s_traceModeRes }, {"sendAuthenticationInfo", true, 56, s_noTag, s_sendAuthenticationInfoArgs, s_noTag, s_sendAuthenticationInfoRes }, {"restoreData", true, 57, s_sequenceTag, s_restoreDataArgs, s_sequenceTag, s_restoreDataRes }, {"sendIMSI", true, 58, s_noTag, s_sendIMSIArgs, s_noTag, s_sendIMSIRes }, {"processUnstructuredSS-Request", true, 59, s_sequenceTag, s_unstructuredSSArgs, s_sequenceTag, s_unstructuredSSRes }, {"unstructuredSS-Request", true, 60, s_sequenceTag, s_unstructuredSSArgs, s_sequenceTag, s_unstructuredSSRes }, {"unstructuredSS-Notify", true, 61, s_sequenceTag, s_unstructuredSSArgs, s_noTag, 0 }, {"informServiceCentre", true, 63, s_sequenceTag, s_informServiceCentreArgs, s_noTag, 0 }, {"alertServiceCentre", true, 64, s_sequenceTag, s_alertServiceCentreArgs, s_noTag, 0 }, {"readyForSM", true, 66, s_sequenceTag, s_readyForSMArgs, s_sequenceTag, s_extensionContainerRes }, {"purgeMS", true, 67, s_ctxtCstr_3_Tag, s_purgeMSArgs, s_sequenceTag, s_purgeMSRes }, {"anyTimeInterrogation", true, 71, s_sequenceTag, s_anyTimeInterrogationArgs, s_sequenceTag, s_anyTimeInterrogationRes }, {"setReportingState", true, 73, s_sequenceTag, s_setReportingStateArgs, s_sequenceTag, s_setReportingStateRes }, {"statusReport", true, 74, s_sequenceTag, s_statusReportArgs, s_sequenceTag, s_statusReportRes }, {"sendRoutingInfoForLCS", true, 85, s_sequenceTag, s_sendRoutingInfoForLCSArgs, s_sequenceTag, s_sendRoutingInfoForLCSRes }, {"", false, 0, s_noTag, 0, s_noTag, 0 }, }; static const Capability s_camelCapab[] = { {"Camel", {"initialDP", "assistRequestInstructions", "establishTemporaryConnection", "disconnectForwardConnection", "connectToResource", "connect", "releaseCall", "requestReportBCSMEvent","eventReportBCSM", "continue", "resetTimer", "furnishChargingInformation", "applyCharging", "applyChargingReport", "callInformationReport", "callInformationRequest", "sendChargingInformation", "playAnnouncement", "promptAndCollectUserInformation", "specializedResourceReport", "cancel", "activityTest", ""}}, {0, {""}}, }; 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, s_sequenceTag, s_initialDPArgs, s_noTag, 0 }, {"assistRequestInstructions", true, 16, s_sequenceTag, s_assistRequestInstructionsArgs, s_noTag, 0 }, {"establishTemporaryConnection", true, 17, s_sequenceTag, s_establishTemporaryConnectionArgs, s_noTag, 0 }, {"disconnectForwardConnection", true, 18, s_noTag, 0, s_noTag, 0 }, {"connectToResource", true, 19, s_sequenceTag, s_connectToResourceArgs, s_noTag, 0 }, {"connect", true, 20, s_sequenceTag, s_connectArgs, s_noTag, 0 }, {"releaseCall", true, 22, s_noTag, s_releaseCallArgs, s_noTag, 0 }, {"requestReportBCSMEvent", true, 23, s_sequenceTag, s_requestReportBCSMEventArgs, s_noTag, 0 }, {"eventReportBCSM", true, 24, s_sequenceTag, s_eventReportBCSMArgs, s_noTag, 0 }, {"continue", true, 31, s_noTag, 0, s_noTag, 0 }, {"resetTimer", true, 33, s_sequenceTag, s_resetTimerArgs, s_noTag, 0 }, {"furnishChargingInformation", true, 34, s_noTag, s_FCIBillingChargingCharacteristics, s_noTag, 0 }, {"applyCharging", true, 35, s_sequenceTag, s_applyChargingArgs, s_noTag, 0 }, {"applyChargingReport", true, 36, s_noTag, s_callResult, s_noTag, 0 }, {"callInformationReport", true, 44, s_sequenceTag, s_callInformationArgs, s_noTag, 0 }, {"callInformationRequest", true, 45, s_sequenceTag, s_callInformationRequestArgs, s_noTag, 0 }, {"sendChargingInformation", true, 46, s_sequenceTag, s_sendChargingInformationArgs, s_noTag, 0 }, {"playAnnouncement", true, 47, s_sequenceTag, s_playAnnouncementArgs, s_noTag, 0 }, {"promptAndCollectUserInformation", true, 48, s_sequenceTag, s_promptAndCollectUserInformationArgs, s_noTag, 0 }, {"specializedResourceReport", true, 49, s_noTag, 0, s_noTag, 0 }, {"cancel", true, 53, s_noTag, s_cancelChoice, s_noTag, 0 }, {"activityTest", true, 55, s_noTag, 0, s_noTag, 0 }, {"", false, 0, s_noTag, 0, s_noTag, 0 }, }; const TokenDict s_unknownSubscriberDiagnostic[] = { {"imsiUnknown", 0}, {"gprsSubscriptionUnknown", 1}, {"npdbMismatch", 2}, {0, 0}, }; const TokenDict s_roamingNotAllowedCause[] = { {"plmnRoamingNotAllowed", 0}, {"operatorDeterminedBarring", 3}, {0, 0}, }; const TokenDict s_additionalRoamingNotAllowedCause[] = { {"supportedRAT-TypesNotAllowed ", 0}, {0, 0}, }; const TokenDict s_absentSubscriberReason[] = { {"imsiDetach", 0 }, {"restrictedArea", 1 }, {"noPageResponse", 2 }, {"purgedMS", 3 }, {"mtRoamingRetry", 4 }, {0, 0}, }; const TokenDict s_smDeliveryFailureCause[] = { {"memoryCapacityExceeded", 0 }, {"equipmentProtocolError", 1 }, {"equipmentNotSM-Equipped ", 2 }, {"unknownServiceCentre", 3 }, {"sc-Congestion", 4 }, {"invalidSME-Address", 5 }, {"subscriberNotSC-Subscriber", 6 }, {0, 0}, }; const TokenDict s_networkResource[] = { {"plmn", 0 }, {"hlr", 1 }, {"vlr ", 2 }, {"pvlr", 3 }, {"controllingMSC", 4 }, {"vmsc", 5 }, {"eir", 6 }, {"rss", 7 }, {0, 0}, }; const TokenDict s_additionalNetworkResource[] = { {"sgsn", 0}, {"ggsn", 1}, {"gmlc", 2}, {"gsmSCF", 3}, {"nplr", 4}, {"auc", 5}, {"ue", 6}, {"mme", 7}, {0, 0}, }; const TokenDict s_failureCauseParam[] = { {"limitReachedOnNumberOfConcurrentLocationRequests", 0}, {0, 0}, }; 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}, }; 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}, }; const TokenDict s_pwRegistrationFailureCause[] = { {"undetermined", 0 }, {"invalidFormat", 1 }, {"newPasswordsMismatch", 2 }, {0, 0}, }; const TokenDict s_callBarringCause[] = { {"barringServiceActive", 0 }, {"operatorBarring", 1 }, {0, 0}, }; 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_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_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 Operation s_mapErrors[] = { {"unknownSubscriber", true, 1, s_sequenceTag, s_unknownSubscriberErr, s_noTag, 0 }, {"unknownMSC", true, 3, s_noTag, 0, s_noTag, 0 }, {"unidentifiedSubscriber", true, 5, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"absentsubscriberSM", true, 6, s_sequenceTag, s_absentsubscriberSMErr, s_noTag, 0 }, {"unknownEquipment", true, 7, s_noTag, 0, s_noTag, 0 }, {"roamingNotAllowed", true, 8, s_sequenceTag, s_roamingNotAllowedErr, s_noTag, 0 }, {"illegalSubscriber", true, 9, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"bearerServiceNotProvisioned", true, 10, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"teleserviceNotProvisioned", true, 11, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"illegalEquipment", true, 12, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"callBarred", true, 13, s_noTag, s_callBarredErr, s_noTag, 0 }, {"forwardingViolation", true, 14, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"illegalSS-Operation", true, 16, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"ss-ErrorStatus", true, 17, s_noTag, s_ssErrorStatusErr, s_noTag, 0 }, {"ss-NotAvailable", true, 18, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"ss-SubscriptionViolation", true, 19, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"ss-Incompatibility", true, 20, s_sequenceTag, s_ssIncompatibilityErr, s_noTag, 0 }, {"facilityNotSupported", true, 21, s_sequenceTag, s_facilityNotSupportedErr, s_noTag, 0 }, {"absentSubscriber", true, 27, s_sequenceTag, s_absentSubscriberErr, s_noTag, 0 }, {"sm-DeliveryFailure", true, 32, s_sequenceTag, s_smDeliveryFailureErr, s_noTag, 0 }, {"messageWaitingListFull", true, 33, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"systemFailure", true, 34, s_noTag, s_systemFailure, s_noTag, 0 }, {"dataMissing", true, 35, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"unexpectedDataValue", true, 36, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"pw-RegistrationFailure", true, 37, s_noTag, s_pwRegistrationFailureErr, s_noTag, 0 }, {"negativePW-Check", true, 38, s_noTag, 0, s_noTag, 0 }, {"noRoamingNumberAvailable", true, 39, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"tracingBufferFull", true, 40, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"numberOfPW-AttemptsViolation", true, 43, s_noTag, 0, s_noTag, 0 }, {"busySubscriber", true, 45, s_sequenceTag, s_busySubscriberErr, s_noTag, 0 }, {"noSubscriberReply", true, 46, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"or-NotAllowed", true, 48, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"ati-NotAllowed", true, 49, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"resourceLimitation", true, 51, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"unauthorizedRequestingNetwork", true, 52, s_sequenceTag, s_extensionContainerRes, s_noTag, 0 }, {"unknownAlphabet", true, 71, s_noTag, 0, s_noTag, 0 }, {"ussd-Busy", true, 72, s_noTag, 0, s_noTag, 0 }, {"", false, 0, 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, s_noTag, 0, s_noTag, 0 }, {"cancelFailed", true, 1, s_sequenceTag, s_cancelFailedErr, s_noTag, 0 }, {"eTCFailed", true, 3, s_noTag, 0, s_noTag, 0 }, {"improperCallerResponse", true, 4, s_noTag, 0, s_noTag, 0 }, {"missingCustomerRecord", true, 6, s_noTag, 0, s_noTag, 0 }, {"missingParameter", true, 7, s_noTag, 0, s_noTag, 0 }, {"parameterOutOfRange", true, 8, s_noTag, 0, s_noTag, 0 }, {"requestedInfoError", true, 10, s_noTag, s_requestedInfoErr, s_noTag, 0 }, {"systemFailure", true, 11, s_noTag, s_systemFailureCamelErr, s_noTag, 0 }, {"taskRefused", true, 12, s_noTag, s_taskRefusedErr, s_noTag, 0 }, {"unavailableResource", true, 13, s_noTag, 0, s_noTag, 0 }, {"unexpectedComponentSequence", true, 14, s_noTag, 0, s_noTag, 0 }, {"unexpectedDataValue", true, 15, s_noTag, 0, s_noTag, 0 }, {"unexpectedParameter", true, 16, s_noTag, 0, s_noTag, 0 }, {"unknownLegID", true, 17, s_noTag, 0, s_noTag, 0 }, {"", false, 0, s_noTag, 0, s_noTag, 0 }, }; static const AppCtxt s_mapDialogCtxt[] = { {"map-DialogueAS", "0.4.0.0.1.1.1.1", "map-open,map-accept,map-close,map-refuse,map-userAbort,map-providerAbort"}, {0, 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; ObjList* ops = ctxt->ops.split(',',false); bool ok = (0 != ops->find(op->name)); TelEngine::destruct(ops); return ok; } 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)",lookup(type,s_userTypes),opCode,String::boolText(opLocal)); const Operation* ops = (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++; } return 0; } static const Operation* findOperation(TcapXUser::UserType type, const String& op, const AppCtxt* ctxt = 0) { DDebug(&__plugin,DebugAll,"findOperation(opCode=%s)",op.c_str()); const Operation* ops = (type == TcapXUser::MAP ? s_mapOps : s_camelOps); while (!TelEngine::null(ops->name)) { if (op == ops->name && isAppCtxtOperation(ctxt,ops)) return ops; ops++; } 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) { int index = 0; while (!TelEngine::null(cap->ops[index])) { if (opName == cap->ops[index]) return cap; index++; } 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) { int index = 0; while (!TelEngine::null(cap->ops[index])) { if (cap->ops[index] == oid) return cap; index++; } 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(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(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(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(o->get()); if (!TelEngine::null(ns) && (*ns) == tcapID) return ns; } return 0; } /** * 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())) continue; if (!writeOk || error) 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,DebugGoOn, "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\\.np$"), "transport.sccp.CallingPartyAddress.gt", "plan", TcapToXml::Attribute}, {Regexp("^CallingPartyAddress\\.gt\\.nature$"), "transport.sccp.CallingPartyAddress.gt", "nature", TcapToXml::Attribute}, {Regexp("^CallingPartyAddress\\.gt\\.tt$"), "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\\.np$"), "transport.sccp.CalledPartyAddress.gt", "plan", TcapToXml::Attribute}, {Regexp("^CalledPartyAddress\\.gt\\.nature$"), "transport.sccp.CalledPartyAddress.gt", "nature", TcapToXml::Attribute}, {Regexp("^CalledPartyAddress\\.gt\\.tt$"), "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\\..\\+\\..\\+"), "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)) { ObjList* pdus = ctxt->ops.split(',',false); bool ok = (0 != pdus->find(param->name)); TelEngine::destruct(pdus); 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(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,¶ms,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); 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.encoding", false, "CallingPartyAddress.gt.encoding"}, {"transport.sccp.CallingPartyAddress.gt.plan", false, "CallingPartyAddress.gt.np"}, {"transport.sccp.CallingPartyAddress.gt.nature", false, "CallingPartyAddress.gt.nature"}, {"transport.sccp.CallingPartyAddress.gt.translation", false, "CallingPartyAddress.gt.tt"}, {"transport.sccp.CallingPartyAddress.", true, "CallingPartyAddress"}, {"transport.sccp.CalledPartyAddress.gt.encoding", false, "CalledPartyAddress.gt.encoding"}, {"transport.sccp.CalledPartyAddress.gt.plan", false, "CalledPartyAddress.gt.np"}, {"transport.sccp.CalledPartyAddress.gt.nature", false, "CalledPartyAddress.gt.nature"}, {"transport.sccp.CalledPartyAddress.gt.translation", false, "CalledPartyAddress.gt.tt"}, {"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; Operation* op = 0; int type = 0; const NamedList& comp = elem->attributes(); for (unsigned int i = 0; i < comp.count(); 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) { op = (Operation*)findOperation(m_app->type(),*ns,appCtxt); if (!op) continue; tcapParams.setParam(prefix + "." + s_tcapOpCode,String(op->code)); tcapParams.setParam(prefix + "." + s_tcapOpCodeType,(op->local ? "local" : "global")); } else if (ns->name() == s_tcapErrCode) { op = (Operation*)findError(m_app->type(),*ns); if (!op) continue; tcapParams.setParam(prefix + "." + s_tcapErrCode,String(op->code)); tcapParams.setParam(prefix + "." + s_tcapErrCodeType,(op->local ? "local" : "global")); } else if (ns->name() == s_tcapProblemCode) tcapParams.setParam(prefix + "." + s_tcapProblemCode,String(lookup(*ns,SS7TCAPError::s_errorTypes))); else tcapParams.setParam(prefix + "." + ns->name(),*ns); } 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); tcapParams.setParam(s_tcapCompCount,String(index)); 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) { ObjList* pdus = ctxt->ops.split(',',false); bool ok = (param && param->name && pdus->find(param->name)); TelEngine::destruct(pdus); 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(map->name,*ns); else tcapParams.addParam(ns->name(),elem->getText()); } } 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(o->get()); if (!(str && (*str == cap))) return false; return true; } bool TcapXApplication::canHandle(NamedList& params) { DDebug(&__plugin,DebugAll,"TcapXApplication::canHandle(params=%p) [%p]",¶ms,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) continue; const Capability* cap = findCapability(m_type,op->name); if (!cap) continue; 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); m_io = io; if (!m_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]",¶ms,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; DDebug(&__plugin,DebugInfo,"TcapXApplication::reportError(error=%s) [%p]",err,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); 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(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("print-messages",false); m_addEnc = sect.getBoolValue("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(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(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]",¶ms,(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(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(); TcapXApplication* ins = 0; while (next) { TcapXApplication* nextApp = static_cast(next->get()); if (nextApp) { if (app->trCount() + 1 > nextApp->trCount()) { if (!ins) { ins = app; m_apps.remove(app,false); } next = next->next(); } else { if (ins) { next->insert(app); ins = 0; } break; } } else break; } if (ins) 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(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(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(o->get()) : 0); if (!usr) { usr = new TcapXUser(name); 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(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(o->get()); if (!user) continue; user->statusString(str); } } }; // anonymous namespace /* vi: set ts=8 sw=4 sts=4 noet enc=utf-8: */