Skip to content

Commit 85ab469

Browse files
committed
cc3200: Move wlan socket glue functions from modwlan to modusocket.
It saves about 400 bytes of code space because the functions can now be inlined.
1 parent 71ae3f3 commit 85ab469

3 files changed

Lines changed: 243 additions & 254 deletions

File tree

cc3200/mods/modusocket.c

Lines changed: 243 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,252 @@
3636
#include "py/stream.h"
3737
#include "netutils.h"
3838
#include "modnetwork.h"
39-
#include "modwlan.h"
4039
#include "modusocket.h"
4140
#include "mpexception.h"
4241

42+
/******************************************************************************/
43+
// The following set of macros and functions provide a glue between the CC3100
44+
// simplelink layer and the functions/methods provided by the usocket module.
45+
// They were historically in a separate file because usocket was designed to
46+
// work with multiple NICs, and the wlan_XXX functions just provided one
47+
// particular NIC implementation (that of the CC3100). But the CC3200 port only
48+
// supports a single NIC (being the CC3100) so it's unnecessary and inefficient
49+
// to provide an intermediate wrapper layer. Hence the wlan_XXX functions
50+
// are provided below as static functions so they can be inlined directly by
51+
// the corresponding usocket calls.
52+
53+
#define WLAN_MAX_RX_SIZE 16000
54+
#define WLAN_MAX_TX_SIZE 1476
55+
56+
#define MAKE_SOCKADDR(addr, ip, port) SlSockAddr_t addr; \
57+
addr.sa_family = SL_AF_INET; \
58+
addr.sa_data[0] = port >> 8; \
59+
addr.sa_data[1] = port; \
60+
addr.sa_data[2] = ip[3]; \
61+
addr.sa_data[3] = ip[2]; \
62+
addr.sa_data[4] = ip[1]; \
63+
addr.sa_data[5] = ip[0];
64+
65+
#define UNPACK_SOCKADDR(addr, ip, port) port = (addr.sa_data[0] << 8) | addr.sa_data[1]; \
66+
ip[0] = addr.sa_data[5]; \
67+
ip[1] = addr.sa_data[4]; \
68+
ip[2] = addr.sa_data[3]; \
69+
ip[3] = addr.sa_data[2];
70+
71+
STATIC int wlan_gethostbyname(const char *name, mp_uint_t len, uint8_t *out_ip, uint8_t family) {
72+
uint32_t ip;
73+
int result = sl_NetAppDnsGetHostByName((_i8 *)name, (_u16)len, (_u32*)&ip, (_u8)family);
74+
out_ip[0] = ip;
75+
out_ip[1] = ip >> 8;
76+
out_ip[2] = ip >> 16;
77+
out_ip[3] = ip >> 24;
78+
return result;
79+
}
80+
81+
STATIC int wlan_socket_socket(mod_network_socket_obj_t *s, int *_errno) {
82+
int16_t sd = sl_Socket(s->sock_base.u_param.domain, s->sock_base.u_param.type, s->sock_base.u_param.proto);
83+
if (sd < 0) {
84+
*_errno = sd;
85+
return -1;
86+
}
87+
s->sock_base.sd = sd;
88+
return 0;
89+
}
90+
91+
STATIC void wlan_socket_close(mod_network_socket_obj_t *s) {
92+
// this is to prevent the finalizer to close a socket that failed when being created
93+
if (s->sock_base.sd >= 0) {
94+
modusocket_socket_delete(s->sock_base.sd);
95+
sl_Close(s->sock_base.sd);
96+
s->sock_base.sd = -1;
97+
}
98+
}
99+
100+
STATIC int wlan_socket_bind(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno) {
101+
MAKE_SOCKADDR(addr, ip, port)
102+
int ret = sl_Bind(s->sock_base.sd, &addr, sizeof(addr));
103+
if (ret != 0) {
104+
*_errno = ret;
105+
return -1;
106+
}
107+
return 0;
108+
}
109+
110+
STATIC int wlan_socket_listen(mod_network_socket_obj_t *s, mp_int_t backlog, int *_errno) {
111+
int ret = sl_Listen(s->sock_base.sd, backlog);
112+
if (ret != 0) {
113+
*_errno = ret;
114+
return -1;
115+
}
116+
return 0;
117+
}
118+
119+
STATIC int wlan_socket_accept(mod_network_socket_obj_t *s, mod_network_socket_obj_t *s2, byte *ip, mp_uint_t *port, int *_errno) {
120+
// accept incoming connection
121+
int16_t sd;
122+
SlSockAddr_t addr;
123+
SlSocklen_t addr_len = sizeof(addr);
124+
125+
sd = sl_Accept(s->sock_base.sd, &addr, &addr_len);
126+
// save the socket descriptor
127+
s2->sock_base.sd = sd;
128+
if (sd < 0) {
129+
*_errno = sd;
130+
return -1;
131+
}
132+
133+
// return ip and port
134+
UNPACK_SOCKADDR(addr, ip, *port);
135+
return 0;
136+
}
137+
138+
STATIC int wlan_socket_connect(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno) {
139+
MAKE_SOCKADDR(addr, ip, port)
140+
int ret = sl_Connect(s->sock_base.sd, &addr, sizeof(addr));
141+
if (ret != 0) {
142+
*_errno = ret;
143+
return -1;
144+
}
145+
return 0;
146+
}
147+
148+
STATIC int wlan_socket_send(mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, int *_errno) {
149+
mp_int_t bytes = 0;
150+
if (len > 0) {
151+
bytes = sl_Send(s->sock_base.sd, (const void *)buf, len, 0);
152+
}
153+
if (bytes <= 0) {
154+
*_errno = bytes;
155+
return -1;
156+
}
157+
return bytes;
158+
}
159+
160+
STATIC int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int *_errno) {
161+
int ret = sl_Recv(s->sock_base.sd, buf, MIN(len, WLAN_MAX_RX_SIZE), 0);
162+
if (ret < 0) {
163+
*_errno = ret;
164+
return -1;
165+
}
166+
return ret;
167+
}
168+
169+
STATIC int wlan_socket_sendto( mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) {
170+
MAKE_SOCKADDR(addr, ip, port)
171+
int ret = sl_SendTo(s->sock_base.sd, (byte*)buf, len, 0, (SlSockAddr_t*)&addr, sizeof(addr));
172+
if (ret < 0) {
173+
*_errno = ret;
174+
return -1;
175+
}
176+
return ret;
177+
}
178+
179+
STATIC int wlan_socket_recvfrom(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) {
180+
SlSockAddr_t addr;
181+
SlSocklen_t addr_len = sizeof(addr);
182+
mp_int_t ret = sl_RecvFrom(s->sock_base.sd, buf, MIN(len, WLAN_MAX_RX_SIZE), 0, &addr, &addr_len);
183+
if (ret < 0) {
184+
*_errno = ret;
185+
return -1;
186+
}
187+
UNPACK_SOCKADDR(addr, ip, *port);
188+
return ret;
189+
}
190+
191+
STATIC int wlan_socket_setsockopt(mod_network_socket_obj_t *s, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) {
192+
int ret = sl_SetSockOpt(s->sock_base.sd, level, opt, optval, optlen);
193+
if (ret < 0) {
194+
*_errno = ret;
195+
return -1;
196+
}
197+
return 0;
198+
}
199+
200+
STATIC int wlan_socket_settimeout(mod_network_socket_obj_t *s, mp_uint_t timeout_s, int *_errno) {
201+
int ret;
202+
bool has_timeout;
203+
if (timeout_s == 0 || timeout_s == -1) {
204+
SlSockNonblocking_t option;
205+
if (timeout_s == 0) {
206+
// set non-blocking mode
207+
option.NonblockingEnabled = 1;
208+
} else {
209+
// set blocking mode
210+
option.NonblockingEnabled = 0;
211+
}
212+
ret = sl_SetSockOpt(s->sock_base.sd, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &option, sizeof(option));
213+
has_timeout = false;
214+
} else {
215+
// set timeout
216+
struct SlTimeval_t timeVal;
217+
timeVal.tv_sec = timeout_s; // seconds
218+
timeVal.tv_usec = 0; // microseconds. 10000 microseconds resolution
219+
ret = sl_SetSockOpt(s->sock_base.sd, SL_SOL_SOCKET, SL_SO_RCVTIMEO, &timeVal, sizeof(timeVal));
220+
has_timeout = true;
221+
}
222+
223+
if (ret != 0) {
224+
*_errno = ret;
225+
return -1;
226+
}
227+
228+
s->sock_base.has_timeout = has_timeout;
229+
return 0;
230+
}
231+
232+
STATIC int wlan_socket_ioctl (mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t arg, int *_errno) {
233+
mp_int_t ret;
234+
if (request == MP_STREAM_POLL) {
235+
mp_uint_t flags = arg;
236+
ret = 0;
237+
int32_t sd = s->sock_base.sd;
238+
239+
// init fds
240+
SlFdSet_t rfds, wfds, xfds;
241+
SL_FD_ZERO(&rfds);
242+
SL_FD_ZERO(&wfds);
243+
SL_FD_ZERO(&xfds);
244+
245+
// set fds if needed
246+
if (flags & MP_STREAM_POLL_RD) {
247+
SL_FD_SET(sd, &rfds);
248+
}
249+
if (flags & MP_STREAM_POLL_WR) {
250+
SL_FD_SET(sd, &wfds);
251+
}
252+
if (flags & MP_STREAM_POLL_HUP) {
253+
SL_FD_SET(sd, &xfds);
254+
}
255+
256+
// call simplelink's select with minimum timeout
257+
SlTimeval_t tv;
258+
tv.tv_sec = 0;
259+
tv.tv_usec = 1;
260+
int32_t nfds = sl_Select(sd + 1, &rfds, &wfds, &xfds, &tv);
261+
262+
// check for errors
263+
if (nfds == -1) {
264+
*_errno = nfds;
265+
return -1;
266+
}
267+
268+
// check return of select
269+
if (SL_FD_ISSET(sd, &rfds)) {
270+
ret |= MP_STREAM_POLL_RD;
271+
}
272+
if (SL_FD_ISSET(sd, &wfds)) {
273+
ret |= MP_STREAM_POLL_WR;
274+
}
275+
if (SL_FD_ISSET(sd, &xfds)) {
276+
ret |= MP_STREAM_POLL_HUP;
277+
}
278+
} else {
279+
*_errno = EINVAL;
280+
ret = MP_STREAM_ERROR;
281+
}
282+
return ret;
283+
}
284+
43285
/******************************************************************************
44286
DEFINE PRIVATE CONSTANTS
45287
******************************************************************************/

0 commit comments

Comments
 (0)