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 #include<sstream>
39 #include <iomanip>
40 
41 #include "mipi_syst_decode.h"
42 #include "mipi_syst_printf.h"
43 
44 MIPI_SYST_NAMESPACE_BEGIN
45 
46 /// Helper to extract string from byte array,
47 //
48 // @param dest where to write bytes to
49 // @param offset where to start from
50 // @param data byte array
51 // @param len number of bytes in array
52 //
53 // @return bytes consumed or < 0 if no null byte found
54 //
bytes2String(std::string & dest,const uint8_t * data,uint32_t len)55 static int32_t bytes2String(std::string& dest, const uint8_t * data, uint32_t len)
56 {
57 	uint32_t i(0);
58 
59 	while(i <len)
60 	{
61 		if (!data[i]) {
62 			break;  // null byte found
63 		}
64 		dest += data[i++];
65 	}
66 
67 	if (i == len && data[i - 1]) {
68 		return -1;
69 	}
70 
71 	return (uint32_t)dest.size();
72 }
73 
74 // Helper for printf formating
75 //
printfFormat(const std::string & fmt,bool is32Bit,const void * data,uint32_t len)76 static std::string printfFormat(
77 	const std::string& fmt,
78 	bool is32Bit,
79 	const void * data,
80 	uint32_t len)
81 {
82 	msgprintf printer(is32Bit);
83 	std::string result;
84 	if (len > 0) {
85 		printer.format(fmt, data, len, result);
86 	}
87 	else {
88 		printer.format(fmt, NULL, 0, result);
89 	}
90 	return result;
91 }
92 
setBuildNumber(uint64_t id,const guid & g) const93 void decoder::setBuildNumber(uint64_t id, const guid& g) const
94 {
95 	// cache guid <-> id association
96 	// TODO: A production quality implementation should add a sanity check here
97 	//      and issue a warning if the ID changes compared to an earlier one.
98 	//
99 	if (build_by_guid.find(g) != build_by_guid.end()) {
100 		build_by_guid[g] = id;
101 	}
102 
103 	// Remove an eventually earlier cached collateral to guid mapping. We recompute
104 	// next time with the now known build id.
105 	//
106 	auto cache_hit(collateral_by_guid.find(g));
107 	if (cache_hit != collateral_by_guid.end()) {
108 		collateral_by_guid.erase(cache_hit);
109 	}
110 }
111 
112 
113 // Decode single SyS-T message
114 //
decode(message & dest,const std::vector<uint8_t> & data,const decode_context * ctx) const115 bool decoder::decode(message& dest, const std::vector<uint8_t>& data, const decode_context * ctx) const
116 {
117 	bool rt(false);
118 
119 	try {
120 		// header
121 		//
122 		if (data.size() < sizeof(uint32_t)) throw tooshort_exception();
123 		message::header hdr(bytes2ValLE<uint32_t>(&data[0]));
124 
125 		// short message ?
126 		//
127 		if (message::isShort(hdr)) {
128 			rt =  decodeShortMessage(dest, &data[0], (uint32_t)data.size(), ctx);
129 		} else {
130 			rt = decodeNormalMessage(dest, &data[0], (uint32_t)data.size(), ctx);
131 		}
132 
133 		if (rt  && dest.getHeader().field.type == message::BUILD) {
134 			// found build message, store build number for later
135 			//
136 			setBuildNumber(dest.getBuild(), dest.getGuid());
137 		}
138 	} catch (decode_exception& de) {
139 		dest.setStatus(de.get_state());
140 
141 		// decode failed, show raw byte dump as payload
142 		//
143 		std::stringstream sstr;
144 		sstr << std::hex << std::uppercase << std::setfill('0') << std::setw(2);
145 		for (auto uc : data) {
146 			sstr << (uint16_t)uc;
147 		}
148 		dest.setPayload(sstr.str());
149 	}
150 	return rt;
151 }
152 
153 
decodeShortPayload(message & m,T v)154 template<class T> void decodeShortPayload(message & m, T v)
155 {
156 	const collateral * coll(m.getCollateral());
157 	const collateral::catalogentry<T> * entry(
158 		coll ? coll->getShortEntry(v) : nullptr);
159 
160 	if (entry) {
161 		std::stringstream dest;
162 		hostPrintf(dest, entry->msg, v & (~entry->mask), std::vector<int>());
163 		m.setPayload(dest.str());
164 	} else {
165 		m.setPayload(toHexValue(v));
166 	}
167 }
168 
decodeShortMessage(message & dest,const uint8_t * data,uint32_t length,const decode_context * ctx) const169 bool decoder::decodeShortMessage(
170 	message& dest,
171 	const uint8_t *data, uint32_t length,
172 	const decode_context * ctx) const
173 {
174 	if (length < sizeof(uint32_t)) throw tooshort_exception();
175 
176 	uint32_t type(data[0] & 0x0F); // Bit 0..3 = type
177 	uint32_t subtype(data[3] & 0x3F); // Bit 24..29 = subtype
178 
179 	dest.setHeader(0);  // all optional fields off
180 	dest.setType(type);
181 	dest.setLength(length);
182 	dest.setCollateral(ctx ? findCollateral(ctx->getGuid()) : nullptr);
183 	dest.setContextTS(ctx ? ctx->getTS() : 0);
184 
185 	switch (type) {
186 	case message::type::SHORT32:
187 		decodeShortPayload(dest, bytes2ValLE<uint32_t>(data) >> 4);
188 		break;
189 
190 	case message::type::SHORT64:
191 		if (length < sizeof(uint64_t)) throw tooshort_exception();
192 		decodeShortPayload(dest, bytes2ValLE<uint64_t>(data) >> 4);
193 		break;
194 
195 	case message::type::BUILD:
196 		dest.setSubType(subtype);
197 		switch (subtype) {
198 		case message::subtype_build::BUILD_COMPACT32:
199 		{
200 			uint32_t val(bytes2ValLE<uint32_t>(data));
201 			val = ((val & 0x00FFFFF0) >> 4) | ((val & 0x30000000) >> 10);
202 			dest.setBuild(val);
203 			dest.setPayload(toHexValue(val));
204 			break;
205 		}
206 		case message::subtype_build::BUILD_COMPACT64:
207 		{
208 			if (length < sizeof(uint64_t)) throw tooshort_exception();
209 
210 			uint64_t val(bytes2ValLE<uint64_t>(data));
211 			val = ((val & 0x0000000000FFFFF0ull) >> 4) |
212 				((val & 0xFFFFFFFF30000000ull) >> 10);
213 			dest.setBuild(val);
214 			dest.setPayload(toHexValue(val));
215 
216 			break;
217 		}
218 		default:
219 			throw unknown_type_exception();
220 		}
221 		break;
222 	default:
223 		throw unknown_type_exception();
224 	}
225 
226 	dest.setStatus(message::decode_state::OK);
227 
228 	return true;
229 }
230 
231 // Decode "normal" SyS-T message data
232 //
decodeNormalMessage(message & dest,const uint8_t * data,uint32_t length,const decode_context * ctx) const233 bool decoder::decodeNormalMessage(message& dest, const uint8_t * data, uint32_t length, const decode_context * ctx) const
234 {
235 	uint32_t offset(0);
236 
237 	dest.setContextTS(ctx ? ctx->getTS() : 0);
238 	dest.setLength(length);
239 
240 	// header
241 	//
242 	if (length < (offset + sizeof(uint32_t))) throw tooshort_exception();
243 	dest.setHeader(bytes2ValLE<uint32_t>(data+offset));
244 	offset += sizeof(uint32_t);
245 
246 	// checksum at the end ?
247 	//
248 	if (dest.getHeader().field.chksum) {
249 		if (length < offset + sizeof(uint32_t)) throw tooshort_exception();
250 		length -= sizeof(uint32_t);
251 		dest.setCrc(bytes2ValLE<uint32_t>(data+length));
252 	}
253 
254 	// guid
255 	//
256 	if (dest.getHeader().field.guid) {
257 		if (length < (offset + sizeof(uint64_t[2]))) throw tooshort_exception();
258 
259 		dest.setGuid(guid(data+offset));
260 		offset += sizeof(uint64_t[2]);
261 	} else {
262 		dest.setGuid(generatePseudoGuid(dest.getHeaderOrigin()));
263 	}
264 
265 	// location
266 	//
267 	if (dest.getHeader().field.location) {
268 		if (length < offset + sizeof(uint8_t)) throw tooshort_exception();
269 		uint32_t tag(data[offset++]);
270 		if (tag & 0x1) {
271 			// 64 bit
272 			if (length < offset + sizeof(uint64_t)) throw tooshort_exception();
273 			if (tag & 0x2) { // addr
274 				uint64_t addr(bytes2ValLE<uint64_t>(data+offset));
275 				dest.setLocAddr64(addr);
276 			} else {
277 				uint32_t file(bytes2ValLE<uint32_t>(data + offset));
278 				uint32_t line(bytes2ValLE<uint32_t>(data + offset + 4));
279 				dest.setLocFileLine(file, line);
280 			}
281 			offset += sizeof(uint64_t);
282 		} else {
283 			// 32 bit
284 			if (length < offset + sizeof(uint32_t)) throw tooshort_exception();
285 			if (tag & 0x2) { // addr
286 				uint32_t addr(bytes2ValLE<uint32_t>(data + offset));
287 				dest.setLocAddr32(addr);
288 			} else {
289 				uint16_t file(bytes2ValLE<uint16_t>(data + offset));
290 				uint16_t line(bytes2ValLE<uint16_t>(data + offset + 2));
291 				dest.setLocFileLine(file, line);
292 			}
293 			offset += sizeof(uint32_t);
294 		}
295 	}
296 
297 	// length
298 	//
299 	uint32_t payload_len(length - offset);
300 
301 	if (dest.getHeader().field.length) {
302 		if (length < offset + sizeof(uint16_t)) throw tooshort_exception();
303 		payload_len = bytes2ValLE<uint16_t>(data + offset);
304 		offset += sizeof(uint16_t);
305 	}
306 
307 	// timestamp
308 	//
309 	if (dest.getHeader().field.timestamp) {
310 		if (length < offset + sizeof(uint64_t)) throw tooshort_exception();
311 		dest.setMessageTS(bytes2ValLE<uint64_t>(data + offset));
312 		offset += sizeof(uint64_t);
313 	}
314 
315 	if (dest.getHeader().field.length) {
316 		// length given, compare with remaining payload length
317 		//
318 		int diff(length - offset - payload_len);
319 		if (diff < 0) {
320 			throw tooshort_exception();
321 		} else if (diff > 0) {
322 			throw toolong_exception();
323 		}
324 	}
325 
326 	// check CRC32 if set
327 	//
328 	if (dest.getHeader().field.chksum) {
329 		uint32_t crc = getCrc32(data, length);
330 		if (crc != dest.getCrc()) {
331 			throw crc_error_exception();
332 		}
333 	}
334 
335 	// Check for collateral information
336 	//
337 	const collateral* coll = findCollateral(dest.getGuid());
338 	dest.setCollateral(coll);
339 
340 	// Set client name based on collateral (or use raw guid/origin from message)
341 	//
342 	if (coll != nullptr) {
343 		dest.setClientName(coll->getName());
344 	}
345 	else {
346 		std::stringstream sstr;
347 		if (dest.getHeader().field.guid) {
348 			sstr << dest.getGuid();
349 		} else {
350 			sstr << dest.getHeaderOrigin();
351 		}
352 		dest.setClientName(sstr.str());
353 	}
354 
355 	// Payload decode depening on type
356 	//
357 	(this->*payloadDecode[dest.getHeader().field.type])(dest, data+offset, length - offset);
358 
359 	dest.setStatus(message::decode_state::OK);
360 	return true;
361 }
362 
decodeInvalidType(message & dest,const uint8_t * data,uint32_t len) const363 void decoder::decodeInvalidType(message& dest, const uint8_t * data, uint32_t len) const
364 {
365 	(void)dest;
366 	(void)data;
367 	(void)len;
368 
369 	throw unknown_type_exception();
370 }
371 
decodeBuildPayload(message & dest,const uint8_t * data,uint32_t len) const372 void decoder::decodeBuildPayload(message& dest, const uint8_t * data, uint32_t len) const
373 {
374 	std::stringstream sstr;
375 
376 	switch (dest.getHeader().field.subtype) {
377 	case message::subtype_build::BUILD_LONG:
378 		if (len < sizeof(uint64_t)) throw tooshort_exception();
379 
380 		dest.setBuild(bytes2ValLE<uint64_t>(data));
381 		sstr << toHexValue(dest.getBuild());
382 
383 		data += sizeof(uint64_t);
384 		len  -= sizeof(uint64_t);
385 
386 		if (0 != len) { // string follows ....
387 			std::string payload;
388 			if (bytes2String(payload, data, len) > 0) {
389 				sstr << " " << payload;
390 			} else {
391 				throw tooshort_exception();
392 			}
393 		}
394 		break;
395 	default:
396 		throw unknown_type_exception();
397 		break;
398 	}
399 
400 	dest.setPayload(sstr.str());
401 }
402 
decodeStringPayload(message & dest,const uint8_t * data,uint32_t len) const403 void decoder::decodeStringPayload(message& dest, const uint8_t * data, uint32_t len) const
404 {
405 	std::string format;
406 	int fmtlen;
407 
408 	if (!len || (fmtlen = bytes2String(format, data, len)) <= 0) {
409 		throw tooshort_exception();
410 	}
411 
412 	std::stringstream sstr;
413 
414 	switch (dest.getHeader().field.subtype) {
415 	case message::subtype_string::STRING_PRINTF_32:
416 	case message::subtype_string::STRING_PRINTF_64:
417 		sstr << printfFormat(
418 			format,
419 			dest.getHeader().field.subtype ==
420 			message::subtype_string::STRING_PRINTF_32,
421 			&data[fmtlen+1],
422 			len - fmtlen - 1);
423 		break;
424 
425 	case message::subtype_string::STRING_ASSERT:
426 	case message::subtype_string::STRING_FUNCTIONENTER:
427 	case message::subtype_string::STRING_FUNCTIONEXIT:
428 	case message::subtype_string::STRING_GENERIC:
429 	case message::subtype_string::STRING_INVALIDPARAM:
430 		sstr << format;
431 		break;
432 	default:
433 		throw unknown_type_exception();
434 		break;
435 	}
436 
437 	dest.setPayload(sstr.str());
438 }
439 
decodeCatalogPayload(message & dest,const uint8_t * data,uint32_t len) const440 void decoder::decodeCatalogPayload(message& dest, const uint8_t * data, uint32_t len) const
441 {
442 	const collateral * coll(dest.getCollateral());
443 	if (coll == nullptr) throw missing_collateral_exception();
444 
445 	std::stringstream sstr;
446 	bool is32Bit(false);
447 	const collateral::sourcepos * srcpos(nullptr);
448 	const std::string * fmt(nullptr);
449 
450 	switch (dest.getHeader().field.subtype) {
451 	case message::subtype_catalog::CATALOG_ID32_P32:
452 		is32Bit = true;
453 		// fall through
454 
455 	case message::subtype_catalog::CATALOG_ID32_P64:
456 	{
457 		if (len < sizeof(uint32_t)) throw tooshort_exception();
458 		const collateral::catalogentry<uint32_t> * entry(nullptr);
459 
460 		if ((entry = coll->getCatalogEntry(bytes2ValLE<uint32_t>(data))) == nullptr) {
461 			sstr
462 				<< "Undefined catalog id 0x"
463 				<< toHexValue(bytes2ValLE<uint32_t>(data));
464 		} else {
465 			fmt = &entry->msg;
466 			srcpos = entry;
467 		}
468 		data += sizeof(uint32_t);
469 		len -= sizeof(uint32_t);
470 		break;
471 	}
472 	case message::subtype_catalog::CATALOG_ID64_P32:
473 		is32Bit = true;
474 		// fall through
475 	case message::subtype_catalog::CATALOG_ID64_P64:
476 	{
477 		if (len < sizeof(uint64_t)) throw tooshort_exception();
478 		const collateral::catalogentry<uint64_t> * entry(nullptr);
479 
480 		if ((entry = coll->getCatalogEntry(bytes2ValLE<uint64_t>(data))) == nullptr) {
481 			sstr
482 				<< "Undefined catalog id 0x"
483 				<< toHexValue(bytes2ValLE<uint64_t>(data));
484 		} else {
485 			fmt = &entry->msg;
486 			srcpos = entry;
487 		}
488 		data += sizeof(uint64_t);
489 		len -= sizeof(uint64_t);
490 		break;
491 	}
492 	default:
493 		throw unknown_type_exception();
494 		break;
495 	}
496 
497 	if (fmt != nullptr) {
498 		sstr << printfFormat(*fmt, is32Bit, data, len);
499 
500 		// if current message has no file attribute from payload, but the catalog entry
501 		// does provides one, use the one from the catalog
502 		//
503 		if (0 != srcpos->m_file && 0 == (dest.getLocation().tag & message::IDANDLINE))
504 		{
505 			dest.setLocFileLine(srcpos->m_file, srcpos->m_line);
506 		}
507 	}
508 
509 	dest.setPayload(sstr.str());
510 }
511 
decodeRawPayload(message & dest,const uint8_t * data,uint32_t len) const512 void decoder::decodeRawPayload(message& dest, const uint8_t * data, uint32_t len) const
513 {
514 	std::stringstream sstr;
515 
516 	while (len--) {
517 		sstr << std::setfill('0') << std::setw(2) << std::hex << (uint16_t)*data++;
518 	}
519 
520 	dest.setPayload(sstr.str());
521 }
522 
loadCollateral(const std::string & filename)523 void decoder::loadCollateral(const std::string& filename)
524 {
525 	for (auto items : collateral::parseXml(filename)) {
526 		collaterals.insert(collaterals.end(), items);
527 	}
528 }
529 
generatePseudoGuid(uint8_t origin)530 guid decoder::generatePseudoGuid(uint8_t origin)
531 {
532 	// A pseudo-guid is defined by storing the origin value into
533 	// bits [7..0] of the guid[8] byte. The highest bit is forced
534 	// to zero, which distiquishes it from an RFC4122 compliant
535 	// GUID.
536 	// This example code has no additional transport data for
537 	// identifying the message client. All other values are
538 	// set to 0.
539 	//
540 	uint8_t pseudo_guid_data[16] = {
541 		0,0,0,0,
542 		0,0,0,origin,
543 		0,0,0,0,
544 		0,0,0,0
545 	};
546 	return guid(pseudo_guid_data);
547 }
548 
findCollateral(const guid & g) const549 collateral * decoder::findCollateral(const guid& g) const
550 {
551 	// do we already know the catalog for this GUID ?
552 	//
553 	auto cache_hit(collateral_by_guid.find(g));
554 	if (cache_hit != collateral_by_guid.end()) {
555 		return cache_hit->second;
556 	}
557 
558 	uint64_t build(0);
559 	auto  build_hit(build_by_guid.find(g));
560 	if (build_hit != build_by_guid.end()) {
561 		build = build_hit->second;
562 	}
563 
564 	// search all catalogs
565 	//
566 	auto match = std::find_if(collaterals.begin(), collaterals.end(),
567 		[&g,build](const collateral* v)
568 	{
569 		return (v->match(g, build));
570 	});
571 
572 	if (match != collaterals.end()) {
573 		collateral_by_guid[g] = *match;
574 		return *match;
575 	}
576 	return nullptr;
577 }
578 
579 // Message type dependend payload decode handlers
580 //
581 decoder::decode_payload_f decoder::payloadDecode[] = {
582 	&decoder::decodeBuildPayload,		// [0]
583 	&decoder::decodeInvalidType,		// [1]
584 	&decoder::decodeStringPayload,		// [2]
585 	&decoder::decodeCatalogPayload,		// [3]
586 	&decoder::decodeInvalidType,		// [4]
587 	&decoder::decodeInvalidType,		// [5]
588 	&decoder::decodeRawPayload,		// [6]
589 	&decoder::decodeInvalidType,		// [7]
590 	&decoder::decodeInvalidType,		// [8]
591 	&decoder::decodeInvalidType,		// [9]
592 	&decoder::decodeInvalidType,		// [10]
593 	&decoder::decodeInvalidType,		// [11]
594 	&decoder::decodeInvalidType,		// [12]
595 	&decoder::decodeInvalidType,		// [13]
596 	&decoder::decodeInvalidType,		// [14]
597 	&decoder::decodeInvalidType		// [15]
598 };
599 
600 // Build CRC over a byte buffer (Castagnoli CRC-32C)
601 //
getCrc32(const uint8_t * data,size_t len)602 uint32_t decoder::getCrc32(const uint8_t * data, size_t len)
603 {
604 	uint32_t crc(0xFFFFFFFF);
605 
606 	while (len--) {
607 		crc = crc32c_table[((int)crc ^ (*data++)) & 0xFF] ^ (crc >> 8);
608 	}
609 	return crc ^ 0xFFFFFFFF;
610 }
611 
612 // Pre-computed CRC-C values for all byte values using the
613 // polynomial 0x1EDC6F41 (Castagnoli).
614 //
615 const uint32_t decoder::crc32c_table[256] = {
616 	0x00000000,
617 	0xF26B8303,
618 	0xE13B70F7,
619 	0x1350F3F4,
620 	0xC79A971F,
621 	0x35F1141C,
622 	0x26A1E7E8,
623 	0xD4CA64EB,
624 	0x8AD958CF,
625 	0x78B2DBCC,
626 	0x6BE22838,
627 	0x9989AB3B,
628 	0x4D43CFD0,
629 	0xBF284CD3,
630 	0xAC78BF27,
631 	0x5E133C24,
632 	0x105EC76F,
633 	0xE235446C,
634 	0xF165B798,
635 	0x030E349B,
636 	0xD7C45070,
637 	0x25AFD373,
638 	0x36FF2087,
639 	0xC494A384,
640 	0x9A879FA0,
641 	0x68EC1CA3,
642 	0x7BBCEF57,
643 	0x89D76C54,
644 	0x5D1D08BF,
645 	0xAF768BBC,
646 	0xBC267848,
647 	0x4E4DFB4B,
648 	0x20BD8EDE,
649 	0xD2D60DDD,
650 	0xC186FE29,
651 	0x33ED7D2A,
652 	0xE72719C1,
653 	0x154C9AC2,
654 	0x061C6936,
655 	0xF477EA35,
656 	0xAA64D611,
657 	0x580F5512,
658 	0x4B5FA6E6,
659 	0xB93425E5,
660 	0x6DFE410E,
661 	0x9F95C20D,
662 	0x8CC531F9,
663 	0x7EAEB2FA,
664 	0x30E349B1,
665 	0xC288CAB2,
666 	0xD1D83946,
667 	0x23B3BA45,
668 	0xF779DEAE,
669 	0x05125DAD,
670 	0x1642AE59,
671 	0xE4292D5A,
672 	0xBA3A117E,
673 	0x4851927D,
674 	0x5B016189,
675 	0xA96AE28A,
676 	0x7DA08661,
677 	0x8FCB0562,
678 	0x9C9BF696,
679 	0x6EF07595,
680 	0x417B1DBC,
681 	0xB3109EBF,
682 	0xA0406D4B,
683 	0x522BEE48,
684 	0x86E18AA3,
685 	0x748A09A0,
686 	0x67DAFA54,
687 	0x95B17957,
688 	0xCBA24573,
689 	0x39C9C670,
690 	0x2A993584,
691 	0xD8F2B687,
692 	0x0C38D26C,
693 	0xFE53516F,
694 	0xED03A29B,
695 	0x1F682198,
696 	0x5125DAD3,
697 	0xA34E59D0,
698 	0xB01EAA24,
699 	0x42752927,
700 	0x96BF4DCC,
701 	0x64D4CECF,
702 	0x77843D3B,
703 	0x85EFBE38,
704 	0xDBFC821C,
705 	0x2997011F,
706 	0x3AC7F2EB,
707 	0xC8AC71E8,
708 	0x1C661503,
709 	0xEE0D9600,
710 	0xFD5D65F4,
711 	0x0F36E6F7,
712 	0x61C69362,
713 	0x93AD1061,
714 	0x80FDE395,
715 	0x72966096,
716 	0xA65C047D,
717 	0x5437877E,
718 	0x4767748A,
719 	0xB50CF789,
720 	0xEB1FCBAD,
721 	0x197448AE,
722 	0x0A24BB5A,
723 	0xF84F3859,
724 	0x2C855CB2,
725 	0xDEEEDFB1,
726 	0xCDBE2C45,
727 	0x3FD5AF46,
728 	0x7198540D,
729 	0x83F3D70E,
730 	0x90A324FA,
731 	0x62C8A7F9,
732 	0xB602C312,
733 	0x44694011,
734 	0x5739B3E5,
735 	0xA55230E6,
736 	0xFB410CC2,
737 	0x092A8FC1,
738 	0x1A7A7C35,
739 	0xE811FF36,
740 	0x3CDB9BDD,
741 	0xCEB018DE,
742 	0xDDE0EB2A,
743 	0x2F8B6829,
744 	0x82F63B78,
745 	0x709DB87B,
746 	0x63CD4B8F,
747 	0x91A6C88C,
748 	0x456CAC67,
749 	0xB7072F64,
750 	0xA457DC90,
751 	0x563C5F93,
752 	0x082F63B7,
753 	0xFA44E0B4,
754 	0xE9141340,
755 	0x1B7F9043,
756 	0xCFB5F4A8,
757 	0x3DDE77AB,
758 	0x2E8E845F,
759 	0xDCE5075C,
760 	0x92A8FC17,
761 	0x60C37F14,
762 	0x73938CE0,
763 	0x81F80FE3,
764 	0x55326B08,
765 	0xA759E80B,
766 	0xB4091BFF,
767 	0x466298FC,
768 	0x1871A4D8,
769 	0xEA1A27DB,
770 	0xF94AD42F,
771 	0x0B21572C,
772 	0xDFEB33C7,
773 	0x2D80B0C4,
774 	0x3ED04330,
775 	0xCCBBC033,
776 	0xA24BB5A6,
777 	0x502036A5,
778 	0x4370C551,
779 	0xB11B4652,
780 	0x65D122B9,
781 	0x97BAA1BA,
782 	0x84EA524E,
783 	0x7681D14D,
784 	0x2892ED69,
785 	0xDAF96E6A,
786 	0xC9A99D9E,
787 	0x3BC21E9D,
788 	0xEF087A76,
789 	0x1D63F975,
790 	0x0E330A81,
791 	0xFC588982,
792 	0xB21572C9,
793 	0x407EF1CA,
794 	0x532E023E,
795 	0xA145813D,
796 	0x758FE5D6,
797 	0x87E466D5,
798 	0x94B49521,
799 	0x66DF1622,
800 	0x38CC2A06,
801 	0xCAA7A905,
802 	0xD9F75AF1,
803 	0x2B9CD9F2,
804 	0xFF56BD19,
805 	0x0D3D3E1A,
806 	0x1E6DCDEE,
807 	0xEC064EED,
808 	0xC38D26C4,
809 	0x31E6A5C7,
810 	0x22B65633,
811 	0xD0DDD530,
812 	0x0417B1DB,
813 	0xF67C32D8,
814 	0xE52CC12C,
815 	0x1747422F,
816 	0x49547E0B,
817 	0xBB3FFD08,
818 	0xA86F0EFC,
819 	0x5A048DFF,
820 	0x8ECEE914,
821 	0x7CA56A17,
822 	0x6FF599E3,
823 	0x9D9E1AE0,
824 	0xD3D3E1AB,
825 	0x21B862A8,
826 	0x32E8915C,
827 	0xC083125F,
828 	0x144976B4,
829 	0xE622F5B7,
830 	0xF5720643,
831 	0x07198540,
832 	0x590AB964,
833 	0xAB613A67,
834 	0xB831C993,
835 	0x4A5A4A90,
836 	0x9E902E7B,
837 	0x6CFBAD78,
838 	0x7FAB5E8C,
839 	0x8DC0DD8F,
840 	0xE330A81A,
841 	0x115B2B19,
842 	0x020BD8ED,
843 	0xF0605BEE,
844 	0x24AA3F05,
845 	0xD6C1BC06,
846 	0xC5914FF2,
847 	0x37FACCF1,
848 	0x69E9F0D5,
849 	0x9B8273D6,
850 	0x88D28022,
851 	0x7AB90321,
852 	0xAE7367CA,
853 	0x5C18E4C9,
854 	0x4F48173D,
855 	0xBD23943E,
856 	0xF36E6F75,
857 	0x0105EC76,
858 	0x12551F82,
859 	0xE03E9C81,
860 	0x34F4F86A,
861 	0xC69F7B69,
862 	0xD5CF889D,
863 	0x27A40B9E,
864 	0x79B737BA,
865 	0x8BDCB4B9,
866 	0x988C474D,
867 	0x6AE7C44E,
868 	0xBE2DA0A5,
869 	0x4C4623A6,
870 	0x5F16D052,
871 	0xAD7D5351
872 };
873 
874 MIPI_SYST_NAMESPACE_END