/******************************************************************************* * Boap.h Boap RPC protocol * T.Barnaby, BEAM Ltd, 8/5/03 * Copyright (c) 2012 All Right Reserved, Beam Ltd, http://www.beam.ltd.uk ******************************************************************************* */ #ifndef Boap_HH #define Boap_HH #include <stdint.h> #include <BTypes.h> #include <BPoll.h> #include <BSocket.h> #include <BThread.h> #include <BError.h> #include <BEvent1.h> #include <BMutex.h> #include <BTimeStamp.h> #include <BBuffer.h> // Main BOAP Types const BUInt32 BoapMagic = 0x424F4100; enum BoapType { BoapTypeRpc, BoapTypeRpcReply, BoapTypeSignal, BoapTypeRpcError }; typedef BUInt32 BoapService; enum BoapPriority { BoapPriorityLow, BoapPriorityNormal, BoapPriorityHigh }; // Boap packet header struct BoapPacketHead { BUInt32 type; BUInt32 length; BUInt32 service; BUInt32 cmd; }; // Boap packet class BoapPacket : public BBufferStore { public: BoapPacket(); ~BoapPacket(); BUInt32 getCmd(); int peekHead(BoapPacketHead& head); int pushHead(BoapPacketHead& head); int popHead(BoapPacketHead& head); void updateHead(); }; /******************************************************************************* * Main Client communications classes ******************************************************************************* */ /******************************************************************************* * Base for all Client Objects ******************************************************************************* */ class BoapClientObject : public BSocket { public: BoapClientObject(BString name = ""); virtual ~BoapClientObject(); BError connectService(BString name); ///< Connects to the named service BError disconnectService(); ///< Disconnects from the named service BString getServiceName(); ///< Get the name of the service BError ping(BUInt32& apiVersion); ///< Pings the connection and finds the remotes version number BError setConnectionPriority(BoapPriority priority); ///< Sets the connection priority void setMaxLength(BUInt32 maxLength); ///< Sets the maximum packet length void setTimeout(int timeout); ///< Sets the timeout in micro seconds. -1 is wait indefinitely protected: BError pingLocked(BUInt32& apiVersion); BError checkApiVersion(); BError performCall(BoapPacket& tx, BoapPacket& rx); ///< Performs a RPC call to the named service BError performSend(BoapPacket& tx); ///< Performs a send to the named service BError performRecv(BoapPacket& rx); ///< Performs a receive virtual BError handleReconnect(BError err); ///< Handle a reconnect performing autorisaztion if required BString oname; BUInt32 oapiVersion; BoapPriority opriority; BoapService oservice; int oconnected; BUInt32 omaxLength; BoapPacket otx; BoapPacket orx; BMutex olock; int otimeout; int oreconnect; ///< Handle an automatic reconnect on timeout }; class BoapSignalObject : public BSocket { public: BoapSignalObject(); protected: BError performSend(BoapPacket& tx); // Performs a send to the named service BoapPacket otx; BoapPacket orx; }; /******************************************************************************* * Main Server communications class ******************************************************************************* */ class BoapServiceObject; class BoapServiceEntry { public: BoapServiceEntry(BoapService service = 0, BoapServiceObject* object = 0){ oservice = service; oobject = object; } BoapService oservice; BoapServiceObject* oobject; }; class BoapServer; class BoapServerConnection : public BThread { public: BoapServerConnection(BoapServer& boapServer, int fd); virtual ~BoapServerConnection(); virtual BError init(); ///< Initialise connection virtual BError process(); virtual BSocket& getSocket(); virtual void setMaxLength(BUInt32 maxLength); virtual BError getHead(BoapPacketHead& head); virtual BError validate(); ///< Validate the connection private: void* function(); BoapServer& oboapServer; BSocket osocket; BoapPacket orx; BoapPacket otx; BUInt32 omaxLength; }; namespace Boapns { class Boapns; } class BoapServer : public BThread { public: enum { NOTHREADS=0, THREADED=1 }; BoapServer(); virtual ~BoapServer(); virtual BError init(BString boapNsHost = "", int port = 0, int threaded = 0, int isBoapns = 0); virtual BError run(int inThread = 0); virtual BError process(BoapServerConnection* conn, BoapPacket& rx, BoapPacket& tx); virtual BError processEvent(BoapPacket& rx); // Support routines virtual BError addObject(BoapServiceObject* object); virtual BError sendEvent(BoapPacket& tx); virtual BError processEvent(int fd); virtual void clientGone(BoapServerConnection* client); BSocket& getSocket(); BSocket& getEventSocket(); BString getHostName(); int getConnectionsNumber(); // Override functions virtual BoapServerConnection* newConnection(int fd, BSocketAddressINET address); private: void* function(); int othreaded; int oisBoapns; Boapns::Boapns* oboapns; BList<BoapServerConnection*> oclients; BEvent1Int oclientGoneEvent; BList<BoapServiceEntry> oservices; BPoll opoll; BSocket onet; BSocket onetEvent; BSocketAddressINET onetEventAddress; BString ohostName; public: BUInt64 onumOperations; }; /******************************************************************************* * Base for all Server Objects ******************************************************************************* */ class BoapServiceObject; typedef BError (BoapServiceObject::*BoapFunc)(BoapServerConnection* conn, BoapPacket& rx, BoapPacket& tx); class BoapFuncEntry { public: BoapFuncEntry(int cmd, BoapFunc func); BUInt32 ocmd; BoapFunc ofunc; }; class BoapServiceObject { public: BoapServiceObject(BoapServer& server, BString name = ""); virtual ~BoapServiceObject(); BError setName(BString name); BError sendEvent(BString signalName, BInt32 arg); virtual BError processEvent(BString objectName, BString name, BInt32 arg); BString name(); BError doPing(BoapServerConnection* conn, BoapPacket& rx, BoapPacket& tx); BError doConnectionPriority(BoapServerConnection* conn, BoapPacket& rx, BoapPacket& tx); BError process(BoapServerConnection* conn, BoapPacket& rx, BoapPacket& tx); virtual BError processEvent(BoapPacket& rx); protected: BError sendEvent(BoapPacket& tx); BoapServer& oserver; BString oname; BUInt32 oapiVersion; BList<BoapFuncEntry> ofuncList; }; #endif