Dawn Framework 1.0
Universal data acquisition framework for embedded systems
transport.cxx
1// dawn/src/proto/wakaama/transport.cxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#include "dawn/proto/wakaama/wakaama.hxx"
7#include "client.hxx"
8#include "transport.hxx"
9
10extern "C"
11{
12#include <liblwm2m.h>
13}
14
15#ifdef CONFIG_DAWN_PROTO_WAKAAMA_DTLS_PSK
16extern "C"
17{
18# include <tinydtls/dtls.h>
19# include <tinydtls/tinydtls.h>
20}
21#endif
22
23#include <arpa/inet.h>
24#include <cerrno>
25#include <cstdio>
26#include <cstring>
27#include <netinet/in.h>
28#include <new>
29#include <sys/select.h>
30#include <sys/socket.h>
31#include <unistd.h>
32
33using namespace dawn;
34using namespace dawn::wakaama_internal;
35
36#if defined(CONFIG_ARCH_SIM) && defined(CONFIG_SIM_NETUSRSOCK)
37# define DAWN_WAKAAMA_POLL_RECV 1
38extern "C" void host_usrsock_loop(void);
39#endif
40
41namespace
42{
43void resetConnection(Transport::Connection *conn);
44bool parseServerUri(const char *uri, char *host, size_t hostSize, uint16_t *port, uint8_t *scheme);
45bool sockaddrEqual(const sockaddr_storage &lhs,
46 socklen_t lhsLen,
47 const sockaddr_storage &rhs,
48 socklen_t rhsLen);
49#ifdef CONFIG_DAWN_PROTO_WAKAAMA_DTLS_PSK
50int dtlsSendToPeer(dtls_context_t *ctx, session_t *session, uint8 *data, size_t len);
51int dtlsReadFromPeer(dtls_context_t *ctx, session_t *session, uint8 *data, size_t len);
52int dtlsGetPskInfo(dtls_context_t *ctx,
53 const session_t *session,
54 dtls_credentials_type_t type,
55 const unsigned char *id,
56 size_t idLen,
57 unsigned char *result,
58 size_t resultLen);
59#endif
60} // namespace
61
63 : owner(owner_)
64 , connections(nullptr)
65 , sockfd(-1)
66#ifdef CONFIG_DAWN_PROTO_WAKAAMA_DTLS_PSK
67 , dtlsContext(nullptr)
68 , dtlsHandler()
69#endif
70{
71}
72
74{
77
78 for (Connection *conn : connectionPool)
79 {
80 delete conn;
81 }
82
83 connectionPool.clear();
84
85 if (sockfd >= 0)
86 {
87 close(sockfd);
88 sockfd = -1;
89 }
90}
91
93{
94 const size_t capacity = owner.serverPoolCapacity();
95
96 connectionPool.reserve(capacity);
97 for (size_t i = 0; i < capacity; i++)
98 {
99 Connection *conn = new (std::nothrow) Connection();
100 if (conn == nullptr)
101 {
102 return -ENOMEM;
103 }
104
105 resetConnection(conn);
106 connectionPool.push_back(conn);
107 }
108
109 return OK;
110}
111
113{
114 sockaddr_in addr;
115
116 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
117 if (sockfd < 0)
118 {
119 return -errno;
120 }
121
122 std::memset(&addr, 0, sizeof(addr));
123 addr.sin_family = AF_INET;
124 addr.sin_addr.s_addr = htonl(INADDR_ANY);
125 addr.sin_port = htons(owner.localPort);
126 if (bind(sockfd, reinterpret_cast<sockaddr *>(&addr), sizeof(addr)) < 0)
127 {
128 int err = errno;
129 close(sockfd);
130 sockfd = -1;
131 return -err;
132 }
133
134 return OK;
135}
136
138{
139#ifdef CONFIG_DAWN_PROTO_WAKAAMA_DTLS_PSK
140 for (const CProtoWakaama::ServerConfig &server : owner.servers)
141 {
142 if (server.scheme == CProtoWakaama::WAKAAMA_SERVER_SCHEME_COAPS)
143 {
144 dtls_init();
145 dtlsContext = dtls_new_context(this);
146 if (dtlsContext == nullptr)
147 {
148 return -ENOMEM;
149 }
150
151 std::memset(&dtlsHandler, 0, sizeof(dtlsHandler));
152 dtlsHandler.write = dtlsSendToPeer;
153 dtlsHandler.read = dtlsReadFromPeer;
154 dtlsHandler.get_psk_info = dtlsGetPskInfo;
155 dtls_set_handler(dtlsContext, &dtlsHandler);
156 break;
157 }
158 }
159
160 if (dtlsContext != nullptr)
161 {
162 for (const CProtoWakaama::ServerConfig &server : owner.servers)
163 {
164 if (server.scheme == CProtoWakaama::WAKAAMA_SERVER_SCHEME_COAPS &&
165 connectServer(server.securityInstanceId) == nullptr)
166 {
167 return -EIO;
168 }
169 }
170 }
171#endif
172
173 return OK;
174}
175
177{
178#ifdef CONFIG_DAWN_PROTO_WAKAAMA_DTLS_PSK
179 if (dtlsContext != nullptr)
180 {
181 dtls_free_context(dtlsContext);
182 dtlsContext = nullptr;
183 }
184#endif
185}
186
188{
189 char host[256];
190 sockaddr_in serverAddr;
191 const CProtoWakaama::ServerConfig *server;
192 security_instance_s *secInst;
193 Connection *conn;
194 uint16_t serverPortValue;
195 uint8_t scheme;
196
197 if (sockfd < 0)
198 {
199 return nullptr;
200 }
201
202 for (conn = connections; conn != nullptr; conn = conn->next)
203 {
204 if (conn->securityInstanceId == securityInstanceId)
205 {
206 return conn;
207 }
208 }
209
210 server = owner.findServer(securityInstanceId);
211 secInst =
212 owner.runtime == nullptr ? nullptr : owner.runtime->findSecurityInstance(securityInstanceId);
213
214 if (server != nullptr)
215 {
216 std::snprintf(host, sizeof(host), "%s", server->host.c_str());
217 serverPortValue = server->port;
218 scheme = server->scheme;
219 }
220 else if (secInst != nullptr &&
221 parseServerUri(secInst->uri, host, sizeof(host), &serverPortValue, &scheme))
222 {
223 if (scheme == CProtoWakaama::WAKAAMA_SERVER_SCHEME_COAPS)
224 {
225 DAWNERR("Wakaama bootstrap-created coaps server is not preallocated\n");
226 return nullptr;
227 }
228 }
229 else
230 {
231 return nullptr;
232 }
233
234 std::memset(&serverAddr, 0, sizeof(serverAddr));
235 serverAddr.sin_family = AF_INET;
236 serverAddr.sin_port = htons(serverPortValue);
237 if (inet_pton(AF_INET, host, &serverAddr.sin_addr) != 1)
238 {
239 DAWNERR("Wakaama server host must be a numeric IPv4 address: %s\n", host);
240 return nullptr;
241 }
242
243 conn = nullptr;
244 for (Connection *slot : connectionPool)
245 {
246 if (slot->sock < 0)
247 {
248 conn = slot;
249 break;
250 }
251 }
252
253 if (conn == nullptr)
254 {
255 return nullptr;
256 }
257
258 resetConnection(conn);
259 conn->sock = sockfd;
260 conn->securityInstanceId = securityInstanceId;
261 if (server != nullptr)
262 {
263 conn->pskIdentity = reinterpret_cast<const uint8_t *>(server->pskIdentity.data());
264 conn->pskIdentityLen = server->pskIdentity.size();
265 conn->pskKey = server->pskKey.data();
266 conn->pskKeyLen = server->pskKey.size();
267 }
268 else if (secInst != nullptr)
269 {
270 conn->pskIdentity = secInst->publicIdentity;
271 conn->pskIdentityLen = secInst->publicIdentityLen;
272 conn->pskKey = secInst->secretKey;
273 conn->pskKeyLen = secInst->secretKeyLen;
274 }
275 std::memcpy(&conn->addr, &serverAddr, sizeof(serverAddr));
276 conn->addrLen = sizeof(serverAddr);
277#ifdef CONFIG_DAWN_PROTO_WAKAAMA_DTLS_PSK
278 conn->dtls = scheme == CProtoWakaama::WAKAAMA_SERVER_SCHEME_COAPS;
279 if (conn->dtls)
280 {
281 if (dtlsContext == nullptr)
282 {
283 resetConnection(conn);
284 return nullptr;
285 }
286
287 std::memset(&conn->dtlsSession, 0, sizeof(conn->dtlsSession));
288 std::memcpy(&conn->dtlsSession.addr.st, &conn->addr, conn->addrLen);
289 conn->dtlsSession.size = conn->addrLen;
290 conn->dtlsContext = dtlsContext;
291 conn->lastSend = lwm2m_gettime();
292 if (dtls_connect(conn->dtlsContext, &conn->dtlsSession) != 0)
293 {
294 resetConnection(conn);
295 return nullptr;
296 }
297 }
298#endif
299 conn->next = connections;
300 connections = conn;
301
302 return conn;
303}
304
306{
307 if (conn == nullptr)
308 {
309 return;
310 }
311
312 Connection **link = &connections;
313 while (*link != nullptr)
314 {
315 if (*link == conn)
316 {
317 *link = conn->next;
318#ifdef CONFIG_DAWN_PROTO_WAKAAMA_DTLS_PSK
319 if (conn->dtls && conn->dtlsContext != nullptr)
320 {
321 dtls_peer_t *peer = dtls_get_peer(conn->dtlsContext, &conn->dtlsSession);
322 if (peer != nullptr)
323 {
324 dtls_reset_peer(conn->dtlsContext, peer);
325 }
326 }
327#endif
328 resetConnection(conn);
329 return;
330 }
331
332 link = &(*link)->next;
333 }
334}
335
336Transport::Connection *Transport::findConnection(const void *addr, size_t addrLen)
337{
338 const sockaddr_storage *peer = static_cast<const sockaddr_storage *>(addr);
339
340 if (peer == nullptr)
341 {
342 return nullptr;
343 }
344
345 for (Connection *conn = connections; conn != nullptr; conn = conn->next)
346 {
347 if (sockaddrEqual(conn->addr, conn->addrLen, *peer, static_cast<socklen_t>(addrLen)))
348 {
349 return conn;
350 }
351 }
352
353 return nullptr;
354}
355
356void Transport::handlePacket(Connection *conn, uint8_t *buffer, size_t length)
357{
358 if (owner.runtime != nullptr && conn != nullptr)
359 {
360 owner.runtime->handlePacket(buffer, length, conn);
361 }
362}
363
365{
366 while (connections != nullptr)
367 {
368 closeConnection(connections);
369 }
370
371 for (Connection *conn : connectionPool)
372 {
373 resetConnection(conn);
374 }
375
376 connections = nullptr;
377}
378
379bool Transport::receiveOne(uint8_t *buffer, size_t capacity)
380{
381 sockaddr_storage addr;
382 socklen_t addrLen = sizeof(addr);
383 ssize_t len;
384
385 len = recvfrom(sockfd, buffer, capacity, 0, reinterpret_cast<sockaddr *>(&addr), &addrLen);
386 if (len > 0)
387 {
388 Connection *conn = connections;
389
390 while (conn != nullptr)
391 {
392 if (sockaddrEqual(conn->addr, conn->addrLen, addr, addrLen))
393 {
394 break;
395 }
396
397 conn = conn->next;
398 }
399
400 if (conn != nullptr)
401 {
402#ifdef CONFIG_DAWN_PROTO_WAKAAMA_DTLS_PSK
403 if (conn->dtls)
404 {
405 dtls_handle_message(
406 conn->dtlsContext, &conn->dtlsSession, buffer, static_cast<size_t>(len));
407 }
408 else
409#endif
410 {
411 owner.runtime->handlePacket(buffer, static_cast<size_t>(len), conn);
412 }
413 }
414 else
415 {
416 DAWNWARN("Wakaama packet from unknown peer\n");
417 }
418
419 return true;
420 }
421
422 if (len < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
423 {
424 DAWNERR("Wakaama recvfrom failed: %d\n", errno);
425 }
426
427 return false;
428}
429
431{
432 uint8_t buffer[CProtoWakaama::RX_BUFFER_SIZE];
433
434 while (!owner.workerThread().shouldQuit())
435 {
436 time_t timeout = 1;
437 int ret;
438
439#ifdef CONFIG_DAWN_IO_NOTIFY
440 owner.processChangedResources();
441#endif
442
443 if (owner.runtime == nullptr)
444 {
445 DAWNERR("Wakaama runtime gone; stopping client thread\n");
446 break;
447 }
448
449 ret = owner.runtime->step(&timeout);
450 if (ret != 0)
451 {
452 /* Keep the client alive on transient step errors; breaking here
453 * would drop the registration until reboot. */
454
455 DAWNERR("lwm2m_step failed: %d (continuing)\n", ret);
456 timeout = 1;
457
458 if (owner.runtime->recoverFromBootstrapWedge())
459 {
460 DAWNINFO("Wakaama: re-registering after registration failure\n");
461 }
462 }
463
464#ifdef DAWN_WAKAAMA_POLL_RECV
465 host_usrsock_loop();
466#endif
467
468 fd_set readfds;
469 FD_ZERO(&readfds);
470 FD_SET(sockfd, &readfds);
471
472 timeval tv;
473 tv.tv_sec = timeout > 0 ? timeout : 1;
474 tv.tv_usec = 0;
475#ifdef DAWN_WAKAAMA_POLL_RECV
476 if (tv.tv_sec > 0)
477 {
478 tv.tv_sec = 0;
479 tv.tv_usec = 100000;
480 }
481#endif
482
483 ret = select(sockfd + 1, &readfds, nullptr, nullptr, &tv);
484 if (ret > 0 && FD_ISSET(sockfd, &readfds))
485 {
486 receiveOne(buffer, sizeof(buffer));
487 }
488 else if (ret < 0)
489 {
490 DAWNERR("Wakaama select failed: %d\n", errno);
491 }
492
493#ifdef DAWN_WAKAAMA_POLL_RECV
494 host_usrsock_loop();
495#endif
496 }
497
498 owner.workerThread().markThreadFinished();
499}
500
501int CProtoWakaama::initConnectionPool()
502{
503 if (transport == nullptr)
504 {
505 transport = new (std::nothrow) Transport(*this);
506 if (transport == nullptr)
507 {
508 return -ENOMEM;
509 }
510 }
511
512 return transport->initConnectionPool();
513}
514
515int CProtoWakaama::openSocket()
516{
517 return transport == nullptr ? -ENODEV : transport->openSocket();
518}
519
520int CProtoWakaama::initDtls()
521{
522 return transport == nullptr ? -ENODEV : transport->initDtls();
523}
524
525void CProtoWakaama::destroyDtls()
526{
527 if (transport != nullptr)
528 {
529 transport->destroyDtls();
530 }
531}
532
533void CProtoWakaama::closeAllConnections()
534{
535 if (transport != nullptr)
536 {
537 transport->closeAllConnections();
538 }
539}
540
541void CProtoWakaama::destroyConnectionPool()
542{
543 delete transport;
544 transport = nullptr;
545}
546
547void CProtoWakaama::thread()
548{
549 if (transport != nullptr)
550 {
551 transport->thread();
552 }
553}
554
555extern "C" uint8_t lwm2m_buffer_send(void *sessionH, uint8_t *buffer, size_t length, void *userdata)
556{
557 Transport::Connection *conn = static_cast<Transport::Connection *>(sessionH);
558
559 UNUSED(userdata);
560
561 if (conn == nullptr)
562 {
563 return COAP_500_INTERNAL_SERVER_ERROR;
564 }
565
566#ifdef CONFIG_DAWN_PROTO_WAKAAMA_DTLS_PSK
567 if (conn->dtls)
568 {
569 if (dtls_write(conn->dtlsContext, &conn->dtlsSession, buffer, length) < 0)
570 {
571 return COAP_500_INTERNAL_SERVER_ERROR;
572 }
573
574 return COAP_NO_ERROR;
575 }
576#endif
577
578 if (sendto(
579 conn->sock, buffer, length, 0, reinterpret_cast<sockaddr *>(&conn->addr), conn->addrLen) <
580 0)
581 {
582 return COAP_500_INTERNAL_SERVER_ERROR;
583 }
584
585 return COAP_NO_ERROR;
586}
587
588extern "C" bool lwm2m_session_is_equal(void *session1, void *session2, void *userData)
589{
590 UNUSED(userData);
591
592 return session1 == session2;
593}
594
595extern "C" void *lwm2m_connect_server(uint16_t secObjInstID, void *userData)
596{
597 Transport *transport = static_cast<Transport *>(userData);
598
599 return transport == nullptr ? nullptr : transport->connectServer(secObjInstID);
600}
601
602extern "C" void lwm2m_close_connection(void *sessionH, void *userData)
603{
604 Transport *transport = static_cast<Transport *>(userData);
605 Transport::Connection *conn = static_cast<Transport::Connection *>(sessionH);
606
607 if (transport != nullptr && conn != nullptr)
608 {
609 transport->closeConnection(conn);
610 }
611}
612
613namespace
614{
615void resetConnection(Transport::Connection *conn)
616{
617 if (conn != nullptr)
618 {
619 std::memset(conn, 0, sizeof(*conn));
620 conn->sock = -1;
621 }
622}
623
624#ifdef CONFIG_DAWN_PROTO_WAKAAMA_DTLS_PSK
625int dtlsSendToPeer(dtls_context_t *ctx, session_t *session, uint8 *data, size_t len)
626{
627 Transport *transport = static_cast<Transport *>(ctx->app);
629 transport == nullptr ? nullptr : transport->findConnection(&session->addr.st, session->size);
630
631 if (conn == nullptr)
632 {
633 return -1;
634 }
635
636 if (sendto(conn->sock, data, len, 0, reinterpret_cast<sockaddr *>(&conn->addr), conn->addrLen) <
637 0)
638 {
639 return -1;
640 }
641
642 conn->lastSend = lwm2m_gettime();
643 return static_cast<int>(len);
644}
645
646int dtlsReadFromPeer(dtls_context_t *ctx, session_t *session, uint8 *data, size_t len)
647{
648 Transport *transport = static_cast<Transport *>(ctx->app);
650 transport == nullptr ? nullptr : transport->findConnection(&session->addr.st, session->size);
651
652 if (conn == nullptr)
653 {
654 return -1;
655 }
656
657 transport->handlePacket(conn, data, len);
658 return 0;
659}
660
661int dtlsGetPskInfo(dtls_context_t *ctx,
662 const session_t *session,
663 dtls_credentials_type_t type,
664 const unsigned char *id,
665 size_t idLen,
666 unsigned char *result,
667 size_t resultLen)
668{
669 Transport *transport = static_cast<Transport *>(ctx->app);
671 transport == nullptr ? nullptr : transport->findConnection(&session->addr.st, session->size);
672 const uint8_t *value = nullptr;
673 size_t valueLen = 0;
674
675 UNUSED(id);
676 UNUSED(idLen);
677
678 if (conn == nullptr)
679 {
680 return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
681 }
682
683 switch (type)
684 {
685 case DTLS_PSK_IDENTITY:
686 value = conn->pskIdentity;
687 valueLen = conn->pskIdentityLen;
688 break;
689
690 case DTLS_PSK_KEY:
691 value = conn->pskKey;
692 valueLen = conn->pskKeyLen;
693 break;
694
695 case DTLS_PSK_HINT:
696 return 0;
697
698 default:
699 return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
700 }
701
702 if (value == nullptr || valueLen == 0 || resultLen < valueLen)
703 {
704 return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
705 }
706
707 std::memcpy(result, value, valueLen);
708 return static_cast<int>(valueLen);
709}
710#endif
711
712bool parseServerUri(const char *uri, char *host, size_t hostSize, uint16_t *port, uint8_t *scheme)
713{
714 const char *begin;
715 const char *portSep;
716 size_t hostLen;
717 unsigned long parsedPort;
718 char *end;
719
720 if (uri == nullptr || host == nullptr || hostSize == 0 || port == nullptr || scheme == nullptr)
721 {
722 return false;
723 }
724
725 if (std::strncmp(uri, "coaps://", 8) == 0)
726 {
727 begin = uri + 8;
728 *scheme = CProtoWakaama::WAKAAMA_SERVER_SCHEME_COAPS;
729 }
730 else if (std::strncmp(uri, "coap://", 7) == 0)
731 {
732 begin = uri + 7;
733 *scheme = CProtoWakaama::WAKAAMA_SERVER_SCHEME_COAP;
734 }
735 else
736 {
737 return false;
738 }
739
740 portSep = std::strrchr(begin, ':');
741 if (portSep == nullptr)
742 {
743 return false;
744 }
745
746 hostLen = static_cast<size_t>(portSep - begin);
747 if (hostLen == 0 || hostLen >= hostSize)
748 {
749 return false;
750 }
751
752 if (hostLen >= 2 && begin[0] == '[' && begin[hostLen - 1] == ']')
753 {
754 begin++;
755 hostLen -= 2;
756 }
757
758 if (hostLen == 0)
759 {
760 return false;
761 }
762
763 std::memcpy(host, begin, hostLen);
764 host[hostLen] = '\0';
765
766 parsedPort = std::strtoul(portSep + 1, &end, 10);
767 if (*end != '\0' || parsedPort == 0 || parsedPort > UINT16_MAX)
768 {
769 return false;
770 }
771
772 *port = static_cast<uint16_t>(parsedPort);
773 return true;
774}
775
776bool sockaddrEqual(const sockaddr_storage &lhs,
777 socklen_t lhsLen,
778 const sockaddr_storage &rhs,
779 socklen_t rhsLen)
780{
781 if (lhs.ss_family != rhs.ss_family)
782 {
783 return false;
784 }
785
786 switch (lhs.ss_family)
787 {
788 case AF_INET:
789 {
790 const sockaddr_in *lhs4 = reinterpret_cast<const sockaddr_in *>(&lhs);
791 const sockaddr_in *rhs4 = reinterpret_cast<const sockaddr_in *>(&rhs);
792
793 return lhsLen >= sizeof(sockaddr_in) && rhsLen >= sizeof(sockaddr_in) &&
794 lhs4->sin_port == rhs4->sin_port && lhs4->sin_addr.s_addr == rhs4->sin_addr.s_addr;
795 }
796
797#ifdef AF_INET6
798 case AF_INET6:
799 {
800 const sockaddr_in6 *lhs6 = reinterpret_cast<const sockaddr_in6 *>(&lhs);
801 const sockaddr_in6 *rhs6 = reinterpret_cast<const sockaddr_in6 *>(&rhs);
802
803 return lhsLen >= sizeof(sockaddr_in6) && rhsLen >= sizeof(sockaddr_in6) &&
804 lhs6->sin6_port == rhs6->sin6_port && lhs6->sin6_scope_id == rhs6->sin6_scope_id &&
805 std::memcmp(&lhs6->sin6_addr, &rhs6->sin6_addr, sizeof(lhs6->sin6_addr)) == 0;
806 }
807#endif
808
809 default:
810 {
811 return lhsLen == rhsLen && std::memcmp(&lhs, &rhs, lhsLen) == 0;
812 }
813 }
814}
815} // namespace
Wakaama LwM2M client protocol implementation.
Definition wakaama.hxx:52
CThreadedObject & workerThread()
Get a reference to this thread controller.
Definition thread.hxx:280
bool recoverFromBootstrapWedge()
Nudge a registration-failed client (parked in STATE_BOOTSTRAP_REQUIRED with no bootstrap server) back...
Definition client.cxx:274
security_instance_s * findSecurityInstance(uint16_t securityInstanceId) const
Find a Security object instance by instance ID.
Definition client.cxx:299
int step(time_t *timeout)
Run one Wakaama state-machine step.
Definition client.cxx:269
void handlePacket(uint8_t *buffer, size_t length, void *session)
Deliver one received packet into the Wakaama client context.
Definition client.cxx:291
UDP and optional DTLS transport used by the Wakaama client runtime.
Definition transport.hxx:30
void closeAllConnections()
Close every active server connection.
int openSocket()
Open and bind the local UDP socket.
void handlePacket(Connection *conn, uint8_t *buffer, size_t length)
Deliver one received packet into the Wakaama runtime.
~Transport()
Close sockets, DTLS state, and connection-pool allocations.
Definition transport.cxx:73
Connection * findConnection(const void *addr, size_t addrLen)
Find an active connection by peer address.
int initDtls()
Initialize optional shared DTLS context state.
void destroyDtls()
Destroy optional shared DTLS context state.
void closeConnection(Connection *conn)
Close one active server connection.
Connection * connectServer(uint16_t securityInstanceId)
Connect to the server referenced by a Security object instance.
int initConnectionPool()
Allocate the fixed connection pool used by Wakaama callbacks.
Definition transport.cxx:92
void thread()
Run the transport receive loop.
Transport(CProtoWakaama &owner)
Construct transport state for a Wakaama protocol owner.
Definition transport.cxx:62
Out-of-tree user-extension hooks for Dawn.
Definition bindable.hxx:13
Runtime state for one remote LwM2M server connection.
Definition transport.hxx:35
Runtime representation of one LwM2M Security object instance.
Definition internal.hxx:53