Socket interface for C027Interface. Implements the NetworkSocketAPI

Dependencies:   C027_Support

Dependents:   HelloC027Interface U_Blox_DeviceConnector U_Blox_DeviceConnector U-Blox_Client

Fork of LWIPInterface by NetworkSocketAPI

Committer:
mbed_official
Date:
Mon Mar 27 15:54:45 2017 -0500
Revision:
22:69ea34ad7fc6
Parent:
21:0c4d90bc84af
Child:
23:5e320842ccad
Fix bug allowing events to interrupt socket send and recv

Who changed what in which revision?

UserRevisionLine numberNew contents of line
geky 12:181a9415736b 1 /* C027 implementation of NetworkInterfaceAPI
geky 12:181a9415736b 2 * Copyright (c) 2015 ARM Limited
geky 12:181a9415736b 3 *
geky 12:181a9415736b 4 * Licensed under the Apache License, Version 2.0 (the "License");
geky 12:181a9415736b 5 * you may not use this file except in compliance with the License.
geky 12:181a9415736b 6 * You may obtain a copy of the License at
geky 12:181a9415736b 7 *
geky 12:181a9415736b 8 * http://www.apache.org/licenses/LICENSE-2.0
geky 12:181a9415736b 9 *
geky 12:181a9415736b 10 * Unless required by applicable law or agreed to in writing, software
geky 12:181a9415736b 11 * distributed under the License is distributed on an "AS IS" BASIS,
geky 12:181a9415736b 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
geky 12:181a9415736b 13 * See the License for the specific language governing permissions and
geky 12:181a9415736b 14 * limitations under the License.
geky 12:181a9415736b 15 */
geky 12:181a9415736b 16
geky 12:181a9415736b 17 #include "C027Interface.h"
geky 12:181a9415736b 18 #include "mbed.h"
mbed_official 22:69ea34ad7fc6 19 #include <math.h>
geky 12:181a9415736b 20
geky 12:181a9415736b 21
geky 12:181a9415736b 22 // C027Interface implementation
geky 12:181a9415736b 23 C027Interface::C027Interface(const char *simpin, bool debug)
geky 12:181a9415736b 24 : _debug(debug)
geky 12:181a9415736b 25 {
geky 12:181a9415736b 26 strcpy(_pin, simpin);
sarahmarshy 19:fed715eb9c83 27 running = false;
geky 12:181a9415736b 28 }
geky 12:181a9415736b 29
mbed_official 21:0c4d90bc84af 30 C027Interface::~C027Interface()
mbed_official 21:0c4d90bc84af 31 {
mbed_official 21:0c4d90bc84af 32 _thread.join();
mbed_official 21:0c4d90bc84af 33 }
mbed_official 21:0c4d90bc84af 34
mbed_official 21:0c4d90bc84af 35 nsapi_error_t C027Interface::set_credentials(const char *apn, const char *username, const char *password)
mbed_official 21:0c4d90bc84af 36 {
mbed_official 21:0c4d90bc84af 37 memset(_apn, 0, sizeof(_apn));
mbed_official 21:0c4d90bc84af 38 strncpy(_apn, apn, sizeof(_apn));
mbed_official 21:0c4d90bc84af 39
mbed_official 21:0c4d90bc84af 40 memset(_username, 0, sizeof(_username));
mbed_official 21:0c4d90bc84af 41 strncpy(_username, username, sizeof(_username));
mbed_official 21:0c4d90bc84af 42
mbed_official 21:0c4d90bc84af 43 memset(_password, 0, sizeof(_password));
mbed_official 21:0c4d90bc84af 44 strncpy(_password, password, sizeof(_password));
mbed_official 21:0c4d90bc84af 45 return 0;
mbed_official 21:0c4d90bc84af 46 }
mbed_official 21:0c4d90bc84af 47
mbed_official 21:0c4d90bc84af 48 nsapi_error_t C027Interface::connect()
geky 12:181a9415736b 49 {
geky 12:181a9415736b 50 // create the modem
geky 12:181a9415736b 51 _mdm = new MDMSerial;
geky 12:181a9415736b 52 if (_debug) {
geky 12:181a9415736b 53 _mdm->setDebug(4);
geky 12:181a9415736b 54 } else {
geky 12:181a9415736b 55 _mdm->setDebug(0);
geky 12:181a9415736b 56 }
geky 12:181a9415736b 57
geky 12:181a9415736b 58 // initialize the modem
geky 12:181a9415736b 59 MDMParser::DevStatus devStatus = {};
geky 12:181a9415736b 60 MDMParser::NetStatus netStatus = {};
geky 12:181a9415736b 61 bool mdmOk = _mdm->init(_pin, &devStatus);
geky 12:181a9415736b 62 if (_debug) {
geky 12:181a9415736b 63 _mdm->dumpDevStatus(&devStatus);
geky 12:181a9415736b 64 }
geky 12:181a9415736b 65
geky 12:181a9415736b 66 if (mdmOk) {
geky 12:181a9415736b 67 // wait until we are connected
geky 12:181a9415736b 68 mdmOk = _mdm->registerNet(&netStatus);
geky 12:181a9415736b 69 if (_debug) {
geky 12:181a9415736b 70 _mdm->dumpNetStatus(&netStatus);
geky 12:181a9415736b 71 }
geky 12:181a9415736b 72 }
geky 12:181a9415736b 73
Christopher Haster 14:3d1845f5cd81 74 if (mdmOk) {
geky 12:181a9415736b 75 // join the internet connection
mbed_official 21:0c4d90bc84af 76 MDMParser::IP ip = _mdm->join(_apn, _username, _password);
geky 15:21d4f56eb172 77 _ip_address.set_ip_bytes(&ip, NSAPI_IPv4);
geky 12:181a9415736b 78 mdmOk = (ip != NOIP);
geky 12:181a9415736b 79 }
geky 12:181a9415736b 80
Christopher Haster 14:3d1845f5cd81 81 return mdmOk ? 0 : NSAPI_ERROR_DEVICE_ERROR;
geky 12:181a9415736b 82 }
mbed_official 21:0c4d90bc84af 83
mbed_official 21:0c4d90bc84af 84 nsapi_error_t C027Interface::connect(const char *apn, const char *username, const char *password)
mbed_official 21:0c4d90bc84af 85 {
mbed_official 21:0c4d90bc84af 86
mbed_official 21:0c4d90bc84af 87 set_credentials(apn, username, password);
mbed_official 21:0c4d90bc84af 88 return connect();
mbed_official 21:0c4d90bc84af 89 }
geky 12:181a9415736b 90
Christopher Haster 14:3d1845f5cd81 91 int C027Interface::disconnect()
geky 12:181a9415736b 92 {
geky 12:181a9415736b 93 if (!_mdm->disconnect()) {
Christopher Haster 14:3d1845f5cd81 94 return NSAPI_ERROR_DEVICE_ERROR;
geky 12:181a9415736b 95 }
geky 12:181a9415736b 96
geky 12:181a9415736b 97 return 0;
geky 12:181a9415736b 98 }
geky 12:181a9415736b 99
Christopher Haster 14:3d1845f5cd81 100 const char *C027Interface::get_ip_address()
geky 12:181a9415736b 101 {
geky 15:21d4f56eb172 102 return _ip_address.get_ip_address();
geky 12:181a9415736b 103 }
geky 12:181a9415736b 104
Christopher Haster 14:3d1845f5cd81 105 const char *C027Interface::get_mac_address()
geky 12:181a9415736b 106 {
geky 12:181a9415736b 107 return 0;
geky 12:181a9415736b 108 }
geky 12:181a9415736b 109
Christopher Haster 14:3d1845f5cd81 110 struct c027_socket {
Christopher Haster 14:3d1845f5cd81 111 int socket;
Christopher Haster 14:3d1845f5cd81 112 MDMParser::IpProtocol proto;
Christopher Haster 14:3d1845f5cd81 113 MDMParser::IP ip;
Christopher Haster 14:3d1845f5cd81 114 int port;
Christopher Haster 14:3d1845f5cd81 115 };
Christopher Haster 14:3d1845f5cd81 116
Christopher Haster 14:3d1845f5cd81 117 int C027Interface::socket_open(void **handle, nsapi_protocol_t proto)
geky 12:181a9415736b 118 {
Christopher Haster 14:3d1845f5cd81 119 MDMParser::IpProtocol mdmproto = (proto == NSAPI_UDP) ? MDMParser::IPPROTO_UDP : MDMParser::IPPROTO_TCP;
Christopher Haster 14:3d1845f5cd81 120 int fd = _mdm->socketSocket(mdmproto);
Christopher Haster 14:3d1845f5cd81 121 if (fd < 0) {
Christopher Haster 14:3d1845f5cd81 122 return NSAPI_ERROR_NO_SOCKET;
geky 12:181a9415736b 123 }
geky 12:181a9415736b 124
Christopher Haster 14:3d1845f5cd81 125 _mdm->socketSetBlocking(fd, 10000);
Christopher Haster 14:3d1845f5cd81 126 struct c027_socket *socket = new struct c027_socket;
Christopher Haster 14:3d1845f5cd81 127 if (!socket) {
Christopher Haster 14:3d1845f5cd81 128 return NSAPI_ERROR_NO_SOCKET;
Christopher Haster 14:3d1845f5cd81 129 }
geky 12:181a9415736b 130
Christopher Haster 14:3d1845f5cd81 131 socket->socket = fd;
Christopher Haster 14:3d1845f5cd81 132 socket->proto = mdmproto;
Christopher Haster 14:3d1845f5cd81 133 *handle = socket;
Christopher Haster 14:3d1845f5cd81 134 return 0;
geky 12:181a9415736b 135 }
geky 12:181a9415736b 136
Christopher Haster 14:3d1845f5cd81 137 int C027Interface::socket_close(void *handle)
geky 12:181a9415736b 138 {
Christopher Haster 14:3d1845f5cd81 139 struct c027_socket *socket = (struct c027_socket *)handle;
Christopher Haster 14:3d1845f5cd81 140 _mdm->socketFree(socket->socket);
geky 12:181a9415736b 141
geky 12:181a9415736b 142 delete socket;
Christopher Haster 14:3d1845f5cd81 143 return 0;
geky 12:181a9415736b 144 }
geky 12:181a9415736b 145
Christopher Haster 14:3d1845f5cd81 146 int C027Interface::socket_bind(void *handle, const SocketAddress &address)
Christopher Haster 14:3d1845f5cd81 147 {
Christopher Haster 14:3d1845f5cd81 148 return NSAPI_ERROR_UNSUPPORTED;
Christopher Haster 14:3d1845f5cd81 149 }
geky 12:181a9415736b 150
Christopher Haster 14:3d1845f5cd81 151 int C027Interface::socket_listen(void *handle, int backlog)
geky 12:181a9415736b 152 {
Christopher Haster 14:3d1845f5cd81 153 return NSAPI_ERROR_UNSUPPORTED;
Christopher Haster 14:3d1845f5cd81 154 }
Christopher Haster 14:3d1845f5cd81 155
Christopher Haster 14:3d1845f5cd81 156 int C027Interface::socket_connect(void *handle, const SocketAddress &addr)
Christopher Haster 14:3d1845f5cd81 157 {
Christopher Haster 14:3d1845f5cd81 158 struct c027_socket *socket = (struct c027_socket *)handle;
geky 12:181a9415736b 159
Christopher Haster 14:3d1845f5cd81 160 if (!_mdm->socketConnect(socket->socket, addr.get_ip_address(), addr.get_port())) {
Christopher Haster 14:3d1845f5cd81 161 return NSAPI_ERROR_DEVICE_ERROR;
geky 12:181a9415736b 162 }
geky 12:181a9415736b 163
geky 12:181a9415736b 164 return 0;
geky 12:181a9415736b 165 }
geky 12:181a9415736b 166
mbed_official 21:0c4d90bc84af 167 nsapi_error_t C027Interface::socket_accept(nsapi_socket_t server,
mbed_official 21:0c4d90bc84af 168 nsapi_socket_t *handle, SocketAddress *address)
geky 12:181a9415736b 169 {
Christopher Haster 14:3d1845f5cd81 170 return NSAPI_ERROR_UNSUPPORTED;
geky 12:181a9415736b 171 }
geky 12:181a9415736b 172
Christopher Haster 14:3d1845f5cd81 173 int C027Interface::socket_send(void *handle, const void *data, unsigned size)
geky 12:181a9415736b 174 {
mbed_official 22:69ea34ad7fc6 175 m.lock();
mbed_official 22:69ea34ad7fc6 176 struct c027_socket *socket = (struct c027_socket *)handle;
Christopher Haster 14:3d1845f5cd81 177
Christopher Haster 14:3d1845f5cd81 178 int sent = _mdm->socketSend(socket->socket, (const char *)data, size);
mbed_official 22:69ea34ad7fc6 179 m.unlock();
Christopher Haster 14:3d1845f5cd81 180 if (sent == SOCKET_ERROR) {
Christopher Haster 14:3d1845f5cd81 181 return NSAPI_ERROR_DEVICE_ERROR;
geky 12:181a9415736b 182 }
geky 12:181a9415736b 183
Christopher Haster 14:3d1845f5cd81 184 return sent;
geky 12:181a9415736b 185 }
geky 12:181a9415736b 186
Christopher Haster 14:3d1845f5cd81 187 int C027Interface::socket_recv(void *handle, void *data, unsigned size)
geky 12:181a9415736b 188 {
mbed_official 22:69ea34ad7fc6 189 m.lock();
mbed_official 22:69ea34ad7fc6 190 struct c027_socket *socket = (struct c027_socket *)handle;
mbed_official 21:0c4d90bc84af 191
mbed_official 21:0c4d90bc84af 192 if (!_mdm->socketReadable(socket->socket)) {
mbed_official 22:69ea34ad7fc6 193 m.unlock();
Christopher Haster 14:3d1845f5cd81 194 return NSAPI_ERROR_WOULD_BLOCK;
geky 12:181a9415736b 195 }
mbed_official 22:69ea34ad7fc6 196
mbed_official 22:69ea34ad7fc6 197 int size_r = size >= 200 ? 200 : size;
mbed_official 22:69ea34ad7fc6 198
mbed_official 22:69ea34ad7fc6 199 int recv = _mdm->socketRecv(socket->socket, (char *)data, size_r);
mbed_official 22:69ea34ad7fc6 200 m.unlock();
geky 12:181a9415736b 201 if (recv == SOCKET_ERROR) {
Christopher Haster 14:3d1845f5cd81 202 return NSAPI_ERROR_DEVICE_ERROR;
geky 12:181a9415736b 203 }
geky 12:181a9415736b 204 return recv;
geky 12:181a9415736b 205 }
geky 12:181a9415736b 206
Christopher Haster 14:3d1845f5cd81 207 int C027Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
Christopher Haster 14:3d1845f5cd81 208 {
Christopher Haster 14:3d1845f5cd81 209 struct c027_socket *socket = (struct c027_socket *)handle;
geky 12:181a9415736b 210
geky 15:21d4f56eb172 211 int sent = _mdm->socketSendTo(socket->socket,
geky 15:21d4f56eb172 212 *(MDMParser::IP *)addr.get_ip_bytes(), addr.get_port(),
geky 15:21d4f56eb172 213 (const char *)data, size);
geky 15:21d4f56eb172 214
Christopher Haster 14:3d1845f5cd81 215 if (sent == SOCKET_ERROR) {
Christopher Haster 14:3d1845f5cd81 216 return NSAPI_ERROR_DEVICE_ERROR;
Christopher Haster 14:3d1845f5cd81 217 }
Christopher Haster 14:3d1845f5cd81 218
Christopher Haster 14:3d1845f5cd81 219 return sent;
Christopher Haster 14:3d1845f5cd81 220 }
Christopher Haster 14:3d1845f5cd81 221
Christopher Haster 14:3d1845f5cd81 222 int C027Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
Christopher Haster 14:3d1845f5cd81 223 {
Christopher Haster 14:3d1845f5cd81 224 struct c027_socket *socket = (struct c027_socket *)handle;
Christopher Haster 14:3d1845f5cd81 225 if (!_mdm->socketReadable(socket->socket)) {
Christopher Haster 14:3d1845f5cd81 226 return NSAPI_ERROR_WOULD_BLOCK;
Christopher Haster 14:3d1845f5cd81 227 }
Christopher Haster 14:3d1845f5cd81 228
Christopher Haster 14:3d1845f5cd81 229 MDMParser::IP ip;
Christopher Haster 14:3d1845f5cd81 230 int port;
Christopher Haster 14:3d1845f5cd81 231
Christopher Haster 14:3d1845f5cd81 232 int recv = _mdm->socketRecvFrom(socket->socket, &ip, &port, (char *)data, size);
Christopher Haster 14:3d1845f5cd81 233 if (recv == SOCKET_ERROR) {
Christopher Haster 14:3d1845f5cd81 234 return NSAPI_ERROR_DEVICE_ERROR;
Christopher Haster 14:3d1845f5cd81 235 }
Christopher Haster 14:3d1845f5cd81 236
Christopher Haster 14:3d1845f5cd81 237 if (addr) {
geky 15:21d4f56eb172 238 addr->set_ip_bytes(&ip, NSAPI_IPv4);
Christopher Haster 14:3d1845f5cd81 239 addr->set_port(port);
Christopher Haster 14:3d1845f5cd81 240 }
Christopher Haster 14:3d1845f5cd81 241
Christopher Haster 14:3d1845f5cd81 242 return recv;
Christopher Haster 14:3d1845f5cd81 243 }
Christopher Haster 14:3d1845f5cd81 244
sarahmarshy 19:fed715eb9c83 245 void C027Interface::socket_check()
sarahmarshy 16:eaf31bd133f0 246 {
sarahmarshy 19:fed715eb9c83 247 while(running){
mbed_official 21:0c4d90bc84af 248 for (int i = 0; i < NUMSOCKETS; i++){
mbed_official 22:69ea34ad7fc6 249 m.lock();
mbed_official 21:0c4d90bc84af 250 int readable = _mdm->socketReadable(i);
mbed_official 22:69ea34ad7fc6 251 m.unlock();
mbed_official 22:69ea34ad7fc6 252 if (readable != -1 && readable != 0) {
mbed_official 21:0c4d90bc84af 253 event();
sarahmarshy 19:fed715eb9c83 254 }
sarahmarshy 19:fed715eb9c83 255 }
mbed_official 21:0c4d90bc84af 256 wait(1);
mbed_official 21:0c4d90bc84af 257 }
mbed_official 21:0c4d90bc84af 258 running = false;
sarahmarshy 19:fed715eb9c83 259 }
sarahmarshy 19:fed715eb9c83 260
sarahmarshy 19:fed715eb9c83 261
sarahmarshy 19:fed715eb9c83 262 void C027Interface::event(){
mbed_official 21:0c4d90bc84af 263 for (int i = 0; i < NUMSOCKETS; i++){
mbed_official 21:0c4d90bc84af 264 if (_cbs[i].callback) {
mbed_official 21:0c4d90bc84af 265 _cbs[i].callback(_cbs[i].data);
mbed_official 21:0c4d90bc84af 266 }
mbed_official 21:0c4d90bc84af 267 }
sarahmarshy 16:eaf31bd133f0 268 }
sarahmarshy 16:eaf31bd133f0 269
Christopher Haster 14:3d1845f5cd81 270 void C027Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
Christopher Haster 14:3d1845f5cd81 271 {
mbed_official 21:0c4d90bc84af 272 struct c027_socket *socket = (struct c027_socket *)handle;
mbed_official 21:0c4d90bc84af 273 _cbs[socket->socket].callback = callback;
mbed_official 21:0c4d90bc84af 274 _cbs[socket->socket].data = data;
sarahmarshy 19:fed715eb9c83 275 if(!running){
sarahmarshy 19:fed715eb9c83 276 running = true;
sarahmarshy 19:fed715eb9c83 277 _thread.start(this, &C027Interface::socket_check);
sarahmarshy 19:fed715eb9c83 278 }
Christopher Haster 14:3d1845f5cd81 279 }
sarahmarshy 19:fed715eb9c83 280