Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 16:31c387e94b6d, committed 2017-05-11
- Comitter:
- terencez
- Date:
- Thu May 11 12:40:25 2017 +0000
- Parent:
- 15:d0f20339c1ad
- Commit message:
- Added a demo temperature object based on sensor LM75B.
Changed in this revision
--- a/main.cpp Sun May 07 03:00:16 2017 +0000 +++ b/main.cpp Thu May 11 12:40:25 2017 +0000 @@ -1,61 +1,23 @@ #include "mbed.h" #include "C12832.h" #include "LM75B.h" - #include "EthernetInterface.h" - extern "C" { #include "liblwm2m.h" //External API - -#if 0 - /* - * object_server.c - */ - lwm2m_object_t * get_server_object(int serverId, const char* binding, int lifetime, bool storing); - void clean_server_object(lwm2m_object_t * object); - void display_server_object(lwm2m_object_t * objectP); - void copy_server_object(lwm2m_object_t * objectDest, lwm2m_object_t * objectSrc); - - /* - * object_device.c - */ - lwm2m_object_t * get_object_device(void); - void free_object_device(lwm2m_object_t * objectP); - uint8_t device_change(lwm2m_data_t * dataArray, lwm2m_object_t * objectP); - void display_device_object(lwm2m_object_t * objectP); - /* - * object_security.c - */ - lwm2m_object_t * get_security_object(int serverId, const char* serverUri, char * bsPskId, char * psk, uint16_t pskLen, bool isBootstrap); - void clean_security_object(lwm2m_object_t * objectP); - char * get_server_uri(lwm2m_object_t * objectP, uint16_t secObjInstID); - void display_security_object(lwm2m_object_t * objectP); - void copy_security_object(lwm2m_object_t * objectDest, lwm2m_object_t * objectSrc); - /* - * object_test.c - */ - #define TEST_OBJECT_ID 1024 - lwm2m_object_t * get_test_object(void); - void free_test_object(lwm2m_object_t * object); - void display_test_object(lwm2m_object_t * objectP); - -#else -extern lwm2m_object_t * get_object_device(void); -extern void free_object_device(lwm2m_object_t * objectP); -extern lwm2m_object_t * get_server_object(void); -extern void free_server_object(lwm2m_object_t * object); -extern lwm2m_object_t * get_security_object(void); -extern void free_security_object(lwm2m_object_t * objectP); -extern char * get_server_uri(lwm2m_object_t * objectP, uint16_t secObjInstID); -extern lwm2m_object_t * get_test_object(void); -extern void free_test_object(lwm2m_object_t * object); + extern lwm2m_object_t * get_object_device(void); + extern void free_object_device(lwm2m_object_t * objectP); + extern lwm2m_object_t * get_server_object(void); + extern void free_server_object(lwm2m_object_t * object); + extern lwm2m_object_t * get_security_object(void); + extern void free_security_object(lwm2m_object_t * objectP); + extern char * get_server_uri(lwm2m_object_t * objectP, uint16_t secObjInstID); +} +#ifdef ENABLE_RGB_LED +lwm2m_object_t * get_object_rgb_led(void); #endif - - - -} +lwm2m_object_t * get_object_temperature(void); //Global definitions #define ENDPOINT_NAME "MBED-OS-EXAMPLE-WAKAAMA" @@ -64,11 +26,14 @@ #define LESHAN_PORT 5683 #define UDP_TIMEOUT 60000 #define UDP_PORT 5683 + +#ifdef ENABLE_RGB_LED +#define DEVICE_OBJ_NUM 5 +#else #define DEVICE_OBJ_NUM 4 - +#endif #define LOCAL_PORT 5683 - // LCD 128X32 C12832 lcd(p5, p7, p6, p8, p11); // Sensor of temperature @@ -210,11 +175,6 @@ } printf("\n--------------------------\n"); } -void test_udp(EthernetInterface eth) -{ - //TBD -} - void test_tcp(EthernetInterface eth) { TCPSocket tcp; @@ -304,6 +264,11 @@ return COAP_NO_ERROR; } +void get_temperature(float *temp) +{ + *temp = sensor_temp.read(); + printf("SYSTEM TEMP: %.3f",*temp); +} int main() { @@ -352,14 +317,22 @@ return -1; } - objArray[3] = get_test_object(); + + objArray[3] = get_object_temperature(); if (NULL == objArray[3]) { - fprintf(stderr, "Failed to create Test object\r\n"); + fprintf(stderr, "Failed to create temperature object\r\n"); return -1; } - - + +#ifdef ENABLE_RGB_LED + objArray[4] = get_object_rgb_led(); + if (NULL == objArray[4]) + { + fprintf(stderr, "Failed to create RGB LED object\r\n"); + return -1; + } +#endif /* * The liblwm2m library is now initialized with the functions that will be in * charge of communication @@ -432,3 +405,5 @@ }//while() }//main + +
--- a/share/object_device.c Sun May 07 03:00:16 2017 +0000 +++ b/share/object_device.c Thu May 11 12:40:25 2017 +0000 @@ -127,6 +127,8 @@ { int min_index; + printf("### TERENCE:%s:%d\n",__FUNCTION__,__LINE__); + if (length != 3 && length != 5 && length != 6) return 0; if (buffer[0] != '-' && buffer[0] != '+') return 0; switch (buffer[1]) @@ -164,6 +166,7 @@ static uint8_t prv_set_value(lwm2m_data_t * dataP, device_data_t * devDataP) { + printf("### TERENCE:%s:%d\n",__FUNCTION__,__LINE__); // a simple switch structure is used to respond at the specified resource asked switch (dataP->id) { @@ -289,13 +292,14 @@ { uint8_t result; int i; + printf("### TERENCE:%s:%d\n",__FUNCTION__,__LINE__); printf(" TERENCE:%s, %d,instanceId = %d\n",__FUNCTION__, __LINE__,instanceId); // this is a single instance object if (instanceId != 0) { return COAP_404_NOT_FOUND; } - printf(" TERENCE:%s, %d: numDataP = %d\n",__FUNCTION__, __LINE__, *numDataP); + // is the server asking for the full object ? if (*numDataP == 0) { @@ -331,7 +335,7 @@ } } - printf(" TERENCE:%s, %d: \n",__FUNCTION__, __LINE__); + i = 0; do { @@ -350,6 +354,7 @@ uint8_t result; int i; + printf("### TERENCE:%s:%d\n",__FUNCTION__,__LINE__); // this is a single instance object if (instanceId != 0) { @@ -357,7 +362,7 @@ } result = COAP_205_CONTENT; - + printf("### TERENCE:%s:%d\n",__FUNCTION__,__LINE__); // is the server asking for the full object ? if (*numDataP == 0) { @@ -430,7 +435,7 @@ { int i; uint8_t result; - + printf("### TERENCE:%s:%d\n",__FUNCTION__,__LINE__); // this is a single instance object if (instanceId != 0) { @@ -489,6 +494,7 @@ int length, lwm2m_object_t * objectP) { + printf("### TERENCE:%s:%d\n",__FUNCTION__,__LINE__); // this is a single instance object if (instanceId != 0) { @@ -517,6 +523,7 @@ void display_device_object(lwm2m_object_t * object) { + printf("### TERENCE:%s:%d\n",__FUNCTION__,__LINE__); #ifdef WITH_LOGS device_data_t * data = (device_data_t *)object->userData; fprintf(stdout, " /%u: Device object:\r\n", object->objID); @@ -535,6 +542,7 @@ */ lwm2m_object_t * deviceObj; + printf("### TERENCE:%s:%d\n",__FUNCTION__,__LINE__); deviceObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t)); if (NULL != deviceObj) @@ -597,6 +605,7 @@ void free_object_device(lwm2m_object_t * objectP) { + printf("### TERENCE:%s:%d\n",__FUNCTION__,__LINE__); if (NULL != objectP->userData) { lwm2m_free(objectP->userData); @@ -616,6 +625,9 @@ { uint8_t result; + + printf("### TERENCE:%s:%d\n",__FUNCTION__,__LINE__); + switch (dataArray->id) { case RES_O_BATTERY_LEVEL:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/object_mbed_rgb_led.cpp Thu May 11 12:40:25 2017 +0000 @@ -0,0 +1,318 @@ + +/******************************************************************************* + * + * Copyright (c) 2013, 2014 Intel Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * The Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Simon Bernard + *******************************************************************************/ +#include "liblwm2m.h" + +#ifdef ENABLE_RGB_LED +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include "mbed.h" + +#define LWM2M_LIGHT_OBJECT_ID 3311 + +// Resource Id's: +#define RES_COLOUR 5706 +#define RES_ON_OFF 5850 + +typedef struct { + // state of the light + bool on; + // the current color choose by user + float rv; + float gv; + float bv; +} rgb_data_t; + +PwmOut * rpw; +PwmOut * gpw; +PwmOut * bpw; + +InterruptIn on_button(p13); +InterruptIn off_button(p16); +rgb_data_t * state; + +void switchon() { + printf("LIGHT ON"); + state->on = true; + *rpw = state->rv; + *gpw = state->gv; + *bpw = state->bv; +} + +void switchoff() { + printf("LIGHT OFF"); + state->on = false; + *rpw = 1.0f; + *gpw = 1.0f; + *bpw = 1.0f; +} + +// change the led color +static int set_color(const char * htmlcolor, unsigned length, rgb_data_t * rgb) { + // create color string ended with \0 + char color[length + 1]; + memset(color, 0, length + 1); + strncpy(color, htmlcolor, length); + + // parse value to extract rgb (255,255,255) + int r, g, b; + if (sscanf(color, "#%2x%2x%2x", &r, &g, &b) != 3) { + printf("failed to parse color string, sscanf failed for %s", color); + return -1; + } + printf("Set Color to rgb(%d, %d, %d)", r, g, b); + + // convert it in led power and update current color + rgb->rv = -((r / 255.0f) - 1.0f); + rgb->gv = -((g / 255.0f) - 1.0f); + rgb->bv = -((b / 255.0f) - 1.0f); + + // apply color only if the light is ON. + if (rgb->on) { + *rpw = rgb->rv; + *gpw = rgb->gv; + *bpw = rgb->bv; + } + + return 0; +} + +// read the current color +static char * get_color(rgb_data_t * rgb) { + // get current value and convert it in rgb(255,255,255) + int r = (1.0f - rgb->rv) * 255; + int g = (1.0f - rgb->gv) * 255; + int b = (1.0f - rgb->bv) * 255; + + // build the corresponding string + printf("Read Color rgb(%d,%d,%d)", r, g, b); + char * color = (char *) malloc(8); + if (0 > sprintf(color, "#%02X%02X%02X", r, g, b)) { + printf("failed to create color string, sprintf failed"); + free(color); + return NULL; + } + + return color; +} + +static uint8_t prv_set_value(lwm2m_data_t * dataP, rgb_data_t * devDataP) { + // a simple switch structure is used to respond at the specified resource asked + switch (dataP->id) { + case RES_COLOUR: { + char * color = get_color(devDataP); + lwm2m_data_encode_int((int64_t)(*color),dataP); + return COAP_205_CONTENT ; + } + case RES_ON_OFF: { + bool on = (rpw->read() < 1.0f || gpw->read() < 1.0f || bpw->read() < 1.0f); + lwm2m_data_encode_bool(on,dataP); + return COAP_205_CONTENT ; + } + default: + return COAP_404_NOT_FOUND ; + } +} + + +void lwm2m_data_encode_string(const char * string, lwm2m_data_t * dataP); +void lwm2m_data_encode_nstring(const char * string, size_t length, lwm2m_data_t * dataP); +void lwm2m_data_encode_opaque(uint8_t * buffer, size_t length, lwm2m_data_t * dataP); +void lwm2m_data_encode_int(int64_t value, lwm2m_data_t * dataP); +int lwm2m_data_decode_int(const lwm2m_data_t * dataP, int64_t * valueP); +void lwm2m_data_encode_float(double value, lwm2m_data_t * dataP); +int lwm2m_data_decode_float(const lwm2m_data_t * dataP, double * valueP); +void lwm2m_data_encode_bool(bool value, lwm2m_data_t * dataP); +int lwm2m_data_decode_bool(const lwm2m_data_t * dataP, bool * valueP); +void lwm2m_data_encode_objlink(uint16_t objectId, uint16_t objectInstanceId, lwm2m_data_t * dataP); +void lwm2m_data_encode_instances(lwm2m_data_t * subDataP, size_t count, lwm2m_data_t * dataP); +void lwm2m_data_include(lwm2m_data_t * subDataP, size_t count, lwm2m_data_t * dataP); + + +static uint8_t prv_rgb_read(uint16_t instanceId, int * numDataP, lwm2m_data_t ** dataArrayP, lwm2m_object_t * objectP) { + uint8_t result; + int i; + + // this is a single instance object + if (instanceId != 0) { + return COAP_404_NOT_FOUND ; + } + + // is the server asking for the full object ? + if (*numDataP == 0) { + + uint16_t resList[] = { + RES_COLOUR, + RES_ON_OFF, }; + int nbRes = sizeof(resList) / sizeof(uint16_t); + + *dataArrayP = lwm2m_data_new(nbRes); + if (*dataArrayP == NULL) + return COAP_500_INTERNAL_SERVER_ERROR ; + *numDataP = nbRes; + for (i = 0; i < nbRes; i++) { + (*dataArrayP)[i].id = resList[i]; + } + } + + i = 0; + do { + result = prv_set_value((*dataArrayP) + i, (rgb_data_t*) (objectP->userData)); + i++; + } while (i < *numDataP && result == COAP_205_CONTENT ); + + return result; +} + +static uint8_t prv_rgb_write(uint16_t instanceId, int numData, lwm2m_data_t * dataArray, lwm2m_object_t * objectP) { + int i; + uint8_t result; + + // this is a single instance object + if (instanceId != 0) { + return COAP_404_NOT_FOUND ; + } + + i = 0; + + do { + switch (dataArray[i].id) { + case RES_COLOUR: + if (-1 != set_color((char*) dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length, (rgb_data_t*) (objectP->userData))) { + result = COAP_204_CHANGED; + } else { + result = COAP_500_INTERNAL_SERVER_ERROR; + } + break; + case RES_ON_OFF: + bool on; + if (1 == lwm2m_data_decode_bool(dataArray + i, &on)) { + if (on) { + switchon(); + } else { + switchoff(); + } + result = COAP_204_CHANGED; + } else { + result = COAP_400_BAD_REQUEST; + } + break; + default: + result = COAP_405_METHOD_NOT_ALLOWED; + } + + i++; + } while (i < numData && result == COAP_204_CHANGED ); + + return result; +} + +static void prv_rgb_close(lwm2m_object_t * objectP) { + if (NULL != objectP->userData) { + lwm2m_free(objectP->userData); + objectP->userData = NULL; + } + if (NULL != objectP->instanceList) { + lwm2m_free(objectP->instanceList); + objectP->instanceList = NULL; + } +} + +void display_rgb_object(lwm2m_object_t * object) { +#ifdef WITH_LOGS + rgb_data_t * data = (rgb_data_t *) object->userData; + fprintf(stdout, " /%u: rgb object:\r\n", object->objID); + if (NULL != data) { + fprintf(stdout, " previous x: %f, previous y: %f, previous z: %f\r\n", data->rv, data->gv, data->bv); + } +#endif +} + +lwm2m_object_t * get_object_rgb_led() { + + /* + * The get_object_rgb_led function create the object itself and return a pointer to the structure that represent it. + */ + lwm2m_object_t * rgbObj; + + rgbObj = (lwm2m_object_t *) lwm2m_malloc(sizeof(lwm2m_object_t)); + + if (NULL != rgbObj) { + memset(rgbObj, 0, sizeof(lwm2m_object_t)); + + /* + * It assigns his unique ID + * The 3313 is the standard ID for the mandatory object "IPSO Light Control". + */ + rgbObj->objID = LWM2M_LIGHT_OBJECT_ID; + + /* + * there is only one instance of RGB LED on the Application Board for mbed NXP LPC1768. + * + */ + rgbObj->instanceList = (lwm2m_list_t *) lwm2m_malloc(sizeof(lwm2m_list_t)); + if (NULL != rgbObj->instanceList) { + memset(rgbObj->instanceList, 0, sizeof(lwm2m_list_t)); + } else { + lwm2m_free(rgbObj); + return NULL; + } + + /* + * And the private function that will access the object. + * Those function will be called when a read/write/execute query is made by the server. In fact the library don't need to + * know the resources of the object, only the server does. + */ + rgbObj->readFunc = prv_rgb_read; + rgbObj->writeFunc = prv_rgb_write; + rgbObj->executeFunc = NULL; + state = (rgb_data_t *) lwm2m_malloc(sizeof(rgb_data_t)); + rgbObj->userData = state; + + /* + * Also some user data can be stored in the object with a private structure containing the needed variables + */ + if (NULL != rgbObj->userData) { + + rpw = new PwmOut(p23); + gpw = new PwmOut(p24); + bpw = new PwmOut(p25); + + // light off to start + ((rgb_data_t*) rgbObj->userData)->on = false; + *rpw = 1.0f; + *gpw = 1.0f; + *bpw = 1.0f; + + // blue as default color + ((rgb_data_t*) rgbObj->userData)->rv = 1.0f; + ((rgb_data_t*) rgbObj->userData)->gv = 1.0f; + ((rgb_data_t*) rgbObj->userData)->bv = 0.0f; + } else { + lwm2m_free(rgbObj); + rgbObj = NULL; + } + + on_button.rise(&switchon); + off_button.rise(&switchoff); + } + + return rgbObj; +} +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/object_mbed_temperature.cpp Thu May 11 12:40:25 2017 +0000 @@ -0,0 +1,134 @@ +#include "liblwm2m.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#define LWM2M_TEMPERATURE_OBJECT_ID 3303 +#define LWM2M_TEMPERATURE_SENSOR_UNITS "Celsius" +#define LWM2M_TEMPERATURE_LOCATION "Shenzhen,China" + + +#define RES_SENSOR_MIN 5601 +#define RES_SENSOR_MAX 5602 +#define RES_SENSOR_MIN_RANGE 5603 +#define RES_SENSOR_MAX_RANGE 5604 +#define RES_SENSOR_RESET 5605 +#define RES_SENSOR_VALUE 5700 +#define RES_SENSOR_UNITS 5701 +#define RES_SENSOR_LOCATION 5702 + +void get_temperature(float *temp); + +static uint8_t prv_set_value(lwm2m_data_t * dataP) +{ + float temp =0; + // a simple switch structure is used to respond at the specified resource asked + switch (dataP->id) { + case RES_SENSOR_VALUE: + get_temperature(&temp); + lwm2m_data_encode_float(temp, dataP); + return COAP_205_CONTENT ; + + case RES_SENSOR_UNITS: + lwm2m_data_encode_string(LWM2M_TEMPERATURE_SENSOR_UNITS, dataP); + return COAP_205_CONTENT ; + + case RES_SENSOR_MIN: + case RES_SENSOR_MAX: + case RES_SENSOR_RESET: + lwm2m_data_encode_string("Not Support!", dataP); + return COAP_205_CONTENT ; + case RES_SENSOR_MIN_RANGE: + lwm2m_data_encode_float(-55, dataP); + return COAP_205_CONTENT ; + case RES_SENSOR_MAX_RANGE: + lwm2m_data_encode_float(125, dataP); + return COAP_205_CONTENT ; + //case RES_SENSOR_LOCATION: + // lwm2m_data_encode_string(LWM2M_TEMPERATURE_LOCATION, dataP); + // return COAP_205_CONTENT ; + default: + return COAP_404_NOT_FOUND ; + } +} + +static uint8_t prv_temperature_read(uint16_t instanceId, int * numDataP, lwm2m_data_t ** dataArrayP, lwm2m_object_t * objectP) { + uint8_t result; + int i; + + // this is a single instance object + if (instanceId != 0) { + return COAP_404_NOT_FOUND ; + } + + // is the server asking for the full object ? + if (*numDataP == 0) { + + uint16_t resList[] = { RES_SENSOR_VALUE, RES_SENSOR_UNITS, }; + + int nbRes = sizeof(resList) / sizeof(uint16_t); + + *dataArrayP = lwm2m_data_new(nbRes); + if (*dataArrayP == NULL) + return COAP_500_INTERNAL_SERVER_ERROR ; + + *numDataP = nbRes; + for (i = 0; i < nbRes; i++) { + (*dataArrayP)[i].id = resList[i]; + } + } + + i = 0; + do { + result = prv_set_value((*dataArrayP) + i); + i++; + } while (i < *numDataP && result == COAP_205_CONTENT ); + + return result; +} + + +lwm2m_object_t * get_object_temperature() { + /* + * The get_object_tem function create the object itself and return a pointer to the structure that represent it. + */ + lwm2m_object_t * temperatureObj = (lwm2m_object_t *) lwm2m_malloc(sizeof(lwm2m_object_t)); + + if (NULL != temperatureObj) { + memset(temperatureObj, 0, sizeof(lwm2m_object_t)); + + /* + * It assigns his unique ID + * The 3313 is the standard ID for the mandatory object "IPSO Accelerometer". + */ + temperatureObj->objID = LWM2M_TEMPERATURE_OBJECT_ID; + + /* + * there is only one instance of accelerometer on the Application Board for mbed NXP LPC1768. + * + */ + temperatureObj->instanceList = (lwm2m_list_t *) lwm2m_malloc(sizeof(lwm2m_list_t)); + if (NULL != temperatureObj->instanceList) { + memset(temperatureObj->instanceList, 0, sizeof(lwm2m_list_t)); + } else { + lwm2m_free(temperatureObj); + return NULL; + } + + /* + * And the private function that will access the object. + * Those function will be called when a read/write/execute query is made by the server. In fact the library don't need to + * know the resources of the object, only the server does. + */ + temperatureObj->readFunc = prv_temperature_read; + temperatureObj->writeFunc = NULL; + temperatureObj->executeFunc = NULL; + temperatureObj->userData = NULL; + + + } + + return temperatureObj; +}
--- a/share/test_object.c Sun May 07 03:00:16 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,390 +0,0 @@ -/******************************************************************************* - * - * Copyright (c) 2013, 2014 Intel Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * The Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * David Navarro, Intel Corporation - initial API and implementation - * domedambrosio - Please refer to git log - * Fabien Fleutot - Please refer to git log - * Axel Lorente - Please refer to git log - * Achim Kraus, Bosch Software Innovations GmbH - Please refer to git log - * Pascal Rieux - Please refer to git log - * - *******************************************************************************/ - -/* - Copyright (c) 2013, 2014 Intel Corporation - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Intel Corporation nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - THE POSSIBILITY OF SUCH DAMAGE. - - David Navarro <david.navarro@intel.com> - -*/ - -/* - * Implements an object for testing purpose - * - * Multiple - * Object | ID | Instances | Mandatoty | - * Test | 1024 | Yes | No | - * - * Ressources: - * Supported Multiple - * Name | ID | Operations | Instances | Mandatory | Type | Range | Units | Description | - * test | 1 | R/W | No | Yes | Integer | 0-255 | | | - * exec | 2 | E | No | Yes | | | | | - * dec | 3 | R/W | No | Yes | Float | | | | - * sig | 4 | R/W | No | Yes | Integer | | | 16-bit signed integer | - * - */ - -#include "liblwm2m.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> - -static void prv_output_buffer(uint8_t * buffer, - int length) -{ - int i; - uint8_t array[16]; - - i = 0; - while (i < length) - { - int j; - fprintf(stderr, " "); - - memcpy(array, buffer+i, 16); - - for (j = 0 ; j < 16 && i+j < length; j++) - { - fprintf(stderr, "%02X ", array[j]); - } - while (j < 16) - { - fprintf(stderr, " "); - j++; - } - fprintf(stderr, " "); - for (j = 0 ; j < 16 && i+j < length; j++) - { - if (isprint(array[j])) - fprintf(stderr, "%c ", array[j]); - else - fprintf(stderr, ". "); - } - fprintf(stderr, "\n"); - - i += 16; - } -} - -/* - * Multiple instance objects can use userdata to store data that will be shared between the different instances. - * The lwm2m_object_t object structure - which represent every object of the liblwm2m as seen in the single instance - * object - contain a chained list called instanceList with the object specific structure prv_instance_t: - */ -typedef struct _prv_instance_ -{ - /* - * The first two are mandatories and represent the pointer to the next instance and the ID of this one. The rest - * is the instance scope user data (uint8_t test in this case) - */ - struct _prv_instance_ * next; // matches lwm2m_list_t::next - uint16_t shortID; // matches lwm2m_list_t::id - uint8_t test; - double dec; - int16_t sig; -} prv_instance_t; - -static uint8_t prv_read(uint16_t instanceId, - int * numDataP, - lwm2m_data_t ** dataArrayP, - lwm2m_object_t * objectP) -{ - prv_instance_t * targetP; - int i; - - targetP = (prv_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId); - if (NULL == targetP) return COAP_404_NOT_FOUND; - - if (*numDataP == 0) - { - *dataArrayP = lwm2m_data_new(3); - if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; - *numDataP = 3; - (*dataArrayP)[0].id = 1; - (*dataArrayP)[1].id = 3; - (*dataArrayP)[2].id = 4; - } - - for (i = 0 ; i < *numDataP ; i++) - { - switch ((*dataArrayP)[i].id) - { - case 1: - lwm2m_data_encode_int(targetP->test, *dataArrayP + i); - break; - case 2: - return COAP_405_METHOD_NOT_ALLOWED; - case 3: - lwm2m_data_encode_float(targetP->dec, *dataArrayP + i); - break; - case 4: - lwm2m_data_encode_int(targetP->sig, *dataArrayP + i); - break; - default: - return COAP_404_NOT_FOUND; - } - } - - return COAP_205_CONTENT; -} - -static uint8_t prv_discover(uint16_t instanceId, - int * numDataP, - lwm2m_data_t ** dataArrayP, - lwm2m_object_t * objectP) -{ - int i; - - // is the server asking for the full object ? - if (*numDataP == 0) - { - *dataArrayP = lwm2m_data_new(4); - if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; - *numDataP = 4; - (*dataArrayP)[0].id = 1; - (*dataArrayP)[1].id = 2; - (*dataArrayP)[2].id = 3; - (*dataArrayP)[3].id = 4; - } - else - { - for (i = 0; i < *numDataP; i++) - { - switch ((*dataArrayP)[i].id) - { - case 1: - case 2: - case 3: - case 4: - break; - default: - return COAP_404_NOT_FOUND; - } - } - } - return COAP_205_CONTENT; -} - -static uint8_t prv_write(uint16_t instanceId, - int numData, - lwm2m_data_t * dataArray, - lwm2m_object_t * objectP) -{ - prv_instance_t * targetP; - int i; - - targetP = (prv_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId); - if (NULL == targetP) return COAP_404_NOT_FOUND; - - for (i = 0 ; i < numData ; i++) - { - switch (dataArray[i].id) - { - case 1: - { - int64_t value; - - if (1 != lwm2m_data_decode_int(dataArray + i, &value) || value < 0 || value > 0xFF) - { - return COAP_400_BAD_REQUEST; - } - targetP->test = (uint8_t)value; - } - break; - case 2: - return COAP_405_METHOD_NOT_ALLOWED; - case 3: - if (1 != lwm2m_data_decode_float(dataArray + i, &(targetP->dec))) - { - return COAP_400_BAD_REQUEST; - } - break; - case 4: - { - int64_t value; - - if (1 != lwm2m_data_decode_int(dataArray + i, &value) || value < INT16_MIN || value > INT16_MAX) - { - return COAP_400_BAD_REQUEST; - } - targetP->sig = (int16_t)value; - } - break; - default: - return COAP_404_NOT_FOUND; - } - } - - return COAP_204_CHANGED; -} - -static uint8_t prv_delete(uint16_t id, - lwm2m_object_t * objectP) -{ - prv_instance_t * targetP; - - objectP->instanceList = lwm2m_list_remove(objectP->instanceList, id, (lwm2m_list_t **)&targetP); - if (NULL == targetP) return COAP_404_NOT_FOUND; - - lwm2m_free(targetP); - - return COAP_202_DELETED; -} - -static uint8_t prv_create(uint16_t instanceId, - int numData, - lwm2m_data_t * dataArray, - lwm2m_object_t * objectP) -{ - prv_instance_t * targetP; - uint8_t result; - - - targetP = (prv_instance_t *)lwm2m_malloc(sizeof(prv_instance_t)); - if (NULL == targetP) return COAP_500_INTERNAL_SERVER_ERROR; - memset(targetP, 0, sizeof(prv_instance_t)); - - targetP->shortID = instanceId; - objectP->instanceList = LWM2M_LIST_ADD(objectP->instanceList, targetP); - - result = prv_write(instanceId, numData, dataArray, objectP); - - if (result != COAP_204_CHANGED) - { - (void)prv_delete(instanceId, objectP); - } - else - { - result = COAP_201_CREATED; - } - - return result; -} - -static uint8_t prv_exec(uint16_t instanceId, - uint16_t resourceId, - uint8_t * buffer, - int length, - lwm2m_object_t * objectP) -{ - - if (NULL == lwm2m_list_find(objectP->instanceList, instanceId)) return COAP_404_NOT_FOUND; - - switch (resourceId) - { - case 1: - return COAP_405_METHOD_NOT_ALLOWED; - case 2: - fprintf(stdout, "\r\n-----------------\r\n" - "Execute on %hu/%d/%d\r\n" - " Parameter (%d bytes):\r\n", - objectP->objID, instanceId, resourceId, length); - prv_output_buffer((uint8_t*)buffer, length); - fprintf(stdout, "-----------------\r\n\r\n"); - return COAP_204_CHANGED; - case 3: - return COAP_405_METHOD_NOT_ALLOWED; - default: - return COAP_404_NOT_FOUND; - } -} - -lwm2m_object_t * get_test_object(void) -{ - lwm2m_object_t * testObj; - - testObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t)); - - if (NULL != testObj) - { - int i; - prv_instance_t * targetP; - - memset(testObj, 0, sizeof(lwm2m_object_t)); - - testObj->objID = 1024; - for (i=0 ; i < 3 ; i++) - { - targetP = (prv_instance_t *)lwm2m_malloc(sizeof(prv_instance_t)); - if (NULL == targetP) return NULL; - memset(targetP, 0, sizeof(prv_instance_t)); - targetP->shortID = 10 + i; - targetP->test = 20 + i; - targetP->dec = -30 + i + (double)i/100.0; - targetP->sig = 0 - i; - testObj->instanceList = LWM2M_LIST_ADD(testObj->instanceList, targetP); - } - /* - * From a single instance object, two more functions are available. - * - The first one (createFunc) create a new instance and filled it with the provided informations. If an ID is - * provided a check is done for verifying his disponibility, or a new one is generated. - * - The other one (deleteFunc) delete an instance by removing it from the instance list (and freeing the memory - * allocated to it) - */ - testObj->readFunc = prv_read; - testObj->writeFunc = prv_write; - testObj->executeFunc = prv_exec; - testObj->createFunc = prv_create; - testObj->deleteFunc = prv_delete; - testObj->discoverFunc = prv_discover; - } - - return testObj; -} - -void free_test_object(lwm2m_object_t * object) -{ - LWM2M_LIST_FREE(object->instanceList); - if (object->userData != NULL) - { - lwm2m_free(object->userData); - object->userData = NULL; - } - lwm2m_free(object); -}
--- a/wakaama/er-coap-13/er-coap-13.c Sun May 07 03:00:16 2017 +0000 +++ b/wakaama/er-coap-13/er-coap-13.c Thu May 11 12:40:25 2017 +0000 @@ -48,7 +48,7 @@ #include "liblwm2m.h" /* for lwm2m_malloc() and lwm2m_free() */ -#define DEBUG 1 +#define DEBUG 0 #if DEBUG #include <stdio.h> #define PRINTF(...) printf(__VA_ARGS__)
--- a/wakaama/liblwm2m.h Sun May 07 03:00:16 2017 +0000 +++ b/wakaama/liblwm2m.h Thu May 11 12:40:25 2017 +0000 @@ -79,6 +79,8 @@ #define LWM2M_WITH_LOGS #define SHARED_DEFINITIONS #define WAKAAMA_DEFINITIONS + +//#define ENABLE_RGB_LED, WIP #endif #ifndef LWM2M_EMBEDDED_MODE @@ -297,6 +299,8 @@ #define LWM2M_LIST_FIND(H,I) lwm2m_list_find((lwm2m_list_t *)H, I) #define LWM2M_LIST_FREE(H) lwm2m_list_free((lwm2m_list_t *)H) + + /* * URI * @@ -349,7 +353,6 @@ LWM2M_TYPE_OBJECT, LWM2M_TYPE_OBJECT_INSTANCE, LWM2M_TYPE_MULTIPLE_RESOURCE, - LWM2M_TYPE_STRING, LWM2M_TYPE_OPAQUE, LWM2M_TYPE_INTEGER, @@ -765,6 +768,68 @@ #ifdef MBED_OS_EXAMPLE_WAKAAMA int lwm2m_add_server(lwm2m_context_t * contextP, uint16_t shortID, uint32_t lifetime, char * sms, lwm2m_binding_t binding, void * sessionH, lwm2m_security_t * securityP); + +#if 0 + +/* + * TLV + */ + +#define LWM2M_TLV_HEADER_MAX_LENGTH 6 + +/* + * Bitmask for the lwm2m_tlv_t::flag + * LWM2M_TLV_FLAG_STATIC_DATA specifies that lwm2m_tlv_t::value + * points to static memory and must no be freeed by the caller. + * LWM2M_TLV_FLAG_TEXT_FORMAT specifies that lwm2m_tlv_t::value + * is expressed or requested in plain text format. + */ +#define LWM2M_TLV_FLAG_STATIC_DATA 0x01 +#define LWM2M_TLV_FLAG_TEXT_FORMAT 0x02 + +#ifdef LWM2M_BOOTSTRAP +#define LWM2M_TLV_FLAG_BOOTSTRAPPING 0x04 +#endif + +/* + * Bits 7 and 6 of assigned values for LWM2M_TYPE_RESOURCE, + * LWM2M_TYPE_MULTIPLE_RESOURCE, LWM2M_TYPE_RESOURCE_INSTANCE + * and LWM2M_TYPE_OBJECT_INSTANCE must match the ones defined + * in the TLV format from LWM2M TS §6.3.3 + * + */ + /* +typedef enum +{ + LWM2M_TYPE_RESOURCE = 0xC0, + LWM2M_TYPE_MULTIPLE_RESOURCE = 0x80, + LWM2M_TYPE_RESOURCE_INSTANCE = 0x40, + LWM2M_TYPE_OBJECT_INSTANCE = 0x00 +} lwm2m_tlv_type_t; +*/ +typedef struct +{ + uint8_t flags; + lwm2m_tlv_type_t type; + lwm2m_data_type_t dataType; + uint16_t id; + size_t length; + uint8_t * value; +} lwm2m_tlv_t; + +lwm2m_tlv_t * lwm2m_tlv_new(int size); +int lwm2m_tlv_parse(uint8_t * buffer, size_t bufferLen, lwm2m_tlv_t ** dataP); +int lwm2m_tlv_serialize(int size, lwm2m_tlv_t * tlvP, uint8_t ** bufferP); +void lwm2m_tlv_free(int size, lwm2m_tlv_t * tlvP); + +void lwm2m_tlv_encode_int(int64_t data, lwm2m_tlv_t * tlvP); +int lwm2m_tlv_decode_int(lwm2m_tlv_t * tlvP, int64_t * dataP); +void lwm2m_tlv_encode_float(double data, lwm2m_tlv_t * tlvP); +int lwm2m_tlv_decode_float(lwm2m_tlv_t * tlvP, double * dataP); +void lwm2m_tlv_encode_bool(bool data, lwm2m_tlv_t * tlvP); +int lwm2m_tlv_decode_bool(lwm2m_tlv_t * tlvP, bool * dataP); +void lwm2m_tlv_include(lwm2m_tlv_t * subTlvP, size_t count, lwm2m_tlv_t * tlvP); +#endif #endif // initialize a liblwm2m context.
--- a/wakaama/list.c Sun May 07 03:00:16 2017 +0000 +++ b/wakaama/list.c Thu May 11 12:40:25 2017 +0000 @@ -46,15 +46,11 @@ lwm2m_list_t * lwm2m_list_find(lwm2m_list_t * head, uint16_t id) -{ - printf(" ## %d, %d\n",id, head->id); - +{ while (NULL != head && head->id < id) { - printf(" ##-- %d, %d\n",id, head->id); head = head->next; } - printf(" ## %d, %d\n",id, head->id); if (NULL != head && head->id == id) return head;
--- a/wakaama/management.c Sun May 07 03:00:16 2017 +0000 +++ b/wakaama/management.c Thu May 11 12:40:25 2017 +0000 @@ -211,7 +211,6 @@ { lwm2m_data_t * dataP = NULL; int size = 0; - printf("dm_handleRequest: %d\n",__LINE__); result = object_readData(contextP, uriP, &size, &dataP); if (COAP_205_CONTENT == result) @@ -237,7 +236,6 @@ && message->accept_num == 1 && message->accept[0] == APPLICATION_LINK_FORMAT) { - printf("dm_handleRequest: %d\n",__LINE__); format = LWM2M_CONTENT_LINK; result = object_discover(contextP, uriP, serverP, &buffer, &length); } @@ -247,8 +245,7 @@ { format = utils_convertMediaType(message->accept[0]); } - printf("dm_handleRequest: %d\n",__LINE__); - + result = object_read(contextP, uriP, &format, &buffer, &length); } if (COAP_205_CONTENT == result)
--- a/wakaama/packet.c Sun May 07 03:00:16 2017 +0000 +++ b/wakaama/packet.c Thu May 11 12:40:25 2017 +0000 @@ -118,9 +118,7 @@ #else uriP = uri_decode(NULL, message->uri_path); #endif - printf("TERENCE:%s:%d\n",__FUNCTION__,__LINE__); if (uriP == NULL) return COAP_400_BAD_REQUEST; - printf("TERENCE:%s:%d uriP->flag = %d\n",__FUNCTION__,__LINE__, uriP->flag); switch(uriP->flag & LWM2M_URI_MASK_TYPE) { #ifdef LWM2M_CLIENT_MODE @@ -128,18 +126,15 @@ { lwm2m_server_t * serverP; - printf("TERENCE:%s:%d\n",__FUNCTION__,__LINE__); - + serverP = utils_findServer(contextP, fromSessionH); if (serverP != NULL) { - printf("TERENCE:%s:%d\n",__FUNCTION__,__LINE__); result = dm_handleRequest(contextP, uriP, serverP, message, response); } #ifdef LWM2M_BOOTSTRAP else { - printf("TERENCE:%s:%d\n",__FUNCTION__,__LINE__); serverP = utils_findBootstrapServer(contextP, fromSessionH); if (serverP != NULL) {