Skip to content

Commit 1512ed2

Browse files
Przemyslaw Bidakartben
authored andcommitted
net: openthread: Adding diag transmit command.
Commit adds `diag transmit` used for transmission IEEE802154 packets in specific amount and interval. Signed-off-by: Przemyslaw Bida <[email protected]>
1 parent 60a2888 commit 1512ed2

File tree

1 file changed

+169
-12
lines changed
  • modules/openthread/platform

1 file changed

+169
-12
lines changed

modules/openthread/platform/diag.c

Lines changed: 169 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,44 @@
88
#include <zephyr/drivers/gpio.h>
99

1010
#include <openthread/error.h>
11+
#include <openthread/platform/alarm-milli.h>
1112
#include <openthread/platform/diag.h>
13+
#include <openthread/platform/radio.h>
1214

1315
#include "platform-zephyr.h"
1416
#include "zephyr/sys/util.h"
1517

18+
enum {
19+
DIAG_TRANSMIT_MODE_IDLE,
20+
DIAG_TRANSMIT_MODE_PACKETS,
21+
DIAG_TRANSMIT_MODE_CARRIER,
22+
DIAG_TRANSMIT_MODE_MODCARRIER
23+
24+
} diag_trasmit_mode;
25+
1626
/**
1727
* Diagnostics mode variables.
1828
*
1929
*/
30+
2031
static bool sDiagMode;
2132
static void *sDiagCallbackContext;
2233
static otPlatDiagOutputCallback sDiagOutputCallback;
34+
static uint8_t sTransmitMode = DIAG_TRANSMIT_MODE_IDLE;
35+
static uint8_t sChannel = 20;
36+
static uint32_t sTxPeriod = 1;
37+
static int32_t sTxCount;
38+
static int32_t sTxRequestedCount = 1;
2339

2440
static otError startModCarrier(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]);
41+
static otError processTransmit(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]);
42+
43+
static otError parse_long(char *aArgs, long *aValue)
44+
{
45+
char *endptr;
46+
*aValue = strtol(aArgs, &endptr, 0);
47+
return (*endptr == '\0') ? OT_ERROR_NONE : OT_ERROR_PARSE;
48+
}
2549

