BA / Mbed OS BaBoRo_test2
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AT_CellularStack.cpp Source File

AT_CellularStack.cpp

00001 /*
00002  * Copyright (c) 2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "AT_CellularStack.h"
00019 #include "CellularUtil.h"
00020 #include "CellularLog.h"
00021 
00022 using namespace mbed_cellular_util;
00023 using namespace mbed;
00024 
00025 AT_CellularStack::AT_CellularStack(ATHandler &at, int cid, nsapi_ip_stack_t stack_type) : AT_CellularBase(at), _socket(NULL),_socket_count(0),_cid(cid), _stack_type(stack_type)
00026 {
00027     memset(_ip,0, PDP_IPV6_SIZE);
00028 }
00029 
00030 AT_CellularStack::~AT_CellularStack()
00031 {
00032     for (int i = 0; i < _socket_count; i++) {
00033         if (_socket[i]) {
00034             delete _socket[i];
00035             _socket[i] = NULL;
00036         }
00037     }
00038     _socket_count = 0;
00039 
00040     delete [] _socket;
00041     _socket = NULL;
00042 }
00043 
00044 /** NetworkStack
00045  */
00046 
00047 const char * AT_CellularStack::get_ip_address()
00048 {
00049     _at.lock();
00050 
00051     _at.cmd_start("AT+CGPADDR=");
00052     _at.write_int(_cid);
00053     _at.cmd_stop();
00054 
00055     _at.resp_start("+CGPADDR:");
00056 
00057     if (_at.info_resp()) {
00058 
00059         _at.skip_param();
00060 
00061         int len = _at.read_string(_ip, NSAPI_IPv4_SIZE-1);
00062         if (len == -1) {
00063             _ip[0] = '\0';
00064             _at.unlock();
00065             // no IPV4 address, return
00066             return NULL;
00067         }
00068 
00069         // in case stack type is not IPV4 only, try to look also for IPV6 address
00070         if (_stack_type != IPV4_STACK) {
00071             (void)_at.read_string(_ip, PDP_IPV6_SIZE-1);
00072         }
00073     }
00074 
00075     _at.resp_stop();
00076     _at.unlock();
00077 
00078     // we have at least IPV4 address
00079     convert_ipv6(_ip);
00080 
00081     return _ip;
00082 }
00083 
00084 nsapi_error_t AT_CellularStack::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
00085 {
00086     if (!is_protocol_supported(proto) || !handle) {
00087         return NSAPI_ERROR_UNSUPPORTED ;
00088     }
00089 
00090     int max_socket_count = get_max_socket_count();
00091 
00092     if (!_socket) {
00093         _socket = new CellularSocket*[max_socket_count];
00094         if (!_socket) {
00095             tr_error("No memory to open socket!");
00096             return NSAPI_ERROR_NO_SOCKET ;
00097         }
00098         _socket_count = max_socket_count;
00099         for (int i = 0; i < max_socket_count; i++) {
00100             _socket[i] = 0;
00101         }
00102     }
00103 
00104     int index = -1;
00105     for (int i = 0; i < max_socket_count; i++) {
00106         if (!_socket[i]) {
00107             index = i;
00108             break;
00109         }
00110     }
00111 
00112     if (index == -1) {
00113         tr_error("No socket found!");
00114         return NSAPI_ERROR_NO_SOCKET ;
00115     }
00116 
00117     tr_info("Socket open index: %d", index);
00118     // create local socket structure, socket on modem is created when app calls sendto/recvfrom
00119     _socket[index] = new CellularSocket;
00120     CellularSocket *psock;
00121     psock = _socket[index];
00122     memset(psock, 0, sizeof(CellularSocket));
00123     SocketAddress addr(0, get_dynamic_ip_port());
00124     psock->id = index;
00125     psock->localAddress = addr;
00126     psock->proto = proto;
00127     *handle = psock;
00128 
00129     return NSAPI_ERROR_OK ;
00130 }
00131 
00132 nsapi_error_t AT_CellularStack::socket_close(nsapi_socket_t handle)
00133 {
00134     int err = NSAPI_ERROR_DEVICE_ERROR ;
00135 
00136     struct CellularSocket *socket = (struct CellularSocket *)handle;
00137     if (!socket){
00138         return err;
00139     }
00140     int sock_id = socket->id;
00141     bool sock_created = socket->created;
00142     int max_socket_count = get_max_socket_count();
00143 
00144     int index = -1;
00145     for (int i = 0; i < max_socket_count; i++) {
00146         if (_socket[i] == socket) {
00147             index = i;
00148             break;
00149         }
00150     }
00151 
00152     tr_info("Close socket index: %d id: %d created: %d", index, sock_id, socket->created);
00153 
00154     if (index == -1) {
00155         tr_error("No socket found to be closed");
00156         return err;
00157     }
00158 
00159     _socket[index] = NULL;
00160     delete socket;
00161     err = NSAPI_ERROR_OK ;
00162 
00163     // Close the socket on the modem if it was created
00164     _at.lock();
00165     if (sock_created) {
00166         err = socket_close_impl(sock_id);
00167     }
00168     _at.unlock();
00169 
00170     return err;
00171 }
00172 
00173 nsapi_error_t AT_CellularStack::socket_bind(nsapi_socket_t handle, const SocketAddress &addr)
00174 {
00175     struct CellularSocket *socket = (CellularSocket *)handle;
00176     if (!socket) {
00177         return NSAPI_ERROR_DEVICE_ERROR ;
00178     }
00179 
00180     if (addr) {
00181         socket->localAddress.set_addr(addr.get_addr());
00182     }
00183 
00184     if (addr.get_port()) {
00185         socket->localAddress.set_port(addr.get_port());
00186     }
00187 
00188     _at.lock();
00189 
00190     if (!socket->created) {
00191         create_socket_impl(socket);
00192     }
00193 
00194     return _at.unlock_return_error();
00195 }
00196 
00197 nsapi_error_t AT_CellularStack::socket_listen(nsapi_socket_t handle, int backlog)
00198 {
00199     return NSAPI_ERROR_UNSUPPORTED ;;
00200 }
00201 
00202 nsapi_error_t AT_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &addr)
00203 {
00204     CellularSocket *socket = (CellularSocket *)handle;
00205     if (!socket) {
00206         return NSAPI_ERROR_DEVICE_ERROR ;
00207     }
00208     socket->remoteAddress = addr;
00209     socket->connected = true;
00210 
00211     return NSAPI_ERROR_OK ;
00212 }
00213 
00214 nsapi_error_t AT_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr)
00215 {
00216     return NSAPI_ERROR_UNSUPPORTED ;;
00217 }
00218 
00219 nsapi_size_or_error_t AT_CellularStack::socket_send(nsapi_socket_t handle, const void *data, unsigned size)
00220 {
00221     CellularSocket *socket = (CellularSocket *)handle;
00222     if (!socket || !socket->connected) {
00223         return NSAPI_ERROR_DEVICE_ERROR ;
00224     }
00225     return socket_sendto(handle, socket->remoteAddress, data, size);
00226 }
00227 
00228 nsapi_size_or_error_t AT_CellularStack::socket_sendto(nsapi_socket_t handle, const SocketAddress &addr, const void *data, unsigned size)
00229 {
00230     CellularSocket *socket = (CellularSocket *)handle;
00231     if (!socket) {
00232         return NSAPI_ERROR_DEVICE_ERROR ;
00233     }
00234 
00235     nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK ;
00236 
00237     if (!socket->created) {
00238         _at.lock();
00239 
00240         ret_val = create_socket_impl(socket);
00241 
00242         _at.unlock();
00243         if (ret_val != NSAPI_ERROR_OK ) {
00244             return ret_val;
00245         }
00246     }
00247 
00248     unsigned max_packet_size = get_max_packet_size();
00249 
00250     /* Check parameters */
00251     if (addr.get_ip_version() == NSAPI_UNSPEC  ||
00252             size > max_packet_size) {
00253         return NSAPI_ERROR_DEVICE_ERROR ;
00254     }
00255 
00256     _at.lock();
00257 
00258     ret_val = socket_sendto_impl(socket, addr, data, size);
00259 
00260     _at.unlock();
00261 
00262     return ret_val;
00263 }
00264 
00265 nsapi_size_or_error_t AT_CellularStack::socket_recv(nsapi_socket_t handle, void *data, unsigned size)
00266 {
00267     return socket_recvfrom(handle, NULL, data, size);
00268 }
00269 
00270 nsapi_size_or_error_t AT_CellularStack::socket_recvfrom(nsapi_socket_t handle, SocketAddress *addr, void *buffer, unsigned size)
00271 {
00272     CellularSocket *socket = (CellularSocket *)handle;
00273     if (!socket) {
00274         return NSAPI_ERROR_DEVICE_ERROR ;
00275     }
00276 
00277     nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK ;
00278 
00279     if (!socket->created) {
00280         _at.lock();
00281 
00282         ret_val = create_socket_impl(socket);
00283 
00284         _at.unlock();
00285         if (ret_val != NSAPI_ERROR_OK ) {
00286             return ret_val;
00287         }
00288     }
00289 
00290     _at.lock();
00291 
00292     ret_val = socket_recvfrom_impl(socket, addr, buffer, size);
00293 
00294     _at.unlock();
00295 
00296     return ret_val;
00297 }
00298 
00299 void AT_CellularStack::socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data)
00300 {
00301     CellularSocket *socket = (CellularSocket *)handle;
00302     if (!socket) {
00303         return;
00304     }
00305     socket->_cb = callback;
00306     socket->_data = data;
00307 }