xref: /aosp_15_r20/external/openthread/examples/platforms/simulation/ble.c (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1 /*
2  *  Copyright (c) 2023, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "platform-simulation.h"
30 
31 #include <errno.h>
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <openthread/platform/ble.h>
36 
37 #include "openthread/error.h"
38 #include "openthread/tcat.h"
39 #include "utils/code_utils.h"
40 
41 #define PLAT_BLE_MSG_DATA_MAX 2048
42 static uint8_t sBleBuffer[PLAT_BLE_MSG_DATA_MAX];
43 
44 static int sFd = -1;
45 
46 static const uint16_t kPortBase = 10000;
47 static uint16_t       sPort     = 0;
48 struct sockaddr_in    sSockaddr;
49 
initFds(void)50 static void initFds(void)
51 {
52     int                fd;
53     int                one = 1;
54     struct sockaddr_in sockaddr;
55 
56     memset(&sockaddr, 0, sizeof(sockaddr));
57 
58     sPort                    = (uint16_t)(kPortBase + gNodeId);
59     sockaddr.sin_family      = AF_INET;
60     sockaddr.sin_port        = htons(sPort);
61     sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
62 
63     otEXPECT_ACTION((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1, perror("socket(sFd)"));
64 
65     otEXPECT_ACTION(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != -1,
66                     perror("setsockopt(sFd, SO_REUSEADDR)"));
67     otEXPECT_ACTION(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) != -1,
68                     perror("setsockopt(sFd, SO_REUSEPORT)"));
69 
70     otEXPECT_ACTION(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != -1, perror("bind(sFd)"));
71 
72     // Fd is successfully initialized.
73     sFd = fd;
74 
75 exit:
76     if (sFd == -1)
77     {
78         exit(EXIT_FAILURE);
79     }
80 }
81 
deinitFds(void)82 static void deinitFds(void)
83 {
84     if (sFd != -1)
85     {
86         close(sFd);
87         sFd = -1;
88     }
89 }
90 
otPlatBleGetAdvertisementBuffer(otInstance * aInstance,uint8_t ** aAdvertisementBuffer)91 otError otPlatBleGetAdvertisementBuffer(otInstance *aInstance, uint8_t **aAdvertisementBuffer)
92 {
93     OT_UNUSED_VARIABLE(aInstance);
94     static uint8_t sAdvertisementBuffer[OT_TCAT_ADVERTISEMENT_MAX_LEN];
95 
96     *aAdvertisementBuffer = sAdvertisementBuffer;
97 
98     return OT_ERROR_NONE;
99 }
100 
otPlatBleEnable(otInstance * aInstance)101 otError otPlatBleEnable(otInstance *aInstance)
102 {
103     OT_UNUSED_VARIABLE(aInstance);
104     initFds();
105     return OT_ERROR_NONE;
106 }
107 
otPlatBleDisable(otInstance * aInstance)108 otError otPlatBleDisable(otInstance *aInstance)
109 {
110     deinitFds();
111     OT_UNUSED_VARIABLE(aInstance);
112     return OT_ERROR_NONE;
113 }
114 
otPlatBleGapAdvStart(otInstance * aInstance,uint16_t aInterval)115 otError otPlatBleGapAdvStart(otInstance *aInstance, uint16_t aInterval)
116 {
117     OT_UNUSED_VARIABLE(aInstance);
118     OT_UNUSED_VARIABLE(aInterval);
119     return OT_ERROR_NONE;
120 }
121 
otPlatBleGapAdvStop(otInstance * aInstance)122 otError otPlatBleGapAdvStop(otInstance *aInstance)
123 {
124     OT_UNUSED_VARIABLE(aInstance);
125     return OT_ERROR_NONE;
126 }
127 
otPlatBleGapDisconnect(otInstance * aInstance)128 otError otPlatBleGapDisconnect(otInstance *aInstance)
129 {
130     OT_UNUSED_VARIABLE(aInstance);
131     return OT_ERROR_NONE;
132 }
133 
otPlatBleGattMtuGet(otInstance * aInstance,uint16_t * aMtu)134 otError otPlatBleGattMtuGet(otInstance *aInstance, uint16_t *aMtu)
135 {
136     OT_UNUSED_VARIABLE(aInstance);
137     *aMtu = PLAT_BLE_MSG_DATA_MAX - 1;
138     return OT_ERROR_NONE;
139 }
140 
otPlatBleGattServerIndicate(otInstance * aInstance,uint16_t aHandle,const otBleRadioPacket * aPacket)141 otError otPlatBleGattServerIndicate(otInstance *aInstance, uint16_t aHandle, const otBleRadioPacket *aPacket)
142 {
143     OT_UNUSED_VARIABLE(aInstance);
144     OT_UNUSED_VARIABLE(aHandle);
145 
146     ssize_t rval;
147     otError error = OT_ERROR_NONE;
148 
149     otEXPECT_ACTION(sFd != -1, error = OT_ERROR_INVALID_STATE);
150     rval = sendto(sFd, (const char *)aPacket->mValue, aPacket->mLength, 0, (struct sockaddr *)&sSockaddr,
151                   sizeof(sSockaddr));
152     if (rval == -1)
153     {
154         perror("BLE simulation sendto failed.");
155     }
156 
157 exit:
158     return error;
159 }
160 
platformBleDeinit(void)161 void platformBleDeinit(void) { deinitFds(); }
162 
platformBleUpdateFdSet(fd_set * aReadFdSet,fd_set * aWriteFdSet,struct timeval * aTimeout,int * aMaxFd)163 void platformBleUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, struct timeval *aTimeout, int *aMaxFd)
164 {
165     OT_UNUSED_VARIABLE(aTimeout);
166     OT_UNUSED_VARIABLE(aWriteFdSet);
167 
168     if (aReadFdSet != NULL && sFd != -1)
169     {
170         FD_SET(sFd, aReadFdSet);
171 
172         if (aMaxFd != NULL && *aMaxFd < sFd)
173         {
174             *aMaxFd = sFd;
175         }
176     }
177 }
178 
platformBleProcess(otInstance * aInstance,const fd_set * aReadFdSet,const fd_set * aWriteFdSet)179 void platformBleProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet)
180 {
181     OT_UNUSED_VARIABLE(aWriteFdSet);
182 
183     otEXPECT(sFd != -1);
184 
185     if (FD_ISSET(sFd, aReadFdSet))
186     {
187         socklen_t len = sizeof(sSockaddr);
188         ssize_t   rval;
189         memset(&sSockaddr, 0, sizeof(sSockaddr));
190         rval = recvfrom(sFd, sBleBuffer, sizeof(sBleBuffer), 0, (struct sockaddr *)&sSockaddr, &len);
191         if (rval > 0)
192         {
193             otBleRadioPacket myPacket;
194             myPacket.mValue  = sBleBuffer;
195             myPacket.mLength = (uint16_t)rval;
196             myPacket.mPower  = 0;
197             otPlatBleGattServerOnWriteRequest(
198                 aInstance, 0,
199                 &myPacket); // TODO consider passing otPlatBleGattServerOnWriteRequest as a callback function
200         }
201         else if (rval == 0)
202         {
203             // socket is closed, which should not happen
204             assert(false);
205         }
206         else if (errno != EINTR && errno != EAGAIN)
207         {
208             perror("recvfrom BLE simulation failed");
209             exit(EXIT_FAILURE);
210         }
211     }
212 exit:
213     return;
214 }
215 
otPlatBleGattServerOnWriteRequest(otInstance * aInstance,uint16_t aHandle,const otBleRadioPacket * aPacket)216 OT_TOOL_WEAK void otPlatBleGattServerOnWriteRequest(otInstance             *aInstance,
217                                                     uint16_t                aHandle,
218                                                     const otBleRadioPacket *aPacket)
219 {
220     OT_UNUSED_VARIABLE(aInstance);
221     OT_UNUSED_VARIABLE(aHandle);
222     OT_UNUSED_VARIABLE(aPacket);
223     assert(false);
224     /* In case of rcp there is a problem with linking to otPlatBleGattServerOnWriteRequest
225      * which is available in FTD/MTD library.
226      */
227 }
228 
otPlatBleGetLinkCapabilities(otInstance * aInstance,otBleLinkCapabilities * aBleLinkCapabilities)229 void otPlatBleGetLinkCapabilities(otInstance *aInstance, otBleLinkCapabilities *aBleLinkCapabilities)
230 {
231     OT_UNUSED_VARIABLE(aInstance);
232     aBleLinkCapabilities->mGattNotifications = 1;
233     aBleLinkCapabilities->mL2CapDirect       = 0;
234     aBleLinkCapabilities->mRsv               = 0;
235 }
236 
otPlatBleGapAdvSetData(otInstance * aInstance,uint8_t * aAdvertisementData,uint16_t aAdvertisementLen)237 otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementData, uint16_t aAdvertisementLen)
238 {
239     OT_UNUSED_VARIABLE(aInstance);
240     OT_UNUSED_VARIABLE(aAdvertisementData);
241     OT_UNUSED_VARIABLE(aAdvertisementLen);
242     return OT_ERROR_NONE;
243 }
244 
otPlatBleSupportsMultiRadio(otInstance * aInstance)245 bool otPlatBleSupportsMultiRadio(otInstance *aInstance)
246 {
247     OT_UNUSED_VARIABLE(aInstance);
248     return false;
249 }
250