ThreadError Client::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, otCoapResponseHandler aHandler, void *aContext) { ThreadError error; Header header; RequestMetadata requestMetadata; Message *storedCopy = NULL; uint16_t copyLength = 0; SuccessOrExit(error = header.FromMessage(aMessage, false)); // Set Message Id if it was not already set. if (header.GetMessageId() == 0) { header.SetMessageId(mMessageId++); aMessage.Write(0, Header::kMinHeaderLength, header.GetBytes()); } if (header.IsConfirmable()) { // Create a copy of entire message and enqueue it. copyLength = aMessage.GetLength(); } else if (header.IsNonConfirmable() && header.IsRequest() && (aHandler != NULL)) { // As we do not retransmit non confirmable messages, create a copy of header only, for token information. copyLength = header.GetLength(); } if (copyLength > 0) { requestMetadata = RequestMetadata(header.IsConfirmable(), aMessageInfo, aHandler, aContext); VerifyOrExit((storedCopy = CopyAndEnqueueMessage(aMessage, copyLength, requestMetadata)) != NULL, error = kThreadError_NoBufs); } SuccessOrExit(error = mSender(this, aMessage, aMessageInfo)); exit: if (error != kThreadError_None && storedCopy != NULL) { DequeueMessage(*storedCopy); } return error; }
ThreadError Client::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { ThreadError error; Message *messageCopy = NULL; // Create a message copy for lower layers. VerifyOrExit((messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(RequestMetadata))) != NULL, error = kThreadError_NoBufs); // Send the copy. SuccessOrExit(error = mSender(this, *messageCopy, aMessageInfo)); exit: if (error != kThreadError_None && messageCopy != NULL) { messageCopy->Free(); } return error; }
/** * This method sends a message. * * @param[in] aMessage A reference to the message to send. * @param[in] aMessageInfo A reference to the message info associated with @p aMessage. * * @retval OT_ERROR_NONE Successfully sent CoAP message. * @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data. * */ otError Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { return mSender(*this, aMessage, aMessageInfo); }
void Client::SendEmptyMessage(const Ip6::Address &aAddress, uint16_t aPort, uint16_t aMessageId, Header::Type aType) { Header header; Ip6::MessageInfo messageInfo; Message *message; ThreadError error = kThreadError_None; header.Init(aType, kCoapCodeEmpty); header.SetMessageId(aMessageId); VerifyOrExit((message = NewMessage(header)) != NULL, ;); messageInfo.SetPeerAddr(aAddress); messageInfo.SetPeerPort(aPort); SuccessOrExit(error = mSender(this, *message, messageInfo)); exit: if (error != kThreadError_None && message != NULL) { message->Free(); } } void Client::HandleRetransmissionTimer(void *aContext) { static_cast<Client *>(aContext)->HandleRetransmissionTimer(); } void Client::HandleRetransmissionTimer(void)