Skip to content

Commit 653832e

Browse files
committed
Merge pull request #188 from geky/c027
Revert "Revert "Add the C027Interface""
2 parents 30a5366 + 3e49a6c commit 653832e

File tree

3 files changed

+479
-0
lines changed

3 files changed

+479
-0
lines changed

net/C027Interface/C027Interface.cpp

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
/* C027 implementation of NetworkInterfaceAPI
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 "C027Interface.h"
18+
#include "mbed.h"
19+
#include "rtos.h"
20+
21+
22+
// Portable big -> little endian
23+
static inline MDMParser::IP ntohl(MDMParser::IP ip) {
24+
ip = ((0xff & (ip >> 24)) << 0)
25+
| ((0xff & (ip >> 16)) << 8)
26+
| ((0xff & (ip >> 8)) << 16)
27+
| ((0xff & (ip >> 0)) << 24);
28+
return ip;
29+
}
30+
31+
static inline MDMParser::IP htonl(MDMParser::IP ip) {
32+
return ntohl(ip);
33+
}
34+
35+
36+
// C027Interface implementation
37+
C027Interface::C027Interface(const char *simpin, bool debug)
38+
: _debug(debug)
39+
{
40+
strcpy(_pin, simpin);
41+
}
42+
43+
int C027Interface::connect(const char *apn, const char *username, const char *password)
44+
{
45+
// create the modem
46+
_mdm = new MDMSerial(
47+
MDM_IF(MDMTXD, D1),
48+
MDM_IF(MDMRXD, D0),
49+
MDM_IF(MDMBAUD, 115200),
50+
#if DEVICE_SERIAL_FC
51+
MDM_IF(MDMRTS, NC),
52+
MDM_IF(MDMCTS, NC),
53+
#endif
54+
1024,
55+
1024);
56+
57+
if (_debug) {
58+
_mdm->setDebug(4);
59+
} else {
60+
_mdm->setDebug(0);
61+
}
62+
63+
// initialize the modem
64+
MDMParser::DevStatus devStatus = {};
65+
MDMParser::NetStatus netStatus = {};
66+
bool mdmOk = _mdm->init(_pin, &devStatus);
67+
if (_debug) {
68+
_mdm->dumpDevStatus(&devStatus);
69+
}
70+
71+
if (mdmOk) {
72+
// wait until we are connected
73+
mdmOk = _mdm->registerNet(&netStatus);
74+
if (_debug) {
75+
_mdm->dumpNetStatus(&netStatus);
76+
}
77+
}
78+
79+
if (mdmOk) {
80+
// join the internet connection
81+
MDMParser::IP ip = htonl(_mdm->join(apn, username, password));
82+
_ip_address.set_ip_bytes(&ip, NSAPI_IPv4);
83+
mdmOk = (ip != NOIP);
84+
}
85+
86+
return mdmOk ? 0 : NSAPI_ERROR_DEVICE_ERROR;
87+
}
88+
89+
int C027Interface::disconnect()
90+
{
91+
if (!_mdm->disconnect()) {
92+
return NSAPI_ERROR_DEVICE_ERROR;
93+
}
94+
95+
return 0;
96+
}
97+
98+
const char *C027Interface::get_ip_address()
99+
{
100+
return _ip_address.get_ip_address();
101+
}
102+
103+
const char *C027Interface::get_mac_address()
104+
{
105+
return 0;
106+
}
107+
108+
struct c027_socket {
109+
int socket;
110+
MDMParser::IpProtocol proto;
111+
MDMParser::IP ip;
112+
int port;
113+
114+
MDMSerial *mdm;
115+
Thread thread;
116+
Mutex mutex;
117+
volatile bool running;
118+
void (*callback)(void *);
119+
void *data;
120+
};
121+
122+
static void socket_poll(struct c027_socket *socket) {
123+
while (socket->running) {
124+
socket->mutex.lock();
125+
if (socket->mdm->socketReadable(socket->socket)) {
126+
if (socket->callback) {
127+
socket->callback(socket->data);
128+
}
129+
}
130+
socket->mutex.unlock();
131+
Thread::yield();
132+
}
133+
}
134+
135+
int C027Interface::socket_open(void **handle, nsapi_protocol_t proto)
136+
{
137+
MDMParser::IpProtocol mdmproto = (proto == NSAPI_UDP) ? MDMParser::IPPROTO_UDP : MDMParser::IPPROTO_TCP;
138+
int fd = _mdm->socketSocket(mdmproto);
139+
if (fd < 0) {
140+
return NSAPI_ERROR_NO_SOCKET;
141+
}
142+
143+
_mdm->socketSetBlocking(fd, 10000);
144+
struct c027_socket *socket = new struct c027_socket;
145+
if (!socket) {
146+
return NSAPI_ERROR_NO_SOCKET;
147+
}
148+
149+
socket->socket = fd;
150+
socket->proto = mdmproto;
151+
socket->mdm = _mdm;
152+
153+
socket->running = true;
154+
socket->thread.start(socket, socket_poll);
155+
156+
*handle = socket;
157+
return 0;
158+
}
159+
160+
int C027Interface::socket_close(void *handle)
161+
{
162+
struct c027_socket *socket = (struct c027_socket *)handle;
163+
164+
socket->running = false;
165+
socket->thread.join();
166+
167+
_mdm->socketFree(socket->socket);
168+
169+
delete socket;
170+
return 0;
171+
}
172+
173+
int C027Interface::socket_bind(void *handle, const SocketAddress &address)
174+
{
175+
return NSAPI_ERROR_UNSUPPORTED;
176+
}
177+
178+
int C027Interface::socket_listen(void *handle, int backlog)
179+
{
180+
return NSAPI_ERROR_UNSUPPORTED;
181+
}
182+
183+
int C027Interface::socket_connect(void *handle, const SocketAddress &addr)
184+
{
185+
struct c027_socket *socket = (struct c027_socket *)handle;
186+
187+
socket->mutex.lock();
188+
bool success = _mdm->socketConnect(socket->socket, addr.get_ip_address(), addr.get_port());
189+
if (socket->callback) {
190+
socket->callback(socket->data);
191+
}
192+
socket->mutex.unlock();
193+
194+
if (!success) {
195+
return NSAPI_ERROR_DEVICE_ERROR;
196+
}
197+
198+
return 0;
199+
}
200+
201+
int C027Interface::socket_accept(void **handle, void *server)
202+
{
203+
return NSAPI_ERROR_UNSUPPORTED;
204+
}
205+
206+
int C027Interface::socket_send(void *handle, const void *data, unsigned size)
207+
{
208+
struct c027_socket *socket = (struct c027_socket *)handle;
209+
210+
socket->mutex.lock();
211+
int sent = _mdm->socketSend(socket->socket, (const char *)data, size);
212+
213+
if (socket->callback) {
214+
socket->callback(socket->data);
215+
}
216+
socket->mutex.unlock();
217+
218+
if (sent == SOCKET_ERROR) {
219+
return NSAPI_ERROR_DEVICE_ERROR;
220+
}
221+
222+
return sent;
223+
}
224+
225+
int C027Interface::socket_recv(void *handle, void *data, unsigned size)
226+
{
227+
struct c027_socket *socket = (struct c027_socket *)handle;
228+
229+
socket->mutex.lock();
230+
if (!_mdm->socketReadable(socket->socket)) {
231+
socket->mutex.unlock();
232+
return NSAPI_ERROR_WOULD_BLOCK;
233+
}
234+
235+
int recv = _mdm->socketRecv(socket->socket, (char *)data, size);
236+
socket->mutex.unlock();
237+
238+
if (recv == SOCKET_ERROR) {
239+
return NSAPI_ERROR_DEVICE_ERROR;
240+
}
241+
242+
if (recv == 0) {
243+
return NSAPI_ERROR_WOULD_BLOCK;
244+
}
245+
246+
return recv;
247+
}
248+
249+
int C027Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
250+
{
251+
struct c027_socket *socket = (struct c027_socket *)handle;
252+
253+
socket->mutex.lock();
254+
int sent = _mdm->socketSendTo(socket->socket,
255+
ntohl(*(MDMParser::IP *)addr.get_ip_bytes()), addr.get_port(),
256+
(const char *)data, size);
257+
258+
if (socket->callback) {
259+
socket->callback(socket->data);
260+
}
261+
socket->mutex.unlock();
262+
263+
if (sent == SOCKET_ERROR) {
264+
return NSAPI_ERROR_DEVICE_ERROR;
265+
}
266+
267+
return sent;
268+
}
269+
270+
int C027Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
271+
{
272+
struct c027_socket *socket = (struct c027_socket *)handle;
273+
274+
socket->mutex.lock();
275+
if (!_mdm->socketReadable(socket->socket)) {
276+
socket->mutex.unlock();
277+
return NSAPI_ERROR_WOULD_BLOCK;
278+
}
279+
280+
MDMParser::IP ip;
281+
int port;
282+
283+
int recv = _mdm->socketRecvFrom(socket->socket, &ip, &port, (char *)data, size);
284+
socket->mutex.unlock();
285+
286+
if (recv == SOCKET_ERROR) {
287+
return NSAPI_ERROR_DEVICE_ERROR;
288+
}
289+
290+
if (recv == 0) {
291+
return NSAPI_ERROR_WOULD_BLOCK;
292+
}
293+
294+
if (addr) {
295+
ip = htonl(ip);
296+
addr->set_ip_bytes(&ip, NSAPI_IPv4);
297+
addr->set_port(port);
298+
}
299+
300+
return recv;
301+
}
302+
303+
void C027Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
304+
{
305+
struct c027_socket *socket = (struct c027_socket *)handle;
306+
socket->mutex.lock();
307+
socket->callback = callback;
308+
socket->data = data;
309+
socket->mutex.unlock();
310+
}

0 commit comments

Comments
 (0)