diff options
Diffstat (limited to 'lib/chibios-contrib/os/hal/src/usbh/hal_usbh_desciter.c')
-rw-r--r-- | lib/chibios-contrib/os/hal/src/usbh/hal_usbh_desciter.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/lib/chibios-contrib/os/hal/src/usbh/hal_usbh_desciter.c b/lib/chibios-contrib/os/hal/src/usbh/hal_usbh_desciter.c new file mode 100644 index 000000000..0ccf4e46b --- /dev/null +++ b/lib/chibios-contrib/os/hal/src/usbh/hal_usbh_desciter.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio | ||
3 | Copyright (C) 2015..2019 Diego Ismirlian, (dismirlian(at)google's mail) | ||
4 | |||
5 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | you may not use this file except in compliance with the License. | ||
7 | You may obtain a copy of the License at | ||
8 | |||
9 | http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | |||
11 | Unless required by applicable law or agreed to in writing, software | ||
12 | distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | See the License for the specific language governing permissions and | ||
15 | limitations under the License. | ||
16 | */ | ||
17 | |||
18 | #include "hal.h" | ||
19 | |||
20 | #if HAL_USE_USBH | ||
21 | |||
22 | #include "usbh/defs.h" | ||
23 | #include "usbh/desciter.h" | ||
24 | |||
25 | void cfg_iter_init(generic_iterator_t *icfg, const uint8_t *buff, uint16_t rem) { | ||
26 | icfg->valid = 0; | ||
27 | |||
28 | if ((rem < 2) || (buff[0] < 2) || (rem < buff[0]) | ||
29 | || (buff[0] < USBH_DT_CONFIG_SIZE) | ||
30 | || (buff[1] != USBH_DT_CONFIG)) | ||
31 | return; | ||
32 | |||
33 | if (rem > ((usbh_config_descriptor_t *)buff)->wTotalLength) { | ||
34 | rem = ((usbh_config_descriptor_t *)buff)->wTotalLength; | ||
35 | } | ||
36 | |||
37 | icfg->valid = 1; | ||
38 | icfg->rem = rem; | ||
39 | icfg->curr = buff; | ||
40 | } | ||
41 | |||
42 | void if_iter_next(if_iterator_t *iif) { | ||
43 | const uint8_t *curr = iif->curr; | ||
44 | uint16_t rem = iif->rem; | ||
45 | |||
46 | iif->valid = 0; | ||
47 | |||
48 | if ((rem < 2) || (curr[0] < 2) || (rem < curr[0])) | ||
49 | return; | ||
50 | |||
51 | for (;;) { | ||
52 | rem -= curr[0]; | ||
53 | curr += curr[0]; | ||
54 | |||
55 | if ((rem < 2) || (curr[0] < 2) || (rem < curr[0])) | ||
56 | return; | ||
57 | |||
58 | if (curr[1] == USBH_DT_INTERFACE_ASSOCIATION) { | ||
59 | if (curr[0] < USBH_DT_INTERFACE_ASSOCIATION_SIZE) | ||
60 | return; | ||
61 | |||
62 | iif->iad = (usbh_ia_descriptor_t *)curr; | ||
63 | |||
64 | } else if (curr[1] == USBH_DT_INTERFACE) { | ||
65 | if (curr[0] < USBH_DT_INTERFACE_SIZE) | ||
66 | return; | ||
67 | |||
68 | if (iif->iad) { | ||
69 | if ((curr[2] < iif->iad->bFirstInterface) | ||
70 | || (curr[2] >= (iif->iad->bFirstInterface + iif->iad->bInterfaceCount))) | ||
71 | iif->iad = 0; | ||
72 | } | ||
73 | break; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | iif->valid = 1; | ||
78 | iif->rem = rem; | ||
79 | iif->curr = curr; | ||
80 | } | ||
81 | |||
82 | void if_iter_init(if_iterator_t *iif, const generic_iterator_t *icfg) { | ||
83 | iif->iad = 0; | ||
84 | iif->curr = icfg->curr; | ||
85 | iif->rem = icfg->rem; | ||
86 | if_iter_next(iif); | ||
87 | } | ||
88 | |||
89 | void ep_iter_next(generic_iterator_t *iep) { | ||
90 | const uint8_t *curr = iep->curr; | ||
91 | uint16_t rem = iep->rem; | ||
92 | |||
93 | iep->valid = 0; | ||
94 | |||
95 | if ((rem < 2) || (curr[0] < 2) || (rem < curr[0])) | ||
96 | return; | ||
97 | |||
98 | for (;;) { | ||
99 | rem -= curr[0]; | ||
100 | curr += curr[0]; | ||
101 | |||
102 | if ((rem < 2) || (curr[0] < 2) || (rem < curr[0])) | ||
103 | return; | ||
104 | |||
105 | if ((curr[1] == USBH_DT_INTERFACE_ASSOCIATION) | ||
106 | || (curr[1] == USBH_DT_INTERFACE) | ||
107 | || (curr[1] == USBH_DT_CONFIG)) { | ||
108 | return; | ||
109 | } else if (curr[1] == USBH_DT_ENDPOINT) { | ||
110 | if (curr[0] < USBH_DT_ENDPOINT_SIZE) | ||
111 | return; | ||
112 | |||
113 | break; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | iep->valid = 1; | ||
118 | iep->rem = rem; | ||
119 | iep->curr = curr; | ||
120 | } | ||
121 | |||
122 | void ep_iter_init(generic_iterator_t *iep, const if_iterator_t *iif) { | ||
123 | iep->curr = iif->curr; | ||
124 | iep->rem = iif->rem; | ||
125 | ep_iter_next(iep); | ||
126 | } | ||
127 | |||
128 | void cs_iter_next(generic_iterator_t *ics) { | ||
129 | const uint8_t *curr = ics->curr; | ||
130 | uint16_t rem = ics->rem; | ||
131 | |||
132 | ics->valid = 0; | ||
133 | |||
134 | if ((rem < 2) || (curr[0] < 2) || (rem < curr[0])) | ||
135 | return; | ||
136 | |||
137 | rem -= curr[0]; | ||
138 | curr += curr[0]; | ||
139 | |||
140 | if ((rem < 2) || (curr[0] < 2) || (rem < curr[0])) | ||
141 | return; | ||
142 | |||
143 | if ((curr[1] == USBH_DT_INTERFACE_ASSOCIATION) | ||
144 | || (curr[1] == USBH_DT_INTERFACE) | ||
145 | || (curr[1] == USBH_DT_CONFIG) | ||
146 | || (curr[1] == USBH_DT_ENDPOINT)) { | ||
147 | return; | ||
148 | } | ||
149 | |||
150 | ics->valid = 1; | ||
151 | ics->rem = rem; | ||
152 | ics->curr = curr; | ||
153 | } | ||
154 | |||
155 | void cs_iter_init(generic_iterator_t *ics, const generic_iterator_t *iter) { | ||
156 | ics->curr = iter->curr; | ||
157 | ics->rem = iter->rem; | ||
158 | cs_iter_next(ics); | ||
159 | } | ||
160 | |||
161 | #endif | ||