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(¶m->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,¶ms,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]",¶ms,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]",¶ms,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]",¶ms,(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