Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong
GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/wl/shared/wlu_common.c
17850 views
1
/*
2
* Common code for wl routines
3
*
4
* $Copyright (C) 2002-2005 Broadcom Corporation$
5
*
6
* $Id: wlu_common.c 288685 2011-10-08 00:50:34Z pgarg $
7
*/
8
9
#ifdef WIN32
10
#include <windows.h>
11
#endif
12
13
#include "wlu_common.h"
14
#include "wlu.h"
15
#include <bcmendian.h>
16
17
extern int wl_get(void *wl, int cmd, void *buf, int len);
18
extern int wl_set(void *wl, int cmd, void *buf, int len);
19
20
wl_cmd_list_t cmd_list;
21
int cmd_pkt_list_num;
22
bool cmd_batching_mode;
23
24
const char *wlu_av0;
25
26
#ifdef SERDOWNLOAD
27
extern int debug;
28
#endif
29
30
#ifdef ATE_BUILD
31
int wlu_iovar_get(void *wl, const char *iovar, void *outbuf, int len);
32
int wlu_get(void *wl, int cmd, void *cmdbuf, int len);
33
int wlu_set(void *wl, int cmd, void *cmdbuf, int len);
34
int add_one_batched_cmd(int cmd, void *cmdbuf, int len);
35
int wlu_iovar_setint(void *wl, const char *iovar, int val);
36
int wlu_iovar_set(void *wl, const char *iovar, void *param, int paramlen);
37
#endif /* ATE_BUILD */
38
39
/*
40
* format an iovar buffer
41
* iovar name is converted to lower case
42
*/
43
static uint
44
wl_iovar_mkbuf(const char *name, char *data, uint datalen, char *iovar_buf, uint buflen, int *perr)
45
{
46
uint iovar_len;
47
char *p;
48
49
iovar_len = strlen(name) + 1;
50
51
/* check for overflow */
52
if ((iovar_len + datalen) > buflen) {
53
*perr = BCME_BUFTOOSHORT;
54
return 0;
55
}
56
57
/* copy data to the buffer past the end of the iovar name string */
58
if (datalen > 0)
59
memmove(&iovar_buf[iovar_len], data, datalen);
60
61
/* copy the name to the beginning of the buffer */
62
strcpy(iovar_buf, name);
63
64
/* wl command line automatically converts iovar names to lower case for
65
* ease of use
66
*/
67
p = iovar_buf;
68
while (*p != '\0') {
69
*p = tolower((int)*p);
70
p++;
71
}
72
73
*perr = 0;
74
return (iovar_len + datalen);
75
}
76
77
void
78
init_cmd_batchingmode(void)
79
{
80
cmd_pkt_list_num = 0;
81
cmd_batching_mode = FALSE;
82
}
83
84
void
85
clean_up_cmd_list(void)
86
{
87
wl_seq_cmd_pkt_t *this_cmd, *next_cmd;
88
89
this_cmd = cmd_list.head;
90
while (this_cmd != NULL) {
91
next_cmd = this_cmd->next;
92
if (this_cmd->data != NULL) {
93
free(this_cmd->data);
94
}
95
free(this_cmd);
96
this_cmd = next_cmd;
97
}
98
cmd_list.head = NULL;
99
cmd_list.tail = NULL;
100
cmd_pkt_list_num = 0;
101
}
102
103
int
104
add_one_batched_cmd(int cmd, void *cmdbuf, int len)
105
{
106
wl_seq_cmd_pkt_t *new_cmd;
107
108
new_cmd = malloc(sizeof(wl_seq_cmd_pkt_t));
109
110
if (new_cmd == NULL) {
111
printf("malloc(%d) failed, free %d batched commands and exit batching mode\n",
112
(int)sizeof(wl_seq_cmd_pkt_t), cmd_pkt_list_num);
113
goto free_and_exit;
114
} else {
115
#ifdef SERDOWNLOAD
116
if (debug)
117
#endif /* SERDOWNLOAD */
118
printf("batching %dth command %d\n", cmd_pkt_list_num+1, cmd);
119
120
}
121
122
new_cmd->cmd_header.cmd = cmd;
123
new_cmd->cmd_header.len = len;
124
new_cmd->next = NULL;
125
126
new_cmd->data = malloc(len);
127
128
if (new_cmd->data == NULL) {
129
printf("malloc(%d) failed, free %d batched commands and exit batching mode\n",
130
len, cmd_pkt_list_num);
131
free(new_cmd);
132
goto free_and_exit;
133
}
134
135
memcpy(new_cmd->data, cmdbuf, len);
136
137
if (cmd_list.tail != NULL)
138
cmd_list.tail->next = new_cmd;
139
else
140
cmd_list.head = new_cmd;
141
142
cmd_list.tail = new_cmd;
143
144
cmd_pkt_list_num ++;
145
return 0;
146
147
free_and_exit:
148
149
clean_up_cmd_list();
150
151
if (cmd_batching_mode) {
152
cmd_batching_mode = FALSE;
153
}
154
else {
155
printf("calling add_one_batched_cmd() at non-command-batching mode, weird\n");
156
}
157
158
return -1;
159
}
160
161
#ifndef ATE_BUILD
162
int
163
wlu_get_req_buflen(int cmd, void *cmdbuf, int len)
164
{
165
int modified_len = len;
166
char *cmdstr = (char *)cmdbuf;
167
168
if (len == WLC_IOCTL_MAXLEN) {
169
if ((strcmp(cmdstr, "dump") == 0) ||
170
(cmd == WLC_SCAN_RESULTS))
171
modified_len = WLC_IOCTL_MAXLEN;
172
else
173
modified_len = WLC_IOCTL_MEDLEN;
174
}
175
return modified_len;
176
}
177
#endif /* !ATE_BUILD */
178
179
/* now IOCTL GET commands shall call wlu_get() instead of wl_get() so that the commands
180
* can be batched when needed
181
*/
182
int
183
wlu_get(void *wl, int cmd, void *cmdbuf, int len)
184
{
185
if (cmd_batching_mode) {
186
if (!WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd)) {
187
printf("IOCTL GET command %d is not supported in batching mode\n", cmd);
188
return IOCTL_ERROR;
189
}
190
}
191
192
return wl_get(wl, cmd, cmdbuf, len);
193
}
194
195
/* now IOCTL SET commands shall call wlu_set() instead of wl_set() so that the commands
196
* can be batched when needed
197
*/
198
int
199
wlu_set(void *wl, int cmd, void *cmdbuf, int len)
200
{
201
if (cmd_batching_mode) {
202
return add_one_batched_cmd(cmd, cmdbuf, len);
203
}
204
else {
205
return wl_set(wl, cmd, cmdbuf, len);
206
}
207
}
208
209
/*
210
* get named iovar providing both parameter and i/o buffers
211
* iovar name is converted to lower case
212
*/
213
int
214
wlu_iovar_getbuf(void* wl, const char *iovar,
215
void *param, int paramlen, void *bufptr, int buflen)
216
{
217
int err;
218
219
wl_iovar_mkbuf(iovar, param, paramlen, bufptr, buflen, &err);
220
if (err)
221
return err;
222
223
return wlu_get(wl, WLC_GET_VAR, bufptr, buflen);
224
}
225
226
/*
227
* set named iovar providing both parameter and i/o buffers
228
* iovar name is converted to lower case
229
*/
230
int
231
wlu_iovar_setbuf(void* wl, const char *iovar,
232
void *param, int paramlen, void *bufptr, int buflen)
233
{
234
int err;
235
int iolen;
236
237
iolen = wl_iovar_mkbuf(iovar, param, paramlen, bufptr, buflen, &err);
238
if (err)
239
return err;
240
241
return wlu_set(wl, WLC_SET_VAR, bufptr, iolen);
242
}
243
244
/*
245
* get named iovar without parameters into a given buffer
246
* iovar name is converted to lower case
247
*/
248
int
249
wlu_iovar_get(void *wl, const char *iovar, void *outbuf, int len)
250
{
251
char smbuf[WLC_IOCTL_SMLEN];
252
int err;
253
254
/* use the return buffer if it is bigger than what we have on the stack */
255
if (len > (int)sizeof(smbuf)) {
256
err = wlu_iovar_getbuf(wl, iovar, NULL, 0, outbuf, len);
257
} else {
258
memset(smbuf, 0, sizeof(smbuf));
259
err = wlu_iovar_getbuf(wl, iovar, NULL, 0, smbuf, sizeof(smbuf));
260
if (err == 0)
261
memcpy(outbuf, smbuf, len);
262
}
263
264
return err;
265
}
266
267
/*
268
* set named iovar given the parameter buffer
269
* iovar name is converted to lower case
270
*/
271
int
272
wlu_iovar_set(void *wl, const char *iovar, void *param, int paramlen)
273
{
274
char smbuf[WLC_IOCTL_SMLEN*2];
275
276
memset(smbuf, 0, sizeof(smbuf));
277
278
return wlu_iovar_setbuf(wl, iovar, param, paramlen, smbuf, sizeof(smbuf));
279
}
280
281
/*
282
* get named iovar as an integer value
283
* iovar name is converted to lower case
284
*/
285
int
286
wlu_iovar_getint(void *wl, const char *iovar, int *pval)
287
{
288
int ret;
289
290
ret = wlu_iovar_get(wl, iovar, pval, sizeof(int));
291
if (ret >= 0)
292
{
293
*pval = dtoh32(*pval);
294
}
295
return ret;
296
}
297
298
/*
299
* set named iovar given an integer parameter
300
* iovar name is converted to lower case
301
*/
302
int
303
wlu_iovar_setint(void *wl, const char *iovar, int val)
304
{
305
val = htod32(val);
306
return wlu_iovar_set(wl, iovar, &val, sizeof(int));
307
}
308
309