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_MESSAGE_H_included
40 #define MIPI_SYST_MESSAGE_H_included
41 
42 #include <cstdint>
43 #include <string>
44 #include <vector>
45 #include <ostream>
46 
47 #include "mipi_syst_printer.h"
48 #include "mipi_syst_guid.h"
49 
50 MIPI_SYST_NAMESPACE_BEGIN
51 
52 class collateral;
53 
54 /// Internal representation of a decoded SyS-T message
55 ///
56 class message {
57 public:
58 	enum decode_state {
59 		OK = 0,
60 		UNKNOWN_TYPE = 1,
61 		TOO_SHORT = 2,
62 		TOO_LONG = 3,
63 		CHECKSUM_ERROR = 4,
64 		MISSING_COLLATERAL = 5
65 	};
66 
67 	union header {
68 		public:
69 		struct fields {
70 #if defined(MIPI_SYST_BIG_ENDIAN)
71 			uint32_t res31 : 1;        ///< reserved, must be 0
72 			uint32_t res30 : 1;        ///< reserved, must be 0
73 			uint32_t subtype : 6;      ///< type dependent sub category
74 			uint32_t guid : 1;         ///< 128 bit GUID present
75 			uint32_t originUnit : 11;  ///< unit for GUID or module:unit pair
76 			uint32_t timestamp : 1;    ///< indicate 64 bit timestamp
77 			uint32_t chksum : 1;       ///< indicate 32bit CRC
78 			uint32_t length : 1;       ///< indicate variable length message
79 			uint32_t location : 1;     ///< indicate location information
80 			uint32_t res7 : 1;         ///<reserved, must be 0
81 			uint32_t severity : 3;     ///< severity level of message
82 			uint32_t type : 4;         ///< SyS-T message type ID
83 #else
84 			uint32_t type : 4;         ///< SyS-T message type ID
85 			uint32_t severity : 3;     ///< severity level of message
86 			uint32_t res7 : 1;         /// <reserved, must be 0
87 			uint32_t location : 1;     ///< indicate location information
88 			uint32_t length : 1;       ///< indicate variable length message
89 			uint32_t chksum : 1;       ///< indicate 32bit CRC
90 			uint32_t timestamp : 1;    ///< indicate 64 bit timestamp
91 			uint32_t originUnit : 11;  ///< unit for GUID or module:unit pair
92 			uint32_t guid : 1;         ///< 128 bit GUID present
93 			uint32_t subtype : 6;      ///< type dependent sub category
94 			uint32_t res30 : 1;        ///< reserved, must be 0
95 			uint32_t res31 : 1;        ///< reserved, must be 0
96 #endif
97 		} field;
98 		uint32_t val;
99 
val(v)100 		header(uint32_t v = 0) : val(v) {};
101 	};
102 
103 	enum location_type {
104 		NONE        = 0,
105 		ADDRESS32   = (1<<1),
106 		ADDRESS64   = (1<<2),
107 		IDANDLINE   = (1<<3)
108 	};
109 
110 	struct location {
111 		uint32_t tag;
112 		uint64_t address;
113 		uint32_t file;
114 		uint32_t line;
115 
locationlocation116 		location() : tag(0), address(0), file(0), line(0) {}
117 	};
118 
119 	enum type {
120 		BUILD = 0,           ///< client build version  messages
121 		SHORT32 = 1,         ///< tag only message
122 		STRING = 2,          ///< text message output
123 		CATALOG = 3,         ///< catalog message output
124 		RAW = 6,             ///< raw binary data
125 		SHORT64 = 7,         ///*< raw binary data
126 		CLOCK = 8,           ///< clock sync records
127 	};
128 	enum subtype_build {
129 		BUILD_COMPACT32 = 0, ///< 32 bit compressed version record
130 		BUILD_COMPACT64 = 1, ///< 64 bit compressed version record
131 		BUILD_LONG = 2       ///< complete version record
132 	};
133 
134 	enum subtype_string {
135 		STRING_GENERIC = 1,       ///< string generic debug
136 		STRING_FUNCTIONENTER = 2, ///< string is function name
137 		STRING_FUNCTIONEXIT = 3,  ///< string is function name
138 		STRING_INVALIDPARAM = 5,  ///< invalid SyS-T APIcall
139 		STRING_ASSERT = 7,        ///< Software Assert: failure
140 		STRING_PRINTF_32 = 11,    ///< printf support 32bit packing
141 		STRING_PRINTF_64 = 12     ///< printf support 64bit packing
142 	};
143 
144 	enum subtype_catalog {
145 		CATALOG_ID32_P32 = 1,   ///< 32 bit catalog ID, 32 bit packing
146 		CATALOG_ID64_P32 = 2,   ///< 64 bit catalog ID, 32 bit packing
147 		CATALOG_ID32_P64 = 5,   ///< 32 bit catalog ID, 64 bit packing
148 		CATALOG_ID64_P64 = 6    ///< 64 bit catalog ID, 64 bit packing
149 	};
150 	enum subtype_clock {
151 		CLOCK_SYNC = 1          ///< HW clock &frequency sync
152 	};
153 
154 	enum severity {
155 		SEVERITY_MAX = 0,	///< no assigined severity
156 		SEVERITY_FATAL = 1,	///< critical error level
157 		SEVERITY_ERROR = 2,	///< error message level
158 		SEVERITY_WARNING = 3,	///< warning message level
159 		SEVERITY_INFO = 4,	///< information message level
160 		SEVERITY_USER1 = 5,	///< user defined level 5
161 		SEVERITY_USER2 = 6,	///< user defined level 6
162 		SEVERITY_DEBUG = 7	///< debug information level
163 	};
164 
165 
166 public:
167 
message()168 	message() : m_state(UNKNOWN_TYPE), m_build(0) {}
169 
setHeader(uint32_t val)170 	void setHeader(uint32_t val) { m_hdr.val = val; }
setStatus(const decode_state & s)171 	void setStatus(const decode_state& s) { m_state = s; }
setPayload(const std::string & s)172 	void setPayload(const std::string& s) { m_payload = s; }
setType(uint32_t val)173 	void setType(uint32_t val) { m_hdr.field.type = val; }
setSubType(uint32_t val)174 	void setSubType(uint32_t val) { m_hdr.field.subtype = val; }
setGuid(const guid & g)175 	void setGuid(const guid& g) { m_guid = g;  }
setBuild(uint64_t b)176 	void setBuild(uint64_t b) { m_build = b; }
setCrc(const uint32_t c)177 	void setCrc(const uint32_t c) { m_crc = c; }
setLength(const uint32_t l)178 	void setLength(const uint32_t l) { m_length = l; }
setClientName(const std::string & s)179 	void setClientName(const std::string& s) { m_clientname = s; }
setCollateral(const collateral * c)180 	void setCollateral(const collateral *c ) { m_coll = c; }
181 
182 	void setLocAddr32(uint32_t addr);
183 	void setLocAddr64(uint64_t addr);
184 	void setLocFileLine(uint32_t file, uint32_t line);
185 
setMessageTS(uint64_t ts)186 	void setMessageTS(uint64_t ts) { m_msgTS = ts;  }
setContextTS(uint64_t ts)187 	void setContextTS(uint64_t ts) { m_ctxTS = ts; }
188 
getHeader()189 	const header& getHeader() const { return m_hdr; }
getPayload()190 	const std::string& getPayload() const { return m_payload; }
getState()191 	const decode_state& getState() const { return m_state; }
getGuid()192 	const guid& getGuid() const { return m_guid; }
getLocation()193 	const location& getLocation() const { return m_loc; }
getCrc()194 	const uint32_t getCrc() const { return m_crc; }
getLength()195 	const uint32_t getLength() const { return m_length; }
getClientName()196 	const std::string& getClientName() const { return m_clientname; }
getCollateral()197 	const collateral * getCollateral() const { return m_coll; }
getHeaderOrigin()198 	uint8_t getHeaderOrigin() const { return (uint8_t)(m_hdr.field.originUnit >> 4); }
getUnit()199 	uint32_t getUnit() const {
200 		return m_hdr.field.guid ? m_hdr.field.originUnit : (m_hdr.field.originUnit & 0xF);
201 	}
getMessageTS()202 	uint64_t getMessageTS() const{ return m_msgTS;  }
getContextTS()203 	uint64_t getContextTS()const { return m_ctxTS; }
getBuild()204 	uint64_t getBuild() const    { return m_build; }
isShort()205 	bool isShort() const { return isShort(getHeader()); };
206 
207 	static bool isShort(header hdr);
208 	static const char csvHeaderString[];
209 private:
210 	decode_state m_state;
211 
212 	header       m_hdr;
213 	uint64_t     m_msgTS;
214 	uint64_t     m_ctxTS;
215 	uint64_t     m_build;
216 	guid         m_guid;
217 	location     m_loc;
218 	std::string  m_payload;
219 	std::string  m_clientname;
220 	uint32_t     m_length;
221 	uint32_t     m_crc;
222 	const collateral * m_coll;
223 };
224 
225 std::ostream& operator<<(std::ostream& os, const message& msg);
226 MIPI_SYST_NAMESPACE_END
227 
228 #endif // MIPI_SYST_MESSAGE_H_included
229