• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
36 #include <openthread/error.h>
37 #include <openthread/tcat.h>
38 #include <openthread/platform/ble.h>
39 
40 #include "lib/platform/exit_code.h"
41 #include "utils/code_utils.h"
42 
43 #define PLAT_BLE_MSG_DATA_MAX 2048
44 static uint8_t sBleBuffer[PLAT_BLE_MSG_DATA_MAX];
45 
46 static int sFd = -1;
47 
48 static const uint16_t kPortBase = 10000;
49 static uint16_t       sPort     = 0;
50 struct sockaddr_in    sSockaddr;
51 
initFds(void)52 static void initFds(void)
53 {
54     int                fd;
55     int                one = 1;
56     struct sockaddr_in sockaddr;
57 
58     memset(&sockaddr, 0, sizeof(sockaddr));
59 
60     sPort                    = (uint16_t)(kPortBase + gNodeId);
61     sockaddr.sin_family      = AF_INET;
62     sockaddr.sin_port        = htons(sPort);
63     sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
64 
65     otEXPECT_ACTION((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1, perror("socket(sFd)"));
66 
67     otEXPECT_ACTION(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != -1,
68                     perror("setsockopt(sFd, SO_REUSEADDR)"));
69     otEXPECT_ACTION(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) != -1,
70                     perror("setsockopt(sFd, SO_REUSEPORT)"));
71 
72     otEXPECT_ACTION(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != -1, perror("bind(sFd)"));
73 
74     // Fd is successfully initialized.
75     sFd = fd;
76 
77 exit:
78     if (sFd == -1)
79     {
80         DieNow(OT_EXIT_FAILURE);
81     }
82 }
83 
deinitFds(void)84 static void deinitFds(void)
85 {
86     if (sFd != -1)
87     {
88         close(sFd);
89         sFd = -1;
90     }
91 }
92 
otPlatBleGetAdvertisementBuffer(otInstance * aInstance,uint8_t ** aAdvertisementBuffer)93 otError otPlatBleGetAdvertisementBuffer(otInstance *aInstance, uint8_t **aAdvertisementBuffer)
94 {
95     OT_UNUSED_VARIABLE(aInstance);
96     static uint8_t sAdvertisementBuffer[OT_TCAT_ADVERTISEMENT_MAX_LEN];
97 
98     *aAdvertisementBuffer = sAdvertisementBuffer;
99 
100     return OT_ERROR_NONE;
101 }
102 
otPlatBleEnable(otInstance * aInstance)103 otError otPlatBleEnable(otInstance *aInstance)
104 {
105     OT_UNUSED_VARIABLE(aInstance);
106     initFds();
107     return OT_ERROR_NONE;
108 }
109 
otPlatBleDisable(otInstance * aInstance)110 otError otPlatBleDisable(otInstance *aInstance)
111 {
112     deinitFds();
113     OT_UNUSED_VARIABLE(aInstance);
114     return OT_ERROR_NONE;
115 }
116 
otPlatBleGapAdvStart(otInstance * aInstance,uint16_t aInterval)117 otError otPlatBleGapAdvStart(otInstance *aInstance, uint16_t aInterval)
118 {
119     OT_UNUSED_VARIABLE(aInstance);
120     OT_UNUSED_VARIABLE(aInterval);
121     return OT_ERROR_NONE;
122 }
123 
otPlatBleGapAdvStop(otInstance * aInstance)124 otError otPlatBleGapAdvStop(otInstance *aInstance)
125 {
126     OT_UNUSED_VARIABLE(aInstance);
127     return OT_ERROR_NONE;
128 }
129 
otPlatBleGapDisconnect(otInstance * aInstance)130 otError otPlatBleGapDisconnect(otInstance *aInstance)
131 {
132     OT_UNUSED_VARIABLE(aInstance);
133     return OT_ERROR_NONE;
134 }
135 
otPlatBleGattMtuGet(otInstance * aInstance,uint16_t * aMtu)136 otError otPlatBleGattMtuGet(otInstance *aInstance, uint16_t *aMtu)
137 {
138     OT_UNUSED_VARIABLE(aInstance);
139     *aMtu = PLAT_BLE_MSG_DATA_MAX - 1;
140     return OT_ERROR_NONE;
141 }
142 
otPlatBleGattServerIndicate(otInstance * aInstance,uint16_t aHandle,const otBleRadioPacket * aPacket)143 otError otPlatBleGattServerIndicate(otInstance *aInstance, uint16_t aHandle, const otBleRadioPacket *aPacket)
144 {
145     OT_UNUSED_VARIABLE(aInstance);
146     OT_UNUSED_VARIABLE(aHandle);
147 
148     ssize_t rval;
149     otError error = OT_ERROR_NONE;
150 
151     otEXPECT_ACTION(sFd != -1, error = OT_ERROR_INVALID_STATE);
152     rval = sendto(sFd, (const char *)aPacket->mValue, aPacket->mLength, 0, (struct sockaddr *)&sSockaddr,
153                   sizeof(sSockaddr));
154     if (rval == -1)
155     {
156         perror("BLE simulation sendto failed.");
157     }
158 
159 exit:
160     return error;
161 }
162 
platformBleDeinit(void)163 void platformBleDeinit(void) { deinitFds(); }
164 
platformBleUpdateFdSet(fd_set * aReadFdSet,fd_set * aWriteFdSet,struct timeval * aTimeout,int * aMaxFd)165 void platformBleUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, struct timeval *aTimeout, int *aMaxFd)
166 {
167     OT_UNUSED_VARIABLE(aTimeout);
168     OT_UNUSED_VARIABLE(aWriteFdSet);
169 
170     if (aReadFdSet != NULL && sFd != -1)
171     {
172         FD_SET(sFd, aReadFdSet);
173 
174         if (aMaxFd != NULL && *aMaxFd < sFd)
175         {
176             *aMaxFd = sFd;
177         }
178     }
179 }
180 
platformBleProcess(otInstance * aInstance,const fd_set * aReadFdSet,const fd_set * aWriteFdSet)181 void platformBleProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet)
182 {
183     OT_UNUSED_VARIABLE(aWriteFdSet);
184 
185     otEXPECT(sFd != -1);
186 
187     if (FD_ISSET(sFd, aReadFdSet))
188     {
189         socklen_t len = sizeof(sSockaddr);
190         ssize_t   rval;
191         memset(&sSockaddr, 0, sizeof(sSockaddr));
192         rval = recvfrom(sFd, sBleBuffer, sizeof(sBleBuffer), 0, (struct sockaddr *)&sSockaddr, &len);
193         if (rval > 0)
194         {
195             otBleRadioPacket myPacket;
196             myPacket.mValue  = sBleBuffer;
197             myPacket.mLength = (uint16_t)rval;
198             myPacket.mPower  = 0;
199             otPlatBleGattServerOnWriteRequest(
200                 aInstance, 0,
201                 &myPacket); // TODO consider passing otPlatBleGattServerOnWriteRequest as a callback function
202         }
203         else if (rval == 0)
204         {
205             // socket is closed, which should not happen
206             assert(false);
207         }
208         else if (errno != EINTR && errno != EAGAIN)
209         {
210             perror("recvfrom BLE simulation failed");
211             DieNow(OT_EXIT_FAILURE);
212         }
213     }
214 exit:
215     return;
216 }
217 
otPlatBleGattServerOnWriteRequest(otInstance * aInstance,uint16_t aHandle,const otBleRadioPacket * aPacket)218 OT_TOOL_WEAK void otPlatBleGattServerOnWriteRequest(otInstance             *aInstance,
219                                                     uint16_t                aHandle,
220                                                     const otBleRadioPacket *aPacket)
221 {
222     OT_UNUSED_VARIABLE(aInstance);
223     OT_UNUSED_VARIABLE(aHandle);
224     OT_UNUSED_VARIABLE(aPacket);
225     assert(false);
226     /* In case of rcp there is a problem with linking to otPlatBleGattServerOnWriteRequest
227      * which is available in FTD/MTD library.
228      */
229 }
230 
otPlatBleGetLinkCapabilities(otInstance * aInstance,otBleLinkCapabilities * aBleLinkCapabilities)231 void otPlatBleGetLinkCapabilities(otInstance *aInstance, otBleLinkCapabilities *aBleLinkCapabilities)
232 {
233     OT_UNUSED_VARIABLE(aInstance);
234     aBleLinkCapabilities->mGattNotifications = 1;
235     aBleLinkCapabilities->mL2CapDirect       = 0;
236     aBleLinkCapabilities->mRsv               = 0;
237 }
238 
otPlatBleGapAdvSetData(otInstance * aInstance,uint8_t * aAdvertisementData,uint16_t aAdvertisementLen)239 otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementData, uint16_t aAdvertisementLen)
240 {
241     OT_UNUSED_VARIABLE(aInstance);
242     OT_UNUSED_VARIABLE(aAdvertisementData);
243     OT_UNUSED_VARIABLE(aAdvertisementLen);
244     return OT_ERROR_NONE;
245 }
246 
otPlatBleSupportsMultiRadio(otInstance * aInstance)247 bool otPlatBleSupportsMultiRadio(otInstance *aInstance)
248 {
249     OT_UNUSED_VARIABLE(aInstance);
250     return false;
251 }
252