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