Send the data of GR-PEACH_HVC-P2_sample to the cloud.

Dependencies:   AsciiFont GR-PEACH_video GraphicsFramework LCD_shield_config R_BSP USBHost_custom easy-connect-gr-peach

Fork of mbed-os-example-client by mbed-os-examples

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 #define __STDC_FORMAT_MACROS
00017 #include <inttypes.h>
00018 #include "simpleclient.h"
00019 #include <string>
00020 #include <sstream>
00021 #include <vector>
00022 #include "mbed-trace/mbed_trace.h"
00023 #include "mbedtls/entropy_poll.h"
00024 
00025 #include "security.h"
00026 
00027 #include "mbed.h"
00028 #include "DisplayBace.h"
00029 #include "rtos.h"
00030 #include "LCD_shield_config_4_3inch.h"
00031 #include "recognition_proc.h"
00032 #include "touch_proc.h"
00033 
00034 // easy-connect compliancy, it has 2 sets of wifi pins we have only one
00035 #define MBED_CONF_APP_ESP8266_TX MBED_CONF_APP_WIFI_TX
00036 #define MBED_CONF_APP_ESP8266_RX MBED_CONF_APP_WIFI_RX
00037 #include "easy-connect.h"
00038 
00039 
00040 // These are example resource values for the Device Object
00041 struct MbedClientDevice device = {
00042     "Manufacturer_String",      // Manufacturer
00043     "Type_String",              // Type
00044     "ModelNumber_String",       // ModelNumber
00045     "SerialNumber_String"       // SerialNumber
00046 };
00047 
00048 // Instantiate the class which implements LWM2M Client API (from simpleclient.h)
00049 MbedClient mbed_client(device);
00050 
00051 static DisplayBase Display;
00052 static DigitalOut  lcd_pwon(P7_15);
00053 static DigitalOut  lcd_blon(P8_1);
00054 static PwmOut      lcd_cntrst(P8_15);
00055 static Thread      recognitionTask;
00056 static Thread      touchTask;
00057 static char send_cloud_buf_last[1024 * 4];
00058 
00059 // LED Output
00060 DigitalOut led1(LED1);
00061 DigitalOut led2(LED2);
00062 DigitalOut led3(LED3);
00063 
00064 /*
00065  * The Led contains one property (pattern) and a function (blink).
00066  * When the function blink is executed, the pattern is read, and the LED
00067  * will blink based on the pattern.
00068  */
00069 class LedResource {
00070 public:
00071     LedResource() {
00072         // create ObjectID with metadata tag of '3201', which is 'digital output'
00073         led_object = M2MInterfaceFactory::create_object("3201");
00074         M2MObjectInstance* led_inst = led_object->create_object_instance();
00075 
00076         // 5855 = Multi-state output
00077         M2MResource* color_res = led_inst->create_dynamic_resource("5855", "Color",
00078             M2MResourceInstance::STRING, false);
00079         // read and write
00080         color_res->set_operation(M2MBase::GET_PUT_ALLOWED);
00081         // set red as initial color
00082         color_res->set_value((const uint8_t*)"red", 3);
00083         
00084         // 5853 = Multi-state output
00085         M2MResource* pattern_res = led_inst->create_dynamic_resource("5853", "Pattern",
00086             M2MResourceInstance::STRING, false);
00087         // read and write
00088         pattern_res->set_operation(M2MBase::GET_PUT_ALLOWED);
00089         // set initial pattern (toggle every 200ms. 7 toggles in total)
00090         pattern_res->set_value((const uint8_t*)"500:500:500:500:500:500:500", 27);
00091 
00092         // there's not really an execute LWM2M ID that matches... hmm...
00093         M2MResource* led_res = led_inst->create_dynamic_resource("5850", "Blink",
00094             M2MResourceInstance::OPAQUE, false);
00095         // we allow executing a function here...
00096         led_res->set_operation(M2MBase::POST_ALLOWED);
00097         // when a POST comes in, we want to execute the led_execute_callback
00098         led_res->set_execute_function(execute_callback(this, &LedResource::blink));
00099     }
00100 
00101     M2MObject* get_object() {
00102         return led_object;
00103     }
00104 
00105     void blink(void *) {
00106         // read the value of 'Pattern'
00107         M2MObjectInstance* inst = led_object->object_instance();
00108         M2MResource* res = inst->resource("5853");
00109         // read the value of 'Color'
00110         M2MObjectInstance* instC = led_object->object_instance();
00111         M2MResource* resC = instC->resource("5855");
00112 
00113         // values in mbed Client are all buffers, and we need a vector of int's
00114         uint8_t* buffIn = NULL;
00115         uint32_t sizeIn;
00116         res->get_value(buffIn, sizeIn);
00117         
00118         uint8_t* cbuffIn = NULL;
00119         uint32_t csizeIn;
00120         resC->get_value(cbuffIn, csizeIn);
00121 
00122         // turn the buffer into a string, and initialize a vector<int> on the heap
00123         std::string s((char*)buffIn, sizeIn);
00124         std::vector<uint32_t>* v = new std::vector<uint32_t>;
00125 
00126         printf("led_execute_callback pattern=%s\r\n", s.c_str());
00127 
00128         // our pattern is something like 500:200:500, so parse that
00129         std::size_t found = s.find_first_of(":");
00130         while (found!=std::string::npos) {
00131 
00132             v->push_back(atoi((const char*)s.substr(0,found).c_str()));
00133             s = s.substr(found+1);
00134             found=s.find_first_of(":");
00135             if(found == std::string::npos) {
00136                 v->push_back(atoi((const char*)s.c_str()));
00137             }
00138         }
00139 
00140         int position = 0;
00141         while (1) {
00142             do_blink(cbuffIn);
00143             if (position >= v->size()) {
00144                 break;
00145             }
00146             // how long do we need to wait before the next blink?
00147             Thread::wait(v->at(position));
00148             position++;
00149         }
00150         free(buffIn);
00151         free(cbuffIn);
00152         delete v;
00153     }
00154 
00155 private:
00156     M2MObject* led_object;
00157 
00158     void do_blink(uint8_t* color) {
00159         if (!strcmp((char *)color, "red")) {
00160             // blink the LED in red color
00161             led1 = !led1;
00162         }
00163         else if (!strcmp((char *)color, "green")) {
00164             // blink in green color
00165             led2 = !led2;
00166         }
00167         else if (!strcmp((char *)color, "blue")) {
00168             // blink in blue color
00169             led3 = !led3;
00170         }
00171         else if (!strcmp((char *)color, "cyan")) {
00172             // blink in cyan color
00173             led2 = !led2;
00174             led3 = !led3;
00175         }
00176         else if (!strcmp((char *)color, "yellow")) {
00177             // blink in yellow color
00178             led1 = !led1;
00179             led2 = !led2;
00180         }
00181         else if (!strcmp((char *)color, "magenta")) {
00182             // blink in magenta color
00183             led1 = !led1;
00184             led3 = !led3;
00185         }            
00186         else if (!strcmp((char *)color, "white")) {
00187             // blink in white color
00188             led1 = !led1;
00189             led2 = !led2;
00190             led3 = !led3;
00191         }
00192         else {
00193             // no operation
00194         }
00195     }
00196 };
00197 
00198 /*
00199  * The HVC contains a function (send string).
00200  * When `handle_string_send` is executed, the string after decoding is sent.
00201  */
00202 class HVCResource {
00203 public:
00204     HVCResource() {
00205         // create ObjectID with metadata tag of '3202', which is 'send string'
00206         hvc_object = M2MInterfaceFactory::create_object("3202");
00207         M2MObjectInstance* hvc_inst = hvc_object->create_object_instance();
00208         // create resource with ID '5700', which is 'send string'
00209         M2MResource* hvc_res = hvc_inst->create_dynamic_resource("5700", "hvc",
00210             M2MResourceInstance::STRING, true);
00211         // we can read this value
00212         hvc_res->set_operation(M2MBase::GET_ALLOWED);
00213         // set initial value (all values in mbed Client are buffers)
00214         // to be able to read this data easily in the Connector console, we'll use a string
00215         hvc_res->set_value((uint8_t*)"0", 1);
00216     }
00217 
00218     ~HVCResource() {
00219     }
00220 
00221     M2MObject* get_object() {
00222         return hvc_object;
00223     }
00224 
00225     /*
00226      * When you success the decode process of barcode, we send the string after decoding to mbed Device Connector.
00227      */
00228     void handle_string_send(char * addr, int size) {
00229         M2MObjectInstance* inst = hvc_object->object_instance();
00230         M2MResource* res = inst->resource("5700");
00231 
00232         printf("%s\r\n", addr);
00233 
00234         // tell the string to connector
00235         res->set_value((uint8_t *)addr, size);
00236     }
00237 
00238 private:
00239     M2MObject* hvc_object;
00240 };
00241 
00242 // Network interaction must be performed outside of interrupt context
00243 Semaphore updates(0);
00244 osThreadId mainThread;
00245 
00246 HVCResource hvc_resource;
00247 volatile bool sent = false;
00248 Timer send_timer;
00249 
00250 void HVCSendData(char * addr, int size) {
00251     if (send_timer.read_ms() > 500) {
00252         if (memcmp(send_cloud_buf_last, addr, sizeof(send_cloud_buf_last)) != 0) {
00253             memcpy(send_cloud_buf_last, addr, sizeof(send_cloud_buf_last));
00254             send_timer.reset();
00255             hvc_resource.handle_string_send(addr, size);
00256             sent = true;
00257             updates.release();
00258         }
00259     }
00260 }
00261 
00262 // LCD
00263 static void IntCallbackFunc_LoVsync(DisplayBase::int_type_t int_type) {
00264     /* Interrupt callback function for Vsync interruption */
00265     touch_lcd_int(int_type);
00266 }
00267 
00268 static void Init_LCD_Display(void) {
00269     DisplayBase::graphics_error_t error;
00270     DisplayBase::lcd_config_t lcd_config;
00271     PinName lvds_pin[8] = {
00272         /* data pin */
00273         P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0
00274     };
00275 
00276     lcd_pwon = 0;
00277     lcd_blon = 0;
00278     Thread::wait(100);
00279     lcd_pwon = 1;
00280     lcd_blon = 1;
00281 
00282     Display.Graphics_Lvds_Port_Init(lvds_pin, 8);
00283 
00284     /* Graphics initialization process */
00285     lcd_config = LcdCfgTbl_LCD_shield;
00286     error = Display.Graphics_init(&lcd_config);
00287     if (error != DisplayBase::GRAPHICS_OK) {
00288         printf("Line %d, error %d\n", __LINE__, error);
00289         mbed_die();
00290     }
00291 
00292     /* Interrupt callback function setting (Vsync signal output from scaler 0) */
00293     error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_LO_VSYNC, 0, IntCallbackFunc_LoVsync);
00294     if (error != DisplayBase::GRAPHICS_OK) {
00295         printf("Line %d, error %d\n", __LINE__, error);
00296         mbed_die();
00297     }
00298 }
00299 
00300 // Entry point to the program
00301 int main() {
00302 
00303     unsigned int seed;
00304     size_t len;
00305 
00306     /* Initialization of LCD */
00307     Init_LCD_Display();
00308 
00309     /* Start recognition processing */
00310     recognitionTask.start(callback(recognition_task, &Display));
00311 
00312     /* Start touch panel processing */
00313     touchTask.start(callback(touch_task, &Display));
00314 
00315     /* Backlight on */
00316     Thread::wait(200);
00317     lcd_cntrst.write(1.0);
00318 
00319 #ifdef MBEDTLS_ENTROPY_HARDWARE_ALT
00320     // Used to randomize source port
00321     mbedtls_hardware_poll(NULL, (unsigned char *) &seed, sizeof seed, &len);
00322 
00323 #elif defined MBEDTLS_TEST_NULL_ENTROPY
00324 
00325 #warning "mbedTLS security feature is disabled. Connection will not be secure !! Implement proper hardware entropy for your selected hardware."
00326     // Used to randomize source port
00327     mbedtls_null_entropy_poll( NULL,(unsigned char *) &seed, sizeof seed, &len);
00328 
00329 #else
00330 
00331 #error "This hardware does not have entropy, endpoint will not register to Connector.\
00332 You need to enable NULL ENTROPY for your application, but if this configuration change is made then no security is offered by mbed TLS.\
00333 Add MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES and MBEDTLS_TEST_NULL_ENTROPY in mbed_app.json macros to register your endpoint."
00334 
00335 #endif
00336 
00337     srand(seed);
00338     // Keep track of the main thread
00339     mainThread = osThreadGetId();
00340     printf("\nStarting mbed Client example in ");
00341 #if defined (MESH) || (MBED_CONF_LWIP_IPV6_ENABLED==true)
00342     printf("IPv6 mode\n");
00343 #else
00344     printf("IPv4 mode\n");
00345 #endif
00346 
00347     mbed_trace_init();
00348 
00349     NetworkInterface* network = easy_connect(true);
00350     if(network == NULL) {
00351         printf("\nConnection to Network Failed - exiting application...\n");
00352         return -1;
00353     }
00354 
00355     // we create our button and LED resources
00356     LedResource led_resource;
00357 
00358 
00359     // Create endpoint interface to manage register and unregister
00360     mbed_client.create_interface(MBED_SERVER_ADDRESS, network);
00361 
00362     // Create Objects of varying types, see simpleclient.h for more details on implementation.
00363     M2MSecurity* register_object = mbed_client.create_register_object(); // server object specifying connector info
00364     M2MDevice*   device_object   = mbed_client.create_device_object();   // device resources object
00365 
00366     // Create list of Objects to register
00367     M2MObjectList object_list;
00368 
00369     // Add objects to list
00370     object_list.push_back(device_object);
00371     object_list.push_back(led_resource.get_object());
00372     object_list.push_back(hvc_resource.get_object());
00373 
00374     // Set endpoint registration object
00375     mbed_client.set_register_object(register_object);
00376 
00377     // Register with mbed Device Connector
00378     mbed_client.test_register(register_object, object_list);
00379     send_timer.start();
00380     while (1) {
00381         updates.wait(25000);
00382         if(!sent) {
00383             mbed_client.test_update_register();
00384         }
00385         sent = false;
00386     }
00387 }