Own fork of MbedSmartRestMain

Dependencies:   C027_Support C12832 LM75B MMA7660 MbedSmartRest mbed-rtos mbed

Fork of MbedSmartRestMain by Cumulocity Official

Files at this revision

API Documentation at this revision

Comitter:
vwochnik
Date:
Wed Oct 29 21:09:29 2014 +0000
Parent:
61:15719dbe8820
Child:
63:010bbbb4732a
Commit message:
introduced operation store

Changed in this revision

operation/OperationExecutor.cpp Show annotated file Show diff for this revision Revisions of this file
operation/OperationExecutor.h Show annotated file Show diff for this revision Revisions of this file
operation/OperationStore.cpp Show annotated file Show diff for this revision Revisions of this file
operation/OperationStore.h Show annotated file Show diff for this revision Revisions of this file
operation/OperationSupport.cpp Show annotated file Show diff for this revision Revisions of this file
operation/OperationSupport.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/operation/OperationExecutor.cpp	Wed Oct 29 21:09:29 2014 +0000
@@ -0,0 +1,30 @@
+#include "OperationExecutor.h"
+#include "ComposedRecord.h"
+#include "CharValue.h"
+#include "IntegerValue.h"
+
+OperationExecutor::OperationExecutor(AbstractSmartRest& client, SmartRestTemplate& tpl, long& deviceId) :
+    _client(client),
+    _tpl(tpl),
+    _deviceId(deviceId)
+{
+    _init = false;
+}
+
+bool OperationExecutor::init()
+{
+    if (_init)
+        return false;
+    
+    // Get operation
+    // USAGE: 110,<OPERATION/ID>,<STATE>
+    if (!_tpl.add("10,112,GET,/devicecontrol/operations/%%,,application/vnd.com.nsn.cumulocity.operation+json,%%,UNSIGNED,\r\n"))
+        return false;
+
+    _init = true;
+    return true;
+}
+
+bool OperationExecutor::executeOperation(OperationStore::Operation& op)
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/operation/OperationExecutor.h	Wed Oct 29 21:09:29 2014 +0000
@@ -0,0 +1,23 @@
+#ifndef OPERATIONEXECUTOR_H
+#define OPERATIONEXECUTOR_H
+
+#include "AbstractSmartRest.h"
+#include "SmartRestTemplate.h"
+#include "OperationStore.h"
+
+class OperationExecutor
+{
+public:
+    OperationExecutor(AbstractSmartRest&, SmartRestTemplate&, long&);
+    
+    bool init();
+    bool executeOperation(OperationStore::Operation&);
+
+private:
+    bool _init;
+    long& _deviceId;
+    SmartRestTemplate& _tpl;
+    AbstractSmartRest& _client;
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/operation/OperationStore.cpp	Wed Oct 29 21:09:29 2014 +0000
@@ -0,0 +1,137 @@
+#include "OperationStore.h"
+#include <stdlib.h>
+#include <string.h>
+
+/*#define OPERATION_PENDING    0
+#define OPERATION_EXECUTING  1
+#define OPERATION_SUCCESS    2
+#define OPERATION_FAILURE    3
+#define OPERATION_STORE_SIZE 128*/
+
+OperationStore::OperationStore() :
+    _count(0),
+    _offset(0)
+{
+}
+
+bool OperationStore::enqueue(Operation& operation)
+{
+    _mutex.lock();
+    if ((full()) || (getByIdentifier(operation.identifier) != NULL) ||
+            (operation.state != OPERATION_PENDING)) {
+        _mutex.unlock();
+        return false;
+    }
+    
+    memcpy(get(_count++), &operation, sizeof(OperationStore::Operation));
+    _mutex.unlock();
+    return true;
+}
+
+bool OperationStore::takePending(Operation& operation)
+{
+    size_t n;
+    Operation *tmp;
+
+    _mutex.lock();
+    for (n = 0; n < _count; n++) {
+        tmp = get(n);
+        if (tmp->state != OPERATION_PENDING)
+            continue;
+        
+        tmp->state = OPERATION_EXECUTING;
+        memcpy(&operation, tmp, sizeof(OperationStore::Operation));
+
+        _mutex.unlock();
+        return true;
+    }
+
+    _mutex.unlock();    
+    return false;
+}
+    
+bool OperationStore::markAsDone(Operation& operation, bool successful)
+{
+    Operation *tmp;
+
+    _mutex.lock();    
+    tmp = getByIdentifier(operation.identifier);
+    if ((tmp == NULL) || (tmp->state != OPERATION_EXECUTING)) {
+        _mutex.unlock();
+        return false;
+    }
+    
+    tmp->state = (successful) ? OPERATION_SUCCESSFUL : OPERATION_FAILED;
+    _mutex.unlock();
+    return true;
+}
+    
+bool OperationStore::takeDone(Operation& operation)
+{
+    Operation *tmp;
+    
+    _mutex.lock();
+    tmp = get(0);
+    if ((tmp == NULL) || ((tmp->state != OPERATION_SUCCESSFUL) &&
+            (tmp->state != OPERATION_FAILED))) {
+        _mutex.unlock();
+        return false;
+    }
+    
+    if (++_offset == OPERATION_STORE_SIZE)
+        _offset = 0;
+    _count--;
+    
+    memcpy(&operation, tmp, sizeof(OperationStore::Operation));
+
+    _mutex.unlock();
+    return true;
+}
+    
+bool OperationStore::full()
+{
+    bool ret;
+    
+    _mutex.lock();
+    ret = (_count == OPERATION_STORE_SIZE);
+    _mutex.unlock();
+
+    return ret;
+}
+
+bool OperationStore::empty()
+{
+    bool ret;
+    
+    _mutex.lock();
+    ret = (_count == 0);
+    _mutex.unlock();
+    
+    return ret;
+}
+
+OperationStore::Operation * OperationStore::get(size_t index)
+{
+    size_t i;
+    
+    if (_offset + index < OPERATION_STORE_SIZE)
+        i = _offset + index;
+    else
+        i = index - (OPERATION_STORE_SIZE - _offset);
+    
+    return &_store[i];
+}
+
+OperationStore::Operation * OperationStore::getByIdentifier(long identifier)
+{
+    size_t n;
+    Operation *tmp;
+    
+    for (n = 0; n < _count; n++) {
+        tmp = get(n);
+        if (tmp->identifier == identifier)
+            return tmp;
+    }
+
+    return NULL;
+}
--- a/operation/OperationStore.h	Fri Oct 24 15:21:21 2014 +0000
+++ b/operation/OperationStore.h	Wed Oct 29 21:09:29 2014 +0000
@@ -1,19 +1,84 @@
 #ifndef OPERATIONSTORE_H
 #define OPERATIONSTORE_H
 
-#define STATE_PENDING 0
-#define STATE_EXECUTING 1
-#define STATE_SUCCESSFUL 2
-#define STATE_FAILED 3
+#include <stddef.h>
+#include <stdint.h>
+#include "rtos.h"
+
+#define OPERATION_PENDING    0
+#define OPERATION_EXECUTING  1
+#define OPERATION_SUCCESSFUL 2
+#define OPERATION_FAILED     3
 
+/**
+ * Number of operations which can be stored in the OperationStore
+ */
+#define OPERATION_STORE_SIZE 128
+
+/**
+ * OperationStore utilizing a circular buffer for storage.
+ */
 class OperationStore
 {
 public:
+    OperationStore();
+    
     struct Operation {
         long identifier;
-        const char *description;
+        const char *descriptor;
         uint8_t state;
     };
+    
+    /**
+     * Enqueues a pending-state operation.
+     * A defensive copy of the operation is madw.
+     * @param operation the operation to enqueue
+     * @return true on success, false otherwise
+     */
+    bool enqueue(Operation&);
+    
+    /**
+     * Dequeues a pending-state operation and sets its state to executing.
+     * @param operation a reference to write the operation to
+     * @return true on success, false otherwise
+     */
+    bool takePending(Operation&);
+    
+    /**
+     * Marks a previously dequeued operation as done.
+     * @param operation the operation to mark as done
+     * @param successful set whether the operation was successful
+     * @return true on success, false otherwise
+     */
+    bool markAsDone(Operation&, bool);
+    
+    /**
+     * Dequeues a done-state operation and removes it from the store.
+     * @param operation a reference to write the operation to
+     * @return true on success, false otherwise
+     */
+    bool takeDone(Operation&);
+    
+    /**
+     * Retrieves whether the operation store is full.
+     * @return true when full, false otherwise
+     */
+    bool full();
+
+    /**
+     * Retrieves whether the operation store is empty.
+     * @return true when empty, false otherwise
+     */
+    bool empty();
+
+protected:
+    Operation * get(size_t);
+    Operation * getByIdentifier(long);
+
+private:
+    Operation _store[OPERATION_STORE_SIZE];
+    size_t _offset, _count;
+    Mutex _mutex;
 };
 
-#endif
\ No newline at end of file
+#endif
--- a/operation/OperationSupport.cpp	Fri Oct 24 15:21:21 2014 +0000
+++ b/operation/OperationSupport.cpp	Wed Oct 29 21:09:29 2014 +0000
@@ -14,6 +14,7 @@
     _client(client),
     _tpl(tpl),
     _deviceId(deviceId),
+    _executor(client, tpl, deviceId),
     _thread(OperationSupport::thread_func, this)
 {
     _init = false;
@@ -83,7 +84,7 @@
     }
     
     for (size_t i = 0; i < nops; i++) {
-        ops[i].state = STATE_SUCCESSFUL;
+        ops[i].state = OPERATION_SUCCESSFUL;
         if (!updateOperation(ops[i]))
             puts("Operation update failed.");
     }
@@ -105,13 +106,13 @@
     op.identifier = received.value(2).integerValue();
     tmp = received.value(3).characterValue();
     if (strcmp(tmp, "EXECUTING") == 0)
-        op.state = STATE_EXECUTING;
+        op.state = OPERATION_EXECUTING;
     else if (strcmp(tmp, "SUCCESSFUL") == 0)
-        op.state = STATE_SUCCESSFUL;
+        op.state = OPERATION_SUCCESSFUL;
     else if (strcmp(tmp, "FAILED") == 0)
-        op.state = STATE_FAILED;
+        op.state = OPERATION_FAILED;
     else
-        op.state = STATE_PENDING;
+        op.state = OPERATION_PENDING;
     
     return true;
 }
@@ -152,11 +153,11 @@
 CharValue& OperationSupport::operationStateValue(OperationStore::Operation& op)
 {
     switch (op.state) {
-    case STATE_EXECUTING:
+    case OPERATION_EXECUTING:
         return aOperationStateExecuting;
-    case STATE_SUCCESSFUL:
+    case OPERATION_SUCCESSFUL:
         return aOperationStateSuccessful;
-    case STATE_FAILED:
+    case OPERATION_FAILED:
         return aOperationStateFailed;
     default:
         return aOperationStatePending;
--- a/operation/OperationSupport.h	Fri Oct 24 15:21:21 2014 +0000
+++ b/operation/OperationSupport.h	Wed Oct 29 21:09:29 2014 +0000
@@ -2,6 +2,7 @@
 #define OPERATIONSUPPORT_H
 
 #include "rtos.h"
+#include "OperationExecutor.h"
 #include "AbstractSmartRest.h"
 #include "SmartRestTemplate.h"
 #include "ComposedRecord.h"
@@ -30,6 +31,8 @@
     long& _deviceId;
     SmartRestTemplate& _tpl;
     AbstractSmartRest& _client;
+    OperationStore _store;
+    OperationExecutor _executor;
     Thread _thread;
 };