[cli] clean up coaps example implementation (#3795)

This commit is contained in:
Jonathan Hui
2019-05-06 08:48:02 -07:00
committed by Jonathan Hui
parent 1b9c50112e
commit d4063fe9b8
3 changed files with 345 additions and 360 deletions
+317 -342
View File
@@ -46,6 +46,15 @@
namespace ot {
namespace Cli {
const struct CoapSecure::Command CoapSecure::sCommands[] = {
{"help", &CoapSecure::ProcessHelp}, {"connect", &CoapSecure::ProcessConnect},
{"delete", &CoapSecure::ProcessRequest}, {"disconnect", &CoapSecure::ProcessDisconnect},
{"get", &CoapSecure::ProcessRequest}, {"post", &CoapSecure::ProcessRequest},
{"psk", &CoapSecure::ProcessPsk}, {"put", &CoapSecure::ProcessRequest},
{"resource", &CoapSecure::ProcessResource}, {"start", &CoapSecure::ProcessStart},
{"stop", &CoapSecure::ProcessStop}, {"x509", &CoapSecure::ProcessX509},
};
CoapSecure::CoapSecure(Interpreter &aInterpreter)
: mInterpreter(aInterpreter)
, mShutdownFlag(false)
@@ -58,39 +67,6 @@ CoapSecure::CoapSecure(Interpreter &aInterpreter)
memset(&mPskId, 0, sizeof(mPskId));
}
void CoapSecure::PrintHeaderInfos(otMessage *aMessage) const
{
otCoapCode mCoapCode;
otCoapType mCoapType;
mCoapCode = otCoapMessageGetCode(aMessage);
mCoapType = otCoapMessageGetType(aMessage);
mInterpreter.mServer->OutputFormat("\r\n CoapSecure RX Header Information:"
"\r\n Type %d => ",
static_cast<uint16_t>(mCoapType));
switch (mCoapType)
{
case OT_COAP_TYPE_ACKNOWLEDGMENT:
mInterpreter.mServer->OutputFormat("Ack");
break;
case OT_COAP_TYPE_CONFIRMABLE:
mInterpreter.mServer->OutputFormat("Confirmable");
break;
case OT_COAP_TYPE_NON_CONFIRMABLE:
mInterpreter.mServer->OutputFormat("NonConfirmable");
break;
case OT_COAP_TYPE_RESET:
mInterpreter.mServer->OutputFormat("Reset");
break;
default:
break;
}
mInterpreter.mServer->OutputFormat("\r\n Code %d => %s\r\n", static_cast<uint16_t>(mCoapCode),
static_cast<const char *>(otCoapMessageCodeToString(aMessage)));
}
void CoapSecure::PrintPayload(otMessage *aMessage) const
{
uint8_t buf[kMaxBufferSize];
@@ -100,341 +76,108 @@ void CoapSecure::PrintPayload(otMessage *aMessage) const
if (length > 0)
{
mInterpreter.mServer->OutputFormat(" With payload [UTF8]:\r\n", aMessage);
mInterpreter.mServer->OutputFormat(" with payload: ");
while (length > 0)
{
bytesToPrint = (length < sizeof(buf)) ? length : sizeof(buf);
otMessageRead(aMessage, otMessageGetOffset(aMessage) + bytesPrinted, buf, bytesToPrint);
for (int i = 0; i < bytesToPrint; i++)
{
mInterpreter.mServer->OutputFormat("%c", buf[i]);
}
mInterpreter.mServer->OutputFormat("\r\n");
mInterpreter.OutputBytes(buf, static_cast<uint8_t>(bytesToPrint));
length -= bytesToPrint;
bytesPrinted += bytesToPrint;
}
}
else
{
mInterpreter.mServer->OutputFormat(" No payload.");
}
mInterpreter.mServer->OutputFormat("\r\n> ");
mInterpreter.mServer->OutputFormat("\r\n");
}
otError CoapSecure::Process(int argc, char *argv[])
otError CoapSecure::ProcessHelp(int argc, char *argv[])
{
otError error = OT_ERROR_NONE;
bool mVerifyPeerCert = true;
long value;
OT_UNUSED_VARIABLE(argc);
OT_UNUSED_VARIABLE(argv);
VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
if (strcmp(argv[0], "start") == 0)
for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
{
if (argc > 1)
{
if (strcmp(argv[1], "false") == 0)
{
mVerifyPeerCert = false;
}
else if (strcmp(argv[1], "true") != 0)
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
}
otCoapSecureSetSslAuthMode(mInterpreter.mInstance, mVerifyPeerCert);
SuccessOrExit(error = otCoapSecureStart(mInterpreter.mInstance, OT_DEFAULT_COAP_SECURE_PORT));
otCoapSecureSetClientConnectedCallback(mInterpreter.mInstance, &CoapSecure::HandleClientConnect, this);
#if CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
otCoapSecureSetDefaultHandler(mInterpreter.mInstance, &CoapSecure::DefaultHandler, this);
#endif // CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
if (mUseCertificate)
{
mInterpreter.mServer->OutputFormat("Verify Peer Certificate: %s. Coap Secure service started: ",
mVerifyPeerCert ? "true" : "false");
}
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
mInterpreter.mServer->OutputFormat("%s\r\n", sCommands[i].mName);
}
else if (strcmp(argv[0], "set") == 0)
return OT_ERROR_NONE;
}
otError CoapSecure::ProcessResource(int argc, char *argv[])
{
otError error = OT_ERROR_NONE;
if (argc > 1)
{
if (argc > 1)
{
if (strcmp(argv[1], "psk") == 0)
{
if (argc > 3)
{
size_t length;
VerifyOrExit(strlen(argv[1]) < kMaxUriLength, error = OT_ERROR_INVALID_ARGS);
length = strlen(argv[2]);
VerifyOrExit(length <= sizeof(mPsk), error = OT_ERROR_INVALID_ARGS);
mPskLength = static_cast<uint8_t>(length);
memcpy(mPsk, argv[2], mPskLength);
length = strlen(argv[3]);
VerifyOrExit(length <= sizeof(mPskId), error = OT_ERROR_INVALID_ARGS);
mPskIdLength = static_cast<uint8_t>(length);
memcpy(mPskId, argv[3], mPskIdLength);
SuccessOrExit(
error = otCoapSecureSetPsk(mInterpreter.mInstance, mPsk, mPskLength, mPskId, mPskIdLength));
mUseCertificate = false;
mInterpreter.mServer->OutputFormat("Coap Secure set PSK: ");
}
else
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
}
else if (strcmp(argv[1], "x509") == 0)
{
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
SuccessOrExit(error = otCoapSecureSetCertificate(
mInterpreter.mInstance, (const uint8_t *)OT_CLI_COAPS_X509_CERT,
sizeof(OT_CLI_COAPS_X509_CERT), (const uint8_t *)OT_CLI_COAPS_PRIV_KEY,
sizeof(OT_CLI_COAPS_PRIV_KEY)));
SuccessOrExit(error = otCoapSecureSetCaCertificateChain(
mInterpreter.mInstance, (const uint8_t *)OT_CLI_COAPS_TRUSTED_ROOT_CERTIFICATE,
sizeof(OT_CLI_COAPS_TRUSTED_ROOT_CERTIFICATE)));
mUseCertificate = true;
mInterpreter.mServer->OutputFormat("Coap Secure set own .X509 certificate: ");
#else
ExitNow(error = OT_ERROR_DISABLED_FEATURE);
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
}
else
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
}
else
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
}
else if (strcmp(argv[0], "connect") == 0)
{
// Destination IPv6 address
if (argc > 1)
{
otSockAddr sockaddr;
memset(&sockaddr, 0, sizeof(sockaddr));
SuccessOrExit(error = otIp6AddressFromString(argv[1], &sockaddr.mAddress));
sockaddr.mPort = OT_DEFAULT_COAP_SECURE_PORT;
sockaddr.mScopeId = OT_NETIF_INTERFACE_ID_THREAD;
// check for port specification
if (argc > 2)
{
error = Interpreter::ParseLong(argv[2], value);
SuccessOrExit(error);
sockaddr.mPort = static_cast<uint16_t>(value);
}
SuccessOrExit(
error = otCoapSecureConnect(mInterpreter.mInstance, &sockaddr, &CoapSecure::HandleClientConnect, this));
mInterpreter.mServer->OutputFormat("Coap Secure connect: ");
}
else
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
}
else if (strcmp(argv[0], "resource") == 0)
{
mResource.mUriPath = mUriPath;
mResource.mContext = this;
mResource.mHandler = &CoapSecure::HandleServerResponse;
mResource.mHandler = &CoapSecure::HandleRequest;
if (argc > 1)
{
strlcpy(mUriPath, argv[1], kMaxUriLength);
SuccessOrExit(error = otCoapSecureAddResource(mInterpreter.mInstance, &mResource));
}
mInterpreter.mServer->OutputFormat("Resource name is '%s': ", mResource.mUriPath);
}
else if (strcmp(argv[0], "disconnect") == 0)
{
otCoapSecureDisconnect(mInterpreter.mInstance);
}
else if (strcmp(argv[0], "stop") == 0)
{
if (otCoapSecureIsConnectionActive(mInterpreter.mInstance))
{
otCoapSecureDisconnect(mInterpreter.mInstance);
mShutdownFlag = true;
}
else
{
Stop();
}
}
else if (strcmp(argv[0], "help") == 0)
{
mInterpreter.mServer->OutputFormat("CLI CoAPS help:\r\n\r\n");
mInterpreter.mServer->OutputFormat(">'coaps start (false)' "
": start coap secure service, false disable peer cert verification\r\n");
mInterpreter.mServer->OutputFormat(">'coaps set psk <psk> <client id>' "
": set Preshared Key and Client Identity (Ciphersuite PSK_AES128)\r\n");
mInterpreter.mServer->OutputFormat(">'coaps set x509' "
": set X509 Cert und Private Key (Ciphersuite ECDHE_ECDSA_AES128)\r\n");
mInterpreter.mServer->OutputFormat(">'coaps connect <servers ipv6 addr> (port)' "
": start dtls session with a server\r\n");
mInterpreter.mServer->OutputFormat(">'coaps get' 'coaps put' 'coaps post' 'coaps delete' "
": interact with coap resource from server, ipv6 is not need as client\r\n");
mInterpreter.mServer->OutputFormat(
" >> args:(ipv6_addr_srv) <coap_src> and, if you have payload: <con> <payload>\r\n");
mInterpreter.mServer->OutputFormat(">'coaps resource <uri>' "
": add a coap server resource with 'helloWorld' as content.\r\n");
mInterpreter.mServer->OutputFormat(">'coaps disconnect' "
": stop dtls session with a server\r\n");
mInterpreter.mServer->OutputFormat(">'coaps stop' "
": stop coap secure service\r\n");
mInterpreter.mServer->OutputFormat("\r\n legend: <>: must, (): opt "
"\r\n");
mInterpreter.mServer->OutputFormat("\r\n");
strlcpy(mUriPath, argv[1], kMaxUriLength);
SuccessOrExit(error = otCoapSecureAddResource(mInterpreter.mInstance, &mResource));
}
else
{
error = ProcessRequest(argc, argv);
mInterpreter.mServer->OutputFormat("%s\r\n", mResource.mUriPath);
}
exit:
return OT_ERROR_NONE;
}
otError CoapSecure::ProcessStart(int argc, char *argv[])
{
otError error;
bool verifyPeerCert = true;
if (argc > 1)
{
if (strcmp(argv[1], "false") == 0)
{
verifyPeerCert = false;
}
else if (strcmp(argv[1], "true") != 0)
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
}
otCoapSecureSetSslAuthMode(mInterpreter.mInstance, verifyPeerCert);
otCoapSecureSetClientConnectedCallback(mInterpreter.mInstance, &CoapSecure::HandleConnected, this);
#if CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
otCoapSecureSetDefaultHandler(mInterpreter.mInstance, &CoapSecure::DefaultHandler, this);
#endif
SuccessOrExit(error = otCoapSecureStart(mInterpreter.mInstance, OT_DEFAULT_COAP_SECURE_PORT));
exit:
return error;
}
void CoapSecure::Stop(void)
otError CoapSecure::ProcessStop(int argc, char *argv[])
{
OT_UNUSED_VARIABLE(argc);
OT_UNUSED_VARIABLE(argv);
otCoapRemoveResource(mInterpreter.mInstance, &mResource);
otCoapSecureStop(mInterpreter.mInstance);
mInterpreter.mServer->OutputFormat("Coap Secure service stopped");
}
void OTCALL CoapSecure::HandleClientConnect(bool aConnected, void *aContext)
{
static_cast<CoapSecure *>(aContext)->HandleClientConnect(aConnected);
}
void CoapSecure::HandleClientConnect(bool aConnected)
{
OT_UNUSED_VARIABLE(aConnected);
if (aConnected)
if (otCoapSecureIsConnectionActive(mInterpreter.mInstance))
{
mInterpreter.mServer->OutputFormat("CoAP Secure connected!\r\n> ");
otCoapSecureDisconnect(mInterpreter.mInstance);
mShutdownFlag = true;
}
else
{
if (!mShutdownFlag)
{
mInterpreter.mServer->OutputFormat("CoAP Secure not connected or disconnected.\r\n> ");
}
else
{
mInterpreter.mServer->OutputFormat("CoAP Secure disconnected before stop.\r\n> ");
Stop();
mInterpreter.mServer->OutputFormat(" Done\r\n> ");
mShutdownFlag = false;
}
}
}
void OTCALL CoapSecure::HandleServerResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
static_cast<CoapSecure *>(aContext)->HandleServerResponse(aMessage, aMessageInfo);
}
void CoapSecure::HandleServerResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
otError error = OT_ERROR_NONE;
otMessage *responseMessage = NULL;
otCoapCode responseCode = OT_COAP_CODE_EMPTY;
char responseContent[] = "helloWorld";
mInterpreter.mServer->OutputFormat(
"Received coap secure request from [%x:%x:%x:%x:%x:%x:%x:%x]: ",
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[0]), HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[1]),
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[2]), HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[3]),
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[4]), HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[5]),
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[6]), HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[7]));
switch (otCoapMessageGetCode(aMessage))
{
case OT_COAP_CODE_GET:
mInterpreter.mServer->OutputFormat("GET");
break;
case OT_COAP_CODE_DELETE:
mInterpreter.mServer->OutputFormat("DELETE");
break;
case OT_COAP_CODE_PUT:
mInterpreter.mServer->OutputFormat("PUT");
break;
case OT_COAP_CODE_POST:
mInterpreter.mServer->OutputFormat("POST");
break;
default:
mInterpreter.mServer->OutputFormat("Undefined\r\n");
return;
Stop();
}
PrintPayload(aMessage);
if ((otCoapMessageGetType(aMessage) == OT_COAP_TYPE_CONFIRMABLE) ||
(otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET))
{
if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
{
responseCode = OT_COAP_CODE_CONTENT;
}
else
{
responseCode = OT_COAP_CODE_VALID;
}
responseMessage = otCoapNewMessage(mInterpreter.mInstance, NULL);
VerifyOrExit(responseMessage != NULL, error = OT_ERROR_NO_BUFS);
otCoapMessageInit(responseMessage, OT_COAP_TYPE_ACKNOWLEDGMENT, responseCode);
otCoapMessageSetMessageId(responseMessage, otCoapMessageGetMessageId(aMessage));
otCoapMessageSetToken(responseMessage, otCoapMessageGetToken(aMessage), otCoapMessageGetTokenLength(aMessage));
if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
{
otCoapMessageSetPayloadMarker(responseMessage);
}
if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
{
SuccessOrExit(error = otMessageAppend(responseMessage, &responseContent, sizeof(responseContent)));
}
SuccessOrExit(error = otCoapSecureSendResponse(mInterpreter.mInstance, responseMessage, aMessageInfo));
}
exit:
if (error != OT_ERROR_NONE && responseMessage != NULL)
{
mInterpreter.mServer->OutputFormat("Cannot send coap secure response message: Error %d: %s\r\n", error,
otThreadErrorToString(error));
otMessageFree(responseMessage);
}
else if (responseCode >= OT_COAP_CODE_RESPONSE_MIN)
{
mInterpreter.mServer->OutputFormat("coap secure response sent successfully!\r\n");
}
return OT_ERROR_NONE;
}
otError CoapSecure::ProcessRequest(int argc, char *argv[])
@@ -541,15 +284,13 @@ otError CoapSecure::ProcessRequest(int argc, char *argv[])
if ((coapType == OT_COAP_TYPE_CONFIRMABLE) || (coapCode == OT_COAP_CODE_GET))
{
error = otCoapSecureSendRequest(mInterpreter.mInstance, message, &CoapSecure::HandleClientResponse, this);
error = otCoapSecureSendRequest(mInterpreter.mInstance, message, &CoapSecure::HandleResponse, this);
}
else
{
error = otCoapSecureSendRequest(mInterpreter.mInstance, message, NULL, NULL);
}
mInterpreter.mServer->OutputFormat("Sending coap secure request: ");
exit:
if ((error != OT_ERROR_NONE) && (message != NULL))
@@ -560,33 +301,268 @@ exit:
return error;
}
void OTCALL CoapSecure::HandleClientResponse(void * aContext,
otMessage * aMessage,
const otMessageInfo *aMessageInfo,
otError aError)
otError CoapSecure::ProcessConnect(int argc, char *argv[])
{
static_cast<CoapSecure *>(aContext)->HandleClientResponse(aMessage, aMessageInfo, aError);
otError error;
otSockAddr sockaddr;
VerifyOrExit(argc > 1, error = OT_ERROR_INVALID_ARGS);
// Destination IPv6 address
memset(&sockaddr, 0, sizeof(sockaddr));
SuccessOrExit(error = otIp6AddressFromString(argv[1], &sockaddr.mAddress));
sockaddr.mPort = OT_DEFAULT_COAP_SECURE_PORT;
sockaddr.mScopeId = OT_NETIF_INTERFACE_ID_THREAD;
// check for port specification
if (argc > 2)
{
long value;
error = Interpreter::ParseLong(argv[2], value);
SuccessOrExit(error);
sockaddr.mPort = static_cast<uint16_t>(value);
}
SuccessOrExit(error = otCoapSecureConnect(mInterpreter.mInstance, &sockaddr, &CoapSecure::HandleConnected, this));
exit:
return error;
}
void CoapSecure::HandleClientResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError)
otError CoapSecure::ProcessDisconnect(int argc, char *argv[])
{
OT_UNUSED_VARIABLE(argc);
OT_UNUSED_VARIABLE(argv);
otCoapSecureDisconnect(mInterpreter.mInstance);
return OT_ERROR_NONE;
}
otError CoapSecure::ProcessPsk(int argc, char *argv[])
{
otError error;
size_t length;
VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
length = strlen(argv[1]);
VerifyOrExit(length <= sizeof(mPsk), error = OT_ERROR_INVALID_ARGS);
mPskLength = static_cast<uint8_t>(length);
memcpy(mPsk, argv[1], mPskLength);
length = strlen(argv[2]);
VerifyOrExit(length <= sizeof(mPskId), error = OT_ERROR_INVALID_ARGS);
mPskIdLength = static_cast<uint8_t>(length);
memcpy(mPskId, argv[2], mPskIdLength);
SuccessOrExit(error = otCoapSecureSetPsk(mInterpreter.mInstance, mPsk, mPskLength, mPskId, mPskIdLength));
mUseCertificate = false;
exit:
return error;
}
otError CoapSecure::ProcessX509(int argc, char *argv[])
{
OT_UNUSED_VARIABLE(argc);
OT_UNUSED_VARIABLE(argv);
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
otError error;
SuccessOrExit(error = otCoapSecureSetCertificate(
mInterpreter.mInstance, (const uint8_t *)OT_CLI_COAPS_X509_CERT, sizeof(OT_CLI_COAPS_X509_CERT),
(const uint8_t *)OT_CLI_COAPS_PRIV_KEY, sizeof(OT_CLI_COAPS_PRIV_KEY)));
SuccessOrExit(error = otCoapSecureSetCaCertificateChain(mInterpreter.mInstance,
(const uint8_t *)OT_CLI_COAPS_TRUSTED_ROOT_CERTIFICATE,
sizeof(OT_CLI_COAPS_TRUSTED_ROOT_CERTIFICATE)));
mUseCertificate = true;
exit:
return error;
#else
return OT_ERROR_DISABLED_FEATURE
#endif
}
otError CoapSecure::Process(int argc, char *argv[])
{
otError error = OT_ERROR_PARSE;
if (argc < 1)
{
ProcessHelp(0, NULL);
error = OT_ERROR_INVALID_ARGS;
}
else
{
for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
{
if (strcmp(argv[0], sCommands[i].mName) == 0)
{
error = (this->*sCommands[i].mCommand)(argc, argv);
break;
}
}
}
return error;
}
void CoapSecure::Stop(void)
{
otCoapRemoveResource(mInterpreter.mInstance, &mResource);
otCoapSecureStop(mInterpreter.mInstance);
}
void CoapSecure::HandleConnected(bool aConnected, void *aContext)
{
static_cast<CoapSecure *>(aContext)->HandleConnected(aConnected);
}
void CoapSecure::HandleConnected(bool aConnected)
{
if (aConnected)
{
mInterpreter.mServer->OutputFormat("coaps connected\r\n");
}
else
{
mInterpreter.mServer->OutputFormat("coaps disconnected\r\n");
if (mShutdownFlag)
{
Stop();
mShutdownFlag = false;
}
}
}
void CoapSecure::HandleRequest(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
static_cast<CoapSecure *>(aContext)->HandleRequest(aMessage, aMessageInfo);
}
void CoapSecure::HandleRequest(otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
otError error = OT_ERROR_NONE;
otMessage *responseMessage = NULL;
otCoapCode responseCode = OT_COAP_CODE_EMPTY;
char responseContent[] = "helloWorld";
mInterpreter.mServer->OutputFormat(
"coaps request from [%x:%x:%x:%x:%x:%x:%x:%x] ", HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[0]),
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[1]), HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[2]),
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[3]), HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[4]),
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[5]), HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[6]),
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[7]));
switch (otCoapMessageGetCode(aMessage))
{
case OT_COAP_CODE_GET:
mInterpreter.mServer->OutputFormat("GET");
break;
case OT_COAP_CODE_DELETE:
mInterpreter.mServer->OutputFormat("DELETE");
break;
case OT_COAP_CODE_PUT:
mInterpreter.mServer->OutputFormat("PUT");
break;
case OT_COAP_CODE_POST:
mInterpreter.mServer->OutputFormat("POST");
break;
default:
mInterpreter.mServer->OutputFormat("Undefined\r\n");
return;
}
PrintPayload(aMessage);
if ((otCoapMessageGetType(aMessage) == OT_COAP_TYPE_CONFIRMABLE) ||
(otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET))
{
if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
{
responseCode = OT_COAP_CODE_CONTENT;
}
else
{
responseCode = OT_COAP_CODE_VALID;
}
responseMessage = otCoapNewMessage(mInterpreter.mInstance, NULL);
VerifyOrExit(responseMessage != NULL, error = OT_ERROR_NO_BUFS);
otCoapMessageInit(responseMessage, OT_COAP_TYPE_ACKNOWLEDGMENT, responseCode);
otCoapMessageSetMessageId(responseMessage, otCoapMessageGetMessageId(aMessage));
otCoapMessageSetToken(responseMessage, otCoapMessageGetToken(aMessage), otCoapMessageGetTokenLength(aMessage));
if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
{
otCoapMessageSetPayloadMarker(responseMessage);
}
if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_GET)
{
SuccessOrExit(error = otMessageAppend(responseMessage, &responseContent, sizeof(responseContent)));
}
SuccessOrExit(error = otCoapSecureSendResponse(mInterpreter.mInstance, responseMessage, aMessageInfo));
}
exit:
if (error != OT_ERROR_NONE)
{
if (responseMessage != NULL)
{
mInterpreter.mServer->OutputFormat("coaps send response error %d: %s\r\n", error,
otThreadErrorToString(error));
otMessageFree(responseMessage);
}
}
else if (responseCode >= OT_COAP_CODE_RESPONSE_MIN)
{
mInterpreter.mServer->OutputFormat("coaps response sent\r\n");
}
}
void CoapSecure::HandleResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError)
{
static_cast<CoapSecure *>(aContext)->HandleResponse(aMessage, aMessageInfo, aError);
}
void CoapSecure::HandleResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError)
{
OT_UNUSED_VARIABLE(aMessageInfo);
if (aError != OT_ERROR_NONE)
{
mInterpreter.mServer->OutputFormat("Error receiving coap secure response message: Error %d: %s\r\n", aError,
mInterpreter.mServer->OutputFormat("coaps receive response error %d: %s\r\n", aError,
otThreadErrorToString(aError));
}
else
{
mInterpreter.mServer->OutputFormat("Received coap secure response");
PrintHeaderInfos(aMessage);
mInterpreter.mServer->OutputFormat(
"coaps response from [%x:%x:%x:%x:%x:%x:%x:%x]", HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[0]),
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[1]), HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[2]),
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[3]), HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[4]),
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[5]), HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[6]),
HostSwap16(aMessageInfo->mPeerAddr.mFields.m16[7]));
PrintPayload(aMessage);
}
}
#if CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
void OTCALL CoapSecure::DefaultHandler(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
void CoapSecure::DefaultHandler(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
static_cast<CoapSecure *>(aContext)->DefaultHandler(aMessage, aMessageInfo);
}
@@ -610,8 +586,7 @@ void CoapSecure::DefaultHandler(otMessage *aMessage, const otMessageInfo *aMessa
}
exit:
mInterpreter.mServer->OutputFormat("Default handler called.\r\n> ");
return;
}
#endif // CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
+24 -14
View File
@@ -79,36 +79,46 @@ private:
kPskIdMaxLength = 32
};
void PrintHeaderInfos(otMessage *aMessage) const;
struct Command
{
const char *mName;
otError (CoapSecure::*mCommand)(int argc, char *argv[]);
};
void PrintPayload(otMessage *aMessage) const;
otError ProcessHelp(int argc, char *argv[]);
otError ProcessConnect(int argc, char *argv[]);
otError ProcessDisconnect(int argc, char *argv[]);
otError ProcessPsk(int argc, char *argv[]);
otError ProcessRequest(int argc, char *argv[]);
otError ProcessResource(int argc, char *argv[]);
otError ProcessStart(int argc, char *argv[]);
otError ProcessStop(int argc, char *argv[]);
otError ProcessX509(int argc, char *argv[]);
void Stop(void);
static void OTCALL HandleServerResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleServerResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo);
static void HandleRequest(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleRequest(otMessage *aMessage, const otMessageInfo *aMessageInfo);
static void OTCALL HandleClientResponse(void * aContext,
otMessage * aMessage,
const otMessageInfo *aMessageInfo,
otError aError);
void HandleClientResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError);
static void HandleResponse(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError);
void HandleResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, otError aError);
#if CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
static void OTCALL DefaultHandler(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void DefaultHandler(otMessage *aMessage, const otMessageInfo *aMessageInfo);
static void DefaultHandler(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void DefaultHandler(otMessage *aMessage, const otMessageInfo *aMessageInfo);
#endif // CLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER
static void OTCALL HandleClientConnect(bool aConnected, void *aContext);
void HandleClientConnect(bool aConnected);
static void HandleConnected(bool aConnected, void *aContext);
void HandleConnected(bool aConnected);
static const Command sCommands[];
Interpreter & mInterpreter;
otCoapResource mResource;
char mUriPath[kMaxUriLength];
Interpreter &mInterpreter;
bool mShutdownFlag;
bool mUseCertificate;
uint8_t mPsk[kPskMaxLength];
+4 -4
View File
@@ -854,7 +854,7 @@ class otCli:
self._expect('Done')
def coaps_start_psk(self, psk, pskIdentity):
cmd = 'coaps set psk ' + psk + ' ' + pskIdentity
cmd = 'coaps psk ' + psk + ' ' + pskIdentity
self.send_command(cmd)
self._expect('Done')
@@ -863,7 +863,7 @@ class otCli:
self._expect('Done')
def coaps_start_x509(self):
cmd = 'coaps set x509'
cmd = 'coaps x509'
self.send_command(cmd)
self._expect('Done')
@@ -898,7 +898,7 @@ class otCli:
else:
timeout = 5
self._expect('CoAP Secure connected!', timeout=timeout)
self._expect('coaps connected', timeout=timeout)
def coaps_disconnect(self):
cmd = 'coaps disconnect'
@@ -916,7 +916,7 @@ class otCli:
else:
timeout = 5
self._expect('Received coap secure response', timeout=timeout)
self._expect('coaps response', timeout=timeout)
def commissioner_mgmtset(self, tlvs_binary):
cmd = 'commissioner mgmtset binary ' + tlvs_binary