Skip to content

Commit 23b0891

Browse files
committed
Changes to the PR 10978 (LWIP: Add RAWIPSocket support)
1 parent 421ad37 commit 23b0891

File tree

9 files changed

+408
-281
lines changed

9 files changed

+408
-281
lines changed

features/lwipstack/LWIPStack.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,34 @@ nsapi_error_t LWIP::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
230230
return NSAPI_ERROR_NO_SOCKET;
231231
}
232232

233-
enum netconn_type lwip_proto = proto == NSAPI_TCP ? NETCONN_TCP : NETCONN_UDP;
233+
enum netconn_type netconntype;
234+
if ( proto == NSAPI_TCP)
235+
{
236+
netconntype = NETCONN_TCP;
237+
}
238+
else if ( proto == NSAPI_UDP )
239+
{
240+
netconntype = NETCONN_UDP;
241+
}
242+
else
243+
{
244+
netconntype = NETCONN_RAW;
245+
}
234246

235247
#if LWIP_IPV6
236248
// Enable IPv6 (or dual-stack)
237-
lwip_proto = (enum netconn_type)(lwip_proto | NETCONN_TYPE_IPV6);
249+
netconntype = (enum netconn_type)(netconntype | NETCONN_TYPE_IPV6);
238250
#endif
239251

240-
s->conn = netconn_new_with_callback(lwip_proto, &LWIP::socket_callback);
252+
if (proto == NSAPI_ICMP )
253+
{
254+
s->conn = netconn_new_with_proto_and_callback(NETCONN_RAW,
255+
(u8_t)IP_PROTO_ICMP, &LWIP::socket_callback);
256+
}
257+
else
258+
{
259+
s->conn = netconn_new_with_callback(netconntype, &LWIP::socket_callback);
260+
}
241261

