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