• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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