-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathdiag_pkt.c
151 lines (138 loc) · 4.34 KB
/
diag_pkt.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
Copyright 2023 Quectel Wireless Solutions Co.,Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
static const int diag_pkt_debug = 0;
struct diag_pkt;
typedef void(handle_pkt_func)(struct diag_pkt *diag_pkt);
struct diag_pkt
{
size_t max_pkt_len;
size_t min_pkt_len;
uint32_t start_7e;
uint32_t last_7d;
uint32_t errors;
size_t pkt_len;
handle_pkt_func *handle_pkt;
uint8_t reserved[8];
uint8_t buf[0];
};
static struct diag_pkt *diag_pkt_malloc(size_t min_size, size_t max_size, uint32_t start_7e, handle_pkt_func handle_pkt)
{
struct diag_pkt *diag_pkt = (struct diag_pkt *)malloc((max_size + min_size) * 2);
if (!diag_pkt)
return NULL;
diag_pkt->max_pkt_len = max_size;
diag_pkt->min_pkt_len = min_size;
diag_pkt->start_7e = start_7e;
diag_pkt->last_7d = 0;
diag_pkt->errors = 0;
diag_pkt->pkt_len = 0;
diag_pkt->handle_pkt = handle_pkt;
return diag_pkt;
}
static void diag_pkt_input(struct diag_pkt *diag_pkt, const uint8_t *pSrc, size_t size)
{
size_t i;
if (diag_pkt->last_7d)
{
if (diag_pkt->start_7e == 0 || diag_pkt->pkt_len)
{
diag_pkt->buf[diag_pkt->pkt_len++] = (*pSrc ^ 0x20);
}
else
{
diag_pkt->errors++;
if (diag_pkt_debug)
qlog_dbg("should get 0x7e here 1 !\n");
}
pSrc++;
size--;
diag_pkt->last_7d = 0;
}
for (i = 0; i < size; i++)
{
if (*pSrc == 0x7d)
{
pSrc++;
i++;
if (i == size)
{
if (diag_pkt_debug)
qlog_dbg("last_7d\n");
diag_pkt->last_7d = 1;
break;
}
if (diag_pkt->start_7e == 0 || diag_pkt->pkt_len)
{
diag_pkt->buf[diag_pkt->pkt_len++] = (*pSrc++ ^ 0x20);
}
else
{
diag_pkt->errors++;
if (diag_pkt_debug)
qlog_dbg("should get 0x7e here 2 !\n");
}
}
else if (*pSrc == 0x7E)
{
diag_pkt->buf[diag_pkt->pkt_len++] = (*pSrc++);
if (diag_pkt->pkt_len >= diag_pkt->min_pkt_len)
{
static size_t max_pkt_size = 0;
if (diag_pkt->pkt_len > max_pkt_size)
{
max_pkt_size = diag_pkt->pkt_len;
if (diag_pkt_debug)
qlog_dbg("max_pkt_size %zd\n", max_pkt_size);
}
diag_pkt->handle_pkt(diag_pkt);
diag_pkt->pkt_len = 0;
}
else if (diag_pkt->start_7e && diag_pkt->pkt_len == 1)
{
qlog_dbg("start of frame\n");
}
else if (diag_pkt->start_7e && diag_pkt->pkt_len == 2)
{
diag_pkt->errors++;
if (diag_pkt_debug)
qlog_dbg("get 7e7e here!\n");
diag_pkt->pkt_len = 1;
}
else
{
diag_pkt->errors++;
if (diag_pkt_debug)
qlog_dbg("two short pkt len %zd!\n", diag_pkt->pkt_len);
diag_pkt->pkt_len = 0;
}
}
else if (diag_pkt->start_7e && diag_pkt->pkt_len == 0)
{
diag_pkt->errors++;
if (diag_pkt_debug)
qlog_dbg("should get 0x7e here 3 !\n");
pSrc++;
}
else
{
diag_pkt->buf[diag_pkt->pkt_len++] = (*pSrc++);
if (diag_pkt->pkt_len > diag_pkt->max_pkt_len)
{
diag_pkt->errors++;
if (diag_pkt_debug)
qlog_dbg("two long pkt len %zd!\n", diag_pkt->pkt_len);
diag_pkt->pkt_len = 0;
}
}
}
}