adaptive byte-order

This commit is contained in:
Matej Sekoranja
2011-09-18 20:45:18 +02:00
parent 409c1f17d7
commit 24d8cb96a3
4 changed files with 53 additions and 14 deletions

View File

@@ -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
//

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);