Initial Push of Arduino Sample Apps
authorJoseph Morrow <joseph.l.morrow@intel.com>
Mon, 18 Aug 2014 21:04:21 +0000 (17:04 -0400)
committerJoseph Morrow <joseph.l.morrow@intel.com>
Wed, 20 Aug 2014 18:15:28 +0000 (14:15 -0400)
Right now, tokens are messed up. I cannot get Observe operation to
function properly on Linux or Arduino.

Right now, here is the Arduino server only.

Patch Set 2: Removed "local.properties." This file should NEVER be
committed.

Patch Set 4: Made changes to READMEs as proposed by Bill Dieter.

Patch Set 5-7: Rebases

Path Set 8: Updated stack files to build for Arduino as well.
Arduino compiler is a little bit more per-snickety than the linux compiler.

Change-Id: I21b9396d1d22b9189db65ef31d4528720b01c5b9

csdk/README
csdk/occoap/src/occoap.c
csdk/stack/samples/arduino/SimpleClientServer/README [new file with mode: 0644]
csdk/stack/samples/arduino/SimpleClientServer/makefile [new file with mode: 0644]
csdk/stack/samples/arduino/SimpleClientServer/ocserver/README [new file with mode: 0644]
csdk/stack/samples/arduino/SimpleClientServer/ocserver/makefile [new file with mode: 0644]
csdk/stack/samples/arduino/SimpleClientServer/ocserver/ocserver.cpp [new file with mode: 0644]
csdk/stack/src/occollection.c
csdk/stack/src/ocobserve.c
csdk/stack/src/ocresource.c

index 518b2f3..9fd2a4f 100644 (file)
@@ -1,7 +1,39 @@
-To make the OCTBStack library, run "make" from this directory.
+-------------------------------------------------------------------------------
+**Linux**
+-------------------------------------------------------------------------------
+To make octbstack.a in release mode:
 
-To clean, you have two options:
+       make
 
-make clean     //Cleans all the *.o and *.a files generated directly from this makefile.
+To make octbstack.a in debug mode:
+
+       make BUILD=debug
+
+-------------------------------------------------------------------------------
+**Arduino**
+-------------------------------------------------------------------------------
+Touch (i.e. create) file named "local.properties" at this directory level with
+the following definition(s):
+
+       ARDUINO_DIR = <PATH_TO_ARDUINO_INSTALL_DIR>/arduino-1.0.5
+
+To make octbstack.a in release mode:
+
+       make PLATFORM=arduino
+
+To make octbstack.a in debug mode:
+
+       make PLATFORM=arduino BUILD=debug
+
+-------------------------------------------------------------------------------
+**Clean-Up**
+-------------------------------------------------------------------------------
+To clean only stack modules:
+
+       make clean
+
+To clean stack modules and libcoap (i.e. networking) modules & its
+dependencies:
+
+       make deepclean
 
