1ef8d727ca0eb346af951d15d84ba6f2b9564adf5Kevin Rocard/*
29368eea42a1afb01dd44110582f997115b50e742François Gaffie * Copyright (c) 2011-2015, Intel Corporation
3b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * All rights reserved.
4b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner *
5b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * Redistribution and use in source and binary forms, with or without modification,
6b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * are permitted provided that the following conditions are met:
7b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner *
8b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 1. Redistributions of source code must retain the above copyright notice, this
9b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * list of conditions and the following disclaimer.
10b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner *
11b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 2. Redistributions in binary form must reproduce the above copyright notice,
12b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * this list of conditions and the following disclaimer in the documentation and/or
13b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * other materials provided with the distribution.
14b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner *
15b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 3. Neither the name of the copyright holder nor the names of its contributors
16b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * may be used to endorse or promote products derived from this software without
17b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * specific prior written permission.
18b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner *
19b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2968a912857707864bbaaff9808717813105072a6ePatrick Benavoli */
3068a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include "Message.h"
3168a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include "Socket.h"
329368eea42a1afb01dd44110582f997115b50e742François Gaffie#include "Iterator.hpp"
339368eea42a1afb01dd44110582f997115b50e742François Gaffie#include <asio.hpp>
349368eea42a1afb01dd44110582f997115b50e742François Gaffie#include <vector>
359368eea42a1afb01dd44110582f997115b50e742François Gaffie#include <numeric>
369368eea42a1afb01dd44110582f997115b50e742François Gaffie#include <cassert>
3768a912857707864bbaaff9808717813105072a6ePatrick Benavoli
38d9526499d6ab53b7d13d1434f748f6f2161c2e0aSebastien Gonzalveusing std::string;
39d9526499d6ab53b7d13d1434f748f6f2161c2e0aSebastien Gonzalve
409368eea42a1afb01dd44110582f997115b50e742François GaffieCMessage::CMessage(MsgType ucMsgId) : _ucMsgId(ucMsgId), _uiIndex(0)
4168a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
4268a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
4368a912857707864bbaaff9808717813105072a6ePatrick Benavoli
449368eea42a1afb01dd44110582f997115b50e742François GaffieCMessage::CMessage() : _ucMsgId(MsgType::EInvalid), _uiIndex(0)
4568a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
4668a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
4768a912857707864bbaaff9808717813105072a6ePatrick Benavoli
489368eea42a1afb01dd44110582f997115b50e742François Gaffie// Msg Id
499368eea42a1afb01dd44110582f997115b50e742François GaffieCMessage::MsgType CMessage::getMsgId() const
5068a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
519368eea42a1afb01dd44110582f997115b50e742François Gaffie    return _ucMsgId;
5268a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
5368a912857707864bbaaff9808717813105072a6ePatrick Benavoli
549368eea42a1afb01dd44110582f997115b50e742François Gaffiebool CMessage::isValidAccess(size_t offset, size_t size) const
5568a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
569368eea42a1afb01dd44110582f997115b50e742François Gaffie    return offset + size <= getMessageDataSize();
5768a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
5868a912857707864bbaaff9808717813105072a6ePatrick Benavoli
5968a912857707864bbaaff9808717813105072a6ePatrick Benavoli// Data
609368eea42a1afb01dd44110582f997115b50e742François Gaffievoid CMessage::writeData(const void *pvData, size_t size)
6168a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
629368eea42a1afb01dd44110582f997115b50e742François Gaffie    assert(isValidAccess(_uiIndex, size));
639368eea42a1afb01dd44110582f997115b50e742François Gaffie
649368eea42a1afb01dd44110582f997115b50e742François Gaffie    auto first = MAKE_ARRAY_ITERATOR(static_cast<const uint8_t *>(pvData), size);
659368eea42a1afb01dd44110582f997115b50e742François Gaffie    auto last = first + size;
669368eea42a1afb01dd44110582f997115b50e742François Gaffie    auto destFirst = begin(mData) + _uiIndex;
6768a912857707864bbaaff9808717813105072a6ePatrick Benavoli
689368eea42a1afb01dd44110582f997115b50e742François Gaffie    std::copy(first, last, destFirst);
6968a912857707864bbaaff9808717813105072a6ePatrick Benavoli
709368eea42a1afb01dd44110582f997115b50e742François Gaffie    _uiIndex += size;
7168a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
7268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
739368eea42a1afb01dd44110582f997115b50e742François Gaffievoid CMessage::readData(void *pvData, size_t size)
7468a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
759368eea42a1afb01dd44110582f997115b50e742François Gaffie    assert(isValidAccess(_uiIndex, size));
7668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
779368eea42a1afb01dd44110582f997115b50e742François Gaffie    auto first = begin(mData) + _uiIndex;
789368eea42a1afb01dd44110582f997115b50e742François Gaffie    auto last = first + size;
799368eea42a1afb01dd44110582f997115b50e742François Gaffie    auto destFirst = MAKE_ARRAY_ITERATOR(static_cast<uint8_t *>(pvData), size);
8068a912857707864bbaaff9808717813105072a6ePatrick Benavoli
819368eea42a1afb01dd44110582f997115b50e742François Gaffie    std::copy(first, last, destFirst);
829368eea42a1afb01dd44110582f997115b50e742François Gaffie
839368eea42a1afb01dd44110582f997115b50e742François Gaffie    _uiIndex += size;
8468a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
8568a912857707864bbaaff9808717813105072a6ePatrick Benavoli
869368eea42a1afb01dd44110582f997115b50e742François Gaffievoid CMessage::writeString(const string &strData)
8768a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
8868a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Size
899368eea42a1afb01dd44110582f997115b50e742François Gaffie    uint32_t size = static_cast<uint32_t>(strData.length());
9068a912857707864bbaaff9808717813105072a6ePatrick Benavoli
919368eea42a1afb01dd44110582f997115b50e742François Gaffie    writeData(&size, sizeof(size));
9268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
9368a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Content
949368eea42a1afb01dd44110582f997115b50e742François Gaffie    writeData(strData.c_str(), size);
9568a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
9668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
979368eea42a1afb01dd44110582f997115b50e742François Gaffievoid CMessage::readString(string &strData)
9868a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
9968a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Size
10068a912857707864bbaaff9808717813105072a6ePatrick Benavoli    uint32_t uiSize;
10168a912857707864bbaaff9808717813105072a6ePatrick Benavoli
10268a912857707864bbaaff9808717813105072a6ePatrick Benavoli    readData(&uiSize, sizeof(uiSize));
10368a912857707864bbaaff9808717813105072a6ePatrick Benavoli
10468a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Data
1059368eea42a1afb01dd44110582f997115b50e742François Gaffie    std::vector<char> string(uiSize + 1);
10668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
10768a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Content
1089368eea42a1afb01dd44110582f997115b50e742François Gaffie    readData(string.data(), uiSize);
10968a912857707864bbaaff9808717813105072a6ePatrick Benavoli
11068a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // NULL-terminate string
1119368eea42a1afb01dd44110582f997115b50e742François Gaffie    string.back() = '\0';
11268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
11368a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Output
1149368eea42a1afb01dd44110582f997115b50e742François Gaffie    strData = string.data();
11568a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
11668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
1179368eea42a1afb01dd44110582f997115b50e742François Gaffiesize_t CMessage::getStringSize(const string &strData) const
11868a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
11968a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Return string length plus room to store its length
12068a912857707864bbaaff9808717813105072a6ePatrick Benavoli    return strData.length() + sizeof(uint32_t);
12168a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
12268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
12368a912857707864bbaaff9808717813105072a6ePatrick Benavoli// Remaining data size
124911844b16c6b627f421bc3368de427de3ca9f60cPatrick Benavolisize_t CMessage::getRemainingDataSize() const
12568a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
1269368eea42a1afb01dd44110582f997115b50e742François Gaffie    return getMessageDataSize() - _uiIndex;
12768a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
12868a912857707864bbaaff9808717813105072a6ePatrick Benavoli
12968a912857707864bbaaff9808717813105072a6ePatrick Benavoli// Send/Receive
1309368eea42a1afb01dd44110582f997115b50e742François GaffieCMessage::Result CMessage::serialize(Socket &&socket, bool bOut, string &strError)
13168a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
1329368eea42a1afb01dd44110582f997115b50e742François Gaffie    asio::ip::tcp::socket &asioSocket = socket.get();
1339368eea42a1afb01dd44110582f997115b50e742François Gaffie
13468a912857707864bbaaff9808717813105072a6ePatrick Benavoli    if (bOut) {
1359368eea42a1afb01dd44110582f997115b50e742François Gaffie        asio::error_code ec;
13668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
13768a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Make room for data to send
13868a912857707864bbaaff9808717813105072a6ePatrick Benavoli        allocateData(getDataSize());
13968a912857707864bbaaff9808717813105072a6ePatrick Benavoli
14068a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Get data from derived
14168a912857707864bbaaff9808717813105072a6ePatrick Benavoli        fillDataToSend();
14268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
14368a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Finished providing data?
1449368eea42a1afb01dd44110582f997115b50e742François Gaffie        assert(_uiIndex == getMessageDataSize());
14568a912857707864bbaaff9808717813105072a6ePatrick Benavoli
14668a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // First send sync word
14768a912857707864bbaaff9808717813105072a6ePatrick Benavoli        uint16_t uiSyncWord = SYNC_WORD;
14868a912857707864bbaaff9808717813105072a6ePatrick Benavoli
1499368eea42a1afb01dd44110582f997115b50e742François Gaffie        if (!asio::write(asioSocket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) {
15068a912857707864bbaaff9808717813105072a6ePatrick Benavoli
1519368eea42a1afb01dd44110582f997115b50e742François Gaffie            if (ec == asio::error::eof) {
152e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard                return peerDisconnected;
153e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            }
154e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
15568a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
15668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
15768a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Size
1589368eea42a1afb01dd44110582f997115b50e742François Gaffie        uint32_t uiSize = (uint32_t)(sizeof(_ucMsgId) + getMessageDataSize());
15968a912857707864bbaaff9808717813105072a6ePatrick Benavoli
1609368eea42a1afb01dd44110582f997115b50e742François Gaffie        if (!asio::write(asioSocket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) {
16168a912857707864bbaaff9808717813105072a6ePatrick Benavoli
1629368eea42a1afb01dd44110582f997115b50e742François Gaffie            strError += string("Size write failed: ") + ec.message();
163e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
16468a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
16568a912857707864bbaaff9808717813105072a6ePatrick Benavoli
16668a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Msg Id
1679368eea42a1afb01dd44110582f997115b50e742François Gaffie        if (!asio::write(asioSocket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) {
16868a912857707864bbaaff9808717813105072a6ePatrick Benavoli
1699368eea42a1afb01dd44110582f997115b50e742François Gaffie            strError += string("Msg write failed: ") + ec.message();
170e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
17168a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
17268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
17368a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Data
1749368eea42a1afb01dd44110582f997115b50e742François Gaffie        if (!asio::write(asioSocket, asio::buffer(mData), ec)) {
17568a912857707864bbaaff9808717813105072a6ePatrick Benavoli
1769368eea42a1afb01dd44110582f997115b50e742François Gaffie            strError = string("Data write failed: ") + ec.message();
177e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
17868a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
17968a912857707864bbaaff9808717813105072a6ePatrick Benavoli
18068a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Checksum
18168a912857707864bbaaff9808717813105072a6ePatrick Benavoli        uint8_t ucChecksum = computeChecksum();
18268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
1839368eea42a1afb01dd44110582f997115b50e742François Gaffie        if (!asio::write(asioSocket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) {
18468a912857707864bbaaff9808717813105072a6ePatrick Benavoli
1859368eea42a1afb01dd44110582f997115b50e742François Gaffie            strError = string("Checksum write failed: ") + ec.message();
186e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
18768a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
18868a912857707864bbaaff9808717813105072a6ePatrick Benavoli
18968a912857707864bbaaff9808717813105072a6ePatrick Benavoli    } else {
19068a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // First read sync word
1919368eea42a1afb01dd44110582f997115b50e742François Gaffie        uint16_t uiSyncWord = 0;
1929368eea42a1afb01dd44110582f997115b50e742François Gaffie        asio::error_code ec;
19368a912857707864bbaaff9808717813105072a6ePatrick Benavoli
1949368eea42a1afb01dd44110582f997115b50e742François Gaffie        if (!asio::read(asioSocket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) {
1959368eea42a1afb01dd44110582f997115b50e742François Gaffie            strError = string("Sync read failed: ") + ec.message();
1969368eea42a1afb01dd44110582f997115b50e742François Gaffie            if (ec == asio::error::eof) {
197e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard                return peerDisconnected;
198e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            }
199e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
20068a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
20168a912857707864bbaaff9808717813105072a6ePatrick Benavoli
20268a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Check Sync word
20368a912857707864bbaaff9808717813105072a6ePatrick Benavoli        if (uiSyncWord != SYNC_WORD) {
20468a912857707864bbaaff9808717813105072a6ePatrick Benavoli
205ef8d727ca0eb346af951d15d84ba6f2b9564adf5Kevin Rocard            strError = "Sync word incorrect";
206e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
20768a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
20868a912857707864bbaaff9808717813105072a6ePatrick Benavoli
20968a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Size
2109368eea42a1afb01dd44110582f997115b50e742François Gaffie        uint32_t uiSize = 0;
21168a912857707864bbaaff9808717813105072a6ePatrick Benavoli
2129368eea42a1afb01dd44110582f997115b50e742François Gaffie        if (!asio::read(asioSocket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) {
2139368eea42a1afb01dd44110582f997115b50e742François Gaffie            strError = string("Size read failed: ") + ec.message();
214e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
21568a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
21668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
21768a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Msg Id
2189368eea42a1afb01dd44110582f997115b50e742François Gaffie        if (!asio::read(asioSocket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) {
2199368eea42a1afb01dd44110582f997115b50e742François Gaffie            strError = string("Msg id read failed: ") + ec.message();
220e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
22168a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
22268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
22368a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Data
22468a912857707864bbaaff9808717813105072a6ePatrick Benavoli
22568a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Allocate
22668a912857707864bbaaff9808717813105072a6ePatrick Benavoli        allocateData(uiSize - sizeof(_ucMsgId));
22768a912857707864bbaaff9808717813105072a6ePatrick Benavoli
22868a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Data receive
2299368eea42a1afb01dd44110582f997115b50e742François Gaffie        if (!asio::read(asioSocket, asio::buffer(mData), ec)) {
2309368eea42a1afb01dd44110582f997115b50e742François Gaffie            strError = string("Data read failed: ") + ec.message();
231e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
23268a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
23368a912857707864bbaaff9808717813105072a6ePatrick Benavoli
23468a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Checksum
2359368eea42a1afb01dd44110582f997115b50e742François Gaffie        uint8_t ucChecksum = 0;
23668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
2379368eea42a1afb01dd44110582f997115b50e742François Gaffie        if (!asio::read(asioSocket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) {
2389368eea42a1afb01dd44110582f997115b50e742François Gaffie            strError = string("Checksum read failed: ") + ec.message();
239e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
24068a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
24168a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Compare
24268a912857707864bbaaff9808717813105072a6ePatrick Benavoli        if (ucChecksum != computeChecksum()) {
24368a912857707864bbaaff9808717813105072a6ePatrick Benavoli
244ef8d727ca0eb346af951d15d84ba6f2b9564adf5Kevin Rocard            strError = "Received checksum != computed checksum";
245e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard            return error;
24668a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
24768a912857707864bbaaff9808717813105072a6ePatrick Benavoli
24868a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Collect data in derived
24968a912857707864bbaaff9808717813105072a6ePatrick Benavoli        collectReceivedData();
25068a912857707864bbaaff9808717813105072a6ePatrick Benavoli    }
25168a912857707864bbaaff9808717813105072a6ePatrick Benavoli
252e874c2575c1203648e71426cd34f747cbd34b2b4Kevin Rocard    return success;
25368a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
25468a912857707864bbaaff9808717813105072a6ePatrick Benavoli
25568a912857707864bbaaff9808717813105072a6ePatrick Benavoli// Checksum
25668a912857707864bbaaff9808717813105072a6ePatrick Benavoliuint8_t CMessage::computeChecksum() const
25768a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
2589368eea42a1afb01dd44110582f997115b50e742François Gaffie    return accumulate(begin(mData), end(mData), static_cast<uint8_t>(_ucMsgId));
25968a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
26068a912857707864bbaaff9808717813105072a6ePatrick Benavoli
261911844b16c6b627f421bc3368de427de3ca9f60cPatrick Benavoli// Allocation of room to store the message
2629368eea42a1afb01dd44110582f997115b50e742François Gaffievoid CMessage::allocateData(size_t size)
26368a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
26468a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Remove previous one
2659368eea42a1afb01dd44110582f997115b50e742François Gaffie    mData.clear();
26668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
26768a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Do allocate
2689368eea42a1afb01dd44110582f997115b50e742François Gaffie    mData.resize(size);
26968a912857707864bbaaff9808717813105072a6ePatrick Benavoli
27068a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Reset Index
27168a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _uiIndex = 0;
27268a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
273