1 /*
2  * Copyright (c) 2022 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "mock_backend.h"
8 #include <zephyr/ztest.h>
9 #include <zephyr/logging/log_core.h>
10 #include <zephyr/logging/log_backend_std.h>
11 #include <stdlib.h>
12 
13 static uint32_t log_format_current = CONFIG_LOG_BACKEND_MOCK_OUTPUT_DEFAULT;
14 union log_msg_generic *test_msg;
15 
16 static uint8_t mock_output_buf[1];
17 uint8_t test_output_buf[256];
18 int pos_in_buf;
19 
20 /**
21  * @brief This function takes in the characters and copies
22  * them in the temporary buffer.
23  *
24  * @return No. of characters copied to the temporary buffer.
25  */
char_out(uint8_t * data,size_t length,void * ctx)26 static int char_out(uint8_t *data, size_t length, void *ctx)
27 {
28 	ARG_UNUSED(ctx);
29 	size_t output_length = length;
30 
31 	while (length > 0) {
32 		test_output_buf[pos_in_buf] = *data;
33 		pos_in_buf++;
34 		data++;
35 		length--;
36 
37 		zassert_not_equal(pos_in_buf, sizeof(test_output_buf)-1,
38 				  "Increase the size of test_output_buf");
39 	}
40 	return output_length;
41 }
42 
43 LOG_OUTPUT_DEFINE(log_output_mock, char_out, mock_output_buf, sizeof(mock_output_buf));
44 
process(const struct log_backend * const backend,union log_msg_generic * msg)45 static void process(const struct log_backend *const backend,
46 		union log_msg_generic *msg)
47 {
48 	uint32_t flags = log_backend_std_get_flags();
49 
50 	test_msg = msg;
51 
52 	log_format_func_t log_output_func = log_format_func_t_get(log_format_current);
53 
54 	log_output_func(&log_output_mock, &msg->log, flags);
55 }
56 
is_kth_bit_set(int n,int k)57 bool is_kth_bit_set(int n, int k)
58 {
59 	return ((n & (1 << (k - 1))) != 0);
60 }
61 
validate_msg(const char * type,const char * optional_flags,const char * module_id,const char * sub_type,const char * payload)62 void validate_msg(const char *type, const char *optional_flags,
63 		  const char *module_id, const char *sub_type,
64 		  const char *payload)
65 {
66 	const char *raw_data_str = "SYS-T RAW DATA: ";
67 	const char *output_str = test_output_buf;
68 	const char *syst_format_headers[4] = {type, optional_flags, module_id, sub_type};
69 	const char *syst_headers_name[4] = {"type", "optional_flags", "module_id", "sub_type"};
70 
71 	/* Validate "SYS-T RAW DATA: " prefix in the output_str */
72 	zassert_mem_equal(raw_data_str, output_str, strlen(raw_data_str),
73 			  "Incorrect Format comparison");
74 
75 	output_str += strlen(raw_data_str);
76 
77 	/* Validate the headers in the SYS-T data format */
78 	for (int i = 0; i < ARRAY_SIZE(syst_format_headers); i++) {
79 		zassert_mem_equal(output_str, syst_format_headers[i],
80 				  strlen(syst_format_headers[i]),
81 				  "Incorrect Comparison of %s", syst_headers_name[i]);
82 
83 		output_str = output_str+2;
84 	}
85 
86 	/* After the headers the output_str will contain the content of optional flags.
87 	 * Optional flags are contained in 1st byte of data in output_str. There are 4 bits
88 	 * reserved for Optional flags. 1st bit = Location, 2nd Bit = payload length
89 	 * 3rd bit = Sys-t Checksum, 4th bit = Sys-t Timestamp. Support for validating the
90 	 * content based on optional flags is not supported, hence the corresponding
91 	 * characters are skipped. skip_bytes array contains the number of hex characters
92 	 * to skip in the output_str.
93 	 */
94 	size_t skip_bytes[5] = {0, 18, 4, 8, 16};
95 
96 	for (int i = 1; i < ARRAY_SIZE(skip_bytes); i++) {
97 		if (is_kth_bit_set(strtol(optional_flags, 0, 16), i)) {
98 			output_str += skip_bytes[i];
99 		}
100 	}
101 
102 	zassert_mem_equal(output_str, payload, strlen(payload),
103 			  "Incorrect Comparison of payload");
104 
105 	memset(test_output_buf, 0, sizeof(test_output_buf));
106 	pos_in_buf = 0;
107 }
108 
format_set(const struct log_backend * const backend,uint32_t log_type)109 static int format_set(const struct log_backend *const backend, uint32_t log_type)
110 {
111 	log_format_current = log_type;
112 	return 0;
113 }
114 
mock_init(struct log_backend const * const backend)115 static void mock_init(struct log_backend const *const backend)
116 {
117 
118 }
119 
panic(struct log_backend const * const backend)120 static void panic(struct log_backend const *const backend)
121 {
122 
123 }
124 
125 const struct log_backend_api mock_log_backend_api = {
126 	.process = process,
127 	.init = mock_init,
128 	.format_set = format_set,
129 	.panic = panic
130 };
131