OCServerRequest * GetServerRequestUsingToken (const OCCoAPToken token) { OCServerRequest * out = NULL; LL_FOREACH (serverRequestList, out) { OC_LOG(INFO, TAG,PCF("comparing tokens")); OC_LOG_BUFFER(INFO, TAG, token.token, token.tokenLength); OC_LOG_BUFFER(INFO, TAG, out->requestToken.token, out->requestToken.tokenLength); if((out->requestToken.tokenLength == token.tokenLength) && (memcmp(out->requestToken.token, token.token, token.tokenLength) == 0)) { return out; } }
//This function is called back by libcoap when ack or rst are received static void HandleCoAPAckRst(struct coap_context_t * ctx, uint8_t msgType, const coap_queue_t * sentQueue){ // silence warnings (void) ctx; coap_pdu_t * sentPdu = sentQueue->pdu; OCStackResult result = OC_STACK_ERROR; uint32_t observationOption = OC_OBSERVE_NO_OPTION; // {{0}} to eliminate warning for known compiler bug 53119 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119 OCCoAPToken sentToken = {{0}}; result = ParseCoAPPdu(sentPdu, NULL, NULL, &observationOption, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); VERIFY_SUCCESS(result, OC_STACK_OK); // fill OCCoAPToken structure RetrieveOCCoAPToken(sentPdu, &sentToken); if(msgType == COAP_MESSAGE_RST) { if(myStackMode != OC_CLIENT) { result = OCStackFeedBack(&sentToken, OC_OBSERVER_NOT_INTERESTED); if(result == OC_STACK_OK) { OC_LOG_V(DEBUG, TAG, "Received RST, removing all queues associated with Token %d bytes", sentToken.tokenLength); OC_LOG_BUFFER(INFO, TAG, sentToken.token, sentToken.tokenLength); coap_cancel_all_messages(ctx, &sentQueue->remote, sentToken.token, sentToken.tokenLength); } } } else if(observationOption != OC_OBSERVE_NO_OPTION && msgType == COAP_MESSAGE_ACK) { OC_LOG_V(DEBUG, TAG, "Received ACK, for Token %d bytes",sentToken.tokenLength); OC_LOG_BUFFER(INFO, TAG, sentToken.token, sentToken.tokenLength); // now the observer is still interested if(myStackMode != OC_CLIENT) { OCStackFeedBack(&sentToken, OC_OBSERVER_STILL_INTERESTED); } } exit: return; }
void ocInitialize () { char ipAddr[16] = ""; OCGetInterfaceAddress (NULL, 0, AF_INET, (uint8_t *)ipAddr, 16); OC_LOG(DEBUG, TAG, PCF("IP addr is:")); OC_LOG_BUFFER(INFO, TAG, (uint8_t*)ipAddr, sizeof(ipAddr)); delay(2000); OCInit (ipAddr, 8001, OC_SERVER); }
ResourceObserver* GetObserverUsingToken (const OCCoAPToken * token) { ResourceObserver *out = NULL; if(token) { LL_FOREACH (serverObsList, out) { OC_LOG(INFO, TAG,PCF("comparing tokens")); OC_LOG_BUFFER(INFO, TAG, token->token, token->tokenLength); OC_LOG_BUFFER(INFO, TAG, out->token.token, out->token.tokenLength); if((out->token.tokenLength == token->tokenLength) && (memcmp(out->token.token, token->token, token->tokenLength) == 0)) { return out; } } }
ResourceObserver* GetObserverUsingToken (const CAToken_t token, uint8_t tokenLength) { ResourceObserver *out = NULL; if(token && *token) { OC_LOG(INFO, TAG, "Looking for token"); OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength); OC_LOG(INFO, TAG, "\tFound token:"); LL_FOREACH (serverObsList, out) { OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength); if((memcmp(out->token, token, tokenLength) == 0)) { return out; } }
ClientCB* GetClientCB(const CAToken_t token, uint8_t tokenLength, OCDoHandle handle, const char * requestUri) { ClientCB* out = NULL; if(token && *token && tokenLength <= CA_MAX_TOKEN_LEN && tokenLength > 0) { OC_LOG (INFO, TAG, "Looking for token"); OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength); OC_LOG(INFO, TAG, "\tFound in callback list"); LL_FOREACH(cbList, out) { OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)out->token, tokenLength); if(memcmp(out->token, token, tokenLength) == 0) { return out; } CheckAndDeleteTimedOutCB(out); }
OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse) { uint8_t remoteIpAddr[4]; uint16_t remotePortNu; if (ctx == (void*) DEFAULT_CONTEXT_VALUE) { OC_LOG(INFO, TAG, "<====Callback Context for GET received successfully====>"); } else { OC_LOG(ERROR, TAG, "<====Callback Context for GET fail====>"); } if (clientResponse) { OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr, remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3); OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu); OC_LOG_V(INFO, TAG,"Get Response: %s \nFrom %d.%d.%d.%d:%d\n", clientResponse->resJSONPayload, remoteIpAddr[0], remoteIpAddr[1], remoteIpAddr[2], remoteIpAddr[3], remotePortNu); if (clientResponse->rcvdVendorSpecificHeaderOptions && clientResponse->numRcvdVendorSpecificHeaderOptions) { OC_LOG (INFO, TAG, "Received vendor specific options"); uint8_t i = 0; OCHeaderOption * rcvdOptions = clientResponse->rcvdVendorSpecificHeaderOptions; for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++) { if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID) { OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with", ((OCHeaderOption)rcvdOptions[i]).optionID ); OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData, MAX_HEADER_OPTION_DATA_LENGTH); } } } } else { OC_LOG(ERROR, TAG, "<====GET Callback fail to receive clientResponse====>\n"); } return OC_STACK_DELETE_TRANSACTION; }
OCStackApplicationResult getReqCB(void* ctx, OCDoHandle /*handle*/, OCClientResponse * clientResponse) { if (ctx == (void*) DEFAULT_CONTEXT_VALUE) { OC_LOG(INFO, TAG, "<====Callback Context for GET received successfully====>"); } else { OC_LOG(ERROR, TAG, "<====Callback Context for GET fail====>"); } if (clientResponse) { OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result)); OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber); OC_LOG_PAYLOAD(INFO, clientResponse->payload); OC_LOG(INFO, TAG, ("=============> Get Response")); if (clientResponse->numRcvdVendorSpecificHeaderOptions > 0 ) { OC_LOG (INFO, TAG, "Received vendor specific options"); uint8_t i = 0; OCHeaderOption * rcvdOptions = clientResponse->rcvdVendorSpecificHeaderOptions; for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++) { if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID) { OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with", ((OCHeaderOption)rcvdOptions[i]).optionID ); OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData, MAX_HEADER_OPTION_DATA_LENGTH); } } } } else { OC_LOG(ERROR, TAG, "<====GET Callback fail to receive clientResponse====>\n"); } return OC_STACK_DELETE_TRANSACTION; }
void DeleteClientCB(ClientCB * cbNode) { if(cbNode) { LL_DELETE(cbList, cbNode); OC_LOG (INFO, TAG, "Deleting token"); OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, cbNode->tokenLength); CADestroyToken (cbNode->token); OICFree(cbNode->devAddr); OICFree(cbNode->handle); OC_LOG_V (INFO, TAG, "Deleting callback with uri %s", cbNode->requestUri); OICFree(cbNode->requestUri); if(cbNode->deleteCallback) { cbNode->deleteCallback(cbNode->context); } #ifdef WITH_PRESENCE if(cbNode->presence) { OICFree(cbNode->presence->timeOut); OICFree(cbNode->presence); } if(cbNode->method == OC_REST_PRESENCE) { OCResourceType * pointer = cbNode->filterResourceType; OCResourceType * next = NULL; while(pointer) { next = pointer->next; OICFree(pointer->resourcetypename); OICFree(pointer); pointer = next; } } #endif // WITH_PRESENCE OICFree(cbNode); cbNode = NULL; } }
OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse) { if(clientResponse == NULL) { OC_LOG(INFO, TAG, "getReqCB received NULL clientResponse"); return OC_STACK_DELETE_TRANSACTION; } if(ctx == (void*)DEFAULT_CONTEXT_VALUE) { OC_LOG(INFO, TAG, "Callback Context for GET query recvd successfully"); } OC_LOG_V(INFO, TAG, "StackResult: %s", getResult(clientResponse->result)); OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber); OC_LOG_V(INFO, TAG, "JSON = %s =============> Get Response", clientResponse->resJSONPayload); if(clientResponse->rcvdVendorSpecificHeaderOptions && clientResponse->numRcvdVendorSpecificHeaderOptions) { OC_LOG (INFO, TAG, "Received vendor specific options"); uint8_t i = 0; OCHeaderOption * rcvdOptions = clientResponse->rcvdVendorSpecificHeaderOptions; for( i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions; i++) { if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID) { OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with", ((OCHeaderOption)rcvdOptions[i]).optionID ); OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData, MAX_HEADER_OPTION_DATA_LENGTH); } } } return OC_STACK_DELETE_TRANSACTION; }
/** * Function to save ownerPSK at provisioning tool end. * * @param[in] selectedDeviceInfo selected device information to performing provisioning. * @return OC_STACK_OK on success */ static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo) { OC_LOG(DEBUG, TAG, "IN SaveOwnerPSK"); OCStackResult res = OC_STACK_ERROR; CAEndpoint_t endpoint; memset(&endpoint, 0x00, sizeof(CAEndpoint_t)); OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE_CA, selectedDeviceInfo->endpoint.addr); endpoint.addr[MAX_ADDR_STR_SIZE_CA - 1] = '\0'; endpoint.port = selectedDeviceInfo->securePort; OicUuid_t ptDeviceID = {.id={0}}; if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID)) { OC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID"); return res; } uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0}; //Generating OwnerPSK CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint, (uint8_t *)GetOxmString(selectedDeviceInfo->doxm->oxmSel), strlen(GetOxmString(selectedDeviceInfo->doxm->oxmSel)), ptDeviceID.id, sizeof(ptDeviceID.id), selectedDeviceInfo->doxm->deviceID.id, sizeof(selectedDeviceInfo->doxm->deviceID.id), ownerPSK, OWNER_PSK_LENGTH_128); if (CA_STATUS_OK == pskRet) { OC_LOG(INFO, TAG,"ownerPSK dump:\n"); OC_LOG_BUFFER(INFO, TAG,ownerPSK, OWNER_PSK_LENGTH_128); //Generating new credential for provisioning tool size_t ownLen = 1; uint32_t outLen = 0; char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {}; B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff, sizeof(base64Buff), &outLen); VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR); OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID, SYMMETRIC_PAIR_WISE_KEY, NULL, base64Buff, ownLen, &ptDeviceID); VERIFY_NON_NULL(TAG, cred, ERROR); res = AddCredential(cred); if(res != OC_STACK_OK) { DeleteCredList(cred); return res; } } else { OC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed"); } OC_LOG(DEBUG, TAG, "OUT SaveOwnerPSK"); exit: return res; }
OCStackResult AddClientCB (ClientCB** clientCB, OCCallbackData* cbData, CAToken_t token, uint8_t tokenLength, OCDoHandle *handle, OCMethod method, OCDevAddr *devAddr, char * requestUri, char * resourceTypeName, uint32_t ttl) { if(!clientCB || !cbData || !handle || !requestUri || tokenLength > CA_MAX_TOKEN_LEN) { return OC_STACK_INVALID_PARAM; } ClientCB *cbNode = NULL; #ifdef WITH_PRESENCE if(method == OC_REST_PRESENCE) { // Retrieve the presence callback structure for this specific requestUri. cbNode = GetClientCB(NULL, 0, NULL, requestUri); } #endif // WITH_PRESENCE if(!cbNode)// If it does not already exist, create new node. { cbNode = (ClientCB*) OICMalloc(sizeof(ClientCB)); if(!cbNode) { *clientCB = NULL; goto exit; } else { OC_LOG(INFO, TAG, "Adding client callback with token"); OC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength); cbNode->callBack = cbData->cb; cbNode->context = cbData->context; cbNode->deleteCallback = cbData->cd; //Note: token memory is allocated in the caller OCDoResource //but freed in DeleteClientCB cbNode->token = token; cbNode->tokenLength = tokenLength; cbNode->handle = *handle; cbNode->method = method; cbNode->sequenceNumber = 0; #ifdef WITH_PRESENCE cbNode->presence = NULL; cbNode->filterResourceType = NULL; #endif // WITH_PRESENCE if (method == OC_REST_PRESENCE || method == OC_REST_OBSERVE || method == OC_REST_OBSERVE_ALL) { cbNode->TTL = 0; } else { cbNode->TTL = ttl; } cbNode->requestUri = requestUri; // I own it now cbNode->devAddr = devAddr; // I own it now OC_LOG_V(INFO, TAG, "Added Callback for uri : %s", requestUri); LL_APPEND(cbList, cbNode); *clientCB = cbNode; } } else { // Ensure that the handle the SDK hands back up to the application layer for the // OCDoResource call matches the found ClientCB Node. *clientCB = cbNode; if (cbData->cd) { cbData->cd(cbData->context); } OICFree(token); OICFree(*handle); OICFree(requestUri); OICFree(devAddr); *handle = cbNode->handle; } #ifdef WITH_PRESENCE if(method == OC_REST_PRESENCE && resourceTypeName) { // Amend the found or created node by adding a new resourceType to it. return InsertResourceTypeFilter(cbNode,(char *)resourceTypeName); // I own resourceTypName now. } else { OICFree(resourceTypeName); } #else OICFree(resourceTypeName); #endif return OC_STACK_OK; exit: return OC_STACK_NO_MEMORY; }
OCEntityHandlerResult OCEntityHandlerCb (OCEntityHandlerFlag flag, OCEntityHandlerRequest *entityHandlerRequest) { OC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag); OCEntityHandlerResult ehResult = OC_EH_OK; OCEntityHandlerResponse response; char payload[MAX_RESPONSE_LENGTH] = {0}; // Validate pointer if (!entityHandlerRequest) { OC_LOG (ERROR, TAG, "Invalid request pointer"); return OC_EH_ERROR; } // Initialize certain response fields response.numSendVendorSpecificHeaderOptions = 0; memset(response.sendVendorSpecificHeaderOptions, 0, sizeof response.sendVendorSpecificHeaderOptions); memset(response.resourceUri, 0, sizeof response.resourceUri); if (flag & OC_INIT_FLAG) { OC_LOG (INFO, TAG, "Flag includes OC_INIT_FLAG"); } if (flag & OC_REQUEST_FLAG) { OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG"); if (OC_REST_GET == entityHandlerRequest->method) { OC_LOG (INFO, TAG, "Received OC_REST_GET from client"); ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1); } else if (OC_REST_PUT == entityHandlerRequest->method) { OC_LOG (INFO, TAG, "Received OC_REST_PUT from client"); ehResult = ProcessPutRequest (entityHandlerRequest, payload, sizeof(payload) - 1); } else if (OC_REST_POST == entityHandlerRequest->method) { OC_LOG (INFO, TAG, "Received OC_REST_POST from client"); ehResult = ProcessPostRequest (entityHandlerRequest, &response, payload, sizeof(payload) - 1); } else if (OC_REST_DELETE == entityHandlerRequest->method) { OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client"); ehResult = ProcessDeleteRequest (entityHandlerRequest, payload, sizeof(payload) - 1); } else { OC_LOG_V (INFO, TAG, "Received unsupported method %d from client", entityHandlerRequest->method); } // If the result isn't an error or forbidden, send response if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN))) { // Format the response. Note this requires some info about the request response.requestHandle = entityHandlerRequest->requestHandle; response.resourceHandle = entityHandlerRequest->resource; response.ehResult = ehResult; response.payload = (unsigned char *)payload; response.payloadSize = strlen(payload); // Indicate that response is NOT in a persistent buffer response.persistentBufferFlag = 0; // Handle vendor specific options if(entityHandlerRequest->rcvdVendorSpecificHeaderOptions && entityHandlerRequest->numRcvdVendorSpecificHeaderOptions) { OC_LOG (INFO, TAG, "Received vendor specific options"); uint8_t i = 0; OCHeaderOption * rcvdOptions = entityHandlerRequest->rcvdVendorSpecificHeaderOptions; for( i = 0; i < entityHandlerRequest->numRcvdVendorSpecificHeaderOptions; i++) { if(((OCHeaderOption)rcvdOptions[i]).protocolID == OC_COAP_ID) { OC_LOG_V(INFO, TAG, "Received option with OC_COAP_ID and ID %u with", ((OCHeaderOption)rcvdOptions[i]).optionID ); OC_LOG_BUFFER(INFO, TAG, ((OCHeaderOption)rcvdOptions[i]).optionData, ((OCHeaderOption)rcvdOptions[i]).optionLength); } } OCHeaderOption * sendOptions = response.sendVendorSpecificHeaderOptions; uint8_t option2[] = {21,22,23,24,25,26,27,28,29,30}; uint8_t option3[] = {31,32,33,34,35,36,37,38,39,40}; sendOptions[0].protocolID = OC_COAP_ID; sendOptions[0].optionID = 2248; memcpy(sendOptions[0].optionData, option2, sizeof(option2)); sendOptions[0].optionLength = 10; sendOptions[1].protocolID = OC_COAP_ID; sendOptions[1].optionID = 2600; memcpy(sendOptions[1].optionData, option3, sizeof(option3)); sendOptions[1].optionLength = 10; response.numSendVendorSpecificHeaderOptions = 2; } // Send the response if (OCDoResponse(&response) != OC_STACK_OK) { OC_LOG(ERROR, TAG, "Error sending response"); ehResult = OC_EH_ERROR; } } } if (flag & OC_OBSERVE_FLAG) { OC_LOG(INFO, TAG, "Flag includes OC_OBSERVE_FLAG"); if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action) { OC_LOG (INFO, TAG, "Received OC_OBSERVE_REGISTER from client"); ProcessObserveRegister (entityHandlerRequest); } else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action) { OC_LOG (INFO, TAG, "Received OC_OBSERVE_DEREGISTER from client"); ProcessObserveDeregister (entityHandlerRequest); } } return ehResult; }
//This function is called back by libcoap when a response is received static void HandleCoAPResponses(struct coap_context_t *ctx, const coap_queue_t * rcvdResponse) { OCResponse * response = NULL; OCCoAPToken rcvdToken; OCClientResponse clientResponse = {0}; ClientCB * cbNode = NULL; unsigned char bufRes[MAX_RESPONSE_LENGTH] = {0}; uint32_t sequenceNumber = OC_OBSERVE_NO_OPTION; uint32_t maxAge = 0; OCStackResult result = OC_STACK_ERROR; coap_pdu_t * sendPdu = NULL; coap_pdu_t * recvPdu = NULL; unsigned char rcvdUri[MAX_URI_LENGTH] = { 0 }; uint8_t isObserveNotification = 0; #ifdef WITH_PRESENCE char * resourceTypeName = NULL; uint8_t remoteIpAddr[4]; uint16_t remotePortNu; unsigned char fullUri[MAX_URI_LENGTH] = { 0 }; uint8_t isPresenceNotification = 0; uint8_t isMulticastPresence = 0; uint32_t lowerBound; uint32_t higherBound; char * tok = NULL; #endif coap_block_t rcvdBlock1 = {COAP_BLOCK_FILL_VALUE}; coap_block_t rcvdBlock2 = {COAP_BLOCK_FILL_VALUE}; uint16_t rcvdSize2 = 0; VERIFY_NON_NULL(ctx); VERIFY_NON_NULL(rcvdResponse); recvPdu = rcvdResponse->pdu; result = ParseCoAPPdu(recvPdu, rcvdUri, NULL, &sequenceNumber, &maxAge, &clientResponse.numRcvdVendorSpecificHeaderOptions, clientResponse.rcvdVendorSpecificHeaderOptions, &rcvdBlock1, &rcvdBlock2, NULL, &rcvdSize2, bufRes); VERIFY_SUCCESS(result, OC_STACK_OK); OC_LOG_V(DEBUG, TAG, "The sequenceNumber/NONCE of this response %u", sequenceNumber); OC_LOG_V(DEBUG, TAG, "The maxAge/TTL of this response %u", maxAge); OC_LOG_V(DEBUG, TAG, "The response received is %s", bufRes); if(sequenceNumber >= OC_OFFSET_SEQUENCE_NUMBER) { isObserveNotification = 1; OC_LOG(INFO, TAG, PCF("Received an observe notification")); } #ifdef WITH_PRESENCE if(!strcmp((char *)rcvdUri, (char *)OC_PRESENCE_URI)){ char* tokSavePtr; isPresenceNotification = 1; OC_LOG(INFO, TAG, PCF("Received a presence notification")); tok = strtok_r((char *)bufRes, "[:]}", &tokSavePtr); bufRes[strlen((char *)bufRes)] = ':'; tok = strtok_r(NULL, "[:]}", &tokSavePtr); bufRes[strlen((char *)bufRes)] = ':'; VERIFY_NON_NULL(tok); sequenceNumber = (uint32_t )atol(tok); OC_LOG_V(DEBUG, TAG, "The received NONCE is %u", sequenceNumber); tok = strtok_r(NULL, "[:]}", &tokSavePtr); VERIFY_NON_NULL(tok); maxAge = (uint32_t )atol(tok); OC_LOG_V(DEBUG, TAG, "The received TTL is %u", maxAge); tok = strtok_r(NULL, "[:]}", &tokSavePtr); if(tok) { bufRes[strlen((char *)bufRes)] = ':'; resourceTypeName = (char *)OCMalloc(strlen(tok)); if(!resourceTypeName) { goto exit; } strcpy(resourceTypeName, tok); OC_LOG_V(DEBUG, TAG, "----------------resourceTypeName %s", resourceTypeName); } bufRes[strlen((char *)bufRes)] = ']'; } #endif // fill OCCoAPToken structure RetrieveOCCoAPToken(recvPdu, &rcvdToken); OC_LOG_V(INFO, TAG,"Received a pdu with Token", rcvdToken.tokenLength); OC_LOG_BUFFER(INFO, TAG, rcvdToken.token, rcvdToken.tokenLength); // fill OCClientResponse structure result = FormOCClientResponse(&clientResponse, CoAPToOCResponseCode(recvPdu->hdr->code), (OCDevAddr *) &(rcvdResponse->remote), sequenceNumber, bufRes); VERIFY_SUCCESS(result, OC_STACK_OK); cbNode = GetClientCB(&rcvdToken, NULL, NULL); #ifdef WITH_PRESENCE // Check if the application subscribed for presence if(!cbNode) { // get the address of the remote OCDevAddrToIPv4Addr((OCDevAddr *) &(rcvdResponse->remote), remoteIpAddr, remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3); OCDevAddrToPort((OCDevAddr *) &(rcvdResponse->remote), &remotePortNu); snprintf((char *)fullUri, sizeof(fullUri), "coap://%d.%d.%d.%d:%d%s", remoteIpAddr[0],remoteIpAddr[1],remoteIpAddr[2],remoteIpAddr[3], remotePortNu,rcvdUri); cbNode = GetClientCB(NULL, NULL, fullUri); } // Check if application subscribed for multicast presence if(!cbNode) { snprintf((char *)fullUri, sizeof(fullUri), "%s%s", OC_MULTICAST_IP, rcvdUri); cbNode = GetClientCB(NULL, NULL, fullUri); isMulticastPresence = 1; isPresenceNotification = 0; } #endif // fill OCResponse structure result = FormOCResponse(&response, cbNode, maxAge, &clientResponse); VERIFY_SUCCESS(result, OC_STACK_OK); if(cbNode) { if(!isObserveNotification) { #ifdef WITH_PRESENCE if(!isPresenceNotification) { #endif OC_LOG(INFO, TAG, PCF("Received a regular response")); if(recvPdu->hdr->type == COAP_MESSAGE_CON) { sendPdu = GenerateCoAPPdu(COAP_MESSAGE_ACK, 0, recvPdu->hdr->id, NULL, NULL, NULL); VERIFY_NON_NULL(sendPdu); result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, sendPdu, (coap_send_flags_t)(rcvdResponse->secure ? SEND_SECURE_PORT : 0)); } #ifdef WITH_PRESENCE } #endif } if(isObserveNotification) { OC_LOG(INFO, TAG, PCF("Received an observe notification")); if(recvPdu->hdr->type == COAP_MESSAGE_CON) { sendPdu = GenerateCoAPPdu(COAP_MESSAGE_ACK, 0, recvPdu->hdr->id, NULL, NULL, NULL); VERIFY_NON_NULL(sendPdu); result = SendCoAPPdu(gCoAPCtx, (coap_address_t*) &rcvdResponse->remote, 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 && (clientResponse.sequenceNumber <= cbNode->sequenceNumber || (clientResponse.sequenceNumber > cbNode->sequenceNumber && clientResponse.sequenceNumber == (MAX_SEQUENCE_NUMBER)))) { OC_LOG_V(DEBUG, TAG, "Observe notification came out of order. \ Ignoring Incoming:%d Against Current:%d.", clientResponse.sequenceNumber, cbNode->sequenceNumber); goto exit; } if(clientResponse.sequenceNumber > cbNode->sequenceNumber){ cbNode->sequenceNumber = clientResponse.sequenceNumber; } } else { #ifdef WITH_PRESENCE if(isPresenceNotification)
//This function is called back by libcoap when a request is received static void HandleCoAPRequests(struct coap_context_t *ctx, const coap_queue_t * rcvdRequest) { // silence warnings (void) ctx; OCServerProtocolRequest protocolRequest = {(OCMethod)0}; coap_block_t rcvdBlock1; coap_block_t rcvdBlock2; memset(&rcvdBlock1, COAP_BLOCK_FILL_VALUE, sizeof(coap_block_t)); memset(&rcvdBlock2, COAP_BLOCK_FILL_VALUE, sizeof(coap_block_t)); uint16_t rcvdSize1 = 0; coap_pdu_t * rcvdPdu = rcvdRequest->pdu; coap_pdu_t * sendPdu = NULL; coap_send_flags_t sendFlag; OCStackResult result = OC_STACK_ERROR; OCStackResult requestResult = OC_STACK_ERROR; if(myStackMode == OC_CLIENT) { //TODO: should the client be responding to requests? return; } protocolRequest.observationOption = OC_OBSERVE_NO_OPTION; protocolRequest.qos = (rcvdPdu->hdr->type == COAP_MESSAGE_CON) ? OC_HIGH_QOS : OC_LOW_QOS; protocolRequest.coapID = rcvdPdu->hdr->id; protocolRequest.delayedResNeeded = rcvdRequest->delayedResNeeded; protocolRequest.secured = rcvdRequest->secure; // fill OCCoAPToken structure RetrieveOCCoAPToken(rcvdPdu, &protocolRequest.requestToken); OC_LOG_V(INFO, TAG, " Token received %d bytes", protocolRequest.requestToken.tokenLength); OC_LOG_BUFFER(INFO, TAG, protocolRequest.requestToken.token, protocolRequest.requestToken.tokenLength); // fill OCDevAddr memcpy(&protocolRequest.requesterAddr, (OCDevAddr *) &rcvdRequest->remote, sizeof(OCDevAddr)); // Retrieve Uri and Query from received coap pdu result = ParseCoAPPdu(rcvdPdu, protocolRequest.resourceUrl, protocolRequest.query, &(protocolRequest.observationOption), NULL, &(protocolRequest.numRcvdVendorSpecificHeaderOptions), protocolRequest.rcvdVendorSpecificHeaderOptions, &rcvdBlock1, &rcvdBlock2, &rcvdSize1, NULL, protocolRequest.reqJSONPayload); VERIFY_SUCCESS(result, OC_STACK_OK); switch (rcvdPdu->hdr->code) { case COAP_REQUEST_GET: { protocolRequest.method = OC_REST_GET; break; } case COAP_REQUEST_POST: { protocolRequest.method = OC_REST_POST; break; } case COAP_REQUEST_DELETE: { protocolRequest.method = OC_REST_DELETE; break; } case COAP_REQUEST_PUT: { protocolRequest.method = OC_REST_PUT; break; } default: { OC_LOG_V(ERROR, TAG, "Received CoAP method %d not supported", rcvdPdu->hdr->code); goto exit; } } if(rcvdBlock1.szx != 7) { protocolRequest.reqPacketSize = 1 << (rcvdBlock1.szx + 4); protocolRequest.reqMorePacket = rcvdBlock1.m; protocolRequest.reqPacketNum = rcvdBlock1.num; } else { // No block1 received rcvdSize1 = strlen((const char *)protocolRequest.reqJSONPayload)+1; protocolRequest.reqTotalSize = rcvdSize1; } if(rcvdBlock2.szx != 7) { protocolRequest.resPacketSize = 1 << (rcvdBlock2.szx + 4); protocolRequest.resPacketNum = rcvdBlock2.num; } requestResult = HandleStackRequests(&protocolRequest); if(requestResult == OC_STACK_VIRTUAL_DO_NOT_HANDLE || requestResult == OC_STACK_OK || requestResult == OC_STACK_RESOURCE_CREATED || requestResult == OC_STACK_RESOURCE_DELETED || requestResult == OC_STACK_INVALID_DEVICE_INFO) { goto exit; } else if(requestResult == OC_STACK_NO_MEMORY || requestResult == OC_STACK_ERROR || requestResult == OC_STACK_NOTIMPL || requestResult == OC_STACK_NO_RESOURCE || requestResult == OC_STACK_RESOURCE_ERROR) { // TODO: should we send an error also when we receive a non-secured request to a secure resource? // TODO: should we consider some sort of error response OC_LOG(DEBUG, TAG, PCF("We should send some sort of error message")); // generate the pdu, if the request was CON, then the response is ACK, otherwire NON sendPdu = GenerateCoAPPdu((rcvdPdu->hdr->type == COAP_MESSAGE_CON)? COAP_MESSAGE_ACK : COAP_MESSAGE_NON, OCToCoAPResponseCode(requestResult), rcvdPdu->hdr->id, &protocolRequest.requestToken, NULL, NULL); VERIFY_NON_NULL(sendPdu); coap_show_pdu(sendPdu); sendFlag = (coap_send_flags_t)(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")); } goto exit; } else if(requestResult == OC_STACK_SLOW_RESOURCE) { if(rcvdPdu->hdr->type == COAP_MESSAGE_CON) { // generate the pdu, if the request was CON, then the response is ACK, otherwire NON sendPdu = GenerateCoAPPdu(COAP_MESSAGE_ACK, 0, rcvdPdu->hdr->id, NULL, NULL, NULL); VERIFY_NON_NULL(sendPdu); coap_show_pdu(sendPdu); sendFlag = (coap_send_flags_t)(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")); } } else { goto exit; } } exit: return; }
//Start sample app 'sendrecv' on different Linux box. void SendReceiveTest() { Serial.println("entering SendReceiveTest..."); OCDevAddr ipAddr, peerAddr, recvAddr; int32_t sfd; int32_t recvLen; uint8_t buf[MAX_BUF_SIZE]; uint16_t recvPort; VERIFY_SUCCESS(OCBuildIPv4Address( 0, 0, 0, 0, TEST_PORT_NUM, &ipAddr), ERR_SUCCESS); VERIFY_SUCCESS(OCBuildIPv4Address(PEER_IP_ADDR[0], PEER_IP_ADDR[1], PEER_IP_ADDR[2], PEER_IP_ADDR[3], TEST_PORT_NUM, &peerAddr), ERR_SUCCESS); VERIFY_SUCCESS(OCInitUDP( &ipAddr, &sfd), ERR_SUCCESS); OC_LOG(DEBUG, MOD_NAME, PCF("Peer Addr :")); OC_LOG_BUFFER(INFO, MOD_NAME, peerAddr.addr, peerAddr.size); for (int i = 0; i < 300; i++) { OC_LOG_V(DEBUG, MOD_NAME, "--------------------- i --------------- %d", i); VERIFY_SUCCESS(OCSendTo(sfd, TEST_BUF, i + 10, 0, &peerAddr), i+10); delay(2000); recvLen = OCRecvFrom(sfd, buf, MAX_BUF_SIZE, 0, &recvAddr); if (recvLen > 0) { OC_LOG(DEBUG, MOD_NAME, PCF("Rcvd data from :")); OC_LOG_BUFFER(INFO, MOD_NAME, recvAddr.addr, recvAddr.size); OCDevAddrToPort(&recvAddr, &recvPort); OC_LOG_V(DEBUG, MOD_NAME, "Recv Data from Port %hu", recvPort); OC_LOG(DEBUG, MOD_NAME, PCF("Data Length :")); OC_LOG_BUFFER(INFO, MOD_NAME, (uint8_t*)&recvLen, sizeof(recvLen)); OC_LOG(DEBUG, MOD_NAME, PCF("Data :")); if (recvLen < 255) { OC_LOG_BUFFER(INFO, MOD_NAME, buf, recvLen); } else { int idx = 0; int rem = recvLen; do { if (rem > 255) { OC_LOG_BUFFER(INFO, MOD_NAME, buf + idx, 255); rem = rem - 255; } else { OC_LOG_BUFFER(INFO, MOD_NAME, buf + idx, rem); rem = 0; } idx = idx + 255; }while(rem > 0); } } } VERIFY_SUCCESS(OCClose( sfd), ERR_SUCCESS); OC_LOG(DEBUG, MOD_NAME, PCF("WifiTest - Completed")); }