#define RM_TAG "OIC_RM_RAP"
/**
+ * Default routing option data length is 1 byte with any of the following values.
+ * 00 - source and destination address is not present.
+ * 01 - source and destination address is present with message type as ACK.
+ * 10 - source and destination address is present with message type as RESET.
+ * 11 - source and destination address is present with message type as NORMAL.
+ */
+#define DEFAULT_ROUTE_OPTION_LEN 1
+
+/**
* Minimum routing option data length is
- * length of src address(1byte) + length of destination address(1byte) + hop count(2bytes)
+ * Msg Type(1 bytes) + length of src address(1byte) + length of destination address(1byte) +
+ * Seq Num(2bytes)
+ */
+#define MIN_ROUTE_OPTION_LEN 5
+
+/**
+ * Acknowledge message type is denoted as 01000000
+ */
+#define ACK_MESSAGE_TYPE (1 << 6)
+
+/**
+ * Reset message type is denoted as 10000000
*/
-#define MIN_ROUTE_OPTION_LEN 4
+#define RST_MESSAGE_TYPE (1 << 7)
+
+/**
+ * Normal message type is denoted as 11000000
+ */
+#define NORMAL_MESSAGE_TYPE (3 << 6)
+
+/**
+ * Stack mode.
+ */
+static OCMode g_rmStackMode = OC_CLIENT;
+
+void RMSetStackMode(OCMode mode)
+{
+ g_rmStackMode = mode;
+}
// destination and source are <GatewayId><ClientId> here, where ClientId is optional.
-OCStackResult RMAddInfo(const char *destination, CAHeaderOption_t **options,
- uint8_t *numOptions)
+OCStackResult RMAddInfo(const char *destination, void *message, bool isRequest,
+ bool *doPost)
{
- OC_LOG(DEBUG, TAG, "IN");
- RM_NULL_CHECK_WITH_RET(options, TAG, "options");
- RM_NULL_CHECK_WITH_RET(numOptions, TAG, "numOptions");
+ RM_NULL_CHECK_WITH_RET(message, TAG, "options");
+
+ CAHeaderOption_t **options = NULL;
+ uint8_t *numOptions = NULL;
+
+ if (isRequest)
+ {
+ CARequestInfo_t *requestMsg = message;
+ options = &(requestMsg->info.options);
+ RM_NULL_CHECK_WITH_RET(options, TAG, "options");
+ numOptions = &(requestMsg->info.numOptions);
+ RM_NULL_CHECK_WITH_RET(numOptions, TAG, "numOptions");
+ }
+ else
+ {
+ CAResponseInfo_t *respMsg = message;
+ if ('\0' == destination[0] && (CA_EMPTY == respMsg->result))
+ {
+ OIC_LOG(DEBUG, TAG, "Response is for an Endpoint, No need to add the routing Option");
+ return OC_STACK_OK;
+ }
+ options = &(respMsg->info.options);
+ RM_NULL_CHECK_WITH_RET(options, TAG, "options");
+ numOptions = &(respMsg->info.numOptions);
+ RM_NULL_CHECK_WITH_RET(numOptions, TAG, "numOptions");
+ }
+
CAHeaderOption_t *optionPtr = NULL;
int8_t index = -1;
if (-1 < index)
{
- OC_LOG(INFO, TAG, "Route option is present");
+ OIC_LOG(INFO, TAG, "Route option is present");
optionPtr = *options;
}
else
{
- OC_LOG(INFO, TAG, "Route option is not present");
+ OIC_LOG(INFO, TAG, "Route option is not present");
index = *numOptions;
optionPtr = OICCalloc((*numOptions + 1), sizeof(CAHeaderOption_t));
if (!optionPtr)
{
- OC_LOG(ERROR, TAG, "OICCalloc failed");
+ OIC_LOG(ERROR, TAG, "OICCalloc failed");
return OC_STACK_NO_MEMORY;
}
RMRouteOption_t routeOption = {.destGw = 0};
if (*numOptions != index)
{
- OC_LOG(INFO, TAG, "Route option is already present");
+ OIC_LOG(INFO, TAG, "Route option is already present");
res = RMParseRouteOption(&optionPtr[index], &routeOption);
if (OC_STACK_OK != res)
{
- OC_LOG(ERROR, TAG, "RMParseRouteOption failed");
+ OIC_LOG(ERROR, TAG, "RMParseRouteOption failed");
return OC_STACK_ERROR;
}
}
+ if (!isRequest)
+ {
+ CAResponseInfo_t *respMsg = message;
+ if (CA_EMPTY == respMsg->result && CA_MSG_ACKNOWLEDGE == respMsg->info.type)
+ {
+ OIC_LOG(DEBUG, TAG, "CA_EMPTY WITH ACKNOWLEDGEMENT");
+ routeOption.msgType = ACK;
+ if (OC_SERVER == g_rmStackMode)
+ {
+ OIC_LOG(DEBUG, TAG, "This is server mode");
+ // Send the Empty message in the response with adding the MSGType in Route option.
+ respMsg->info.type = CA_MSG_NONCONFIRM;
+ respMsg->result = CA_CONTENT;
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "Send a POST request");
+ if (NULL != doPost)
+ {
+ *doPost = true;
+ }
+ }
+ }
+ else if (CA_EMPTY == respMsg->result && CA_MSG_RESET == respMsg->info.type)
+ {
+ OIC_LOG(DEBUG, TAG, "CA_EMPTY WITH RESET");
+ routeOption.msgType = RST;
+ respMsg->info.type = CA_MSG_NONCONFIRM;
+ respMsg->result = CA_CONTENT;
+ }
+ }
+
if(destination)
{
memcpy(&(routeOption.destGw), destination, sizeof(routeOption.destGw));
res = RMCreateRouteOption(&routeOption, optionPtr + index);
if (OC_STACK_OK != res)
{
- OC_LOG(ERROR, TAG, "Creation of routing option failed");
+ OIC_LOG(ERROR, TAG, "Creation of routing option failed");
OICFree(optionPtr);
return res;
}
*options = optionPtr;
}
- OC_LOG(DEBUG, TAG, "OUT");
return OC_STACK_OK;
}
OCStackResult RMUpdateInfo(CAHeaderOption_t **options, uint8_t *numOptions,
CAEndpoint_t *endpoint)
{
- OC_LOG(DEBUG, TAG, "IN");
RM_NULL_CHECK_WITH_RET(options, TAG, "options");
RM_NULL_CHECK_WITH_RET(*options, TAG, "invalid option");
RM_NULL_CHECK_WITH_RET(numOptions, TAG, "numOptions");
if (0 >= *numOptions)
{
- OC_LOG(ERROR, TAG, "Invalid arguement: numOptions");
+ OIC_LOG(ERROR, TAG, "Invalid arguement: numOptions");
return OC_STACK_ERROR;
}
if (-1 >= routeIndex)
{
- OC_LOG(DEBUG, TAG, "Nothing to remove.");
+ OIC_LOG(DEBUG, TAG, "Nothing to remove.");
return OC_STACK_OK;
}
// Update Endpoint with source address from RM header option.
- if (0 != (*options + routeIndex)->optionLength)
+ if (DEFAULT_ROUTE_OPTION_LEN < (*options + routeIndex)->optionLength )
{
uint8_t dLen = 0;
- uint16_t count = sizeof(dLen);
- memcpy(&dLen, (*options + routeIndex)->optionData, sizeof(dLen));
+ uint16_t count = sizeof(dLen) + DEFAULT_ROUTE_OPTION_LEN;
+ memcpy(&dLen, (*options + routeIndex)->optionData + DEFAULT_ROUTE_OPTION_LEN, sizeof(dLen));
count += dLen;
uint8_t sLen = 0;
memcpy(&sLen, (*options + routeIndex)->optionData + count, sizeof(sLen));
{
memcpy(endpoint->routeData, (*options + routeIndex)->optionData + count,
GATEWAY_ID_LENGTH);
- OC_LOG_V(DEBUG, TAG, "adding srcgid: %u in endpoint [%d]",
- *((uint32_t *)endpoint->routeData), sLen);
+
+ uint32_t rData1 = 0;
+ memcpy(&rData1, endpoint->routeData, sizeof(rData1));
+ OIC_LOG_V(DEBUG, TAG, "adding srcgid: %u in endpoint [%d]", rData1, sLen);
count += GATEWAY_ID_LENGTH;
{
memcpy(endpoint->routeData + GATEWAY_ID_LENGTH,
(*options + routeIndex)->optionData + count, ENDPOINT_ID_LENGTH);
- OC_LOG_V(DEBUG, TAG, "adding srceid: %u in endpoint",
- *((uint16_t *)(endpoint->routeData + GATEWAY_ID_LENGTH)));
+
+ uint16_t rData2 = 0;
+ memcpy(&rData2, endpoint->routeData + GATEWAY_ID_LENGTH, sizeof(rData2));
+ OIC_LOG_V(DEBUG, TAG, "adding srceid: %u in endpoint", rData2);
}
}
}
OICFree(*options);
*options = NULL;
}
- OC_LOG(DEBUG, TAG, "OUT");
return OC_STACK_OK;
}
void RMGetRouteOptionIndex(const CAHeaderOption_t *options, uint8_t numOptions, int8_t *index)
{
- OC_LOG(DEBUG, TAG, "IN");
- RM_NULL_CHECK_VOID(options, TAG, "options");
RM_NULL_CHECK_VOID(index, TAG, "index");
+
+ if (NULL == options)
+ {
+ OIC_LOG(INFO, TAG, "No existing options");
+ return;
+ }
+
for (uint32_t i = 0; i < numOptions; i++)
{
- OC_LOG_V(DEBUG, TAG, "Request- optionID: %u", options[i].optionID);
+ OIC_LOG_V(DEBUG, TAG, "Request- optionID: %u", options[i].optionID);
if (RM_OPTION_MESSAGE_SWITCHING == options[i].optionID)
{
- OC_LOG_V(INFO, TAG, "Found Option at %d", i);
+ OIC_LOG_V(INFO, TAG, "Found Option at %d", i);
*index = i;
break;
}
}
- OC_LOG(DEBUG, TAG, "OUT");
}
OCStackResult RMCreateRouteOption(const RMRouteOption_t *optValue, CAHeaderOption_t *options)
{
- OC_LOG(DEBUG, RM_TAG, "IN");
RM_NULL_CHECK_WITH_RET(optValue, RM_TAG, "optValue");
RM_NULL_CHECK_WITH_RET(options, RM_TAG, "options");
uint8_t sLen = (optValue->srcGw ? GATEWAY_ID_LENGTH:0) +
(optValue->srcEp ? ENDPOINT_ID_LENGTH:0);
- OC_LOG_V(DEBUG, RM_TAG, "createoption dlen %u slen [%u]", dLen, sLen);
- unsigned int totalLength = MIN_ROUTE_OPTION_LEN + dLen + sLen;
- void *tempData = OICCalloc(totalLength, sizeof(char));
- if (NULL == tempData)
+ OIC_LOG_V(DEBUG, RM_TAG, "createoption dlen %u slen [%u]", dLen, sLen);
+
+ unsigned int totalLength = 0;
+ uint8_t *tempData = NULL;
+
+ if (0 == dLen && 0 == sLen)
{
- OC_LOG(ERROR, RM_TAG, "Calloc failed");
- return OC_STACK_NO_MEMORY;
+ OIC_LOG(DEBUG, RM_TAG, "Source and destination is not present");
+ totalLength = DEFAULT_ROUTE_OPTION_LEN;
+ tempData = OICCalloc(totalLength, sizeof(char));
+ if (NULL == tempData)
+ {
+ OIC_LOG(ERROR, RM_TAG, "Calloc failed");
+ return OC_STACK_NO_MEMORY;
+ }
+
+ if (ACK == optValue->msgType)
+ {
+ OIC_LOG(DEBUG, RM_TAG, "OptValue ACK Message Type");
+ memset(tempData, ACK_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
+ }
+ else if (RST == optValue->msgType)
+ {
+ OIC_LOG(DEBUG, RM_TAG, "OptValue RST Message Type");
+ memset(tempData, RST_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
+ }
+ else
+ {
+ OIC_LOG(DEBUG, RM_TAG, "OptValue NOR Message Type");
+ memset(tempData, NORMAL_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
+ }
}
- memcpy(tempData, &dLen, sizeof(dLen));
- unsigned int count = sizeof(dLen);
- if (0 < dLen)
+ else
{
- if (optValue->destGw)
+ totalLength = MIN_ROUTE_OPTION_LEN + dLen + sLen;
+ tempData = OICCalloc(totalLength, sizeof(char));
+ if (NULL == tempData)
{
- memcpy(tempData + count, &(optValue->destGw), GATEWAY_ID_LENGTH);
- count += GATEWAY_ID_LENGTH;
+ OIC_LOG(ERROR, RM_TAG, "Calloc failed");
+ return OC_STACK_NO_MEMORY;
}
- if (optValue->destEp)
+ if (ACK == optValue->msgType)
{
- memcpy(tempData + count, &(optValue->destEp), ENDPOINT_ID_LENGTH);
- count += ENDPOINT_ID_LENGTH;
+ OIC_LOG(DEBUG, RM_TAG, "OptValue ACK Message Type");
+ memset(tempData, ACK_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
+ }
+ else if (RST == optValue->msgType)
+ {
+ OIC_LOG(DEBUG, RM_TAG, "OptValue RST Message Type");
+ memset(tempData, RST_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
+ }
+ else
+ {
+ OIC_LOG(DEBUG, RM_TAG, "OptValue NOR Message Type");
+ memset(tempData, NORMAL_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
}
- }
- memcpy(tempData + count, &sLen, sizeof(sLen));
- count += sizeof(sLen);
- if (0 < sLen)
- {
- if (optValue->srcGw)
+ memcpy(tempData + DEFAULT_ROUTE_OPTION_LEN, &dLen, sizeof(dLen));
+ unsigned int count = sizeof(dLen) + DEFAULT_ROUTE_OPTION_LEN;
+ if (0 < dLen)
{
- memcpy(tempData + count, &(optValue->srcGw), GATEWAY_ID_LENGTH);
- count += GATEWAY_ID_LENGTH;
+ if (optValue->destGw)
+ {
+ memcpy(tempData + count, &(optValue->destGw), GATEWAY_ID_LENGTH);
+ count += GATEWAY_ID_LENGTH;
+ }
+
+ if (optValue->destEp)
+ {
+ memcpy(tempData + count, &(optValue->destEp), ENDPOINT_ID_LENGTH);
+ count += ENDPOINT_ID_LENGTH;
+ }
}
- if (optValue->srcEp)
+ memcpy(tempData + count, &sLen, sizeof(sLen));
+ count += sizeof(sLen);
+ if (0 < sLen)
{
- memcpy(tempData + count, &(optValue->srcEp), ENDPOINT_ID_LENGTH);
- count += ENDPOINT_ID_LENGTH;
+ if (optValue->srcGw)
+ {
+ memcpy(tempData + count, &(optValue->srcGw), GATEWAY_ID_LENGTH);
+ count += GATEWAY_ID_LENGTH;
+ }
+
+ if (optValue->srcEp)
+ {
+ memcpy(tempData + count, &(optValue->srcEp), ENDPOINT_ID_LENGTH);
+ count += ENDPOINT_ID_LENGTH;
+ }
}
+
+ memcpy(tempData + count, &optValue->mSeqNum, sizeof(optValue->mSeqNum));
}
- memcpy(tempData + count, &optValue->mSeqNum, sizeof(optValue->mSeqNum));
memcpy(options->optionData, tempData, totalLength);
options->optionID = RM_OPTION_MESSAGE_SWITCHING;
options->optionLength = totalLength;
- OC_LOG_V(INFO, RM_TAG, "Option Length is %d", options->optionLength);
+ OIC_LOG_V(INFO, RM_TAG, "Option Length is %d", options->optionLength);
OICFree(tempData);
- OC_LOG(DEBUG, RM_TAG, "OUT");
return OC_STACK_OK;
}
OCStackResult RMParseRouteOption(const CAHeaderOption_t *options, RMRouteOption_t *optValue)
{
- OC_LOG(DEBUG, RM_TAG, "IN");
RM_NULL_CHECK_WITH_RET(options, RM_TAG, "options");
RM_NULL_CHECK_WITH_RET(optValue, RM_TAG, "optValue");
if (0 == options->optionLength)
{
- OC_LOG(ERROR, RM_TAG, "Option data is not present");
+ OIC_LOG(ERROR, RM_TAG, "Option data is not present");
return OC_STACK_ERROR;
}
- uint8_t dLen = 0 ;
- uint16_t count = sizeof(dLen);
- memcpy(&dLen, options->optionData, sizeof(dLen));
- if (0 < dLen)
- {
- memcpy(&(optValue->destGw), options->optionData + count, GATEWAY_ID_LENGTH);
- count += GATEWAY_ID_LENGTH;
+ OIC_LOG_V(DEBUG, RM_TAG, "Option Length is %d", options->optionLength);
+ uint8_t mType = 0;
+ memcpy(&mType, options->optionData, sizeof(mType));
- if (GATEWAY_ID_LENGTH < dLen)
- {
- memcpy(&(optValue->destEp), options->optionData + count, ENDPOINT_ID_LENGTH);
- count += ENDPOINT_ID_LENGTH;
- }
+ if (ACK_MESSAGE_TYPE == mType)
+ {
+ OIC_LOG(INFO, RM_TAG, "ACK_MESSAGE_TYPE");
+ optValue->msgType = ACK;
+ }
+ else if (RST_MESSAGE_TYPE == mType)
+ {
+ OIC_LOG(INFO, RM_TAG, "RST_MESSAGE_TYPE");
+ optValue->msgType = RST;
+ }
+ else if (NORMAL_MESSAGE_TYPE == mType)
+ {
+ OIC_LOG(INFO, RM_TAG, "NOR_MESSAGE_TYPE");
+ optValue->msgType = NOR;
}
- uint8_t sLen = 0;
- memcpy(&sLen, options->optionData + count, sizeof(sLen));
- count += sizeof(sLen);
- if (0 < sLen)
+ if (DEFAULT_ROUTE_OPTION_LEN == options->optionLength)
+ {
+ OIC_LOG(INFO, RM_TAG, "No source and destination are present");
+ }
+ else
{
- memcpy(&(optValue->srcGw), options->optionData + count, GATEWAY_ID_LENGTH);
- count += GATEWAY_ID_LENGTH;
+ uint8_t dLen = 0 ;
+ uint16_t count = DEFAULT_ROUTE_OPTION_LEN;
+ memcpy(&dLen, options->optionData + count, sizeof(dLen));
+ count += sizeof(dLen);
+ if (0 < dLen)
+ {
+ memcpy(&(optValue->destGw), options->optionData + count, GATEWAY_ID_LENGTH);
+ count += GATEWAY_ID_LENGTH;
- if (GATEWAY_ID_LENGTH < sLen)
+ if (GATEWAY_ID_LENGTH < dLen)
+ {
+ memcpy(&(optValue->destEp), options->optionData + count, ENDPOINT_ID_LENGTH);
+ count += ENDPOINT_ID_LENGTH;
+ }
+ }
+
+ uint8_t sLen = 0;
+ memcpy(&sLen, options->optionData + count, sizeof(sLen));
+ count += sizeof(sLen);
+ if (0 < sLen)
{
- memcpy(&(optValue->srcEp), options->optionData + count, ENDPOINT_ID_LENGTH);
- count += ENDPOINT_ID_LENGTH;
+ memcpy(&(optValue->srcGw), options->optionData + count, GATEWAY_ID_LENGTH);
+ count += GATEWAY_ID_LENGTH;
+
+ if (GATEWAY_ID_LENGTH < sLen)
+ {
+ memcpy(&(optValue->srcEp), options->optionData + count, ENDPOINT_ID_LENGTH);
+ count += ENDPOINT_ID_LENGTH;
+ }
}
+ memcpy(&optValue->mSeqNum, options->optionData + count, sizeof(optValue->mSeqNum));
}
- memcpy(&optValue->mSeqNum, options->optionData + count, sizeof(optValue->mSeqNum));
- OC_LOG_V(INFO, RM_TAG, "Option hopcount is %d", optValue->mSeqNum);
- OC_LOG_V(INFO, RM_TAG, "Option Sender Addr is [%u][%u]", optValue->srcGw, optValue->srcEp);
- OC_LOG_V(INFO, RM_TAG, "Option Dest Addr is [%u][%u]", optValue->destGw, optValue->destEp);
- OC_LOG(DEBUG, RM_TAG, "OUT");
+ OIC_LOG_V(INFO, RM_TAG, "Option hopcount is %d", optValue->mSeqNum);
+ OIC_LOG_V(INFO, RM_TAG, "Option Sender Addr is [%u][%u]", optValue->srcGw, optValue->srcEp);
+ OIC_LOG_V(INFO, RM_TAG, "Option Dest Addr is [%u][%u]", optValue->destGw, optValue->destEp);
+ OIC_LOG_V(INFO, RM_TAG, "Message Type is [%u]", optValue->msgType);
return OC_STACK_OK;
}