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 
35 namespace PFCP
36 {
39 
42  Void Initialize();
44  Void Uninitialize();
45 
48 
50 
52 
53  class Translator;
54  template<class TWorker> class ApplicationWorkGroup;
55  class TranslationThread;
56  class CommunicationThread;
57 
58  class RemoteNode;
59  typedef std::shared_ptr<RemoteNode> RemoteNodeSPtr;
60 
61  class LocalNode;
62  typedef std::shared_ptr<LocalNode> LocalNodeSPtr;
63 
64  class ReqOut;
65  typedef ReqOut *ReqOutPtr;
66  typedef std::unordered_map<ULong,ReqOutPtr> ReqOutUMap;
67 
68  class RspOut;
69  typedef RspOut *RspOutPtr;
70 
73 
74  #define SEND_TO_APPLICATION(a,b) \
75  (PFCP::Configuration::threadApplication()._sendThreadMessage(EThreadMessage( \
76  static_cast<UInt>(PFCP::ApplicationEvents::a),static_cast<pVoid>(b))))
77  #define SEND_TO_TRANSLATION(a,b) \
78  (PFCP::TranslationThread::Instance().sendMessage(EThreadMessage( \
79  static_cast<UInt>(PFCP::TranslationThread::Events::a),static_cast<pVoid>(b))))
80  #define SEND_TO_COMMUNICATION(a,b) \
81  (PFCP::CommunicationThread::Instance().sendMessage(EThreadMessage( \
82  static_cast<UInt>(PFCP::CommunicationThread::Events::a),static_cast<pVoid>(b))))
83 
86 
87  typedef ULongLong Seid;
88  typedef UChar MsgType;
89 
90  enum class MsgClass
91  {
92  Unknown,
93  Node,
94  Session
95  };
96 
99 
100  class EventBase
101  {
102  public:
103  static void* operator new(size_t sz);
104  static void operator delete(void* m);
105  private:
106  static EMemory::Pool pool_;
107  };
108 
111 
112  DECLARE_ERROR(Configuration_LoggerNotDefined);
113  DECLARE_ERROR(Configuration_TranslatorNotDefined);
114  DECLARE_ERROR(Configuration_ApplicationNotDefined);
115 
117 
120  {
121  friend LocalNode;
122  friend RemoteNode;
123  friend TranslationThread;
124  friend CommunicationThread;
125  public:
126  static UShort port() { return port_; }
127  static UShort setPort(UShort port) { return port_ = port; }
128 
129  static Int socketBufferSize() { return bufsize_; }
130  static Int setSocketBufferSize(Int sz) { return bufsize_ = sz; }
131 
132  static LongLong t1() { return t1_; }
133  static LongLong setT1(LongLong t1) { return t1_ = t1; }
134 
135  static LongLong heartbeatT1() { return hbt1_; }
136  static LongLong setHeartbeatT1(LongLong hbt1) { return hbt1_ = hbt1; }
137 
138  static Int n1() { return n1_; }
139  static Int setN1(Int n1) { return n1_ = n1; }
140 
141  static Int heartbeatN1() { return hbn1_; }
142  static Int setHeartbeatN1(Int hbn1) { return hbn1_ = hbn1; }
143 
144  static Long maxRspWait() { return static_cast<Long>(std::max(t1_,hbt1_) * std::max(n1_,hbn1_)); }
145 
146  static size_t nbrActivityWnds() { return naw_; }
147  static size_t setNnbrActivityWnds(size_t naw) { return naw_ = naw; }
148 
149  static Long lenActivityWnd() { return law_; }
150  static Long setLenActivityWnd(Long law) { return law_ = law; }
151 
152  static ELogger &logger() { if (logger_ == nullptr) throw Configuration_LoggerNotDefined(); return *logger_; }
153  static ELogger &setLogger(ELogger &log) { logger_ = &log; return *logger_; }
154 
155  static Bool assignTeidRange() { return atr_; }
156  static Bool setAssignTeidRange(Bool atr) { return atr_ = atr; }
157 
158  static Int teidRangeBits() { return trb_; }
159  static Int setTeidRangeBits(Int trb) { return trb_ = trb; }
160 
161  static Translator &translator() { if (xlator_ == nullptr) throw Configuration_TranslatorNotDefined(); return *xlator_; }
162  static Translator &setTranslator(Translator &xlator) { return *(xlator_ = &xlator); }
163 
164  static Int minApplicationWorkers() { return aminw_; }
165  static Int setMinApplicationWorkers(Int w) { return aminw_ = w; }
166 
167  static Int maxApplicationWorkers() { return amaxw_; }
168  static Int setMaxApplicationWorkers(Int w) { return amaxw_ = w; }
169 
170  static Int minTranslatorWorkers() { return tminw_; }
171  static Int setMinTranslatorWorkers(Int w) { return tminw_ = w; }
172 
173  static Int maxTranslatorWorkers() { return tmaxw_; }
174  static Int setMaxTranslatorWorkers(Int w) { return tmaxw_ = w; }
175 
176  template<class TWorker>
177  static Void setApplication(ApplicationWorkGroup<TWorker> &app) { app_ = &app; baseapp_ = &app; }
178 
179  static MsgType pfcpHeartbeatReq;
180  static MsgType pfcpHeartbeatRsp;
183  static MsgType pfcpAssociationSetupReq;
184  static MsgType pfcpAssociationSetupRsp;
185 
186  protected:
187  static _EThreadEventNotification &threadApplication() { if (app_ == nullptr) throw Configuration_ApplicationNotDefined(); return *app_; }
188  static ApplicationWorkGroupBase &baseApplication() { if (baseapp_ == nullptr) throw Configuration_ApplicationNotDefined(); return *baseapp_; }
189 
190  private:
191  static UShort port_;
192  static Int bufsize_;
193  static LongLong t1_;
194  static LongLong hbt1_;
195  static Int n1_;
196  static Int hbn1_;
197  static ELogger *logger_;
198  static size_t naw_;
199  static Long law_;
200  static Int trb_;
201  static Bool atr_;
202  static Translator *xlator_;
203  static Int aminw_;
204  static Int amaxw_;
205  static Int tminw_;
206  static Int tmaxw_;
207  static _EThreadEventNotification *app_;
208  static ApplicationWorkGroupBase *baseapp_;
209  };
210 
213 
217  {
218  public:
220  SequenceManager(): next_(SEQUENCE_MIN) {}
223  ULong alloc()
224  {
225  unsigned long sn;
226  while ((sn = next_++) > SEQUENCE_MAX)
227  next_.compare_exchange_strong(++sn, SEQUENCE_MIN);
228  return sn;
229  }
231  Void free(ULong sn)
232  {
233  // currently, nothing is done to "free" a sequence number
234  }
235  private:
236  static const ULong SEQUENCE_MIN = 0;
237  static const ULong SEQUENCE_MAX = 0x00ffffffff;
238  std::atomic_ulong next_;
239  };
240 
243 
247  {
248  public:
250  SeidManager() : next_(SEID_MINIMUM) {}
252  Seid alloc()
253  {
254  Seid seid;
255  // this logic depends on the numeric overflow from a max value to zero
256  // when the value is incremented.
257  while ((seid = next_++) < SEID_MINIMUM);
258  return seid;
259  }
261  Void free(Seid seid)
262  {
263  // currently, nothing is done to "free" a SEID
264  }
265  private:
266  static const Seid SEID_MINIMUM = 1;
267  std::atomic_ullong next_;
268  };
269 
272 
275  class FqSeid
276  {
277  public:
280  : addr_(),
281  seid_(0)
282  {
283  }
286  FqSeid(const FqSeid &fqseid)
287  : addr_(fqseid.addr_),
288  seid_(fqseid.seid_)
289  {
290  }
291 
294  FqSeid &operator=(const FqSeid &fqseid)
295  {
296  addr_ = fqseid.addr_;
297  seid_ = fqseid.seid_;
298  return *this;
299  }
300 
303  const EIpAddress &address() const { return addr_; }
306  EIpAddress &setAddress() { return addr_; }
307 
310  const Seid seid() const { return seid_; }
314  FqSeid &setSeid(Seid seid) { seid_ = seid; return *this; }
315 
316  private:
317  EIpAddress addr_;
318  Seid seid_;
319  };
320 
323 
325  class RcvdReq
326  {
327  public:
328  RcvdReq()
329  : sn_(0),
330  rw_(0)
331  {
332  }
333  RcvdReq(ULong seqNbr)
334  : sn_(seqNbr),
335  rw_(0)
336  {
337  }
338  RcvdReq(const RcvdReq &rr)
339  : sn_(rr.sn_),
340  rw_(rr.rw_)
341  {
342  }
343 
344  ULong seqNbr() const { return sn_; }
345  RcvdReq &setSeqNbr(ULong seqNbr) { sn_ = seqNbr; return *this; }
346 
347  Int rspWnd() const { return rw_; }
348  RcvdReq &setRspWnd(Int rw) { rw_ = rw; return *this; }
349 
350  private:
351  ULong sn_;
352  Int rw_;
353  };
354  typedef std::unordered_map<ULong,RcvdReq> RcvdReqUMap;
356 
359 
363  {
364  friend class LocalNode;
365  public:
367  NodeSocket();
369  virtual ~NodeSocket();
370 
374  NodeSocket &setLocalNode(LocalNodeSPtr &ln) { ln_ = ln; return *this; }
377  NodeSocket &clearLocalNode() { ln_.reset(); return *this; }
378 
379  protected:
386  Void onReceive(const ESocket::Address &src, const ESocket::Address &dst, cpUChar data, Int len);
389  Void onError();
390 
391  private:
392  LocalNodeSPtr ln_;
393  };
394 
397 
398  DECLARE_ERROR(SessionBase_LocalSeidAlreadySet);
399  DECLARE_ERROR(SessionBase_RemoteSeidAlreadySet);
400 
401  class SessionBase;
402  typedef std::shared_ptr<SessionBase> SessionBaseSPtr;
403 
408  {
409  public:
413  SessionBase(LocalNodeSPtr &ln, RemoteNodeSPtr &rn)
414  : ln_(ln),
415  rn_(rn),
416  ls_(0),
417  rs_(0)
418  {
419  created_++;
420  }
424  : ln_(s.ln_),
425  rn_(s.rn_),
426  ls_(s.ls_),
427  rs_(s.rs_)
428  {
429  created_++;
430  }
432  virtual ~SessionBase();
433 
436  LocalNodeSPtr &localNode() { return ln_; }
439  RemoteNodeSPtr &remoteNode() { return rn_; }
442  const Seid localSeid() const { return ls_; }
445  const Seid remoteSeid() const { return rs_; }
451  SessionBase &setSeid(SessionBaseSPtr &s, Seid ls, Seid rs, Bool notify = True);
456  SessionBase &setLocalSeid(SessionBaseSPtr &s, Seid ls) { return setSeid(s, ls, 0); }
461  SessionBase &setRemoteSeid(SessionBaseSPtr &s, Seid rs) { return setSeid(s, 0, rs); }
463  virtual Void destroy(SessionBaseSPtr &s);
464 
465  static ULongLong sessionsCreated() { return created_; }
466  static ULongLong sessionsDeleted() { return deleted_; }
467 
468  static void* operator new(size_t sz)
469  {
470  if (pool_.allocSize() == 0)
471  {
472  if (sz >= (32768 - sizeof(EMemory::Node)))
473  {
474  pool_.setSize(sz, 0, 5);
475  }
476  else
477  {
478  size_t ns = 32768 - sizeof(EMemory::Node);
479  size_t bs = sz + sizeof(EMemory::Block);
480  bs += bs % sizeof(pVoid);
481  size_t bc = ns / bs;
482  if (bc < 5)
483  {
484  pool_.setSize(sz, 0, 5);
485  }
486  else
487  {
488  ns = sizeof(EMemory::Node) + bc * bs;
489  pool_.setSize(sz, ns);
490  }
491  }
492  }
493  if (sz > pool_.allocSize())
494  {
495  EError ex;
496  ex.setSevere();
497  ex.setText("session allocation size is larger than memory pool block size");
498  throw ex;
499  }
500  return pool_.allocate();
501  }
502  static void operator delete(void* m)
503  {
504  pool_.deallocate(m);
505  }
506 private: \
507 
508  private:
509  SessionBase();
510  static EMemory::Pool pool_;
511  static ULongLong created_;
512  static ULongLong deleted_;
513  LocalNodeSPtr ln_;
514  RemoteNodeSPtr rn_;
515  Seid ls_;
516  Seid rs_;
517  };
518  typedef std::unordered_map<Seid,SessionBaseSPtr> SessionBaseSPtrUMap;
519 
522 
525  class Node
526  {
527  public:
529  Node() { ++created_; }
531  virtual ~Node() { ++deleted_; }
532 
535  EIpAddress &ipAddress() { return ipaddr_; }
539  Node &setIpAddress(const EIpAddress &ipaddr) { ipaddr_ = ipaddr; return *this; }
540 
545  ESocket::Address &address() { return addr_; }
551  {
552  addr_ = addr;
553  ipaddr_ = addr.getSockAddrStorage();
554  return *this;
555  }
556 
559  const ETime &startTime() const { return st_; }
563  Node &setStartTime(const ETime &st = ETime::Now()) { st_ = st; return *this; }
564 
568  SessionBaseSPtr getSession(Seid seid)
569  {
570  auto it = sessions_.find(seid);
571  if (it == sessions_.end())
572  return SessionBaseSPtr();
573  return it->second;
574  }
575 
576  static ULongLong nodesCreated() { return created_; }
577  static ULongLong nodesDeleted() { return deleted_; }
578 
579  protected:
581  Node &_addSession(Seid seid, SessionBaseSPtr &session)
582  {
583  auto it = sessions_.find(seid);
584  if (it == sessions_.end())
585  sessions_[seid] = session;
586  return *this;
587  }
588  Node &_delSession(Seid seid)
589  {
590  if (seid != 0)
591  sessions_.erase(seid);
592  return *this;
593  }
594  SessionBaseSPtr getFirstSession()
595  {
596  if (sessions_.empty())
597  return SessionBaseSPtr();
598  return sessions_.begin()->second;
599  }
601 
602  private:
603  static ULongLong created_;
604  static ULongLong deleted_;
605 
606  ETime st_;
607  EIpAddress ipaddr_;
608  ESocket::Address addr_;
609  SessionBaseSPtrUMap sessions_;
610  };
611 
612  typedef std::shared_ptr<Node> NodeSPtr;
613 
616 
618  DECLARE_ERROR(RemoteNodeException_UnableToAssignTeidRangeValue);
620 
622  class RemoteNode : public Node
623  {
624  friend LocalNode;
625  friend CommunicationThread;
626  public:
627  enum class State { Initialized, Started, Stopping, Stopped, Failed, Restarted };
628 
630  RemoteNode();
632  virtual ~RemoteNode();
633 
636  Int teidRangeValue() const { return trv_; }
640  RemoteNode &setTeidRangeValue(Int trv) { trv_ = trv; return *this; }
641 
645  RemoteNode &setNbrActivityWnds(size_t nbr);
646 
651  RemoteNode &deleteAllSesssions(RemoteNodeSPtr &rn);
652 
656  RemoteNode &disconnect(RemoteNodeSPtr &rn);
657 
660  State state() const { return state_; }
661 
662  protected:
664  RemoteNode &changeState(RemoteNodeSPtr &rn, State state);
665  RemoteNode &restarted(RemoteNodeSPtr &rn, const ETime &restartTime);
666  Bool addRcvdReq(ULong sn);
667  Bool delRcvdReq(ULong sn) { return rrumap_.erase(sn) == 1; }
668  Bool setRcvdReqRspWnd(ULong sn, Int wnd);
669  Bool setRcvdReqRspWnd(ULong sn);
670  Void removeRcvdRqstEntries(Int wnd);
671  Bool rcvdReqExists(ULong sn) const { return rrumap_.find(sn) != rrumap_.end(); }
672 
673  Void nextActivityWnd(Int wnd);
674  Bool checkActivity();
675  Void incrementActivity() { awnds_[aw_]++; }
676 
677  Void removeOldReqs(Int rw);
678 
679  RemoteNode &addSession(SessionBaseSPtr &s);
680  RemoteNode &delSession(SessionBaseSPtr &s);
682 
683  private:
684  State state_;
685  ESocket::Address addr_;
686  Int trv_;
687  RcvdReqUMap rrumap_;
688  std::vector<ULong> awnds_;
689  size_t awndcnt_;
690  size_t aw_;
691  };
692  typedef std::unordered_map<EIpAddress,RemoteNodeSPtr> RemoteNodeUMap;
693  typedef std::pair<EIpAddress,RemoteNodeSPtr> RemoteNodeUMapPair;
694 
695  class RemoteNodeStateChangeEvent : public EventBase
696  {
697  public:
699  : rn_(rn),
700  os_(oldst),
701  ns_(newst)
702  {
703  }
704 
705  RemoteNodeSPtr &remoteNode() { return rn_; }
706  RemoteNode::State oldState() const { return os_; }
707  RemoteNode::State newState() const { return ns_; }
708 
709  private:
711  RemoteNodeSPtr rn_;
712  RemoteNode::State os_;
713  RemoteNode::State ns_;
714  };
715 
716  class RemoteNodeRestartEvent : public EventBase
717  {
718  public:
719  RemoteNodeRestartEvent(RemoteNodeSPtr &rn, RemoteNode::State oldst,
720  RemoteNode::State newst, const ETime &restartTime)
721  : rn_(rn),
722  os_(oldst),
723  ns_(newst),
724  rt_(restartTime)
725  {
726  }
727 
728  RemoteNodeSPtr &remoteNode() { return rn_; }
729  RemoteNode::State oldState() const { return os_; }
730  RemoteNode::State newState() const { return ns_; }
731  const ETime &restartTime() const { return rt_; }
732 
733  private:
735  RemoteNodeSPtr rn_;
736  RemoteNode::State os_;
737  RemoteNode::State ns_;
738  ETime rt_;
739  };
740 
743 
745  DECLARE_ERROR(LocalNodeException_UnableToCreateRemoteNode);
746  DECLARE_ERROR(LocalNodeException_RemoteNodeUMapInsertFailed);
748 
750  class LocalNode : public Node
751  {
752  friend NodeSocket;
753  friend CommunicationThread;
754  public:
755  enum class State { Initialized, Started, Stopping, Stopped };
756 
758  LocalNode();
760  virtual ~LocalNode();
761 
764  State state() { return state_; }
765 
768  Seid allocSeid();
771  Void freeSeid(Seid seid);
774  ULong allocSeqNbr();
777  Void freeSeqNbr(ULong sn);
778 
781  Void setNbrActivityWnds(size_t nbr);
782 
786  RemoteNodeSPtr createRemoteNode(cpStr addr, UShort port)
787  {
788  EIpAddress ipaddr(addr);
789  return createRemoteNode(ipaddr, port);
790  }
795  RemoteNodeSPtr createRemoteNode(EIpAddress &address, UShort port);
796 
802  SessionBaseSPtr createSession(LocalNodeSPtr &ln, RemoteNodeSPtr &rn);
803 
806  NodeSocket &socket() { return socket_; }
807 
810  State state() const { return state_; }
811 
812  protected:
813 
815  LocalNode &changeState(LocalNodeSPtr &ln, State state);
816  Bool rqstOutExists(ULong seqnbr) const;
817  Bool addRqstOut(ReqOut *ro);
818  Bool setRqstOutRespWnd(ULong seqnbr, Int wnd);
819  Void removeRqstOutEntries(Int wnd);
820  Void clearRqstOutEntries();
821 
822  Void nextActivityWnd(Int wnd);
823  Void checkActivity(LocalNodeSPtr &ln);
824 
825  Void onReceive(LocalNodeSPtr &ln, const ESocket::Address &src, const ESocket::Address &dst, cpUChar msg, Int len);
826  Bool onReqOutTimeout(ReqOutPtr ro);
827  Void removeOldReqs(Int rw);
828 
829  Void sndInitialReq(ReqOutPtr ro);
830  Bool sndReq(ReqOutPtr ro);
831  Void sndRsp(RspOutPtr ro);
832 
833  LocalNode &addSession(SessionBaseSPtr &s)
834  {
835  if (s && s->localSeid() != 0)
836  _addSession(s->localSeid(), s);
837  return *this;
838  }
839  LocalNode &delSession(SessionBaseSPtr &s)
840  {
841  if (s && s->localSeid() != 0)
842  _delSession(s->localSeid());
843  return *this;
844  }
845  SessionBaseSPtr createSession(LocalNodeSPtr &ln, Seid rs, RemoteNodeSPtr &rn);
847 
848  private:
849  State state_;
850  SeidManager seidmgr_;
851  SequenceManager seqmgr_;
852  NodeSocket socket_;
853  ReqOutUMap roumap_;
854  RemoteNodeUMap rns_;
855  };
856 
857  typedef std::unordered_map<EIpAddress,LocalNodeSPtr> LocalNodeUMap;
858  typedef std::pair<EIpAddress,LocalNodeSPtr> LocalNodeUMapEIpAddressPair;
859  typedef std::pair<ULong,LocalNodeSPtr> LocalNodeUMapULongPair;
860 
861  class LocalNodeStateChangeEvent : public EventBase
862  {
863  public:
865  : ln_(ln),
866  os_(oldst),
867  ns_(newst)
868  {
869  }
870 
871  LocalNodeSPtr &localNode() { return ln_; }
872  LocalNode::State oldState() const { return os_; }
873  LocalNode::State newState() const { return ns_; }
874 
875  private:
877  LocalNodeSPtr ln_;
878  LocalNode::State os_;
879  LocalNode::State ns_;
880  };
883 
885  class AppMsg
886  {
887  public:
889  virtual ~AppMsg()
890  {
891  }
892 
895  ULong seqNbr() const { return seq_; }
898  MsgType msgType() const { return mt_; }
901  MsgClass msgClass() const { return mc_; }
903  Bool isReq() const { return rqst_; }
904 
907  AppMsg &setSeqNbr(const ULong sn) { seq_ = sn; return *this; }
908 
911  virtual const EString &className()
912  {
913  static EString cn_ = ::__CLASS_NAME__;
914  return cn_;
915  }
916 
918  virtual Void postDecode() {}
920 
921  protected:
923  : seq_(0),
924  mt_(0),
925  mc_(MsgClass::Unknown),
926  rqst_(False)
927  {
928  }
929  AppMsg(const AppMsg &dm)
930  : seq_(dm.seq_),
931  mt_(dm.mt_),
932  mc_(dm.mc_),
933  rqst_(dm.rqst_)
934  {
935  }
936 
937  AppMsg &setMsgType(const MsgType mt) { mt_ = mt; return*this; }
938  AppMsg &setMsgClass(const MsgClass mc) { mc_ = mc; return*this; }
939  AppMsg &setIsReq(const Bool rqst) { rqst_ = rqst; return *this; }
940 
941  private:
942  ULong seq_;
943  MsgType mt_;
944  MsgClass mc_;
945  Bool rqst_;
946  };
947 
948  typedef AppMsg *AppMsgPtr;
949 
952 
954  class AppMsgReq : public AppMsg
955  {
956  public:
958  virtual ~AppMsgReq()
959  {
960  }
961 
964  LocalNodeSPtr &localNode() { return ln_; }
967  RemoteNodeSPtr &remoteNode() { return rn_; }
968 
969  protected:
972  {
973  setIsReq(True);
974  }
978  AppMsgReq(LocalNodeSPtr &ln, RemoteNodeSPtr &rn, Bool allocSeqNbr)
979  : ln_(ln),
980  rn_(rn)
981  {
982  setIsReq(True);
983  if (allocSeqNbr)
984  setSeqNbr(ln->allocSeqNbr());
985  }
986 
987  private:
988  LocalNodeSPtr ln_;
989  RemoteNodeSPtr rn_;
990  };
992 
995 
998  class AppMsgNodeReq : public AppMsgReq
999  {
1000  public:
1003  {
1004  setMsgClass(PFCP::MsgClass::Node);
1005  }
1009  AppMsgNodeReq(LocalNodeSPtr &ln, RemoteNodeSPtr &rn, Bool allocSeqNbr)
1010  : AppMsgReq(ln, rn, allocSeqNbr)
1011  {
1012  setMsgClass(PFCP::MsgClass::Node);
1013  }
1015  virtual ~AppMsgNodeReq()
1016  {
1017  }
1018  };
1019 
1021 
1024 
1027  {
1028  public:
1031  {
1032  setMsgClass(PFCP::MsgClass::Session);
1033  }
1037  AppMsgSessionReq(SessionBaseSPtr &ses, Bool allocSeqNbr)
1038  : AppMsgReq(ses->localNode(), ses->remoteNode(), allocSeqNbr),
1039  ses_(ses)
1040  {
1041  setMsgClass(PFCP::MsgClass::Session);
1042  }
1045  {
1046  }
1047 
1050  SessionBaseSPtr &session() { return ses_; }
1051 
1052  private:
1053  SessionBaseSPtr ses_;
1054  };
1055 
1057 
1060 
1062  class AppMsgRsp : public AppMsg
1063  {
1064  public:
1067  : amrq_(nullptr)
1068  {
1069  setIsReq(False);
1070  }
1074  AppMsgRsp(AppMsgReqPtr amrq)
1075  : amrq_(amrq)
1076  {
1077  setIsReq(False);
1078  }
1080  virtual ~AppMsgRsp()
1081  {
1082  if (amrq_)
1083  delete amrq_;
1084  }
1085 
1088  AppMsgReqPtr req() { return amrq_; }
1091  LocalNodeSPtr &localNode() { return amrq_->localNode(); }
1094  RemoteNodeSPtr &remoteNode() { return amrq_->remoteNode(); }
1095 
1099  {
1100  amrq_ = req;
1101  if (amrq_)
1102  setSeqNbr(amrq_->seqNbr());
1103  return *this;
1104  }
1105 
1106  private:
1107  AppMsgReqPtr amrq_;
1108  };
1110 
1113 
1115  class AppMsgNodeRsp : public AppMsgRsp
1116  {
1117  public:
1120  : AppMsgRsp(nullptr)
1121  {
1122  setMsgClass(PFCP::MsgClass::Node);
1123  setIsReq(False);
1124  }
1128  AppMsgNodeRsp(AppMsgNodeReqPtr &amrq)
1129  : AppMsgRsp(amrq)
1130  {
1131  setMsgClass(PFCP::MsgClass::Node);
1132  setIsReq(False);
1133  }
1135  virtual ~AppMsgNodeRsp()
1136  {
1137  }
1138 
1141  AppMsgNodeReqPtr req() { return static_cast<AppMsgNodeReqPtr>(AppMsgRsp::req()); }
1142 
1145  AppMsgNodeRsp &setReq(AppMsgNodeReqPtr req) { AppMsgRsp::setReq(req); return *this; }
1146  };
1147 
1149 
1152 
1155  {
1156  public:
1159  : AppMsgRsp(nullptr)
1160  {
1161  setMsgClass(PFCP::MsgClass::Session);
1162  }
1166  AppMsgSessionRsp(AppMsgSessionReqPtr &amrq)
1167  : AppMsgRsp(amrq)
1168  {
1169  setMsgClass(PFCP::MsgClass::Session);
1170  }
1173  {
1174  }
1175 
1178  AppMsgSessionReqPtr req() { return static_cast<AppMsgSessionReqPtr>(AppMsgRsp::req()); }
1179 
1182  AppMsgSessionRsp &setReq(AppMsgSessionReqPtr req) { AppMsgRsp::setReq(req); return *this; }
1183  };
1184 
1186 
1189 
1191  class SndHeartbeatReqData
1192  {
1193  public:
1194  SndHeartbeatReqData()
1195  {
1196  }
1197  SndHeartbeatReqData(LocalNodeSPtr &ln, RemoteNodeSPtr &rn)
1198  : ln_(ln),
1199  rn_(rn)
1200  {
1201  }
1202  SndHeartbeatReqData(const SndHeartbeatReqData &hb)
1203  {
1204  ln_ = hb.ln_;
1205  rn_ = hb.rn_;
1206  }
1207 
1208  LocalNodeSPtr &localNode() { return ln_; }
1209  RemoteNodeSPtr &remoteNode() { return rn_; }
1210 
1211  SndHeartbeatReqData &setLocalNode(LocalNodeSPtr &ln) { ln_ = ln; return *this; }
1212  SndHeartbeatReqData &setRemoteNode(RemoteNodeSPtr &rn) { rn_ = rn; return *this; }
1213 
1214  private:
1215  LocalNodeSPtr ln_;
1216  RemoteNodeSPtr rn_;
1217  };
1218  typedef SndHeartbeatReqData *SndHeartbeatReqDataPtr;
1220 
1223 
1225  class RcvdHeartbeatReqData
1226  {
1227  public:
1228  RcvdHeartbeatReqData()
1229  : am_(nullptr)
1230  {
1231  }
1232  RcvdHeartbeatReqData(const RcvdHeartbeatReqData &hb)
1233  {
1234  am_ = hb.am_;
1235  started_ = hb.started_;
1236  }
1237 
1238  AppMsgNodeReqPtr req() const { return am_; }
1239  const ETime &startTime() const { return started_; }
1240 
1241  RcvdHeartbeatReqData &setReq(AppMsgNodeReqPtr am) { am_ = am; return *this;}
1242  RcvdHeartbeatReqData &setStartTime(const ETime &started) { started_ = started; return *this; }
1243 
1244  private:
1245  AppMsgNodeReqPtr am_;
1246  ETime started_;
1247  };
1248  typedef RcvdHeartbeatReqData *RcvdHeartbeatReqDataPtr;
1250 
1253 
1255  class SndHeartbeatRspData
1256  {
1257  public:
1258  SndHeartbeatRspData()
1259  : am_(nullptr)
1260  {
1261  }
1262  SndHeartbeatRspData(AppMsgNodeReqPtr am)
1263  : am_(am)
1264  {
1265  }
1266 
1267  AppMsgNodeReq &req() { return *am_; }
1268 
1269  SndHeartbeatRspData &setReq(AppMsgNodeReqPtr am) { am_ = am; return *this; }
1270 
1271  private:
1272  AppMsgNodeReqPtr am_;
1273  };
1274  typedef SndHeartbeatRspData *SndHeartbeatRspDataPtr;
1276 
1279 
1281  class RcvdHeartbeatRspData
1282  {
1283  public:
1284  RcvdHeartbeatRspData()
1285  : am_(nullptr)
1286  {
1287  }
1288  RcvdHeartbeatRspData(AppMsgNodeReqPtr am)
1289  : am_(am)
1290  {
1291  }
1292  ~RcvdHeartbeatRspData()
1293  {
1294  if (am_)
1295  {
1296  delete am_;
1297  am_ = nullptr;
1298  }
1299  }
1300 
1301  AppMsgNodeReq &req() { return *am_; }
1302  const ETime &startTime() const { return started_; }
1303 
1304  RcvdHeartbeatRspData &setReq(AppMsgNodeReqPtr am) { am_ = am; return *this; }
1305  RcvdHeartbeatRspData &setStartTime(const ETime &started) { started_ = started; return *this; }
1306 
1307  private:
1308  AppMsgNodeReqPtr am_;
1309  ETime started_;
1310  };
1311  typedef RcvdHeartbeatRspData *RcvdHeartbeatRspDataPtr;
1313 
1316 
1318  DECLARE_ERROR(InternalMsg_OutOfMemory);
1319 
1320  class TranslatorMsgInfo;
1321 
1322  class InternalMsg
1323  {
1324  public:
1325  InternalMsg()
1326  : seq_(0),
1327  mt_(0),
1328  mc_(MsgClass::Unknown),
1329  rqst_(False),
1330  data_(nullptr),
1331  len_(0)
1332  {
1333  }
1334  InternalMsg(const InternalMsg &im)
1335  : ln_(im.ln_),
1336  rn_(im.rn_),
1337  ses_(im.ses_),
1338  seq_(im.seq_),
1339  mt_(im.mt_),
1340  mc_(im.mc_),
1341  rqst_(im.rqst_),
1342  data_(nullptr),
1343  len_(0)
1344  {
1345  assign(im.data_, im.len_);
1346  }
1347  InternalMsg(const LocalNodeSPtr &ln, const RemoteNodeSPtr &rn, const TranslatorMsgInfo &tmi, cpUChar data, UShort len);
1348  virtual ~InternalMsg()
1349  {
1350  if (data_ != nullptr)
1351  delete [] data_;
1352  }
1353 
1354  InternalMsg &operator=(const InternalMsg &im)
1355  {
1356  ln_ = im.ln_;
1357  rn_ = im.rn_;
1358  ses_ = im.ses_;
1359  seq_ = im.seq_;
1360  mt_ = im.mt_;
1361  mc_ = im.mc_;
1362  rqst_ = im.rqst_;
1363  assign(im.data_, im.len_);
1364  return *this;
1365  }
1366 
1367  LocalNodeSPtr &localNode() { return ln_; }
1368  RemoteNodeSPtr &remoteNode() { return rn_; }
1369  SessionBaseSPtr &session() { return ses_; }
1370  ULong seqNbr() const { return seq_; }
1371  MsgType msgType() const { return mt_; }
1372  MsgClass msgClass() const { return mc_; }
1373  Bool isReq() const { return rqst_; }
1374  UChar version() const { return ver_; }
1375  cpUChar data() const { return data_; }
1376  UShort len() const { return len_; }
1377 
1378  InternalMsg &setLocalNode(const LocalNodeSPtr &ln) { ln_ = ln; return *this; }
1379  InternalMsg &setRemoteNode(const RemoteNodeSPtr &rn) { rn_ = rn; return *this; }
1380  InternalMsg &setSession(const SessionBaseSPtr &ses) { ses_ = ses; return *this; }
1381  InternalMsg &setSeqNbr(const ULong sn) { seq_ = sn; return *this; }
1382  InternalMsg &setMsgType(const MsgType mt) { mt_ = mt; return *this; }
1383  InternalMsg &setMsgClass(const MsgClass mc) { mc_ = mc; return *this; }
1384  InternalMsg &setIsReq(const Bool rqst) { rqst_ = rqst; return *this; }
1385  InternalMsg &setVersion(const UChar ver) { ver_ = ver; return *this; }
1386 
1387  InternalMsg &assign(cpUChar data, UShort len)
1388  {
1389  // allocate the memory if necessary
1390  if (len_ != len)
1391  {
1392  if (data_ != nullptr)
1393  delete [] data_;
1394  len_ = len;
1395  try
1396  {
1397  data_ = new UChar[len_];
1398  }
1399  catch(const std::bad_alloc& e)
1400  {
1401  throw InternalMsg_OutOfMemory();
1402  }
1403  }
1404  // copy the data
1405  std::memcpy(data_, data, len);
1406  return *this;
1407  }
1408 
1409  static void* operator new(size_t sz);
1410  static void operator delete(void* m);
1411 
1412  private:
1413  static EMemory::Pool pool_;
1414  LocalNodeSPtr ln_;
1415  RemoteNodeSPtr rn_;
1416  SessionBaseSPtr ses_;
1417  ULong seq_;
1418  MsgType mt_;
1419  MsgClass mc_;
1420  Bool rqst_;
1421  UChar ver_;
1422  pUChar data_;
1423  UShort len_;
1424  };
1425 
1426  typedef InternalMsg *InternalMsgPtr;
1428 
1431 
1433  class RspOut : public InternalMsg
1434  {
1435  public:
1436  RspOut()
1437  : am_(nullptr)
1438  {
1439  }
1440  RspOut(const RspOut &sr)
1441  : InternalMsg(sr)
1442  {
1443  }
1444  virtual ~RspOut()
1445  {
1446  if (am_ != nullptr)
1447  delete am_;
1448  }
1449 
1450  RspOut &operator=(const RspOut &ro)
1451  {
1452  InternalMsg::operator=(ro);
1453  am_ = ro.am_;
1454  return *this;
1455  }
1456 
1457  AppMsgRspPtr rsp() const { return am_; }
1458  RspOut &setRsp(AppMsgRspPtr am) { am_ = am; return *this; }
1459 
1460  private:
1461  AppMsgRspPtr am_;
1462  };
1463  typedef RspOut *RspOutPtr;
1465 
1468 
1470  class RspIn : public InternalMsg
1471  {
1472  public:
1473  RspIn()
1474  : am_(nullptr),
1475  rs_(0)
1476  {
1477  }
1478  RspIn(const RspIn &ri)
1479  : InternalMsg(ri),
1480  am_(ri.am_),
1481  rs_(ri.rs_)
1482  {
1483  }
1484  RspIn(const LocalNodeSPtr &ln, const RemoteNodeSPtr &rn, const TranslatorMsgInfo &tmi, cpUChar data, UShort len, AppMsgReqPtr am)
1485  : InternalMsg(ln, rn, tmi, data, len),
1486  am_(am)
1487  {
1488  }
1489  virtual ~RspIn()
1490  {
1491  }
1492 
1493  RspIn &operator=(const RspIn &ri)
1494  {
1495  InternalMsg::operator=(ri);
1496  am_ = ri.am_;
1497  return *this;
1498  }
1499 
1500  AppMsgReqPtr req() const { return am_; }
1501  RspIn &setReq(AppMsgReqPtr am) { am_ = am; return *this; }
1502 
1503  Seid remoteSeid() const { return rs_; }
1504  RspIn &remoteSeid(Seid rs) { rs_ = rs; return *this; }
1505 
1506  const ETime &remoteStartTime() { return rst_; }
1507  RspIn &remoteStartTime(const ETime &rst) { rst_ = rst; return *this; }
1508  private:
1509  AppMsgReqPtr am_;
1510  Seid rs_;
1511  ETime rst_;
1512  };
1513  typedef RspIn *RspInPtr;
1515 
1518 
1520  class ReqOut : public InternalMsg
1521  {
1522  public:
1523  ReqOut()
1524  : InternalMsg(),
1525  am_(),
1526  n1_(Configuration::n1()),
1527  t1_(Configuration::t1()),
1528  t1id_(0),
1529  rw_(0)
1530  {
1531  }
1532  ReqOut(const ReqOut &ro)
1533  : InternalMsg(ro),
1534  am_(ro.am_),
1535  n1_(ro.n1_),
1536  t1_(ro.t1_),
1537  t1id_(ro.t1id_),
1538  rw_(ro.rw_)
1539  {
1540  }
1541  virtual ~ReqOut()
1542  {
1543  if (am_)
1544  {
1545  delete am_;
1546  am_ = nullptr;
1547  }
1548  }
1549 
1550  ReqOut &operator=(const ReqOut &ro)
1551  {
1552  InternalMsg::operator=(ro);
1553  am_ = ro.am_;
1554  n1_ = ro.n1_;
1555  t1_ = ro.t1_;
1556  t1id_ = ro.t1id_;
1557  rw_ = ro.rw_;
1558  return *this;
1559  }
1560 
1561  AppMsgReqPtr appMsg() { return am_; }
1562  ReqOut &setAppMsg(AppMsgReqPtr am)
1563  {
1564  am_ = am;
1565  if (am)
1566  {
1567  setMsgType(am->msgType());
1568  setMsgClass(am->msgClass());
1569  }
1570  return *this;
1571  }
1572 
1573  Bool okToSnd() { if (n1_ < 1) return False; n1_--; return True; }
1574 
1575  Int n1() const { return n1_; }
1576  ReqOut &setN1(Int n1) { n1_ = n1; return *this; }
1577 
1578  LongLong t1() const { return t1_; }
1579  ReqOut &setT1(LongLong t1) { t1_ = t1; return *this; }
1580 
1581  Int rspWnd() const { return rw_; }
1582  ReqOut &setRspWnd(Int rw) { rw_ = rw; return *this; }
1583 
1584  Void startT1();
1585  Void stopT1()
1586  {
1587  if (t1id_ > 0)
1588  {
1590  t1id_ = 0;
1591  }
1592  }
1593 
1594  private:
1595  AppMsgReqPtr am_;
1596  Int n1_;
1597  LongLong t1_;
1598  ULong t1id_;
1599  Int rw_;
1600  };
1602 
1605 
1607  class ReqIn : public InternalMsg
1608  {
1609  public:
1610  ReqIn()
1611  : rs_(0)
1612  {
1613  }
1614  ReqIn(const ReqIn &ri)
1615  : InternalMsg(ri),
1616  rs_(ri.rs_)
1617  {
1618  }
1619  ReqIn(const LocalNodeSPtr &ln, const RemoteNodeSPtr &rn, const TranslatorMsgInfo &tmi, cpUChar data, UShort len)
1620  : InternalMsg(ln, rn, tmi, data, len)
1621  {
1622  }
1623  virtual ~ReqIn()
1624  {
1625  }
1626 
1627  Seid remoteSeid() { return rs_; }
1628  ReqIn &remoteSeid(Seid rs) { rs_ = rs; return *this; }
1629 
1630  const ETime &remoteStartTime() { return rst_; }
1631  ReqIn &remoteStartTime(const ETime &rst) { rst_ = rst; return *this; }
1632  private:
1633  Seid rs_;
1634  ETime rst_;
1635  };
1636  typedef ReqIn *ReqInPtr;
1638 
1641 
1642 #if 0
1643  InternalMsg
1644  SEID
1645  seqNbr
1646  MsgType
1647  isReq
1648  buffer
1649  len
1650  application structure allocated by EncoderDecoder based on msg type
1651 
1652  RspOut
1653  InternalMsg
1654 
1655  RspIn
1656  InternalMsg
1657  AppMsgSPtr
1658 
1659  ReqOut
1660  InternalMsg
1661  AppMsgSPtr
1662  timerId
1663  sendCount
1664  rspWnd (0,1,2)
1665 
1666  ReqIn
1667  InternalMsg
1668 
1669  RcvdReq
1670  seqNbr
1671  rspWnd (0,1,2)
1672 
1673 
1674 Snding a Req (ReqOut)
1675  add ReqOut object local Node retransmission list (seqnbr is key)
1676  set sendCount = 0
1677  perform "retransmission timer expiration" procedure
1678  start retransmission timer
1679 
1680  retransmission timer expiration
1681  sendCount >= N1
1682  send ReqMsgPtr to application layer indicating rsp timeout
1683  remove SentReq from retransmission list
1684  sendCount < N1
1685  send the req
1686  increment sendCount
1687  start expiration timer
1688 
1689 Receiving a Req
1690  Lookup seqNbr in ReqIn list of remote Node
1691  entry found
1692  log duplicate req
1693  discard msg
1694  entry not found
1695  create RcvdReq with seqNbr, rspWnd=0
1696  add RcvdReq to remove Node RcvdReq list (seqNbr)
1697  send EncodedMsg to EcDc layer to decoding
1698 
1699 Snding a Rsp
1700  Lookup sequence in ReqIn list of the remote node
1701  entry found
1702  update rspWnd in ReqIn to the current wnd
1703  send the msg
1704  entry not found
1705  discard msg(?)
1706 
1707 Receiving a Rsp
1708  lookup ReqOut in local Node retransmission list (seqNbr)
1709  ReqOut found
1710  set ReqOut rspWnd to current wnd
1711  create RspIn and send to EcDc layer to decode
1712  ReqOut not found
1713  log error
1714  discard msg
1715 
1716 
1717 Receiving a msg
1718  perform partial header parsing (seqNbr, isReq)
1719  isReq is TRUE
1720  go to Receiving a Req
1721  isReq is FALSE
1722  go to Receiving a Reponse
1723 
1724 #endif
1725 
1728 
1730  DECLARE_ERROR_ADVANCED(TeidRangeManager_InvalidRangeBits);
1731  inline TeidRangeManager_InvalidRangeBits::TeidRangeManager_InvalidRangeBits() {
1732  setText("The number of range bits must be between 0 and 7");
1733  }
1734 
1735  class TeidRangeManager
1736  {
1737  public:
1738  TeidRangeManager(Int rangeBits=0);
1739  ~TeidRangeManager();
1740 
1741  Bool assign(RemoteNodeSPtr &n);
1742  Void release(RemoteNodeSPtr &n);
1743 
1744  private:
1745  Int bits_;
1746  std::list<Int> free_;
1747  std::unordered_map<Int,RemoteNodeSPtr> used_;
1748  };
1750 
1753 
1755  class TranslatorMsgInfo
1756  {
1757  public:
1758  TranslatorMsgInfo()
1759  : seid_(0),
1760  mt_(0),
1761  sn_(0),
1762  ver_(0),
1763  rqst_(False)
1764  {
1765  }
1766 
1767  Seid seid() const { return seid_; }
1768  MsgType msgType() const { return mt_; }
1769  MsgClass msgClass() const { return mc_; }
1770  ULong seqNbr() const { return sn_; }
1771  UChar version() const { return ver_; }
1772  Bool isReq() const { return rqst_; }
1773  Bool createSession() const { return create_; }
1774 
1775  TranslatorMsgInfo &setSeid(const Seid seid) { seid_ = seid; return *this; }
1776  TranslatorMsgInfo &setMsgType(const MsgType mt) { mt_ = mt; return *this; }
1777  TranslatorMsgInfo &setMsgClass(const MsgClass mc) { mc_ = mc; return *this; }
1778  TranslatorMsgInfo &setSeqNbr(const ULong sn) { sn_ = sn; return *this; }
1779  TranslatorMsgInfo &setVersion(UChar ver) { ver_ = ver; return *this; }
1780  TranslatorMsgInfo &setReq(Bool rqst) { rqst_ = rqst; return *this; }
1781  TranslatorMsgInfo &setCreateSession(Bool create) { create_ = create; return *this; }
1782 
1783  private:
1784  Seid seid_;
1785  MsgType mt_;
1786  MsgClass mc_;
1787  ULong sn_;
1788  UChar ver_;
1789  Bool rqst_;
1790  Bool create_;
1791  };
1793 
1796 
1801  {
1802  public:
1804  Translator();
1806  virtual ~Translator();
1807 
1811  virtual ReqOutPtr encodeHeartbeatReq(SndHeartbeatReqData &hb) = 0;
1815  virtual RspOutPtr encodeHeartbeatRsp(SndHeartbeatRspData &hb) = 0;
1819  virtual RspOutPtr encodeVersionNotSupportedRsp(ReqInPtr msg) = 0;
1820 
1825  virtual ReqOutPtr encodeReq(AppMsgReqPtr msg) = 0;
1830  virtual RspOutPtr encodeRsp(AppMsgRspPtr msg) = 0;
1831 
1835  virtual AppMsgReqPtr decodeReq(ReqInPtr msg) = 0;
1839  virtual AppMsgRspPtr decodeRsp(RspInPtr msg) = 0;
1840 
1844  virtual RcvdHeartbeatReqDataPtr decodeHeartbeatReq(ReqInPtr msg) = 0;
1848  virtual RcvdHeartbeatRspDataPtr decodeHeartbeatRsp(RspInPtr msg) = 0;
1849 
1854  virtual Void getMsgInfo(TranslatorMsgInfo &info, cpUChar msg, Int len) = 0;
1857  virtual Bool isVersionSupported(UChar ver) = 0;
1860  virtual MsgClass messageClass(MsgType mt) = 0;
1861 
1864  virtual MsgType pfcpHeartbeatReq() = 0;
1867  virtual MsgType pfcpHeartbeatRsp() = 0;
1870  virtual MsgType pfcpSessionEstablishmentReq() = 0;
1873  virtual MsgType pfcpSessionEstablishmentRsp() = 0;
1876  virtual MsgType pfcpAssociationSetupReq() = 0;
1879  virtual MsgType pfcpAssociationSetupRsp() = 0;
1880 
1881  protected:
1883  pUChar data() { return data_; }
1885 
1886  private:
1887  UChar data_[ESocket::UPD_MAX_MSG_LENGTH];
1888  };
1889 
1892 
1894  DECLARE_ERROR(SndReqException);
1895  struct SndReqExceptionData
1896  {
1897  AppMsgReqPtr req;
1898  SndReqException err;
1899  };
1900  typedef SndReqExceptionData *SndReqExceptionDataPtr;
1901 
1902  DECLARE_ERROR(SndRspException);
1903  struct SndRspExceptionData
1904  {
1905  AppMsgRspPtr rsp;
1906  SndRspException err;
1907  };
1908  typedef SndRspExceptionData *SndRspExceptionDataPtr;
1909 
1910  DECLARE_ERROR(SndHeartbeatReqException);
1911  struct SndHeartbeatReqExceptionData
1912  {
1913  SndHeartbeatReqDataPtr req;
1914  SndHeartbeatReqException err;
1915  };
1916  typedef SndHeartbeatReqExceptionData *SndHeartbeatReqExceptionDataPtr;
1917 
1918  DECLARE_ERROR(SndHeartbeatRspException);
1919  struct SndHeartbeatRspExceptionData
1920  {
1921  SndHeartbeatRspDataPtr rsp;
1922  SndHeartbeatRspException err;
1923  };
1924  typedef SndHeartbeatRspExceptionData *SndHeartbeatRspExceptionDataPtr;
1925 
1926  DECLARE_ERROR(RcvdReqException);
1927  struct RcvdReqExceptionData
1928  {
1929  ReqInPtr req;
1930  RcvdReqException err;
1931  };
1932  typedef RcvdReqExceptionData *RcvdReqExceptionDataPtr;
1933 
1934  DECLARE_ERROR(RcvdRspException);
1935  struct RcvdRspExceptionData
1936  {
1937  RspInPtr rsp;
1938  RcvdRspException err;
1939  };
1940  typedef RcvdRspExceptionData *RcvdRspExceptionDataPtr;
1941 
1942  DECLARE_ERROR(EncodeReqException);
1943  struct EncodeReqExceptionData
1944  {
1945  AppMsgReqPtr req;
1946  EncodeReqException err;
1947  };
1948  typedef EncodeReqExceptionData *EncodeReqExceptionDataPtr;
1949 
1950  DECLARE_ERROR(EncodeRspException);
1951  struct EncodeRspExceptionData
1952  {
1953  AppMsgRspPtr rsp;
1954  EncodeRspException err;
1955  };
1956  typedef EncodeRspExceptionData *EncodeRspExceptionDataPtr;
1958 
1961 
1963  #define APPLICATION_BASE_EVENT (EM_USER + 10000)
1964 
1967  enum class ApplicationEvents : UInt
1968  {
1970  RcvdReq = (APPLICATION_BASE_EVENT + 1),
1972  RcvdRsp = (APPLICATION_BASE_EVENT + 2),
1974  ReqTimeout = (APPLICATION_BASE_EVENT + 3),
1976  LocalNodeStateChange = (APPLICATION_BASE_EVENT + 4),
1978  RemoteNodeStateChange = (APPLICATION_BASE_EVENT + 5),
1980  RemoteNodeRestart = (APPLICATION_BASE_EVENT + 6),
1982  SndReqError = (APPLICATION_BASE_EVENT + 9),
1984  SndRspError = (APPLICATION_BASE_EVENT + 8),
1986  EncodeReqError = (APPLICATION_BASE_EVENT + 9),
1988  EncodeRspError = (APPLICATION_BASE_EVENT + 10),
1990  DecodeReqError = (APPLICATION_BASE_EVENT + 11),
1992  DecodeRspError = (APPLICATION_BASE_EVENT + 12)
1993  };
1994 
1997 
1999  DECLARE_ERROR(ApplicationWorkGroup_UnrecognizedAddressFamily);
2001 
2003  {
2004  friend LocalNode;
2005  friend CommunicationThread;
2006  protected:
2009  virtual LocalNodeSPtr _createLocalNode() = 0;
2010 
2013  virtual RemoteNodeSPtr _createRemoteNode() = 0;
2014 
2017  virtual SessionBaseSPtr _createSession(LocalNodeSPtr &ln, RemoteNodeSPtr &rn) = 0;
2018  };
2019 
2022  template <class TWorker>
2024  {
2025  friend CommunicationThread;
2026  public:
2032  LocalNodeSPtr createLocalNode(cpStr ipaddr, UShort port = PFCP::Configuration::port(), Bool start = True)
2033  {
2034  ESocket::Address addr(ipaddr, port);
2035  return createLocalNode(addr, start);
2036  }
2037  LocalNodeSPtr createLocalNode(const EIpAddress &ipaddr, UShort port = PFCP::Configuration::port(), Bool start = True)
2038  {
2039  ESocket::Address addr;
2040  switch (ipaddr.family())
2041  {
2042  case AF_INET: { addr.setAddress(ipaddr.ipv4Address(), port); break; }
2043  case AF_INET6: { addr.setAddress(ipaddr.ipv6Address(), port); break; }
2044  default:
2045  {
2046  throw ApplicationWorkGroup_UnrecognizedAddressFamily();
2047  }
2048  }
2049  return createLocalNode(addr, start);
2050  }
2052 
2056  LocalNodeSPtr createLocalNode(ESocket::Address &addr, Bool start = True);
2057 
2060  Void startLocalNode(LocalNodeSPtr &ln);
2063  Void stopLocalNode(LocalNodeSPtr &ln);
2064  };
2065 
2068 
2074  {
2075  friend Void Uninitialize();
2076  public:
2079  virtual Void onInit();
2083  virtual Void onQuit();
2084 
2087  virtual Void onRcvdReq(AppMsgReqPtr req);
2090  virtual Void onRcvdRsp(AppMsgRspPtr rsp);
2095  virtual Void onReqTimeout(AppMsgReqPtr req);
2100  virtual Void onLocalNodeStateChange(LocalNodeSPtr &ln, LocalNode::State oldState, LocalNode::State newState);
2105  virtual Void onRemoteNodeStateChange(RemoteNodeSPtr &rn, RemoteNode::State oldState, RemoteNode::State newState);
2108  virtual Void onRemoteNodeRestart(RemoteNodeSPtr &rn, const ETime &restartTime);
2112  virtual Void onSndReqError(AppMsgReqPtr req, SndReqException &err);
2117  virtual Void onSndRspError(AppMsgRspPtr rsp, SndRspException &err);
2122  virtual Void onEncodeReqError(AppMsgReqPtr req, EncodeReqException &err);
2127  virtual Void onEncodeRspError(AppMsgRspPtr rsp, EncodeRspException &err);
2128 
2129  protected:
2132  ~ApplicationWorker();
2133 
2134  Void _onRcvdReq(EThreadMessage &msg);
2135  Void _onRcvdRsp(EThreadMessage &msg);
2136  Void _onReqTimeout(EThreadMessage &msg);
2137  Void _onLocalNodeStateChange(EThreadMessage &msg);
2138  Void _onRemoteNodeStateChange(EThreadMessage &msg);
2139  Void _onRemoteNodeRestart(EThreadMessage &msg);
2140  Void _onSndReqError(EThreadMessage &msg);
2141  Void _onSndRspError(EThreadMessage &msg);
2142  Void _onEncodeReqError(EThreadMessage &msg);
2143  Void _onEncodeRspError(EThreadMessage &msg);
2144 
2146  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::RcvdReq), ApplicationWorker::_onRcvdReq)
2147  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::RcvdRsp), ApplicationWorker::_onRcvdRsp)
2148  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::ReqTimeout), ApplicationWorker::_onReqTimeout)
2149  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::LocalNodeStateChange), ApplicationWorker::_onLocalNodeStateChange)
2150  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::RemoteNodeStateChange), ApplicationWorker::_onRemoteNodeStateChange)
2151  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::RemoteNodeRestart), ApplicationWorker::_onRemoteNodeRestart)
2152  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::SndReqError), ApplicationWorker::_onSndReqError)
2153  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::SndRspError), ApplicationWorker::_onSndRspError)
2154  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::EncodeReqError), ApplicationWorker::_onEncodeReqError)
2155  ON_MESSAGE2(static_cast<UInt>(ApplicationEvents::EncodeRspError), ApplicationWorker::_onEncodeRspError)
2158  private:
2159  };
2160 
2163 
2165  #define TRANSLATION_BASE_EVENT (EM_USER + 20000)
2166 
2167  class TranslationThread : public EThreadPrivate
2168  {
2169  friend Void Uninitialize();
2170  friend AppMsgReq;
2171  friend AppMsgRsp;
2172  public:
2173  enum class Events : UInt
2174  {
2175  SndMsg = (TRANSLATION_BASE_EVENT + 1), // ApplicationWorkGroup --> TranslationThread - AppMsgPtr
2176  RcvdReq = (TRANSLATION_BASE_EVENT + 2), // CommunicationThread --> TranslationThread - ReqInPtr
2177  RcvdRsp = (TRANSLATION_BASE_EVENT + 3), // CommunicationThread --> TranslationThread - RspInPtr
2178  SndHeartbeatReq = (TRANSLATION_BASE_EVENT + 4), // CommunicationThread --> TranslationThread - SndHeartbeatReqDataPtr
2179  SndHeartbeatRsp = (TRANSLATION_BASE_EVENT + 5) // CommunicationThread --> TranslationThread - SndHeartbeatRspDataPtr
2180  };
2181 
2182  ~TranslationThread();
2183 
2184  static TranslationThread &Instance()
2185  {
2186  if (this_ == nullptr)
2187  this_ = new TranslationThread();
2188  return *this_;
2189  }
2190 
2191  Void onInit();
2192  Void onQuit();
2193 
2194  // virtual Void onRcv(AppMsgPtr &am);
2195 
2197 
2198  protected:
2199  Void onSndPfcpMsg(EThreadMessage &msg);
2200  Void onRcvdReq(EThreadMessage &msg);
2201  Void onRcvdRsp(EThreadMessage &msg);
2202  Void onSndHeartbeatReq(EThreadMessage &msg);
2203  Void onSndHeartbeatRsp(EThreadMessage &msg);
2204 
2205  // static Bool send(AppMsgReqPtr &amrq)
2206  // {
2207  // return this_->sendMsg(new EThreadMessage(TRANSLATE_SEND_REQUEST_EVENT, amrq.release()));
2208  // }
2209 
2210  // static Bool send(AppMsgRspUPtr &amrs)
2211  // {
2212  // return this_->sendMsg(new EThreadMessage(TRANSLATE_SEND_RESPONSE_EVENT, amrs.release()));
2213  // }
2214 
2215  static Void cleanup()
2216  {
2217  delete this_;
2218  this_ = NULL;
2219  }
2220 
2221  private:
2222  static TranslationThread *this_;
2223  TranslationThread();
2224  Translator &xlator_;
2225  };
2227 
2230 
2232  #define COMMUNICATION_BASE_EVENT (EM_USER + 30000)
2233 
2234  class CommunicationThread : public ESocket::ThreadPrivate
2235  {
2236  friend Void Uninitialize();
2237  friend TranslationThread;
2238  public:
2239  enum class Events : UInt
2240  {
2241  SndReq = (COMMUNICATION_BASE_EVENT + 1), // TranslationThread --> CommunicationThread - ReqOutPtr
2242  SndRsp = (COMMUNICATION_BASE_EVENT + 2), // TranslationThread --> CommunicationThread - RspOutPtr
2243  HeartbeatReq = (COMMUNICATION_BASE_EVENT + 3), // TranslationThread --> CommunicationThread - RcvdHeartbeatReqDataPtr
2244  HeartbeatRsp = (COMMUNICATION_BASE_EVENT + 4), // TranslationThread --> CommunicationThread - SndHeartbeatRspDataPtr
2245  SndHeartbeatReqError = (COMMUNICATION_BASE_EVENT + 5), // TranslationThread --> CommunicationThread - SndHeartbeatReqExceptionDataPtr - (Translator failure to create Heartbeat Req)
2246  SndHeartbeatRspError = (COMMUNICATION_BASE_EVENT + 6), // TranslationThread --> CommunicationThread - SndHeartbeatRspExceptionDataPtr - (Translator failure to create Heartbeat Rsp)
2247  RcvdReqError = (COMMUNICATION_BASE_EVENT + 7), // TranslationThread --> CommunicationThread - RcvdReqExceptionDataPtr - (Translator failure to parse req)
2248  RcvdRspError = (COMMUNICATION_BASE_EVENT + 8), // TranslationThread --> CommunicationThread - RcvdRspExceptionDataPtr - (Translator failure to parse response)
2249  ReqTimeout = (COMMUNICATION_BASE_EVENT + 9), // ETimerPool --> CommunicationThread - ReqOutPtr
2250  AddSession = (COMMUNICATION_BASE_EVENT + 10), // ApplicationThread --> CommunicationThread - *SessionBaseSPtr
2251  DelSession = (COMMUNICATION_BASE_EVENT + 11), // ApplicationThread --> CommunicationThread - *SessionBaseSPtr
2252  DelNxtRmtSession = (COMMUNICATION_BASE_EVENT + 12) // ApplicationThread/CommunicationThread --> CommunicationThread - *RemoteNodeSPtr
2253  };
2254 
2255  ~CommunicationThread();
2256 
2257  static CommunicationThread &Instance()
2258  {
2259  if (this_ == nullptr)
2260  this_ = new CommunicationThread();
2261  return *this_;
2262  }
2263 
2264  Void onInit();
2265  Void onQuit();
2266  Void onTimer(EThreadEventTimer *ptimer);
2267 
2268  Void errorHandler(EError &err, ESocket::BasePrivate *psocket);
2269 
2270  const ESocket::Address &address() { return address_; }
2271  CommunicationThread &setAddress(const ESocket::Address &address) { address_ = address; return *this; }
2272  ESocket::Address &setAddress() { return address_; }
2273 
2274  Bool addLocalNode(LocalNodeSPtr &ln)
2275  {
2276  EWRLock lck(lnslck_);
2277  return lns_.insert(std::make_pair(ln->ipAddress(), ln)).second;
2278  }
2279 
2280  Bool assignTeidRangeValue(RemoteNodeSPtr &rn)
2281  {
2282  return trm_.assign(rn);
2283  }
2284 
2285  Void releaseTeidRangeValue(RemoteNodeSPtr &rn)
2286  {
2287  trm_.release(rn);
2288  }
2289 
2290  Void startLocalNode(LocalNodeSPtr &ln);
2291  Void stopLocalNode(LocalNodeSPtr &ln);
2292  LocalNodeSPtr createLocalNode(ESocket::Address &addr, Bool start = True);
2293  LocalNodeSPtr registerLocalNode(ESocket::Address &addr);
2294 
2295  LocalNodeUMap &localNodes() { return lns_; }
2296 
2297  Void setNbrActivityWnds(size_t nbr);
2298  Void nextActivityWnd();
2299  size_t currentActivityWnd() const { return caw_; }
2300 
2301  Int currentRspWnd() const { return crw_; }
2302 
2304 
2305  protected:
2306  Void releaseLocalNodes();
2307 
2308  Void onSndReq(EThreadMessage &msg);
2309  Void onSndRsp(EThreadMessage &msg);
2310  Void onHeartbeatReq(EThreadMessage &msg);
2311  Void onHeartbeatRsp(EThreadMessage &msg);
2312  Void onSndHeartbeatReqError(EThreadMessage &msg);
2313  Void onSndHeartbeatRspError(EThreadMessage &msg);
2314  Void onRcvdReqError(EThreadMessage &msg);
2315  Void onRcvdRspError(EThreadMessage &msg);
2316  Void onReqTimeout(EThreadMessage &msg);
2317  Void onAddSession(EThreadMessage &msg);
2318  Void onDelSession(EThreadMessage &msg);
2319  Void onDelNxtRmtSession(EThreadMessage &msg);
2320 
2321  Void onHeartbeatReqTimtout(AppMsgReqPtr am);
2322 
2323  static Void cleanup()
2324  {
2325  delete this_;
2326  this_ = NULL;
2327  }
2328 
2329  private:
2330  static const Int rwOne_ = 1;
2331  static const Int rwTwo_ = 2;
2332  static const Int rwToggle_ = (rwOne_ ^ rwTwo_);
2333  static CommunicationThread *this_;
2334 
2335  CommunicationThread();
2336  Void addSession(SessionBaseSPtr &s);
2337  Void delSession(SessionBaseSPtr &s);
2338 
2339  ESocket::Address address_;
2340  TeidRangeManager trm_;
2341  ERWLock lnslck_;
2342  LocalNodeUMap lns_;
2343  EThreadEventTimer atmr_;
2344  EThreadEventTimer rsptmr_;
2345  size_t caw_;
2346  Int crw_;
2347  };
2349 
2352 
2354  inline SessionBase::~SessionBase()
2355  {
2356  static EString __method__ = __METHOD_NAME__;
2357  // Configuration::logger().debug(
2358  // "{} - destroying session localNode={} remoteNode={} localSeid={} remoteSeid={}",
2359  // __method__, localNode()->address().getAddress(),
2360  // remoteNode()->address().getAddress(), localSeid(), remoteSeid());
2361  ++deleted_;
2362  }
2363 
2364  inline SessionBase &SessionBase::setSeid(SessionBaseSPtr &s, Seid ls, Seid rs, Bool notify)
2365  {
2366  if (ls != 0)
2367  {
2368  if (ls_ != 0)
2369  throw SessionBase_LocalSeidAlreadySet();
2370  ls_ = ls;
2371  }
2372  if (rs != 0)
2373  {
2374  if (rs_ != 0)
2375  throw SessionBase_RemoteSeidAlreadySet();
2376  rs_ = rs;
2377  }
2378  if (notify)
2379  {
2380  auto s2 = new SessionBaseSPtr(s);
2381  SEND_TO_COMMUNICATION(AddSession, s2);
2382  }
2383  return *this;
2384  }
2385 
2386  inline Void SessionBase::destroy(SessionBaseSPtr &s)
2387  {
2388  auto s2 = new SessionBaseSPtr(s);
2389  SEND_TO_COMMUNICATION(DelSession, s2);
2390  }
2391 
2392  inline InternalMsg::InternalMsg(const LocalNodeSPtr &ln, const RemoteNodeSPtr &rn, const TranslatorMsgInfo &tmi, cpUChar data, UShort len)
2393  : ln_(ln),
2394  rn_(rn),
2395  seq_(tmi.seqNbr()),
2396  mt_(tmi.msgType()),
2397  mc_(tmi.msgClass()),
2398  rqst_(tmi.isReq()),
2399  ver_(tmi.version()),
2400  data_(nullptr),
2401  len_(0)
2402  {
2403  assign(data, len);
2404  }
2405 
2406  inline Void ReqOut::startT1()
2407  {
2408  stopT1();
2409  EThreadMessage *msg = new EThreadMessage(
2410  static_cast<UInt>(CommunicationThread::Events::ReqTimeout),
2411  static_cast<pVoid>(this));
2412  t1id_ = ETimerPool::Instance().registerTimer(t1(), msg, CommunicationThread::Instance());
2413  }
2414 
2415  inline Bool RemoteNode::setRcvdReqRspWnd(ULong sn)
2416  {
2417  return setRcvdReqRspWnd(sn, PFCP::CommunicationThread::Instance().currentRspWnd());
2418  }
2419 
2420  template<class TWorker>
2421  inline LocalNodeSPtr ApplicationWorkGroup<TWorker>::createLocalNode(ESocket::Address &addr, Bool start)
2422  {
2423  return CommunicationThread::Instance().createLocalNode(addr, start);
2424  }
2425 
2426  template<class TWorker>
2427  inline Void ApplicationWorkGroup<TWorker>::startLocalNode(LocalNodeSPtr &ln)
2428  {
2429  CommunicationThread::Instance().startLocalNode(ln);
2430  }
2431 
2432  template<class TWorker>
2433  inline Void ApplicationWorkGroup<TWorker>::stopLocalNode(LocalNodeSPtr &ln)
2434  {
2435  CommunicationThread::Instance().stopLocalNode(ln);
2436  }
2437 
2438  inline void* InternalMsg::operator new(size_t sz)
2439  {
2440  if (pool_.allocSize() == 0)
2441  {
2442  size_t as = 0;
2443  if (sizeof(RspOut) > as) as = sizeof(RspOut);
2444  if (sizeof(RspIn) > as) as = sizeof(RspIn);
2445  if (sizeof(ReqOut) > as) as = sizeof(ReqOut);
2446  if (sizeof(ReqIn) > as) as = sizeof(ReqIn);
2447 
2448  size_t ns = 32768 - sizeof(EMemory::Node);
2449  size_t bs = as + sizeof(EMemory::Block);
2450  bs += bs % sizeof(pVoid);
2451  size_t bc = ns / bs;
2452  ns = sizeof(EMemory::Node) + bc * bs;
2453  pool_.setSize(as, ns);
2454  }
2455  if (sz > pool_.allocSize())
2456  {
2457  EError ex;
2458  ex.setSevere();
2459  ex.setText("internal message allocation size is larger than memory pool block size");
2460  throw ex;
2461  }
2462  return pool_.allocate();
2463  }
2464 
2465  inline void InternalMsg::operator delete(void* m)
2466  {
2467  pool_.deallocate(m);
2468  }
2470 }
2471 
2473 namespace std
2474 {
2475 template <>
2476 struct hash<PFCP::RemoteNodeSPtr>
2477 {
2478  std::size_t operator()(const PFCP::RemoteNodeSPtr &rn) const noexcept
2479  {
2480  return std::hash<ESocket::Address>{}(rn->address());
2481  }
2482 };
2484 
2485 }
2486 
2487 #endif // #ifndef __EPFCP_H
LocalNodeStateChange - CommunicationThread –> ApplicationWorkGroup - *LocalNodeStateChangeEvent.
LocalNode::State oldState() const
Definition: epfcp.h:872
static LongLong setT1(LongLong t1)
Definition: epfcp.h:133
AppMsgSessionRsp()
Default construtor.
Definition: epfcp.h:1158
static Int setMaxApplicationWorkers(Int w)
Definition: epfcp.h:168
const EIpAddress & address() const
Retrieves the IP address object associated with the FqSeid.
Definition: epfcp.h:303
std::unordered_map< EIpAddress, LocalNodeSPtr > LocalNodeUMap
Definition: epfcp.h:857
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:1091
RemoteNode::State oldState() const
Definition: epfcp.h:706
Node & setAddress(const ESocket::Address &addr)
Assigns the ESocket::Address object representing the IP address for this node.
Definition: epfcp.h:550
static Int setHeartbeatN1(Int hbn1)
Definition: epfcp.h:142
virtual ~AppMsgNodeReq()
Class destructor.
Definition: epfcp.h:1015
#define True
True.
Definition: ebase.h:25
static Long setLenActivityWnd(Long law)
Definition: epfcp.h:150
AppMsgNodeRsp * AppMsgNodeRspPtr
Definition: epfcp.h:1148
static LongLong t1()
Definition: epfcp.h:132
AppMsgRsp()
Default construtor.
Definition: epfcp.h:1066
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:1967
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:967
static ETime Now()
Retrieves the current time.
Definition: etime.cpp:1147
EncodeRspError - TranslationThread –> ApplicationWorkGroup - EncodeRspExceptionDataPtr.
SndRspError - CommunicationThread –> ApplicationWorkGroup - SndRspExceptionDataPtr.
State
Definition: epfcp.h:627
SessionBase(LocalNodeSPtr &ln, RemoteNodeSPtr &rn)
Class constructor.
Definition: epfcp.h:413
static Int teidRangeBits()
Definition: epfcp.h:158
The PFCP Translator is used to encode and decode PFCP messages. This is a pure virtual base class tha...
Definition: epfcp.h:1800
std::pair< EIpAddress, LocalNodeSPtr > LocalNodeUMapEIpAddressPair
Definition: epfcp.h:858
std::shared_ptr< Node > NodeSPtr
Definition: epfcp.h:612
base class for EThreadPrivate and EThreadPublic
Definition: etevent.h:1062
const ETime & startTime() const
Returns the Node start time.
Definition: epfcp.h:559
RemoteNodeRestartEvent(RemoteNodeSPtr &rn, RemoteNode::State oldst, RemoteNode::State newst, const ETime &restartTime)
Definition: epfcp.h:719
static Long lenActivityWnd()
Definition: epfcp.h:149
static ULongLong nodesCreated()
Definition: epfcp.h:576
LocalNode::State newState() const
Definition: epfcp.h:873
PFCP stack namespace.
Definition: epfcp.h:35
virtual ~AppMsgRsp()
Class destructor.
Definition: epfcp.h:1080
static Void setApplication(ApplicationWorkGroup< TWorker > &app)
Definition: epfcp.h:177
static ApplicationWorkGroupBase & baseApplication()
Definition: epfcp.h:188
LocalNodeSPtr createLocalNode(const EIpAddress &ipaddr, UShort port=PFCP::Configuration::port(), Bool start=True)
Definition: epfcp.h:2037
AppMsgSessionRsp * AppMsgSessionRspPtr
Definition: epfcp.h:1185
AppMsgReq(LocalNodeSPtr &ln, RemoteNodeSPtr &rn, Bool allocSeqNbr)
Class constructor.
Definition: epfcp.h:978
Void setSevere()
Sets the severity level of this error object to "Error".
Definition: eerror.h:237
EncodeReqError - TranslationThread –> ApplicationWorkGroup - EncodeReqExceptionDataPtr.
AppMsgNodeRsp & setReq(AppMsgNodeReqPtr req)
Sets the request message that this response is associated with.
Definition: epfcp.h:1145
MsgClass msgClass() const
Returns the message class for this message (Node or Session).
Definition: epfcp.h:901
const ETime & restartTime() const
Definition: epfcp.h:731
static Int minApplicationWorkers()
Definition: epfcp.h:164
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:223
static size_t setNnbrActivityWnds(size_t naw)
Definition: epfcp.h:147
static Int setTeidRangeBits(Int trb)
Definition: epfcp.h:159
static Long maxRspWait()
Definition: epfcp.h:144
STL namespace.
Definition: epfcp.h:695
static MsgType pfcpHeartbeatReq
Definition: epfcp.h:179
Definition: ememory.h:72
AppMsgRsp(AppMsgReqPtr amrq)
Class constructor.
Definition: epfcp.h:1074
LocalNodeSPtr createLocalNode(cpStr ipaddr, UShort port=PFCP::Configuration::port(), Bool start=True)
Creates a local node.
Definition: epfcp.h:2032
static Bool assignTeidRange()
Definition: epfcp.h:155
AppMsgReqPtr req()
Returns a shared pointer to the request application message.
Definition: epfcp.h:1088
Definition: ememory.h:34
Contains the base functionality for all aplication messages.
Definition: epfcp.h:885
static Int setMinApplicationWorkers(Int w)
Definition: epfcp.h:165
Definition: epfcp.h:716
State state()
Gets the state of the local node.
Definition: epfcp.h:764
EIpAddress & setAddress()
Returns a modifiable reference to the IP address.
Definition: epfcp.h:306
AppMsg & setMsgClass(const MsgClass mc)
Definition: epfcp.h:938
SessionBaseSPtr getSession(Seid seid)
Returns the session object for the specified SEID.
Definition: epfcp.h:568
RemoteNodeStateChangeEvent(RemoteNodeSPtr &rn, RemoteNode::State oldst, RemoteNode::State newst)
Definition: epfcp.h:698
static Int setMinTranslatorWorkers(Int w)
Definition: epfcp.h:171
const Seid seid() const
Returns the SEID.
Definition: epfcp.h:310
static ULongLong sessionsDeleted()
Definition: epfcp.h:466
Seid alloc()
Assigns the next available SEID. This operation is thread safe.
Definition: epfcp.h:252
LocalNodeStateChangeEvent(LocalNodeSPtr &ln, LocalNode::State oldst, LocalNode::State newst)
Definition: epfcp.h:864
RcvdReq - TranslationThread –> ApplicationWorkGroup - AppMsgReqPtr.
static _EThreadEventNotification & threadApplication()
Definition: epfcp.h:187
RemoteNode::State oldState() const
Definition: epfcp.h:729
AppMsg(const AppMsg &dm)
Definition: epfcp.h:929
static Int socketBufferSize()
Definition: epfcp.h:129
virtual const EString & className()
Returns the class name for this object.
Definition: epfcp.h:911
Int teidRangeValue() const
Returns the currently configured TEID range value.
Definition: epfcp.h:636
SessionBase & setLocalSeid(SessionBaseSPtr &s, Seid ls)
Sets the local SEID for this session.
Definition: epfcp.h:456
Encapsulates the UDP Socket functionality used to communicate with a PFCP peer.
Definition: epfcp.h:362
SeidManager()
Default constructor.
Definition: epfcp.h:250
Contains the basic Node functionality common to both a LocalNode and a RemoteNode.
Definition: epfcp.h:525
The application worker thread class. The various virtual methods should be overridden to implement ap...
Definition: epfcp.h:2073
static ETimerPool & Instance()
Retrieves the single instance of the ETimerPool object.
Definition: etimerpool.h:70
Represents a request application message.
Definition: epfcp.h:954
static ELogger & setLogger(ELogger &log)
Definition: epfcp.h:153
Represents a response application message.
Definition: epfcp.h:1154
#define False
False.
Definition: ebase.h:27
RemoteNodeSPtr & remoteNode()
Returns a reference to the remote node object for this message.
Definition: epfcp.h:1094
Void free(ULong sn)
Releases a previously allocated sequence number.
Definition: epfcp.h:231
Definition: epfcp.h:2002
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:539
RcvdRsp - TranslationThread –> ApplicationWorkGroup - AppMsgRspPtr.
static ULongLong sessionsCreated()
Definition: epfcp.h:465
FqSeid()
Default constructor.
Definition: epfcp.h:279
RemoteNodeStateChange - CommunicationThread –> ApplicationWorkGroup - *RemoteNodeStateChangeEvent.
AppMsgSessionReq * AppMsgSessionReqPtr
Definition: epfcp.h:1056
static Int maxApplicationWorkers()
Definition: epfcp.h:167
SequenceManager()
Default constructor.
Definition: epfcp.h:220
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:246
Represents a worker thread that is part of a work group.
Definition: etevent.h:1444
AppMsgRsp * AppMsgRspPtr
Definition: epfcp.h:1109
AppMsgReq()
Default constructor.
Definition: epfcp.h:971
static Translator & setTranslator(Translator &xlator)
Definition: epfcp.h:162
static Int heartbeatN1()
Definition: epfcp.h:141
std::pair< EIpAddress, RemoteNodeSPtr > RemoteNodeUMapPair
Definition: epfcp.h:693
The PFCP application work group template. This template contains the common event queue for the appli...
Definition: epfcp.h:2023
Defines the EIpAddress and EIpFilterRule classes.
AppMsgNodeReq()
Default constructor.
Definition: epfcp.h:1002
virtual ~AppMsgReq()
Class destructor.
Definition: epfcp.h:958
static UShort setPort(UShort port)
Definition: epfcp.h:127
static MsgType pfcpAssociationSetupRsp
Definition: epfcp.h:184
AppMsgNodeRsp(AppMsgNodeReqPtr &amrq)
Class constructor.
Definition: epfcp.h:1128
virtual ~Node()
Class destructor.
Definition: epfcp.h:531
static Int minTranslatorWorkers()
Definition: epfcp.h:170
ULong seqNbr() const
Returns the sequence number associated wtih this message.
Definition: epfcp.h:895
Thread timer class.
Definition: etevent.h:828
SndReqError - CommunicationThread –> ApplicationWorkGroup - SndReqExceptionDataPtr.
virtual ~AppMsgSessionReq()
Class destructor.
Definition: epfcp.h:1044
AppMsgNodeRsp()
Default construtor.
Definition: epfcp.h:1119
AppMsg()
Definition: epfcp.h:922
AppMsg * AppMsgPtr
Definition: epfcp.h:948
AppMsgRsp & setReq(AppMsgReq *req)
Sets the request message that this response is associated with.
Definition: epfcp.h:1098
std::shared_ptr< SessionBase > SessionBaseSPtr
Definition: epfcp.h:401
std::unordered_map< Seid, SessionBaseSPtr > SessionBaseSPtrUMap
Definition: epfcp.h:518
A UDP socket class capabile of sending and receiving data.
Definition: esocket.h:1204
Void Uninitialize()
Uninitializes/stops the PFCP stack.
Definition: epfcp.cpp:145
static LongLong heartbeatT1()
Definition: epfcp.h:135
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:1656
FqSeid & setSeid(Seid seid)
Assigns the SEID value.
Definition: epfcp.h:314
Represents the local PFCP node.
Definition: epfcp.h:750
AppMsg & setSeqNbr(const ULong sn)
Assigns the sequence number for this message.
Definition: epfcp.h:907
#define END_MESSAGE_MAP2()
Ends the message map declaration.
Definition: etevent.h:1433
AppMsgNodeReq * AppMsgNodeReqPtr
Definition: epfcp.h:1020
static Translator & translator()
Definition: epfcp.h:161
LocalNodeSPtr & localNode()
Definition: epfcp.h:871
Void startLocalNode(LocalNodeSPtr &ln)
Startes an externally constructed local node.
AppMsg & setMsgType(const MsgType mt)
Definition: epfcp.h:937
DecodeRspError - TranslationThread –> ApplicationWorkGroup - EncodeRspExceptionDataPtr.
EIpAddress & ipAddress()
Returns the IP address associated with this node.
Definition: epfcp.h:535
LocalNodeSPtr & localNode()
Returns a reference to the local node object for this message.
Definition: epfcp.h:964
Bool isReq() const
Returns True if this message is a request message, otherwise False.
Definition: epfcp.h:903
AppMsgSessionReq()
Default constructor.
Definition: epfcp.h:1030
The base class for exceptions derived from std::exception.
Definition: eerror.h:94
static MsgType pfcpAssociationSetupReq
Definition: epfcp.h:183
Definition: ememory.h:92
Represents an IP address with mask.
Definition: eip.h:40
static MsgType pfcpHeartbeatRsp
Definition: epfcp.h:180
std::pair< ULong, LocalNodeSPtr > LocalNodeUMapULongPair
Definition: epfcp.h:859
State state() const
Returns the current state of the local node.
Definition: epfcp.h:660
RemoteNodeSPtr createRemoteNode(cpStr addr, UShort port)
Creates a remote Node that this local node will "talk" to.
Definition: epfcp.h:786
MsgType msgType() const
Returns the message type for this message.
Definition: epfcp.h:898
Represents a remote or peer PFCP node or host.
Definition: epfcp.h:622
std::unordered_map< EIpAddress, RemoteNodeSPtr > RemoteNodeUMap
Definition: epfcp.h:692
Represents a PFCP session. It is expected that a developer utilizing this library will derive their o...
Definition: epfcp.h:407
Represents a response application message.
Definition: epfcp.h:1115
static Bool setAssignTeidRange(Bool atr)
Definition: epfcp.h:156
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:439
virtual ~AppMsgSessionRsp()
Class destructor.
Definition: epfcp.h:1172
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:136
AppMsgReq * AppMsgReqPtr
Definition: epfcp.h:991
virtual ~SessionBase()
Class destructor.
virtual Void destroy(SessionBaseSPtr &s)
Starts the destruction process for the session.
static Int setN1(Int n1)
Definition: epfcp.h:139
LocalNodeSPtr & localNode()
Returns the LocalNode object associated with this session.
Definition: epfcp.h:436
ETimerPool & unregisterTimer(ULong timerid)
Unregisters an expiration timer.
Definition: etimerpool.cpp:143
static size_t nbrActivityWnds()
Definition: epfcp.h:146
AppMsgSessionReq(SessionBaseSPtr &ses, Bool allocSeqNbr)
Class constructor.
Definition: epfcp.h:1037
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:577
Represents a Fully Qualified SEID. This combines an IP address with a SEID.
Definition: epfcp.h:275
virtual ~AppMsgNodeRsp()
Class destructor.
Definition: epfcp.h:1135
The base socket class.
Definition: esocket.h:441
FqSeid(const FqSeid &fqseid)
Copy constructor.
Definition: epfcp.h:286
static ELogger & logger()
Definition: epfcp.h:152
SessionBase & setRemoteSeid(SessionBaseSPtr &s, Seid rs)
Sets the remote SEID for this session.
Definition: epfcp.h:461
AppMsgNodeReqPtr req()
Returns a shared pointer to the request application message.
Definition: epfcp.h:1141
Represents a request application node message (not associated with a session).
Definition: epfcp.h:998
AppMsg & setIsReq(const Bool rqst)
Definition: epfcp.h:939
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:216
Definition: epfcp.h:861
static UShort port()
Definition: epfcp.h:126
Contains all of the configuration values used in the PFCP stack.
Definition: epfcp.h:119
State
Definition: epfcp.h:755
NodeSocket & socket()
Returns a reference to the underlying socket object for this local host.
Definition: epfcp.h:806
State state() const
Returns the current state of the local node.
Definition: epfcp.h:810
RemoteNodeRestart - CommunicationThread –> ApplicationWorkGroup - *RemoteNodeRestartEvent.
RemoteNode & setTeidRangeValue(Int trv)
Sets the TEID range value.
Definition: epfcp.h:640
Definition: esocket.h:2205
const Seid remoteSeid() const
Returns the remote SEID associated with this session.
Definition: epfcp.h:445
NodeSocket & clearLocalNode()
Clears the assigned LocalNode.
Definition: epfcp.h:377
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:707
RemoteNode::State newState() const
Definition: epfcp.h:730
AppMsgSessionReqPtr req()
Returns a shared pointer to the request application message.
Definition: epfcp.h:1178
const Seid localSeid() const
Returns the SEID associated with this session.
Definition: epfcp.h:442
AppMsgSessionRsp(AppMsgSessionReqPtr &amrq)
Class constructor.
Definition: epfcp.h:1166
virtual ~AppMsg()
Class destructor.
Definition: epfcp.h:889
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:529
ESocket::Address & address()
Returns the ESocket::Address object representing the IP address for this node.
Definition: epfcp.h:545
RemoteNodeSPtr & remoteNode()
Definition: epfcp.h:705
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:174
NodeSocket & setLocalNode(LocalNodeSPtr &ln)
Assigns the LocalNode that this socket is associated with.
Definition: epfcp.h:374
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:423
#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:563
SessionBaseSPtr & session()
Returs a reference to the session shaerd pointer.
Definition: epfcp.h:1050
Void Initialize()
Initializes/starts the PFCP stack. This should be called after setting the initial configuration valu...
Definition: epfcp.cpp:120
static Int n1()
Definition: epfcp.h:138
Represents a response application message.
Definition: epfcp.h:1062
RemoteNodeSPtr & remoteNode()
Definition: epfcp.h:728
static MsgType pfcpSessionEstablishmentReq
Definition: epfcp.h:181
Represents a request application session message.
Definition: epfcp.h:1026
AppMsgSessionRsp & setReq(AppMsgSessionReqPtr req)
Sets the request message that this response is associated with.
Definition: epfcp.h:1182
FqSeid & operator=(const FqSeid &fqseid)
Assignment operator.
Definition: epfcp.h:294
Address & setAddress(cpStr addr, UShort port)
Assigns the socket address.
Definition: esocket.h:307
static Int setSocketBufferSize(Int sz)
Definition: epfcp.h:130
static Int maxTranslatorWorkers()
Definition: epfcp.h:173
static MsgType pfcpSessionEstablishmentRsp
Definition: epfcp.h:182
AppMsgNodeReq(LocalNodeSPtr &ln, RemoteNodeSPtr &rn, Bool allocSeqNbr)
Class constructor.
Definition: epfcp.h:1009
Void free(Seid seid)
Releases a previously allocated SEID.
Definition: epfcp.h:261