1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: diag rx
15 * This file should be changed only infrequently and with great care.
16 */
17 #include "zdiag_rx_api.h"
18 #include "securec.h"
19 #include "zdiag_mem.h"
20 #include "diag_pkt.h"
21 #include "errcode.h"
22 #include "diag_channel_item.h"
23 #include "zdiag_pkt_router.h"
24 #include "diag_adapt_layer.h"
25 #include "diag_dfx.h"
26
27 #define MUX_START_OFFSET 0
28 #define MAX_MUX_PARAM_SIZE 512
29
zdiag_find_start_flag(uint8_t * data,uint16_t size)30 STATIC int32_t zdiag_find_start_flag(uint8_t *data, uint16_t size)
31 {
32 int i;
33 int pos = -1;
34 uint32_t start_flag = MUX_START_FLAG;
35 for (i = 0; i < size; i++) {
36 uint8_t *flag = &data[i];
37 if (memcmp(flag, &start_flag, sizeof(start_flag)) == 0) {
38 pos = i;
39 break;
40 }
41 }
42 return pos;
43 }
44
soc_diag_chan_copy_data(diag_channel_item_t * item,uint8_t * data,uint16_t size)45 STATIC int32_t soc_diag_chan_copy_data(diag_channel_item_t *item, uint8_t *data, uint16_t size)
46 {
47 uint16_t free_size = item->rx_buf_len - item->rx_buf_pos;
48 uint16_t copy_size = uapi_min(size, free_size);
49 if (memcpy_s(&item->rx_buf[item->rx_buf_pos], free_size, data, copy_size) != EOK) {
50 return ERRCODE_FAIL;
51 }
52 item->rx_buf_pos += copy_size;
53 return copy_size;
54 }
55
diag_rest_rx_buf(diag_channel_item_t * item)56 STATIC void diag_rest_rx_buf(diag_channel_item_t *item)
57 {
58 item->rx_buf_pos = MUX_START_OFFSET;
59 item->rx_buf_is_using = false;
60 }
61
diag_get_rx_data_size(diag_channel_item_t * item)62 STATIC uint16_t diag_get_rx_data_size(diag_channel_item_t *item)
63 {
64 return item->rx_buf_pos - MUX_START_OFFSET;
65 }
66
diag_chan_full_pkt_receive(diag_channel_item_t * item)67 STATIC msp_mux_packet_head_stru_t *diag_chan_full_pkt_receive(diag_channel_item_t *item)
68 {
69 errcode_t ret;
70 msp_mux_packet_head_stru_t *mux = (msp_mux_packet_head_stru_t *)&item->rx_buf[MUX_START_OFFSET];
71 if (mux->packet_data_size > MAX_MUX_PARAM_SIZE) {
72 diag_rest_rx_buf(item);
73 return NULL;
74 }
75
76 if (diag_get_rx_data_size(item) < sizeof(msp_mux_packet_head_stru_t) + mux->packet_data_size) {
77 return NULL;
78 }
79
80 ret = zdiag_check_mux_pkt(mux, sizeof(msp_mux_packet_head_stru_t) + mux->packet_data_size);
81 if (ret != ERRCODE_SUCC) {
82 diag_rest_rx_buf(item);
83 return NULL;
84 }
85 return mux;
86 }
87
diag_chan_move_buf(diag_channel_item_t * item,uint32_t dst,uint32_t src,uint32_t len)88 STATIC errcode_t diag_chan_move_buf(diag_channel_item_t *item, uint32_t dst, uint32_t src, uint32_t len)
89 {
90 if (memmove_s(&item->rx_buf[dst], item->rx_buf_len, &item->rx_buf[src], len) != EOK) {
91 return ERRCODE_FAIL;
92 }
93 item->rx_buf_pos -= (uint16_t)(src - dst);
94 return ERRCODE_SUCC;
95 }
96
diag_chan_rx_mux_char_data(diag_channel_item_t * item,uint8_t * data,uint16_t size)97 STATIC int32_t diag_chan_rx_mux_char_data(diag_channel_item_t *item, uint8_t *data, uint16_t size)
98 {
99 int32_t copied_size = 0;
100 int32_t start_flag_pos;
101 int32_t frame_count = 0;
102 diag_pkt_process_param_t process_param;
103 diag_pkt_handle_t pkt;
104
105 while (copied_size != size && item->rx_buf_pos != item->rx_buf_len) { /* 数据未处理完成 并且 接收缓存有空间 */
106 copied_size += soc_diag_chan_copy_data(item, data + copied_size, (uint16_t)(size - copied_size));
107 if (item->rx_buf_is_using) {
108 return frame_count;
109 }
110
111 if (diag_get_rx_data_size(item) < sizeof(msp_mux_packet_head_stru_t)) {
112 continue;
113 }
114
115 start_flag_pos = zdiag_find_start_flag(&item->rx_buf[MUX_START_OFFSET], item->rx_buf_pos - MUX_START_OFFSET);
116 if (start_flag_pos < 0) {
117 diag_rest_rx_buf(item);
118 continue;
119 } else if (start_flag_pos > 0) {
120 diag_chan_move_buf(item, MUX_START_OFFSET, (uint32_t)start_flag_pos,
121 (uint32_t)(item->rx_buf_pos - start_flag_pos));
122 }
123
124 if (diag_get_rx_data_size(item) < sizeof(msp_mux_packet_head_stru_t)) {
125 continue;
126 }
127
128 do {
129 msp_mux_packet_head_stru_t *mux = diag_chan_full_pkt_receive(item);
130 if (mux == NULL) {
131 break;
132 }
133
134 item->au_id = mux->au_id;
135 mux->src = item->hso_addr;
136 mux->ctrl = 0;
137 if (mux->dst == 0) {
138 mux->dst = diag_adapt_get_local_addr();
139 }
140
141 diag_pkt_handle_init(&pkt, 1);
142 diag_pkt_handle_set_data(&pkt, DIAG_PKT_DATA_ID_DATA_0, (uint8_t*)mux,
143 sizeof(msp_mux_packet_head_stru_t) + mux->packet_data_size, DIAG_PKT_DATA_STACK);
144
145 process_param.cur_proc = DIAG_PKT_PROC_PORT_PKT;
146 diag_pkt_router(&pkt, &process_param);
147 frame_count++;
148 diag_chan_move_buf(item, MUX_START_OFFSET, sizeof(msp_mux_packet_head_stru_t) + mux->packet_data_size,
149 item->rx_buf_pos - (sizeof(msp_mux_packet_head_stru_t) + mux->packet_data_size));
150 } while (true);
151 }
152 return frame_count;
153 }
154
155 /* 字符串数据接收函数 */
soc_diag_channel_rx_mux_char_data(diag_channel_id_t id,uint8_t * data,uint16_t size)156 int32_t soc_diag_channel_rx_mux_char_data(diag_channel_id_t id, uint8_t *data, uint16_t size)
157 {
158 int32_t frame_cnt;
159 diag_channel_item_t *item = diag_chan_idx_2_item(id);
160
161 if (item == NULL) {
162 return ERRCODE_FAIL;
163 }
164
165 diag_dfx_channel_receive_data(id, size);
166 frame_cnt = diag_chan_rx_mux_char_data(item, data, size);
167 diag_dfx_channel_receive_frame(id, (uint32_t)frame_cnt);
168 return frame_cnt;
169 }
170
soc_diag_channel_rx_mux_data(diag_channel_id_t id,uint8_t * data,uint16_t size)171 errcode_t soc_diag_channel_rx_mux_data(diag_channel_id_t id, uint8_t *data, uint16_t size)
172 {
173 errcode_t ret;
174 diag_channel_item_t *item = diag_chan_idx_2_item(id);
175 msp_mux_packet_head_stru_t *mux = (msp_mux_packet_head_stru_t *)data;
176 diag_pkt_handle_t pkt;
177 diag_pkt_process_param_t process_param;
178
179 if (item == NULL) {
180 return ERRCODE_FAIL;
181 }
182
183 diag_dfx_channel_receive_data(id, size);
184
185 ret = zdiag_check_mux_pkt(mux, size);
186 if (ret != ERRCODE_SUCC) {
187 return ret;
188 }
189
190 diag_pkt_handle_init(&pkt, 1);
191 diag_pkt_handle_set_data(&pkt, DIAG_PKT_DATA_ID_DATA_0, (uint8_t*)mux,
192 sizeof(msp_mux_packet_head_stru_t) + mux->packet_data_size, DIAG_PKT_DATA_STACK);
193 process_param.cur_proc = DIAG_PKT_PROC_PORT_PKT;
194
195 return diag_pkt_router(&pkt, &process_param);
196 }
197