/*******************************************************************************
* Boap.h Boap RPC protocol
* T.Barnaby, BEAM Ltd, 8/5/03
*******************************************************************************
*/
#ifndef Boap_HH
#define Boap_HH
#include <stdint.h>
#include <BPoll.h>
#include <BSocket.h>
#include <BThread.h>
#include <BError.h>
#include <BEvent.h>
#include <BMutex.h>
#include <BTypes.h>
// Main BOAP Types
const UInt32 BoapMagic = 0x424F4100;
enum BoapType { BoapTypeRpc, BoapTypeRpcReply, BoapTypeSignal };
typedef UInt32 BoapService;
enum BoapPriority { BoapPriorityLow, BoapPriorityNormal, BoapPriorityHigh };
// Boap packet header
struct BoapPacketHead {
UInt32 type;
UInt32 length;
UInt32 service;
UInt32 cmd;
};
// Boap packet
class BoapPacket {
public:
BoapPacket();
~BoapPacket();
int resize(int size);
BError setData(void* data, int nbytes);
int nbytes();
char* data();
int peekHead(BoapPacketHead& head);
UInt32 getCmd();
int pushHead(BoapPacketHead& head);
int push(Int8 v);
int push(UInt8 v);
int push(Int16 v);
int push(UInt16 v);
int push(Int32 v);
int push(UInt32 v);
int push(Int64 v);
int push(UInt64 v);
int push(const BString& v);
int push(Double v);
int push(const BError& v);
int push(UInt32 nBytes, const void* data, char* swapType = "1");
int popHead(BoapPacketHead& head);
int pop(Int8& v);
int pop(UInt8& v);
int pop(Int16& v);
int pop(UInt16& v);
int pop(Int32& v);
int pop(UInt32& v);
int pop(Int64& v);
int pop(UInt64& v);
int pop(BString& v);
int pop(Double& v);
int pop(BError& v);
int pop(UInt32 nBytes, void* data, char* swapType = "1");
private:
void copyWithSwap(void* dst, const void* src, UInt32 nBytes, char* swapType);
void updateLen();
int osize;
int onbytes;
char* odata;
int opos;
};
/*******************************************************************************
* Main Client communications classes
*******************************************************************************
*/
/*******************************************************************************
* Base for all Client Objects
*******************************************************************************
*/
class BoapClientObject : public BSocket {
public:
BoapClientObject(BString name = "");
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
BString oname;
BUInt32 oapiVersion;
BoapPriority opriority;
BoapService oservice;
int oconnected;
BUInt32 omaxLength;
BoapPacket otx;
BoapPacket orx;
BMutex olock;
int otimeout;
int oreconnect;
};
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);
BError process();
BSocket& getSocket();
void setMaxLength(BUInt32 maxLength);
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();
~BoapServer();
BError init(BString boapNsHost = "", int threaded = 0, int isBoapns = 0);
BError run(int inThread = 0);
BError processEvent(BoapPacket& rx);
// Support routines
BError addObject(BoapServiceObject* object);
BError process(BoapServerConnection* conn, BoapPacket& rx, BoapPacket& tx);
BError sendEvent(BoapPacket& tx);
BSocket& getSocket();
BSocket& getEventSocket();
BError processEvent(int fd);
BString getHostName();
void clientGone(BoapServerConnection* client);
int getConnectionsNumber();
private:
void* function();
int othreaded;
int oisBoapns;
Boapns::Boapns* oboapns;
BList<BoapServerConnection*> oclients;
BEventInt oclientGoneEvent;
BList<BoapServiceEntry> oservices;
BPoll opoll;
BSocket onet;
BSocket onetEvent;
BSocketAddressINET onetEventAddress;
BString ohostName;
};
/*******************************************************************************
* 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);
UInt32 ocmd;
BoapFunc ofunc;
};
class BoapServiceObject {
public:
BoapServiceObject(BoapServer& server, BString name = "");
virtual ~BoapServiceObject();
BError setName(BString name);
BError sendEvent(BString signalName, Int32 arg);
virtual BError processEvent(BString objectName, BString name, Int32 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