1 /*
2  * Copyright (c) 2011-2015, Intel Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation and/or
13  * other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software without
17  * specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #pragma once
31 
32 #include "NonCopyable.hpp"
33 #include <vector>
34 #include <string>
35 #include <cstdint>
36 
37 #include <remote_processor_export.h>
38 
39 class Socket;
40 
41 class REMOTE_PROCESSOR_EXPORT CMessage : private utility::NonCopyable
42 {
43 public:
44     enum class MsgType : std::uint8_t
45     {
46         ECommandRequest,
47         ESuccessAnswer,
48         EFailureAnswer,
49         EInvalid = static_cast<uint8_t>(-1),
50     };
51     CMessage(MsgType ucMsgId);
52     CMessage();
53     virtual ~CMessage() = default;
54 
55     enum Result
56     {
57         success,
58         peerDisconnected,
59         error
60     };
61 
62     /** Write or read the message on pSocket.
63      *
64      * @param[in,out] socket is the socket on wich IO operation will be made.
65      * @param[in] bOut if true message should be read,
66      *                 if false it should be written.
67      * @param[out] strError on failure, a string explaining the error,
68      *                      on success, undefined.
69      *
70      * @return success if a correct message could be recv/send
71      *         peerDisconnected if the peer disconnected before the first socket access.
72      *         error if the message could not be read/write for any other reason
73      */
74     Result serialize(Socket &&socket, bool bOut, std::string &strError);
75 
76 protected:
77     // Msg Id
78     MsgType getMsgId() const;
79 
80     /** Write raw data to the message
81     *
82     * @param[in] pvData pointer to the data array
83     * @param[in] uiSize array size in bytes
84     */
85     void writeData(const void *pvData, size_t uiSize);
86 
87     /** Read raw data from the message
88     *
89     * @param[out] pvData pointer to the data array
90     * @param[in] uiSize array size in bytes
91     */
92     void readData(void *pvData, size_t uiSize);
93 
94     /** Write string to the message
95     *
96     * @param[in] strData the string to write
97     */
98     void writeString(const std::string &strData);
99 
100     /** Write string to the message
101     *
102     * @param[out] strData the string to read to
103     */
104     void readString(std::string &strData);
105 
106     /** @return string length plus room to store its length
107     *
108     * @param[in] strData the string to get the size from
109     */
110     size_t getStringSize(const std::string &strData) const;
111 
112     /** @return remaining data size to read or to write depending on the context
113     * (request: write, answer: read)
114     */
115     size_t getRemainingDataSize() const;
116 
117 private:
118     bool isValidAccess(size_t offset, size_t size) const;
119 
120     /** Allocate room to store the message
121     *
122     * @param[int] uiDataSize the szie to allocate in bytes
123     */
124     void allocateData(size_t uiDataSize);
125     // Fill data to send
126     virtual void fillDataToSend() = 0;
127     // Collect received data
128     virtual void collectReceivedData() = 0;
129 
130     /** @return size of the transaction data in bytes
131     */
132     virtual size_t getDataSize() const = 0;
133 
134     // Checksum
135     uint8_t computeChecksum() const;
136 
137     // MsgId
138     MsgType _ucMsgId;
139 
getMessageDataSize()140     size_t getMessageDataSize() const { return mData.size(); }
141 
142     using Data = std::vector<uint8_t>;
143     Data mData;
144     /** Read/Write Index used to iterate across the message data */
145     size_t _uiIndex;
146 
147     static const uint16_t SYNC_WORD = 0xBABE;
148 };
149