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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers C027Interface.cpp Source File

C027Interface.cpp

00001 /* C027 implementation of NetworkInterfaceAPI
00002  * Copyright (c) 2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "C027Interface.h"
00018 #include "mbed.h"
00019 #include <math.h>
00020 
00021 
00022 // C027Interface implementation
00023 C027Interface::C027Interface(const char *simpin, bool debug)
00024     : _debug(debug)
00025 {
00026     strcpy(_pin, simpin);
00027     memset(_cbs, 0, sizeof(_cbs));
00028     running = false;
00029 }
00030 
00031 C027Interface::~C027Interface()
00032 {
00033     if(running)
00034         _thread.join();
00035 }
00036 
00037 nsapi_error_t C027Interface::set_credentials(const char *apn, const char *username, const char *password)
00038 {
00039     memset(_apn, 0, sizeof(_apn));
00040     strncpy(_apn, apn, sizeof(_apn));
00041  
00042     memset(_username, 0, sizeof(_username));
00043     strncpy(_username, username, sizeof(_username));
00044     
00045     memset(_password, 0, sizeof(_password));
00046     strncpy(_password, password, sizeof(_password));
00047     return 0;
00048 }
00049 
00050 nsapi_error_t C027Interface::connect()
00051 {
00052     // create the modem
00053     _mdm = new MDMSerial;
00054     if (_debug) {
00055         _mdm->setDebug(4);
00056     } else {
00057         _mdm->setDebug(0);
00058     }
00059     
00060     // initialize the modem 
00061     MDMParser::DevStatus devStatus = {};
00062     MDMParser::NetStatus netStatus = {};
00063     bool mdmOk = _mdm->init(_pin, &devStatus);
00064     if (_debug) {
00065         _mdm->dumpDevStatus(&devStatus);
00066     }
00067     
00068     if (mdmOk) {
00069         // wait until we are connected
00070         mdmOk = _mdm->registerNet(&netStatus);
00071         if (_debug) {
00072             _mdm->dumpNetStatus(&netStatus);
00073         }
00074     }
00075     
00076     if (mdmOk) {
00077         // join the internet connection 
00078         MDMParser::IP ip = _mdm->join(_apn, _username, _password);
00079         _ip_address.set_ip_bytes(&ip, NSAPI_IPv4);
00080         mdmOk = (ip != NOIP);
00081     }
00082     
00083     return mdmOk ? 0 : NSAPI_ERROR_DEVICE_ERROR;
00084 }
00085  
00086 nsapi_error_t C027Interface::connect(const char *apn, const char *username, const char *password)
00087 {
00088     
00089     set_credentials(apn, username, password);
00090     return connect();
00091 }
00092 
00093 int C027Interface::disconnect()
00094 {
00095     if (!_mdm->disconnect()) {
00096         return NSAPI_ERROR_DEVICE_ERROR;
00097     }
00098     
00099     return 0;
00100 }
00101 
00102 const char *C027Interface::get_ip_address()
00103 {
00104     return _ip_address.get_ip_address();
00105 }
00106 
00107 const char *C027Interface::get_mac_address()
00108 {
00109     return 0;
00110 }
00111 
00112 struct c027_socket {
00113     int socket;
00114     MDMParser::IpProtocol proto;
00115     MDMParser::IP ip;
00116     int port;
00117 };
00118 
00119 int C027Interface::socket_open(void **handle, nsapi_protocol_t proto)
00120 {
00121     MDMParser::IpProtocol mdmproto = (proto == NSAPI_UDP) ? MDMParser::IPPROTO_UDP : MDMParser::IPPROTO_TCP;
00122     int fd = _mdm->socketSocket(mdmproto);
00123     if (fd < 0) {
00124         return NSAPI_ERROR_NO_SOCKET;
00125     }
00126     
00127     _mdm->socketSetBlocking(fd, 10000);
00128     struct c027_socket *socket = new struct c027_socket;
00129     if (!socket) {
00130         return NSAPI_ERROR_NO_SOCKET;
00131     }
00132 
00133     socket->socket = fd;
00134     socket->proto = mdmproto;
00135     *handle = socket;
00136     return 0;
00137 }
00138 
00139 int C027Interface::socket_close(void *handle)
00140 {
00141     struct c027_socket *socket = (struct c027_socket *)handle;
00142     _mdm->socketFree(socket->socket);
00143 
00144     delete socket;
00145     return 0;
00146 }
00147 
00148 int C027Interface::socket_bind(void *handle, const SocketAddress &address)
00149 {
00150     return NSAPI_ERROR_UNSUPPORTED;
00151 }
00152 
00153 int C027Interface::socket_listen(void *handle, int backlog)
00154 {
00155     return NSAPI_ERROR_UNSUPPORTED;
00156 }
00157 
00158 int C027Interface::socket_connect(void *handle, const SocketAddress &addr)
00159 {
00160     struct c027_socket *socket = (struct c027_socket *)handle;
00161     
00162     if (!_mdm->socketConnect(socket->socket, addr.get_ip_address(), addr.get_port())) {
00163         return NSAPI_ERROR_DEVICE_ERROR;
00164     }
00165     
00166     return 0;
00167 }
00168 
00169 nsapi_error_t C027Interface::socket_accept(nsapi_socket_t server,
00170             nsapi_socket_t *handle, SocketAddress *address)
00171 {
00172     return NSAPI_ERROR_UNSUPPORTED;
00173 }
00174 
00175 int C027Interface::socket_send(void *handle, const void *data, unsigned size)
00176 {
00177     m.lock();
00178         struct c027_socket *socket = (struct c027_socket *)handle;
00179 
00180     int sent = _mdm->socketSend(socket->socket, (const char *)data, size);
00181         m.unlock();
00182     if (sent == SOCKET_ERROR) {
00183         return NSAPI_ERROR_DEVICE_ERROR;
00184     }
00185     
00186     return sent;
00187 }
00188 
00189 int C027Interface::socket_recv(void *handle, void *data, unsigned size)
00190 {
00191     m.lock();
00192         struct c027_socket *socket = (struct c027_socket *)handle;
00193     
00194         if (!_mdm->socketReadable(socket->socket)) {
00195                 m.unlock();
00196         return NSAPI_ERROR_WOULD_BLOCK;
00197     }
00198 
00199         int size_r = size >= 200 ? 200 : size;
00200 
00201     int recv = _mdm->socketRecv(socket->socket, (char *)data, size_r);
00202         m.unlock();
00203     if (recv == SOCKET_ERROR) {
00204         return NSAPI_ERROR_DEVICE_ERROR;
00205     }
00206     return recv;
00207 }
00208 
00209 int C027Interface::socket_sendto(void *handle, const SocketAddress &addr, const void *data, unsigned size)
00210 {
00211     struct c027_socket *socket = (struct c027_socket *)handle;
00212 
00213     int sent = _mdm->socketSendTo(socket->socket,
00214             *(MDMParser::IP *)addr.get_ip_bytes(), addr.get_port(),
00215             (const char *)data, size);
00216             
00217     if (sent == SOCKET_ERROR) {
00218         return NSAPI_ERROR_DEVICE_ERROR;
00219     }
00220     
00221     return sent;
00222 }
00223 
00224 int C027Interface::socket_recvfrom(void *handle, SocketAddress *addr, void *data, unsigned size)
00225 {
00226     struct c027_socket *socket = (struct c027_socket *)handle;
00227     if (!_mdm->socketReadable(socket->socket)) {
00228         return NSAPI_ERROR_WOULD_BLOCK;
00229     }
00230     
00231     MDMParser::IP ip;
00232     int port;
00233 
00234     int recv = _mdm->socketRecvFrom(socket->socket, &ip, &port, (char *)data, size);
00235     if (recv == SOCKET_ERROR) {
00236         return NSAPI_ERROR_DEVICE_ERROR;
00237     }
00238 
00239     if (addr) {
00240         addr->set_ip_bytes(&ip, NSAPI_IPv4);
00241         addr->set_port(port);
00242     }
00243     
00244     return recv;
00245 }
00246 
00247 void C027Interface::socket_check()
00248 {
00249     while(running){
00250         for (int i = 0; i < NUMSOCKETS; i++){
00251                         m.lock();
00252             int readable = _mdm->socketReadable(i);
00253                         m.unlock();
00254             if (readable != -1 && readable != 0) {
00255                 event();        
00256             }
00257         }
00258         wait(1);
00259     }
00260     running = false;
00261 }
00262     
00263 
00264 void C027Interface::event(){
00265     for (int i = 0; i < NUMSOCKETS; i++){
00266         if (_cbs[i].callback) {
00267             _cbs[i].callback(_cbs[i].data);
00268         }
00269     }
00270 }
00271 
00272 void C027Interface::socket_attach(void *handle, void (*callback)(void *), void *data)
00273 {
00274     struct c027_socket *socket = (struct c027_socket *)handle;   
00275     _cbs[socket->socket].callback = callback;
00276     _cbs[socket->socket].data = data;
00277     if(!running){
00278         running = true;
00279         _thread.start(this, &C027Interface::socket_check);
00280     }
00281 }
00282