44 |
44 |
static size_t _channelwrite(void *instance, const uint8_t *bp, size_t n)
|
45 |
45 |
{
|
46 |
46 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) {
|
47 |
|
return streamWrite(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n);
|
|
47 |
return streamWrite(((AosShellChannel*)instance)->asyncchannel, bp, n);
|
48 |
48 |
} else {
|
49 |
49 |
return 0;
|
50 |
50 |
}
|
... | ... | |
55 |
55 |
*/
|
56 |
56 |
static size_t _channelread(void *instance, uint8_t *bp, size_t n)
|
57 |
57 |
{
|
58 |
|
return streamRead(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n);
|
|
58 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_INPUT_ENABLED) {
|
|
59 |
return streamRead(((AosShellChannel*)instance)->asyncchannel, bp, n);
|
|
60 |
} else {
|
|
61 |
return 0;
|
|
62 |
}
|
59 |
63 |
}
|
60 |
64 |
|
61 |
65 |
/**
|
... | ... | |
64 |
68 |
static msg_t _channelput(void *instance, uint8_t b)
|
65 |
69 |
{
|
66 |
70 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) {
|
67 |
|
return streamPut(((AosShellChannel*)instance)->iochannel->asyncchannel, b);
|
|
71 |
return streamPut(((AosShellChannel*)instance)->asyncchannel, b);
|
68 |
72 |
} else {
|
69 |
73 |
return MSG_RESET;
|
70 |
74 |
}
|
... | ... | |
75 |
79 |
*/
|
76 |
80 |
static msg_t _channelget(void *instance)
|
77 |
81 |
{
|
78 |
|
return streamGet(((AosShellChannel*)instance)->iochannel->asyncchannel);
|
|
82 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_INPUT_ENABLED) {
|
|
83 |
return streamGet(((AosShellChannel*)instance)->asyncchannel);
|
|
84 |
} else {
|
|
85 |
return MSG_RESET;
|
|
86 |
}
|
79 |
87 |
}
|
80 |
88 |
|
81 |
89 |
/**
|
... | ... | |
84 |
92 |
static msg_t _channelputt(void *instance, uint8_t b, systime_t time)
|
85 |
93 |
{
|
86 |
94 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) {
|
87 |
|
return chnPutTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, b, time);
|
|
95 |
return chnPutTimeout(((AosShellChannel*)instance)->asyncchannel, b, time);
|
88 |
96 |
} else {
|
89 |
97 |
return MSG_RESET;
|
90 |
98 |
}
|
... | ... | |
95 |
103 |
*/
|
96 |
104 |
static msg_t _channelgett(void *instance, systime_t time)
|
97 |
105 |
{
|
98 |
|
return chnGetTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, time);
|
|
106 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_INPUT_ENABLED) {
|
|
107 |
return chnGetTimeout(((AosShellChannel*)instance)->asyncchannel, time);
|
|
108 |
} else {
|
|
109 |
return MSG_RESET;
|
|
110 |
}
|
99 |
111 |
}
|
100 |
112 |
|
101 |
113 |
/**
|
... | ... | |
104 |
116 |
static size_t _channelwritet(void *instance, const uint8_t *bp, size_t n, systime_t time)
|
105 |
117 |
{
|
106 |
118 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) {
|
107 |
|
return chnWriteTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n, time);
|
|
119 |
return chnWriteTimeout(((AosShellChannel*)instance)->asyncchannel, bp, n, time);
|
108 |
120 |
} else {
|
109 |
121 |
return 0;
|
110 |
122 |
}
|
... | ... | |
115 |
127 |
*/
|
116 |
128 |
static size_t _channelreadt(void *instance, uint8_t *bp, size_t n, systime_t time)
|
117 |
129 |
{
|
118 |
|
return chnReadTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n, time);
|
|
130 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_INPUT_ENABLED) {
|
|
131 |
return chnReadTimeout(((AosShellChannel*)instance)->asyncchannel, bp, n, time);
|
|
132 |
} else {
|
|
133 |
return 0;
|
|
134 |
}
|
119 |
135 |
}
|
120 |
136 |
|
121 |
137 |
static const struct AosShellChannelVMT _channelvmt = {
|
... | ... | |
163 |
179 |
|
164 |
180 |
// local variables
|
165 |
181 |
AosShellChannel* channel = ((AosShellStream*)instance)->channel;
|
166 |
|
msg_t ret;
|
|
182 |
msg_t ret = MSG_OK;
|
167 |
183 |
|
168 |
184 |
// iterate through the list of channels
|
169 |
185 |
while (channel != NULL) {
|
170 |
|
ret = streamPut(channel, b);
|
171 |
|
if (ret != MSG_OK) {
|
172 |
|
return ret;
|
173 |
|
}
|
|
186 |
msg_t ret_ = streamPut(channel, b);
|
|
187 |
ret = (ret_ < ret) ? ret_ : ret;
|
174 |
188 |
channel = channel->next;
|
175 |
189 |
}
|
176 |
190 |
|
177 |
|
return MSG_OK;
|
|
191 |
return ret;
|
178 |
192 |
}
|
179 |
193 |
|
180 |
194 |
static msg_t _streamget(void *instance)
|
... | ... | |
535 |
549 |
// local variables
|
536 |
550 |
aos_shellaction_t action = AOS_SHELL_ACTION_NONE;
|
537 |
551 |
char c;
|
|
552 |
special_key_t key;
|
538 |
553 |
|
539 |
554 |
// initialize output variables
|
540 |
555 |
*n = 0;
|
541 |
556 |
|
542 |
557 |
// read character by character from the channel
|
543 |
558 |
while (chnReadTimeout(channel, (uint8_t*)&c, 1, TIME_IMMEDIATE)) {
|
544 |
|
special_key_t key = KEY_UNKNOWN;
|
|
559 |
key = KEY_UNKNOWN;
|
545 |
560 |
|
546 |
561 |
// parse escape sequence
|
547 |
562 |
if (shell->inputdata.escp > 0) {
|
... | ... | |
1094 |
1109 |
/**
|
1095 |
1110 |
* @brief Initialize an AosShellChannel object with the specified parameters.
|
1096 |
1111 |
*
|
1097 |
|
* @param[in] channel The AosShellChannel to initialize.
|
1098 |
|
* @param[in] iochannel An AosIOChannel this AosShellChannel is associated with.
|
|
1112 |
* @param[in] channel The AosShellChannel to initialize.
|
|
1113 |
* @param[in] asyncchannel An BaseAsynchronousChannel this AosShellChannel is associated with.
|
1099 |
1114 |
*/
|
1100 |
|
void aosShellChannelInit(AosShellChannel* channel, AosIOChannel* iochannel)
|
|
1115 |
void aosShellChannelInit(AosShellChannel* channel, BaseAsynchronousChannel* asyncchannel)
|
1101 |
1116 |
{
|
1102 |
1117 |
aosDbgCheck(channel != NULL);
|
1103 |
|
aosDbgCheck(iochannel != NULL && iochannel->asyncchannel != NULL);
|
|
1118 |
aosDbgCheck(asyncchannel != NULL);
|
1104 |
1119 |
|
1105 |
1120 |
channel->vmt = &_channelvmt;
|
1106 |
|
channel->iochannel = iochannel;
|
|
1121 |
channel->asyncchannel = asyncchannel;
|
|
1122 |
channel->listener.wflags = 0;
|
1107 |
1123 |
channel->next = NULL;
|
1108 |
1124 |
channel->flags = 0;
|
1109 |
1125 |
|
... | ... | |
1225 |
1241 |
void aosShellStreamAddChannel(AosShellStream* stream, AosShellChannel* channel)
|
1226 |
1242 |
{
|
1227 |
1243 |
aosDbgCheck(stream != NULL);
|
1228 |
|
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL && channel->next == NULL && (channel->flags & AOS_SHELLCHANNEL_ATTACHED) == 0);
|
|
1244 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL && channel->next == NULL && (channel->flags & AOS_SHELLCHANNEL_ATTACHED) == 0);
|
1229 |
1245 |
|
1230 |
1246 |
// prepend the new channel
|
1231 |
1247 |
chSysLock();
|
... | ... | |
1247 |
1263 |
aos_status_t aosShellStreamRemoveChannel(AosShellStream* stream, AosShellChannel* channel)
|
1248 |
1264 |
{
|
1249 |
1265 |
aosDbgCheck(stream != NULL);
|
1250 |
|
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL && channel->flags & AOS_SHELLCHANNEL_ATTACHED);
|
|
1266 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL && channel->flags & AOS_SHELLCHANNEL_ATTACHED);
|
1251 |
1267 |
|
1252 |
1268 |
// local varibales
|
1253 |
1269 |
AosShellChannel* prev = NULL;
|
... | ... | |
1282 |
1298 |
*/
|
1283 |
1299 |
void aosShellChannelInputEnable(AosShellChannel* channel)
|
1284 |
1300 |
{
|
1285 |
|
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL);
|
|
1301 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL);
|
1286 |
1302 |
|
1287 |
1303 |
chSysLock();
|
1288 |
1304 |
channel->listener.wflags |= CHN_INPUT_AVAILABLE;
|
... | ... | |
1299 |
1315 |
*/
|
1300 |
1316 |
void aosShellChannelInputDisable( AosShellChannel* channel)
|
1301 |
1317 |
{
|
1302 |
|
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL);
|
|
1318 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL);
|
1303 |
1319 |
|
1304 |
1320 |
chSysLock();
|
1305 |
1321 |
channel->listener.wflags &= ~CHN_INPUT_AVAILABLE;
|
... | ... | |
1316 |
1332 |
*/
|
1317 |
1333 |
void aosShellChannelOutputEnable(AosShellChannel* channel)
|
1318 |
1334 |
{
|
1319 |
|
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL);
|
|
1335 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL);
|
1320 |
1336 |
|
1321 |
1337 |
channel->flags |= AOS_SHELLCHANNEL_OUTPUT_ENABLED;
|
1322 |
1338 |
|
... | ... | |
1330 |
1346 |
*/
|
1331 |
1347 |
void aosShellChannelOutputDisable(AosShellChannel* channel)
|
1332 |
1348 |
{
|
1333 |
|
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL);
|
|
1349 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL);
|
1334 |
1350 |
|
1335 |
1351 |
channel->flags &= ~AOS_SHELLCHANNEL_OUTPUT_ENABLED;
|
1336 |
1352 |
|
... | ... | |
1361 |
1377 |
chEvtRegisterMask(((aos_shell_t*)shell)->os.eventSource, &(((aos_shell_t*)shell)->os.eventListener), AOS_SHELL_EVENTMASK_OS);
|
1362 |
1378 |
// register events to all input channels
|
1363 |
1379 |
for (channel = ((aos_shell_t*)shell)->stream.channel; channel != NULL; channel = channel->next) {
|
1364 |
|
chEvtRegisterMaskWithFlags(&(channel->iochannel->asyncchannel->event), &(channel->listener), AOS_SHELL_EVENTMASK_INPUT, channel->listener.wflags);
|
|
1380 |
chEvtRegisterMaskWithFlags(&(channel->asyncchannel->event), &(channel->listener), AOS_SHELL_EVENTMASK_INPUT, channel->listener.wflags);
|
1365 |
1381 |
}
|
1366 |
1382 |
|
1367 |
1383 |
// fire start event
|
... | ... | |
1401 |
1417 |
eventflags = chEvtGetAndClearFlags(&channel->listener);
|
1402 |
1418 |
// if there is new input
|
1403 |
1419 |
if (eventflags & CHN_INPUT_AVAILABLE) {
|
1404 |
|
// if the channel is configured as input
|
1405 |
|
if (channel->flags & AOS_SHELLCHANNEL_INPUT_ENABLED) {
|
1406 |
|
// read input from channel
|
1407 |
|
readeval = _readChannel((aos_shell_t*)shell, channel, &nchars);
|
1408 |
|
// parse input line to argument list only if the input shall be executed
|
1409 |
|
nargs = (readeval == AOS_SUCCESS && nchars > 0) ? _parseArguments((aos_shell_t*)shell) : 0;
|
1410 |
|
// check number of arguments
|
1411 |
|
if (nargs > ((aos_shell_t*)shell)->arglistsize) {
|
1412 |
|
// error too many arguments
|
1413 |
|
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "\ttoo many arguments\n");
|
1414 |
|
} else if (nargs > 0) {
|
1415 |
|
// search command list for arg[0] and execute callback
|
1416 |
|
cmd = ((aos_shell_t*)shell)->commands;
|
1417 |
|
while (cmd != NULL) {
|
1418 |
|
if (strcmp(((aos_shell_t*)shell)->arglist[0], cmd->name) == 0) {
|
1419 |
|
((aos_shell_t*)shell)->execstatus.command = cmd;
|
1420 |
|
chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_EXEC);
|
1421 |
|
((aos_shell_t*)shell)->execstatus.retval = cmd->callback((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, nargs, ((aos_shell_t*)shell)->arglist);
|
1422 |
|
chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_DONE);
|
1423 |
|
// notify if the command was not successful
|
1424 |
|
if (((aos_shell_t*)shell)->execstatus.retval != 0) {
|
1425 |
|
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "command returned exit status %d\n", ((aos_shell_t*)shell)->execstatus.retval);
|
1426 |
|
}
|
1427 |
|
break;
|
|
1420 |
// read input from channel
|
|
1421 |
readeval = _readChannel((aos_shell_t*)shell, channel, &nchars);
|
|
1422 |
// parse input line to argument list only if the input shall be executed
|
|
1423 |
nargs = (readeval == AOS_SUCCESS && nchars > 0) ? _parseArguments((aos_shell_t*)shell) : 0;
|
|
1424 |
// check number of arguments
|
|
1425 |
if (nargs > ((aos_shell_t*)shell)->arglistsize) {
|
|
1426 |
// error too many arguments
|
|
1427 |
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "\ttoo many arguments\n");
|
|
1428 |
} else if (nargs > 0) {
|
|
1429 |
// search command list for arg[0] and execute callback
|
|
1430 |
cmd = ((aos_shell_t*)shell)->commands;
|
|
1431 |
while (cmd != NULL) {
|
|
1432 |
if (strcmp(((aos_shell_t*)shell)->arglist[0], cmd->name) == 0) {
|
|
1433 |
((aos_shell_t*)shell)->execstatus.command = cmd;
|
|
1434 |
chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_EXEC);
|
|
1435 |
((aos_shell_t*)shell)->execstatus.retval = cmd->callback((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, nargs, ((aos_shell_t*)shell)->arglist);
|
|
1436 |
chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_DONE);
|
|
1437 |
// notify if the command was not successful
|
|
1438 |
if (((aos_shell_t*)shell)->execstatus.retval != 0) {
|
|
1439 |
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "command returned exit status %d\n", ((aos_shell_t*)shell)->execstatus.retval);
|
1428 |
1440 |
}
|
1429 |
|
cmd = cmd->next;
|
1430 |
|
} /* end of while */
|
1431 |
|
|
1432 |
|
// if no matching command was found, print an error
|
1433 |
|
if (cmd == NULL) {
|
1434 |
|
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "%s: command not found\n", ((aos_shell_t*)shell)->arglist[0]);
|
|
1441 |
break;
|
1435 |
1442 |
}
|
1436 |
|
}
|
|
1443 |
cmd = cmd->next;
|
|
1444 |
} /* end of while */
|
1437 |
1445 |
|
1438 |
|
// rreset some internal variables and eprint a new prompt
|
1439 |
|
if (readeval == AOS_SUCCESS && !chThdShouldTerminateX()) {
|
1440 |
|
((aos_shell_t*)shell)->inputdata.cursorpos = 0;
|
1441 |
|
((aos_shell_t*)shell)->inputdata.lineend = 0;
|
1442 |
|
_printPrompt((aos_shell_t*)shell);
|
|
1446 |
// if no matching command was found, print an error
|
|
1447 |
if (cmd == NULL) {
|
|
1448 |
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "%s: command not found\n", ((aos_shell_t*)shell)->arglist[0]);
|
1443 |
1449 |
}
|
1444 |
1450 |
}
|
1445 |
|
// if the channel is not configured as input
|
1446 |
|
else {
|
1447 |
|
// read but drop all data
|
1448 |
|
uint8_t c;
|
1449 |
|
while (chnReadTimeout(channel, &c, 1, TIME_IMMEDIATE)) {
|
1450 |
|
continue;
|
1451 |
|
}
|
|
1451 |
|
|
1452 |
// reset some internal variables and eprint a new prompt
|
|
1453 |
if (readeval == AOS_SUCCESS && !chThdShouldTerminateX()) {
|
|
1454 |
((aos_shell_t*)shell)->inputdata.cursorpos = 0;
|
|
1455 |
((aos_shell_t*)shell)->inputdata.lineend = 0;
|
|
1456 |
_printPrompt((aos_shell_t*)shell);
|
1452 |
1457 |
}
|
1453 |
1458 |
}
|
1454 |
1459 |
|