Giter VIP home page Giter VIP logo

connectivityfoundry / awalwm2m Goto Github PK

View Code? Open in Web Editor NEW
100.0 25.0 66.0 4.96 MB

Awa LWM2M is an implementation of the OMA Lightweight M2M protocol in C.

License: BSD 3-Clause "New" or "Revised" License

CMake 0.78% Makefile 0.20% C 61.16% Objective-C 0.08% Python 7.14% C++ 30.42% Shell 0.20% Dockerfile 0.02%
lwm2m m2m iot coap oma iot-framework device-management internet-of-things contiki openwrt

awalwm2m's Introduction

Imagination Technologies Limited logo


Awa LightweightM2M

Build Status License (3-Clause BSD) Coverity Scan

The Internet of Things (IoT) is currently fragmented by numerous proprietary methods of device management. In order for the IoT to reach its full potential, devices from different vendors must be able to communicate effectively with each other. This is where open standards such as the Open Mobile Alliance's (OMA) Lightweight Machine to Machine protocol (LWM2M) become important.

The LWM2M protocol has been designed to be highly efficient in terms of data transfer and memory footprint, making it suitable for deployment on larger gateway devices as well as the more constrained devices.

Awa LightweightM2M is an implementation of the OMA Lightweight M2M protocol that provides a secure and standards compliant device management solution to simplify the development of M2M applications by providing an intuitive API that enables customization without the need for an intimate knowledge of M2M protocols.

Awa application overview

Awa LightweightM2M is a development suite that provides a number of components and tools which can be combined in various ways depending on requirement. For example:

  • When running on a larger Linux based device, Awa LightweightM2M can be deployed as a series of daemons that interact with your application via the Awa API.
  • For more constrained devices, your application code can be built against the Awa static API and compiled along with the Awa LightweightM2M client code into a binary to be deployed on your device.

Regardless of the method, adding LWM2M support for your device is simply a matter of incorporating any objects you need into your own M2M application.


News

2016-08-17: Awa LightweightM2M is a finalist in the New Zealand Open Source Awards.

Getting started

The easiest way to get started with Awa LightweightM2M is to use our docker container.

Alternatively, you can build Awa on a Linux PC. The following instructions are based on the Ubuntu Linux distribution and assume that the user is familiar with the GNU compiler toolchain, and with the process of installing packages using the package manager.

Firstly, to obtain a copy of the Awa LightweightM2M source code:

  • Sign up for a Github account

  • Install Git:

sudo apt-get install git
  • Clone the repository:
git clone https://github.com/FlowM2M/AwaLWM2M.git

Further information can be found in the Quick start guide.


Documentation

This project assumes a basic knowledge of The Open Mobile Alliance's (OMA) LWM2M, its functionality and services. For more detail, see our introductory LWM2M overview.

Awa LightweightM2M documentation is available both at a general level (project information, user and developer guides), and a technical level (the API guide). All documentation is available in this repository. The doc directory contains information relating to the project in general, and the api/doc directory contains the lower level documentation for the Awa API.

Note that for our purposes the terms user and developer have the following definitions:

  • User - An M2M application developer who uses the tools and libraries supplied by this project as the foundation of, or enhancement to, their own M2M application.
  • Developer - A developer who develops for and contributes to the Awa LightweightM2M project.

General documentation

  • For project users:

    • For build instructions, see the Quick start guide.
    • Examples of how to use the tools can be found in the User guide.
    • A sample application tutorial using the Awa API can be found here.
    • A list of Awa API examples can be found here.
    • A sample application tutorial using the Awa Static API can be found here.
  • For contributors:

API guide

The Awa API documentation is available as a Doxygen presentation which is generated via the following process.

  1. Install Doxygen and Graphviz:

     sudo apt-get install doxygen graphviz
    
  2. Generate the documentation:

     make docs
    

The output can be found in the api/doc/html directory and viewed by opening index.html with your web browser.

For convenience you can also find the latest version of this documentation here.


Contributing

We welcome all contributions to this project and we give credit where it's due. Anything from enhancing functionality to improving documentation and bug reporting - it's all good.

Find out more in the contributor guide.

Credits

We would like to thank all of our current contributors.

We would also like to acknowledge and thank the authors of the following projects.

Development tasks

A list of ongoing development tasks can be seen here.


License information


Made in New Zealand.

awalwm2m's People

Contributors

abhimanyuv-img avatar abhimanyuv1 avatar andreibosco avatar boyvinall avatar cdewbery avatar cheekyhalf avatar datachi7d avatar davidantliff avatar delmet avatar dependabot[bot] avatar francois-berder avatar haydenb-img avatar mkowalczyk88 avatar mtusnio avatar pranit-sirsat-imgtec avatar scop avatar seank-img avatar shpinkso avatar thetoster avatar tonywalsworthimg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

awalwm2m's Issues

Possible memory corruption in lwm2m_bootstrap.c

In file lwm2m_bootstrap.c it looks like it's possible to have memory overwritten. Variable buffer is defined as 128 bytes long, it's filled by method Lwm2mCore_GetEndPointClientName. From signature of this method it looks like whole buffer might be used, so we will have 128 bytes of data. Then this buffer is copied to variable uriQuery which is also 128 bytes long, however copy is done through sprintf(uriQuery, "?ep=%s", buffer) which might result in memory corruption.

Static client Process function problem when ethernet link goes down

Hello!

First of all, thank you for the great framework! I´ve been using AwaLWM2M as configuration and side monitoring channel on my own custom IoT solution. I use AwaLWM2M compiled as static client in more than one kind of arm based device. AwaLWM2M objects are dedicated to configuration and runtinme information channel (for IoT data I have my own framwrok objects and other channels completely independent). For what I need, it is working very well, but unfortunetly I detected a behavior that is causing a problem:

