Denislam Valeev / Mbed OS Nucleo_rtos_basic
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             len = _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             return NSAPI_ERROR_NO_SOCKET ;
00096         }
00097         _socket_count = max_socket_count;
00098         for (int i = 0; i < max_socket_count; i++) {
00099             _socket[i] = 0;
00100         }
00101     }
00102 
00103     int index = -1;
00104     for (int i = 0; i < max_socket_count; i++) {
00105         if (!_socket[i]) {
00106             index = i;
00107             break;
00108         }
00109     }
00110 
00111     if (index == -1) {
00112         return NSAPI_ERROR_NO_SOCKET ;
00113     }
00114 
00115     // create local socket structure, socket on modem is created when app calls sendto/recvfrom
00116     _socket[index] = new CellularSocket;
00117     CellularSocket *psock;
00118     psock = _socket[index];
00119     memset(psock, 0, sizeof(CellularSocket));
00120     SocketAddress addr(0, get_dynamic_ip_port());
00121     psock->id = index;
00122     psock->localAddress = addr;
00123     psock->proto = proto;
00124     *handle = psock;
00125 
00126     return NSAPI_ERROR_OK ;
00127 }
00128 
00129 nsapi_error_t AT_CellularStack::socket_close(nsapi_socket_t handle)
00130 {
00131     int err = NSAPI_ERROR_DEVICE_ERROR ;
00132 
00133     struct CellularSocket *socket = (struct CellularSocket *)handle;
00134     if (!socket){
00135         return err;
00136     }
00137     int sock_id = socket->id;
00138     int max_socket_count = get_max_socket_count();
00139 
00140     int index = -1;
00141     for (int i = 0; i < max_socket_count; i++) {
00142         if (_socket[i] && _socket[i]->id == sock_id) {
00143             index = i;
00144             break;
00145         }
00146     }
00147 
00148     if (index == -1) {
00149         return err;
00150     }
00151     _socket[index] = NULL;
00152     err = NSAPI_ERROR_OK ;
00153 
00154     _at.lock();
00155 
00156     err = socket_close_impl(sock_id);
00157 
00158     _at.unlock();
00159 
00160     delete socket;
00161     socket = NULL;
00162 
00163     return err;
00164 }
00165 
00166 nsapi_error_t AT_CellularStack::socket_bind(nsapi_socket_t handle, const SocketAddress &addr)
00167 {
00168     struct CellularSocket *socket = (CellularSocket *)handle;
00169     if (!socket) {
00170         return NSAPI_ERROR_DEVICE_ERROR ;
00171     }
00172 
00173     if (addr) {
00174         socket->localAddress.set_addr(addr.get_addr());
00175     }
00176 
00177     if (addr.get_port()) {
00178         socket->localAddress.set_port(addr.get_port());
00179     }
00180 
00181     _at.lock();
00182 
00183     if (!socket->created) {
00184         create_socket_impl(socket);
00185     }
00186 
00187     return _at.unlock_return_error();
00188 }
00189 
00190 nsapi_error_t AT_CellularStack::socket_listen(nsapi_socket_t handle, int backlog)
00191 {
00192     return NSAPI_ERROR_UNSUPPORTED ;;
00193 }
00194 
00195 nsapi_error_t AT_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &addr)
00196 {
00197     CellularSocket *socket = (CellularSocket *)handle;
00198     if (!socket) {
00199         return NSAPI_ERROR_DEVICE_ERROR ;
00200     }
00201     socket->remoteAddress = addr;
00202     socket->connected = true;
00203 
00204     return NSAPI_ERROR_OK ;
00205 }
00206 
00207 nsapi_error_t AT_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr)
00208 {
00209     return NSAPI_ERROR_UNSUPPORTED ;;
00210 }
00211 
00212 nsapi_size_or_error_t AT_CellularStack::socket_send(nsapi_socket_t handle, const void *data, unsigned size)
00213 {
00214     CellularSocket *socket = (CellularSocket *)handle;
00215     if (!socket || !socket->connected) {
00216         return NSAPI_ERROR_DEVICE_ERROR ;
00217     }
00218     return socket_sendto(handle, socket->remoteAddress, data, size);
00219 }
00220 
00221 nsapi_size_or_error_t AT_CellularStack::socket_sendto(nsapi_socket_t handle, const SocketAddress &addr, const void *data, unsigned size)
00222 {
00223     CellularSocket *socket = (CellularSocket *)handle;
00224     if (!socket) {
00225         return NSAPI_ERROR_DEVICE_ERROR ;
00226     }
00227 
00228     nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK ;
00229 
00230     if (!socket->created) {
00231         _at.lock();
00232 
00233         ret_val = create_socket_impl(socket);
00234 
00235         _at.unlock();
00236         if (ret_val != NSAPI_ERROR_OK ) {
00237             return ret_val;
00238         }
00239     }
00240 
00241     unsigned max_packet_size = get_max_packet_size();
00242 
00243     /* Check parameters */
00244     if (addr.get_ip_version() == NSAPI_UNSPEC  ||
00245             size > max_packet_size) {
00246         return NSAPI_ERROR_DEVICE_ERROR ;
00247     }
00248 
00249     _at.lock();
00250 
00251     ret_val = socket_sendto_impl(socket, addr, data, size);
00252 
00253     _at.unlock();
00254 
00255     return ret_val;
00256 }
00257 
00258 nsapi_size_or_error_t AT_CellularStack::socket_recv(nsapi_socket_t handle, void *data, unsigned size)
00259 {
00260     return socket_recvfrom(handle, NULL, data, size);
00261 }
00262 
00263 nsapi_size_or_error_t AT_CellularStack::socket_recvfrom(nsapi_socket_t handle, SocketAddress *addr, void *buffer, unsigned size)
00264 {
00265     CellularSocket *socket = (CellularSocket *)handle;
00266     if (!socket) {
00267         return NSAPI_ERROR_DEVICE_ERROR ;
00268     }
00269 
00270     nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK ;
00271 
00272     if (!socket->created) {
00273         _at.lock();
00274 
00275         ret_val = create_socket_impl(socket);
00276 
00277         _at.unlock();
00278         if (ret_val != NSAPI_ERROR_OK ) {
00279             return ret_val;
00280         }
00281     }
00282 
00283     _at.lock();
00284 
00285     ret_val = socket_recvfrom_impl(socket, addr, buffer, size);
00286 
00287     _at.unlock();
00288 
00289     return ret_val;
00290 }
00291 
00292 void AT_CellularStack::socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data)
00293 {
00294     CellularSocket *socket = (CellularSocket *)handle;
00295     if (!socket) {
00296         return;
00297     }
00298     socket->_cb = callback;
00299     socket->_data = data;
00300 }