From: Jin-Seong Kim Date: Wed, 21 Jun 2017 02:20:22 +0000 (+0900) Subject: external/wakaama : Revert client example to 1.0_Public_M1 version X-Git-Tag: 1.1_Public_Release~453^2~19 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bf632a63ba3fef9e1c94d38993a08c0d91990f38;p=rtos%2Ftinyara.git external/wakaama : Revert client example to 1.0_Public_M1 version This commit is revert commit for wakaama client example - SW R&D Center(DS) has been seperated client example from DM framework wakaama client example will be only used by DM framework So, we'll revert our patches on client example to prevent maintaining issue on it Change-Id: I6d75c729b4d694025af067a0cb84d1b9ba132805 Signed-off-by: Jin-Seong Kim Signed-off-by: EunBong Song --- diff --git a/external/wakaama/examples/client/CMakeLists.txt b/external/wakaama/examples/client/CMakeLists.txt index 4a043b3..a9c7f98 100644 --- a/external/wakaama/examples/client/CMakeLists.txt +++ b/external/wakaama/examples/client/CMakeLists.txt @@ -13,18 +13,18 @@ add_definitions(${SHARED_DEFINITIONS} ${WAKAAMA_DEFINITIONS}) include_directories (${WAKAAMA_SOURCES_DIR} ${SHARED_INCLUDE_DIRS}) SET(SOURCES - ${CMAKE_CURRENT_LIST_DIR}/lwm2mclient.c - ${CMAKE_CURRENT_LIST_DIR}/lwm2mclient.h - ${CMAKE_CURRENT_LIST_DIR}/system_api.c - ${CMAKE_CURRENT_LIST_DIR}/object_security.c - ${CMAKE_CURRENT_LIST_DIR}/object_server.c - ${CMAKE_CURRENT_LIST_DIR}/object_device.c - ${CMAKE_CURRENT_LIST_DIR}/object_firmware.c - ${CMAKE_CURRENT_LIST_DIR}/object_location.c - ${CMAKE_CURRENT_LIST_DIR}/object_connectivity_moni.c - ${CMAKE_CURRENT_LIST_DIR}/object_connectivity_stat.c - ${CMAKE_CURRENT_LIST_DIR}/object_access_control.c - ${CMAKE_CURRENT_LIST_DIR}/test_object.c + lwm2mclient.c + lwm2mclient.h + system_api.c + object_security.c + object_server.c + object_device.c + object_firmware.c + object_location.c + object_connectivity_moni.c + object_connectivity_stat.c + object_access_control.c + test_object.c ) add_executable(${PROJECT_NAME} ${SOURCES} ${WAKAAMA_SOURCES} ${SHARED_SOURCES}) diff --git a/external/wakaama/examples/client/Make.defs b/external/wakaama/examples/client/Make.defs index 1a1ab4b..56f8d47 100644 --- a/external/wakaama/examples/client/Make.defs +++ b/external/wakaama/examples/client/Make.defs @@ -35,25 +35,13 @@ ifeq ($(CONFIG_DM),y) -CSRCS += lwm2mclient.c -CSRCS += object_access_control.c -CSRCS += object_connectivity_moni.c object_connectivity_stat.c -CSRCS += object_device.c -CSRCS += object_firmware.c -CSRCS += object_location.c -CSRCS += object_security.c -CSRCS += object_server.c -CSRCS += system_api.c -CSRCS += test_object.c +# Routing table support -# Interface API functions for dm frameworks -CSRCS += connectivity_interface.c +CSRCS += object_access_control.c object_connectivity_moni.c object_connectivity_stat.c object_device.c object_firmware.c object_location.c object_security.c object_server.c system_api.c test_object.c lwm2mclient.c common_monitor_interface.c connectivity_interface.c power_monitor_interface.c object_power_moni.c CFLAGS+=-I$(TOPDIR)/../external/wakaama/core CFLAGS+=-I$(TOPDIR)/../external/wakaama/examples/shared -CFLAGS+=-D__TINYARA__ - DEPPATH += --dep-path wakaama/examples/client VPATH += :wakaama/examples/client diff --git a/external/wakaama/examples/client/common_monitor_interface.c b/external/wakaama/examples/client/common_monitor_interface.c new file mode 100644 index 0000000..87e08d4 --- /dev/null +++ b/external/wakaama/examples/client/common_monitor_interface.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include +#include +#include +#include +#include "common_monitor_interface.h" + + +int readonce(FAR const char *filename, FAR char *buffer, uint8_t buflen) +{ + int ret; + + printf("opening %s\n", filename); + int fd = open(filename, O_RDONLY); + + memset(buffer, 0x00, buflen); + if (fd < 0) + { + printf("error reading file %s\n", filename); + return ERROR; + } + else + { + size_t nbytes; + + + /* Read until we hit the end of the file, until we have exhausted the + * buffer space, or until some irrecoverable error occurs + */ + + *buffer = '\0'; /* NUL terminate the empty buffer */ + ret = ERROR; /* Assume failure */ + + nbytes = read(fd, buffer, buflen); + printf("%d bytes read\n", nbytes); + if (nbytes < 0) + { + /* Read error */ + + int errcode = errno; + DEBUGASSERT(errcode > 0); + + /* EINTR is not a read error. It simply means that a signal was + * received while waiting for the read to complete. + */ + + if (errcode != EINTR) + { + /* Fatal error */ + + printf("EINTR error\n"); + } + } + else if (nbytes >= 0) + { + *(buffer+nbytes) = '\0'; + ret = OK; + } + + } + + /* Close the file and return. */ + + close(fd); + return ret; +} + +int readfile(FAR const char *filename, FAR char *buffer, uint8_t buflen) +{ + FAR char *bufptr; + size_t remaining; + ssize_t nread; + ssize_t ntotal; + int ret; + + printf("opening %s\n", filename); + int fd = open(filename, O_RDONLY); + + if (fd < 0) + { + printf("error reading file %s\n", filename); + return ERROR; + } + else + { + size_t nbytes; + + + /* Read until we hit the end of the file, until we have exhausted the + * buffer space, or until some irrecoverable error occurs + */ + + ntotal = 0; /* No bytes read yet */ + *buffer = '\0'; /* NUL terminate the empty buffer */ + bufptr = buffer; /* Working pointer */ + remaining = buflen - 1; /* Reserve one byte for a NUL terminator */ + ret = ERROR; /* Assume failure */ + + do { + nbytes = read(fd, buffer, buflen); + printf("%d bytes read\n", nbytes); + if (nbytes < 0) + { + /* Read error */ + + int errcode = errno; + DEBUGASSERT(errcode > 0); + + /* EINTR is not a read error. It simply means that a signal was + * received while waiting for the read to complete. + */ + + if (errcode != EINTR) + { + /* Fatal error */ + + printf("EINTR error\n"); + break; + } + } + else if (nbytes == 0) + { + /* End of file */ + + ret = OK; + break; + } + else + { + /* Successful read. Make sure that the buffer is null terminated */ + + DEBUGASSERT(nbytes <= remaining); + ntotal += nbytes; + buffer[ntotal] = '\0'; + + /* Bump up the read count and continuing reading to the end of + * file. + */ + + bufptr += nbytes; + remaining -= nbytes; + } + } while (buflen > 0); + } + + /* Close the file and return. */ + + close(fd); + return ret; +} + +void mount_procfs(void) +{ + int ret; + ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL); +} + diff --git a/external/wakaama/examples/client/common_monitor_interface.h b/external/wakaama/examples/client/common_monitor_interface.h new file mode 100644 index 0000000..5f58601 --- /dev/null +++ b/external/wakaama/examples/client/common_monitor_interface.h @@ -0,0 +1,11 @@ +#ifndef _COMMON_MONITOR_INTERFACE_H +#define _COMMON_MONITOR_INTERFACE_H +#include +#define PROC_BUFFER_LEN 128 +#define PROC_MOUNTPOINT "/proc" + +int readonce(FAR const char *filename, FAR char *buffer, uint8_t buflen); +int readfile(FAR const char *filename, FAR char *buffer, uint8_t buflen); +void mount_procfs(void); +#endif + diff --git a/external/wakaama/examples/client/connectivity_interface.c b/external/wakaama/examples/client/connectivity_interface.c index aec0c6f..33b6aa3 100644 --- a/external/wakaama/examples/client/connectivity_interface.c +++ b/external/wakaama/examples/client/connectivity_interface.c @@ -1,8 +1,15 @@ +#include +#include +#include +#include +#include +#include +#include -#include -#include -#include +#include +#include +#include #include "connectivity_interface.h" @@ -10,6 +17,12 @@ #include #endif +#include "common_monitor_interface.h" + + +uint8_t cm_iobuffer[PROC_BUFFER_LEN]; + + /*Read APIs*/ @@ -18,20 +31,22 @@ * * Description: * Get the underlined interface name - * + * * * Returned Value: * ****************************************************************************/ - + void get_interface_name(char *mac) { #if defined(CONFIG_WICED) - strcpy(mac, "en1"); + strcpy(mac,"en1"); #elif defined(CONFIG_NET_ETHERNET) - strcpy(mac, "eth0"); + strcpy(mac,"eth0"); #elif defined(CONFIG_NET_802154) - strcpy(mac, "wlan0"); + strcpy(mac,"wlan0"); +#elif defined(CONFIG_ARCH_BOARD_SIDK_S5JT200) + strcpy(mac, "wl1"); #endif } @@ -43,26 +58,23 @@ void get_interface_name(char *mac) * Fetch IPv4/IPv6 address * * Returned Value: - * + * * ****************************************************************************/ - + void get_ip_address(char *ipAddr) { - printf("Calling inet_ntop\n"); - char mac[4]; - get_interface_name(mac); -#ifdef CONFIG_NET_IPv4 - struct in_addr addr; - netlib_get_ipv4addr(mac, &addr); - inet_ntop(AF_INET, &addr, ipAddr, INET_ADDRSTRLEN); -#endif -#ifdef CONFIG_NET_IPv6 - struct in6_addr addr; - netlib_get_ipv6addr(mac, &addr); - inet_ntop(AF_INET6, &addr, ipAddr, INET6_ADDRSTRLEN); -#endif - printf("After inet_ntop\n"); + int ret; + uint8_t *filepath; + ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL); + printf("mount returns value %d\n", ret); + ret = asprintf(&filepath, "%s/connectivity/ipaddr", PROC_MOUNTPOINT); + ret = readonce(filepath, cm_iobuffer, PROC_BUFFER_LEN); + strncpy(ipAddr, cm_iobuffer, strlen(cm_iobuffer)); + if (ret == OK) + { + printf("IP addr is %s\n", ipAddr); + } } /**************************************************************************** @@ -72,43 +84,51 @@ void get_ip_address(char *ipAddr) * Get the router IPv4/IPv6 address * * Returned Value: - * + * * ****************************************************************************/ - + void get_router_ip_address(char *routerIPAddr) { - char mac[4]; - get_interface_name(mac); -#ifdef CONFIG_NET_IPv4 - struct in_addr addr; - netlib_get_dripv4addr(mac, addr); - inet_ntop(AF_INET, &addr, routerIPAddr, INET_ADDRSTRLEN); + char mac[4]; + get_interface_name(mac); +#ifdef CONFIG_NET_IPv4 + struct in_addr addr; + netlib_get_dripv4addr(mac,addr); + inet_ntop(AF_INET, &addr, routerIPAddr, INET_ADDRSTRLEN); #endif #ifdef CONFIG_NET_IPv6 - struct in6_addr addr; - netlib_get_dripv6addr(mac, addr); - inet_ntop(AF_INET6, &addr, routerIPAddr, INET6_ADDRSTRLEN); -#endif + struct in6_addr addr; + netlib_get_dripv6addr(mac,addr); + inet_ntop(AF_INET6, &addr, routerIPAddr, INET6_ADDRSTRLEN); +#endif } /**************************************************************************** * Name: get_signal_strength * * Description: - * Get Signal Strength value (RSSI in case of IEEE 802.15.4) + * Get Signal Strength value (RSSI in case of IEEE 802.15.4) * * Returned Value: * Return the appropriate Callback flags * ****************************************************************************/ - -uint8_t get_signal_strength(void) + +void get_signal_strength(int *rssi_value) { -#if defined(CONFIG_NET_802154) - return get_rssi(); -#endif - return -1; + int ret; + uint8_t *filepath; + ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL); + printf("mount returns value %d\n", ret); + ret = asprintf(&filepath, "%s/connectivity/rssi", PROC_MOUNTPOINT); + ret = readonce(filepath, cm_iobuffer, PROC_BUFFER_LEN); + if (ret == OK) + { +// *rssi_value = atoi(cm_iobuffer); + sscanf(cm_iobuffer, "%d", rssi_value); + printf("rssi is %d\n", *rssi_value); + } } /**************************************************************************** @@ -118,16 +138,16 @@ uint8_t get_signal_strength(void) * Get link quality index value from MAC/PHY * * Returned Value: - * + * * ****************************************************************************/ -int get_lqi(void) +int get_lqi() { #if defined(CONFIG_NET_802154) - return get_lqi_val(); + return get_lqi_val(); #endif - return -1; + return -1; } /**************************************************************************** @@ -137,11 +157,11 @@ int get_lqi(void) * Get link utilization statictics from MAC/PHY * * Returned Value: - * + * * ****************************************************************************/ - -int get_link_utilization(void) + +int get_link_utilization() { return 0; } @@ -154,14 +174,13 @@ int get_link_utilization(void) * Get tx data value from MAC/PHY * * Returned Value: - * + * * ****************************************************************************/ - + int get_tx_data() { //TODO: Feature implementation - return 0; } /**************************************************************************** @@ -171,14 +190,13 @@ int get_tx_data() * Get rx data value from MAC/PHY * * Returned Value: - * + * * ****************************************************************************/ - + int get_rx_data() { ///TODO: Feature implementation - return 0; } /**************************************************************************** @@ -188,11 +206,83 @@ int get_rx_data() * Get maximum message size * * Returned Value: - * + * * ****************************************************************************/ -int get_max_message_size() + int get_max_message_size() { ///TODO: Feature implementation - return 0; } + + +/**************************************************************************** + * Name: get_bitrate + * + * Description: + * Get bitrate + * + * Returned Value: + * + * + ****************************************************************************/ + void get_bitrate(int *bitrate) + { + int ret; + uint8_t *filepath; + ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL); + printf("mount returns value %d\n", ret); + ret = asprintf(&filepath, "%s/connectivity/bitrate", PROC_MOUNTPOINT); + ret = readonce(filepath, cm_iobuffer, PROC_BUFFER_LEN); + if (ret == OK) + { + *bitrate = atoi(cm_iobuffer); + } + } + +/**************************************************************************** + * Name: get_network_bearer + * + * Description: + * Get Network Bearer + * + * Returned Value: + * + * + ****************************************************************************/ +void get_network_bearer(int *nwbearer) +{ + int ret; + uint8_t *filepath; + ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL); + printf("mount returns value %d\n", ret); + ret = asprintf(&filepath, "%s/connectivity/nwbearer", PROC_MOUNTPOINT); + ret = readonce(filepath, cm_iobuffer, PROC_BUFFER_LEN); + if (ret == OK) + sscanf(cm_iobuffer, "%d", nwbearer); +} + +/**************************************************************************** + * Name: get_avl_network_bearer + * + * Description: + * Get Available Network Bearer + * + * Returned Value: + * + * + ****************************************************************************/ +void get_avl_network_bearer(int *nwbearer) +{ + int ret; + uint8_t *filepath; + ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL); + printf("mount returns value %d\n", ret); + ret = asprintf(&filepath, "%s/connectivity/available_bearer", PROC_MOUNTPOINT); + ret = readonce(filepath, cm_iobuffer, PROC_BUFFER_LEN); + if (ret == OK) + sscanf(cm_iobuffer, "%d", nwbearer); +} + + + + diff --git a/external/wakaama/examples/client/connectivity_interface.h b/external/wakaama/examples/client/connectivity_interface.h index 5efe0e8..4556bdf 100644 --- a/external/wakaama/examples/client/connectivity_interface.h +++ b/external/wakaama/examples/client/connectivity_interface.h @@ -1,4 +1,6 @@ + + /*Util Functions*/ /**************************************************************************** @@ -49,7 +51,7 @@ void get_ip_address(char *ipAddr); * Return the appropriate Callback flags * ****************************************************************************/ -uint8_t get_signal_strength(void); +void get_signal_strength(int *rssi_value); /**************************************************************************** * Name: get_link_utilization @@ -85,6 +87,7 @@ int get_lqi(void); * * ****************************************************************************/ + int get_tx_data(void); /**************************************************************************** @@ -97,6 +100,7 @@ int get_tx_data(void); * * ****************************************************************************/ + int get_rx_data(void); /**************************************************************************** @@ -110,3 +114,41 @@ int get_rx_data(void); * ****************************************************************************/ int get_max_message_size(void); + + +/**************************************************************************** + * Name: get_bitrate + * + * Description: + * Get bitrate + * + * Returned Value: + * + * + ****************************************************************************/ + void get_bitrate(int *bitrate); + + +/**************************************************************************** + * Name: get_network_bearer + * + * Description: + * Get Network Bearer + * + * Returned Value: + * + * + ****************************************************************************/ +void get_network_bearer(int *nwbearer); + +/**************************************************************************** + * Name: get_avl_network_bearer + * + * Description: + * Get Available Network Bearer + * + * Returned Value: + * + * + ****************************************************************************/ +void get_avl_network_bearer(int *nwbearer); diff --git a/external/wakaama/examples/client/lwm2mclient.c b/external/wakaama/examples/client/lwm2mclient.c index af750c1..6cf362e 100644 --- a/external/wakaama/examples/client/lwm2mclient.c +++ b/external/wakaama/examples/client/lwm2mclient.c @@ -55,6 +55,11 @@ Bosch Software Innovations GmbH - Please refer to git log */ +#include +#include +#ifdef CONFIG_NET_LWIP + +//#include "object_connectivity_stat.h" #include "lwm2mclient.h" #include "liblwm2m.h" @@ -75,48 +80,54 @@ #include #include #include -#include #include #include #include +#include +#include +#include -#if defined (__TINYARA__) -#include -#endif +#include +#include + +#include +#include +#include -#define MAX_PACKET_SIZE 1024 -#define DEFAULT_SERVER_IPV6 "[::1]" -#define DEFAULT_SERVER_IPV4 "coap://127.0.0.1" /**************************************************************************** - * TINYARA - * - definition and global variables - * - APIs used for dm frameworks + * Definitions ****************************************************************************/ -#if defined(__TINYARA__) -/* Definitions*/ -#ifndef FD_SETSIZE -#define FD_SETSIZE (CONFIG_NFILE_DESCRIPTORS + CONFIG_NSOCKET_DESCRIPTORS) -#endif - -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 +#if defined(CONFIG_NET_ETHERNET) && CONFIG_NET_ETHERNET == 1 +#if LWIP_HAVE_LOOPIF +#define NET_DEVNAME "en1" +#else +#define NET_DEVNAME "en0" #endif -#ifndef STDERR_FILENO -#define STDERR_FILENO 2 +#elif defined(CONFIG_NET_802154) && CONFIG_NET_802154 == 1 +#define NET_DEVNAME "wpan0" +#else +#error "undefined CONFIG_NET_, check your .config" #endif -#define SET_PARAM_DM_FRAMEWORK -10 +/**************************************************************************** + * Private Data + ****************************************************************************/ -#define DEFAULT_CLIENT_NAME "myawesomeclient" +#define MAX_PACKET_SIZE 1024 +#define DEFAULT_SERVER_IPV6 "[::1]" +#define DEFAULT_SERVER_IPV4 "127.0.0.1" #define IPADDRLEN_MAX 32 #define PORTLEN_MAX 6 +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +#endif + +static int cc = 0; +int g_reboot = 0; +static int g_quit = 0; -/* Global variables */ static char g_serverAddr[IPADDRLEN_MAX]; static char g_serverPort[PORTLEN_MAX]; static char g_bootstrapserverAddr[IPADDRLEN_MAX]; @@ -124,1425 +135,749 @@ static char g_bootstrapserverPort[PORTLEN_MAX]; static uint16_t g_lifetime; bool g_bootstrapRequested; -#endif /* __TINYARA__ */ - -int g_reboot = 0; -static int g_quit = 0; - -static char coap_uri_prefix [COAP_PROTOCOL_MAX][COAP_MAX_URI_PREFIX_SIZE] = { - "coap://", - "coaps://", - "coap+tcp://", - "coaps+tcp://" -}; - -lwm2m_context_t * lwm2mH; - -#define OBJ_COUNT 9 -lwm2m_object_t * objArray[OBJ_COUNT]; +#define OBJ_COUNT 10 +lwm2m_object_t *objArray[OBJ_COUNT]; // only backup security and server objects # define BACKUP_OBJECT_COUNT 2 -lwm2m_object_t * backupObjectArray[BACKUP_OBJECT_COUNT]; +lwm2m_object_t *backupObjectArray[BACKUP_OBJECT_COUNT]; -typedef struct -{ - lwm2m_object_t * securityObjP; - lwm2m_object_t * serverObject; - int sock; +typedef struct { + lwm2m_object_t *securityObjP; + lwm2m_object_t *serverObject; + int sock; #ifdef WITH_TINYDTLS - dtls_connection_t * connList; - lwm2m_context_t * lwm2mH; + dtls_connection_t *connList; + lwm2m_context_t *lwm2mH; #else - connection_t * connList; + connection_t *connList; #endif - int addressFamily; + int addressFamily; } client_data_t; -#if defined (__TINYARA__) -/* Private Functions */ -static void clear_client_globals(void); -static void prv_close_sock(void); -static void prv_update_server(client_data_t *dataP, uint16_t secObjInstID); -static void process_udpconn(int sockfd, fd_set *readfds, client_data_t data); +lwm2m_context_t *lwm2mH; +client_data_t data; -static int read_input_command_line(char *buf); -#endif /*__TINYARA__*/ +static void clear_client_globals(void) +{ + memset(g_bootstrapserverAddr, 0x00, IPADDRLEN_MAX); + memset(g_bootstrapserverPort, 0x00, 6); + if (lwm2mH->state == STATE_REGISTER_REQUIRED || + lwm2mH->state == STATE_REGISTERING || + lwm2mH->state == STATE_READY) { + printf("g_bootstrapRequested = false\n"); + g_bootstrapRequested = false; + } +} -static void prv_quit(char * buffer, - void * user_data) +static void prv_update_server(client_data_t *dataP, + uint16_t secObjInstID) { - g_quit = 1; + char *uri; + char *server_host; + char *server_port; + + uri = get_server_uri(dataP->securityObjP, secObjInstID); + + if (uri == NULL) { + return; + } + + // parse uri in the form "coaps://[server_host]:[port]" + if (0 == strncmp(uri, "coaps://", strlen("coaps://"))) { + server_host = uri + strlen("coaps://"); + } else if (0 == strncmp(uri, "coap://", strlen("coap://"))) { + server_host = uri + strlen("coap://"); + } else { + return; + } + server_port = strrchr(server_host, ':'); + if (server_port == NULL) { + return; + } + // remove brackets + if (server_host[0] == '[') { + server_host++; + if (*(server_port - 1) == ']') { + *(server_port - 1) = 0; + } else { + return; + } + } + // split strings + *server_port = 0; + server_port++; + + client_set_serverAddr(server_host, false); + client_set_serverPort(server_port, false); } -void handle_sigint(int signum) + +static void prv_quit(char *buffer, + void *user_data) { - g_quit = 2; + g_quit = 1; } -void handle_value_changed(lwm2m_context_t * lwm2mP, - lwm2m_uri_t * uri, - const char * value, - size_t valueLength) +void handle_sigint(int signum) { - lwm2m_object_t * object = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mP->objectList, uri->objectId); - - if (NULL != object) - { - if (object->writeFunc != NULL) - { - lwm2m_data_t * dataP; - int result; - - dataP = lwm2m_data_new(1); - if (dataP == NULL) - { - fprintf(stderr, "Internal allocation failure !\n"); - return; - } - dataP->id = uri->resourceId; - lwm2m_data_encode_nstring(value, valueLength, dataP); - - result = object->writeFunc(uri->instanceId, 1, dataP, object); - if (COAP_405_METHOD_NOT_ALLOWED == result) - { - switch (uri->objectId) - { - case LWM2M_DEVICE_OBJECT_ID: - result = device_change(dataP, object); - break; - default: - break; - } - } - - if (COAP_204_CHANGED != result) - { - fprintf(stderr, "Failed to change value!\n"); - } - else - { - fprintf(stderr, "value changed!\n"); - lwm2m_resource_value_changed(lwm2mP, uri); - } - lwm2m_data_free(1, dataP); - return; - } - else - { - fprintf(stderr, "write not supported for specified resource!\n"); - } - return; - } - else - { - fprintf(stderr, "Object not found !\n"); - } + g_quit = 2; } -static coap_protocol_t coap_get_protocol_from_uri(const char *uri) +void handle_value_changed(lwm2m_context_t *lwm2mH, + lwm2m_uri_t *uri, + const char *value, + size_t valueLength) { - coap_protocol_t type; - for (type = COAP_UDP; type < COAP_PROTOCOL_MAX; type++) { - if (!strncmp(uri, coap_uri_prefix[type], strlen(coap_uri_prefix[type]))) { - return type; + lwm2m_object_t *object = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, uri->objectId); + + if (NULL != object) { + if (object->writeFunc != NULL) { + lwm2m_data_t *dataP; + int result; + + dataP = lwm2m_data_new(1); + if (dataP == NULL) { + fprintf(stderr, "Internal allocation failure !\n"); + return; + } + dataP->id = uri->resourceId; + lwm2m_data_encode_nstring(value, valueLength, dataP); + + result = object->writeFunc(uri->instanceId, 1, dataP, object); + if (COAP_405_METHOD_NOT_ALLOWED == result) { + switch (uri->objectId) { + case LWM2M_DEVICE_OBJECT_ID: + result = device_change(dataP, object); + break; + default: + break; + } + } + + if (COAP_204_CHANGED != result) { + fprintf(stderr, "Failed to change value!\n"); + } else { + fprintf(stderr, "value changed!\n"); + lwm2m_resource_value_changed(lwm2mH, uri); + } + lwm2m_data_free(1, dataP); + return; + } else { + fprintf(stderr, "write not supported for specified resource!\n"); + } + return; + } else { + fprintf(stderr, "Object not found !\n"); } - } - return type; } #ifdef WITH_TINYDTLS -void * lwm2m_connect_server(uint16_t secObjInstID, - void * userData) +void *lwm2m_connect_server(uint16_t secObjInstID, + void *userData) { - client_data_t * dataP; - lwm2m_list_t * instance; - dtls_connection_t * newConnP = NULL; - dataP = (client_data_t *)userData; - lwm2m_object_t * securityObj = dataP->securityObjP; - - instance = LWM2M_LIST_FIND(dataP->securityObjP->instanceList, secObjInstID); - if (instance == NULL) return NULL; - - newConnP = connection_create(dataP->connList, dataP->sock, securityObj, instance->id, dataP->lwm2mH, dataP->addressFamily); - if (newConnP == NULL) - { - fprintf(stderr, "Connection creation failed.\n"); - return NULL; - } - - dataP->connList = newConnP; - return (void *)newConnP; + client_data_t *dataP; + lwm2m_list_t *instance; + dtls_connection_t *newConnP = NULL; + dataP = (client_data_t *)userData; + lwm2m_object_t *securityObj = dataP->securityObjP; + + instance = LWM2M_LIST_FIND(dataP->securityObjP->instanceList, secObjInstID); + if (instance == NULL) { + return NULL; + } + + + newConnP = connection_create(dataP->connList, dataP->sock, securityObj, instance->id, dataP->lwm2mH, dataP->addressFamily); + if (newConnP == NULL) { + fprintf(stderr, "Connection creation failed.\n"); + return NULL; + } + + dataP->connList = newConnP; + return (void *)newConnP; } #else -void * lwm2m_connect_server(uint16_t secObjInstID, - void * userData) +void *lwm2m_connect_server(uint16_t secObjInstID, + void *userData) { - client_data_t * dataP; - char * uri; - char * host; - char * port; - connection_t * newConnP = NULL; - coap_protocol_t proto = COAP_UDP; + client_data_t *dataP; + char *uri; + char *host; + char *port; + connection_t *newConnP = NULL; - dataP = (client_data_t *)userData; + dataP = (client_data_t *)userData; - uri = get_server_uri(dataP->securityObjP, secObjInstID); + uri = get_server_uri(dataP->securityObjP, secObjInstID); - if (uri == NULL) return NULL; + if (uri == NULL) { + return NULL; + } - // parse uri in the form "coaps://[host]:[port]" + // parse uri in the form "coaps://[host]:[port]" + if (0 == strncmp(uri, "coaps://", strlen("coaps://"))) { + host = uri + strlen("coaps://"); + } else if (0 == strncmp(uri, "coap://", strlen("coap://"))) { + host = uri + strlen("coap://"); + } else { + goto exit; + } + port = strrchr(host, ':'); + if (port == NULL) { + goto exit; + } + // remove brackets + if (host[0] == '[') { + host++; + if (*(port - 1) == ']') { + *(port - 1) = 0; + } else { + goto exit; + } + } + // split strings + *port = 0; + port++; - proto = coap_get_protocol_from_uri(uri); - if (proto >= COAP_PROTOCOL_MAX) { - fprintf(stderr, "Not supported protocol : %d\n", proto); - goto exit; + fprintf(stderr, "Opening connection to server at %s:%s\r\n", host, port); + newConnP = connection_create(dataP->connList, dataP->sock, host, port, dataP->addressFamily); + if (newConnP == NULL) { + fprintf(stderr, "Connection creation failed.\r\n"); } else { - /* move pointer to address field */ - host = uri + strlen(coap_uri_prefix[proto]); - } - - port = strrchr(host, ':'); - if (port == NULL) goto exit; - // remove brackets - if (host[0] == '[') - { - host++; - if (*(port - 1) == ']') - { - *(port - 1) = 0; - } - else goto exit; - } - // split strings - *port = 0; - port++; - - fprintf(stderr, "Opening connection to server at %s:%s\r\n", host, port); - fprintf(stderr, "Connection protocol type : %d\r\n", proto); - newConnP = connection_create(proto, dataP->connList, dataP->sock, host, port, dataP->addressFamily); - if (newConnP == NULL) { - fprintf(stderr, "Connection creation failed.\r\n"); - } - else { - dataP->connList = newConnP; - } + dataP->connList = newConnP; + } +#ifdef LWM2M_CLIENT_MODE + printf("lwm2mH->state = %d\n", lwm2mH->state); + if (lwm2mH->state == STATE_REGISTERING || + lwm2mH->state == STATE_REGISTER_REQUIRED) { + prv_update_server(dataP, secObjInstID); + } + +#endif exit: - lwm2m_free(uri); - return (void *)newConnP; + lwm2m_free(uri); + return (void *)newConnP; } #endif -void lwm2m_close_connection(void * sessionH, - void * userData) +void lwm2m_close_connection(void *sessionH, + void *userData) { - client_data_t * app_data; + client_data_t *app_data; #ifdef WITH_TINYDTLS - dtls_connection_t * targetP; + dtls_connection_t *targetP; #else - connection_t * targetP; + connection_t *targetP; #endif - app_data = (client_data_t *)userData; + app_data = (client_data_t *)userData; #ifdef WITH_TINYDTLS - targetP = (dtls_connection_t *)sessionH; + targetP = (dtls_connection_t *)sessionH; #else - targetP = (connection_t *)sessionH; + targetP = (connection_t *)sessionH; #endif - if (targetP == app_data->connList) - { - app_data->connList = targetP->next; - lwm2m_free(targetP); - } - else - { + if (targetP == app_data->connList) { + app_data->connList = targetP->next; + lwm2m_free(targetP); + } else { #ifdef WITH_TINYDTLS - dtls_connection_t * parentP; + dtls_connection_t *parentP; #else - connection_t * parentP; + connection_t *parentP; #endif - parentP = app_data->connList; - while (parentP != NULL && parentP->next != targetP) - { - parentP = parentP->next; - } - if (parentP != NULL) - { - parentP->next = targetP->next; - lwm2m_free(targetP); - } - } + parentP = app_data->connList; + while (parentP != NULL && parentP->next != targetP) { + parentP = parentP->next; + } + if (parentP != NULL) { + parentP->next = targetP->next; + lwm2m_free(targetP); + } + } } +#endif -static void prv_output_servers(char * buffer, - void * user_data) +static void prv_output_servers(char *buffer, + void *user_data) { - lwm2mH = (lwm2m_context_t *) user_data; - lwm2m_server_t * targetP; - - targetP = lwm2mH->bootstrapServerList; - - if (lwm2mH->bootstrapServerList == NULL) - { - fprintf(stdout, "No Bootstrap Server.\r\n"); - } - else - { - fprintf(stdout, "Bootstrap Servers:\r\n"); - for (targetP = lwm2mH->bootstrapServerList ; targetP != NULL ; targetP = targetP->next) - { - fprintf(stdout, " - Security Object ID %d", targetP->secObjInstID); - fprintf(stdout, "\tHold Off Time: %lu s", (unsigned long)targetP->lifetime); - fprintf(stdout, "\tstatus: "); - switch(targetP->status) - { - case STATE_DEREGISTERED: - fprintf(stdout, "DEREGISTERED\r\n"); - break; - case STATE_BS_HOLD_OFF: - fprintf(stdout, "CLIENT HOLD OFF\r\n"); - break; - case STATE_BS_INITIATED: - fprintf(stdout, "BOOTSTRAP INITIATED\r\n"); - break; - case STATE_BS_PENDING: - fprintf(stdout, "BOOTSTRAP PENDING\r\n"); - break; - case STATE_BS_FINISHED: - fprintf(stdout, "BOOTSTRAP FINISHED\r\n"); - break; - case STATE_BS_FAILED: - fprintf(stdout, "BOOTSTRAP FAILED\r\n"); - break; - default: - fprintf(stdout, "INVALID (%d)\r\n", (int)targetP->status); - } - } - } - - if (lwm2mH->serverList == NULL) - { - fprintf(stdout, "No LWM2M Server.\r\n"); - } - else - { - fprintf(stdout, "LWM2M Servers:\r\n"); - for (targetP = lwm2mH->serverList ; targetP != NULL ; targetP = targetP->next) - { - fprintf(stdout, " - Server ID %d", targetP->shortID); - fprintf(stdout, "\tstatus: "); - switch(targetP->status) - { - case STATE_DEREGISTERED: - fprintf(stdout, "DEREGISTERED\r\n"); - break; - case STATE_REG_PENDING: - fprintf(stdout, "REGISTRATION PENDING\r\n"); - break; - case STATE_REGISTERED: - fprintf(stdout, "REGISTERED\tlocation: \"%s\"\tLifetime: %lus\r\n", targetP->location, (unsigned long)targetP->lifetime); - break; - case STATE_REG_UPDATE_PENDING: - fprintf(stdout, "REGISTRATION UPDATE PENDING\r\n"); - break; - case STATE_DEREG_PENDING: - fprintf(stdout, "DEREGISTRATION PENDING\r\n"); - break; - case STATE_REG_FAILED: - fprintf(stdout, "REGISTRATION FAILED\r\n"); - break; - default: - fprintf(stdout, "INVALID (%d)\r\n", (int)targetP->status); - } - } - } + lwm2m_context_t *lwm2mH = (lwm2m_context_t *) user_data; + lwm2m_server_t *targetP; + + targetP = lwm2mH->bootstrapServerList; + + if (lwm2mH->bootstrapServerList == NULL) { + fprintf(stdout, "No Bootstrap Server.\r\n"); + } else { + fprintf(stdout, "Bootstrap Servers:\r\n"); + for (targetP = lwm2mH->bootstrapServerList ; targetP != NULL ; targetP = targetP->next) { + fprintf(stdout, " - Security Object ID %d", targetP->secObjInstID); + fprintf(stdout, "\tHold Off Time: %lu s", (unsigned long)targetP->lifetime); + fprintf(stdout, "\tstatus: "); + switch (targetP->status) { + case STATE_DEREGISTERED: + fprintf(stdout, "DEREGISTERED\r\n"); + break; + case STATE_BS_HOLD_OFF: + fprintf(stdout, "CLIENT HOLD OFF\r\n"); + break; + case STATE_BS_INITIATED: + fprintf(stdout, "BOOTSTRAP INITIATED\r\n"); + break; + case STATE_BS_PENDING: + fprintf(stdout, "BOOTSTRAP PENDING\r\n"); + break; + case STATE_BS_FINISHED: + fprintf(stdout, "BOOTSTRAP FINISHED\r\n"); + break; + case STATE_BS_FAILED: + fprintf(stdout, "BOOTSTRAP FAILED\r\n"); + break; + default: + fprintf(stdout, "INVALID (%d)\r\n", (int)targetP->status); + } + } + } + + if (lwm2mH->serverList == NULL) { + fprintf(stdout, "No LWM2M Server.\r\n"); + } else { + fprintf(stdout, "LWM2M Servers:\r\n"); + for (targetP = lwm2mH->serverList ; targetP != NULL ; targetP = targetP->next) { + fprintf(stdout, " - Server ID %d", targetP->shortID); + fprintf(stdout, "\tstatus: "); + switch (targetP->status) { + case STATE_DEREGISTERED: + fprintf(stdout, "DEREGISTERED\r\n"); + break; + case STATE_REG_PENDING: + fprintf(stdout, "REGISTRATION PENDING\r\n"); + break; + case STATE_REGISTERED: + fprintf(stdout, "REGISTERED\tlocation: \"%s\"\tLifetime: %lus\r\n", targetP->location, (unsigned long)targetP->lifetime); + break; + case STATE_REG_UPDATE_PENDING: + fprintf(stdout, "REGISTRATION UPDATE PENDING\r\n"); + break; + case STATE_DEREG_PENDING: + fprintf(stdout, "DEREGISTRATION PENDING\r\n"); + break; + case STATE_REG_FAILED: + fprintf(stdout, "REGISTRATION FAILED\r\n"); + break; + default: + fprintf(stdout, "INVALID (%d)\r\n", (int)targetP->status); + } + } + } } -static void prv_change(char * buffer, - void * user_data) +static void prv_change(char *buffer, + void *user_data) { - lwm2mH = (lwm2m_context_t *) user_data; - lwm2m_uri_t uri; - char * end = NULL; - int result; - - end = get_end_of_arg(buffer); - if (end[0] == 0) goto syntax_error; - - result = lwm2m_stringToUri(buffer, end - buffer, &uri); - if (result == 0) goto syntax_error; - - buffer = get_next_arg(end, &end); - - if (buffer[0] == 0) - { - fprintf(stderr, "report change!\n"); - lwm2m_resource_value_changed(lwm2mH, &uri); - } - else - { - handle_value_changed(lwm2mH, &uri, buffer, end - buffer); - } - return; + + lwm2m_uri_t uri; + char *end = NULL; + int result; + + end = get_end_of_arg(buffer); +// if (end[0] == 0) goto syntax_error; + + result = lwm2m_stringToUri(buffer, end - buffer, &uri); + if (result == 0) { + goto syntax_error; + } + + buffer = get_next_arg(end, &end); + + if (buffer[0] == 0) { + fprintf(stderr, "report change!\n"); + lwm2m_resource_value_changed(lwm2mH, &uri); + } else { + handle_value_changed(lwm2mH, &uri, buffer, end - buffer); + } + return; syntax_error: - fprintf(stdout, "Syntax error !\n"); + fprintf(stdout, "Syntax error !\n"); } -static void prv_object_list(char * buffer, - void * user_data) +static void prv_object_list(char *buffer, + void *user_data) { - lwm2mH = (lwm2m_context_t *)user_data; - lwm2m_object_t * objectP; - - for (objectP = lwm2mH->objectList; objectP != NULL; objectP = objectP->next) - { - if (objectP->instanceList == NULL) - { - fprintf(stdout, "/%d ", objectP->objID); - } - else - { - lwm2m_list_t * instanceP; - - for (instanceP = objectP->instanceList; instanceP != NULL ; instanceP = instanceP->next) - { - fprintf(stdout, "/%d/%d ", objectP->objID, instanceP->id); - } - } - fprintf(stdout, "\r\n"); - } + lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data; + lwm2m_object_t *objectP; + + for (objectP = lwm2mH->objectList; objectP != NULL; objectP = objectP->next) { + if (objectP->instanceList == NULL) { + fprintf(stdout, "/%d ", objectP->objID); + } else { + lwm2m_list_t *instanceP; + + for (instanceP = objectP->instanceList; instanceP != NULL ; instanceP = instanceP->next) { + fprintf(stdout, "/%d/%d ", objectP->objID, instanceP->id); + } + } + fprintf(stdout, "\r\n"); + } } -static void prv_instance_dump(lwm2m_object_t * objectP, - uint16_t id) +static void prv_instance_dump(lwm2m_object_t *objectP, + uint16_t id) { - int numData; - lwm2m_data_t * dataArray; - uint16_t res; - - numData = 0; - res = objectP->readFunc(id, &numData, &dataArray, objectP); - if (res != COAP_205_CONTENT) - { - printf("Error "); - print_status(stdout, res); - printf("\r\n"); - return; - } - - dump_tlv(stdout, numData, dataArray, 0); + int numData; + lwm2m_data_t *dataArray; + uint16_t res; + + numData = 0; + res = objectP->readFunc(id, &numData, &dataArray, objectP); + if (res != COAP_205_CONTENT) { + printf("Error "); + print_status(stdout, res); + printf("\r\n"); + return; + } + + dump_tlv(stdout, numData, dataArray, 0); } -static void prv_object_dump(char * buffer, - void * user_data) +static void prv_object_dump(char *buffer, + void *user_data) { - lwm2mH = (lwm2m_context_t *) user_data; - lwm2m_uri_t uri; - char * end = NULL; - int result; - lwm2m_object_t * objectP; - - end = get_end_of_arg(buffer); - if (end[0] == 0) goto syntax_error; - - result = lwm2m_stringToUri(buffer, end - buffer, &uri); - if (result == 0) goto syntax_error; - if (uri.flag & LWM2M_URI_FLAG_RESOURCE_ID) goto syntax_error; - - objectP = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, uri.objectId); - if (objectP == NULL) - { - fprintf(stdout, "Object not found.\n"); - return; - } - - if (uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) - { - prv_instance_dump(objectP, uri.instanceId); - } - else - { - lwm2m_list_t * instanceP; - - for (instanceP = objectP->instanceList; instanceP != NULL ; instanceP = instanceP->next) - { - fprintf(stdout, "Instance %d:\r\n", instanceP->id); - prv_instance_dump(objectP, instanceP->id); - fprintf(stdout, "\r\n"); - } - } - - return; + lwm2m_context_t *lwm2mH = (lwm2m_context_t *) user_data; + lwm2m_uri_t uri; + char *end = NULL; + int result; + lwm2m_object_t *objectP; + + end = get_end_of_arg(buffer); + //if (end[0] == 0) goto syntax_error; + + result = lwm2m_stringToUri(buffer, end - buffer, &uri); + if (result == 0) { + goto syntax_error; + } + if (uri.flag & LWM2M_URI_FLAG_RESOURCE_ID) { + goto syntax_error; + } + + objectP = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, uri.objectId); + if (objectP == NULL) { + fprintf(stdout, "Object not found.\n"); + return; + } + + if (uri.flag & LWM2M_URI_FLAG_INSTANCE_ID) { + prv_instance_dump(objectP, uri.instanceId); + } else { + lwm2m_list_t *instanceP; + + for (instanceP = objectP->instanceList; instanceP != NULL ; instanceP = instanceP->next) { + fprintf(stdout, "Instance %d:\r\n", instanceP->id); + prv_instance_dump(objectP, instanceP->id); + fprintf(stdout, "\r\n"); + } + } + + return; syntax_error: - fprintf(stdout, "Syntax error !\n"); + fprintf(stdout, "Syntax error !\n"); } -static void prv_update(char * buffer, - void * user_data) +static void prv_update(char *buffer, + void *user_data) { - lwm2mH = (lwm2m_context_t *)user_data; - if (buffer[0] == 0) goto syntax_error; - - uint16_t serverId = (uint16_t) atoi(buffer); - int res = lwm2m_update_registration(lwm2mH, serverId, false); - if (res != 0) - { - fprintf(stdout, "Registration update error: "); - print_status(stdout, res); - fprintf(stdout, "\r\n"); - } - return; + lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data; + if (buffer[0] == 0) { + goto syntax_error; + } + + uint16_t serverId = (uint16_t) atoi(buffer); + int res = lwm2m_update_registration(lwm2mH, serverId, false); + if (res != 0) { + fprintf(stdout, "Registration update error: "); + print_status(stdout, res); + fprintf(stdout, "\r\n"); + } + return; syntax_error: - fprintf(stdout, "Syntax error !\n"); + fprintf(stdout, "Syntax error !\n"); } -static void update_battery_level(lwm2m_context_t * context) +static void update_battery_level(lwm2m_context_t *context) { - static time_t next_change_time = 0; - time_t tv_sec; - - tv_sec = lwm2m_gettime(); - if (tv_sec < 0) return; - - if (next_change_time < tv_sec) - { - char value[15]; - int valueLength; - lwm2m_uri_t uri; - int level = rand() % 100; - - if (0 > level) level = -level; - if (lwm2m_stringToUri("/3/0/9", 6, &uri)) - { - valueLength = sprintf(value, "%d", level); - fprintf(stderr, "New Battery Level: %d\n", level); - handle_value_changed(context, &uri, value, valueLength); - } - level = rand() % 20; - if (0 > level) level = -level; - next_change_time = tv_sec + level + 10; - } + static time_t next_change_time = 0; + time_t tv_sec; + + tv_sec = lwm2m_gettime(); + if (tv_sec < 0) { + return; + } + + if (next_change_time < tv_sec) { + char value[15]; + int valueLength; + lwm2m_uri_t uri; + int level = rand() % 100; + + if (0 > level) { + level = -level; + } + if (lwm2m_stringToUri("/3/0/9", 6, &uri)) { + valueLength = sprintf(value, "%d", level); + fprintf(stderr, "New Battery Level: %d\n", level); + handle_value_changed(context, &uri, value, valueLength); + } + level = rand() % 20; + if (0 > level) { + level = -level; + } + next_change_time = tv_sec + level + 10; + } } -static void prv_add(char * buffer, - void * user_data) +static void prv_add(char *buffer, + void *user_data) { - lwm2mH = (lwm2m_context_t *)user_data; - lwm2m_object_t * objectP; - int res; - - objectP = get_test_object(); - if (objectP == NULL) - { - fprintf(stdout, "Creating object 1024 failed.\r\n"); - return; - } - res = lwm2m_add_object(lwm2mH, objectP); - if (res != 0) - { - fprintf(stdout, "Adding object 1024 failed: "); - print_status(stdout, res); - fprintf(stdout, "\r\n"); - } - else - { - fprintf(stdout, "Object 1024 added.\r\n"); - } - return; + lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data; + lwm2m_object_t *objectP; + int res; + + objectP = get_test_object(); + if (objectP == NULL) { + fprintf(stdout, "Creating object 1024 failed.\r\n"); + return; + } + res = lwm2m_add_object(lwm2mH, objectP); + if (res != 0) { + fprintf(stdout, "Adding object 1024 failed: "); + print_status(stdout, res); + fprintf(stdout, "\r\n"); + } else { + fprintf(stdout, "Object 1024 added.\r\n"); + } + return; } -static void prv_remove(char * buffer, - void * user_data) +static void prv_remove(char *buffer, + void *user_data) { - lwm2mH = (lwm2m_context_t *)user_data; - int res; - - res = lwm2m_remove_object(lwm2mH, 1024); - if (res != 0) - { - fprintf(stdout, "Removing object 1024 failed: "); - print_status(stdout, res); - fprintf(stdout, "\r\n"); - } - else - { - fprintf(stdout, "Object 1024 removed.\r\n"); - } - return; + lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data; + int res; + + res = lwm2m_remove_object(lwm2mH, 1024); + if (res != 0) { + fprintf(stdout, "Removing object 1024 failed: "); + print_status(stdout, res); + fprintf(stdout, "\r\n"); + } else { + fprintf(stdout, "Object 1024 removed.\r\n"); + } + return; } #ifdef LWM2M_BOOTSTRAP -static void prv_initiate_bootstrap(char * buffer, - void * user_data) +static void prv_initiate_bootstrap(char *buffer, + void *user_data) { - lwm2mH = (lwm2m_context_t *)user_data; - lwm2m_server_t * targetP; - - // HACK !!! - lwm2mH->state = STATE_BOOTSTRAP_REQUIRED; - targetP = lwm2mH->bootstrapServerList; - while (targetP != NULL) - { - targetP->lifetime = 0; - targetP = targetP->next; - } + lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data; + lwm2m_server_t *targetP; + + // HACK !!! + lwm2mH->state = STATE_BOOTSTRAP_REQUIRED; + targetP = lwm2mH->bootstrapServerList; + while (targetP != NULL) { + targetP->lifetime = 0; + targetP = targetP->next; + } } -static void prv_display_objects(char * buffer, - void * user_data) +static void prv_display_objects(char *buffer, + void *user_data) { - lwm2mH = (lwm2m_context_t *)user_data; - lwm2m_object_t * object; - - for (object = lwm2mH->objectList; object != NULL; object = object->next){ - if (NULL != object) { - switch (object->objID) - { - case LWM2M_SECURITY_OBJECT_ID: - display_security_object(object); - break; - case LWM2M_SERVER_OBJECT_ID: - display_server_object(object); - break; - case LWM2M_ACL_OBJECT_ID: - break; - case LWM2M_DEVICE_OBJECT_ID: - display_device_object(object); - break; - case LWM2M_CONN_MONITOR_OBJECT_ID: - break; - case LWM2M_FIRMWARE_UPDATE_OBJECT_ID: - display_firmware_object(object); - break; - case LWM2M_LOCATION_OBJECT_ID: - display_location_object(object); - break; - case LWM2M_CONN_STATS_OBJECT_ID: - break; - case TEST_OBJECT_ID: - display_test_object(object); - break; - } - } - } + lwm2m_context_t *lwm2mH = (lwm2m_context_t *)user_data; + lwm2m_object_t *object; + + for (object = lwm2mH->objectList; object != NULL; object = object->next) { + if (NULL != object) { + switch (object->objID) { + case LWM2M_SECURITY_OBJECT_ID: + display_security_object(object); + break; + case LWM2M_SERVER_OBJECT_ID: + display_server_object(object); + break; + case LWM2M_ACL_OBJECT_ID: + break; + case LWM2M_DEVICE_OBJECT_ID: + display_device_object(object); + break; + case LWM2M_CONN_MONITOR_OBJECT_ID: + break; + case LWM2M_FIRMWARE_UPDATE_OBJECT_ID: + display_firmware_object(object); + break; + case LWM2M_LOCATION_OBJECT_ID: + display_location_object(object); + break; + case LWM2M_CONN_STATS_OBJECT_ID: + break; + case TEST_OBJECT_ID: + display_test_object(object); + break; + } + } + } } -static void prv_display_backup(char * buffer, - void * user_data) +static void prv_display_backup(char *buffer, + void *user_data) { - int i; - for (i = 0 ; i < BACKUP_OBJECT_COUNT ; i++) { - lwm2m_object_t * object = backupObjectArray[i]; - if (NULL != object) { - switch (object->objID) - { - case LWM2M_SECURITY_OBJECT_ID: - display_security_object(object); - break; - case LWM2M_SERVER_OBJECT_ID: - display_server_object(object); - break; - default: - break; - } - } - } + if (NULL != backupObjectArray) { + int i; + for (i = 0 ; i < BACKUP_OBJECT_COUNT ; i++) { + lwm2m_object_t *object = backupObjectArray[i]; + if (NULL != object) { + switch (object->objID) { + case LWM2M_SECURITY_OBJECT_ID: + display_security_object(object); + break; + case LWM2M_SERVER_OBJECT_ID: + display_server_object(object); + break; + default: + break; + } + } + } + } } -static void prv_backup_objects(lwm2m_context_t * context) +static void prv_backup_objects(lwm2m_context_t *context) { - uint16_t i; - - for (i = 0; i < BACKUP_OBJECT_COUNT; i++) { - if (NULL != backupObjectArray[i]) { - switch (backupObjectArray[i]->objID) - { - case LWM2M_SECURITY_OBJECT_ID: - clean_security_object(backupObjectArray[i]); - lwm2m_free(backupObjectArray[i]); - break; - case LWM2M_SERVER_OBJECT_ID: - clean_server_object(backupObjectArray[i]); - lwm2m_free(backupObjectArray[i]); - break; - default: - break; - } - } - backupObjectArray[i] = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t)); - memset(backupObjectArray[i], 0, sizeof(lwm2m_object_t)); - } - - /* - * Backup content of objects 0 (security) and 1 (server) - */ - copy_security_object(backupObjectArray[0], (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SECURITY_OBJECT_ID)); - copy_server_object(backupObjectArray[1], (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SERVER_OBJECT_ID)); + uint16_t i; + + for (i = 0; i < BACKUP_OBJECT_COUNT; i++) { + if (NULL != backupObjectArray[i]) { + switch (backupObjectArray[i]->objID) { + case LWM2M_SECURITY_OBJECT_ID: + clean_security_object(backupObjectArray[i]); + lwm2m_free(backupObjectArray[i]); + break; + case LWM2M_SERVER_OBJECT_ID: + clean_server_object(backupObjectArray[i]); + lwm2m_free(backupObjectArray[i]); + break; + default: + break; + } + } + backupObjectArray[i] = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t)); + memset(backupObjectArray[i], 0, sizeof(lwm2m_object_t)); + } + + /* + * Backup content of objects 0 (security) and 1 (server) + */ + copy_security_object(backupObjectArray[0], (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SECURITY_OBJECT_ID)); + copy_server_object(backupObjectArray[1], (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SERVER_OBJECT_ID)); } -static void prv_restore_objects(lwm2m_context_t * context) +static void prv_restore_objects(lwm2m_context_t *context) { - lwm2m_object_t * targetP; - - /* - * Restore content of objects 0 (security) and 1 (server) - */ - targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SECURITY_OBJECT_ID); - // first delete internal content - clean_security_object(targetP); - // then restore previous object - copy_security_object(targetP, backupObjectArray[0]); - - targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SERVER_OBJECT_ID); - // first delete internal content - clean_server_object(targetP); - // then restore previous object - copy_server_object(targetP, backupObjectArray[1]); - - // restart the old servers - fprintf(stdout, "[BOOTSTRAP] ObjectList restored\r\n"); + lwm2m_object_t *targetP; + + /* + * Restore content of objects 0 (security) and 1 (server) + */ + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SECURITY_OBJECT_ID); + // first delete internal content + clean_security_object(targetP); + // then restore previous object + copy_security_object(targetP, backupObjectArray[0]); + + targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SERVER_OBJECT_ID); + // first delete internal content + clean_server_object(targetP); + // then restore previous object + copy_server_object(targetP, backupObjectArray[1]); + + // restart the old servers + fprintf(stdout, "[BOOTSTRAP] ObjectList restored\r\n"); } -static void update_bootstrap_info(lwm2m_client_state_t * previousBootstrapState, - lwm2m_context_t * context) +static void update_bootstrap_info(lwm2m_client_state_t *previousBootstrapState, + lwm2m_context_t *context) { - if (*previousBootstrapState != context->state) - { - *previousBootstrapState = context->state; - switch(context->state) - { - case STATE_BOOTSTRAPPING: + if (*previousBootstrapState != context->state) { + *previousBootstrapState = context->state; + switch (context->state) { + case STATE_BOOTSTRAPPING: #ifdef WITH_LOGS - fprintf(stdout, "[BOOTSTRAP] backup security and server objects\r\n"); + fprintf(stdout, "[BOOTSTRAP] backup security and server objects\r\n"); #endif - prv_backup_objects(context); - break; - default: - break; - } - } + prv_backup_objects(context); + break; + default: + break; + } + } } static void close_backup_object() { - int i; - for (i = 0; i < BACKUP_OBJECT_COUNT; i++) { - switch (backupObjectArray[i]->objID) - { - case LWM2M_SECURITY_OBJECT_ID: - clean_security_object(backupObjectArray[i]); - lwm2m_free(backupObjectArray[i]); - break; - case LWM2M_SERVER_OBJECT_ID: - clean_server_object(backupObjectArray[i]); - lwm2m_free(backupObjectArray[i]); - break; - default: - break; - } - } + int i; + for (i = 0; i < BACKUP_OBJECT_COUNT; i++) { + if (NULL != backupObjectArray[i]) { + switch (backupObjectArray[i]->objID) { + case LWM2M_SECURITY_OBJECT_ID: + clean_security_object(backupObjectArray[i]); + lwm2m_free(backupObjectArray[i]); + break; + case LWM2M_SERVER_OBJECT_ID: + clean_server_object(backupObjectArray[i]); + lwm2m_free(backupObjectArray[i]); + break; + default: + break; + } + } + } } -#endif /* LWM2M_BOOTSTRAP */ - +#endif void print_usage(void) { - fprintf(stdout, "Usage: lwm2mclient [OPTION]\r\n"); - fprintf(stdout, "Launch a LWM2M client.\r\n"); - fprintf(stdout, "Options:\r\n"); - fprintf(stdout, " -n NAME\tSet the endpoint name of the Client. Default: testlwm2mclient\r\n"); - fprintf(stdout, " -l PORT\tSet the local UDP port of the Client. Default: 56830\r\n"); - fprintf(stdout, " -h HOST\tSet the hostname of the LWM2M Server to connect to. Default: localhost\r\n"); - fprintf(stdout, " -p PORT\tSet the port of the LWM2M Server to connect to. Default: "LWM2M_STANDARD_PORT_STR"\r\n"); - fprintf(stdout, " -4\t\tUse IPv4 connection. Default: IPv6 connection\r\n"); - fprintf(stdout, " -t TIME\tSet the lifetime of the Client. Default: 300\r\n"); - fprintf(stdout, " -b\t\tBootstrap requested.\r\n"); - fprintf(stdout, " -c\t\tChange battery level over time.\r\n"); + fprintf(stdout, "Usage: lwm2mclient [OPTION]\r\n"); + fprintf(stdout, "Launch a LWM2M client.\r\n"); + fprintf(stdout, "Options:\r\n"); + fprintf(stdout, " -n NAME\tSet the endpoint name of the Client. Default: testlwm2mclient\r\n"); + fprintf(stdout, " -l PORT\tSet the local UDP port of the Client. Default: 56830\r\n"); + fprintf(stdout, " -h HOST\tSet the hostname of the LWM2M Server to connect to. Default: localhost\r\n"); + fprintf(stdout, " -p PORT\tSet the port of the LWM2M Server to connect to. Default: "LWM2M_STANDARD_PORT_STR"\r\n"); + fprintf(stdout, " -4\t\tUse IPv4 connection. Default: IPv6 connection\r\n"); + fprintf(stdout, " -t TIME\tSet the lifetime of the Client. Default: 300\r\n"); + fprintf(stdout, " -b\t\tBootstrap requested.\r\n"); + fprintf(stdout, " -c\t\tChange battery level over time.\r\n"); #ifdef WITH_TINYDTLS - fprintf(stdout, " -i STRING\tSet the device management or bootstrap server PSK identity. If not set use none secure mode\r\n"); - fprintf(stdout, " -s HEXSTRING\tSet the device management or bootstrap server Pre-Shared-Key. If not set use none secure mode\r\n"); + fprintf(stdout, " -i STRING\tSet the device management or bootstrap server PSK identity. If not set use none secure mode\r\n"); + fprintf(stdout, " -s HEXSTRING\tSet the device management or bootstrap server Pre-Shared-Key. If not set use none secure mode\r\n"); #endif - fprintf(stdout, "Examples:\r\n"); - fprintf(stdout, " lwm2mclient -h coap://127.0.0.1 -4\r\n"); - fprintf(stdout, "\r\n"); + fprintf(stdout, "\r\n"); } -int lwm2m_client_main(int argc, char *argv[]) -{ - client_data_t data; - int result; - lwm2mH = NULL; - int i; - const char * localPort = "56830"; - const char * server = NULL; - const char * serverPort = LWM2M_STANDARD_PORT_STR; - char * name = "testlwm2mclient"; - int lifetime = 300; - int batterylevelchanging = 0; - time_t reboot_time = 0; - int opt; - bool bootstrapRequested = false; - bool serverPortChanged = false; - -#ifdef LWM2M_BOOTSTRAP - lwm2m_client_state_t previousState = STATE_INITIAL; -#endif - - char * pskId = NULL; - uint16_t pskLen = -1; - char * pskBuffer = NULL; - - coap_protocol_t proto = COAP_UDP; - - /* - * The function start by setting up the command line interface (which may or not be useful depending on your project) - * - * This is an array of commands describes as { name, description, long description, callback, userdata }. - * The firsts tree are easy to understand, the callback is the function that will be called when this command is typed - * and in the last one will be stored the lwm2m context (allowing access to the server settings and the objects). - */ - command_desc_t commands[] = - { - {"list", "List known servers.", NULL, prv_output_servers, NULL}, - {"change", "Change the value of resource.", " change URI [DATA]\r\n" - " URI: uri of the resource such as /3/0, /3/0/2\r\n" - " DATA: (optional) new value\r\n", prv_change, NULL}, - {"update", "Trigger a registration update", " update SERVER\r\n" - " SERVER: short server id such as 123\r\n", prv_update, NULL}, -#ifdef LWM2M_BOOTSTRAP - {"bootstrap", "Initiate a DI bootstrap process", NULL, prv_initiate_bootstrap, NULL}, - {"dispb", "Display current backup of objects/instances/resources\r\n" - "\t(only security and server objects are backupped)", NULL, prv_display_backup, NULL}, - - {"disp", "Display current objects/instances/resources", NULL, prv_display_objects, NULL}, -#endif - {"ls", "List Objects and Instances", NULL, prv_object_list, NULL}, - {"dump", "Dump an Object", "dump URI" - "URI: uri of the Object or Instance such as /3/0, /1\r\n", prv_object_dump, NULL}, - {"add", "Add support of object 1024", NULL, prv_add, NULL}, - {"rm", "Remove support of object 1024", NULL, prv_remove, NULL}, - {"quit", "Quit the client gracefully.", NULL, prv_quit, NULL}, - {"^C", "Quit the client abruptly (without sending a de-register message).", NULL, NULL, NULL}, - - COMMAND_END_LIST - }; - - memset(&data, 0, sizeof(client_data_t)); - data.addressFamily = AF_INET; - - opt = 1; - while (opt < argc) - { - if (argv[opt] == NULL - || argv[opt][0] != '-' - || argv[opt][2] != 0) - { - print_usage(); - return 0; - } - switch (argv[opt][1]) - { - case 'b': - bootstrapRequested = true; - if (!serverPortChanged) serverPort = LWM2M_BSSERVER_PORT_STR; - break; - case 'c': - batterylevelchanging = 1; - break; - case 't': - opt++; - if (opt >= argc) - { - print_usage(); - return 0; - } - if (1 != sscanf(argv[opt], "%d", &lifetime)) - { - print_usage(); - return 0; - } - break; -#ifdef WITH_TINYDTLS - case 'i': - opt++; - if (opt >= argc) - { - print_usage(); - return 0; - } - pskId = argv[opt]; - break; - case 's': - opt++; - if (opt >= argc) - { - print_usage(); - return 0; - } - psk = argv[opt]; - break; -#endif - case 'n': - opt++; - if (opt >= argc) - { - print_usage(); - return 0; - } - name = argv[opt]; - break; - case 'l': - opt++; - if (opt >= argc) - { - print_usage(); - return 0; - } - localPort = argv[opt]; - break; - case 'h': - opt++; - if (opt >= argc) - { - print_usage(); - return 0; - } - server = argv[opt]; - break; - case 'p': - opt++; - if (opt >= argc) - { - print_usage(); - return 0; - } - serverPort = argv[opt]; - serverPortChanged = true; - break; - case '4': - data.addressFamily = AF_INET; - break; - default: - print_usage(); - return 0; - } - opt += 1; - } -#if defined (__TINYARA__) - if (argc == SET_PARAM_DM_FRAMEWORK) { - /* To handling parameters set through dm frameworks */ - name = DEFAULT_CLIENT_NAME; - lifetime = g_lifetime; - - bootstrapRequested = g_bootstrapRequested; - - if (bootstrapRequested) { - server = g_bootstrapserverAddr; - serverPort = g_bootstrapserverPort; - } else { - server = g_serverAddr; - serverPort = g_serverPort; - } - } -#endif /* __TINYARA__ */ - if (!server) - { - proto = COAP_UDP; - server = (AF_INET == data.addressFamily ? DEFAULT_SERVER_IPV4 : DEFAULT_SERVER_IPV6); - } else { - /* - * Parse server URI to distinguish protocol and server address - */ - proto = coap_get_protocol_from_uri(server); - if (proto >= COAP_PROTOCOL_MAX) { - fprintf(stderr, "Not supported protocol : %d\n", proto); - return -1; - } else { - /* move pointer to address field */ - server += strlen(coap_uri_prefix[proto]); - } - } - - /* - * This call an internal function that create an IPV6 socket on the port 5683. - */ - fprintf(stderr, "Trying to bind LWM2M Client to port %s\r\n", localPort); - data.sock = create_socket(proto, localPort, data.addressFamily); - if (data.sock < 0) - { - fprintf(stderr, "Failed to open socket: %d %s\r\n", errno, strerror(errno)); - return -1; - } - - /* - * Now the main function fill an array with each object, this list will be later passed to liblwm2m. - * Those functions are located in their respective object file. - */ -#ifdef WITH_TINYDTLS - if (psk != NULL) - { - pskLen = strlen(psk) / 2; - pskBuffer = malloc(pskLen); - - if (NULL == pskBuffer) - { - fprintf(stderr, "Failed to create PSK binary buffer\r\n"); - return -1; - } - // Hex string to binary - char *h = psk; - char *b = pskBuffer; - char xlate[] = "0123456789ABCDEF"; - - for ( ; *h; h += 2, ++b) - { - char *l = strchr(xlate, toupper(*h)); - char *r = strchr(xlate, toupper(*(h+1))); - - if (!r || !l) - { - fprintf(stderr, "Failed to parse Pre-Shared-Key HEXSTRING\r\n"); - return -1; - } - - *b = ((l - xlate) << 4) + (r - xlate); - } - } -#endif - - char serverUri[50]; - int serverId = 123; - sprintf (serverUri, "coap://%s%s:%s", coap_uri_prefix[proto], server, serverPort); -#ifdef LWM2M_BOOTSTRAP - objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, bootstrapRequested); -#else - objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, false); -#endif - if (NULL == objArray[0]) - { - fprintf(stderr, "Failed to create security object\r\n"); - return -1; - } - data.securityObjP = objArray[0]; - - /* - * Bind Accordingly Protocol (e.g., TCP, UDP) - * get_server_object(serverId, "T", lifetime, false); - */ - switch(proto) { - case COAP_TCP: - case COAP_TCP_TLS: - objArray[1] = get_server_object(serverId, "T", lifetime, false); - break; - case COAP_UDP: - case COAP_UDP_DTLS: - objArray[1] = get_server_object(serverId, "U", lifetime, false); - break; - default: - fprintf(stderr, "Cannot get_server_object with protocol %d\n", proto); - break; - } - - objArray[1] = get_server_object(serverId, "U", lifetime, false); - if (NULL == objArray[1]) - { - fprintf(stderr, "Failed to create server object\r\n"); - return -1; - } - - objArray[2] = get_object_device(); - if (NULL == objArray[2]) - { - fprintf(stderr, "Failed to create Device object\r\n"); - return -1; - } - - objArray[3] = get_object_firmware(); - if (NULL == objArray[3]) - { - fprintf(stderr, "Failed to create Firmware object\r\n"); - return -1; - } - - objArray[4] = get_object_location(); - if (NULL == objArray[4]) - { - fprintf(stderr, "Failed to create location object\r\n"); - return -1; - } - - objArray[5] = get_test_object(); - if (NULL == objArray[5]) - { - fprintf(stderr, "Failed to create test object\r\n"); - return -1; - } - - objArray[6] = get_object_conn_m(); - if (NULL == objArray[6]) - { - fprintf(stderr, "Failed to create connectivity monitoring object\r\n"); - return -1; - } - - objArray[7] = get_object_conn_s(); - if (NULL == objArray[7]) - { - fprintf(stderr, "Failed to create connectivity statistics object\r\n"); - return -1; - } - - int instId = 0; - objArray[8] = acc_ctrl_create_object(); - if (NULL == objArray[8]) - { - fprintf(stderr, "Failed to create Access Control object\r\n"); - return -1; - } - else if (acc_ctrl_obj_add_inst(objArray[8], instId, 3, 0, serverId)==false) - { - fprintf(stderr, "Failed to create Access Control object instance\r\n"); - return -1; - } - else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 0, 0b000000000001111)==false) - { - fprintf(stderr, "Failed to create Access Control ACL default resource\r\n"); - return -1; - } - else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 999, 0b000000000000001)==false) - { - fprintf(stderr, "Failed to create Access Control ACL resource for serverId: 999\r\n"); - return -1; - } - /* - * The liblwm2m library is now initialized with the functions that will be in - * charge of communication - */ - /* Use new API to set protocol type */ - lwm2mH = lwm2m_init2(&data, proto); - if (NULL == lwm2mH) - { - fprintf(stderr, "lwm2m_init2() failed\r\n"); - return -1; - } - -#ifdef WITH_TINYDTLS - data.lwm2mH = lwm2mH; -#endif - - /* - * We configure the liblwm2m library with the name of the client - which shall be unique for each client - - * the number of objects we will be passing through and the objects array - */ - result = lwm2m_configure(lwm2mH, name, NULL, NULL, OBJ_COUNT, objArray); - if (result != 0) - { - fprintf(stderr, "lwm2m_configure() failed: 0x%X\r\n", result); - return -1; - } - - //signal(SIGINT, handle_sigint); - - /** - * Initialize value changed callback. - */ - init_value_change(lwm2mH); - - /* - * As you now have your lwm2m context complete you can pass it as an argument to all the command line functions - * precedently viewed (first point) - */ - for (i = 0 ; commands[i].name != NULL ; i++) - { - commands[i].userData = (void *)lwm2mH; - } - fprintf(stdout, "LWM2M Client \"%s\" started on port %s\r\n", name, localPort); - fprintf(stdout, "> "); fflush(stdout); - /* - * We now enter in a while loop that will handle the communications from the server - */ - while (0 == g_quit) - { - struct timeval tv; - fd_set readfds; - - if (g_reboot) - { - time_t tv_sec; - - tv_sec = lwm2m_gettime(); - - if (0 == reboot_time) - { - reboot_time = tv_sec + 5; - } - if (reboot_time < tv_sec) - { - /* - * Message should normally be lost with reboot ... - */ - fprintf(stderr, "reboot time expired, rebooting ..."); - system_reboot(); - } - else - { - tv.tv_sec = reboot_time - tv_sec; - } - } - else if (batterylevelchanging) - { - update_battery_level(lwm2mH); - tv.tv_sec = 5; - } - else - { - tv.tv_sec = 60; - } - tv.tv_usec = 0; - - FD_ZERO(&readfds); - FD_SET(data.sock, &readfds); -#if defined (__TINYARA__) - FD_SET(STDIN_FILENO, &readfds); -#else - FD_SET(stdin, &readfds); -#endif - - /* - * This function does two things: - * - first it does the work needed by liblwm2m (eg. (re)sending some packets). - * - Secondly it adjusts the timeout value (default 60s) depending on the state of the transaction - * (eg. retransmission) and the time between the next operation - */ - result = lwm2m_step(lwm2mH, &(tv.tv_sec)); - fprintf(stdout, " -> State: "); - switch (lwm2mH->state) - { - case STATE_INITIAL: - fprintf(stdout, "STATE_INITIAL\r\n"); - break; - case STATE_BOOTSTRAP_REQUIRED: - fprintf(stdout, "STATE_BOOTSTRAP_REQUIRED\r\n"); - break; - case STATE_BOOTSTRAPPING: - fprintf(stdout, "STATE_BOOTSTRAPPING\r\n"); - break; - case STATE_REGISTER_REQUIRED: - fprintf(stdout, "STATE_REGISTER_REQUIRED\r\n"); - break; - case STATE_REGISTERING: - fprintf(stdout, "STATE_REGISTERING\r\n"); - break; - case STATE_READY: - fprintf(stdout, "STATE_READY\r\n"); - break; - default: - fprintf(stdout, "Unknown...\r\n"); - break; - } - if (result != 0) - { - fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result); -#ifdef LWM2M_BOOTSTRAP - if(previousState == STATE_BOOTSTRAPPING) - { -#ifdef WITH_LOGS - fprintf(stdout, "[BOOTSTRAP] restore security and server objects\r\n"); -#endif - prv_restore_objects(lwm2mH); - lwm2mH->state = STATE_INITIAL; - } - else -#endif /* LWM2M_BOOTSTRAP */ - return -1; - } -#ifdef LWM2M_BOOTSTRAP - update_bootstrap_info(&previousState, lwm2mH); -#endif - /* - * This part will set up an interruption until an event happen on SDTIN or the socket until "tv" timed out (set - * with the precedent function) - */ - result = select(FD_SETSIZE, &readfds, NULL, NULL, &tv); - - if (result < 0) - { - if (errno != EINTR) - { - fprintf(stderr, "Error in select(): %d %s\r\n", errno, strerror(errno)); - } - } - else if (result > 0) - { - uint8_t buffer[MAX_PACKET_SIZE]; - int numBytes; - - /* - * If an event happens on the socket - */ - if (FD_ISSET(data.sock, &readfds)) - { - struct sockaddr_storage addr; - socklen_t addrLen; - - addrLen = sizeof(addr); - - /* - * We retrieve the data received - */ - numBytes = connection_read(proto, data.sock, buffer, MAX_PACKET_SIZE, &addr, &addrLen); - - if (0 > numBytes) - { - fprintf(stderr, "Error in recvfrom(): %d %s\r\n", errno, strerror(errno)); - } - else if (0 < numBytes) - { - char s[INET6_ADDRSTRLEN]; - in_port_t port = 0; - -#ifdef WITH_TINYDTLS - dtls_connection_t * connP; -#else - connection_t * connP; -#endif - if (AF_INET == addr.ss_family) - { - struct sockaddr_in *saddr = (struct sockaddr_in *)&addr; - inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN); - port = saddr->sin_port; - } - else if (AF_INET6 == addr.ss_family) - { - struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr; - inet_ntop(saddr->sin6_family, &saddr->sin6_addr, s, INET6_ADDRSTRLEN); - port = saddr->sin6_port; - } - fprintf(stderr, "%d bytes received from [%s]:%hu\r\n", numBytes, s, ntohs(port)); - - /* - * Display it in the STDERR - */ - output_buffer(stderr, buffer, numBytes, 0); - - connP = connection_find(data.connList, &addr, addrLen); - if (connP != NULL) - { - /* - * Let liblwm2m respond to the query depending on the context - */ -#ifdef WITH_TINYDTLS - int result = connection_handle_packet(connP, buffer, numBytes); - if (0 != result) - { - printf("error handling message %d\n",result); - } -#else - lwm2m_handle_packet(lwm2mH, buffer, numBytes, connP); -#endif - conn_s_updateRxStatistic(objArray[7], numBytes, false); - } - else - { - fprintf(stderr, "received bytes ignored!\r\n"); - } - } - } - - /* - * If the event happened on the SDTIN - */ -#if defined (__TINYARA__) - else if (FD_ISSET(STDIN_FILENO, &readfds)) -#else - else if (FD_ISSET(stdin, &readfds)) -#endif - { -#if defined (__TINYARA__) - numBytes = read_input_command_line((char *)buffer); -#else - numBytes = read(stdin, buffer, MAX_PACKET_SIZE - 1); -#endif - - if (numBytes > 1) - { - buffer[numBytes] = 0; - /* - * We call the corresponding callback of the typed command passing it the buffer for further arguments - */ - handle_command(commands, (char*)buffer); - } - if (g_quit == 0) - { - fprintf(stdout, "\r\n> "); - fflush(stdout); - } - else - { - fprintf(stdout, "\r\n"); - } - } - } - } - - /* - * Finally when the loop is left smoothly - asked by user in the command line interface - we unregister our client from it - */ - if (g_quit == 1) - { -#ifdef LWM2M_BOOTSTRAP - close_backup_object(); -#endif - lwm2m_close(lwm2mH); - } - close(data.sock); - connection_free(data.connList); - - clean_security_object(objArray[0]); - lwm2m_free(objArray[0]); - clean_server_object(objArray[1]); - lwm2m_free(objArray[1]); - free_object_device(objArray[2]); - free_object_firmware(objArray[3]); - free_object_location(objArray[4]); - free_test_object(objArray[5]); - free_object_conn_m(objArray[6]); - free_object_conn_s(objArray[7]); - acl_ctrl_free_object(objArray[8]); - -#ifdef MEMORY_TRACE - if (g_quit == 1) - { - trace_print(0, 1); - } -#endif - - return 0; -} /**************************************************************************** - * TINYARA - * DM (Device Management) Frameworks supporting APIs + * API support ****************************************************************************/ - -#if defined (__TINYARA__) - -/* Public APIs */ - -pthread_addr_t lwm2m_client_run(void *arg) -{ - lwm2m_client_main(SET_PARAM_DM_FRAMEWORK, NULL); - return 0; -} - -char *client_set_serverAddr(FAR const char *serverAddr, bool isbootstrap) +char *client_set_serverAddr(FAR const char *serverAddr, + bool isbootstrap) { if (serverAddr) { if (isbootstrap) { @@ -1565,7 +900,9 @@ char *client_get_serverAddr(void) return g_serverAddr; } -char *client_set_serverPort(FAR const char *serverPort, bool isbootstrap) + +char *client_set_serverPort(FAR const char *serverPort, + bool isbootstrap) { if (serverPort) { if (isbootstrap) { @@ -1582,11 +919,14 @@ char *client_set_serverPort(FAR const char *serverPort, bool isbootstrap) } } + char *client_get_serverPort(void) { return g_serverPort; + } + int client_set_lifetime(int lifetime) { g_lifetime = lifetime; @@ -1609,7 +949,7 @@ int client_change_resource(char *buffer, void *user_data) return 0; } -static void process_udpconn(int sockfd, fd_set *readfds, client_data_t data) +static void process_udpconn(int sockfd, fd_set *readfds) { uint8_t buffer[MAX_PACKET_SIZE]; int numBytes; @@ -1676,148 +1016,554 @@ static void process_udpconn(int sockfd, fd_set *readfds, client_data_t data) } } - -lwm2m_context_t *wrapper_get_context(void) +static void prv_close_sock(void) { - return lwm2mH; + connection_t *connPtr = NULL; + + connPtr = ((client_data_t *)(lwm2mH->userData))->connList; + + while (connPtr != NULL) { + close(connPtr->sock); + connPtr = connPtr->next; + } } -int client_object_dump(char *buffer) +pthread_addr_t client_main(void) { - if (lwm2mH != NULL) { - prv_object_dump(buffer, lwm2mH); - return 0; + int result; + int i; + + const char *localPort = "56830"; +#if 0 + const char *server = "192.168.0.4"; + const char *serverPort = LWM2M_STANDARD_PORT_STR; + char *name = "testlwm2mclient"; + int lifetime = 300; +#endif + char *server = g_serverAddr; + char *serverPort = g_serverPort; + char *name = "myawesomeclient"; + int lifetime = g_lifetime; + int batterylevelchanging = 0; + time_t reboot_time = 0; + int opt; + bool bootstrapRequested = g_bootstrapRequested; + bool serverPortChanged = false; + + if (bootstrapRequested) { + server = g_bootstrapserverAddr; + serverPort = g_bootstrapserverPort; } else { - fprintf(stderr, "Error calling object dump\n"); + server = g_serverAddr; + serverPort = g_serverPort; } - return -1; -} - -/* Private APIs */ -static int read_input_command_line(char *buf) -{ - char buffer[MAX_PACKET_SIZE] = {0,}; - int nbytes = 0; - int pos = 0; - int char_idx = 0; - int bufsize = MAX_PACKET_SIZE; +#ifdef LWM2M_BOOTSTRAP + lwm2m_client_state_t previousState = STATE_INITIAL; +#endif - do { - nbytes = read(STDIN_FILENO, &buffer[pos], (bufsize - pos)); - if (nbytes <= 0) { - fprintf(stderr, "cannot read command\n"); + char *pskId = NULL; + char *psk = NULL; + uint16_t pskLen = -1; + char *pskBuffer = NULL; + + /* + * The function start by setting up the command line interface (which may or not be useful depending on your project) + * + * This is an array of commands describes as { name, description, long description, callback, userdata }. + * The firsts tree are easy to understand, the callback is the function that will be called when this command is typed + * and in the last one will be stored the lwm2m context (allowing access to the server settings and the objects). + */ + command_desc_t commands[] = { + {"list", "List known servers.", NULL, prv_output_servers, NULL}, + { + "change", "Change the value of resource.", " change URI [DATA]\r\n" + " URI: uri of the resource such as /3/0, /3/0/2\r\n" + " DATA: (optional) new value\r\n", prv_change, NULL + }, + { + "update", "Trigger a registration update", " update SERVER\r\n" + " SERVER: short server id such as 123\r\n", prv_update, NULL + }, +#ifdef LWM2M_BOOTSTRAP + {"bootstrap", "Initiate a DI bootstrap process", NULL, prv_initiate_bootstrap, NULL}, + { + "dispb", "Display current backup of objects/instances/resources\r\n" + "\t(only security and server objects are backupped)", NULL, prv_display_backup, NULL + }, +#endif + {"ls", "List Objects and Instances", NULL, prv_object_list, NULL}, + {"disp", "Display current objects/instances/resources", NULL, prv_display_objects, NULL}, + { + "dump", "Dump an Object", "dump URI" + "URI: uri of the Object or Instance such as /3/0, /1\r\n", prv_object_dump, NULL + }, + {"add", "Add support of object 1024", NULL, prv_add, NULL}, + {"rm", "Remove support of object 1024", NULL, prv_remove, NULL}, + {"quit", "Quit the client gracefully.", NULL, prv_quit, NULL}, + {"^C", "Quit the client abruptly (without sending a de-register message).", NULL, NULL, NULL}, + + COMMAND_END_LIST + }; + + printf("Inside client_main check serial\n"); + + memset(&data, 0, sizeof(client_data_t)); + data.addressFamily = AF_INET; +#if 0 + opt = 1; + while (opt < argc) { + if (argv[opt] == NULL + || argv[opt][0] != '-' + || argv[opt][2] != 0) { + print_usage(); return 0; } + switch (argv[opt][1]) { + case 'b': + bootstrapRequested = true; + if (!serverPortChanged) { + serverPort = LWM2M_BSSERVER_PORT_STR; + } + break; + case 'c': + batterylevelchanging = 1; + break; + case 't': + opt++; + if (opt >= argc) { + print_usage(); + return 0; + } + if (1 != sscanf(argv[opt], "%d", &lifetime)) { + print_usage(); + return 0; + } + break; +#ifdef WITH_TINYDTLS + case 'i': + opt++; + if (opt >= argc) { + print_usage(); + return 0; + } + pskId = argv[opt]; + break; + case 's': + opt++; + if (opt >= argc) { + print_usage(); + return 0; + } + psk = argv[opt]; + break; +#endif + case 'n': + opt++; + if (opt >= argc) { + print_usage(); + return 0; + } + name = argv[opt]; + break; + case 'l': + opt++; + if (opt >= argc) { + print_usage(); + return 0; + } + localPort = argv[opt]; + break; + case 'h': + opt++; + if (opt >= argc) { + print_usage(); + return 0; + } + server = argv[opt]; + break; + case 'p': + opt++; + if (opt >= argc) { + print_usage(); + return 0; + } + serverPort = argv[opt]; + serverPortChanged = true; + break; + case '4': + data.addressFamily = AF_INET; + break; + default: + print_usage(); + return 0; + } + opt += 1; + } +#endif + if (!server) { + server = (AF_INET == data.addressFamily ? DEFAULT_SERVER_IPV4 : DEFAULT_SERVER_IPV6); + } - for (char_idx = 0; char_idx < nbytes; char_idx++) { - if ((buffer[pos] == ASCII_BS) || (buffer[pos] == ASCII_DEL)) { - int valid_char_pos = pos + 1; - - if (pos > 0) { - pos--; - /* update screen */ - if (write(STDOUT_FILENO, "\b \b",3) <= 0) { - fprintf(stderr, "write failed (errno = %d)\n", get_errno()); - } - } - - if (buffer[valid_char_pos] != 0x0 && (valid_char_pos < MAX_PACKET_SIZE)) { - memcpy(&buffer[pos], &buffer[valid_char_pos], (bufsize - valid_char_pos)); - } - } else { - if (buffer[pos] == ASCII_CR) { - buffer[pos] = ASCII_LF; - } - - /* echo */ - if (write(STDOUT_FILENO, &buffer[pos], 1) <= 0) { - fprintf(stderr, "failed to write (errno = %d)\n", get_errno()); - } + /* + *This call an internal function that create an IPV6 socket on the port 5683. + */ + fprintf(stderr, "Trying to bind LWM2M Client to port %s\r\n", localPort); + data.sock = create_socket(localPort, data.addressFamily); + if (data.sock < 0) { + fprintf(stderr, "Failed to open socket: %d %s\r\n", errno, strerror(errno)); + return -1; + } - if (buffer[pos] == ASCII_LF) { - pos++; - break; - } + /* + * Now the main function fill an array with each object, this list will be later passed to liblwm2m. + * Those functions are located in their respective object file. + */ +#ifdef WITH_TINYDTLS + if (psk != NULL) { + pskLen = strlen(psk) / 2; + pskBuffer = malloc(pskLen); - pos++; - if (pos >= MAX_PACKET_SIZE) { - fprintf(stderr, "out of range : command is too long, maximum length %d\n", MAX_PACKET_SIZE); - memset(buf, 0x0, MAX_PACKET_SIZE); - return 0; - } - } + if (NULL == pskBuffer) { + fprintf(stderr, "Failed to create PSK binary buffer\r\n"); + return -1; } - } while(buffer[pos - 1] != ASCII_LF); + // Hex string to binary + char *h = psk; + char *b = pskBuffer; + char xlate[] = "0123456789ABCDEF"; + + for (; *h; h += 2, ++b) { + char *l = strchr(xlate, toupper(*h)); + char *r = strchr(xlate, toupper(*(h + 1))); + + if (!r || !l) { + fprintf(stderr, "Failed to parse Pre-Shared-Key HEXSTRING\r\n"); + return -1; + } - memcpy(buf, buffer, pos); + *b = ((l - xlate) << 4) + (r - xlate); + } + } +#endif - return pos; -} + char serverUri[50]; + int serverId = 123; + sprintf(serverUri, "coap://%s:%s", server, serverPort); +#ifdef LWM2M_BOOTSTRAP + objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, bootstrapRequested); +#else + objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, false); +#endif + if (NULL == objArray[0]) { + fprintf(stderr, "Failed to create security object\r\n"); + return -1; + } + data.securityObjP = objArray[0]; -static void prv_close_sock(void) -{ - connection_t *connPtr = NULL; + objArray[1] = get_server_object(serverId, "U", lifetime, false); + if (NULL == objArray[1]) { + fprintf(stderr, "Failed to create server object\r\n"); + return -1; + } - connPtr = ((client_data_t *)(lwm2mH->userData))->connList; + objArray[2] = get_object_device(); + if (NULL == objArray[2]) { + fprintf(stderr, "Failed to create Device object\r\n"); + return -1; + } - while (connPtr != NULL) { - close(connPtr->sock); - connPtr = connPtr->next; + objArray[3] = get_object_firmware(); + if (NULL == objArray[3]) { + fprintf(stderr, "Failed to create Firmware object\r\n"); + return -1; } -} -static void clear_client_globals(void) -{ - memset(g_bootstrapserverAddr, 0x00, IPADDRLEN_MAX); - memset(g_bootstrapserverPort, 0x00, 6); - if (lwm2mH->state == STATE_REGISTER_REQUIRED || - lwm2mH->state == STATE_REGISTERING || - lwm2mH->state == STATE_READY) { - printf("g_bootstrapRequested = false\n"); - g_bootstrapRequested = false; + objArray[4] = get_object_location(); + if (NULL == objArray[4]) { + fprintf(stderr, "Failed to create location object\r\n"); + return -1; } -} -static void prv_update_server(client_data_t *dataP, uint16_t secObjInstID) -{ - char *uri; - char *server_host; - char *server_port; + objArray[5] = get_test_object(); + if (NULL == objArray[5]) { + fprintf(stderr, "Failed to create test object\r\n"); + return -1; + } - uri = get_server_uri(dataP->securityObjP, secObjInstID); + objArray[6] = get_object_conn_m(); + if (NULL == objArray[6]) { + fprintf(stderr, "Failed to create connectivity monitoring object\r\n"); + return -1; + } - if (uri == NULL) { - return; + objArray[7] = get_object_conn_s(); + if (NULL == objArray[7]) { + fprintf(stderr, "Failed to create connectivity statistics object\r\n"); + return -1; } - // parse uri in the form "coaps://[server_host]:[port]" - if (0 == strncmp(uri, "coaps://", strlen("coaps://"))) { - server_host = uri + strlen("coaps://"); - } else if (0 == strncmp(uri, "coap://", strlen("coap://"))) { - server_host = uri + strlen("coap://"); + int instId = 0; + objArray[8] = acc_ctrl_create_object(); + if (NULL == objArray[8]) { + fprintf(stderr, "Failed to create Access Control object\r\n"); + return -1; + } else if (acc_ctrl_obj_add_inst(objArray[8], instId, 3, 0, serverId) == false) { + fprintf(stderr, "Failed to create Access Control object instance\r\n"); + return -1; + } else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 0, 0b000000000001111) == false) { + fprintf(stderr, "Failed to create Access Control ACL default resource\r\n"); + return -1; + } else if (acc_ctrl_oi_add_ac_val(objArray[8], instId, 999, 0b000000000000001) == false) { + fprintf(stderr, "Failed to create Access Control ACL resource for serverId: 999\r\n"); + return -1; + } + objArray[9] = get_power_monitor_object(); + if (NULL == objArray[9]) { + fprintf(stderr, "Failed to create Power Monitoring object\r\n"); + return -1; } else { - return; + if (power_monitor_obj_add_inst(objArray[9], instId, 0) == false) { + fprintf(stderr, "Failed to create Power Monitoring object instance\r\n"); + return -1; + } + if (power_monitor_obj_add_inst(objArray[9], instId + 1, 0) == false) { + fprintf(stderr, "Failed to create Power Monitoring object instance\r\n"); + return -1; + } + if (power_monitor_obj_add_inst(objArray[9], instId + 2, 0) == false) { + fprintf(stderr, "Failed to create Power Monitoring object instance\r\n"); + return -1; + } } - server_port = strrchr(server_host, ':'); - if (server_port == NULL) { - return; + /* + * The liblwm2m library is now initialized with the functions that will be in + * charge of communication + */ + lwm2mH = lwm2m_init(&data); + if (NULL == lwm2mH) { + fprintf(stderr, "lwm2m_init() failed\r\n"); + return -1; } - // remove brackets - if (server_host[0] == '[') { - server_host++; - if (*(server_port - 1) == ']') { - *(server_port - 1) = 0; + +#ifdef WITH_TINYDTLS + data.lwm2mH = lwm2mH; +#endif + + /* + * We configure the liblwm2m library with the name of the client - which shall be unique for each client - + * the number of objects we will be passing through and the objects array + */ + result = lwm2m_configure(lwm2mH, name, NULL, NULL, OBJ_COUNT, objArray); + if (result != 0) { + fprintf(stderr, "lwm2m_configure() failed: 0x%X\r\n", result); + return -1; + } + + //signal(SIGINT, handle_sigint); + printf("Instantiated objects\n"); + + /** + * Initialize value changed callback. + */ + init_value_change(lwm2mH); + + /* + * As you now have your lwm2m context complete you can pass it as an argument to all the command line functions + * precedently viewed (first point) + */ + for (i = 0 ; commands[i].name != NULL ; i++) { + commands[i].userData = (void *)lwm2mH; + } + fprintf(stdout, "LWM2M Client \"%s\" started on port %s\r\n", name, localPort); + fprintf(stdout, "> "); + fflush(stdout); + /* + * We now enter in a while loop that will handle the communications from the server + */ + while (0 == g_quit) { + struct timeval tv; + fd_set readfds; + int sockfd; + connection_t *connPtr = NULL; + + struct timespec tv1; + struct timespec tv2; + int ret_timestamp; + + if (g_reboot) { + time_t tv_sec; + + tv_sec = lwm2m_gettime(); + + if (0 == reboot_time) { + reboot_time = tv_sec + 5; + } + if (reboot_time < tv_sec) { + /* + * Message should normally be lost with reboot ... + */ + fprintf(stderr, "reboot time expired, rebooting ..."); + system_reboot(); + } else { + tv.tv_sec = reboot_time - tv_sec; + } + } else if (batterylevelchanging) { + update_battery_level(lwm2mH); + tv.tv_sec = 5; } else { - return; + tv.tv_sec = 60; + } + tv.tv_usec = 0; + + FD_ZERO(&readfds); + connPtr = ((client_data_t *)(lwm2mH->userData))->connList; + while (connPtr != NULL) { + printf("setting %d\n", connPtr->sock); + FD_SET(connPtr->sock, &readfds); + connPtr = connPtr->next; + } + + ret_timestamp = clock_gettime(CLOCK_REALTIME, &tv1); + printf("checking lwm2m_step\n"); + usleep(20000); + + /* + * This function does two things: + * - first it does the work needed by liblwm2m (eg. (re)sending some packets). + * - Secondly it adjusts the timeout value (default 60s) depending on the state of the transaction + * (eg. retransmission) and the time between the next operation + */ + result = lwm2m_step(lwm2mH, &(tv.tv_sec)); + fprintf(stdout, " -> State: "); + switch (lwm2mH->state) { + case STATE_INITIAL: + fprintf(stdout, "STATE_INITIAL\r\n"); + break; + case STATE_BOOTSTRAP_REQUIRED: + fprintf(stdout, "STATE_BOOTSTRAP_REQUIRED\r\n"); + break; + case STATE_BOOTSTRAPPING: + fprintf(stdout, "STATE_BOOTSTRAPPING\r\n"); + break; + case STATE_REGISTER_REQUIRED: + fprintf(stdout, "STATE_REGISTER_REQUIRED\r\n"); + break; + case STATE_REGISTERING: + fprintf(stdout, "STATE_REGISTERING\r\n"); + break; + case STATE_READY: + fprintf(stdout, "STATE_READY\r\n"); + break; + default: + fprintf(stdout, "Unknown...\r\n"); + break; + } + if (result != 0) { + fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result); + if (previousState == STATE_BOOTSTRAPPING) { +#ifdef WITH_LOGS + fprintf(stdout, "[BOOTSTRAP] restore security and server objects\r\n"); +#endif + prv_restore_objects(lwm2mH); + lwm2mH->state = STATE_INITIAL; + } else { + return -1; + } + } +#ifdef LWM2M_BOOTSTRAP + update_bootstrap_info(&previousState, lwm2mH); +#endif + printf("got connection, now trying select %d:%d, %lu:%lu\n", data.sock + 1, CONFIG_NSOCKET_DESCRIPTORS, + tv.tv_sec, tv.tv_usec); + usleep(20000); + /* + * This part will set up an interruption until an event happen on SDTIN or the socket until "tv" timed out (set + * with the precedent function) + */ + result = select(CONFIG_NFILE_DESCRIPTORS + + CONFIG_NSOCKET_DESCRIPTORS, &readfds, + NULL, NULL, &tv); + ret_timestamp = clock_gettime(CLOCK_REALTIME, &tv2); + printf("select exits with value %d\n", result); + usleep(20000); + printf("time diff %lu:%lu\n", tv2.tv_sec - tv1.tv_sec, + tv2.tv_nsec - tv1.tv_nsec); + usleep(20000); + if (result < 0) { + if (errno != EINTR) { + fprintf(stderr, "Error in select(): %d %s\r\n", errno, strerror(errno)); + } + } else if (result > 0) { + uint8_t buffer[MAX_PACKET_SIZE]; + int numBytes; + + /* + * If an event happens on the socket + */ + connPtr = ((client_data_t *)(lwm2mH->userData))->connList; + while (connPtr != NULL) { + process_udpconn(connPtr->sock, &readfds); + connPtr = connPtr->next; + } } } - // split strings - *server_port = 0; - server_port++; - client_set_serverAddr(server_host, false); - client_set_serverPort(server_port, false); + /* + * Finally when the loop is left smoothly - asked by user in the command line interface - we unregister our client from it + */ + if (g_quit == 1) { +#ifdef LWM2M_BOOTSTRAP + if (g_bootstrapRequested == true) { + close_backup_object(); + } +#endif + clear_client_globals(); + lwm2m_close(lwm2mH); + } + + close(data.sock); + prv_close_sock(); + connection_free(data.connList); + + clean_security_object(objArray[0]); + lwm2m_free(objArray[0]); + clean_server_object(objArray[1]); + lwm2m_free(objArray[1]); + free_object_device(objArray[2]); + free_object_firmware(objArray[3]); + free_object_location(objArray[4]); + free_test_object(objArray[5]); + free_object_conn_m(objArray[6]); + free_object_conn_s(objArray[7]); + acl_ctrl_free_object(objArray[8]); + power_monitor_free_object(objArray[9]); + +#ifdef MEMORY_TRACE + if (g_quit == 1) { + trace_print(0, 1); + } +#endif + + + printf("Exiting wakaama client thread\n"); + g_quit = 0; + return 0; +} + +lwm2m_context_t *wrapper_get_context(void) +{ + return lwm2mH; +} + +int client_object_dump(char *buffer) +{ + if (lwm2mH != NULL) { + prv_object_dump(buffer, lwm2mH); + return 0; + } else { + fprintf(stderr, "Error calling object dump\n"); + } + return -1; } -#endif /* __TINYARA__ */ diff --git a/external/wakaama/examples/client/lwm2mclient.h b/external/wakaama/examples/client/lwm2mclient.h index d992d25..f8660c7 100644 --- a/external/wakaama/examples/client/lwm2mclient.h +++ b/external/wakaama/examples/client/lwm2mclient.h @@ -27,114 +27,103 @@ #ifndef LWM2MCLIENT_H_ #define LWM2MCLIENT_H_ #include - #include "liblwm2m.h" -/* - * struct lwm2mclient_input can be used for - * pthread arguments called by lwm2m_client_run API - */ -struct lwm2mclient_input { - int argc; - char **argv; -}; - extern int g_reboot; +extern char *ipaddr; +extern char *port; /* * 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); +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_firmware.c */ -lwm2m_object_t * get_object_firmware(void); -void free_object_firmware(lwm2m_object_t * objectP); -void display_firmware_object(lwm2m_object_t * objectP); +lwm2m_object_t *get_object_firmware(void); +void free_object_firmware(lwm2m_object_t *objectP); +void display_firmware_object(lwm2m_object_t *objectP); /* * object_location.c */ -lwm2m_object_t * get_object_location(void); -void free_object_location(lwm2m_object_t * object); -void display_location_object(lwm2m_object_t * objectP); +lwm2m_object_t *get_object_location(void); +void free_object_location(lwm2m_object_t *object); +void display_location_object(lwm2m_object_t *objectP); /* * 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); +lwm2m_object_t *get_test_object(void); +void free_test_object(lwm2m_object_t *object); +void display_test_object(lwm2m_object_t *objectP); /* * 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); +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_connectivity_moni.c */ -lwm2m_object_t * get_object_conn_m(void); -void free_object_conn_m(lwm2m_object_t * objectP); -uint8_t connectivity_moni_change(lwm2m_data_t * dataArray, lwm2m_object_t * objectP); +lwm2m_object_t *get_object_conn_m(void); +void free_object_conn_m(lwm2m_object_t *objectP); +uint8_t connectivity_moni_change(lwm2m_data_t *dataArray, lwm2m_object_t *objectP); /* * object_connectivity_stat.c */ -extern lwm2m_object_t * get_object_conn_s(void); -void free_object_conn_s(lwm2m_object_t * objectP); -extern void conn_s_updateTxStatistic(lwm2m_object_t * objectP, uint16_t txDataByte, bool smsBased); -extern void conn_s_updateRxStatistic(lwm2m_object_t * objectP, uint16_t rxDataByte, bool smsBased); +extern lwm2m_object_t *get_object_conn_s(void); +void free_object_conn_s(lwm2m_object_t *objectP); +extern void conn_s_updateTxStatistic(lwm2m_object_t *objectP, uint16_t txDataByte, bool smsBased); +extern void conn_s_updateRxStatistic(lwm2m_object_t *objectP, uint16_t rxDataByte, bool smsBased); /* * object_access_control.c */ -lwm2m_object_t* acc_ctrl_create_object(void); -void acl_ctrl_free_object(lwm2m_object_t * objectP); -bool acc_ctrl_obj_add_inst (lwm2m_object_t* accCtrlObjP, uint16_t instId, - uint16_t acObjectId, uint16_t acObjInstId, uint16_t acOwner); -bool acc_ctrl_oi_add_ac_val(lwm2m_object_t* accCtrlObjP, uint16_t instId, - uint16_t aclResId, uint16_t acValue); +lwm2m_object_t *acc_ctrl_create_object(void); +void acl_ctrl_free_object(lwm2m_object_t *objectP); +bool acc_ctrl_obj_add_inst(lwm2m_object_t *accCtrlObjP, uint16_t instId, + uint16_t acObjectId, uint16_t acObjInstId, uint16_t acOwner); +bool acc_ctrl_oi_add_ac_val(lwm2m_object_t *accCtrlObjP, uint16_t instId, + uint16_t aclResId, uint16_t acValue); /* * lwm2mclient.c */ -void handle_value_changed(lwm2m_context_t* lwm2mH, lwm2m_uri_t* uri, const char * value, size_t valueLength); +void handle_value_changed(lwm2m_context_t *lwm2mH, lwm2m_uri_t *uri, const char *value, size_t valueLength); +/* + * system_api.c + */ +void init_value_change(lwm2m_context_t *lwm2m); +void system_reboot(void); /* - * TINYARA - * DM (Device Management) Frameworks APIs + * 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); +pthread_addr_t client_main(void); + +/* + * Server IP address, Port */ -pthread_addr_t lwm2m_client_run(void *arg); char *client_set_serverAddr(FAR const char *serverAddr, bool isbootstrap); char *client_get_serverAddr(void); char *client_set_serverPort(FAR const char *serverPort, bool isbootstrap); char *client_get_serverPort(void); - int client_object_dump(char *buffer); -int client_set_lifetime(int lifetime); -int client_change_resource(char *buffer, void *user_data); + +int client_set_lifetime(int lifetime); void client_initiate_bootstrap(void); void client_close(void); - -/* - * system_api.c - */ -void init_value_change(lwm2m_context_t * lwm2m); -void system_reboot(void); - -/* - * 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); - +int client_change_resource(char *buffer, void *user_data); #endif /* LWM2MCLIENT_H_ */ diff --git a/external/wakaama/examples/client/object_access_control.c b/external/wakaama/examples/client/object_access_control.c index 6781def..7edda7b 100644 --- a/external/wakaama/examples/client/object_access_control.c +++ b/external/wakaama/examples/client/object_access_control.c @@ -189,7 +189,7 @@ static uint8_t prv_write_resources(uint16_t instanceId, int numData, lwm2m_data_t* tlvArray, lwm2m_object_t* objectP, bool doCreate) { int i; - uint8_t result = COAP_404_NOT_FOUND; + uint8_t result; int64_t value; acc_ctrl_oi_t* accCtrlOiP = (acc_ctrl_oi_t *) diff --git a/external/wakaama/examples/client/object_connectivity_stat.c b/external/wakaama/examples/client/object_connectivity_stat.c index 939b32b..17f793a 100644 --- a/external/wakaama/examples/client/object_connectivity_stat.c +++ b/external/wakaama/examples/client/object_connectivity_stat.c @@ -20,18 +20,18 @@ * * Resources: * - * Name | ID | Oper. | Inst. | Mand.| Type | Range | Units | Description | - * SMS Tx Counter | 0 | R | Single| No | Integer | | | | - * SMS Rx Counter | 1 | R | Single| No | Integer | | | | - * Tx Data | 2 | R | Single| No | Integer | | kByte | | - * Rx Data | 3 | R | Single| No | Integer | | kByte | | - * Max Message Size | 4 | R | Single| No | Integer | | Byte | | - * Average Message Size | 5 | R | Single| No | Integer | | Byte | | - * StartOrReset | 6 | E | Single| Yes | Integer | | | | + * Name | ID | Oper. | Inst. | Mand.| Type | Range | Units | Descripton | + * SMS Tx Counter | 0 | R | Single| No | Integer | | | | + * SMS Rx Counter | 1 | R | Single| No | Integer | | | | + * Tx Data | 2 | R | Single| No | Integer | | kByte | | + * Rx Data | 3 | R | Single| No | Integer | | kByte | | + * Max Message Size | 4 | R | Single| No | Integer | | Byte | | + * Average Message Size | 5 | R | Single| No | Integer | | Byte | | + * StartOrReset | 6 | E | Single| Yes | Integer | | | | */ #include "liblwm2m.h" - +#include "tinyara/net/net.h" #include #include #include @@ -45,6 +45,7 @@ #define RES_O_MAX_MESSAGE_SIZE 4 #define RES_O_AVERAGE_MESSAGE_SIZE 5 #define RES_M_START_OR_RESET 6 +#define RES_O_COLLECTION_PERIOD 7 typedef struct { @@ -56,35 +57,240 @@ typedef struct int64_t avrMessageSize; int64_t messageCount; // private for incremental average calc. bool collectDataStarted; + uint32_t collectionPeriod; } conn_s_data_t; + +/**************************************************************************** + * Name: fetch_smsTx + * + * Description: + * To get the smsTx statistic value for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_smsTx(int *value); + + /**************************************************************************** + * Name: fetch_smsRx + * + * Description: + * To get the smsRx statistic value forlwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_smsRx(int *value); + +/**************************************************************************** + * Name: fetch_txDataByte + * + * Description: + * To get the txDataByte value for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_txDataByte(int *value); + +/**************************************************************************** + * Name: fetch_rxDataByte + * + * Description: + * To get the rxDataByte value for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_rxDataByte(int *value); + +/**************************************************************************** + * Name: fetch_maxMessageSize + * + * Description: + * To get the maximum message size for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_maxMessageSize(int *value); + +/**************************************************************************** + * Name: fetch_avrMessageSize + * + * Description: + * To get the avegare message size for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_avrMessageSize(int *value); + + + +/**************************************************************************** + * Name: fetch_smsTx + * + * Description: + * To get the smsTx statistic value for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + + void fetch_smsTx(int *value) +{ + (*value)=0; +} + + /**************************************************************************** + * Name: fetch_smsRx + * + * Description: + * To get the smsRx statistic value forlwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + +void fetch_smsRx(int *value) +{ + (*value)=0; +} + + /**************************************************************************** + * Name: fetch_txDataByte + * + * Description: + * To get the txDataByte value for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + +void fetch_txDataByte(int *value) +{ +#ifdef CONFIG_WL_WICED + (*value)= wifi_tx_count/1000; +#endif +#ifdef CONFIG_ENC28J60 + (*value)= eth_tx_count/1000; +#endif + +} + + /**************************************************************************** + * Name: fetch_rxDataByte + * + * Description: + * To get the rxDataByte value for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + + void fetch_rxDataByte(int *value) +{ +#ifdef CONFIG_WL_WICED + (*value)=wifi_total_message_size/1000; +#endif +#ifdef CONFIG_ENC28J60 + (*value)=eth_total_message_size/1000; +#endif +} + + /**************************************************************************** + * Name: fetch_maxMessageSize + * + * Description: + * To get the maximum message size for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + + void fetch_maxMessageSize(int *value) +{ +#ifdef CONFIG_WL_WICED + (*value)=wifi_max_message_size/1000; +#endif +#ifdef CONFIG_ENC28J60 + (*value)=eth_max_message_size/1000; +#endif +} + + /**************************************************************************** + * Name: fetch_avrMessageSize + * + * Description: + * To get the avegare message size for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + + void fetch_avrMessageSize(int *value) +{ +#ifdef CONFIG_WL_WICED + (*value)=wifi_avg_message_size/1000; +#endif +#ifdef CONFIG_ENC28J60 + (*value)=eth_avg_message_size/1000; +#endif + +} + static uint8_t prv_set_tlv(lwm2m_data_t * dataP, conn_s_data_t * connStDataP) { switch (dataP->id) { case RES_O_SMS_TX_COUNTER: + //fetch_smsTx(&connStDataP->smsTxCounter); lwm2m_data_encode_int(connStDataP->smsTxCounter, dataP); return COAP_205_CONTENT; break; case RES_O_SMS_RX_COUNTER: + // fetch_smsRx(&connStDataP->smsRxCounter); lwm2m_data_encode_int(connStDataP->smsRxCounter, dataP); return COAP_205_CONTENT; break; case RES_O_TX_DATA: + //fetch_txDataByte(&connStDataP->txDataByte); lwm2m_data_encode_int(connStDataP->txDataByte/1024, dataP); return COAP_205_CONTENT; break; case RES_O_RX_DATA: + //fetch_rxDataByte(&connStDataP->rxDataByte); lwm2m_data_encode_int(connStDataP->rxDataByte/1024, dataP); return COAP_205_CONTENT; break; case RES_O_MAX_MESSAGE_SIZE: + //fetch_maxMessageSize(&connStDataP->maxMessageSize); lwm2m_data_encode_int(connStDataP->maxMessageSize, dataP); return COAP_205_CONTENT; break; case RES_O_AVERAGE_MESSAGE_SIZE: + //fetch_avrMessageSize(&connStDataP->avrMessageSize); lwm2m_data_encode_int(connStDataP->avrMessageSize, dataP); return COAP_205_CONTENT; break; + case RES_O_COLLECTION_PERIOD: + //fetch_avrMessageSize(&connStDataP->collectionPeriod); + lwm2m_data_encode_int(connStDataP->collectionPeriod, dataP); + return COAP_205_CONTENT; + break; default: return COAP_404_NOT_FOUND ; } @@ -110,7 +316,8 @@ static uint8_t prv_read(uint16_t instanceId, int * numDataP, lwm2m_data_t** data RES_O_TX_DATA, RES_O_RX_DATA, RES_O_MAX_MESSAGE_SIZE, - RES_O_AVERAGE_MESSAGE_SIZE + RES_O_AVERAGE_MESSAGE_SIZE, + RES_O_COLLECTION_PERIOD, }; int nbRes = sizeof(resList) / sizeof(uint16_t); @@ -144,7 +351,23 @@ static void prv_resetCounter(lwm2m_object_t* objectP, bool start) myData->maxMessageSize = 0; myData->avrMessageSize = 0; myData->messageCount = 0; + myData->collectionPeriod = 0; myData->collectDataStarted = start; +#ifdef CONFIG_WL_WICED + wifi_tx_count=0; + wifi_rx_count=0; + wifi_max_message_size=0; + wifi_avg_message_size=0; + wifi_total_message_size=0; +#endif +#ifdef CONFIG_ENC28J60 + eth_tx_count=0; + eth_rx_count=0; + eth_max_message_size=0; + eth_avg_message_size=0; + eth_total_message_size=0; +#endif + } static uint8_t prv_exec(uint16_t instanceId, uint16_t resourceId, @@ -168,6 +391,7 @@ static uint8_t prv_exec(uint16_t instanceId, uint16_t resourceId, } } +#if 1 void conn_s_updateTxStatistic(lwm2m_object_t * objectP, uint16_t txDataByte, bool smsBased) { conn_s_data_t* myData = (conn_s_data_t*) (objectP->userData); @@ -198,7 +422,7 @@ void conn_s_updateRxStatistic(lwm2m_object_t * objectP, uint16_t rxDataByte, boo if (smsBased) myData->smsRxCounter++; } } - +#endif lwm2m_object_t * get_object_conn_s(void) { diff --git a/external/wakaama/examples/client/object_connectivity_stat.h b/external/wakaama/examples/client/object_connectivity_stat.h new file mode 100644 index 0000000..069fa29 --- /dev/null +++ b/external/wakaama/examples/client/object_connectivity_stat.h @@ -0,0 +1,120 @@ + +/* + * This connectivity statistics object is optional and single instance only + * + * Resources: + * + * Name | ID | Oper. | Inst. | Mand.| Type | Range | Units | Descripton | + * SMS Tx Counter | 0 | R | Single| No | Integer | | | | + * SMS Rx Counter | 1 | R | Single| No | Integer | | | | + * Tx Data | 2 | R | Single| No | Integer | | kByte | | + * Rx Data | 3 | R | Single| No | Integer | | kByte | | + * Max Message Size | 4 | R | Single| No | Integer | | Byte | | + * Average Message Size | 5 | R | Single| No | Integer | | Byte | | + * StartOrReset | 6 | E | Single| Yes | Integer | | | | + */ + + +#include +#include +#include +#include + +#include "../../core/liblwm2m.h" +#include "../../../../os/include/tinyara/net/net.h" + + +// Resource Id's: +#define RES_O_SMS_TX_COUNTER 0 +#define RES_O_SMS_RX_COUNTER 1 +#define RES_O_TX_DATA 2 +#define RES_O_RX_DATA 3 +#define RES_O_MAX_MESSAGE_SIZE 4 +#define RES_O_AVERAGE_MESSAGE_SIZE 5 +#define RES_M_START_OR_RESET 6 +#define RES_O_COLLECTION_PERIOD 7 + +typedef struct +{ + int64_t smsTxCounter; + int64_t smsRxCounter; + int64_t txDataByte; // report in kByte! + int64_t rxDataByte; // report in kByte! + int64_t maxMessageSize; + int64_t avrMessageSize; + int64_t messageCount; // private for incremental average calc. + bool collectDataStarted; + uint32_t collectionPeriod; +} conn_s_data_t; + +/**************************************************************************** + * Name: fetch_smsTx + * + * Description: + * To get the smsTx statistic value for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_smsTx(int *value); + + /**************************************************************************** + * Name: fetch_smsRx + * + * Description: + * To get the smsRx statistic value forlwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_smsRx(int *value); + +/**************************************************************************** + * Name: fetch_txDataByte + * + * Description: + * To get the txDataByte value for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_txDataByte(int *value); + +/**************************************************************************** + * Name: fetch_rxDataByte + * + * Description: + * To get the rxDataByte value for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_rxDataByte(int *value); + +/**************************************************************************** + * Name: fetch_maxMessageSize + * + * Description: + * To get the maximum message size for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_maxMessageSize(int *value); + +/**************************************************************************** + * Name: fetch_avrMessageSize + * + * Description: + * To get the avegare message size for lwm2m from connectivity manager + * + * Returned Value: + * + * + ****************************************************************************/ + void fetch_avrMessageSize(int *value); diff --git a/external/wakaama/examples/client/object_device.c b/external/wakaama/examples/client/object_device.c index 9e6e30c..9b31f9f 100644 --- a/external/wakaama/examples/client/object_device.c +++ b/external/wakaama/examples/client/object_device.c @@ -57,7 +57,7 @@ #include "liblwm2m.h" #include "lwm2mclient.h" - +#include "power_monitor_interface.h" #include #include #include @@ -108,6 +108,12 @@ #define RES_O_SOFTWARE_VERSION 19 #define RES_O_BATTERY_STATUS 20 #define RES_O_MEMORY_TOTAL 21 +/* Added for Tinyara */ +#define RES_O_POWER_STATES 22 +#define RES_O_POWER_CURR_STATE 23 +#define RES_O_POWER_TIME_SPENT 24 +#define RES_O_POWER_EXPECTED_LIFETIME 25 + typedef struct @@ -117,6 +123,9 @@ typedef struct int64_t time; uint8_t battery_level; char time_offset[PRV_OFFSET_MAXLEN]; + char power_states[POWER_STATES_LEN]; + char battery_lifetime[BATTERY_LIFETIME_LEN]; + char battery_levels[BATTERY_LEVEL_LEN]; } device_data_t; @@ -238,7 +247,9 @@ static uint8_t prv_set_value(lwm2m_data_t * dataP, } case RES_O_BATTERY_LEVEL: - lwm2m_data_encode_int(devDataP->battery_level, dataP); + fetch_battery_level(devDataP->battery_levels); + lwm2m_data_encode_string(devDataP->battery_levels, dataP); + printf("power level = %s\n", devDataP->battery_levels); return COAP_205_CONTENT; case RES_O_MEMORY_FREE: @@ -276,6 +287,26 @@ static uint8_t prv_set_value(lwm2m_data_t * dataP, case RES_M_BINDING_MODES: lwm2m_data_encode_string(PRV_BINDING_MODE, dataP); return COAP_205_CONTENT; + + case RES_O_POWER_STATES: + fetch_power_states(devDataP->power_states); + lwm2m_data_encode_string(devDataP->power_states, dataP); + printf("power states = %s\n", devDataP->power_states); + return COAP_205_CONTENT; + + case RES_O_POWER_CURR_STATE: + + return COAP_205_CONTENT; + + case RES_O_POWER_TIME_SPENT: + + return COAP_205_CONTENT; + + case RES_O_POWER_EXPECTED_LIFETIME: + fetch_battery_lifetime(devDataP->battery_lifetime); + lwm2m_data_encode_string(devDataP->battery_lifetime, dataP); + printf("battery lifetime = %s\n", devDataP->battery_lifetime); + return COAP_205_CONTENT; default: return COAP_404_NOT_FOUND; @@ -316,7 +347,11 @@ static uint8_t prv_device_read(uint16_t instanceId, RES_O_CURRENT_TIME, RES_O_UTC_OFFSET, RES_O_TIMEZONE, - RES_M_BINDING_MODES + RES_M_BINDING_MODES, + RES_O_POWER_STATES, + RES_O_POWER_CURR_STATE, + RES_O_POWER_TIME_SPENT, + RES_O_POWER_EXPECTED_LIFETIME, }; int nbRes = sizeof(resList)/sizeof(uint16_t); @@ -479,7 +514,13 @@ static uint8_t prv_device_write(uint16_t instanceId, return result; } - +static void prv_reboot(void) +{ + g_reboot = 1; +#ifdef CONFIG_ARCH_CHIP_S5JT200 + *(int*)0x80090400 = 1; +#endif +} static uint8_t prv_device_execute(uint16_t instanceId, uint16_t resourceId, uint8_t * buffer, @@ -498,7 +539,7 @@ static uint8_t prv_device_execute(uint16_t instanceId, { case RES_M_REBOOT: fprintf(stdout, "\n\t REBOOT\r\n\n"); - g_reboot = 1; + prv_reboot(); return COAP_204_CHANGED; case RES_O_FACTORY_RESET: fprintf(stdout, "\n\t FACTORY RESET\r\n\n"); @@ -589,6 +630,7 @@ lwm2m_object_t * get_object_device() } } + mount_procfs(); return deviceObj; } diff --git a/external/wakaama/examples/client/object_location.c b/external/wakaama/examples/client/object_location.c index c8736c4..40336bc 100644 --- a/external/wakaama/examples/client/object_location.c +++ b/external/wakaama/examples/client/object_location.c @@ -31,17 +31,14 @@ * Resources: * Name | ID | Oper.|Instances|Mand.| Type | Range | Units | Description | * -------------+-----+------+---------+-----+---------+-------+-------+----------------------------------------------------------------------------------+ - * Latitude | 0 | R | Single | Yes | Float | | Deg | The decimal notation of latitude e.g. - 45.5723 [Worlds Geodetic System 1984].| - * Longitude | 1 | R | Single | Yes | Float | | Deg | The decimal notation of longitude e.g. - 153.21760 [Worlds Geodetic System 1984].| - * Altitude | 2 | R | Single | No | Float | | m | The decimal notation of altitude in meters above sea level. | - * Radius | 3 | R | Single | No | Float | | m | The value in the Radius Resource indicates the size in meters of a circular area | - * | | | | | | | | around a point of geometry. | + * Latitude | 0 | R | Single | Yes | String | | Deg | The decimal notation of latitude e.g. - 45.5723 [Worlds Geodetic System 1984].| + * Longitude | 1 | R | Single | Yes | String | | Deg | The decimal notation of longitude e.g. - 153.21760 [Worlds Geodetic System 1984].| + * Altidude | 2 | R | Single | No | String | | m | The decimal notation of altidude in meters above sea level. | + * Uncertainty | 3 | R | Single | No | String | | m | The accuracy of the position in meters. | * Velocity | 4 | R | Single | No | Opaque | | * | The velocity of the device as defined in 3GPP 23.032 GAD specification(*). | * | | | | | | | | This set of values may not be available if the device is static. | * | | | | | | | | opaque: see OMA_TS 6.3.2 | * Timestamp | 5 | R | Single | Yes | Time | | s | The timestamp when the location measurement was performed. | - * Speed | 6 | R | Single | No | Float | | m/s | Speed is the time rate of change in position of a LwM2M Client without regard | - * | | | | | | | | for direction: the scalar component of velocity. | */ #include "liblwm2m.h" @@ -59,27 +56,26 @@ #define RES_M_LATITUDE 0 #define RES_M_LONGITUDE 1 #define RES_O_ALTITUDE 2 -#define RES_O_RADIUS 3 +#define RES_O_UNCERTAINTY 3 #define RES_O_VELOCITY 4 #define RES_M_TIMESTAMP 5 -#define RES_O_SPEED 6 //----- 3GPP TS 23.032 V11.0.0(2012-09) --------- #define HORIZONTAL_VELOCITY 0 // for Octet-1 upper half(..<<4) #define HORIZONTAL_VELOCITY_VERTICAL 1 // set vertical direction bit! #define HORIZONTAL_VELOCITY_WITH_UNCERTAINTY 2 -#define VELOCITY_OCTETS 5 // for HORIZONTAL_VELOCITY_WITH_UNCERTAINTY +#define VELOCITY_OCTETS 5 // for HORITZOL_VELOCITY_WITH_UNCERTAINTY +#define DEG_DECIMAL_PLACES 6 // configuration: degree decimals implementation typedef struct { - float latitude; - float longitude; - float altitude; - float radius; - uint8_t velocity [VELOCITY_OCTETS]; //3GPP notation 1st step: HORIZONTAL_VELOCITY_WITH_UNCERTAINTY + char latitude [5 + DEG_DECIMAL_PLACES]; //"359.12345" frag=5, 9+1=10! degrees +\0 + char longitude [5 + DEG_DECIMAL_PLACES]; + char altitude [5 + DEG_DECIMAL_PLACES]; + char uncertainty[5 + DEG_DECIMAL_PLACES]; + uint8_t velocity [VELOCITY_OCTETS]; //3GPP notation 1st step: HORITZOL_VELOCITY_WITH_UNCERTAINTY unsigned long timestamp; - float speed; } location_data_t; /** @@ -93,26 +89,23 @@ static uint8_t prv_res2tlv(lwm2m_data_t* dataP, switch (dataP->id) // location resourceId { case RES_M_LATITUDE: - lwm2m_data_encode_float(locDataP->latitude, dataP); + lwm2m_data_encode_string(locDataP->latitude, dataP); break; case RES_M_LONGITUDE: - lwm2m_data_encode_float(locDataP->longitude, dataP); + lwm2m_data_encode_string(locDataP->longitude, dataP); break; case RES_O_ALTITUDE: - lwm2m_data_encode_float(locDataP->altitude, dataP); + lwm2m_data_encode_string(locDataP->altitude, dataP); break; - case RES_O_RADIUS: - lwm2m_data_encode_float(locDataP->radius, dataP); + case RES_O_UNCERTAINTY: + lwm2m_data_encode_string(locDataP->uncertainty, dataP); break; case RES_O_VELOCITY: - lwm2m_data_encode_string((const char*)locDataP->velocity, dataP); + lwm2m_data_encode_string(locDataP->velocity, dataP); break; case RES_M_TIMESTAMP: lwm2m_data_encode_int(locDataP->timestamp, dataP); break; - case RES_O_SPEED: - lwm2m_data_encode_float(locDataP->speed, dataP); - break; default: ret = COAP_404_NOT_FOUND; break; @@ -152,10 +145,9 @@ static uint8_t prv_location_read(uint16_t objInstId, RES_M_LATITUDE, RES_M_LONGITUDE, RES_O_ALTITUDE, - RES_O_RADIUS, + RES_O_UNCERTAINTY, RES_O_VELOCITY, - RES_M_TIMESTAMP, - RES_O_SPEED + RES_M_TIMESTAMP }; // readable resources! *numDataP = sizeof(readResIds)/sizeof(uint16_t); @@ -185,8 +177,8 @@ void display_location_object(lwm2m_object_t * object) fprintf(stdout, " /%u: Location object:\r\n", object->objID); if (NULL != data) { - fprintf(stdout, " latitude: %.6f, longitude: %.6f, altitude: %.6f, radius: %.6f, timestamp: %lu, speed: %.6f\r\n", - data->latitude, data->longitude, data->altitude, data->radius, data->timestamp, data->speed); + fprintf(stdout, " latitude: %s, longitude: %s, altitude: %s, uncertainty: %s, timestamp: %lu\r\n", + data->latitude, data->longitude, data->altitude, data->uncertainty, data->timestamp); } #endif } @@ -233,9 +225,16 @@ void location_setLocationAtTime(lwm2m_object_t* locationObj, //-------------------------------------------------------------------- JH -- location_data_t* pData = locationObj->userData; - pData->latitude = latitude; - pData->longitude = longitude; - pData->altitude = altitude; +#if defined(ARDUINO) + dtostrf (latitude, -8, 6, pData->latitude); + dtostrf (longitude, -8, 6, pData->longitude); + dtostrf (altitude, -8, 4, pData->altitude); +#else + snprintf(pData->latitude, 5+DEG_DECIMAL_PLACES, "%-8.6f", (double)latitude); + snprintf(pData->longitude,5+DEG_DECIMAL_PLACES, "%-8.6f", (double)longitude); + snprintf(pData->altitude, 5+DEG_DECIMAL_PLACES, "%-8.4f", (double)altitude); +#endif + pData->timestamp = timestamp; } @@ -281,13 +280,12 @@ lwm2m_object_t * get_object_location(void) if (NULL != locationObj->userData) { location_data_t* data = (location_data_t*)locationObj->userData; - data->latitude = 27.986065; // Mount Everest :) - data->longitude = 86.922623; - data->altitude = 8495.0000; - data->radius = 0.0; + strcpy (data->latitude, "27.986065"); // Mount Everest :) + strcpy (data->longitude, "86.922623"); + strcpy (data->altitude, "8495.0000"); + strcpy (data->uncertainty, "0.01"); location_setVelocity(locationObj, 0, 0, 255); // 255: speedUncertainty not supported! data->timestamp = time(NULL); - data->speed = 0.0; } else { diff --git a/external/wakaama/examples/client/object_power_moni.c b/external/wakaama/examples/client/object_power_moni.c new file mode 100644 index 0000000..dc91712 --- /dev/null +++ b/external/wakaama/examples/client/object_power_moni.c @@ -0,0 +1,410 @@ +/******************************************************************************* + * + * Copyright (c) 2014 Bosch Software Innovations GmbH Germany. + * 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: + * Bosch Software Innovations GmbH - Please refer to git log + * Pascal Rieux - Please refer to git log + * + *******************************************************************************/ + +#include "liblwm2m.h" + +#include +#include +#include +#include + +// Resource Id's: +#define RES_M_OBJ_ID 0 +#define RES_M_OBJINST_ID 1 +#define RES_O_STATE 2 +#define RES_O_CURRENT 3 +#define RES_O_TIME 4 + +struct power_m_data_s +{ + char state[10]; + int current; + int time; + int W; +}; + +typedef struct power_m_data_s power_m_data_t; + +struct power_monitor_oi_s +{ //linked list: + struct power_monitor_oi_s* next; // matches lwm2m_list_t::next + uint16_t objInstId; // matches lwm2m_list_t::id + // resources + power_m_data_t *power_monitor_resource; +}; + +typedef struct power_monitor_oi_s power_monitor_oi_t; + +typedef enum +{ + STATE_NORMAL, + STATE_IDLE, + STATE_STANDBY, + STATE_SLEEP, +} dm_lwm2m_power_state_e; + + +static const char *power_state_str[] = {"NORMAL", "IDLE", "STANDBY", "SLEEP"}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: fetch_state + * + * Description: + * To get the state (idle, normal, sleep, standby) of a device + * + * Returned Value: + * + * +****************************************************************************/ +static void fetch_objID(int *value) +{ + (*value) = 8; +} +/****************************************************************************/ +static void fetch_objInstId(int *value) +{ + (*value) = 0; +} + +/*****************************************************************************/ +static void fetch_state(int *value) +{ + (*value) = STATE_NORMAL; +} + +/****************************************************************************/ + +static void fetch_time (int *value) +{ + (*value) = 1000; +} + +/****************************************************************************/ +static void fetch_current (int *value) +{ + (*value) = 1; +} +/****************************************************************************/ +static void fetch_write (int *value) +{ + + (*value) = 1; +} +/****************************************************************************/ + + +static uint8_t prv_set_value(lwm2m_data_t * dataP, power_m_data_t *powerDataP) +{ + int value; + + switch (dataP->id) + { + + case RES_O_STATE: + fetch_state(&value); + printf("state is %d\n", value); usleep(20000); + printf("Device power state is %s\n", power_state_str[value]); + strncpy(powerDataP->state, power_state_str[value], strlen(power_state_str[value])); + lwm2m_data_encode_string(powerDataP->state, dataP); + return COAP_205_CONTENT; + + case RES_O_CURRENT : + fetch_current(&value); + printf("Current consumption is %d\n", value); + powerDataP->current = value; + lwm2m_data_encode_int(powerDataP->current, dataP); + return COAP_205_CONTENT; + + case RES_O_TIME : + fetch_time(&value); + printf("Time spent in the state is %d\n", value); + powerDataP->time = value; + lwm2m_data_encode_int(powerDataP->time, dataP); + return COAP_205_CONTENT; + } +} + + + +static uint8_t prv_write_resources(uint16_t instanceId, int numData, + lwm2m_data_t* tlvArray, lwm2m_object_t* objectP, bool doCreate) +{ + int i; + uint8_t result; + int64_t value; + + power_monitor_oi_t* powerMonitorOiP = (power_monitor_oi_t *) + lwm2m_list_find(objectP->instanceList, instanceId); + if (NULL == powerMonitorOiP) + return COAP_404_NOT_FOUND ; + + i = 0; + do + { + switch (tlvArray[i].id) + { + case RES_O_STATE: + if (doCreate==false) + { + result = COAP_405_METHOD_NOT_ALLOWED; + } + else + { + if (1 != lwm2m_data_decode_int(&tlvArray[i], &value)) + { + result = COAP_400_BAD_REQUEST; + } + else + { + // TODO + } + } + break; + + case RES_O_CURRENT: + if (doCreate==false) + { + result = COAP_405_METHOD_NOT_ALLOWED; + } + else + { + if (1 != lwm2m_data_decode_int(&tlvArray[i], &value)) + { + result = COAP_400_BAD_REQUEST; + } + else + { + // TODO + } + } + break; + + case RES_O_TIME: + if (doCreate==false) + { + result = COAP_405_METHOD_NOT_ALLOWED; + } + else + { + if (1 != lwm2m_data_decode_int(&tlvArray[i], &value)) + { + result = COAP_400_BAD_REQUEST; + } + else + { + // TODO + } + } + break; + default: + return COAP_404_NOT_FOUND ; + } + i++; + } while (i < numData && result == COAP_204_CHANGED ); + + return result; +} + +static uint8_t prv_write(uint16_t instanceId, int numData, + lwm2m_data_t* tlvArray, lwm2m_object_t* objectP) +{ + return prv_write_resources(instanceId, numData, tlvArray, objectP, false); +} + +static uint8_t prv_delete(uint16_t id, lwm2m_object_t * objectP) +{ + power_monitor_oi_t* targetP; + + objectP->instanceList = lwm2m_list_remove(objectP->instanceList, id, + (lwm2m_list_t**)&targetP); + if (NULL == targetP) return COAP_404_NOT_FOUND; + +// LWM2M_LIST_FREE(targetP->accCtrlValList); + lwm2m_free(targetP); + + return COAP_202_DELETED; +} + +static uint8_t prv_read(uint16_t instanceId, + int * numDataP, + lwm2m_data_t ** dataArrayP, + lwm2m_object_t * objectP) +{ + uint8_t result; + int i; + + power_monitor_oi_t* powerMoniOiP = + (power_monitor_oi_t *)lwm2m_list_find(objectP->instanceList, instanceId); + printf("instance Id is %d\n", instanceId); + if (powerMoniOiP == NULL) + { + printf("No instance found\n"); + return COAP_404_NOT_FOUND ; + } + + + if (*numDataP == 0) + { + uint16_t resList[] = { + + RES_O_STATE, + RES_O_CURRENT, + RES_O_TIME + }; + 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, powerMoniOiP->power_monitor_resource); + i++; + } while (i < *numDataP && result == COAP_205_CONTENT); + return result; +} + +static uint8_t prv_create(uint16_t objInstId, int numData, + lwm2m_data_t * tlvArray, lwm2m_object_t * objectP) +{ + power_monitor_oi_t * targetP; + uint8_t result; + + targetP = (power_monitor_oi_t *)lwm2m_malloc(sizeof(power_monitor_oi_t)); + if (NULL == targetP) return COAP_500_INTERNAL_SERVER_ERROR; + memset(targetP, 0, sizeof(power_monitor_oi_t)); + + targetP->objInstId = objInstId; + objectP->instanceList = LWM2M_LIST_ADD(objectP->instanceList, targetP); + + result = prv_write_resources(objInstId, numData, tlvArray, objectP, true); + + if (result != COAP_204_CHANGED) + { + prv_delete(objInstId, objectP); + } + else + { + result = COAP_201_CREATED; + } + return result; +} + +lwm2m_object_t * get_power_monitor_object(void) +{ + lwm2m_object_t * powerObj; + + powerObj = (lwm2m_object_t *) malloc(sizeof(lwm2m_object_t)); + + if (powerObj != NULL) + { + memset(powerObj, 0x00, sizeof(lwm2m_object_t)); + + powerObj->objID = LWM2M_POWER_MONITOR_OBJECT_ID; + + powerObj->readFunc = prv_read; + powerObj->writeFunc = prv_write; + powerObj->createFunc = prv_create; + powerObj->deleteFunc = prv_delete; + powerObj->executeFunc = NULL; + } + + return powerObj; +} + + +bool power_monitor_obj_add_inst (lwm2m_object_t* powerMonitorObjP, uint16_t instId, + int domain_code) +{ + bool ret = false; + + if (NULL == powerMonitorObjP) + { + return ret; + } + else + { + // create an access control object instance + power_monitor_oi_t* powerMonitorOiP; + powerMonitorOiP = (power_monitor_oi_t *)lwm2m_malloc(sizeof(power_monitor_oi_t)); + if (NULL == powerMonitorOiP) + { + return ret; + } + else + { + memset(powerMonitorOiP, 0, sizeof(power_monitor_oi_t)); + // list: key + powerMonitorOiP->objInstId = instId; + // object instance data: + powerMonitorOiP->power_monitor_resource = (power_m_data_t *) + lwm2m_malloc(sizeof(power_m_data_t)); + powerMonitorOiP->power_monitor_resource->W = domain_code; + + powerMonitorObjP->instanceList = + LWM2M_LIST_ADD(powerMonitorObjP->instanceList, powerMonitorOiP); + ret = true; + } + } + return ret; +} +#if 0 +bool power_monitor_oi_add_ac_val (lwm2m_object_t* powerMonitorObjP, uint16_t instId, + uint16_t pmResId, uint16_t pmValue) +{ + bool ret = false; + + power_monitor_oi_t* powerMonitorOiP = (power_monitor_oi_t *) + lwm2m_list_find(powerMonitorObjP->instanceList, instId); + if (NULL == powerMonitorOiP) + return ret; + + return prv_add_ac_val (powerMonitorOiP, pmResId, pmValue); +} +#endif + +void power_monitor_free_object(lwm2m_object_t * objectP) +{ + power_monitor_oi_t *powermOiT; + power_monitor_oi_t *powermOiP = (power_monitor_oi_t*)objectP->instanceList; + while (powermOiP != NULL) + { + // first free acl (multiple resource!): + powermOiT = powermOiP; + powermOiP = powermOiP->next; + if (powermOiT->power_monitor_resource != NULL) + lwm2m_free(powermOiT->power_monitor_resource); + + lwm2m_free(powermOiT); + } + lwm2m_free(objectP); +} +/****************************************************************************/ + + + diff --git a/external/wakaama/examples/client/object_security.c b/external/wakaama/examples/client/object_security.c index 0ffb3f3..530711c 100644 --- a/external/wakaama/examples/client/object_security.c +++ b/external/wakaama/examples/client/object_security.c @@ -99,15 +99,15 @@ static uint8_t prv_get_value(lwm2m_data_t * dataP, return COAP_205_CONTENT; case LWM2M_SECURITY_PUBLIC_KEY_ID: - lwm2m_data_encode_opaque((uint8_t*)targetP->publicIdentity, targetP->publicIdLen, dataP); + lwm2m_data_encode_opaque(targetP->publicIdentity, targetP->publicIdLen, dataP); return COAP_205_CONTENT; case LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID: - lwm2m_data_encode_opaque((uint8_t*)targetP->serverPublicKey, targetP->serverPublicKeyLen, dataP); + lwm2m_data_encode_opaque(targetP->serverPublicKey, targetP->serverPublicKeyLen, dataP); return COAP_205_CONTENT; case LWM2M_SECURITY_SECRET_KEY_ID: - lwm2m_data_encode_opaque((uint8_t*)targetP->secretKey, targetP->secretKeyLen, dataP); + lwm2m_data_encode_opaque(targetP->secretKey, targetP->secretKeyLen, dataP); return COAP_205_CONTENT; case LWM2M_SECURITY_SMS_SECURITY_ID: @@ -115,11 +115,11 @@ static uint8_t prv_get_value(lwm2m_data_t * dataP, return COAP_205_CONTENT; case LWM2M_SECURITY_SMS_KEY_PARAM_ID: - lwm2m_data_encode_opaque((uint8_t*)targetP->smsParams, targetP->smsParamsLen, dataP); + lwm2m_data_encode_opaque(targetP->smsParams, targetP->smsParamsLen, dataP); return COAP_205_CONTENT; case LWM2M_SECURITY_SMS_SECRET_KEY_ID: - lwm2m_data_encode_opaque((uint8_t*)targetP->smsSecret, targetP->smsSecretLen, dataP); + lwm2m_data_encode_opaque(targetP->smsSecret, targetP->smsSecretLen, dataP); return COAP_205_CONTENT; case LWM2M_SECURITY_SMS_SERVER_NUMBER_ID: diff --git a/external/wakaama/examples/client/power_monitor_interface.c b/external/wakaama/examples/client/power_monitor_interface.c new file mode 100644 index 0000000..40845cb --- /dev/null +++ b/external/wakaama/examples/client/power_monitor_interface.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "power_monitor_interface.h" +#include "common_monitor_interface.h" + + +uint8_t pm_iobuffer[PROC_BUFFER_LEN]; + +void fetch_power_states(FAR char *powerstates) +{ + int ret; + uint8_t *filepath; + ret = asprintf(&filepath, "%s/power/system/states", PROC_MOUNTPOINT); + ret = readfile(filepath, pm_iobuffer, PROC_BUFFER_LEN); + if (ret == OK) + { + strncpy(powerstates, pm_iobuffer, strlen(pm_iobuffer)); + printf("powerstates %s:%s:%d\n", powerstates, pm_iobuffer, strlen(pm_iobuffer)); + } +} + +void fetch_battery_lifetime(FAR char *expectedlifetime) +{ + int ret; + uint8_t *filepath; + ret = mount(NULL, PROC_MOUNTPOINT, "procfs", 0, NULL); + printf("mount returns value %d\n", ret); + ret = asprintf(&filepath, "%s/power/battery/runtime", PROC_MOUNTPOINT); + ret = readfile(filepath, pm_iobuffer, PROC_BUFFER_LEN); + if (ret == OK) + { + strncpy(expectedlifetime, pm_iobuffer, strlen(pm_iobuffer)); + printf("expectedlifetime %s:%s:%d\n", expectedlifetime, pm_iobuffer, strlen(pm_iobuffer)); + } +} + +void fetch_battery_level(FAR char * batterylevel) +{ + int ret; + uint8_t *filepath; + ret = asprintf(&filepath, "%s/power/battery/life", PROC_MOUNTPOINT); + ret = readfile(filepath, pm_iobuffer, PROC_BUFFER_LEN); + if (ret == OK) + { + strncpy(batterylevel, pm_iobuffer, strlen(pm_iobuffer)); + printf("batterylevel %s:%s:%d\n", batterylevel, pm_iobuffer, strlen(pm_iobuffer)); + } +} \ No newline at end of file diff --git a/external/wakaama/examples/client/power_monitor_interface.h b/external/wakaama/examples/client/power_monitor_interface.h new file mode 100644 index 0000000..d0732f7 --- /dev/null +++ b/external/wakaama/examples/client/power_monitor_interface.h @@ -0,0 +1,18 @@ +#ifndef _POWER_MONITOR_INTERFACE_H +#define _POWER_MONITOR_INTERFACE_H +enum power_state_e { + POWER_STATE_HIGH = 0, + POWER_STATE_MEDIUM, + POWER_STATE_LOW +}; + +#define POWER_STATES_LEN 64 +#define BATTERY_LIFETIME_LEN 32 +#define BATTERY_LEVEL_LEN 32 +void fetch_power_states(FAR char *powerstates); +void fetch_power_curr_state(char *currstate); +void fetch_power_time_spent(char *timespent); +void fetch_power_battery_state(char *batterystate); +void fetch_battery_lifetime(FAR char *expectedlifetime); +void fetch_battery_level(FAR char * batterylevel); +#endif \ No newline at end of file