From e2fb840abe809f7cd7be00a94afe24010f8a0a62 Mon Sep 17 00:00:00 2001 From: clairiky Date: Tue, 19 Aug 2014 09:07:30 -0700 Subject: [PATCH] Check-in for container tests for C APIs. They were supposed to be in the previous commit, somehow they got missed during rebase. Removed tabs Change-Id: Id5c6f6d64d42cf3ac25ad866ef926c209f7812ec --- .../linux/SimpleClientServer/occlientcoll.cpp | 333 +++++++++++++++++++++ .../linux/SimpleClientServer/ocservercoll.cpp | 272 +++++++++++++++++ 2 files changed, 605 insertions(+) create mode 100644 csdk/stack/samples/linux/SimpleClientServer/occlientcoll.cpp create mode 100644 csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp diff --git a/csdk/stack/samples/linux/SimpleClientServer/occlientcoll.cpp b/csdk/stack/samples/linux/SimpleClientServer/occlientcoll.cpp new file mode 100644 index 0000000..329ba61 --- /dev/null +++ b/csdk/stack/samples/linux/SimpleClientServer/occlientcoll.cpp @@ -0,0 +1,333 @@ +//****************************************************************** +// +// Copyright 2014 Intel Corporation All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#include +#include +#include +#include +#include +#include +#include +#include +#include "logger.h" +const char *getResult(OCStackResult result); +std::string getIPAddrTBServer(OCClientResponse * clientResponse); +std::string getPortTBServer(OCClientResponse * clientResponse); +std::string getQueryStrForGetPut(unsigned const char * responsePayload); + +#define TAG PCF("occlient") +#define CTX_VAL 0x99 +#ifndef MAX_LENGTH_IPv4_ADDR +#define MAX_LENGTH_IPv4_ADDR 16 +#endif + +#define MAX_TEST_CASES 5 + +static int UNICAST_DISCOVERY = 0; +static int TEST_CASE = 0; +static std::string putPayload = "{\"state\":\"off\",\"power\":\"0\"}"; + +// The handle for the observe registration +OCDoHandle gObserveDoHandle; +// After this crosses a threshold client deregisters for further observations +int gNumNotifies = 1; + +int gQuitFlag = 0; +/* SIGINT handler: set gQuitFlag to 1 for graceful termination */ +void handleSigInt(int signum) { + if (signum == SIGINT) { + gQuitFlag = 1; + } +} + +// Forward Declaration +OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse); +int InitGetRequestToUnavailableResource(OCClientResponse * clientResponse); +int InitObserveRequest(OCClientResponse * clientResponse); +int InitPutRequest(OCClientResponse * clientResponse); +int InitGetRequest(OCClientResponse * clientResponse); +int InitDiscovery(); + +void PrintUsage() +{ + OC_LOG(INFO, TAG, "Usage : occlient "); + OC_LOG(INFO, TAG, "Test Case 1 : Discover Resources"); + OC_LOG(INFO, TAG, "Test Case 2 : Discover Resources and Initiate Get Request"); + OC_LOG(INFO, TAG, "Test Case 3 : Discover Resources and Initiate Get/Put Requests"); + OC_LOG(INFO, TAG, "Test Case 4 : Discover Resources and Initiate Observe Requests"); + OC_LOG(INFO, TAG, "Test Case 5 : Discover Resources and Initiate Get Request for a resource which is unavailable"); +} + +OCStackApplicationResult putReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse) { + if(clientResponse) {} + if(ctx == (void*)CTX_VAL) { + OC_LOG_V(INFO, TAG, "Callback Context for PUT query recvd successfully"); + OC_LOG_V(INFO, TAG, "JSON = %s =============> Discovered", clientResponse->resJSONPayload); + } + + return OC_STACK_KEEP_TRANSACTION; +} + +OCStackApplicationResult getReqCB(void* ctx, OCDoHandle handle, OCClientResponse * clientResponse) { + OC_LOG_V(INFO, TAG, "StackResult: %s", + getResult(clientResponse->result)); + if(ctx == (void*)CTX_VAL) { + OC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber); + if(clientResponse->sequenceNumber == 0) { + OC_LOG_V(INFO, TAG, "Callback Context for GET query recvd successfully"); + OC_LOG_V(INFO, TAG, "Fnd' Rsrc': %s", clientResponse->resJSONPayload); + } + else { + OC_LOG_V(INFO, TAG, "Callback Context for OBSERVE notification recvd successfully %d", gNumNotifies); + OC_LOG_V(INFO, TAG, "Fnd' Rsrc': %s", clientResponse->resJSONPayload); + gNumNotifies++; + if (gNumNotifies == 3) + { + if (OCCancel (gObserveDoHandle) != OC_STACK_OK){ + OC_LOG(ERROR, TAG, "Observe cancel error"); + } + } + } + } + InitPutRequest(clientResponse); + return OC_STACK_KEEP_TRANSACTION; +} + + +// This is a function called back when a device is discovered +OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle handle, + OCClientResponse * clientResponse) { + uint8_t remoteIpAddr[4]; + uint16_t remotePortNu; + + OC_LOG(INFO, TAG, + "Entering discoveryReqCB (Application Layer CB)"); + OC_LOG_V(INFO, TAG, "StackResult: %s", + getResult(clientResponse->result)); + + if (ctx == (void*) CTX_VAL) { + OC_LOG_V(INFO, TAG, "Callback Context recvd successfully"); + } + + OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr, + remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3); + OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu); +#if 0 + OC_LOG_V(INFO, TAG, + "Device =============> Discovered %s @ %d.%d.%d.%d:%d", + clientResponse->resJSONPayload, remoteIpAddr[0], remoteIpAddr[1], + remoteIpAddr[2], remoteIpAddr[3], remotePortNu); +#endif + + InitGetRequest(clientResponse); + + return OC_STACK_KEEP_TRANSACTION; +} + + +int InitGetRequestToUnavailableResource(OCClientResponse * clientResponse) +{ + OCStackResult ret; + OCCallbackData cbData; + OCDoHandle handle; + std::ostringstream getQuery; + getQuery << "coap://" << getIPAddrTBServer(clientResponse) << ":" << getPortTBServer(clientResponse) << "/SomeUnknownResource"; + cbData.cb = getReqCB; + cbData.context = (void*)CTX_VAL; + ret = OCDoResource(&handle, OC_REST_GET, getQuery.str().c_str(), 0, 0, OC_NON_CONFIRMABLE, &cbData); + if (ret != OC_STACK_OK) + { + OC_LOG(ERROR, TAG, "OCStack resource error"); + } + return ret; +} + + +int InitObserveRequest(OCClientResponse * clientResponse) +{ + OCStackResult ret; + OCCallbackData cbData; + OCDoHandle handle; + std::ostringstream obsReg; + obsReg << "coap://" << getIPAddrTBServer(clientResponse) << ":" << getPortTBServer(clientResponse) << getQueryStrForGetPut(clientResponse->resJSONPayload); + cbData.cb = getReqCB; + cbData.context = (void*)CTX_VAL; + OC_LOG_V(INFO, TAG, "PUT payload from client = %s ", putPayload.c_str()); + ret = OCDoResource(&handle, OC_REST_OBSERVE, obsReg.str().c_str(), 0, 0, OC_NON_CONFIRMABLE, &cbData); + if (ret != OC_STACK_OK) + { + OC_LOG(ERROR, TAG, "OCStack resource error"); + } + else + { + gObserveDoHandle = handle; + } + return ret; +} + + +int InitPutRequest(OCClientResponse * clientResponse) +{ + OCStackResult ret; + OCCallbackData cbData; + OCDoHandle handle; + //* Make a PUT query*/ + std::ostringstream getQuery; + getQuery << "coap://" << getIPAddrTBServer(clientResponse) << ":" << getPortTBServer(clientResponse) << + "/a/sroom?if=oc.mi.b"; + cbData.cb = putReqCB; + cbData.context = (void*)CTX_VAL; + OC_LOG_V(INFO, TAG, "PUT payload from client = %s ", putPayload.c_str()); + ret = OCDoResource(&handle, OC_REST_PUT, getQuery.str().c_str(), 0, putPayload.c_str(), OC_NON_CONFIRMABLE, &cbData); + if (ret != OC_STACK_OK) + { + OC_LOG(ERROR, TAG, "OCStack resource error"); + } + return ret; +} + + +int InitGetRequest(OCClientResponse * clientResponse) +{ + OCStackResult ret; + OCCallbackData cbData; + OCDoHandle handle; + + uint8_t remoteIpAddr[4]; + uint16_t remotePortNu; + + OCDevAddrToIPv4Addr((OCDevAddr *) clientResponse->addr, remoteIpAddr, + remoteIpAddr + 1, remoteIpAddr + 2, remoteIpAddr + 3); + OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNu); + + //* Make a GET query*/ + std::ostringstream getQuery; + getQuery << "coap://" << getIPAddrTBServer(clientResponse) << ":" << getPortTBServer(clientResponse) << + //"/a/sroom?if=oc.mi.def"; + //"/a/sroom?if=oc.mi.ll"; + "/a/sroom?if=oc.mi.b"; + + std::cout << "Get Query: " << getQuery.str() << std::endl; + + cbData.cb = getReqCB; + cbData.context = (void*)CTX_VAL; + ret = OCDoResource(&handle, OC_REST_GET, getQuery.str().c_str(), 0, 0, OC_NON_CONFIRMABLE, &cbData); + if (ret != OC_STACK_OK) + { + OC_LOG(ERROR, TAG, "OCStack resource error"); + } + return ret; +} + +#define TEST_APP_UNICAST_DISCOVERY_QUERY PCF("coap://0.0.0.0:5683/oc/core") +int InitDiscovery() +{ + OCStackResult ret; + OCCallbackData cbData; + OCDoHandle handle; + /* Start a discovery query*/ + char szQueryUri[64] = { 0 }; + + //strcpy(szQueryUri, "coap://224.0.1.187:5683/oc/core");//?rt=core.sroom"); + strcpy(szQueryUri, "coap://0.0.0.0:5683/oc/core"); + + cbData.cb = discoveryReqCB; + cbData.context = (void*)CTX_VAL; + ret = OCDoResource(&handle, OC_REST_GET, szQueryUri, 0, 0, OC_NON_CONFIRMABLE, &cbData); + if (ret != OC_STACK_OK) + { + OC_LOG(ERROR, TAG, "OCStack resource error"); + } + return ret; +} + +int main(int argc, char* argv[]) { + uint8_t addr[20] = {0}; + uint8_t* paddr = NULL; + uint16_t port = USE_RANDOM_PORT; + uint8_t ifname[] = "eth0"; + + /*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 occlient on address %s",addr); + paddr = addr; + } + + /* Initialize OCStack*/ + if (OCInit((char *) paddr, port, OC_CLIENT) != OC_STACK_OK) { + OC_LOG(ERROR, TAG, "OCStack init error"); + return 0; + } + + InitDiscovery(); + + // Break from loop with Ctrl+C + OC_LOG(INFO, TAG, "Entering occlient main loop..."); + signal(SIGINT, handleSigInt); + while (!gQuitFlag) { + + if (OCProcess() != OC_STACK_OK) { + OC_LOG(ERROR, TAG, "OCStack process error"); + return 0; + } + + sleep(3); + } + OC_LOG(INFO, TAG, "Exiting occlient main loop..."); + + if (OCStop() != OC_STACK_OK) { + OC_LOG(ERROR, TAG, "OCStack stop error"); + } + + return 0; +} + +std::string getIPAddrTBServer(OCClientResponse * clientResponse) { + if(!clientResponse) return ""; + if(!clientResponse->addr) return ""; + uint8_t a, b, c, d = 0; + if(0 != OCDevAddrToIPv4Addr(clientResponse->addr, &a, &b, &c, &d) ) return ""; + + char ipaddr[16] = {'\0'}; + snprintf(ipaddr, sizeof(ipaddr), "%d.%d.%d.%d", a,b,c,d); // ostringstream not working correctly here, hence snprintf + //printf("IP address string of the TB server = %s\n", *out_ipaddr); + return std::string (ipaddr); +} + + +std::string getPortTBServer(OCClientResponse * clientResponse){ + if(!clientResponse) return ""; + if(!clientResponse->addr) return ""; + uint16_t p = 0; + if(0 != OCDevAddrToPort(clientResponse->addr, &p) ) return ""; + std::ostringstream ss; + ss << p; + return ss.str(); +} + +std::string getQueryStrForGetPut(unsigned const char * responsePayload){ + + std::string jsonPayload(reinterpret_cast(const_cast(responsePayload))); + + return "/a/sroom"; +} diff --git a/csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp b/csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp new file mode 100644 index 0000000..754d354 --- /dev/null +++ b/csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp @@ -0,0 +1,272 @@ +//****************************************************************** +// +// Copyright 2014 Intel Corporation All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + +#include +#include +#include +#include +#include +#include +#include +#include + +const char *getResult(OCStackResult result); + +#define TAG PCF("ocservercontainer") + +int gQuitFlag = 0; +int gLEDUnderObservation = 0; +void createResources(); +typedef struct LEDRESOURCE{ + OCResourceHandle handle; + bool state; + int power; +} LEDResource; + +static LEDResource LED; + +// TODO : hard coded for now, change after Sprint4 +const char rspGetLed[] = "{\"href\":\"/a/led\",\"rep\":{\"state\":\"on\",\"color\":\"yellow\"}}"; +// TODO : Needs to be changed to retrieve current status of led and return that in response +const char rspPutLed[] = "{\"href\":\"/a/led\",\"rep\":{\"state\":\"off\",\"color\":\"off\"}}"; +const char rspFailureLed[] = "{\"href\":\"/a/led\",\"rep\":{\"error\":\"LED_OP_FAIL\"}}"; + + +// TODO : hard coded for now, change after Sprint4 +const char rspGetFan[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"on\",\"speed\":10}}"; +// TODO : Needs to be changed to retrieve current status of fan and return that in response +const char rspPutFan[] = "{\"href\":\"/a/fan\",\"rep\":{\"state\":\"off\",\"speed\":0}}"; +const char rspFailureFan[] = "{\"href\":\"/a/fan\",\"rep\":{\"error\":\"FAN_OP_FAIL\"}}"; + +static OCEntityHandlerResult +HandleCallback(OCEntityHandlerRequest * ehRequest, const char* opStr, const char* errStr) +{ + OCEntityHandlerResult ret = OC_EH_OK; + + if (strlen(opStr) < ehRequest->resJSONPayloadLen) + { + strncpy((char*)ehRequest->resJSONPayload, opStr, ehRequest->resJSONPayloadLen); + } + else if (strlen(errStr) < ehRequest->resJSONPayloadLen) + { + strncpy((char*)ehRequest->resJSONPayload, errStr, ehRequest->resJSONPayloadLen); + ret = OC_EH_ERROR; + } + else + { + ret = OC_EH_ERROR; + } + + return ret; +} + +static void +PrintReceivedMsgInfo(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest ) +{ + const char* typeOfMessage; + + switch (flag) { + case OC_INIT_FLAG: + typeOfMessage = "OC_INIT_FLAG"; + break; + case OC_REQUEST_FLAG: + typeOfMessage = "OC_REQUEST_FLAG"; + break; + case OC_OBSERVE_FLAG: + typeOfMessage = "OC_OBSERVE_FLAG"; + break; + default: + typeOfMessage = "UNKNOWN"; + } + + OC_LOG_V(INFO, TAG, "Receiving message type: %s, method %s", + typeOfMessage, + (ehRequest->method == OC_REST_GET) ? "OC_REST_GET" : "OC_REST_PUT" ); +} + +OCEntityHandlerResult OCEntityHandlerLedCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest ) { + OCEntityHandlerResult ret = OC_EH_OK; + + OC_LOG_V(INFO, TAG, "Callback for Led"); + PrintReceivedMsgInfo(flag, ehRequest ); + + if(ehRequest && flag == OC_REQUEST_FLAG) + { + if(OC_REST_GET == ehRequest->method) + { + ret = HandleCallback(ehRequest, rspGetLed, rspFailureLed); + } + if(OC_REST_PUT == ehRequest->method) + { + ret = HandleCallback(ehRequest, rspPutLed, rspFailureLed); + } + } + else if (ehRequest && flag == OC_OBSERVE_FLAG) + { + gLEDUnderObservation = 1; + } + + return ret; +} + +OCEntityHandlerResult OCEntityHandlerFanCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest ) { + OCEntityHandlerResult ret = OC_EH_OK; + + OC_LOG_V(INFO, TAG, "Callback for Fan"); + PrintReceivedMsgInfo(flag, ehRequest ); + + if(ehRequest && flag == OC_REQUEST_FLAG) + { + if(OC_REST_GET == ehRequest->method) + { + ret = HandleCallback(ehRequest, rspGetFan, rspFailureFan); + } + if(OC_REST_PUT == ehRequest->method) + { + ret = HandleCallback(ehRequest, rspPutFan, rspFailureFan); + } + } + else if (ehRequest && flag == OC_OBSERVE_FLAG) + { + gLEDUnderObservation = 1; + } + + return ret; +} + +/* SIGINT handler: set gQuitFlag to 1 for graceful termination */ +void handleSigInt(int signum) { + if (signum == SIGINT) { + gQuitFlag = 1; + } +} + +void *ChangeLEDRepresentation (void *param) +{ + (void)param; + OCStackResult result = OC_STACK_ERROR; + + while (1) + { + sleep(10); + LED.power += 5; + if (gLEDUnderObservation) + { + OC_LOG_V(INFO, TAG, " =====> Notifying stack of new power level %d\n", LED.power); + result = OCNotifyObservers (LED.handle); + if (OC_STACK_NO_OBSERVERS == result) + { + gLEDUnderObservation = 0; + } + } + } + return NULL; +} + +int main() { + printf("hello world from main\n"); + OC_LOG(DEBUG, TAG, "OCServer is starting..."); + uint8_t addr[20] = {0}; + uint8_t* paddr = NULL; + uint16_t port = 5683; + uint8_t ifname[] = "eth0"; + pthread_t threadId; + + /*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 + */ + createResources(); + + /* + * Create a thread for changing the representation of the LED + */ + pthread_create (&threadId, NULL, ChangeLEDRepresentation, (void *)NULL); + + // 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(3); + } + + OC_LOG(INFO, TAG, "Exiting ocserver main loop..."); + + if (OCStop() != OC_STACK_OK) { + OC_LOG(ERROR, TAG, "OCStack process error"); + } + + return 0; +} +void createResources() { + LED.state = false; + OCResourceHandle room; + OCStackResult res = OCCreateResource(&room, + "core.sroom", + "oc.mi.ll", + "/a/sroom", + NULL, + OC_DISCOVERABLE); + OC_LOG_V(INFO, TAG, "Created room resource with result: %s", getResult(res)); + + OCResourceHandle light; + res = OCCreateResource(&light, + "core.light", + "oc.mi.def", + "/a/led", + OCEntityHandlerLedCb, + OC_DISCOVERABLE|OC_OBSERVABLE); + OC_LOG_V(INFO, TAG, "Created light resource with result: %s", getResult(res)); + + OCResourceHandle fan; + res = OCCreateResource(&fan, + "core.fan", + "oc.mi.def", + "/a/fan", + OCEntityHandlerFanCb, + OC_DISCOVERABLE|OC_OBSERVABLE); + OC_LOG_V(INFO, TAG, "Created fan resource with result: %s", getResult(res)); + + res = OCBindResource(room, light); + OC_LOG_V(INFO, TAG, "OC Bind Contained Resource to resource: %s", getResult(res)); + + res = OCBindResource(room, fan); + OC_LOG_V(INFO, TAG, "OC Bind Contained Resource to resource: %s", getResult(res)); +} + + -- 2.7.4