From 24d8cb96a3f8c813744dc2760a6021829a0b58a3 Mon Sep 17 00:00:00 2001 From: Matej Sekoranja Date: Sun, 18 Sep 2011 20:45:18 +0200 Subject: [PATCH] adaptive byte-order --- .../remote/blockingServerTCPTransport.cpp | 13 ++++++++ pvAccessApp/remote/blockingTCPTransport.cpp | 33 ++++++++++++++----- pvAccessApp/remote/blockingUDPTransport.cpp | 17 +++++++--- pvAccessApp/remote/channelSearchManager.cpp | 4 +-- 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/pvAccessApp/remote/blockingServerTCPTransport.cpp b/pvAccessApp/remote/blockingServerTCPTransport.cpp index a1a0fd7..b2ce4bc 100644 --- a/pvAccessApp/remote/blockingServerTCPTransport.cpp +++ b/pvAccessApp/remote/blockingServerTCPTransport.cpp @@ -109,6 +109,19 @@ namespace epics { void BlockingServerTCPTransport::send(ByteBuffer* buffer, TransportSendControl* control) { + + // + // set byte order control message + // + + control->ensureBuffer(CA_MESSAGE_HEADER_SIZE); + buffer->putByte(CA_MAGIC); + buffer->putByte(CA_VERSION); + buffer->putByte(0x01 | ((EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG) ? 0x80 : 0x00)); // control + big endian + buffer->putByte(2); // set byte order + buffer->putInt(0); + + // // send verification message // diff --git a/pvAccessApp/remote/blockingTCPTransport.cpp b/pvAccessApp/remote/blockingTCPTransport.cpp index bcb849c..8e2d736 100644 --- a/pvAccessApp/remote/blockingTCPTransport.cpp +++ b/pvAccessApp/remote/blockingTCPTransport.cpp @@ -124,12 +124,12 @@ namespace epics { // TODO minor tweak: deque size is not preallocated... - _socketBuffer = new ByteBuffer(max((int)(MAX_TCP_RECV+MAX_ENSURE_DATA_BUFFER_SIZE), receiveBufferSize), EPICS_ENDIAN_BIG); + _socketBuffer = new ByteBuffer(max((int)(MAX_TCP_RECV+MAX_ENSURE_DATA_BUFFER_SIZE), receiveBufferSize)); _socketBuffer->setPosition(_socketBuffer->getLimit()); _startPosition = _socketBuffer->getPosition(); // allocate buffer - _sendBuffer = new ByteBuffer(_socketBuffer->getSize(), EPICS_ENDIAN_BIG); + _sendBuffer = new ByteBuffer(_socketBuffer->getSize()); _maxPayloadSize = _sendBuffer->getSize() - 2*CA_MESSAGE_HEADER_SIZE; // one for header, one for flow control // get send buffer size @@ -330,7 +330,7 @@ namespace epics { _lastMessageStartPosition = _sendBuffer->getPosition(); _sendBuffer->putByte(CA_MAGIC); _sendBuffer->putByte(CA_VERSION); - _sendBuffer->putByte(_lastSegmentedMessageType); // data + _sendBuffer->putByte(_lastSegmentedMessageType | ((EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG) ? 0x80 : 0x00)); // data + endianess _sendBuffer->putByte(command); // command _sendBuffer->putInt(0); // temporary zero payload @@ -574,20 +574,27 @@ namespace epics { // read payload size _payloadSize = _socketBuffer->getInt(); - // data int8 type = (int8)(_packetType&0x0F); - if(type==0) { + if(type==0) + { + // data _stage = PROCESS_PAYLOAD; } - else if(type==1) { - if(_command==0) { + else if(type==1) + { + // control + + // marker request sent + if (_command == 0) { _flowControlMutex.lock(); if(_markerToSend==0) _markerToSend = _payloadSize; // TODO send back response _flowControlMutex.unlock(); } - else //if (command == 1) + + // marker received back + else if (_command == 1) { _flowControlMutex.lock(); int difference = (int)_totalBytesSent-_payloadSize+CA_MESSAGE_HEADER_SIZE; @@ -600,6 +607,16 @@ namespace epics { // TODO if this is calculated wrong, this can be critical !!! _flowControlMutex.unlock(); } + // set byte order + else if (_command == 2) + { + // check 7-th bit + + // TODO no sync !!! on send + _socketBuffer->setEndianess(_packetType < 0 ? EPICS_ENDIAN_BIG : EPICS_ENDIAN_LITTLE); + _sendBuffer->setEndianess(_packetType < 0 ? EPICS_ENDIAN_BIG : EPICS_ENDIAN_LITTLE); + } + // no payload //stage = ReceiveStage.PROCESS_HEADER; diff --git a/pvAccessApp/remote/blockingUDPTransport.cpp b/pvAccessApp/remote/blockingUDPTransport.cpp index e18e2e4..75955cc 100644 --- a/pvAccessApp/remote/blockingUDPTransport.cpp +++ b/pvAccessApp/remote/blockingUDPTransport.cpp @@ -44,8 +44,8 @@ namespace epics { _sendAddresses(0), _ignoredAddresses(0), _sendToEnabled(false), - _receiveBuffer(new ByteBuffer(MAX_UDP_RECV, EPICS_ENDIAN_BIG)), - _sendBuffer(new ByteBuffer(MAX_UDP_RECV, EPICS_ENDIAN_BIG)), + _receiveBuffer(new ByteBuffer(MAX_UDP_RECV)), + _sendBuffer(new ByteBuffer(MAX_UDP_RECV)), _lastMessageStartPosition(0), _threadId(0) { @@ -146,7 +146,7 @@ namespace epics { _lastMessageStartPosition = _sendBuffer->getPosition(); _sendBuffer->putByte(CA_MAGIC); _sendBuffer->putByte(CA_VERSION); - _sendBuffer->putByte(0); // data + _sendBuffer->putByte((EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG) ? 0x80 : 0x00); // data + 7-bit endianess _sendBuffer->putByte(command); // command _sendBuffer->putInt(0); // temporary zero payload } @@ -267,7 +267,16 @@ namespace epics { return false; // only data for UDP - receiveBuffer->getByte(); + int8 flags = receiveBuffer->getByte(); + if (flags < 0) + { + // 7-bit set + receiveBuffer->setEndianess(EPICS_ENDIAN_BIG); + } + else + { + receiveBuffer->setEndianess(EPICS_ENDIAN_LITTLE); + } // command ID and paylaod int8 command = receiveBuffer->getByte(); diff --git a/pvAccessApp/remote/channelSearchManager.cpp b/pvAccessApp/remote/channelSearchManager.cpp index 7ac7c62..16bcdd0 100644 --- a/pvAccessApp/remote/channelSearchManager.cpp +++ b/pvAccessApp/remote/channelSearchManager.cpp @@ -488,7 +488,7 @@ ChannelSearchManager::ChannelSearchManager(Context* context): _sequenceNumber(0) { // create and initialize send buffer - _sendBuffer = new ByteBuffer(MAX_UDP_SEND, EPICS_ENDIAN_BIG); + _sendBuffer = new ByteBuffer(MAX_UDP_SEND); initializeSendBuffer(); // TODO should be configurable @@ -639,7 +639,7 @@ void ChannelSearchManager::initializeSendBuffer() _sendBuffer->clear(); _sendBuffer->putByte(CA_MAGIC); _sendBuffer->putByte(CA_VERSION); - _sendBuffer->putByte((int8)0); // data + _sendBuffer->putByte((EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG) ? 0x80 : 0x00); // data + 7-bit endianess _sendBuffer->putByte((int8)3); // search _sendBuffer->putInt(sizeof(int32)/sizeof(int8) + 1); // "zero" payload _sendBuffer->putInt(_sequenceNumber);