// For details on compatibility and glibc support,
// Refer http://www.gnu.org/software/libc/manual/html_node/BSD-Random.html
#define _DEFAULT_SOURCE
-#define _BSD_SOURCE
// Defining _POSIX_C_SOURCE macro with 199309L (or greater) as value
// causes header files to expose definitions
#define _POSIX_C_SOURCE 200809L
#endif
+#include "iotivity_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef TB_LOG
+#include <inttypes.h>
+#endif
#ifndef SINGLE_THREAD
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#include <time.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
+#ifdef HAVE_SYS_TIMEB_H
+#include <sys/timeb.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#endif
#if defined(__ANDROID__)
#include <linux/time.h>
#include "caremotehandler.h"
#include "caprotocolmessage.h"
#include "oic_malloc.h"
+#include "oic_time.h"
+#include "ocrandom.h"
#include "logger.h"
-#define TAG "CA"
+#define TAG "OIC_CA_RETRANS"
typedef struct
{
#endif
uint8_t triedCount; /**< retransmission count */
uint16_t messageId; /**< coap PDU message id */
+ CADataType_t dataType; /**< data Type (Request/Response) */
CAEndpoint_t *endpoint; /**< remote endpoint */
void *pdu; /**< coap PDU */
uint32_t size; /**< coap PDU size */
} CARetransmissionData_t;
static const uint64_t USECS_PER_SEC = 1000000;
-
-/**
- * @brief getCurrent monotonic time
- * @return current time in microseconds
- */
-uint64_t getCurrentTimeInMicroSeconds();
+static const uint64_t MSECS_PER_SEC = 1000;
#ifndef SINGLE_THREAD
/**
*/
static uint64_t CAGetTimeoutValue()
{
- return ((DEFAULT_ACK_TIMEOUT_SEC * 1000) + ((1000 * (random() & 0xFF)) >> 8)) *
+ return ((DEFAULT_ACK_TIMEOUT_SEC * 1000) + ((1000 * OCGetRandomByte()) >> 8)) *
(uint64_t) 1000;
}
if (currentTime >= retData->timeStamp + timeout)
{
- OIC_LOG_V(DEBUG, TAG, "%d microseconds time out!!, tried count(%ld)",
+ OIC_LOG_V(DEBUG, TAG, "%" PRIu64 " microseconds time out!!, tried count(%d)",
timeout, retData->triedCount);
return true;
}
#else
// #1. calculate timeout
- uint64_t timeOut = (2 << retData->triedCount) * 1000000;
+ uint64_t timeOut = (2 << retData->triedCount) * (uint64_t) 1000000;
if (currentTime >= retData->timeStamp + timeOut)
{
continue;
}
- uint64_t currentTime = getCurrentTimeInMicroSeconds();
+ uint64_t currentTime = OICGetCurrentTime(TIME_IN_US);
if (CACheckTimeout(currentTime, retData))
{
{
OIC_LOG_V(DEBUG, TAG, "retransmission CON data!!, msgid=%d",
retData->messageId);
- context->dataSendMethod(retData->endpoint, retData->pdu, retData->size);
+ context->dataSendMethod(retData->endpoint, retData->pdu,
+ retData->size, retData->dataType);
}
// #3. increase the retransmission count and update timestamp.
else if (!context->isStop)
{
// check each RETRANSMISSION_CHECK_PERIOD_SEC time.
- OIC_LOG_V(DEBUG, TAG, "wait..(%ld)microseconds",
+ OIC_LOG_V(DEBUG, TAG, "wait..(%" PRIu64 ")microseconds",
RETRANSMISSION_CHECK_PERIOD_SEC * (uint64_t) USECS_PER_SEC);
// wait
memset(context, 0, sizeof(CARetransmission_t));
- CARetransmissionConfig_t cfg = { 0 };
+ CARetransmissionConfig_t cfg = { .supportType = DEFAULT_RETRANSMISSION_TYPE,
+ .tryingCount = DEFAULT_RETRANSMISSION_COUNT };
- if (NULL == config)
- {
- // setDefault
- cfg.supportType = DEFAULT_RETRANSMISSION_TYPE;
- cfg.tryingCount = DEFAULT_RETRANSMISSION_COUNT;
- }
- else
+ if (config)
{
cfg = *config;
}
CAResult_t CARetransmissionSentData(CARetransmission_t *context,
const CAEndpoint_t *endpoint,
+ CADataType_t dataType,
const void *pdu, uint32_t size)
{
if (NULL == context || NULL == endpoint || NULL == pdu)
}
// #2. add additional information. (time stamp, retransmission count...)
- retData->timeStamp = getCurrentTimeInMicroSeconds();
+ retData->timeStamp = OICGetCurrentTime(TIME_IN_US);
#ifndef SINGLE_THREAD
retData->timeout = CAGetTimeoutValue();
#endif
retData->endpoint = remoteEndpoint;
retData->pdu = pduData;
retData->size = size;
+ retData->dataType = dataType;
#ifndef SINGLE_THREAD
// mutex lock
ca_mutex_lock(context->threadMutex);
// ACK, RST --> remove the CON data
CAMessageType_t type = CAGetMessageTypeFromPduBinaryData(pdu, size);
uint16_t messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
+ CAResponseResult_t code = CAGetCodeFromPduBinaryData(pdu, size);
- OIC_LOG_V(DEBUG, TAG, "received pdu, msgtype=%d, msgid=%d", type, messageId);
+ OIC_LOG_V(DEBUG, TAG, "received pdu, msgtype=%d, msgid=%d, code=%d",
+ type, messageId, code);
- if ((CA_MSG_ACKNOWLEDGE != type) && (CA_MSG_RESET != type))
+ if (((CA_MSG_ACKNOWLEDGE != type) && (CA_MSG_RESET != type))
+ || (CA_MSG_RESET == type && CA_EMPTY != code))
{
return CA_STATUS_OK;
}
OIC_LOG(DEBUG, TAG, "retransmission context destroy..");
+ ca_mutex_lock(context->threadMutex);
+ uint32_t len = u_arraylist_length(context->dataList);
+ for (uint32_t i = 0; i < len; i++)
+ {
+ CARetransmissionData_t *data = u_arraylist_get(context->dataList, i);
+ if (NULL == data)
+ {
+ continue;
+ }
+ CAFreeEndpoint(data->endpoint);
+ OICFree(data->pdu);
+ }
+ ca_mutex_unlock(context->threadMutex);
ca_mutex_free(context->threadMutex);
context->threadMutex = NULL;
ca_cond_free(context->threadCond);
return CA_STATUS_OK;
}
-
-uint64_t getCurrentTimeInMicroSeconds()
-{
- OIC_LOG(DEBUG, TAG, "IN");
- uint64_t currentTime = 0;
-
-#ifdef __ANDROID__
- struct timespec getTs;
-
- clock_gettime(CLOCK_MONOTONIC, &getTs);
-
- currentTime = (getTs.tv_sec * (uint64_t)1000000000 + getTs.tv_nsec)/1000;
- OIC_LOG_V(DEBUG, TAG, "current time = %ld", currentTime);
-#elif defined __ARDUINO__
- currentTime = millis() * 1000;
- OIC_LOG_V(DEBUG, TAG, "currtime=%lu", currentTime);
-#else
-#if _POSIX_TIMERS > 0
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- currentTime = ts.tv_sec * USECS_PER_SEC + ts.tv_nsec / 1000;
-#else
- struct timeval tv;
- gettimeofday(&tv, NULL);
- currentTime = tv.tv_sec * USECS_PER_SEC + tv.tv_usec;
-#endif
-#endif
-
- OIC_LOG(DEBUG, TAG, "OUT");
- return currentTime;
-}