1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker * Copyright (c) 2019-2021, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker * All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker *
5*cfb92d14SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker *
16*cfb92d14SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker */
28*cfb92d14SAndroid Build Coastguard Worker
29*cfb92d14SAndroid Build Coastguard Worker /**
30*cfb92d14SAndroid Build Coastguard Worker * @file
31*cfb92d14SAndroid Build Coastguard Worker * This file implements platform for TREL using IPv6/UDP socket under POSIX.
32*cfb92d14SAndroid Build Coastguard Worker */
33*cfb92d14SAndroid Build Coastguard Worker
34*cfb92d14SAndroid Build Coastguard Worker #include "openthread-posix-config.h"
35*cfb92d14SAndroid Build Coastguard Worker
36*cfb92d14SAndroid Build Coastguard Worker #include "platform-posix.h"
37*cfb92d14SAndroid Build Coastguard Worker
38*cfb92d14SAndroid Build Coastguard Worker #include <arpa/inet.h>
39*cfb92d14SAndroid Build Coastguard Worker #include <assert.h>
40*cfb92d14SAndroid Build Coastguard Worker #include <fcntl.h>
41*cfb92d14SAndroid Build Coastguard Worker #include <netinet/in.h>
42*cfb92d14SAndroid Build Coastguard Worker #include <sys/socket.h>
43*cfb92d14SAndroid Build Coastguard Worker #include <unistd.h>
44*cfb92d14SAndroid Build Coastguard Worker
45*cfb92d14SAndroid Build Coastguard Worker #include <openthread/logging.h>
46*cfb92d14SAndroid Build Coastguard Worker #include <openthread/openthread-system.h>
47*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/trel.h>
48*cfb92d14SAndroid Build Coastguard Worker
49*cfb92d14SAndroid Build Coastguard Worker #include "logger.hpp"
50*cfb92d14SAndroid Build Coastguard Worker #include "radio_url.hpp"
51*cfb92d14SAndroid Build Coastguard Worker #include "system.hpp"
52*cfb92d14SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
53*cfb92d14SAndroid Build Coastguard Worker
54*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
55*cfb92d14SAndroid Build Coastguard Worker
56*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kMaxPacketSize = 1400; // The max size of a TREL packet.
57*cfb92d14SAndroid Build Coastguard Worker
58*cfb92d14SAndroid Build Coastguard Worker typedef struct TxPacket
59*cfb92d14SAndroid Build Coastguard Worker {
60*cfb92d14SAndroid Build Coastguard Worker struct TxPacket *mNext;
61*cfb92d14SAndroid Build Coastguard Worker uint8_t mBuffer[kMaxPacketSize];
62*cfb92d14SAndroid Build Coastguard Worker uint16_t mLength;
63*cfb92d14SAndroid Build Coastguard Worker otSockAddr mDestSockAddr;
64*cfb92d14SAndroid Build Coastguard Worker } TxPacket;
65*cfb92d14SAndroid Build Coastguard Worker
66*cfb92d14SAndroid Build Coastguard Worker static uint8_t sRxPacketBuffer[kMaxPacketSize];
67*cfb92d14SAndroid Build Coastguard Worker static uint16_t sRxPacketLength;
68*cfb92d14SAndroid Build Coastguard Worker static TxPacket sTxPacketPool[OPENTHREAD_POSIX_CONFIG_TREL_TX_PACKET_POOL_SIZE];
69*cfb92d14SAndroid Build Coastguard Worker static TxPacket *sFreeTxPacketHead; // A singly linked list of free/available `TxPacket` from pool.
70*cfb92d14SAndroid Build Coastguard Worker static TxPacket *sTxPacketQueueTail; // A circular linked list for queued tx packets.
71*cfb92d14SAndroid Build Coastguard Worker static otPlatTrelCounters sCounters;
72*cfb92d14SAndroid Build Coastguard Worker
73*cfb92d14SAndroid Build Coastguard Worker static char sInterfaceName[IFNAMSIZ + 1];
74*cfb92d14SAndroid Build Coastguard Worker static bool sInitialized = false;
75*cfb92d14SAndroid Build Coastguard Worker static bool sEnabled = false;
76*cfb92d14SAndroid Build Coastguard Worker static int sSocket = -1;
77*cfb92d14SAndroid Build Coastguard Worker
78*cfb92d14SAndroid Build Coastguard Worker static const char kLogModuleName[] = "Trel";
79*cfb92d14SAndroid Build Coastguard Worker
LogCrit(const char * aFormat,...)80*cfb92d14SAndroid Build Coastguard Worker static void LogCrit(const char *aFormat, ...)
81*cfb92d14SAndroid Build Coastguard Worker {
82*cfb92d14SAndroid Build Coastguard Worker va_list args;
83*cfb92d14SAndroid Build Coastguard Worker
84*cfb92d14SAndroid Build Coastguard Worker va_start(args, aFormat);
85*cfb92d14SAndroid Build Coastguard Worker otLogPlatArgs(OT_LOG_LEVEL_CRIT, kLogModuleName, aFormat, args);
86*cfb92d14SAndroid Build Coastguard Worker va_end(args);
87*cfb92d14SAndroid Build Coastguard Worker }
88*cfb92d14SAndroid Build Coastguard Worker
LogWarn(const char * aFormat,...)89*cfb92d14SAndroid Build Coastguard Worker static void LogWarn(const char *aFormat, ...)
90*cfb92d14SAndroid Build Coastguard Worker {
91*cfb92d14SAndroid Build Coastguard Worker va_list args;
92*cfb92d14SAndroid Build Coastguard Worker
93*cfb92d14SAndroid Build Coastguard Worker va_start(args, aFormat);
94*cfb92d14SAndroid Build Coastguard Worker otLogPlatArgs(OT_LOG_LEVEL_WARN, kLogModuleName, aFormat, args);
95*cfb92d14SAndroid Build Coastguard Worker va_end(args);
96*cfb92d14SAndroid Build Coastguard Worker }
97*cfb92d14SAndroid Build Coastguard Worker
LogNote(const char * aFormat,...)98*cfb92d14SAndroid Build Coastguard Worker static void LogNote(const char *aFormat, ...)
99*cfb92d14SAndroid Build Coastguard Worker {
100*cfb92d14SAndroid Build Coastguard Worker va_list args;
101*cfb92d14SAndroid Build Coastguard Worker
102*cfb92d14SAndroid Build Coastguard Worker va_start(args, aFormat);
103*cfb92d14SAndroid Build Coastguard Worker otLogPlatArgs(OT_LOG_LEVEL_NOTE, kLogModuleName, aFormat, args);
104*cfb92d14SAndroid Build Coastguard Worker va_end(args);
105*cfb92d14SAndroid Build Coastguard Worker }
106*cfb92d14SAndroid Build Coastguard Worker
LogInfo(const char * aFormat,...)107*cfb92d14SAndroid Build Coastguard Worker static void LogInfo(const char *aFormat, ...)
108*cfb92d14SAndroid Build Coastguard Worker {
109*cfb92d14SAndroid Build Coastguard Worker va_list args;
110*cfb92d14SAndroid Build Coastguard Worker
111*cfb92d14SAndroid Build Coastguard Worker va_start(args, aFormat);
112*cfb92d14SAndroid Build Coastguard Worker otLogPlatArgs(OT_LOG_LEVEL_INFO, kLogModuleName, aFormat, args);
113*cfb92d14SAndroid Build Coastguard Worker va_end(args);
114*cfb92d14SAndroid Build Coastguard Worker }
115*cfb92d14SAndroid Build Coastguard Worker
LogDebg(const char * aFormat,...)116*cfb92d14SAndroid Build Coastguard Worker static void LogDebg(const char *aFormat, ...)
117*cfb92d14SAndroid Build Coastguard Worker {
118*cfb92d14SAndroid Build Coastguard Worker va_list args;
119*cfb92d14SAndroid Build Coastguard Worker
120*cfb92d14SAndroid Build Coastguard Worker va_start(args, aFormat);
121*cfb92d14SAndroid Build Coastguard Worker otLogPlatArgs(OT_LOG_LEVEL_DEBG, kLogModuleName, aFormat, args);
122*cfb92d14SAndroid Build Coastguard Worker va_end(args);
123*cfb92d14SAndroid Build Coastguard Worker }
124*cfb92d14SAndroid Build Coastguard Worker
Ip6AddrToString(const void * aAddress)125*cfb92d14SAndroid Build Coastguard Worker static const char *Ip6AddrToString(const void *aAddress)
126*cfb92d14SAndroid Build Coastguard Worker {
127*cfb92d14SAndroid Build Coastguard Worker static char string[INET6_ADDRSTRLEN];
128*cfb92d14SAndroid Build Coastguard Worker return inet_ntop(AF_INET6, aAddress, string, sizeof(string));
129*cfb92d14SAndroid Build Coastguard Worker }
130*cfb92d14SAndroid Build Coastguard Worker
BufferToString(const uint8_t * aBuffer,uint16_t aLength)131*cfb92d14SAndroid Build Coastguard Worker static const char *BufferToString(const uint8_t *aBuffer, uint16_t aLength)
132*cfb92d14SAndroid Build Coastguard Worker {
133*cfb92d14SAndroid Build Coastguard Worker const uint16_t kMaxWrite = 16;
134*cfb92d14SAndroid Build Coastguard Worker static char string[1600];
135*cfb92d14SAndroid Build Coastguard Worker
136*cfb92d14SAndroid Build Coastguard Worker uint16_t num = 0;
137*cfb92d14SAndroid Build Coastguard Worker char *cur = &string[0];
138*cfb92d14SAndroid Build Coastguard Worker char *end = &string[sizeof(string) - 1];
139*cfb92d14SAndroid Build Coastguard Worker
140*cfb92d14SAndroid Build Coastguard Worker cur += snprintf(cur, (uint16_t)(end - cur), "[(len:%d) ", aLength);
141*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(cur < end);
142*cfb92d14SAndroid Build Coastguard Worker
143*cfb92d14SAndroid Build Coastguard Worker while (aLength-- && (num < kMaxWrite))
144*cfb92d14SAndroid Build Coastguard Worker {
145*cfb92d14SAndroid Build Coastguard Worker cur += snprintf(cur, (uint16_t)(end - cur), "%02x ", *aBuffer++);
146*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(cur < end);
147*cfb92d14SAndroid Build Coastguard Worker
148*cfb92d14SAndroid Build Coastguard Worker num++;
149*cfb92d14SAndroid Build Coastguard Worker }
150*cfb92d14SAndroid Build Coastguard Worker
151*cfb92d14SAndroid Build Coastguard Worker if (aLength != 0)
152*cfb92d14SAndroid Build Coastguard Worker {
153*cfb92d14SAndroid Build Coastguard Worker cur += snprintf(cur, (uint16_t)(end - cur), "... ");
154*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(cur < end);
155*cfb92d14SAndroid Build Coastguard Worker }
156*cfb92d14SAndroid Build Coastguard Worker
157*cfb92d14SAndroid Build Coastguard Worker *cur++ = ']';
158*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(cur < end);
159*cfb92d14SAndroid Build Coastguard Worker
160*cfb92d14SAndroid Build Coastguard Worker *cur = '\0';
161*cfb92d14SAndroid Build Coastguard Worker
162*cfb92d14SAndroid Build Coastguard Worker exit:
163*cfb92d14SAndroid Build Coastguard Worker *end = '\0';
164*cfb92d14SAndroid Build Coastguard Worker return string;
165*cfb92d14SAndroid Build Coastguard Worker }
166*cfb92d14SAndroid Build Coastguard Worker
PrepareSocket(uint16_t & aUdpPort)167*cfb92d14SAndroid Build Coastguard Worker static void PrepareSocket(uint16_t &aUdpPort)
168*cfb92d14SAndroid Build Coastguard Worker {
169*cfb92d14SAndroid Build Coastguard Worker int val;
170*cfb92d14SAndroid Build Coastguard Worker struct sockaddr_in6 sockAddr;
171*cfb92d14SAndroid Build Coastguard Worker socklen_t sockLen;
172*cfb92d14SAndroid Build Coastguard Worker
173*cfb92d14SAndroid Build Coastguard Worker LogDebg("PrepareSocket()");
174*cfb92d14SAndroid Build Coastguard Worker
175*cfb92d14SAndroid Build Coastguard Worker sSocket = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, 0, kSocketNonBlock);
176*cfb92d14SAndroid Build Coastguard Worker VerifyOrDie(sSocket >= 0, OT_EXIT_ERROR_ERRNO);
177*cfb92d14SAndroid Build Coastguard Worker
178*cfb92d14SAndroid Build Coastguard Worker // Make the socket non-blocking to allow immediate tx attempt.
179*cfb92d14SAndroid Build Coastguard Worker val = fcntl(sSocket, F_GETFL, 0);
180*cfb92d14SAndroid Build Coastguard Worker VerifyOrDie(val != -1, OT_EXIT_ERROR_ERRNO);
181*cfb92d14SAndroid Build Coastguard Worker val = val | O_NONBLOCK;
182*cfb92d14SAndroid Build Coastguard Worker VerifyOrDie(fcntl(sSocket, F_SETFL, val) == 0, OT_EXIT_ERROR_ERRNO);
183*cfb92d14SAndroid Build Coastguard Worker
184*cfb92d14SAndroid Build Coastguard Worker // Bind the socket.
185*cfb92d14SAndroid Build Coastguard Worker
186*cfb92d14SAndroid Build Coastguard Worker memset(&sockAddr, 0, sizeof(sockAddr));
187*cfb92d14SAndroid Build Coastguard Worker sockAddr.sin6_family = AF_INET6;
188*cfb92d14SAndroid Build Coastguard Worker sockAddr.sin6_addr = in6addr_any;
189*cfb92d14SAndroid Build Coastguard Worker sockAddr.sin6_port = OPENTHREAD_POSIX_CONFIG_TREL_UDP_PORT;
190*cfb92d14SAndroid Build Coastguard Worker
191*cfb92d14SAndroid Build Coastguard Worker if (bind(sSocket, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) == -1)
192*cfb92d14SAndroid Build Coastguard Worker {
193*cfb92d14SAndroid Build Coastguard Worker LogCrit("Failed to bind socket");
194*cfb92d14SAndroid Build Coastguard Worker DieNow(OT_EXIT_ERROR_ERRNO);
195*cfb92d14SAndroid Build Coastguard Worker }
196*cfb92d14SAndroid Build Coastguard Worker
197*cfb92d14SAndroid Build Coastguard Worker #ifdef __linux__
198*cfb92d14SAndroid Build Coastguard Worker // Bind to the TREL interface
199*cfb92d14SAndroid Build Coastguard Worker if (setsockopt(sSocket, SOL_SOCKET, SO_BINDTODEVICE, sInterfaceName, strlen(sInterfaceName)) < 0)
200*cfb92d14SAndroid Build Coastguard Worker {
201*cfb92d14SAndroid Build Coastguard Worker LogCrit("Failed to bind socket to the interface %s", sInterfaceName);
202*cfb92d14SAndroid Build Coastguard Worker DieNow(OT_EXIT_ERROR_ERRNO);
203*cfb92d14SAndroid Build Coastguard Worker }
204*cfb92d14SAndroid Build Coastguard Worker #endif
205*cfb92d14SAndroid Build Coastguard Worker
206*cfb92d14SAndroid Build Coastguard Worker sockLen = sizeof(sockAddr);
207*cfb92d14SAndroid Build Coastguard Worker
208*cfb92d14SAndroid Build Coastguard Worker if (getsockname(sSocket, (struct sockaddr *)&sockAddr, &sockLen) == -1)
209*cfb92d14SAndroid Build Coastguard Worker {
210*cfb92d14SAndroid Build Coastguard Worker LogCrit("Failed to get the socket name");
211*cfb92d14SAndroid Build Coastguard Worker DieNow(OT_EXIT_ERROR_ERRNO);
212*cfb92d14SAndroid Build Coastguard Worker }
213*cfb92d14SAndroid Build Coastguard Worker
214*cfb92d14SAndroid Build Coastguard Worker aUdpPort = ntohs(sockAddr.sin6_port);
215*cfb92d14SAndroid Build Coastguard Worker }
216*cfb92d14SAndroid Build Coastguard Worker
SendPacket(const uint8_t * aBuffer,uint16_t aLength,const otSockAddr * aDestSockAddr)217*cfb92d14SAndroid Build Coastguard Worker static otError SendPacket(const uint8_t *aBuffer, uint16_t aLength, const otSockAddr *aDestSockAddr)
218*cfb92d14SAndroid Build Coastguard Worker {
219*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
220*cfb92d14SAndroid Build Coastguard Worker struct sockaddr_in6 sockAddr;
221*cfb92d14SAndroid Build Coastguard Worker ssize_t ret;
222*cfb92d14SAndroid Build Coastguard Worker
223*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(sSocket >= 0, error = OT_ERROR_INVALID_STATE);
224*cfb92d14SAndroid Build Coastguard Worker
225*cfb92d14SAndroid Build Coastguard Worker memset(&sockAddr, 0, sizeof(sockAddr));
226*cfb92d14SAndroid Build Coastguard Worker sockAddr.sin6_family = AF_INET6;
227*cfb92d14SAndroid Build Coastguard Worker sockAddr.sin6_port = htons(aDestSockAddr->mPort);
228*cfb92d14SAndroid Build Coastguard Worker memcpy(&sockAddr.sin6_addr, &aDestSockAddr->mAddress, sizeof(otIp6Address));
229*cfb92d14SAndroid Build Coastguard Worker
230*cfb92d14SAndroid Build Coastguard Worker ret = sendto(sSocket, aBuffer, aLength, 0, (struct sockaddr *)&sockAddr, sizeof(sockAddr));
231*cfb92d14SAndroid Build Coastguard Worker
232*cfb92d14SAndroid Build Coastguard Worker if (ret != aLength)
233*cfb92d14SAndroid Build Coastguard Worker {
234*cfb92d14SAndroid Build Coastguard Worker LogDebg("SendPacket() -- sendto() failed errno %d", errno);
235*cfb92d14SAndroid Build Coastguard Worker
236*cfb92d14SAndroid Build Coastguard Worker switch (errno)
237*cfb92d14SAndroid Build Coastguard Worker {
238*cfb92d14SAndroid Build Coastguard Worker case ENETUNREACH:
239*cfb92d14SAndroid Build Coastguard Worker case ENETDOWN:
240*cfb92d14SAndroid Build Coastguard Worker case EHOSTUNREACH:
241*cfb92d14SAndroid Build Coastguard Worker error = OT_ERROR_ABORT;
242*cfb92d14SAndroid Build Coastguard Worker break;
243*cfb92d14SAndroid Build Coastguard Worker
244*cfb92d14SAndroid Build Coastguard Worker default:
245*cfb92d14SAndroid Build Coastguard Worker error = OT_ERROR_INVALID_STATE;
246*cfb92d14SAndroid Build Coastguard Worker }
247*cfb92d14SAndroid Build Coastguard Worker }
248*cfb92d14SAndroid Build Coastguard Worker else
249*cfb92d14SAndroid Build Coastguard Worker {
250*cfb92d14SAndroid Build Coastguard Worker ++sCounters.mTxPackets;
251*cfb92d14SAndroid Build Coastguard Worker sCounters.mTxBytes += aLength;
252*cfb92d14SAndroid Build Coastguard Worker }
253*cfb92d14SAndroid Build Coastguard Worker
254*cfb92d14SAndroid Build Coastguard Worker exit:
255*cfb92d14SAndroid Build Coastguard Worker LogDebg("SendPacket([%s]:%u) err:%s pkt:%s", Ip6AddrToString(&aDestSockAddr->mAddress), aDestSockAddr->mPort,
256*cfb92d14SAndroid Build Coastguard Worker otThreadErrorToString(error), BufferToString(aBuffer, aLength));
257*cfb92d14SAndroid Build Coastguard Worker if (error != OT_ERROR_NONE)
258*cfb92d14SAndroid Build Coastguard Worker {
259*cfb92d14SAndroid Build Coastguard Worker ++sCounters.mTxFailure;
260*cfb92d14SAndroid Build Coastguard Worker }
261*cfb92d14SAndroid Build Coastguard Worker return error;
262*cfb92d14SAndroid Build Coastguard Worker }
263*cfb92d14SAndroid Build Coastguard Worker
ReceivePacket(int aSocket,otInstance * aInstance)264*cfb92d14SAndroid Build Coastguard Worker static void ReceivePacket(int aSocket, otInstance *aInstance)
265*cfb92d14SAndroid Build Coastguard Worker {
266*cfb92d14SAndroid Build Coastguard Worker struct sockaddr_in6 sockAddr;
267*cfb92d14SAndroid Build Coastguard Worker socklen_t sockAddrLen = sizeof(sockAddr);
268*cfb92d14SAndroid Build Coastguard Worker ssize_t ret;
269*cfb92d14SAndroid Build Coastguard Worker
270*cfb92d14SAndroid Build Coastguard Worker memset(&sockAddr, 0, sizeof(sockAddr));
271*cfb92d14SAndroid Build Coastguard Worker
272*cfb92d14SAndroid Build Coastguard Worker ret = recvfrom(aSocket, (char *)sRxPacketBuffer, sizeof(sRxPacketBuffer), 0, (struct sockaddr *)&sockAddr,
273*cfb92d14SAndroid Build Coastguard Worker &sockAddrLen);
274*cfb92d14SAndroid Build Coastguard Worker VerifyOrDie(ret >= 0, OT_EXIT_ERROR_ERRNO);
275*cfb92d14SAndroid Build Coastguard Worker
276*cfb92d14SAndroid Build Coastguard Worker sRxPacketLength = (uint16_t)(ret);
277*cfb92d14SAndroid Build Coastguard Worker
278*cfb92d14SAndroid Build Coastguard Worker if (sRxPacketLength > sizeof(sRxPacketBuffer))
279*cfb92d14SAndroid Build Coastguard Worker {
280*cfb92d14SAndroid Build Coastguard Worker sRxPacketLength = sizeof(sRxPacketLength);
281*cfb92d14SAndroid Build Coastguard Worker }
282*cfb92d14SAndroid Build Coastguard Worker
283*cfb92d14SAndroid Build Coastguard Worker LogDebg("ReceivePacket() - received from [%s]:%d, id:%d, pkt:%s", Ip6AddrToString(&sockAddr.sin6_addr),
284*cfb92d14SAndroid Build Coastguard Worker ntohs(sockAddr.sin6_port), sockAddr.sin6_scope_id, BufferToString(sRxPacketBuffer, sRxPacketLength));
285*cfb92d14SAndroid Build Coastguard Worker
286*cfb92d14SAndroid Build Coastguard Worker if (sEnabled)
287*cfb92d14SAndroid Build Coastguard Worker {
288*cfb92d14SAndroid Build Coastguard Worker ++sCounters.mRxPackets;
289*cfb92d14SAndroid Build Coastguard Worker sCounters.mRxBytes += sRxPacketLength;
290*cfb92d14SAndroid Build Coastguard Worker otPlatTrelHandleReceived(aInstance, sRxPacketBuffer, sRxPacketLength);
291*cfb92d14SAndroid Build Coastguard Worker }
292*cfb92d14SAndroid Build Coastguard Worker }
293*cfb92d14SAndroid Build Coastguard Worker
InitPacketQueue(void)294*cfb92d14SAndroid Build Coastguard Worker static void InitPacketQueue(void)
295*cfb92d14SAndroid Build Coastguard Worker {
296*cfb92d14SAndroid Build Coastguard Worker sTxPacketQueueTail = NULL;
297*cfb92d14SAndroid Build Coastguard Worker
298*cfb92d14SAndroid Build Coastguard Worker // Chain all the packets in pool in the free linked list.
299*cfb92d14SAndroid Build Coastguard Worker sFreeTxPacketHead = NULL;
300*cfb92d14SAndroid Build Coastguard Worker
301*cfb92d14SAndroid Build Coastguard Worker for (uint16_t index = 0; index < OT_ARRAY_LENGTH(sTxPacketPool); index++)
302*cfb92d14SAndroid Build Coastguard Worker {
303*cfb92d14SAndroid Build Coastguard Worker TxPacket *packet = &sTxPacketPool[index];
304*cfb92d14SAndroid Build Coastguard Worker
305*cfb92d14SAndroid Build Coastguard Worker packet->mNext = sFreeTxPacketHead;
306*cfb92d14SAndroid Build Coastguard Worker sFreeTxPacketHead = packet;
307*cfb92d14SAndroid Build Coastguard Worker }
308*cfb92d14SAndroid Build Coastguard Worker }
309*cfb92d14SAndroid Build Coastguard Worker
SendQueuedPackets(void)310*cfb92d14SAndroid Build Coastguard Worker static void SendQueuedPackets(void)
311*cfb92d14SAndroid Build Coastguard Worker {
312*cfb92d14SAndroid Build Coastguard Worker while (sTxPacketQueueTail != NULL)
313*cfb92d14SAndroid Build Coastguard Worker {
314*cfb92d14SAndroid Build Coastguard Worker TxPacket *packet = sTxPacketQueueTail->mNext; // tail->mNext is the head of the list.
315*cfb92d14SAndroid Build Coastguard Worker
316*cfb92d14SAndroid Build Coastguard Worker if (SendPacket(packet->mBuffer, packet->mLength, &packet->mDestSockAddr) == OT_ERROR_INVALID_STATE)
317*cfb92d14SAndroid Build Coastguard Worker {
318*cfb92d14SAndroid Build Coastguard Worker LogDebg("SendQueuedPackets() - SendPacket() would block");
319*cfb92d14SAndroid Build Coastguard Worker break;
320*cfb92d14SAndroid Build Coastguard Worker }
321*cfb92d14SAndroid Build Coastguard Worker
322*cfb92d14SAndroid Build Coastguard Worker // Remove the `packet` from the packet queue (circular
323*cfb92d14SAndroid Build Coastguard Worker // linked list).
324*cfb92d14SAndroid Build Coastguard Worker
325*cfb92d14SAndroid Build Coastguard Worker if (packet == sTxPacketQueueTail)
326*cfb92d14SAndroid Build Coastguard Worker {
327*cfb92d14SAndroid Build Coastguard Worker sTxPacketQueueTail = NULL;
328*cfb92d14SAndroid Build Coastguard Worker }
329*cfb92d14SAndroid Build Coastguard Worker else
330*cfb92d14SAndroid Build Coastguard Worker {
331*cfb92d14SAndroid Build Coastguard Worker sTxPacketQueueTail->mNext = packet->mNext;
332*cfb92d14SAndroid Build Coastguard Worker }
333*cfb92d14SAndroid Build Coastguard Worker
334*cfb92d14SAndroid Build Coastguard Worker // Add the `packet` to the free packet singly linked list.
335*cfb92d14SAndroid Build Coastguard Worker
336*cfb92d14SAndroid Build Coastguard Worker packet->mNext = sFreeTxPacketHead;
337*cfb92d14SAndroid Build Coastguard Worker sFreeTxPacketHead = packet;
338*cfb92d14SAndroid Build Coastguard Worker }
339*cfb92d14SAndroid Build Coastguard Worker }
340*cfb92d14SAndroid Build Coastguard Worker
EnqueuePacket(const uint8_t * aBuffer,uint16_t aLength,const otSockAddr * aDestSockAddr)341*cfb92d14SAndroid Build Coastguard Worker static void EnqueuePacket(const uint8_t *aBuffer, uint16_t aLength, const otSockAddr *aDestSockAddr)
342*cfb92d14SAndroid Build Coastguard Worker {
343*cfb92d14SAndroid Build Coastguard Worker TxPacket *packet;
344*cfb92d14SAndroid Build Coastguard Worker
345*cfb92d14SAndroid Build Coastguard Worker // Allocate an available packet entry (from the free packet list)
346*cfb92d14SAndroid Build Coastguard Worker // and copy the packet content into it.
347*cfb92d14SAndroid Build Coastguard Worker
348*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(sFreeTxPacketHead != NULL, LogWarn("EnqueuePacket failed, queue is full"));
349*cfb92d14SAndroid Build Coastguard Worker packet = sFreeTxPacketHead;
350*cfb92d14SAndroid Build Coastguard Worker sFreeTxPacketHead = sFreeTxPacketHead->mNext;
351*cfb92d14SAndroid Build Coastguard Worker
352*cfb92d14SAndroid Build Coastguard Worker memcpy(packet->mBuffer, aBuffer, aLength);
353*cfb92d14SAndroid Build Coastguard Worker packet->mLength = aLength;
354*cfb92d14SAndroid Build Coastguard Worker packet->mDestSockAddr = *aDestSockAddr;
355*cfb92d14SAndroid Build Coastguard Worker
356*cfb92d14SAndroid Build Coastguard Worker // Add packet to the tail of TxPacketQueue circular linked-list.
357*cfb92d14SAndroid Build Coastguard Worker
358*cfb92d14SAndroid Build Coastguard Worker if (sTxPacketQueueTail == NULL)
359*cfb92d14SAndroid Build Coastguard Worker {
360*cfb92d14SAndroid Build Coastguard Worker packet->mNext = packet;
361*cfb92d14SAndroid Build Coastguard Worker sTxPacketQueueTail = packet;
362*cfb92d14SAndroid Build Coastguard Worker }
363*cfb92d14SAndroid Build Coastguard Worker else
364*cfb92d14SAndroid Build Coastguard Worker {
365*cfb92d14SAndroid Build Coastguard Worker packet->mNext = sTxPacketQueueTail->mNext;
366*cfb92d14SAndroid Build Coastguard Worker sTxPacketQueueTail->mNext = packet;
367*cfb92d14SAndroid Build Coastguard Worker sTxPacketQueueTail = packet;
368*cfb92d14SAndroid Build Coastguard Worker }
369*cfb92d14SAndroid Build Coastguard Worker
370*cfb92d14SAndroid Build Coastguard Worker LogDebg("EnqueuePacket([%s]:%u) - %s", Ip6AddrToString(&aDestSockAddr->mAddress), aDestSockAddr->mPort,
371*cfb92d14SAndroid Build Coastguard Worker BufferToString(aBuffer, aLength));
372*cfb92d14SAndroid Build Coastguard Worker
373*cfb92d14SAndroid Build Coastguard Worker exit:
374*cfb92d14SAndroid Build Coastguard Worker return;
375*cfb92d14SAndroid Build Coastguard Worker }
376*cfb92d14SAndroid Build Coastguard Worker
ResetCounters()377*cfb92d14SAndroid Build Coastguard Worker static void ResetCounters() { memset(&sCounters, 0, sizeof(sCounters)); }
378*cfb92d14SAndroid Build Coastguard Worker
379*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
380*cfb92d14SAndroid Build Coastguard Worker // trelDnssd
381*cfb92d14SAndroid Build Coastguard Worker //
382*cfb92d14SAndroid Build Coastguard Worker // The functions below are tied to mDNS or DNS-SD library being used on
383*cfb92d14SAndroid Build Coastguard Worker // a device and need to be implemented per project/platform. A weak empty
384*cfb92d14SAndroid Build Coastguard Worker // implementation is provided here which describes the expected
385*cfb92d14SAndroid Build Coastguard Worker // behavior. They need to be overridden during project/platform
386*cfb92d14SAndroid Build Coastguard Worker // integration.
387*cfb92d14SAndroid Build Coastguard Worker
trelDnssdInitialize(const char * aTrelNetif)388*cfb92d14SAndroid Build Coastguard Worker OT_TOOL_WEAK void trelDnssdInitialize(const char *aTrelNetif)
389*cfb92d14SAndroid Build Coastguard Worker {
390*cfb92d14SAndroid Build Coastguard Worker // This function initialize the TREL DNS-SD module on the given
391*cfb92d14SAndroid Build Coastguard Worker // TREL Network Interface.
392*cfb92d14SAndroid Build Coastguard Worker
393*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aTrelNetif);
394*cfb92d14SAndroid Build Coastguard Worker }
395*cfb92d14SAndroid Build Coastguard Worker
trelDnssdStartBrowse(void)396*cfb92d14SAndroid Build Coastguard Worker OT_TOOL_WEAK void trelDnssdStartBrowse(void)
397*cfb92d14SAndroid Build Coastguard Worker {
398*cfb92d14SAndroid Build Coastguard Worker // This function initiates an ongoing DNS-SD browse on the service
399*cfb92d14SAndroid Build Coastguard Worker // name "_trel._udp" within the local browsing domain to discover
400*cfb92d14SAndroid Build Coastguard Worker // other devices supporting TREL. The ongoing browse will produce
401*cfb92d14SAndroid Build Coastguard Worker // two different types of events: `add` events and `remove` events.
402*cfb92d14SAndroid Build Coastguard Worker // When the browse is started, it should produce an `add` event for
403*cfb92d14SAndroid Build Coastguard Worker // every TREL peer currently present on the network. Whenever a
404*cfb92d14SAndroid Build Coastguard Worker // TREL peer goes offline, a "remove" event should be produced.
405*cfb92d14SAndroid Build Coastguard Worker // `Remove` events are not guaranteed, however. When a TREL service
406*cfb92d14SAndroid Build Coastguard Worker // instance is discovered, a new ongoing DNS-SD query for an AAAA
407*cfb92d14SAndroid Build Coastguard Worker // record MUST be started on the hostname indicated in the SRV
408*cfb92d14SAndroid Build Coastguard Worker // record of the discovered instance. If multiple host IPv6
409*cfb92d14SAndroid Build Coastguard Worker // addressees are discovered for a peer, one with highest scope
410*cfb92d14SAndroid Build Coastguard Worker // among all addresses MUST be reported (if there are multiple
411*cfb92d14SAndroid Build Coastguard Worker // address at same scope, one must be selected randomly).
412*cfb92d14SAndroid Build Coastguard Worker //
413*cfb92d14SAndroid Build Coastguard Worker // The platform MUST signal back the discovered peer info using
414*cfb92d14SAndroid Build Coastguard Worker // `otPlatTrelHandleDiscoveredPeerInfo()` callback. This callback
415*cfb92d14SAndroid Build Coastguard Worker // MUST be invoked when a new peer is discovered, or when there is
416*cfb92d14SAndroid Build Coastguard Worker // a change in an existing entry (e.g., new TXT record or new port
417*cfb92d14SAndroid Build Coastguard Worker // number or new IPv6 address), or when the peer is removed.
418*cfb92d14SAndroid Build Coastguard Worker }
419*cfb92d14SAndroid Build Coastguard Worker
trelDnssdStopBrowse(void)420*cfb92d14SAndroid Build Coastguard Worker OT_TOOL_WEAK void trelDnssdStopBrowse(void)
421*cfb92d14SAndroid Build Coastguard Worker {
422*cfb92d14SAndroid Build Coastguard Worker // This function stops the ongoing DNS-SD browse started from an
423*cfb92d14SAndroid Build Coastguard Worker // earlier call to `trelDnssdStartBrowse()`.
424*cfb92d14SAndroid Build Coastguard Worker }
425*cfb92d14SAndroid Build Coastguard Worker
trelDnssdRegisterService(uint16_t aPort,const uint8_t * aTxtData,uint8_t aTxtLength)426*cfb92d14SAndroid Build Coastguard Worker OT_TOOL_WEAK void trelDnssdRegisterService(uint16_t aPort, const uint8_t *aTxtData, uint8_t aTxtLength)
427*cfb92d14SAndroid Build Coastguard Worker {
428*cfb92d14SAndroid Build Coastguard Worker // This function registers a new service to be advertised using
429*cfb92d14SAndroid Build Coastguard Worker // DNS-SD.
430*cfb92d14SAndroid Build Coastguard Worker //
431*cfb92d14SAndroid Build Coastguard Worker // The service name is "_trel._udp". The platform should use its own
432*cfb92d14SAndroid Build Coastguard Worker // hostname, which when combined with the service name and the
433*cfb92d14SAndroid Build Coastguard Worker // local DNS-SD domain name will produce the full service instance
434*cfb92d14SAndroid Build Coastguard Worker // name, for example "example-host._trel._udp.local.".
435*cfb92d14SAndroid Build Coastguard Worker //
436*cfb92d14SAndroid Build Coastguard Worker // The domain under which the service instance name appears will
437*cfb92d14SAndroid Build Coastguard Worker // be 'local' for mDNS, and will be whatever domain is used for
438*cfb92d14SAndroid Build Coastguard Worker // service registration in the case of a non-mDNS local DNS-SD
439*cfb92d14SAndroid Build Coastguard Worker // service.
440*cfb92d14SAndroid Build Coastguard Worker //
441*cfb92d14SAndroid Build Coastguard Worker // A subsequent call to this function updates the previous service.
442*cfb92d14SAndroid Build Coastguard Worker // It is used to update the TXT record data and/or the port
443*cfb92d14SAndroid Build Coastguard Worker // number.
444*cfb92d14SAndroid Build Coastguard Worker //
445*cfb92d14SAndroid Build Coastguard Worker // The `aTxtData` buffer is not persisted after the return from this
446*cfb92d14SAndroid Build Coastguard Worker // function. The platform layer MUST not keep the pointer and
447*cfb92d14SAndroid Build Coastguard Worker // instead copy the content if needed.
448*cfb92d14SAndroid Build Coastguard Worker
449*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aPort);
450*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aTxtData);
451*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aTxtLength);
452*cfb92d14SAndroid Build Coastguard Worker }
453*cfb92d14SAndroid Build Coastguard Worker
trelDnssdRemoveService(void)454*cfb92d14SAndroid Build Coastguard Worker OT_TOOL_WEAK void trelDnssdRemoveService(void)
455*cfb92d14SAndroid Build Coastguard Worker {
456*cfb92d14SAndroid Build Coastguard Worker // This function removes any previously registered "_trel._udp"
457*cfb92d14SAndroid Build Coastguard Worker // service using `platTrelRegisterService()`. Device must stop
458*cfb92d14SAndroid Build Coastguard Worker // advertising TREL service after this call.
459*cfb92d14SAndroid Build Coastguard Worker }
460*cfb92d14SAndroid Build Coastguard Worker
trelDnssdUpdateFdSet(otSysMainloopContext * aContext)461*cfb92d14SAndroid Build Coastguard Worker OT_TOOL_WEAK void trelDnssdUpdateFdSet(otSysMainloopContext *aContext)
462*cfb92d14SAndroid Build Coastguard Worker {
463*cfb92d14SAndroid Build Coastguard Worker // This function can be used to update the file descriptor sets
464*cfb92d14SAndroid Build Coastguard Worker // by DNS-SD layer (if needed).
465*cfb92d14SAndroid Build Coastguard Worker
466*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aContext);
467*cfb92d14SAndroid Build Coastguard Worker }
468*cfb92d14SAndroid Build Coastguard Worker
trelDnssdProcess(otInstance * aInstance,const otSysMainloopContext * aContext)469*cfb92d14SAndroid Build Coastguard Worker OT_TOOL_WEAK void trelDnssdProcess(otInstance *aInstance, const otSysMainloopContext *aContext)
470*cfb92d14SAndroid Build Coastguard Worker {
471*cfb92d14SAndroid Build Coastguard Worker // This function performs processing by DNS-SD (if needed).
472*cfb92d14SAndroid Build Coastguard Worker
473*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aInstance);
474*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aContext);
475*cfb92d14SAndroid Build Coastguard Worker }
476*cfb92d14SAndroid Build Coastguard Worker
477*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
478*cfb92d14SAndroid Build Coastguard Worker // otPlatTrel
479*cfb92d14SAndroid Build Coastguard Worker
otPlatTrelEnable(otInstance * aInstance,uint16_t * aUdpPort)480*cfb92d14SAndroid Build Coastguard Worker void otPlatTrelEnable(otInstance *aInstance, uint16_t *aUdpPort)
481*cfb92d14SAndroid Build Coastguard Worker {
482*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aInstance);
483*cfb92d14SAndroid Build Coastguard Worker
484*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(!IsSystemDryRun());
485*cfb92d14SAndroid Build Coastguard Worker
486*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(sInitialized && !sEnabled);
487*cfb92d14SAndroid Build Coastguard Worker
488*cfb92d14SAndroid Build Coastguard Worker PrepareSocket(*aUdpPort);
489*cfb92d14SAndroid Build Coastguard Worker trelDnssdStartBrowse();
490*cfb92d14SAndroid Build Coastguard Worker
491*cfb92d14SAndroid Build Coastguard Worker sEnabled = true;
492*cfb92d14SAndroid Build Coastguard Worker
493*cfb92d14SAndroid Build Coastguard Worker exit:
494*cfb92d14SAndroid Build Coastguard Worker return;
495*cfb92d14SAndroid Build Coastguard Worker }
496*cfb92d14SAndroid Build Coastguard Worker
otPlatTrelDisable(otInstance * aInstance)497*cfb92d14SAndroid Build Coastguard Worker void otPlatTrelDisable(otInstance *aInstance)
498*cfb92d14SAndroid Build Coastguard Worker {
499*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aInstance);
500*cfb92d14SAndroid Build Coastguard Worker
501*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(!IsSystemDryRun());
502*cfb92d14SAndroid Build Coastguard Worker
503*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(sInitialized && sEnabled);
504*cfb92d14SAndroid Build Coastguard Worker
505*cfb92d14SAndroid Build Coastguard Worker close(sSocket);
506*cfb92d14SAndroid Build Coastguard Worker sSocket = -1;
507*cfb92d14SAndroid Build Coastguard Worker trelDnssdStopBrowse();
508*cfb92d14SAndroid Build Coastguard Worker trelDnssdRemoveService();
509*cfb92d14SAndroid Build Coastguard Worker sEnabled = false;
510*cfb92d14SAndroid Build Coastguard Worker
511*cfb92d14SAndroid Build Coastguard Worker exit:
512*cfb92d14SAndroid Build Coastguard Worker return;
513*cfb92d14SAndroid Build Coastguard Worker }
514*cfb92d14SAndroid Build Coastguard Worker
otPlatTrelSend(otInstance * aInstance,const uint8_t * aUdpPayload,uint16_t aUdpPayloadLen,const otSockAddr * aDestSockAddr)515*cfb92d14SAndroid Build Coastguard Worker void otPlatTrelSend(otInstance *aInstance,
516*cfb92d14SAndroid Build Coastguard Worker const uint8_t *aUdpPayload,
517*cfb92d14SAndroid Build Coastguard Worker uint16_t aUdpPayloadLen,
518*cfb92d14SAndroid Build Coastguard Worker const otSockAddr *aDestSockAddr)
519*cfb92d14SAndroid Build Coastguard Worker {
520*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aInstance);
521*cfb92d14SAndroid Build Coastguard Worker
522*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(!IsSystemDryRun());
523*cfb92d14SAndroid Build Coastguard Worker
524*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(sEnabled);
525*cfb92d14SAndroid Build Coastguard Worker
526*cfb92d14SAndroid Build Coastguard Worker assert(aUdpPayloadLen <= kMaxPacketSize);
527*cfb92d14SAndroid Build Coastguard Worker
528*cfb92d14SAndroid Build Coastguard Worker // We try to send the packet immediately. If it fails (e.g.,
529*cfb92d14SAndroid Build Coastguard Worker // network is down) `SendPacket()` returns `OT_ERROR_ABORT`. If
530*cfb92d14SAndroid Build Coastguard Worker // the send operation would block (e.g., socket is not yet ready
531*cfb92d14SAndroid Build Coastguard Worker // or is out of buffer) we get `OT_ERROR_INVALID_STATE`. In that
532*cfb92d14SAndroid Build Coastguard Worker // case we enqueue the packet to send it later when socket becomes
533*cfb92d14SAndroid Build Coastguard Worker // ready.
534*cfb92d14SAndroid Build Coastguard Worker
535*cfb92d14SAndroid Build Coastguard Worker if ((sTxPacketQueueTail != NULL) ||
536*cfb92d14SAndroid Build Coastguard Worker (SendPacket(aUdpPayload, aUdpPayloadLen, aDestSockAddr) == OT_ERROR_INVALID_STATE))
537*cfb92d14SAndroid Build Coastguard Worker {
538*cfb92d14SAndroid Build Coastguard Worker EnqueuePacket(aUdpPayload, aUdpPayloadLen, aDestSockAddr);
539*cfb92d14SAndroid Build Coastguard Worker }
540*cfb92d14SAndroid Build Coastguard Worker
541*cfb92d14SAndroid Build Coastguard Worker exit:
542*cfb92d14SAndroid Build Coastguard Worker return;
543*cfb92d14SAndroid Build Coastguard Worker }
544*cfb92d14SAndroid Build Coastguard Worker
otPlatTrelRegisterService(otInstance * aInstance,uint16_t aPort,const uint8_t * aTxtData,uint8_t aTxtLength)545*cfb92d14SAndroid Build Coastguard Worker void otPlatTrelRegisterService(otInstance *aInstance, uint16_t aPort, const uint8_t *aTxtData, uint8_t aTxtLength)
546*cfb92d14SAndroid Build Coastguard Worker {
547*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aInstance);
548*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(!IsSystemDryRun());
549*cfb92d14SAndroid Build Coastguard Worker
550*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(sEnabled);
551*cfb92d14SAndroid Build Coastguard Worker
552*cfb92d14SAndroid Build Coastguard Worker trelDnssdRegisterService(aPort, aTxtData, aTxtLength);
553*cfb92d14SAndroid Build Coastguard Worker
554*cfb92d14SAndroid Build Coastguard Worker exit:
555*cfb92d14SAndroid Build Coastguard Worker return;
556*cfb92d14SAndroid Build Coastguard Worker }
557*cfb92d14SAndroid Build Coastguard Worker
558*cfb92d14SAndroid Build Coastguard Worker // We keep counters at the platform layer because TREL failures can only be captured accurately within
559*cfb92d14SAndroid Build Coastguard Worker // the platform layer as the platform sometimes only queues the packet and the packet will be sent later
560*cfb92d14SAndroid Build Coastguard Worker // and the error is only known after sent.
otPlatTrelGetCounters(otInstance * aInstance)561*cfb92d14SAndroid Build Coastguard Worker const otPlatTrelCounters *otPlatTrelGetCounters(otInstance *aInstance)
562*cfb92d14SAndroid Build Coastguard Worker {
563*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aInstance);
564*cfb92d14SAndroid Build Coastguard Worker return &sCounters;
565*cfb92d14SAndroid Build Coastguard Worker }
566*cfb92d14SAndroid Build Coastguard Worker
otPlatTrelResetCounters(otInstance * aInstance)567*cfb92d14SAndroid Build Coastguard Worker void otPlatTrelResetCounters(otInstance *aInstance)
568*cfb92d14SAndroid Build Coastguard Worker {
569*cfb92d14SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aInstance);
570*cfb92d14SAndroid Build Coastguard Worker ResetCounters();
571*cfb92d14SAndroid Build Coastguard Worker }
572*cfb92d14SAndroid Build Coastguard Worker
otSysTrelInit(const char * aInterfaceName)573*cfb92d14SAndroid Build Coastguard Worker void otSysTrelInit(const char *aInterfaceName)
574*cfb92d14SAndroid Build Coastguard Worker {
575*cfb92d14SAndroid Build Coastguard Worker // To silence "unused function" warning.
576*cfb92d14SAndroid Build Coastguard Worker (void)LogCrit;
577*cfb92d14SAndroid Build Coastguard Worker (void)LogWarn;
578*cfb92d14SAndroid Build Coastguard Worker (void)LogInfo;
579*cfb92d14SAndroid Build Coastguard Worker (void)LogNote;
580*cfb92d14SAndroid Build Coastguard Worker (void)LogDebg;
581*cfb92d14SAndroid Build Coastguard Worker
582*cfb92d14SAndroid Build Coastguard Worker LogDebg("otSysTrelInit(aInterfaceName:\"%s\")", aInterfaceName != nullptr ? aInterfaceName : "");
583*cfb92d14SAndroid Build Coastguard Worker
584*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(!sInitialized && !sEnabled && aInterfaceName != nullptr);
585*cfb92d14SAndroid Build Coastguard Worker
586*cfb92d14SAndroid Build Coastguard Worker strncpy(sInterfaceName, aInterfaceName, sizeof(sInterfaceName) - 1);
587*cfb92d14SAndroid Build Coastguard Worker sInterfaceName[sizeof(sInterfaceName) - 1] = '\0';
588*cfb92d14SAndroid Build Coastguard Worker
589*cfb92d14SAndroid Build Coastguard Worker trelDnssdInitialize(sInterfaceName);
590*cfb92d14SAndroid Build Coastguard Worker
591*cfb92d14SAndroid Build Coastguard Worker InitPacketQueue();
592*cfb92d14SAndroid Build Coastguard Worker sInitialized = true;
593*cfb92d14SAndroid Build Coastguard Worker
594*cfb92d14SAndroid Build Coastguard Worker ResetCounters();
595*cfb92d14SAndroid Build Coastguard Worker
596*cfb92d14SAndroid Build Coastguard Worker exit:
597*cfb92d14SAndroid Build Coastguard Worker return;
598*cfb92d14SAndroid Build Coastguard Worker }
599*cfb92d14SAndroid Build Coastguard Worker
otSysTrelDeinit(void)600*cfb92d14SAndroid Build Coastguard Worker void otSysTrelDeinit(void) { platformTrelDeinit(); }
601*cfb92d14SAndroid Build Coastguard Worker
602*cfb92d14SAndroid Build Coastguard Worker //---------------------------------------------------------------------------------------------------------------------
603*cfb92d14SAndroid Build Coastguard Worker // platformTrel system
604*cfb92d14SAndroid Build Coastguard Worker
platformTrelInit(const char * aTrelUrl)605*cfb92d14SAndroid Build Coastguard Worker void platformTrelInit(const char *aTrelUrl)
606*cfb92d14SAndroid Build Coastguard Worker {
607*cfb92d14SAndroid Build Coastguard Worker LogDebg("platformTrelInit(aTrelUrl:\"%s\")", aTrelUrl != nullptr ? aTrelUrl : "");
608*cfb92d14SAndroid Build Coastguard Worker
609*cfb92d14SAndroid Build Coastguard Worker if (aTrelUrl != nullptr)
610*cfb92d14SAndroid Build Coastguard Worker {
611*cfb92d14SAndroid Build Coastguard Worker ot::Posix::RadioUrl url(aTrelUrl);
612*cfb92d14SAndroid Build Coastguard Worker
613*cfb92d14SAndroid Build Coastguard Worker otSysTrelInit(url.GetPath());
614*cfb92d14SAndroid Build Coastguard Worker }
615*cfb92d14SAndroid Build Coastguard Worker }
616*cfb92d14SAndroid Build Coastguard Worker
platformTrelDeinit(void)617*cfb92d14SAndroid Build Coastguard Worker void platformTrelDeinit(void)
618*cfb92d14SAndroid Build Coastguard Worker {
619*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(sInitialized && !sEnabled);
620*cfb92d14SAndroid Build Coastguard Worker
621*cfb92d14SAndroid Build Coastguard Worker sInterfaceName[0] = '\0';
622*cfb92d14SAndroid Build Coastguard Worker sInitialized = false;
623*cfb92d14SAndroid Build Coastguard Worker LogDebg("platformTrelDeinit()");
624*cfb92d14SAndroid Build Coastguard Worker
625*cfb92d14SAndroid Build Coastguard Worker exit:
626*cfb92d14SAndroid Build Coastguard Worker return;
627*cfb92d14SAndroid Build Coastguard Worker }
628*cfb92d14SAndroid Build Coastguard Worker
platformTrelUpdateFdSet(otSysMainloopContext * aContext)629*cfb92d14SAndroid Build Coastguard Worker void platformTrelUpdateFdSet(otSysMainloopContext *aContext)
630*cfb92d14SAndroid Build Coastguard Worker {
631*cfb92d14SAndroid Build Coastguard Worker assert(aContext != nullptr);
632*cfb92d14SAndroid Build Coastguard Worker
633*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(sEnabled);
634*cfb92d14SAndroid Build Coastguard Worker
635*cfb92d14SAndroid Build Coastguard Worker FD_SET(sSocket, &aContext->mReadFdSet);
636*cfb92d14SAndroid Build Coastguard Worker
637*cfb92d14SAndroid Build Coastguard Worker if (sTxPacketQueueTail != nullptr)
638*cfb92d14SAndroid Build Coastguard Worker {
639*cfb92d14SAndroid Build Coastguard Worker FD_SET(sSocket, &aContext->mWriteFdSet);
640*cfb92d14SAndroid Build Coastguard Worker }
641*cfb92d14SAndroid Build Coastguard Worker
642*cfb92d14SAndroid Build Coastguard Worker if (aContext->mMaxFd < sSocket)
643*cfb92d14SAndroid Build Coastguard Worker {
644*cfb92d14SAndroid Build Coastguard Worker aContext->mMaxFd = sSocket;
645*cfb92d14SAndroid Build Coastguard Worker }
646*cfb92d14SAndroid Build Coastguard Worker
647*cfb92d14SAndroid Build Coastguard Worker trelDnssdUpdateFdSet(aContext);
648*cfb92d14SAndroid Build Coastguard Worker
649*cfb92d14SAndroid Build Coastguard Worker exit:
650*cfb92d14SAndroid Build Coastguard Worker return;
651*cfb92d14SAndroid Build Coastguard Worker }
652*cfb92d14SAndroid Build Coastguard Worker
platformTrelProcess(otInstance * aInstance,const otSysMainloopContext * aContext)653*cfb92d14SAndroid Build Coastguard Worker void platformTrelProcess(otInstance *aInstance, const otSysMainloopContext *aContext)
654*cfb92d14SAndroid Build Coastguard Worker {
655*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(sEnabled);
656*cfb92d14SAndroid Build Coastguard Worker
657*cfb92d14SAndroid Build Coastguard Worker if (FD_ISSET(sSocket, &aContext->mWriteFdSet))
658*cfb92d14SAndroid Build Coastguard Worker {
659*cfb92d14SAndroid Build Coastguard Worker SendQueuedPackets();
660*cfb92d14SAndroid Build Coastguard Worker }
661*cfb92d14SAndroid Build Coastguard Worker
662*cfb92d14SAndroid Build Coastguard Worker if (FD_ISSET(sSocket, &aContext->mReadFdSet))
663*cfb92d14SAndroid Build Coastguard Worker {
664*cfb92d14SAndroid Build Coastguard Worker ReceivePacket(sSocket, aInstance);
665*cfb92d14SAndroid Build Coastguard Worker }
666*cfb92d14SAndroid Build Coastguard Worker
667*cfb92d14SAndroid Build Coastguard Worker trelDnssdProcess(aInstance, aContext);
668*cfb92d14SAndroid Build Coastguard Worker
669*cfb92d14SAndroid Build Coastguard Worker exit:
670*cfb92d14SAndroid Build Coastguard Worker return;
671*cfb92d14SAndroid Build Coastguard Worker }
672*cfb92d14SAndroid Build Coastguard Worker
673*cfb92d14SAndroid Build Coastguard Worker #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
674