1 /*
2  Copyright (c) 2018, MIPI Alliance, Inc.
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions
7  are met:
8 
9  * Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11 
12  * Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in
14    the documentation and/or other materials provided with the
15    distribution.
16 
17  * Neither the name of the copyright holder nor the names of its
18    contributors may be used to endorse or promote products derived
19    from this software without specific prior written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 /*
35  * Contributors:
36  * Norbert Schulz (Intel Corporation) - Initial API and implementation
37  */
38 
39 #ifndef MIPI_SYST_DECODE_H_included
40 #define MIPI_SYST_DECODE_H_included
41 
42 #include <vector>
43 #include "mipi_syst_printer.h"
44 #include "mipi_syst_collateral.h"
45 #include "mipi_syst_message.h"
46 
47 MIPI_SYST_NAMESPACE_BEGIN
48 
49 class message;
50 class collateral;
51 
52 /// Base class for decoding exceptions
53 //
54 class decode_exception {
55 public:
56 	decode_exception(message::decode_state s,
57 		const std::string& what = std::string())
state(s)58 		: state(s), msg(what)
59 	{}
~decode_exception()60 	virtual ~decode_exception() {};
61 
what()62 	virtual const std::string& what() const { return msg; }
get_state()63 	message::decode_state get_state() const { return state; }
64 
65 protected:
66 	message::decode_state state;
67 	std::string msg;
68 };
69 
70 
71 class tooshort_exception : public decode_exception
72 {
73 public:
tooshort_exception()74 	tooshort_exception() :
75 		decode_exception(message::decode_state::TOO_SHORT) {}
76 };
77 class toolong_exception : public decode_exception
78 {
79 public:
toolong_exception()80 	toolong_exception() :
81 		decode_exception(message::decode_state::TOO_LONG) {}
82 };
83 class unknown_type_exception : public decode_exception
84 {
85 public:
unknown_type_exception()86 	unknown_type_exception() :
87 		decode_exception(message::decode_state::UNKNOWN_TYPE) {}
88 };
89 
90 class crc_error_exception : public decode_exception
91 {
92 public:
crc_error_exception()93 	crc_error_exception() :
94 		decode_exception(message::decode_state::CHECKSUM_ERROR) {}
95 };
96 
97 class missing_collateral_exception : public decode_exception
98 {
99 public:
missing_collateral_exception()100 	missing_collateral_exception() :
101 		decode_exception(message::decode_state::MISSING_COLLATERAL) {}
102 };
103 
104 /// Decode context information.
105 //
106 //  This class is delivering timstamp and identifcation information as
107 //  side-band data.
108 //  Context based message identification is needed for client identification
109 //  if messages  don't carry GUID information as part of the message data.
110 //  Short messages are one example for such messages. In this case
111 //  collateral matching relies on side-band information. In systems using
112 //  MIPI System Trace Protocol (STP), the master and channel 16-bit values
113 //  are typically used for this purpose.
114 //  A timestamp is often also provided through a transport protocol and not
115 //  embedded into SyS-T messages.
116 //
117 class decode_context {
118 public:
119 	virtual const guid& getGuid() const = 0;  ///< get context based guid
120 	virtual  uint64_t getTS() const = 0;      ///< get context timestamp
~decode_context()121 	virtual ~decode_context() {}
122 };
123 
124 ///  MIPI SyS-T data protocol decoder
125 //
126 // This class is decoding a sequence of bytes that represent one SyS-T message into
127 // a message data structure for post processing.
128 //
129 class decoder {
130 public:
131 	/// Parse given file as a SyS-T collateral XML file
132 	//
133 	// Parse and add provided file as SyS-T collateral data. The function
134 	// throws an exception if the XML is malformed.
135 	//
136 	// @param file filename to load
137 	//
138 	void loadCollateral(const std::string& file);
139 
140 	/// Store Build ID for given GUID
141 	//
142 	// Cache build ID for given GUID to make collateral matching "build number"
143 	// aware. If a build ID was seen, the decode looks for collateral matching this
144 	// one.
145 	//
146 	// @param id 64-Bit build number to remember
147 	// @param g  client guid associated with this build number
148 	//
149 	void setBuildNumber(uint64_t id, const guid& g) const;
150 
151 	/// Decode single SyS-T raw binary message
152 	//
153 	// @param dest message data structed holding decode result
154 	// @param data raw data bytes representing one SyS-T message
155 	//
156 	// @return true on success
157 	//
158 	bool decode(message& dest, const std::vector<uint8_t>& data, const decode_context * ctx) const;
159 
160 private:
161 	bool decodeShortMessage(message& dest, const uint8_t *data, uint32_t length, const decode_context * ctx) const;
162 	bool decodeNormalMessage(message& dest,  const uint8_t *data, uint32_t length, const decode_context * ctx) const;
163 
164 	void decodeBuildPayload(message& dest, const uint8_t * data, uint32_t len) const;
165 	void decodeStringPayload(message& dest, const uint8_t * data, uint32_t len) const;
166 	void decodeCatalogPayload(message& dest, const uint8_t * data, uint32_t len) const;
167 	void decodeRawPayload(message& dest, const uint8_t * data, uint32_t len) const;
168 	void decodeInvalidType(message& dest, const uint8_t * data, uint32_t len) const;
169 
170 
171 	collateral * findCollateral(const guid& m) const;
172 
173 	static guid generatePseudoGuid(uint8_t origin);
174 	static uint32_t getCrc32(const uint8_t * data, size_t len);
175 
176 	std::vector<collateral*> collaterals;
177 	mutable std::map<guid, collateral*> collateral_by_guid;
178 	mutable std::map<guid, uint64_t> build_by_guid;
179 	typedef void (decoder::*decode_payload_f)(message&, const uint8_t *, uint32_t len) const;
180 
181 	static decode_payload_f payloadDecode[16];
182 	static const uint32_t crc32c_table[256];
183 };
184 
185 MIPI_SYST_NAMESPACE_END
186 
187 #endif // MIPI_SYST_PRINTER_H_included
188