OCStackResult AddObserver (const char *resUri, const char *query, OCObservationId obsId, OCCoAPToken *token, OCDevAddr *addr, OCResource *resHandle, OCQualityOfService qos) { ResourceObserver *obsNode = NULL; obsNode = (ResourceObserver *) OCCalloc(1, sizeof(ResourceObserver)); if (obsNode) { obsNode->observeId = obsId; obsNode->resUri = (unsigned char *)OCMalloc(strlen(resUri)+1); VERIFY_NON_NULL (obsNode->resUri); memcpy (obsNode->resUri, resUri, strlen(resUri)+1); obsNode->qos = qos; if(query) { obsNode->query = (unsigned char *)OCMalloc(strlen(query)+1); VERIFY_NON_NULL (obsNode->query); memcpy (obsNode->query, query, strlen(query)+1); } obsNode->token.tokenLength = token->tokenLength; memcpy (obsNode->token.token, token->token, token->tokenLength); obsNode->addr = (OCDevAddr *)OCMalloc(sizeof(OCDevAddr)); VERIFY_NON_NULL (obsNode->addr); memcpy (obsNode->addr, addr, sizeof(OCDevAddr)); obsNode->resource = resHandle; LL_APPEND (serverObsList, obsNode); return OC_STACK_OK; } exit: if (obsNode) { OCFree(obsNode->resUri); OCFree(obsNode->query); OCFree(obsNode->addr); OCFree(obsNode); } return OC_STACK_NO_MEMORY; }
OCEntityHandlerRequest *CopyRequest(OCEntityHandlerRequest *entityHandlerRequest) { OC_LOG(INFO, TAG, "Copying received request for slow response"); OCEntityHandlerRequest *request = (OCEntityHandlerRequest *)OCMalloc(sizeof(OCEntityHandlerRequest)); if (request) { // Do shallow copy memcpy(request, entityHandlerRequest, sizeof(OCEntityHandlerRequest)); // Do deep copy of query request->query = (unsigned char * )OCMalloc(strlen((const char *)entityHandlerRequest->query) + 1); if (request->query) { strcpy((char *)request->query, (const char *)entityHandlerRequest->query); // Copy the request payload request->reqJSONPayload = (unsigned char * )OCMalloc(strlen((const char *)entityHandlerRequest->reqJSONPayload) + 1); if (request->reqJSONPayload) { strcpy((char *)request->reqJSONPayload, (const char *)entityHandlerRequest->reqJSONPayload); // Ignore vendor specific header options for example request->numRcvdVendorSpecificHeaderOptions = 0; request->rcvdVendorSpecificHeaderOptions = NULL; } else { OCFree(request->query); OCFree(request); request = NULL; } } else { OCFree(request); request = NULL; } } if (request) { OC_LOG(INFO, TAG, "Copied client request"); } else { OC_LOG(ERROR, TAG, "Error copying client request"); } return request; }
void GetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo) { // CA layer interface publishes security data structures ONLY if // stack is compiled in SECURED mode CADtlsPskCredsBlob_t * caBlob = NULL; if(secConfigData && credInfo) { unsigned int i = 0; OCSecBlob * osb = (OCSecBlob*)secConfigData->blob; for ( ;(i<secConfigData->numBlob) && osb; i++) { if (osb->type == OC_BLOB_TYPE_PSK) { caBlob = (CADtlsPskCredsBlob_t *)OCCalloc(sizeof(CADtlsPskCredsBlob_t), 1); if (caBlob) { OCDtlsPskCredsBlob * ocBlob = (OCDtlsPskCredsBlob *)osb->val; memcpy(caBlob->identity, ocBlob->identity, sizeof(caBlob->identity)); caBlob->num = ocBlob->num; caBlob->creds = (OCDtlsPskCreds*) OCMalloc(caBlob->num * sizeof(OCDtlsPskCreds)); if (caBlob->creds) { memcpy(caBlob->creds, ocBlob->creds, caBlob->num * sizeof(OCDtlsPskCreds)); *credInfo = caBlob; // We copied the credential blob in the CA data structure. // Let's get out of here. return; } } break; } osb = config_data_next_blob(osb); } } // Clear memory if any memory allocation failed above if(caBlob) { OCFree(caBlob->creds); OCFree(caBlob); } }
/** * This internal API removes/clears the global variable holding the security * config data. This needs to be invoked when OIC stack is shutting down. * * @retval none */ void DeinitOCSecurityInfo() { if (secConfigData) { // Initialize sensitive data to zeroes before freeing. memset(secConfigData, 0, secConfigDataLen); OCFree(secConfigData); secConfigData = NULL; } }
OCStackResult ExtractKeyValueFromRequest(char *request, char **key, char **value) { OCStackResult result = OC_STACK_OK; size_t length = 0; char* pRequest = (char *)request + strlen(OIC_ACTION_PREFIX); char* iterToken, *iterTokenPtr; iterToken = (char *) strtok_r(pRequest, ":", &iterTokenPtr); length = strlen(iterToken) + 1; *key = (char *)OCMalloc(length); VARIFY_POINTER_NULL(*key, result, exit); strncpy(*key, iterToken + 1, length); ((*key)[ (( length - 1 ) - 2) ]) = '\0'; iterToken = (char *) strtok_r(NULL, "}", &iterTokenPtr); length = strlen(iterToken) + 1; *value = (char *)OCMalloc(length); VARIFY_POINTER_NULL(*key, result, exit); strncpy(*value, iterToken + 1, length); ((*value)[ (( length - 1 ) - 2) ]) = '\0'; exit: if(result != OC_STACK_OK) { OCFree(*key); OCFree(*value); *key = NULL; *value = NULL; } return result; }
// SIGINT alarm handler: alarm set by entity handler. Does // slow response when fired void AlarmHandler(int sig) { if (sig == SIGALRM) { OC_LOG (INFO, TAG, "Server starting slow response"); if (gRequestList.empty()) { OC_LOG (INFO, TAG, "No requests to service"); return; } // Get the request from the list OCEntityHandlerRequest *entityHandlerRequest = gRequestList.front(); gRequestList.pop_front(); if (entityHandlerRequest->method == OC_REST_GET) { OC_LOG (INFO, TAG, "Received OC_REST_GET from client"); ProcessGetRequest (entityHandlerRequest); } else { OC_LOG_V (INFO, TAG, "Received unsupported method %d from client", entityHandlerRequest->method); } // Free the request OCFree(entityHandlerRequest->query); OCFree(entityHandlerRequest->reqJSONPayload); OCFree(entityHandlerRequest); // If there are more requests in list, re-arm the alarm signal if (gRequestList.empty()) { alarm(SLOW_RESPONSE_DELAY_SEC); } } }
void DeleteActionSet(OCActionSet** actionset) { OCAction* pointer = (*actionset)->head; OCAction* pDel = NULL; while (pointer) { pDel = pointer; pointer = pointer->next; DeleteAction(&pDel); pDel->next = NULL; } OCFree((*actionset)->actionsetName); (*actionset)->head = NULL; }
void DeleteAction(OCAction** action) { OCCapability* pointer = (*action)->head; OCCapability* pDel = NULL; while (pointer) { pDel = pointer; pointer = pointer->next; DeleteCapability(pDel); pDel->next = NULL; } OCFree((*action)->resourceUri); (*action)->resourceUri = NULL; (*action)->next = NULL; }
OCStackApplicationResult ActionSetCB(void* context, OCDoHandle handle, OCClientResponse* clientResponse) { printf("\n\n\tcallback is called\n\n"); ClientRequstInfo *info = GetClientRequestInfo(clientRequstList, handle); if (info) { int idx; unsigned char *responseJson; responseJson = (unsigned char *) OCMalloc( (unsigned int) (strlen((char *) clientResponse->resJSONPayload) + 1)); // We need the body of response. // Copy the body from the response strcpy((char *) responseJson, ((char *) clientResponse->resJSONPayload + OC_JSON_PREFIX_LEN)); idx = strlen((char *) responseJson) - OC_JSON_SUFFIX_LEN; // And insert NULL at the end of body. (responseJson[idx]) = 0; OCEntityHandlerResponse response = { 0 }; response.ehResult = OC_EH_OK; response.payload = responseJson; response.payloadSize = (unsigned int) strlen((char *) responseJson) + 1; response.persistentBufferFlag = 0; response.requestHandle = (OCRequestHandle) info->ehRequest; response.resourceHandle = (OCResourceHandle) info->collResource; OCDoResponse(&response); RemoveClientRequestInfo(&clientRequstList, info); OCFree(responseJson); } // g_AggregateResponseHandle return OC_STACK_KEEP_TRANSACTION; }
OCStackResult BuildCollectionGroupActionJSONResponse(OCMethod method/*OCEntityHandlerFlag flag*/, OCResource *resource, OCEntityHandlerRequest *ehRequest) { OCStackResult stackRet = OC_STACK_ERROR; OC_LOG(INFO, TAG, PCF("Group Action is requested.")); // if (stackRet == OC_STACK_OK) { char *doWhat = NULL; char *details = NULL; size_t bufferLength = 0; unsigned char buffer[MAX_RESPONSE_LENGTH] = { 0 }; unsigned char *bufferPtr = NULL; bufferPtr = buffer; OCResource * collResource = (OCResource *) ehRequest->resource; char *jsonResponse; ExtractKeyValueFromRequest((char *)ehRequest->reqJSONPayload, &doWhat, &details); cJSON *json; cJSON *format; if (method == OC_REST_PUT) { json = cJSON_CreateObject(); cJSON_AddStringToObject(json, "href", resource->uri); cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject()); OC_LOG(INFO, TAG, PCF("Group Action[PUT].")); if(strcmp(doWhat, "ActionSet") == 0) { OCActionSet *actionSet; BuildActionSetFromString(&actionSet, details); if(actionSet != NULL) { AddActionSet(&resource->actionsetHead, actionSet); stackRet = OC_STACK_OK; } else { stackRet = OC_STACK_ERROR; } } else if (strcmp(doWhat, "DelActionSet") == 0) { if (FindAndDeleteActionSet(&resource, details) == OC_STACK_OK) { stackRet = OC_STACK_OK; } else { stackRet = OC_STACK_ERROR; } } jsonResponse = cJSON_Print(json); cJSON_Delete(json); strcat((char *) bufferPtr, jsonResponse); bufferLength = strlen((const char *) buffer); if (bufferLength > 0) { OCEntityHandlerResponse response = { 0 }; response.ehResult = OC_EH_OK; response.payload = buffer; response.payloadSize = bufferLength + 1; response.persistentBufferFlag = 0; response.requestHandle = (OCRequestHandle) ehRequest->requestHandle; response.resourceHandle = (OCResourceHandle) collResource; stackRet = OCDoResponse(&response); } stackRet = OC_STACK_OK; } if (method == OC_REST_POST) { OC_LOG(INFO, TAG, PCF("Group Action[POST].")); OCActionSet *actionset = NULL; json = cJSON_CreateObject(); cJSON_AddStringToObject(json, "href", resource->uri); if (strcmp(doWhat, "DoAction") == 0) { if (GetActionSet(details, resource->actionsetHead, &actionset) != OC_STACK_OK) { OC_LOG(INFO, TAG, PCF("ERROR")); stackRet = OC_STACK_ERROR; } if (actionset == NULL) { OC_LOG(INFO, TAG, PCF("ERROR")); stackRet = OC_STACK_ERROR; } else { OCAction *pointerAction = actionset->head; unsigned int num = GetNumOfTargetResource(pointerAction); ((OCServerRequest *) ehRequest->requestHandle)->ehResponseHandler = HandleAggregateResponse; ((OCServerRequest *) ehRequest->requestHandle)->numResponses = num + 1; while (pointerAction != NULL) { unsigned char actionDesc[MAX_RESPONSE_LENGTH] = { 0 }; unsigned char* actionDescPtr = actionDesc; uint16_t remaining = MAX_RESPONSE_LENGTH; strncpy((char *) actionDescPtr, (const char *) OC_JSON_PREFIX, strlen((const char *) OC_JSON_PREFIX) + 1); BuildActionJSON(pointerAction, actionDescPtr, &remaining); strncat((char *) actionDescPtr, (const char *) OC_JSON_SUFFIX, strlen((const char *) OC_JSON_SUFFIX)); ClientRequstInfo *info = (ClientRequstInfo *) OCMalloc( sizeof(ClientRequstInfo)); memset(info, 0, sizeof(ClientRequstInfo)); info->collResource = resource; info->ehRequest = (OCServerRequest *) ehRequest->requestHandle; SendAction(&info->required, pointerAction->resourceUri, actionDescPtr); AddClientRequestInfo(&clientRequstList, info); pointerAction = pointerAction->next; } stackRet = OC_STACK_OK; } } else if (strcmp(doWhat, "GetActionSet") == 0) { char *plainText = NULL; OCActionSet *actionset = NULL; cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject()); GetActionSet(details, resource->actionsetHead, &actionset); if (actionset != NULL) { BuildStringFromActionSet(actionset, &plainText); if (plainText != NULL) { cJSON_AddStringToObject(format, "ActionSet", plainText); } stackRet = OC_STACK_OK; } } jsonResponse = cJSON_Print(json); cJSON_Delete(json); strcat((char *) bufferPtr, jsonResponse); bufferLength = strlen((const char *) buffer); if (bufferLength > 0) { OCEntityHandlerResponse response = { 0 }; response.ehResult = OC_EH_OK; response.payload = buffer; response.payloadSize = bufferLength + 1; response.persistentBufferFlag = 0; response.requestHandle = (OCRequestHandle) ehRequest->requestHandle; response.resourceHandle = (OCResourceHandle) collResource; stackRet = OCDoResponse(&response); } } OCFree(doWhat); OCFree(details); } return stackRet; }
OCStackResult BuildActionSetFromString(OCActionSet **set, char* actiondesc) { OCStackResult result = OC_STACK_OK; char *iterToken = NULL, *iterTokenPtr = NULL; char *descIterToken = NULL, *descIterTokenPtr = NULL; char *attrIterToken = NULL, *attrIterTokenPtr = NULL; char *desc = NULL, *attr = NULL; char *key = NULL, *value = NULL; OCAction *action = NULL; OCCapability *capa = NULL; OC_LOG(INFO, TAG, PCF("Build ActionSet Instance.")); *set = (OCActionSet*) OCMalloc(sizeof(OCActionSet)); VARIFY_POINTER_NULL(*set, result, exit) iterToken = (char *) strtok_r(actiondesc, ACTION_DELIMITER, &iterTokenPtr); memset(*set, 0, sizeof(OCActionSet)); (*set)->actionsetName = (char *)OCMalloc(sizeof(OCActionSet)); VARIFY_POINTER_NULL((*set)->actionsetName, result, exit) VARIFY_PARAM_NULL(iterToken, result, exit) strncpy((*set)->actionsetName, iterToken, strlen(iterToken) + 1); OC_LOG_V(INFO, TAG, "ActionSet Name : %s", (*set)->actionsetName); iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr); while(iterToken) { desc = (char *)OCMalloc(strlen(iterToken) + 1); strncpy(desc, iterToken, strlen(iterToken) + 1); descIterToken = (char *) strtok_r(desc, ATTR_DELIMITER, &descIterTokenPtr); while(descIterToken) { attr = (char *)OCMalloc(strlen(descIterToken) + 1); strncpy(attr, descIterToken, strlen(descIterToken) + 1); attrIterToken = (char *) strtok_r(attr, ATTR_ASSIGN, &attrIterTokenPtr); key = (char *)OCMalloc(strlen(attrIterToken) + 1); VARIFY_POINTER_NULL(key, result, exit) VARIFY_PARAM_NULL(attrIterToken, result, exit) strncpy(key, attrIterToken, strlen(attrIterToken) + 1); attrIterToken = (char *) strtok_r(NULL, ATTR_ASSIGN, &attrIterTokenPtr); value = (char *)OCMalloc(strlen(attrIterToken) + 1); VARIFY_POINTER_NULL(value, result, exit) VARIFY_PARAM_NULL(attrIterToken, result, exit) strncpy(value, attrIterToken, strlen(attrIterToken) + 1); if(strcmp(key, "uri") == 0) { OC_LOG(INFO, TAG, PCF("Build OCAction Instance.")); action = (OCAction*)OCMalloc(sizeof(OCAction)); VARIFY_POINTER_NULL(action, result, exit) memset(action, 0, sizeof(OCAction)); action->resourceUri = (char *)OCMalloc(strlen(value) + 1); VARIFY_POINTER_NULL(action->resourceUri, result, exit) VARIFY_PARAM_NULL(value, result, exit) strncpy(action->resourceUri, value, strlen(value) + 1); } else { if( (key != NULL) && (value != NULL)) { OC_LOG(INFO, TAG, PCF("Build OCCapability Instance.")); capa = (OCCapability*)OCMalloc(sizeof(OCCapability)); VARIFY_POINTER_NULL(capa, result, exit) memset(capa, 0, sizeof(OCCapability)); capa->capability = (char *)OCMalloc(strlen(key) + 1); capa->status = (char *)OCMalloc(strlen(value) + 1); strncpy(capa->capability, key, strlen(key) + 1); strncpy(capa->status, value, strlen(value) + 1); VARIFY_POINTER_NULL(action, result, exit) AddCapability(&action->head, capa); } } OCFree(key); OCFree(value); OCFree(attr); descIterToken = (char *) strtok_r(NULL, ATTR_DELIMITER, &descIterTokenPtr); } AddAction(&(*set)->head, action); iterToken = (char *) strtok_r(NULL, ACTION_DELIMITER, &iterTokenPtr); OCFree(desc); } return OC_STACK_OK; exit: OCFree(attr); OCFree(desc); OCFree(capa); OCFree(action); OCFree(*set); *set = NULL; return result; }
OCStackResult SendListObserverNotification (OCResource * resource, OCObservationId *obsIdList, uint8_t numberOfIds, unsigned char *notificationJSONPayload, uint32_t maxAge, OCQualityOfService qos) { uint8_t numIds = numberOfIds; ResourceObserver *observation = NULL; uint8_t numSentNotification = 0; OCServerRequest * request = NULL; OCStackResult result = OC_STACK_ERROR; OCEntityHandlerResponse ehResponse = {0}; OC_LOG(INFO, TAG, PCF("Entering SendListObserverNotification")); while(numIds) { OC_LOG_V(INFO, TAG, "Need to notify observation id %d", *obsIdList); observation = NULL; observation = GetObserverUsingId (*obsIdList); if(observation) { // Found observation - verify if it matches the resource handle if (observation->resource == resource) { qos = DetermineObserverQoS(OC_REST_GET, observation, qos); result = AddServerRequest(&request, 0, 0, 0, 1, OC_REST_GET, 0, resource->sequenceNum, qos, observation->query, NULL, NULL, &observation->token, observation->addr, observation->resUri, 0); request->observeResult = OC_STACK_OK; if(request && result == OC_STACK_OK) { memset(&ehResponse, 0, sizeof(OCEntityHandlerResponse)); ehResponse.ehResult = OC_EH_OK; ehResponse.payload = (unsigned char *) OCMalloc(MAX_RESPONSE_LENGTH); if(!ehResponse.payload) { FindAndDeleteServerRequest(request); continue; } strcpy((char *)ehResponse.payload, (const char *)notificationJSONPayload); ehResponse.payloadSize = strlen((const char *)ehResponse.payload) + 1; ehResponse.persistentBufferFlag = 0; ehResponse.requestHandle = (OCRequestHandle) request; ehResponse.resourceHandle = (OCResourceHandle) resource; result = OCDoResponse(&ehResponse); if(result == OC_STACK_OK) { OCFree(ehResponse.payload); FindAndDeleteServerRequest(request); } } else { FindAndDeleteServerRequest(request); } numSentNotification++; } } obsIdList++; numIds--; } if(numSentNotification == numberOfIds) { return OC_STACK_OK; } else if(numSentNotification == 0) { return OC_STACK_NO_OBSERVERS; } else { //TODO: we need to signal that not every one in the // list got an update, should we also indicate who did not receive on? return OC_STACK_OK; } }
int main(int argc, char* argv[]) { uint8_t addr[20] = {0}; uint8_t* paddr = NULL; uint16_t port = OC_WELL_KNOWN_PORT; uint8_t ifname[] = "eth0"; OC_LOG(DEBUG, TAG, "OCServer is starting..."); /*Get Ip address on defined interface and initialize coap on it with random port number * this port number will be used as a source port in all coap communications*/ if ( OCGetInterfaceAddress(ifname, sizeof(ifname), AF_INET, addr, sizeof(addr)) == ERR_SUCCESS) { OC_LOG_V(INFO, TAG, "Starting ocserver on address %s:%d",addr,port); paddr = addr; } if (OCInit((char *) paddr, port, OC_SERVER) != OC_STACK_OK) { OC_LOG(ERROR, TAG, "OCStack init error"); return 0; } /* * Declare and create the example resource: LED */ createLEDResource(gResourceUri, &LED, false, 0); // Initialize slow response alarm signal(SIGALRM, AlarmHandler); // Break from loop with Ctrl-C OC_LOG(INFO, TAG, "Entering ocserver main loop..."); signal(SIGINT, handleSigInt); while (!gQuitFlag) { if (OCProcess() != OC_STACK_OK) { OC_LOG(ERROR, TAG, "OCStack process error"); return 0; } sleep(2); } OC_LOG(INFO, TAG, "Exiting ocserver main loop..."); // Free requests if (!gRequestList.empty()) { for (auto iter = gRequestList.begin(); iter != gRequestList.end(); ++iter) { OCFree((*iter)->query); OCFree((*iter)->reqJSONPayload); OCFree(*iter); } gRequestList.clear(); } if (OCStop() != OC_STACK_OK) { OC_LOG(ERROR, TAG, "OCStack process error"); } return 0; }