Skip to content

Commit 834fc28

Browse files
committed
Merge pull request #108 from geky/c027
Add the C027Interface
2 parents c9641f9 + 9ce315a commit 834fc28

File tree

3 files changed

+475
-0
lines changed

3 files changed

+475
-0
lines changed

net/C027Interface/C027Interface.cpp

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

0 commit comments

Comments
 (0)