EpcTools
An event based multi-threaded C++ development framework.
epfcp.h
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2020 Sprint
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 #ifndef __EPFCP_H
18 #define __EPFCP_H
19 
22 
23 #include <atomic>
24 #include <unordered_map>
25 #include <utility>
26 
27 #include "epctools.h"
28 #include "eip.h"
29 #include "esocket.h"
30 #include "eteid.h"
31 #include "etimerpool.h"
32 #include "ememory.h"
33 #include "ejsonbuilder.h"
34 
36 namespace PFCP
37 {
40 
43  Void Initialize();
45  Void Uninitialize();
46 
49 
51 
53 
54  class Translator;
55  template<class TWorker> class ApplicationWorkGroup;
56  class TranslationThread;
57  class CommunicationThread;
58 
59  class RemoteNode;
60  typedef std::shared_ptr<RemoteNode> RemoteNodeSPtr;
61 
62  class LocalNode;
63  typedef std::shared_ptr<LocalNode> LocalNodeSPtr;
64 
65  class ReqOut;
66  typedef ReqOut *ReqOutPtr;
67  typedef std::unordered_map<ULong,ReqOutPtr> ReqOutUMap;
68 
69  class RspOut;
70  typedef RspOut *RspOutPtr;
71 
74 
75  #define SEND_TO_APPLICATION(a,b) \
76  (PFCP::Configuration::threadApplication()._sendThreadMessage(EThreadMessage( \
77  static_cast<UInt>(PFCP::ApplicationEvents::a),static_cast<pVoid>(b))))
78  #define SEND_TO_TRANSLATION(a,b) \
79  (PFCP::TranslationThread::Instance().sendMessage(EThreadMessage( \
80  static_cast<UInt>(PFCP::TranslationThread::Events::a),static_cast<pVoid>(b))))
81  #define SEND_TO_COMMUNICATION(a,b) \
82  (PFCP::CommunicationThread::Instance().sendMessage(EThreadMessage( \
83  static_cast<UInt>(PFCP::CommunicationThread::Events::a),static_cast<pVoid>(b))))
84 
87 
88  typedef ULongLong Seid;
89  typedef UChar MsgType;
90 
91  enum class MsgClass
92  {
93  Unknown,
94  Node,
95  Session
96  };
97 
100 
102  using MessageId = UInt;
103 
106  #define MAX_ATTEMPS 8
107 
109  class MessageStats
110  {
111  public:
116  using SentArray = std::array<UInt, MAX_ATTEMPS + 1>;
117 
121  MessageStats(MessageId id, cpStr name);
122 
126  MessageStats(MessageId id, const EString &name);
127 
130  MessageStats(const MessageStats &m);
131 
133  Void reset();
134 
137  MessageId getId() const { return id_; }
138 
141  const EString &getName() const { return name_; }
142 
146  UInt getReceived() const { return received_; }
147 
152  const SentArray &getSent() const { return sent_; }
153 
157  UInt getTimeout() const { return timeout_; }
158 
161  UInt incReceived() { return ++received_; }
162 
167  UInt incSent(UInt attempt = 0);
168 
171  UInt incTimeout() { return ++timeout_; }
172 
173  private:
174  MessageStats();
175 
176  MessageId id_;
177  EString name_;
178  std::atomic<UInt> received_;
179  SentArray sent_;
180  std::atomic<UInt> timeout_;
181  };
182 
183  using MessageStatsMap = std::unordered_map<MessageId, MessageStats>;
184 
187 
189  class Stats
190  {
191  public:
201  static Void collectNodeStats(EJsonBuilder &builder);
202 
204  static Void reset();
205 
210  static ETime lastReset();
211 
212  private:
213  static ERWLock lastresetlck_;
214  static ETime lastreset_;
215  };
216 
219 
220  class EventBase
221  {
222  public:
223  static void* operator new(size_t sz);
224  static void operator delete(void* m);
225  private:
226  static EMemory::Pool pool_;
227  };
228 
231 
232  DECLARE_ERROR(Configuration_LoggerNotDefined);
233  DECLARE_ERROR(Configuration_TranslatorNotDefined);
234  DECLARE_ERROR(Configuration_ApplicationNotDefined);
235 
237 
240  {
241  friend LocalNode;
242  friend RemoteNode;
243  friend TranslationThread;
244  friend CommunicationThread;
245  public:
246  static UShort port() { return port_; }
247  static UShort setPort(UShort port) { return port_ = port; }
248 
249  static Int socketBufferSize() { return bufsize_; }
250  static Int setSocketBufferSize(Int sz) { return bufsize_ = sz; }
251 
252  static LongLong t1() { return t1_; }
253  static LongLong setT1(LongLong t1) { return t1_ = t1; }
254 
255  static LongLong heartbeatT1() { return hbt1_; }
256  static LongLong setHeartbeatT1(LongLong hbt1) { return hbt1_ = hbt1; }
257 
258  static Int n1() { return n1_; }
259  static Int setN1(Int n1) { return n1_ = n1; }
260 
261  static Int heartbeatN1() { return hbn1_; }
262  static Int setHeartbeatN1(Int hbn1) { return hbn1_ = hbn1; }
263 
264  static Long maxRspWait() { return static_cast<Long>(std::max(t1_,hbt1_) * std::max(n1_,hbn1_)); }
265 
266  static size_t nbrActivityWnds() { return naw_; }
267  static size_t setNnbrActivityWnds(size_t naw) { return naw_ = naw; }
268 
269  static Long lenActivityWnd() { return law_; }
270  static Long setLenActivityWnd(Long law) { return law_ = law; }
271 
272  static ELogger &logger() { if (logger_ == nullptr) throw Configuration_LoggerNotDefined(); return *logger_; }
273  static ELogger &setLogger(ELogger &log) { logger_ = &log; return *logger_; }
274 
275  static Bool assignTeidRange() { return atr_; }
276  static Bool setAssignTeidRange(Bool atr) { return atr_ = atr; }
277 
278  static Int teidRangeBits() { return trb_; }
279  static Int setTeidRangeBits(Int trb) { return trb_ = trb; }
280 
281  static Translator &translator() { if (xlator_ == nullptr) throw Configuration_TranslatorNotDefined(); return *xlator_; }
282  static Translator &setTranslator(Translator &xlator) { return *(xlator_ = &xlator); }
283 
284  static Int minApplicationWorkers() { return aminw_; }
285  static Int setMinApplicationWorkers(Int w) { return aminw_ = w; }
286 
287  static Int maxApplicationWorkers() { return amaxw_; }
288  static Int setMaxApplicationWorkers(Int w) { return amaxw_ = w; }
289 
290  static Int minTranslatorWorkers() { return tminw_; }
291  static Int setMinTranslatorWorkers(Int w) { return tminw_ = w; }
292 
293  static Int maxTranslatorWorkers() { return tmaxw_; }
294  static Int setMaxTranslatorWorkers(Int w) { return tmaxw_ = w; }
295 
296  template<class TWorker>
297  static Void setApplication(ApplicationWorkGroup<TWorker> &app) { app_ = &app; baseapp_ = &app; }
298 
305  static MessageStatsMap &messageStatsTemplate() { return msgstats_template_; }
306 
307  static MsgType pfcpHeartbeatReq;
308  static MsgType pfcpHeartbeatRsp;
311  static MsgType pfcpAssociationSetupReq;
312  static MsgType pfcpAssociationSetupRsp;
313 
314  protected:
315  static _EThreadEventNotification &threadApplication() { if (app_ == nullptr) throw Configuration_ApplicationNotDefined(); return *app_; }
316  static ApplicationWorkGroupBase &baseApplication() { if (baseapp_ == nullptr) throw Configuration_ApplicationNotDefined(); return *baseapp_; }
317 
318  private:
319  static UShort port_;
320  static Int bufsize_;
321  static LongLong t1_;
322  static LongLong hbt1_;
323  static Int n1_;
324  static Int hbn1_;
325  static ELogger *logger_;
326  static size_t naw_;
327  static Long law_;
328  static Int trb_;
329  static Bool atr_;
330  static Translator *xlator_;
331  static Int aminw_;
332  static Int amaxw_;
333  static Int tminw_;
334  static Int tmaxw_;
335  static _EThreadEventNotification *app_;
336  static ApplicationWorkGroupBase *baseapp_;
337  static MessageStatsMap msgstats_template_;
338  };
339 
342 
346  {
347  public:
349  SequenceManager(): next_(SEQUENCE_MIN) {}
352  ULong alloc()
353  {
354  unsigned long sn;
355  while ((sn = next_++) > SEQUENCE_MAX)
356  next_.compare_exchange_strong(++sn, SEQUENCE_MIN);
357  return sn;
358  }
360  Void free(ULong sn)
361  {
362  // currently, nothing is done to "free" a sequence number
363  }
364  private:
365  static const ULong SEQUENCE_MIN = 0;
366  static const ULong SEQUENCE_MAX = 0x00ffffffff;
367  std::atomic_ulong next_;
368  };
369 
372 
376  {
377  public:
379  SeidManager() : next_(SEID_MINIMUM) {}
381  Seid alloc()
382  {
383  Seid seid;
384  // this logic depends on the numeric overflow from a max value to zero
385  // when the value is incremented.
386  while ((seid = next_++) < SEID_MINIMUM);
387  return seid;
388  }
390  Void free(Seid seid)
391  {
392  // currently, nothing is done to "free" a SEID
393  }
394  private:
395  static const Seid SEID_MINIMUM = 1;
396  std::atomic_ullong next_;
397  };
398 
401 
404  class FqSeid
405  {
406  public:
409  : addr_(),
410  seid_(0)
411  {
412  }
415  FqSeid(const FqSeid &fqseid)
416  : addr_(fqseid.addr_),
417  seid_(fqseid.seid_)
418  {
419  }
420 
423  FqSeid &operator=(const FqSeid &fqseid)
424  {
425  addr_ = fqseid.addr_;
426  seid_ = fqseid.seid_;
427  return *this;
428  }
429 
432  const EIpAddress &address() const { return addr_; }
435  EIpAddress &setAddress() { return addr_; }
436 
439  const Seid seid() const { return seid_; }
443  FqSeid &setSeid(Seid seid) { seid_ = seid; return *this; }
444 
445  private:
446  EIpAddress addr_;
447  Seid seid_;
448  };
449 
452 
454  class RcvdReq
455  {
456  public:
457  RcvdReq()
458  : sn_(0),
459  rw_(0)
460  {
461  }
462  RcvdReq(ULong seqNbr)
463  : sn_(seqNbr),
464  rw_(0)
465  {
466  }
467  RcvdReq(const RcvdReq &rr)
468  : sn_(rr.sn_),
469  rw_(rr.rw_)
470  {
471  }
472 
473  ULong seqNbr() const { return sn_; }
474  RcvdReq &setSeqNbr(ULong seqNbr) { sn_ = seqNbr; return *this; }
475 
476  Int rspWnd() const { return rw_; }
477  RcvdReq &setRspWnd(Int rw) { rw_ = rw; return *this; }
478 
479  private:
480  ULong sn_;
481  Int rw_;
482  };
483  typedef std::unordered_map<ULong,RcvdReq> RcvdReqUMap;
485 
488 
492  {
493  friend class LocalNode;
494  public:
496  NodeSocket();
498  virtual ~NodeSocket();
499 
503  NodeSocket &setLocalNode(LocalNodeSPtr &ln) { ln_ = ln; return *this; }
506  NodeSocket &clearLocalNode() { ln_.reset(); return *this; }
507 
508  protected:
515  Void onReceive(const ESocket::Address &src, const ESocket::Address &dst, cpUChar data, Int len);
518  Void onError();
519 
520  private:
521  LocalNodeSPtr ln_;
522  };
523 
526 
527  DECLARE_ERROR(SessionBase_LocalSeidAlreadySet);
528  DECLARE_ERROR(SessionBase_RemoteSeidAlreadySet);
529 
530  class SessionBase;
531  typedef std::shared_ptr<SessionBase> SessionBaseSPtr;
532 
537  {
538  public:
542  SessionBase(LocalNodeSPtr &ln, RemoteNodeSPtr &rn)
543  : ln_(ln),
544  rn_(rn),
545  ls_(0),
546  rs_(0)
547  {
548  created_++;
549  }
553  : ln_(s.ln_),
554  rn_(s.rn_),
555  ls_(s.ls_),
556  rs_(s.rs_)
557  {
558  created_++;
559  }
561  virtual ~SessionBase();
562 
565  LocalNodeSPtr &localNode() { return ln_; }
568  RemoteNodeSPtr &remoteNode() { return rn_; }
571  const Seid localSeid() const { return ls_; }
574  const Seid remoteSeid() const { return rs_; }
580  SessionBase &setSeid(SessionBaseSPtr &s, Seid ls, Seid rs, Bool notify = True);
585  SessionBase &setLocalSeid(SessionBaseSPtr &s, Seid ls) { return setSeid(s, ls, 0); }
590  SessionBase &setRemoteSeid(SessionBaseSPtr &s, Seid rs) { return setSeid(s, 0, rs); }
592  virtual Void destroy(SessionBaseSPtr &s);
593 
594  static ULongLong sessionsCreated() { return created_; }
595  static ULongLong sessionsDeleted() { return deleted_; }
596 
597  static void* operator new(size_t sz)
598  {
599  if (pool_.allocSize() == 0)
600  {
601  if (sz >= (32768 - sizeof(EMemory::Node)))
602  {
603  pool_.setSize(sz, 0, 5);
604  }
605  else
606  {
607  size_t ns = 32768 - sizeof(EMemory::Node);
608  size_t bs = sz + sizeof(EMemory::Block);
609  bs += bs % sizeof(pVoid);
610  size_t bc = ns / bs;
611  if (bc < 5)
612  {
613  pool_.setSize(sz, 0, 5);
614  }
615  else
616  {
617  ns = sizeof(EMemory::Node) + bc * bs;
618  pool_.setSize(sz, ns);
619  }
620  }
621  }
622  if (sz > pool_.allocSize())
623  {
624  EError ex;
625  ex.setSevere();
626  ex.setText("session allocation size is larger than memory pool block size");
627  throw ex;
628  }
629  return pool_.allocate();
630  }
631  static void operator delete(void* m)
632  {
633  pool_.deallocate(m);
634  }
635 private: \
636 
637  private:
638  SessionBase();
639  static EMemory::Pool pool_;
640  static ULongLong created_;
641  static ULongLong deleted_;
642  LocalNodeSPtr ln_;
643  RemoteNodeSPtr rn_;
644  Seid ls_;
645  Seid rs_;
646  };
647  typedef std::unordered_map<Seid,SessionBaseSPtr> SessionBaseSPtrUMap;
648 
651 
654  class Node
655  {
656  public:
658  Node() { ++created_; }
660  virtual ~Node() { ++deleted_; }
661 
664  EIpAddress &ipAddress() { return ipaddr_; }
668  Node &setIpAddress(const EIpAddress &ipaddr) { ipaddr_ = ipaddr; return *this; }
669 
674  ESocket::Address &address() { return addr_; }
680  {
681  addr_ = addr;
682  ipaddr_ = addr.getSockAddrStorage();
683  return *this;
684  }
685 
688  const ETime &startTime() const { return st_; }
692  Node &setStartTime(const ETime &st = ETime::Now()) { st_ = st; return *this; }
693 
697  SessionBaseSPtr getSession(Seid seid)
698  {
699  auto it = sessions_.find(seid);
700  if (it == sessions_.end())
701  return SessionBaseSPtr();
702  return it->second;
703  }
704 
705  static ULongLong nodesCreated() { return created_; }
706  static ULongLong nodesDeleted() { return deleted_; }
707 
708  protected:
710  Node &_addSession(Seid seid, SessionBaseSPtr &session)
711  {
712  auto it = sessions_.find(seid);
713  if (it == sessions_.end())
714  sessions_[seid] = session;
715  return *this;
716  }
717  Node &_delSession(Seid seid)
718  {
719  if (seid != 0)
720  sessions_.erase(seid);
721  return *this;
722  }
723  SessionBaseSPtr getFirstSession()
724  {
725  if (sessions_.empty())
726  return SessionBaseSPtr();
727  return sessions_.begin()->second;
728  }
730 
731  private:
732  static ULongLong created_;
733  static ULongLong deleted_;
734 
735  ETime st_;
736  EIpAddress ipaddr_;
737  ESocket::Address addr_;
738  SessionBaseSPtrUMap sessions_;
739  };
740 
741  typedef std::shared_ptr<Node> NodeSPtr;
742 
745 
747  DECLARE_ERROR(RemoteNodeException_UnableToAssignTeidRangeValue);
749 
751  class RemoteNode : public Node
752  {
753  friend LocalNode;
754  friend CommunicationThread;
755  public:
756  enum class State { Initialized, Started, Stopping, Stopped, Failed, Restarted };
757 
759  RemoteNode();
761  RemoteNode(const RemoteNode &) = delete;
763  virtual ~RemoteNode();
764 
767  Int teidRangeValue() const { return trv_; }
771  RemoteNode &setTeidRangeValue(Int trv) { trv_ = trv; return *this; }
772 
776  RemoteNode &setNbrActivityWnds(size_t nbr);
777 
782  RemoteNode &deleteAllSesssions(RemoteNodeSPtr &rn);
783 
785  class Stats
786  {
787  public:
791  ERWLock &getLock() { return lock_; }
792 
797  MessageStatsMap &messageStats() { return msgstats_; }
798 
802  ETime getLastActivity();
803 
806  Void setLastActivity();
807 
810  Void reset();
811 
818  UInt incReceived(MessageId msgid);
819 
828  UInt incSent(MessageId msgid, UInt attempt = 0);
829 
836  UInt incTimeout(MessageId msgid);
837 
838  private:
839  ERWLock lock_;
840  MessageStatsMap msgstats_;
841  ETime lastactivity_;
842  };
843 
846  Stats &stats() { return stats_; }
847 
855  virtual Void collectStats(EJsonBuilder &builder);
856 
860  RemoteNode &disconnect(RemoteNodeSPtr &rn);
861 
864  State state() const { return state_; }
865 
866  protected:
868  RemoteNode &changeState(RemoteNodeSPtr &rn, State state);
869  RemoteNode &restarted(RemoteNodeSPtr &rn, const ETime &restartTime);
870  Bool addRcvdReq(ULong sn);
871  Bool delRcvdReq(ULong sn) { return rrumap_.erase(sn) == 1; }
872  Bool setRcvdReqRspWnd(ULong sn, Int wnd);
873  Bool setRcvdReqRspWnd(ULong sn);
874  Void removeRcvdRqstEntries(Int wnd);
875  Bool rcvdReqExists(ULong sn) const { return rrumap_.find(sn) != rrumap_.end(); }
876 
877  Void nextActivityWnd(Int wnd);
878  Bool checkActivity();
879  Void incrementActivity() { awnds_[aw_]++; }
880 
881  Void removeOldReqs(Int rw);
882 
883  RemoteNode &addSession(SessionBaseSPtr &s);
884  RemoteNode &delSession(SessionBaseSPtr &s);
886 
887  private:
888  State state_;
889  ESocket::Address addr_;
890  Int trv_;
891  RcvdReqUMap rrumap_;
892  std::vector<ULong> awnds_;
893  size_t awndcnt_;
894  size_t aw_;
895  Stats stats_;
896  };
897  typedef std::unordered_map<EIpAddress,RemoteNodeSPtr> RemoteNodeUMap;
898  typedef std::pair<EIpAddress,RemoteNodeSPtr> RemoteNodeUMapPair;
899 
900  class RemoteNodeStateChangeEvent : public EventBase
901  {
902  public:
904  : rn_(rn),
905  os_(oldst),
906  ns_(newst)
907  {
908  }
909 
910  RemoteNodeSPtr &remoteNode() { return rn_; }
911  RemoteNode::State oldState() const { return os_; }
912  RemoteNode::State newState() const { return ns_; }
913 
914  private:
916  RemoteNodeSPtr rn_;
917  RemoteNode::State os_;
918  RemoteNode::State ns_;
919  };
920 
921  class RemoteNodeRestartEvent : public EventBase
922  {
923  public:
924  RemoteNodeRestartEvent(RemoteNodeSPtr &rn, RemoteNode::State oldst,
925  RemoteNode::State newst, const ETime &restartTime)
926  : rn_(rn),
927  os_(oldst),
928  ns_(newst),
929  rt_(restartTime)
930  {
931  }
932 
933  RemoteNodeSPtr &remoteNode() { return rn_; }
934  RemoteNode::State oldState() const { return os_; }
935  RemoteNode::State newState() const { return ns_; }
936  const ETime &restartTime() const { return rt_; }
937 
938  private:
940  RemoteNodeSPtr rn_;
941  RemoteNode::State os_;
942  RemoteNode::State ns_;
943  ETime rt_;
944  };
945 
948 
950  DECLARE_ERROR(LocalNodeException_UnableToCreateRemoteNode);
951  DECLARE_ERROR(LocalNodeException_RemoteNodeUMapInsertFailed);
953 
955  class LocalNode : public Node
956  {
957  friend NodeSocket;
958  friend CommunicationThread;
959  public:
960  enum class State { Initialized, Started, Stopping, Stopped };
961 
963  LocalNode();
965  virtual ~LocalNode();
966 
969  State state() { return state_; }
970 
973  Seid allocSeid();
976  Void freeSeid(Seid seid);
979  ULong allocSeqNbr();
982  Void freeSeqNbr(ULong sn);
983 
986  Void setNbrActivityWnds(size_t nbr);
987 
991  RemoteNodeSPtr createRemoteNode(cpStr addr, UShort port)
992  {
993  EIpAddress ipaddr(addr);
994  return createRemoteNode(ipaddr, port);
995  }
1000  RemoteNodeSPtr createRemoteNode(EIpAddress &address, UShort port);
1001 
1006  RemoteNodeUMap &remoteNodes() { return rns_; }
1007 
1010  ERWLock &remoteNodesLock() { return rnslck_; }
1011 
1019  virtual Void collectStats(EJsonBuilder &builder);
1020 
1026  SessionBaseSPtr createSession(LocalNodeSPtr &ln, RemoteNodeSPtr &rn);
1027 
1030  NodeSocket &socket() { return socket_; }
1031 
1034  State state() const { return state_; }
1035 
1036  protected:
1037 
1039  LocalNode &changeState(LocalNodeSPtr &ln, State state);
1040  Bool rqstOutExists(ULong seqnbr) const;
1041  Bool addRqstOut(ReqOut *ro);
1042  Bool setRqstOutRespWnd(ULong seqnbr, Int wnd);
1043  Void removeRqstOutEntries(Int wnd);
1044  Void clearRqstOutEntries();
1045 
1046  Void nextActivityWnd(Int wnd);
1047  Void checkActivity(LocalNodeSPtr &ln);
1048 
1049  Void onReceive(LocalNodeSPtr &ln, const ESocket::Address &src, const ESocket::Address &dst, cpUChar msg, Int len);
1050  Bool onReqOutTimeout(ReqOutPtr ro);
1051  Void removeOldReqs(Int rw);
1052 
1053  Void sndInitialReq(ReqOutPtr ro);
1054  Bool sndReq(ReqOutPtr ro);
1055  Void sndRsp(RspOutPtr ro);
1056 
1057  LocalNode &addSession(SessionBaseSPtr &s)
1058  {
1059  if (s && s->localSeid() != 0)
1060  _addSession(s->localSeid(), s);
1061  return *this;
1062  }
1063  LocalNode &delSession(SessionBaseSPtr &s)
1064  {
1065  if (s && s->localSeid() != 0)
1066  _delSession(s->localSeid());
1067  return *this;
1068  }
1069  SessionBaseSPtr createSession(LocalNodeSPtr &ln, Seid rs, RemoteNodeSPtr &rn);
1071 
1072  private:
1073  State state_;
1074  SeidManager seidmgr_;
1075  SequenceManager seqmgr_;
1076  NodeSocket socket_;
1077  ReqOutUMap roumap_;
1078  RemoteNodeUMap rns_;
1079  ERWLock rnslck_;
1080  };
1081 
1082  typedef std::unordered_map<EIpAddress,LocalNodeSPtr> LocalNodeUMap;
1083  typedef std::pair<EIpAddress,LocalNodeSPtr> LocalNodeUMapEIpAddressPair;
1084  typedef std::pair<ULong,LocalNodeSPtr> LocalNodeUMapULongPair;
1085 
1086  class LocalNodeStateChangeEvent : public EventBase
1087  {
1088  public:
1090  : ln_(ln),
1091  os_(oldst),
1092  ns_(newst)
1093  {
1094  }
1095 
1096  LocalNodeSPtr &localNode() { return ln_; }
1097  LocalNode::State oldState() const { return os_; }
1098  LocalNode::State newState() const { return ns_; }
1099 
1100  private:
1102  LocalNodeSPtr ln_;
1103  LocalNode::State os_;
1104  LocalNode::State ns_;
1105  };
1108 
1110  class AppMsg
1111  {
1112  public:
1114  virtual ~AppMsg()
1115  {
1116  }
1117 
1120  ULong seqNbr() const { return seq_; }
1123  MsgType msgType() const { return mt_; }
1126  MsgClass msgClass() const { return mc_; }
1128  Bool isReq() const { return rqst_; }
1129 
1132  AppMsg &setSeqNbr(const ULong sn) { seq_ = sn; return *this; }
1133 
1136  virtual const EString &className()
1137  {
1138  static EString cn_ = ::__CLASS_NAME__;
1139  return cn_;
1140  }
1141 
1143  virtual Void postDecode() {}
1145 
1146  protected:
1148  : seq_(0),
1149  mt_(0),
1150  mc_(MsgClass::Unknown),
1151  rqst_(False)
1152  {
1153  }
1154  AppMsg(const AppMsg &dm)
1155  : seq_(dm.seq_),
1156  mt_(dm.mt_),
1157  mc_(dm.mc_),
1158  rqst_(dm.rqst_)
1159  {
1160  }
1161 
1162  AppMsg &setMsgType(const MsgType mt) { mt_ = mt; return*this; }
1163  AppMsg &setMsgClass(const MsgClass mc) { mc_ = mc; return*this; }
1164  AppMsg &setIsReq(const Bool rqst) { rqst_ = rqst; return *this; }
1165 
1166  private:
1167  ULong seq_;
1168  MsgType mt_;
1169  MsgClass mc_;
1170  Bool rqst_;
1171  };
1172 
1173  typedef AppMsg *AppMsgPtr;
1174 
1177 
1179  class AppMsgReq : public AppMsg
1180  {
1181  public:
1183  virtual ~AppMsgReq()
1184  {
1185  }
1186 
1189  LocalNodeSPtr &localNode() { return ln_; }
1192  RemoteNodeSPtr &remoteNode() { return rn_; }
1193 
1194  protected:
1197  {
1198  setIsReq(True);
1199  }
1203  AppMsgReq(LocalNodeSPtr &ln, RemoteNodeSPtr &rn, Bool allocSeqNbr)
1204  : ln_(ln),
1205  rn_(rn)
1206  {
1207  setIsReq(True);
1208  if (allocSeqNbr)
1209  setSeqNbr(ln->allocSeqNbr());
1210  }
1211 
1212  private:
1213  LocalNodeSPtr ln_;
1214  RemoteNodeSPtr rn_;
1215  };
1217 
1220 
1223  class AppMsgNodeReq : public AppMsgReq
1224  {
1225  public:
1228  {
1229  setMsgClass(PFCP::MsgClass::Node);
1230  }
1234  AppMsgNodeReq(LocalNodeSPtr &ln, RemoteNodeSPtr &rn, Bool allocSeqNbr)
1235  : AppMsgReq(ln, rn, allocSeqNbr)
1236  {
1237  setMsgClass(PFCP::MsgClass::Node);
1238  }
1240  virtual ~AppMsgNodeReq()
1241  {
1242  }
1243  };
1244 
1246 
1249 
1252  {
1253  public:
1256  {
1257  setMsgClass(PFCP::MsgClass::Session);
1258  }
1262  AppMsgSessionReq(SessionBaseSPtr &ses, Bool allocSeqNbr)
1263  : AppMsgReq(ses->localNode(), ses->remoteNode(), allocSeqNbr),
1264  ses_(ses)
1265  {
1266  setMsgClass(PFCP::MsgClass::Session);
1267  }
1270  {
1271  }
1272 
1275  SessionBaseSPtr &session() { return ses_; }
1276 
1277  private:
1278  SessionBaseSPtr ses_;
1279  };
1280 
1282 
1285 
1287  class AppMsgRsp : public AppMsg
1288  {
1289  public:
1292  : amrq_(nullptr)
1293  {
1294  setIsReq(False);
1295  }
1299  AppMsgRsp(AppMsgReqPtr amrq)
1300  : amrq_(amrq)
1301  {
1302  setIsReq(False);
1303  }
1305  virtual ~AppMsgRsp()
1306  {
1307  if (amrq_)
1308  delete amrq_;
1309  }
1310 
1313  AppMsgReqPtr req() { return amrq_; }
1316  LocalNodeSPtr &localNode() { return amrq_->localNode(); }
1319  RemoteNodeSPtr &remoteNode() { return amrq_->remoteNode(); }
1320 
1324  {
1325  amrq_ = req;
1326  if (amrq_)
1327  setSeqNbr(amrq_->seqNbr());
1328  return *this;
1329  }
1330 
1331  private:
1332  AppMsgReqPtr amrq_;
1333  };
1335 
1338 
1340  class AppMsgNodeRsp : public AppMsgRsp
1341  {
1342  public:
1345  : AppMsgRsp(nullptr)
1346  {
1347  setMsgClass(PFCP::MsgClass::Node);
1348  setIsReq(False);
1349  }
1353  AppMsgNodeRsp(AppMsgNodeReqPtr &amrq)
1354  : AppMsgRsp(amrq)
1355  {
1356  setMsgClass(PFCP::MsgClass::Node);
1357  setIsReq(False);
1358  }
1360  virtual ~AppMsgNodeRsp()
1361  {
1362  }
1363 
1366  AppMsgNodeReqPtr req() { return static_cast<AppMsgNodeReqPtr>(AppMsgRsp::req()); }
1367 
1370  AppMsgNodeRsp &setReq(AppMsgNodeReqPtr req) { AppMsgRsp::setReq(req); return *this; }
1371  };
1372 
1374 
1377 
1380  {
1381  public:
1384  : AppMsgRsp(nullptr)
1385  {
1386  setMsgClass(PFCP::MsgClass::Session);
1387  }
1391  AppMsgSessionRsp(AppMsgSessionReqPtr &amrq)
1392  : AppMsgRsp(amrq)
1393  {
1394  setMsgClass(PFCP::MsgClass::Session);
1395  }
1398  {
1399  }
1400 
1403  AppMsgSessionReqPtr req() { return static_cast<AppMsgSessionReqPtr>(AppMsgRsp::req()); }
1404 
1407  AppMsgSessionRsp &setReq(AppMsgSessionReqPtr req) { AppMsgRsp::setReq(req); return *this; }
1408  };
1409 
1411 
1414 
1416  class SndHeartbeatReqData
1417  {
1418  public:
1419  SndHeartbeatReqData()
1420  {
1421  }
1422  SndHeartbeatReqData(LocalNodeSPtr &ln, RemoteNodeSPtr &rn)
1423  : ln_(ln),
1424  rn_(rn)
1425  {
1426  }
1427  SndHeartbeatReqData(const SndHeartbeatReqData &hb)
1428  {
1429  ln_ = hb.ln_;
1430  rn_ = hb.rn_;
1431  }
1432 
1433  LocalNodeSPtr &localNode() { return ln_; }
1434  RemoteNodeSPtr &remoteNode() { return rn_; }
1435 
1436  SndHeartbeatReqData &setLocalNode(LocalNodeSPtr &ln) { ln_ = ln; return *this; }
1437  SndHeartbeatReqData &setRemoteNode(RemoteNodeSPtr &rn) { rn_ = rn; return *this; }
1438 
1439  private:
1440  LocalNodeSPtr ln_;
1441  RemoteNodeSPtr rn_;
1442  };
1443  typedef SndHeartbeatReqData *SndHeartbeatReqDataPtr;
1445 
1448 
1450  class RcvdHeartbeatReqData
1451  {
1452  public:
1453  RcvdHeartbeatReqData()
1454  : am_(nullptr)
1455  {
1456  }
1457  RcvdHeartbeatReqData(const RcvdHeartbeatReqData &hb)
1458  {
1459  am_ = hb.am_;
1460  started_ = hb.started_;
1461  }
1462 
1463  AppMsgNodeReqPtr req() const { return am_; }
1464  const ETime &startTime() const { return started_; }
1465 
1466  RcvdHeartbeatReqData &setReq(AppMsgNodeReqPtr am) { am_ = am; return *this;}
1467  RcvdHeartbeatReqData &setStartTime(const ETime &started) { started_ = started; return *this; }
1468 
1469  private:
1470  AppMsgNodeReqPtr am_;
1471  ETime started_;
1472  };
1473  typedef RcvdHeartbeatReqData *RcvdHeartbeatReqDataPtr;
1475 
1478 
1480  class SndHeartbeatRspData
1481  {
1482  public:
1483  SndHeartbeatRspData()
1484  : am_(nullptr)
1485  {
1486  }
1487  SndHeartbeatRspData(AppMsgNodeReqPtr am)
1488  : am_(am)
1489  {
1490  }
1491 
1492  AppMsgNodeReq &req() { return *am_; }
1493 
1494  SndHeartbeatRspData &setReq(AppMsgNodeReqPtr am) { am_ = am; return *this; }
1495 
1496  private:
1497  AppMsgNodeReqPtr am_;
1498  };
1499  typedef SndHeartbeatRspData *SndHeartbeatRspDataPtr;
1501 
1504 
1506  class RcvdHeartbeatRspData
1507  {
1508  public:
1509  RcvdHeartbeatRspData()
1510  : am_(nullptr)
1511  {
1512  }
1513  RcvdHeartbeatRspData(AppMsgNodeReqPtr am)
1514  : am_(am)
1515  {
1516  }
1517  ~RcvdHeartbeatRspData()
1518  {
1519  if (am_)
1520  {
1521  delete am_;
1522  am_ = nullptr;
1523  }
1524  }
1525 
1526  AppMsgNodeReq &req() { return *am_; }
1527  const ETime &startTime() const { return started_; }
1528 
1529  RcvdHeartbeatRspData &setReq(AppMsgNodeReqPtr am) { am_ = am; return *this; }
1530  RcvdHeartbeatRspData &setStartTime(const ETime &started) { started_ = started; return *this; }
1531 
1532  private:
1533  AppMsgNodeReqPtr am_;
1534  ETime started_;
1535  };
1536  typedef RcvdHeartbeatRspData *RcvdHeartbeatRspDataPtr;
1538 
1541 
1543  DECLARE_ERROR(InternalMsg_OutOfMemory);
1544 
1545  class TranslatorMsgInfo;
1546 
1547  class InternalMsg
1548  {
1549  public:
1550  InternalMsg()
1551  : seq_(0),
1552  mt_(0),
1553  mc_(MsgClass::Unknown),
1554  rqst_(False),
1555  data_(nullptr),
1556  len_(0)
1557  {
1558  }
1559  InternalMsg(const InternalMsg &im)
1560  : ln_(im.ln_),
1561  rn_(im.rn_),
1562  ses_(im.ses_),
1563  seq_(im.seq_),
1564  mt_(im.mt_),
1565  mc_(im.mc_),
1566  rqst_(im.rqst_),
1567  data_(nullptr),
1568  len_(0)
1569  {
1570  assign(im.data_, im.len_);
1571  }
1572  InternalMsg(const LocalNodeSPtr &ln, const RemoteNodeSPtr &rn, const TranslatorMsgInfo &tmi, cpUChar data, UShort len);
1573  virtual ~InternalMsg()
1574  {
1575  if (data_ != nullptr)
1576  delete [] data_;
1577  }
1578 
1579  InternalMsg &operator=(const InternalMsg &im)
1580  {
1581  ln_ = im.ln_;
1582  rn_ = im.rn_;
1583  ses_ = im.ses_;
1584  seq_ = im.seq_;
1585  mt_ = im.mt_;
1586  mc_ = im.mc_;
1587  rqst_ = im.rqst_;
1588  assign(im.data_, im.len_);
1589  return *this;
1590  }
1591 
1592  LocalNodeSPtr &localNode() { return ln_; }
1593  RemoteNodeSPtr &remoteNode() { return rn_; }
1594  SessionBaseSPtr &session() { return ses_; }
1595  ULong seqNbr() const { return seq_; }
1596  MsgType msgType() const { return mt_; }
1597  MsgClass msgClass() const { return mc_; }
1598  Bool isReq() const { return rqst_; }
1599  UChar version() const { return ver_; }
1600  cpUChar data() const { return data_; }
1601  UShort len() const { return len_; }
1602 
1603  InternalMsg &setLocalNode(const LocalNodeSPtr &ln) { ln_ = ln; return *this; }
1604  InternalMsg &setRemoteNode(const RemoteNodeSPtr &rn) { rn_ = rn; return *this; }
1605  InternalMsg &setSession(const SessionBaseSPtr &ses) { ses_ = ses; return *this; }
1606  InternalMsg &setSeqNbr(const ULong sn) { seq_ = sn; return *this; }
1607  InternalMsg &setMsgType(const MsgType mt) { mt_ = mt; return *this; }
1608  InternalMsg &setMsgClass(const MsgClass mc) { mc_ = mc; return *this; }
1609  InternalMsg &setIsReq(const Bool rqst) { rqst_ = rqst; return *this; }
1610  InternalMsg &setVersion(const UChar ver) { ver_ = ver; return *this; }
1611 
1612  InternalMsg &assign(cpUChar data, UShort len)
1613  {
1614  // allocate the memory if necessary
1615  if (len_ != len)
1616  {
1617  if (data_ != nullptr)
1618  delete [] data_;
1619  len_ = len;
1620  try
1621  {
1622  data_ = new UChar[len_];
1623  }
1624  catch(const std::bad_alloc& e)
1625  {
1626  throw InternalMsg_OutOfMemory();
1627  }
1628  }
1629  // copy the data
1630  std::memcpy(data_, data, len);
1631  return *this;
1632  }
1633 
1634  static void* operator new(size_t sz);
1635  static void operator delete(void* m);
1636 
1637  private:
1638  static EMemory::Pool pool_;
1639  LocalNodeSPtr ln_;
1640  RemoteNodeSPtr rn_;
1641  SessionBaseSPtr ses_;
1642  ULong seq_;
1643  MsgType mt_;
1644  MsgClass mc_;
1645  Bool rqst_;
1646  UChar ver_;
1647  pUChar data_;
1648  UShort len_;
1649  };
1650 
1651  typedef InternalMsg *InternalMsgPtr;
1653 
1656 
1658  class RspOut : public InternalMsg
1659  {
1660  public:
1661  RspOut()
1662  : am_(nullptr)
1663  {
1664  }
1665  RspOut(const RspOut &sr)
1666  : InternalMsg(sr)
1667  {
1668  }
1669  virtual ~RspOut()
1670  {
1671  if (am_ != nullptr)
1672  delete am_;
1673  }
1674 
1675  RspOut &operator=(const RspOut &ro)
1676  {
1677  InternalMsg::operator=(ro);
1678  am_ = ro.am_;
1679  return *this;
1680  }
1681 
1682  AppMsgRspPtr appMsg() { return am_; }
1683  RspOut &setAppMsg(AppMsgRspPtr am)
1684  {
1685  am_ = am;
1686  if (am)
1687  {
1688  setMsgType(am->msgType());
1689  setMsgClass(am->msgClass());
1690  }
1691  return *this;
1692  }
1693 
1694  private:
1695  AppMsgRspPtr am_;
1696  };
1697  typedef RspOut *RspOutPtr;
1699 
1702 
1704  class RspIn : public InternalMsg
1705  {
1706  public:
1707  RspIn()
1708  : am_(nullptr),
1709  rs_(0)
1710  {
1711  }
1712  RspIn(const RspIn &ri)
1713  : InternalMsg(ri),
1714  am_(ri.am_),
1715  rs_(ri.rs_)
1716  {
1717  }
1718  RspIn(const LocalNodeSPtr &ln, const RemoteNodeSPtr &rn, const TranslatorMsgInfo &tmi, cpUChar data, UShort len, AppMsgReqPtr am)
1719  : InternalMsg(ln, rn, tmi, data, len),
1720  am_(am)
1721  {
1722  }
1723  virtual ~RspIn()
1724  {
1725  }
1726 
1727  RspIn &operator=(const RspIn &ri)
1728  {
1729  InternalMsg::operator=(ri);
1730  am_ = ri.am_;
1731  return *this;
1732  }
1733 
1734  AppMsgReqPtr req() const { return am_; }
1735  RspIn &setReq(AppMsgReqPtr am) { am_ = am; return *this; }
1736 
1737  Seid remoteSeid() const { return rs_; }
1738  RspIn &remoteSeid(Seid rs) { rs_ = rs; return *this; }
1739 
1740  const ETime &remoteStartTime() { return rst_; }
1741  RspIn &remoteStartTime(const ETime &rst) { rst_ = rst; return *this; }
1742  private:
1743  AppMsgReqPtr am_;
1744  Seid rs_;
1745  ETime rst_;
1746  };
1747  typedef RspIn *RspInPtr;
1749 
1752 
1754  class ReqOut : public InternalMsg
1755  {
1756  public:
1757  ReqOut()
1758  : InternalMsg(),
1759  am_(),
1760  n1_(Configuration::n1()),
1761  t1_(Configuration::t1()),
1762  t1id_(0),
1763  rw_(0)
1764  {
1765  }
1766  ReqOut(const ReqOut &ro)
1767  : InternalMsg(ro),
1768  am_(ro.am_),
1769  n1_(ro.n1_),
1770  t1_(ro.t1_),
1771  t1id_(ro.t1id_),
1772  rw_(ro.rw_)
1773  {
1774  }
1775  virtual ~ReqOut()
1776  {
1777  if (am_)
1778  {
1779  delete am_;
1780  am_ = nullptr;
1781  }
1782  }
1783 
1784  ReqOut &operator=(const ReqOut &ro)
1785  {
1786  InternalMsg::operator=(ro);
1787  am_ = ro.am_;
1788  n1_ = ro.n1_;
1789  t1_ = ro.t1_;
1790  t1id_ = ro.t1id_;
1791  rw_ = ro.rw_;
1792  return *this;
1793  }
1794 
1795  AppMsgReqPtr appMsg() { return am_; }
1796  ReqOut &setAppMsg(AppMsgReqPtr am)
1797  {
1798  am_ = am;
1799  if (am)
1800  {
1801  setMsgType(am->msgType());
1802  setMsgClass(am->msgClass());
1803  }
1804  return *this;
1805  }
1806 
1807  Bool okToSnd() { if (n1_ < 1) return False; n1_--; return True; }
1808 
1809  Int n1() const { return n1_; }
1810  ReqOut &setN1(Int n1) { n1_ = n1; return *this; }
1811 
1812  LongLong t1() const { return t1_; }
1813  ReqOut &setT1(LongLong t1) { t1_ = t1; return *this; }
1814 
1815  Int rspWnd() const { return rw_; }
1816  ReqOut &setRspWnd(Int rw) { rw_ = rw; return *this; }
1817 
1818  Void startT1();
1819  Void stopT1()
1820  {
1821  if (t1id_ > 0)
1822  {
1824  t1id_ = 0;
1825  }
1826  }
1827 
1828  private:
1829  AppMsgReqPtr am_;
1830  Int n1_;
1831  LongLong t1_;
1832  ULong t1id_;
1833  Int rw_;
1834  };
1836 
1839 
1841  class ReqIn : public InternalMsg
1842  {
1843  public:
1844  ReqIn()
1845  : rs_(0)
1846  {
1847  }
1848  ReqIn(const ReqIn &ri)
1849  : InternalMsg(ri),
1850  rs_(ri.rs_)
1851  {
1852  }
1853  ReqIn(const LocalNodeSPtr &ln, const RemoteNodeSPtr &rn, const TranslatorMsgInfo &tmi, cpUChar data, UShort len)
1854  : InternalMsg(ln, rn, tmi, data, len)
1855  {
1856  }
1857  virtual ~ReqIn()
1858  {
1859  }
1860 
1861  Seid remoteSeid() { return rs_; }
1862  ReqIn &remoteSeid(Seid rs) { rs_ = rs; return *this; }
1863 
1864  const ETime &remoteStartTime() { return rst_; }
1865  ReqIn &remoteStartTime(const ETime &rst) { rst_ = rst; return *this; }
1866  private:
1867  Seid rs_;
1868  ETime rst_;
1869  };
1870  typedef ReqIn *ReqInPtr;
1872 
1875 
1876 #if 0
1877  InternalMsg
1878  SEID
1879  seqNbr
1880  MsgType
1881  isReq
1882  buffer
1883  len
1884  application structure allocated by EncoderDecoder based on msg type
1885 
1886  RspOut
1887  InternalMsg
1888 
1889  RspIn
1890  InternalMsg
1891  AppMsgSPtr
1892 
1893  ReqOut
1894  InternalMsg
1895  AppMsgSPtr
1896  timerId
1897  sendCount
1898  rspWnd (0,1,2)
1899 
1900  ReqIn
1901  InternalMsg
1902 
1903  RcvdReq
1904  seqNbr
1905  rspWnd (0,1,2)
1906 
1907 
1908 Snding a Req (ReqOut)
1909  add ReqOut object local Node retransmission list (seqnbr is key)
1910  set sendCount = 0
1911  perform "retransmission timer expiration" procedure
1912  start retransmission timer
1913 
1914  retransmission timer expiration
1915  sendCount >= N1
1916  send ReqMsgPtr to application layer indicating rsp timeout
1917  remove SentReq from retransmission list
1918  sendCount < N1
1919  send the req
1920  increment sendCount
1921  start expiration timer
1922 
1923 Receiving a Req
1924  Lookup seqNbr in ReqIn list of remote Node
1925  entry found
1926  log duplicate req
1927  discard msg
1928  entry not found
1929  create RcvdReq with seqNbr, rspWnd=0
1930  add RcvdReq to remove Node RcvdReq list (seqNbr)
1931  send EncodedMsg to EcDc layer to decoding
1932 
1933 Snding a Rsp
1934  Lookup sequence in ReqIn list of the remote node
1935  entry found
1936  update rspWnd in ReqIn to the current wnd
1937  send the msg
1938  entry not found
1939  discard msg(?)
1940 
1941 Receiving a Rsp
1942  lookup ReqOut in local Node retransmission list (seqNbr)
1943  ReqOut found
1944  set ReqOut rspWnd to current wnd
1945  create RspIn and send to EcDc layer to decode
1946  ReqOut not found
1947  log error
1948  discard msg
1949 
1950 
1951 Receiving a msg
1952  perform partial header parsing (seqNbr, isReq)
1953  isReq is TRUE
1954  go to Receiving a Req
1955  isReq is FALSE
1956  go to Receiving a Reponse
1957 
1958 #endif
1959 
1962 
1964  DECLARE_ERROR_ADVANCED(TeidRangeManager_InvalidRangeBits);
1965  inline TeidRangeManager_InvalidRangeBits::TeidRangeManager_InvalidRangeBits() {
1966  setText("The number of range bits must be between 0 and 7");
1967  }
1968 
1969  class TeidRangeManager
1970  {
1971  public:
1972  TeidRangeManager(Int rangeBits=0);
1973  ~TeidRangeManager();
1974 
1975  Bool assign(RemoteNodeSPtr &n);
1976  Void release(RemoteNodeSPtr &n);
1977 
1978  private:
1979  Int bits_;
1980  std::list<Int> free_;
1981  std::unordered_map<Int,RemoteNodeSPtr> used_;
1982  };
1984 
1987 
1989  class TranslatorMsgInfo
1990  {
1991  public:
1992  TranslatorMsgInfo()
1993  : seid_(0),
1994  mt_(0),
1995  sn_(0),
1996  ver_(0),
1997  rqst_(False)
1998  {
1999  }
2000 
2001  Seid seid() const { return seid_; }
2002  MsgType msgType() const { return mt_; }
2003  MsgClass msgClass() const { return mc_; }
2004  ULong seqNbr() const { return sn_; }
2005  UChar version() const { return ver_; }
2006  Bool isReq() const { return rqst_; }
2007  Bool createSession() const { return create_; }
2008 
2009  TranslatorMsgInfo &setSeid(const Seid seid) { seid_ = seid; return *this; }
2010  TranslatorMsgInfo &setMsgType(const MsgType mt) { mt_ = mt; return *this; }
2011  TranslatorMsgInfo &setMsgClass(const MsgClass mc) { mc_ = mc; return *this; }
2012  TranslatorMsgInfo &setSeqNbr(const ULong sn) { sn_ = sn; return *this; }
2013  TranslatorMsgInfo &setVersion(UChar ver) { ver_ = ver; return *this; }
2014  TranslatorMsgInfo &setReq(Bool rqst) { rqst_ = rqst; return *this; }
2015  TranslatorMsgInfo &setCreateSession(Bool create) { create_ = create; return *this; }
2016 
2017  private:
2018  Seid seid_;
2019  MsgType mt_;
2020  MsgClass mc_;
2021  ULong sn_;
2022  UChar ver_;
2023  Bool rqst_;
2024  Bool create_;
2025  };
2027 
2030 
2035  {
2036  public:
2038  Translator();
2040  virtual ~Translator();
2041 
2045  virtual ReqOutPtr encodeHeartbeatReq(SndHeartbeatReqData &hb) = 0;
2049  virtual RspOutPtr encodeHeartbeatRsp(SndHeartbeatRspData &hb) = 0;
2053  virtual RspOutPtr encodeVersionNotSupportedRsp(ReqInPtr msg) = 0;
2054 
2059  virtual ReqOutPtr encodeReq(AppMsgReqPtr msg) = 0;
2064  virtual RspOutPtr encodeRsp(AppMsgRspPtr msg) = 0;
2065 
2069  virtual AppMsgReqPtr decodeReq(ReqInPtr msg) = 0;
2073  virtual AppMsgRspPtr decodeRsp(RspInPtr msg) = 0;
2074 
2078  virtual RcvdHeartbeatReqDataPtr decodeHeartbeatReq(ReqInPtr msg) = 0;
2082  virtual RcvdHeartbeatRspDataPtr decodeHeartbeatRsp(RspInPtr msg) = 0;
2083 
2088  virtual Void getMsgInfo(TranslatorMsgInfo &info, cpUChar msg, Int len) = 0;
2091  virtual Bool isVersionSupported(UChar ver) = 0;
2094  virtual MsgClass messageClass(MsgType mt) = 0;
2095 
2098  virtual MsgType pfcpHeartbeatReq() = 0;
2101  virtual MsgType pfcpHeartbeatRsp() = 0;
2104  virtual MsgType pfcpSessionEstablishmentReq() = 0;
2107  virtual MsgType pfcpSessionEstablishmentRsp() = 0;
2110  virtual MsgType pfcpAssociationSetupReq() = 0;
2113  virtual MsgType pfcpAssociationSetupRsp() = 0;
2114 
2115  protected:
2117  pUChar data() { return data_; }
2119 
2120  private:
2121  UChar data_[ESocket::UPD_MAX_MSG_LENGTH];
2122  };
2123 
2126 
2128  DECLARE_ERROR(SndReqException);
2129  struct SndReqExceptionData
2130  {
2131  AppMsgReqPtr req;
2132  SndReqException err;
2133  };
2134  typedef SndReqExceptionData *SndReqExceptionDataPtr;
2135 
2136  DECLARE_ERROR(SndRspException);
2137  struct SndRspExceptionData
2138  {
2139  AppMsgRspPtr rsp;
2140  SndRspException err;
2141  };
2142  typedef SndRspExceptionData *SndRspExceptionDataPtr;
2143 
2144  DECLARE_ERROR(SndHeartbeatReqException);
2145  struct SndHeartbeatReqExceptionData
2146  {
2147  SndHeartbeatReqDataPtr req;
2148  SndHeartbeatReqException err;
2149  };
2150  typedef SndHeartbeatReqExceptionData *SndHeartbeatReqExceptionDataPtr;
2151 
2152  DECLARE_ERROR(SndHeartbeatRspException);
2153  struct SndHeartbeatRspExceptionData
2154  {
2155  SndHeartbeatRspDataPtr rsp;
2156  SndHeartbeatRspException err;
2157  };
2158  typedef SndHeartbeatRspExceptionData *SndHeartbeatRspExceptionDataPtr;
2159 
2160  DECLARE_ERROR(RcvdReqException);
2161  struct RcvdReqExceptionData
2162  {
2163  ReqInPtr req;
2164  RcvdReqException err;
2165  };
2166  typedef RcvdReqExceptionData *RcvdReqExceptionDataPtr;
2167 
2168  DECLARE_ERROR(RcvdRspException);
2169  struct RcvdRspExceptionData
2170  {
2171  RspInPtr rsp;
2172  RcvdRspException err;
2173  };
2174  typedef RcvdRspExceptionData *RcvdRspExceptionDataPtr;
2175 
2176  DECLARE_ERROR(EncodeReqException);
2177  struct EncodeReqExceptionData
2178  {
2179  AppMsgReqPtr req;
2180  EncodeReqException err;
2181  };
2182  typedef EncodeReqExceptionData *EncodeReqExceptionDataPtr;
2183 
2184  DECLARE_ERROR(EncodeRspException);
2185  struct EncodeRspExceptionData
2186  {
2187  AppMsgRspPtr rsp;
2188  EncodeRspException err;
2189  };
2190  typedef EncodeRspExceptionData *EncodeRspExceptionDataPtr;
2192 
2195 
2197  #define APPLICATION_BASE_EVENT (EM_USER + 10000)
2198 
2201  enum class ApplicationEvents : UInt
2202  {
2204  RcvdReq = (APPLICATION_BASE_EVENT + 1),
2206  RcvdRsp = (APPLICATION_BASE_EVENT + 2),
2208  ReqTimeout = (APPLICATION_BASE_EVENT + 3),
2210  LocalNodeStateChange = (APPLICATION_BASE_EVENT + 4),
2212  RemoteNodeStateChange = (APPLICATION_BASE_EVENT + 5),
2214  RemoteNodeRestart = (APPLICATION_BASE_EVENT + 6),
2216  SndReqError = (APPLICATION_BASE_EVENT + 9),
2218  SndRspError = (APPLICATION_BASE_EVENT + 8),
2220  EncodeReqError = (APPLICATION_BASE_EVENT + 9),
2222  EncodeRspError = (APPLICATION_BASE_EVENT + 10),
2224  DecodeReqError = (APPLICATION_BASE_EVENT + 11),
2226  DecodeRspError = (APPLICATION_BASE_EVENT + 12)
2227  };
2228 
2231 
2233  DECLARE_ERROR(ApplicationWorkGroup_UnrecognizedAddressFamily);
2235 
2237  {
2238  friend LocalNode;
2239  friend CommunicationThread;
2240  protected:
2243  virtual LocalNodeSPtr _createLocalNode() = 0;
2244 
2247  virtual RemoteNodeSPtr _createRemoteNode() = 0;
2248 
2251  virtual SessionBaseSPtr _createSession(LocalNodeSPtr &ln, RemoteNodeSPtr &rn) = 0;
2252  };
2253 
2256  template <class TWorker>
2258  {
2259  friend CommunicationThread;
2260  public:
2266  LocalNodeSPtr createLocalNode(cpStr ipaddr, UShort port = PFCP::Configuration::port(), Bool start = True)
2267  {
2268  ESocket::Address addr(ipaddr, port);
2269  return createLocalNode(addr, start);
2270  }
2271  LocalNodeSPtr createLocalNode(const EIpAddress &ipaddr, UShort port = PFCP::Configuration::port(), Bool start = True)
2272  {
2273  ESocket::Address addr;
2274  switch (ipaddr.family())
2275  {
2276  case AF_INET: { addr.setAddress(ipaddr.ipv4Address(), port); break; }
2277  case AF_INET6: { addr.setAddress(ipaddr.ipv6Address(), port); break; }
2278  default:
2279  {
2280  throw ApplicationWorkGroup_UnrecognizedAddressFamily();
2281  }
2282  }
2283  return createLocalNode(addr, start);
2284  }
2286 
2290  LocalNodeSPtr createLocalNode(ESocket::Address &addr, Bool start = True);
2291 
2294  Void startLocalNode(LocalNodeSPtr &ln);
2297  Void stopLocalNode(LocalNodeSPtr &ln);
2298  };
2299 
2302 
2308  {
2309  friend Void Uninitialize();
2310  public:
2313  virtual Void onInit();
2317  virtual Void onQuit();
2318 
2321  virtual Void onRcvdReq(AppMsgReqPtr req);
2324  virtual Void onRcvdRsp(AppMsgRspPtr rsp);
2329  virtual Void onReqTimeout(AppMsgReqPtr req);
2334  virtual Void onLocalNodeStateChange(LocalNodeSPtr &ln, LocalNode::State oldState, LocalNode::State newState);
2339  virtual Void onRemoteNodeStateChange(RemoteNodeSPtr &rn, RemoteNode::State oldState, RemoteNode::State newState);
2342  virtual Void onRemoteNodeRestart(RemoteNodeSPtr &rn, const ETime &restartTime);
2346  virtual Void onSndReqError(AppMsgReqPtr req, SndReqException &err);
2351  virtual Void onSndRspError(AppMsgRspPtr rsp, SndRspException &err);
2356  virtual Void onEncodeReqError(AppMsgReqPtr req, EncodeReqException &err);
2361  virtual Void onEncodeRspError(AppMsgRspPtr rsp, EncodeRspException &err);
2362 
2363  protected:
2366  ~ApplicationWorker();
2367 
2368  Void _onRcvdReq(EThreadMessage &msg);
2369  Void _onRcvdRsp(EThreadMessage &msg);
2370  Void _onReqTimeout(EThreadMessage &msg);
2371  Void _onLocalNodeStateChange(EThreadMessage &msg);
2372  Void _onRemoteNodeStateChange(EThreadMessage &msg);
2373  Void _onRemoteNodeRestart(EThreadMessage &msg);
2374  Void _onSndReqError(EThreadMessage &msg);
2375  Void _onSndRspError(EThreadMessage &msg);
2376  Void _onEncodeReqError(EThreadMessage &msg);
2377  Void _onEncodeRspError(EThreadMessage &msg);
2378 
2380  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::RcvdReq), ApplicationWorker::_onRcvdReq)
2381  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::RcvdRsp), ApplicationWorker::_onRcvdRsp)
2382  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::ReqTimeout), ApplicationWorker::_onReqTimeout)
2383  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::LocalNodeStateChange), ApplicationWorker::_onLocalNodeStateChange)
2384  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::RemoteNodeStateChange), ApplicationWorker::_onRemoteNodeStateChange)
2385  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::RemoteNodeRestart), ApplicationWorker::_onRemoteNodeRestart)
2386  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::SndReqError), ApplicationWorker::_onSndReqError)
2387  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::SndRspError), ApplicationWorker::_onSndRspError)
2388  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::EncodeReqError), ApplicationWorker::_onEncodeReqError)
2389  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::EncodeRspError), ApplicationWorker::_onEncodeRspError)
2392  private:
2393  };
2394 
2397 
2399  #define TRANSLATION_BASE_EVENT (EM_USER + 20000)
2400 
2401  class TranslationThread : public EThreadPrivate
2402  {
2403  friend Void Uninitialize();
2404  friend AppMsgReq;
2405  friend AppMsgRsp;
2406  public:
2407  enum class Events : UInt
2408  {
2409  SndMsg = (TRANSLATION_BASE_EVENT + 1), // ApplicationWorkGroup --> TranslationThread - AppMsgPtr
2410  RcvdReq = (TRANSLATION_BASE_EVENT + 2), // CommunicationThread --> TranslationThread - ReqInPtr
2411  RcvdRsp = (TRANSLATION_BASE_EVENT + 3), // CommunicationThread --> TranslationThread - RspInPtr
2412  SndHeartbeatReq = (TRANSLATION_BASE_EVENT + 4), // CommunicationThread --> TranslationThread - SndHeartbeatReqDataPtr
2413  SndHeartbeatRsp = (TRANSLATION_BASE_EVENT + 5) // CommunicationThread --> TranslationThread - SndHeartbeatRspDataPtr
2414  };
2415 
2416  ~TranslationThread();
2417 
2418  static TranslationThread &Instance()
2419  {
2420  if (this_ == nullptr)
2421  this_ = new TranslationThread();
2422  return *this_;
2423  }
2424 
2425  Void onInit();
2426  Void onQuit();
2427 
2428  // virtual Void onRcv(AppMsgPtr &am);
2429 
2431 
2432  protected:
2433  Void onSndPfcpMsg(EThreadMessage &msg);
2434  Void onRcvdReq(EThreadMessage &msg);
2435  Void onRcvdRsp(EThreadMessage &msg);
2436  Void onSndHeartbeatReq(EThreadMessage &msg);
2437  Void onSndHeartbeatRsp(EThreadMessage &msg);
2438 
2439  // static Bool send(AppMsgReqPtr &amrq)
2440  // {
2441  // return this_->sendMsg(new EThreadMessage(TRANSLATE_SEND_REQUEST_EVENT, amrq.release()));
2442  // }
2443 
2444  // static Bool send(AppMsgRspUPtr &amrs)
2445  // {
2446  // return this_->sendMsg(new EThreadMessage(TRANSLATE_SEND_RESPONSE_EVENT, amrs.release()));
2447  // }
2448 
2449  static Void cleanup()
2450  {
2451  delete this_;
2452  this_ = NULL;
2453  }
2454 
2455  private:
2456  static TranslationThread *this_;
2457  TranslationThread();
2458  Translator &xlator_;
2459  };
2461 
2464 
2466  #define COMMUNICATION_BASE_EVENT (EM_USER + 30000)
2467 
2468  class CommunicationThread : public ESocket::ThreadPrivate
2469  {
2470  friend Void Uninitialize();
2471  friend TranslationThread;
2472  public:
2473  enum class Events : UInt
2474  {
2475  SndReq = (COMMUNICATION_BASE_EVENT + 1), // TranslationThread --> CommunicationThread - ReqOutPtr
2476  SndRsp = (COMMUNICATION_BASE_EVENT + 2), // TranslationThread --> CommunicationThread - RspOutPtr
2477  HeartbeatReq = (COMMUNICATION_BASE_EVENT + 3), // TranslationThread --> CommunicationThread - RcvdHeartbeatReqDataPtr
2478  HeartbeatRsp = (COMMUNICATION_BASE_EVENT + 4), // TranslationThread --> CommunicationThread - SndHeartbeatRspDataPtr
2479  SndHeartbeatReqError = (COMMUNICATION_BASE_EVENT + 5), // TranslationThread --> CommunicationThread - SndHeartbeatReqExceptionDataPtr - (Translator failure to create Heartbeat Req)
2480  SndHeartbeatRspError = (COMMUNICATION_BASE_EVENT + 6), // TranslationThread --> CommunicationThread - SndHeartbeatRspExceptionDataPtr - (Translator failure to create Heartbeat Rsp)
2481  RcvdReqError = (COMMUNICATION_BASE_EVENT + 7), // TranslationThread --> CommunicationThread - RcvdReqExceptionDataPtr - (Translator failure to parse req)
2482  RcvdRspError = (COMMUNICATION_BASE_EVENT + 8), // TranslationThread --> CommunicationThread - RcvdRspExceptionDataPtr - (Translator failure to parse response)
2483  ReqTimeout = (COMMUNICATION_BASE_EVENT + 9), // ETimerPool --> CommunicationThread - ReqOutPtr
2484  AddSession = (COMMUNICATION_BASE_EVENT + 10), // ApplicationThread --> CommunicationThread - *SessionBaseSPtr
2485  DelSession = (COMMUNICATION_BASE_EVENT + 11), // ApplicationThread --> CommunicationThread - *SessionBaseSPtr
2486  DelNxtRmtSession = (COMMUNICATION_BASE_EVENT + 12) // ApplicationThread/CommunicationThread --> CommunicationThread - *RemoteNodeSPtr
2487  };
2488 
2489  ~CommunicationThread();
2490 
2491  static CommunicationThread &Instance()
2492  {
2493  if (this_ == nullptr)
2494  this_ = new CommunicationThread();
2495  return *this_;
2496  }
2497 
2498  Void onInit();
2499  Void onQuit();
2500  Void onTimer(EThreadEventTimer *ptimer);
2501 
2502  Void errorHandler(EError &err, ESocket::BasePrivate *psocket);
2503 
2504  const ESocket::Address &address() { return address_; }
2505  CommunicationThread &setAddress(const ESocket::Address &address) { address_ = address; return *this; }
2506  ESocket::Address &setAddress() { return address_; }
2507 
2508  Bool addLocalNode(LocalNodeSPtr &ln)
2509  {
2510  EWRLock lck(lnslck_);
2511  return lns_.insert(std::make_pair(ln->ipAddress(), ln)).second;
2512  }
2513 
2514  Bool assignTeidRangeValue(RemoteNodeSPtr &rn)
2515  {
2516  return trm_.assign(rn);
2517  }
2518 
2519  Void releaseTeidRangeValue(RemoteNodeSPtr &rn)
2520  {
2521  trm_.release(rn);
2522  }
2523 
2524  Void startLocalNode(LocalNodeSPtr &ln);
2525  Void stopLocalNode(LocalNodeSPtr &ln);
2526  LocalNodeSPtr createLocalNode(ESocket::Address &addr, Bool start = True);
2527  LocalNodeSPtr registerLocalNode(ESocket::Address &addr);
2528 
2529  LocalNodeUMap &localNodes() { return lns_; }
2530  ERWLock &localNodesLock() { return lnslck_; }
2531 
2532  Void setNbrActivityWnds(size_t nbr);
2533  Void nextActivityWnd();
2534  size_t currentActivityWnd() const { return caw_; }
2535 
2536  Int currentRspWnd() const { return crw_; }
2537 
2539 
2540  protected:
2541  Void releaseLocalNodes();
2542 
2543  Void onSndReq(EThreadMessage &msg);
2544  Void onSndRsp(EThreadMessage &msg);
2545  Void onHeartbeatReq(EThreadMessage &msg);
2546  Void onHeartbeatRsp(EThreadMessage &msg);
2547  Void onSndHeartbeatReqError(EThreadMessage &msg);
2548  Void onSndHeartbeatRspError(EThreadMessage &msg);
2549  Void onRcvdReqError(EThreadMessage &msg);
2550  Void onRcvdRspError(EThreadMessage &msg);
2551  Void onReqTimeout(EThreadMessage &msg);
2552  Void onAddSession(EThreadMessage &msg);
2553  Void onDelSession(EThreadMessage &msg);
2554  Void onDelNxtRmtSession(EThreadMessage &msg);
2555 
2556  Void onHeartbeatReqTimtout(AppMsgReqPtr am);
2557 
2558  static Void cleanup()
2559  {
2560  delete this_;
2561  this_ = NULL;
2562  }
2563 
2564  private:
2565  static const Int rwOne_ = 1;
2566  static const Int rwTwo_ = 2;
2567  static const Int rwToggle_ = (rwOne_ ^ rwTwo_);
2568  static CommunicationThread *this_;
2569 
2570  CommunicationThread();
2571  Void addSession(SessionBaseSPtr &s);
2572  Void delSession(SessionBaseSPtr &s);
2573 
2574  ESocket::Address address_;
2575  TeidRangeManager trm_;
2576  ERWLock lnslck_;
2577  LocalNodeUMap lns_;
2578  EThreadEventTimer atmr_;
2579  EThreadEventTimer rsptmr_;
2580  size_t caw_;
2581  Int crw_;
2582  };
2584 
2587 
2589  inline SessionBase::~SessionBase()
2590  {
2591  static EString __method__ = __METHOD_NAME__;
2592  // Configuration::logger().debug(
2593  // "{} - destroying session localNode={} remoteNode={} localSeid={} remoteSeid={}",
2594  // __method__, localNode()->address().getAddress(),
2595  // remoteNode()->address().getAddress(), localSeid(), remoteSeid());
2596  ++deleted_;
2597  }
2598 
2599  inline SessionBase &SessionBase::setSeid(SessionBaseSPtr &s, Seid ls, Seid rs, Bool notify)
2600  {
2601  if (ls != 0)
2602  {
2603  if (ls_ != 0)
2604  throw SessionBase_LocalSeidAlreadySet();
2605  ls_ = ls;
2606  }
2607  if (rs != 0)
2608  {
2609  if (rs_ != 0)
2610  throw SessionBase_RemoteSeidAlreadySet();
2611  rs_ = rs;
2612  }
2613  if (notify)
2614  {
2615  auto s2 = new SessionBaseSPtr(s);
2616  SEND_TO_COMMUNICATION(AddSession, s2);
2617  }
2618  return *this;
2619  }
2620 
2621  inline Void SessionBase::destroy(SessionBaseSPtr &s)
2622  {
2623  auto s2 = new SessionBaseSPtr(s);
2624  SEND_TO_COMMUNICATION(DelSession, s2);
2625  }
2626 
2627  inline InternalMsg::InternalMsg(const LocalNodeSPtr &ln, const RemoteNodeSPtr &rn, const TranslatorMsgInfo &tmi, cpUChar data, UShort len)
2628  : ln_(ln),
2629  rn_(rn),
2630  seq_(tmi.seqNbr()),
2631  mt_(tmi.msgType()),
2632  mc_(tmi.msgClass()),
2633  rqst_(tmi.isReq()),
2634  ver_(tmi.version()),
2635  data_(nullptr),
2636  len_(0)
2637  {
2638  assign(data, len);
2639  }
2640 
2641  inline Void ReqOut::startT1()
2642  {
2643  stopT1();
2644  EThreadMessage *msg = new EThreadMessage(
2645  static_cast<UInt>(CommunicationThread::Events::ReqTimeout),
2646  static_cast<pVoid>(this));
2647  t1id_ = ETimerPool::Instance().registerTimer(t1(), msg, CommunicationThread::Instance());
2648  }
2649 
2650  inline Bool RemoteNode::setRcvdReqRspWnd(ULong sn)
2651  {
2652  return setRcvdReqRspWnd(sn, PFCP::CommunicationThread::Instance().currentRspWnd());
2653  }
2654 
2655  template<class TWorker>
2656  inline LocalNodeSPtr ApplicationWorkGroup<TWorker>::createLocalNode(ESocket::Address &addr, Bool start)
2657  {
2658  return CommunicationThread::Instance().createLocalNode(addr, start);
2659  }
2660 
2661  template<class TWorker>
2662  inline Void ApplicationWorkGroup<TWorker>::startLocalNode(LocalNodeSPtr &ln)
2663  {
2664  CommunicationThread::Instance().startLocalNode(ln);
2665  }
2666 
2667  template<class TWorker>
2668  inline Void ApplicationWorkGroup<TWorker>::stopLocalNode(LocalNodeSPtr &ln)
2669  {
2670  CommunicationThread::Instance().stopLocalNode(ln);
2671  }
2672 
2673  inline void* InternalMsg::operator new(size_t sz)
2674  {
2675  if (pool_.allocSize() == 0)
2676  {
2677  size_t as = 0;
2678  if (sizeof(RspOut) > as) as = sizeof(RspOut);
2679  if (sizeof(RspIn) > as) as = sizeof(RspIn);
2680  if (sizeof(ReqOut) > as) as = sizeof(ReqOut);
2681  if (sizeof(ReqIn) > as) as = sizeof(ReqIn);
2682 
2683  size_t ns = 32768 - sizeof(EMemory::Node);
2684  size_t bs = as + sizeof(EMemory::Block);
2685  bs += bs % sizeof(pVoid);
2686  size_t bc = ns / bs;
2687  ns = sizeof(EMemory::Node) + bc * bs;
2688  pool_.setSize(as, ns);
2689  }
2690  if (sz > pool_.allocSize())
2691  {
2692  EError ex;
2693  ex.setSevere();
2694  ex.setText("internal message allocation size is larger than memory pool block size");
2695  throw ex;
2696  }
2697  return pool_.allocate();
2698  }
2699 
2700  inline void InternalMsg::operator delete(void* m)
2701  {
2702  pool_.deallocate(m);
2703  }
2705 }
2706 
2708 namespace std
2709 {
2710 template <>
2711 struct hash<PFCP::RemoteNodeSPtr>
2712 {
2713  std::size_t operator()(const PFCP::RemoteNodeSPtr &rn) const noexcept
2714  {
2715  return std::hash<ESocket::Address>{}(rn->address());
2716  }
2717 };
2719 
2720 }
2721 
2722 #endif // #ifndef __EPFCP_H
LocalNodeStateChange - CommunicationThread –> ApplicationWorkGroup - *LocalNodeStateChangeEvent.
LocalNode::State oldState() const
Definition: epfcp.h:1097
static LongLong setT1(LongLong t1)
Definition: epfcp.h:253
AppMsgSessionRsp()
Default construtor.
Definition: epfcp.h:1383
static Int setMaxApplicationWorkers(Int w)
Definition: epfcp.h:288
const EIpAddress & address() const
Retrieves the IP address object associated with the FqSeid.
Definition: epfcp.h:432
std::unordered_map< EIpAddress, LocalNodeSPtr > LocalNodeUMap
Definition: epfcp.h:1082
const struct sockaddr_storage & getSockAddrStorage() const
Retrieves a sockaddr pointer to the socket address.
Definition: esocket.h:214
LocalNodeSPtr & localNode()
Returns a reference to the local node object for this message.
Definition: epfcp.h:1316
RemoteNode::State oldState() const
Definition: epfcp.h:911
Node & setAddress(const ESocket::Address &addr)
Assigns the ESocket::Address object representing the IP address for this node.
Definition: epfcp.h:679
static Int setHeartbeatN1(Int hbn1)
Definition: epfcp.h:262
virtual ~AppMsgNodeReq()
Class destructor.
Definition: epfcp.h:1240
#define True
True.
Definition: ebase.h:25
static Long setLenActivityWnd(Long law)
Definition: epfcp.h:270
AppMsgNodeRsp * AppMsgNodeRspPtr
Definition: epfcp.h:1373
static LongLong t1()
Definition: epfcp.h:252
AppMsgRsp()
Default construtor.
Definition: epfcp.h:1291
Void stopLocalNode(LocalNodeSPtr &ln)
Stops the local node.
DecodeReqError - TranslationThread –> ApplicationWorkGroup - DecodeReqExceptionDataPtr.
ApplicationEvents
The events that will be received by the application work group.
Definition: epfcp.h:2201
Stats & stats()
Returns the stats object for this remote node.
Definition: epfcp.h:846
Work group template definition. The work group contains the event queue that all of the associated wo...
Definition: etevent.h:1704
RemoteNodeSPtr & remoteNode()
Returns a reference to the remote node object for this message.
Definition: epfcp.h:1192
static ETime Now()
Retrieves the current time.
Definition: etime.cpp:1147
EncodeRspError - TranslationThread –> ApplicationWorkGroup - EncodeRspExceptionDataPtr.
SndRspError - CommunicationThread –> ApplicationWorkGroup - SndRspExceptionDataPtr.
State
Definition: epfcp.h:756
SessionBase(LocalNodeSPtr &ln, RemoteNodeSPtr &rn)
Class constructor.
Definition: epfcp.h:542
static Int teidRangeBits()
Definition: epfcp.h:278
The PFCP Translator is used to encode and decode PFCP messages. This is a pure virtual base class tha...
Definition: epfcp.h:2034
std::pair< EIpAddress, LocalNodeSPtr > LocalNodeUMapEIpAddressPair
Definition: epfcp.h:1083
std::shared_ptr< Node > NodeSPtr
Definition: epfcp.h:741
base class for EThreadPrivate and EThreadPublic
Definition: etevent.h:1062
const ETime & startTime() const
Returns the Node start time.
Definition: epfcp.h:688
RemoteNodeRestartEvent(RemoteNodeSPtr &rn, RemoteNode::State oldst, RemoteNode::State newst, const ETime &restartTime)
Definition: epfcp.h:924
static Long lenActivityWnd()
Definition: epfcp.h:269
static ULongLong nodesCreated()
Definition: epfcp.h:705
LocalNode::State newState() const
Definition: epfcp.h:1098
PFCP stack namespace.
Definition: epfcp.h:36
virtual ~AppMsgRsp()
Class destructor.
Definition: epfcp.h:1305
static Void setApplication(ApplicationWorkGroup< TWorker > &app)
Definition: epfcp.h:297
static ApplicationWorkGroupBase & baseApplication()
Definition: epfcp.h:316
LocalNodeSPtr createLocalNode(const EIpAddress &ipaddr, UShort port=PFCP::Configuration::port(), Bool start=True)
Definition: epfcp.h:2271
AppMsgSessionRsp * AppMsgSessionRspPtr
Definition: epfcp.h:1410
AppMsgReq(LocalNodeSPtr &ln, RemoteNodeSPtr &rn, Bool allocSeqNbr)
Class constructor.
Definition: epfcp.h:1203
Void setSevere()
Sets the severity level of this error object to "Error".
Definition: eerror.h:237
EncodeReqError - TranslationThread –> ApplicationWorkGroup - EncodeReqExceptionDataPtr.
MessageStatsMap & messageStats()
Returns the message stats map for this remote node. Access to this reference must be protected with t...
Definition: epfcp.h:797
AppMsgNodeRsp & setReq(AppMsgNodeReqPtr req)
Sets the request message that this response is associated with.
Definition: epfcp.h:1370
MsgClass msgClass() const
Returns the message class for this message (Node or Session).
Definition: epfcp.h:1126
const ETime & restartTime() const
Definition: epfcp.h:936
static Int minApplicationWorkers()
Definition: epfcp.h:284
Void setText(cpStr pszText)
Sets the text associated with this error.
Definition: eerror.h:208
Request a write lock for the specified read-write lock object.
Definition: esynch.h:574
ULong alloc()
Assigns the next available sequence number. This operation is thread safe.
Definition: epfcp.h:352
static size_t setNnbrActivityWnds(size_t naw)
Definition: epfcp.h:267
static Int setTeidRangeBits(Int trb)
Definition: epfcp.h:279
static Long maxRspWait()
Definition: epfcp.h:264
STL namespace.
Definition: epfcp.h:900
static MsgType pfcpHeartbeatReq
Definition: epfcp.h:307
Definition: ememory.h:72
AppMsgRsp(AppMsgReqPtr amrq)
Class constructor.
Definition: epfcp.h:1299
LocalNodeSPtr createLocalNode(cpStr ipaddr, UShort port=PFCP::Configuration::port(), Bool start=True)
Creates a local node.
Definition: epfcp.h:2266
static Bool assignTeidRange()
Definition: epfcp.h:275
AppMsgReqPtr req()
Returns a shared pointer to the request application message.
Definition: epfcp.h:1313
Definition: ememory.h:34
Contains the base functionality for all aplication messages.
Definition: epfcp.h:1110
static Int setMinApplicationWorkers(Int w)
Definition: epfcp.h:285
Definition: epfcp.h:921
ERWLock & getLock()
Returns the read/write lock protecting the message stats map and access to last activity.
Definition: epfcp.h:791
State state()
Gets the state of the local node.
Definition: epfcp.h:969
EIpAddress & setAddress()
Returns a modifiable reference to the IP address.
Definition: epfcp.h:435
AppMsg & setMsgClass(const MsgClass mc)
Definition: epfcp.h:1163
SessionBaseSPtr getSession(Seid seid)
Returns the session object for the specified SEID.
Definition: epfcp.h:697
RemoteNodeUMap & remoteNodes()
Returns the map of current remote nodes. Access to this map must be protected with the read/write loc...
Definition: epfcp.h:1006
RemoteNodeStateChangeEvent(RemoteNodeSPtr &rn, RemoteNode::State oldst, RemoteNode::State newst)
Definition: epfcp.h:903
static Int setMinTranslatorWorkers(Int w)
Definition: epfcp.h:291
const Seid seid() const
Returns the SEID.
Definition: epfcp.h:439
static ULongLong sessionsDeleted()
Definition: epfcp.h:595
Seid alloc()
Assigns the next available SEID. This operation is thread safe.
Definition: epfcp.h:381
LocalNodeStateChangeEvent(LocalNodeSPtr &ln, LocalNode::State oldst, LocalNode::State newst)
Definition: epfcp.h:1089
RcvdReq - TranslationThread –> ApplicationWorkGroup - AppMsgReqPtr.
static _EThreadEventNotification & threadApplication()
Definition: epfcp.h:315
RemoteNode::State oldState() const
Definition: epfcp.h:934
AppMsg(const AppMsg &dm)
Definition: epfcp.h:1154
static Int socketBufferSize()
Definition: epfcp.h:249
virtual const EString & className()
Returns the class name for this object.
Definition: epfcp.h:1136
Int teidRangeValue() const
Returns the currently configured TEID range value.
Definition: epfcp.h:767
SessionBase & setLocalSeid(SessionBaseSPtr &s, Seid ls)
Sets the local SEID for this session.
Definition: epfcp.h:585
Encapsulates the UDP Socket functionality used to communicate with a PFCP peer.
Definition: epfcp.h:491
SeidManager()
Default constructor.
Definition: epfcp.h:379
Contains the basic Node functionality common to both a LocalNode and a RemoteNode.
Definition: epfcp.h:654
The application worker thread class. The various virtual methods should be overridden to implement ap...
Definition: epfcp.h:2307
static ETimerPool & Instance()
Retrieves the single instance of the ETimerPool object.
Definition: etimerpool.h:70
Represents a request application message.
Definition: epfcp.h:1179
static ELogger & setLogger(ELogger &log)
Definition: epfcp.h:273
Represents a response application message.
Definition: epfcp.h:1379
#define False
False.
Definition: ebase.h:27
RemoteNodeSPtr & remoteNode()
Returns a reference to the remote node object for this message.
Definition: epfcp.h:1319
Void free(ULong sn)
Releases a previously allocated sequence number.
Definition: epfcp.h:360
Definition: epfcp.h:2236
Class for manipulating date and time of day values.
Definition: etime.h:199
Node & setIpAddress(const EIpAddress &ipaddr)
Assigns the IP address for this node.
Definition: epfcp.h:668
RcvdRsp - TranslationThread –> ApplicationWorkGroup - AppMsgRspPtr.
static ULongLong sessionsCreated()
Definition: epfcp.h:594
FqSeid()
Default constructor.
Definition: epfcp.h:408
RemoteNodeStateChange - CommunicationThread –> ApplicationWorkGroup - *RemoteNodeStateChangeEvent.
AppMsgSessionReq * AppMsgSessionReqPtr
Definition: epfcp.h:1281
static Int maxApplicationWorkers()
Definition: epfcp.h:287
SequenceManager()
Default constructor.
Definition: epfcp.h:349
Allocates and deallocates SEID&#39;s (PFCP session ID&#39;s). Each "slice" should have it&#39;s own instance of t...
Definition: epfcp.h:375
Represents a worker thread that is part of a work group.
Definition: etevent.h:1444
AppMsgRsp * AppMsgRspPtr
Definition: epfcp.h:1334
AppMsgReq()
Default constructor.
Definition: epfcp.h:1196
static Translator & setTranslator(Translator &xlator)
Definition: epfcp.h:282
static Int heartbeatN1()
Definition: epfcp.h:261
std::pair< EIpAddress, RemoteNodeSPtr > RemoteNodeUMapPair
Definition: epfcp.h:898
The PFCP application work group template. This template contains the common event queue for the appli...
Definition: epfcp.h:2257
Defines the EIpAddress and EIpFilterRule classes.
AppMsgNodeReq()
Default constructor.
Definition: epfcp.h:1227
virtual ~AppMsgReq()
Class destructor.
Definition: epfcp.h:1183
static UShort setPort(UShort port)
Definition: epfcp.h:247
static MsgType pfcpAssociationSetupRsp
Definition: epfcp.h:312
AppMsgNodeRsp(AppMsgNodeReqPtr &amrq)
Class constructor.
Definition: epfcp.h:1353
virtual ~Node()
Class destructor.
Definition: epfcp.h:660
static Int minTranslatorWorkers()
Definition: epfcp.h:290
ULong seqNbr() const
Returns the sequence number associated wtih this message.
Definition: epfcp.h:1120
Thread timer class.
Definition: etevent.h:828
ERWLock & remoteNodesLock()
Returns a lock protected access to the remote nodes map.
Definition: epfcp.h:1010
SndReqError - CommunicationThread –> ApplicationWorkGroup - SndReqExceptionDataPtr.
virtual ~AppMsgSessionReq()
Class destructor.
Definition: epfcp.h:1269
AppMsgNodeRsp()
Default construtor.
Definition: epfcp.h:1344
AppMsg()
Definition: epfcp.h:1147
AppMsg * AppMsgPtr
Definition: epfcp.h:1173
AppMsgRsp & setReq(AppMsgReq *req)
Sets the request message that this response is associated with.
Definition: epfcp.h:1323
std::shared_ptr< SessionBase > SessionBaseSPtr
Definition: epfcp.h:530
std::unordered_map< Seid, SessionBaseSPtr > SessionBaseSPtrUMap
Definition: epfcp.h:647
A UDP socket class capabile of sending and receiving data.
Definition: esocket.h:1222
Void Uninitialize()
Uninitializes/stops the PFCP stack.
Definition: epfcp.cpp:331
static LongLong heartbeatT1()
Definition: epfcp.h:255
An event message that is to be sent to a thread.
Definition: etevent.h:264
The socket thread base class. An event based thread class capable of surfacing socket events...
Definition: esocket.h:1674
FqSeid & setSeid(Seid seid)
Assigns the SEID value.
Definition: epfcp.h:443
Represents the local PFCP node.
Definition: epfcp.h:955
AppMsg & setSeqNbr(const ULong sn)
Assigns the sequence number for this message.
Definition: epfcp.h:1132
#define END_MESSAGE_MAP2()
Ends the message map declaration.
Definition: etevent.h:1433
AppMsgNodeReq * AppMsgNodeReqPtr
Definition: epfcp.h:1245
static Translator & translator()
Definition: epfcp.h:281
LocalNodeSPtr & localNode()
Definition: epfcp.h:1096
Void startLocalNode(LocalNodeSPtr &ln)
Startes an externally constructed local node.
AppMsg & setMsgType(const MsgType mt)
Definition: epfcp.h:1162
DecodeRspError - TranslationThread –> ApplicationWorkGroup - EncodeRspExceptionDataPtr.
EIpAddress & ipAddress()
Returns the IP address associated with this node.
Definition: epfcp.h:664
LocalNodeSPtr & localNode()
Returns a reference to the local node object for this message.
Definition: epfcp.h:1189
Bool isReq() const
Returns True if this message is a request message, otherwise False.
Definition: epfcp.h:1128
AppMsgSessionReq()
Default constructor.
Definition: epfcp.h:1255
The base class for exceptions derived from std::exception.
Definition: eerror.h:94
static MsgType pfcpAssociationSetupReq
Definition: epfcp.h:311
Definition: ememory.h:92
Represents an IP address with mask.
Definition: eip.h:40
static MsgType pfcpHeartbeatRsp
Definition: epfcp.h:308
std::pair< ULong, LocalNodeSPtr > LocalNodeUMapULongPair
Definition: epfcp.h:1084
A class used to build JSON strings. It maintains a stack of JSON objects which allows you to build a ...
Definition: ejsonbuilder.h:30
State state() const
Returns the current state of the local node.
Definition: epfcp.h:864
RemoteNodeSPtr createRemoteNode(cpStr addr, UShort port)
Creates a remote Node that this local node will "talk" to.
Definition: epfcp.h:991
MsgType msgType() const
Returns the message type for this message.
Definition: epfcp.h:1123
Represents a remote or peer PFCP node or host.
Definition: epfcp.h:751
std::unordered_map< EIpAddress, RemoteNodeSPtr > RemoteNodeUMap
Definition: epfcp.h:897
Represents a PFCP session. It is expected that a developer utilizing this library will derive their o...
Definition: epfcp.h:536
Represents a response application message.
Definition: epfcp.h:1340
static Bool setAssignTeidRange(Bool atr)
Definition: epfcp.h:276
const in_addr & ipv4Address() const
Returns a reference to the in_addr structure that represents an IPv4 address.
Definition: eip.h:225
RemoteNodeSPtr & remoteNode()
Returns the RemoteNode object associated with this session.
Definition: epfcp.h:568
virtual ~AppMsgSessionRsp()
Class destructor.
Definition: epfcp.h:1397
const sa_family_t family() const
Returns the address family associated with this address object.
Definition: eip.h:231
static LongLong setHeartbeatT1(LongLong hbt1)
Definition: epfcp.h:256
AppMsgReq * AppMsgReqPtr
Definition: epfcp.h:1216
virtual ~SessionBase()
Class destructor.
virtual Void destroy(SessionBaseSPtr &s)
Starts the destruction process for the session.
static Int setN1(Int n1)
Definition: epfcp.h:259
LocalNodeSPtr & localNode()
Returns the LocalNode object associated with this session.
Definition: epfcp.h:565
ETimerPool & unregisterTimer(ULong timerid)
Unregisters an expiration timer.
Definition: etimerpool.cpp:143
static size_t nbrActivityWnds()
Definition: epfcp.h:266
AppMsgSessionReq(SessionBaseSPtr &ses, Bool allocSeqNbr)
Class constructor.
Definition: epfcp.h:1262
ULong registerTimer(LongLong ms, _EThreadEventMessageBase *msg, _EThreadEventNotification &notify)
Registers an expiration timer.
Definition: etimerpool.cpp:68
DECLARE_ERROR(SessionBase_LocalSeidAlreadySet)
#define DECLARE_MESSAGE_MAP()
Inserts message map declarations into the thread class.
Definition: etevent.h:1015
static ULongLong nodesDeleted()
Definition: epfcp.h:706
Represents a Fully Qualified SEID. This combines an IP address with a SEID.
Definition: epfcp.h:404
virtual ~AppMsgNodeRsp()
Class destructor.
Definition: epfcp.h:1360
The base socket class.
Definition: esocket.h:447
FqSeid(const FqSeid &fqseid)
Copy constructor.
Definition: epfcp.h:415
static ELogger & logger()
Definition: epfcp.h:272
SessionBase & setRemoteSeid(SessionBaseSPtr &s, Seid rs)
Sets the remote SEID for this session.
Definition: epfcp.h:590
AppMsgNodeReqPtr req()
Returns a shared pointer to the request application message.
Definition: epfcp.h:1366
Represents a request application node message (not associated with a session).
Definition: epfcp.h:1223
AppMsg & setIsReq(const Bool rqst)
Definition: epfcp.h:1164
Defines a logger.
Definition: elogger.h:76
Allocates and deallocates sequence numbers used in PFCP request messages. Each "slice" should have it...
Definition: epfcp.h:345
Definition: epfcp.h:1086
static UShort port()
Definition: epfcp.h:246
Contains all of the configuration values used in the PFCP stack.
Definition: epfcp.h:239
State
Definition: epfcp.h:960
NodeSocket & socket()
Returns a reference to the underlying socket object for this local host.
Definition: epfcp.h:1030
State state() const
Returns the current state of the local node.
Definition: epfcp.h:1034
static MessageStatsMap & messageStatsTemplate()
Returns a reference to the message stats template map. Derived applications should populate this with...
Definition: epfcp.h:305
RemoteNodeRestart - CommunicationThread –> ApplicationWorkGroup - *RemoteNodeRestartEvent.
RemoteNode & setTeidRangeValue(Int trv)
Sets the TEID range value.
Definition: epfcp.h:771
Definition: esocket.h:2223
const Seid remoteSeid() const
Returns the remote SEID associated with this session.
Definition: epfcp.h:574
NodeSocket & clearLocalNode()
Clears the assigned LocalNode.
Definition: epfcp.h:506
Contains the class definitions to support the pool based memory allocation.
#define ON_MESSAGE2(id, memberFxn)
Defines an invidual event handler.
Definition: etevent.h:1429
RemoteNode::State newState() const
Definition: epfcp.h:912
RemoteNode::State newState() const
Definition: epfcp.h:935
AppMsgSessionReqPtr req()
Returns a shared pointer to the request application message.
Definition: epfcp.h:1403
const Seid localSeid() const
Returns the SEID associated with this session.
Definition: epfcp.h:571
AppMsgSessionRsp(AppMsgSessionReqPtr &amrq)
Class constructor.
Definition: epfcp.h:1391
virtual ~AppMsg()
Class destructor.
Definition: epfcp.h:1114
SessionBase & setSeid(SessionBaseSPtr &s, Seid ls, Seid rs, Bool notify=True)
Sets the local and remote SEID for this session.
Node()
Default constructor.
Definition: epfcp.h:658
ESocket::Address & address()
Returns the ESocket::Address object representing the IP address for this node.
Definition: epfcp.h:674
RemoteNodeSPtr & remoteNode()
Definition: epfcp.h:910
ReqTimeout - CommunicationThread –> ApplicationWorkGroup - AppMsgReqPtr.
#define DECLARE_ERROR_ADVANCED(__e__)
Declares exception class derived from EError with no constructor parameters and developer defined con...
Definition: eerror.h:61
static Int setMaxTranslatorWorkers(Int w)
Definition: epfcp.h:294
NodeSocket & setLocalNode(LocalNodeSPtr &ln)
Assigns the LocalNode that this socket is associated with.
Definition: epfcp.h:503
const in6_addr & ipv6Address() const
Returns a reference to the in6_addr structure that represents an IPv6 address.
Definition: eip.h:228
SessionBase(const SessionBase &s)
Copy constructor.
Definition: epfcp.h:552
A class to hold message statistics for the remote node.
Definition: epfcp.h:785
#define BEGIN_MESSAGE_MAP2(theClass, baseClass)
Definition: etevent.h:1415
String class.
Definition: estring.h:31
Encapsulates a sockaddr_storage structure that represents a socket address.
Definition: esocket.h:148
Encapsulates a read-write lock object.
Definition: esynch.h:507
Node & setStartTime(const ETime &st=ETime::Now())
Assigns the Node start time.
Definition: epfcp.h:692
SessionBaseSPtr & session()
Returs a reference to the session shaerd pointer.
Definition: epfcp.h:1275
Void Initialize()
Initializes/starts the PFCP stack. This should be called after setting the initial configuration valu...
Definition: epfcp.cpp:306
static Int n1()
Definition: epfcp.h:258
Represents a response application message.
Definition: epfcp.h:1287
RemoteNodeSPtr & remoteNode()
Definition: epfcp.h:933
static MsgType pfcpSessionEstablishmentReq
Definition: epfcp.h:309
Represents a request application session message.
Definition: epfcp.h:1251
AppMsgSessionRsp & setReq(AppMsgSessionReqPtr req)
Sets the request message that this response is associated with.
Definition: epfcp.h:1407
FqSeid & operator=(const FqSeid &fqseid)
Assignment operator.
Definition: epfcp.h:423
Address & setAddress(cpStr addr, UShort port)
Assigns the socket address.
Definition: esocket.h:307
static Int setSocketBufferSize(Int sz)
Definition: epfcp.h:250
static Int maxTranslatorWorkers()
Definition: epfcp.h:293
static MsgType pfcpSessionEstablishmentRsp
Definition: epfcp.h:310
AppMsgNodeReq(LocalNodeSPtr &ln, RemoteNodeSPtr &rn, Bool allocSeqNbr)
Class constructor.
Definition: epfcp.h:1234
Void free(Seid seid)
Releases a previously allocated SEID.
Definition: epfcp.h:390