1 /**
2  * camel_map.cpp
3  * This file is part of the YATE Project http://YATE.null.ro
4  *
5  * MAP/CAMEL TCAP <-> XML translators
6  *
7  * Yet Another Telephony Engine - a fully featured software PBX and IVR
8  * Copyright (C) 2011-2014 Null Team
9  *
10  * This software is distributed under multiple licenses;
11  * see the COPYING file in the main directory for licensing
12  * information for this specific distribution.
13  *
14  * This use of this software may be subject to additional restrictions.
15  * See the LEGAL file in the main directory for details.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  */
21 
22 #include <yatephone.h>
23 #include <yatesig.h>
24 #include <string.h>
25 #include <yatexml.h>
26 #include <yateasn.h>
27 
28 using namespace TelEngine;
29 
30 namespace {
31 
32 class TcapXUser;
33 class TcapXModule;
34 class XMLConnListener;
35 class XMLConnection;
36 class TcapXApplication;
37 class TcapToXml;
38 class XmlToTcap;
39 class StringList;
40 struct MapCamelType;
41 struct Parameter;
42 struct Operation;
43 
44 struct XMLMap {
45     Regexp name;
46     const char* map;
47     const char* tag;
48     int type;
49 };
50 
51 struct TCAPMap {
52     const char* path;
53     bool isPrefix;     // for this path, XML children are expected to exist
54     const String name;
55 };
56 
57 struct OpTable {
58     const Operation* mainTable;
59     const OpTable* fallbackTable;
60 };
61 
62 struct AppCtxt {
63     const char* name;
64     const char* oid;
65     const ObjList& ops;
66     const OpTable* opTable;
67 };
68 
69 struct Capability {
70     const char* name;
71     const ObjList& ops;
72 };
73 
74 class StringList
75 {
76 public:
77     StringList(const char* list, char sep = ',');
78     virtual ~StringList();
operator const ObjList&() const79     inline operator const ObjList&() const
80 	{ return *m_list; }
81 private:
82     ObjList* m_list;
83 };
84 
85 class MyDomParser : public XmlDomParser
86 {
87 public:
88     MyDomParser(TcapXApplication* app, const char* name = "MyDomParser", bool fragment = false);
89     virtual ~MyDomParser();
90 
91 protected:
92     virtual void gotElement(const NamedList& element, bool empty);
93     virtual void endElement(const String& name);
94     void verifyRoot();
95 
96 private:
97     TcapXApplication* m_app;
98 };
99 
100 class XMLConnection : public Thread
101 {
102 public:
103     XMLConnection(Socket* skt, TcapXApplication* app);
104     ~XMLConnection();
105     // inherited from thread
106     void start();
107     void run();
108     void cleanup();
109 
110     bool writeData(XmlFragment* frag);
111 private:
112     Socket* m_socket;
113     String m_address;
114     TcapXApplication* m_app;
115     MyDomParser m_parser;
116 };
117 
118 class XMLConnListener : public Thread
119 {
120 public:
121     XMLConnListener(TcapXUser* user, const NamedList& sect);
122     ~XMLConnListener();
123     virtual bool init();
124     virtual void run();
125     void cleanup();
126     bool createConn(Socket* skt, String& addr);
127 protected:
128     // the socket on which we accept connections
129     TcapXUser* m_user;
130     Socket m_socket;
131     String m_host;
132     int m_port;
133 };
134 
135 class Transaction : public NamedString
136 {
137 public:
Transaction(const char * tcapID,const char * appID,const AppCtxt * ctxt=0)138     inline Transaction(const char* tcapID, const char* appID, const AppCtxt* ctxt = 0)
139 	: NamedString(tcapID,appID), m_ctxt(ctxt)
140 	{}
~Transaction()141     inline ~Transaction()
142 	{}
context()143     inline const AppCtxt* context()
144 	{ return m_ctxt; }
setContext(AppCtxt * ctxt)145     inline void setContext(AppCtxt* ctxt)
146 	{ m_ctxt = ctxt; }
147 
148 private:
149     const AppCtxt* m_ctxt;
150 };
151 
152 class IDMap : public ObjList
153 {
154 public:
IDMap()155     inline IDMap()
156 	{}
~IDMap()157     inline ~IDMap()
158 	{}
159     void appendID(const char* tcapID, const char* appID, const AppCtxt* ctxt = 0);
160     const String& findTcapID(const char* appID);
161     const String& findAppID(const char* tcapID);
162     Transaction*  findByAppID(const char* appID);
163     Transaction*  findByTcapID(const char* tcapID);
164 };
165 
166 class XmlToTcap : public GenObject, public Mutex
167 {
168 public:
169     enum MsgType {
170 	Unknown,
171 	Capability,
172 	Tcap,
173     };
174     XmlToTcap(TcapXApplication* app);
175     ~XmlToTcap();
hasDeclaration()176     inline bool hasDeclaration()
177 	{ return m_decl != 0; }
message()178     inline XmlElement* message()
179 	{ return m_elem; }
type()180     inline MsgType type()
181 	{ return m_type; }
182     bool validDeclaration();
183     bool valid(XmlDocument* doc);
184     bool checkXmlns();
185     bool parse(NamedList& tcapParams);
186     bool parse(NamedList& tcapParams, XmlElement* elem, String prefix, const AppCtxt* ctxt);
187     bool handleComponent(NamedList& tcapParams, XmlElement* elem, const AppCtxt* ctxt);
188     bool handleMAPDialog(NamedList& tcapParams, XmlElement* elem, String prefix);
189     void reset();
190     static const TCAPMap s_tcapMap[];
191     const TCAPMap* findMap(String& path);
192     bool encodeComponent(DataBlock& payload, XmlElement* elem, bool searchArgs, int& err, Operation* op);
193     void encodeOperation(Operation* op, XmlElement* elem, DataBlock& payload, int& err, bool searchArgs);
194 private:
195     TcapXApplication* m_app;
196     XmlDeclaration* m_decl;
197     XmlElement* m_elem;
198     MsgType m_type;
199 };
200 
201 class TcapToXml : public GenObject, public Mutex
202 {
203 public:
204     enum MsgType {
205 	Unknown,
206 	State,
207 	Tcap,
208     };
209     enum XmlType {
210 	None,
211 	Element,
212 	NewElement,
213 	Attribute,
214 	Value,
215 	End,
216     };
217     TcapToXml(TcapXApplication* app);
218     ~TcapToXml();
type()219     inline MsgType type()
220 	{ return m_type; }
221     bool buildXMLMessage(NamedList& msg, XmlFragment* frag, MsgType type, const AppCtxt* ctxt = 0);
222     static const XMLMap s_xmlMap[];
223     void reset();
224     void handleMAPDialog(XmlElement* root, NamedList& params);
225     bool decodeDialogPDU(XmlElement* el, const AppCtxt* ctxt, DataBlock& data);
226     XmlElement* addToXml(XmlElement* root, const XMLMap* map, NamedString* val);
227     void addComponentsToXml(XmlElement* root, NamedList& params, const AppCtxt* ctxt);
228     const XMLMap* findMap(String& elem);
229     void addParametersToXml(XmlElement* elem, String& payloadHex, Operation* op, bool searchArgs = true);
230     void decodeTcapToXml(TelEngine::XmlElement*, TelEngine::DataBlock&, Operation* op, unsigned int index = 0, bool seachArgs = true);
231     bool decodeOperation(Operation* op, XmlElement* elem, DataBlock& data, bool searchArgs = true);
232 private:
233     TcapXApplication* m_app;
234     MsgType m_type;
235 };
236 
237 class TcapXUser : public TCAPUser, public Mutex
238 {
239 public:
240     enum UserType {
241 	MAP,
242 	CAMEL,
243     };
244     TcapXUser(const char* name);
245     ~TcapXUser();
246     virtual bool tcapIndication(NamedList& params);
247     virtual bool managementNotify(SCCP::Type type, NamedList& params);
248     bool findTCAP(const char* name);
249     int managementState();
250     void notifyManagementState(bool forced = false);
251     bool initialize(NamedList& sect);
252     bool createApplication(Socket* skt, String& addr);
253     void setListener(XMLConnListener* list);
254     void removeApp(TcapXApplication* app);
255     SS7TCAPError applicationRequest(TcapXApplication* app, NamedList& params, int reqType);
256     bool sendToApp(NamedList& params, TcapXApplication* app = 0, bool saveID = true);
257     TcapXApplication* findApplication(NamedList& params);
258     void reorderApps(TcapXApplication* app);
type()259     inline UserType type()
260 	{ return m_type; }
printMessages()261     inline bool printMessages()
262 	{ return m_printMsg; }
addEncoding()263     inline bool addEncoding()
264 	{ return m_addEnc; }
applicationCount()265     inline unsigned int applicationCount()
266     {
267 	Lock l(m_appsMtx);
268 	return m_apps.count();
269     }
270     void statusString(String& str);
271 protected:
272     ObjList m_apps;
273     Mutex m_appsMtx;
274     XMLConnListener* m_listener;
275     ObjList m_trIDs;
276     UserType m_type;
277     bool m_printMsg;
278     bool m_addEnc;
279     SCCPManagement::LocalBroadcast m_mngtStatus;
280 };
281 
282 class TcapXApplication : public RefObject, public Mutex
283 {
284 public:
285     enum State {
286 	Waiting,
287 	Active,
288 	ShutDown,
289 	Inactive,
290     };
291     enum ParamType {
292 	Unknown,
293 	Null,
294 	Bool,
295 	Integer,
296 	OID,
297 	HexString,
298 	BitString,
299 	TBCD,
300 	AddressString,
301 	AppString,
302 	Enumerated,
303 	Choice,
304 	Sequence,
305 	SequenceOf,
306 	SetOf,
307 	GSMString,
308 	Flags,
309 	CellIdFixedLength,
310 	LAIFixedLength,
311 	CalledPartyNumber,
312 	CallingPartyNumber,
313 	LocationNumber,
314 	OriginalCalledNumber,
315 	RedirectingNumber,
316 	GenericNumber,
317 	ChargeNumber,
318 	HiLayerCompat,
319 	UserServiceInfo,
320 	RedirectionInformation,
321 	None,
322     };
323     enum EncType {
324 	BoolEnc,
325 	IntEnc,
326 	OIDEnc,
327 	StringEnc,
328 	NullEnc,
329 	HexEnc,
330 	TelephonyEnc,
331 	NoEnc,
332     };
333     enum Error {
334 	NoError,
335 	DataMissing,
336 	UnexpectedDataValue,
337     };
338     TcapXApplication(const char* name, Socket* skt, TcapXUser* user);
339     ~TcapXApplication();
340     bool hasCapability(const char* oper);
341     bool handleXML();
342     void receivedXML(XmlDocument* frag);
toString() const343     const String& toString() const
344 	{ return m_name; }
345     void setIO(XMLConnection* io);
346     void reportState(State state, const char* error = 0);
347     void closeConnection();
348     bool supportCapability(const String& capab);
349     void sendStateResponse(const char* error = 0);
350     bool handleCapability(NamedList& params);
351     bool handleTcap(NamedList& params);
352     bool handleIndication(NamedList& params);
353     void reportError(const char* err);
354     bool sendTcapMsg(NamedList& params, const AppCtxt* ctxt = 0);
355     bool canHandle(NamedList& params);
356     void status(NamedList& status);
357     const AppCtxt* findCtxt(const String& appID, const String& remoteID);
state()358     inline State state()
359 	{ return m_state; }
trCount()360     inline unsigned int trCount()
361 	{ Lock l(this); return m_ids.count() + m_pending.count(); }
type()362     inline TcapXUser::UserType type()
363 	{ return m_type; }
addEncoding()364     inline bool addEncoding()
365 	{ return (m_user ? m_user->addEncoding() : false); }
366 
367 private:
368     IDMap m_ids;
369     IDMap m_pending;
370     ObjList m_capab;
371     XMLConnection* m_io;
372     String m_name;
373     TcapXUser* m_user;
374     unsigned int m_sentXml;
375     unsigned int m_receivedXml;
376     unsigned int m_sentTcap;
377     unsigned int m_receivedTcap;
378     State m_state;
379     TcapToXml m_tcap2Xml;
380     XmlToTcap m_xml2Tcap;
381     TcapXUser::UserType m_type;
382 };
383 
384 class TcapXModule : public Module
385 {
386 public:
387     TcapXModule();
388     virtual ~TcapXModule();
389     //inherited methods
390     virtual void initialize();
391     // uninstall relays and message handlers
392     bool unload();
showMissing()393     inline bool showMissing()
394 	{ return m_showMissing; }
395 protected:
396     // inherited methods
397     virtual bool received(Message& msg, int id);
398     virtual void statusModule(String& str);
399     void initUsers(Configuration& cfg);
400     virtual void statusParams(String& str);
401     virtual void statusDetail(String& str);
402     unsigned int applicationCount();
403 private:
404     Mutex m_usersMtx;
405     ObjList m_users;
406     bool m_showMissing;
407 };
408 
409 INIT_PLUGIN(TcapXModule);
410 
UNLOAD_PLUGIN(unloadNow)411 UNLOAD_PLUGIN(unloadNow)
412 {
413     if (unloadNow && !__plugin.unload())
414 	return false;
415     return true;
416 }
417 
printMissing(const char * missing,const char * parent,bool atEncoding=true)418 void printMissing(const char* missing, const char* parent, bool atEncoding = true)
419 {
420     if (__plugin.showMissing())
421 	Debug(&__plugin,DebugMild,
422 	    (atEncoding ?
423 		"Missing mandatory child '%s' in XML parent '%s'" :
424 		"Missing mandatory parameter '%s' in payload for '%s'"),
425 	    missing,parent);
426 }
427 
428 const String s_namespace = "http://yate.null.ro/xml/tcap/v1";
429 
430 static const String s_msgTag = "m";
431 static const String s_capabTag = "c";
432 static const String s_component = "component";
433 static const String s_typeStr = "type";
434 static const String s_tagAttr = "tag";
435 static const String s_encAttr = "enc";
436 static const String s_qualifierAttr = "qualifier";
437 static const String s_planAttr = "plan";
438 static const String s_natureAttr = "nature";
439 static const String s_innAttr = "inn";
440 static const String s_completeAttr = "complete";
441 static const String s_restrictAttr = "restrict";
442 static const String s_screenedtAttr = "screened";
443 static const String s_userInformation = "userInformation";
444 static const String s_encodingContentsTag = "encoding-contents";
445 static const String s_directReferenceTag = "direct-reference";
446 static const String s_appContext = "application";
447 static const String s_localTID = "localTID";
448 static const String s_remoteTID = "remoteTID";
449 
450 static const String s_tcapUser = "tcap.user";
451 static const String s_tcapRequestError = "tcap.request.error";
452 static const String s_tcapLocalTID = "tcap.transaction.localTID";
453 static const String s_tcapRemoteTID = "tcap.transaction.remoteTID";
454 static const String s_tcapEndNow = "tcap.transaction.endNow";
455 static const String s_tcapAppCtxt = "tcap.dialogPDU.application-context-name";
456 static const String s_tcapDirectReference = "tcap.dialogPDU.userInformation.direct-reference";
457 static const String s_tcapEncodingContent = "tcap.dialogPDU.userInformation.encoding-contents";
458 static const String s_tcapEncodingType = "tcap.dialogPDU.userInformation.encoding-type";
459 static const String s_tcapReqType = "tcap.request.type";
460 static const String s_tcapCompCount = "tcap.component.count";
461 static const String s_tcapCompPrefix = "tcap.component";
462 static const String s_tcapCompPrefixSep = "tcap.component.";
463 static const String s_tcapAbortCause = "tcap.transaction.abort.cause";
464 static const String s_tcapAbortInfo = "tcap.transaction.abort.information";
465 static const String s_tcapCompType = "componentType";
466 static const String s_tcapOpCodeType = "operationCodeType";
467 static const String s_tcapOpCode = "operationCode";
468 static const String s_tcapOpClass = "operationClass";
469 static const String s_tcapErrCodeType = "errorCodeType";
470 static const String s_tcapErrCode = "errorCode";
471 static const String s_tcapProblemCode = "problemCode";
472 
473 static NamedString s_encodingPath(s_tcapEncodingContent,"");
474 
475 static const TokenDict s_tagTypes[] = {
476     {"universal",    AsnTag::Universal},
477     {"application",  AsnTag::Application},
478     {"context",      AsnTag::Context},
479     {"private",      AsnTag::Private},
480     {0,0}
481 };
482 
483 struct Parameter {
484     const String name;
485     const AsnTag& tag;
486     bool isOptional;
487     TcapXApplication::ParamType type;
488     const void* content;
489 };
490 
491 struct Operation {
492     const String name;
493     bool local;
494     int code;
495     int opClass;
496     const AsnTag& argTag;
497     const Parameter* args;
498     const AsnTag& retTag;
499     const Parameter* res;
500 };
501 
502 static const TokenDict s_dict_numNature[] = {
503     { "unknown",             0x00 },
504     { "international",       0x10 },
505     { "national",            0x20 },
506     { "network-specific",    0x30 },
507     { "subscriber",          0x40 },
508     { "reserved",            0x50 },
509     { "abbreviated",         0x60 },
510     { "extension-reserved",  0x70 },
511     { 0, 0 },
512 };
513 
514 // Numbering Plan Indicator
515 static const TokenDict s_dict_numPlan[] = {
516     { "unknown",      0 },
517     { "isdn",         1 },
518     { "data",         3 },
519     { "telex",        4 },
520     { "land-mobile",  6 },
521     { "isdn-mobile",  7 },
522     { "national",     8 },
523     { "private",      9 },
524     { "extension-reserved",      15 },
525     { 0, 0 },
526 };
527 
528 struct MapCamelType {
529     TcapXApplication::ParamType type;
530     TcapXApplication::EncType encoding;
531     bool (*decode)(const Parameter*, MapCamelType*, AsnTag& tag, DataBlock&, XmlElement*, bool, int& err);
532     bool (*encode)(const Parameter*, MapCamelType*, DataBlock&, XmlElement*, int& err);
533 };
534 
535 static const MapCamelType* findType(TcapXApplication::ParamType type);
536 
537 static AsnTag s_sequenceTag(AsnTag::Universal,AsnTag::Constructor,16);
538 static AsnTag s_intTag(AsnTag::Universal, AsnTag::Primitive, 2);
539 static AsnTag s_bitsTag(AsnTag::Universal, AsnTag::Primitive, 3);
540 static AsnTag s_nullTag(AsnTag::Universal, AsnTag::Primitive, 5);
541 static AsnTag s_oidTag(AsnTag::Universal, AsnTag::Primitive, 6);
542 static AsnTag s_hexTag(AsnTag::Universal, AsnTag::Primitive, 4);
543 static AsnTag s_numStrTag(AsnTag::Universal, AsnTag::Primitive, 18);
544 static AsnTag s_noTag(AsnTag::Universal, AsnTag::Primitive, 0);
545 static AsnTag s_enumTag(AsnTag::Universal, AsnTag::Primitive, 10);
546 static AsnTag s_boolTag(AsnTag::Universal, AsnTag::Primitive, 1);
547 
findParam(const Parameter * param,const String & tag)548 static const Parameter* findParam(const Parameter* param, const String& tag)
549 {
550     if (!param)
551 	return 0;
552     XDebug(DebugAll,"findParam(param=%s,tag=%s)",param->name.c_str(),tag.c_str());
553     if (param->type == TcapXApplication::Choice && param->content) {
554 	const Parameter* p = static_cast<const Parameter*>(param->content);
555 	if (p)
556 	    return findParam(p,tag);
557     }
558     while (param && !TelEngine::null(param->name)) {
559 	if (tag == param->name)
560 	    return param;
561 	param++;
562     }
563     return 0;
564 }
565 
566 static bool encodeParam(const Parameter* param, DataBlock& data, XmlElement* elem, int& err);
567 
encodeRaw(const Parameter * param,DataBlock & payload,XmlElement * elem,int & err)568 static bool encodeRaw(const Parameter* param, DataBlock& payload, XmlElement* elem, int& err)
569 {
570     if (!elem)
571 	return true;
572 
573     XDebug(&__plugin,DebugAll,"encodeRaw(param=[%p],elem=%s[%p])",param,elem->getTag().c_str(),elem);
574     bool hasChildren = false;
575     bool status = true;
576     while (XmlElement* child = elem->pop()) {
577 	hasChildren = true;
578 	DataBlock db;
579 	Parameter* p = (Parameter*)findParam(param,elem->getTag());
580 	if (p)
581 	    status = encodeParam(p,db,child,err);
582 	else
583 	    status = encodeRaw(p,db,child,err);
584 	payload.append(db);
585 	TelEngine::destruct(child);
586 	if (!status)
587 	    break;
588     }
589     AsnTag tag;
590     const String* clas = elem->getAttribute(s_typeStr);
591     bool checkParam = (param && !TelEngine::null(param->name));
592     if (TelEngine::null(clas)) {
593 	if (checkParam)
594 	    tag.classType(param->tag.classType());
595 	else {
596 	    Debug(DebugMild,"In <%s> missing %s=\"...\" attribute!",elem->getTag().c_str(),s_typeStr.c_str());
597 	    return false;
598 	}
599     }
600     else
601 	tag.classType((AsnTag::Class)lookup(*clas,s_tagTypes,AsnTag::Universal));
602     clas = elem->getAttribute(s_tagAttr);
603     if (TelEngine::null(clas)) {
604 	if (checkParam)
605 	    tag.code(param->tag.code());
606 	else {
607 	    Debug(DebugMild,"In <%s> missing %s=\"...\" attribute!",elem->getTag().c_str(),s_tagAttr.c_str());
608 	    return false;
609 	}
610     }
611     else
612 	tag.code(clas->toInteger());
613 
614     const String& text = elem->getText();
615     if (!hasChildren) {
616 	clas = elem->getAttribute(s_encAttr);
617 	if (TelEngine::null(clas)) {
618 	    if (text) {
619 		Debug(DebugMild,"In <%s> missing %s=\"...\" attribute!",elem->getTag().c_str(),s_encAttr.c_str());
620 		return false;
621 	    }
622 	    payload.clear();
623 	    tag.type(param ? param->tag.type() : AsnTag::Primitive);
624 	    clas = &String::empty();
625 	}
626 	else
627 	    tag.type(AsnTag::Primitive);
628 	if (*clas == "hex")
629 	    payload.unHexify(text.c_str(),text.length(),' ');
630 	else if (*clas == "int")
631 	    payload.insert(ASNLib::encodeInteger(text.toInteger(),false));
632 	else if (*clas == "str")
633 	    payload.insert(ASNLib::encodeUtf8(text,false));
634 	else if (*clas == "null")
635 	    payload.clear();
636 	else if (*clas == "oid") {
637 	    ASNObjId obj = text;
638 	    payload.insert(ASNLib::encodeOID(obj,false));
639 	}
640 	else if (*clas == "bool")
641 	    payload.insert(ASNLib::encodeBoolean(text.toBoolean(),false));
642 	payload.insert(ASNLib::buildLength(payload));
643 	AsnTag::encode(tag.classType(),tag.type(),tag.code(),payload);
644     }
645     else {
646 	tag.type(AsnTag::Constructor);
647 	payload.insert(ASNLib::buildLength(payload));
648 	AsnTag::encode(tag.classType(),tag.type(),tag.code(),payload);
649     }
650     return true;
651 }
652 
encodeParam(const Parameter * param,DataBlock & data,XmlElement * elem,int & err)653 static bool encodeParam(const Parameter* param, DataBlock& data, XmlElement* elem, int& err)
654 {
655     if (!(param && elem))
656 	return false;
657     XDebug(&__plugin,DebugAll,"encodeParam(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
658     MapCamelType* type = const_cast<MapCamelType*>(findType(param->type));
659     bool ok = true;
660     if (!type)
661 	ok = encodeRaw(param,data,elem,err);
662     else {
663 	XmlElement* child = (elem->getTag() == s_component || elem->getTag() == s_encodingContentsTag ? elem->findFirstChild(&param->name) : elem);
664 	if (!child) {
665 	    if (!param->isOptional)
666 		return false;
667 	    return true;
668 	}
669 	if (child->getAttribute(s_tagAttr) || child->getAttribute(s_encAttr))
670 	    ok = encodeRaw(param,data,child,err);
671 	else {
672 	    if (param->tag.type() == AsnTag::Constructor &&
673 		!(param->type == TcapXApplication::HexString || param->type == TcapXApplication::SequenceOf
674 		|| param->type == TcapXApplication::Sequence || param->type == TcapXApplication::Choice
675 		|| param->type == TcapXApplication::SetOf))
676 		Debug(&__plugin,DebugCrit,"Encoding definition conflict for param='%s', tag is defined as contructor"
677 		    " while its type is primitive",param->name.c_str());
678 	    ok = type->encode(param,type,data,child,err);
679 	}
680 	elem->removeChild(child);
681     }
682 #ifdef XDEBUG
683     String str;
684     str.hexify(data.data(),data.length(),' ');
685     Debug(&__plugin,DebugAll,"encodeParam(param=%s[%p],elem=%s[%p] has %ssucceeded, encodedData=%s)",param->name.c_str(),param,
686 		elem->getTag().c_str(),elem,(ok ? "" : "not "),str.c_str());
687 #endif
688     return ok;
689 }
690 
decodeRaw(XmlElement * elem,DataBlock & data,bool singleParam=false)691 static bool decodeRaw(XmlElement* elem, DataBlock& data, bool singleParam = false)
692 {
693     if (!(elem && data.length()))
694 	return false;
695     DDebug(&__plugin,DebugAll,"decodeRaw(elem=%s[%p])",elem->getTag().c_str(),elem);
696     while (data.length()) {
697 	AsnTag tag;
698 	AsnTag::decode(tag,data);
699 
700 	data.cut(-(int)tag.coding().length());
701 
702 	XmlElement* child = new XmlElement("u");
703 	elem->addChild(child);
704 	child->setAttributeValid(s_typeStr,lookup(tag.classType(),s_tagTypes,""));
705 	child->setAttributeValid(s_tagAttr,String((unsigned int)tag.code()));
706 
707 	if (tag.type() == AsnTag::Primitive) {
708 
709 	    String enc;
710 	    String value;
711 	    int len = 0;
712 	    u_int8_t fullTag = tag.classType() | tag.type() | tag.code();
713 	    switch (fullTag) {
714 		case ASNLib::BOOLEAN: {
715 			bool val;
716 			if (ASNLib::decodeBoolean(data,&val,false) < 0)
717 			    return false;
718 			value = String::boolText(val);
719 			enc = "bool";
720 		    }
721 		    break;
722 		case ASNLib::INTEGER: {
723 			u_int64_t val;
724 			if (ASNLib::decodeInteger(data,val,sizeof(val),false) < 0)
725 			    return false;
726 			    // to do fix conversion from u_int64_t
727 			value = String((int)val);
728 			enc = "int";
729 		    }
730 		    break;
731 		case ASNLib::OBJECT_ID: {
732 			ASNObjId val;
733 			if (ASNLib::decodeOID(data,&val,false) < 0)
734 			    return false;
735 			value = val.toString();
736 			enc = "oid";
737 		    }
738 		    break;
739 		case ASNLib::UTF8_STR: {
740 			if (ASNLib::decodeUtf8(data,&enc,false) < 0)
741 			    return false;
742 			value = enc;
743 			enc = "str";
744 		    }
745 		    break;
746 		case ASNLib::NULL_ID:
747 		    if (ASNLib::decodeNull(data,false) < 0)
748 			return false;
749 		    enc = "null";
750 		    break;
751 		case ASNLib::NUMERIC_STR:
752 		case ASNLib::PRINTABLE_STR:
753 		case ASNLib::IA5_STR:
754 		case ASNLib::VISIBLE_STR: {
755 			int type;
756 			if (ASNLib::decodeString(data,&enc,&type,false) < 0)
757 			    return false;
758 			value = enc;
759 			enc = "str";
760 		    }
761 		    break;
762 		default:
763 		    len = ASNLib::decodeLength(data);
764 		    if (len < 0) {
765 			DDebug(&__plugin,DebugWarn,"decodeRaw() - invalid length=%d while decoding, stopping",len);
766 			return false;
767 		    }
768 		    value.hexify(data.data(),(len > (int)data.length() ? data.length() : len),' ');
769 		    data.cut(-len);
770 		    enc = "hex";
771 		    break;
772 	    }
773 
774 	    child->setAttributeValid(s_encAttr,enc);
775 	    child->addText(value);
776 	}
777 	else {
778 	    int len = ASNLib::decodeLength(data);
779 	    DataBlock payload(data.data(),len);
780 	    data.cut(-len);
781 	    decodeRaw(child,payload);
782 	}
783 	if (singleParam)
784 	    break;
785     }
786     return true;
787 }
788 
decodeParam(const Parameter * param,AsnTag & tag,DataBlock & data,XmlElement * elem,bool addEnc,int & err)789 static bool decodeParam(const Parameter* param, AsnTag& tag, DataBlock& data, XmlElement* elem, bool addEnc, int& err)
790 {
791     if (!(param && elem && data.length()))
792 	return false;
793     String str;
794     str.hexify(data.data(),data.length(),' ');
795 
796     XDebug(&__plugin,DebugAll,"decodeParam(param=%s[%p],elem=%s[%p]) - data = %s",param->name.c_str(),param,elem->getTag().c_str(),
797 	elem,str.c_str());
798     MapCamelType* type = (MapCamelType*)findType(param->type);
799     bool ok = true;
800     if (!type)
801 	ok =  decodeRaw(elem,data,true);
802     else
803 	ok = type->decode(param,type,tag,data,elem,addEnc,err);
804 
805     XDebug(&__plugin,DebugAll,"decodeParam(param=%s[%p],elem=%s[%p]) %s",param->name.c_str(),param,elem->getTag().c_str(),
806 	    elem, (ok ? "OK" : "FAILED"));
807     return ok;
808 }
809 
decodeBCD(unsigned int length,String & digits,unsigned char * buff)810 static unsigned int decodeBCD(unsigned int length, String& digits, unsigned char* buff)
811 {
812     if (!(buff && length))
813 	return 0;
814     static const char s_digits[] = "0123456789*#ABC";
815     unsigned int index = 0;
816     while (index < length) {
817 	digits += s_digits[(buff[index] & 0x0f)];
818 	u_int8_t odd = (buff[index] >> 4);
819 	if ((odd & 0x0f) != 0x0f)
820 	    digits += s_digits[(buff[index] >> 4)];
821 	index++;
822     }
823     XDebug(&__plugin,DebugAll,"Decoded BCD digits=%s",digits.c_str());
824     return index;
825 }
826 
encodeBCD(const String & digits,DataBlock & data)827 void encodeBCD(const String& digits, DataBlock& data)
828 {
829     XDebug(&__plugin,DebugAll,"encodeBCD(digit=%s)",digits.c_str());
830     unsigned int len = digits.length() / 2 + (digits.length() % 2 ?  1 : 0);
831     unsigned char buf[32];
832     unsigned int i = 0;
833     unsigned int j = 0;
834     bool odd = false;
835     while((i < digits.length()) && (j < len)) {
836 	char c = digits[i++];
837 	unsigned char d = 0;
838 	if (('0' <= c) && (c <= '9'))
839 	    d = c - '0';
840 	else if ('*' == c)
841 	    d = 10;
842 	else if ('#' == c)
843 	    d = 11;
844 	else if ('a' == c || 'A' == c)
845 	    d = 12;
846 	else if ('b' == c || 'B' == c)
847 	    d = 13;
848 	else if ('c' == c || 'C' == c)
849 	    d = 14;
850 // 	else if ('.' == c)
851 // 	    d = 15;
852 	else
853 	    continue;
854 	odd = !odd;
855 	if (odd)
856 	    buf[j] = d;
857 	else
858 	    buf[j++] |= (d << 4);
859     }
860     if (odd)
861 	buf[j++] |= 0xf0;
862 
863     data.append(&buf,j);
864 }
865 
decodeTBCD(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)866 static bool decodeTBCD(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
867 {
868     if (!(param && type && data.length() && parent))
869 	return false;
870     XDebug(&__plugin,DebugAll,"decodeTBCD(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,parent->getTag().c_str(),parent);
871     if (param->tag != tag)
872 	return false;
873 
874     data.cut(-(int)tag.coding().length());
875 
876     XmlElement* child = new XmlElement(param->name);
877     parent->addChild(child);
878     if (addEnc)
879 	child->setAttribute(s_encAttr,"str");
880     int len = ASNLib::decodeLength(data);
881     String digits;
882     len = decodeBCD(len,digits,data.data(0,len));
883     data.cut(-len);
884     child->addText(digits);
885     return true;
886 }
887 
encodeTBCD(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)888 static bool encodeTBCD(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
889 {
890     if (!(param && elem))
891 	return false;
892     XDebug(&__plugin,DebugAll,"encodeTBCD(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
893     const String& text = elem->getText();
894     encodeBCD(text,data);
895     data.insert(ASNLib::buildLength(data));
896     data.insert(param->tag.coding());
897     return true;
898 }
899 
decodeTel(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)900 static bool decodeTel(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
901 {
902     if (!(param && type && data.length() && parent))
903 	return false;
904     XDebug(&__plugin,DebugAll,"decodeTel(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
905 	parent,data.length());
906     if (param->tag != tag)
907 	return false;
908     data.cut(-(int)tag.coding().length());
909 
910     XmlElement* child = new XmlElement(param->name);
911     parent->addChild(child);
912     int len = ASNLib::decodeLength(data);
913     if (len < 1)
914 	return false;
915     u_int8_t attr = data[0];
916     child->setAttribute(s_natureAttr,lookup((attr & 0x70),s_dict_numNature,"unknown"));
917     child->setAttribute(s_planAttr,lookup((attr & 0x0f),s_dict_numPlan,"unknown"));
918     if ((attr & 0x0f) == 1)
919 	child->setAttribute(s_encAttr,"e164");
920     else if ((attr & 0x0f) == 6)
921 	child->setAttribute(s_encAttr,"e212");
922     String digits;
923     decodeBCD(len - 1,digits,data.data(1,len - 1 ));
924 
925     data.cut(-len);
926     child->addText(digits);
927     return true;
928 }
929 
encodeTel(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)930 static bool encodeTel(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
931 {
932     if (!(param && elem))
933 	return false;
934     XDebug(&__plugin,DebugAll,"encodeTel(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,elem->getTag().c_str(),
935 	elem,data.length());
936 
937     u_int8_t first = 0x80; // noExtension bit set
938     first |= lookup(elem->attribute(s_natureAttr),s_dict_numNature,0);
939     first |= lookup(elem->attribute(s_planAttr),s_dict_numPlan,0);
940     data.append(&first,sizeof(first));
941 
942     const String& digits = elem->getText();
943     encodeBCD(digits,data);
944 
945     data.insert(ASNLib::buildLength(data));
946     data.insert(param->tag.coding());
947     return true;
948 }
949 
decodeHex(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)950 static bool decodeHex(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
951 {
952     if (!(param && type && data.length() && parent))
953 	return false;
954     XDebug(&__plugin,DebugAll,"decodeHex(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
955 	parent,data.length());
956     if (param->tag != tag)
957 	return false;
958     data.cut(-(int)tag.coding().length());
959 
960     XmlElement* child = new XmlElement(param->name);
961     parent->addChild(child);
962     if (addEnc)
963 	child->setAttribute(s_encAttr,"hex");
964 
965     int len = ASNLib::decodeLength(data);
966     bool checkEoC = (len == ASNLib::IndefiniteForm && tag.type() == AsnTag::Constructor);
967     if (!checkEoC && len < 0)
968 	return false;
969     String octets;
970     if (checkEoC) {
971 	DataBlock d(data.data(),data.length());
972 	int l = ASNLib::parseUntilEoC(d);
973 	octets.hexify(data.data(),l,' ');
974 	data.cut(-l);
975 	ASNLib::matchEOC(data);
976     }
977     else {
978 	octets.hexify(data.data(),(len > (int)data.length() ? data.length() : len),' ');
979 	data.cut(-len);
980     }
981     child->addText(octets);
982     return true;
983 }
984 
encodeHex(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)985 static bool encodeHex(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
986 {
987     if (!(param && elem))
988 	return false;
989     XDebug(&__plugin,DebugAll,"encodeHexparam=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
990     const String& text = elem->getText();
991     if (!data.unHexify(text.c_str(),text.length(),' ')) {
992 	Debug(&__plugin,DebugWarn,"Failed to parse hexified string '%s'",text.c_str());
993 	return false;
994     }
995     data.insert(ASNLib::buildLength(data));
996     data.insert(param->tag.coding());;
997     return true;
998 }
999 
decodeOID(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1000 static bool decodeOID(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
1001 {
1002     if (!(param && type && data.length() && parent))
1003 	return false;
1004     XDebug(&__plugin,DebugAll,"decodeOID(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
1005 	parent,data.length());
1006     if (param->tag != tag)
1007 	return false;
1008     data.cut(-(int)tag.coding().length());
1009 
1010     XmlElement* child = new XmlElement(param->name);
1011     parent->addChild(child);
1012     if (addEnc)
1013 	child->setAttribute(s_encAttr,"oid");
1014 
1015     ASNObjId obj;
1016     ASNLib::decodeOID(data,&obj,false);
1017     child->addText(obj.toString());
1018 
1019     return true;
1020 }
1021 
encodeOID(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1022 static bool encodeOID(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1023 {
1024     if (!(param && elem))
1025 	return false;
1026     XDebug(&__plugin,DebugAll,"encodeOID(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1027     ASNObjId oid = elem->getText();
1028     data.append(ASNLib::encodeOID(oid,false));
1029     data.insert(ASNLib::buildLength(data));
1030     data.insert(param->tag.coding());
1031     return true;
1032 }
1033 
decodeNull(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1034 static bool decodeNull(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
1035 {
1036     if (!(param && type && data.length() && parent))
1037 	return false;
1038     XDebug(&__plugin,DebugAll,"decodeNull(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
1039 	parent,data.length());
1040     if (param->tag != tag)
1041 	return false;
1042     data.cut(-(int)tag.coding().length());
1043 
1044     XmlElement* child = new XmlElement(param->name);
1045     parent->addChild(child);
1046     if (addEnc)
1047 	child->setAttribute(s_encAttr,"null");
1048 
1049     int len = ASNLib::decodeNull(data,false);
1050     data.cut(-len);
1051     return true;
1052 }
1053 
encodeNull(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1054 static bool encodeNull(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1055 {
1056     if (!(param && elem))
1057 	return false;
1058     XDebug(&__plugin,DebugAll,"encodeNull(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1059     ASNObjId oid = elem->getText();
1060     data.append(ASNLib::encodeNull(false));
1061     data.insert(ASNLib::buildLength(data));
1062     data.insert(param->tag.coding());
1063     return true;
1064 }
1065 
decodeInt(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1066 static bool decodeInt(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
1067 {
1068     if (!(param && type && data.length() && parent))
1069 	return false;
1070     XDebug(&__plugin,DebugAll,"decodeInt(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
1071 	parent,data.length());
1072     if (param->tag != tag)
1073 	return false;
1074     data.cut(-(int)tag.coding().length());
1075 
1076     XmlElement* child = new XmlElement(param->name);
1077     parent->addChild(child);
1078     if (addEnc)
1079 	child->setAttribute(s_encAttr,"int");
1080 
1081     u_int64_t val;
1082     ASNLib::decodeInteger(data,val,sizeof(val),false);
1083     child->addText(String((int)val));
1084     return true;
1085 }
1086 
encodeInt(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1087 static bool encodeInt(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1088 {
1089     if (!(param && elem))
1090 	return false;
1091     XDebug(&__plugin,DebugAll,"encodeInt(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1092     u_int64_t val = elem->getText().toInteger();
1093     data.append(ASNLib::encodeInteger(val,false));
1094     data.insert(ASNLib::buildLength(data));
1095     data.insert(param->tag.coding());
1096     return true;
1097 }
1098 
decodeSeq(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1099 static bool decodeSeq(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
1100 {
1101     if (!(param && type && data.length() && parent))
1102 	return false;
1103     XDebug(&__plugin,DebugAll,"decodeSeq(param=%s[%p],elem=%s[%p],datalen=%d,first=0x%x)",param->name.c_str(),param,
1104 		parent->getTag().c_str(),parent,data.length(),data[0]);
1105     if (param->tag != tag)
1106 	return false;
1107     data.cut(-(int)tag.coding().length());
1108 
1109     int len = ASNLib::decodeLength(data);
1110     bool checkEoC = (len == ASNLib::IndefiniteForm);
1111     len = (checkEoC ? data.length() : len);
1112     if (!checkEoC && len < 0)
1113 	return false;
1114     int initLen = data.length();
1115 
1116     XmlElement* child = new XmlElement(param->name);
1117     parent->addChild(child);
1118 
1119     if (param->content) {
1120 	const Parameter* params= static_cast<const Parameter*>(param->content);
1121 	while (params && params->name) {
1122 	    if ((initLen - (int)data.length() >= len) || (checkEoC && ASNLib::matchEOC(data) > 0))
1123 		break;
1124 	    AsnTag childTag;
1125 	    AsnTag::decode(childTag,data);
1126 	    if (!decodeParam(params,childTag,data,child,addEnc,err)) {
1127 		if (!params->isOptional) {
1128 		    if (err != TcapXApplication::DataMissing)
1129 			printMissing(params->name.c_str(),param->name.c_str(),false);
1130 		    err = TcapXApplication::DataMissing;
1131 		    return false;
1132 		}
1133 		else {
1134 		    params++;
1135 		    continue;
1136 		}
1137 	    }
1138 	    params++;
1139 	}
1140     }
1141     return true;
1142 }
1143 
encodeSeq(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1144 static bool encodeSeq(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1145 {
1146     if (!(param && elem))
1147 	return false;
1148     XDebug(&__plugin,DebugAll,"encodeSeq(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1149 
1150     if (param->content) {
1151 	const Parameter* params= static_cast<const Parameter*>(param->content);
1152 	while (params && params->name) {
1153 	    const String& name = params->name;
1154 	    XmlElement* child = elem->findFirstChild(&name);
1155 	    if (!child) {
1156 		if (!params->isOptional) {
1157 		    printMissing(params->name.c_str(),param->name.c_str());
1158 		    err = TcapXApplication::DataMissing;
1159 		    return false;
1160 		}
1161 		else {
1162 		    params++;
1163 		    continue;
1164 		}
1165 	    }
1166 	    DataBlock db;
1167 	    if (!encodeParam(params,db,child,err))
1168 		return false;
1169 	    data.append(db);
1170 	    elem->removeChild(child);
1171 	    params++;
1172 	}
1173     }
1174 
1175     if (param->tag != s_noTag) {
1176 	data.insert(ASNLib::buildLength(data));
1177 	data.insert(param->tag.coding());
1178     }
1179     return true;
1180 }
1181 
decodeSeqOf(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1182 static bool decodeSeqOf(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc,
1183 	    int& err)
1184 {
1185     if (!(param && type && data.length() && parent))
1186 	return false;
1187     XDebug(&__plugin,DebugAll,"decodeSeqOf(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
1188 	    parent,data.length());
1189     if (param->tag != tag)
1190 	return false;
1191     data.cut(-(int)tag.coding().length());
1192 
1193     int len = ASNLib::decodeLength(data);
1194     bool checkEoC = (len == ASNLib::IndefiniteForm);
1195     if (!checkEoC && len < 0)
1196 	return false;
1197     XmlElement* child = new XmlElement(param->name);
1198     parent->addChild(child);
1199 
1200     int initLength = data.length();
1201     int payloadLen = (checkEoC ? data.length() : len);
1202     if (param->content) {
1203 	const Parameter* params= static_cast<const Parameter*>(param->content);
1204 	while (params && !TelEngine::null(params->name) && payloadLen) {
1205 	    if (checkEoC && ASNLib::matchEOC(data) > 0)
1206 		break;
1207 	    AsnTag childTag;
1208 	    AsnTag::decode(childTag,data);
1209 	    if (!decodeParam(params,childTag,data,child,addEnc,err)) {
1210 		if (!param->isOptional) {
1211 		    if (err != TcapXApplication::DataMissing)
1212 			printMissing(params->name.c_str(),param->name.c_str(),false);
1213 		    err = TcapXApplication::DataMissing;
1214 		    return false;
1215 		}
1216 		else
1217 		    break;
1218 	    }
1219 	    payloadLen = data.length() - (initLength - len);
1220 	}
1221     }
1222     return true;
1223 }
1224 
encodeSeqOf(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1225 static bool encodeSeqOf(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1226 {
1227     if (!(param && elem))
1228 	return false;
1229     XDebug(&__plugin,DebugAll,"encodeSeqOf(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1230 
1231     if (param->content) {
1232 	const Parameter* params = static_cast<const Parameter*>(param->content);
1233 	XmlElement* child = elem->pop();
1234 	bool atLeastOne = false;
1235 	while (params && params->name && child) {
1236 	    if (!(child->getTag() == params->name)) {
1237 		Debug(&__plugin,DebugAll,"Skipping over unknown parameter '%s' for parent '%s', expecting '%s'",
1238 		    child->tag(),elem->tag(),params->name.c_str());
1239 		TelEngine::destruct(child);
1240 		child = elem->pop();
1241 		continue;
1242 	    }
1243 	    DataBlock db;
1244 	    if (!encodeParam(params,db,child,err)) {
1245 		TelEngine::destruct(child);
1246 		if (err != TcapXApplication::DataMissing) {
1247 		    printMissing(params->name.c_str(),param->name.c_str());
1248 		    err = TcapXApplication::DataMissing;
1249 		}
1250 		if (!param->isOptional && !(elem->findFirstChild()) && !atLeastOne)
1251 		    return false;
1252 		else {
1253 		    child = elem->pop();
1254 		    continue;
1255 		}
1256 	    }
1257 	    else
1258 		atLeastOne = true;
1259 	    data.append(db);
1260 	    TelEngine::destruct(child);
1261 	    child = elem->pop();
1262 	}
1263     }
1264     if (param->tag != s_noTag) {
1265 	data.insert(ASNLib::buildLength(data));
1266 	data.insert(param->tag.coding());
1267     }
1268     return true;
1269 }
1270 
1271 
decodeChoice(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1272 static bool decodeChoice(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
1273 {
1274     if (!(param && type && data.length() && parent))
1275 	return false;
1276     XDebug(&__plugin,DebugAll,"decodeChoice(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
1277 	parent,data.length());
1278     bool checkEoC = false;
1279     if (param->tag != s_noTag) {
1280 	if (param->tag != tag)
1281 	    return false;
1282 	data.cut(-(int)tag.coding().length());
1283 	int len = ASNLib::decodeLength(data);
1284 	checkEoC = (len == ASNLib::IndefiniteForm);
1285 	if (!checkEoC && len < 0)
1286 	    return false;
1287     }
1288     XmlElement* child = new XmlElement(param->name);
1289 
1290     bool showDebug = !(param->tag == s_noTag && param->isOptional);
1291     if (param->content) {
1292 	const Parameter* params= static_cast<const Parameter*>(param->content);
1293 	while (params && !TelEngine::null(params->name)) {
1294 	    AsnTag childTag;
1295 	    AsnTag::decode(childTag,data);
1296 	    if (!decodeParam(params,childTag,data,child,addEnc,err)) {
1297 		params++;
1298 		continue;
1299 	    }
1300 	    if (checkEoC)
1301 		ASNLib::matchEOC(data);
1302 	    parent->addChild(child);
1303 	    return true;
1304 	}
1305 	if (err != TcapXApplication::DataMissing && showDebug) {
1306 	    if (__plugin.showMissing())
1307 		Debug(&__plugin,DebugNote,"No valid choice in payload for '%s'",child->tag());
1308 	    err = TcapXApplication::DataMissing;
1309 	}
1310     }
1311     TelEngine::destruct(child);
1312     return false;
1313 }
1314 
encodeChoice(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1315 static bool encodeChoice(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1316 {
1317     if (!(param && elem))
1318 	return false;
1319     XDebug(&__plugin,DebugAll,"encodeChoice(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1320 
1321     if (param->content) {
1322 	const Parameter* params = static_cast<const Parameter*>(param->content);
1323 	XmlElement* child = elem->pop();
1324 	while (child && params && !TelEngine::null(params->name)) {
1325 	    if (child->getTag() == params->name) {
1326 		DataBlock db;
1327 		if (!encodeParam(params,db,child,err)) {
1328 		    TelEngine::destruct(child);
1329 		    return false;
1330 		}
1331 		data.append(db);
1332 		if (param->tag != s_noTag) {
1333 		    data.insert(ASNLib::buildLength(data));
1334 		    data.insert(param->tag.coding());
1335 		}
1336 		TelEngine::destruct(child);
1337 		return true;
1338 	    }
1339 	    params++;
1340 	}
1341 	TelEngine::destruct(child);
1342     }
1343     if (err != TcapXApplication::DataMissing) {
1344 	if (__plugin.showMissing())
1345 	    Debug(&__plugin,DebugNote,"No valid choice was given for parent '%s'",elem->tag());
1346 	err = TcapXApplication::DataMissing;
1347     }
1348     return false;
1349 }
1350 
decodeEnumerated(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1351 static bool decodeEnumerated(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
1352 {
1353     if (!(param && type && data.length() && parent))
1354 	return false;
1355     XDebug(&__plugin,DebugAll,"decodeEnumerated(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
1356 	parent,data.length());
1357     if (param->tag != tag)
1358 	return false;
1359     data.cut(-(int)tag.coding().length());
1360 
1361     int len = ASNLib::decodeLength(data);
1362     if (len < 0)
1363 	return false;
1364 
1365     XmlElement* child = new XmlElement(param->name);
1366     parent->addChild(child);
1367 
1368     u_int8_t val = data[0];
1369     data.cut(-1);
1370     if (param->content) {
1371 	const TokenDict* dict = static_cast<const TokenDict*>(param->content);
1372 	if (!dict)
1373 	    return false;
1374 	child->addText(lookup(val,dict,""));
1375 	if (addEnc)
1376 	    child->setAttribute(s_encAttr,"str");
1377     }
1378     else {
1379 	child->addText(String(val));
1380 	if (addEnc)
1381 	    child->setAttribute(s_encAttr,"int");
1382     }
1383     return true;
1384 }
1385 
encodeEnumerated(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1386 static bool encodeEnumerated(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1387 {
1388     if (!(param && elem))
1389 	return false;
1390     XDebug(&__plugin,DebugAll,"encodeEnumerated(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1391 
1392     if (param->content) {
1393 	const TokenDict* dict = static_cast<const TokenDict*>(param->content);
1394 	if (!dict)
1395 	    return false;
1396 	const String& text = elem->getText();
1397 	int val = lookup(text,dict,-1);
1398 	if (val < 0 || val > 255) {
1399 	    err = TcapXApplication::UnexpectedDataValue;
1400 	    return false;
1401 	}
1402 	u_int8_t enumVal = val & 0xff;
1403 	data.append(&enumVal,sizeof(enumVal));
1404     }
1405     if (param->tag != s_noTag) {
1406 	data.insert(ASNLib::buildLength(data));
1407 	data.insert(param->tag.coding());
1408     }
1409     return true;
1410 }
1411 
decodeBitString(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1412 static bool decodeBitString(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
1413 {
1414     if (!(param && type && data.length() && parent))
1415 	return false;
1416     XDebug(&__plugin,DebugAll,"decodeBitString(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
1417 	parent,data.length());
1418     if (param->tag != tag)
1419 	return false;
1420     data.cut(-(int)tag.coding().length());
1421 
1422     XmlElement* child = new XmlElement(param->name);
1423     parent->addChild(child);
1424     if (addEnc)
1425 	child->setAttribute(s_encAttr,"str");
1426 
1427     String val, str;
1428     int value = 0;
1429     ASNLib::decodeBitString(data,&val,false);
1430     for (unsigned int i = 0; i < val.length(); i++) {
1431 	char c = val[i];
1432 	if (c == '1') {
1433 	    int mask = 1 << i;
1434 	    value |= mask;
1435 	}
1436     }
1437     if (param->content) {
1438 	const TokenDict* dict = static_cast<const TokenDict*>(param->content);
1439 	if (!dict)
1440 	    return true;
1441 	while (dict->token){
1442 	    if ((dict->value & value) == dict->value)
1443 		str.append(dict->token,",");
1444 	    dict++;
1445 	}
1446     }
1447     child->addText(str);
1448     return true;
1449 }
1450 
encodeBitString(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1451 static bool encodeBitString(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1452 {
1453     if (!(param && elem))
1454 	return false;
1455     XDebug(&__plugin,DebugAll,"encodeBitString(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1456 
1457     if (param->content) {
1458 	const TokenDict* dict = static_cast<const TokenDict*>(param->content);
1459 	String val;
1460 	int value = 0;
1461 	if (dict) {
1462 	    const String& text = elem->getText();
1463 	    ObjList* list = text.split(',',false);
1464 	    while(dict->token){
1465 		if (list->find(dict->token))
1466 		    value |= dict->value;
1467 		dict++;
1468 	    }
1469 	    TelEngine::destruct(list);
1470 	}
1471 
1472 	int size = sizeof(value) * 8;
1473 	bool start = false;
1474 	while (size > 0) {
1475 	    size--;
1476 	    u_int8_t b = (value >> size) & 0x01;
1477 	    if (b == 1 && !start)
1478 		start = true;
1479 	    if (start)
1480 		val = (b == 1? "1" : "0") + val;
1481 	}
1482 
1483 	data.append(ASNLib::encodeBitString(val,false));
1484     }
1485     if (param->tag != s_noTag) {
1486 	data.insert(ASNLib::buildLength(data));
1487 	data.insert(param->tag.coding());
1488     }
1489     return true;
1490 }
1491 
1492 // These tables contain embedded UTF-8 characters
1493 static const char* const s_gsm7base[128] = {
1494     "@", "£", "$", "¥", "è", "é", "ù", "ì", "ò", "Ç", "\n", "Ø", "ø", "\r", "Å", "å",
1495     "Δ", "_", "Φ", "Γ", "Λ", "Ω", "Π", "Ψ", "Σ", "Θ", "Ξ", "", "Æ", "æ", "ß", "É",
1496     " ", "!", "\"", "#", "¤", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/",
1497     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
1498     "¡", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
1499     "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Ä", "Ö", "Ñ", "Ü", "§",
1500     "¿", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
1501     "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "ä", "ö", "ñ", "ü", "à"
1502 };
1503 
1504 static const char* const s_gsm7esc[128] = {
1505     "", "", "", "", "", "", "", "", "", "", "\f", "", "", "", "", "",
1506     "", "", "", "", "^", "", "", "", "", "", "", "", "", "", "", "",
1507     "", "", "", "", "", "", "", "", "{", "}", "", "", "", "", "", "\\",
1508     "", "", "", "", "", "", "", "", "", "", "", "", "[", "~", "]", "",
1509     "|", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
1510     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
1511     "", "", "", "", "", "€", "", "", "", "", "", "", "", "", "", "",
1512     "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
1513 };
1514 
decodeGSM7Bit(DataBlock & data,int & len,String & decoded)1515 static void decodeGSM7Bit(DataBlock& data, int& len, String& decoded)
1516 {
1517     u_int8_t bits = 0;
1518     u_int16_t buf = 0;
1519     bool esc = false;
1520     for (int i = 0; i < len; i++) {
1521 	buf |= ((u_int16_t)data[i]) << bits;
1522 	bits += 8;
1523 	while (bits >= 7) {
1524 	    if (esc) {
1525 		decoded << s_gsm7esc[buf & 0x7f];
1526 		esc = false;
1527 	    }
1528 	    else if ((buf & 0x7f) == 0x1b)
1529 		esc = true;
1530 	    else
1531 		decoded << s_gsm7base[buf & 0x7f];
1532 	    buf >>= 7;
1533 	    bits -= 7;
1534 	}
1535     }
1536     data.cut(-len);
1537     if ((bits == 0) && decoded.endsWith("\r"))
1538 	decoded.assign(decoded,decoded.length()-1);
1539 }
1540 
decodeGSMString(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1541 static bool decodeGSMString(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
1542 {
1543     if (!(param && type && data.length() && parent))
1544 	return false;
1545     XDebug(&__plugin,DebugAll,"decodeGSMString(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,parent->getTag().c_str(),
1546 	parent,data.length());
1547 
1548     if (param->tag != tag)
1549 	return false;
1550     data.cut(-(int)tag.coding().length());
1551 
1552     int len = ASNLib::decodeLength(data);
1553     if (len < 0)
1554 	return false;
1555 
1556     // TODO - should check Encoding Scheme at some point as also translation tables
1557     XmlElement* enc = new XmlElement(param->name);
1558     parent->addChild(enc);
1559     if (addEnc)
1560 	enc->setAttribute(s_encAttr,"str");
1561     String str;
1562     decodeGSM7Bit(data,len,str);
1563     enc->addText(str);
1564     return true;
1565 }
1566 
encodeGSM7Bit(const String & str,DataBlock & db)1567 static void encodeGSM7Bit(const String& str, DataBlock& db)
1568 {
1569     if (str.null())
1570 	return;
1571     u_int8_t bits = 0;
1572     u_int32_t buf = 0;
1573     String tmp = str;
1574     while (tmp) {
1575 	bool notFound = true;
1576 	for (int i = 0; i < 128; i++) {
1577 	    if (tmp.startSkip(s_gsm7base[i],false)) {
1578 		buf |= (i << bits);
1579 		bits += 7;
1580 		notFound = false;
1581 		break;
1582 	    }
1583 	}
1584 	if (notFound) {
1585 	    for (int i = 0; i < 128; i++) {
1586 		if (tmp.startSkip(s_gsm7esc[i],false)) {
1587 		    buf |= ((i << 7) | 0x1b) << bits;
1588 		    bits += 14;
1589 		    notFound = false;
1590 		    break;
1591 		}
1592 	    }
1593 	    if (notFound) {
1594 		// TODO: skip one UTF-8 instead of one C char
1595 		tmp = tmp.c_str() + 1;
1596 		continue;
1597 	    }
1598 	}
1599 	while (bits >= 8) {
1600 	    u_int8_t byte = buf & 0xff;
1601 	    db.append(&byte,sizeof(byte));
1602 	    buf >>= 8;
1603 	    bits -= 8;
1604 	}
1605     }
1606     if (bits) {
1607 	u_int8_t byte = buf & 0xff;
1608 	// if just 1 bit use a shifted \r as filler
1609 	if (bits == 1)
1610 	    byte |= 0x1a;
1611 	db.append(&byte,sizeof(byte));
1612     }
1613 }
1614 
encodeGSMString(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1615 static bool encodeGSMString(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1616 {
1617     if (!(param && elem))
1618 	return false;
1619 
1620     XDebug(&__plugin,DebugAll,"encodeGSMString(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1621 
1622     if (elem->getTag() != param->name)
1623 	return false;
1624 
1625     const String& str = elem->getText();
1626     encodeGSM7Bit(str,data);
1627 
1628     if (param->tag != s_noTag) {
1629 	data.insert(ASNLib::buildLength(data));
1630 	data.insert(param->tag.coding());
1631     }
1632     return true;
1633 }
1634 
decodeFlags(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1635 static bool decodeFlags(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
1636 {
1637     if (!(param && type && data.length() && parent))
1638 	return false;
1639     XDebug(&__plugin,DebugAll,"decodeFlags(param=%s[%p],elem=%s[%p],datalen=%d, data[0]=%d)",param->name.c_str(),param,
1640 	   parent->getTag().c_str(),parent,data.length(),data[0]);
1641     if (param->tag != tag)
1642 	return false;
1643     data.cut(-(int)tag.coding().length());
1644 
1645     int len = ASNLib::decodeLength(data);
1646     if (len <= 0)
1647 	return false;
1648 
1649     XmlElement* child = new XmlElement(param->name);
1650     parent->addChild(child);
1651 
1652     if (addEnc)
1653 	child->setAttribute(s_encAttr,"str");
1654 
1655     u_int8_t flags = data[0];
1656     String str;
1657     if (param->content) {
1658 	const SignallingFlags* list = static_cast<const SignallingFlags*>(param->content);
1659 	if (!list)
1660 	    return false;
1661 	for (; list->mask; list++) {
1662 	    if ((flags & list->mask) == list->value)
1663 		str.append(list->name,",");
1664 	}
1665     }
1666     data.cut(-len);
1667     child->addText(str);
1668     return true;
1669 }
1670 
encodeFlags(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1671 static bool encodeFlags(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1672 {
1673     if (!(param && elem))
1674 	return false;
1675 
1676     XDebug(&__plugin,DebugAll,"encodeFlags(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1677 
1678     u_int8_t byte = 0;
1679     if (param->content) {
1680  	const SignallingFlags* flags = static_cast<const SignallingFlags*>(param->content);
1681 	if (!flags)
1682 	    return false;
1683 	const String& text = elem->getText();
1684 	ObjList* list = text.split(',',false);
1685 
1686 	for (ObjList* o = list->skipNull(); o; o = o->skipNext()) {
1687 	    String* s = static_cast<String*>(o->get());
1688 	    const SignallingFlags* flag = flags;
1689 	    for (; flag->mask && *s != flag->name; flag++);
1690 	    if (!flag->name) {
1691 		DDebug(&__plugin,DebugAll,"encodeFlags '%s' not found",s->c_str());
1692 		continue;
1693 	    }
1694 	    byte |= flag->value;
1695 	}
1696 	TelEngine::destruct(list);
1697     }
1698     data.append(&byte,sizeof(byte));
1699     if (param->tag != s_noTag) {
1700 	data.insert(ASNLib::buildLength(data));
1701 	data.insert(param->tag.coding());
1702     }
1703     return true;
1704 }
1705 
decodeString(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1706 static bool decodeString(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
1707 {
1708     if (!(param && type && data.length() && parent))
1709 	return false;
1710     XDebug(&__plugin,DebugAll,"decodeString(param=%s[%p],elem=%s[%p],datalen=%d, data[0]=%d)",param->name.c_str(),param,parent->getTag().c_str(),
1711 	parent,data.length(),data[0]);
1712     if (param->tag != tag)
1713 	return false;
1714     data.cut(-(int)tag.coding().length());
1715 
1716     String value;
1717     int t = 0;
1718     int len = ASNLib::decodeString(data,&value,&t,false);
1719     if (len <= 0)
1720 	return false;
1721 
1722     XmlElement* child = new XmlElement(param->name);
1723     parent->addChild(child);
1724     child->addText(value);
1725     if (addEnc)
1726 	child->setAttribute(s_encAttr,"str");
1727     return true;
1728 }
1729 
encodeString(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1730 static bool encodeString(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1731 {
1732     if (!(param && elem))
1733 	return false;
1734 
1735     XDebug(&__plugin,DebugAll,"encodeString(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1736 
1737     const String& text = elem->getText();
1738     data.append(ASNLib::encodeString(text,ASNLib::PRINTABLE_STR,false));
1739     if (param->tag != s_noTag) {
1740 	data.insert(ASNLib::buildLength(data));
1741 	data.insert(param->tag.coding());
1742     }
1743     return true;
1744 }
1745 
decodeBool(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1746 static bool decodeBool(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data, XmlElement* parent, bool addEnc, int& err)
1747 {
1748     if (!(param && type && data.length() && parent))
1749 	return false;
1750     XDebug(&__plugin,DebugAll,"decodeBool(param=%s[%p],elem=%s[%p],datalen=%d, data[0]=%d)",param->name.c_str(),param,parent->getTag().c_str(),
1751 	parent,data.length(),data[0]);
1752     if (param->tag != tag)
1753 	return false;
1754     data.cut(-(int)tag.coding().length());
1755 
1756     bool value = false;
1757     int len = ASNLib::decodeBoolean(data,&value,false);
1758     if (len <= 0)
1759 	return false;
1760 
1761     XmlElement* child = new XmlElement(param->name);
1762     parent->addChild(child);
1763     child->addText(String::boolText(value));
1764     if (addEnc)
1765 	child->setAttribute(s_encAttr,"bool");
1766     return true;
1767 }
1768 
encodeBool(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)1769 static bool encodeBool(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
1770 {
1771     if (!(param && elem))
1772 	return false;
1773     XDebug(&__plugin,DebugAll,"encodeBool(param=%s[%p],elem=%s[%p])",param->name.c_str(),param,elem->getTag().c_str(),elem);
1774 
1775     bool val = elem->getText().toBoolean();
1776     data.append(ASNLib::encodeBoolean(val,false));
1777     if (param->tag != s_noTag) {
1778 	data.insert(ASNLib::buildLength(data));
1779 	data.insert(param->tag.coding());
1780     }
1781     return true;
1782 }
1783 
1784 // Nature of Address Indicator
1785 static const TokenDict s_dict_nai[] = {
1786     { "subscriber",        1 },
1787     { "unknown",           2 },
1788     { "national",          3 },
1789     { "international",     4 },
1790     { "network-specific",  5 },
1791     { "national-routing",  6 },
1792     { "specific-routing",  7 },
1793     { "routing-with-cdn",  8 },
1794     { 0, 0 }
1795 };
1796 
1797 // Numbering Plan Indicator
1798 static const TokenDict s_dict_numPlanIsup[] = {
1799     { "unknown",  0 },
1800     { "isdn",     1 },
1801     { "data",     3 },
1802     { "telex",    4 },
1803     { "private",  5 },
1804     { "national", 6 },
1805     { 0, 0 }
1806 };
1807 
1808 // Address Presentation
1809 static const TokenDict s_dict_presentation[] = {
1810     { "allowed",     0 },
1811     { "restricted",  1 },
1812     { "unavailable", 2 },
1813     // aliases for restrict=...
1814     { "no",    0 },
1815     { "false", 0 },
1816     { "yes",   1 },
1817     { "true",  1 },
1818     { 0, 0 }
1819 };
1820 
1821 // Screening Indicator
1822 static const TokenDict s_dict_screening[] = {
1823     { "user-provided",        0 },
1824     { "user-provided-passed", 1 },
1825     { "user-provided-failed", 2 },
1826     { "network-provided",     3 },
1827     // aliases for screened=...
1828     { "no",    0 },
1829     { "false", 0 },
1830     { "yes",   1 },
1831     { "true",  1 },
1832     { 0, 0 }
1833 };
1834 
1835 // Generic number qualifier
1836 static const TokenDict s_dict_qual[] = {
1837     { "dialed-digits",        0 },
1838     { "called-additional",    1 },
1839     { "caller-failed",        2 },
1840     { "caller-not-screened",  3 },
1841     { "terminating",          4 },
1842     { "connected-additional", 5 },
1843     { "caller-additional",    6 },
1844     { "called-original",      7 },
1845     { "redirecting",          8 },
1846     { "redirection",          9 },
1847     { 0, 0 }
1848 };
1849 
1850 // Utility function - extract just ISUP digits from a parameter
getDigits(String & num,bool odd,const unsigned char * buf,unsigned int len)1851 static void getDigits(String& num, bool odd, const unsigned char* buf, unsigned int len)
1852 {
1853     static const char digits[] = "0123456789ABCDE.";
1854     for (unsigned int i = 0; i < len; i++) {
1855 	num += digits[buf[i] & 0x0f];
1856 	if (odd && ((i+1) == len))
1857 	    break;
1858 	num += digits[buf[i] >> 4];
1859     }
1860 }
1861 
1862 // Utility function - write digit sequences
setDigits(DataBlock & data,const char * val,unsigned char nai,int b2=-1,int b0=-1)1863 static void setDigits(DataBlock& data, const char* val, unsigned char nai, int b2 = -1, int b0 = -1)
1864 {
1865     unsigned char buf[32];
1866     unsigned int len = 0;
1867     if (b0 >= 0)
1868 	buf[len++] = b0 & 0xff;
1869     unsigned int naiPos = len++;
1870     buf[naiPos] = nai & 0x7f;
1871     if (b2 >= 0)
1872 	buf[len++] = b2 & 0xff;
1873 
1874     bool odd = false;
1875     while (val && (len < sizeof(buf))) {
1876 	char c = *val++;
1877 	if (!c)
1878 	    break;
1879 	unsigned char n = 0;
1880 	if (('0' <= c) && (c <= '9'))
1881 	    n = c - '0';
1882 	else switch (c) {
1883 	    case 'A':
1884 	    case 'a':
1885 		n = 10;
1886 		break;
1887 	    case 'B':
1888 	    case 'b':
1889 	    case '*':
1890 		n = 11;
1891 		break;
1892 	    case 'C':
1893 	    case 'c':
1894 	    case '#':
1895 		n = 12;
1896 		break;
1897 	    case 'D':
1898 	    case 'd':
1899 		n = 13;
1900 		break;
1901 	    case 'E':
1902 	    case 'e':
1903 		n = 14;
1904 		break;
1905 	    case 'F':
1906 	    case 'f':
1907 	    case '.':
1908 		n = 15;
1909 		break;
1910 	    default:
1911 		continue;
1912 	}
1913 	odd = !odd;
1914 	if (odd)
1915 	    buf[len] = n;
1916 	else
1917 	    buf[len++] |= (n << 4);
1918     }
1919     if (odd) {
1920 	buf[naiPos] |= 0x80;
1921 	len++;
1922     }
1923     XDebug(&__plugin,DebugAll,"setDigits encoding %u octets (%s)",len,odd ? "odd" : "even");
1924     data.append(buf,len);
1925 }
1926 
decodeCallNumber(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)1927 static bool decodeCallNumber(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data,
1928 	XmlElement* parent, bool addEnc, int& err)
1929 {
1930     if (!(param && type && data.length() && parent))
1931 	return false;
1932     XDebug(&__plugin,DebugAll,"decodeCallNumber(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
1933 	    parent->getTag().c_str(),parent,data.length());
1934     if (param->tag != tag)
1935 	return false;
1936     data.cut(-(int)tag.coding().length());
1937 
1938     XmlElement* child = new XmlElement(param->name);
1939     parent->addChild(child);
1940     int len = ASNLib::decodeLength(data);
1941     if (len < 2)
1942 	return false;
1943     unsigned int index = 0;
1944     unsigned char qualifier = 0;
1945     if (type->type == TcapXApplication::GenericNumber) {
1946 	if (len < 3)
1947 	    return false;
1948 	qualifier = data[index];
1949 	index++;
1950     }
1951     bool odd = (data[index] & 0x80) != 0;
1952     unsigned char nai = data[index] & 0x7f;
1953     index++;
1954     unsigned char plan = (data[index] >> 4) & 7;
1955     unsigned char pres = (data[index] >> 2) & 3;
1956     unsigned char scrn = data[index] & 3;
1957 
1958     if (type->type == TcapXApplication::GenericNumber)
1959 	child->setAttribute(s_qualifierAttr,lookup(qualifier,s_dict_qual,"unknown"));
1960     child->setAttribute(s_natureAttr,lookup(nai,s_dict_nai,"unknown"));
1961     child->setAttribute(s_planAttr,lookup(plan,s_dict_numPlanIsup,"unknown"));
1962     if (plan == 1)
1963 	child->setAttribute(s_encAttr,"e164");
1964 
1965     String tmp;
1966     switch (type->type) {
1967 	case TcapXApplication::CalledPartyNumber:
1968 	case TcapXApplication::LocationNumber:
1969 	    tmp = ((data[index] & 0x80) == 0);
1970 	    child->setAttribute(s_innAttr,tmp);
1971 	    break;
1972 	case TcapXApplication::CallingPartyNumber:
1973 	case TcapXApplication::GenericNumber:
1974 	    tmp = ((data[index] & 0x80) == 0);
1975 	    child->setAttribute(s_completeAttr,tmp);
1976 	    break;
1977 	default:
1978 	    break;
1979     }
1980     switch (type->type) {
1981 	case TcapXApplication::CallingPartyNumber:
1982 	case TcapXApplication::RedirectingNumber:
1983 	case TcapXApplication::OriginalCalledNumber:
1984 	case TcapXApplication::LocationNumber:
1985 	case TcapXApplication::GenericNumber:
1986 	    child->setAttribute(s_restrictAttr,lookup(pres,s_dict_presentation));
1987 	default:
1988 	    break;
1989     }
1990     switch (type->type) {
1991 	case TcapXApplication::CallingPartyNumber:
1992 	case TcapXApplication::LocationNumber:
1993 	case TcapXApplication::GenericNumber:
1994 	    child->setAttribute(s_screenedtAttr,lookup(scrn,s_dict_screening));
1995 	default:
1996 	    break;
1997     }
1998 
1999     index++;
2000     String digits;
2001     getDigits(digits,odd,data.data(index,len - index),len - index);
2002 
2003     data.cut(-len);
2004     child->addText(digits);
2005     return true;
2006 }
2007 
encodeCallNumber(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)2008 static bool encodeCallNumber(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
2009 {
2010     if (!(param && elem))
2011 	return false;
2012     XDebug(&__plugin,DebugAll,"encodeCallNumber(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
2013 	elem->getTag().c_str(),elem,data.length());
2014 
2015     unsigned char nai = lookup(elem->attribute(s_natureAttr),s_dict_nai,2) & 0x7f;
2016     unsigned char plan = lookup(elem->attribute(s_planAttr),s_dict_numPlanIsup,1);
2017 
2018     int b0 = -1;
2019     if (type->type == TcapXApplication::GenericNumber) {
2020 	b0 = 0;
2021 	b0 = 0xff & (lookup(elem->attribute(s_qualifierAttr),s_dict_presentation));
2022     }
2023 
2024     // Numbering plan
2025     unsigned char b2 = (plan & 7) << 4;
2026 
2027     switch (type->type) {
2028 	case TcapXApplication::CalledPartyNumber:
2029 	case TcapXApplication::LocationNumber:
2030 	    if (!TelEngine::null(elem->getAttribute(s_innAttr)) && !elem->getAttribute(s_innAttr)->toBoolean(true))
2031 		b2 |= 0x80;
2032 	    break;
2033 	case TcapXApplication::CallingPartyNumber:
2034 	case TcapXApplication::GenericNumber:
2035 	    if (!TelEngine::null(elem->getAttribute(s_completeAttr)) && !elem->getAttribute(s_completeAttr)->toBoolean(true))
2036 		b2 |= 0x80;
2037 	    break;
2038 	default:
2039 	    break;
2040     }
2041     switch (type->type) {
2042 	case TcapXApplication::CallingPartyNumber:
2043 	case TcapXApplication::RedirectingNumber:
2044 	case TcapXApplication::OriginalCalledNumber:
2045 	case TcapXApplication::LocationNumber:
2046 	case TcapXApplication::GenericNumber:
2047 	    b2 |= (lookup(elem->attribute(s_restrictAttr),s_dict_presentation) & 3) << 2;
2048 	default:
2049 	    break;
2050     }
2051     switch (param->type) {
2052 	case TcapXApplication::CallingPartyNumber:
2053 	case TcapXApplication::LocationNumber:
2054 	case TcapXApplication::GenericNumber:
2055 	    b2 |= (lookup(elem->attribute(s_screenedtAttr),s_dict_screening) & 3);
2056 	default:
2057 	    break;
2058     }
2059     const String& digits = elem->getText();
2060     setDigits(data,digits,nai,b2,b0);
2061 
2062     data.insert(ASNLib::buildLength(data));
2063     data.insert(param->tag.coding());
2064     return true;
2065 }
2066 
2067 
2068 // Redirection Information (Q,763 3.45) bits CBA
2069 static const TokenDict s_dict_redir_main[] = {
2070     { "none",                     0 },
2071     { "rerouted",                 1 },
2072     { "rerouted-restrict-all",    2 },
2073     { "diverted",                 3 },
2074     { "diverted-restrict-all",    4 },
2075     { "rerouted-restrict-number", 5 },
2076     { "diverted-restrict-number", 6 },
2077     { 0, 0 }
2078 };
2079 
2080 // Redirection Information (Q,763 3.45) bits HGFE or PONM
2081 static const TokenDict s_dict_redir_reason[] = {
2082     { "busy",      1 },
2083     { "noanswer",  2 },
2084     { "always",    3 },
2085     { "deflected", 4 },
2086     { "diverted",  5 },
2087     { "offline",   6 },
2088     { 0, 0 }
2089 };
2090 
2091 static const String s_reasonOrigAttr = "reason_original";
2092 static const String s_counterAttr = "counter";
2093 static const String s_reasonAttr = "reason";
2094 
decodeRedir(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)2095 static bool decodeRedir(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data,
2096 	XmlElement* parent, bool addEnc, int& err)
2097 {
2098     if (!(param && type && data.length() && parent))
2099 	return false;
2100     XDebug(&__plugin,DebugAll,"decodeRedir(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
2101 	    parent->getTag().c_str(),parent,data.length());
2102     if (param->tag != tag)
2103 	return false;
2104     data.cut(-(int)tag.coding().length());
2105 
2106     XmlElement* child = new XmlElement(param->name);
2107     parent->addChild(child);
2108     int len = ASNLib::decodeLength(data);
2109     if (len < 1)
2110 	return false;
2111 
2112     // Redirecting indicator
2113     unsigned char reason = data[0] & 0x07;
2114     child->addText(lookup(reason,s_dict_redir_main,""));
2115 
2116     // Original reason
2117     reason = data[0] >> 4;
2118     child->setAttribute(s_reasonOrigAttr,lookup(reason,s_dict_redir_reason));
2119 
2120     if (len > 1) {
2121 	// Counter
2122 	int count = data[1] & 0x07;
2123 	if (count)
2124 	    child->setAttribute(s_counterAttr,String(count));
2125 	// Reason
2126 	reason = data[1] >> 4;
2127 	if (reason)
2128 	    child->setAttribute(s_reasonAttr,lookup(reason,s_dict_redir_reason));
2129     }
2130     if (addEnc)
2131 	child->setAttribute(s_encAttr,"str");
2132     data.cut(-len);
2133     return true;
2134 }
2135 
encodeRedir(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)2136 static bool encodeRedir(const Parameter* param, MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
2137 {
2138     if (!(param && elem))
2139 	return false;
2140     XDebug(&__plugin,DebugAll,"encodeRedir(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
2141 	elem->getTag().c_str(),elem,data.length());
2142 
2143     unsigned char b0 = lookup(elem->getText(),s_dict_redir_main,0) & 0x07;
2144     b0 |= (lookup(elem->attribute(s_reasonOrigAttr),s_dict_redir_reason,0) & 0x0f) << 4;
2145     data.append(&b0,sizeof(b0));
2146 
2147     unsigned char b1 = String(elem->attribute(s_counterAttr)).toInteger() & 0x07;
2148     b1 |= (lookup(elem->attribute(s_reasonAttr),s_dict_redir_reason,0) & 0x0f) << 4;
2149     data.append(&b1,sizeof(b1));
2150 
2151     data.insert(ASNLib::buildLength(data));
2152     data.insert(param->tag.coding());
2153     return true;
2154 }
2155 
2156 // Coding standard as defined in Q.931/Q.850
2157 static const TokenDict s_dict_codingStandard[] = {
2158     {"CCITT",            0x00},
2159     {"ISO/IEC",          0x20},
2160     {"national",         0x40},
2161     {"network specific", 0x60},
2162     {0,0}
2163 };
2164 
2165 // Q.931 4.5.5. Information transfer capability: Bits 0-4
2166 // Defined for CCITT coding standard
2167 static const TokenDict s_dict_transferCapCCITT[] = {
2168     {"speech",       0x00},          // Speech
2169     {"udi",          0x08},          // Unrestricted digital information
2170     {"rdi",          0x09},          // Restricted digital information
2171     {"3.1khz-audio", 0x10},          // 3.1 khz audio
2172     {"udi-ta",       0x11},          // Unrestricted digital information with tone/announcements
2173     {"video",        0x18},          // Video
2174     {0,0}
2175 };
2176 
2177 // Q.931 4.5.5. Transfer mode: Bits 5,6
2178 // Defined for CCITT coding standard
2179 static const TokenDict s_dict_transferModeCCITT[] = {
2180     {"circuit",      0x00},          // Circuit switch mode
2181     {"packet",       0x40},          // Packet mode
2182     {0,0}
2183 };
2184 
2185 // Q.931 4.5.5. Transfer rate: Bits 0-4
2186 // Defined for CCITT coding standard
2187 static const TokenDict s_dict_transferRateCCITT[] = {
2188     {"packet",        0x00},         // Packet mode only
2189     {"64kbit",        0x10},         // 64 kbit/s
2190     {"2x64kbit",      0x11},         // 2x64 kbit/s
2191     {"384kbit",       0x13},         // 384 kbit/s
2192     {"1536kbit",      0x15},         // 1536 kbit/s
2193     {"1920kbit",      0x17},         // 1920 kbit/s
2194     {"multirate",     0x18},         // Multirate (64 kbit/s base rate)
2195     {0,0}
2196 };
2197 
2198 // Q.931 4.5.5. User information Layer 1 protocol: Bits 0-4
2199 // Defined for CCITT coding standard
2200 static const TokenDict s_dict_formatCCITT[] = {
2201     {"v110",          0x01},         // Recomendation V.110 and X.30
2202     {"mulaw",         0x02},         // Recomendation G.711 mu-law
2203     {"alaw",          0x03},         // Recomendation G.711 A-law
2204     {"g721",          0x04},         // Recomendation G.721 32kbit/s ADPCM and I.460
2205     {"h221",          0x05},         // Recomendation H.221 and H.242
2206     {"non-CCITT",     0x07},         // Non CCITT standardized rate adaption
2207     {"v120",          0x08},         // Recomendation V.120
2208     {"x31",           0x09},         // Recomendation X.31 HDLC flag stuffing
2209     {0,0}
2210 };
2211 
2212 static const String s_codingAttr = "coding";
2213 static const String s_transferCapAttr = "transfercap";
2214 static const String s_transferModeAttr = "transfermode";
2215 static const String s_transferRateAttr = "transferrate";
2216 static const String s_multiplierAttr = "multiplier";
2217 
decodeUSI(const Parameter * param,MapCamelType * type,AsnTag & tag,DataBlock & data,XmlElement * parent,bool addEnc,int & err)2218 static bool decodeUSI(const Parameter* param, MapCamelType* type, AsnTag& tag, DataBlock& data,
2219 	XmlElement* parent, bool addEnc, int& err)
2220 {
2221     if (!(param && type && data.length() && parent))
2222 	return false;
2223     XDebug(&__plugin,DebugAll,"decodeUSI(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
2224 	    parent->getTag().c_str(),parent,data.length());
2225     if (param->tag != tag)
2226 	return false;
2227     data.cut(-(int)tag.coding().length());
2228 
2229     XmlElement* child = new XmlElement(param->name);
2230     parent->addChild(child);
2231     int len = ASNLib::decodeLength(data);
2232     if (len < 2)
2233 	return false;
2234 
2235     // Byte 0: Coding standard (bit 5,6), Information transfer capability (bit 0-4)
2236     // Byte 1: Transfer mode (bit 5,6), Transfer rate (bit 0-4)
2237     unsigned char coding = data[0] & 0x60;
2238     child->setAttribute(s_codingAttr,lookup(coding,s_dict_codingStandard));
2239     coding = data[0] & 0x1f;
2240     child->setAttribute(s_transferCapAttr,lookup(coding,s_dict_transferCapCCITT));
2241     coding = data[1] & 0x60;
2242     child->setAttribute(s_transferModeAttr,lookup(coding,s_dict_transferModeCCITT));
2243     u_int8_t rate = data[1] & 0x1f;
2244     child->setAttribute(s_transferRateAttr,lookup(rate,s_dict_transferRateCCITT));
2245     // Figure 4.11 Note 1: Next byte is the rate multiplier if the transfer rate is 'multirate' (0x18)
2246     u_int8_t crt = 2;
2247     if (rate == 0x18) {
2248 	if (len < 3) {
2249 	    Debug(&__plugin,DebugMild,"decodeUSI(). Invalid length %u. No rate multiplier",len);
2250 	    return false;
2251 	}
2252 	child->setAttribute(s_multiplierAttr,String(data[2] & 0x7f));
2253 	crt = 3;
2254     }
2255     if (len <= crt) {
2256 	data.cut(-len);
2257 	return true;
2258     }
2259 
2260     u_int8_t ident = (data[crt] & 0x60) >> 5;
2261     if (ident != 1) {
2262 	Debug(&__plugin,DebugNote,"decodeUSI(). Invalid layer 1 ident %u",ident);
2263 	return true;
2264     }
2265     child->addText(lookup(data[crt] & 0x1f,s_dict_formatCCITT));
2266 
2267     data.cut(-len);
2268     return true;
2269 }
2270 
encodeUSI(const Parameter * param,MapCamelType * type,DataBlock & data,XmlElement * elem,int & err)2271 static bool encodeUSI(const Parameter* param,  MapCamelType* type, DataBlock& data, XmlElement* elem, int& err)
2272 {
2273     if (!(param && elem))
2274 	return false;
2275     XDebug(&__plugin,DebugAll,"encodUSI(param=%s[%p],elem=%s[%p],datalen=%d)",param->name.c_str(),param,
2276 	elem->getTag().c_str(),elem,data.length());
2277 
2278     u_int8_t buff[5] = {2,0x00,0x80,0x80,0x80};
2279     unsigned char coding = lookup(elem->attribute(s_codingAttr),s_dict_codingStandard,0);
2280     unsigned char cap = lookup(elem->attribute(s_transferCapAttr),s_dict_transferCapCCITT,0);
2281     unsigned char mode = lookup(elem->attribute(s_transferModeAttr),s_dict_transferModeCCITT,0);
2282     unsigned char rate = lookup(elem->attribute(s_transferRateAttr),s_dict_transferRateCCITT,0x10);
2283 
2284     buff[1] = (coding & 0x60) | (cap & 0x1f);
2285     buff[2] |= (mode & 0x60) | (rate & 0x1f);
2286     if (rate == 0x18) {
2287 	buff[0] = 3;
2288 	rate = String(elem->attribute(s_multiplierAttr)).toInteger();
2289 	buff[3] |= rate & 0x7f;
2290     }
2291     // User information layer data
2292     // Bit 7 = 1, Bits 5,6 = layer (1), Bits 0-4: the value
2293     int format = lookup(elem->getText(),s_dict_formatCCITT,-1);
2294     if (format != -1) {
2295 	buff[buff[0] + 1] |= 0x20 | (((unsigned char)format) & 0x1f);
2296 	buff[0]++;
2297     }
2298     data.assign(buff,buff[0] + 1);
2299     data.insert(param->tag.coding());
2300     return true;
2301 }
2302 
2303 static const StringList s_locationManagementCapabOps("updateLocation,cancelLocation,purgeMS,updateGprsLocation,anyTimeInterrogation");
2304 static const StringList s_authenticationCapabOps("sendAuthenticationInfo,authenticationFailureReport");
2305 static const StringList s_subscriberDataCapabOps("insertSubscriberData,deleteSubscriberData,restoreData");
2306 static const StringList s_routingCapabOps("sendRoutingInfoForGprs,sendRoutingInfoForLCS,statusReport");
2307 static const StringList s_vlrRoutingCapabOps("provideRoamingNumber,provideSubscriberInfo");
2308 static const StringList s_traceSubscriberCapabOps("activateTraceMode,deactivateTraceMode");
2309 static const StringList s_servicesCapabOps("registerSS,eraseSS,activateSS,deactivateSS,interrogateSS,registerPassword,getPassword,"
2310 				    "processUnstructuredSS-Request,unstructuredSS-Request,unstructuredSS-Notify");
2311 static const StringList s_miscellaneousCapabOps("sendIMSI,readyForSM,setReportingState");
2312 static const StringList s_errorRecoveryCapabOps("reset,forwardCheckSS-Indication,failureReport");
2313 static const StringList s_smscCapabOps("informServiceCentre,alertServiceCentre,sendRoutingInfoForSM,mo-forwardSM,mt-forwardSM,forwardSM");
2314 
2315 static const StringList s_noOps("");
2316 
2317 static const Capability s_mapCapab[] = {
2318     {"LocationManagement",       s_locationManagementCapabOps},
2319     {"Authentication",           s_authenticationCapabOps},
2320     {"SubscriberData",           s_subscriberDataCapabOps},
2321     {"Routing",                  s_routingCapabOps},
2322     {"VLR-Routing",              s_vlrRoutingCapabOps},
2323     {"TraceSubscriber",          s_traceSubscriberCapabOps},
2324     {"Services",                 s_servicesCapabOps},
2325     {"Miscellaneous",            s_miscellaneousCapabOps},
2326     {"ErrorRecovery",            s_errorRecoveryCapabOps},
2327     {"Charging",                 s_noOps},
2328     {"SMSC",                     s_smscCapabOps},
2329     {"None",                     s_noOps},
2330     {0, s_noOps},
2331 };
2332 
2333 static const StringList s_smscCapabOIDs("shortMsgMO-RelayContext-v3,shortMsgMO-RelayContext-v2,shortMsgMO-RelayContext-v1,"
2334 					"shortMsgMT-RelayContext-v3,shortMsgMT-RelayContext-v2");
2335 static const Capability s_mapCapabOID[] = {
2336     {"SMSC",                     s_smscCapabOIDs},
2337     {"None",                     s_noOps},
2338     {0, s_noOps},
2339 };
2340 
2341 static const Capability s_camelCapabOID[] = {
2342     {"None",                     s_noOps},
2343     {0, s_noOps},
2344 };
2345 
2346 
2347 static const MapCamelType s_types[] = {
2348     {TcapXApplication::Null,                   TcapXApplication::NullEnc,       decodeNull,        encodeNull},
2349     {TcapXApplication::Integer,                TcapXApplication::IntEnc,        decodeInt,         encodeInt},
2350     {TcapXApplication::OID,                    TcapXApplication::OIDEnc,        decodeOID,         encodeOID},
2351     {TcapXApplication::TBCD,                   TcapXApplication::StringEnc,     decodeTBCD,        encodeTBCD},
2352     {TcapXApplication::AddressString,          TcapXApplication::TelephonyEnc,  decodeTel,         encodeTel},
2353     {TcapXApplication::HexString,              TcapXApplication::HexEnc,        decodeHex,         encodeHex},
2354     {TcapXApplication::Sequence,               TcapXApplication::NoEnc,         decodeSeq,         encodeSeq},
2355     {TcapXApplication::SequenceOf,             TcapXApplication::NoEnc,         decodeSeqOf,       encodeSeqOf},
2356     // for now, use the same encoder/decoder as SequenceOf, TODO - if needed,replace it
2357     {TcapXApplication::SetOf,                  TcapXApplication::NoEnc,         decodeSeqOf,       encodeSeqOf},
2358     {TcapXApplication::Choice,                 TcapXApplication::NoEnc,         decodeChoice,      encodeChoice},
2359     {TcapXApplication::Enumerated,             TcapXApplication::NoEnc,         decodeEnumerated,  encodeEnumerated},
2360     {TcapXApplication::GSMString,              TcapXApplication::StringEnc,     decodeGSMString,   encodeGSMString},
2361     {TcapXApplication::BitString,              TcapXApplication::HexEnc,        decodeBitString,   encodeBitString},
2362     {TcapXApplication::Flags,                  TcapXApplication::StringEnc,     decodeFlags,       encodeFlags},
2363     {TcapXApplication::AppString,              TcapXApplication::StringEnc,     decodeString,      encodeString},
2364     {TcapXApplication::Bool,                   TcapXApplication::BoolEnc,       decodeBool,        encodeBool},
2365     {TcapXApplication::CellIdFixedLength,      TcapXApplication::StringEnc,     decodeTBCD,        encodeTBCD},
2366     {TcapXApplication::LAIFixedLength,         TcapXApplication::StringEnc,     decodeTBCD,        encodeTBCD},
2367     {TcapXApplication::CalledPartyNumber,      TcapXApplication::TelephonyEnc,  decodeCallNumber,  encodeCallNumber},
2368     {TcapXApplication::CallingPartyNumber,     TcapXApplication::TelephonyEnc,  decodeCallNumber,  encodeCallNumber},
2369     {TcapXApplication::LocationNumber,         TcapXApplication::TelephonyEnc,  decodeCallNumber,  encodeCallNumber},
2370     {TcapXApplication::OriginalCalledNumber,   TcapXApplication::TelephonyEnc,  decodeCallNumber,  encodeCallNumber},
2371     {TcapXApplication::RedirectingNumber,      TcapXApplication::TelephonyEnc,  decodeCallNumber,  encodeCallNumber},
2372     {TcapXApplication::GenericNumber,          TcapXApplication::TelephonyEnc,  decodeCallNumber,  encodeCallNumber},
2373     {TcapXApplication::ChargeNumber,           TcapXApplication::TelephonyEnc,  decodeCallNumber,  encodeCallNumber},
2374     {TcapXApplication::RedirectionInformation, TcapXApplication::StringEnc,     decodeRedir,       encodeRedir},
2375     {TcapXApplication::UserServiceInfo,        TcapXApplication::NoEnc,         decodeUSI,         encodeUSI},
2376     // TODO High Layer Compatibility encode/decode implementation  - see User teleservice information (Q.763 3.59)
2377     {TcapXApplication::HiLayerCompat,          TcapXApplication::NoEnc,         decodeHex,         encodeHex},
2378     {TcapXApplication::None,                   TcapXApplication::NoEnc,         0,                 0},
2379 };
2380 
2381 
findType(TcapXApplication::ParamType type)2382 static const MapCamelType* findType(TcapXApplication::ParamType type)
2383 {
2384     const MapCamelType* t = s_types;
2385     while (t->type != TcapXApplication::None) {
2386 	if (t->type == type)
2387 	    return t;
2388 	t++;
2389     }
2390     return 0;
2391 }
2392 
2393 static const AsnTag s_ctxtPrim_0_Tag(AsnTag::Context, AsnTag::Primitive, 0);
2394 static const AsnTag s_ctxtPrim_1_Tag(AsnTag::Context, AsnTag::Primitive, 1);
2395 static const AsnTag s_ctxtPrim_2_Tag(AsnTag::Context, AsnTag::Primitive, 2);
2396 static const AsnTag s_ctxtPrim_3_Tag(AsnTag::Context, AsnTag::Primitive, 3);
2397 static const AsnTag s_ctxtPrim_4_Tag(AsnTag::Context, AsnTag::Primitive, 4);
2398 static const AsnTag s_ctxtPrim_5_Tag(AsnTag::Context, AsnTag::Primitive, 5);
2399 static const AsnTag s_ctxtPrim_6_Tag(AsnTag::Context, AsnTag::Primitive, 6);
2400 static const AsnTag s_ctxtPrim_7_Tag(AsnTag::Context, AsnTag::Primitive, 7);
2401 static const AsnTag s_ctxtPrim_8_Tag(AsnTag::Context, AsnTag::Primitive, 8);
2402 static const AsnTag s_ctxtPrim_9_Tag(AsnTag::Context, AsnTag::Primitive, 9);
2403 static const AsnTag s_ctxtPrim_10_Tag(AsnTag::Context, AsnTag::Primitive, 10);
2404 static const AsnTag s_ctxtPrim_11_Tag(AsnTag::Context, AsnTag::Primitive, 11);
2405 static const AsnTag s_ctxtPrim_12_Tag(AsnTag::Context, AsnTag::Primitive, 12);
2406 static const AsnTag s_ctxtPrim_13_Tag(AsnTag::Context, AsnTag::Primitive, 13);
2407 static const AsnTag s_ctxtPrim_14_Tag(AsnTag::Context, AsnTag::Primitive, 14);
2408 static const AsnTag s_ctxtPrim_15_Tag(AsnTag::Context, AsnTag::Primitive, 15);
2409 static const AsnTag s_ctxtPrim_16_Tag(AsnTag::Context, AsnTag::Primitive, 16);
2410 static const AsnTag s_ctxtPrim_17_Tag(AsnTag::Context, AsnTag::Primitive, 17);
2411 static const AsnTag s_ctxtPrim_18_Tag(AsnTag::Context, AsnTag::Primitive, 18);
2412 static const AsnTag s_ctxtPrim_19_Tag(AsnTag::Context, AsnTag::Primitive, 19);
2413 static const AsnTag s_ctxtPrim_20_Tag(AsnTag::Context, AsnTag::Primitive, 20);
2414 static const AsnTag s_ctxtPrim_21_Tag(AsnTag::Context, AsnTag::Primitive, 21);
2415 static const AsnTag s_ctxtPrim_22_Tag(AsnTag::Context, AsnTag::Primitive, 22);
2416 static const AsnTag s_ctxtPrim_23_Tag(AsnTag::Context, AsnTag::Primitive, 23);
2417 static const AsnTag s_ctxtPrim_24_Tag(AsnTag::Context, AsnTag::Primitive, 24);
2418 static const AsnTag s_ctxtPrim_25_Tag(AsnTag::Context, AsnTag::Primitive, 25);
2419 static const AsnTag s_ctxtPrim_26_Tag(AsnTag::Context, AsnTag::Primitive, 26);
2420 static const AsnTag s_ctxtPrim_27_Tag(AsnTag::Context, AsnTag::Primitive, 27);
2421 static const AsnTag s_ctxtPrim_28_Tag(AsnTag::Context, AsnTag::Primitive, 28);
2422 static const AsnTag s_ctxtPrim_29_Tag(AsnTag::Context, AsnTag::Primitive, 29);
2423 static const AsnTag s_ctxtPrim_30_Tag(AsnTag::Context, AsnTag::Primitive, 30);
2424 static const AsnTag s_ctxtPrim_33_Tag(AsnTag::Context, AsnTag::Primitive, 33);
2425 static const AsnTag s_ctxtPrim_34_Tag(AsnTag::Context, AsnTag::Primitive, 34);
2426 static const AsnTag s_ctxtPrim_35_Tag(AsnTag::Context, AsnTag::Primitive, 35);
2427 static const AsnTag s_ctxtPrim_50_Tag(AsnTag::Context, AsnTag::Primitive, 50);
2428 static const AsnTag s_ctxtPrim_53_Tag(AsnTag::Context, AsnTag::Primitive, 53);
2429 static const AsnTag s_ctxtPrim_54_Tag(AsnTag::Context, AsnTag::Primitive, 54);
2430 static const AsnTag s_ctxtPrim_55_Tag(AsnTag::Context, AsnTag::Primitive, 55);
2431 static const AsnTag s_ctxtPrim_56_Tag(AsnTag::Context, AsnTag::Primitive, 56);
2432 static const AsnTag s_ctxtPrim_57_Tag(AsnTag::Context, AsnTag::Primitive, 57);
2433 static const AsnTag s_ctxtPrim_58_Tag(AsnTag::Context, AsnTag::Primitive, 58);
2434 
2435 static const AsnTag s_ctxtCstr_0_Tag(AsnTag::Context, AsnTag::Constructor, 0);
2436 static const AsnTag s_ctxtCstr_1_Tag(AsnTag::Context, AsnTag::Constructor, 1);
2437 static const AsnTag s_ctxtCstr_2_Tag(AsnTag::Context, AsnTag::Constructor, 2);
2438 static const AsnTag s_ctxtCstr_3_Tag(AsnTag::Context, AsnTag::Constructor, 3);
2439 static const AsnTag s_ctxtCstr_4_Tag(AsnTag::Context, AsnTag::Constructor, 4);
2440 static const AsnTag s_ctxtCstr_5_Tag(AsnTag::Context, AsnTag::Constructor, 5);
2441 static const AsnTag s_ctxtCstr_6_Tag(AsnTag::Context, AsnTag::Constructor, 6);
2442 static const AsnTag s_ctxtCstr_7_Tag(AsnTag::Context, AsnTag::Constructor, 7);
2443 static const AsnTag s_ctxtCstr_8_Tag(AsnTag::Context, AsnTag::Constructor, 8);
2444 static const AsnTag s_ctxtCstr_9_Tag(AsnTag::Context, AsnTag::Constructor, 9);
2445 static const AsnTag s_ctxtCstr_10_Tag(AsnTag::Context, AsnTag::Constructor, 10);
2446 static const AsnTag s_ctxtCstr_11_Tag(AsnTag::Context, AsnTag::Constructor, 11);
2447 static const AsnTag s_ctxtCstr_12_Tag(AsnTag::Context, AsnTag::Constructor, 12);
2448 static const AsnTag s_ctxtCstr_13_Tag(AsnTag::Context, AsnTag::Constructor, 13);
2449 static const AsnTag s_ctxtCstr_14_Tag(AsnTag::Context, AsnTag::Constructor, 14);
2450 static const AsnTag s_ctxtCstr_15_Tag(AsnTag::Context, AsnTag::Constructor, 15);
2451 static const AsnTag s_ctxtCstr_16_Tag(AsnTag::Context, AsnTag::Constructor, 16);
2452 static const AsnTag s_ctxtCstr_17_Tag(AsnTag::Context, AsnTag::Constructor, 17);
2453 static const AsnTag s_ctxtCstr_18_Tag(AsnTag::Context, AsnTag::Constructor, 18);
2454 static const AsnTag s_ctxtCstr_21_Tag(AsnTag::Context, AsnTag::Constructor, 21);
2455 static const AsnTag s_ctxtCstr_22_Tag(AsnTag::Context, AsnTag::Constructor, 22);
2456 static const AsnTag s_ctxtCstr_23_Tag(AsnTag::Context, AsnTag::Constructor, 23);
2457 static const AsnTag s_ctxtCstr_24_Tag(AsnTag::Context, AsnTag::Constructor, 24);
2458 static const AsnTag s_ctxtCstr_25_Tag(AsnTag::Context, AsnTag::Constructor, 25);
2459 static const AsnTag s_ctxtCstr_27_Tag(AsnTag::Context, AsnTag::Constructor, 27);
2460 static const AsnTag s_ctxtCstr_28_Tag(AsnTag::Context, AsnTag::Constructor, 28);
2461 static const AsnTag s_ctxtCstr_29_Tag(AsnTag::Context, AsnTag::Constructor, 29);
2462 static const AsnTag s_ctxtCstr_30_Tag(AsnTag::Context, AsnTag::Constructor, 30);
2463 static const AsnTag s_ctxtCstr_31_Tag(AsnTag::Context, AsnTag::Constructor, 31);
2464 static const AsnTag s_ctxtCstr_32_Tag(AsnTag::Context, AsnTag::Constructor, 32);
2465 static const AsnTag s_ctxtCstr_50_Tag(AsnTag::Context, AsnTag::Constructor, 50);
2466 static const AsnTag s_ctxtCstr_51_Tag(AsnTag::Context, AsnTag::Constructor, 51);
2467 static const AsnTag s_ctxtCstr_52_Tag(AsnTag::Context, AsnTag::Constructor, 52);
2468 static const AsnTag s_ctxtCstr_53_Tag(AsnTag::Context, AsnTag::Constructor, 53);
2469 static const AsnTag s_ctxtCstr_57_Tag(AsnTag::Context, AsnTag::Constructor, 57);
2470 static const AsnTag s_ctxtCstr_59_Tag(AsnTag::Context, AsnTag::Constructor, 59);
2471 
2472 static const TokenDict s_camelPhases[] = {
2473     {"phase1",      1},
2474     {"phase2",      2},
2475     {"phase3",      4},
2476     {"phase4",      8},
2477     {0,0},
2478 };
2479 
2480 static const TokenDict s_ISTSupportIndicator[] = {
2481     {"basicISTSupported",   0},
2482     {"istCommandSupported", 1},
2483     {0,                     0},
2484 };
2485 
2486 static const Parameter s_superChargerInfo[] = {
2487     {"sendSubscriberData",      s_ctxtPrim_0_Tag, false, TcapXApplication::Null,          0},
2488     {"subscriberDataStored",    s_ctxtPrim_1_Tag, false, TcapXApplication::HexString,     0},
2489     {"",                        s_noTag,          false, TcapXApplication::None,          0},
2490 };
2491 
2492 static const TokenDict s_supportedLCSCapabilitySets[] = {
2493     {"lcsCapabilitySet1",  0x01},
2494     {"lcsCapabilitySet2",  0x02},
2495     {"lcsCapabilitySet3",  0x04},
2496     {"lcsCapabilitySet4",  0x08},
2497     {"lcsCapabilitySet5",  0x10},
2498     {0,                    0},
2499 };
2500 
2501 static const TokenDict s_offeredCamel4CSIs[] = {
2502     {"o-csi",            0x01},
2503     {"d-csi",            0x02},
2504     {"vt-csi",           0x04},
2505     {"t-csi",            0x08},
2506     {"mt-sms-csi",       0x10},
2507     {"mg-csi",           0x20},
2508     {"psi-enhancements", 0x40},
2509     {0,                  0},
2510 };
2511 
2512 static const TokenDict s_supportedRATTypes[] = {
2513     {"utran",            0x01},
2514     {"geran",            0x02},
2515     {"gan",              0x04},
2516     {"i-hspa-evolution", 0x08},
2517     {"e-utran",          0x10},
2518     {0,                  0},
2519 };
2520 
2521 static const Parameter s_vlrCapability[] = {
2522     {"supportedCamelPhases",                        s_ctxtPrim_0_Tag, true, TcapXApplication::BitString,  s_camelPhases},
2523     {"extensionContainer",                          s_sequenceTag,    true, TcapXApplication::HexString,  0},
2524     {"solsaSupportIndicator",                       s_ctxtPrim_2_Tag, true, TcapXApplication::Null,       0},
2525     {"istSupportIndicator",                         s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_ISTSupportIndicator},
2526     {"superChargerSupportedInServingNetworkEntity", s_ctxtCstr_3_Tag, true, TcapXApplication::Choice,     s_superChargerInfo},
2527     {"longFTN-Supported",                           s_ctxtPrim_4_Tag, true, TcapXApplication::Null,       0},
2528     {"supportedLCS-CapabilitySets",                 s_ctxtPrim_5_Tag, true, TcapXApplication::BitString,  s_supportedLCSCapabilitySets},
2529     {"offeredCamel4CSIs",                           s_ctxtPrim_6_Tag, true, TcapXApplication::BitString,  s_offeredCamel4CSIs},
2530     {"supportedRAT-TypesIndicator",                 s_ctxtPrim_7_Tag, true, TcapXApplication::BitString,  s_supportedRATTypes},
2531     {"longGroupID-Supported",                       s_ctxtPrim_8_Tag, true, TcapXApplication::Null,       0},
2532     {"",                                            s_noTag,          false,TcapXApplication::None,       0},
2533 };
2534 
2535 static const Parameter s_addInfoSeq[] = {
2536     {"imeisv",                       s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD, 0},
2537     {"skipSubscriberDataUpdate",     s_ctxtPrim_1_Tag, true,  TcapXApplication::Null, 0},
2538     {"",                             s_noTag,          false, TcapXApplication::None, 0},
2539 };
2540 
2541 static const Parameter s_locationArea[] = {
2542     {"laiFixedLength",    s_ctxtPrim_0_Tag, false, TcapXApplication::LAIFixedLength,    0},
2543     {"lac",               s_ctxtPrim_1_Tag, false, TcapXApplication::HexString,         0},
2544     {"",                  s_noTag,          false, TcapXApplication::None,              0},
2545 };
2546 
2547 static const Parameter s_locationAreaChoice[] = {
2548     {"locationArea",      s_noTag, false, TcapXApplication::Choice,    s_locationArea},
2549     {"",                  s_noTag, false, TcapXApplication::None,      0},
2550 };
2551 
2552 static const Parameter s_imsiWithLmsi[] = {
2553     {"imsi",              s_hexTag,    false,   TcapXApplication::TBCD,      0},
2554     {"lmsi",              s_hexTag,    false,   TcapXApplication::HexString, 0},
2555     {"",                  s_noTag,     false,   TcapXApplication::None,      0},
2556 };
2557 
2558 static const Parameter s_mapIdentity[] = {
2559     {"imsi",              s_hexTag,         false,    TcapXApplication::TBCD,      0},
2560     {"imsi-WithLMSI",     s_sequenceTag,    false,    TcapXApplication::Sequence,  s_imsiWithLmsi},
2561     {"",                  s_noTag,          false,    TcapXApplication::None,      0},
2562 };
2563 
2564 static const TokenDict s_cancellationType[] = {
2565     {"updateProcedure",         0x00},
2566     {"subscriptionWithdraw",    0x01},
2567     {"initialAttachProcedure",  0x02},
2568     {0,0},
2569 };
2570 
2571 static const TokenDict s_typeOfUpdate[] = {
2572     {"sgsn-change",   0x00},
2573     {"mme-change",    0x01},
2574     {0,0},
2575 };
2576 
2577 static const TokenDict s_protocolId[] = {
2578     {"gsm-0408",    0x01},
2579     {"gsm-0806",    0x02},
2580     {"gsm-BSSMAP",  0x03},
2581     {"ets-300102-1",0x04},
2582     {0,0},
2583 };
2584 
2585 static const Parameter s_externalSignalInfo[] = {
2586     {"protocolId",        s_enumTag,       false,    TcapXApplication::Enumerated,    s_protocolId},
2587     {"signalInfo",        s_hexTag,        false,    TcapXApplication::HexString,     0},
2588     {"extensionContainer",s_sequenceTag,   true,     TcapXApplication::HexString,     0},
2589     {"",                  s_noTag,         false,    TcapXApplication::None,          0},
2590 };
2591 
2592 static const TokenDict s_alertPattern[] = {
2593     {"alertingLevel-0",    0x00},
2594     {"alertingLevel-1",    0x01},//   AlertingPattern ::= '00000001'B
2595     {"alertingLevel-2",    0x02},//   AlertingPattern ::= '00000010'B
2596     {"alertingCategory-1", 0x04},//   AlertingPattern ::= '00000100'B
2597     {"alertingCategory-2", 0x05},//   AlertingPattern ::= '00000101'B
2598     {"alertingCategory-3", 0x06},//   AlertingPattern ::= '00000110'B
2599     {"alertingCategory-4", 0x07},//   AlertingPattern ::= '00000111'B
2600     {"alertingCategory-5", 0x08},//   AlertingPattern ::= '00001000'B
2601     {0,0},
2602 };
2603 
2604 static const TokenDict s_extProtocolId[] = {
2605     {"ets-300356",    0x01},
2606     {0,0},
2607 };
2608 
2609 static const Parameter s_extExtenalSignalInfo[] = {
2610     {"ext-protocolId",    s_enumTag,      false,    TcapXApplication::Enumerated,    s_extProtocolId},
2611     {"signalInfo",        s_hexTag,       false,    TcapXApplication::HexString,     0},
2612     {"extensionContainer",s_sequenceTag,  true,     TcapXApplication::HexString,     0},
2613     {"",                  s_noTag,        false,    TcapXApplication::None,          0},
2614 };
2615 
2616 static const TokenDict s_category[] = {
2617     { "unknown",     0x00 },                // calling party's category is unknown
2618     { "operator-FR", 0x01 },                // operator, language French
2619     { "operator-EN", 0x02 },                // operator, language English
2620     { "operator-DE", 0x03 },                // operator, language German
2621     { "operator-RU", 0x04 },                // operator, language Russian
2622     { "operator-ES", 0x05 },                // operator, language Spanish
2623     { "ordinary",    0x0a },                // ordinary calling subscriber
2624     { "priority",    0x0b },                // calling subscriber with priority
2625     { "data",        0x0c },                // data call (voice band data)
2626     { "test",        0x0d },                // test call
2627     { "payphone",    0x0f },                // payphone
2628     { 0, 0 },
2629 };
2630 
2631 static const TokenDict s_subscriberStatus[] = {
2632     {"serviceGranted",                 0x00},
2633     {"operatorDeterminedBarring",      0x01},
2634     {0,0},
2635 };
2636 
2637 static const TokenDict s_SSCode[] = {
2638 // TS 100 974 v7.15.0 page 321
2639     {"allSS",                      0x00}, //    SS-Code ::= '00000000'B  -- all SS
2640     {"allLineIdentificationSS",    0x10}, //    SS-Code ::= '00010000'B  -- all line identification SS
2641     {"clip",                       0x11}, //    SS-Code ::= '00010001'B  -- calling line identification presentation
2642     {"clir",                       0x12}, //    SS-Code ::= '00010010'B  -- calling line identification restriction
2643     {"colp",                       0x13}, //    SS-Code ::= '00010011'B  -- connected line identification presentation
2644     {"colr",                       0x14}, //    SS-Code ::= '00010100'B  -- connected line identification restriction
2645     {"mci",                        0x15}, //    SS-Code ::= '00010101'B  -- malicious call identification
2646     {"allNameIdentificationSS",    0x18}, //    SS-Code ::= '00011000'B  -- all name identification SS
2647     {"cnap",                       0x19}, //    SS-Code ::= '00011001'B  -- calling name presentation
2648     {"allForwardingSS",            0x20}, //    SS-Code ::= '00100000'B  -- all forwarding SS
2649     {"cfu",                        0x21}, //    SS-Code ::= '00100001'B  -- call forwarding unconditional
2650     {"allCondForwardingSS",        0x28}, //    SS-Code ::= '00101000'B  -- all conditional forwarding SS
2651     {"cfb",                        0x29}, //    SS-Code ::= '00101001'B  -- call forwarding on mobile subscriber busy
2652     {"cfnry",                      0x2a}, //    SS-Code ::= '00101010'B  -- call forwarding on no reply
2653     {"cfnrc",                      0x2b}, //    SS-Code ::= '00101011'B  -- call forwarding on mobile subscriber not reachable
2654     {"cd",                         0x24}, //    SS-Code ::= '00100100'B  -- call deflection
2655     {"allCallOfferingSS",          0x30}, //    SS-Code ::= '00110000'B  -- all call offering SS includes also all forwarding SS
2656     {"ect",                        0x31}, //    SS-Code ::= '00110001'B  -- explicit call transfer
2657     {"mah",                        0x32}, //    SS-Code ::= '00110010'B  -- mobile access hunting
2658     {"allCallCompletionSS",        0x40}, //    SS-Code ::= '01000000'B  -- all Call completion SS
2659     {"cw",                         0x41}, //    SS-Code ::= '01000001'B  -- call waiting
2660     {"hold",                       0x42}, //    SS-Code ::= '01000010'B  -- call hold
2661     {"ccbs-A",                     0x43}, //    SS-Code ::= '01000011'B  -- completion of call to busy subscribers, originating side
2662     {"ccbs-B",                     0x44}, //    SS-Code ::= '01000100'B  -- completion of call to busy subscribers, destination side
2663     {"allMultiPartySS",            0x50}, //    SS-Code ::= '01010000'B  -- all multiparty SS
2664     {"multiPTY",                   0x51}, //    SS-Code ::= '01010001'B  -- multiparty
2665     {"allCommunityOfInterest-SS",  0x60}, //    SS-Code ::= '01100000'B  -- all community of interest SS
2666     {"cug",                        0x61}, //    SS-Code ::= '01100001'B  -- closed user group
2667     {"allChargingSS",              0x70}, //    SS-Code ::= '01110000'B  -- all charging SS
2668     {"aoci",                       0x71}, //    SS-Code ::= '01110001'B  -- advice of charge information
2669     {"aocc",                       0x72}, //    SS-Code ::= '01110010'B  -- advice of charge charging
2670     {"allAdditionalInfoTransferSS",0x80}, //    SS-Code ::= '10000000'B  -- all additional information transfer SS
2671     {"uus1",                       0x81}, //    SS-Code ::= '10000001'B  -- UUS1 user-to-user signalling
2672     {"uus2",                       0x82}, //    SS-Code ::= '10000010'B  -- UUS2 user-to-user signalling
2673     {"uus3",                       0x83}, //    SS-Code ::= '10000011'B  -- UUS3 user-to-user signalling
2674     {"allBarringSS",               0x90}, //    SS-Code ::= '10010000'B  -- all barring SS
2675     {"barringOfOutgoingCalls",     0x91}, //    SS-Code ::= '10010001'B  -- barring of outgoing calls
2676     {"baoc",                       0x92}, //    SS-Code ::= '10010010'B  -- barring of all outgoing calls
2677     {"boic",                       0x93}, //    SS-Code ::= '10010011'B  -- barring of outgoing international calls
2678     {"boicExHC",                   0x94}, //    SS-Code ::= '10010100'B  -- barring of outgoing international calls except those directed to the home PLMN
2679     {"barringOfIncomingCalls",     0x99}, //    SS-Code ::= '10011001'B  -- barring of incoming calls
2680     {"baic",                       0x9a}, //    SS-Code ::= '10011010'B  -- barring of all incoming calls
2681     {"bicRoam",                    0x9b}, //    SS-Code ::= '10011011'B  -- barring of incoming calls when roaming outside home PLMN Country
2682     {"allPLMN-specificSS",         0xf0}, //    SS-Code ::= '11110000'B
2683     {"plmn-specificSS-1",          0xf1}, //    SS-Code ::= '11110001'B
2684     {"plmn-specificSS-2",          0xf2}, //    SS-Code ::= '11110010'B
2685     {"plmn-specificSS-3",          0xf3}, //    SS-Code ::= '11110011'B
2686     {"plmn-specificSS-4",          0xf4}, //    SS-Code ::= '11110100'B
2687     {"plmn-specificSS-5",          0xf5}, //    SS-Code ::= '11110101'B
2688     {"plmn-specificSS-6",          0xf6}, //    SS-Code ::= '11110110'B
2689     {"plmn-specificSS-7",          0xf7}, //    SS-Code ::= '11110111'B
2690     {"plmn-specificSS-8",          0xf8}, //    SS-Code ::= '11111000'B
2691     {"plmn-specificSS-9",          0xf9}, //    SS-Code ::= '11111001'B
2692     {"plmn-specificSS-A",          0xfa}, //    SS-Code ::= '11111010'B
2693     {"plmn-specificSS-B",          0xfb}, //    SS-Code ::= '11111011'B
2694     {"plmn-specificSS-C",          0xfc}, //    SS-Code ::= '11111100'B
2695     {"plmn-specificSS-D",          0xfd}, //    SS-Code ::= '11111101'B
2696     {"plmn-specificSS-E",          0xfe}, //    SS-Code ::= '11111110'B
2697     {"plmn-specificSS-F",          0xff}, //    SS-Code ::= '11111111'B
2698     {"allCallPrioritySS",          0xa0}, //    SS-Code ::= '10100000'B  -- all call priority SS
2699     {"emlpp",                      0xa1}, //    SS-Code ::= '10100001'B  -- enhanced Multilevel Precedence Pre-emption (EMLPP) service
2700     {"allLCSPrivacyException",     0xb0}, //    SS-Code ::= '10110000'B  -- all LCS Privacy Exception Classes
2701     {"universal",                  0xb1}, //    SS-Code ::= '10110001'B  -- allow location by any LCS client
2702     {"callrelated",                0xb2}, //    SS-Code ::= '10110010'B  -- allow location by any value added LCS client to which a call
2703 //                                                                       -- is established from the target MS
2704     {"callunrelated",              0xb3}, //    SS-Code ::= '10110011'B  -- allow location by designated external value added LCS clients
2705     {"plmnoperator",               0xb4}, //    SS-Code ::= '10110100'B  -- allow location by designated PLMN operator LCS clients
2706     {"allMOLR-SS",                 0xc0}, //    SS-Code ::= '11000000'B  -- all Mobile Originating Location Request Classes
2707     {"basicSelfLocation",          0xc1}, //    SS-Code ::= '11000001'B  -- allow an MS to request its own location
2708     {"autonomousSelfLocation",     0xc2}, //    SS-Code ::= '11000010'B  -- allow an MS to perform self location without interaction
2709 //                                                                       -- with the PLMN for a predetermined period of time
2710     {"transferToThirdParty",       0xc3}, //    SS-Code ::= '11000011'B  -- allow an MS to request transfer of its location to another LCS client
2711     {0,0},
2712 };
2713 
2714 static const TokenDict s_bearerServiceCode[] = {
2715     {"allBearerServices",      0x00}, // BearerServiceCode ::= '00000000'B
2716     {"allDataCDA-Services",    0x10}, // BearerServiceCode ::= '00010000'B
2717     {"dataCDA-300bps",         0x11}, // BearerServiceCode ::= '00010001'B
2718     {"dataCDA-1200bps",        0x12}, // BearerServiceCode ::= '00010010'B
2719     {"dataCDA-1200-75bps",     0x13}, // BearerServiceCode ::= '00010011'B
2720     {"dataCDA-2400bps",        0x14}, // BearerServiceCode ::= '00010100'B
2721     {"dataCDA-4800bps",        0x15}, // BearerServiceCode ::= '00010101'B
2722     {"dataCDA-9600bps",        0x16}, // BearerServiceCode ::= '00010110'B
2723     {"general-dataCDA",        0x17}, // BearerServiceCode ::= '00010111'B
2724     {"allDataCDS-Services",    0x18}, // BearerServiceCode ::= '00011000'B
2725     {"dataCDS-1200bps",        0x1a}, // BearerServiceCode ::= '00011010'B
2726     {"dataCDS-2400bps",        0x1c}, // BearerServiceCode ::= '00011100'B
2727     {"dataCDS-4800bps",        0x1d}, // BearerServiceCode ::= '00011101'B
2728     {"dataCDS-9600bps",        0x1e}, // BearerServiceCode ::= '00011110'B
2729     {"general-dataCDS",        0x1f}, // BearerServiceCode ::= '00011111'B
2730     {"allPadAccessCA-Services",0x20}, // BearerServiceCode ::= '00100000'B
2731     {"padAccessCA-300bps",     0x21}, // BearerServiceCode ::= '00100001'B
2732     {"padAccessCA-1200bps",    0x22}, // BearerServiceCode ::= '00100010'B
2733     {"padAccessCA-1200-75bps", 0x23}, // BearerServiceCode ::= '00100011'B
2734     {"padAccessCA-2400bps",    0x24}, // BearerServiceCode ::= '00100100'B
2735     {"padAccessCA-4800bps",    0x25}, // BearerServiceCode ::= '00100101'B
2736     {"padAccessCA-9600bps",    0x26}, // BearerServiceCode ::= '00100110'B
2737     {"general-padAccessCA",    0x27}, // BearerServiceCode ::= '00100111'B
2738     {"allDataPDS-Services",    0x28}, // BearerServiceCode ::= '00101000'B
2739     {"dataPDS-2400bps",        0x2c}, // BearerServiceCode ::= '00101100'B
2740     {"dataPDS-4800bps",        0x2d}, // BearerServiceCode ::= '00101101'B
2741     {"dataPDS-9600bps",        0x2e}, // BearerServiceCode ::= '00101110'B
2742     {"general-dataPDS",        0x2f}, // BearerServiceCode ::= '00101111'B
2743 
2744     {"allAlternateSpeech-DataCDA",    0x30}, // BearerServiceCode ::= '00110000'B
2745     {"allAlternateSpeech-DataCDS",    0x38}, // BearerServiceCode ::= '00111000'B
2746     {"allSpeechFollowedByDataCDA",    0x40}, // BearerServiceCode ::= '01000000'B
2747     {"allSpeechFollowedByDataCDS",    0x48}, // BearerServiceCode ::= '01001000'B
2748     {"allDataCircuitAsynchronous",    0x50}, // BearerServiceCode ::= '01010000'B
2749     {"allAsynchronousServices",       0x60}, // BearerServiceCode ::= '01100000'B
2750     {"allDataCircuitSynchronous",     0x58}, // BearerServiceCode ::= '01011000'B
2751     {"allSynchronousServices",        0x68}, // BearerServiceCode ::= '01101000'B
2752 
2753     {"allPLMN-specificBS",   0xd0}, //        BearerServiceCode ::= '11010000'B
2754     {"plmn-specificBS-1",    0xd1}, //        BearerServiceCode ::= '11010001'B
2755     {"plmn-specificBS-2",    0xd2}, //        BearerServiceCode ::= '11010010'B
2756     {"plmn-specificBS-3",    0xd3}, //        BearerServiceCode ::= '11010011'B
2757     {"plmn-specificBS-4",    0xd4}, //        BearerServiceCode ::= '11010100'B
2758     {"plmn-specificBS-5",    0xd5}, //        BearerServiceCode ::= '11010101'B
2759     {"plmn-specificBS-6",    0xd6}, //        BearerServiceCode ::= '11010110'B
2760     {"plmn-specificBS-7",    0xd7}, //        BearerServiceCode ::= '11010111'B
2761     {"plmn-specificBS-8",    0xd8}, //        BearerServiceCode ::= '11011000'B
2762     {"plmn-specificBS-9",    0xd9}, //        BearerServiceCode ::= '11011001'B
2763     {"plmn-specificBS-A",    0xda}, //        BearerServiceCode ::= '11011010'B
2764     {"plmn-specificBS-B",    0xdb}, //        BearerServiceCode ::= '11011011'B
2765     {"plmn-specificBS-C",    0xdc}, //        BearerServiceCode ::= '11011100'B
2766     {"plmn-specificBS-D",    0xdd}, //        BearerServiceCode ::= '11011101'B
2767     {"plmn-specificBS-E",    0xde}, //        BearerServiceCode ::= '11011110'B
2768     {"plmn-specificBS-F",    0xdf}, //        BearerServiceCode ::= '11011111'B
2769     {0,0},
2770 };
2771 
2772 static const TokenDict s_teleserviceCode[] = {
2773     {"allTeleservices",                  0x00},  // TeleserviceCode ::= '00000000'B
2774     {"allSpeechTransmissionServices",    0x10},  // TeleserviceCode ::= '00010000'B
2775     {"telephony",                        0x11},  // TeleserviceCode ::= '00010001'B
2776     {"emergencyCalls",                   0x12},  // TeleserviceCode ::= '00010010'B
2777     {"allShortMessageServices",          0x20},  // TeleserviceCode ::= '00100000'B
2778     {"shortMessageMT-PP",                0x21},  // TeleserviceCode ::= '00100001'B
2779     {"shortMessageMO-PP",                0x22},  // TeleserviceCode ::= '00100010'B
2780     {"allFacsimileTransmissionServices", 0x60},  // TeleserviceCode ::= '01100000'B
2781     {"facsimileGroup3AndAlterSpeech",    0x61},  // TeleserviceCode ::= '01100001'B
2782     {"automaticFacsimileGroup3",         0x62},  // TeleserviceCode ::= '01100010'B
2783     {"facsimileGroup4",                  0x63},  // TeleserviceCode ::= '01100011'B
2784     {"allDataTeleservices",              0x70},  // TeleserviceCode ::= '01110000'B
2785     {"allTeleservices-ExeptSMS",         0x80},  // TeleserviceCode ::= '10000000'B
2786     {"allVoiceGroupCallServices",        0x90},  // TeleserviceCode ::= '10010000'B
2787     {"voiceGroupCall",                   0x91},  // TeleserviceCode ::= '10010001'B
2788     {"voiceBroadcastCall",               0x92},  // TeleserviceCode ::= '10010010'B
2789     {"allPLMN-specificTS",               0xd0},  // TeleserviceCode ::= '11010000'B
2790     {"plmn-specificTS-1",                0xd1},  // TeleserviceCode ::= '11010001'B
2791     {"plmn-specificTS-2",                0xd2},  // TeleserviceCode ::= '11010010'B
2792     {"plmn-specificTS-3",                0xd3},  // TeleserviceCode ::= '11010011'B
2793     {"plmn-specificTS-4",                0xd4},  // TeleserviceCode ::= '11010100'B
2794     {"plmn-specificTS-5",                0xd5},  // TeleserviceCode ::= '11010101'B
2795     {"plmn-specificTS-6",                0xd6},  // TeleserviceCode ::= '11010110'B
2796     {"plmn-specificTS-7",                0xd7},  // TeleserviceCode ::= '11010111'B
2797     {"plmn-specificTS-8",                0xd8},  // TeleserviceCode ::= '11011000'B
2798     {"plmn-specificTS-9",                0xd9},  // TeleserviceCode ::= '11011001'B
2799     {"plmn-specificTS-A",                0xda},  // TeleserviceCode ::= '11011010'B
2800     {"plmn-specificTS-B",                0xdb},  // TeleserviceCode ::= '11011011'B
2801     {"plmn-specificTS-C",                0xdc},  // TeleserviceCode ::= '11011100'B
2802     {"plmn-specificTS-D",                0xdd},  // TeleserviceCode ::= '11011101'B
2803     {"plmn-specificTS-E",                0xde},  // TeleserviceCode ::= '11011110'B
2804     {"plmn-specificTS-F",                0xdf},  // TeleserviceCode ::= '11011111'B
2805     {0,0},
2806 };
2807 
2808 static const Parameter s_extBearerServiceCode[] = {
2809     {"ext-BearerServiceCode",   s_hexTag,    false,    TcapXApplication::HexString,         0},
2810     {"",                        s_noTag,     false,    TcapXApplication::None,              0},
2811 };
2812 
2813 static const Parameter s_extTeleserviceCode[] = {
2814     {"ext-TeleserviceCode",     s_hexTag,   false,    TcapXApplication::HexString,       0},
2815     {"",                        s_noTag,    false,    TcapXApplication::None,            0},
2816 };
2817 
2818 static const Parameter s_bearerService[] = {
2819     {"bearerService",           s_hexTag,   false,    TcapXApplication::Enumerated,        s_bearerServiceCode},
2820     {"",                        s_noTag,    false,    TcapXApplication::None,              0},
2821 };
2822 
2823 static const Parameter s_teleservice[] = {
2824     {"teleservice",             s_hexTag,   false,    TcapXApplication::Enumerated,      s_teleserviceCode},
2825     {"",                        s_noTag,    false,    TcapXApplication::None,            0},
2826 };
2827 
2828 static const Parameter s_basicServiceCode[] = {
2829     {"bearerService",  s_ctxtPrim_2_Tag,   false,   TcapXApplication::Enumerated, s_bearerServiceCode},
2830     {"teleservice",    s_ctxtPrim_3_Tag,   false,   TcapXApplication::Enumerated, s_teleserviceCode},
2831     {"",               s_noTag,            false,   TcapXApplication::None,       0},
2832 };
2833 
2834 static const Parameter s_extBasicServiceCode[] = {
2835     {"ext-BearerService",       s_ctxtPrim_2_Tag,   false,   TcapXApplication::HexString, 0},
2836     {"ext-Teleservice",         s_ctxtPrim_3_Tag,   false,   TcapXApplication::HexString, 0},
2837     {"",                        s_noTag,            false,   TcapXApplication::None,      0},
2838 };
2839 
2840 
2841 static const SignallingFlags s_forwardOptions[] = {
2842     { 0x80, 0x80, "notify-called" },
2843     { 0x40, 0x40, "presentation" },
2844     { 0x20, 0x20, "notify-caller" },
2845     { 0x0c, 0x00, "offline" },
2846     { 0x0c, 0x04, "busy" },
2847     { 0x0c, 0x08, "noanswer" },
2848     { 0x0c, 0x0c, "always" },
2849     { 0, 0, 0 },
2850 };
2851 
2852 static const SignallingFlags s_ssStatus[] = {
2853     { 0x01, 0x01, "active" },
2854     { 0x02, 0x02, "registered" },
2855     { 0x04, 0x04, "provisioned" },
2856     { 0x08, 0x08, "quiescent" },
2857     { 0, 0, 0 },
2858 };
2859 
2860 static const Parameter s_forwFeatureSeq[] = {
2861     {"basicService",            s_noTag,           true,   TcapXApplication::Choice,        s_basicServiceCode},
2862     {"ss-Status",               s_ctxtPrim_4_Tag,  false,  TcapXApplication::Flags,         s_ssStatus},
2863     {"forwardedToNumber",       s_ctxtPrim_5_Tag,  true,   TcapXApplication::AddressString, 0},
2864     {"forwardedToSubaddress",   s_ctxtPrim_8_Tag,  true,   TcapXApplication::HexString,     0},
2865     {"forwardingOptions",       s_ctxtPrim_6_Tag,  true,   TcapXApplication::Flags,         s_forwardOptions},
2866     {"noReplyConditionTime",    s_ctxtPrim_7_Tag,  true,   TcapXApplication::Integer,       0},
2867     {"extensionContainer",      s_ctxtCstr_9_Tag,  true,   TcapXApplication::HexString,     0},
2868     {"longForwardedToNumber",   s_ctxtPrim_10_Tag, true,   TcapXApplication::AddressString, 0},
2869     {"",                        s_noTag,           false,  TcapXApplication::None,          0},
2870 };
2871 
2872 static const Parameter s_forwFeature[] = {
2873     {"forwardingFeature",       s_sequenceTag,  true,     TcapXApplication::Sequence,             s_forwFeatureSeq},
2874     {"",                        s_noTag,        false,    TcapXApplication::None,                 0},
2875 };
2876 
2877 static const Parameter s_extForwInfo[] = {
2878     {"ss-Code",               s_hexTag,          false,  TcapXApplication::Enumerated,    s_SSCode},
2879     {"forwardingFeatureList", s_sequenceTag,     false,  TcapXApplication::SequenceOf,    s_forwFeature},
2880     {"extensionContainer",    s_ctxtCstr_0_Tag,  true,   TcapXApplication::HexString,     0},
2881     {"",                      s_noTag,           false,  TcapXApplication::None,          0},
2882 };
2883 
2884 static const Parameter s_extCallBarFeatureSeq[] = {
2885     {"basicService",          s_noTag,           true,  TcapXApplication::Choice,    s_basicServiceCode},
2886     {"ss-Status",             s_ctxtPrim_4_Tag,  false, TcapXApplication::Flags,     s_ssStatus},
2887     {"extensionContainer",    s_sequenceTag,     true,  TcapXApplication::HexString, 0},
2888     {"",                      s_noTag,           false, TcapXApplication::None,      0},
2889 };
2890 
2891 static const Parameter s_extCallBarFeature[] = {
2892     {"ext-CallBarFeature",    s_sequenceTag,   true,     TcapXApplication::Sequence,      s_extCallBarFeatureSeq},
2893     {"",                      s_noTag,         false,    TcapXApplication::None,          0},
2894 };
2895 
2896 static const Parameter s_extCallBarInfo[] = {
2897     {"ss-Code",               s_hexTag,         false,  TcapXApplication::Enumerated,    s_SSCode},
2898     {"callBarringFeatureList",s_sequenceTag,    false,  TcapXApplication::SequenceOf,    s_extCallBarFeature},
2899     {"extensionContainer",    s_sequenceTag,    true,   TcapXApplication::HexString,     0},
2900     {"",                      s_noTag,          false,  TcapXApplication::None,          0},
2901 };
2902 
2903 static const TokenDict s_intraCUGOptions[] = {
2904     {"noCUG-Restrictions",    0},
2905     {"cugIC-CallBarred",      1},
2906     {"cugOG-CallBarred",      2},
2907     {0,0},
2908 };
2909 
2910 static const Parameter s_basicServiceCodeType[] = {
2911     {"basicService",          s_noTag,    true,     TcapXApplication::Choice,        s_basicServiceCode},
2912     {"",                      s_noTag,    false,    TcapXApplication::None,          0},
2913 };
2914 
2915 static const Parameter s_CUGSubscriptionSeq[] = {
2916     {"cug-Index",             s_intTag,          false,  TcapXApplication::Integer,       0},
2917     {"cug-Interlock",         s_hexTag,          false,  TcapXApplication::HexString,     0},
2918     {"intraCUG-Options",      s_enumTag,         false,  TcapXApplication::Enumerated,    s_intraCUGOptions},
2919     {"basicServiceGroupList", s_sequenceTag,     true,   TcapXApplication::SequenceOf,    s_basicServiceCodeType},
2920     {"extensionContainer",    s_ctxtCstr_0_Tag,  true,   TcapXApplication::HexString,     0},
2921     {"",                      s_noTag,           false,  TcapXApplication::None,          0},
2922 };
2923 
2924 static const Parameter s_CUGSubscription[] = {
2925     {"cug-Subscription",      s_sequenceTag,   false,    TcapXApplication::Sequence,      s_CUGSubscriptionSeq},
2926     {"",                      s_noTag,         false,    TcapXApplication::None,          0},
2927 };
2928 
2929 static const TokenDict s_interCUGRestrinctions[] = {
2930     {"CUG-only",                       0x00},
2931     {"CUG-outgoing-access",            0x01},
2932     {"CUG-incoming-access",            0x02},
2933     {"CUG-both",                       0x03},
2934     {0,0},
2935 };
2936 
2937 static const Parameter s_CUGFeatureSeq[] = {
2938     {"basicService",              s_noTag,        true,   TcapXApplication::Choice,       s_basicServiceCode},
2939     {"preferentialCUG-Indicator", s_intTag,       true,   TcapXApplication::Integer,      0},
2940     {"interCUG-Restrictions",     s_hexTag,       false,  TcapXApplication::Enumerated,   s_interCUGRestrinctions},
2941     {"extensionContainer",        s_sequenceTag,  true,   TcapXApplication::HexString,    0},
2942     {"",                          s_noTag,        false,  TcapXApplication::None,         0},
2943 };
2944 
2945 static const Parameter s_CUGFeature[] = {
2946     {"cug-Feature",   s_sequenceTag,  false,  TcapXApplication::Sequence,     s_CUGFeatureSeq},
2947     {"",              s_noTag,        false,  TcapXApplication::None,         0},
2948 };
2949 
2950 static const Parameter s_cugInfo[] = {
2951     {"cug-SubscriptionList",  s_sequenceTag,    false,  TcapXApplication::SequenceOf,    s_CUGSubscription},
2952     {"cug-FeatureList",       s_sequenceTag,    true,   TcapXApplication::SequenceOf,    s_CUGFeature},
2953     {"extensionContainer",    s_ctxtCstr_0_Tag, true,   TcapXApplication::HexString,     0},
2954     {"",                      s_noTag,          false,  TcapXApplication::None,          0},
2955 };
2956 
2957 static const TokenDict s_cliRestrictionOption[] = {
2958     {"permanent",                       0},
2959     {"temporaryDefaultRestricted",      1},
2960     {"temporaryDefaultAllowed",         2},
2961     {0,0},
2962 };
2963 
2964 static const TokenDict s_overrideCategory[] = {
2965     {"overrideEnabled",       0},
2966     {"overrideDisabled",      1},
2967     {0,0},
2968 };
2969 
2970 static const Parameter s_ssSubscriptionOption[] = {
2971     {"cliRestrictionOption",  s_ctxtPrim_2_Tag,   false,  TcapXApplication::Enumerated, s_cliRestrictionOption},
2972     {"overrideCategory",      s_ctxtPrim_1_Tag,   false,  TcapXApplication::Enumerated, s_overrideCategory},
2973     {"",                      s_noTag,                                         false,  TcapXApplication::None,       0},
2974 };
2975 
2976 static const Parameter s_extSSData[] = {
2977     {"ss-Code",               s_hexTag,          false,    TcapXApplication::Enumerated,    s_SSCode},
2978     {"ss-Status",             s_ctxtPrim_4_Tag,  false,    TcapXApplication::Flags,         s_ssStatus},
2979     {"ss-SubscriptionOption", s_noTag,           true,     TcapXApplication::Choice,        s_ssSubscriptionOption},
2980     {"basicServiceGroupList", s_sequenceTag,     true,     TcapXApplication::SequenceOf,    s_basicServiceCodeType},
2981     {"extensionContainer",    s_ctxtCstr_5_Tag,  true,     TcapXApplication::HexString,     0},
2982     {"",                      s_noTag,           false,    TcapXApplication::None,          0},
2983 };
2984 
2985 static const TokenDict s_EMLPPPriority[] = {
2986     {"priorityLevel0", 0},
2987     {"priorityLevel1", 1},
2988     {"priorityLevel2", 2},
2989     {"priorityLevel3", 3},
2990     {"priorityLevel4", 4},
2991     {"priorityLevelB", 5},
2992     {"priorityLevelA", 6},
2993     {0,0},
2994 };
2995 
2996 static const Parameter s_EMLPPInfo[] = {
2997     {"maximumentitledPriority", s_intTag,        false,    TcapXApplication::Enumerated,    s_EMLPPPriority},
2998     {"defaultPriority",         s_intTag,        false,    TcapXApplication::Enumerated,    s_EMLPPPriority},
2999     {"extensionContainer",      s_sequenceTag,   true,     TcapXApplication::HexString,     0},
3000     {"",                        s_noTag,         false,    TcapXApplication::None,          0},
3001 };
3002 
3003 static const Parameter s_extSSInfoChoice[] = {
3004     {"forwardingInfo",  s_ctxtCstr_0_Tag, false,  TcapXApplication::Sequence, s_extForwInfo},
3005     {"callBarringInfo", s_ctxtCstr_1_Tag, false,  TcapXApplication::Sequence, s_extCallBarInfo},
3006     {"cug-Info",        s_ctxtCstr_2_Tag, false,  TcapXApplication::Sequence, s_cugInfo},
3007     {"ss-Data",         s_ctxtCstr_3_Tag, false,  TcapXApplication::Sequence, s_extSSData},
3008     {"emlpp-Info",      s_ctxtCstr_4_Tag, false,  TcapXApplication::Sequence, s_EMLPPInfo},
3009     {"",                s_noTag,          false,  TcapXApplication::None,     0},
3010 };
3011 
3012 static const Parameter s_extSSInfo[] = {
3013     {"SS-Info",         s_noTag,     false,    TcapXApplication::Choice, s_extSSInfoChoice},
3014     {"",                s_noTag,     false,    TcapXApplication::None,   0},
3015 };
3016 
3017 static const TokenDict s_odbGeneralData[] = {
3018     {"allOG-CallsBarred",                                                   0x00000001},
3019     {"internationalOGCallsBarred",                                          0x00000002},
3020     {"internationalOGCallsNotToHPLMN-CountryBarred",                        0x00000004},
3021     {"interzonalOGCallsBarred",                                             0x00000040},
3022     {"interzonalOGCallsNotToHPLMN-CountryBarred",                           0x00000080},
3023     {"interzonalOGCallsAndInternationalOGCallsNotToHPLMN-CountryBarred",    0x00000100},
3024     {"premiumRateInformationOGCallsBarred",                                 0x00000008},
3025     {"premiumRateEntertainementOGCallsBarred",                              0x00000010},
3026     {"ss-AccessBarred",                                                     0x00000020},
3027     {"allECT-Barred",                                                       0x00000200},
3028     {"chargeableECT-Barred",                                                0x00000400},
3029     {"internationalECT-Barred",                                             0x00000800},
3030     {"interzonalECT-Barred",                                                0x00001000},
3031     {"doublyChargeableECT-Barred",                                          0x00002000},
3032     {"multipleECT-Barred",                                                  0x00004000},
3033     {"allPacketOrientedServicesBarred",                                     0x00008000},
3034     {"roamerAccessToHPLMN-AP-Barred",                                       0x00010000},
3035     {"roamerAccessToVPLMN-AP-Barred",                                       0x00020000},
3036     {"roamingOutsidePLMNOG-CallsBarred",                                    0x00040000},
3037     {"allIC-CallsBarred",                                                   0x00080000},
3038     {"roamingOutsidePLMNIC-CallsBarred",                                    0x00100000},
3039     {"roamingOutsidePLMNICountryIC-CallsBarred",                            0x00200000},
3040     {"roamingOutsidePLMN-Barred",                                           0x00400000},
3041     {"roamingOutsidePLMN-CountryBarred",                                    0x00800000},
3042     {"registrationAllCF-Barred",                                            0x01000000},
3043     {"registrationCFNotToHPLMN-Barred",                                     0x02000000},
3044     {"registrationInterzonalCF-Barred",                                     0x04000000},
3045     {"registrationInterzonalCFNotToHPLMN-Barred",                           0x08000000},
3046     {"registrationInternationalCF-Barred",                                  0x10000000},
3047     {0,0},
3048 };
3049 
3050 static const TokenDict s_odbHPLMNData[] = {
3051     {"plmn-SpecificBarringType1", 0x01},
3052     {"plmn-SpecificBarringType2", 0x02},
3053     {"plmn-SpecificBarringType3", 0x04},
3054     {"plmn-SpecificBarringType4", 0x08},
3055     {0,0},
3056 };
3057 
3058 static const Parameter s_odbData[] = {
3059     {"odb-GeneralData",        s_bitsTag,       false,    TcapXApplication::BitString,  s_odbGeneralData},
3060     {"odb-HPLMN-Data",         s_bitsTag,       true,     TcapXApplication::BitString,  s_odbHPLMNData},
3061     {"extensionContainer",     s_sequenceTag,   true,     TcapXApplication::HexString,  0},
3062     {"",                       s_noTag,         false,    TcapXApplication::None,       0},
3063 };
3064 
3065 static const Parameter s_zoneCode[] = {
3066     {"zoneCode",        s_hexTag,   false,    TcapXApplication::HexString,    0},
3067     {"",                s_noTag,    false,    TcapXApplication::None,         0},
3068 };
3069 
3070 static const Parameter s_voiceBroadcastDataSeq[] = {
3071     {"groupid",                  s_hexTag,         false,   TcapXApplication::TBCD,       0},
3072     {"broadcastInitEntitlement", s_nullTag,        true,    TcapXApplication::Null,       0},
3073     {"extensionContainer",       s_sequenceTag,    true,    TcapXApplication::HexString,  0},
3074     {"longGroupId",              s_ctxtPrim_0_Tag, true,    TcapXApplication::TBCD,       0},
3075     {"",                         s_noTag,          false,   TcapXApplication::None,       0},
3076 };
3077 
3078 static const Parameter s_voiceBroadcastData[] = {
3079     {"voiceBroadcastData",       s_sequenceTag,    false,   TcapXApplication::Sequence,   s_voiceBroadcastDataSeq},
3080     {"",                         s_noTag,          false,   TcapXApplication::None,       0},
3081 };
3082 
3083 static const TokenDict s_additionalSubscriptions[] = {
3084     {"privilegedUplinkRequest",  0x01},
3085     {"emergencyUplinkRequest",   0x02},
3086     {"emergencyReset",           0x04},
3087     {0,0},
3088 };
3089 
3090 static const Parameter s_voiceGroupCallDataSeq[] = {
3091     {"groupid",                  s_hexTag,         false,   TcapXApplication::TBCD,          0},
3092     {"extensionContainer",       s_sequenceTag,    true,    TcapXApplication::HexString,     0},
3093     {"additionalSubscriptions",  s_bitsTag,        true,    TcapXApplication::BitString,     s_additionalSubscriptions},
3094     // additionalInfo is BitString, but no definition was found in 3GPP TS 43.068, leaved as hex string
3095     {"additionalInfo",           s_ctxtPrim_0_Tag, true,    TcapXApplication::HexString,     0},
3096     {"longGroupId",              s_ctxtPrim_1_Tag, true,    TcapXApplication::TBCD,          0},
3097     {"",                         s_noTag,          false,   TcapXApplication::None,          0},
3098 };
3099 
3100 static const Parameter s_voiceGroupCallData[] = {
3101     {"voiceGroupCallData",       s_sequenceTag,    false,   TcapXApplication::Sequence,      s_voiceGroupCallDataSeq},
3102     {"",                         s_noTag,          false,   TcapXApplication::None,          0},
3103 };
3104 
3105 static const TokenDict s_OBcsmTriggerDetectionPoint[] = {
3106     {"collectedInfo",      2},
3107     {"routeSelectFailure", 4},
3108     {0,0},
3109 };
3110 
3111 static const TokenDict s_defaultCallHandling[] = {
3112     {"continueCall",    0},
3113     {"releaseCall",     1},
3114     {0,0},
3115 };
3116 
3117 static const Parameter s_OBcsmCamelTDPDataSeq[] = {
3118     {"o-BcsmTriggerDetectionPoint",  s_enumTag,        false,  TcapXApplication::Enumerated,    s_OBcsmTriggerDetectionPoint},
3119     {"serviceKey",                   s_intTag,         false,  TcapXApplication::Integer,       0},
3120     {"gsmSCF-Address",               s_ctxtPrim_0_Tag, false,  TcapXApplication::AddressString, 0},
3121     {"defaultCallHandling",          s_ctxtPrim_1_Tag, false,  TcapXApplication::Enumerated,    s_defaultCallHandling},
3122     {"extensionContainer",           s_ctxtCstr_2_Tag, true,   TcapXApplication::HexString,     0},
3123     {"",                             s_noTag,          false,  TcapXApplication::None,          0},
3124 };
3125 
3126 static const Parameter s_OBcsmCamelTDPData[] = {
3127     {"o-BcsmCamelTDPData",  s_sequenceTag,    false,  TcapXApplication::Sequence,      s_OBcsmCamelTDPDataSeq},
3128     {"",                    s_noTag,          false,  TcapXApplication::None,          0},
3129 };
3130 
3131 static const TokenDict s_camelCapabilityHandling[] = {
3132     {"phase1",      1},
3133     {"phase2",      2},
3134     {"phase3",      3},
3135     {"phase4",      4},
3136     {0,0},
3137 };
3138 
3139 static const Parameter s_OCSI[] = {
3140     {"o-BcsmCamelTDPDataList",   s_sequenceTag,    false,   TcapXApplication::SequenceOf, s_OBcsmCamelTDPData},
3141     {"extensionContainer",       s_sequenceTag,    true,    TcapXApplication::HexString,  0},
3142     {"camelCapabilityHandling",  s_ctxtPrim_0_Tag, true,    TcapXApplication::Enumerated, s_camelCapabilityHandling},
3143     {"notificationToCSE",        s_ctxtPrim_1_Tag, true,    TcapXApplication::Null,       0},
3144     {"csiActive",                s_ctxtPrim_2_Tag, true,    TcapXApplication::Null,       0},
3145     {"",                         s_noTag,          false,   TcapXApplication::None,       0},
3146 };
3147 
3148 static const Parameter s_ssCode[] = {
3149     {"ss-Code",                  s_hexTag,   false,    TcapXApplication::Enumerated,    s_SSCode},
3150     {"",                         s_noTag,    false,    TcapXApplication::None,          0},
3151 };
3152 
3153 static const Parameter s_SSCamelData[] = {
3154     {"ss-EventList",            s_sequenceTag,     false, TcapXApplication::SequenceOf,    s_ssCode},
3155     {"gsmSCF-Address",          s_hexTag,          false, TcapXApplication::AddressString, 0},
3156     {"extensionContainer",      s_ctxtCstr_0_Tag,  true,  TcapXApplication::HexString,     0},
3157     {"",                        s_noTag,           false, TcapXApplication::None,          0},
3158 };
3159 
3160 static const Parameter s_SSCSI[] = {
3161     {"ss-CamelData",             s_sequenceTag,    false,   TcapXApplication::Sequence,   s_SSCamelData},
3162     {"extensionContainer",       s_sequenceTag,    true,    TcapXApplication::HexString,  0},
3163     {"notificationToCSE",        s_ctxtPrim_0_Tag, true,    TcapXApplication::Null,       0},
3164     {"csiActive",                s_ctxtPrim_1_Tag, true,    TcapXApplication::Null,       0},
3165     {"",                         s_noTag,          false,   TcapXApplication::None,       0},
3166 };
3167 
3168 static const TokenDict s_matchType[] = {
3169     {"inhibiting", 0x00},
3170     {"enabling",   0x01},
3171     {0,0},
3172 };
3173 
3174 static const Parameter s_destinationNumber[] = {
3175     {"destinationNumber",  s_hexTag,         false, TcapXApplication::AddressString, 0},
3176     {"",                   s_noTag,          false, TcapXApplication::None,          0},
3177 };
3178 
3179 static const Parameter s_destinationNumberLength[] = {
3180     {"destinationNumberLength",  s_intTag,         false, TcapXApplication::Integer,       0},
3181     {"",                         s_noTag,          false, TcapXApplication::None,          0},
3182 };
3183 
3184 static const Parameter s_destinationNumberCriteria[] = {
3185 // TS 100 974 v7.15.0 page 306
3186     {"matchType",                   s_ctxtPrim_0_Tag,  false,   TcapXApplication::Enumerated, s_matchType},
3187     {"destinationNumberList",       s_ctxtCstr_1_Tag,  true,    TcapXApplication::SequenceOf, s_destinationNumber},
3188     {"destinationNumberLengthList", s_ctxtCstr_2_Tag,  true,    TcapXApplication::SequenceOf, s_destinationNumberLength},
3189     {"",                            s_noTag,           false,   TcapXApplication::None,       0},
3190 };
3191 
3192 static const TokenDict s_callTypeCriteria[] = {
3193 // TS 100 974 v7.15.0 page 307
3194     {"forwarded",        0x00},
3195     {"notForwarded",     0x01},
3196     {0,0},
3197 };
3198 
3199 static const Parameter s_causeValue[]={
3200     {"causeValue",  s_hexTag,    false,  TcapXApplication::HexString,   0},
3201     {"",            s_noTag,     false,  TcapXApplication::None,        0},
3202 };
3203 
3204 static const Parameter s_OBcsmCamelTDPCriteriaSeq[] = {
3205     {"o-BcsmTriggerDetectionPoint",  s_enumTag,        false,  TcapXApplication::Enumerated,    s_OBcsmTriggerDetectionPoint},
3206     {"destinationNumberCriteria",    s_ctxtCstr_0_Tag, true,   TcapXApplication::Sequence,      s_destinationNumberCriteria},
3207     {"basicServiceCriteria",         s_ctxtCstr_1_Tag, true,   TcapXApplication::SequenceOf,    s_basicServiceCodeType},
3208     {"callTypeCriteria",             s_ctxtPrim_2_Tag, true,   TcapXApplication::Enumerated,    s_callTypeCriteria},
3209     {"o-CauseValueCriteria",         s_ctxtCstr_3_Tag, true,   TcapXApplication::SequenceOf,    s_causeValue},
3210     {"extensionContainer",           s_ctxtCstr_4_Tag, true,   TcapXApplication::HexString,     0},
3211     {"",                             s_noTag,          false,  TcapXApplication::None,          0},
3212 };
3213 
3214 static const Parameter s_OBcsmCamelTDPCriteria[] = {
3215     {"o-BcsmCamelTDP-Criteria",      s_sequenceTag,    false,  TcapXApplication::Sequence,      s_OBcsmCamelTDPCriteriaSeq},
3216     {"",                             s_noTag,          false,  TcapXApplication::None,          0},
3217 };
3218 
3219 static const TokenDict s_MMCodeValues[] = {
3220     {"Location-update-in-same-VLR",                                0x00}, //    MM-Code ::= '00000000'B
3221     {"Location-update-to-other-VLR",                               0x01}, //    MM-Code ::= '00000001'B
3222     {"IMSI-Attach",                                                0x02}, //    MM-Code ::= '00000010'B
3223     {"MS-initiated-IMSI-Detach",                                   0x03}, //    MM-Code ::= '00000011'B
3224     {"Network-initiated-IMSI-Detach",                              0x04}, //    MM-Code ::= '00000100'B
3225     {"Routeing-Area-update-in-same-SGSN",                          0x80}, //    MM-Code ::= '10000000'B
3226     {"Routeing-Area-update-to-other-SGSN-update-from-new-SGSN",    0x81}, //    MM-Code ::= '10000001'B
3227     {"Routeing-Area-update-to-other-SGSN-disconnect-by-detach",    0x82}, //    MM-Code ::= '10000010'B
3228     {"GPRS-Attach",                                                0x83}, //    MM-Code ::= '10000011'B
3229     {"MS-initiated-GPRS-Detach",                                   0x84}, //    MM-Code ::= '10000100'B
3230     {"Network-initiated-GPRS-Detach",                              0x85}, //    MM-Code ::= '10000101'B
3231     {"Network-initiated-transfer-to-MS-not-reachable-for-paging",  0x86}, //    MM-Code ::= '10000110'B
3232     {0,0},
3233 };
3234 
3235 static const Parameter s_MMCode[] = {
3236     {"MM-Code",      s_hexTag,    false,  TcapXApplication::Enumerated, s_MMCodeValues},
3237     {"",             s_noTag,     false,  TcapXApplication::None,       0},
3238 };
3239 
3240 static const Parameter s_M_CSI[] = {
3241     {"mobilityTriggers",   s_sequenceTag,    false, TcapXApplication::SequenceOf,     s_MMCode},
3242     {"serviceKey",         s_intTag,         false, TcapXApplication::Integer,       0},
3243     {"gsmSCF-Address",     s_ctxtPrim_0_Tag, false, TcapXApplication::AddressString, 0},
3244     {"extensionContainer", s_ctxtCstr_1_Tag, true,  TcapXApplication::HexString,     0},
3245     {"notificationToCSE",  s_ctxtPrim_2_Tag, true,  TcapXApplication::Null,          0},
3246     {"csiActive",          s_ctxtPrim_3_Tag, true,  TcapXApplication::Null,          0},
3247     {"",                   s_noTag,          false, TcapXApplication::None,          0},
3248 };
3249 
3250 static const TokenDict s_SMSTriggerDetectionPoint[] = {
3251     {"sms-CollectedInfo",    1},
3252     {"sms-DeliveryRequest",  2},
3253     {0, 0},
3254 };
3255 
3256 static const TokenDict s_defaultSMSHandling[] = {
3257     {"continueTransaction",    0},
3258     {"releaseTransaction",     1},
3259     {0, 0},
3260 };
3261 
3262 static const Parameter s_SMS_CAMEL_TDPDataSeq[] = {
3263     {"sms-TriggerDetectionPoint",  s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated,    s_SMSTriggerDetectionPoint},
3264     {"serviceKey",                 s_ctxtPrim_1_Tag, false, TcapXApplication::Integer,       0},
3265     {"gsmSCF-Address",             s_ctxtPrim_2_Tag, false, TcapXApplication::AddressString, 0},
3266     {"defaultSMS-Handling",        s_ctxtPrim_3_Tag, false, TcapXApplication::Enumerated,    s_defaultSMSHandling},
3267     {"extensionContainer",         s_ctxtCstr_4_Tag, true,  TcapXApplication::HexString,     0},
3268     {"",                           s_noTag,          false, TcapXApplication::None,          0},
3269 };
3270 
3271 static const Parameter s_SMS_CAMEL_TDPData[] = {
3272     {"sms-CAMEL-TDP-Data",      s_sequenceTag,    false,  TcapXApplication::Sequence,      s_SMS_CAMEL_TDPDataSeq},
3273     {"",                              s_noTag,    false,  TcapXApplication::None,          0},
3274 };
3275 
3276 static const Parameter s_SMS_CSI[] = {
3277     {"sms-CAMEL-TDP-DataList",  s_ctxtCstr_0_Tag,   true,   TcapXApplication::SequenceOf,   s_SMS_CAMEL_TDPData},
3278     {"camelCapabilityHandling", s_ctxtPrim_1_Tag,   true,   TcapXApplication::Enumerated,   s_camelCapabilityHandling},
3279     {"extensionContainer",      s_ctxtCstr_2_Tag,   true,   TcapXApplication::HexString,    0},
3280     {"notificationToCSE",       s_ctxtPrim_3_Tag,   true,   TcapXApplication::Null,         0},
3281     {"csiActive",               s_ctxtPrim_4_Tag,   true,   TcapXApplication::Null,         0},
3282     {"",                        s_noTag,            false,  TcapXApplication::None,         0},
3283 };
3284 
3285 static const TokenDict s_TBcsmTriggerDetectionPoint[] = {
3286     {"termAttemptAuthorized", 12},
3287     {"tBusy",                 13},
3288     {"tNoAnswer",             14},
3289     {0, 0},
3290 };
3291 
3292 static const Parameter s_TBcsmCamelTDPDataSeq[] = {
3293     {"t-BcsmTriggerDetectionPoint",  s_enumTag,        false,  TcapXApplication::Enumerated,    s_TBcsmTriggerDetectionPoint},
3294     {"serviceKey",                   s_intTag,         false,  TcapXApplication::Integer,       0},
3295     {"gsmSCF-Address",               s_ctxtPrim_0_Tag, false,  TcapXApplication::AddressString, 0},
3296     {"defaultCallHandling",          s_ctxtPrim_1_Tag, false,  TcapXApplication::Enumerated,    s_defaultCallHandling},
3297     {"extensionContainer",           s_ctxtCstr_2_Tag, true,   TcapXApplication::HexString,     0},
3298     {"",                             s_noTag,          false,  TcapXApplication::None,          0},
3299 };
3300 
3301 static const Parameter s_TBcsmCamelTDPData[] = {
3302     {"t-BcsmCamelTDPData",  s_sequenceTag,   true,   TcapXApplication::Sequence,   s_TBcsmCamelTDPDataSeq},
3303     {"",                    s_noTag,         false,  TcapXApplication::None,         0},
3304 };
3305 
3306 static const Parameter s_T_CSI[] = {
3307     {"t-BcsmCamelTDPDataList",  s_sequenceTag,      false,  TcapXApplication::SequenceOf,   s_TBcsmCamelTDPData},
3308     {"extensionContainer",      s_sequenceTag,      true,   TcapXApplication::HexString,    0},
3309     {"camelCapabilityHandling", s_ctxtPrim_0_Tag,   true,   TcapXApplication::Enumerated,   s_camelCapabilityHandling},
3310     {"notificationToCSE",       s_ctxtPrim_1_Tag,   true,   TcapXApplication::Null,         0},
3311     {"csiActive",               s_ctxtPrim_2_Tag,   true,   TcapXApplication::Null,         0},
3312     {"",                        s_noTag,            false,  TcapXApplication::None,         0},
3313 };
3314 
3315 static const Parameter s_T_BCSM_CAMEL_TDPCriteriaSeq[] = {
3316     {"t-BCSM-TriggerDetectionPoint",  s_enumTag,        false,  TcapXApplication::Enumerated,    s_TBcsmTriggerDetectionPoint},
3317     {"basicServiceCriteria",          s_ctxtCstr_0_Tag, true,   TcapXApplication::SequenceOf,    s_basicServiceCodeType},
3318     {"t-CauseValueCriteria",          s_ctxtCstr_1_Tag, true,   TcapXApplication::SequenceOf,    s_causeValue},
3319     {"",                              s_noTag,          false,  TcapXApplication::None,          0},
3320 };
3321 
3322 static const Parameter s_T_BCSM_CAMEL_TDPCriteria[] = {
3323     {"t-BCSM-CAMEL-TDP-Criteria",  s_sequenceTag,      false,  TcapXApplication::SequenceOf,   s_T_BCSM_CAMEL_TDPCriteriaSeq},
3324     {"",                           s_noTag,            false,  TcapXApplication::None,         0},
3325 };
3326 
3327 static const Parameter s_DP_AnalysedInfoCriteriumSeq[] = {
3328     {"dialledNumber",              s_hexTag,      false, TcapXApplication::HexString,     0},
3329     {"serviceKey",                 s_intTag,      false, TcapXApplication::Integer,       0},
3330     {"gsmSCF-Address",             s_hexTag,      false, TcapXApplication::AddressString, 0},
3331     {"defaultCallHandling",        s_enumTag,     false, TcapXApplication::Enumerated,    s_defaultCallHandling},
3332     {"extensionContainer",         s_sequenceTag, true,  TcapXApplication::HexString,     0},
3333     {"",                           s_noTag,       false, TcapXApplication::None,          0},
3334 };
3335 
3336 static const Parameter s_DP_AnalysedInfoCriterium[] = {
3337     {"DP-AnalysedInfoCriterium",  s_sequenceTag,      false,  TcapXApplication::SequenceOf,   s_DP_AnalysedInfoCriteriumSeq},
3338     {"",                          s_noTag,            false,  TcapXApplication::None,         0},
3339 };
3340 
3341 static const Parameter s_D_CSI[] = {
3342     {"dp-AnalysedInfoCriteriaList", s_ctxtCstr_0_Tag,   true,   TcapXApplication::SequenceOf,   s_DP_AnalysedInfoCriterium},
3343     {"camelCapabilityHandling",     s_ctxtPrim_1_Tag,   true,   TcapXApplication::Enumerated,   s_camelCapabilityHandling},
3344     {"extensionContainer",          s_ctxtCstr_2_Tag,   true,   TcapXApplication::HexString,    0},
3345     {"notificationToCSE",           s_ctxtPrim_3_Tag,   true,   TcapXApplication::Null,         0},
3346     {"csiActive",                   s_ctxtPrim_4_Tag,   true,   TcapXApplication::Null,         0},
3347     {"",                            s_noTag,            false,  TcapXApplication::None,         0},
3348 };
3349 
3350 static const TokenDict s_MT_SMS_TPDUTypeEnum[] = {
3351     {"sms-DELIVER",         0},
3352     {"sms-SUBMIT-REPORT",   1},
3353     {"sms-STATUS-REPORT",   2},
3354     {0, 0},
3355 };
3356 
3357 static const Parameter s_MT_SMS_TPDUType[] = {
3358     {"MT-SMS-TPDU-Type",  s_enumTag,         false, TcapXApplication::Enumerated,  s_MT_SMS_TPDUTypeEnum},
3359     {"",                  s_noTag,           false, TcapXApplication::None,        0},
3360 };
3361 
3362 static const Parameter s_MT_smsCAMELTDP_CriteriaSeq[] = {
3363     {"sms-TriggerDetectionPoint",  s_enumTag,         false, TcapXApplication::Enumerated,  s_SMSTriggerDetectionPoint},
3364     {"tpdu-TypeCriterion",         s_ctxtCstr_0_Tag,  true,  TcapXApplication::SequenceOf,  s_MT_SMS_TPDUType},
3365     {"",                           s_noTag,           false, TcapXApplication::None,        0},
3366 };
3367 
3368 static const Parameter s_MT_smsCAMELTDP_Criteria[] = {
3369     {"MT-smsCAMELTDP-Criteria", s_sequenceTag,   false,  TcapXApplication::Sequence,   s_MT_smsCAMELTDP_CriteriaSeq},
3370     {"",                        s_noTag,         false,  TcapXApplication::None,       0},
3371 };
3372 
3373 static const Parameter s_VlrCamelSubscriptionInfo[] = {
3374     {"o-CSI",                        s_ctxtCstr_0_Tag,    true,    TcapXApplication::Sequence,   s_OCSI},
3375     {"extensionContainer",           s_ctxtCstr_1_Tag,    true,    TcapXApplication::HexString,  0},
3376     {"ss-CSI",                       s_ctxtCstr_2_Tag,    true,    TcapXApplication::Sequence,   s_SSCSI},
3377     {"o-BcsmCamelTDP-CriteriaList",  s_ctxtCstr_4_Tag,    true,    TcapXApplication::SequenceOf, s_OBcsmCamelTDPCriteria},
3378     {"tif-CSI",                      s_ctxtPrim_3_Tag,    true,    TcapXApplication::Null,       0},
3379     {"m-CSI",                        s_ctxtCstr_5_Tag,    true,    TcapXApplication::Sequence,   s_M_CSI},
3380     {"mo-sms-CSI",                   s_ctxtCstr_6_Tag,    true,    TcapXApplication::Sequence,   s_SMS_CSI},
3381     {"vt-CSI",                       s_ctxtCstr_7_Tag,    true,    TcapXApplication::Sequence,   s_T_CSI},
3382     {"t-BCSM-CAMEL-TDP-CriteriaList",s_ctxtCstr_8_Tag,    true,    TcapXApplication::SequenceOf, s_T_BCSM_CAMEL_TDPCriteria},
3383     {"d-CSI",                        s_ctxtCstr_9_Tag,    true,    TcapXApplication::Sequence,   s_D_CSI},
3384     {"mt-sms-CSI",                   s_ctxtCstr_10_Tag,   true,    TcapXApplication::Sequence,   s_SMS_CSI},
3385     {"mt-smsCAMELTDP-CriteriaList",  s_ctxtCstr_11_Tag,   true,    TcapXApplication::SequenceOf, s_MT_smsCAMELTDP_Criteria},
3386     {"",                             s_noTag,             false,   TcapXApplication::None,       0},
3387 };
3388 
3389 static const Parameter s_naeaPreferredCI[] = {
3390 // NAEAPreferredICI
3391     {"naea-PreferredCIC",  s_ctxtPrim_0_Tag,   false,   TcapXApplication::TBCD,         0},
3392     {"extensionContainer", s_ctxtCstr_1_Tag,   true,    TcapXApplication::HexString,    0},
3393     {"",                   s_noTag,            false,   TcapXApplication::None,         0},
3394 };
3395 
3396 static const Parameter s_PDPContextSeq[] = {
3397     {"pdp-ContextId",                s_intTag,            false, TcapXApplication::Integer,      0},
3398     {"pdp-Type",                     s_ctxtPrim_16_Tag,   false, TcapXApplication::HexString,    0},
3399     {"pdp-Address",                  s_ctxtPrim_17_Tag,   true,  TcapXApplication::HexString,    0},
3400     {"qos-Subscribed",               s_ctxtPrim_18_Tag,   false, TcapXApplication::HexString,    0},
3401     {"vplmnAddressAllowed",          s_ctxtPrim_19_Tag,   true,  TcapXApplication::Null,         0},
3402     {"apn",                          s_ctxtPrim_20_Tag,   false, TcapXApplication::HexString,    0},
3403     {"extensionContainer",           s_ctxtCstr_21_Tag,   true,  TcapXApplication::HexString,    0},
3404     {"ext-QoS-Subscribed",           s_ctxtPrim_0_Tag,    true,  TcapXApplication::HexString,    0},
3405     {"pdp-ChargingCharacteristics",  s_ctxtPrim_1_Tag,    true,  TcapXApplication::HexString,    0},
3406     {"ext2-QoS-Subscribed",          s_ctxtPrim_2_Tag,    true,  TcapXApplication::HexString,    0},
3407     {"ext3-QoS-Subscribed",          s_ctxtPrim_3_Tag,    true,  TcapXApplication::HexString,    0},
3408     {"ext4-QoS-Subscribed",          s_ctxtPrim_4_Tag,    true,  TcapXApplication::HexString,    0},
3409     {"apn-oi-Replacement",           s_ctxtPrim_5_Tag,    true,  TcapXApplication::HexString,    0},
3410     {"ext-pdp-Type",                 s_ctxtPrim_6_Tag,    true,  TcapXApplication::HexString,    0},
3411     {"ext-pdp-Address",              s_ctxtPrim_7_Tag,    true,  TcapXApplication::HexString,    0},
3412     {"",                             s_noTag,             false, TcapXApplication::None,         0},
3413 };
3414 
3415 static const Parameter s_PDPContext[] = {
3416     {"pdp-Context",  s_sequenceTag,   false,   TcapXApplication::Sequence,     s_PDPContextSeq},
3417     {"",                   s_noTag,   false,   TcapXApplication::None,         0},
3418 };
3419 
3420 static const Parameter s_GPRSSubscriptionData[] = {
3421     {"completeDataListIncluded", s_nullTag,        true,  TcapXApplication::Null,       0},
3422     {"gprsDataList",             s_ctxtCstr_1_Tag, false, TcapXApplication::SequenceOf, s_PDPContext},
3423     {"extensionContainer",       s_ctxtCstr_2_Tag, true,  TcapXApplication::HexString,  0},
3424     {"apn-oi-Replacement",       s_ctxtPrim_3_Tag, true,  TcapXApplication::HexString,  0},
3425     {"",                         s_noTag,          false, TcapXApplication::None,       0},
3426 };
3427 
3428 static const TokenDict s_networkAccessMode[] = {
3429     {"bothMSCAndSGSN",    0x00},
3430     {"onlyMSC",           0x01},
3431     {"onlySGSN",          0x02},
3432     {0,0},
3433 };
3434 
3435 static const TokenDict s_lsaOnlyAccessIndicator[] = {
3436     {"accessOutsideLSAsAllowed",     0x00},
3437     {"accessOutsideLSAsRestricted",  0x01},
3438     {0,0},
3439 };
3440 
3441 static const Parameter s_LSADataSeq[] = {
3442     {"lsaIdentity",            s_ctxtPrim_0_Tag, false, TcapXApplication::HexString,   0},
3443     {"lsaAttributes",          s_ctxtPrim_1_Tag, false, TcapXApplication::HexString,   0},
3444     {"lsaActiveModeIndicator", s_ctxtPrim_2_Tag, true,  TcapXApplication::Null,        0},
3445     {"extensionContainer",     s_ctxtCstr_3_Tag, true,  TcapXApplication::HexString,   0},
3446     {"",                       s_noTag,          false, TcapXApplication::None,        0},
3447 };
3448 
3449 static const Parameter s_LSAData[] = {
3450     {"lsaData", s_sequenceTag,  false,  TcapXApplication::Sequence,   s_LSADataSeq},
3451     {"",        s_noTag,        false,  TcapXApplication::None,       0},
3452 };
3453 
3454 static const Parameter s_LSAInformation[] = {
3455     {"completeDataListIncluded", s_nullTag,         true, TcapXApplication::Null,        0},
3456     {"lsaOnlyAccessIndicator",   s_ctxtPrim_1_Tag,  true, TcapXApplication::Enumerated,  s_lsaOnlyAccessIndicator},
3457     {"lsaDataList",              s_ctxtCstr_2_Tag,  true, TcapXApplication::SequenceOf,  s_LSAData},
3458     {"extensionContainer",       s_ctxtCstr_3_Tag,  true, TcapXApplication::HexString,   0},
3459     {"",                         s_noTag,           false,TcapXApplication::None,        0},
3460 };
3461 
3462 static const Parameter s_GMLC[] = {
3463     {"gmlc",  s_hexTag, false,    TcapXApplication::AddressString, 0},
3464     {"",      s_noTag,  false,    TcapXApplication::None,          0},
3465 };
3466 
3467 static const TokenDict s_notificationToMSUser[] = {
3468     {"notifyLocationAllowed",                           0x00},
3469     {"notifyAndVerify-LocationAllowedIfNoResponse",     0x01},
3470     {"notifyAndVerify-LocationNotAllowedIfNoResponse",  0x02},
3471     {"locationNotAllowed",                              0x03},
3472     {0,0},
3473 };
3474 
3475 static const TokenDict s_GMLCRestriction[] = {
3476     {"gmlc-List",       0x00},
3477     {"home-Country",    0x01},
3478     {0,0},
3479 };
3480 
3481 static const Parameter s_LCSClientExternalIDSeq[] = {
3482     {"externalAddress",      s_ctxtPrim_0_Tag, true,  TcapXApplication::AddressString, 0},
3483     {"extensionContainer",   s_ctxtCstr_1_Tag, true,  TcapXApplication::HexString,     0},
3484     {"",                     s_noTag,          false, TcapXApplication::None,          0},
3485 };
3486 
3487 static const Parameter s_externalClientSeq[] = {
3488     {"clientIdentity",       s_sequenceTag,    false,  TcapXApplication::Sequence,   s_LCSClientExternalIDSeq},
3489     {"gmlc-Restriction",     s_ctxtPrim_0_Tag, true,   TcapXApplication::Enumerated, s_GMLCRestriction},
3490     {"notificationToMSUser", s_ctxtPrim_1_Tag, true,   TcapXApplication::Enumerated, s_notificationToMSUser},
3491     {"extensionContainer",   s_ctxtCstr_2_Tag, true,   TcapXApplication::HexString,  0},
3492     {"",                     s_noTag,          false,  TcapXApplication::None,       0},
3493 };
3494 
3495 static const Parameter s_externalClient[] = {
3496     {"externalClient",  s_sequenceTag, false,    TcapXApplication::Sequence, s_externalClientSeq},
3497     {"",                s_noTag,       false,    TcapXApplication::None,          0},
3498 };
3499 
3500 static const TokenDict s_LCSClientInternalIDEnum[] = {
3501     {"broadcastService",             0x00},
3502     {"o-andM-HPLMN",                 0x01},
3503     {"o-andM-VPLMN",                 0x02},
3504     {"anonymousLocation",            0x03},
3505     {"targetMSsubscribedService",    0x04},
3506     {0,0},
3507 };
3508 
3509 
3510 static const Parameter s_LCSClientInternalID[] = {
3511     {"lcsClientInternalID",  s_enumTag, false,    TcapXApplication::Enumerated, s_LCSClientInternalIDEnum},
3512     {"",                     s_noTag,   false,    TcapXApplication::None,       0},
3513 };
3514 
3515 static const Parameter s_serviceTypeSeq[] = {
3516     {"serviceTypeIdentity",    s_intTag,         false,TcapXApplication::Integer,    0},
3517     {"gmlc-Restriction",       s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_GMLCRestriction},
3518     {"notificationToMSUser",   s_ctxtPrim_1_Tag, true, TcapXApplication::Enumerated, s_notificationToMSUser},
3519     {"extensionContainer",     s_ctxtCstr_2_Tag, true, TcapXApplication::HexString,  0},
3520     {"",                       s_noTag,          false,TcapXApplication::None,       0},
3521 };
3522 
3523 static const Parameter s_serviceType[] = {
3524     {"serviceType",  s_sequenceTag, false,    TcapXApplication::Sequence, s_serviceTypeSeq},
3525     {"",             s_noTag,       false,    TcapXApplication::None,     0},
3526 };
3527 
3528 static const Parameter s_LCSPrivacyClassSeq[] = {
3529     {"ss-Code",                s_hexTag,         false,TcapXApplication::Enumerated, s_SSCode},
3530     {"ss-Status",              s_hexTag,         false,TcapXApplication::Flags,      s_ssStatus},
3531     {"notificationToMSUser",   s_ctxtPrim_0_Tag, true, TcapXApplication::Enumerated, s_notificationToMSUser},
3532     {"externalClientList",     s_ctxtCstr_1_Tag, true, TcapXApplication::SequenceOf, s_externalClient},
3533     {"plmnClientList",         s_ctxtCstr_2_Tag, true, TcapXApplication::SequenceOf, s_LCSClientInternalID},
3534     {"extensionContainer",     s_ctxtCstr_3_Tag, true, TcapXApplication::HexString,  0},
3535     {"ext-externalClientList", s_ctxtCstr_4_Tag, true, TcapXApplication::SequenceOf, s_externalClient},
3536     {"serviceTypeList",        s_ctxtCstr_5_Tag, true, TcapXApplication::SequenceOf, s_serviceType},
3537     {"",                       s_noTag,          false,TcapXApplication::None,       0},
3538 };
3539 
3540 static const Parameter s_LCSPrivacyException[] = {
3541     {"lcsPrivacyClass",  s_sequenceTag, false,    TcapXApplication::Sequence, s_LCSPrivacyClassSeq},
3542     {"",                 s_noTag,       false,    TcapXApplication::None,     0},
3543 };
3544 
3545 static const Parameter s_MOLRClassSeq[] = {
3546     {"ss-Code",              s_hexTag,         false,TcapXApplication::Enumerated, s_SSCode},
3547     {"ss-Status",            s_hexTag,         false,TcapXApplication::Flags,      s_ssStatus},
3548     {"extensionContainer",   s_ctxtCstr_0_Tag, true, TcapXApplication::HexString,  0},
3549     {"",                     s_noTag,          false,TcapXApplication::None,       0},
3550 };
3551 
3552 static const Parameter s_MOLRClass[] = {
3553     {"mOLRClass",  s_sequenceTag, false,    TcapXApplication::Sequence, s_MOLRClassSeq},
3554     {"",           s_noTag,       false,    TcapXApplication::None,     0},
3555 };
3556 
3557 static const Parameter s_LCSInformation[] = {
3558     {"gmlc-List",                    s_ctxtCstr_0_Tag, true,  TcapXApplication::SequenceOf,  s_GMLC},
3559     {"lcs-PrivacyExceptionList",     s_ctxtCstr_1_Tag, true,  TcapXApplication::SequenceOf,  s_LCSPrivacyException},
3560     {"molr-List",                    s_ctxtCstr_2_Tag, true,  TcapXApplication::SequenceOf,  s_MOLRClass},
3561     {"add-lcs-PrivacyExceptionList", s_ctxtCstr_3_Tag, true,  TcapXApplication::SequenceOf,  s_LCSPrivacyException},
3562     {"",                             s_noTag,          false, TcapXApplication::None,        0},
3563 };
3564 
3565 static const Parameter s_MC_SSInfo[] = {
3566     {"ss-Code",                 s_ctxtPrim_0_Tag,    false,  TcapXApplication::Enumerated,  s_SSCode},
3567     {"ss-Status",               s_ctxtPrim_1_Tag,    false,  TcapXApplication::Flags,       s_ssStatus},
3568     {"nbrSB",                   s_ctxtPrim_2_Tag,    false,  TcapXApplication::Integer,     0},
3569     {"nbrUser",                 s_ctxtPrim_3_Tag,    false,  TcapXApplication::Integer,     0},
3570     {"extensionContainer",      s_ctxtCstr_4_Tag,    true,   TcapXApplication::HexString,   0},
3571     {"",                        s_noTag,          false, TcapXApplication::None,        0},
3572 };
3573 
3574 static const TokenDict s_GPRSTriggerDetectionPoint[] = {
3575     {"attach",                                    1},
3576     {"attachChangeOfPosition",                    2},
3577     {"pdp-ContextEstablishment",                 11},
3578     {"pdp-ContextEstablishmentAcknowledgement",  12},
3579     {"pdp-ContextChangeOfPosition",              14},
3580     {0,0},
3581 };
3582 
3583 static const TokenDict s_defaultGPRSHandling[] = {
3584     {"continueTransaction",    0},
3585     {"releaseTransaction",     1},
3586     {0,0},
3587 };
3588 
3589 static const Parameter s_GPRSCamelTDPDataSeq[] = {
3590     {"gprs-TriggerDetectionPoint",  s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated,    s_GPRSTriggerDetectionPoint},
3591     {"serviceKey",                  s_ctxtPrim_1_Tag, false, TcapXApplication::Integer,       0},
3592     {"gsmSCF-Address",              s_ctxtPrim_2_Tag, false, TcapXApplication::AddressString, 0},
3593     {"defaultSessionHandling",      s_ctxtPrim_3_Tag, false, TcapXApplication::Enumerated,    s_defaultGPRSHandling},
3594     {"extensionContainer",          s_ctxtCstr_4_Tag, true,  TcapXApplication::HexString,     0},
3595     {"",                            s_noTag,          false, TcapXApplication::None,          0},
3596 };
3597 
3598 static const Parameter s_GPRSCamelTDPData[] = {
3599     {"gprs-CamelTDPData",       s_sequenceTag,    false, TcapXApplication::Sequence,    s_GPRSCamelTDPDataSeq},
3600     {"",                        s_noTag,          false, TcapXApplication::None,        0},
3601 };
3602 
3603 static const Parameter s_GPRS_CSISeq[] = {
3604     {"gprs-CamelTDPDataList",   s_ctxtCstr_0_Tag, true,  TcapXApplication::SequenceOf,  s_GPRSCamelTDPData},
3605     {"camelCapabilityHandling", s_ctxtPrim_1_Tag, true,  TcapXApplication::Enumerated,  s_camelCapabilityHandling},
3606     {"extensionContainer",      s_ctxtCstr_2_Tag, true,  TcapXApplication::HexString,   0},
3607     {"notificationToCSE",       s_ctxtPrim_3_Tag, true,  TcapXApplication::Null,        0},
3608     {"csiActive",               s_ctxtPrim_4_Tag, true,  TcapXApplication::Null,        0},
3609     {"",                        s_noTag,          false, TcapXApplication::None,        0},
3610 };
3611 
3612 static const Parameter s_SGSN_CAMELSubscriptionInfoSeq[] = {
3613     {"gprs-CSI",                    s_ctxtCstr_0_Tag,    true,   TcapXApplication::Sequence,    s_GPRS_CSISeq},
3614     {"mo-sms-CSI",                  s_ctxtCstr_1_Tag,    true,   TcapXApplication::Sequence,    s_SMS_CSI},
3615     {"extensionContainer",          s_ctxtCstr_2_Tag,    true,   TcapXApplication::HexString,   0},
3616     {"mt-sms-CSI",                  s_ctxtCstr_3_Tag,    true,   TcapXApplication::Sequence,    s_SMS_CSI},
3617     {"mt-smsCAMELTDP-CriteriaList", s_ctxtCstr_4_Tag,    true,   TcapXApplication::SequenceOf,  s_MT_smsCAMELTDP_Criteria},
3618     {"mg-csi",                      s_ctxtCstr_5_Tag,    true,   TcapXApplication::Sequence,    s_M_CSI},
3619     {"",                            s_noTag,             false,  TcapXApplication::None,        0},
3620 };
3621 
3622 static const TokenDict s_accessRestrictionData[] = {
3623     {"utranNotAllowed",               0x01},
3624     {"geranNotAllowed",               0x02},
3625     {"ganNotAllowed",                 0x03},
3626     {"i-hspa-evolutionNotAllowed",    0x04},
3627     {"e-utranNotAllowed",             0x05},
3628     {"ho-toNon3GPP-AccessNotAllowed", 0x06},
3629     {0,0},
3630 };
3631 
3632 static const Parameter s_AMBRSeq[] = {
3633     {"max-RequestedBandwidth-UL",   s_ctxtPrim_0_Tag,    false,  TcapXApplication::Integer,     0},
3634     {"max-RequestedBandwidth-DL",   s_ctxtPrim_1_Tag,    false,  TcapXApplication::Integer,     0},
3635     {"extensionContainer",          s_ctxtCstr_2_Tag,    true,   TcapXApplication::HexString,   0},
3636     {"",                            s_noTag,             false,  TcapXApplication::None,        0},
3637 };
3638 
3639 static const Parameter s_AllocationRetentionPrioritySeq[] = {
3640     {"priority-level",                 s_ctxtPrim_0_Tag,    false,  TcapXApplication::Integer,     0},
3641     {"pre-emption-capability",         s_ctxtPrim_1_Tag,    true,   TcapXApplication::Bool,        0},
3642     {"pre-emption-vulnerability",      s_ctxtPrim_1_Tag,    true,   TcapXApplication::Bool,        0},
3643     {"extensionContainer",             s_ctxtCstr_3_Tag,    true,   TcapXApplication::HexString,   0},
3644     {"",                               s_noTag,             false,  TcapXApplication::None,        0},
3645 };
3646 
3647 static const Parameter s_EPS_QoS_SubscribedSeq[] = {
3648     {"qos-Class-Identifier",           s_ctxtPrim_0_Tag,    false,  TcapXApplication::Integer,     0},
3649     {"allocation-Retention-Priority",  s_ctxtCstr_1_Tag,    false,  TcapXApplication::Sequence,    s_AllocationRetentionPrioritySeq},
3650     {"extensionContainer",             s_ctxtCstr_2_Tag,    true,   TcapXApplication::HexString,   0},
3651     {"",                               s_noTag,             false,  TcapXApplication::None,        0},
3652 };
3653 
3654 static const Parameter s_PDN_GW_Identity[] = {
3655     {"pdn-gw-ipv4-Address",         s_ctxtPrim_0_Tag, true,  TcapXApplication::HexString, 0},
3656     {"pdn-gw-ipv6-Address",         s_ctxtPrim_1_Tag, true,  TcapXApplication::HexString, 0},
3657     {"pdn-gw-name",                 s_ctxtPrim_2_Tag, true,  TcapXApplication::HexString, 0},
3658     {"extensionContainer",          s_ctxtCstr_3_Tag, true,  TcapXApplication::HexString, 0},
3659     {"",                            s_noTag,          false, TcapXApplication::None,      0},
3660 };
3661 
3662 static const TokenDict s_PDN_GW_AllocationType[] = {
3663     {"static",   0},
3664     {"dynamic",  1},
3665     {0,0},
3666 };
3667 
3668 static const Parameter s_SpecificAPNInfoSeq[] = {
3669     {"apn",                   s_ctxtPrim_0_Tag,    false,  TcapXApplication::HexString, 0},
3670     {"pdn-gw-Identity",       s_ctxtCstr_1_Tag,    false,  TcapXApplication::Sequence,  s_PDN_GW_Identity},
3671     {"extensionContainer",    s_ctxtCstr_2_Tag,    true,   TcapXApplication::HexString, 0},
3672     {"",                      s_noTag,             false,  TcapXApplication::None,      0},
3673 };
3674 
3675 static const Parameter s_SpecificAPNInfo[] = {
3676     {"specificAPNInfo",       s_sequenceTag, false,  TcapXApplication::Sequence,  s_SpecificAPNInfoSeq},
3677     {"",                      s_noTag,       false,  TcapXApplication::None,      0},
3678 };
3679 
3680 static const Parameter s_APNConfigurationSeq[] = {
3681     {"contextId",                    s_ctxtPrim_0_Tag,    false, TcapXApplication::Integer,     0},
3682     {"pdn-Type",                     s_ctxtPrim_1_Tag,    false, TcapXApplication::HexString,   0},
3683     {"servedPartyIP-IPv4-Address",   s_ctxtPrim_2_Tag,    true,  TcapXApplication::HexString,   0},
3684     {"apn",                          s_ctxtPrim_3_Tag,    false, TcapXApplication::HexString,   0},
3685     {"eps-qos-Subscribed",           s_ctxtCstr_4_Tag,    false, TcapXApplication::Sequence,    s_EPS_QoS_SubscribedSeq},
3686     {"pdn-gw-Identity",              s_ctxtCstr_5_Tag,    true,  TcapXApplication::Sequence,    s_PDN_GW_Identity},
3687     {"pdn-gw-AllocationType",        s_ctxtPrim_6_Tag,    true,  TcapXApplication::Enumerated,  s_PDN_GW_AllocationType},
3688     {"vplmnAddressAllowed",          s_ctxtPrim_7_Tag,    true,  TcapXApplication::Null,        0},
3689     {"chargingCharacteristics",      s_ctxtPrim_8_Tag,    true,  TcapXApplication::HexString,   0},
3690     {"ambr",                         s_ctxtCstr_9_Tag,    true,  TcapXApplication::Sequence,    s_AMBRSeq},
3691     {"specificAPNInfoList",          s_ctxtCstr_10_Tag,   true,  TcapXApplication::SequenceOf,  s_SpecificAPNInfo},
3692     {"extensionContainer",           s_ctxtCstr_11_Tag,   true,  TcapXApplication::HexString,   0},
3693     {"servedPartyIP-IPv6-Address",   s_ctxtPrim_12_Tag,   true,  TcapXApplication::HexString,   0},
3694     {"apn-oi-Replacement",           s_ctxtPrim_13_Tag,   true,  TcapXApplication::HexString,   0},
3695     {"",                             s_noTag,             false, TcapXApplication::None,        0},
3696 };
3697 
3698 static const Parameter s_APNConfiguration[] = {
3699     {"APN-Configuration",           s_sequenceTag,    false,  TcapXApplication::Sequence,    s_APNConfigurationSeq},
3700     {"",                            s_noTag,          false,  TcapXApplication::None,        0},
3701 };
3702 
3703 static const Parameter s_APN_ConfigurationProfileSeq[] = {
3704     {"defaultContext",           s_intTag,            false, TcapXApplication::Integer,     0},
3705     {"completeDataListIncluded", s_nullTag,           true,  TcapXApplication::Null,        0},
3706     {"epsDataList",              s_ctxtCstr_1_Tag,    false, TcapXApplication::SequenceOf,  s_APNConfiguration},
3707     {"extensionContainer",       s_ctxtCstr_2_Tag,    true,  TcapXApplication::HexString,   0},
3708     {"",                         s_noTag,             false, TcapXApplication::None,        0},
3709 };
3710 
3711 static const Parameter s_EPS_SubscriptionData[] = {
3712     {"apn-oi-Replacement",      s_ctxtPrim_0_Tag,    true,   TcapXApplication::HexString,      0},
3713     {"rfsp-id",                 s_ctxtPrim_2_Tag,    true,   TcapXApplication::Integer,        0},
3714     {"ambr",                    s_ctxtCstr_3_Tag,    true,   TcapXApplication::Sequence,       s_AMBRSeq},
3715     {"apn-ConfigurationProfile",s_ctxtCstr_4_Tag,    true,   TcapXApplication::Sequence,       s_APN_ConfigurationProfileSeq},
3716     {"stn-sr",                  s_ctxtPrim_6_Tag,    true,   TcapXApplication::AddressString,  0},
3717     {"extensionContainer",      s_ctxtCstr_5_Tag,    true,   TcapXApplication::HexString,      0},
3718     {"",                        s_noTag,             false,  TcapXApplication::None,           0},
3719 };
3720 
3721 static const Parameter s_CSG_SubscriptionDataSeq[] = {
3722     // should find encoding for csg-ID
3723     {"csg-Id",                s_bitsTag,        false, TcapXApplication::HexString,      0},
3724     {"expirationDate",        s_hexTag,         true,  TcapXApplication::HexString,      0},
3725     {"extensionContainer",    s_sequenceTag,    true,  TcapXApplication::HexString,      0},
3726     {"",                      s_noTag,          false, TcapXApplication::None,           0},
3727 };
3728 
3729 static const Parameter s_CSG_SubscriptionData[] = {
3730     {"CSG-SubscriptionData",    s_sequenceTag,    false,  TcapXApplication::Sequence,    s_CSG_SubscriptionDataSeq},
3731     {"",                        s_noTag,          false,  TcapXApplication::None,        0},
3732 };
3733 
3734 static const Parameter s_contextId[] = {
3735 // TS 100 974 v7.15.0 page 305
3736     {"contextId",      s_intTag, false, TcapXApplication::Integer,    0},
3737     {"",               s_noTag,  false, TcapXApplication::None,       0},
3738 };
3739 
3740 static const Parameter s_GPRSSubscriptionDataWithdraw[] = {
3741 // TS 100 974 v7.15.0 page 305
3742     {"allGPRSData",      s_nullTag,     false, TcapXApplication::Null,       0},
3743     {"contextIdList",    s_sequenceTag, false, TcapXApplication::SequenceOf, s_contextId},
3744     {"",                 s_noTag,       false, TcapXApplication::None,       0},
3745 };
3746 
3747 static const Parameter s_LSAIdentity[] = {
3748 // TS 100 974 v7.15.0 page 300
3749     {"lsaIdentity",    s_hexTag, false, TcapXApplication::HexString,  0},
3750     {"",               s_noTag,  false, TcapXApplication::None,       0},
3751 };
3752 
3753 static const Parameter s_LSAInformationWithdraw[] = {
3754 // TS 100 974 v7.15.0 page 305
3755     {"allLSAData",      s_nullTag,     false, TcapXApplication::Null,       0},
3756     {"lsaIdentityList", s_sequenceTag, false, TcapXApplication::SequenceOf, s_LSAIdentity},
3757     {"",                s_noTag,       false, TcapXApplication::None,       0},
3758 };
3759 
3760 static const TokenDict s_specificCSI_Withdraw[] = {
3761     {"o-csi",      0x0001},
3762     {"ss-csi",     0x0002},
3763     {"tif-csi",    0x0004},
3764     {"d-csi",      0x0008},
3765     {"vt-csi",     0x0010},
3766     {"mo-sms-csi", 0x0020},
3767     {"m-csi",      0x0040},
3768     {"gprs-csi",   0x0080},
3769     {"t-csi",      0x0100},
3770     {"mt-sms-csi", 0x0200},
3771     {"mg-csi",     0x0400},
3772     {"o-IM-CSI",   0x0800},
3773     {"d-IM-CSI",   0x1000},
3774     {"vt-IM-CSI",  0x2000},
3775     {0,0},
3776 };
3777 
3778 static const Parameter s_EPS_SubscriptionDataWithdraw[] = {
3779     {"allEPS-Data",      s_nullTag,     false, TcapXApplication::Null,       0},
3780     {"contextIdList",    s_sequenceTag, false, TcapXApplication::SequenceOf, s_contextId},
3781     {"",                 s_noTag,       false, TcapXApplication::None,       0},
3782 };
3783 
3784 
3785 static const TokenDict s_regionalSubscriptionResponse[] = {
3786 // TS 100 974 v7.15.0 page 305
3787     {"networkNode-AreaRestricted", 0},
3788     {"tooManyZoneCodes",           1},
3789     {"zoneCodesConflict",          2},
3790     {"regionalSubscNotSupported",  3},
3791     {0,0},
3792 };
3793 
3794 static const TokenDict s_supportedFeatures[] = {
3795     {"odb-all-apn",                                                    0x00000001},
3796     {"odb-HPLMN-APN",                                                  0x00000002},
3797     {"odb-VPLMN-APN",                                                  0x00000004},
3798     {"odb-all-og",                                                     0x00000008},
3799     {"odb-all-international-og",                                       0x00000010},
3800     {"odb-all-int-og-not-to-HPLMN-country",                            0x00000020},
3801     {"odb-all-interzonal-og",                                          0x00000040},
3802     {"odb-all-interzonal-og-not-to-HPLMN-country",                     0x00000080},
3803     {"odb-all-interzonal-og-and-internat-og-not-to-HPLMN-country",     0x00000100},
3804     {"regSub",                                                         0x00000200},
3805     {"trace",                                                          0x00000400},
3806     {"lcs-all-PrivExcep",                                              0x00000800},
3807     {"lcs-universal",                                                  0x00001000},
3808     {"lcs-CallSessionRelated",                                         0x00002000},
3809     {"lcs-CallSessionUnrelated",                                       0x00004000},
3810     {"lcs-PLMN-operator",                                              0x00008000},
3811     {"lcs-ServiceType",                                                0x00010000},
3812     {"lcs-all-MOLR-SS",                                                0x00020000},
3813     {"lcs-basicSelfLocation",                                          0x00040000},
3814     {"lcs-autonomousSelfLocation",                                     0x00080000},
3815     {"lcs-transferToThirdParty",                                       0x00100000},
3816     {"sm-mo-pp",                                                       0x00200000},
3817     {"barring-OutgoingCalls",                                          0x00400000},
3818     {"baoc",                                                           0x00800000},
3819     {"boic",                                                           0x01000000},
3820     {"boicExHC",                                                       0x02000000},
3821     {0, 0},
3822 };
3823 
3824 static const Parameter s_SSForBSCode[] = {
3825 // TS 100 974 v7.15.0 page 319
3826     {"ss-Code",                   s_hexTag,           false,  TcapXApplication::Enumerated,  s_SSCode},
3827     {"basicService",              s_noTag,            true,   TcapXApplication::Choice,      s_basicServiceCode},
3828     {"longFTN-Supported",         s_ctxtPrim_4_Tag,   true,   TcapXApplication::Null,        0},
3829     {"",                          s_noTag,            false,  TcapXApplication::None,        0},
3830 };
3831 
3832 static const Parameter s_ccbsFeature[] = {
3833 // TS 100 974 v7.15.0 page 319
3834     {"ccbs-Index",             s_ctxtPrim_0_Tag,   true,    TcapXApplication::Integer,             0},
3835     {"b-subscriberNumber",     s_ctxtPrim_1_Tag,   true,    TcapXApplication::AddressString,       0},
3836     {"b-subscriberSubaddress", s_ctxtPrim_2_Tag,   true,    TcapXApplication::HexString ,          0},
3837     {"basicServiceGroup",      s_ctxtCstr_3_Tag,   true,    TcapXApplication::Choice,              s_extBasicServiceCode},
3838     {"",                       s_noTag,            false,   TcapXApplication::None,                0},
3839 };
3840 
3841 static const Parameter s_CCBSFeature[] = {
3842 // TS 100 974 v7.15.0 page 319
3843     {"CCBS-Feature",              s_sequenceTag,    false,   TcapXApplication::Sequence,  s_ccbsFeature},
3844     {"",                          s_noTag,          false,   TcapXApplication::None,      0},
3845 };
3846 
3847 static const Parameter s_genericServiceInfo[] = {
3848 // TS 100 974 v7.15.0 page 319
3849     {"ss-Status",               s_hexTag,         false,    TcapXApplication::Flags,         s_ssStatus},
3850     {"cliRestrictionOption",    s_enumTag,        true,     TcapXApplication::Enumerated,    s_cliRestrictionOption},
3851     {"maximumentitledPriority", s_ctxtPrim_0_Tag, true,     TcapXApplication::Enumerated,    s_EMLPPPriority},
3852     {"defaultPriority",         s_ctxtPrim_1_Tag, true,     TcapXApplication::Enumerated,    s_EMLPPPriority},
3853     {"ccbs-FeatureList",        s_ctxtCstr_2_Tag, true,     TcapXApplication::SequenceOf,    s_CCBSFeature},
3854     {"nbrSB",                   s_ctxtPrim_3_Tag, true,     TcapXApplication::Integer,       0},
3855     {"nbrUser",                 s_ctxtPrim_4_Tag, true,     TcapXApplication::Integer,       0},
3856     {"nbrSN",                   s_ctxtPrim_5_Tag, true,     TcapXApplication::Integer,       0},
3857     {"",                        s_noTag,          false,    TcapXApplication::None,          0},
3858 };
3859 
3860 static const Parameter s_InterrogateSSRes[] = {
3861 // TS 100 974 v7.15.0 page 319
3862     {"ss-Status",              s_ctxtPrim_0_Tag,   false,    TcapXApplication::Flags,         s_ssStatus},
3863     {"basicServiceGroupList",  s_ctxtCstr_2_Tag,   false,    TcapXApplication::SequenceOf,    s_basicServiceCodeType},
3864     {"forwardingFeatureList",  s_ctxtCstr_3_Tag,   false,    TcapXApplication::SequenceOf,    s_forwFeature},
3865     {"genericServiceInfo",     s_ctxtCstr_4_Tag,   false,    TcapXApplication::Sequence,      s_genericServiceInfo},
3866     {"",                       s_noTag,            false,    TcapXApplication::None,          0},
3867 };
3868 
3869 static const TokenDict s_failureCauseEnum[] = {
3870 // TS 129 002 v9.3.0 page 353
3871     {"wrongUserResponse",     0x00},
3872     {"wrongNetworkSignature", 0x01},
3873     {0,                       0x00},
3874 };
3875 
3876 static const TokenDict s_accessTypeEnum[] = {
3877 // TS 129 002 v9.3.0 page 353
3878     {"call",                  0x00},
3879     {"emergencyCall",         0x01},
3880     {"locationUpdating",      0x02},
3881     {"supplementaryService",  0x03},
3882     {"shortMessage",          0x04},
3883     {"gprsAttach",            0x05},
3884     {"routingAreaUpdating",   0x06},
3885     {"serviceRequest",        0x07},
3886     {"pdpContextActivation",  0x08},
3887     {"pdpContextDeactivation",0x09},
3888     {"gprsDetach",            0x0a},
3889     {0,                       0x00},
3890 };
3891 
3892 static const TokenDict s_guidanceInfo[] = {
3893     {"enterPW",           0 },
3894     {"enterNewPW",        1 },
3895     {"enterNewPW-Again",  2 },
3896     {0, 0},
3897 };
3898 
3899 static const Parameter s_SGSN_CapabilitySeq[] = {
3900     {"solsaSupportIndicator",                      s_nullTag,         true, TcapXApplication::Null,       0},
3901     {"extensionContainer",                         s_ctxtCstr_1_Tag,  true, TcapXApplication::HexString,  0},
3902     {"superChargerSupportedInServingNetworkEntity",s_ctxtCstr_2_Tag,  true, TcapXApplication::Choice,     s_superChargerInfo},
3903     {"gprsEnhancementsSupportIndicator",           s_ctxtPrim_3_Tag,  true, TcapXApplication::Null,       0},
3904     {"supportedCamelPhases",                       s_ctxtPrim_4_Tag,  true, TcapXApplication::BitString,  s_camelPhases},
3905     {"supportedLCS-CapabilitySets",                s_ctxtPrim_5_Tag,  true, TcapXApplication::BitString,  s_supportedLCSCapabilitySets},
3906     {"offeredCamel4CSIs",                          s_ctxtPrim_6_Tag,  true, TcapXApplication::BitString,  s_offeredCamel4CSIs},
3907     {"smsCallBarringSupportIndicator",             s_ctxtPrim_7_Tag,  true, TcapXApplication::Null,       0},
3908     {"supportedRAT-TypesIndicator",                s_ctxtPrim_8_Tag,  true, TcapXApplication::BitString,  s_supportedRATTypes},
3909     {"supportedFeatures",                          s_ctxtPrim_9_Tag,  true, TcapXApplication::BitString,  s_supportedFeatures},
3910     {"t-adsDataRetrieval",                         s_ctxtPrim_10_Tag, true, TcapXApplication::Null,       0},
3911     {"homogeneousSupportOfIMSVoiceOverPSSessions", s_ctxtPrim_11_Tag, true, TcapXApplication::Bool,       0},
3912     {"",                                           s_noTag,           false,TcapXApplication::None,       0},
3913 };
3914 
3915 static const Parameter s_PDN_GW_UpdateSeq[] = {
3916     {"apn",               s_ctxtPrim_0_Tag, true, TcapXApplication::HexString, 0},
3917     {"pdn-gw-Identity",   s_ctxtCstr_1_Tag, true, TcapXApplication::Sequence,  s_PDN_GW_Identity},
3918     {"contextId",         s_ctxtPrim_2_Tag, true, TcapXApplication::Integer,   0},
3919     {"extensionContainer",s_ctxtCstr_3_Tag, true, TcapXApplication::HexString, 0},
3920     {"",                  s_noTag,          false,TcapXApplication::None,      0},
3921 };
3922 
3923 static const TokenDict s_ISR_Information[] = {
3924     {"updateMME",               0x01},
3925     {"cancelSGSN",              0x02},
3926     {"initialAttachIndicator",  0x04},
3927     {0, 0},
3928 };
3929 
3930 static const Parameter s_EPS_InfoChoice[] = {
3931     {"pdn-gw-update",      s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence,  s_PDN_GW_UpdateSeq},
3932     {"isr-Information",    s_ctxtPrim_1_Tag, false, TcapXApplication::BitString, s_ISR_Information},
3933     {"",                   s_noTag,          false, TcapXApplication::None,      0},
3934 };
3935 
3936 static const TokenDict s_used_RAT_Type[] = {
3937     {"utran",            0},
3938     {"geran",            1},
3939     {"gan",              2},
3940     {"i-hspa-evolution", 3},
3941     {"e-utran",          4},
3942     {0, 0},
3943 };
3944 
3945 static const Parameter s_hlrId[] = {
3946     {"HLR-Id",            s_hexTag,   false,   TcapXApplication::TBCD,       0},
3947     {"",                  s_noTag,    false,   TcapXApplication::None,       0},
3948 };
3949 
3950 static const Parameter s_additionalNumber[] = {
3951     {"msc-Number",  s_ctxtPrim_0_Tag, false,  TcapXApplication::AddressString, 0},
3952     {"sgsn-Number", s_ctxtPrim_1_Tag, false,  TcapXApplication::AddressString, 0},
3953     {"",            s_noTag,          false,  TcapXApplication::None,          0},
3954 };
3955 
3956 static const TokenDict s_SM_DeliveryNotIntended[] = {
3957     {"onlyIMSI-requested",    0},
3958     {"onlyMCC-MNC-requested", 1},
3959     {0, 0},
3960 };
3961 
3962 static const Parameter s_locationInfoWithLMSI[] = {
3963 // TS 100 974 v7.15.0 page 324
3964     {"networkNode-Number",  s_ctxtPrim_1_Tag,  false,  TcapXApplication::AddressString, 0},
3965     {"lmsi",                s_hexTag,          true,   TcapXApplication::HexString,     0},
3966     {"extensionContainer",  s_sequenceTag,     true,   TcapXApplication::HexString,     0},
3967     {"gprsNodeIndicator",   s_ctxtPrim_5_Tag,  true,   TcapXApplication::Null,          0},
3968     {"additional-Number",   s_ctxtCstr_6_Tag,  true,   TcapXApplication::Choice,        s_additionalNumber},
3969     {"",                    s_noTag,           false,  TcapXApplication::None,          0},
3970 };
3971 
3972 static const TokenDict s_traceDepth[] = {
3973     {"minimum", 0},
3974     {"medium",  1},
3975     {"maximum", 2},
3976     {0, 0},
3977 };
3978 
3979 static const Parameter s_traceDepthListSeq[] = {
3980     {"msc-s-TraceDepth",  s_ctxtPrim_0_Tag,  true,  TcapXApplication::Enumerated,  s_traceDepth},
3981     {"mgw-TraceDepth",    s_ctxtPrim_1_Tag,  true,  TcapXApplication::Enumerated,  s_traceDepth},
3982     {"sgsn-TraceDepth",   s_ctxtPrim_2_Tag,  true,  TcapXApplication::Enumerated,  s_traceDepth},
3983     {"ggsn-TraceDepth",   s_ctxtPrim_3_Tag,  true,  TcapXApplication::Enumerated,  s_traceDepth},
3984     {"rnc-TraceDepth",    s_ctxtPrim_4_Tag,  true,  TcapXApplication::Enumerated,  s_traceDepth},
3985     {"bmsc-TraceDepth",   s_ctxtPrim_5_Tag,  true,  TcapXApplication::Enumerated,  s_traceDepth},
3986     {"mme-TraceDepth",    s_ctxtPrim_6_Tag,  true,  TcapXApplication::Enumerated,  s_traceDepth},
3987     {"sgw-TraceDepth",    s_ctxtPrim_7_Tag,  true,  TcapXApplication::Enumerated,  s_traceDepth},
3988     {"pgw-TraceDepth",    s_ctxtPrim_8_Tag,  true,  TcapXApplication::Enumerated,  s_traceDepth},
3989     {"eNB-TraceDepth",    s_ctxtPrim_9_Tag,  true,  TcapXApplication::Enumerated,  s_traceDepth},
3990     {"",                  s_noTag,           false, TcapXApplication::None,        0},
3991 };
3992 
3993 static const TokenDict s_traceNETypeList[] = {
3994     {"msc-s",0x0001},
3995     {"mgw",  0x0002},
3996     {"sgsn", 0x0004},
3997     {"ggsn", 0x0008},
3998     {"rnc",  0x0010},
3999     {"bm-sc",0x0020},
4000     {"mme",  0x0040},
4001     {"sgw",  0x0080},
4002     {"pgw",  0x0100},
4003     {"eNB",  0x0200},
4004     {0, 0},
4005 };
4006 
4007 static const TokenDict s_MSC_S_InterfaceList[] = {
4008     {"a",      0x0001},
4009     {"iu",     0x0002},
4010     {"mc",     0x0004},
4011     {"map-g",  0x0008},
4012     {"map-b",  0x0010},
4013     {"map-e",  0x0020},
4014     {"map-f",  0x0040},
4015     {"cap",    0x0080},
4016     {"map-d",  0x0100},
4017     {"map-c",  0x0200},
4018     {0, 0},
4019 };
4020 
4021 static const TokenDict s_MGW_InterfaceList[] = {
4022     {"mc",        0x01},
4023     {"nb-up",     0x02},
4024     {"iu-up",     0x04},
4025     {0, 0},
4026 };
4027 
4028 static const TokenDict s_SGSN_InterfaceList[] = {
4029     {"gb",      0x0001},
4030     {"iu",      0x0002},
4031     {"gn",      0x0004},
4032     {"map-gr",  0x0008},
4033     {"map-gd",  0x0010},
4034     {"map-gf",  0x0020},
4035     {"gs",      0x0040},
4036     {"ge",      0x0080},
4037     {"s3",      0x0100},
4038     {"s4",      0x0200},
4039     {"s6d",     0x0400},
4040     {0, 0},
4041 };
4042 
4043 static const TokenDict s_GGSN_InterfaceList[] = {
4044     {"gn",        0x01},
4045     {"gi",        0x02},
4046     {"gmb",       0x04},
4047     {0, 0},
4048 };
4049 
4050 static const TokenDict s_RNC_InterfaceList[] = {
4051     {"iu",       0x01},
4052     {"iur",      0x02},
4053     {"iub",      0x04},
4054     {"uu",       0x08},
4055     {0, 0},
4056 };
4057 
4058 static const TokenDict s_BMSC_InterfaceList[] = {
4059     {"gmb",       0x01},
4060     {0, 0},
4061 };
4062 
4063 static const TokenDict s_MME_InterfaceList[] = {
4064     {"s1-mme",    0x01},
4065     {"s3",        0x02},
4066     {"s6a",       0x04},
4067     {"s10",       0x08},
4068     {"s11",       0x10},
4069     {0, 0},
4070 };
4071 
4072 static const TokenDict s_SGW_InterfaceList[] = {
4073     {"s4",        0x01},
4074     {"s5",        0x02},
4075     {"s8b",       0x04},
4076     {"s11",       0x08},
4077     {"gxc",       0x10},
4078     {0, 0},
4079 };
4080 
4081 static const TokenDict s_PGW_InterfaceList[] = {
4082     {"s2a", 0x01},
4083     {"s2b", 0x02},
4084     {"s2c", 0x04},
4085     {"s5",  0x08},
4086     {"s6b", 0x10},
4087     {"gx",  0x20},
4088     {"s8b", 0x40},
4089     {"sgi", 0x80},
4090     {0, 0},
4091 };
4092 
4093 static const TokenDict s_ENB_InterfaceList[] = {
4094     {"s1-mme",   0x01},
4095     {"x2",       0x02},
4096     {"uu",       0x04},
4097     {0, 0},
4098 };
4099 
4100 static const Parameter s_traceInterfaceListSeq[] = {
4101     {"msc-s-List",  s_ctxtPrim_0_Tag,  true,  TcapXApplication::BitString,  s_MSC_S_InterfaceList},
4102     {"mgw-List",    s_ctxtPrim_1_Tag,  true,  TcapXApplication::BitString,  s_MGW_InterfaceList},
4103     {"sgsn-List",   s_ctxtPrim_2_Tag,  true,  TcapXApplication::BitString,  s_SGSN_InterfaceList},
4104     {"ggsn-List",   s_ctxtPrim_3_Tag,  true,  TcapXApplication::BitString,  s_GGSN_InterfaceList},
4105     {"rnc-List",    s_ctxtPrim_4_Tag,  true,  TcapXApplication::BitString,  s_RNC_InterfaceList},
4106     {"bmsc-List",   s_ctxtPrim_5_Tag,  true,  TcapXApplication::BitString,  s_BMSC_InterfaceList},
4107     {"mme-List",    s_ctxtPrim_6_Tag,  true,  TcapXApplication::BitString,  s_MME_InterfaceList},
4108     {"sgw-List",    s_ctxtPrim_7_Tag,  true,  TcapXApplication::BitString,  s_SGW_InterfaceList},
4109     {"pgw-List",    s_ctxtPrim_8_Tag,  true,  TcapXApplication::BitString,  s_PGW_InterfaceList},
4110     {"eNB-List",    s_ctxtPrim_9_Tag,  true,  TcapXApplication::BitString,  s_ENB_InterfaceList},
4111     {"",            s_noTag,           false, TcapXApplication::None,       0},
4112 };
4113 
4114 static const TokenDict s_MSC_S_EventList[] = {
4115     {"mo-mtCall",                 0x01},
4116     {"mo-mt-sms",                 0x02},
4117     {"lu-imsiAttach-imsiDetach",  0x04},
4118     {"handovers",                 0x08},
4119     {"ss",                        0x10},
4120     {0, 0},
4121 };
4122 
4123 static const TokenDict s_MGW_EventList[] = {
4124     {"context",                 0x01},
4125     {0, 0},
4126 };
4127 
4128 static const TokenDict s_SGSN_EventList[] = {
4129     {"pdpContext",                0x01},
4130     {"mo-mt-sms",                 0x02},
4131     {"rau-gprsAttach-gprsDetach", 0x04},
4132     {"mbmsContext",               0x08},
4133     {0, 0},
4134 };
4135 
4136 static const TokenDict s_GGSN_EventList[] = {
4137     {"pdpContext",                0x01},
4138     {"mbmsContext",               0x02},
4139     {0, 0},
4140 };
4141 
4142 static const TokenDict s_BMSC_EventList[] = {
4143     {"mbmsMulticastServiceActivation",      0x01},
4144     {0, 0},
4145 };
4146 
4147 static const TokenDict s_MME_EventList[] = {
4148     {"ue-initiatedPDNconectivityRequest",      0x01},
4149     {"serviceRequestts",                       0x02},
4150     {"initialAttachTrackingAreaUpdateDetach",  0x04},
4151     {"ue-initiatedPDNdisconnection",           0x08},
4152     {"bearerActivationModificationDeletion",   0x10},
4153     {"handover",                               0x20},
4154     {0, 0},
4155 };
4156 
4157 static const TokenDict s_SPGW_EventList[] = {
4158     {"pdn-connectionCreation",               0x01},
4159     {"pdn-connectionTermination",            0x02},
4160     {"bearerActivationModificationDeletion", 0x04},
4161     {0, 0},
4162 };
4163 
4164 static const Parameter s_traceEventListSeq[] = {
4165     {"msc-s-List",  s_ctxtPrim_0_Tag,  true,  TcapXApplication::BitString,  s_MSC_S_EventList},
4166     {"mgw-List",    s_ctxtPrim_1_Tag,  true,  TcapXApplication::BitString,  s_MGW_EventList},
4167     {"sgsn-List",   s_ctxtPrim_2_Tag,  true,  TcapXApplication::BitString,  s_SGSN_EventList},
4168     {"ggsn-List",   s_ctxtPrim_3_Tag,  true,  TcapXApplication::BitString,  s_GGSN_EventList},
4169     {"bmsc-List",   s_ctxtPrim_4_Tag,  true,  TcapXApplication::BitString,  s_BMSC_EventList},
4170     {"mme-List",    s_ctxtPrim_5_Tag,  true,  TcapXApplication::BitString,  s_MME_EventList},
4171     {"sgw-List",    s_ctxtPrim_6_Tag,  true,  TcapXApplication::BitString,  s_SPGW_EventList},
4172     {"pgw-List",    s_ctxtPrim_7_Tag,  true,  TcapXApplication::BitString,  s_SPGW_EventList},
4173     {"",            s_noTag,           false, TcapXApplication::None,       0},
4174 };
4175 
4176 
4177 static const Parameter s_authenticationSetSeq[] = {
4178 // TS 100 974 v7.15.0 page 298
4179     {"rand",   s_hexTag,  false,  TcapXApplication::HexString, 0},
4180     {"sres",   s_hexTag,  false,  TcapXApplication::HexString, 0},
4181     {"kc",     s_hexTag,  false,  TcapXApplication::HexString, 0},
4182     {"",       s_noTag,   false,  TcapXApplication::None,      0},
4183 };
4184 
4185 static const Parameter s_authenticationSet[] = {
4186     {"set",    s_sequenceTag,  false,  TcapXApplication::Sequence,  s_authenticationSetSeq},
4187     {"",       s_noTag,        false,  TcapXApplication::None,      0},
4188 };
4189 
4190 static const Parameter s_authenticationTriplet[] = {
4191     {"triplet",    s_sequenceTag,  false,  TcapXApplication::Sequence,  s_authenticationSetSeq},
4192     {"",           s_noTag,        false,  TcapXApplication::None,      0},
4193 };
4194 
4195 static const Parameter s_authenticationQuintupletSeq[] = {
4196     {"rand",   s_hexTag,  false,  TcapXApplication::HexString, 0},
4197     {"xres",   s_hexTag,  false,  TcapXApplication::HexString, 0},
4198     {"ck",     s_hexTag,  false,  TcapXApplication::HexString, 0},
4199     {"ik",     s_hexTag,  false,  TcapXApplication::HexString, 0},
4200     {"autn",   s_hexTag,  false,  TcapXApplication::HexString, 0},
4201     {"",       s_noTag,   false,  TcapXApplication::None,      0},
4202 };
4203 
4204 static const Parameter s_authenticationQuintuplet[] = {
4205     {"quintuplet",    s_sequenceTag,  false,  TcapXApplication::Sequence,  s_authenticationQuintupletSeq},
4206     {"",              s_noTag,        false,  TcapXApplication::None,      0},
4207 };
4208 
4209 static const Parameter s_authChoice[] = {
4210     {"tripletList",    s_ctxtCstr_0_Tag, false, TcapXApplication::SequenceOf,  s_authenticationTriplet},
4211     {"quintupletList", s_ctxtCstr_1_Tag, false, TcapXApplication::SequenceOf,  s_authenticationQuintuplet},
4212     {"",               s_noTag,          false, TcapXApplication::None,        0},
4213 };
4214 
4215 static const Parameter s_epcAvSeq[] = {
4216     {"rand",                s_hexTag,      false,  TcapXApplication::HexString, 0},
4217     {"xres",                s_hexTag,      false,  TcapXApplication::HexString, 0},
4218     {"autn",                s_hexTag,      false,  TcapXApplication::HexString, 0},
4219     {"kasme",               s_hexTag,      false,  TcapXApplication::HexString, 0},
4220     {"extensionContainer",  s_sequenceTag, true,   TcapXApplication::HexString, 0},
4221     {"",                    s_noTag,       false,  TcapXApplication::None,      0},
4222 };
4223 
4224 static const Parameter s_EPCAV[] = {
4225 // TS 129 002 V9.3.0 page 359
4226     {"EPC-AV",    s_sequenceTag,  false,  TcapXApplication::Sequence,  s_epcAvSeq},
4227     {"",                s_noTag,  false,  TcapXApplication::None,      0},
4228 };
4229 
4230 static const Parameter s_authenticationRes[] = {
4231 // TS 129 002 V9.3.0 page 352
4232     {"authenticationSetList",     s_noTag,          true,   TcapXApplication::Choice,     s_authChoice},
4233     {"extensionContainer",        s_sequenceTag,    true,   TcapXApplication::HexString,  0},
4234     {"eps-AuthenticationSetList", s_ctxtCstr_2_Tag, true,   TcapXApplication::SequenceOf, s_EPCAV},
4235     {"",                          s_noTag,          false,  TcapXApplication::None,       0},
4236 };
4237 
4238 static const TokenDict s_alertReason[] = {
4239 // TS 100 974 v7.15.0 page 326
4240     {"ms-Present",       0},
4241     {"memoryAvailable",  1},
4242     {0,0},
4243 };
4244 
4245 static const Parameter s_subscriberIdentity[] = {
4246 // TS 100 974 v7.15.0 page 335
4247     {"imsi",     s_ctxtPrim_0_Tag,    false,   TcapXApplication::TBCD,             0},
4248     {"msisdn",   s_ctxtPrim_1_Tag,    false,   TcapXApplication::AddressString,    0},
4249     {"",         s_noTag,             false,   TcapXApplication::None,             0},
4250 };
4251 
4252 static const TokenDict s_domainType[] = {
4253     {"cs-Domain",       0},
4254     {"ps-Domain",       1},
4255     {0,0},
4256 };
4257 
4258 static const TokenDict s_requestedNodes[] = {
4259     {"mme",  0x01},
4260     {"sgsn", 0x02},
4261     {0,0},
4262 };
4263 
4264 static const Parameter s_requestedInfo[] = {
4265 // TS 100 974 v7.15.0 page 309
4266     {"locationInformation", s_ctxtPrim_0_Tag, true,   TcapXApplication::Null,         0},
4267     {"subscriberState",     s_ctxtPrim_1_Tag, true,   TcapXApplication::Null,         0},
4268     {"extensionContainer",  s_ctxtCstr_2_Tag, true,   TcapXApplication::HexString,    0},
4269     {"currentLocation",     s_ctxtPrim_3_Tag, true,   TcapXApplication::Null,         0},
4270     {"requestedDomain",     s_ctxtPrim_4_Tag, true,   TcapXApplication::Enumerated,   s_domainType},
4271     {"imei",                s_ctxtPrim_6_Tag, true,   TcapXApplication::Null,         0},
4272     {"ms-classmark",        s_ctxtPrim_5_Tag, true,   TcapXApplication::Null,         0},
4273     {"mnpRequestedInfo",    s_ctxtPrim_7_Tag, true,   TcapXApplication::Null,         0},
4274     {"t-adsData",           s_ctxtPrim_8_Tag, true,   TcapXApplication::Null,         0},
4275     {"requestedNodes",      s_ctxtPrim_9_Tag, true,   TcapXApplication::BitString,    s_requestedNodes},
4276     {"",                    s_noTag,          false,  TcapXApplication::None,         0},
4277 };
4278 
4279 static const Parameter s_cellIdOrLAI[] = {
4280 // TS 100 974 v7.15.0 page 335
4281     {"cellIdFixedLength", s_ctxtPrim_0_Tag, false, TcapXApplication::CellIdFixedLength, 0},
4282     {"laiFixedLength",    s_ctxtPrim_1_Tag, false, TcapXApplication::LAIFixedLength,    0},
4283     {"",                  s_noTag,          false, TcapXApplication::None,              0},
4284 };
4285 
4286 static const Parameter s_locationInformationEPSSeq[] = {
4287     {"e-utranCellGlobalIdentity",   s_ctxtPrim_0_Tag, true, TcapXApplication::HexString,  0},
4288     {"trackingAreaIdentity",        s_ctxtPrim_1_Tag, true, TcapXApplication::HexString,  0},
4289     {"extensionContainer",          s_ctxtCstr_2_Tag, true, TcapXApplication::HexString,  0},
4290     {"geographicalInformation",     s_ctxtPrim_3_Tag, true, TcapXApplication::HexString,  0},
4291     {"geodeticInformation",         s_ctxtPrim_4_Tag, true, TcapXApplication::HexString,  0},
4292     {"currentLocationRetrieved",    s_ctxtPrim_5_Tag, true, TcapXApplication::Null,       0},
4293     {"ageOfLocationInformation",    s_ctxtPrim_6_Tag, true, TcapXApplication::Integer,    0},
4294     {"",                            s_noTag,          false,TcapXApplication::None,       0},
4295 };
4296 
4297 static const Parameter s_userCSGInformationSeq[] = {
4298     {"csg-Id",                s_ctxtPrim_0_Tag,  false, TcapXApplication::HexString,      0},
4299     {"extensionContainer",    s_ctxtCstr_1_Tag,  true,  TcapXApplication::HexString,      0},
4300     {"accessMode",            s_ctxtPrim_2_Tag,  true,  TcapXApplication::HexString,      0},
4301     {"cmi",                   s_ctxtPrim_3_Tag,  true,  TcapXApplication::HexString,      0},
4302     {"",                      s_noTag,           false, TcapXApplication::None,           0},
4303 };
4304 
4305 static const Parameter s_locationInformation[] = {
4306 // TS 100 974 v7.15.0 page 309
4307     {"ageOfLocationInformation", s_intTag,         true,   TcapXApplication::Integer,       0},
4308     {"geographicalInformation",  s_ctxtPrim_0_Tag, true,   TcapXApplication::HexString,     0},
4309     {"vlr-Number",               s_ctxtPrim_1_Tag, true,   TcapXApplication::AddressString, 0},
4310     {"locationNumber",           s_ctxtPrim_2_Tag, true,   TcapXApplication::HexString,     0},
4311     {"cellIdOrLAI",              s_ctxtCstr_3_Tag, true,   TcapXApplication::Choice,        s_cellIdOrLAI},
4312     {"extensionContainer",       s_ctxtCstr_4_Tag, true,   TcapXApplication::HexString,     0},
4313     {"selectedLSA-Id",           s_ctxtPrim_5_Tag, true,   TcapXApplication::HexString,     0},
4314     {"msc-Number",               s_ctxtPrim_6_Tag, true,   TcapXApplication::AddressString, 0},
4315     {"geodeticInformation",      s_ctxtPrim_7_Tag, true,   TcapXApplication::HexString,     0},
4316     {"currentLocationRetrieved", s_ctxtPrim_8_Tag, true,   TcapXApplication::Null,          0},
4317     {"sai-Present",              s_ctxtPrim_9_Tag, true,   TcapXApplication::Null,          0},
4318     {"locationInformationEPS",   s_ctxtCstr_10_Tag,true,   TcapXApplication::Sequence,      s_locationInformationEPSSeq},
4319     {"userCSGInformation",       s_ctxtCstr_11_Tag,true,   TcapXApplication::Sequence,      s_userCSGInformationSeq},
4320     {"",                         s_noTag,          false,  TcapXApplication::None,          0},
4321 };
4322 
4323 static const TokenDict s_notReachableReason[] = {
4324     {"msPurged",        0},
4325     {"imsiDetached",    1},
4326     {"restrictedArea",  2},
4327     {"notRegistered",   3},
4328     {0,0},
4329 };
4330 
4331 static const Parameter s_subscriberState[] = {
4332 // TS 100 974 v7.15.0 page 309
4333     {"assumedIdle",         s_ctxtPrim_0_Tag,   false, TcapXApplication::Null,       0},
4334     {"camelBusy",           s_ctxtPrim_1_Tag,   false, TcapXApplication::Null,       0},
4335     {"netDetNotReachable",  s_enumTag,          false, TcapXApplication::Enumerated, s_notReachableReason},
4336     {"notProvidedFromVLR",  s_ctxtPrim_2_Tag,   false, TcapXApplication::Null,       0},
4337     {"",                    s_noTag,            false, TcapXApplication::None,       0},
4338 };
4339 
4340 static const Parameter s_cellGlobalIdOrServiceAreaIdOrLAI[] = {
4341     {"cellGlobalIdOrServiceAreaIdFixedLength", s_ctxtPrim_0_Tag, false,  TcapXApplication::HexString,         0},
4342     {"laiFixedLength",                         s_ctxtPrim_1_Tag, false,  TcapXApplication::LAIFixedLength,    0},
4343     {"",                                       s_noTag,          false,  TcapXApplication::None,              0},
4344 };
4345 
4346 static const Parameter s_locationInformationGPRSSeq[] = {
4347     {"cellGlobalIdOrServiceAreaIdOrLAI", s_ctxtCstr_0_Tag,  true,  TcapXApplication::Choice,         s_cellGlobalIdOrServiceAreaIdOrLAI},
4348     {"routeingAreaIdentity",             s_ctxtPrim_1_Tag,  true,  TcapXApplication::HexString,      0},
4349     {"geographicalInformation",          s_ctxtPrim_2_Tag,  true,  TcapXApplication::HexString,      0},
4350     {"sgsn-Number",                      s_ctxtPrim_3_Tag,  true,  TcapXApplication::AddressString,  0},
4351     {"selectedLSAIdentity",              s_ctxtPrim_4_Tag,  true,  TcapXApplication::HexString,      0},
4352     {"extensionContainer",               s_ctxtCstr_5_Tag,  true,  TcapXApplication::HexString,      0},
4353     {"sai-Present",                      s_ctxtPrim_6_Tag,  true,  TcapXApplication::Null,           0},
4354     {"geodeticInformation",              s_ctxtPrim_7_Tag,  true,  TcapXApplication::HexString,      0},
4355     {"currentLocationRetrieved",         s_ctxtPrim_8_Tag,  true,  TcapXApplication::Null,           0},
4356     {"ageOfLocationInformation",         s_ctxtPrim_9_Tag,  true,  TcapXApplication::Integer,        0},
4357     {"userCSGInformation",               s_ctxtCstr_10_Tag, true,  TcapXApplication::Sequence,       s_userCSGInformationSeq},
4358     {"",                                 s_noTag,           false, TcapXApplication::None,           0},
4359 };
4360 
4361 static const Parameter s_PDP_ContextInfoSeq[] = {
4362     {"pdp-ContextIdentifier",    s_ctxtPrim_0_Tag,   false,  TcapXApplication::Integer,   0},
4363     {"pdp-ContextActive",        s_ctxtPrim_1_Tag,   true,   TcapXApplication::Null,      0},
4364     {"pdp-Type",                 s_ctxtPrim_2_Tag,   false,  TcapXApplication::HexString, 0},
4365     {"pdp-Address",              s_ctxtPrim_3_Tag,   true,   TcapXApplication::HexString, 0},
4366     {"apn-Subscribed",           s_ctxtPrim_4_Tag,   true,   TcapXApplication::HexString, 0},
4367     {"apn-InUse",                s_ctxtPrim_5_Tag,   true,   TcapXApplication::HexString, 0},
4368     {"nsapi",                    s_ctxtPrim_6_Tag,   true,   TcapXApplication::Integer,   0},
4369     {"transactionId",            s_ctxtPrim_7_Tag,   true,   TcapXApplication::HexString, 0},
4370     {"teid-ForGnAndGp",          s_ctxtPrim_8_Tag,   true,   TcapXApplication::HexString, 0},
4371     {"teid-ForIu",               s_ctxtPrim_9_Tag,   true,   TcapXApplication::HexString, 0},
4372     {"ggsn-Address",             s_ctxtPrim_10_Tag,  true,   TcapXApplication::HexString, 0},
4373     {"qos-Subscribed",           s_ctxtPrim_11_Tag,  true,   TcapXApplication::HexString, 0},
4374     {"qos-Requested",            s_ctxtPrim_12_Tag,  true,   TcapXApplication::HexString, 0},
4375     {"qos-Negotiated",           s_ctxtPrim_13_Tag,  true,   TcapXApplication::HexString, 0},
4376     {"chargingId",               s_ctxtPrim_14_Tag,  true,   TcapXApplication::HexString, 0},
4377     {"chargingCharacteristics",  s_ctxtPrim_15_Tag,  true,   TcapXApplication::HexString, 0},
4378     {"rnc-Address",              s_ctxtPrim_16_Tag,  true,   TcapXApplication::HexString, 0},
4379     {"extensionContainer",       s_ctxtCstr_17_Tag,  true,   TcapXApplication::HexString, 0},
4380     {"qos2-Subscribed",          s_ctxtPrim_18_Tag,  true,   TcapXApplication::HexString, 0},
4381     {"qos2-Requested",           s_ctxtPrim_19_Tag,  true,   TcapXApplication::HexString, 0},
4382     {"qos2-Negotiated",          s_ctxtPrim_20_Tag,  true,   TcapXApplication::HexString, 0},
4383     {"qos3-Subscribed",          s_ctxtPrim_21_Tag,  true,   TcapXApplication::HexString, 0},
4384     {"qos3-Requested",           s_ctxtPrim_22_Tag,  true,   TcapXApplication::HexString, 0},
4385     {"qos3-Negotiated",          s_ctxtPrim_23_Tag,  true,   TcapXApplication::HexString, 0},
4386     {"qos4-Subscribed",          s_ctxtPrim_25_Tag,  true,   TcapXApplication::HexString, 0},
4387     {"qos4-Requested",           s_ctxtPrim_26_Tag,  true,   TcapXApplication::HexString, 0},
4388     {"ext-pdp-Type",             s_ctxtPrim_28_Tag,  true,   TcapXApplication::HexString, 0},
4389     {"ext-pdp-Address",          s_ctxtPrim_29_Tag,  true,   TcapXApplication::HexString, 0},
4390     {"",                         s_noTag,            false,  TcapXApplication::None,      0},
4391 };
4392 
4393 
4394 static const Parameter s_PDP_ContextInfo[] = {
4395     {"PDP-ContextInfo",                  s_sequenceTag,     false, TcapXApplication::Sequence,       s_PDP_ContextInfoSeq},
4396     {"",                                 s_noTag,           false, TcapXApplication::None,           0},
4397 };
4398 
4399 static const Parameter s_PS_SubscriberStateChoice[] = {
4400     {"notProvidedFromSGSNorMME",          s_ctxtPrim_0_Tag,  false, TcapXApplication::Null,           0},
4401     {"ps-Detached",                       s_ctxtPrim_1_Tag,  false, TcapXApplication::Null,           0},
4402     {"ps-AttachedNotReachableForPaging",  s_ctxtPrim_2_Tag,  false, TcapXApplication::Null,           0},
4403     {"ps-AttachedReachableForPaging",     s_ctxtPrim_3_Tag,  false, TcapXApplication::Null,           0},
4404     {"ps-PDP-ActiveNotReachableForPaging",s_ctxtCstr_4_Tag,  false, TcapXApplication::SequenceOf,     s_PDP_ContextInfo},
4405     {"ps-PDP-ActiveReachableForPaging",   s_ctxtCstr_5_Tag,  false, TcapXApplication::SequenceOf,     s_PDP_ContextInfo},
4406     {"netDetNotReachable",                s_enumTag,         false, TcapXApplication::Enumerated,     s_notReachableReason},
4407     {"",                                  s_noTag,           false, TcapXApplication::None,           0},
4408 };
4409 
4410 static const Parameter s_GPRSMSClassSeq[] = {
4411     {"mSNetworkCapability",      s_ctxtPrim_0_Tag,  false,  TcapXApplication::HexString,  0},
4412     {"mSRadioAccessCapability",  s_ctxtPrim_1_Tag,  true,   TcapXApplication::HexString,  0},
4413     {"",                         s_noTag,           false,  TcapXApplication::None,       0},
4414 };
4415 
4416 static const TokenDict s_numberPortabilityStatus[] = {
4417     {"notKnownToBePorted",                    0},
4418     {"ownNumberPortedOut",                    1},
4419     {"foreignNumberPortedToForeignNetwork",   2},
4420     {"ownNumberNotPortedOut",                 4},
4421     {"foreignNumberPortedIn",                 5},
4422     {0,0}
4423 };
4424 
4425 static const Parameter s_MNPInfoResSeq[] = {
4426     {"routeingNumber",           s_ctxtPrim_0_Tag,  true,    TcapXApplication::TBCD,          0},
4427     {"imsi",                     s_ctxtPrim_1_Tag,  true,    TcapXApplication::TBCD,          0},
4428     {"msisdn",                   s_ctxtPrim_2_Tag,  true,    TcapXApplication::AddressString, 0},
4429     {"numberPortabilityStatus",  s_ctxtPrim_3_Tag,  true,    TcapXApplication::Enumerated,    s_numberPortabilityStatus},
4430     {"extensionContainer",       s_ctxtCstr_4_Tag,  true,    TcapXApplication::HexString,     0},
4431     {"",                         s_noTag,           false,   TcapXApplication::None,          0},
4432 };
4433 
4434 static const TokenDict s_IMS_VoiceOverPS_SessionsInd[] = {
4435     {"imsVoiceOverPS-SessionsNotSupported",   0},
4436     {"imsVoiceOverPS-SessionsSupported",      1},
4437     {0,0}
4438 };
4439 
4440 static const Parameter s_subscriberInfo[] = {
4441 // TS 100 974 v7.15.0 page 309
4442     {"locationInformation",               s_ctxtCstr_0_Tag, true, TcapXApplication::Sequence,  s_locationInformation},
4443     {"subscriberState",                   s_ctxtCstr_1_Tag, true, TcapXApplication::Choice,    s_subscriberState},
4444     {"extensionContainer",                s_ctxtCstr_2_Tag, true, TcapXApplication::HexString, 0},
4445     {"locationInformationGPRS",           s_ctxtCstr_3_Tag, true, TcapXApplication::Sequence,  s_locationInformationGPRSSeq},
4446     {"ps-SubscriberState",                s_ctxtCstr_4_Tag, true, TcapXApplication::Choice,    s_PS_SubscriberStateChoice},
4447     {"imei",                              s_ctxtPrim_5_Tag, true, TcapXApplication::TBCD,      0},
4448     {"ms-Classmark2",                     s_ctxtPrim_6_Tag, true, TcapXApplication::HexString, 0},
4449     {"gprs-MS-Class",                     s_ctxtCstr_7_Tag, true, TcapXApplication::Sequence,  s_GPRSMSClassSeq},
4450     {"mnpInfoRes",                        s_ctxtCstr_8_Tag, true, TcapXApplication::Sequence,  s_MNPInfoResSeq},
4451     {"imsVoiceOverPS-SessionsIndication", s_ctxtPrim_9_Tag, true, TcapXApplication::Enumerated,s_IMS_VoiceOverPS_SessionsInd},
4452     {"lastUE-ActivityTime",               s_ctxtPrim_10_Tag,true, TcapXApplication::HexString, 0},
4453     {"lastRAT-Type",                      s_ctxtPrim_11_Tag,true, TcapXApplication::Enumerated,s_used_RAT_Type},
4454     {"eps-SubscriberState",               s_ctxtCstr_12_Tag,true, TcapXApplication::Choice,    s_PS_SubscriberStateChoice},
4455     {"locationInformationEPS",            s_ctxtCstr_13_Tag,true, TcapXApplication::Sequence,  s_locationInformationEPSSeq},
4456     {"",                                  s_noTag,          false,TcapXApplication::None,      0},
4457 };
4458 
4459 static const TokenDict s_reportingState[] = {
4460     {"stopMonitoring",   0},
4461     {"startMonitoring",  1},
4462     {0,0}
4463 };
4464 
4465 static const TokenDict s_CCBSSubscriberStatus[] = {
4466     {"ccbsNotIdle",         0},
4467     {"ccbsIdle",            1},
4468     {"ccbsNotReachable",    2},
4469     {0,0}
4470 };
4471 
4472 static const Parameter s_eventReportData[] = {
4473 // TS 100 974 v7.15.0 page 315
4474     {"ccbs-SubscriberStatus",   s_ctxtPrim_0_Tag, true,  TcapXApplication::Enumerated,   s_CCBSSubscriberStatus},
4475     {"extensionContainer",      s_ctxtCstr_1_Tag, true,  TcapXApplication::HexString,    0},
4476     {"",                        s_noTag,          false, TcapXApplication::None,         0},
4477 };
4478 
4479 static const TokenDict s_monitoringMode[] = {
4480 // TS 100 974 v7.15.0 page 315
4481     {"a-side", 0},
4482     {"b-side", 1},
4483     {0,0}
4484 };
4485 static const TokenDict s_callOutcome[] = {
4486 // TS 100 974 v7.15.0 page 316
4487     {"success", 0},
4488     {"failure", 1},
4489     {"busy",    2},
4490     {0,0}
4491 };
4492 
4493 static const Parameter s_callReportData[] = {
4494 // TS 100 974 v7.15.0 page 315
4495     {"monitoringMode",          s_ctxtPrim_0_Tag,  true,    TcapXApplication::Enumerated,   s_monitoringMode},
4496     {"callOutcome",             s_ctxtPrim_1_Tag,  true,    TcapXApplication::Enumerated,   s_callOutcome},
4497     {"extensionContainer",      s_ctxtCstr_2_Tag,  true,    TcapXApplication::HexString,     0},
4498     {"",                        s_noTag,           false,   TcapXApplication::None,          0},
4499 };
4500 
4501 static const Parameter s_updateLocationArgs[] = {
4502     // update location args
4503     {"imsi",                        s_hexTag,          false,   TcapXApplication::TBCD,          0},
4504     {"msc-Number",                  s_ctxtPrim_1_Tag,  false,   TcapXApplication::AddressString, 0},
4505     {"vlr-Number",                  s_hexTag,          false,   TcapXApplication::AddressString, 0},
4506     {"lmsi",                        s_ctxtPrim_10_Tag, true,    TcapXApplication::HexString,     0},
4507     {"extensionContainer",          s_sequenceTag,     true,    TcapXApplication::HexString,     0},
4508     {"vlr-Capability",              s_ctxtCstr_6_Tag,  true,    TcapXApplication::Sequence,      s_vlrCapability},
4509     {"informPreviousNetworkEntity", s_ctxtPrim_11_Tag, true,    TcapXApplication::Null,          0},
4510     {"cs-LCS-NotSupportedByUE",     s_ctxtPrim_12_Tag, true,    TcapXApplication::Null,          0},
4511     {"v-gmlc-Address",              s_ctxtPrim_2_Tag,  true,    TcapXApplication::HexString,     0},
4512     {"add-info",                    s_ctxtCstr_13_Tag, true,    TcapXApplication::Sequence,      s_addInfoSeq},
4513     {"pagingArea",                  s_ctxtCstr_14_Tag, true,    TcapXApplication::SequenceOf,    s_locationAreaChoice},
4514     {"skipSubscriberDataUpdate",    s_ctxtPrim_15_Tag, true,    TcapXApplication::Null,          0},
4515     {"restorationIndicator",        s_ctxtPrim_16_Tag, true,    TcapXApplication::Null,          0},
4516     {"",                            s_noTag,           false,   TcapXApplication::None,          0},
4517 };
4518 
4519 static const Parameter s_updateLocationRes[] = {
4520     {"hlr-Number",        s_hexTag,         false,   TcapXApplication::AddressString,0},
4521     {"extensionContainer",s_sequenceTag,    true,    TcapXApplication::HexString,    0},
4522     {"add-Capability",    s_nullTag,        true,    TcapXApplication::Null,         0},
4523     {"pagingArea-Capability",s_ctxtPrim_0_Tag, true, TcapXApplication::Null,         0},
4524     {"",                  s_noTag,          false,   TcapXApplication::None,         0},
4525 };
4526 
4527 static const Parameter s_cancelLocationArgs[] = {
4528     {"identity",          s_noTag,          false,    TcapXApplication::Choice,       s_mapIdentity},
4529     {"cancellationType",  s_enumTag,        true,     TcapXApplication::Enumerated,   s_cancellationType},
4530     {"extensionContainer",s_sequenceTag,    true,     TcapXApplication::HexString,    0},
4531     {"typeOfUpdate",      s_ctxtPrim_0_Tag, true,     TcapXApplication::Enumerated,   s_typeOfUpdate},
4532     {"",                  s_noTag,          false,    TcapXApplication::None,         0},
4533 };
4534 
4535 static const Parameter s_extensionContainerRes[] = {
4536     {"extensionContainer",s_sequenceTag,    true,     TcapXApplication::HexString,     0},
4537     {"",                  s_noTag,          false,    TcapXApplication::None,          0},
4538 };
4539 
4540 static const Parameter s_provideRoamingNumberArgs[] = {
4541     {"imsi",                      s_ctxtPrim_0_Tag,    false,   TcapXApplication::TBCD,             0},
4542     {"msc-Number",                s_ctxtPrim_1_Tag,    false,   TcapXApplication::AddressString,    0},
4543     {"msisdn",                    s_ctxtPrim_2_Tag,    true,    TcapXApplication::AddressString,    0},
4544     {"lmsi",                      s_ctxtPrim_4_Tag,    true,    TcapXApplication::HexString,        0},
4545     {"gsm-BearerCapability",      s_ctxtCstr_5_Tag,    true,    TcapXApplication::Sequence,         s_externalSignalInfo},
4546     {"networkSignalInfo",         s_ctxtCstr_6_Tag,    true,    TcapXApplication::Sequence,         s_externalSignalInfo},
4547     {"suppressionOfAnnouncement", s_ctxtPrim_7_Tag,    true,    TcapXApplication::Null,             0},
4548     {"gmsc-Address",              s_ctxtPrim_8_Tag,    true,    TcapXApplication::AddressString,    0},
4549     {"callReferenceNumber",       s_ctxtPrim_9_Tag,    true,    TcapXApplication::HexString,        0},
4550     {"or-Interrogation",          s_ctxtPrim_10_Tag,   true,    TcapXApplication::Null,             0},
4551     {"extensionContainer",        s_ctxtCstr_11_Tag,   true,    TcapXApplication::HexString,        0},
4552     {"alertingPattern",           s_ctxtPrim_12_Tag,   true,    TcapXApplication::Enumerated,       s_alertPattern},
4553     {"ccbs-Call",                 s_ctxtPrim_13_Tag,   true,    TcapXApplication::Null,             0},
4554     {"supportedCamelPhasesInGMSC",s_ctxtPrim_15_Tag,   true,    TcapXApplication::BitString,        s_camelPhases},
4555     {"additionalSignalInfo",      s_ctxtCstr_14_Tag,   true,    TcapXApplication::Sequence,         s_extExtenalSignalInfo},
4556     {"orNotSupportedInGMSC",      s_ctxtPrim_16_Tag,   true,    TcapXApplication::Null,             0},
4557     {"pre-pagingSupported",       s_ctxtPrim_17_Tag,   true,    TcapXApplication::Null,             0},
4558     {"longFTN-Supported",         s_ctxtPrim_18_Tag,   true,    TcapXApplication::Null,             0},
4559     {"suppress-VT-CSI",           s_ctxtPrim_19_Tag,   true,    TcapXApplication::Null,             0},
4560     {"offeredCamel4CSIsInInterrogatingNode", s_ctxtPrim_20_Tag, true, TcapXApplication::BitString,  s_offeredCamel4CSIs},
4561     {"mtRoamingRetrySupported",   s_ctxtPrim_21_Tag,   true,    TcapXApplication::Null,             0},
4562     {"pagingArea",                s_ctxtCstr_22_Tag,   true,    TcapXApplication::SequenceOf,       s_locationAreaChoice},
4563     {"callPriority",              s_ctxtPrim_23_Tag,   true,    TcapXApplication::Enumerated,       s_EMLPPPriority},
4564     {"",                          s_noTag,             false,   TcapXApplication::None,             0},
4565 };
4566 
4567 static const Parameter s_provideRoamingNumberRes[] = {
4568     {"roamingNumber",             s_hexTag,         false,TcapXApplication::AddressString,  0},
4569     {"extensionContainer",        s_sequenceTag,    true, TcapXApplication::HexString,      0},
4570     {"releaseResourcesSupported", s_nullTag,        true, TcapXApplication::Null,           0},
4571     {"",                          s_noTag,          false,TcapXApplication::None,           0},
4572 };
4573 
4574 static const Parameter s_insertSubscriberDataArgs[] = {
4575     {"imsi",                                           s_ctxtPrim_0_Tag,  true,   TcapXApplication::TBCD,         0},
4576     {"msisdn",                                         s_ctxtPrim_1_Tag,  true,   TcapXApplication::AddressString,0},
4577     {"category",                                       s_ctxtPrim_2_Tag,  true,   TcapXApplication::Enumerated,   s_category},
4578     {"subscriberStatus",                               s_ctxtPrim_3_Tag,  true,   TcapXApplication::Enumerated,   s_subscriberStatus},
4579     {"bearerServiceList",                              s_ctxtCstr_4_Tag,  true,   TcapXApplication::SequenceOf,   s_bearerService},
4580     {"teleserviceList",                                s_ctxtCstr_6_Tag,  true,   TcapXApplication::SequenceOf,   s_teleservice},
4581     {"provisionedSS",                                  s_ctxtCstr_7_Tag,  true,   TcapXApplication::SequenceOf,   s_extSSInfo},
4582     {"odb-Data",                                       s_ctxtCstr_8_Tag,  true,   TcapXApplication::Sequence,     s_odbData},
4583     {"roamingRestrictionDueToUnsupportedFeature",      s_ctxtPrim_9_Tag,  true,   TcapXApplication::Null,         0},
4584     {"regionalSubscriptionData",                       s_ctxtCstr_10_Tag, true,   TcapXApplication::SequenceOf,   s_zoneCode},
4585     {"vbsSubscriptionData",                            s_ctxtCstr_11_Tag, true,   TcapXApplication::SequenceOf,   s_voiceBroadcastData},
4586     {"vgcsSubscriptionData",                           s_ctxtCstr_12_Tag, true,   TcapXApplication::SequenceOf,   s_voiceGroupCallData},
4587     {"vlrCamelSubscriptionInfo",                       s_ctxtCstr_13_Tag, true,   TcapXApplication::Sequence,     s_VlrCamelSubscriptionInfo},
4588     {"extensionContainer",                             s_ctxtCstr_14_Tag, true,   TcapXApplication::HexString,     0},
4589     {"naea-PreferredCI",                               s_ctxtCstr_15_Tag, true,   TcapXApplication::Sequence,     s_naeaPreferredCI},
4590     {"gprsSubscriptionData",                           s_ctxtCstr_16_Tag, true,   TcapXApplication::Sequence,     s_GPRSSubscriptionData},
4591     {"roamingRestrictedInSgsnDueToUnsupportedFeature", s_ctxtPrim_23_Tag, true,   TcapXApplication::Null,         0},
4592     {"networkAccessMode",                              s_ctxtPrim_24_Tag, true,   TcapXApplication::Enumerated,   s_networkAccessMode},
4593     {"lsaInformation",                                 s_ctxtCstr_25_Tag, true,   TcapXApplication::Sequence,     s_LSAInformation},
4594     {"lmu-Indicator",                                  s_ctxtPrim_21_Tag, true,   TcapXApplication::Null,         0},
4595     {"lcsInformation",                                 s_ctxtCstr_22_Tag, true,   TcapXApplication::Sequence,     s_LCSInformation},
4596     {"istAlertTimer",                                  s_ctxtPrim_26_Tag, true,   TcapXApplication::Integer,      0},
4597     {"superChargerSupportedInHLR",                     s_ctxtPrim_27_Tag, true,   TcapXApplication::HexString,    0},
4598     {"mc-SS-Info",                                     s_ctxtCstr_28_Tag, true,   TcapXApplication::Sequence,     s_MC_SSInfo},
4599     {"cs-AllocationRetentionPriority",                 s_ctxtPrim_29_Tag, true,   TcapXApplication::HexString,    0},
4600     {"sgsn-CAMEL-SubscriptionInfo",                    s_ctxtCstr_17_Tag, true,   TcapXApplication::Sequence,     s_SGSN_CAMELSubscriptionInfoSeq},
4601     {"chargingCharacteristics",                        s_ctxtPrim_18_Tag, true,   TcapXApplication::HexString,    0},
4602     {"accessRestrictionData",                          s_ctxtPrim_19_Tag, true,   TcapXApplication::BitString,    s_accessRestrictionData},
4603     {"ics-Indicator",                                  s_ctxtPrim_20_Tag, true,   TcapXApplication::Bool,         0},
4604     {"eps-SubscriptionData",                           s_ctxtCstr_31_Tag, true,   TcapXApplication::Sequence,     s_EPS_SubscriptionData},
4605     {"csg-SubscriptionDataList",                       s_ctxtCstr_32_Tag, true,   TcapXApplication::SequenceOf,   s_CSG_SubscriptionData},
4606     {"ue-ReachabilityRequestIndicator",                s_ctxtPrim_33_Tag, true,   TcapXApplication::Null,         0},
4607     {"sgsn-Number",                                    s_ctxtPrim_34_Tag, true,   TcapXApplication::AddressString,0},
4608     {"mme-Name",                                       s_ctxtPrim_35_Tag, true,   TcapXApplication::HexString,    0},
4609     {"",                                               s_noTag,           false,  TcapXApplication::None,         0},
4610 };
4611 
4612 static const Parameter s_insertSubscriberDataRes[] = {
4613     {"teleserviceList",             s_ctxtCstr_1_Tag,  true,     TcapXApplication::SequenceOf,   s_teleservice},
4614     {"bearerServiceList",           s_ctxtCstr_2_Tag,  true,     TcapXApplication::SequenceOf,   s_bearerService},
4615     {"ss-List",                     s_ctxtCstr_3_Tag,  true,     TcapXApplication::SequenceOf,   s_ssCode},
4616     {"odb-GeneralData",             s_ctxtPrim_4_Tag,  true,     TcapXApplication::BitString,    s_odbGeneralData},
4617     {"regionalSubscriptionResponse",s_ctxtPrim_5_Tag,  true,     TcapXApplication::Enumerated,   s_regionalSubscriptionResponse},
4618     {"supportedCamelPhases",        s_ctxtPrim_6_Tag,  true,     TcapXApplication::BitString,    s_camelPhases},
4619     {"extensionContainer",          s_ctxtCstr_7_Tag,  true,     TcapXApplication::HexString,    0},
4620     {"offeredCamel4CSIs",           s_ctxtPrim_8_Tag,  true,     TcapXApplication::BitString,    s_offeredCamel4CSIs},
4621     {"supportedFeatures",           s_ctxtPrim_9_Tag,  true,     TcapXApplication::BitString,    s_supportedFeatures},
4622     {"",                            s_noTag,           false,    TcapXApplication::None,         0},
4623 };
4624 
4625 static const Parameter s_deleteSubscriberDataArgs[] = {
4626     {"imsi",                                            s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD,       0},
4627     {"basicServiceList",                                s_ctxtCstr_1_Tag, true,  TcapXApplication::SequenceOf, s_basicServiceCodeType},
4628     {"ss-List",                                         s_ctxtCstr_2_Tag, true,  TcapXApplication::SequenceOf, s_ssCode},
4629     {"roamingRestrictionDueToUnsupportedFeature",       s_ctxtPrim_4_Tag, true,  TcapXApplication::Null,       0},
4630     {"regionalSubscriptionIdentifier",                  s_ctxtPrim_5_Tag, true,  TcapXApplication::HexString,  0},
4631     {"vbsGroupIndication",                              s_ctxtPrim_7_Tag, true,  TcapXApplication::Null,       0},
4632     {"vgcsGroupIndication",                             s_ctxtPrim_8_Tag, true,  TcapXApplication::Null,       0},
4633     {"camelSubscriptionInfoWithdraw",                   s_ctxtPrim_9_Tag, true,  TcapXApplication::Null,       0},
4634     {"extensionContainer",                              s_ctxtCstr_6_Tag, true,  TcapXApplication::HexString,  0},
4635     {"gprsSubscriptionDataWithdraw",                    s_ctxtCstr_10_Tag,true,  TcapXApplication::Choice,     s_GPRSSubscriptionDataWithdraw},
4636     {"roamingRestrictedInSgsnDueToUnsuppportedFeature", s_ctxtPrim_11_Tag,true,  TcapXApplication::Null,       0},
4637     {"lsaInformationWithdraw",                          s_ctxtCstr_12_Tag,true,  TcapXApplication::Choice,     s_LSAInformationWithdraw},
4638     {"gmlc-ListWithdraw",                               s_ctxtPrim_13_Tag,true,  TcapXApplication::Null,       0},
4639     {"istInformationWithdraw",                          s_ctxtPrim_14_Tag,true,  TcapXApplication::Null,       0},
4640     {"specificCSI-Withdraw",                            s_ctxtPrim_15_Tag,true,  TcapXApplication::BitString,  s_specificCSI_Withdraw},
4641     {"chargingCharacteristicsWithdraw",                 s_ctxtPrim_16_Tag,true,  TcapXApplication::Null,       0},
4642     {"stn-srWithdraw",                                  s_ctxtPrim_17_Tag,true,  TcapXApplication::Null,       0},
4643     {"epsSubscriptionDataWithdraw",                     s_ctxtCstr_18_Tag,true,  TcapXApplication::Choice,     s_EPS_SubscriptionDataWithdraw},
4644     {"apn-oi-replacementWithdraw",                      s_ctxtPrim_19_Tag,true,  TcapXApplication::Null,       0},
4645     {"csg-SubscriptionDeleted",                         s_ctxtPrim_20_Tag,true,  TcapXApplication::Null,       0},
4646     {"",                                                s_noTag,          false, TcapXApplication::None,       0},
4647 };
4648 
4649 static const Parameter s_deleteSubscriberDataRes[] = {
4650     {"regionalSubscriptionResponse", s_ctxtPrim_0_Tag,  true, TcapXApplication::Enumerated,   s_regionalSubscriptionResponse},
4651     {"extensionContainer",           s_sequenceTag,     true, TcapXApplication::HexString,    0},
4652     {"",                             s_noTag,           false,TcapXApplication::None,         0},
4653 };
4654 
4655 // GSM 09.02 v5.3.0 page 721
4656 static const Parameter s_subscriberId[] = {
4657     {"imsi",     s_ctxtPrim_0_Tag,    false,   TcapXApplication::TBCD,       0},
4658     {"tmsi",     s_ctxtPrim_1_Tag,    false,   TcapXApplication::HexString,  0},
4659     {"",         s_noTag,             false,   TcapXApplication::None,       0},
4660 };
4661 
4662 // GSM 09.02 v5.3.0 page 721
4663 static const TokenDict s_requestParamEnum[] = {
4664     {"requestIMSI",               0},
4665     {"requestAuthenticationSet",  1},
4666     {"requestSubscriberData",     2},
4667     {"requestKi",                 4},
4668     {0,0}
4669 };
4670 
4671 // GSM 09.02 v5.3.0 page 721
4672 static const Parameter s_requestParameter[] = {
4673     {"requestParameter",  s_enumTag,  true, TcapXApplication::Enumerated, s_requestParamEnum},
4674     {"",                  s_noTag,   false, TcapXApplication::None,       0},
4675 };
4676 
4677 // GSM 09.02 v5.3.0 pp 721-723
4678 static const Parameter s_sentParameterChoice[] = {
4679     {"imsi",               s_ctxtPrim_0_Tag,  true,  TcapXApplication::TBCD,       0},
4680     {"authenticationSet",  s_ctxtCstr_1_Tag,  true,  TcapXApplication::Sequence,   s_authenticationSetSeq},
4681     {"subscriberData",     s_ctxtCstr_2_Tag,  true,  TcapXApplication::Sequence,   s_insertSubscriberDataArgs},
4682     {"ki",                 s_ctxtPrim_3_Tag,  true,  TcapXApplication::HexString,  0},
4683     {"",                   s_noTag,          false,  TcapXApplication::None,       0},
4684 };
4685 
4686 // GSM 09.02 v5.3.0 pp 721-723
4687 static const Parameter s_sentParameterList[] = {
4688     {"sentParameter",  s_noTag,  false,  TcapXApplication::Choice,  s_sentParameterChoice},
4689     {"",               s_noTag,  false,  TcapXApplication::None,    0},
4690 };
4691 
4692 // GSM 09.02 v5.3.0 page 721
4693 static const Parameter s_sendParametersDataArgs[] = {
4694     {"subscriberId",         s_noTag,        false,  TcapXApplication::Choice,      s_subscriberId},
4695     {"requestParameterList", s_sequenceTag,  false,  TcapXApplication::SequenceOf,  s_requestParameter},
4696     {"",                     s_noTag,        false,  TcapXApplication::None,        0},
4697 };
4698 
4699 // GSM 09.02 v5.3.0 pp. 721
4700 static const Parameter s_sendParametersDataRes[] = {
4701     {"sentParameterList",  s_sequenceTag,  false,  TcapXApplication::SequenceOf,  s_sentParameterList},
4702     {"",                   s_noTag,        false,  TcapXApplication::None,        0},
4703 };
4704 
4705 static const Parameter s_registerSSArgs[] = {
4706     {"ss-Code",                  s_hexTag,           false,  TcapXApplication::Enumerated,           s_SSCode},
4707     {"basicService",             s_noTag,            true,   TcapXApplication::Choice,               s_basicServiceCode},
4708     {"forwardedToNumber",        s_ctxtPrim_4_Tag,   true,   TcapXApplication::AddressString,        0},
4709     {"forwardedToSubaddress",    s_ctxtPrim_6_Tag,   true,   TcapXApplication::HexString,            0},
4710     {"noReplyConditionTime",     s_ctxtPrim_5_Tag,   true,   TcapXApplication::Integer,              0},
4711     {"defaultPriority",          s_ctxtPrim_7_Tag,   true,   TcapXApplication::Enumerated,           s_EMLPPPriority},
4712     {"nbrUser",                  s_ctxtPrim_8_Tag,   true,   TcapXApplication::Integer,              0},
4713     {"longFTN-Supported",        s_ctxtPrim_9_Tag,   true,   TcapXApplication::Null,                 0},
4714     {"",                         s_noTag,            false,  TcapXApplication::None,                 0},
4715 };
4716 
4717 static const Parameter s_ssInfoRes[] = {
4718     {"ss-Info",                  s_noTag,    false,   TcapXApplication::Choice,    s_extSSInfoChoice},
4719     {"",                         s_noTag,    false,   TcapXApplication::None,      0},
4720 };
4721 
4722 static const Parameter s_ssCodeArgs[] = {
4723     {"ss-Code",                  s_hexTag,         false,  TcapXApplication::Enumerated,  s_SSCode},
4724     {"basicService",             s_noTag,          true,   TcapXApplication::Choice,      s_basicServiceCode},
4725     {"longFTN-Supported",        s_ctxtPrim_4_Tag, true,   TcapXApplication::Null,        0},
4726     {"",                         s_noTag,          false,  TcapXApplication::None,        0},
4727 };
4728 
4729 static const Parameter s_authFailureArgs[] = {
4730     {"imsi",               s_hexTag,          false,   TcapXApplication::TBCD,            0},
4731     {"failureCause",       s_enumTag,         false,   TcapXApplication::Enumerated,      s_failureCauseEnum},
4732     {"extensionContainer", s_sequenceTag,     true,    TcapXApplication::HexString,       0},
4733     {"re-attempt",         s_boolTag,         true,    TcapXApplication::Bool,            0},
4734     {"accessType",         s_enumTag,         true,    TcapXApplication::Enumerated,      s_accessTypeEnum},
4735     {"rand",               s_hexTag,          true,    TcapXApplication::HexString,       0},
4736     {"vlr-Number",         s_ctxtPrim_0_Tag,  true,    TcapXApplication::AddressString,   0},
4737     {"sgsn-Number",        s_ctxtPrim_1_Tag,  true,    TcapXApplication::AddressString,   0},
4738     {"",                   s_noTag,           false,   TcapXApplication::None,            0},
4739 };
4740 
4741 static const Parameter s_registerPasswordArgs[] = {
4742     {"ss-Code",                  s_hexTag, false, TcapXApplication::Enumerated,  s_SSCode},
4743     {"",                         s_noTag,  false, TcapXApplication::None,        0},
4744 };
4745 
4746 static const Parameter s_registerPasswordRes[] = {
4747     {"newPassword",              s_numStrTag, false, TcapXApplication::AppString, 0},
4748     {"",                         s_noTag,     false, TcapXApplication::None,      0},
4749 };
4750 
4751 static const Parameter s_getPasswordArgs[] = {
4752     {"guidanceInfo",             s_enumTag, false, TcapXApplication::Enumerated,  s_guidanceInfo},
4753     {"",                         s_noTag,   false, TcapXApplication::None,        0},
4754 };
4755 
4756 static const Parameter s_getPasswordRes[] = {
4757     {"currentPassword",          s_numStrTag, false, TcapXApplication::AppString, 0},
4758     {"",                         s_noTag,     false, TcapXApplication::None,      0},
4759 };
4760 
4761 static const Parameter s_updateGprsLocationArgs[] = {
4762     {"imsi",                            s_hexTag,          false,   TcapXApplication::TBCD,           0},
4763     {"sgsn-Number",                     s_hexTag,          false,   TcapXApplication::AddressString,  0},
4764     {"sgsn-Address",                    s_hexTag,          false,   TcapXApplication::HexString,      0},
4765     {"extensionContainer",              s_sequenceTag,     true,    TcapXApplication::HexString,      0},
4766     {"sgsn-Capability",                 s_ctxtCstr_0_Tag,  true,    TcapXApplication::Sequence,       s_SGSN_CapabilitySeq},
4767     {"informPreviousNetworkEntity",     s_ctxtPrim_1_Tag,  true,    TcapXApplication::Null,           0},
4768     {"ps-LCS-NotSupportedByUE",         s_ctxtPrim_2_Tag,  true,    TcapXApplication::Null,           0},
4769     {"v-gmlc-Address",                  s_ctxtPrim_3_Tag,  true,    TcapXApplication::HexString,      0},
4770     {"add-info",                        s_ctxtCstr_4_Tag,  true,    TcapXApplication::Sequence,       s_addInfoSeq},
4771     {"eps-info",                        s_ctxtCstr_5_Tag,  true,    TcapXApplication::Choice,         s_EPS_InfoChoice},
4772     {"servingNodeTypeIndicator",        s_ctxtPrim_6_Tag,  true,    TcapXApplication::Null,           0},
4773     {"skipSubscriberDataUpdate",        s_ctxtPrim_7_Tag,  true,    TcapXApplication::Null,           0},
4774     {"usedRAT-Type",                    s_ctxtPrim_8_Tag,  true,    TcapXApplication::Enumerated,     s_used_RAT_Type},
4775     {"gprsSubscriptionDataNotNeeded",   s_ctxtPrim_9_Tag,  true,    TcapXApplication::Null,           0},
4776     {"nodeTypeIndicator",               s_ctxtPrim_10_Tag, true,    TcapXApplication::Null,           0},
4777     {"areaRestricted",                  s_ctxtPrim_11_Tag, true,    TcapXApplication::Null,           0},
4778     {"ue-reachableIndicator",           s_ctxtPrim_12_Tag, true,    TcapXApplication::Null,           0},
4779     {"epsSubscriptionDataNotNeeded",    s_ctxtPrim_13_Tag, true,    TcapXApplication::Null,           0},
4780     {"",                                s_noTag,           false,   TcapXApplication::None,           0},
4781 };
4782 
4783 static const Parameter s_updateGprsLocationRes[] = {
4784     {"hlr-Number",                     s_hexTag,         false,   TcapXApplication::AddressString,  0},
4785     {"extensionContainer",             s_sequenceTag,    true,    TcapXApplication::HexString,      0},
4786     {"add-Capability",                 s_nullTag,        true,    TcapXApplication::Null,           0},
4787     {"sgsn-mmeSeparationSupported",    s_ctxtPrim_0_Tag, true,    TcapXApplication::Null,           0},
4788     {"",                               s_noTag,          false ,  TcapXApplication::None,           0},
4789 };
4790 
4791 static const Parameter s_sendRoutingInfoForGprsArgs[] = {
4792     {"imsi",              s_ctxtPrim_0_Tag,    false,   TcapXApplication::TBCD,           0},
4793     {"ggsn-Address",      s_ctxtPrim_1_Tag,    true,    TcapXApplication::HexString,      0},
4794     {"ggsn-Number",       s_ctxtPrim_2_Tag,    false,   TcapXApplication::AddressString,  0},
4795     {"extensionContainer",s_ctxtCstr_3_Tag,    true,    TcapXApplication::HexString,      0},
4796     {"",                  s_noTag,             false,   TcapXApplication::None,           0},
4797 };
4798 
4799 static const Parameter s_sendRoutingInfoForGprsRes[] = {
4800     {"sgsn-Address",                    s_ctxtPrim_0_Tag,    false,   TcapXApplication::HexString,     0},
4801     {"ggsn-Address",                    s_ctxtPrim_1_Tag,    true,    TcapXApplication::HexString,     0},
4802     {"mobileNotReachableReason",        s_ctxtPrim_2_Tag,    true,    TcapXApplication::Integer,       0},
4803     {"extensionContainer",              s_ctxtCstr_3_Tag,    true,    TcapXApplication::HexString,     0},
4804     {"",                                s_noTag,             false,   TcapXApplication::None,          0},
4805 };
4806 
4807 static const Parameter s_failureReportArgs[] = {
4808     {"imsi",              s_ctxtPrim_0_Tag,    false,   TcapXApplication::TBCD,          0},
4809     {"ggsn-Number",       s_ctxtPrim_1_Tag,    false,   TcapXApplication::AddressString, 0},
4810     {"ggsn-Address",      s_ctxtPrim_2_Tag,    true,    TcapXApplication::HexString,     0},
4811     {"extensionContainer",s_ctxtCstr_3_Tag,    true,    TcapXApplication::HexString,     0},
4812     {"",                  s_noTag,             false,   TcapXApplication::None,          0},
4813 };
4814 
4815 static const Parameter s_failureReportRes[] = {
4816     {"ggsn-Address",      s_ctxtPrim_0_Tag,    true,    TcapXApplication::HexString,      0},
4817     {"extensionContainer",s_ctxtCstr_1_Tag,    true,    TcapXApplication::HexString,      0},
4818     {"",                  s_noTag,             false,   TcapXApplication::None,           0},
4819 };
4820 
4821 static const Parameter s_resetArgs[] = {
4822     {"hlr-Number",        s_hexTag,         false,   TcapXApplication::AddressString,     0},
4823     {"hlr-List",          s_sequenceTag,    true,    TcapXApplication::SequenceOf,        s_hlrId},
4824     {"",                  s_noTag,          false,   TcapXApplication::None,              0},
4825 };
4826 
4827 static const Parameter s_sendRoutingInfoForSMArgs[] = {
4828     {"msisdn",                 s_ctxtPrim_0_Tag,  false,   TcapXApplication::AddressString,    0},
4829     {"sm-RP-PRI",              s_ctxtPrim_1_Tag,  false,   TcapXApplication::Bool,             0},
4830     {"serviceCentreAddress",   s_ctxtPrim_2_Tag,  false,   TcapXApplication::AddressString,    0},
4831     {"extensionContainer",     s_ctxtCstr_6_Tag,  true,    TcapXApplication::HexString,        0},
4832     {"gprsSupportIndicator",   s_ctxtPrim_7_Tag,  true,    TcapXApplication::Null,             0},
4833     {"sm-RP-MTI",              s_ctxtPrim_8_Tag,  true,    TcapXApplication::Integer,          0},
4834     {"sm-RP-SMEA",             s_ctxtPrim_9_Tag,  true,    TcapXApplication::HexString,        0},
4835     {"sm-deliveryNotIntended", s_ctxtPrim_10_Tag, true,    TcapXApplication::Enumerated,       s_SM_DeliveryNotIntended},
4836     {"",                       s_noTag,           false,   TcapXApplication::None,             0},
4837 };
4838 
4839 static const Parameter s_sendRoutingInfoForSMRes[] = {
4840     {"imsi",                   s_hexTag,          false,   TcapXApplication::TBCD,           0},
4841     {"locationInfoWithLMSI",   s_ctxtCstr_0_Tag,  false,   TcapXApplication::Sequence,       s_locationInfoWithLMSI},
4842     {"extensionContainer",     s_ctxtCstr_4_Tag,  true,    TcapXApplication::HexString,      0},
4843     {"",                       s_noTag,           false,   TcapXApplication::None,           0},
4844 };
4845 
4846 static const Parameter s_smRpDa[] = {
4847     {"imsi",                   s_ctxtPrim_0_Tag,  false,   TcapXApplication::TBCD,           0},
4848     {"lmsi",                   s_ctxtPrim_1_Tag,  false,   TcapXApplication::HexString,      0},
4849     {"serviceCentreAddressDA", s_ctxtPrim_4_Tag,  false,   TcapXApplication::AddressString,  0},
4850     {"noSM-RP-DA",             s_ctxtPrim_5_Tag,  false,   TcapXApplication::Null,           0},
4851     {"",                       s_noTag,           false,   TcapXApplication::None,           0},
4852 };
4853 
4854 static const Parameter s_smRpOa[] = {
4855     {"msisdn",                 s_ctxtPrim_2_Tag,  false,   TcapXApplication::AddressString,  0},
4856     {"serviceCentreAddressOA", s_ctxtPrim_4_Tag,  false,   TcapXApplication::AddressString,  0},
4857     {"noSM-RP-OA",             s_ctxtPrim_5_Tag,  false,   TcapXApplication::Null,           0},
4858     {"",                       s_noTag,           false,   TcapXApplication::None,           0},
4859 };
4860 
4861 static const Parameter s_mtForwardSMArgs[] = {
4862     {"sm-RP-DA",               s_noTag,           false,   TcapXApplication::Choice,         s_smRpDa},
4863     {"sm-RP-OA",               s_noTag,           false,   TcapXApplication::Choice,         s_smRpOa},
4864     {"sm-RP-UI",               s_hexTag,          false,   TcapXApplication::HexString,      0},
4865     {"extensionContainer",     s_sequenceTag,     true,    TcapXApplication::HexString,      0},
4866     {"",                       s_noTag,           false,   TcapXApplication::None,           0},
4867 };
4868 
4869 static const Parameter s_moForwardSMArgs[] = {
4870     {"sm-RP-DA",               s_noTag,           false,   TcapXApplication::Choice,         s_smRpDa},
4871     {"sm-RP-OA",               s_noTag,           false,   TcapXApplication::Choice,         s_smRpOa},
4872     {"sm-RP-UI",               s_hexTag,          false,   TcapXApplication::HexString,      0},
4873     {"moreMessagesToSend",     s_nullTag,         true,    TcapXApplication::Null,           0},
4874     {"extensionContainer",     s_sequenceTag,     true,    TcapXApplication::HexString,      0},
4875     {"imsi",                   s_hexTag,          true,    TcapXApplication::TBCD,           0},
4876     {"",                       s_noTag,           false,   TcapXApplication::None,           0},
4877 };
4878 
4879 static const Parameter s_forwardSMRes[] = {
4880     {"sm-RP-UI",               s_hexTag,          true,    TcapXApplication::HexString,      0},
4881     {"extensionContainer",     s_sequenceTag,     true,    TcapXApplication::HexString,      0},
4882     {"",                       s_noTag,           false,   TcapXApplication::None,           0},
4883 };
4884 
4885 static const Parameter s_forwardSMArgs[] = {
4886     {"sm-RP-DA",               s_noTag,           false,   TcapXApplication::Choice,         s_smRpDa},
4887     {"sm-RP-OA",               s_noTag,           false,   TcapXApplication::Choice,         s_smRpOa},
4888     {"sm-RP-UI",               s_hexTag,          false,   TcapXApplication::HexString,      0},
4889     {"moreMessagesToSend",     s_nullTag,         true,    TcapXApplication::Null,           0},
4890     {"",                       s_noTag,           false,   TcapXApplication::None,           0},
4891 };
4892 
4893 static const TokenDict s_SMDeliveryOutcomeEnum[] = {
4894     {"memoryCapacityExceeded", 0},
4895     {"absentSubscriber",       1},
4896     {"successfulTransfer",     2},
4897     {0,0}
4898 };
4899 
4900 static const Parameter s_reportSMDeliveryArgs[] = {
4901     {"msisdn",                                  s_hexTag,         false, TcapXApplication::AddressString, 0},
4902     {"serviceCentreAddress",                    s_hexTag,         false, TcapXApplication::AddressString, 0},
4903     {"sm-DeliveryOutcome",                      s_enumTag,        false, TcapXApplication::Enumerated,    s_SMDeliveryOutcomeEnum},
4904     {"absentSubscriberDiagnosticSM",            s_ctxtPrim_0_Tag, true,  TcapXApplication::Integer,       0},
4905     {"extensionContainer",                      s_ctxtCstr_1_Tag, true,  TcapXApplication::HexString,     0},
4906     {"gprsSupportIndicator",                    s_ctxtPrim_2_Tag, true,  TcapXApplication::Null,          0},
4907     {"deliveryOutcomeIndicator",                s_ctxtPrim_3_Tag, true,  TcapXApplication::Null,          0},
4908     {"additionalSM-DeliveryOutcome",            s_ctxtPrim_4_Tag, true,  TcapXApplication::Enumerated,    s_SMDeliveryOutcomeEnum},
4909     {"additionalAbsentSubscriberDiagnosticSM",  s_ctxtPrim_5_Tag, true,  TcapXApplication::Integer,       0},
4910     {"ip-sm-gw-Indicator",                      s_ctxtPrim_6_Tag, true,  TcapXApplication::Null,          0},
4911     {"ip-sm-gw-sm-deliveryOutcome",             s_ctxtPrim_7_Tag, true,  TcapXApplication::Enumerated,    s_SMDeliveryOutcomeEnum},
4912     {"ip-sm-gw-absentSubscriberDiagnosticSM",   s_ctxtPrim_8_Tag, true,  TcapXApplication::Integer,       0},
4913     {"",                                        s_noTag,          false, TcapXApplication::None,          0},
4914 };
4915 
4916 static const Parameter s_reportSMDeliveryRes[] = {
4917     { "storedMSISDN",       s_hexTag,      true,  TcapXApplication::AddressString, 0},
4918     { "extensionContainer", s_sequenceTag, true,  TcapXApplication::HexString,     0},
4919     {"",                    s_noTag,       false, TcapXApplication::None,          0},
4920 };
4921 
4922 static const Parameter s_activateTraceModeArgs[] = {
4923     {"imsi",                  s_ctxtPrim_0_Tag,    true,    TcapXApplication::TBCD,          0},
4924     {"traceReference",        s_ctxtPrim_1_Tag,    false,   TcapXApplication::HexString,     0},
4925     {"traceType",             s_ctxtPrim_2_Tag,    false,   TcapXApplication::Integer,       0},
4926     {"omc-Id",                s_ctxtPrim_3_Tag,    true,    TcapXApplication::AddressString, 0},
4927     {"extensionContainer",    s_ctxtCstr_4_Tag,    true,    TcapXApplication::HexString,     0},
4928     {"traceReference2",       s_ctxtPrim_5_Tag,    true,    TcapXApplication::HexString,     0},
4929     {"traceDepthList",        s_ctxtCstr_6_Tag,    true,    TcapXApplication::Sequence,      s_traceDepthListSeq},
4930     {"traceNE-TypeList",      s_ctxtPrim_7_Tag,    true,    TcapXApplication::BitString,     s_traceNETypeList},
4931     {"traceInterfaceList",    s_ctxtCstr_8_Tag,    true,    TcapXApplication::Sequence,      s_traceInterfaceListSeq},
4932     {"traceEventList",        s_ctxtCstr_9_Tag,    true,    TcapXApplication::Sequence,      s_traceEventListSeq},
4933     {"traceCollectionEntity", s_ctxtPrim_10_Tag,   true,    TcapXApplication::HexString,     0},
4934     {"",                      s_noTag,             false,   TcapXApplication::None,          0},
4935 };
4936 
4937 static const Parameter s_traceModeRes[] = {
4938     {"extensionContainer",    s_ctxtCstr_0_Tag,    true,    TcapXApplication::HexString,    0},
4939     {"traceSupportIndicator", s_ctxtPrim_1_Tag,    true,    TcapXApplication::Null,         0},
4940     {"",                      s_noTag,             false,   TcapXApplication::None,         0},
4941 };
4942 
4943 static const Parameter s_deactivateTraceModeArgs[] = {
4944     {"imsi",              s_ctxtPrim_0_Tag,    true,    TcapXApplication::TBCD,         0},
4945     {"traceReference",    s_ctxtPrim_1_Tag,    false,   TcapXApplication::HexString,    0},
4946     {"extensionContainer",s_ctxtCstr_2_Tag,    true,    TcapXApplication::HexString,    0},
4947     {"traceReference2",   s_ctxtPrim_3_Tag,    true,    TcapXApplication::HexString,    0},
4948     {"",                  s_noTag,             false,   TcapXApplication::None,         0},
4949 };
4950 
4951 static const Parameter s_lcsLocationInfo[] = {
4952     {"msc-Number",                      s_hexTag,          false,  TcapXApplication::AddressString, 0},
4953     {"lmsi",                            s_ctxtPrim_0_Tag,  true,   TcapXApplication::HexString,     0},
4954     {"extensionContainer",              s_ctxtCstr_1_Tag,  true,   TcapXApplication::HexString,     0},
4955     {"gprsNodeIndicator",               s_ctxtPrim_2_Tag,  true,   TcapXApplication::Null,          0},
4956     {"additional-Number",               s_ctxtCstr_3_Tag,  true,   TcapXApplication::Choice,        s_additionalNumber},
4957     {"supportedLCS-CapabilitySets",     s_ctxtPrim_4_Tag,  true,   TcapXApplication::BitString,     s_supportedLCSCapabilitySets},
4958     {"additional-LCS-CapabilitySets",   s_ctxtPrim_5_Tag,  true,   TcapXApplication::BitString,     s_supportedLCSCapabilitySets},
4959     {"mme-Name",                        s_ctxtPrim_6_Tag,  true,   TcapXApplication::HexString,     0},
4960     {"aaa-Server-Name",                 s_ctxtPrim_8_Tag,  true,   TcapXApplication::HexString,     0},
4961     {"",                                s_noTag,           false,  TcapXApplication::None,          0},
4962 };
4963 
4964 static const Parameter s_sendRoutingInfoForLCSArgs[] = {
4965     {"mlcNumber",         s_ctxtPrim_0_Tag,    false,   TcapXApplication::AddressString, 0},
4966     {"targetMS",          s_ctxtCstr_1_Tag,    false,   TcapXApplication::Choice,        s_subscriberIdentity},
4967     {"extensionContainer",s_ctxtCstr_2_Tag,    true,    TcapXApplication::HexString,     0},
4968     {"",                  s_noTag,             false,   TcapXApplication::None,          0},
4969 };
4970 
4971 static const Parameter s_sendRoutingInfoForLCSRes[] = {
4972     {"targetMS",                        s_ctxtCstr_0_Tag,    false,   TcapXApplication::Choice,        s_subscriberIdentity},
4973     {"lcsLocationInfo",                 s_ctxtCstr_1_Tag,    false,   TcapXApplication::Sequence,      s_lcsLocationInfo},
4974     {"extensionContainer",              s_ctxtCstr_2_Tag,    true,    TcapXApplication::HexString,     0},
4975     {"v-gmlc-Address",                  s_ctxtPrim_3_Tag,    true,    TcapXApplication::HexString,     0},
4976     {"h-gmlc-Address",                  s_ctxtPrim_4_Tag,    true,    TcapXApplication::HexString,     0},
4977     {"ppr-Address",                     s_ctxtPrim_5_Tag,    true,    TcapXApplication::HexString,     0},
4978     {"additional-v-gmlc-Address",       s_ctxtPrim_6_Tag,    true,    TcapXApplication::HexString,     0},
4979     {"",                                s_noTag,             false,   TcapXApplication::None,          0},
4980 };
4981 
4982 static const Parameter s_resynchronisationInfo[] = {
4983     {"rand",   s_hexTag,  false,  TcapXApplication::HexString, 0},
4984     {"auts",   s_hexTag,  false,  TcapXApplication::HexString, 0},
4985     {"",       s_noTag,   false,  TcapXApplication::None,      0},
4986 };
4987 
4988 static const TokenDict s_requestingNodeType[] = {
4989     {"vlr",              0},
4990     {"sgsn",             1},
4991     {"s-cscf",           2},
4992     {"bsf",              3},
4993     {"gan-aaa-server",   4},
4994     {"wlan-aaa-server",  5},
4995     {"mme",             16},
4996     {"mme-sgsn",        17},
4997     {0, 0},
4998 };
4999 
5000 static const Parameter s_sendAuthInfoSeq[] = {
5001     {"imsi",                                 s_ctxtPrim_0_Tag,  false, TcapXApplication::TBCD,       0},
5002     {"numberOfRequestedVectors",             s_intTag,          false, TcapXApplication::Integer,    0},
5003     {"segmentationProhibited",               s_nullTag,         true,  TcapXApplication::Null,       0},
5004     {"immediateResponsePreferred",           s_ctxtPrim_1_Tag,  true,  TcapXApplication::Null,       0},
5005     {"re-synchronisationInfo",               s_sequenceTag,     true,  TcapXApplication::Sequence,   s_resynchronisationInfo},
5006     {"extensionContainer",                   s_ctxtCstr_2_Tag,  true,  TcapXApplication::HexString,  0},
5007     {"requestingNodeType",                   s_ctxtPrim_3_Tag,  true,  TcapXApplication::Enumerated, s_requestingNodeType},
5008     {"requestingPLMN-Id",                    s_ctxtPrim_4_Tag,  true,  TcapXApplication::TBCD,       0},
5009     {"numberOfRequestedAdditional-Vectors",  s_ctxtPrim_5_Tag,  true,  TcapXApplication::Integer,    0},
5010     {"additionalVectorsAreForEPS",           s_ctxtPrim_6_Tag,  true,  TcapXApplication::Null,       0},
5011     {"",                                     s_noTag,           false, TcapXApplication::None,       0},
5012 };
5013 
5014 static const Parameter s_sendAuthenticationInfoArgs[] = {
5015     {"imsi",                                 s_hexTag,          false, TcapXApplication::TBCD,       0},
5016     {"sendAuthenticationInfoArgs",           s_sequenceTag,     false, TcapXApplication::Sequence,   s_sendAuthInfoSeq},
5017     {"",                                     s_noTag,           false, TcapXApplication::None,       0},
5018 };
5019 
5020 static const Parameter s_sendAuthenticationInfoRes[] = {
5021     {"sendAuthenticationInfoRes-v2", s_sequenceTag,     false, TcapXApplication::SequenceOf, s_authenticationSet},
5022     {"sendAuthenticationInfoRes-v3", s_ctxtCstr_3_Tag,  false, TcapXApplication::Sequence,   s_authenticationRes},
5023     {"",                             s_noTag,           false, TcapXApplication::None,       0},
5024 };
5025 
5026 static const Parameter s_restoreDataArgs[] = {
5027     {"imsi",                 s_hexTag,          false,   TcapXApplication::TBCD,        0},
5028     {"lmsi",                 s_hexTag,          true,    TcapXApplication::HexString,   0},
5029     {"extensionContainer",   s_sequenceTag,     true,    TcapXApplication::HexString,   0},
5030     {"vlr-Capability",       s_ctxtCstr_6_Tag,  true,    TcapXApplication::Sequence,    s_vlrCapability},
5031     {"restorationIndicator", s_ctxtPrim_7_Tag,  true,    TcapXApplication::Null,        0},
5032     {"",                     s_noTag,           false,   TcapXApplication::None,        0},
5033 };
5034 
5035 static const Parameter s_restoreDataRes[] = {
5036     {"hlr-Number",         s_hexTag,         false,   TcapXApplication::AddressString, 0},
5037     {"msNotReachable",     s_nullTag,        true,    TcapXApplication::Null,          0},
5038     {"extensionContainer", s_sequenceTag,    true,    TcapXApplication::HexString,     0},
5039     {"",                   s_noTag,          false,   TcapXApplication::None,          0},
5040 };
5041 
5042 static const Parameter s_sendIMSIArgs[] = {
5043     {"msisdn",        s_hexTag,    false,   TcapXApplication::AddressString,    0},
5044     {"",              s_noTag,     false,   TcapXApplication::None,             0},
5045 };
5046 
5047 static const Parameter s_sendIMSIRes[] = {
5048     {"imsi",          s_hexTag,    false,   TcapXApplication::TBCD,        0},
5049     {"",              s_noTag,     false,   TcapXApplication::None,        0},
5050 };
5051 
5052 static const Parameter s_unstructuredSSArgs[] = {
5053     {"ussd-DataCodingScheme", s_hexTag,            false,    TcapXApplication::HexString,        0},
5054     {"ussd-String",           s_hexTag,            false,    TcapXApplication::GSMString,        0},
5055     {"alertingPattern",       s_hexTag,            true,     TcapXApplication::Enumerated,       s_alertPattern},
5056     {"msisdn",                s_ctxtPrim_0_Tag,    true,     TcapXApplication::AddressString,    0},
5057     {"",                      s_noTag,             false,    TcapXApplication::None,             0},
5058 };
5059 
5060 static const Parameter s_unstructuredSSRes[] = {
5061     {"ussd-DataCodingScheme", s_hexTag,    false,    TcapXApplication::HexString,        0},
5062     {"ussd-String",           s_hexTag,    false,    TcapXApplication::GSMString,        0},
5063     {"",                      s_noTag,     false,    TcapXApplication::None,             0},
5064 };
5065 
5066 static const TokenDict s_mwStatus[] = {
5067     { "sc-AddressNotIncluded",  0x01 },
5068     { "mnrf-Set",               0x02 },
5069     { "mcef-Set",               0x04 },
5070     { "mnrg-Set",               0x08 },
5071     { 0, 0 }
5072 };
5073 
5074 static const Parameter s_informServiceCentreArgs[] = {
5075     { "storedMSISDN",                           s_hexTag,            true,  TcapXApplication::AddressString,    0 },
5076     { "mw-Status",                              s_bitsTag,           true,  TcapXApplication::BitString,        s_mwStatus },
5077     { "extensionContainer",                     s_sequenceTag,       true,  TcapXApplication::HexString,        0 },
5078     { "absentSubscriberDiagnosticSM",           s_intTag,            true,  TcapXApplication::Integer,          0 },
5079     { "additionalAbsentSubscriberDiagnosticSM", s_ctxtPrim_0_Tag,    true,  TcapXApplication::Integer,          0 },
5080     { "",                                       s_noTag,             false, TcapXApplication::None,             0 },
5081 };
5082 
5083 static const Parameter s_alertServiceCentreArgs[] = {
5084     {"msisdn",                s_hexTag,    false,     TcapXApplication::AddressString,    0},
5085     {"serviceCentreAddress",  s_hexTag,    false,     TcapXApplication::AddressString,    0},
5086     {"",                      s_noTag,     false,     TcapXApplication::None,             0},
5087 };
5088 
5089 static const Parameter s_readyForSMArgs[] = {
5090     {"imsi",                           s_ctxtPrim_0_Tag,    false,   TcapXApplication::TBCD,        0},
5091     {"alertReason",                    s_enumTag,           false,   TcapXApplication::Enumerated,  s_alertReason},
5092     {"alertReasonIndicator",           s_nullTag,           true,    TcapXApplication::Null,        0},
5093     {"extensionContainer",             s_sequenceTag,       true,    TcapXApplication::HexString,   0},
5094     {"additionalAlertReasonIndicator", s_ctxtPrim_1_Tag,    true,    TcapXApplication::Null,        0},
5095     {"",                               s_noTag,             false,   TcapXApplication::None,        0},
5096 };
5097 
5098 static const Parameter s_purgeMSArgs[] = {
5099     {"imsi",              s_hexTag,            false,   TcapXApplication::TBCD,            0},
5100     {"vlr-Number",        s_ctxtPrim_0_Tag,    true,    TcapXApplication::AddressString,   0},
5101     {"sgsn-Number",       s_ctxtPrim_1_Tag,    true,    TcapXApplication::AddressString,   0},
5102     {"extensionContainer",s_sequenceTag,       true,    TcapXApplication::HexString,       0},
5103     {"",                  s_noTag,             false,   TcapXApplication::None,            0},
5104 };
5105 
5106 static const Parameter s_purgeMSRes[] = {
5107     {"freezeTMSI",        s_ctxtPrim_0_Tag,    true,   TcapXApplication::Null,         0},
5108     {"freezeP-TMSI",      s_ctxtPrim_1_Tag,    true,   TcapXApplication::Null,         0},
5109     {"extensionContainer",s_sequenceTag,       true,   TcapXApplication::HexString,    0},
5110     {"freezeM-TMSI",      s_ctxtPrim_2_Tag,    true,   TcapXApplication::Null,         0},
5111     {"",                  s_noTag,             false,  TcapXApplication::None,         0},
5112 };
5113 
5114 static const Parameter s_provideSubscriberInfoArgs[] = {
5115     {"imsi",              s_ctxtPrim_0_Tag,    false,  TcapXApplication::TBCD,         0},
5116     {"lmsi",              s_ctxtPrim_1_Tag,    true,   TcapXApplication::HexString,    0},
5117     {"requestedInfo",     s_ctxtCstr_2_Tag,    false,  TcapXApplication::Sequence,     s_requestedInfo},
5118     {"extensionContainer",s_ctxtCstr_3_Tag,    true,   TcapXApplication::HexString,    0},
5119     {"",                  s_noTag,             false,  TcapXApplication::None,         0},
5120 };
5121 
5122 static const Parameter s_provideSubscriberInfoRes[] = {
5123     {"subscriberInfo",        s_sequenceTag,   false,   TcapXApplication::Sequence,      s_subscriberInfo},
5124     {"extensionContainer",    s_sequenceTag,   true,    TcapXApplication::HexString,     0},
5125     {"",                      s_noTag,         false,   TcapXApplication::None,          0},
5126 };
5127 
5128 static const Parameter s_anyTimeInterrogationArgs[] = {
5129     {"subscriberIdentity",    s_ctxtCstr_0_Tag,    false,   TcapXApplication::Choice,        s_subscriberIdentity},
5130     {"requestedInfo",         s_ctxtCstr_1_Tag,    false,   TcapXApplication::Sequence,      s_requestedInfo},
5131     {"gsmSCF-Address",        s_ctxtPrim_3_Tag,    false,   TcapXApplication::AddressString, 0},
5132     {"extensionContainer",    s_ctxtCstr_2_Tag,    true,    TcapXApplication::HexString,     0},
5133     {"",                      s_noTag,             false,   TcapXApplication::None,          0},
5134 };
5135 
5136 static const Parameter s_anyTimeInterrogationRes[] = {
5137     {"subscriberInfo",        s_sequenceTag,   false,   TcapXApplication::Sequence,      s_subscriberInfo},
5138     {"extensionContainer",    s_sequenceTag,   true,    TcapXApplication::HexString,     0},
5139     {"",                      s_noTag,         false,   TcapXApplication::None,          0},
5140 };
5141 
5142 static const Parameter s_setReportingStateArgs[] = {
5143     {"imsi",                  s_ctxtPrim_0_Tag,    true,    TcapXApplication::TBCD,         0},
5144     {"lmsi",                  s_ctxtPrim_1_Tag,    true,    TcapXApplication::HexString,    0},
5145     {"ccbs-Monitoring",       s_ctxtPrim_2_Tag,    true,    TcapXApplication::Enumerated,   s_reportingState},
5146     {"extensionContainer",    s_ctxtCstr_3_Tag,    true,    TcapXApplication::HexString,    0},
5147     {"",                      s_noTag,             false,   TcapXApplication::None,         0},
5148 };
5149 
5150 static const Parameter s_setReportingStateRes[] = {
5151     {"ccbs-SubscriberStatus", s_ctxtPrim_0_Tag, true,   TcapXApplication::Enumerated,    s_CCBSSubscriberStatus},
5152     {"extensionContainer",    s_ctxtCstr_1_Tag, true,   TcapXApplication::HexString,     0},
5153     {"",                      s_noTag,         false,   TcapXApplication::None,          0},
5154 };
5155 
5156 static const Parameter s_statusReportArgs[] = {
5157     {"imsi",                  s_ctxtPrim_0_Tag,    false,    TcapXApplication::TBCD,         0},
5158     {"eventReportData",       s_ctxtCstr_1_Tag,    true,     TcapXApplication::Sequence,     s_eventReportData},
5159     {"callReportdata",        s_ctxtCstr_2_Tag,    true,     TcapXApplication::Sequence,     s_callReportData},
5160     {"extensionContainer",    s_ctxtCstr_3_Tag,    true,     TcapXApplication::HexString,    0},
5161     {"",                      s_noTag,             false,    TcapXApplication::None,         0},
5162 };
5163 
5164 static const Parameter s_statusReportRes[] = {
5165     {"extensionContainer",    s_ctxtCstr_0_Tag,   true,    TcapXApplication::HexString,     0},
5166     {"",                      s_noTag,            false,   TcapXApplication::None,          0},
5167 };
5168 
5169 static const Operation s_mapOps[] = {
5170     {"updateLocation",                true,   2,  SS7TCAP::SuccessOrFailureReport,
5171 	s_sequenceTag, s_updateLocationArgs,
5172 	s_sequenceTag, s_updateLocationRes
5173     },
5174     {"cancelLocation",                true,   3,  SS7TCAP::SuccessOrFailureReport,
5175 	s_ctxtCstr_3_Tag, s_cancelLocationArgs,
5176 	s_sequenceTag,    s_extensionContainerRes
5177     },
5178     {"provideRoamingNumber",          true,   4,  SS7TCAP::SuccessOrFailureReport,
5179 	s_sequenceTag, s_provideRoamingNumberArgs,
5180 	s_sequenceTag, s_provideRoamingNumberRes
5181     },
5182     {"insertSubscriberData",          true,   7,  SS7TCAP::SuccessOrFailureReport,
5183 	s_sequenceTag, s_insertSubscriberDataArgs,
5184 	s_sequenceTag, s_insertSubscriberDataRes
5185     },
5186     {"deleteSubscriberData",          true,   8,  SS7TCAP::SuccessOrFailureReport,
5187 	s_sequenceTag, s_deleteSubscriberDataArgs,
5188 	s_sequenceTag, s_deleteSubscriberDataRes
5189     },
5190     {"sendParameters",                true,   9,  SS7TCAP::SuccessOrFailureReport,
5191 	s_sequenceTag, s_sendParametersDataArgs,
5192 	s_noTag, s_sendParametersDataRes
5193     },
5194     {"registerSS",                    true,  10,  SS7TCAP::SuccessOrFailureReport,
5195 	s_sequenceTag, s_registerSSArgs,
5196 	s_noTag,       s_extSSInfoChoice
5197     },
5198     {"eraseSS",                       true,  11,  SS7TCAP::SuccessOrFailureReport,
5199 	s_sequenceTag, s_ssCodeArgs,
5200 	s_noTag,       s_extSSInfoChoice
5201     },
5202     {"activateSS",                    true,  12,  SS7TCAP::SuccessOrFailureReport,
5203 	s_sequenceTag, s_ssCodeArgs,
5204 	s_noTag,       s_extSSInfoChoice
5205     },
5206     {"deactivateSS",                  true,  13,  SS7TCAP::SuccessOrFailureReport,
5207 	s_sequenceTag, s_ssCodeArgs,
5208 	s_noTag,       s_extSSInfoChoice
5209     },
5210     {"interrogateSS",                 true,  14,  SS7TCAP::SuccessOrFailureReport,
5211 	s_sequenceTag, s_ssCodeArgs,
5212 	s_noTag,       s_InterrogateSSRes
5213     },
5214     {"authenticationFailureReport",   true,  15,  SS7TCAP::SuccessOrFailureReport,
5215 	s_sequenceTag, s_authFailureArgs,
5216 	s_sequenceTag, s_extensionContainerRes,
5217     },
5218     {"registerPassword",              true,  17,  SS7TCAP::SuccessOrFailureReport,
5219 	s_noTag, s_registerPasswordArgs,
5220 	s_noTag, s_registerPasswordRes
5221     },
5222     {"getPassword",                   true,  18,  SS7TCAP::SuccessOnlyReport,
5223 	s_noTag, s_getPasswordArgs,
5224 	s_noTag, s_getPasswordRes
5225     },
5226     {"updateGprsLocation",            true,  23,  SS7TCAP::SuccessOrFailureReport,
5227 	s_sequenceTag, s_updateGprsLocationArgs,
5228 	s_sequenceTag, s_updateGprsLocationRes
5229     },
5230     {"sendRoutingInfoForGprs",        true,  24,  SS7TCAP::SuccessOrFailureReport,
5231 	s_sequenceTag, s_sendRoutingInfoForGprsArgs,
5232 	s_sequenceTag, s_sendRoutingInfoForGprsRes
5233     },
5234     {"failureReport",                 true,  25,  SS7TCAP::SuccessOrFailureReport,
5235 	s_sequenceTag, s_failureReportArgs,
5236 	s_sequenceTag, s_failureReportRes
5237     },
5238     {"reset",                         true,  37,  SS7TCAP::NoReport,
5239 	s_sequenceTag, s_resetArgs,
5240 	s_noTag, 0
5241     },
5242     {"forwardCheckSS-Indication",     true,  38,  SS7TCAP::NoReport,
5243 	s_noTag, 0,
5244 	s_noTag, 0
5245     },
5246     {"mt-forwardSM",                  true,  44,  SS7TCAP::SuccessOrFailureReport,
5247 	s_sequenceTag, s_mtForwardSMArgs,
5248 	s_sequenceTag, s_forwardSMRes
5249     },
5250     {"sendRoutingInfoForSM",          true,  45,  SS7TCAP::SuccessOrFailureReport,
5251 	s_sequenceTag, s_sendRoutingInfoForSMArgs,
5252 	s_sequenceTag, s_sendRoutingInfoForSMRes
5253     },
5254     {"mo-forwardSM",                  true,  46,  SS7TCAP::SuccessOrFailureReport,
5255 	s_sequenceTag, s_moForwardSMArgs,
5256 	s_sequenceTag, s_forwardSMRes
5257     },
5258     {"forwardSM",                     true,  46,  SS7TCAP::SuccessOrFailureReport,
5259 	s_sequenceTag, s_forwardSMArgs,
5260 	s_noTag, 0
5261     },
5262     {"reportSM-DeliveryStatus",       true,  47,  SS7TCAP::SuccessOrFailureReport,
5263 	s_sequenceTag, s_reportSMDeliveryArgs,
5264 	s_sequenceTag, s_reportSMDeliveryRes,
5265 
5266     },
5267     {"activateTraceMode",             true,  50,  SS7TCAP::SuccessOrFailureReport,
5268 	s_sequenceTag, s_activateTraceModeArgs,
5269 	s_sequenceTag, s_traceModeRes
5270     },
5271     {"deactivateTraceMode",           true,  51,  SS7TCAP::SuccessOrFailureReport,
5272 	s_sequenceTag, s_deactivateTraceModeArgs,
5273 	s_sequenceTag, s_traceModeRes
5274     },
5275     {"sendAuthenticationInfo",        true,  56,  SS7TCAP::SuccessOrFailureReport,
5276 	s_noTag, s_sendAuthenticationInfoArgs,
5277 	s_noTag, s_sendAuthenticationInfoRes
5278     },
5279     {"restoreData",                   true,  57,  SS7TCAP::SuccessOrFailureReport,
5280 	s_sequenceTag, s_restoreDataArgs,
5281 	s_sequenceTag, s_restoreDataRes
5282     },
5283     {"sendIMSI",                      true,  58,  SS7TCAP::SuccessOrFailureReport,
5284 	s_noTag, s_sendIMSIArgs,
5285 	s_noTag, s_sendIMSIRes
5286     },
5287     {"processUnstructuredSS-Request", true,  59,  SS7TCAP::SuccessOrFailureReport,
5288 	s_sequenceTag, s_unstructuredSSArgs,
5289 	s_sequenceTag, s_unstructuredSSRes
5290     },
5291     {"unstructuredSS-Request",        true,  60,  SS7TCAP::SuccessOrFailureReport,
5292 	s_sequenceTag, s_unstructuredSSArgs,
5293 	s_sequenceTag, s_unstructuredSSRes
5294     },
5295     {"unstructuredSS-Notify",         true,  61,  SS7TCAP::SuccessOrFailureReport,
5296 	s_sequenceTag, s_unstructuredSSArgs,
5297 	s_noTag, 0
5298     },
5299     {"informServiceCentre",           true,  63,  SS7TCAP::NoReport,
5300 	s_sequenceTag, s_informServiceCentreArgs,
5301 	s_noTag, 0
5302     },
5303     {"alertServiceCentre",            true,  64,  SS7TCAP::SuccessOrFailureReport,
5304 	s_sequenceTag, s_alertServiceCentreArgs,
5305 	s_noTag, 0
5306     },
5307     {"readyForSM",                    true,  66,  SS7TCAP::SuccessOrFailureReport,
5308 	s_sequenceTag, s_readyForSMArgs,
5309 	s_sequenceTag, s_extensionContainerRes
5310     },
5311     {"purgeMS",                       true,  67,  SS7TCAP::SuccessOrFailureReport,
5312 	s_ctxtCstr_3_Tag, s_purgeMSArgs,
5313 	s_sequenceTag,    s_purgeMSRes
5314     },
5315     {"provideSubscriberInfo",         true,  70,  SS7TCAP::SuccessOrFailureReport,
5316 	s_sequenceTag, s_provideSubscriberInfoArgs,
5317 	s_sequenceTag, s_provideSubscriberInfoRes
5318     },
5319     {"anyTimeInterrogation",          true,  71,  SS7TCAP::SuccessOrFailureReport,
5320 	s_sequenceTag, s_anyTimeInterrogationArgs,
5321 	s_sequenceTag, s_anyTimeInterrogationRes
5322     },
5323     {"setReportingState",             true,  73,  SS7TCAP::SuccessOrFailureReport,
5324  	s_sequenceTag, s_setReportingStateArgs,
5325 	s_sequenceTag, s_setReportingStateRes
5326     },
5327     {"statusReport",                  true,  74,  SS7TCAP::SuccessOrFailureReport,
5328 	s_sequenceTag, s_statusReportArgs,
5329 	s_sequenceTag, s_statusReportRes
5330     },
5331     {"sendRoutingInfoForLCS",         true,  85,  SS7TCAP::SuccessOrFailureReport,
5332 	s_sequenceTag, s_sendRoutingInfoForLCSArgs,
5333 	s_sequenceTag, s_sendRoutingInfoForLCSRes
5334     },
5335     {"",                              false,  0,  -1,
5336 	s_noTag,  0,
5337 	s_noTag,  0
5338     },
5339 };
5340 
5341 static const StringList s_camelCapabOps("initialDP,assistRequestInstructions,establishTemporaryConnection,disconnectForwardConnection,"
5342 		"connectToResource,connect,releaseCall,requestReportBCSMEvent,eventReportBCSM,continue,resetTimer,"
5343 		"furnishChargingInformation,applyCharging,applyChargingReport,callInformationReport,callInformationRequest,"
5344 		"sendChargingInformation,playAnnouncement,promptAndCollectUserInformation,specializedResourceReport,"
5345 		"cancel,activityTest,initiateCallAttempt,disconnectLeg,moveLeg,splitLeg,entityReleased,"
5346 		"continueWithArgument,disconnectForwardConnectionWithArgument,playTone,callGap");
5347 
5348 static const Capability s_camelCapab[] = {
5349     {"Camel",  s_camelCapabOps},
5350     {0, s_noOps},
5351 };
5352 
5353 static TokenDict s_eventTypeBCSM[] = {
5354     {"collectedInfo",             2},
5355     {"routeSelectFailure",        4},
5356     {"oCalledPartyBusy",          5},
5357     {"oNoAnswer",                 6},
5358     {"oAnswer",                   7},
5359     {"oDisconnect",               9},
5360     {"oAbandon",                  10},
5361     {"termAttemptAuthorized",     12},
5362     {"tBusy",                     13},
5363     {"tNoAnswer",                 14},
5364     {"tAnswer",                   15},
5365     {"tDisconnect",               17},
5366     {"tAbandon",                  18},
5367     {0, 0}
5368 };
5369 
5370 static TokenDict s_naCICSelectionType[] = {
5371     {"not-indicated",                     0x00},
5372     {"subscribed-not-dialed",             0x01},
5373     {"subscribed-and-dialed",             0x02},
5374     {"subscribed-dialing-undeterminded",  0x03},
5375     {"dialed-CIC-not-subscribed",         0x04},
5376     {0, 0}
5377 };
5378 
5379 static const Parameter s_naCarrierInformationSeq[] = {
5380     {"naCarrierId",            s_ctxtPrim_0_Tag, true,   TcapXApplication::TBCD,       0}, //Carrier digits
5381     {"naCICSelectionType",     s_ctxtPrim_1_Tag, true,   TcapXApplication::Enumerated, s_naCICSelectionType},
5382     {"",                       s_noTag,                                        false,  TcapXApplication::None,       0},
5383 };
5384 
5385 static const Parameter s_initialDPArgExtension[] = {
5386     {"naCarrierInformation",   s_ctxtCstr_0_Tag, true,   TcapXApplication::Sequence,        s_naCarrierInformationSeq},
5387     {"gmscAddress",            s_ctxtPrim_1_Tag, true,   TcapXApplication::AddressString,   0},
5388     {"",                       s_noTag,          false,  TcapXApplication::None,            0},
5389 };
5390 
5391 static Parameter s_bearerCap[] = {
5392     {"bearerCap",  s_ctxtPrim_0_Tag, false,  TcapXApplication::UserServiceInfo, 0},
5393     {"",           s_noTag,          false,  TcapXApplication::None,            0},
5394 };
5395 
5396 static const Parameter s_initialDPArgs[] = {
5397     {"serviceKey",                     s_ctxtPrim_0_Tag,  false,  TcapXApplication::Integer,                0},
5398     {"calledPartyNumber",              s_ctxtPrim_2_Tag,  true,   TcapXApplication::CalledPartyNumber,      0},
5399     {"callingPartyNumber",             s_ctxtPrim_3_Tag,  true,   TcapXApplication::CallingPartyNumber,     0},
5400     {"callingPartysCategory",          s_ctxtPrim_5_Tag,  true,   TcapXApplication::Enumerated,             s_category},
5401     // TODO decode iPSSPCapabilities according to ETSI TS 101 046 V7.1.0 (2000-07) page 42
5402     {"iPSSPCapabilities",              s_ctxtPrim_8_Tag,  true,   TcapXApplication::HexString,              0},  // might need further decoding
5403     {"locationNumber",                 s_ctxtPrim_10_Tag, true,   TcapXApplication::LocationNumber,         0},
5404     {"originalCalledPartyID",          s_ctxtPrim_12_Tag, true,   TcapXApplication::OriginalCalledNumber,   0},
5405     {"extensions",                     s_ctxtCstr_15_Tag, true,   TcapXApplication::HexString,              0},
5406     {"highLayerCompatibility",         s_ctxtPrim_23_Tag, true,   TcapXApplication::HiLayerCompat,          0}, // might need further decoding
5407     {"additionalCallingPartyNumber",   s_ctxtPrim_25_Tag, true,   TcapXApplication::TBCD,                   0}, // not sure about this either
5408     {"bearerCapability",               s_ctxtCstr_27_Tag, true,   TcapXApplication::Choice,                 s_bearerCap},
5409     {"eventTypeBCSM",                  s_ctxtPrim_28_Tag, true,   TcapXApplication::Enumerated,             s_eventTypeBCSM},
5410     {"redirectingPartyID",             s_ctxtPrim_29_Tag, true,   TcapXApplication::RedirectingNumber,      0},
5411     {"redirectionInformation",         s_ctxtPrim_30_Tag, true,   TcapXApplication::RedirectionInformation, 0},
5412     {"imsi",                           s_ctxtPrim_50_Tag, true,   TcapXApplication::TBCD,                   0},
5413     {"subscriberState",                s_ctxtCstr_51_Tag, true,   TcapXApplication::Choice,                 s_subscriberState},
5414     {"locationInformation",            s_ctxtCstr_52_Tag, true,   TcapXApplication::Sequence,               s_locationInformation},
5415     {"ext-basicServiceCode",           s_ctxtCstr_53_Tag, true,   TcapXApplication::Choice,                 s_basicServiceCode},
5416     {"callReferenceNumber",            s_ctxtPrim_54_Tag, true,   TcapXApplication::HexString,              0},
5417     {"mscAddress",                     s_ctxtPrim_55_Tag, true,   TcapXApplication::AddressString,          0},
5418     {"calledPartyBCDNumber",           s_ctxtPrim_56_Tag, true,   TcapXApplication::AddressString,          0}, //should be checked
5419     {"timeAndTimezone",                s_ctxtPrim_57_Tag, true,   TcapXApplication::TBCD,                   0},//might need special decoding
5420     {"gsm-ForwardingPending",          s_ctxtPrim_58_Tag, true,   TcapXApplication::Null,                   0},
5421     {"initialDPArgExtension",          s_ctxtCstr_59_Tag, true,   TcapXApplication::Sequence,               s_initialDPArgExtension},
5422     {"",                               s_noTag,           false,  TcapXApplication::None,                   0},
5423 };
5424 
5425 static const TokenDict s_monitorMode[] = {
5426     {"interrupted",       0x00},
5427     {"notifyAndContinue", 0x01},
5428     {"transparent",       0x02},
5429     {0, 0},
5430 };
5431 
5432 static const TokenDict s_legType[] = {
5433     {"leg1",  0x01},
5434     {"leg2",  0x02},
5435     {0, 0},
5436 };
5437 
5438 static const Parameter s_legID[] = {
5439     {"sendingSideID",   s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_legType},
5440     {"receivingSideID", s_ctxtPrim_1_Tag, false, TcapXApplication::Enumerated, s_legType},
5441     {"",                s_noTag,          false, TcapXApplication::None,       0},
5442 };
5443 
5444 static const Parameter s_DPSpecificCriteria[] = {
5445     {"applicationTimer",s_ctxtPrim_1_Tag, false, TcapXApplication::Integer,    0},
5446     {"",                s_noTag,          false, TcapXApplication::None,       0},
5447 };
5448 
5449 static const Parameter s_bcsmEventSeq[] = {
5450     {"eventTypeBCSM",      s_ctxtPrim_0_Tag, false,   TcapXApplication::Enumerated,   s_eventTypeBCSM},
5451     {"monitorMode",        s_ctxtPrim_1_Tag, false,   TcapXApplication::Enumerated,   s_monitorMode},
5452     {"legID",              s_ctxtCstr_2_Tag, true,    TcapXApplication::Choice,       s_legID},
5453     {"dPSpecificCriteria", s_ctxtCstr_30_Tag,true,    TcapXApplication::Choice,       s_DPSpecificCriteria},
5454     {"",                   s_noTag,          false,   TcapXApplication::None,         0},
5455 };
5456 
5457 static const Parameter s_bcsmEvent[] = {
5458     {"bcsmEvent",     s_sequenceTag, false,  TcapXApplication::Sequence,  s_bcsmEventSeq},
5459     {"",              s_noTag,       false,  TcapXApplication::None,        0},
5460 };
5461 
5462 static const Parameter s_requestReportBCSMEventArgs[] = {
5463     {"bcsmEvents",     s_ctxtCstr_0_Tag, false,  TcapXApplication::SequenceOf,  s_bcsmEvent},
5464     {"extensions",     s_ctxtCstr_2_Tag, true,   TcapXApplication::HexString,   0},
5465     {"",               s_noTag,          false,  TcapXApplication::None,        0},
5466 };
5467 
5468 static const Parameter s_receivingSideID[] = {
5469     {"receivingSideID", s_ctxtPrim_1_Tag, false, TcapXApplication::Enumerated, s_legType},
5470     {"",                s_noTag,          false, TcapXApplication::None,       0},
5471 };
5472 
5473 static const Parameter s_failureCause[] = {
5474 // failureCause := Cause (should find encoding, for now treated as hex string)
5475     {"failureCause",    s_ctxtPrim_0_Tag, true,  TcapXApplication::HexString, 0},
5476     {"",                s_noTag,          false, TcapXApplication::None,      0},
5477 };
5478 
5479 static const Parameter s_busyCause[] = {
5480 // busyCause := Cause (should find encoding, for now treated as hex string)
5481     {"busyCause",    s_ctxtPrim_0_Tag, true,  TcapXApplication::HexString, 0},
5482     {"",             s_noTag,          false, TcapXApplication::None,      0},
5483 };
5484 
5485 static const Parameter s_releaseCause[] = {
5486 // releaseCause := Cause (should find encoding, for now treated as hex string)
5487     {"releaseCause",    s_ctxtPrim_0_Tag, true,  TcapXApplication::HexString, 0},
5488     {"",                s_noTag,          false, TcapXApplication::None,      0},
5489 };
5490 
5491 static const Parameter s_tNoAsnwerInfo[] = {
5492     {"callForwarded",    s_ctxtPrim_50_Tag, true,  TcapXApplication::Null, 0},
5493     {"",                 s_noTag,           false, TcapXApplication::None, 0},
5494 };
5495 
5496 static const Parameter s_tBusyInfo[] = {
5497 // busyCause := Cause (should find encoding, for now treated as hex string)
5498     {"busyCause",        s_ctxtPrim_0_Tag,  true,  TcapXApplication::HexString, 0},
5499     {"callForwarded",    s_ctxtPrim_50_Tag, true,  TcapXApplication::Null, 0},
5500     {"",                 s_noTag,           false, TcapXApplication::None, 0},
5501 };
5502 
5503 static const Parameter s_eventSpecificInformationBCSM[] = {
5504     {"routeSelectFailureSpecificInfo", s_ctxtCstr_2_Tag,  false, TcapXApplication::Sequence, s_failureCause},
5505     {"oCalledPartyBusySpecificInfo",   s_ctxtCstr_3_Tag,  false, TcapXApplication::Sequence, s_busyCause},
5506     {"oNoAnswerSpecificInfo",          s_ctxtCstr_4_Tag,  false, TcapXApplication::Sequence, 0},
5507     {"oAnswerSpecificInfo",            s_ctxtCstr_5_Tag,  false, TcapXApplication::Sequence, 0},
5508     {"oDisconnectSpecificInfo",        s_ctxtCstr_7_Tag,  false, TcapXApplication::Sequence, s_releaseCause},
5509     {"tBusySpecificInfo",              s_ctxtCstr_8_Tag,  false, TcapXApplication::Sequence, s_tBusyInfo},
5510     {"tNoAnswerSpecificInfo",          s_ctxtCstr_9_Tag,  false, TcapXApplication::Sequence, s_tNoAsnwerInfo},
5511     {"tAnswerSpecificInfo",            s_ctxtCstr_10_Tag, false, TcapXApplication::Sequence, 0},
5512     {"tDisconnectSpecificInfo",        s_ctxtCstr_12_Tag, false, TcapXApplication::Sequence, s_releaseCause},
5513     {"",                               s_noTag,           false, TcapXApplication::None,     0},
5514 };
5515 
5516 static const TokenDict s_messageType[] = {
5517     {"request",       0x00},
5518     {"notification",  0x01},
5519     {0, 0},
5520 };
5521 
5522 static const Parameter s_miscCallInfoSeq[] = {
5523     {"messageType",      s_ctxtPrim_0_Tag,  false, TcapXApplication::Enumerated, s_messageType},
5524     {"",                 s_noTag,           false, TcapXApplication::None,       0},
5525 };
5526 
5527 static const Parameter s_eventReportBCSMArgs[] = {
5528     {"eventTypeBCSM",                s_ctxtPrim_0_Tag,  false,   TcapXApplication::Enumerated, s_eventTypeBCSM},
5529     {"eventSpecificInformationBCSM", s_ctxtCstr_2_Tag,  true,    TcapXApplication::Choice,     s_eventSpecificInformationBCSM},
5530     {"legID",                        s_ctxtCstr_3_Tag,  true,    TcapXApplication::Choice,     s_receivingSideID},
5531     {"miscCallInfo",                 s_ctxtCstr_4_Tag,  false,   TcapXApplication::Sequence,   s_miscCallInfoSeq},
5532     {"extensions",                   s_ctxtCstr_5_Tag,  true,    TcapXApplication::HexString,  0},
5533     {"",                             s_noTag,           false,   TcapXApplication::None,       0},
5534 };
5535 
5536 static const Parameter s_calledPartyNumber[] = {
5537     {"calledPartyNumber",  s_hexTag, false,   TcapXApplication::CalledPartyNumber, 0},
5538     {"",                   s_noTag,  false,   TcapXApplication::None,              0},
5539 };
5540 
5541 static const Parameter s_genericNumber[] = {
5542     {"genericNumber",  s_hexTag, false,   TcapXApplication::GenericNumber,   0},
5543     {"",               s_noTag,  false,   TcapXApplication::None,            0},
5544 };
5545 
5546 static const Parameter s_naInfoSeq[] = {
5547     {"naCarrierInformation",   s_ctxtCstr_0_Tag, true,   TcapXApplication::Sequence,        s_naCarrierInformationSeq},
5548 //    NA Oli information takes the same value as defined in ANSI ISUP T1.113
5549     {"naOliInfo",              s_ctxtPrim_1_Tag, true,   TcapXApplication::HexString,       0},
5550     {"naChargeNumber",         s_ctxtPrim_2_Tag, true,   TcapXApplication::ChargeNumber,    0},
5551     {"",                       s_noTag,          false,  TcapXApplication::None,            0},
5552 };
5553 
5554 static const Parameter s_connectArgs[] = {
5555     {"destinationRoutingAddress",   s_ctxtCstr_0_Tag, false,  TcapXApplication::SequenceOf,      s_calledPartyNumber},
5556     //alertingPattern  decoded as hex string, encoding in GSM 09.02 (ref. 14)
5557     {"alertingPattern",             s_ctxtPrim_1_Tag,  true,   TcapXApplication::HexString,               0},
5558     {"originalCalledPartyID",       s_ctxtPrim_6_Tag,  true,   TcapXApplication::OriginalCalledNumber,    0},
5559     {"extensions",                  s_ctxtCstr_10_Tag, true,   TcapXApplication::HexString,               0},
5560     {"callingPartysCategory",       s_ctxtPrim_28_Tag, true,   TcapXApplication::Enumerated,              s_category},
5561     {"redirectingPartyID",          s_ctxtPrim_29_Tag, true,   TcapXApplication::RedirectingNumber,       0},
5562     {"redirectionInformation",      s_ctxtPrim_30_Tag, true,   TcapXApplication::RedirectionInformation,  0},
5563     {"genericNumbers",              s_ctxtCstr_14_Tag, true,   TcapXApplication::SetOf,                   s_genericNumber},
5564     {"suppressionOfAnnouncement",   s_ctxtPrim_55_Tag, true,   TcapXApplication::Null,                    0},
5565     {"oCSIApplicable",              s_ctxtPrim_56_Tag, true,   TcapXApplication::Null,                    0},
5566     {"na-Info",                     s_ctxtCstr_57_Tag, true,   TcapXApplication::Sequence,                s_naInfoSeq},
5567     {"",                            s_noTag,           false,  TcapXApplication::None,                    0},
5568 };
5569 
5570 static const Parameter s_releaseCallArgs[] = {
5571     // TODO - decode Cause (ETS 300 356-1 [3] Cause and Location values refer to Q.850).
5572     {"cause",    s_hexTag, false,  TcapXApplication::HexString, 0},
5573     {"",         s_noTag,  false,  TcapXApplication::None,      0},
5574 };
5575 
5576 static const Parameter s_assistRequestInstructionsArgs[] = {
5577     // Defined as Digits    - see for encoding   ETS 300 356-1 [3] Generic Number
5578     {"correlationID",     s_ctxtPrim_0_Tag, false,    TcapXApplication::TBCD,            0},
5579     // ETSI TS 101 046 - GSM CAP specification (CAMEL) page 42 for further decoding
5580     {"iPSSPCapabilities", s_ctxtPrim_2_Tag, false,    TcapXApplication::HexString,       0},
5581     {"extensions",        s_ctxtCstr_3_Tag, true,     TcapXApplication::HexString,       0},
5582     {"",                  s_noTag,          false,    TcapXApplication::None,            0},
5583 };
5584 
5585 static const TokenDict s_bothwayThroughConnectionInd[] = {
5586     {"bothwayPathRequired",       0x00},
5587     {"bothwayPathNotRequired",    0x01},
5588     {0, 0},
5589 };
5590 
5591 static const Parameter s_serviceInteractionIndicatorsTwo[] = {
5592 // FROM CS2-datatypes { ccitt(0) identified-organization(4) etsi(0) inDomain(1)
5593 // in-network(1) CS2(20) modules(0) in-cs2-datatypes (0) version1(0)}
5594     {"bothwayThroughConnectionInd", s_ctxtPrim_2_Tag, true,  TcapXApplication::Enumerated, s_bothwayThroughConnectionInd},
5595     {"",                            s_noTag,          false, TcapXApplication::None,       0},
5596 };
5597 
5598 static const Parameter s_establishTemporaryConnectionArgs[] = {
5599     //Digits    - see for encoding   ETS 300 356-1 [3] , definde ETSI TS 101 046 - GSM CAP specification (CAMEL) page 42
5600     {"assistingSSPIPRoutingAddress",   s_ctxtPrim_0_Tag, false, TcapXApplication::TBCD,       0},
5601     // Defined as Digits    - see for encoding   ETS 300 356-1 [3] Generic Number
5602     {"correlationID",                  s_ctxtPrim_1_Tag, true,  TcapXApplication::TBCD,       0},
5603     {"scfID",                          s_ctxtPrim_3_Tag, true,  TcapXApplication::HexString,  0},
5604     {"extensions",                     s_ctxtCstr_4_Tag, true,  TcapXApplication::HexString,  0},
5605     {"serviceInteractionIndicatorsTwo",s_ctxtCstr_7_Tag, true,  TcapXApplication::Sequence,   s_serviceInteractionIndicatorsTwo},
5606     {"na-Info",                        s_ctxtCstr_50_Tag,true,  TcapXApplication::Sequence,   s_naInfoSeq},
5607     {"",                               s_noTag,          false, TcapXApplication::None,       0},
5608 };
5609 
5610 static const Parameter s_resourceAddress[] = {
5611     {"ipRoutingAddress", s_ctxtPrim_0_Tag, false, TcapXApplication::CalledPartyNumber, 0},
5612     {"none",             s_ctxtPrim_3_Tag, false, TcapXApplication::Null,              0},
5613     {"",                 s_noTag,          false, TcapXApplication::None,              0},
5614 };
5615 
5616 static const Parameter s_connectToResourceArgs[] = {
5617     {"resourceAddress",                s_noTag,          false, TcapXApplication::Choice,     s_resourceAddress},
5618     {"extensions",                     s_ctxtCstr_4_Tag, true,  TcapXApplication::HexString,  0},
5619     {"serviceInteractionIndicatorsTwo",s_ctxtCstr_7_Tag, true,  TcapXApplication::Sequence,   s_serviceInteractionIndicatorsTwo},
5620     {"",                               s_noTag,          false, TcapXApplication::None,       0},
5621 };
5622 
5623 static const TokenDict s_timerID[] = {
5624     {"tssf",       0x00},
5625     {0,0},
5626 };
5627 
5628 static const Parameter s_resetTimerArgs[] = {
5629     {"timerID",       s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_timerID},
5630     {"timervalue",    s_ctxtPrim_1_Tag, false, TcapXApplication::Integer,    0},
5631     {"extensions",    s_ctxtCstr_2_Tag, true,  TcapXApplication::HexString,  0},
5632     {"",              s_noTag,          false, TcapXApplication::None,       0},
5633 };
5634 
5635 static const Parameter s_sendingSideID[] = {
5636     {"sendingSideID", s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_legType},
5637     {"",              s_noTag,          false, TcapXApplication::None,       0},
5638 };
5639 
5640 static const Parameter s_fCIBCCCAMELsequenceSeq[] = {
5641     {"freeFormatData",  s_ctxtPrim_0_Tag, false, TcapXApplication::HexString,  0},
5642     {"partyToCharge",   s_ctxtCstr_1_Tag, false, TcapXApplication::Choice,     s_sendingSideID},
5643     {"",                s_noTag,          false, TcapXApplication::None,       0},
5644 };
5645 
5646 static const Parameter s_fCIBillingChargingCharacteristicsChoice[] = {
5647     {"fCIBCCCAMELsequence1", s_ctxtCstr_0_Tag, false,  TcapXApplication::Sequence, s_fCIBCCCAMELsequenceSeq},
5648     {"",                     s_noTag,          false,  TcapXApplication::None,     0},
5649 };
5650 
5651 static const Parameter s_FCIBillingChargingCharacteristics[] = {
5652     {"fCIBillingChargingCharacteristics", s_hexTag, false,  TcapXApplication::Choice,  s_fCIBillingChargingCharacteristicsChoice},
5653     {"",                                  s_noTag,  false,  TcapXApplication::None,    0},
5654 };
5655 
5656 static const Parameter s_releaseIfdurationExceeded[] = {
5657     {"tone",          s_boolTag,         false, TcapXApplication::Bool,       0},
5658     {"extensions",    s_ctxtCstr_10_Tag, true,  TcapXApplication::HexString,  0},
5659     {"",              s_noTag,           false, TcapXApplication::None,       0},
5660 };
5661 
5662 static const Parameter s_timeDuratinChargingSeq[] = {
5663     {"maxCallPeriodDuration",      s_ctxtPrim_0_Tag, false, TcapXApplication::Integer,  0},
5664     {"releaseIfdurationExceeded",  s_ctxtCstr_1_Tag, true,  TcapXApplication::Sequence, s_releaseIfdurationExceeded},
5665     {"tariffSwitchInterval",       s_ctxtPrim_2_Tag, true,  TcapXApplication::Integer,  0},
5666     {"",                           s_noTag,          false, TcapXApplication::None,     0},
5667 };
5668 
5669 
5670 static const Parameter s_aChBillingChargingCharacteristics[] = {
5671     {"timeDurationCharging", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_timeDuratinChargingSeq},
5672     {"",                     s_noTag,          false, TcapXApplication::None,       0},
5673 };
5674 
5675 static const Parameter s_applyChargingArgs[] = {
5676     {"aChBillingChargingCharacteristics", s_ctxtPrim_0_Tag, false, TcapXApplication::Choice,   s_aChBillingChargingCharacteristics},
5677     {"partyToCharge",                     s_ctxtCstr_2_Tag, false, TcapXApplication::Choice,   s_sendingSideID},
5678     {"extensions",                        s_ctxtCstr_3_Tag, true,  TcapXApplication::HexString,0},
5679     {"",                                  s_noTag,          false, TcapXApplication::None,     0},
5680 };
5681 
5682 static const Parameter s_timeIfTariffSwitchSeq[] = {
5683     {"timeSinceTariffSwitch",  s_ctxtPrim_0_Tag, false, TcapXApplication::Integer,  0},
5684     {"tariffSwitchInterval",   s_ctxtPrim_1_Tag, true,  TcapXApplication::Integer,  0},
5685     {"",                       s_noTag,          false, TcapXApplication::None,     0},
5686 };
5687 
5688 static const Parameter s_timeInformation[] = {
5689     {"timeIfNoTariffSwitch",  s_ctxtPrim_0_Tag, false, TcapXApplication::Integer,  0},
5690     {"timeIfTariffSwitch",    s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_timeIfTariffSwitchSeq},
5691     {"",                      s_noTag,          false, TcapXApplication::None,     0},
5692 };
5693 
5694 static const Parameter s_timeDurationChargingResSeq[] = {
5695     {"partyToCharge",   s_ctxtCstr_0_Tag, false, TcapXApplication::Choice,   s_receivingSideID},
5696     {"timeInformation", s_ctxtCstr_1_Tag, false, TcapXApplication::Choice,   s_timeInformation},
5697     {"callActive",      s_ctxtPrim_2_Tag, false, TcapXApplication::Bool,     0},
5698     {"",                s_noTag,          false, TcapXApplication::None,     0},
5699 };
5700 
5701 static const Parameter s_callResultChoice[] = {
5702     {"timeDurationChargingResult", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_timeDurationChargingResSeq},
5703     {"",                           s_noTag,          false, TcapXApplication::None,     0},
5704 };
5705 
5706 static const Parameter s_callResult[] = {
5707     {"callResult", s_hexTag, false, TcapXApplication::Choice,   s_callResultChoice},
5708     {"",           s_noTag,  false, TcapXApplication::None,     0},
5709 };
5710 
5711 static const TokenDict s_requestedInformationType[] = {
5712     {"callAttemptElapsedTime",       0x00},
5713     {"callStopTime",                 0x01},
5714     {"callConnectedElapsedTime",     0x02},
5715     {"releaseCause",                 0x1e},
5716     {0,0}
5717 };
5718 
5719 static const Parameter s_requestedInformationValue[] = {
5720     {"callAttemptElapsedTimeValue",  s_ctxtPrim_0_Tag, false, TcapXApplication::Integer,  0},
5721     {"callStopTimeValue",            s_ctxtPrim_1_Tag, false, TcapXApplication::TBCD,     0},
5722     {"callConnectedElapsedTimeValue",s_ctxtPrim_2_Tag, false, TcapXApplication::Integer,  0},
5723     {"releaseCauseValue",            s_ctxtPrim_30_Tag,false, TcapXApplication::HexString,0},
5724     {"",                             s_noTag,          false, TcapXApplication::None,     0},
5725 };
5726 
5727 static const Parameter s_requestedInformationSeq[] = {
5728     {"requestedInformationType",  s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_requestedInformationType},
5729     {"requestedInformationValue", s_ctxtCstr_1_Tag, false, TcapXApplication::Choice,     s_requestedInformationValue},
5730     {"",                          s_noTag,          false, TcapXApplication::None,       0},
5731 };
5732 
5733 static const Parameter s_requestedInformation[] = {
5734     {"requestedInformation", s_sequenceTag,  false,  TcapXApplication::Sequence,   s_requestedInformationSeq},
5735     {"",                     s_noTag,        false,  TcapXApplication::None,       0},
5736 };
5737 
5738 static const Parameter s_callInformationArgs[] = {
5739     {"requestedInformationList", s_ctxtCstr_0_Tag, false,TcapXApplication::SequenceOf, s_requestedInformation},
5740     {"extensions",               s_ctxtCstr_2_Tag, true, TcapXApplication::HexString,  0},
5741     {"legID",                    s_ctxtCstr_3_Tag, true, TcapXApplication::Choice,     s_receivingSideID},
5742     {"",                         s_noTag,          false,TcapXApplication::None,       0},
5743 };
5744 
5745 static const Parameter s_requestedInfoType[] = {
5746     {"requestedInformationType", s_enumTag, false, TcapXApplication::Enumerated, s_requestedInformationType},
5747     {"",                         s_noTag,   false, TcapXApplication::None,       0},
5748 };
5749 
5750 static const Parameter s_callInformationRequestArgs[] = {
5751     {"requestedInformationTypeList", s_ctxtCstr_0_Tag, false,TcapXApplication::SequenceOf, s_requestedInfoType},
5752     {"extensions",                   s_ctxtCstr_2_Tag, true, TcapXApplication::HexString,  0},
5753     {"legID",                        s_ctxtCstr_3_Tag, true, TcapXApplication::Choice,     s_sendingSideID},
5754     {"",                             s_noTag,          false,TcapXApplication::None,       0},
5755 };
5756 
5757 static const Parameter s_CAIGSM0224Seq[] = {
5758     {"e1", s_ctxtPrim_0_Tag, true, TcapXApplication::Integer, 0},
5759     {"e2", s_ctxtPrim_1_Tag, true, TcapXApplication::Integer, 0},
5760     {"e3", s_ctxtPrim_2_Tag, true, TcapXApplication::Integer, 0},
5761     {"e4", s_ctxtPrim_3_Tag, true, TcapXApplication::Integer, 0},
5762     {"e5", s_ctxtPrim_4_Tag, true, TcapXApplication::Integer, 0},
5763     {"e6", s_ctxtPrim_5_Tag, true, TcapXApplication::Integer, 0},
5764     {"e7", s_ctxtPrim_6_Tag, true, TcapXApplication::Integer, 0},
5765     {"",   s_noTag,          false,TcapXApplication::None,    0},
5766 };
5767 
5768 static const Parameter s_AOCSubsequentSeq[] = {
5769     {"cAI-GSM0224",          s_ctxtCstr_0_Tag, false,TcapXApplication::Sequence, s_CAIGSM0224Seq},
5770     {"tariffSwitchInterval", s_ctxtPrim_1_Tag, true, TcapXApplication::Integer,  0},
5771     {"",                     s_noTag,          false,TcapXApplication::None,     0},
5772 };
5773 
5774 static const Parameter s_AOCBeforeAnswerSeq[] = {
5775     {"aOCInitial",    s_ctxtCstr_0_Tag, false,TcapXApplication::Sequence, s_CAIGSM0224Seq},
5776     {"aOCSubsequent", s_ctxtCstr_1_Tag, true, TcapXApplication::Sequence, s_AOCSubsequentSeq},
5777     {"",              s_noTag,          false,TcapXApplication::None,       0},
5778 };
5779 
5780 static const Parameter s_sCIBillingChargingCharacteristics[] = {
5781     {"aOCBeforeAnswer", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_AOCBeforeAnswerSeq},
5782     {"aOCAfterAnswer",  s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_AOCSubsequentSeq},
5783     {"",                s_noTag,          false, TcapXApplication::None,     0},
5784 };
5785 
5786 static const Parameter s_sendChargingInformationArgs[] = {
5787     {"sCIBillingChargingCharacteristics", s_ctxtPrim_0_Tag, false, TcapXApplication::Choice,    s_sCIBillingChargingCharacteristics},
5788     {"partyToCharge",                     s_ctxtCstr_1_Tag, false, TcapXApplication::Choice,    s_sendingSideID},
5789     {"extensions",                        s_ctxtCstr_2_Tag, true,  TcapXApplication::HexString, 0},
5790     {"",                                  s_noTag,          false, TcapXApplication::None,      0},
5791 };
5792 
5793 static const Parameter s_textSeq[] = {
5794     {"messageContent", s_ctxtPrim_0_Tag, false, TcapXApplication::AppString,  0},
5795     {"attributes",     s_ctxtPrim_1_Tag, true,  TcapXApplication::HexString,  0},
5796     {"",               s_noTag,          false, TcapXApplication::None,       0},
5797 };
5798 
5799 static const Parameter s_elementaryMessageID[] = {
5800     {"elementaryMessageID", s_intTag, false, TcapXApplication::Integer,  0},
5801     {"",                    s_noTag,  false, TcapXApplication::None,     0},
5802 };
5803 
5804 static const Parameter s_variablePartChoice[] = {
5805     {"integer", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer,    0},
5806     {"number",  s_ctxtPrim_1_Tag, false, TcapXApplication::TBCD,       0},
5807     {"time",    s_ctxtPrim_2_Tag, false, TcapXApplication::TBCD,       0},
5808     {"date",    s_ctxtPrim_3_Tag, false, TcapXApplication::TBCD,       0},
5809     {"price",   s_ctxtPrim_4_Tag, false, TcapXApplication::TBCD,       0},
5810     {"",        s_noTag,          false, TcapXApplication::None,       0},
5811 };
5812 
5813 static const Parameter s_variablePart[] = {
5814     {"variablePart", s_noTag, false, TcapXApplication::Choice,  s_variablePartChoice},
5815     {"",             s_noTag, false, TcapXApplication::None,    0},
5816 };
5817 
5818 static const Parameter s_variableMessageSeq[] = {
5819     {"elementaryMessageID", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer,    0},
5820     {"variableParts",       s_ctxtCstr_1_Tag, false, TcapXApplication::SequenceOf, s_variablePart},
5821     {"",                    s_noTag,          false, TcapXApplication::None,       0},
5822 };
5823 
5824 static const Parameter s_messageID[] = {
5825     {"elementaryMessageID", s_ctxtPrim_0_Tag, false, TcapXApplication::Integer,    0},
5826     {"text",                s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence,   s_textSeq},
5827     {"elementaryMessageIDs",s_ctxtCstr_29_Tag,false, TcapXApplication::SequenceOf, s_elementaryMessageID},
5828     {"variableMessage",     s_ctxtCstr_30_Tag,false, TcapXApplication::Sequence,   s_variableMessageSeq},
5829     {"",                    s_noTag,          false, TcapXApplication::None,       0},
5830 };
5831 
5832 static const Parameter s_inbandInfoSeq[] = {
5833     {"messageID",           s_ctxtCstr_0_Tag, false,TcapXApplication::Choice,  s_messageID},
5834     {"numberOfRepetitions", s_ctxtPrim_1_Tag, true, TcapXApplication::Integer, 0},
5835     {"duration",            s_ctxtPrim_2_Tag, true, TcapXApplication::Integer, 0},
5836     {"interval",            s_ctxtPrim_3_Tag, true, TcapXApplication::Integer, 0},
5837     {"",                    s_noTag,          false,TcapXApplication::None,    0},
5838 };
5839 
5840 static const Parameter s_toneSeq[] = {
5841     {"toneID",   s_ctxtPrim_0_Tag, false, TcapXApplication::Integer,   0},
5842     {"duration", s_ctxtPrim_1_Tag, true,  TcapXApplication::Integer,   0},
5843     {"",         s_noTag,          false, TcapXApplication::None,      0},
5844 };
5845 
5846 static const Parameter s_informationToSend[] = {
5847     {"inbandInfo", s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_inbandInfoSeq},
5848     {"tone",       s_ctxtCstr_1_Tag, false, TcapXApplication::Sequence, s_toneSeq},
5849     {"",           s_noTag,          false, TcapXApplication::None,     0},
5850 };
5851 
5852 static const Parameter s_playAnnouncementArgs[] = {
5853     {"informationToSend",           s_ctxtCstr_0_Tag, false, TcapXApplication::Choice,   s_informationToSend},
5854     {"disconnectFromIPForbidden",   s_ctxtPrim_1_Tag, false, TcapXApplication::Bool,     0},
5855     {"requestAnnouncementComplete", s_ctxtPrim_2_Tag, false, TcapXApplication::Bool,     0},
5856     {"extensions",                  s_ctxtCstr_3_Tag, true,  TcapXApplication::HexString,0},
5857     {"",                            s_noTag,          false, TcapXApplication::None,     0},
5858 };
5859 
5860 static const TokenDict s_errorTreatment[] = {
5861     {"stdErrorAndInfo",       0x00},
5862     {"help",                  0x01},
5863     {"repeatPrompt",          0x02},
5864     {0,0}
5865 };
5866 
5867 static const Parameter s_collectedInfoSeq[] = {
5868     {"minimumNbOfDigits",   s_ctxtPrim_0_Tag,  false, TcapXApplication::Integer,   0},
5869     {"maximumNbOfDigits",   s_ctxtPrim_1_Tag,  false, TcapXApplication::Integer,   0},
5870     {"endOfReplyDigit",     s_ctxtPrim_2_Tag,  true,  TcapXApplication::HexString, 0},
5871     {"cancelDigit",         s_ctxtPrim_3_Tag,  true,  TcapXApplication::HexString, 0},
5872     {"startDigit",          s_ctxtPrim_4_Tag,  true,  TcapXApplication::HexString, 0},
5873     {"firstDigitTimeOut",   s_ctxtPrim_5_Tag,  false, TcapXApplication::Integer,   0},
5874     {"interDigitTimeOut",   s_ctxtPrim_6_Tag,  false, TcapXApplication::Integer,   0},
5875     {"errorTreatment",      s_ctxtPrim_7_Tag,  false, TcapXApplication::Enumerated,s_errorTreatment},
5876     {"interruptableAnnInd", s_ctxtPrim_8_Tag,  false, TcapXApplication::Bool,      0},
5877     {"voiceInformation",    s_ctxtPrim_9_Tag,  false, TcapXApplication::Bool,      0},
5878     {"voiceBack",           s_ctxtPrim_10_Tag, false, TcapXApplication::Bool,      0},
5879     {"",                    s_noTag,           false, TcapXApplication::None,      0},
5880 };
5881 
5882 static const Parameter s_collectedInfo[] = {
5883     {"collectedDigits",             s_ctxtCstr_0_Tag, false, TcapXApplication::Sequence, s_collectedInfoSeq},
5884     {"",                            s_noTag,          false, TcapXApplication::None,     0},
5885 };
5886 
5887 static const Parameter s_promptAndCollectUserInformationArgs[] = {
5888     {"collectedInfo",               s_ctxtCstr_0_Tag, false,  TcapXApplication::Choice,   s_collectedInfo},
5889     {"disconnectFromIPForbidden",   s_ctxtPrim_1_Tag, false,  TcapXApplication::Bool,     0},
5890     {"informationToSend",           s_ctxtCstr_2_Tag, true,   TcapXApplication::Choice,   s_informationToSend},
5891     {"extensions",                  s_ctxtCstr_3_Tag, true,   TcapXApplication::HexString,0},
5892     {"",                            s_noTag,          false,  TcapXApplication::None,     0},
5893 };
5894 
5895 static const Parameter s_specializedResourceReportArgs[] = {
5896     {"specializedResourceReportArgs",      s_nullTag, false, TcapXApplication::Null, 0},
5897     {"",                                   s_noTag,   false, TcapXApplication::None, 0},
5898 };
5899 
5900 static const Parameter s_cancelChoice[] = {
5901     {"invokeID",       s_ctxtPrim_0_Tag, false, TcapXApplication::Integer, 0},
5902     {"allRequests",    s_ctxtPrim_1_Tag, false, TcapXApplication::Null,    0},
5903     {"",               s_noTag,          false, TcapXApplication::None,    0},
5904 };
5905 
5906 static const Parameter s_cancelArgs[] = {
5907     {"cancelArg",      s_noTag,   false, TcapXApplication::Choice, s_cancelChoice},
5908     {"",               s_noTag,   false, TcapXApplication::None,   0},
5909 };
5910 
5911 static const Operation s_camelOps[] = {
5912     {"initialDP",                true,   0,   SS7TCAP::FailureOnlyReport,
5913 	s_sequenceTag, s_initialDPArgs,
5914 	s_noTag, 0
5915     },
5916     {"assistRequestInstructions",   true,   16,   SS7TCAP::FailureOnlyReport,
5917 	s_sequenceTag, s_assistRequestInstructionsArgs,
5918 	s_noTag, 0
5919     },
5920     {"establishTemporaryConnection",   true,   17,   SS7TCAP::FailureOnlyReport,
5921 	s_sequenceTag, s_establishTemporaryConnectionArgs,
5922 	s_noTag, 0
5923     },
5924     {"disconnectForwardConnection",   true,   18,   SS7TCAP::FailureOnlyReport,
5925 	s_noTag, 0,
5926 	s_noTag, 0
5927     },
5928     {"connectToResource",   true,   19,   SS7TCAP::FailureOnlyReport,
5929 	s_sequenceTag, s_connectToResourceArgs,
5930 	s_noTag, 0
5931     },
5932     {"connect",   true,   20,   SS7TCAP::FailureOnlyReport,
5933 	s_sequenceTag, s_connectArgs,
5934 	s_noTag, 0
5935     },
5936     {"releaseCall",   true,   22,   SS7TCAP::NoReport,
5937 	s_noTag, s_releaseCallArgs,
5938 	s_noTag, 0
5939     },
5940     {"requestReportBCSMEvent",   true,   23,   SS7TCAP::FailureOnlyReport,
5941 	s_sequenceTag, s_requestReportBCSMEventArgs,
5942 	s_noTag, 0
5943     },
5944     {"eventReportBCSM",   true,   24,   SS7TCAP::NoReport,
5945 	s_sequenceTag, s_eventReportBCSMArgs,
5946 	s_noTag, 0
5947     },
5948     {"continue",   true,   31,   SS7TCAP::NoReport,
5949 	s_noTag, 0,
5950 	s_noTag, 0
5951     },
5952     {"resetTimer",   true,   33,   SS7TCAP::FailureOnlyReport,
5953 	s_sequenceTag, s_resetTimerArgs,
5954 	s_noTag, 0
5955     },
5956     {"furnishChargingInformation",   true,   34,   SS7TCAP::FailureOnlyReport,
5957 	s_noTag, s_FCIBillingChargingCharacteristics,
5958 	s_noTag, 0
5959     },
5960     {"applyCharging",   true,   35,   SS7TCAP::FailureOnlyReport,
5961 	s_sequenceTag, s_applyChargingArgs,
5962 	s_noTag, 0
5963     },
5964     {"applyChargingReport",   true,   36,   SS7TCAP::FailureOnlyReport,
5965 	s_noTag, s_callResult,
5966 	s_noTag, 0
5967     },
5968     {"callInformationReport",   true,   44,   SS7TCAP::NoReport,
5969 	s_sequenceTag, s_callInformationArgs,
5970 	s_noTag, 0
5971     },
5972     {"callInformationRequest",   true,   45,   SS7TCAP::FailureOnlyReport,
5973 	s_sequenceTag, s_callInformationRequestArgs,
5974 	s_noTag, 0
5975     },
5976     {"sendChargingInformation",   true,   46,   SS7TCAP::FailureOnlyReport,
5977 	s_sequenceTag, s_sendChargingInformationArgs,
5978 	s_noTag, 0
5979     },
5980     {"playAnnouncement",   true,   47,   SS7TCAP::FailureOnlyReport,
5981 	s_sequenceTag, s_playAnnouncementArgs,
5982 	s_noTag, 0
5983     },
5984     {"promptAndCollectUserInformation",   true,   48,   SS7TCAP::SuccessOrFailureReport,
5985 	s_sequenceTag, s_promptAndCollectUserInformationArgs,
5986 	s_noTag, 0
5987     },
5988     {"specializedResourceReport",   true,   49,   SS7TCAP::NoReport,
5989 	s_noTag, 0,
5990 	s_noTag, 0
5991     },
5992     {"cancel",   true,   53,   SS7TCAP::FailureOnlyReport,
5993 	s_noTag, s_cancelChoice,
5994 	s_noTag, 0
5995     },
5996     {"activityTest",   true,   55,   SS7TCAP::SuccessOnlyReport,
5997 	s_noTag, 0,
5998 	s_noTag, 0
5999     },
6000     {"",                              false,  0, -1,
6001 	s_noTag, 0,
6002 	s_noTag, 0
6003     },
6004 
6005 };
6006 
6007 
6008 static const TokenDict s_unknownSubscriberDiagnostic[] = {
6009     {"imsiUnknown",                0},
6010     {"gprsSubscriptionUnknown",    1},
6011     {"npdbMismatch",               2},
6012     {0, 0},
6013 };
6014 
6015 static const TokenDict s_roamingNotAllowedCause[] = {
6016     {"plmnRoamingNotAllowed",        0},
6017     {"operatorDeterminedBarring",    3},
6018     {0, 0},
6019 };
6020 
6021 static const TokenDict s_additionalRoamingNotAllowedCause[] = {
6022     {"supportedRAT-TypesNotAllowed",  0},
6023     {0, 0},
6024 };
6025 
6026 static const TokenDict s_absentSubscriberReason[] = {
6027     {"imsiDetach",      0 },
6028     {"restrictedArea",  1 },
6029     {"noPageResponse",  2 },
6030     {"purgedMS",        3 },
6031     {"mtRoamingRetry",  4 },
6032     {0, 0},
6033 };
6034 
6035 static const TokenDict s_smDeliveryFailureCause[] = {
6036     {"memoryCapacityExceeded",      0 },
6037     {"equipmentProtocolError",      1 },
6038     {"equipmentNotSM-Equipped",     2 },
6039     {"unknownServiceCentre",        3 },
6040     {"sc-Congestion",               4 },
6041     {"invalidSME-Address",          5 },
6042     {"subscriberNotSC-Subscriber",  6 },
6043     {0, 0},
6044 };
6045 
6046 static const TokenDict s_networkResource[] = {
6047     {"plmn",            0 },
6048     {"hlr",             1 },
6049     {"vlr",             2 },
6050     {"pvlr",            3 },
6051     {"controllingMSC",  4 },
6052     {"vmsc",            5 },
6053     {"eir",             6 },
6054     {"rss",             7 },
6055     {0, 0},
6056 };
6057 
6058 static const TokenDict s_additionalNetworkResource[] = {
6059     {"sgsn",   0},
6060     {"ggsn",   1},
6061     {"gmlc",   2},
6062     {"gsmSCF", 3},
6063     {"nplr",   4},
6064     {"auc",    5},
6065     {"ue",     6},
6066     {"mme",    7},
6067     {0, 0},
6068 };
6069 
6070 static const TokenDict s_failureCauseParam[] = {
6071     {"limitReachedOnNumberOfConcurrentLocationRequests", 0},
6072     {0, 0},
6073 };
6074 
6075 static const TokenDict s_unauthorizedLcscDiag[] = {
6076     {"noAdditionalInformation",                        0},
6077     {"clientNotInMSPrivacyExceptionList",              1},
6078     {"callToClientNotSetup",                           2},
6079     {"privacyOverrideNotApplicable",                   3},
6080     {"disallowedByLocalRegulatoryRequirements",        4},
6081     {"unauthorizedPrivacyClass",                       5},
6082     {"unauthorizedCallSessionUnrelatedExternalClient", 6},
6083     {"unauthorizedCallSessionRelatedExternalClient",   7},
6084     {0, 0},
6085 };
6086 
6087 static const TokenDict s_positionMethodFailureDiag[] = {
6088     {"congestion",                               0},
6089     {"insufficientResources",                    1},
6090     {"insufficientMeasurementData",              2},
6091     {"inconsistentMeasurementData",              3},
6092     {"locationProcedureNotCompleted",            4},
6093     {"locationProcedureNotSupportedByTargetMS",  5},
6094     {"qoSNotAttainable",                         6},
6095     {"positionMethodNotAvailableInNetwork",      7},
6096     {"positionMethodNotAvailableInLocationArea", 8},
6097     {0, 0},
6098 };
6099 
6100 static const Parameter s_extensibleSystemFailure[] = {
6101     {"networkResource",                s_enumTag,       true,    TcapXApplication::Enumerated,    s_networkResource},
6102     {"extensionContainer",             s_sequenceTag,   true,    TcapXApplication::HexString,     0},
6103     {"additionalNetworkResource",      s_ctxtPrim_0_Tag,true,    TcapXApplication::Enumerated,    s_additionalNetworkResource},
6104     {"failureCauseParam",              s_ctxtPrim_1_Tag,true,    TcapXApplication::Enumerated,    s_failureCauseParam},
6105     {"",                               s_noTag,         false,   TcapXApplication::None,          0},
6106 };
6107 
6108 static const Parameter s_systemFailure[] = {
6109     {"networkResource",                s_enumTag,       false,    TcapXApplication::Enumerated,    s_networkResource},
6110     {"extensibleSystemFailure",        s_sequenceTag,   false,    TcapXApplication::Sequence,      s_extensibleSystemFailure},
6111     {"",                               s_noTag,         false,    TcapXApplication::None,          0},
6112 };
6113 
6114 static const TokenDict s_pwRegistrationFailureCause[] = {
6115     {"undetermined",          0 },
6116     {"invalidFormat",         1 },
6117     {"newPasswordsMismatch",  2 },
6118     {0, 0},
6119 };
6120 
6121 static const TokenDict s_callBarringCause[] = {
6122     {"barringServiceActive",      0 },
6123     {"operatorBarring",           1 },
6124     {0, 0},
6125 };
6126 
6127 static const TokenDict s_cugRejectCause[] = {
6128     {"incomingCallsBarredWithinCUG",                 0 },
6129     {"subscriberNotMemberOfCUG",                     1 },
6130     {"requestedBasicServiceViolatesCUG-Constraints", 5 },
6131     {"calledPartySS-InteractionViolation",           7 },
6132     {0, 0},
6133 };
6134 
6135 static const Parameter s_extensibleCallBarredParam[] = {
6136     {"callBarringCause",               s_enumTag,       true,    TcapXApplication::Enumerated,    s_callBarringCause},
6137     {"extensionContainer",             s_sequenceTag,   true,    TcapXApplication::HexString,     0},
6138     {"unauthorisedMessageOriginator",  s_ctxtPrim_1_Tag,true,    TcapXApplication::Null,          0},
6139     {"",                               s_noTag,         false,   TcapXApplication::None,          0},
6140 };
6141 
6142 static const Parameter s_cugRejectErr[] = {
6143     {"cug-RejectCause",                s_enumTag,       true,    TcapXApplication::Enumerated,    s_cugRejectCause},
6144     {"extensionContainer",             s_sequenceTag,   true,    TcapXApplication::HexString,     0},
6145     {"",                               s_noTag,         false,   TcapXApplication::None,          0},
6146 };
6147 
6148 static const Parameter s_unknownSubscriberErr[] = {
6149     {"extensionContainer",             s_sequenceTag,   true,    TcapXApplication::HexString,     0},
6150     {"unknownSubscriberDiagnostic",    s_enumTag,       true,    TcapXApplication::Enumerated,    s_unknownSubscriberDiagnostic},
6151     {"",                               s_noTag,         false,   TcapXApplication::None,          0},
6152 };
6153 
6154 static const Parameter s_absentsubscriberSMErr[] = {
6155     {"absentSubscriberDiagnosticSM",             s_intTag,        true,    TcapXApplication::Integer,       0},
6156     {"extensionContainer",                       s_sequenceTag,   true,    TcapXApplication::HexString,     0},
6157     {"additionalAbsentSubscriberDiagnosticSM",   s_intTag,        true,    TcapXApplication::Integer,       0},
6158     {"",                                         s_noTag,         false,   TcapXApplication::None,          0},
6159 };
6160 
6161 static const Parameter s_roamingNotAllowedErr[] = {
6162     {"roamingNotAllowedCause",           s_enumTag,        true,    TcapXApplication::Enumerated,    s_roamingNotAllowedCause},
6163     {"extensionContainer",               s_sequenceTag,    true,    TcapXApplication::HexString,     0},
6164     {"additionalRoamingNotAllowedCause", s_ctxtPrim_0_Tag, true,    TcapXApplication::Enumerated,    s_additionalRoamingNotAllowedCause},
6165     {"",                                 s_noTag,          false,   TcapXApplication::None,          0},
6166 };
6167 
6168 static const Parameter s_callBarredErr[] = {
6169     {"callBarringCause",               s_enumTag,       false,   TcapXApplication::Enumerated,    s_callBarringCause},
6170     {"extensibleCallBarredParam",      s_sequenceTag,   false,   TcapXApplication::Sequence,      s_extensibleCallBarredParam},
6171     {"",                               s_noTag,         false,   TcapXApplication::None,          0},
6172 };
6173 
6174 static const Parameter s_ssErrorStatusErr[] = {
6175     {"ss-Status",     s_hexTag,         false,    TcapXApplication::Flags,         s_ssStatus},
6176     {"",              s_noTag,          false,    TcapXApplication::None,          0},
6177 };
6178 
6179 static const Parameter s_ssIncompatibilityErr[] = {
6180     {"ss-Code",               s_ctxtPrim_1_Tag,   true,    TcapXApplication::Enumerated,    s_SSCode},
6181     {"basicService",          s_noTag,            true,    TcapXApplication::Choice,        s_basicServiceCode},
6182     {"ss-Status",             s_ctxtPrim_4_Tag,   true,    TcapXApplication::Flags,         s_ssStatus},
6183     {"",                      s_noTag,            false,   TcapXApplication::None,          0},
6184 };
6185 
6186 static const Parameter s_facilityNotSupportedErr[] = {
6187     {"extensionContainer",                             s_sequenceTag,      true,  TcapXApplication::HexString,   0},
6188     {"shapeOfLocationEstimateNotSupported",            s_ctxtPrim_0_Tag,   true,  TcapXApplication::Null,        0},
6189     {"neededLcsCapabilityNotSupportedInServingNode",   s_ctxtPrim_1_Tag,   true,  TcapXApplication::Null,        0},
6190     {"",                                               s_noTag,            false, TcapXApplication::None,        0},
6191 };
6192 
6193 static const Parameter s_absentSubscriberErr[] = {
6194     {"extensionContainer",             s_sequenceTag,     true,  TcapXApplication::HexString,   0},
6195     {"absentSubscriberReason",         s_ctxtPrim_0_Tag,  true,  TcapXApplication::Enumerated,  s_absentSubscriberReason},
6196     {"",                               s_noTag,           false, TcapXApplication::None,        0},
6197 };
6198 
6199 static const Parameter s_subscriberBusyMtSmsErr[] = {
6200     {"extensionContainer",                s_sequenceTag,    true,    TcapXApplication::HexString,     0},
6201     {"gprsConnectionSuspended",           s_nullTag,        true,    TcapXApplication::Null,          0},
6202     {"",                                  s_noTag,          false,   TcapXApplication::None,          0},
6203 };
6204 
6205 static const Parameter s_smDeliveryFailureErr[] = {
6206     {"sm-EnumeratedDeliveryFailureCause", s_enumTag,        true,    TcapXApplication::Enumerated,    s_smDeliveryFailureCause},
6207     {"diagnosticInfo",                    s_hexTag,         true,    TcapXApplication::HexString,     0},
6208     {"extensionContainer",                s_sequenceTag,    true,    TcapXApplication::HexString,     0},
6209     {"",                                  s_noTag,          false,   TcapXApplication::None,          0},
6210 };
6211 
6212 static const Parameter s_pwRegistrationFailureErr[] = {
6213     {"pw-RegistrationFailureCause",    s_enumTag,   true,    TcapXApplication::Enumerated,    s_pwRegistrationFailureCause},
6214     {"",                               s_noTag,     false,   TcapXApplication::None,          0},
6215 };
6216 
6217 static const Parameter s_busySubscriberErr[] = {
6218     {"extensionContainer",             s_sequenceTag,      true,    TcapXApplication::HexString,     0},
6219     {"ccbs-Possible",                  s_ctxtPrim_0_Tag,   true,    TcapXApplication::Null,          0},
6220     {"ccbs-Busy",                      s_ctxtPrim_1_Tag,   true,    TcapXApplication::Null,          0},
6221     {"",                               s_noTag,            false,   TcapXApplication::None,          0},
6222 };
6223 
6224 static const Parameter s_unauthorizedLcscErr[] = {
6225     {"unauthorizedLCSClient-Diagnostic",  s_ctxtPrim_0_Tag, true,    TcapXApplication::Enumerated,    s_unauthorizedLcscDiag},
6226     {"extensionContainer",                s_ctxtPrim_1_Tag, true,    TcapXApplication::HexString,     0},
6227     {"",                                  s_noTag,          false,   TcapXApplication::None,          0},
6228 };
6229 
6230 static const Parameter s_positionMethodFailureErr[] = {
6231     {"positionMethodFailure-Diagnostic",  s_ctxtPrim_0_Tag, true,    TcapXApplication::Enumerated,    s_positionMethodFailureDiag},
6232     {"extensionContainer",                s_ctxtPrim_1_Tag, true,    TcapXApplication::HexString,     0},
6233     {"",                                  s_noTag,          false,   TcapXApplication::None,          0},
6234 };
6235 
6236 static const Operation s_mapErrors[] = {
6237     {"unknownSubscriber", true, 1, -1,
6238 	s_sequenceTag, s_unknownSubscriberErr,
6239 	s_noTag, 0
6240     },
6241     {"unknownMSC", true, 3, -1,
6242 	s_noTag, 0,
6243 	s_noTag, 0
6244     },
6245     {"unidentifiedSubscriber", true, 5, -1,
6246 	s_sequenceTag, s_extensionContainerRes,
6247 	s_noTag, 0
6248     },
6249     {"absentsubscriberSM", true, 6, -1,
6250 	s_sequenceTag, s_absentsubscriberSMErr,
6251 	s_noTag, 0
6252     },
6253     {"unknownEquipment", true, 7, -1,
6254 	s_noTag, 0,
6255 	s_noTag, 0
6256     },
6257     {"roamingNotAllowed", true, 8, -1,
6258 	s_sequenceTag, s_roamingNotAllowedErr,
6259 	s_noTag, 0
6260     },
6261     {"illegalSubscriber", true, 9, -1,
6262 	s_sequenceTag, s_extensionContainerRes,
6263 	s_noTag, 0
6264     },
6265     {"bearerServiceNotProvisioned", true, 10, -1,
6266 	s_sequenceTag, s_extensionContainerRes,
6267 	s_noTag, 0
6268     },
6269     {"teleserviceNotProvisioned", true, 11, -1,
6270 	s_sequenceTag, s_extensionContainerRes,
6271 	s_noTag, 0
6272     },
6273     {"illegalEquipment", true, 12, -1,
6274 	s_sequenceTag, s_extensionContainerRes,
6275 	s_noTag, 0
6276     },
6277     {"callBarred", true, 13, -1,
6278 	s_noTag, s_callBarredErr,
6279 	s_noTag, 0
6280     },
6281     {"forwardingViolation", true, 14, -1,
6282 	s_sequenceTag, s_extensionContainerRes,
6283 	s_noTag, 0
6284     },
6285     {"cug-Reject", true, 15, -1,
6286 	s_sequenceTag, s_cugRejectErr,
6287 	s_noTag, 0
6288     },
6289     {"illegalSS-Operation", true, 16, -1,
6290 	s_sequenceTag, s_extensionContainerRes,
6291 	s_noTag, 0
6292     },
6293     {"ss-ErrorStatus", true, 17, -1,
6294 	s_noTag, s_ssErrorStatusErr,
6295 	s_noTag, 0
6296     },
6297     {"ss-NotAvailable", true, 18, -1,
6298 	s_sequenceTag, s_extensionContainerRes,
6299 	s_noTag, 0
6300     },
6301     {"ss-SubscriptionViolation", true, 19, -1,
6302 	s_sequenceTag, s_extensionContainerRes,
6303 	s_noTag, 0
6304     },
6305     {"ss-Incompatibility", true, 20, -1,
6306 	s_sequenceTag, s_ssIncompatibilityErr,
6307 	s_noTag, 0
6308     },
6309     {"facilityNotSupported", true, 21, -1,
6310 	s_sequenceTag, s_facilityNotSupportedErr,
6311 	s_noTag, 0
6312     },
6313     {"ongoingGroupCall", true, 22, -1,
6314 	s_sequenceTag, s_extensionContainerRes,
6315 	s_noTag, 0
6316     },
6317     {"noHandoverNumberAvailable", true, 25, -1,
6318 	s_noTag, 0,
6319 	s_noTag, 0
6320     },
6321     {"subsequentHandoverFailure", true, 26, -1,
6322 	s_noTag, 0,
6323 	s_noTag, 0
6324     },
6325     {"absentSubscriber", true, 27, -1,
6326 	s_sequenceTag, s_absentSubscriberErr,
6327 	s_noTag, 0
6328     },
6329     {"incompatibleTerminal", true, 28, -1,
6330 	s_sequenceTag, s_extensionContainerRes,
6331 	s_noTag, 0
6332     },
6333     {"shortTermDenial", true, 29, -1,
6334 	s_sequenceTag, 0,
6335 	s_noTag, 0
6336     },
6337     {"longTermDenial", true, 30, -1,
6338 	s_sequenceTag, 0,
6339 	s_noTag, 0
6340     },
6341     {"subscriberBusyForMT-SMS", true, 31, -1,
6342 	s_sequenceTag, s_subscriberBusyMtSmsErr,
6343 	s_noTag, 0
6344     },
6345     {"sm-DeliveryFailure", true, 32, -1,
6346 	s_sequenceTag, s_smDeliveryFailureErr,
6347 	s_noTag, 0
6348     },
6349     {"messageWaitingListFull", true, 33, -1,
6350 	s_sequenceTag, s_extensionContainerRes,
6351 	s_noTag, 0
6352     },
6353     {"systemFailure", true, 34, -1,
6354 	s_noTag, s_systemFailure,
6355 	s_noTag, 0
6356     },
6357     {"dataMissing", true, 35, -1,
6358 	s_sequenceTag, s_extensionContainerRes,
6359 	s_noTag, 0
6360     },
6361     {"unexpectedDataValue", true, 36, -1,
6362 	s_sequenceTag, s_extensionContainerRes,
6363 	s_noTag, 0
6364     },
6365     {"pw-RegistrationFailure", true, 37, -1,
6366 	s_noTag, s_pwRegistrationFailureErr,
6367 	s_noTag, 0
6368     },
6369     {"negativePW-Check", true, 38, -1,
6370 	s_noTag, 0,
6371 	s_noTag, 0
6372     },
6373     {"noRoamingNumberAvailable", true, 39, -1,
6374 	s_sequenceTag, s_extensionContainerRes,
6375 	s_noTag, 0
6376     },
6377     {"tracingBufferFull", true, 40, -1,
6378 	s_sequenceTag, s_extensionContainerRes,
6379 	s_noTag, 0
6380     },
6381     {"targetCellOutsideGroupCallArea", true, 42, -1,
6382 	s_sequenceTag, s_extensionContainerRes,
6383 	s_noTag, 0
6384     },
6385     {"numberOfPW-AttemptsViolation", true, 43, -1,
6386 	s_noTag, 0,
6387 	s_noTag, 0
6388     },
6389     {"numberChanged", true, 44, -1,
6390 	s_sequenceTag, s_extensionContainerRes,
6391 	s_noTag, 0
6392     },
6393     {"busySubscriber", true, 45, -1,
6394 	s_sequenceTag, s_busySubscriberErr,
6395 	s_noTag, 0
6396     },
6397     {"noSubscriberReply", true, 46, -1,
6398 	s_sequenceTag, s_extensionContainerRes,
6399 	s_noTag, 0
6400     },
6401     {"forwardingFailed", true, 47, -1,
6402 	s_sequenceTag, s_extensionContainerRes,
6403 	s_noTag, 0
6404     },
6405     {"or-NotAllowed", true, 48, -1,
6406 	s_sequenceTag, s_extensionContainerRes,
6407 	s_noTag, 0
6408     },
6409     {"ati-NotAllowed", true, 49, -1,
6410 	s_sequenceTag, s_extensionContainerRes,
6411 	s_noTag, 0
6412     },
6413     {"noGroupCallNumberAvailable", true, 50, -1,
6414 	s_sequenceTag, s_extensionContainerRes,
6415 	s_noTag, 0
6416     },
6417     {"resourceLimitation", true, 51, -1,
6418 	s_sequenceTag, s_extensionContainerRes,
6419 	s_noTag, 0
6420     },
6421     {"unauthorizedRequestingNetwork", true, 52, -1,
6422 	s_sequenceTag, s_extensionContainerRes,
6423 	s_noTag, 0
6424     },
6425     {"unauthorizedLCSClient", true, 53, -1,
6426 	s_sequenceTag, s_unauthorizedLcscErr,
6427 	s_noTag, 0
6428     },
6429     {"positionMethodFailure", true, 54, -1,
6430 	s_sequenceTag, s_positionMethodFailureErr,
6431 	s_noTag, 0
6432     },
6433     {"unknownOrUnreachableLCSClient", true, 58, -1,
6434 	s_sequenceTag, s_extensionContainerRes,
6435 	s_noTag, 0
6436     },
6437     {"mm-EventNotSupported", true, 59, -1,
6438 	s_sequenceTag, s_extensionContainerRes,
6439 	s_noTag, 0
6440     },
6441     {"atsi-NotAllowed", true, 60, -1,
6442 	s_sequenceTag, s_extensionContainerRes,
6443 	s_noTag, 0
6444     },
6445     {"atm-NotAllowed", true, 61, -1,
6446 	s_sequenceTag, s_extensionContainerRes,
6447 	s_noTag, 0
6448     },
6449     {"informationNotAvailable", true, 62, -1,
6450 	s_sequenceTag, s_extensionContainerRes,
6451 	s_noTag, 0
6452     },
6453     {"unknownAlphabet", true, 71, -1,
6454 	s_noTag, 0,
6455 	s_noTag, 0
6456     },
6457     {"ussd-Busy", true, 72, -1,
6458 	s_noTag, 0,
6459 	s_noTag, 0
6460     },
6461     {"",          false,  0, -1,
6462 	s_noTag,  0,
6463 	s_noTag,  0
6464     },
6465 };
6466 
6467 static const TokenDict s_problemEnum[] = {
6468     {"unknownOperation",         0x00},
6469     {"tooLate",                  0x01},
6470     {"operationNotCancellable",  0x02},
6471     {0,0}
6472 };
6473 
6474 static const Parameter s_cancelFailedErr[] = {
6475     {"problem",      s_ctxtPrim_0_Tag, false, TcapXApplication::Enumerated, s_problemEnum},
6476     {"operation",    s_ctxtPrim_1_Tag, false, TcapXApplication::Integer,    0},
6477     {"",             s_noTag,          false, TcapXApplication::None,       0},
6478 };
6479 
6480 static const TokenDict s_requestedInfoEnum[] = {
6481     {"unknownRequestedInfo",       0x01},
6482     {"requestedInfoNotAvailable",  0x02},
6483     {0,0}
6484 };
6485 
6486 static const Parameter s_requestedInfoErr[] = {
6487     {"requestedInfoError",   s_enumTag, false, TcapXApplication::Enumerated, s_requestedInfoEnum},
6488     {"",                     s_noTag,   false, TcapXApplication::None,       0},
6489 };
6490 
6491 static const TokenDict s_systemFailureEnum[] = {
6492     {"unavailableResources",          0x00},
6493     {"componentFailure",              0x01},
6494     {"basicCallProcessingException",  0x02},
6495     {"resourceStatusFailure",         0x03},
6496     {"endUserFailure",                0x04},
6497     {0,0}
6498 };
6499 
6500 static const Parameter s_systemFailureCamelErr[] = {
6501     {"systemFailureError",   s_enumTag, false, TcapXApplication::Enumerated, s_systemFailureEnum},
6502     {"",                     s_noTag,   false, TcapXApplication::None,       0},
6503 };
6504 
6505 
6506 static const TokenDict s_taskRefusedEnum[] = {
6507     {"generic",         0x00},
6508     {"unobtainable",    0x01},
6509     {"congestion",      0x02},
6510     {0,0}
6511 };
6512 
6513 static const Parameter s_taskRefusedErr[] = {
6514     {"taskRefusedError",   s_enumTag, false, TcapXApplication::Enumerated, s_taskRefusedEnum},
6515     {"",                   s_noTag,   false, TcapXApplication::None,       0},
6516 };
6517 
6518 
6519 static const Operation s_camelErrors[] = {
6520     {"cancelled", true, 0, -1,
6521 	s_noTag, 0,
6522 	s_noTag, 0
6523     },
6524     {"cancelFailed", true, 1, -1,
6525 	s_sequenceTag, s_cancelFailedErr,
6526 	s_noTag, 0
6527     },
6528     {"eTCFailed", true, 3, -1,
6529 	s_noTag, 0,
6530 	s_noTag, 0
6531     },
6532     {"improperCallerResponse", true, 4, -1,
6533 	s_noTag, 0,
6534 	s_noTag, 0
6535     },
6536     {"missingCustomerRecord", true, 6, -1,
6537 	s_noTag, 0,
6538 	s_noTag, 0
6539     },
6540     {"missingParameter", true, 7, -1,
6541 	s_noTag, 0,
6542 	s_noTag, 0
6543     },
6544     {"parameterOutOfRange", true, 8, -1,
6545 	s_noTag, 0,
6546 	s_noTag, 0
6547     },
6548     {"requestedInfoError", true, 10, -1,
6549 	s_noTag, s_requestedInfoErr,
6550 	s_noTag, 0
6551     },
6552     {"systemFailure", true, 11, -1,
6553 	s_noTag, s_systemFailureCamelErr,
6554 	s_noTag, 0
6555     },
6556     {"taskRefused", true, 12, -1,
6557 	s_noTag, s_taskRefusedErr,
6558 	s_noTag, 0
6559     },
6560     {"unavailableResource", true, 13, -1,
6561 	s_noTag, 0,
6562 	s_noTag, 0
6563     },
6564     {"unexpectedComponentSequence", true, 14, -1,
6565 	s_noTag, 0,
6566 	s_noTag, 0
6567     },
6568     {"unexpectedDataValue", true, 15, -1,
6569 	s_noTag, 0,
6570 	s_noTag, 0
6571     },
6572     {"unexpectedParameter", true, 16, -1,
6573 	s_noTag, 0,
6574 	s_noTag, 0
6575     },
6576     {"unknownLegID", true, 17, -1,
6577 	s_noTag, 0,
6578 	s_noTag, 0
6579     },
6580     {"",            false,  0,  -1,
6581 	s_noTag,  0,
6582 	s_noTag,  0
6583     },
6584 };
6585 
6586 static const StringList s_netLocUpCtxtOps("updateLocation,forwardCheckSS-Indication,restoreData,insertSubscriberData,activateTraceMode");
6587 static const StringList s_locationCancelCtxtOps("cancelLocation");
6588 static const StringList s_roamingNumberEnqCtxtOps("provideRoamingNumber");
6589 static const StringList s_locationInfoRetrieveCtxtOps("sendRoutingInfo");
6590 static const StringList s_reportingCtxtOps("setReportingState,statusReport,remoteUserFree");
6591 static const StringList s_resetCtxtOps("reset");
6592 static const StringList s_infoRetrieveCtxt2Ops("sendAuthenticationInfo");
6593 static const StringList s_infoRetrieveCtxt1Ops("sendParameters");
6594 static const StringList s_subscriberDataCtxtOps("insertSubscriberData,deleteSubscriberData");
6595 static const StringList s_tracingCtxtOps("activateTraceMode,deactivateTraceMode");
6596 static const StringList s_networkFunctionalSsCtxtOps("registerSS,eraseSS,activateSS,deactivateSS,"
6597 							"interrogateSS,registerPassword,getPassword");
6598 static const StringList s_networkUnstructuredSsCtxt2Ops("processUnstructuredSS-Request,unstructuredSS-Request,unstructuredSS-Notify");
6599 static const StringList s_networkUnstructuredSsCtxt1Ops("processUnstructuredSS-Data");
6600 static const StringList s_shortMsgGatewayCtxtOps("sendRoutingInfoForSM,informServiceCentre");
6601 static const StringList s_shortMsgMOCtxtOps("mo-forwardSM");
6602 static const StringList s_forwardMsgCtxtOps("forwardSM");
6603 static const StringList s_shortMsgAlertCtxtOps("alertServiceCentre");
6604 static const StringList s_mwdMngtCtxtOps("readyForSM");
6605 static const StringList s_shortMsgMTCtxtOps("mt-forwardSM");
6606 static const StringList s_imsiRetrievalCtxtOps("sendIMSI");
6607 static const StringList s_msPurgingCtxtOps("purgeMS");
6608 static const StringList s_subscriberInfoEnquiryCtxOps("provideSubscriberInfo");
6609 static const StringList s_anyTimeInfoEnquiryCtxOps("anyTimeInterrogation");
6610 static const StringList s_gprsLocationUpdateCtxtOps("updateGprsLocation,insertSubscriberData,activateTraceMode");
6611 static const StringList s_gprsLocationInfoRetrieveCtxtOps("sendRoutingInfoForGprs");
6612 static const StringList s_failureReportCtxtOps("failureReport");
6613 static const StringList s_locationSvcGatewayCtxtOps("sendRoutingInfoForLCS");
6614 static const StringList s_authFailureReportCtxtOps("authenticationFailureReport");
6615 
6616 static const OpTable s_defMapOpTable = { s_mapOps, 0};
6617 
6618 static const AppCtxt s_mapAppCtxt[]= {
6619     // Network Loc Up context
6620     {"networkLocUpContext-v3", "0.4.0.0.1.0.1.3", s_netLocUpCtxtOps, &s_defMapOpTable},
6621     {"networkLocUpContext-v2", "0.4.0.0.1.0.1.2", s_netLocUpCtxtOps, &s_defMapOpTable},
6622     {"networkLocUpContext-v1", "0.4.0.0.1.0.1.1", s_netLocUpCtxtOps, &s_defMapOpTable},
6623 
6624     // Location Cancellation context
6625     {"locationCancelationContext-v3", "0.4.0.0.1.0.2.3", s_locationCancelCtxtOps, &s_defMapOpTable},
6626     {"locationCancelationContext-v2", "0.4.0.0.1.0.2.2", s_locationCancelCtxtOps, &s_defMapOpTable},
6627     {"locationCancelationContext-v1", "0.4.0.0.1.0.2.1", s_locationCancelCtxtOps, &s_defMapOpTable},
6628 
6629     // Roaming Number Enquiry Context
6630     {"roamingNumberEnquiryContext-v3", "0.4.0.0.1.0.3.3", s_roamingNumberEnqCtxtOps, &s_defMapOpTable},
6631     {"roamingNumberEnquiryContext-v2", "0.4.0.0.1.0.3.2", s_roamingNumberEnqCtxtOps, &s_defMapOpTable},
6632     {"roamingNumberEnquiryContext-v1", "0.4.0.0.1.0.3.1", s_roamingNumberEnqCtxtOps, &s_defMapOpTable},
6633 
6634     // Location Info Retrieval Context
6635     {"locationInfoRetrievalContext-v3", "0.4.0.0.1.0.5.3", s_locationInfoRetrieveCtxtOps, &s_defMapOpTable},
6636     {"locationInfoRetrievalContext-v2", "0.4.0.0.1.0.5.2", s_locationInfoRetrieveCtxtOps, &s_defMapOpTable},
6637     {"locationInfoRetrievalContext-v1", "0.4.0.0.1.0.5.1", s_locationInfoRetrieveCtxtOps, &s_defMapOpTable},
6638 
6639     // Reporting Context
6640     {"reportingContext-v3", "0.4.0.0.1.0.7.3", s_reportingCtxtOps, &s_defMapOpTable},
6641 
6642     // Reset context
6643     {"resetContext-v2", "0.4.0.0.1.0.10.2", s_resetCtxtOps, &s_defMapOpTable},
6644     {"resetContext-v1", "0.4.0.0.1.0.10.1", s_resetCtxtOps, &s_defMapOpTable},
6645 
6646     // Info retrieval context
6647     {"infoRetrievalContext-v3", "0.4.0.0.1.0.14.3", s_infoRetrieveCtxt2Ops, &s_defMapOpTable},
6648     {"infoRetrievalContext-v2", "0.4.0.0.1.0.14.2", s_infoRetrieveCtxt2Ops, &s_defMapOpTable},
6649     {"infoRetrievalContext-v1", "0.4.0.0.1.0.14.1", s_infoRetrieveCtxt1Ops, &s_defMapOpTable},
6650 
6651     // Subscriber Data Management Context
6652     {"subscriberDataMngtContext-v3", "0.4.0.0.1.0.16.3", s_subscriberDataCtxtOps, &s_defMapOpTable},
6653     {"subscriberDataMngtContext-v2", "0.4.0.0.1.0.16.2", s_subscriberDataCtxtOps, &s_defMapOpTable},
6654     {"subscriberDataMngtContext-v1", "0.4.0.0.1.0.16.1", s_subscriberDataCtxtOps, &s_defMapOpTable},
6655 
6656     // Tracing context
6657     {"tracingContext-v3", "0.4.0.0.1.0.17.3", s_tracingCtxtOps, &s_defMapOpTable},
6658     {"tracingContext-v2", "0.4.0.0.1.0.17.2", s_tracingCtxtOps, &s_defMapOpTable},
6659     {"tracingContext-v1", "0.4.0.0.1.0.17.1", s_tracingCtxtOps, &s_defMapOpTable},
6660 
6661     // Network functional SS context
6662     {"networkFunctionalSsContext-v2", "0.4.0.0.1.0.18.2", s_networkFunctionalSsCtxtOps, &s_defMapOpTable},
6663     {"networkFunctionalSsContext-v1", "0.4.0.0.1.0.18.1", s_networkFunctionalSsCtxtOps, &s_defMapOpTable},
6664 
6665     // Network unstructured SS context
6666     {"networkUnstructuredSsContext-v2", "0.4.0.0.1.0.19.2", s_networkUnstructuredSsCtxt2Ops, &s_defMapOpTable},
6667     {"networkUnstructuredSsContext-v1", "0.4.0.0.1.0.19.1", s_networkUnstructuredSsCtxt1Ops, &s_defMapOpTable},
6668 
6669     // Short message routing
6670     {"shortMsgGatewayContext-v3", "0.4.0.0.1.0.20.3", s_shortMsgGatewayCtxtOps, &s_defMapOpTable},
6671     {"shortMsgGatewayContext-v2", "0.4.0.0.1.0.20.2", s_shortMsgGatewayCtxtOps, &s_defMapOpTable},
6672     {"shortMsgGatewayContext-v1", "0.4.0.0.1.0.20.1", s_shortMsgGatewayCtxtOps, &s_defMapOpTable},
6673 
6674     // Mobile Originated short messages
6675     {"shortMsgMO-RelayContext-v3", "0.4.0.0.1.0.21.3", s_shortMsgMOCtxtOps, &s_defMapOpTable},
6676     {"shortMsgMO-RelayContext-v2", "0.4.0.0.1.0.21.2", s_forwardMsgCtxtOps, &s_defMapOpTable},
6677     {"shortMsgMO-RelayContext-v1", "0.4.0.0.1.0.21.1", s_forwardMsgCtxtOps, &s_defMapOpTable},
6678 
6679     // Short message alerts
6680     {"shortMsgAlertContext-v2", "0.4.0.0.1.0.23.2", s_shortMsgAlertCtxtOps, &s_defMapOpTable},
6681     {"shortMsgAlertContext-v1", "0.4.0.0.1.0.23.1", s_shortMsgAlertCtxtOps, &s_defMapOpTable},
6682 
6683     // readyForSM context
6684     {"mwdMngtContext-v3", "0.4.0.0.1.0.24.3", s_mwdMngtCtxtOps, &s_defMapOpTable},
6685     {"mwdMngtContext-v2", "0.4.0.0.1.0.24.2", s_mwdMngtCtxtOps, &s_defMapOpTable},
6686     {"mwdMngtContext-v1", "0.4.0.0.1.0.24.1", s_mwdMngtCtxtOps, &s_defMapOpTable},
6687 
6688     // Mobile Terminated short messages
6689     {"shortMsgMT-RelayContext-v3", "0.4.0.0.1.0.25.3", s_shortMsgMTCtxtOps, &s_defMapOpTable},
6690     {"shortMsgMT-RelayContext-v2", "0.4.0.0.1.0.25.2", s_forwardMsgCtxtOps, &s_defMapOpTable},
6691 
6692     // sendIMSI Context
6693     {"imsiRetrievalContext-v2", "0.4.0.0.1.0.26.2", s_imsiRetrievalCtxtOps, &s_defMapOpTable},
6694 
6695     // MS Purging Context
6696     {"msPurgingContext-v3", "0.4.0.0.1.0.27.3", s_msPurgingCtxtOps, &s_defMapOpTable},
6697     {"msPurgingContext-v2", "0.4.0.0.1.0.27.2", s_msPurgingCtxtOps, &s_defMapOpTable},
6698 
6699     // Subscriber Information Enquiry Context
6700     {"subscriberInfoEnquiryContext-v3", "0.4.0.0.1.0.28.3", s_subscriberInfoEnquiryCtxOps, &s_defMapOpTable},
6701 
6702     // Any Time Info Enquiry Context
6703     {"anyTimeInfoEnquiryContext-v3", "0.4.0.0.1.0.29.3", s_anyTimeInfoEnquiryCtxOps, &s_defMapOpTable},
6704 
6705     // GPRS Location Update Context
6706     {"gprsLocationUpdateContext-v3", "0.4.0.0.1.0.32.3", s_gprsLocationUpdateCtxtOps, &s_defMapOpTable},
6707 
6708     // GPRS Location Info Retrieval Context
6709     {"gprsLocationInfoRetrievalContext-v3" , "0.4.0.0.1.0.33.3", s_gprsLocationInfoRetrieveCtxtOps, &s_defMapOpTable},
6710 
6711     // Failure Report Context
6712     {"failureReportContext-v3" , "0.4.0.0.1.0.34.3", s_failureReportCtxtOps, &s_defMapOpTable},
6713 
6714     // Location Services Gateway Context
6715     {"locationSvcGatewayContext-v3", "0.4.0.0.1.0.37.3", s_locationSvcGatewayCtxtOps, &s_defMapOpTable},
6716 
6717     // Authentication Failure Report Context
6718     {"authenticationFailureReportContext-v3" , "0.4.0.0.1.0.39.3", s_authFailureReportCtxtOps, &s_defMapOpTable},
6719 
6720     {0, 0, s_noOps, 0},
6721 };
6722 
6723 static const StringList s_cap2gsmSSFgsmSCFCtxtOps("initialDP,establishTemporaryConnection,connectToResource,"
6724 							    "disconnectForwardConnection,connect,releaseCall,eventReportBCSM,"
6725 							    "requestReportBCSMEvent,applyChargingReport,applyCharging,continue,"
6726 							    "resetTimer,furnishChargingInformation,callInformationReport,"
6727 							    "callInformationRequest,sendChargingInformation,specializedResourceReport,"
6728 							    "playAnnouncement,promptAndCollectUserInformation,cancel,activityTest");
6729 static const StringList s_cap2AssistgsmSSFgsmSCFCtxtOps("assistRequestInstructions,disconnectForwardConnection,connectToResource,"
6730 								"resetTimer,specializedResourceReport,playAnnouncement,"
6731 								"promptAndCollectUserInformation,cancel,activityTest");
6732 static const StringList s_cap2gsmSRFgsmSCFCtxtOps("assistRequestInstructions,specializedResourceReport,playAnnouncement,"
6733 							"promptAndCollectUserInformation,cancel,activityTest");
6734 
6735 static OpTable s_defCamelOpTable = { s_camelOps, 0 };
6736 
6737 static const AppCtxt s_camelAppCtxt[] = {
6738     {"CAP-v2-gsmSSF-to-gsmSCF-AC", "0.4.0.0.1.0.50.1", s_cap2gsmSSFgsmSCFCtxtOps, &s_defCamelOpTable},
6739 
6740     {"CAP-v2-assist-gsmSSF-to-gsmSCF-AC", "0.4.0.0.1.0.51.1", s_cap2AssistgsmSSFgsmSCFCtxtOps, &s_defCamelOpTable},
6741 
6742     {"CAP-v2-gsmSRF-to-gsmSCF-AC", "0.4.0.0.1.0.52.1", s_cap2gsmSRFgsmSCFCtxtOps, &s_defCamelOpTable},
6743 
6744     {0, 0, s_noOps, 0}
6745 };
6746 
6747 static const StringList s_mapDialogCtxtOps("map-open,map-accept,map-close,map-refuse,map-userAbort,map-providerAbort");
6748 
6749 static const AppCtxt s_mapDialogCtxt[] = {
6750     {"map-DialogueAS", "0.4.0.0.1.1.1.1", s_mapDialogCtxtOps, 0},
6751     {0, 0, s_noOps, 0}
6752 };
6753 
6754 static const Parameter s_mapOpenSeq[] = {
6755     {"destinationReference",   s_ctxtPrim_0_Tag, true, TcapXApplication::AddressString, 0},
6756     {"originationReference",   s_ctxtPrim_1_Tag, true, TcapXApplication::AddressString, 0},
6757     {"extensionContainer",     s_sequenceTag,    true, TcapXApplication::HexString,     0},
6758     {"",                       s_noTag,          false,TcapXApplication::None,          0},
6759 };
6760 
6761 static const TokenDict s_mapRefuseReasonEnum[] = {
6762     {"noReasonGiven",               0},
6763     {"invalidDestinationReference", 1},
6764     {"invalidOriginatingReference", 2},
6765     {0,0},
6766 };
6767 
6768 static const Parameter s_mapRefuseSeq[] = {
6769     {"reason",                        s_enumTag,        false,   TcapXApplication::Enumerated,    s_mapRefuseReasonEnum},
6770     {"extensionContainer",            s_sequenceTag,    true,    TcapXApplication::HexString,     0},
6771     {"alternativeApplicationContext", s_oidTag,         true,    TcapXApplication::OID,           0},
6772     {"",                              s_noTag,          false,   TcapXApplication::None,          0},
6773 };
6774 
6775 static const TokenDict s_rscUnavailableReason[] = {
6776     {"shortTermResourceLimitation",   0},
6777     {"longTermResourceLimitation",    1},
6778     {0,0},
6779 };
6780 
6781 static const TokenDict s_procCancelReason[] = {
6782     {"handoverCancellation",       0},
6783     {"radioChannelRelease",        1},
6784     {"networkPathRelease",         2},
6785     {"callRelease",                3},
6786     {"associatedProcedureFailure", 4},
6787     {"tandemDialogueRelease",      5},
6788     {"remoteOperationsFailure",    6},
6789     {0,0},
6790 };
6791 
6792 static const Parameter s_mapUserAbortChoice[] = {
6793     {"userSpecificReason",                s_ctxtPrim_0_Tag,     false,  TcapXApplication::Null,         0},
6794     {"userResourceLimitation",            s_ctxtPrim_1_Tag,     false,  TcapXApplication::Null,         0},
6795     {"resourceUnavailable",               s_ctxtPrim_2_Tag,     false,  TcapXApplication::Enumerated,   s_rscUnavailableReason},
6796     {"applicationProcedureCancellation",  s_ctxtPrim_3_Tag,     false,  TcapXApplication::Enumerated,   s_procCancelReason},
6797     {"",                                  s_noTag,              false,   TcapXApplication::None,        0},
6798 };
6799 
6800 static const Parameter s_mapUserAbortSeq[] = {
6801     {"map-UserAbortChoice",           s_noTag,         false,    TcapXApplication::Choice,       s_mapUserAbortChoice},
6802     {"extensionContainer",            s_sequenceTag,    true,    TcapXApplication::HexString,     0},
6803     {"",                              s_noTag,          false,   TcapXApplication::None,          0},
6804 };
6805 
6806 static const TokenDict s_providerAbortReason[] = {
6807     {"abnormalDialogue",   0},
6808     {"invalidPDU",         1},
6809     {0,0},
6810 };
6811 
6812 static const Parameter s_mapProviderAbortSeq[] = {
6813     {"map-ProviderAbortReason",       s_enumTag,        false,   TcapXApplication::Enumerated,    s_providerAbortReason},
6814     {"extensionContainer",            s_sequenceTag,    true,    TcapXApplication::HexString,     0},
6815     {"",                              s_noTag,          false,   TcapXApplication::None,          0},
6816 };
6817 
6818 static const Parameter s_mapDialogChoice[] = {
6819     {"map-open",           s_ctxtCstr_0_Tag, false,  TcapXApplication::Sequence, s_mapOpenSeq},
6820     {"map-accept",         s_ctxtCstr_1_Tag, false,  TcapXApplication::Sequence, s_extensionContainerRes},
6821     {"map-close",          s_ctxtCstr_2_Tag, false,  TcapXApplication::Sequence, s_extensionContainerRes},
6822     {"map-refuse",         s_ctxtCstr_3_Tag, false,  TcapXApplication::Sequence, s_mapRefuseSeq},
6823     {"map-userAbort",      s_ctxtCstr_4_Tag, false,  TcapXApplication::Sequence, s_mapUserAbortSeq},
6824     {"map-providerAbort",  s_ctxtCstr_5_Tag, false,  TcapXApplication::Sequence, s_mapProviderAbortSeq},
6825     {"",                   s_noTag,          false,  TcapXApplication::None,     0},
6826 };
6827 
6828 static const TokenDict s_appStates[] = {
6829     {"waiting",     TcapXApplication::Waiting},
6830     {"active",      TcapXApplication::Active},
6831     {"shutdown",    TcapXApplication::ShutDown},
6832     {"inactive",    TcapXApplication::Inactive},
6833     {0, 0},
6834 };
6835 
6836 static const TokenDict s_userTypes[] = {
6837     {"MAP",     TcapXUser::MAP},
6838     {"CAMEL",   TcapXUser::CAMEL},
6839     {0, 0},
6840 };
6841 
replace(String & str,char what,char with)6842 static void replace(String& str, char what, char with)
6843 {
6844     char* c = (char*)str.c_str();
6845     while (c && *c) {
6846 	if(*c == what)
6847 	    *c = with;
6848 	c++;
6849     }
6850 }
6851 
findError(TcapXUser::UserType type,int opCode,bool opLocal=true)6852 static const Operation* findError(TcapXUser::UserType type, int opCode, bool opLocal = true)
6853 {
6854     DDebug(&__plugin,DebugAll,"findError(opCode=%d, local=%s)",opCode,String::boolText(opLocal));
6855     const Operation* ops = (type == TcapXUser::MAP ? s_mapErrors : s_camelErrors);
6856     while (!TelEngine::null(ops->name)) {
6857 	if (ops->code == opCode && ops->local == opLocal)
6858 	    return ops;
6859 	ops++;
6860     }
6861     return 0;
6862 }
6863 
findError(TcapXUser::UserType type,const String & op)6864 static const Operation* findError(TcapXUser::UserType type, const String& op)
6865 {
6866     DDebug(&__plugin,DebugAll,"findError(opCode=%s)",op.c_str());
6867     const Operation* ops = (type == TcapXUser::MAP ? s_mapErrors : s_camelErrors);
6868     while (!TelEngine::null(ops->name)) {
6869 	if (op == ops->name)
6870 	    return ops;
6871 	ops++;
6872     }
6873     return 0;
6874 }
6875 
isAppCtxtOperation(const AppCtxt * ctxt,const Operation * op)6876 static bool isAppCtxtOperation(const AppCtxt* ctxt, const Operation* op)
6877 {
6878     DDebug(&__plugin,DebugAll,"isAppCtxtOperation(ctxt=%s[%p],op=%s[%p]]",(ctxt ? ctxt->name : ""),ctxt,(op ? op->name.c_str() : ""),op);
6879     if (!ctxt)
6880 	return true;
6881     return (0 != ctxt->ops.find(op->name));
6882 }
6883 
findOperation(TcapXUser::UserType type,int opCode,bool opLocal=true,const AppCtxt * ctxt=0)6884 static const Operation* findOperation(TcapXUser::UserType type, int opCode, bool opLocal = true, const AppCtxt* ctxt = 0)
6885 {
6886     DDebug(&__plugin,DebugAll,"findOperation(type=%s,opCode=%d,local=%s,ctxt=%p)",lookup(type,s_userTypes),opCode,String::boolText(opLocal),ctxt);
6887     const Operation* ops = 0;
6888     const OpTable* opTable = (ctxt ? ctxt->opTable : 0);
6889     do {
6890 	ops = ( opTable ? opTable->mainTable : (type == TcapXUser::MAP ? s_mapOps : s_camelOps));
6891 	while (!TelEngine::null(ops->name)) {
6892 	    if (ops->code == opCode && ops->local == opLocal) {
6893 		if (isAppCtxtOperation(ctxt,ops))
6894 		    return ops;
6895 	    }
6896 	    ops++;
6897 	}
6898 	if (opTable)
6899 	    opTable = opTable->fallbackTable;
6900     } while (opTable);
6901     return 0;
6902 }
6903 
findOperation(TcapXUser::UserType type,const String & op,const AppCtxt * ctxt=0)6904 static const Operation* findOperation(TcapXUser::UserType type, const String& op, const AppCtxt* ctxt = 0)
6905 {
6906     DDebug(&__plugin,DebugAll,"findOperation(opCode=%s,ctxt=%p)",op.c_str(),ctxt);
6907     const Operation* ops = 0;
6908     const OpTable* opTable = (ctxt ? ctxt->opTable : 0);
6909     do {
6910 	ops = ( opTable ? opTable->mainTable : (type == TcapXUser::MAP ? s_mapOps : s_camelOps));
6911 	while (!TelEngine::null(ops->name)) {
6912 	    if (op == ops->name && isAppCtxtOperation(ctxt,ops))
6913 		return ops;
6914 	    ops++;
6915 	}
6916 	if (opTable)
6917 	    opTable = opTable->fallbackTable;
6918     } while (opTable);
6919     return 0;
6920 }
6921 
findCapability(TcapXUser::UserType type,const String & opName)6922 static const Capability* findCapability(TcapXUser::UserType type, const String& opName)
6923 {
6924     DDebug(&__plugin,DebugAll,"findCapability(opName=%s)",opName.c_str());
6925     const Capability* cap = (type == TcapXUser::MAP ? s_mapCapab : s_camelCapab);
6926     while (cap->name) {
6927 	if (cap->ops.find(opName))
6928 	    return cap;
6929 	cap++;
6930     }
6931     return 0;
6932 }
6933 
findCapabilityOID(TcapXUser::UserType type,const char * oid)6934 static const Capability* findCapabilityOID(TcapXUser::UserType type, const char* oid)
6935 {
6936     if (!oid)
6937 	return 0;
6938     DDebug(&__plugin,DebugAll,"findCapabilityOID(oid=%s)",oid);
6939     const Capability* cap = (type == TcapXUser::MAP ? s_mapCapabOID : s_camelCapabOID);
6940     while (cap->name) {
6941 	if (cap->ops.find(oid))
6942 	    return cap;
6943 	cap++;
6944     }
6945     return 0;
6946 }
6947 
findDefCapability(TcapXUser::UserType type,const String & cap)6948 static bool findDefCapability(TcapXUser::UserType type, const String& cap)
6949 {
6950     DDebug(&__plugin,DebugAll,"findDefCapability(opName=%s)",cap.c_str());
6951     const Capability* caps = (type == TcapXUser::MAP ? s_mapCapab : s_camelCapab);
6952     while (caps->name) {
6953 	if (cap == caps->name)
6954 	    return true;
6955 	caps++;
6956     }
6957     return false;
6958 }
6959 
findCtxtFromOid(const String & oid,const AppCtxt * ctxt)6960 static const AppCtxt* findCtxtFromOid(const String& oid, const AppCtxt* ctxt)
6961 {
6962     DDebug(&__plugin,DebugAll,"findCtxtFromOid(oid=%s)",oid.c_str());
6963     while (ctxt && ctxt->name) {
6964 	if (oid == ctxt->oid)
6965 	    return ctxt;
6966 	ctxt++;
6967     }
6968     return 0;
6969 }
6970 
findCtxtFromStr(const String & oid,const AppCtxt * ctxt)6971 static const AppCtxt* findCtxtFromStr(const String& oid, const AppCtxt* ctxt)
6972 {
6973     DDebug(&__plugin,DebugAll,"findCtxtFromStr(ctxt=%s)",oid.c_str());
6974     while (ctxt && ctxt->name) {
6975 	if (oid == ctxt->name)
6976 	    return ctxt;
6977 	ctxt++;
6978     }
6979     return 0;
6980 }
6981 
6982 
6983 /**
6984  * IDMap
6985  */
appendID(const char * tcapID,const char * appID,const AppCtxt * ctxt)6986 void IDMap::appendID(const char* tcapID, const char* appID, const AppCtxt* ctxt)
6987 {
6988     DDebug(&__plugin,DebugAll,"IDMap::appendID(tcapID=%s,appID=%s)",tcapID,appID);
6989     if (tcapID && appID)
6990 	append(new Transaction(appID,tcapID,ctxt));
6991 }
6992 
findTcapID(const char * appID)6993 const String& IDMap::findTcapID(const char* appID)
6994 {
6995     DDebug(&__plugin,DebugAll,"IDMap::findTcapID(appID=%s)",appID);
6996     ObjList* obj = find(appID);
6997     if (obj) {
6998 	NamedString* ns = static_cast<NamedString*>(obj->get());
6999 	if (!TelEngine::null(ns))
7000 	    return (*ns);
7001     }
7002     return String::empty();
7003 }
7004 
findAppID(const char * tcapID)7005 const String& IDMap::findAppID(const char* tcapID)
7006 {
7007     DDebug(&__plugin,DebugAll,"IDMap::findAppID(tcapID=%s)",tcapID);
7008     for (ObjList* o = skipNull(); o; o = o->skipNext()) {
7009 	NamedString* ns = static_cast<NamedString*>(o->get());
7010 	if (!TelEngine::null(ns) && (*ns) == tcapID)
7011 	    return ns->name();
7012     }
7013     return String::empty();
7014 }
7015 
findByAppID(const char * appID)7016 Transaction* IDMap::findByAppID(const char* appID)
7017 {
7018     DDebug(&__plugin,DebugAll,"IDMap::findByAppID(appID=%s)",appID);
7019     ObjList* obj = find(appID);
7020     if (obj) {
7021 	Transaction* ns = static_cast<Transaction*>(obj->get());
7022 	return ns;
7023     }
7024     return 0;
7025 }
7026 
findByTcapID(const char * tcapID)7027 Transaction* IDMap::findByTcapID(const char* tcapID)
7028 {
7029     DDebug(&__plugin,DebugAll,"IDMap::findByTcapID(tcapID=%s)",tcapID);
7030     for (ObjList* o = skipNull(); o; o = o->skipNext()) {
7031 	Transaction* ns = static_cast<Transaction*>(o->get());
7032 	if (!TelEngine::null(ns) && (*ns) == tcapID)
7033 	    return ns;
7034     }
7035     return 0;
7036 }
7037 
7038 /**
7039  * StringList
7040  */
StringList(const char * list,char sep)7041 StringList::StringList(const char* list, char sep)
7042 {
7043     DDebug(&__plugin,DebugAll,"StringList(list=%s) [%p]",list,this);
7044     String str(list);
7045     m_list = str.split(sep,false);
7046 }
7047 
~StringList()7048 StringList::~StringList()
7049 {
7050     XDebug(&__plugin,DebugAll,"~StringList() [%p]",this);
7051     TelEngine::destruct(m_list);
7052 }
7053 
7054 
7055 /**
7056  * MyDomParser
7057  */
MyDomParser(TcapXApplication * app,const char * name,bool fragment)7058 MyDomParser::MyDomParser(TcapXApplication* app, const char* name, bool fragment)
7059     : XmlDomParser(name,fragment),
7060       m_app(app)
7061 {
7062     Debug(DebugAll,"MyDomParser created [%p]",this);
7063 }
~MyDomParser()7064 MyDomParser::~MyDomParser()
7065 {
7066     Debug(DebugAll,"MyDomParser destroyed [%p]",this);
7067 }
7068 
gotElement(const NamedList & element,bool empty)7069 void MyDomParser::gotElement(const NamedList& element, bool empty)
7070 {
7071     XmlDomParser::gotElement(element,empty);
7072     if (empty)
7073 	verifyRoot();
7074 }
7075 
endElement(const String & name)7076 void MyDomParser::endElement(const String& name)
7077 {
7078     XmlDomParser::endElement(name);
7079     verifyRoot();
7080 }
7081 
verifyRoot()7082 void MyDomParser::verifyRoot()
7083 {
7084     if (m_app && document() && document()->root() && document()->root()->completed()) {
7085 	m_app->receivedXML(document());
7086 	document()->reset();
7087     }
7088 }
7089 
7090 /**
7091  * XMLConnection
7092  */
XMLConnection(Socket * skt,TcapXApplication * app)7093 XMLConnection::XMLConnection(Socket* skt, TcapXApplication* app)
7094     : Thread("XMLConnection"),
7095       m_socket(skt), m_app(app),
7096       m_parser(app,"MyDomParser",false)
7097 {
7098     Debug(&__plugin,DebugAll,"XMLConnection created with socket=[%p] for application=%s[%p] [%p]",skt,app->toString().c_str(),app,this);
7099     m_app->ref();
7100     start();
7101 }
7102 
~XMLConnection()7103 XMLConnection::~XMLConnection()
7104 {
7105     Debug(&__plugin,DebugAll,"XMLConnection destroyed [%p]",this);
7106     if (m_socket){
7107 	delete m_socket;
7108 	m_socket = 0;
7109     }
7110     TelEngine::destruct(m_app);
7111 }
7112 
start()7113 void XMLConnection::start()
7114 {
7115     Debug(&__plugin,DebugAll,"XMLConnection start [%p]",this);
7116     m_socket->setBlocking(false);
7117 }
7118 
run()7119 void XMLConnection::run()
7120 {
7121     if (!m_socket)
7122 	return;
7123     char buffer[2048];
7124     for (;;) {
7125 	if (!(m_socket && m_socket->valid()))
7126 	    break;
7127 
7128 	Thread::check();
7129 	bool readOk = false, error = false;
7130 	if (!m_socket->select(&readOk,0,&error,idleUsec()))
7131 	    continue;
7132 
7133 	if (!readOk || error) {
7134 	    if (error) {
7135 		if (m_socket->error())
7136 		    Debug(&__plugin,DebugInfo,"XMLConnection[%p] : Reading data error: %s (%d)",this,strerror(m_socket->error()),
7137 			m_socket->error());
7138 		return;
7139 	    }
7140 	    continue;
7141 	}
7142 	int readSize = m_socket->readData(buffer,sizeof(buffer));
7143 	if (!readSize) {
7144 	    if (m_socket->canRetry()) {
7145 		idle(true);
7146 		continue;
7147 	    }
7148 	    return;
7149 	}
7150 	else if (readSize < 0) {
7151 	    if (m_socket->canRetry()) {
7152 		idle(true);
7153 		continue;
7154 	    }
7155 	    cancel();
7156 	    Debug(&__plugin,DebugWarn,"Read error %s(%d) on socket %p in XMLConnection[%p]",strerror(m_socket->error()),
7157 		    m_socket->error(),m_socket,this);
7158 	    break;
7159 	}
7160 
7161 	buffer[readSize] = 0;
7162 	XDebug(&__plugin,DebugAll,"READ %d : %s",readSize,buffer);
7163 
7164 	if (!m_parser.parse(buffer)) {
7165 	    if (m_parser.error() != XmlSaxParser::Incomplete) {
7166 		Debug(&__plugin,DebugWarn,"Parser error %s in read data [%p] unparsed type %d, buffer = %s, pushed = %s",
7167 		    m_parser.getError(),this,m_parser.unparsed(),m_parser.getBuffer().c_str(),buffer);
7168 		break;
7169 	    }
7170 	}
7171     }
7172 }
7173 
cleanup()7174 void XMLConnection::cleanup()
7175 {
7176     DDebug(&__plugin,DebugAll,"XMLConnection::cleanup() [%p]",this);
7177     m_app->setIO(0);
7178 }
7179 
writeData(XmlFragment * elem)7180 bool XMLConnection::writeData(XmlFragment* elem)
7181 {
7182     if (!elem)
7183 	return false;
7184 
7185     String xml;
7186     elem->toString(xml,true);
7187     XDebug(&__plugin,DebugAll,"WRITE : %s",xml.c_str());
7188     int len = xml.length();
7189     const char* buffer = xml.c_str();
7190     while (m_socket && (len > 0)) {
7191 	bool writeOk = false,error = false;
7192 	if (!m_socket->select(0,&writeOk,&error,idleUsec()) || error) {
7193 	    if (!m_socket->canRetry())
7194 		return false;
7195 	    continue;
7196 	}
7197 	if (!writeOk )
7198 	    continue;
7199 	int w = m_socket->writeData(buffer,len);
7200 	if (w < 0) {
7201 	    if (!m_socket->canRetry()) {
7202 		Debug(&__plugin,DebugWarn,"XMLConnection::writeData(xml=[%p]) [%p] on socket [%p] could not write error : %s",
7203 		    elem,this,m_socket,strerror(m_socket->error()));
7204 		cancel();
7205 		return false;
7206 	    }
7207 	}
7208 	else {
7209 	    buffer += w;
7210 	    len -= w;
7211 	}
7212     }
7213     return true;
7214 }
7215 
7216 
7217 
7218 /**
7219  * XMLConnListener
7220  */
XMLConnListener(TcapXUser * user,const NamedList & sect)7221 XMLConnListener::XMLConnListener(TcapXUser* user, const NamedList& sect)
7222     : Thread("XMLConnListener"),
7223       m_user(user)
7224 {
7225     Debug(&__plugin,DebugAll,"XMLConnListener [%p] created",this);
7226     m_host = sect.getValue(YSTRING("host"),"127.0.0.1");
7227     m_port = sect.getIntValue(YSTRING("port"),5555);
7228 }
7229 
~XMLConnListener()7230 XMLConnListener::~XMLConnListener()
7231 {
7232     Debug(&__plugin,DebugAll,"XMLConnListener [%p] destroyed",this);
7233     m_user = 0;
7234 }
7235 
init()7236 bool XMLConnListener::init()
7237 {
7238     SocketAddr addr;
7239 
7240     if (!addr.assign(AF_INET) || !addr.host(m_host) || !addr.port(m_port)) {
7241 	Debug(m_user,DebugWarn,"Could not assign address=%s:%d for user listener=%s [%p]",m_host.c_str(),m_port,
7242 	    m_user->toString().c_str(),this);
7243 	return false;
7244     }
7245 
7246     if (!m_socket.create(addr.family(),SOCK_STREAM)) {
7247 	Debug(m_user,DebugWarn, "Could not create socket for user listener=%s [%p] error %d: %s",
7248 	    m_user->toString().c_str(),this,m_socket.error(),strerror(m_socket.error()));
7249 	return false;
7250     }
7251 
7252     m_socket.setReuse();
7253 
7254     if (!m_socket.bind(addr)) {
7255 	Debug(m_user,DebugWarn,"Could not bind user listener=%s [%p] error %d: %s",
7256 	    m_user->toString().c_str(),this,m_socket.error(),strerror(m_socket.error()));
7257 	return false;
7258     }
7259     if (!m_socket.setBlocking(false) || !m_socket.listen())
7260 	return false;
7261 
7262     return startup();
7263 }
7264 
run()7265 void XMLConnListener::run()
7266 {
7267     for (;;) {
7268 	Thread::check();
7269 	idle();
7270 	SocketAddr address;
7271 	Socket* newSocket = m_socket.accept(address);
7272 	if (!newSocket) {
7273 	    if (m_socket.canRetry())
7274 		continue;
7275 	    Debug(m_user,DebugWarn,"Accept error: %s",strerror(m_socket.error()));
7276 	    break;
7277 	}
7278 	else {
7279 	    String addr(address.host());
7280 	    addr << ":" << address.port();
7281 	    if (!createConn(newSocket,addr))
7282 		Debug(m_user,DebugInfo,"Connection from %s rejected",addr.c_str());
7283 	}
7284     }
7285 }
7286 
createConn(Socket * skt,String & addr)7287 bool XMLConnListener::createConn(Socket* skt, String& addr)
7288 {
7289     if (!skt->valid()) {
7290 	delete skt;
7291 	return false;
7292     }
7293     if (!skt->setBlocking(false)) {
7294 	Debug(m_user,DebugCrit, "Failed to set TCP socket to nonblocking mode: %s",
7295 	    strerror(skt->error()));
7296 	delete skt;
7297 	return false;
7298     }
7299     if (m_user && !m_user->createApplication(skt,addr)) {
7300 	delete skt;
7301 	return false;
7302     }
7303     return true;
7304 }
7305 
cleanup()7306 void XMLConnListener::cleanup()
7307 {
7308     DDebug(m_user,DebugAll,"XMLConnListener::cleanup() [%p]",this);
7309     m_user->setListener(0);
7310 }
7311 
7312 /**
7313  * TcapToXml
7314  */
7315 const XMLMap TcapToXml::s_xmlMap[] = {
7316     {Regexp("^state$"),                                        "state",                                 "",                          TcapToXml::Value},
7317     {Regexp("^error$"),                                        "error",                                 "",                          TcapToXml::Value},
7318     {Regexp("^LocalPC$"),                                      "transport.mtp",                         "",                          TcapToXml::Element},
7319     {Regexp("^RemotePC$"),                                     "transport.mtp",                         "",                          TcapToXml::Element},
7320     {Regexp("^sls$"),                                          "transport.mtp",                         "",                          TcapToXml::Element},
7321     {Regexp("^ReturnCause$"),                                  "transport.sccp",                        "ReturnCause",               TcapToXml::Element},
7322     {Regexp("^HopCounter$"),                                   "transport.sccp",                        "HopCounter",                TcapToXml::Element},
7323     {Regexp("^CallingPartyAddress\\.gt\\.encoding$"),          "transport.sccp.CallingPartyAddress.gt", "encoding",                  TcapToXml::Attribute},
7324     {Regexp("^CallingPartyAddress\\.gt\\.plan$"),              "transport.sccp.CallingPartyAddress.gt", "plan",                      TcapToXml::Attribute},
7325     {Regexp("^CallingPartyAddress\\.gt\\.nature$"),            "transport.sccp.CallingPartyAddress.gt", "nature",                    TcapToXml::Attribute},
7326     {Regexp("^CallingPartyAddress\\.gt\\.translation$"),       "transport.sccp.CallingPartyAddress.gt", "translation",               TcapToXml::Attribute},
7327     {Regexp("^CallingPartyAddress\\.gt$"),                     "transport.sccp.CallingPartyAddress",    "gt",                        TcapToXml::Element},
7328     {Regexp("^CallingPartyAddress\\.ssn$"),                    "transport.sccp.CallingPartyAddress",    "ssn",                       TcapToXml::Element},
7329     {Regexp("^CallingPartyAddress\\.route$"),                  "transport.sccp.CallingPartyAddress",    "route",                     TcapToXml::Element},
7330     {Regexp("^CallingPartyAddress\\.pointcode$"),              "transport.sccp.CallingPartyAddress",    "pointcode",                 TcapToXml::Element},
7331     {Regexp("^CallingPartyAddress\\..\\+$"),                   "transport.sccp.CallingPartyAddress",    "",                          TcapToXml::Element},
7332     {Regexp("^CalledPartyAddress\\.gt\\.encoding$"),           "transport.sccp.CalledPartyAddress.gt",  "encoding",                  TcapToXml::Attribute},
7333     {Regexp("^CalledPartyAddress\\.gt\\.plan$"),               "transport.sccp.CalledPartyAddress.gt",  "plan",                      TcapToXml::Attribute},
7334     {Regexp("^CalledPartyAddress\\.gt\\.nature$"),             "transport.sccp.CalledPartyAddress.gt",  "nature",                    TcapToXml::Attribute},
7335     {Regexp("^CalledPartyAddress\\.gt\\.translation$"),        "transport.sccp.CalledPartyAddress.gt",  "translation",               TcapToXml::Attribute},
7336     {Regexp("^CalledPartyAddress\\.gt$"),                      "transport.sccp.CalledPartyAddress",     "gt",                        TcapToXml::Element},
7337     {Regexp("^CalledPartyAddress\\.ssn$"),                     "transport.sccp.CalledPartyAddress",     "ssn",                       TcapToXml::Element},
7338     {Regexp("^CalledPartyAddress\\.route$"),                   "transport.sccp.CalledPartyAddress",     "route",                     TcapToXml::Element},
7339     {Regexp("^CalledPartyAddress\\.pointcode$"),               "transport.sccp.CalledPartyAddress",     "pointcode",                 TcapToXml::Element},
7340     {Regexp("^CalledPartyAddress\\..\\+$"),                    "transport.sccp.CalledPartyAddress",     "",                          TcapToXml::Element},
7341     {Regexp("^tcap\\.request\\.type$"),                        "transport.tcap",                        "request-type",              TcapToXml::Element},
7342     {Regexp("^tcap\\.transaction\\.localTID$"),                "transport.tcap",                        "localTID",                  TcapToXml::Element},
7343     {Regexp("^tcap\\.transaction\\.remoteTID$"),               "transport.tcap",                        "remoteTID",                 TcapToXml::Element},
7344     {Regexp("^tcap\\.transaction\\.abort\\.cause$"),           "transport.tcap",                        "abort-cause",               TcapToXml::Element},
7345     {Regexp("^tcap\\.transaction\\.abort\\.information$"),     "transport.tcap",                        "abort-information",         TcapToXml::Element},
7346     {Regexp("^tcap\\.transaction\\..\\+$"),                    "transport.tcap",                        "",                          TcapToXml::Element},
7347     {Regexp("^tcap\\.dialogPDU\\.application-context-name$"),  "application",                           "",                          TcapToXml::Value},
7348     {Regexp("^tcap\\.dialogPDU\\.dialog-pdu-type$"),           "transport.tcap.dialog",                 "type",                      TcapToXml::Attribute},
7349     {Regexp("^tcap\\.dialogPDU\\.protocol-version$"),          "transport.tcap.dialog",                 "version",                   TcapToXml::Attribute},
7350     {Regexp("^tcap\\.dialogPDU\\.abort-source$"),              "transport.tcap.dialog",                 "abort-source",              TcapToXml::Element},
7351     {Regexp("^tcap\\.dialogPDU\\.result$"),                    "transport.tcap.dialog",                 "result",                    TcapToXml::Element},
7352     {Regexp("^tcap\\.dialogPDU\\.result-source-diagnostic$"),  "transport.tcap.dialog",                 "result-source-diagnostic",  TcapToXml::Element},
7353     {Regexp("^tcap\\.dialogPDU\\.userInformation\\.direct-reference$"), "transport.tcap.dialog.userInformation", "direct-reference", TcapToXml::Element},
7354     {Regexp("^tcap\\.dialogPDU\\.userInformation\\.encoding-contents$"),"transport.tcap.dialog.userInformation", "encoding-contents",TcapToXml::Element},
7355     {Regexp("^tcap\\.dialogPDU\\.userInformation\\.encoding-type$"),    "transport.tcap.dialog.userInformation", "encoding-type",    TcapToXml::Element},
7356     {Regexp("^tcap\\.dialogPDU\\.userInformation\\..\\+$"),    "transport.tcap.dialog.userInformation", "",                          TcapToXml::Element},
7357     {Regexp("^tcap\\.component\\.count$"),                     "",                                      "",                          TcapToXml::None},
7358     {Regexp("^tcap\\.component\\..\\+\\.localCID$"),           "component",                             "",                          TcapToXml::Attribute},
7359     {Regexp("^tcap\\.component\\..\\+\\.remoteCID$"),          "component",                             "",                          TcapToXml::Attribute},
7360     {Regexp("^tcap\\.component\\..\\+\\.componentType$"),      "component",                             "type",                      TcapToXml::Attribute},
7361     {Regexp("^tcap\\.component\\..\\+\\.operationCode$"),      "component",                             "",                          TcapToXml::Attribute},
7362     {Regexp("^tcap\\.component\\..\\+\\.operationCodeType$"),  "",                                      "",                          TcapToXml::None},
7363     {Regexp("^tcap\\.component\\..\\+\\.errorCode$"),          "component",                             "",                          TcapToXml::Attribute},
7364     {Regexp("^tcap\\.component\\..\\+\\.errorCodeType$"),      "",                                      "",                          TcapToXml::None},
7365     {Regexp("^tcap\\.component\\..\\+\\.problemCode$"),        "component",                             "",                          TcapToXml::Attribute},
7366     {Regexp("^tcap\\.component\\..\\+\\.operationClass$"),     "component",                             "",                          TcapToXml::Attribute},
7367     {Regexp("^tcap\\.component\\..\\+\\..\\+"),                "component",                             "",                          TcapToXml::NewElement},
7368     {Regexp(""),                                               "",                                      "",                          TcapToXml::End},
7369 };
7370 
7371 
TcapToXml(TcapXApplication * app)7372 TcapToXml::TcapToXml(TcapXApplication* app)
7373     : Mutex(false,"TcapToXml"),
7374       m_app(app), m_type(Unknown)
7375 {
7376     DDebug(&__plugin,DebugAll,"TcapToXml created for application=%s[%p] [%p]",m_app->toString().c_str(),m_app,this);
7377 }
7378 
~TcapToXml()7379 TcapToXml::~TcapToXml()
7380 {
7381     DDebug(&__plugin,DebugAll,"TcapToXml destroyed [%p]",this);
7382     reset();
7383 }
7384 
reset()7385 void TcapToXml::reset()
7386 {
7387     m_type = Unknown;
7388 }
7389 
findMap(String & what)7390 const XMLMap* TcapToXml::findMap(String& what)
7391 {
7392     XDebug(&__plugin,DebugAll,"TcapToXml::findMap(%s) [%p]",what.c_str(),this);
7393     const XMLMap* map = s_xmlMap;
7394     while (map->type != End) {
7395 	if (what.matches(map->name))
7396 	    return map;
7397 	map++;
7398     }
7399     return 0;
7400 }
7401 
buildXMLMessage(NamedList & params,XmlFragment * msg,MsgType type,const AppCtxt * ctxt)7402 bool TcapToXml::buildXMLMessage(NamedList& params, XmlFragment* msg, MsgType type, const AppCtxt* ctxt)
7403 {
7404     DDebug(&__plugin,DebugAll,"TcapToXML::buildXMLMessage() [%p]",this);
7405     if (!msg)
7406 	return false;
7407     XmlDeclaration* decl = new XmlDeclaration();
7408     msg->addChild(decl);
7409     XmlElement* el = new XmlElement(s_msgTag);
7410     el->setXmlns("",true,s_namespace);
7411     msg->addChild(el);
7412 
7413     AppCtxt* appCtxt = 0;
7414     NamedString* ctxtStr = params.getParam(s_tcapAppCtxt);
7415     if (!TelEngine::null(ctxtStr)) {
7416 	const AppCtxt* contexts = (m_app->type() == TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt);
7417 	appCtxt = (AppCtxt*)findCtxtFromOid(*ctxtStr,contexts);
7418     }
7419     if (appCtxt)
7420 	params.setParam(s_tcapAppCtxt,appCtxt->name);
7421 
7422     // translate P-Abort causes
7423     NamedString* param = params.getParam(s_tcapAbortCause);
7424     if (!TelEngine::null(param) && (*param) == "pAbort") {
7425 	int code = params.getIntValue(s_tcapAbortInfo);
7426 	params.setParam(s_tcapAbortInfo,lookup(code,SS7TCAPError::s_errorTypes,*param));
7427     }
7428 
7429     if (m_app->type() == TcapXUser::MAP && !TelEngine::null(params.getParam(s_tcapDirectReference)))
7430 	handleMAPDialog(el,params);
7431 
7432     for (unsigned int i = 0; i < params.count(); i++) {
7433 	NamedString* ns = params.getParam(i);
7434 	if (TelEngine::null(ns))
7435 	    continue;
7436 	if (ns->name().startsWith(s_tcapCompPrefixSep))
7437 	    continue;
7438 	const XMLMap* map = findMap((String&)ns->name());
7439 	if (!map)
7440 	    continue;
7441 	addToXml(el,map,ns);
7442     }
7443 
7444     addComponentsToXml(el,params,ctxt);
7445     return true;
7446 }
7447 
handleMAPDialog(XmlElement * root,NamedList & params)7448 void TcapToXml::handleMAPDialog(XmlElement* root, NamedList& params)
7449 {
7450     if (!root)
7451 	return;
7452     XDebug(&__plugin,DebugAll,"TcapToXml::handleMAPDialog(root=%p) [%p]",root,this);
7453     NamedString* param = params.getParam(s_tcapDirectReference);
7454     if (TelEngine::null(param))
7455 	return;
7456     const AppCtxt* mapCtxt = findCtxtFromOid(*param,s_mapDialogCtxt);
7457     // we don't know the context, leave it alone
7458     if (!mapCtxt)
7459 	return;
7460     if (mapCtxt)
7461 	params.setParam(s_tcapDirectReference,mapCtxt->name);
7462     param = params.getParam(s_tcapEncodingContent);
7463     if (TelEngine::null(param))
7464 	return;
7465     const XMLMap* map = findMap((String&)s_tcapEncodingContent);
7466     if (!map)
7467 	return;
7468     XmlElement* parent = addToXml(root,map,&s_encodingPath);
7469     if (!parent)
7470 	return;
7471     DataBlock db;
7472     db.unHexify(param->c_str(),param->length(),' ');
7473     if (decodeDialogPDU(parent,mapCtxt,db)) {
7474 	params.clearParam(s_tcapEncodingContent);
7475     }
7476 }
7477 
decodeDialogPDU(XmlElement * el,const AppCtxt * ctxt,DataBlock & data)7478 bool TcapToXml::decodeDialogPDU(XmlElement* el, const AppCtxt* ctxt, DataBlock& data)
7479 {
7480     if (!(el && ctxt))
7481 	return false;
7482     XDebug(&__plugin,DebugAll,"TcapToXml::decodeDialogPDU(el=%p) [%p]",el,this);
7483     const Parameter* param = s_mapDialogChoice;
7484     int err = TcapXApplication::NoError;
7485     while (param && param->name) {
7486 	AsnTag tag;
7487 	AsnTag::decode(tag,data);
7488 	if (decodeParam(param,tag,data,el,m_app->addEncoding(),err)) {
7489 	    bool ok = (0 != ctxt->ops.find(param->name));
7490 	    if (!ok)
7491 		el->clearChildren();
7492 	    return ok;
7493 	}
7494 	param++;
7495     }
7496     if (data.length())
7497 	decodeRaw(el,data);
7498     return true;
7499 }
7500 
addToXml(XmlElement * root,const XMLMap * map,NamedString * val)7501 XmlElement* TcapToXml::addToXml(XmlElement* root, const XMLMap* map, NamedString* val)
7502 {
7503     if (!(root && map && val))
7504 	return 0;
7505     if (map->type == None)
7506 	return 0;
7507     XDebug(&__plugin,DebugAll,"TcapToXml::addToXml(frag=%p, map=%s[%p], val=%s[%p]) [%p]",root,map->map,map,val->name().c_str(),val,this);
7508     String mapStr = map->map;
7509     ObjList* path = mapStr.split('.',false);
7510     XmlElement* parent = root;
7511 
7512     for (ObjList* o = path->skipNull(); o; o = o->skipNext()) {
7513 	String* elem = static_cast<String*>(o->get());
7514 	if (TelEngine::null(elem))
7515 	    continue;
7516 	XmlElement* child = parent->findFirstChild(elem);
7517 	if (!child) {
7518 	    child = new XmlElement(*elem);
7519 	    parent->addChild(child);
7520 	}
7521 	parent = child;
7522     }
7523 
7524     if (parent) {
7525 	// add to parent child element if map is elem, or attr if map si attribute
7526 	XmlElement* child = 0;
7527 
7528 	String tag;
7529 	if (TelEngine::null(map->tag)) {
7530 	    tag = val->name();
7531 	    if (tag.find('.') > -1 && tag.startsWith(map->name))
7532 		tag.startSkip(map->name,false);
7533 	    replace(tag,'.','-');
7534 	}
7535 	else
7536 	    tag = map->tag;
7537 	switch (map->type) {
7538 	    case Element:
7539 		child = parent->findFirstChild(&tag);
7540 		if (child) {
7541 		    child->addText(*val);
7542 		    parent = child;
7543 		    break;
7544 		}
7545 		// fall through and create new child if not found
7546 	    case NewElement:
7547 		child = new XmlElement(tag);
7548 		child->addText(*val);
7549 		parent->addChild(child);
7550 		parent = child;
7551 		break;
7552 	    case Value:
7553 		parent->addText(*val);
7554 		break;
7555 	    case Attribute:
7556 		parent->setAttributeValid(tag,*val);
7557 		break;
7558 	    case None:
7559 	    default:
7560 		break;
7561 	}
7562     }
7563     TelEngine::destruct(path);
7564     return parent;
7565 }
7566 
addComponentsToXml(XmlElement * el,NamedList & params,const AppCtxt * ctxt)7567 void TcapToXml::addComponentsToXml(XmlElement* el, NamedList& params, const AppCtxt* ctxt)
7568 {
7569     if (!el)
7570 	return;
7571     DDebug(&__plugin,DebugAll,"TcapToXml::addComponentsToXml(el=%p, params=%p) [%p]",el,&params,this);
7572     int count = params.getIntValue(s_tcapCompCount);
7573     for (int i = 1; i <= count; i++) {
7574 	XmlElement* comp = new XmlElement(s_component);
7575 	el->addChild(comp);
7576 
7577 	String root;
7578 	root << s_tcapCompPrefix << "." << String(i);
7579 	NamedList compParams("");
7580 	compParams.copyParam(params,root,'.');
7581 
7582 	NamedString* opCode = params.getParam(root + "." + s_tcapOpCode);
7583 	NamedString* opType = params.getParam(root + "." + s_tcapOpCodeType);
7584 	Operation* op = 0;
7585 	if (!TelEngine::null(opCode) && !TelEngine::null(opType))
7586 	    op = (Operation*)findOperation(m_app->type(),opCode->toInteger(),(*opType == "local"),ctxt);
7587 	if (op) {
7588 	    compParams.setParam(root + "." + s_tcapOpCode,op->name);
7589 	    if (op->opClass > -1)
7590 		compParams.setParam(root + "." + s_tcapOpClass,lookup(op->opClass,SS7TCAP::s_compOperClasses,"reportAll"));
7591 	}
7592 
7593 	int compType = SS7TCAP::lookupComponent(params.getValue(root + "." + s_tcapCompType));
7594 
7595 	bool searchArgs = true;
7596 	switch (compType) {
7597 	    case SS7TCAP::TC_Invoke:
7598 	    case SS7TCAP::TC_ResultLast:
7599 	    case SS7TCAP::TC_ResultNotLast:
7600 		searchArgs = (compType == SS7TCAP::TC_Invoke);
7601 		break;
7602 	    case SS7TCAP::TC_U_Error:
7603 		opCode = params.getParam(root + "." + s_tcapErrCode);
7604 		opType = params.getParam(root + "." + s_tcapErrCodeType);
7605 		if (!TelEngine::null(opCode) && !TelEngine::null(opType))
7606 		    op = (Operation*)findError(m_app->type(),opCode->toInteger(),(*opType == "local"));
7607 		if (op)
7608 		    compParams.setParam(root + "." + s_tcapErrCode,op->name);
7609 		break;
7610 	    case SS7TCAP::TC_R_Reject:
7611 	    case SS7TCAP::TC_U_Reject:
7612 	    case SS7TCAP::TC_L_Reject:
7613 		    compParams.setParam(root + "." + s_tcapProblemCode,
7614 			    lookup(params.getIntValue(root + "." + s_tcapProblemCode),SS7TCAPError::s_errorTypes));
7615 		break;
7616 	    default:
7617 		break;
7618 	}
7619 	for (unsigned int j = 0; j < compParams.count(); j++) {
7620 	    NamedString* ns = compParams.getParam(j);
7621 	    if (TelEngine::null(ns))
7622 		continue;
7623 
7624 	    const XMLMap* map = findMap((String&)ns->name());
7625 	    if (!map)
7626 		continue;
7627 	    XmlElement* child;
7628 	    int pos = ns->name().rfind('.');
7629 	    String tag = ns->name().substr(pos + 1);
7630 	    tag = (TelEngine::null(map->tag) ? tag : (String)map->tag);
7631 	    switch (map->type) {
7632 		case Element:
7633 		    child = new XmlElement(tag);
7634 		    child->addText(*ns);
7635 		    comp->addChild(child);
7636 		    break;
7637 		case Value:
7638 		    comp->addText(*ns);
7639 		    break;
7640 		case Attribute:
7641 		    comp->setAttributeValid(tag,*ns);
7642 		    break;
7643 		case None:
7644 		default:
7645 		    break;
7646 	    }
7647 	}
7648 	NamedString* payloadHex = params.getParam(root);
7649 	if (TelEngine::null(payloadHex))
7650 	    continue;
7651 	addParametersToXml(comp,*payloadHex,op,searchArgs);
7652     }
7653 }
7654 
addParametersToXml(XmlElement * elem,String & payloadHex,Operation * op,bool searchArgs)7655 void TcapToXml::addParametersToXml(XmlElement* elem, String& payloadHex, Operation* op, bool searchArgs)
7656 {
7657     if (!elem)
7658 	return;
7659     DDebug(&__plugin,DebugAll,"TcapToXml::addParametersToXml(elem=%s[%p], payload=%s, op=%s[%p], searchArgs=%s) [%p]",
7660 	    elem->getTag().c_str(),elem,payloadHex.c_str(),(op ? op->name.c_str() : ""),op,String::boolText(searchArgs),this);
7661 
7662     DataBlock data;
7663     if (!data.unHexify(payloadHex.c_str(),payloadHex.length(),' ')) {
7664 	DDebug(&__plugin,DebugAll,"TcapToXml::addParamtersToXml() invalid hexified payload=%s [%p]",payloadHex.c_str(),this);
7665 	return;
7666     }
7667     if (elem->getTag() == s_component) {
7668 	AsnTag tag = (op ? (searchArgs ? op->argTag : op->retTag) : s_noTag);
7669 	AsnTag decTag;
7670 	AsnTag::decode(decTag,data);
7671 	if (op && tag != decTag) {
7672 	    if (tag != s_noTag)
7673 		op = 0;
7674 	}
7675 	if (decTag.type() == AsnTag::Constructor && tag == decTag) { // initial constructor
7676 	    data.cut(-(int)decTag.coding().length());
7677 	    int len = ASNLib::decodeLength(data);
7678 	    if (len != (int)data.length())
7679 		return;
7680 	}
7681 
7682     }
7683     decodeTcapToXml(elem,data,op,0,searchArgs);
7684 }
7685 
decodeTcapToXml(XmlElement * elem,DataBlock & data,Operation * op,unsigned int index,bool searchArgs)7686 void TcapToXml::decodeTcapToXml(XmlElement* elem, DataBlock& data, Operation* op, unsigned int index, bool searchArgs)
7687 {
7688     DDebug(&__plugin,DebugAll,"TcapToXml::decodeTcapToXml(elem=%s[%p],op=%s[%p], searchArgs=%s) [%p]",
7689 	    elem->getTag().c_str(),elem,(op ? op->name.c_str() : ""),op,String::boolText(searchArgs),this);
7690     if (!data.length() || !elem)
7691 	return;
7692 
7693     if (op)
7694 	decodeOperation(op,elem,data,searchArgs);
7695     else
7696 	decodeRaw(elem,data);
7697 }
7698 
decodeOperation(Operation * op,XmlElement * elem,DataBlock & data,bool searchArgs)7699 bool TcapToXml::decodeOperation(Operation* op, XmlElement* elem, DataBlock& data, bool searchArgs)
7700 {
7701     if (!(op && elem && m_app))
7702 	return false;
7703 
7704     const Parameter* param = (searchArgs ? op->args : op->res);
7705     AsnTag opTag = (searchArgs ? op->argTag : op->retTag);
7706     int err = TcapXApplication::NoError;
7707     while (param && !TelEngine::null(param->name)) {
7708 	AsnTag tag;
7709 	AsnTag::decode(tag,data);
7710 	if (!decodeParam(param,tag,data,elem,m_app->addEncoding(),err)) {
7711 	    if (!param->isOptional && (err != TcapXApplication::DataMissing)) {
7712 		if (opTag == s_noTag) {
7713 		    const Parameter* tmp = param;
7714 		    if ((++tmp) && TelEngine::null(tmp->name))
7715 			printMissing(param->name.c_str(),elem->tag(),false);
7716 		}
7717 		else
7718 		    printMissing(param->name.c_str(),elem->tag(),false);
7719 	    }
7720 	}
7721 	else if (opTag == s_noTag) // should be only one child
7722 		break;
7723 	param++;
7724     }
7725     if (data.length())
7726 	decodeRaw(elem,data);
7727     return true;
7728 }
7729 
7730 /**
7731  * XmlToTcap
7732  */
7733 
7734 const TCAPMap XmlToTcap::s_tcapMap[] = {
7735     {"c",                                                 false,   ""},
7736     {"transport.mtp.",                                    true,    ""},
7737     {"transport.sccp.CallingPartyAddress.gt.",            true,   "CallingPartyAddress.gt"},
7738     {"transport.sccp.CallingPartyAddress.",               true,   "CallingPartyAddress"},
7739     {"transport.sccp.CalledPartyAddress.gt.",             true,   "CalledPartyAddress.gt"},
7740     {"transport.sccp.CalledPartyAddress.",                true,   "CalledPartyAddress"},
7741     {"transport.sccp.",                                   true,   ""},
7742     {"transport.tcap.request-type",                       false,  "tcap.request.type"},
7743     {"transport.tcap.abort-cause",                        false,  "tcap.transaction.abort.cause"},
7744     {"transport.tcap.abort-information",                  false,  "tcap.transaction.abort.information"},
7745     {"transport.tcap.dialog.type",                        false,  "tcap.dialogPDU.dialog-pdu-type"},
7746     {"transport.tcap.dialog.version",                     false,  "tcap.dialogPDU.protocol-version"},
7747     {"transport.tcap.dialog.userInformation",             true,   "tcap.dialogPDU.userInformation"},
7748     {"transport.tcap.dialog.",                            true,   "tcap.dialogPDU"},
7749     {"transport.tcap.",                                   true,   "tcap.transaction"},
7750     {"application",                                       false,  "tcap.dialogPDU.application-context-name"},
7751     {0, ""},
7752 };
7753 
XmlToTcap(TcapXApplication * app)7754 XmlToTcap::XmlToTcap(TcapXApplication* app)
7755     : Mutex(false,"XmlToTcap"),
7756       m_app(app), m_decl(0), m_elem(0)
7757 {
7758     DDebug(&__plugin,DebugAll,"XmlToTcap created for application=%s[%p] [%p]",m_app->toString().c_str(),m_app,this);
7759 }
~XmlToTcap()7760 XmlToTcap::~XmlToTcap()
7761 {
7762     DDebug(&__plugin,DebugAll,"XmlToTcap destroyed [%p]",this);
7763     reset();
7764 }
7765 
reset()7766 void XmlToTcap::reset()
7767 {
7768     m_elem = 0;
7769     m_decl = 0;
7770     m_type = Unknown;
7771 }
7772 
findMap(String & path)7773 const TCAPMap* XmlToTcap::findMap(String& path)
7774 {
7775     XDebug(&__plugin,DebugAll,"XmlToTcap::findMap(%s) [%p]",path.c_str(),this);
7776     const TCAPMap* map = s_tcapMap;
7777     while (map && map->path) {
7778 	if (path == map->path || path.startsWith(map->path))
7779 	    return map;
7780 	map++;
7781     }
7782     return 0;
7783 }
7784 
validDeclaration()7785 bool XmlToTcap::validDeclaration()
7786 {
7787     Lock l(this);
7788     if (!m_decl)
7789 	return false;
7790     DDebug(&__plugin,DebugAll,"XmlToTcap::validDeclaration() [%p]",this);
7791     const NamedList& decl = m_decl->getDec();
7792     NamedString* vers = decl.getParam(YSTRING("version"));
7793     NamedString* enc = decl.getParam(YSTRING("encoding"));
7794     if ((!TelEngine::null(vers) && (*vers != "1.0")) || (!TelEngine::null(enc) && (*enc |= "UTF-8")))
7795 	return false;
7796     return true;
7797 }
7798 
checkXmlns()7799 bool XmlToTcap::checkXmlns()
7800 {
7801     Lock l(this);
7802     if (!m_elem)
7803 	return false;
7804     String* xmlns = m_elem->xmlns();
7805     if (TelEngine::null(xmlns)) {
7806 	if (m_app->state() == TcapXApplication::Waiting)
7807 	    return false;
7808     }
7809     else {
7810 	if (s_namespace != *xmlns)
7811 	    return false;
7812     }
7813     return true;
7814 }
7815 
7816 
valid(XmlDocument * doc)7817 bool XmlToTcap::valid(XmlDocument* doc)
7818 {
7819     Lock l(this);
7820     if (!doc)
7821 	return false;
7822     DDebug(&__plugin,DebugAll,"XmlToTcap::valid() [%p]",this);
7823     reset();
7824     m_decl = doc->declaration();
7825     m_elem = doc->root();
7826     if (!(m_elem && m_elem->getTag() == s_msgTag))
7827 	return false;
7828     return true;
7829 }
7830 
encodeOperation(Operation * op,XmlElement * elem,DataBlock & payload,int & err,bool searchArgs)7831 void XmlToTcap::encodeOperation(Operation* op, XmlElement* elem, DataBlock& payload, int& err, bool searchArgs)
7832 {
7833     if (!(op && elem))
7834 	return;
7835     const Parameter* param = (searchArgs ? op->args : op->res);
7836     AsnTag opTag = (searchArgs ? op->argTag : op->retTag);
7837     while (param && !TelEngine::null(param->name)) {
7838 	DataBlock db;
7839 	err = TcapXApplication::NoError;
7840 	if (!encodeParam(param,db,elem,err)) {
7841 	    if (!param->isOptional && (err != TcapXApplication::DataMissing)) {
7842 		if (opTag == s_noTag) {
7843 		    const Parameter* tmp = param;
7844 		    if ((++tmp) && TelEngine::null(tmp->name))
7845 			printMissing(param->name.c_str(),elem->tag());
7846 		}
7847 		else
7848 		    printMissing(param->name.c_str(),elem->tag());
7849 	    }
7850 	}
7851 	else {
7852 	    payload.append(db);
7853 	    if (opTag == s_noTag)
7854 		break;
7855 	}
7856 	param++;
7857     }
7858     XmlElement* child = elem->pop();
7859     while (child) {
7860 	DataBlock db;
7861 	encodeRaw(param,db,child,err);
7862 	payload.append(db);
7863 	TelEngine::destruct(child);
7864 	child = elem->pop();
7865     }
7866     return;
7867 }
7868 
encodeComponent(DataBlock & payload,XmlElement * elem,bool searchArgs,int & err,Operation * op)7869 bool XmlToTcap::encodeComponent(DataBlock& payload, XmlElement* elem, bool searchArgs, int& err, Operation* op)
7870 {
7871     DDebug(&__plugin,DebugAll,"XmlToTcap::encodeComponent(elem=%p op=%p) [%p]",elem,op,this);
7872     if (!elem)
7873 	return false;
7874 
7875     if (op)
7876 	encodeOperation(op,elem,payload,err,searchArgs);
7877     else if (elem->hasChildren())
7878 	encodeRaw(0,payload,elem,err);
7879 
7880     if (elem->getTag() == s_component) {
7881 	AsnTag tag = ( op ? (searchArgs ? op->argTag : op->retTag) : s_noTag);
7882 	if (tag != s_noTag) {
7883 	    payload.insert(ASNLib::buildLength(payload));
7884 	    payload.insert(tag.coding());
7885 	}
7886     }
7887     return true;
7888 }
7889 
handleComponent(NamedList & tcapParams,XmlElement * elem,const AppCtxt * appCtxt)7890 bool XmlToTcap::handleComponent(NamedList& tcapParams, XmlElement* elem, const AppCtxt* appCtxt)
7891 {
7892     DDebug(&__plugin,DebugAll,"XMLToTcap::handleComponent(params=%p, elem=%p) [%p]",&tcapParams,elem,this);
7893     if (!elem && elem->getTag() == s_component)
7894 	return false;
7895     unsigned int index = tcapParams.getIntValue(s_tcapCompCount) + 1;
7896     String prefix = s_tcapCompPrefix;
7897     prefix << "." << index;
7898 
7899     int type = 0;
7900     const NamedList& comp = elem->attributes();
7901     NamedString* opName = 0;
7902     NamedString* errName = 0;
7903     for (unsigned int i = 0; i < comp.length(); i++) {
7904 	NamedString* ns = comp.getParam(i);
7905 	if (TelEngine::null(ns))
7906 	    continue;
7907 
7908 	if (ns->name() == s_typeStr) {
7909 	    tcapParams.setParam(prefix + "." + s_tcapCompType,*ns);
7910 	    type = SS7TCAP::lookupComponent(*ns);
7911 	}
7912 	else if (ns->name() == s_tcapOpCode)
7913 	    opName = ns;
7914 	else if (ns->name() == s_tcapErrCode)
7915 	    errName = ns;
7916 	else if (ns->name() == s_tcapProblemCode)
7917 	    tcapParams.setParam(prefix + "." + s_tcapProblemCode,String(lookup(*ns,SS7TCAPError::s_errorTypes)));
7918 	else
7919 	    tcapParams.setParam(prefix + "." + ns->name(),*ns);
7920     }
7921 
7922     tcapParams.setParam(s_tcapCompCount,String(index));
7923 
7924     Operation* op = 0;
7925     if (!type) {
7926 	Debug(&__plugin,DebugWarn,"Trying to encode component with index='%u' without component type",index);
7927 	return true;
7928     }
7929     if (type == SS7TCAP::TC_Invoke || type == SS7TCAP::TC_ResultLast || type == SS7TCAP::TC_ResultNotLast) {
7930 	if (opName) {
7931 	    op = (Operation*)findOperation(m_app->type(),*opName,appCtxt);
7932 	    if (!op)
7933 		Debug(&__plugin,DebugMild,"Cannot find operation='%s' in ctxt='%s' [%p]",opName->c_str(),(appCtxt ? appCtxt->name : ""),this);
7934 	    else {
7935 		tcapParams.setParam(prefix + "." + s_tcapOpCode,String(op->code));
7936 		tcapParams.setParam(prefix + "." + s_tcapOpCodeType,(op->local ? "local" : "global"));
7937 	    }
7938 	}
7939 	else {
7940 	    if (type == SS7TCAP::TC_Invoke) {
7941 		Debug(&__plugin,DebugWarn,"Trying to encode Invoke component with index='%u' without operationCode",index);
7942 		return true;
7943 	    }
7944 	}
7945     }
7946     else if (type == SS7TCAP::TC_U_Error) {
7947 	if (!errName) {
7948 	    Debug(&__plugin,DebugWarn,"Trying to encode U_Error component with index='%u' without errorCode",index);
7949 	    return true;
7950 	}
7951 	op = (Operation*)findError(m_app->type(),*errName);
7952 	if (!op)
7953 	    Debug(&__plugin,DebugMild,"Cannot find error='%s' [%p]",errName->c_str(),this);
7954 	else {
7955 	    tcapParams.setParam(prefix + "." + s_tcapErrCode,String(op->code));
7956 	    tcapParams.setParam(prefix + "." + s_tcapErrCodeType,(op->local ? "local" : "global"));
7957 	}
7958     }
7959 
7960     DataBlock payload;
7961     bool searchArgs = (type == SS7TCAP::TC_Invoke || type == SS7TCAP::TC_U_Error ? true : false);
7962 
7963     int err = TcapXApplication::NoError;
7964     if (!encodeComponent(payload,elem,searchArgs,err,op))
7965 	return false;
7966 
7967     String str;
7968     str.hexify(payload.data(),payload.length(),' ');
7969     tcapParams.setParam(prefix,str);
7970 
7971     return true;
7972 }
7973 
handleMAPDialog(NamedList & tcapParams,XmlElement * elem,String prefix)7974 bool XmlToTcap::handleMAPDialog(NamedList& tcapParams, XmlElement* elem, String prefix)
7975 {
7976     DDebug(&__plugin,DebugAll,"XMLToTcap::handleMAPDialog(params=%p, elem=%p, prefix=%s) [%p]",&tcapParams,elem,prefix.c_str(),this);
7977     if (!elem && elem->getTag() != s_userInformation)
7978 	return false;
7979 
7980     XmlElement* content = elem->findFirstChild(&s_encodingContentsTag);
7981     if (!(content && content->findFirstChild()))
7982 	return parse(tcapParams,elem,prefix,0);
7983 
7984     DataBlock payload;
7985     const Parameter* param = s_mapDialogChoice;
7986     int err = TcapXApplication::NoError;
7987     while (param && param->name) {
7988 	DataBlock db;
7989 	if (encodeParam(param,db,content,err)) {
7990 	    payload.append(db);
7991 	    break;
7992 	}
7993 	param++;
7994     }
7995     XmlElement* child = content->pop();
7996     while (child) {
7997 	DataBlock db;
7998 	encodeRaw(param,db,child,err);
7999 	payload.append(db);
8000 	TelEngine::destruct(child);
8001 	child = content->pop();
8002     }
8003     // set encoding contents and encoding contents type
8004     String hexString;
8005     hexString.hexify(payload.data(),payload.length(),' ');
8006     tcapParams.setParam(s_tcapEncodingContent,hexString);
8007     tcapParams.setParam(s_tcapEncodingType,YSTRING("single-ASN1-type-contructor"));
8008 
8009     // set direct reference
8010     XmlElement* reference = elem->findFirstChild(&s_directReferenceTag);
8011     if (reference) {
8012 	const AppCtxt* appCtxt = findCtxtFromStr(reference->getText(),s_mapDialogCtxt);
8013 	if (!appCtxt)
8014 	    tcapParams.setParam(s_tcapDirectReference,reference->getText());
8015 	else
8016 	    tcapParams.setParam(s_tcapDirectReference,appCtxt->oid);
8017     }
8018     else {
8019 	// find reference for decoded param
8020 	const AppCtxt* ctxt = s_mapDialogCtxt;
8021 	while (ctxt && ctxt->name) {
8022 	    bool ok = (param && ctxt->ops.find(param->name));
8023 	    if (ok) {
8024 		tcapParams.setParam(s_tcapDirectReference,ctxt->oid);
8025 		break;
8026 	    }
8027 	}
8028     }
8029     return true;
8030 }
8031 
parse(NamedList & tcapParams)8032 bool XmlToTcap::parse(NamedList& tcapParams)
8033 {
8034     Lock l(this);
8035     XDebug(&__plugin,DebugAll,"XmlToTcap::parse()");
8036     tcapParams.setParam(s_tcapCompCount,String(0));
8037 
8038     XmlElement* ctxtElem = (m_elem ? m_elem->findFirstChild(&s_appContext) : 0);
8039     XmlElement* ltidElem = (m_elem ? m_elem->findFirstChild(&s_localTID) : 0);
8040     XmlElement* rtidElem = (m_elem ? m_elem->findFirstChild(&s_remoteTID) : 0);
8041 
8042     const AppCtxt* appCtxt = 0;
8043     // try to find the associated context for the given ids
8044     if (ltidElem || rtidElem) {
8045 	appCtxt = m_app->findCtxt((ltidElem ? ltidElem->getText() : String::empty()),(rtidElem ? rtidElem->getText() : String::empty()));
8046     }
8047     //if we didn't find a saved context for the current transaction, search context in the XML info
8048     if (!appCtxt && ctxtElem)
8049 	appCtxt = (AppCtxt*)findCtxtFromStr(ctxtElem->getText(),(m_app->type() == TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt));
8050 
8051     bool ok = parse(tcapParams,m_elem,"",appCtxt);
8052     NamedString* c = tcapParams.getParam(s_capabTag);
8053 
8054     if (!c) {
8055 	c = tcapParams.getParam(s_tcapReqType);
8056 	if (c) {
8057 	    m_type = Tcap;
8058 	    // retrieve application context
8059 	    NamedString* ctxt = tcapParams.getParam(s_tcapAppCtxt);
8060 	    if (!TelEngine::null(ctxt)) {
8061 		const AppCtxt* search = (m_app->type() == TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt);
8062 		AppCtxt* appCtxt = (AppCtxt*)findCtxtFromStr(*ctxt,search);
8063 		if (appCtxt)
8064 		    tcapParams.setParam(s_tcapAppCtxt,appCtxt->oid);
8065 	    }
8066 	    // retrieve MAP dialog context
8067 	    ctxt = tcapParams.getParam(s_tcapDirectReference);
8068 	    if (!TelEngine::null(ctxt)) {
8069 		const AppCtxt* search = (m_app->type() == TcapXUser::MAP ? s_mapDialogCtxt : 0);
8070 		AppCtxt* appCtxt = (AppCtxt*)findCtxtFromStr(*ctxt,search);
8071 		if (appCtxt)
8072 		    tcapParams.setParam(s_tcapDirectReference,appCtxt->oid);
8073 	    }
8074 	    // we shoudn't receive P_Abort from application, but make sure anyway
8075 	    ctxt = tcapParams.getParam(s_tcapAbortCause);
8076 	    if (!TelEngine::null(ctxt) && (*ctxt) == "pAbort") {
8077 		ctxt = tcapParams.getParam(s_tcapAbortInfo);
8078 		int code = lookup(*ctxt,SS7TCAPError::s_errorTypes);
8079 		*ctxt = String(code);
8080 	    }
8081 	}
8082     }
8083     else
8084 	m_type = Capability;
8085     return ok;
8086 }
8087 
parse(NamedList & tcapParams,XmlElement * elem,String prefix,const AppCtxt * appCtxt)8088 bool XmlToTcap::parse(NamedList& tcapParams, XmlElement* elem, String prefix, const AppCtxt* appCtxt)
8089 {
8090     XDebug(&__plugin,DebugAll,"XmlToTcap::parse(elem=%p, prefix=%s) [%p]",elem,prefix.c_str(),this);
8091     if (!elem)
8092 	return true;
8093 
8094     bool status = true;
8095     bool hasChildren = false;
8096     while (XmlElement* child = elem->pop()) {
8097 	hasChildren = true;
8098 	if (child->getTag() == s_component)
8099 	    status = handleComponent(tcapParams,child,appCtxt);
8100 	else if (child->getTag() == s_userInformation && m_app->type() == TcapXUser::MAP)
8101 	    status = handleMAPDialog(tcapParams,child,(!TelEngine::null(prefix) ? prefix + "." + child->getTag() : child->getTag()));
8102 	else
8103 	    status = parse(tcapParams,child, (!TelEngine::null(prefix) ? prefix + "." + child->getTag() : child->getTag()),appCtxt);
8104 	TelEngine::destruct(child);
8105 	if (!status)
8106 	    break;
8107     }
8108     const NamedList& attrs = elem->attributes();
8109     for (unsigned int i = 0; i < attrs.count(); i++) {
8110 	NamedString* ns = attrs.getParam(i);
8111 	if (TelEngine::null(ns))
8112 	    continue;
8113 
8114 	String find = (!TelEngine::null(prefix) ? prefix + "." + ns->name() : ns->name());
8115 	const TCAPMap* map = findMap(find);
8116 	if (map) {
8117 	    if (TelEngine::null(map->name))
8118 		tcapParams.addParam(find,*ns);
8119 	    else {
8120 		if (map->isPrefix)
8121 		    tcapParams.addParam(map->name + "." + ns->name(),*ns);
8122 		else
8123 		    tcapParams.addParam(map->name,*ns);
8124 	    }
8125 	}
8126     }
8127     if (!hasChildren) {
8128 	const TCAPMap* map = findMap(prefix);
8129 	if (map) {
8130 	    if (map->isPrefix) {
8131 		if (!TelEngine::null(map->name))
8132 		    tcapParams.addParam(map->name + "." + elem->getTag(),elem->getText());
8133 		else
8134 		    tcapParams.addParam(elem->getTag(),elem->getText());
8135 	    }
8136 	    else {
8137 		if (!TelEngine::null(map->name))
8138 		    tcapParams.addParam(map->name,elem->getText());
8139 		else
8140 		    tcapParams.addParam(elem->getTag(),elem->getText());
8141 	    }
8142 	}
8143     }
8144     return status;
8145 }
8146 
8147 /**
8148  * TcapXApplication
8149  */
TcapXApplication(const char * name,Socket * skt,TcapXUser * user)8150 TcapXApplication::TcapXApplication(const char* name, Socket* skt, TcapXUser* user)
8151     : Mutex(true,name),
8152       m_io(0), m_name(name), m_user(user),
8153       m_sentXml(0), m_receivedXml(0),
8154       m_sentTcap(0), m_receivedTcap(0),
8155       m_state(Waiting),
8156       m_tcap2Xml(this),
8157       m_xml2Tcap(this)
8158 {
8159     if (skt) {
8160 	m_io = new XMLConnection(skt,this);
8161 	if (!m_io->startup()) {
8162 	    delete m_io;
8163 	    m_io = 0;
8164 	}
8165     }
8166     m_type = user->type();
8167     Debug(&__plugin,DebugAll,"TcapXApplication created with name=%s and connection=%p [%p]",m_name.c_str(),m_io,this);
8168 }
8169 
~TcapXApplication()8170 TcapXApplication::~TcapXApplication()
8171 {
8172     Debug(&__plugin,DebugAll,"TcapXApplication with name=%s destroyed [%p]",m_name.c_str(),this);
8173     closeConnection();
8174     while (m_io)
8175 	Thread::idle();
8176     m_user = 0;
8177 }
8178 
hasCapability(const char * cap)8179 bool TcapXApplication::hasCapability(const char* cap)
8180 {
8181     if (!cap)
8182 	return false;
8183     DDebug(&__plugin,DebugAll,"TcapXApplication::hasCapability(cap=%s) [%p]",cap,this);
8184 
8185     Lock l(this);
8186     ObjList* o = m_capab.find(cap);
8187     if (!o)
8188 	return false;
8189     String* str = static_cast<String*>(o->get());
8190     if (!(str && (*str == cap)))
8191 	return false;
8192     return true;
8193 }
8194 
canHandle(NamedList & params)8195 bool TcapXApplication::canHandle(NamedList& params)
8196 {
8197     DDebug(&__plugin,DebugAll,"TcapXApplication::canHandle(params=%p) [%p]",&params,this);
8198     if (m_state != Active)
8199 	return false;
8200     int compCount = params.getIntValue(s_tcapCompCount,0);
8201 
8202     // try matching on application context
8203     const AppCtxt* appCtxt = 0;
8204     while (true) {
8205 	NamedString* appOID = params.getParam(s_tcapAppCtxt);
8206 	if (TelEngine::null(appOID))
8207 	    break;
8208 	appCtxt = findCtxtFromOid(*appOID,(m_type== TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt));
8209 	if (!appCtxt)
8210 	    break;
8211 	const Capability* cap = findCapabilityOID(m_type,appCtxt->name);
8212 	if (!cap) {
8213 	    if (!compCount)
8214 		return false;
8215 	    break;
8216 	}
8217 	if (!hasCapability(cap->name) && !compCount) {
8218 	    Debug(&__plugin,DebugAll,"TcapXApplication '%s' cannot handle oid='%s' [%p]",m_name.c_str(),appCtxt->name,this);
8219 	    return false;
8220 	}
8221 	break;
8222     }
8223     if (!compCount && !appCtxt)
8224 	return false;
8225 
8226     for (int i = 1; i <= compCount; i++) {
8227 
8228 	NamedString* opCode = params.getParam(s_tcapCompPrefixSep + String(i) + "." + s_tcapOpCode);
8229 	NamedString* opType = params.getParam(s_tcapCompPrefixSep + String(i) + "." + s_tcapOpCodeType);
8230 	if (TelEngine::null(opCode) || TelEngine::null(opType))
8231 	    continue;
8232 	const Operation* op = findOperation(m_type,opCode->toInteger(),(*opType == "local"),appCtxt);
8233 	if (!op)
8234 	    return false;
8235 	const Capability* cap = findCapability(m_type,op->name);
8236 	if (!cap)
8237 	    return false;
8238 	if (!hasCapability(cap->name)) {
8239 	    Debug(&__plugin,DebugAll,"TcapXApplication '%s' cannot handle operation='%s' [%p]",m_name.c_str(),op->name.c_str(),this);
8240 	    return false;
8241 	}
8242     }
8243     return true;
8244 }
8245 
closeConnection()8246 void TcapXApplication::closeConnection()
8247 {
8248     DDebug(&__plugin,DebugAll,"TcapXApplication::closeConnection() - app=%s closing [%p]",m_name.c_str(),this);
8249     Lock l(this);
8250     if (m_io)
8251 	m_io->cancel();
8252     l.drop();
8253 }
8254 
setIO(XMLConnection * io)8255 void TcapXApplication::setIO(XMLConnection* io)
8256 {
8257     DDebug(&__plugin,DebugAll,"TcapXApplication::setIO(io=%p) - app=%s[%p]",io,m_name.c_str(),this);
8258     Lock l(this);
8259     if (!m_io)
8260 	return;
8261     m_io = io;
8262     l.drop();
8263     if (!io && m_user)
8264 	m_user->removeApp(this);
8265 }
8266 
supportCapability(const String & capab)8267 bool TcapXApplication::supportCapability(const String& capab)
8268 {
8269     if (!findDefCapability(m_type,capab))
8270 	return false;
8271     return true;
8272 }
8273 
handleXML()8274 bool TcapXApplication::handleXML()
8275 {
8276     Debug(&__plugin,DebugAll,"TcapXApplication::handleXML() - %s[%p]",m_name.c_str(),this);
8277 
8278     if (!m_xml2Tcap.checkXmlns()) {
8279 	Debug(&__plugin,DebugInfo,"TcapXApplication=%s - XMLNS mismatch, closing the connection [%p]",m_name.c_str(),this);
8280 	closeConnection();
8281 	return false;
8282     }
8283 
8284     NamedList params("xml");
8285     if (!m_xml2Tcap.parse(params)) {
8286 	Debug(&__plugin,DebugInfo,"TcapXApplication=%s - parse error, closing the connection [%p]",m_name.c_str(),this);
8287 	closeConnection();
8288 	return false;
8289     };
8290     if (m_user->printMessages()) {
8291 	String tmp;
8292 	params.dump(tmp,"\r\n  ",'\'',true);
8293 	Debug(&__plugin,DebugAll,"App=%s[%p] parsed params %s from xml",m_name.c_str(),this,tmp.c_str());
8294     }
8295     switch (m_xml2Tcap.type()) {
8296 	case XmlToTcap::Capability:
8297 	    return handleCapability(params);
8298 	case XmlToTcap::Tcap:
8299 	    return handleTcap(params);
8300 	case XmlToTcap::Unknown:
8301 	default:
8302 	    Debug(&__plugin,DebugInfo,"TcapXApplication=%s - unknown XML message [%p]",m_name.c_str(),this);
8303 	    closeConnection();
8304 	    return false;
8305     }
8306     return true;
8307 }
8308 
sendTcapMsg(NamedList & params,const AppCtxt * ctxt)8309 bool TcapXApplication::sendTcapMsg(NamedList& params, const AppCtxt* ctxt)
8310 {
8311     DDebug(&__plugin,DebugAll,"TcapXApplication::sentTcapMsg(params=%p) [%p]",&params,this);
8312     XmlFragment* msg = new XmlFragment();
8313     bool ok = m_tcap2Xml.buildXMLMessage(params,msg,TcapToXml::Tcap,ctxt);
8314 
8315     if (m_user->printMessages()) {
8316 	String tmp;
8317 	msg->toString(tmp,false,"\r\n","  ",false);
8318 	Debug(&__plugin,DebugInfo,"App=%s[%p] is sending XML\r\n%s",m_name.c_str(),this,tmp.c_str());
8319     }
8320     if (ok && m_io) {
8321 	m_io->writeData(msg);
8322 	m_sentXml++;
8323     }
8324     delete msg;
8325     return ok;
8326 }
8327 
handleCapability(NamedList & params)8328 bool TcapXApplication::handleCapability(NamedList& params)
8329 {
8330     DDebug(&__plugin,DebugAll,"TcapXApplication::handleCapability() - app=%s [%p]",m_name.c_str(),this);
8331     Lock l(this);
8332     bool firstCap = true;
8333     for (unsigned int i = 0; i < params.count(); i++) {
8334 	NamedString* ns = params.getParam(i);
8335 	if (!ns)
8336 	    continue;
8337 	if (ns->name() == s_capabTag) {
8338 	    if (TelEngine::null(ns))  {
8339 		m_capab.clear();
8340 		reportState(ShutDown);
8341 		return true;
8342 	    }
8343 	    else {
8344 		if (!supportCapability(*ns)) {
8345 		    reportState(Inactive,String("Unsupported: ") + *ns);
8346 		    return false;
8347 		}
8348 		if (firstCap && m_state == Active) {
8349 		    m_capab.clear();
8350 		    firstCap = false;
8351 		}
8352 		m_capab.append(new String(*ns));
8353 	    }
8354 	}
8355     }
8356     if (m_state == Waiting)
8357 	reportState(Active);
8358     return true;
8359 }
8360 
handleIndication(NamedList & tcap)8361 bool TcapXApplication::handleIndication(NamedList& tcap)
8362 {
8363     DDebug(&__plugin,DebugAll,"TcapXApplication::handleIndication() - app=%s state=%s [%p]",m_name.c_str(),lookup(m_state,s_appStates),this);
8364 
8365     if (m_user->printMessages()) {
8366 	String tmp;
8367 	tcap.dump(tmp,"\r\n  ",'\'',true);
8368 	Debug(&__plugin,DebugInfo,"App=%s[%p] received TCAP indication %s",m_name.c_str(),this,tmp.c_str());
8369     }
8370 
8371     int dialog = SS7TCAP::lookupTransaction(tcap.getValue(s_tcapReqType));
8372     String ltid = tcap.getValue(s_tcapLocalTID);
8373     NamedString* rtid = tcap.getParam(s_tcapRemoteTID);
8374 
8375     bool saveID = false, removeID = false;
8376     String appID;
8377     switch (dialog) {
8378 	case SS7TCAP::TC_Unidirectional:
8379 	    if (state() != Active)
8380 		return false;
8381 	    tcap.setParam(s_tcapLocalTID,"");
8382 	    break;
8383 	case SS7TCAP::TC_Begin:
8384 	case SS7TCAP::TC_QueryWithPerm:
8385 	case SS7TCAP::TC_QueryWithoutPerm:
8386 	    if (state() != Active || TelEngine::null(rtid))
8387 		return false;
8388 	    tcap.setParam(s_tcapLocalTID,"");
8389 	    saveID = true;
8390 	    break;
8391 	case SS7TCAP::TC_Continue:
8392 	case SS7TCAP::TC_ConversationWithPerm:
8393 	case SS7TCAP::TC_ConversationWithoutPerm:
8394 	case SS7TCAP::TC_Notice:
8395 	case SS7TCAP::TC_Unknown:
8396 	    if (TelEngine::null(ltid))
8397 		return false;
8398 	    lock();
8399 	    appID = m_ids.findAppID(ltid);
8400 	    if (TelEngine::null(appID)) {
8401 		    if (TelEngine::null(rtid)){
8402 			unlock();
8403 			reportError("Unknown request ID");
8404 			return false;
8405 		    }
8406 		    appID = m_pending.findTcapID(*rtid);
8407 		    if (TelEngine::null(appID)) {
8408 			unlock();
8409 			reportError("Unknown request ID");
8410 			return false;
8411 		    }
8412 		    m_pending.remove(*rtid);
8413 	    }
8414 	    unlock();
8415 	    break;
8416 	case SS7TCAP::TC_End:
8417 	case SS7TCAP::TC_Response:
8418 	case SS7TCAP::TC_U_Abort:
8419 	case SS7TCAP::TC_P_Abort:
8420 	    if (TelEngine::null(ltid))
8421 		return false;
8422 	    lock();
8423 	    appID = m_ids.findAppID(ltid);
8424 	    if (TelEngine::null(appID)) {
8425 		    appID = m_pending.findAppID(ltid);
8426 		    if (TelEngine::null(appID)) {
8427 			unlock();
8428 			reportError("Unknown request ID");
8429 			return false;
8430 		    }
8431 		    m_pending.remove(appID);
8432 	    }
8433 	    unlock();
8434 	    removeID = true;
8435 	    break;
8436 	default:
8437 	    return false;
8438     }
8439 
8440     tcap.setParam(s_tcapLocalTID,appID);
8441 
8442     const AppCtxt* ctxt = 0;
8443     if (saveID) {
8444         NamedString* oid = tcap.getParam(s_tcapAppCtxt);
8445 	if (!TelEngine::null(oid))
8446 	    ctxt = findCtxtFromOid(*oid, m_type == TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt);
8447     }
8448     else
8449 	ctxt = findCtxt(appID,(TelEngine::null(rtid) ? String::empty() : *rtid));
8450 
8451     bool ok = sendTcapMsg(tcap,ctxt);
8452 
8453     Lock l(this);
8454     if (saveID)
8455 	m_pending.appendID(ltid,*rtid,ctxt);
8456     if (removeID) {
8457 	m_ids.remove(appID);
8458 	if (m_state == ShutDown && !trCount())
8459 	    reportState(Inactive);
8460     }
8461     m_receivedTcap++;
8462     return ok;
8463 }
8464 
handleTcap(NamedList & tcap)8465 bool TcapXApplication::handleTcap(NamedList& tcap)
8466 {
8467     DDebug(&__plugin,DebugAll,"TcapXApplication::handleTcap() - app=%s state=%s [%p]",m_name.c_str(),lookup(m_state,s_appStates),this);
8468 
8469     int dialog = SS7TCAP::lookupTransaction(tcap.getValue(s_tcapReqType));
8470     String ltid = tcap.getValue(s_tcapLocalTID);
8471     String rtid = tcap.getValue(s_tcapRemoteTID);
8472     bool endNow = tcap.getBoolValue(s_tcapEndNow,false);
8473 
8474     bool saveID = false;
8475     bool removeID = false;
8476     lock();
8477     String tcapID = m_ids.findTcapID(ltid);
8478     unlock();
8479 
8480     switch (dialog) {
8481 	case SS7TCAP::TC_Unknown:
8482 	case SS7TCAP::TC_Unidirectional:
8483 	    break;
8484 	case SS7TCAP::TC_Begin:
8485 	case SS7TCAP::TC_QueryWithPerm:
8486 	case SS7TCAP::TC_QueryWithoutPerm:
8487 	    if (TelEngine::null(ltid)) {
8488 		reportError("Missing request ID");
8489 		return false;
8490 	    }
8491 	    if (!TelEngine::null(tcapID)) {
8492 		reportError("Duplicate request ID");
8493 		return false;
8494 	    }
8495 	    saveID = true;
8496 	    break;
8497 	case SS7TCAP::TC_Continue:
8498 	case SS7TCAP::TC_ConversationWithPerm:
8499 	case SS7TCAP::TC_ConversationWithoutPerm:
8500 	    if (TelEngine::null(ltid)) {
8501 		reportError("Missing request ID");
8502 		return false;
8503 	    }
8504 	    if (TelEngine::null(tcapID)) {
8505 		if (!TelEngine::null(rtid)) {
8506 		    lock();
8507 		    tcapID = m_pending.findTcapID(rtid);
8508 		    unlock();
8509 		    if (TelEngine::null(tcapID)) {
8510 			reportError("Unknown request ID");
8511 			return false;
8512 		    }
8513 		    lock();
8514 		    m_pending.remove(rtid);
8515 		    unlock();
8516 		    saveID = true;
8517 		}
8518 		else {
8519 		    reportError("Unknown request ID");
8520 		    return false;
8521 		}
8522 	    }
8523 	    break;
8524 	case SS7TCAP::TC_End:
8525 	case SS7TCAP::TC_Response:
8526 	case SS7TCAP::TC_U_Abort:
8527 	    if (TelEngine::null(ltid)) {
8528 		reportError("Missing request ID");
8529 		return false;
8530 	    }
8531 	    if (TelEngine::null(tcapID)) {
8532 		if (!TelEngine::null(rtid)) {
8533 		    lock();
8534 		    tcapID = m_pending.findTcapID(rtid);
8535 		    unlock();
8536 		    if (TelEngine::null(tcapID)) {
8537 			reportError("Unknown request ID");
8538 			return false;
8539 		    }
8540 		    lock();
8541 		    m_pending.remove(rtid);
8542 		    unlock();
8543 		}
8544 		else {
8545 		    reportError("Unknown request ID");
8546 		    return false;
8547 		}
8548 	    }
8549 	    removeID = true;
8550 	    break;
8551 	case SS7TCAP::TC_P_Abort:
8552 	case SS7TCAP::TC_Notice:
8553 	default:
8554 	    reportError("Invalid request");
8555 	    return false;
8556     }
8557     if (!m_user)
8558 	return false;
8559     tcap.setParam(s_tcapLocalTID,tcapID);
8560 
8561     const AppCtxt* ctxt = 0;
8562     if (saveID && !endNow) {
8563 	NamedString* ctxtStr = tcap.getParam(s_tcapAppCtxt);
8564 	if (!TelEngine::null(ctxtStr))
8565 	    ctxt = findCtxtFromOid(*ctxtStr,(m_type == TcapXUser::MAP ? s_mapAppCtxt : s_camelAppCtxt));
8566     }
8567 
8568     if (m_user->printMessages()) {
8569 	String tmp;
8570 	tcap.dump(tmp,"\r\n  ",'\'',true);
8571 	Debug(&__plugin,DebugInfo,"App=%s[%p] is sending TCAP request %s",m_name.c_str(),this,tmp.c_str());
8572     }
8573 
8574     SS7TCAPError error = m_user->applicationRequest(this,tcap,dialog);
8575     if (error.error() != SS7TCAPError::NoError) {
8576 	NamedString* err = tcap.getParam(s_tcapRequestError);
8577 	reportError(TelEngine::null(err) ? error.errorName() : *err);
8578 	return false;
8579     }
8580 
8581     Lock l(this);
8582     if (removeID || endNow) {
8583 	m_ids.remove(ltid);
8584     	if (m_state == ShutDown && !trCount())
8585 	    reportState(Inactive);
8586     }
8587     if (saveID && !endNow)
8588 	m_ids.appendID(tcap.getValue(s_tcapLocalTID),ltid,ctxt);
8589     m_sentTcap++;
8590     return true;
8591 }
8592 
receivedXML(XmlDocument * doc)8593 void TcapXApplication::receivedXML(XmlDocument* doc)
8594 {
8595 
8596     Debug(&__plugin,DebugAll,"TcapXApplication::receivedXML(frag=%p) - %s[%p]",doc,m_name.c_str(),this);
8597     if (!doc)
8598 	return;
8599 
8600     if (m_user->printMessages()) {
8601 	String tmp;
8602 	doc->toString(tmp,false,"\r\n","  ");
8603 	Debug(&__plugin,DebugInfo,"App=%s[%p] received XML\r\n%s",m_name.c_str(),this,tmp.c_str());
8604     }
8605 
8606     if (!m_xml2Tcap.valid(doc)) {
8607 	Debug(&__plugin,DebugInfo,"TcapXApplication=%s - invalid message, closing the connection [%p]",m_name.c_str(),this);
8608 	closeConnection();
8609 	return;
8610     }
8611     if (m_state == Waiting && !m_xml2Tcap.hasDeclaration()) {
8612 	Debug(&__plugin,DebugInfo,"TcapXApplication=%s - initial XML declaration missing, closing the connection [%p]",m_name.c_str(),this);
8613 	closeConnection();
8614 	return;
8615     }
8616     if (m_xml2Tcap.hasDeclaration() && !m_xml2Tcap.validDeclaration()) {
8617 	Debug(&__plugin,DebugInfo,"TcapXApplication=%s - XML declaration mismatch, closing the connection [%p]",m_name.c_str(),this);
8618 	closeConnection();
8619 	return;
8620     }
8621     if (handleXML())
8622 	m_receivedXml++;
8623 }
8624 
reportState(State state,const char * error)8625 void TcapXApplication::reportState(State state, const char* error)
8626 {
8627     DDebug(&__plugin,DebugAll,"TcapXApplication::reportState(state=%s, error=%s) [%p]",lookup(state,s_appStates),error,this);
8628     m_state = state;
8629     switch (m_state) {
8630 	case Waiting:
8631 	    break;
8632 	case Active:
8633 	    sendStateResponse();
8634 	    m_user->notifyManagementState();
8635 	    break;
8636 	case ShutDown:
8637 	    Debug(&__plugin,DebugInfo,"Requested shutdown, %d transactions pending [%p]",trCount(),this);
8638 	    if (trCount())
8639 		break;
8640 	    m_state = Inactive;
8641 	case Inactive:
8642 	    sendStateResponse(error);
8643 	    closeConnection();
8644 	default:
8645 	    break;
8646     }
8647 }
8648 
sendStateResponse(const char * error)8649 void TcapXApplication::sendStateResponse(const char* error)
8650 {
8651     DDebug(&__plugin,DebugAll,"TcapXApplication::sendStateResponse(error=%s) [%p]",error,this);
8652 
8653     NamedList params("xml");
8654     params.setParam("state",lookup(m_state,s_appStates));
8655     if (error)
8656 	params.setParam("error",error);
8657     XmlFragment* msg = new XmlFragment();
8658     bool ok = m_tcap2Xml.buildXMLMessage(params,msg,TcapToXml::State);
8659 
8660     if (m_user->printMessages()) {
8661 	String tmp;
8662 	msg->toString(tmp,false,"\r\n","  ",false);
8663 	Debug(&__plugin,DebugInfo,"App=%s[%p] is sending XML\r\n%s",m_name.c_str(),this,tmp.c_str());
8664     }
8665     if (ok && m_io) {
8666 	m_io->writeData(msg);
8667 	m_sentXml++;
8668     }
8669     delete msg;
8670 }
8671 
reportError(const char * err)8672 void TcapXApplication::reportError(const char* err)
8673 {
8674     if (!err)
8675 	return;
8676     Debug(&__plugin,DebugInfo,"TcapXApplication::reportError(error=%s) - app=%s [%p]",err,m_name.c_str(),this);
8677 }
8678 
status(NamedList & status)8679 void TcapXApplication::status(NamedList& status)
8680 {
8681     DDebug(&__plugin,DebugInfo,"TcapXApplication::status() [%p]",this);
8682 
8683     Lock l(this);
8684     status.setParam("receivedXML",String(m_receivedXml));
8685     status.setParam("sentXML",String(m_sentXml));
8686     status.setParam("receivedTcap",String(m_receivedTcap));
8687     status.setParam("sentTcap",String(m_sentTcap));
8688 }
8689 
findCtxt(const String & appID,const String & remoteID)8690 const AppCtxt* TcapXApplication::findCtxt(const String& appID, const String& remoteID)
8691 {
8692     DDebug(DebugAll,"TcapXApplication::findCtxt('%s','%s') [%p]",appID.c_str(),remoteID.c_str(),this);
8693     Lock l(this);
8694     if (!appID.null()) {
8695 	Transaction* t = m_ids.findByAppID(appID);
8696 	if (t)
8697 	    return t->context();
8698     }
8699     if (!remoteID.null()) {
8700 	Transaction* t = m_pending.findByAppID(remoteID);
8701 	if (t)
8702 	    return t->context();
8703     }
8704     return 0;
8705 }
8706 
8707 /**
8708  * TcapXUser
8709  */
TcapXUser(const char * name)8710 TcapXUser::TcapXUser(const char* name)
8711     : TCAPUser(name),
8712       Mutex(true,name),
8713       m_appsMtx(true,"TCAPXApps"),
8714       m_listener(0), m_type(MAP),
8715       m_printMsg(false), m_addEnc(false),
8716       m_mngtStatus(SCCPManagement::UserOutOfService)
8717 {
8718     Debug(&__plugin,DebugAll,"TcapXUser '%s' created [%p]",toString().c_str(),this);
8719 }
8720 
~TcapXUser()8721 TcapXUser::~TcapXUser()
8722 {
8723     Debug(&__plugin,DebugAll,"TcapXUser '%s' destroyed [%p]",toString().c_str(),this);
8724     lock();
8725     if (m_listener)
8726 	m_listener->cancel();
8727     if (tcap())
8728 	attach(0);
8729     unlock();
8730 
8731     m_appsMtx.lock();
8732     for (ObjList* o = m_apps.skipNull(); o; o = o->skipNext()) {
8733 	TcapXApplication* app = static_cast<TcapXApplication*>(o->get());
8734 	if (app)
8735 	    app->closeConnection();
8736     }
8737     m_appsMtx.unlock();
8738 
8739     while (m_listener)
8740 	Thread::idle();
8741 
8742     while (true) {
8743 	Thread::idle();
8744 	m_appsMtx.lock();
8745 	ObjList* o = m_apps.skipNull();
8746 	m_appsMtx.unlock();
8747 	if (!o)
8748 	    break;
8749     }
8750 }
8751 
initialize(NamedList & sect)8752 bool TcapXUser::initialize(NamedList& sect)
8753 {
8754     Debug(this,DebugAll,"TcapXUser::initialize() [%p]",this);
8755 
8756     Lock l(this);
8757     if (!m_listener) {
8758 	m_listener = new XMLConnListener(this,sect);
8759 	if (!m_listener->init()) {
8760 	    delete m_listener;
8761 	    m_listener = 0;
8762 	    return false;
8763 	}
8764     }
8765 
8766     m_type = (UserType)lookup(sect.getValue(s_typeStr,"MAP"),s_userTypes,m_type);
8767     m_printMsg = sect.getBoolValue(YSTRING("print-messages"),false);
8768     m_addEnc = sect.getBoolValue(YSTRING("add-encoding"),false);
8769     if (!tcap() && !findTCAP(sect.getValue("tcap",0)))
8770 	return false;
8771     notifyManagementState(true);
8772     return true;
8773 }
8774 
removeApp(TcapXApplication * app)8775 void TcapXUser::removeApp(TcapXApplication* app)
8776 {
8777     Debug(this,DebugAll,"Removing application=%s[%p] [%p]",(app ? app->toString().c_str() : ""),app,this);
8778     Lock l(m_appsMtx);
8779     m_apps.remove(app);
8780     l.drop();
8781     notifyManagementState();
8782 }
8783 
tcapIndication(NamedList & params)8784 bool TcapXUser::tcapIndication(NamedList& params)
8785 {
8786     DDebug(this,DebugAll,"TcapXUser::tcapIndication() [%p]",this);
8787 
8788     NamedString* ltid = params.getParam(s_tcapLocalTID);
8789     if (TelEngine::null(ltid)) {
8790 	DDebug(this,DebugAll,"Received transaction without local transaction id, rejecting it");
8791 	return false;
8792     }
8793     int dialog = SS7TCAP::lookupTransaction(params.getValue(s_tcapReqType));
8794 
8795     ObjList* o = m_trIDs.find(*ltid);
8796     NamedString* tcapID = 0;
8797     if (o)
8798 	tcapID = static_cast<NamedString*>(o->get());
8799     bool searchApp = false, removeID = false;
8800     switch (dialog) {
8801 	case SS7TCAP::TC_Unidirectional:
8802 	    return sendToApp(params);
8803 	case SS7TCAP::TC_Begin:
8804 	case SS7TCAP::TC_QueryWithPerm:
8805 	case SS7TCAP::TC_QueryWithoutPerm:
8806 	    if (TelEngine::null(ltid) || !TelEngine::null(tcapID)) {
8807 		DDebug(this,DebugAll,"Received a new transaction with an id that we already have, rejecting it");
8808 		return false;
8809 	    }
8810 	    return sendToApp(params);
8811 	case SS7TCAP::TC_Continue:
8812 	case SS7TCAP::TC_ConversationWithPerm:
8813 	case SS7TCAP::TC_ConversationWithoutPerm:
8814 	case SS7TCAP::TC_Notice:
8815 	case SS7TCAP::TC_Unknown:
8816 	    if (TelEngine::null(ltid) || TelEngine::null(tcapID)) {
8817 		DDebug(this,DebugAll,"Received a dialog continue TCAP message for a dialog that doesn't exist, rejecting it");
8818 		return false;
8819 	    }
8820 	    searchApp = true;
8821 	    break;
8822 	case SS7TCAP::TC_End:
8823 	case SS7TCAP::TC_Response:
8824 	case SS7TCAP::TC_U_Abort:
8825 	case SS7TCAP::TC_P_Abort:
8826 	    if (TelEngine::null(ltid) || TelEngine::null(tcapID)) {
8827 		DDebug(this,DebugAll,"Received a end dialogue TCAP message for a dialog that doesn't exist, rejecting it");
8828 		return false;
8829 	    }
8830 	    searchApp = true;
8831 	    removeID = true;
8832 	    break;
8833 	default:
8834 	    DDebug(this,DebugAll,"Received a TCAP message without type of dialog message, rejecting it");
8835 	    return false;
8836     }
8837 
8838     Lock la(m_appsMtx);
8839     o = m_apps.find(*tcapID);
8840     if (!o && searchApp) {
8841 	Debug(this,DebugMild,"Cannot find application that was handling transaction with id='%s'",ltid->c_str());
8842 	return false;
8843     }
8844 
8845     TcapXApplication* app = static_cast<TcapXApplication*>(o->get());
8846     if (searchApp && !app)
8847 	return false;
8848 
8849     if (removeID) {
8850 	reorderApps(app);
8851 	m_trIDs.remove(tcapID);
8852     }
8853     la.drop();
8854     return sendToApp(params,app,false);
8855 }
8856 
sendToApp(NamedList & params,TcapXApplication * app,bool saveID)8857 bool TcapXUser::sendToApp(NamedList& params, TcapXApplication* app, bool saveID)
8858 {
8859     DDebug(this,DebugAll,"TcapXUser::sendToApp(params=%p,app=%s[%p]) [%p]",&params,(app ? app->toString().c_str() : ""),app,this);
8860 
8861     Lock l(m_appsMtx);
8862     if (!app)
8863 	app = findApplication(params);
8864     if (!app) {
8865 	NamedString* opCode = params.getParam(YSTRING("tcap.component.1.operationCode"));
8866 	NamedString* opType = params.getParam(YSTRING("tcap.component.1.operationCodeType"));
8867 	NamedString* appCtxt = params.getParam(s_tcapAppCtxt);
8868 	if (!(TelEngine::null(opCode) || TelEngine::null(opType))) {
8869 	    const Operation* op = findOperation(m_type,opCode->toInteger(),(*opType == "local"),0);
8870 	    Debug(this,DebugInfo,"TcapXUser::sendToApp() - cannot find application to handle operation='%s' [%p]",(op ? op->name.c_str() : "no operation"),this);
8871 	}
8872 	else {
8873 	    if (!TelEngine::null(appCtxt))
8874 		Debug(this,DebugInfo,"TcapXUser::sendToApp() - cannot find application to handle application OID='%s' [%p]",appCtxt->c_str(),this);
8875 	    else
8876 		Debug(this,DebugInfo,"TcapXUser::sendToApp() - cannot find application to handle transaction with no given operation or app OID [%p]",this);
8877 	}
8878 	return false;
8879     }
8880     if (saveID)
8881 	m_trIDs.append(new NamedString(params.getValue(s_tcapLocalTID),app->toString()));
8882     return (app && app->handleIndication(params));
8883 }
8884 
findApplication(NamedList & params)8885 TcapXApplication* TcapXUser::findApplication(NamedList& params)
8886 {
8887     DDebug(this,DebugAll,"TcapXUser::findApplication() [%p]",this);
8888     for (ObjList* o = m_apps.skipNull(); o; o = o->skipNext()) {
8889 	TcapXApplication* app = static_cast<TcapXApplication*>(o->get());
8890 	if (app->canHandle(params)) {
8891 	    // reorder list
8892 	    reorderApps(app);
8893 	    return app;
8894 	}
8895     }
8896     return 0;
8897 }
8898 
reorderApps(TcapXApplication * app)8899 void TcapXUser::reorderApps(TcapXApplication* app)
8900 {
8901     if (!app)
8902 	return;
8903     ObjList* appObj = m_apps.find(app);
8904     if (!appObj)
8905 	return;
8906     ObjList* next = appObj->next();
8907     // it's already at the bottom of the list
8908     if (!next)
8909 	return;
8910     unsigned int count = app->trCount() + 1;
8911     while (next) {
8912 	TcapXApplication* nextApp = static_cast<TcapXApplication*>(next->get());
8913 	if (nextApp) {
8914 	    if (count < nextApp->trCount())
8915 		break;
8916 	    next = next->next();
8917 	}
8918 	else
8919 	    break;
8920     }
8921     if (next) {
8922 	if (next != appObj->next()) {
8923 	    m_apps.remove(app,false);
8924 	    next->insert(app);
8925 	    return;
8926 	}
8927     }
8928     else {
8929 	m_apps.remove(app,false);
8930 	m_apps.append(app);
8931     }
8932 }
8933 
statusString(String & str)8934 void TcapXUser::statusString(String& str)
8935 {
8936     DDebug(this,DebugAll,"TcapXUser::statusString() [%p]",this);
8937     Lock l(m_appsMtx);
8938     NamedList params("");
8939     for (ObjList* o = m_apps.skipNull(); o; o = o->skipNext()) {
8940 	TcapXApplication* app = static_cast<TcapXApplication*>(o->get());
8941 	if (!app)
8942 	    continue;
8943 	str.append(app->toString(),",") << "=" << toString() << "|" << lookup(m_type,s_userTypes);
8944 	app->status(params);
8945 	str << "|" << params.getIntValue(YSTRING("receivedXML"));
8946 	str << "|" << params.getIntValue(YSTRING("sentXML"));
8947 	str << "|" << params.getIntValue(YSTRING("receivedTcap"));
8948 	str << "|" << params.getIntValue(YSTRING("sentTcap"));
8949     }
8950 }
8951 
managementNotify(SCCP::Type type,NamedList & params)8952 bool TcapXUser::managementNotify(SCCP::Type type, NamedList& params)
8953 {
8954 // TODO
8955 // check docs if they say anything about management
8956     return true;
8957 }
8958 
findTCAP(const char * name)8959 bool TcapXUser::findTCAP(const char* name)
8960 {
8961     if (!name)
8962 	return false;
8963     SignallingComponent* tcap = 0;
8964     SignallingEngine* engine = SignallingEngine::self(true);
8965     if (engine)
8966 	tcap = engine->find(name,"SS7TCAPITU",tcap);
8967     if (tcap) {
8968 	Debug(this,DebugAll,"TcapXUser '%s' attaching to TCAP=%s [%p]",toString().c_str(),name,this);
8969 	attach(YOBJECT(SS7TCAPITU,tcap));
8970     }
8971     return (tcap != 0);
8972 }
8973 
createApplication(Socket * skt,String & addr)8974 bool TcapXUser::createApplication(Socket* skt, String& addr)
8975 {
8976     if (!skt)
8977 	return false;
8978 
8979     String appName = toString() + ":" + addr;
8980     Lock l(m_appsMtx);
8981     // it's new, put it at the top of the list
8982     m_apps.insert(new TcapXApplication(appName,skt,this));
8983     return true;
8984 }
8985 
managementState()8986 int TcapXUser::managementState()
8987 {
8988     DDebug(this,DebugAll,"TcapXUser::managementState() - user=%s[%p]",toString().c_str(),this);
8989     Lock l(m_appsMtx);
8990     for (ObjList* o = m_apps.skipNull(); o; o = o->skipNext()) {
8991 	TcapXApplication* app = static_cast<TcapXApplication*>(o->get());
8992 	if (!app)
8993 	    continue;
8994 	if (app->state() == TcapXApplication::Active)
8995 	    return SCCPManagement::UserInService;
8996     }
8997     return SCCPManagement::UserOutOfService;
8998 }
8999 
notifyManagementState(bool forced)9000 void TcapXUser::notifyManagementState(bool forced)
9001 {
9002     DDebug(this,DebugAll,"TcapXUser::notifyManagementState(forced=%s) [%p]",String::boolText(forced),this);
9003     SCCPManagement::LocalBroadcast state = (SCCPManagement::LocalBroadcast)managementState();
9004     Lock l(this);
9005     if (forced || state != m_mngtStatus) {
9006 	Debug(this,DebugInfo,"Changing management state from '%s' to '%s' [%p]",
9007 	      lookup(m_mngtStatus,SCCPManagement::broadcastType(),""),lookup(state,SCCPManagement::broadcastType(),""),this);
9008 	m_mngtStatus = state;
9009 	l.drop();
9010 	if (tcap()) {
9011 	    NamedList p("");
9012 	    tcap()->updateUserStatus(this,state,p);
9013 	}
9014     }
9015 }
9016 
setListener(XMLConnListener * list)9017 void TcapXUser::setListener(XMLConnListener* list)
9018 {
9019     Lock l(this);
9020     m_listener = list;
9021 }
9022 
applicationRequest(TcapXApplication * app,NamedList & params,int reqType)9023 SS7TCAPError TcapXUser::applicationRequest(TcapXApplication* app, NamedList& params, int reqType)
9024 {
9025     DDebug(this,DebugAll,"TcapXUser::applicationRequest() - user=%s, request from app=%s[%p] [%p]",
9026 	toString().c_str(),(app ? app->toString().c_str() : ""),app,this);
9027 
9028     SS7TCAPError error((tcap() ? tcap()->tcapType() : SS7TCAP::ITUTCAP));
9029     if (!app)
9030 	return error;
9031     if (tcap()) {
9032 	params.setParam(s_tcapUser,toString());
9033 	error = tcap()->userRequest(params);
9034     }
9035     else {
9036 	params.setParam(s_tcapRequestError,"No TCAP attached");
9037 	error.setError(SS7TCAPError::Transact_UnassignedTransactionID);
9038 	return error;
9039     }
9040     bool saveID = false;
9041     bool removeID = false;
9042     switch (reqType) {
9043 	case SS7TCAP::TC_Begin:
9044 	case SS7TCAP::TC_QueryWithPerm:
9045 	case SS7TCAP::TC_QueryWithoutPerm:
9046 	    saveID = true;
9047 	    break;
9048 	case SS7TCAP::TC_End:
9049 	case SS7TCAP::TC_Response:
9050 	case SS7TCAP::TC_U_Abort:
9051 	    removeID = true;
9052 	    break;
9053 	case SS7TCAP::TC_P_Abort:
9054 	case SS7TCAP::TC_Notice:
9055 	case SS7TCAP::TC_Unknown:
9056 	case SS7TCAP::TC_Unidirectional:
9057 	case SS7TCAP::TC_Continue:
9058 	case SS7TCAP::TC_ConversationWithPerm:
9059 	case SS7TCAP::TC_ConversationWithoutPerm:
9060 	default:
9061 	    break;
9062     }
9063 
9064     Lock la(m_appsMtx);
9065     NamedString* ltid = params.getParam(s_tcapLocalTID);
9066     if (saveID) {
9067 	reorderApps(app);
9068 	if (TelEngine::null(ltid)) {
9069 	    params.setParam(s_tcapRequestError,"TCAP error");
9070 	    error.setError(SS7TCAPError::Transact_UnassignedTransactionID);
9071 	}
9072 	else
9073 	    m_trIDs.append(new NamedString(*ltid,app->toString()));
9074     }
9075     if (removeID) {
9076 	reorderApps(app);
9077 	if (TelEngine::null(ltid) ||!m_trIDs.find(*ltid))
9078 	    error.setError(SS7TCAPError::Transact_UnassignedTransactionID);
9079 	else
9080 	    m_trIDs.remove(*ltid);
9081     }
9082     return error;
9083 }
9084 
9085 /**
9086  * TcapXModule
9087  */
TcapXModule()9088 TcapXModule::TcapXModule()
9089     : Module("camel_map","misc"),
9090       m_usersMtx(true,"TCAPXUsers")
9091 {
9092     Output("Loaded TCAPXML module");
9093 }
9094 
~TcapXModule()9095 TcapXModule::~TcapXModule()
9096 {
9097     Output("Unloaded module TCAPXML");
9098 }
9099 
initialize()9100 void TcapXModule::initialize()
9101 {
9102     Output("Initializing module TCAPXML");
9103     Module::initialize();
9104 
9105     Configuration cfg(Engine::configFile(name()));
9106     installRelay(Halt);
9107     cfg.load();
9108     m_showMissing = cfg.getBoolValue(YSTRING("general"),YSTRING("show-missing"),true);
9109     initUsers(cfg);
9110 }
9111 
unload()9112 bool TcapXModule::unload()
9113 {
9114     if (!lock(500000))
9115 	return false;
9116     uninstallRelays();
9117     m_users.clear();
9118     unlock();
9119     return true;
9120 }
9121 
initUsers(Configuration & cfg)9122 void TcapXModule::initUsers(Configuration& cfg)
9123 {
9124     DDebug(&__plugin,DebugAll,"TcapXModule::initUsers() [%p]",this);
9125     int n = cfg.sections();
9126     Lock l(m_usersMtx);
9127     for (int i = 0; i < n; i++) {
9128 	NamedList* sect = cfg.getSection(i);
9129 	if (!sect)
9130 	    continue;
9131 	String name(*sect);
9132 	if (name.startSkip("tcap") && name) {
9133 	    if (!sect->getBoolValue("enable",true)) {
9134 		m_users.remove(name);
9135 		continue;
9136 	    }
9137 	    ObjList* o = m_users.find(name);
9138 	    TcapXUser* usr = (o ? static_cast<TcapXUser*>(o->get()) : 0);
9139 	    if (!usr) {
9140 		usr = new TcapXUser(name);
9141 		usr->debugChain(&__plugin);
9142 		m_users.append(usr);
9143 	    }
9144 	    if (!usr->initialize(*sect)) {
9145 		Debug(&__plugin,DebugInfo,"TcapXModule::initUsers() - user '%s' failed to initialize [%p]",name.c_str(),this);
9146 		m_users.remove(name);
9147 	    }
9148 	}
9149     }
9150 }
9151 
received(Message & msg,int id)9152 bool TcapXModule::received(Message& msg, int id)
9153 {
9154     if (id == Halt)
9155 	unload();
9156     return Module::received(msg,id);
9157 }
9158 
applicationCount()9159 unsigned int TcapXModule::applicationCount()
9160 {
9161     Lock l(m_usersMtx);
9162     unsigned int count = 0;
9163     for (ObjList* o = m_users.skipNull(); o; o = o->skipNext()) {
9164 	TcapXUser* user = static_cast<TcapXUser*>(o->get());
9165 	count += user->applicationCount();
9166     }
9167     return count;
9168 }
9169 
statusModule(String & str)9170 void TcapXModule::statusModule(String& str)
9171 {
9172     Module::statusModule(str);
9173     str.append("format=User|Type|ReceivedXML|SentXML|ReceivedTCAP|SentTcap",",");
9174 }
9175 
statusParams(String & str)9176 void TcapXModule::statusParams(String& str)
9177 {
9178     str.append("count=",",") << applicationCount();
9179 }
9180 
statusDetail(String & str)9181 void TcapXModule::statusDetail(String& str)
9182 {
9183     Lock l(m_usersMtx);
9184     for (ObjList* o = m_users.skipNull(); o; o = o->skipNext()) {
9185 	TcapXUser* user = static_cast<TcapXUser*>(o->get());
9186 	if (!user)
9187 	    continue;
9188 	user->statusString(str);
9189     }
9190 }
9191 
9192 }; // anonymous namespace
9193 
9194 /* vi: set ts=8 sw=4 sts=4 noet enc=utf-8: */
9195