My framework is also based on a continuous loop with various steps, one of these steps is obviously to call: lwm2m_client_->Process(), which is no more than a wrapper to: AwaStaticClient_Process(...);

The solution works rock steady 24/7 (even with the Awa server down, no problem, I know that is by design it only logs registration unsucessfull. Once the server is up again, it connects with no problem).

BUT, if we disconnect the ethernet cable from the device and the ethernet link really goes down, the static client is not able to recover and the AwaStaticClient_Process(...) function blocks, blocking all the loop and the device becomes unresponsive.

As a workaround, I am thinking to put the Process() call inside some kind of worker thread to generate a timeout. Are you aware of the bahavior I described?

The other possibility is to try to look at the Awa source code and see if I can help. May you point the directions to where the problem may be? I am willing to help.

Regards,
Luiz Eduardo Giampaoli

Define custom objects when awa-serverd starts

It would be nice to have a config file into which I can put list of my custom IPSO objects with resources. So when server start after crash/reboot it will have those objects/resources predefined. This will reduce need to call awa-server-define after starting server.

Bootstrap server security flag changes between the initial client write and server response

This might be caused by the workaround described in #296, however I cannot say that with full certainty.

I managed to get the bootstrap going with the workaround at mtusnio/AwaLWM2M@17d8926. After the initial client write is done, the security flag changes from 1 to 0, and the subsequent read of the bootstrap server response is treated like a plaintext read instead of an encrypted message, which obviously derails the process. Again, this might be due to the workaround causing the resolution to kick in every time the ServerIsBootstrap call is made. I quickly got this to work by doing the changes as found in mtusnio/AwaLWM2M@ca225d6, however this is just a quick workaround the issue as far as I can tell.

I'll put up some more logs on Monday with proper debug messages to show exactly where the issue pops up.

Add section on threading restrictions

Currently Awa doesn't support multiple threads. In particular, a session should not be shared between two or more threads. This needs to be explained in the documentation.

IPv6 Link Local address handling

I was trying to use AwaLWM2M between Ci40 and 6lowpan clicker.
I saw following issues:

  1. Even if I explicitly set local ip address on a command line argument of awa_serverd (example: awa_serverd --interface lowpan0 --addressFamily 6 --port 5683 --ip=fe80::c892:fd83:e6b7:c392 -v -o temp_object.xml) it still wants to bind to the Global Scope address (for example to 2001:1418:100::1/48). It should bind to the address I passed as an argument. See "Lwm2mCore_GetIPAddressFromInterface": there is the if-else statement checking firstly "globalIpv6Address" and then does not care about link local at all.
  2. When I forced it to bind to the local link address (by hardcoding it in code) I encoutered new problems. The link local address is kept together with iface name "fe80::c892:fd83:e6b7:c392%lowpan0". Normally this is not a problem, but in function "NetworkAddress_FromIPAddress" there is a call to "inet_pton" which does NOT accept "%iface" format.
  3. When I forced inet_pton to succeed (by hardcoding address without "%iface" in code) it came out that call to "bind" in NetworkSocket_StartListening fails because of "invalid argument". This is because for link local IPv6 addresses, the "sin6_scope_id" should be set.
  4. When I forced sin6_scope_id to be set (by hardcoding result->Address.Sin6.sin6_scope_id = if_nametoindex("lowpan0") inside "NetworkAddress_FromIPAddress") I finally could see my AwaLWM2M client. The UDP packets were exchanged so I saw my client on a list (awa-server-list-clients). Unfortunetly, when I tried to read my resource I got segmentation fault on a server side. I didn't debug it further.

Daemonizing Awa client fails to connect with the device server

I am using following command to start Awa client and connect it to my device server,
awa_clientd --bootstrap coaps://deviceserver.creatordev.io:15684 -s -c /root/certificate.crt --endPointName "weather_station" -d
Executing this command does not display any error but my ci40 client fails to be displayed in my Developer Console account.

Instead, if I use,
awa_clientd --bootstrap coaps://deviceserver.creatordev.io:15684 --endPointName WeatherStationDevice -s -c /etc/config/certificate.crt &
above command client is successfully created and displayed in the Developer Console account.

Lack of dtls retransmission during handshake.

There is no retransmission on dtls protocol layer during handshake.
Probably the issue is common for dtls abstraction, checked against tinydtls and gnutls.

For example:
tinydtls has a callback dtls_check_retransmit() which should be run periodically in application main loop for at least not connected peers. It is never used in AwaLWM2M project.

Reproduction steps:
To simple simulate datagram drop run secure client when server is offline, after couple seconds run server. There is one dtls packet "client_hello" sent, no retransmission. After 32 seconds registration timeout on high protocol lever can be observed.

I think that it is good to have full functional dtls layer with retransmit working. It improves connectivity.

bootstrap configuration file load fail

I'm trying the following configuration file for the bootstrap server:

ServerURI=coap://192.168.30.100:5683
SecurityMode=0
ServerID=1
HoldOffTime=10
ShortServerID=1
Binding=U
LifeTime=30
DisableTimeout=86400
DefaultMinimumPeriod=1
DefaultMaximumPeriod=-1
NotificationStoringWhenDisabledOrOffline=1

And the server is started this way:
$ ./awa_bootstrapd --port 15685 --config bootstrtap.conf

And I aways receive this message.

 [ERROR] [lwm2m_bootstrap.c:104] Configuration file load failed
 [ERROR] [lwm2m_bootstrap.c:247] Failed to initialise bootstrap config for server 0