-make deepclean  //Also cleans the *.o and *.a files generated indirecty from this makefile.
index 307432b..b15c19a 100644 (file)
@@ -232,12 +232,13 @@ static void HandleCoAPResponses(struct coap_context_t *ctx,
     uint32_t sequenceNumber = 0;
     OCStackResult result = OC_STACK_ERROR;
     coap_pdu_t *sendPdu = NULL;
+    coap_pdu_t * recvPdu = NULL;
     //coap_list_t *optList = NULL;
     //uint8_t deregisterObserveOption = OC_RESOURCE_OBSERVE_DEREGISTER;
 
     VERIFY_NON_NULL(ctx);
     VERIFY_NON_NULL(rcvdResponse);
-    coap_pdu_t * recvPdu = rcvdResponse->pdu;
+    recvPdu = rcvdResponse->pdu;
 
     result = ParseCoAPPdu(recvPdu, NULL, NULL, &rcvObserveOption, &bufRes);
     VERIFY_SUCCESS(result, OC_STACK_OK);
@@ -329,7 +330,7 @@ static void HandleCoAPResponses(struct coap_context_t *ctx,
  */
 OCStackResult OCInitCoAP(const char *address, uint16_t port, OCMode mode) {
 
-    int ret = OC_STACK_ERROR;
+    OCStackResult ret = OC_STACK_ERROR;
 
     TODO ("Below should go away and be replaced by OC_LOG");
     coap_log_t log_level = (coap_log_t)(LOG_DEBUG + 1);
@@ -398,7 +399,7 @@ OCStackResult OCDoCoAPResource(OCMethod method, OCQualityOfService qos, OCCoAPTo
                      const char *Uri, const char *payload)
 {
 
-    int ret = OC_STACK_ERROR;
+    OCStackResult ret = OC_STACK_ERROR;
     coap_pdu_t *pdu = NULL;
     coap_uri_t uri;
     OCDevAddr dst;
diff --git a/csdk/stack/samples/arduino/SimpleClientServer/README b/csdk/stack/samples/arduino/SimpleClientServer/README
new file mode 100644 (file)
index 0000000..eaa43a9
--- /dev/null
@@ -0,0 +1,35 @@
+-------------------------------------------------------------------------------
+**Arduino** -- Must be built with the same BUILD mode declared as octbstack.a.
+-------------------------------------------------------------------------------
+When an Arduino SimpleClientServer application is running, it outputs logs to
+serial port. This requires the current user to be a part of the "dialout" user
+group permissions on Ubuntu. If your Arduino device is NOT installed at
+location "/dev/ttyACM0", you must define ARDUINO_PORT to the location it is
+installed at. This location will be referred to as <DEV_PORT>.
+
+You can only install one application at a time. Your choices are "oclient" or
+"ocserver." Your selection will be referred to as <DEV_APP>.
+
+This makefile relies on "local.properties" at the directory level of the
+makefile that generates octbstack.a. Please refer to the README at that level
+to determine what definitions are needed for your environment.
+
+To make occlient or ocserver in release mode:
+
+       make
+
+To make & install occlient or ocserver in release mode, with <DEV_PORT> specified:
+
+       make install APP_INSTALL=<DEV_APP> ARDUINO_PORT=<DEV_PORT>
+
+To make & install occlient or ocserver in debug mode:
+
+       make install APP_INSTALL=<DEV_APP> ARDUINO_PORT=<DEV_PORT> BUILD=debug
+
+-------------------------------------------------------------------------------
+**Clean-Up**
+-------------------------------------------------------------------------------
+To clean occlient & ocserver sample apps and objects:
+
+       sudo make clean
+
diff --git a/csdk/stack/samples/arduino/SimpleClientServer/makefile b/csdk/stack/samples/arduino/SimpleClientServer/makefile
new file mode 100644 (file)
index 0000000..418ff70
--- /dev/null
@@ -0,0 +1,16 @@
+BUILD := release
+ARDUINO_PORT := /dev/ttyACM0
+APP_INSTALL := ocserver
+
+ocserver:
+       $(MAKE) -c ./$@ "BUILD=$(BUILD)"
+
+occlient:
+       $(MAKE) -c ./$@ "BUILD=$(BUILD)"
+
+install:
+       $(MAKE) -C ./$(APP_INSTALL) "install" "ARDUINO_PORT=$(ARDUINO_PORT)" "BUILD=$(BUILD)"
+
+clean:
+       $(MAKE) -C ./occlient "clean"
+       $(MAKE) -C ./ocserver "clean"
diff --git a/csdk/stack/samples/arduino/SimpleClientServer/ocserver/README b/csdk/stack/samples/arduino/SimpleClientServer/ocserver/README
new file mode 100644 (file)
index 0000000..163fe0d
--- /dev/null
@@ -0,0 +1,35 @@
+-------------------------------------------------------------------------------
+**Arduino** -- Must be built with the same BUILD mode declared as octbstack.a.
+-------------------------------------------------------------------------------
+When an Arduino SimpleClientServer application is running, it outputs logs to
+serial port. This requires the current user to be a part of the "dialout" user
+group permissions on Ubuntu. If your Arduino device is NOT installed at
+location "/dev/ttyACM0", you must define ARDUINO_PORT to the location it is
+installed at. This location will be referred to as <DEV_PORT>.
+
+This makefile relies on "local.properties" at the directory level of the
+makefile that generates octbstack.a. Please refer to the README at that level
+to determine what definitions are needed for your environment.
+
+To make ocserver in release mode:
+
+       make
+
+To make & install ocserver in release mode, with <DEV_PORT> NOT specified:
+
+       make install
+
+To make & install ocserver in release mode, with <DEV_PORT> specified:
+
+       make install ARDUINO_PORT=<DEV_PORT>
+
+To make & install ocserver in debug mode, with <DEV_PORT> specified:
+
+       make install ARDUINO_PORT=<DEV_PORT> BUILD=debug
+
+-------------------------------------------------------------------------------
+**Clean-Up**
+-------------------------------------------------------------------------------
+To clean ocserver sample app and objects:
+
+       make clean
diff --git a/csdk/stack/samples/arduino/SimpleClientServer/ocserver/makefile b/csdk/stack/samples/arduino/SimpleClientServer/ocserver/makefile
new file mode 100644 (file)
index 0000000..06c2eb3
--- /dev/null
@@ -0,0 +1,82 @@
+CC=avr-gcc
+CCPLUS=avr-g++
+AR=avr-ar
+RANLIB=avr-ranlib
+
+APP_NAME := ocserver
+BUILD := release
+ARDUINO_PORT := /dev/ttyACM0
+
+OBJ_DIR := ./bin
+
+include ../local.properties
+
+TB_DIR = ../../../../..
+LOGGER_DIR = $(TB_DIR)/logger
+TBSTACK_DIR = $(TB_DIR)/stack
+TBSOCKET_DIR = $(TB_DIR)/ocsocket
+
+#Source directories
+SDIR_ARD_CORE = $(ARDUINO_DIR)/hardware/arduino/cores/arduino
+SDIR_ARD_SPI = $(ARDUINO_DIR)/libraries/SPI
+SDIR_ARD_ETH = $(ARDUINO_DIR)/libraries/Ethernet
+SDIR_ARD_ETH_UTIL = $(ARDUINO_DIR)/libraries/Ethernet/utility
+SDIR_ARD_TIME = $(ARDUINO_DIR)/libraries/Time
+
+VPATH := $(SDIR_ARD_CORE):$(SDIR_ARD_SPI):$(SDIR_ARD_ETH):$(SDIR_ARD_ETH_UTIL):$(OCSOCK_DIR)/src
+
+#include directories
+INCD_ARD_CORE = -I$(ARDUINO_DIR)/hardware/arduino/cores/arduino
+INCD_ARD_VARIANT = -I$(ARDUINO_DIR)/hardware/arduino/variants/mega
+INCD_ARD_SPI = -I$(ARDUINO_DIR)/libraries/SPI
+INCD_ARD_ETH = -I$(ARDUINO_DIR)/libraries/Ethernet
+INCD_ARD_ETH_UTIL = -I$(ARDUINO_DIR)/libraries/Ethernet/utility
+INCD_ARD_TIME = -I$(ARDUINO_DIR)/libraries/Time
+INCD_TBLOGGER = -I$(LOGGER_DIR)/include
+INCD_TBSTACK = -I$(TBSTACK_DIR)/include
+INCD_TBSOCKET = -I$(TBSOCKET_DIR)/include
+
+CPPFLAGSZ := -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=156 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR -MMD
+
+CPPFLAGS := -Wall -Os -c
+CPPFLAGS +=  $(CPPFLAGSZ) $(INCD_ARD_CORE) $(INCD_ARD_VARIANT) $(INCD_ARD_SPI) $(INCD_ARD_ETH) $(INCD_ARD_ETH_UTIL) $(INCD_ARD_TIME) $(INCD_TBLOGGER) $(INCD_TBSTACK) $(INCD_TBSOCKET)
+CPPFLAGS += -Wno-write-strings -ffunction-sections -fdata-sections -fno-exceptions -felide-constructors -std=c++0x -DATMEGA2560 -DTB_LOG
+
+SERVER_CPP_SRC := $(APP_NAME).cpp
+
+CORE_COBJ = WInterrupts.o wiring.o wiring_digital.o
+CORE_CPPOBJ = main.o Stream.o WMath.o WString.o HardwareSerial.o Print.o SPI.o IPAddress.o
+ETH_CPPOBJ = Dhcp.o Dns.o Ethernet.o EthernetUdp.o
+ETH_UTIL_CPPOBJ = socket.o w5100.o
+OCDEPENDENT_CPPOBJ = wiring_analog.o
+
+SERVER_OBJ := $(SERVER_CPP_SRC:.cpp=.o)
+
+all: prep_dirs core.a $(APP_NAME).o $(APP_NAME).elf $(APP_NAME).hex
+
+core.a: $(CORE_COBJ) $(CORE_CPPOBJ) $(ETH_CPPOBJ) $(ETH_UTIL_CPPOBJ)
+       @cd $(OBJ_DIR) && $(AR) -x $(TB_DIR)/../$(BUILD)/liboctbstack.a
+       $(AR) rcs $@ $^ $(OBJ_DIR)/*.o
+       $(RANLIB) $@
+
+prep_dirs:
+       -mkdir $(OBJ_DIR)
+
+%.o: %.cpp
+       $(CCPLUS) $(CPPFLAGS) $< -o $@
+
+$(APP_NAME).elf: $(APP_NAME).o core.a $(OCDEPENDENT_CPPOBJ)
+       $(CC) -Os -Wl,--gc-sections,--relax $(CPPFLAGSZ) $^ -lm -o $@
+
+$(APP_NAME).hex: $(APP_NAME).elf
+       avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $< $(APP_NAME).eep
+       avr-objcopy -O ihex -R .eeprom $< $@
+
+install: all
+       avrdude -C$(ARDUINO_DIR)/hardware/tools/avrdude.conf -v -v -v -v -patmega2560 -cstk500v2 -P$(ARDUINO_PORT) -b115200 -D -Uflash:w:$(APP_NAME).hex:i
+
+.PHONY: clean
+
+clean:
+       @rm -f *.o *.d *.elf *.eep *.a *.hex *-
+       @rm -rf $(OBJ_DIR)
diff --git a/csdk/stack/samples/arduino/SimpleClientServer/ocserver/ocserver.cpp b/csdk/stack/samples/arduino/SimpleClientServer/ocserver/ocserver.cpp
new file mode 100644 (file)
index 0000000..6138a58
--- /dev/null
@@ -0,0 +1,224 @@
+// Do not remove the include below
+#include "Arduino.h"
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+#include <EthernetServer.h>
+#include <Ethernet.h>
+#include <Dns.h>
+#include <EthernetClient.h>
+#include <util.h>
+#include <EthernetUdp.h>
+#include <Dhcp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char *getResult(OCStackResult result);
+
+#define PCF(str) ((const prog_char*)(F(str)))
+
+const prog_char TAG[] PROGMEM = "ArduinoServer";
+
+int gQuitFlag = 0;
+int gLEDUnderObservation = 0;
+void createLEDResource();
+typedef struct LEDRESOURCE{
+    OCResourceHandle handle;
+    bool state;
+    int power;
+} LEDResource;
+
+static LEDResource LED;
+
+// TODO: hard coded for now, change after Sprint4
+static unsigned char responsePayloadGet[] = "{\"oc\": {\"payload\": {\"state\" : \"on\",\"power\" : \"10\"}}}";
+static unsigned char responsePayloadPut[] = "{\"oc\": {\"payload\": {\"state\" : \"off\",\"power\" : \"0\"}}}";
+static uint16_t OC_WELL_KNOWN_PORT = 5683;
+
+OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest )
+{
+    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", typeOfMessage);
+    if(entityHandlerRequest && flag == OC_REQUEST_FLAG)
+    { //[CL]
+        if(OC_REST_GET == entityHandlerRequest->method)
+        {
+            //entityHandlerRequest->resJSONPayload = reinterpret_cast<unsigned char*>(const_cast<unsigned char*> (responsePayloadGet.c_str()));
+            entityHandlerRequest->resJSONPayload = responsePayloadGet;
+        }
+        if(OC_REST_PUT == entityHandlerRequest->method)
+        {
+            //std::cout << std::string(reinterpret_cast<const char*>(entityHandlerRequest->reqJSONPayload)) << std::endl;
+            OC_LOG_V(INFO, TAG, "PUT JSON payload from client: %s", entityHandlerRequest->reqJSONPayload);
+            //entityHandlerRequest->resJSONPayload = reinterpret_cast<unsigned char*>(const_cast<char*> (responsePayloadPut.c_str()));
+            entityHandlerRequest->resJSONPayload = responsePayloadPut;
+            //responsePayloadGet = responsePayloadPut; // just a bad hack!
+         }
+    }
+    else if (entityHandlerRequest && flag == OC_OBSERVE_FLAG)
+    {
+        gLEDUnderObservation = 1;
+    }
+
+    //OC_LOG_V(INFO, TAG, "/nReceiving message type:/n/t %s. /n/nWith request:/n/t %s", typeOfMessage, request);
+
+    return OC_EH_OK;
+}
+static uint8_t modCounter = 0;
+void *ChangeLEDRepresentation (void *param)
+{
+    (void)param;
+    OCStackResult result = OC_STACK_ERROR;
+    modCounter += 1;
+    if(modCounter % 10 == 0)  // Matching the timing that the Linux Sample Server App uses for the same functionality.
+    {
+        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;
+}
+
+//The setup function is called once at startup of the sketch
+void setup()
+{
+    // Add your initialization code here
+    OC_LOG_INIT();
+
+    OC_LOG(DEBUG, TAG, PCF("OCServer is starting..."));
+    uint16_t port = OC_WELL_KNOWN_PORT;
+
+    //Mac address of my ethernet shield
+    uint8_t ETHERNET_MAC[] = {0x90, 0xA2, 0xDA, 0x0E, 0xC4, 0x05};
+    uint8_t error = Ethernet.begin(ETHERNET_MAC);
+    Serial.print(Ethernet.localIP());
+    if (error  == 0)
+    {
+        OC_LOG_V(ERROR, TAG, "error is: %d", error);
+        return;
+    }
+
+    if (OCInit(NULL, port, OC_SERVER) != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, PCF("OCStack init error"));
+        return;
+    }
+
+    /*
+     * Declare and create the example resource: LED
+     */
+    createLEDResource();
+
+}
+
+// The loop function is called in an endless loop
+void loop()
+{
+    delay(2000);
+    if (OCProcess() != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, PCF("OCStack process error"));
+        return;
+    }
+    ChangeLEDRepresentation(NULL);
+}
+
+void createLEDResource()
+{
+    LED.state = false;
+    OCStackResult res = OCCreateResource(&LED.handle,
+            "core.led",
+            "core.rw",
+            "/a/led",
+            OCEntityHandlerCb,
+            OC_DISCOVERABLE|OC_OBSERVABLE);
+    OC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
+}
+const char *getResult(OCStackResult result)
+{
+    char resString[40] = {0};
+    strcpy(resString, "Result: ");
+    switch (result) {
+    case OC_STACK_OK:
+        strcat(resString, "OC_STACK_OK");
+        break;
+    case OC_STACK_INVALID_URI:
+        strcat(resString, "OC_STACK_INVALID_URI");
+        break;
+    case OC_STACK_INVALID_QUERY:
+        strcat(resString, "OC_STACK_INVALID_QUERY");
+        break;
+    case OC_STACK_INVALID_IP:
+        strcat(resString, "OC_STACK_INVALID_IP");
+        break;
+    case OC_STACK_INVALID_PORT:
+        strcat(resString, "OC_STACK_INVALID_PORT");
+        break;
+    case OC_STACK_INVALID_CALLBACK:
+        strcat(resString, "OC_STACK_INVALID_CALLBACK");
+        break;
+    case OC_STACK_INVALID_METHOD:
+        strcat(resString, "OC_STACK_INVALID_METHOD");
+        break;
+    case OC_STACK_NO_MEMORY:
+        strcat(resString, "OC_STACK_NO_MEMORY");
+        break;
+    case OC_STACK_COMM_ERROR:
+        strcat(resString, "OC_STACK_COMM_ERROR");
+        break;
+    case OC_STACK_INVALID_PARAM:
+        strcat(resString, "OC_STACK_INVALID_PARAM");
+        break;
+    case OC_STACK_NOTIMPL:
+        strcat(resString, "OC_STACK_NOTIMPL");
+        break;
+    case OC_STACK_NO_RESOURCE:
+        strcat(resString, "OC_STACK_NO_RESOURCE");
+        break;
+    case OC_STACK_RESOURCE_ERROR:
+        strcat(resString, "OC_STACK_RESOURCE_ERROR");
+        break;
+    case OC_STACK_SLOW_RESOURCE:
+        strcat(resString, "OC_STACK_SLOW_RESOURCE");
+        break;
+    case OC_STACK_NO_OBSERVERS:
+        strcat(resString, "OC_STACK_NO_OBSERVERS");
+        break;
+    case OC_STACK_ERROR:
+        strcat(resString, "OC_STACK_ERROR");
+        break;
+    default:
+        strcat(resString, "UNKNOWN");
+    }
+    char* retString = resString;
+    return retString;
+}
+#ifdef __cplusplus
+} // extern "C"
+#endif
index 95942b2..df7db4e 100644 (file)
@@ -217,10 +217,11 @@ static OCStackResult
 BuildCollectionBatchJSONResponse(OCEntityHandlerFlag flag,
                 OCResource *resource, OCEntityHandlerRequest *ehRequest)
 {
-    OCStackResult ret = OC_STACK_ERROR;
+    OCStackResult stackRet = OC_STACK_ERROR;
+    OCEntityHandlerResult ehRet = OC_EH_ERROR;
 
-    ret = BuildRootResourceJSON(resource, ehRequest);
-    if (ret == OC_STACK_OK)
+    stackRet = BuildRootResourceJSON(resource, ehRequest);
+    if (stackRet == OC_STACK_OK)
     {
         for  (int i = 0; i < MAX_CONTAINED_RESOURCES; i++)
         {
@@ -228,18 +229,26 @@ BuildCollectionBatchJSONResponse(OCEntityHandlerFlag flag,
             if (temp)
             {
                 //TODO ("Proper Error handling");
-                ret = temp->entityHandler(OC_REQUEST_FLAG, ehRequest);
-                unsigned char* buffer = ehRequest->resJSONPayload;
-                ehRequest->resJSONPayloadLen = ehRequest->resJSONPayloadLen - strlen((char*)buffer);
-
-                buffer += strlen((char*)buffer);
-                ehRequest->resJSONPayload = buffer;
-                if ( resource->rsrcResources[i+1] && ehRequest->resJSONPayloadLen > sizeof(OC_JSON_SEPARATOR) )
+                ehRet = temp->entityHandler(OC_REQUEST_FLAG, ehRequest);
+                if(ehRet == OC_EH_OK)
                 {
-                    *buffer = OC_JSON_SEPARATOR;
-                    buffer++;
+                    unsigned char* buffer = ehRequest->resJSONPayload;
+                    ehRequest->resJSONPayloadLen = ehRequest->resJSONPayloadLen - strlen((char*)buffer);
+
+                    buffer += strlen((char*)buffer);
                     ehRequest->resJSONPayload = buffer;
-                    ehRequest->resJSONPayloadLen = ehRequest->resJSONPayloadLen - 1;
+                    if ( resource->rsrcResources[i+1] && ehRequest->resJSONPayloadLen > sizeof(OC_JSON_SEPARATOR) )
+                    {
+                        *buffer = OC_JSON_SEPARATOR;
+                        buffer++;
+                        ehRequest->resJSONPayload = buffer;
+                        ehRequest->resJSONPayloadLen = ehRequest->resJSONPayloadLen - 1;
+                    }
+                }
+                else
+                {
+                    stackRet = OC_STACK_ERROR;
+                    break;
                 }
             }
             else
@@ -248,7 +257,7 @@ BuildCollectionBatchJSONResponse(OCEntityHandlerFlag flag,
             }
         }
     }
-    return ret;
+    return stackRet;
 }
 
 
@@ -265,7 +274,7 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
         return OC_STACK_ERROR;
 
     result = ValidateQuery ((const unsigned char *)ehRequest->query,
-                            ehRequest->resource, &ifQueryParam, &rtQueryParam);
+                            &ehRequest->resource, &ifQueryParam, &rtQueryParam);
 
     if (result != OC_STACK_OK)
         return result;
@@ -284,17 +293,17 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
                 // operation is same as the GET on LL interface.
 
                 OC_LOG(INFO, TAG, "STACK_IF_DEFAULT\n");
-                return BuildCollectionJSONResponse( ehRequest->resource,
+                return BuildCollectionJSONResponse( (OCResource *)ehRequest->resource,
                              ehRequest, STACK_RES_DISCOVERY_NOFILTER, NULL);
 
             case STACK_IF_LL:
                 OC_LOG(INFO, TAG, "STACK_IF_LL\n");
-                return BuildCollectionJSONResponse( ehRequest->resource,
+                return BuildCollectionJSONResponse( (OCResource *)ehRequest->resource,
                              ehRequest, STACK_RES_DISCOVERY_NOFILTER, NULL);
 
             case STACK_IF_BATCH:
                 OC_LOG(INFO, TAG, "STACK_IF_BATCH\n");
-                return BuildCollectionBatchJSONResponse(flag, ehRequest->resource, ehRequest);
+                return BuildCollectionBatchJSONResponse(flag, (OCResource *)ehRequest->resource, ehRequest);
 
             default:
                 return OC_STACK_ERROR;
@@ -311,7 +320,7 @@ OCStackResult DefaultCollectionEntityHandler (OCEntityHandlerFlag flag,
                 return OC_STACK_ERROR;
 
             case STACK_IF_BATCH:
-                return BuildCollectionBatchJSONResponse(flag, ehRequest->resource, ehRequest);
+                return BuildCollectionBatchJSONResponse(flag, (OCResource *)ehRequest->resource, ehRequest);
 
             default:
                 return OC_STACK_ERROR;
index 1ab9915..14d34da 100644 (file)
@@ -99,7 +99,8 @@ OCStackResult OCObserverStatus(OCCoAPToken * token, uint8_t status)
 
 OCStackResult ProcessObserveRequest (OCResource *resource, OCRequest *request)
 {
-    OCStackResult result = OC_STACK_ERROR;
+    OCStackResult stackRet = OC_STACK_ERROR;
+    OCEntityHandlerResult ehRet = OC_EH_ERROR;
     OCEntityHandlerRequest *ehReq = request->entityHandlerRequest;
     OCObserveReq *obs = request->observe;
 
@@ -107,43 +108,50 @@ OCStackResult ProcessObserveRequest (OCResource *resource, OCRequest *request)
 
     // Register new observation
     request->entityHandlerRequest->resource = (OCResourceHandle)resource;
-    result = resource->entityHandler(OC_OBSERVE_FLAG, request->entityHandlerRequest);
-
-    if (obs->option == OC_RESOURCE_OBSERVE_REGISTER)
+    ehRet = resource->entityHandler(OC_OBSERVE_FLAG, request->entityHandlerRequest);
+    if(ehRet == OC_EH_OK)
     {
-        // Add subscriber to the server observation list
-        // TODO: we need to check if the obsrever is already there using its OCDevAdd....
-        result = AddObserver ((const char*)(request->resourceUrl), (const char *)(ehReq->query),
-                obs->token, obs->subAddr, resource, request->qos);
-        if(result == OC_STACK_OK)
+        if (obs->option == OC_RESOURCE_OBSERVE_REGISTER)
         {
-            result = OC_STACK_OBSERVER_ADDED;
+            // Add subscriber to the server observation list
+            // TODO: we need to check if the obsrever is already there using its OCDevAdd....
+            stackRet = AddObserver ((const char*)(request->resourceUrl), (const char *)(ehReq->query),
+                    obs->token, obs->subAddr, resource, request->qos);
+            if(stackRet == OC_STACK_OK)
+            {
+                stackRet = OC_STACK_OBSERVER_ADDED;
+            }
+            OC_LOG(DEBUG, TAG, PCF("adding an observer"));
         }
-        OC_LOG(DEBUG, TAG, PCF("adding an observer"));
-    }
-    else if (obs->option == OC_RESOURCE_OBSERVE_DEREGISTER)
-    {
-        // Deregister observation
-        result = DeleteObserver (obs->token);
-        if(result == OC_STACK_OK)
+        else if (obs->option == OC_RESOURCE_OBSERVE_DEREGISTER)
         {
-            OC_LOG(DEBUG, TAG, PCF("removing an observer"));
-            result = OC_STACK_OBSERVER_REMOVED;
+            // Deregister observation
+            stackRet = DeleteObserver (obs->token);
+            if(stackRet == OC_STACK_OK)
+            {
+                OC_LOG(DEBUG, TAG, PCF("removing an observer"));
+                stackRet = OC_STACK_OBSERVER_REMOVED;
+            }
+        }
+        else
+        {
+            // Invalid option
+            OC_LOG(ERROR, TAG, PCF("Invalid CoAP observe option"));
+            stackRet = OC_STACK_INVALID_OBSERVE_PARAM;
         }
     }
     else
     {
-        // Invalid option
-        OC_LOG(ERROR, TAG, PCF("Invalid CoAP observe option"));
-        result = OC_STACK_INVALID_OBSERVE_PARAM;
+        stackRet = OC_STACK_ERROR;
     }
-    return result;
+    return stackRet;
 }
 
 OCStackResult SendObserverNotification (OCResource *resPtr)
 {
     uint8_t numObs = 0;
-    OCStackResult result = OC_STACK_ERROR;
+    OCStackResult stackRet = OC_STACK_ERROR;
+    OCEntityHandlerResult ehRet = OC_EH_ERROR;
     ResourceObserver *resourceObserver = serverObsList;
     OCEntityHandlerRequest * entityHandlerReq = NULL;
     unsigned char bufRes[MAX_RESPONSE_LENGTH] = {0};
@@ -171,9 +179,10 @@ OCStackResult SendObserverNotification (OCResource *resPtr)
 
             // Even if entity handler for a resource is not successful
             // we continue calling entity handler for other resources
-            result = resPtr->entityHandler (OC_REQUEST_FLAG, entityHandlerReq);
-            if (OC_STACK_OK == result)
+            ehRet = resPtr->entityHandler (OC_REQUEST_FLAG, entityHandlerReq);
+            if (OC_EH_OK == ehRet)
             {
+                stackRet = OC_STACK_OK;
                 OC_LOG_V(INFO, TAG, "OCStack payload: %s",
                         entityHandlerReq->resJSONPayload);
 
@@ -199,20 +208,24 @@ OCStackResult SendObserverNotification (OCResource *resPtr)
                     }
                 }
 
-                OCSendCoAPNotification(resourceObserver->addr, result, qos,
+                OCSendCoAPNotification(resourceObserver->addr, stackRet, qos,
                         resourceObserver->token,
                         (unsigned char *)entityHandlerReq->resJSONPayload,
                         resPtr->sequenceNum);
             }
+            else
+            {
+                stackRet = OC_STACK_ERROR;
+            }
         }
         resourceObserver = resourceObserver->next;
     }
     if (numObs == 0)
     {
         OC_LOG(INFO, TAG, PCF("Resource has no observers"));
-        return OC_STACK_NO_OBSERVERS;
+        stackRet = OC_STACK_NO_OBSERVERS;
     }
-    return OC_STACK_OK;
+    return stackRet;
 }
 
 OCStackResult AddObserver (const char   *resUri,
index d17040b..5e1b712 100644 (file)
@@ -50,7 +50,7 @@ OCEntityHandlerResult defaultResourceEHandler(OCEntityHandlerFlag flag,
     // TODO:  remove silence unused param warnings
     (void) flag;
     (void) request;
-    return  OC_STACK_OK; // Making sure that the Default EH and the Vendor EH have matching signatures
+    return  OC_EH_OK; // Making sure that the Default EH and the Vendor EH have matching signatures
 }
 
 static OCStackResult ValidateUrlQuery (unsigned char *url, unsigned char *query,