2650
static void diag_output(const char *aFormat, ...)
2751
{
@@ -48,15 +72,16 @@ void otPlatDiagSetOutputCallback(otInstance *aInstance,
4872

4973
otError otPlatDiagProcess(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[])
5074
{
51-
ARG_UNUSED(aInstance);
52-
ARG_UNUSED(aArgsLength);
53-
5475
#if defined(CONFIG_IEEE802154_CARRIER_FUNCTIONS)
5576
if (strcmp(aArgs[0], "modcarrier") == 0) {
5677
return startModCarrier(aInstance, aArgsLength - 1, aArgs + 1);
5778
}
5879
#endif
5980

81+
if (strcmp(aArgs[0], "transmit") == 0) {
82+
return processTransmit(aInstance, aArgsLength - 1, aArgs + 1);
83+
}
84+
6085
/* Add more platform specific diagnostics features here. */
6186
diag_output("diag feature '%s' is not supported\r\n", aArgs[0]);
6287

@@ -80,6 +105,7 @@ bool otPlatDiagModeGet(void)
80105
void otPlatDiagChannelSet(uint8_t aChannel)
81106
{
82107
ARG_UNUSED(aChannel);
108+
sChannel = aChannel;
83109
}
84110

85111
void otPlatDiagTxPowerSet(int8_t aTxPower)
@@ -99,19 +125,21 @@ void otPlatDiagRadioReceived(otInstance *aInstance,
99125
#if defined(CONFIG_IEEE802154_CARRIER_FUNCTIONS)
100126
otError otPlatDiagRadioTransmitCarrier(otInstance *aInstance, bool aEnable)
101127
{
102-
if (!otPlatDiagModeGet()) {
128+
if (!otPlatDiagModeGet() || (sTransmitMode != DIAG_TRANSMIT_MODE_IDLE &&
129+
sTransmitMode != DIAG_TRANSMIT_MODE_CARRIER)) {
103130
return OT_ERROR_INVALID_STATE;
104131
}
105132

133+
if (aEnable) {
134+
sTransmitMode = DIAG_TRANSMIT_MODE_CARRIER;
135+
} else {
136+
sTransmitMode = DIAG_TRANSMIT_MODE_IDLE;
137+
}
138+
106139
return platformRadioTransmitCarrier(aInstance, aEnable);
107140
}
108141
#endif /* CONFIG_IEEE802154_CARRIER_FUNCTIONS */
109142

110-
void otPlatDiagAlarmCallback(otInstance *aInstance)
111-
{
112-
ARG_UNUSED(aInstance);
113-
}
114-
115143
/*
116144
* To enable gpio diag commands, in Devicetree create `openthread` node in `/options/` path
117145
* with `compatible = "openthread,config"` property and `diag-gpios` property,
@@ -291,25 +319,154 @@ otError otPlatDiagGpioGetMode(uint32_t aGpio, otGpioMode *aMode)
291319

292320
static otError startModCarrier(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[])
293321
{
294-
ARG_UNUSED(aInstance);
295-
ARG_UNUSED(aArgsLength);
296-
297322
bool enable = true;
298323
uint8_t data[OT_RADIO_FRAME_MAX_SIZE + 1];
299324

300325
if (aArgsLength <= 0) {
301326
return OT_ERROR_INVALID_ARGS;
302327
}
303328

329+
if (!otPlatDiagModeGet() || (sTransmitMode != DIAG_TRANSMIT_MODE_IDLE &&
330+
sTransmitMode != DIAG_TRANSMIT_MODE_MODCARRIER)) {
331+
return OT_ERROR_INVALID_STATE;
332+
}
333+
304334
if (strcmp(aArgs[0], "stop") == 0) {
305335
enable = false;
336+
sTransmitMode = DIAG_TRANSMIT_MODE_IDLE;
306337
} else {
307338
if (hex2bin(aArgs[0], strlen(aArgs[0]), data, ARRAY_SIZE(data)) == 0) {
308339
return OT_ERROR_INVALID_ARGS;
309340
}
341+
sTransmitMode = DIAG_TRANSMIT_MODE_MODCARRIER;
310342
}
311343

312344
return platformRadioTransmitModulatedCarrier(aInstance, enable, data);
313345
}
314346

315347
#endif
348+
349+
void otPlatDiagAlarmCallback(otInstance *aInstance)
350+
{
351+
uint32_t now;
352+
otRadioFrame *txPacket;
353+
const uint16_t diag_packet_len = 30;
354+
355+
if (sTransmitMode == DIAG_TRANSMIT_MODE_PACKETS) {
356+
if ((sTxCount > 0) || (sTxCount == -1)) {
357+
txPacket = otPlatRadioGetTransmitBuffer(aInstance);
358+
359+
txPacket->mInfo.mTxInfo.mTxDelayBaseTime = 0;
360+
txPacket->mInfo.mTxInfo.mTxDelay = 0;
361+
txPacket->mInfo.mTxInfo.mMaxCsmaBackoffs = 0;
362+
txPacket->mInfo.mTxInfo.mMaxFrameRetries = 0;
363+
txPacket->mInfo.mTxInfo.mRxChannelAfterTxDone = sChannel;
364+
txPacket->mInfo.mTxInfo.mTxPower = OT_RADIO_POWER_INVALID;
365+
txPacket->mInfo.mTxInfo.mIsHeaderUpdated = false;
366+
txPacket->mInfo.mTxInfo.mIsARetx = false;
367+
txPacket->mInfo.mTxInfo.mCsmaCaEnabled = false;
368+
txPacket->mInfo.mTxInfo.mCslPresent = false;
369+
txPacket->mInfo.mTxInfo.mIsSecurityProcessed = false;
370+
371+
txPacket->mLength = diag_packet_len;
372+
373+
for (uint8_t i = 0; i < diag_packet_len; i++) {
374+
txPacket->mPsdu[i] = i;
375+
}
376+
377+
otPlatRadioTransmit(aInstance, txPacket);
378+
379+
if (sTxCount != -1) {
380+
sTxCount--;
381+
}
382+
383+
now = otPlatAlarmMilliGetNow();
384+
otPlatAlarmMilliStartAt(aInstance, now, sTxPeriod);
385+
} else {
386+
sTransmitMode = DIAG_TRANSMIT_MODE_IDLE;
387+
otPlatAlarmMilliStop(aInstance);
388+
otPlatLog(OT_LOG_LEVEL_DEBG, OT_LOG_REGION_PLATFORM, "Transmit done");
389+
}
390+
}
391+
}
392+
393+
static otError processTransmit(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[])
394+
{
395+
otError error = OT_ERROR_NONE;
396+
long value;
397+
uint32_t now;
398+
399+
if (!otPlatDiagModeGet()) {
400+
return OT_ERROR_INVALID_STATE;
401+
}
402+
403+
if (aArgsLength == 0) {
404+
diag_output("transmit will send %" PRId32 " diagnostic messages with %" PRIu32
405+
" ms interval\r\n",
406+
sTxRequestedCount, sTxPeriod);
407+
408+
} else if (strcmp(aArgs[0], "stop") == 0) {
409+
if (sTransmitMode == DIAG_TRANSMIT_MODE_IDLE) {
410+
return OT_ERROR_INVALID_STATE;
411+
}
412+
413+
otPlatAlarmMilliStop(aInstance);
414+
diag_output("diagnostic message transmission is stopped\r\n");
415+
sTransmitMode = DIAG_TRANSMIT_MODE_IDLE;
416+
otPlatRadioReceive(aInstance, sChannel);
417+
418+
} else if (strcmp(aArgs[0], "start") == 0) {
419+
if (sTransmitMode != DIAG_TRANSMIT_MODE_IDLE) {
420+
return OT_ERROR_INVALID_STATE;
421+
}
422+
423+
otPlatAlarmMilliStop(aInstance);
424+
sTransmitMode = DIAG_TRANSMIT_MODE_PACKETS;
425+
sTxCount = sTxRequestedCount;
426+
now = otPlatAlarmMilliGetNow();
427+
otPlatAlarmMilliStartAt(aInstance, now, sTxPeriod);
428+
diag_output("sending %" PRId32 " diagnostic messages with %" PRIu32
429+
" ms interval\r\n",
430+
sTxRequestedCount, sTxPeriod);
431+
} else if (strcmp(aArgs[0], "interval") == 0) {
432+
433+
if (aArgsLength != 2) {
434+
return OT_ERROR_INVALID_ARGS;
435+
}
436+
437+
error = parse_long(aArgs[1], &value);
438+
if (error != OT_ERROR_NONE) {
439+
return error;
440+
}
441+
442+
if (value <= 0) {
443+
return OT_ERROR_INVALID_ARGS;
444+
}
445+
sTxPeriod = (uint32_t)(value);
446+
diag_output("set diagnostic messages interval to %" PRIu32
447+
" ms\r\n", sTxPeriod);
448+
449+
} else if (strcmp(aArgs[0], "count") == 0) {
450+
451+
if (aArgsLength != 2) {
452+
return OT_ERROR_INVALID_ARGS;
453+
}
454+
455+
error = parse_long(aArgs[1], &value);
456+
if (error != OT_ERROR_NONE) {
457+
return error;
458+
}
459+
460+
if ((value <= 0) && (value != -1)) {
461+
return OT_ERROR_INVALID_ARGS;
462+
}
463+
464+
sTxRequestedCount = (uint32_t)(value);
465+
diag_output("set diagnostic messages count to %" PRId32 "\r\n",
466+
sTxRequestedCount);
467+
} else {
468+
return OT_ERROR_INVALID_ARGS;
469+
}
470+
471+
return error;
472+
}

0 commit comments

Comments
 (0)