}
coap_tid_t coap_send_ack(coap_context_t *context, const coap_address_t *dst,
- coap_pdu_t *request) {
+ coap_pdu_t *request, coap_send_flags_t flag) {
coap_pdu_t *response;
coap_tid_t result = COAP_INVALID_TID;
response = coap_pdu_init(COAP_MESSAGE_ACK, 0, request->hdr->id,
sizeof(coap_pdu_t));
if (response) {
- result = coap_send(context, dst, response, SEND_NOW);
+ result = coap_send(context, dst, response, flag);
coap_delete_pdu(response);
}
}
#endif /* WITH_LWIP */
coap_tid_t coap_send_error(coap_context_t *context, coap_pdu_t *request,
- const coap_address_t *dst, unsigned char code, coap_opt_filter_t opts) {
+ const coap_address_t *dst, unsigned char code, coap_opt_filter_t opts,
+ coap_send_flags_t flag) {
coap_pdu_t *response;
coap_tid_t result = COAP_INVALID_TID;
response = coap_new_error_response(request, code, opts);
if (response) {
- result = coap_send(context, dst, response, SEND_NOW);
+ result = coap_send(context, dst, response, flag);
coap_delete_pdu(response);
}
}
coap_tid_t coap_send_message_type(coap_context_t *context,
- const coap_address_t *dst, coap_pdu_t *request, unsigned char type) {
+ const coap_address_t *dst, coap_pdu_t *request,
+ coap_send_flags_t flag, unsigned char type) {
coap_pdu_t *response;
coap_tid_t result = COAP_INVALID_TID;
if (request) {
response = coap_pdu_init(type, 0, request->hdr->id, sizeof(coap_pdu_t));
if (response) {
- result = coap_send(context, dst, response, SEND_NOW);
+ result = coap_send(context, dst, response, flag);
coap_delete_pdu(response);
}
}
}
coap_tid_t coap_send(coap_context_t *context,
- const coap_address_t *dst, coap_pdu_t *pdu, const uint8_t flag)
+ const coap_address_t *dst, coap_pdu_t *pdu, coap_send_flags_t flag)
{
coap_queue_t *node = NULL;
coap_tick_t now;
if (!context)
return COAP_INVALID_TID;
- if(flag != SEND_RETX){
+ if(!(flag & SEND_RETX)){
coap_transaction_id(dst, pdu, &tid);
}
- if(flag == SEND_NOW || flag == SEND_RETX)
+ if((flag & SEND_NOW) || (flag & SEND_RETX))
{
goto sending;
}
prng((unsigned char * )&r, sizeof(r));
/* add randomized RESPONSE_TIMEOUT to determine retransmission timeout */
- if(flag == SEND_NOW_CON)
- {
+ if(flag & SEND_NOW_CON) {
node->timeout = COAP_DEFAULT_RESPONSE_TIMEOUT * COAP_TICKS_PER_SECOND
+ (COAP_DEFAULT_RESPONSE_TIMEOUT >> 1)
* ((COAP_TICKS_PER_SECOND * (r & 0xFF)) >> 8);
node->delayedResponse = 1;
}
+ if (flag & SEND_SECURE_PORT) {
+ node->secure = 1;
+ }
+
memcpy(&node->remote, dst, sizeof(coap_address_t));
node->pdu = pdu;
node->id = tid;
}
#endif /* WITH_CONTIKI */
- if(flag == SEND_NOW_CON)
+ if(flag & SEND_NOW_CON)
{
goto sending;
}
coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node) {
coap_tid_t tid = COAP_INVALID_TID;
+ coap_send_flags_t flag;
if (!context || !node)
return COAP_INVALID_TID;
#endif
debug("** retransmission #%d of transaction %d\n", node->retransmit_cnt,
- ntohs(node->pdu->hdr->id));
- tid = coap_send(context, (coap_address_t *)&(node->remote),node->pdu, SEND_RETX);
+ ntohs(node->pdu->hdr->id));
+ flag = (coap_send_flags_t)(SEND_RETX | (node->secure ? SEND_SECURE_PORT : 0));
+ tid = coap_send(context, (coap_address_t *)&(node->remote),node->pdu, flag);
return (tid == COAP_INVALID_TID)? COAP_INVALID_TID : node->id;
}
if (context->request_handler) {
context->request_handler(context, rcvd);
} else {
+ coap_send_flags_t flag = SEND_NOW;
+ flag = (coap_send_flags_t)(flag | (rcvd->secure ? SEND_SECURE_PORT : 0));
/* send ACK if rcvd is confirmable (i.e. a separate response) */
- coap_send_ack(context, &rcvd->remote, rcvd->pdu);
+ coap_send_ack(context, &rcvd->remote, rcvd->pdu, flag);
}
}
if (context->response_handler) {
context->response_handler(context, rcvd);
} else {
+ coap_send_flags_t flag = SEND_NOW;
+ flag = (coap_send_flags_t)(flag | (rcvd->secure ? SEND_SECURE_PORT : 0));
/* send ACK if rcvd is confirmable (i.e. a separate response) */
- coap_send_ack(context, &rcvd->remote, rcvd->pdu);
+ coap_send_ack(context, &rcvd->remote, rcvd->pdu, flag);
}
}
if (!response)
warn("coap_dispatch: cannot create error reponse\n");
else {
- if (coap_send(context, &rcvd->remote,
- response, SEND_NOW) == COAP_INVALID_TID) {
+ coap_send_flags_t flag = SEND_NOW;
+ flag = (coap_send_flags_t)(flag | rcvd->secure ? SEND_SECURE_PORT : 0);
+ if (coap_send(context, &rcvd->remote, response, flag)
+ == COAP_INVALID_TID) {
warn("coap_dispatch: error sending reponse\n");
}
coap_delete_pdu(response);
handle_response(context, rcvd);
}
else {
+ coap_send_flags_t flag;
+ flag = (coap_send_flags_t)(SEND_NOW |
+ (rcvd->secure ? SEND_SECURE_PORT : 0));
debug("dropped message with invalid code\n");
coap_send_message_type(context, &rcvd->remote, rcvd->pdu,
- COAP_MESSAGE_RST);
+ flag, COAP_MESSAGE_RST);
}
}
#include "pdu.h"
#include "coap_time.h"
-#define SEND_NOW (1) /*Flag used when sending non-confirmable, ACK and RESET coap pdus*/
-#define SEND_NOW_CON (2) /*Flag used when sending confirmable coap pdu*/
-#define SEND_DELAYED (3) /*Flag used to delay the transmission of coap pdu*/
-#define SEND_RETX (4) /*Flag used to retransmit a confirmable pdu*/
+typedef enum {
+ SEND_NOW = (1 << 0), /*Flag used when sending non-confirmable, ACK and RESET coap pdus*/
+ SEND_NOW_CON = (1 << 1), /*Flag used when sending confirmable coap pdu*/
+ SEND_DELAYED = (1 << 2), /*Flag used to delay the transmission of coap pdu*/
+ SEND_RETX = (1 << 3), /*Flag used to retransmit a confirmable pdu*/
+ SEND_SECURE_PORT = (1 << 4) /*Flag used to indicate that PDU needs to be transmitted on secure port */
+} coap_send_flags_t;
struct coap_queue_t;
coap_pdu_t *pdu; /**< the CoAP PDU to send */
unsigned char delayedResponse; /**< delayed response flag */
+ unsigned char secure; /**< rx/tx will use secure channel (DTLS) */
} coap_queue_t;
/** Adds node to given queue, ordered by node->t. */
* @param context The CoAP context to use.
* @param dst The address to send to.
* @param pdu The CoAP PDU to send.
- * @param flag The flag indicating if the message will be sent with delay
+ * @param flag The flag indicating how the message will be send
* @return The message id of the sent message or @c COAP_INVALID_TID on error.
*/
-coap_tid_t coap_send(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu, const uint8_t flag);
+coap_tid_t coap_send(coap_context_t *context, const coap_address_t *dst,
+ coap_pdu_t *pdu,
+ coap_send_flags_t flag);
/**
* Sends an error response with code @p code for request @p request to
coap_pdu_t *request,
const coap_address_t *dst,
unsigned char code,
- coap_opt_filter_t opts);
+ coap_opt_filter_t opts,
+ coap_send_flags_t flag);
/**
* Helper funktion to create and send a message with @p type (usually
* @param dst Where to send the context.
* @param request The request that should be responded to.
* @param type Which type to set
+ * @param flag options for sending the message
* @return transaction id on success or @c COAP_INVALID_TID otherwise.
*/
coap_tid_t
coap_send_message_type(coap_context_t *context,
const coap_address_t *dst,
coap_pdu_t *request,
+ coap_send_flags_t flag,
unsigned char type);
/**
* Sends an ACK message with code @c 0 for the specified @p request to
* @param context The context to use.
* @param dst The destination address.
* @param request The request to be acknowledged.
+ * @param flag Options for sending the acknowledgement.
*
* @return The transaction id if ACK was sent or @c COAP_INVALID_TID
* on error.
*/
coap_tid_t coap_send_ack(coap_context_t *context,
const coap_address_t *dst,
- coap_pdu_t *request);
+ coap_pdu_t *request,
+ coap_send_flags_t flag);
/**
* Sends an RST message with code @c 0 for the specified @p request to
* @param context The context to use.
* @param dst The destination address.
* @param request The request to be reset.
+ * @param flag Options for sending the reset message.
*
* @return The transaction id if RST was sent or @c COAP_INVALID_TID
* on error.
static inline coap_tid_t
coap_send_rst(coap_context_t *context,
const coap_address_t *dst,
- coap_pdu_t *request) {
- return coap_send_message_type(context, dst, request, COAP_MESSAGE_RST);
+ coap_pdu_t *request,
+ coap_send_flags_t flag) {
+ return coap_send_message_type(context, dst, request, flag, COAP_MESSAGE_RST);
}
/** Handles retransmissions of confirmable messages */
// Internal function to send a coap pdu, it also handles NON and CON
OCStackResult
SendCoAPPdu(coap_context_t * gCoAPCtx, coap_address_t* dst, coap_pdu_t * pdu,
- uint8_t delayFlag);
+ coap_send_flags_t flag);
// Call back function used by libcoap to order option in coap pdu
int OrderOptions(void *a, void *b);
uint8_t * rcvObserveOption = NULL;
unsigned char * bufReqPayload = NULL;
uint32_t observeOption = OC_RESOURCE_NO_OBSERVE;
+ coap_send_flags_t sendFlag;
memset(&entityHandlerRequest, 0, sizeof(OCEntityHandlerRequest));
coap_pdu_t * recvPdu = rcvdRequest->pdu;
}
default:
{
- OC_LOG_V(ERROR, TAG, "Received CoAP method %d not supported",
+ OC_LOG_V(ERROR, TAG, "Received CoAP method %d not supported",
recvPdu->hdr->code);
goto exit;
}
VERIFY_NON_NULL(sendPdu);
coap_show_pdu(sendPdu);
- if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu, rcvdRequest->delayedResponse)
+ sendFlag = (coap_send_flags_t)(rcvdRequest->delayedResponse ? SEND_DELAYED : 0);
+ sendFlag = (coap_send_flags_t)( sendFlag | (rcvdRequest->secure ? SEND_SECURE_PORT : 0));
+
+ if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) &(rcvdRequest->remote), sendPdu,
+ sendFlag)
!= OC_STACK_OK){
OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
}
recvPdu->hdr->id, NULL, NULL, NULL);
VERIFY_NON_NULL(sendPdu);
result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote,
- sendPdu, 0);
+ sendPdu,
+ (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
}
//TODO: check the standard for methods to detect wrap around condition
if(cbNode->method == OC_REST_OBSERVE &&
sendPdu = GenerateCoAPPdu(COAP_MESSAGE_RST, 0,
recvPdu->hdr->id, NULL, NULL, NULL);
VERIFY_NON_NULL(sendPdu);
- result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, sendPdu, 0);
+ result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, sendPdu,
+ (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
VERIFY_SUCCESS(result, OC_STACK_OK);
}
#ifdef WITH_PRESENCE
sendPdu = GenerateCoAPPdu(COAP_MESSAGE_RST, 0,
recvPdu->hdr->id, NULL, NULL, NULL);
VERIFY_NON_NULL(sendPdu);
- result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, sendPdu, 0);
+ result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, sendPdu,
+ (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0));
VERIFY_SUCCESS(result, OC_STACK_OK);
}
exit:
uint8_t coapMsgType;
uint8_t coapMethod;
uint32_t observeOption;
+ coap_send_flags_t flag = (coap_send_flags_t)0;
OC_LOG(INFO, TAG, PCF("Entering OCDoCoAPResource"));
(uint16_t*)&uri.port, uri.path.length, uri.path.s, uri.query.length,
uri.query.s, options, numOptions), OC_STACK_OK);
+ //TODO : Investigate the scenario where there will be no uri for OCDoCoAPResource
+ //flag = (coap_send_flags_t) (uri.secure ? SEND_SECURE_PORT : 0);
OC_LOG_V(DEBUG, TAG, "uri.host.s %s", uri.host.s);
OC_LOG_V(DEBUG, TAG, "uri.path.s %s", uri.path.s);
OC_LOG_V(DEBUG, TAG, "uri.port %d", uri.port);
(unsigned char*) payload, optList);
VERIFY_NON_NULL(pdu);
- ret = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &dst, pdu, 0);
+ ret = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &dst, pdu, flag);
exit:
if (ret!= OC_STACK_OK)
VERIFY_NON_NULL(sendPdu);
coap_show_pdu(sendPdu);
- if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) dstAddr, sendPdu, 0)
- != OC_STACK_OK){
+ // TODO : resourceProperties will determine if the packet will be send using secure port
+ if(SendCoAPPdu(gCoAPCtx, (coap_address_t*) dstAddr, sendPdu , (coap_send_flags_t)0 )
+ != OC_STACK_OK)
+ {
OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));
}
return OC_STACK_OK;
//Send a coap pdu
OCStackResult
SendCoAPPdu(coap_context_t * gCoAPCtx, coap_address_t* dst, coap_pdu_t * pdu,
- uint8_t delayFlag)
+ coap_send_flags_t flag)
{
coap_tid_t tid = COAP_INVALID_TID;
OCStackResult res = OC_STACK_COMM_ERROR;
- uint8_t sendFlag = SEND_NOW;
- if(delayFlag)
+ if (!(flag & SEND_DELAYED))
{
- sendFlag = SEND_DELAYED;
- }
- else
- {
- if(pdu->hdr->type != COAP_MESSAGE_CON)
- {
- sendFlag = SEND_NOW;
- }
- else
- {
- sendFlag = SEND_NOW_CON;
- }
+ flag = (coap_send_flags_t)( flag |
+ (pdu->hdr->type == COAP_MESSAGE_CON) ? SEND_NOW_CON : SEND_NOW);
}
- tid = coap_send(gCoAPCtx, dst, pdu, sendFlag);
+ tid = coap_send(gCoAPCtx, dst, pdu, flag);
OC_LOG_V(INFO, TAG, "TID %d", tid);
if(tid != COAP_INVALID_TID)
{
res = OC_STACK_OK;
}
- if ((pdu->hdr->type != COAP_MESSAGE_CON && !delayFlag) || tid == COAP_INVALID_TID)
+ if ((pdu->hdr->type != COAP_MESSAGE_CON && (!(flag & SEND_DELAYED))) || tid == COAP_INVALID_TID)
{
OC_LOG(INFO, TAG, PCF("Deleting PDU"));
coap_delete_pdu(pdu);
{
OC_LOG_V(DEBUG, TAG, "Sending Delayed response TID %d",
nextQueue->id);
- if(SendCoAPPdu(ctx, &nextQueue->remote, nextQueue->pdu, 0)
+ if(SendCoAPPdu(ctx, &nextQueue->remote, nextQueue->pdu,
+ (coap_send_flags_t)(nextQueue->secure ? SEND_SECURE_PORT : 0))
== OC_STACK_COMM_ERROR)
{
OC_LOG(DEBUG, TAG, PCF("A problem occurred in sending a pdu"));