242262
if (!s->conn) {
243263
arena_dealloc(s);

features/lwipstack/lwipopts.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,7 @@
8383

8484
#define SYS_LIGHTWEIGHT_PROT 1
8585

86-
#ifndef LWIP_RAW
87-
#define LWIP_RAW 0
88-
#endif
86+
#define LWIP_RAW MBED_CONF_LWIP_RAWIPSOCKET_ENABLED
8987

9088
#define TCPIP_MBOX_SIZE 8
9189
#define DEFAULT_TCP_RECVMBOX_SIZE 8

features/lwipstack/mbed_lib.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@
128128
"ppp-thread-stacksize": {
129129
"help": "Thread stack size for PPP (obsolete: use netsocket/ppp configuration instead)",
130130
"value": 768
131+
},
132+
"rawipsocket-enabled": {
133+
"help": "Enable ICMP RAW",
134+
"value": false
131135
}
132136
},
133137
"target_overrides": {

features/netsocket/NetworkStack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ class NetworkStack: public DNS {
183183

184184
protected:
185185
friend class InternetSocket;
186+
friend class RAWIPSocket;
186187
friend class UDPSocket;
187188
friend class TCPSocket;
188189
friend class TCPServer;

features/netsocket/RAWIPSocket.cpp

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/* Socket
2+
* Copyright (c) 2015 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "RAWIPSocket.h"
18+
#include "Timer.h"
19+
#include "mbed_assert.h"
20+
21+
RAWIPSocket::RAWIPSocket()
22+
{
23+
_socket_stats.stats_update_proto(this, NSAPI_ICMP);
24+
}
25+
26+
RAWIPSocket::~RAWIPSocket()
27+
{
28+
}
29+
30+
nsapi_protocol_t RAWIPSocket::get_proto()
31+
{
32+
return NSAPI_ICMP;
33+
}
34+
35+
nsapi_error_t RAWIPSocket::connect(const SocketAddress &address)
36+
{
37+
_remote_peer = address;
38+
_socket_stats.stats_update_peer(this, _remote_peer);
39+
_socket_stats.stats_update_socket_state(this, SOCK_CONNECTED);
40+
return NSAPI_ERROR_OK;
41+
}
42+
43+
nsapi_size_or_error_t RAWIPSocket::sendto(const char *host, uint16_t port, const void *data, nsapi_size_t size)
44+
{
45+
SocketAddress address;
46+
nsapi_size_or_error_t err;
47+
48+
if (!strcmp(_interface_name, "")) {
49+
err = _stack->gethostbyname(host, &address);
50+
} else {
51+
err = _stack->gethostbyname(host, &address, NSAPI_UNSPEC, _interface_name);
52+
}
53+
54+
if (err) {
55+
return NSAPI_ERROR_DNS_FAILURE;
56+
}
57+
58+
address.set_port(port);
59+
60+
// sendto is thread safe
61+
return sendto(address, data, size);
62+
}
63+
64+
nsapi_size_or_error_t RAWIPSocket::sendto(const SocketAddress &address, const void *data, nsapi_size_t size)
65+
{
66+
_lock.lock();
67+
nsapi_size_or_error_t ret;
68+
69+
_writers++;
70+
if (_socket) {
71+
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
72+
_socket_stats.stats_update_peer(this, address);
73+
}
74+
while (true) {
75+
if (!_socket) {
76+
ret = NSAPI_ERROR_NO_SOCKET;
77+
break;
78+
}
79+
80+
core_util_atomic_flag_clear(&_pending);
81+
nsapi_size_or_error_t sent = _stack->socket_sendto(_socket, address, data, size);
82+
if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) {
83+
_socket_stats.stats_update_sent_bytes(this, sent);
84+
ret = sent;
85+
break;
86+
} else {
87+
uint32_t flag;
88+
89+
// Release lock before blocking so other threads
90+
// accessing this object aren't blocked
91+
_lock.unlock();
92+
flag = _event_flag.wait_any(WRITE_FLAG, _timeout);
93+
_lock.lock();
94+
95+
if (flag & osFlagsError) {
96+
// Timeout break
97+
ret = NSAPI_ERROR_WOULD_BLOCK;
98+
break;
99+
}
100+
}
101+
}
102+
103+
_writers--;
104+
if (!_socket || !_writers) {
105+
_event_flag.set(FINISHED_FLAG);
106+
}
107+
_lock.unlock();
108+
return ret;
109+
}
110+
111+
nsapi_size_or_error_t RAWIPSocket::send(const void *data, nsapi_size_t size)
112+
{
113+
if (!_remote_peer) {
114+
return NSAPI_ERROR_NO_ADDRESS;
115+
}
116+
return sendto(_remote_peer, data, size);
117+
}
118+
119+
nsapi_size_or_error_t RAWIPSocket::recvfrom(SocketAddress *address, void *buffer, nsapi_size_t size)
120+
{
121+
_lock.lock();
122+
nsapi_size_or_error_t ret;
123+
SocketAddress ignored;
124+
125+
if (!address) {
126+
address = &ignored;
127+
}
128+
129+
_readers++;
130+
131+
if (_socket) {
132+
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
133+
}
134+
while (true) {
135+
if (!_socket) {
136+
ret = NSAPI_ERROR_NO_SOCKET;
137+
break;
138+
}
139+
140+
core_util_atomic_flag_clear(&_pending);
141+
nsapi_size_or_error_t recv = _stack->socket_recvfrom(_socket, address, buffer, size);
142+
143+
// Filter incomming packets using connected peer address
144+
if (recv >= 0 && _remote_peer && _remote_peer != *address) {
145+
continue;
146+
}
147+
148+
_socket_stats.stats_update_peer(this, _remote_peer);
149+
// Non-blocking sockets always return. Blocking only returns when success or errors other than WOULD_BLOCK
150+
if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) {
151+
ret = recv;
152+
_socket_stats.stats_update_recv_bytes(this, recv);
153+
break;
154+
} else {
155+
uint32_t flag;
156+
157+
// Release lock before blocking so other threads
158+
// accessing this object aren't blocked
159+
_lock.unlock();
160+
flag = _event_flag.wait_any(READ_FLAG, _timeout);
161+
_lock.lock();
162+
163+
if (flag & osFlagsError) {
164+
// Timeout break
165+
ret = NSAPI_ERROR_WOULD_BLOCK;
166+
break;
167+
}
168+
}
169+
}
170+
171+
_readers--;
172+
if (!_socket || !_readers) {
173+
_event_flag.set(FINISHED_FLAG);
174+
}
175+
176+
_lock.unlock();
177+
return ret;
178+
}
179+
180+
nsapi_size_or_error_t RAWIPSocket::recv(void *buffer, nsapi_size_t size)
181+
{
182+
return recvfrom(NULL, buffer, size);
183+
}
184+
185+
Socket *RAWIPSocket::accept(nsapi_error_t *error)
186+
{
187+
if (error) {
188+
*error = NSAPI_ERROR_UNSUPPORTED;
189+
}
190+
return NULL;
191+
}
192+
193+
nsapi_error_t RAWIPSocket::listen(int)
194+
{
195+
return NSAPI_ERROR_UNSUPPORTED;
196+
}

0 commit comments

Comments
 (0)