There is any problem with the configuration file?
Tested with master and 0.2.3

Single user application limitation for IPC interface

Thank you! Awa LwM2M looks like one of the best LwM2M frameworks available right now.

The user guide states that "Currently the IPC interface is implemented as a simple UDP channel, with an associated UDP port. It is recommended that only a single user application connect to the daemon's IPC interface at any time. ". Can you please give some details on why this limitation exists?

Also, what is the current status of the Python APIs for IPC interface?

Contiki lwm2m fails to register to the AwaLwM2M server

Hi,

I'm trying connect a contiki device to the AwaLwM2M server but the server respond with a "4.00 Bad request" message to the registration:

 [DEBUG] [network_abstraction_linux.c:410] Address add (received)
 [DEBUG] [coap_abstraction_erbium.c:236] Coap POST for /rd
 [DEBUG] [lwm2m_registration.c:418] Lwm2m_RegisterPost /rd ?ep=SmartSensor4B00063A7631
 [DEBUG] [coap_abstraction_erbium.c:265] Coap Response code 400

Wireshark sniffer packet:

image

I start the server as follow:

$ ./awa_serverd -f 6 -a bbbb::10
      _                  _            __  __ ____  __  __ 
     / \__      ____ _  | | __      _|  \/  |___ \|  \/  |
    / _ \ \ /\ / / _` | | | \ \ /\ / / |\/| | __) | |\/| |
   / ___ \ V  V / (_| | | |__\ V  V /| |  | |/ __/| |  | |
  /_/   \_\_/\_/ \__,_| |_____\_/\_/ |_|  |_|_____|_|  |_|

   Copyright (C) 2016, Imagination Technologies Limited.

 [INFO] Awa LWM2M Server, version 0.2.4
 [INFO]   Process ID     : 5902
 [INFO]   DTLS library   : None
 [INFO]   CoAP library   : Erbium
 [INFO]   CoAP port      : 5683
 [INFO]   CoAP Security  : None
 [INFO]   IPC port       : 54321
 [INFO]   IP Address     : bbbb::10
 [INFO] Bind port: 5683

The Awa LwM2M client connects successfully to the server:

$ ./awa_clientd --port 6000 -a 6 --endPointName client1 -f bootstrap.conf
      _                  _            __  __ ____  __  __ 
     / \__      ____ _  | | __      _|  \/  |___ \|  \/  |
    / _ \ \ /\ / / _` | | | \ \ /\ / / |\/| | __) | |\/| |
   / ___ \ V  V / (_| | | |__\ V  V /| |  | |/ __/| |  | |
  /_/   \_\_/\_/ \__,_| |_____\_/\_/ |_|  |_|_____|_|  |_|

   Copyright (C) 2016, Imagination Technologies Limited.

 [INFO] Awa LWM2M Client, version 0.2.4
 [INFO]   Process ID     : 6527
 [INFO]   Endpoint name  : 'client1'
 [INFO]   DTLS library   : None
 [INFO]   CoAP library   : Erbium
 [INFO]   CoAP port      : 6000
 [INFO]   IPC port       : 12345
 [INFO]   Address family : IPv6
 [INFO] Bind port: 6000
 [INFO] Factory Bootstrap:
 [INFO] Server Configuration
 [INFO] ====================
 [INFO] ServerURI            : coap://[bbbb::10]:5683
 [INFO] SecurityMode         : 0
 [INFO] SecretKey            : 
 [INFO] PublicKey            : 
 [INFO] ServerID             : 1
 [INFO] HoldOffTime          : 30
 [INFO] ShortServerID        : 1
 [INFO] Binding              : U
 [INFO] LifeTime             : 30
 [INFO] DisableTimeout       : 86400
 [INFO] DefaultMinimumPeriod : 1
 [INFO] DefaultMaximumPeriod : -1
 [INFO] NotificationStoringWhenDisabledOrOffline : 1
 [INFO] Register with coap://[bbbb::10]:5683
 [INFO] Coap request: coap://[bbbb::10]:5683/rd?ep=client1&lt=30&b=U
 [INFO] Registered with [bbbb::10]:5683
 [INFO] Coap request: coap://[bbbb::10]:5683/rd/2?lt=30&b=U

My contiki device connects to a leshan server without problem on the same machine and I can interact with it through the leshan web interface.

java -jar leshan-server-demo.jar

image

I'm new to the lwM2M protocol. I couldn't actually understand why that doesn't work with the AwaLwM2M server. I don't know how to debug this furthermore.

I'd love to test the Awa LwM2M server with my devices.
Thanks a lot for your help.

Path_MakePath should handle ResourceInstanceID

The api/src/path.c:Path_MakePath should handle ResourceInstanceID argument. The use case is for example when running awa-server-read. Currently, if you pass full URI (for example "/3303/0/5700/0") you'll get the result twice. Also, I guess you cannot read specific resource instance if you have many of them.

AwaClientSession_Connect fails with AwaError_IPCError when STDIN has been closed

When writing a daemon that connects to awa-clientd, if STDIN is closed then AwaClientSession_Connect returns the error code, AwaError_IPCError.

If I close STDIN and leave STDOUT and STDERR open the I get the following output;
[ipc.c:157] Success: Could not create UDP Socket
[session_common.c:510] AwaError_IPCError: Channel missing

Awa 'daemons' do not follow the Forking Readiness Protocol

Affects 0.1.9.

Services are considered ready after the MainPID exits (after the double fork), allowing for time to setup sockets or other resources needed to handle client requests (e.g. a database server or a web server). Awa daemons do not do this, so dependent services may fail to startup properly, as their dependencies aren't actually ready when systemd declares them to be.

http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/unix-daemon-readiness-protocol-problems.html

Add tool to remove client registration from server.

It would be nice to have some tool/script which allows to kick some client from server (unregister).
At this moment I need to wait until instance of crashed client unregister due to timeout, which is little frustrating.

Awa static client fails to retry after registration failed timeout

If the Awa static client registers while the lwm2m server is down - it bootstraps OK then posts a registration request and hangs, with no retry on timeout. e.g.: the client log stops after the following:
...
[INFO] [lwm2m_registration.c:137] Register with coap://127.0.0.1:5683
[DEBUG] [lwm2m_registration.c:139] Register: POST coap://127.0.0.1:5683/rd?ep=AwaStaticClient1&lt=30&b=U

The same test with awa_clientd recovers properly when the server comes back up:
...
[INFO] Register with coap://127.0.0.1:5683
[ERROR] Transaction Timed out
[ERROR] Registration Failed! 504
[INFO] Register with coap://127.0.0.1:5683
[INFO] Registered with 127.0.0.1:5683

incorrect pointer checking

Found a potential bug in the code, the pointer in the below code check will always be true.
Line: 279 - char path[URL_PATH_SIZE] = {0};
File: button_led_controller.c
Line: 288- if (path != NULL)
This is because "path" is a local character array,

should this be
if (path[0] != NULL)

because in the file "api/src/path.c" , the first element of the path is set to NULL if things go wrong?
Line: 279
path[0] = '\0';

[PROPOSAL] - Add configuration file for daemons

Hello,

Here is a proposal for configuring daemon using a file instead of specifying options on the command line.

Description

Launching the client daemon can require many options. For instance, this project, https://github.com/CreatorDev/ci40-weather-station, asks people to run
this command to launch the client daemon:

$ awa_clientd --bootstrap coaps://deviceserver.flowcloud.systems:15684 --endPointName WeatherStationDevice --certificate=/root/certificate.crt --ipcPort 12345 -p7000 -d

It would be more readable if all these options are located in a file. Each line would set only one value in this format: name(=value)?.
Using previous example, these options would be specified in a file config.cfg:

bootstrap=coaps://deviceserver.flowcloud.systems:15684
endPointName=WeatherStationDevice
certificate=/root/certificate.crt
ipcPort=12345
port=7000
daemonize

and the client would be launched in this way:

$ awa_clientd config.cfg

Implementation

I suggest to add, in the main function of all daemons, the following logic:

if argc > 1 && argv[1] matches *.cfg
    override argc and argv with content from config file

And the parsing of the configuration file would be done in daemon/src/common/config.c. It would produce an array of strings, along with the number of strings in the array.
This would be written roughly in this way:

/**
 * @param[in] filePath
 * @param[out] args 
 * @return negative number if an error occured, argc otherwise
 */
int ParseConfigurationFile(char *filePath, char **args)
{
    ret = 1
    open file in filePath
    n = number of non-empty lines

    for each line in file:
        if line is empty:
            skip
        name,value = match(line, "name(=value)?")
        args.append("--" + name)
        ret++    
        if value:
            args.append(value) 
            ret++

    return ret
}

Add common Session_Process() function to allow the client and server API to co-exist in the same application

In the case where a user wants to use both the Client and Server APIs in the same application, the
AwaServerSession_Process() and AwaClientSession_Process() must be called sequentially one after another to handle events. This results in the process call from the Server API blocking the Client API and vice versa. To get around this the timeout can be reduced, but this results in the main loop essentially polling the API for events, which isn't really that desirable. The API would be much improved if a common AwaSession_Process() function was introduced to handle events from both the Client and Server API.

Searching for a position in the Security Object /0

I've observed the following issue while testing awa_clientd.
The bootstrap server and OMA server (leshan) are launched on a single host on different ports as follows:

ps@ps-vm-deb2:~/oma-test$ awa-client-get /0
LWM2MSecurity[/0/0]:
    LWM2MServerURI[/0/0/0]: coap://localhost:15685
    BootstrapServer[/0/0/1]: True
    SecurityMode[/0/0/2]: 0
    PublicKeyorIDentity[/0/0/3]: Opaque (0):
    ServerPublicKeyorIDentity[/0/0/4]: Opaque (0):
    SecretKey[/0/0/5]: Opaque (0):
    SMSBindingKeyParameters[/0/0/7]: Opaque (0):
    SMSBindingSecretKeys[/0/0/8]: Opaque (0):
    ShortServerID[/0/0/10]: 0
    ClientHoldOffTime[/0/0/11]: 0
LWM2MSecurity[/0/1]:
    LWM2MServerURI[/0/1/0]: coap://127.0.0.1:5683
    BootstrapServer[/0/1/1]: False
    SecurityMode[/0/1/2]: 3
    PublicKeyorIDentity[/0/1/3]: Opaque (11):5B 50 75 62 6C 69 63 4B 65 79 5D
    ServerPublicKeyorIDentity[/0/1/4]: Opaque (0):
    SecretKey[/0/1/5]: Opaque (11):5B 53 65 63 72 65 74 4B 65 79 5D
    ShortServerID[/0/1/10]: 1
    ClientHoldOffTime[/0/1/11]: 30

after bootstraping & registration process I see the following logs for requests from the OMA server:

 [DEBUG] [coap_abstraction_erbium.c:249] Coap PUT for /1001/0/0
 [DEBUG] [lwm2m_client_core.c:1893] BOOTSTRAP WRITE: /1001/0/0
 [DEBUG] [lwm2m_client_core.c:163] Deserialise resource 1001/0/0:
 [DEBUG] [lwm2m_observers.c:209] All attributes checked out for server 0, Will notify change to /1001/0/0 when possible.
 [DEBUG] [coap_abstraction_erbium.c:265] Coap Response code 204
 [DEBUG] [lwm2m_xml_interface.c:76] Send 317 bytes on IPC

BOOTSTRAP WRITE seemed suspicious for me since the bootstraping process was already finished and the source of requests was OMA server only (BS server was even killed).

After some investigation I've found the problem in core\src\client\lwm2m_client_core.c while looking for a position in the Security Object (representing a server endpoint):

static LWM2MSecurityInfo * GetSecurityInfoForAddress(Lwm2mContextType * context, AddressType * address)
{
    LWM2MSecurityInfo * info = NULL;
    struct ListHead * current;
    ListForEach(current, Lwm2mCore_GetSecurityObjectList(context))
    {
        LWM2MSecurityInfo * securityInfo = ListEntry(current, LWM2MSecurityInfo, list);
        if (Lwm2mCore_CompareAddresses(address, &securityInfo->address) == 0)
        {
            info = securityInfo;
            break;
        }
    }
    return info;
}

Lwm2mCore_CompareAddresses() uses only an IP4/6 address while searching for a position. Port is completly ignored. E.g. for the Linux implementation we have:

int Lwm2mCore_CompareAddresses(AddressType * addr1, AddressType * addr2)
{
    if (addr1->Addr.Sa.sa_family != addr2->Addr.Sa.sa_family)
    {
        return -1;
    }

    switch (addr1->Addr.Sa.sa_family)
    {
        case AF_INET:
            return memcmp(&addr1->Addr.Sin.sin_addr.s_addr, &addr2->Addr.Sin.sin_addr, sizeof(addr2->Addr.Sin.sin_addr));
        case AF_INET6:
            return memcmp(&addr1->Addr.Sin6.sin6_addr, &addr2->Addr.Sin6.sin6_addr, sizeof(addr2->Addr.Sin6.sin6_addr));
        default:
            Lwm2m_Error("Unsupported address family: %d\n", addr1->Addr.Sa.sa_family);
            break;
    }

    return -1;
}

This causes the servers installed on the same host as indistinguishable (as occurred in my case - the OMA server was identified as BS server).

Investigating further the issue I've found that in the client's device management handler DeviceManagmentEndpointHandler() in lwm2m_client_core.c the AddressType * addr arg contains (probably?) garbage data in the port field (that is addr->Addr.Sin.sin_port for the Linux abstraction) but I didn't have time to investigate what was a root-cause of this.

Question about building only lwm2m static client

hello,

I'm new to AWA and I'm trying to get the smallest footprint needed for the lwm2m client. I've gone through and removed the deamons from my awa directory and I see that the dependency is there for the xml files, so I've put those back in and removed everything else. I am also stripping out the api directory from anything that references the server.

I'm not sure if there's an easier way to build a small footprint of the lwm2m client. Also, I'm not quite sure if there's a strict dependency on xml and why that would be. I have a feeling that's the reason why I get a 500KB client everytime (because of the xml). I'm not building tests or anything extra.

Any guidance on how I can do this easily and the right way would be greatly appreciated? If this is not the correct place to address this, please let me know of other ways to ask these questions.

Thanks,
Maya

awa_clientd DTLS does not send packets

GnuTLS, preshared key inserted from command line
client does not communicate with server (no UDP packets coming to server from client, verified with tcpdump)

coap (unsecured) works fine

You don't need lwm2m server to verify this, just tcpdump :)
Affects master HEAD ad624b5
[DEBUG] [coap_abstraction_erbium.c:302] resolve address from Uri: coaps://10.89.15.1:5684 [DEBUG] [network_abstraction_linux.c:349] Address add: coaps://10.89.15.1:5684 [DEBUG] [network_abstraction_linux.c:304] Address free: coaps://10.89.15.1:5684 [DEBUG] [lwm2m_server_object.c:116] Creating server object instance [DEBUG] [lwm2m_registration.c:268] Registration update for ServerID 0 scheduled [DEBUG] [lwm2m_bootstrap.c:99] Lwm2m_BootstrapFromSmartCard [DEBUG] [lwm2m_bootstrap.c:105] Lwm2m_BootstrapFromFactory: True [DEBUG] [lwm2m_registration.c:135] Registration: POST coaps://10.89.15.1:5684 /rd ?ep=RPI&lt=30&b=U </>;ct=1543,</1/0>,</2/0>,</2/1>,</2/2>,</2/3>,</3/0>,</4/0>,</7>,</5/0>,</6/0> [INFO] [lwm2m_registration.c:137] Register with coaps://10.89.15.1:5684 [DEBUG] [lwm2m_registration.c:139] Register: POST coaps://10.89.15.1:5684/rd?ep=RPI&lt=30&b=U [DEBUG] [network_abstraction_linux.c:349] Address add: coaps://10.89.15.1:5684 [INFO] [coap_abstraction_erbium.c:375] Coap request: coaps://10.89.15.1:5684/rd?ep=RPI&lt=30&b=U [DEBUG] [coap_abstraction_erbium.c:441] Sending transaction [0]: 0x1b984f8 [ERROR] [lwm2m_registration.c:309] Registration attempt timed out. [DEBUG] [lwm2m_registration.c:135] Registration: POST coaps://10.89.15.1:5684 /rd ?ep=RPI&lt=30&b=U </>;ct=1543,</1/0>,</2/0>,</2/1>,</2/2>,</2/3>,</3/0>,</4/0>,</7>,</5/0>,</6/0> [INFO] [lwm2m_registration.c:137] Register with coaps://10.89.15.1:5684 [DEBUG] [lwm2m_registration.c:139] Register: POST coaps://10.89.15.1:5684/rd?ep=RPI&lt=30&b=U [INFO] [coap_abstraction_erbium.c:375] Coap request: coaps://10.89.15.1:5684/rd?ep=RPI&lt=30&b=U [DEBUG] [coap_abstraction_erbium.c:441] Sending transaction [1]: 0x1b98768 [ERROR] [lwm2m_registration.c:309] Registration attempt timed out. [DEBUG] [lwm2m_registration.c:135] Registration: POST coaps://10.89.15.1:5684 /rd ?ep=RPI&lt=30&b=U </>;ct=1543,</1/0>,</2/0>,</2/1>,</2/2>,</2/3>,</3/0>,</4/0>,</7>,</5/0>,</6/0> [INFO] [lwm2m_registration.c:137] Register with coaps://10.89.15.1:5684 [DEBUG] [lwm2m_registration.c:139] Register: POST coaps://10.89.15.1:5684/rd?ep=RPI&lt=30&b=U [INFO] [coap_abstraction_erbium.c:375] Coap request: coaps://10.89.15.1:5684/rd?ep=RPI&lt=30&b=U [WARN] [coap_abstraction_erbium.c:422] Canceled previous transaction [0]: 0x1b984f8 [DEBUG] [coap_abstraction_erbium.c:441] Sending transaction [0]: 0x1b984f8 [ERROR] [lwm2m_registration.c:309] Registration attempt timed out.

Contiki: "No response to client initiated bootstrap"

I'm observing "No response to client initiated bootstrap" error during client-initiated bootstrap on Contiki 6lowpan clicker board. Although the error message is displayed, the bootstrap process completes successfully. I was using global IPv6 addresses.

From my investigation it seems the UDP packet with bootstrap request is not sent because uIP stack is doing Neighbor Solicitation procedure. Instead of sending actual UDP packet after neighbor is discovered, the packet is dropped by network stack. Only after couple of re-tries, when UDP packet is requested to be sent when Neighbor Discovery is completed, the actual UDP data is in the air. Unfortunately, the uIP API doesn't provide return result of UDP send function, so it's really hard to know from app point of view if packet was actually sent. All in all this seems like a Contiki issue, but I'm reporting it here for the record (if someone see the same error) or if you have any idea of workaround/fix it.
Maybe the error should be just a warning? Generally, it's ok if UDP packet doesn't reach a target and it's common practice to re-try UDP communication.
Also note, there is open pull request on Contiki github regarding ND: contiki-os/contiki#1765.

Server operation timeouts can potentially discard partial successful results

If one or more paths of a multi-path server request fail due to client timeout, any successful paths are discarded and the entire operation is returned to the API as "timed out".

Instead, each individual failed path should have AwaLWM2MError_Timeout, but the overall operation should return AwaError_Response.

This can happen when the IPC timeout is less than the CoAP timeout.

Add top-level sequence diagrams

It would be useful to illustrate information flow via the API with some sequence diagrams. For example:

  • Client-side "set" operation
  • Server-side "read" operation
  • Server-side "observe" operation

Wakama vs Awa

What are the biggest differences between wakaama and Awa?

Speed up unit tests

The Awa unit tests currently take minutes to run. A significant number of unit tests have arbitrary and explicit delays, often waiting for some action to complete. Some of these can be removed by the use of Server Events, or restructuring tests.

Add Contiki documentation

Awa has support for Contiki however this is not adequately described in the documentation. We need some sections that explain how Awa can be used with Contiki.

Static API - server initiated bootstrap

I have a question: how to perform server initiated bootstrap on Contiki? Alternatively, how to re-trigger client initiated bootstrap if the server was restarted? Currently, I only run "AwaStaticClient_Process" in main loop and I don't see any way to register callbacks for handling situation when server is restarted and bootstrap procedure must be repeated.

Client subscription on change doesn't work

Another issue from my side. Now the problem is related to client's subscription on a change.

I have my own object /1001/0 with a single resource 0 of type boolean and a subscription to a change of that resource via local client's C code as follows:

// subscribe to a change
AwaClientSubscribeOperation *subscribeOperation =
    AwaClientSubscribeOperation_New(session);

AwaClientChangeSubscription *subscription =
    AwaClientChangeSubscription_New("/1001/0/0", heaterOn_cb, NULL);
AwaClientSubscribeOperation_AddChangeSubscription(
    subscribeOperation, subscription);
AwaClientSubscribeOperation_Perform(
    subscribeOperation, OPERATION_PERFORM_TIMEOUT);

NOTE: The object and the resource are not mandatory, therefore are created at the local client startup:

AwaClientSetOperation_CreateObjectInstance(operation, "/1001/0");
AwaClientSetOperation_CreateOptionalResource(operation, "/1001/0/1");
AwaClientSetOperation_AddValueAsBoolean(operation, "/1001/0/0", heaterOn);

On the previous version of the library (before the fix of my previous bug #269 with BOOTSTRAP WRITE) it worked fine (client was notified via subscription), now (WRITE via CoAP PUT) it doesn't work.

After some investigation I found the root cause in lwm2m_client_core.c and the CoAP PUT handler HandlePutRequest():

switch (Lwm2mTreeNode_GetType(root))
{
    case Lwm2mTreeNodeType_Object:
        Lwm2m_Error("Cannot replace a whole object using PUT\n");
        *responseCode = AwaResult_MethodNotAllowed;
        break;
    case Lwm2mTreeNodeType_ObjectInstance:
        if ((*responseCode = Lwm2mCore_CheckWritePermissionsForObjectInstanceNode(context, origin, root, oir[0], false)) == AwaResult_Success)
        {
            if (Lwm2mCore_Exists(context, oir[0], oir[1], oir[2]) && Lwm2mCore_Delete(context, origin, oir[0], oir[1], oir[2], true) == AwaResult_SuccessDeleted)
            {
                *responseCode = Lwm2mCore_ParseObjectInstanceNodeAndWriteToStore(context, root, oir[0], true, true, false, &oir[1]);
            }
            else
            {
                *responseCode = AwaResult_NotFound;
            }
        }
        break;
    case Lwm2mTreeNodeType_Resource:
        if ((*responseCode = Lwm2mCore_CheckWritePermissionsForResourceNode(context, origin, root, oir[0], oir[1], false)) == AwaResult_Success)
        {
            if (Lwm2mCore_Exists(context, oir[0], oir[1], oir[2]) && Lwm2mCore_Delete(context, origin, oir[0], oir[1], oir[2], true) == AwaResult_SuccessDeleted)
            {
                *responseCode = Lwm2mCore_ParseResourceNodeAndWriteToStore(context, root, oir[0], oir[1], true);
            }
            else
            {
                *responseCode = AwaResult_NotFound;
            }
        }
        break;
    case Lwm2mTreeNodeType_ResourceInstance: // no break
    default:
        // Should never happen.
        Lwm2m_Error("Internal Error\n");
        *responseCode = AwaResult_InternalError;
        break;
}

The root cause is calling Lwm2mCore_Delete() before writing (replacing) object instance OR resource instance.

I don't know the rationale of such implementation for PUT method handling, but such approach will cause object/resource re-creation via Lwm2mCore_ParseObjectInstanceNodeAndWriteToStore() / Lwm2mCore_ParseResourceNodeAndWriteToStore() call for every time on the object instance/resource change. This effectively leads to missing the object/resource change by the registered observer(s). See Lwm2m_MarkObserversChanged() while comparing the new and old values.

On the previous version of the lib (tag 0.2.3) it worked fine since for BOOTSTRAP WRITE (HandleBootstrapPutRequest() handler), the deletion was not called - bootstrapping assumes persistent objects existence.

NOTE: The root cause described here also causes the observer(s) are not called when staring a client with a factory bootstrap file (not via the BS server)!

After removing Lwm2mCore_Delete() calls in HandlePutRequest() everything works fine.

UPDATE: The delete procedure was introduced by the commit 5988c12: "Fixed PUT / POST handling on multiple instance and mandatory resources.", so there is probably some rationale for doing this related to multi-instance handling. BTW as I previously mentioned - my object was not mandatory.

TinyDTLS library as PSK encrypt layer doesn't work with 32 byte keys.

I've builded client on ci40 / linux with enabled tinyDTLS as a security layer. Then I tried to run awa_clientd with PSK identity/key generated on Device Server platform. But as a result I'm getting errors about wrong key sizes. Here is log from console:

[INFO] Awa LWM2M Client, version 0.2.4
[INFO] Process ID : 22396
[INFO] Endpoint name : 'Awa Client'
[INFO] DTLS library : TinyDTLS
[INFO] CoAP library : Erbium
[INFO] CoAP port : 6000
[INFO] IPC port : 12345
[INFO] Address family : IPv4
[INFO] Bind port: 6000
[INFO] Try existing server entries
[INFO] No servers are defined
[INFO] Hold Off expired - attempt client-initiated bootstrap
[INFO] Bootstrap with coaps://ds-mono.flowcloud.systems:15684/bs?ep=Awa Client
[INFO] Coap request: coaps://ds-mono.flowcloud.systems:15684/bs?ep=Awa Client
[WARN] cannot set psk -- buffer too small
Nov 17 14:43:59 CRIT no psk key for session available
Nov 17 14:43:59 WARN error in check_server_hellodone err: -592
Nov 17 14:43:59 WARN error while handling handshake packet

Resolve of DNS is not working correctly on contiki.

It looks like code inside lwm2m_security_object.c is expecting that DNS will be resolved in calls while performing boostratp. However tests shows that bootstraping process might happen before DNS will be resolved. There is no next call to obtain resolved address for network layer. Probably some pulling mechanism is required to update proper structures. We found temporary workaround by adding following lines into mentioned file:

bool Lwm2mCore_ServerIsBootstrap(Lwm2mContextType * context, AddressType * address)
  {		  {
      bool result = false;
 +
 +    struct ListHead * current;
 +    ListForEach(current, Lwm2mCore_GetSecurityObjectList(context))
 +    {
 +        LWM2MSecurityInfo * securityInfo = ListEntry(current, LWM2MSecurityInfo, list);
 +        Lwm2m_Debug("Address found: %s, is bootstrap: %i\n", Lwm2mCore_DebugPrintAddress(&securityInfo->address),
 +        securityInfo->IsBootstrapServer);
 +        if(securityInfo->AddressResolved == 0)
 +        {
 +            securityInfo->AddressResolved = coap_ResolveAddressByURI(securityInfo->ServerURI, &securityInfo->address);
 +        }
 +    }
 +
LWM2MSecurityInfo * security = GetSecurityInfoForAddress(context, address);

Note: We spotted problem in contiki network layer (async handling of DNS requests) however given workaround is placed in security layer, which might be misleading.

Block transfer support

Hello everyone!

Simple question:

Does the Awa library support the Large Object transfer? In other words does tne Awa library
support a coap block transfer for transferring objects larger then single message size?

Best Regards

WB

Bootstrapping and notification issues with awa-0.2.3 on Clickers to Ci40

We are using awa-0.2.3 for CreatorKit project.

We have awa-0.1.10 or awa-0.2.1 running on clickers and they could bootstrap/register with awa server on Ci40 (0.2.3). However when we integrated 0.2.3 on Clickers (see CreatorKit/button-sensor#14),

Now its not able to bootstrap properly to Ci40 running awa-0.2.3. it takes almost 8-10 attempts before it can bootstrap to Ci40.
But after that (our button-sensor applications sends notifications for each button-press), notifications sent to Ci40 are not received there.
I can see with button-sensor app on clicker with awa-0.2.3 is trying to send notify to 13078 port.

�[0mButton press event received
�[37;01m [DEBUG] �[0m�[33m[lwm2m_observers.c:209] �[0m�[0mAll attributes checked out for server 0, Will notify change to /3200/0/5501 when possible.
�[0m�[37;01m [DEBUG] �[0m�[33m[lwm2m_tree_builder.c:62] �[0m�[0mTreebuilder length: 8
�[0m�[37;01m [DEBUG] �[0m�[33m[lwm2m_client_core.c:1355] �[0m�[0mSend Notify to coap://[2001:1418:0100:0000:0000:0000:0000:0001]:13078/3200/0/5501
�[0m�[37;01m [DEBUG] �[0m�[33m[network_abstraction_contiki.c:137] �[0m�[0mCache hit on look up [2001:1418:0100:0000:0000:0000:0000:0001]
�[0m�[37;01m [DEBUG] �[0m�[33m[coap_abstraction_erbium.c:528] �[0m�[0mCoap notify: coap://[2001:1418:0100:0000:0000:0000:0000:0001]:13078/3200/0/5501

where as when it used to succeed with awa-0.2.1 or earlier, it used to send notify to 5683 port.

�[0mButton press event received
�[37;01m [DEBUG] �[0m�[33m[lwm2m_observers.c:209] �[0m�[0mAll attributes checked out for server 0, Will notify change to /3200/0/5501 when possible.
�[0m�[37;01m [DEBUG] �[0m�[33m[lwm2m_tree_builder.c:62] �[0m�[0mTreebuilder length: 8
�[0m�[37;01m [DEBUG] �[0m�[33m[lwm2m_client_core.c:1335] �[0m�[0mSend Notify to coap://[2001:1418:0100:0000:0000:0000:0000:0001]:5683/3200/0/5501
�[0m�[37;01m [DEBUG] �[0m�[33m[coap_abstraction_contiki.c:558] �[0m�[0mCoap notify: coap://[2001:1418:0100:0000:0000:0000:0000:0001]:5683/3200/0/5501
�[0m�[37;01m [DEBUG] �[0m�[33m[coap_abstraction_contiki.c:559] �[0m�[0mCoap IPv6 request address: [2001:1418:0100:0000:0000:0000:0000:0001]
�[0m�[37;01m [DEBUG] �[0m�[33m[coap_abstraction_contiki.c:560] �[0m�[0mCoap request port: 5683


My question is are we missing anything in configuration ? why the behaviour has changed?

Thanks in advance!

Content Type and the data serialization

During an integration my libawa client with the leshan demo server I found an issue related to the Content Type used by the data serialization process. For SerializeOIR() located in core/src/client/lwm2m_client_core.c and called during (among other possibilities) by LWM2M2 READ, we see:

static int SerialiseOIR(Lwm2mTreeNode * root, ContentType acceptContentType, int oir[], int oirLength, ContentType * responseContentType, char * buffer, size_t size)
{
    int len = -1;

    if (acceptContentType == ContentType_None)
    {
        /* If the content type is not specified in the payload of a response message,
        * the default content type (text/plain) is assumed; otherwise the content type
        * MUST be specified in using one of the supported Media Types.
        */
        acceptContentType = ContentType_ApplicationPlainText;
    }

which seems to be a copy-paste version of the same code in DeserializeOIR(). But, whereas it is feasible to assume the content type will be always present in the response msg, (see sect. 6.3 in the "Lightweight Machine to Machine Technical Specification") it is a common case the content type spec. will be absent in requests. This leads to assuming the default content type as text/plain and an error while serialization data other that single resources.

I would rather recommend to use application/vnd.oma.lwm2m+tlv for this case OR use a configuration arg. specifying the default content type. According to the mentioned spec.

If the LWM2M Client doesn’t support that option or the LWM2M Server expresses no data format preference, the LWM2M Client will use its own preferred data format reported in the Content Format of the response message

so, such approach should be possible from the spec. point of view.

Regards & thanks for the great lib
Piotrek

error messages while call to awa-server-explore

When execution tool awa-server-explore I'm getting list of all defined objects/resources but:

  1. every even line message "ResourceOperationToString table is wrong size!" is printed
  2. every resource operation is returned as 'BAD OPERATION'

example of my screen dump:
Object: ID:3303 name:IPSO Temperature Sensor minInstances:0 maxInstances:10
ResourceOperationToString table is wrong size!
Resource: ID:5712 name:Average Value in 24h type:Float minInstances:1 maxInstances:1 operations:BAD OPERATION
ResourceOperationToString table is wrong size!
Resource: ID:5711 name:Average Value in 12h type:Float minInstances:1 maxInstances:1 operations:BAD OPERATION
ResourceOperationToString table is wrong size!

Missing mail list or contact information

Hello,
I could not find information about a mail list for general user questions about AwaLWM2M.
What is the best way to contact community to place general user questions?
Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.