diff --git a/src/pvaproto.h b/src/pvaproto.h index c509450..a096c80 100644 --- a/src/pvaproto.h +++ b/src/pvaproto.h @@ -24,6 +24,8 @@ namespace pvxs {namespace impl { +constexpr bool hostBE{EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG}; + //! view of a slice of a buffer. //! Don't use directly. cf. FixedBuf struct PVXS_API Buffer { @@ -194,7 +196,7 @@ inline void to_wire(Buffer& buf, const T& val) uint8_t b[sizeof(T)]; } pun; pun.v = val; - _to_wire(buf, pun.b, buf.be ^ (EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG)); + _to_wire(buf, pun.b, buf.be ^ hostBE); } template{}, int>::type =0> @@ -220,7 +222,7 @@ inline void from_wire(Buffer& buf, T& val) T v; uint8_t b[sizeof(T)]; } pun; - _from_wire(buf, pun.b, buf.be ^ (EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG)); + _from_wire(buf, pun.b, buf.be ^ hostBE); if(buf.good()) val = pun.v; } diff --git a/src/serverchan.cpp b/src/serverchan.cpp index 0f72692..9a14380 100644 --- a/src/serverchan.cpp +++ b/src/serverchan.cpp @@ -71,8 +71,7 @@ void ServerChannelControl::close() // Send unsolicited Channel Destroy auto tx = bufferevent_get_output(conn->bev.get()); - constexpr bool be = EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG; - EvOutBuf R(be, tx); + EvOutBuf R(hostBE, tx); to_wire(R, Header{CMD_DESTROY_CHANNEL, pva_flags::Server, 8}); to_wire(R, ch->sid); to_wire(R, ch->cid); @@ -84,7 +83,6 @@ void ServerChannelControl::close() void ServerConn::handle_SEARCH() { - const bool be = EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG; EvInBuf M(peerBE, segBuf.get(), 16); uint32_t searchID=0; @@ -145,7 +143,7 @@ void ServerConn::handle_SEARCH() { (void)evbuffer_drain(txBody.get(), evbuffer_get_length(txBody.get())); - EvOutBuf R(be, txBody.get()); + EvOutBuf R(hostBE, txBody.get()); to_wire(M, searchID); to_wire(M, iface->bind_addr); @@ -161,18 +159,11 @@ void ServerConn::handle_SEARCH() } } - auto tx = bufferevent_get_output(bev.get()); - to_evbuf(tx, Header{CMD_SEARCH_RESPONSE, - pva_flags::Server, - uint32_t(evbuffer_get_length(txBody.get()))}, - be); - auto err = evbuffer_add_buffer(tx, txBody.get()); - assert(!err); + enqueueTxBody(CMD_SEARCH_RESPONSE); } void ServerConn::handle_CREATE_CHANNEL() { - const bool be = EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG; const auto self = shared_from_this(); EvInBuf M(peerBE, segBuf.get(), 16); @@ -252,7 +243,7 @@ void ServerConn::handle_CREATE_CHANNEL() { (void)evbuffer_drain(txBody.get(), evbuffer_get_length(txBody.get())); - EvOutBuf R(be, txBody.get()); + EvOutBuf R(hostBE, txBody.get()); to_wire(R, cid); to_wire(R, sid); to_wire(R, sts); @@ -264,13 +255,7 @@ void ServerConn::handle_CREATE_CHANNEL() } } - auto tx = bufferevent_get_output(bev.get()); - to_evbuf(tx, Header{CMD_CREATE_CHANNEL, - pva_flags::Server, - uint32_t(evbuffer_get_length(txBody.get()))}, - be); - auto err = evbuffer_add_buffer(tx, txBody.get()); - assert(!err); + enqueueTxBody(CMD_CREATE_CHANNEL); } if(!M.good()) { @@ -324,8 +309,7 @@ void ServerConn::handle_DESTROY_CHANNEL() { auto tx = bufferevent_get_output(bev.get()); - constexpr bool be = EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG; - EvOutBuf R(be, tx); + EvOutBuf R(hostBE, tx); to_wire(R, Header{CMD_DESTROY_CHANNEL, pva_flags::Server, 8}); to_wire(R, sid); to_wire(R, cid); diff --git a/src/serverconn.cpp b/src/serverconn.cpp index 8647f0a..3f34bd7 100644 --- a/src/serverconn.cpp +++ b/src/serverconn.cpp @@ -53,14 +53,13 @@ ServerConn::ServerConn(ServIface* iface, evutil_socket_t sock, struct sockaddr * auto tx = bufferevent_get_output(bev.get()); std::vector buf(128); - const bool be = EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG; // queue connection validation message { - uint8_t flags = be ? pva_flags::MSB : 0; + uint8_t flags = hostBE ? pva_flags::MSB : 0; flags |= pva_flags::Server; - VectorOutBuf M(be, buf); + VectorOutBuf M(hostBE, buf); to_wire(M, Header{pva_ctrl_msg::SetEndian, pva_flags::Control|pva_flags::Server, 0}); auto save = M.save(); @@ -76,7 +75,7 @@ ServerConn::ServerConn(ServIface* iface, evutil_socket_t sock, struct sockaddr * to_wire(M, "ca"); auto bend = M.save(); - FixedBuf H(be, save, 8); + FixedBuf H(hostBE, save, 8); to_wire(H, Header{CMD_CONNECTION_VALIDATION, pva_flags::Server, uint32_t(bend-bstart)}); assert(M.good() && H.good()); @@ -100,6 +99,17 @@ const std::shared_ptr& ServerConn::lookupSID(uint32_t sid) return it->second; } +void ServerConn::enqueueTxBody(pva_app_msg_t cmd) +{ + auto tx = bufferevent_get_output(bev.get()); + to_evbuf(tx, Header{cmd, + pva_flags::Server, + uint32_t(evbuffer_get_length(txBody.get()))}, + hostBE); + auto err = evbuffer_add_buffer(tx, txBody.get()); + assert(!err); +} + void ServerConn::handle_ECHO() { // Client requests echo as a keep-alive check @@ -107,8 +117,7 @@ void ServerConn::handle_ECHO() auto tx = bufferevent_get_output(bev.get()); uint32_t len = evbuffer_get_length(segBuf.get()); - const bool be = EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG; - to_evbuf(tx, Header{CMD_ECHO, pva_flags::Server, len}, be); + to_evbuf(tx, Header{CMD_ECHO, pva_flags::Server, len}, hostBE); auto err = evbuffer_add_buffer(tx, segBuf.get()); assert(!err); @@ -120,21 +129,14 @@ void ServerConn::handle_ECHO() static void auth_complete(ServerConn *self, const Status& sts) { - const bool be = EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG; (void)evbuffer_drain(self->txBody.get(), evbuffer_get_length(self->txBody.get())); { - EvOutBuf M(be, self->txBody.get()); + EvOutBuf M(hostBE, self->txBody.get()); to_wire(M, sts); } - auto tx = bufferevent_get_output(self->bev.get()); - to_evbuf(tx, Header{CMD_CONNECTION_VALIDATED, - pva_flags::Server, - uint32_t(evbuffer_get_length(self->txBody.get()))}, - be); - auto err = evbuffer_add_buffer(tx, self->txBody.get()); - assert(!err); + self->enqueueTxBody(CMD_CONNECTION_VALIDATED); log_printf(connsetup, PLVL_DEBUG, "%s Auth complete with %d\n", self->peerName.c_str(), sts.code); } diff --git a/src/serverconn.h b/src/serverconn.h index 6965338..ad459fb 100644 --- a/src/serverconn.h +++ b/src/serverconn.h @@ -26,6 +26,7 @@ struct ServerConn; struct ServerChan; struct ServerChan; +// base for tracking in-progress operations. cf. ServerConn::opByIOID and ServerChan::opByIOID struct ServerOp { const std::weak_ptr chan; @@ -109,6 +110,8 @@ struct ServerConn : public std::enable_shared_from_this const std::shared_ptr& lookupSID(uint32_t sid); + void enqueueTxBody(pva_app_msg_t cmd); + private: #define CASE(Op) void handle_##Op(); CASE(ECHO); diff --git a/src/serverget.cpp b/src/serverget.cpp index 05271ae..c654d4d 100644 --- a/src/serverget.cpp +++ b/src/serverget.cpp @@ -82,8 +82,6 @@ struct ServerGetControl : public server::Get if(!conn || !conn->bev) return; - const bool be = EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG; - Status sts{}; uint8_t cmd = oper->state==ServerOp::Creating ? 0x08 : oper->lastRequest ? 0x50 : 0x40; @@ -123,7 +121,7 @@ struct ServerGetControl : public server::Get { (void)evbuffer_drain(conn->txBody.get(), evbuffer_get_length(conn->txBody.get())); - EvOutBuf R(be, conn->txBody.get()); + EvOutBuf R(hostBE, conn->txBody.get()); to_wire(R, uint32_t(oper->ioid)); to_wire(R, cmd); to_wire(R, sts); @@ -141,13 +139,7 @@ struct ServerGetControl : public server::Get } } - auto tx = bufferevent_get_output(conn->bev.get()); - to_evbuf(tx, Header{CMD_GET, - pva_flags::Server, - uint32_t(evbuffer_get_length(conn->txBody.get()))}, - be); - auto err = evbuffer_add_buffer(tx, conn->txBody.get()); - assert(!err); + conn->enqueueTxBody(CMD_GET); if(oper->state == ServerOp::Dead) { conn->opByIOID.erase(oper->ioid); diff --git a/src/serverintrospect.cpp b/src/serverintrospect.cpp index e514c06..14ef199 100644 --- a/src/serverintrospect.cpp +++ b/src/serverintrospect.cpp @@ -68,24 +68,17 @@ struct ServerIntrospectControl : public server::Introspect if(!conn || !conn->bev) return; - const bool be = EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG; { (void)evbuffer_drain(conn->txBody.get(), evbuffer_get_length(conn->txBody.get())); - EvOutBuf R(be, conn->txBody.get()); + EvOutBuf R(hostBE, conn->txBody.get()); to_wire(R, uint32_t(oper->ioid)); to_wire(R, sts); if(type) to_wire(R, type); } - auto tx = bufferevent_get_output(conn->bev.get()); - to_evbuf(tx, Header{CMD_GET_FIELD, - pva_flags::Server, - uint32_t(evbuffer_get_length(conn->txBody.get()))}, - be); - auto err = evbuffer_add_buffer(tx, conn->txBody.get()); - assert(!err); + conn->enqueueTxBody(CMD_GET_FIELD); oper->state = ServerOp::Dead; conn->opByIOID.erase(oper->ioid);