connectivityfoundry / awalwm2m Goto Github PK
View Code? Open in Web Editor NEWAwa LWM2M is an implementation of the OMA Lightweight M2M protocol in C.
License: BSD 3-Clause "New" or "Revised" License
Awa LWM2M is an implementation of the OMA Lightweight M2M protocol in C.
License: BSD 3-Clause "New" or "Revised" License
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.
In particular, the documentation should explain why a bootstrap config file can be used by either the bootstrap server or the client (but not both at the same time).
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.
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.
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
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
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.
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<=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
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.
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.
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.
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:
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<=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
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.
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';
The User Guide jumps around a bit and is confusing. The ordering can be improved to help a user work through the examples in a logical sequence.
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
I was trying to use AwaLWM2M between Ci40 and 6lowpan clicker.
I saw following issues:
Hello,
Here is a proposal for configuring daemon using a file instead of specifying options on the command line.
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
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
}
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.
The documentation does not adequately explain why the WriteAttributes tool exists, especially in terms of how it can be used to affect observations. This needs to be improved.
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.
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<=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<=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<=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<=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<=30&b=U [INFO] [coap_abstraction_erbium.c:375] Coap request: coaps://10.89.15.1:5684/rd?ep=RPI<=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<=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<=30&b=U [INFO] [coap_abstraction_erbium.c:375] Coap request: coaps://10.89.15.1:5684/rd?ep=RPI<=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.
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.
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
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.
It would be useful to illustrate information flow via the API with some sequence diagrams. For example:
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.
When execution tool awa-server-explore I'm getting list of all defined objects/resources but:
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!
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
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
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
Might be tidier to put images into a subdirectory, at the very least. That would make the .md files easier to find.
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.
The main documentation page refers to examples in general in a somewhat vague manner.
Documentation mentions ConnectNotify and DisconnectNotify - should be EstablishNotify, and DisconnectNotify has been removed.
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?
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.
Running the awa-server-exlpore and awa-client-explore produces the error ResourceOperationToString table is wrong size!
in the output.
What are the biggest differences between wakaama and Awa?
Hi,
How is this different than Leshan?
Does this support external data store and clustering support too?
Regards, Santos
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!
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.
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.
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.
It would be nice to have some configuration switch (or preferably script awa-server-undefine) which allow user to remove objects/resources definitions created by call to awa-server-define.
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.
A YouTube video to guide people through the first few steps with Awa would be useful.
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.
And moved from core/ to config/
Several "TODO" sections remain, and should be expanded or removed.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.