Osamu Nakamura / GR-PEACH_mbed-os-client-ZXingSample
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Copyright (c) 2015, 2016 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include "mbed-trace/mbed_trace.h"
00017 #include "mbed.h"
00018 #include "zxing_main.h"
00019 
00020 // Network interaction must be performed outside of interrupt context
00021 osThreadId mainThread;
00022 
00023 #define NO_CONNECT         (-1)
00024 
00025 #if MBED_CONF_APP_NETWORK_INTERFACE == NO_CONNECT
00026 
00027 static void callback_zxing(char * addr, int size) {
00028     printf("%s\r\n", addr);
00029 }
00030 
00031 // Entry point to the program
00032 int main() {
00033     // Keep track of the main thread
00034     mainThread = osThreadGetId();
00035     printf("no connect\n");
00036     mbed_trace_init();
00037     zxing_init(&callback_zxing);
00038 
00039     while (1) {
00040         zxing_loop();
00041         Thread::wait(5);
00042     }
00043 }
00044 
00045 #else // MBED_CONF_APP_NETWORK_INTERFACE != NO_CONNECT
00046 
00047 #define __STDC_FORMAT_MACROS
00048 #include <string>
00049 #include <sstream>
00050 #include <vector>
00051 #include "security.h"
00052 #include "simpleclient.h"
00053 #include "mbedtls/entropy_poll.h"
00054 
00055 // easy-connect compliancy, it has 2 sets of wifi pins we have only one
00056 #define MBED_CONF_APP_ESP8266_TX MBED_CONF_APP_WIFI_TX
00057 #define MBED_CONF_APP_ESP8266_RX MBED_CONF_APP_WIFI_RX
00058 #include "easy-connect.h"
00059 
00060 // These are example resource values for the Device Object
00061 struct MbedClientDevice device = {
00062     "Manufacturer_String",      // Manufacturer
00063     "Type_String",              // Type
00064     "ModelNumber_String",       // ModelNumber
00065     "SerialNumber_String"       // SerialNumber
00066 };
00067 
00068 // Instantiate the class which implements LWM2M Client API (from simpleclient.h)
00069 MbedClient mbed_client(device);
00070 
00071 // LED Output
00072 DigitalOut led1(LED1);
00073 DigitalOut led2(LED2);
00074 DigitalOut led3(LED3);
00075 /*
00076  * The Led contains one property (pattern) and a function (blink).
00077  * When the function blink is executed, the pattern is read, and the LED
00078  * will blink based on the pattern.
00079  */
00080 class LedResource {
00081 public:
00082     LedResource() {
00083         // create ObjectID with metadata tag of '3201', which is 'digital output'
00084         led_object = M2MInterfaceFactory::create_object("3201");
00085         M2MObjectInstance* led_inst = led_object->create_object_instance();
00086 
00087         // 5855 = Multi-state output
00088         M2MResource* color_res = led_inst->create_dynamic_resource("5855", "Color",
00089             M2MResourceInstance::STRING, false);
00090         // read and write
00091         color_res->set_operation(M2MBase::GET_PUT_ALLOWED);
00092         // set red as initial color
00093         color_res->set_value((const uint8_t*)"red", 3);
00094         
00095         // 5853 = Multi-state output
00096         M2MResource* pattern_res = led_inst->create_dynamic_resource("5853", "Pattern",
00097             M2MResourceInstance::STRING, false);
00098         // read and write
00099         pattern_res->set_operation(M2MBase::GET_PUT_ALLOWED);
00100         // set initial pattern (toggle every 200ms. 7 toggles in total)
00101         pattern_res->set_value((const uint8_t*)"500:500:500:500:500:500:500", 27);
00102 
00103         // there's not really an execute LWM2M ID that matches... hmm...
00104         M2MResource* led_res = led_inst->create_dynamic_resource("5850", "Blink",
00105             M2MResourceInstance::OPAQUE, false);
00106         // we allow executing a function here...
00107         led_res->set_operation(M2MBase::POST_ALLOWED);
00108         // when a POST comes in, we want to execute the led_execute_callback
00109         led_res->set_execute_function(execute_callback(this, &LedResource::blink));
00110 
00111     }
00112 
00113     M2MObject* get_object() {
00114         return led_object;
00115     }
00116 
00117     void blink(void *argument) {
00118 
00119 
00120         // read the value of 'Pattern'
00121         M2MObjectInstance* inst = led_object->object_instance();
00122         M2MResource* res = inst->resource("5853");
00123         // read the value of 'Color'
00124         M2MObjectInstance* instC = led_object->object_instance();
00125         M2MResource* resC = instC->resource("5855");
00126 
00127         // values in mbed Client are all buffers, and we need a vector of int's
00128         uint8_t* buffIn = NULL;
00129         uint32_t sizeIn;
00130         res->get_value(buffIn, sizeIn);
00131         
00132         uint8_t* cbuffIn = NULL;
00133         uint32_t csizeIn;
00134         resC->get_value(cbuffIn, csizeIn);
00135 
00136         // turn the buffer into a string, and initialize a vector<int> on the heap
00137         std::string s((char*)buffIn, sizeIn);
00138         std::vector<uint32_t>* v = new std::vector<uint32_t>;
00139 
00140         printf("led_execute_callback pattern=%s\r\n", s.c_str());
00141 
00142         // our pattern is something like 500:200:500, so parse that
00143         std::size_t found = s.find_first_of(":");
00144         while (found!=std::string::npos) {
00145 
00146             v->push_back(atoi((const char*)s.substr(0,found).c_str()));
00147             s = s.substr(found+1);
00148             found=s.find_first_of(":");
00149             if(found == std::string::npos) {
00150                 v->push_back(atoi((const char*)s.c_str()));
00151             }
00152         }
00153         int position = 0;
00154         while (1) {
00155             do_blink(cbuffIn);
00156             if (position >= v->size()) {
00157                 break;
00158             }
00159             // how long do we need to wait before the next blink?
00160             Thread::wait(v->at(position));
00161             position++;
00162         }
00163         free(buffIn);
00164         free(cbuffIn);
00165         delete v;
00166     }
00167 
00168 private:
00169     M2MObject* led_object;
00170     void do_blink(uint8_t* color) {
00171         
00172         if (!strcmp((char *)color, "red")) {
00173             // blink the LED in red color
00174             led1 = !led1;
00175         }
00176         else if (!strcmp((char *)color, "green")) {
00177             // blink in green color
00178             led2 = !led2;
00179         }
00180         else if (!strcmp((char *)color, "blue")) {
00181             // blink in blue color
00182             led3 = !led3;
00183         }
00184         else if (!strcmp((char *)color, "cyan")) {
00185             // blink in cyan color
00186             led2 = !led2;
00187             led3 = !led3;
00188         }
00189         else if (!strcmp((char *)color, "yellow")) {
00190             // blink in yellow color
00191             led1 = !led1;
00192             led2 = !led2;
00193         }
00194         else if (!strcmp((char *)color, "magenta")) {
00195             // blink in magenta color
00196             led1 = !led1;
00197             led3 = !led3;
00198         }            
00199         else if (!strcmp((char *)color, "white")) {
00200             // blink in white color
00201             led1 = !led1;
00202             led2 = !led2;
00203             led3 = !led3;
00204         }
00205         else {
00206             // no operation
00207         }
00208     }
00209 };
00210 
00211 /*
00212  * The Zxing contains a function (send string).
00213  * When `handle_string_send` is executed, the string after decoding is sent.
00214  */
00215 class ZxingResource {
00216 public:
00217     ZxingResource() {
00218         // create ObjectID with metadata tag of '3202', which is 'send string'
00219         zxing_object = M2MInterfaceFactory::create_object("3202");
00220         M2MObjectInstance* zxing_inst = zxing_object->create_object_instance();
00221         // create resource with ID '5700', which is 'send string'
00222         M2MResource* zxing_res = zxing_inst->create_dynamic_resource("5700", "zxing",
00223             M2MResourceInstance::STRING, true);
00224         // we can read this value
00225         zxing_res->set_operation(M2MBase::GET_ALLOWED);
00226         // set initial value (all values in mbed Client are buffers)
00227         // to be able to read this data easily in the Connector console, we'll use a string
00228         zxing_res->set_value((uint8_t*)"0", 1);
00229     }
00230 
00231     ~ZxingResource() {
00232     }
00233 
00234     M2MObject* get_object() {
00235         return zxing_object;
00236     }
00237 
00238     /*
00239      * When you success the decode process of barcode, we send the string after decoding to mbed Device Connector.
00240      */
00241     void handle_string_send(char * addr, int size) {
00242         M2MObjectInstance* inst = zxing_object->object_instance();
00243         M2MResource* res = inst->resource("5700");
00244 
00245         printf("%s\r\n", addr);
00246 
00247         // tell the string to connector
00248         res->set_value((uint8_t *)addr, size);
00249 
00250         // Write 0 to 3202/0/5700 so that the same item can be added to the cart consectively
00251         res->set_value((uint8_t *)"0", 1);
00252     }
00253 
00254 private:
00255     M2MObject* zxing_object;
00256 };
00257 
00258 ZxingResource zxing_resource;
00259 
00260 static void callback_zxing(char * addr, int size) {
00261     zxing_resource.handle_string_send(addr, size);
00262 }
00263 
00264 static volatile bool registered;
00265 
00266 void unregister() {
00267     registered = false;
00268 }
00269 
00270 // Entry point to the program
00271 int main() {
00272 
00273     unsigned int seed;
00274     size_t len;
00275 
00276 #ifdef MBEDTLS_ENTROPY_HARDWARE_ALT
00277     // Used to randomize source port
00278     mbedtls_hardware_poll(NULL, (unsigned char *) &seed, sizeof seed, &len);
00279 
00280 #elif defined MBEDTLS_TEST_NULL_ENTROPY
00281 
00282 #warning "mbedTLS security feature is disabled. Connection will not be secure !! Implement proper hardware entropy for your selected hardware."
00283     // Used to randomize source port
00284     mbedtls_null_entropy_poll( NULL,(unsigned char *) &seed, sizeof seed, &len);
00285 
00286 #else
00287 
00288 #error "This hardware does not have entropy, endpoint will not register to Connector.\
00289 You need to enable NULL ENTROPY for your application, but if this configuration change is made then no security is offered by mbed TLS.\
00290 Add MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES and MBEDTLS_TEST_NULL_ENTROPY in mbed_app.json macros to register your endpoint."
00291 
00292 #endif
00293 
00294     srand(seed);
00295     // Keep track of the main thread
00296     mainThread = osThreadGetId();
00297     printf("\nStarting mbed Client example in ");
00298 
00299 #if defined (MESH) || (MBED_CONF_LWIP_IPV6_ENABLED==true)
00300     printf("IPv6 mode\n");
00301 #else
00302     printf("IPv4 mode\n");
00303 #endif
00304 
00305     mbed_trace_init();
00306 
00307 #if MBED_CONF_APP_NETWORK_INTERFACE == WIFI_BP3595
00308     DigitalOut usb1en(P3_8);
00309     usb1en = 1;
00310     Thread::wait(5);
00311     usb1en = 0;
00312     Thread::wait(5);
00313 #endif
00314 
00315     NetworkInterface* network = easy_connect(true);
00316     if(network == NULL) {
00317         printf("\nConnection to Network Failed - exiting application...\n");
00318         return -1;
00319     }
00320     LedResource led_resource;
00321 
00322     // Create endpoint interface to manage register and unregister
00323     mbed_client.create_interface(MBED_SERVER_ADDRESS, network);
00324 
00325     // Create Objects of varying types, see simpleclient.h for more details on implementation.
00326     M2MSecurity* register_object = mbed_client.create_register_object(); // server object specifying connector info
00327     M2MDevice*   device_object   = mbed_client.create_device_object();   // device resources object
00328 
00329     // Create list of Objects to register
00330     M2MObjectList object_list;
00331 
00332     // Add objects to list
00333     object_list.push_back(device_object);
00334     object_list.push_back(led_resource.get_object());
00335     object_list.push_back(zxing_resource.get_object());
00336 
00337     // Set endpoint registration object
00338     mbed_client.set_register_object(register_object);
00339 
00340     // Register with mbed Device Connector
00341     mbed_client.test_register(register_object, object_list);
00342 
00343     zxing_init(&callback_zxing);
00344 
00345     Timer update_timer;
00346     update_timer.reset();
00347     update_timer.start();
00348 
00349     registered = true;
00350     InterruptIn unreg_button(USER_BUTTON0);
00351     unreg_button.fall(&unregister);
00352 
00353     while (registered) {
00354         if (zxing_loop() == 0) {
00355             update_timer.reset();
00356         } else if (update_timer.read() >= 25) {
00357             mbed_client.test_update_register();
00358             update_timer.reset();
00359         } else {
00360             // do nothing
00361         }
00362         Thread::wait(5);
00363     }
00364 
00365     mbed_client.test_unregister();
00366 }
00367 
00368 #endif // MBED_CONF_APP_NETWORK_INTERFACE != NO_CONNECT
00369 
00370