Revision:
0:2f8d4a574b4e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Jan 12 15:41:00 2018 +0900
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2015, 2016 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * 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 "mbed-trace/mbed_trace.h"
+#include "mbed.h"
+#include "zxing_main.h"
+
+// Network interaction must be performed outside of interrupt context
+osThreadId mainThread;
+
+#define NO_CONNECT         (-1)
+
+#if MBED_CONF_APP_NETWORK_INTERFACE == NO_CONNECT
+
+static void callback_zxing(char * addr, int size) {
+    printf("%s\r\n", addr);
+}
+
+// Entry point to the program
+int main() {
+    // Keep track of the main thread
+    mainThread = osThreadGetId();
+    printf("no connect\n");
+    mbed_trace_init();
+    zxing_init(&callback_zxing);
+
+    while (1) {
+        zxing_loop();
+        Thread::wait(5);
+    }
+}
+
+#else // MBED_CONF_APP_NETWORK_INTERFACE != NO_CONNECT
+
+#define __STDC_FORMAT_MACROS
+#include <string>
+#include <sstream>
+#include <vector>
+#include "security.h"
+#include "simpleclient.h"
+#include "mbedtls/entropy_poll.h"
+
+// easy-connect compliancy, it has 2 sets of wifi pins we have only one
+#define MBED_CONF_APP_ESP8266_TX MBED_CONF_APP_WIFI_TX
+#define MBED_CONF_APP_ESP8266_RX MBED_CONF_APP_WIFI_RX
+#include "easy-connect.h"
+
+// These are example resource values for the Device Object
+struct MbedClientDevice device = {
+    "Manufacturer_String",      // Manufacturer
+    "Type_String",              // Type
+    "ModelNumber_String",       // ModelNumber
+    "SerialNumber_String"       // SerialNumber
+};
+
+// Instantiate the class which implements LWM2M Client API (from simpleclient.h)
+MbedClient mbed_client(device);
+
+// LED Output
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+/*
+ * The Led contains one property (pattern) and a function (blink).
+ * When the function blink is executed, the pattern is read, and the LED
+ * will blink based on the pattern.
+ */
+class LedResource {
+public:
+    LedResource() {
+        // create ObjectID with metadata tag of '3201', which is 'digital output'
+        led_object = M2MInterfaceFactory::create_object("3201");
+        M2MObjectInstance* led_inst = led_object->create_object_instance();
+
+        // 5855 = Multi-state output
+        M2MResource* color_res = led_inst->create_dynamic_resource("5855", "Color",
+            M2MResourceInstance::STRING, false);
+        // read and write
+        color_res->set_operation(M2MBase::GET_PUT_ALLOWED);
+        // set red as initial color
+        color_res->set_value((const uint8_t*)"red", 3);
+        
+        // 5853 = Multi-state output
+        M2MResource* pattern_res = led_inst->create_dynamic_resource("5853", "Pattern",
+            M2MResourceInstance::STRING, false);
+        // read and write
+        pattern_res->set_operation(M2MBase::GET_PUT_ALLOWED);
+        // set initial pattern (toggle every 200ms. 7 toggles in total)
+        pattern_res->set_value((const uint8_t*)"500:500:500:500:500:500:500", 27);
+
+        // there's not really an execute LWM2M ID that matches... hmm...
+        M2MResource* led_res = led_inst->create_dynamic_resource("5850", "Blink",
+            M2MResourceInstance::OPAQUE, false);
+        // we allow executing a function here...
+        led_res->set_operation(M2MBase::POST_ALLOWED);
+        // when a POST comes in, we want to execute the led_execute_callback
+        led_res->set_execute_function(execute_callback(this, &LedResource::blink));
+
+    }
+
+    M2MObject* get_object() {
+        return led_object;
+    }
+
+    void blink(void *argument) {
+
+
+        // read the value of 'Pattern'
+        M2MObjectInstance* inst = led_object->object_instance();
+        M2MResource* res = inst->resource("5853");
+        // read the value of 'Color'
+        M2MObjectInstance* instC = led_object->object_instance();
+        M2MResource* resC = instC->resource("5855");
+
+        // values in mbed Client are all buffers, and we need a vector of int's
+        uint8_t* buffIn = NULL;
+        uint32_t sizeIn;
+        res->get_value(buffIn, sizeIn);
+        
+        uint8_t* cbuffIn = NULL;
+        uint32_t csizeIn;
+        resC->get_value(cbuffIn, csizeIn);
+
+        // turn the buffer into a string, and initialize a vector<int> on the heap
+        std::string s((char*)buffIn, sizeIn);
+        std::vector<uint32_t>* v = new std::vector<uint32_t>;
+
+        printf("led_execute_callback pattern=%s\r\n", s.c_str());
+
+        // our pattern is something like 500:200:500, so parse that
+        std::size_t found = s.find_first_of(":");
+        while (found!=std::string::npos) {
+
+            v->push_back(atoi((const char*)s.substr(0,found).c_str()));
+            s = s.substr(found+1);
+            found=s.find_first_of(":");
+            if(found == std::string::npos) {
+                v->push_back(atoi((const char*)s.c_str()));
+            }
+        }
+        int position = 0;
+        while (1) {
+            do_blink(cbuffIn);
+            if (position >= v->size()) {
+                break;
+            }
+            // how long do we need to wait before the next blink?
+            Thread::wait(v->at(position));
+            position++;
+        }
+        free(buffIn);
+        free(cbuffIn);
+        delete v;
+    }
+
+private:
+    M2MObject* led_object;
+    void do_blink(uint8_t* color) {
+        
+        if (!strcmp((char *)color, "red")) {
+            // blink the LED in red color
+            led1 = !led1;
+        }
+        else if (!strcmp((char *)color, "green")) {
+            // blink in green color
+            led2 = !led2;
+        }
+        else if (!strcmp((char *)color, "blue")) {
+            // blink in blue color
+            led3 = !led3;
+        }
+        else if (!strcmp((char *)color, "cyan")) {
+            // blink in cyan color
+            led2 = !led2;
+            led3 = !led3;
+        }
+        else if (!strcmp((char *)color, "yellow")) {
+            // blink in yellow color
+            led1 = !led1;
+            led2 = !led2;
+        }
+        else if (!strcmp((char *)color, "magenta")) {
+            // blink in magenta color
+            led1 = !led1;
+            led3 = !led3;
+        }            
+        else if (!strcmp((char *)color, "white")) {
+            // blink in white color
+            led1 = !led1;
+            led2 = !led2;
+            led3 = !led3;
+        }
+        else {
+            // no operation
+        }
+    }
+};
+
+/*
+ * The Zxing contains a function (send string).
+ * When `handle_string_send` is executed, the string after decoding is sent.
+ */
+class ZxingResource {
+public:
+    ZxingResource() {
+        // create ObjectID with metadata tag of '3202', which is 'send string'
+        zxing_object = M2MInterfaceFactory::create_object("3202");
+        M2MObjectInstance* zxing_inst = zxing_object->create_object_instance();
+        // create resource with ID '5700', which is 'send string'
+        M2MResource* zxing_res = zxing_inst->create_dynamic_resource("5700", "zxing",
+            M2MResourceInstance::STRING, true);
+        // we can read this value
+        zxing_res->set_operation(M2MBase::GET_ALLOWED);
+        // set initial value (all values in mbed Client are buffers)
+        // to be able to read this data easily in the Connector console, we'll use a string
+        zxing_res->set_value((uint8_t*)"0", 1);
+    }
+
+    ~ZxingResource() {
+    }
+
+    M2MObject* get_object() {
+        return zxing_object;
+    }
+
+    /*
+     * When you success the decode process of barcode, we send the string after decoding to mbed Device Connector.
+     */
+    void handle_string_send(char * addr, int size) {
+        M2MObjectInstance* inst = zxing_object->object_instance();
+        M2MResource* res = inst->resource("5700");
+
+        printf("%s\r\n", addr);
+
+        // tell the string to connector
+        res->set_value((uint8_t *)addr, size);
+
+        // Write 0 to 3202/0/5700 so that the same item can be added to the cart consectively
+        res->set_value((uint8_t *)"0", 1);
+    }
+
+private:
+    M2MObject* zxing_object;
+};
+
+ZxingResource zxing_resource;
+
+static void callback_zxing(char * addr, int size) {
+    zxing_resource.handle_string_send(addr, size);
+}
+
+static volatile bool registered;
+
+void unregister() {
+    registered = false;
+}
+
+// Entry point to the program
+int main() {
+
+    unsigned int seed;
+    size_t len;
+
+#ifdef MBEDTLS_ENTROPY_HARDWARE_ALT
+    // Used to randomize source port
+    mbedtls_hardware_poll(NULL, (unsigned char *) &seed, sizeof seed, &len);
+
+#elif defined MBEDTLS_TEST_NULL_ENTROPY
+
+#warning "mbedTLS security feature is disabled. Connection will not be secure !! Implement proper hardware entropy for your selected hardware."
+    // Used to randomize source port
+    mbedtls_null_entropy_poll( NULL,(unsigned char *) &seed, sizeof seed, &len);
+
+#else
+
+#error "This hardware does not have entropy, endpoint will not register to Connector.\
+You need to enable NULL ENTROPY for your application, but if this configuration change is made then no security is offered by mbed TLS.\
+Add MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES and MBEDTLS_TEST_NULL_ENTROPY in mbed_app.json macros to register your endpoint."
+
+#endif
+
+    srand(seed);
+    // Keep track of the main thread
+    mainThread = osThreadGetId();
+    printf("\nStarting mbed Client example in ");
+
+#if defined (MESH) || (MBED_CONF_LWIP_IPV6_ENABLED==true)
+    printf("IPv6 mode\n");
+#else
+    printf("IPv4 mode\n");
+#endif
+
+    mbed_trace_init();
+
+#if MBED_CONF_APP_NETWORK_INTERFACE == WIFI_BP3595
+    DigitalOut usb1en(P3_8);
+    usb1en = 1;
+    Thread::wait(5);
+    usb1en = 0;
+    Thread::wait(5);
+#endif
+
+    NetworkInterface* network = easy_connect(true);
+    if(network == NULL) {
+        printf("\nConnection to Network Failed - exiting application...\n");
+        return -1;
+    }
+    LedResource led_resource;
+
+    // Create endpoint interface to manage register and unregister
+    mbed_client.create_interface(MBED_SERVER_ADDRESS, network);
+
+    // Create Objects of varying types, see simpleclient.h for more details on implementation.
+    M2MSecurity* register_object = mbed_client.create_register_object(); // server object specifying connector info
+    M2MDevice*   device_object   = mbed_client.create_device_object();   // device resources object
+
+    // Create list of Objects to register
+    M2MObjectList object_list;
+
+    // Add objects to list
+    object_list.push_back(device_object);
+    object_list.push_back(led_resource.get_object());
+    object_list.push_back(zxing_resource.get_object());
+
+    // Set endpoint registration object
+    mbed_client.set_register_object(register_object);
+
+    // Register with mbed Device Connector
+    mbed_client.test_register(register_object, object_list);
+
+    zxing_init(&callback_zxing);
+
+    Timer update_timer;
+    update_timer.reset();
+    update_timer.start();
+
+    registered = true;
+    InterruptIn unreg_button(USER_BUTTON0);
+    unreg_button.fall(&unregister);
+
+    while (registered) {
+        if (zxing_loop() == 0) {
+            update_timer.reset();
+        } else if (update_timer.read() >= 25) {
+            mbed_client.test_update_register();
+            update_timer.reset();
+        } else {
+            // do nothing
+        }
+        Thread::wait(5);
+    }
+
+    mbed_client.test_unregister();
+}
+
+#endif // MBED_CONF_APP_NETWORK_INTERFACE != NO_CONNECT
+
+