Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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_stack_init() 00085 { 00086 return NSAPI_ERROR_OK ; 00087 } 00088 00089 nsapi_error_t AT_CellularStack::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) 00090 { 00091 if (!is_protocol_supported(proto) || !handle) { 00092 return NSAPI_ERROR_UNSUPPORTED ; 00093 } 00094 00095 int max_socket_count = get_max_socket_count(); 00096 00097 if (!_socket) { 00098 if (socket_stack_init() != NSAPI_ERROR_OK ) { 00099 return NSAPI_ERROR_NO_SOCKET ; 00100 } 00101 00102 _socket = new CellularSocket*[max_socket_count]; 00103 if (!_socket) { 00104 tr_error("No memory to open socket!"); 00105 return NSAPI_ERROR_NO_SOCKET ; 00106 } 00107 _socket_count = max_socket_count; 00108 for (int i = 0; i < max_socket_count; i++) { 00109 _socket[i] = 0; 00110 } 00111 } 00112 00113 int index = -1; 00114 for (int i = 0; i < max_socket_count; i++) { 00115 if (!_socket[i]) { 00116 index = i; 00117 break; 00118 } 00119 } 00120 00121 if (index == -1) { 00122 tr_error("No socket found!"); 00123 return NSAPI_ERROR_NO_SOCKET ; 00124 } 00125 00126 tr_info("Socket open index: %d", index); 00127 // create local socket structure, socket on modem is created when app calls sendto/recvfrom 00128 _socket[index] = new CellularSocket; 00129 CellularSocket *psock; 00130 psock = _socket[index]; 00131 memset(psock, 0, sizeof(CellularSocket)); 00132 SocketAddress addr(0, get_dynamic_ip_port()); 00133 psock->id = index; 00134 psock->localAddress = addr; 00135 psock->proto = proto; 00136 *handle = psock; 00137 00138 return NSAPI_ERROR_OK ; 00139 } 00140 00141 nsapi_error_t AT_CellularStack::socket_close(nsapi_socket_t handle) 00142 { 00143 int err = NSAPI_ERROR_DEVICE_ERROR ; 00144 00145 struct CellularSocket *socket = (struct CellularSocket *)handle; 00146 if (!socket){ 00147 return err; 00148 } 00149 int sock_id = socket->id; 00150 bool sock_created = socket->created; 00151 int max_socket_count = get_max_socket_count(); 00152 00153 int index = -1; 00154 for (int i = 0; i < max_socket_count; i++) { 00155 if (_socket[i] == socket) { 00156 index = i; 00157 break; 00158 } 00159 } 00160 00161 tr_info("Close socket index: %d id: %d created: %d", index, sock_id, socket->created); 00162 00163 if (index == -1) { 00164 tr_error("No socket found to be closed"); 00165 return err; 00166 } 00167 00168 _socket[index] = NULL; 00169 delete socket; 00170 err = NSAPI_ERROR_OK ; 00171 00172 // Close the socket on the modem if it was created 00173 _at.lock(); 00174 if (sock_created) { 00175 err = socket_close_impl(sock_id); 00176 } 00177 _at.unlock(); 00178 00179 return err; 00180 } 00181 00182 nsapi_error_t AT_CellularStack::socket_bind(nsapi_socket_t handle, const SocketAddress &addr) 00183 { 00184 struct CellularSocket *socket = (CellularSocket *)handle; 00185 if (!socket) { 00186 return NSAPI_ERROR_DEVICE_ERROR ; 00187 } 00188 00189 if (addr) { 00190 socket->localAddress.set_addr(addr.get_addr()); 00191 } 00192 00193 if (addr.get_port()) { 00194 socket->localAddress.set_port(addr.get_port()); 00195 } 00196 00197 _at.lock(); 00198 00199 if (!socket->created) { 00200 create_socket_impl(socket); 00201 } 00202 00203 return _at.unlock_return_error(); 00204 } 00205 00206 nsapi_error_t AT_CellularStack::socket_listen(nsapi_socket_t handle, int backlog) 00207 { 00208 return NSAPI_ERROR_UNSUPPORTED ;; 00209 } 00210 00211 nsapi_error_t AT_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &addr) 00212 { 00213 CellularSocket *socket = (CellularSocket *)handle; 00214 if (!socket) { 00215 return NSAPI_ERROR_DEVICE_ERROR ; 00216 } 00217 socket->remoteAddress = addr; 00218 socket->connected = true; 00219 00220 return NSAPI_ERROR_OK ; 00221 } 00222 00223 nsapi_error_t AT_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr) 00224 { 00225 return NSAPI_ERROR_UNSUPPORTED ;; 00226 } 00227 00228 nsapi_size_or_error_t AT_CellularStack::socket_send(nsapi_socket_t handle, const void *data, unsigned size) 00229 { 00230 CellularSocket *socket = (CellularSocket *)handle; 00231 if (!socket || !socket->connected) { 00232 return NSAPI_ERROR_DEVICE_ERROR ; 00233 } 00234 return socket_sendto(handle, socket->remoteAddress, data, size); 00235 } 00236 00237 nsapi_size_or_error_t AT_CellularStack::socket_sendto(nsapi_socket_t handle, const SocketAddress &addr, const void *data, unsigned size) 00238 { 00239 CellularSocket *socket = (CellularSocket *)handle; 00240 if (!socket) { 00241 return NSAPI_ERROR_DEVICE_ERROR ; 00242 } 00243 00244 nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK ; 00245 00246 if (!socket->created) { 00247 _at.lock(); 00248 00249 ret_val = create_socket_impl(socket); 00250 00251 _at.unlock(); 00252 if (ret_val != NSAPI_ERROR_OK ) { 00253 return ret_val; 00254 } 00255 } 00256 00257 unsigned max_packet_size = get_max_packet_size(); 00258 00259 /* Check parameters */ 00260 if (addr.get_ip_version() == NSAPI_UNSPEC || 00261 size > max_packet_size) { 00262 return NSAPI_ERROR_DEVICE_ERROR ; 00263 } 00264 00265 _at.lock(); 00266 00267 ret_val = socket_sendto_impl(socket, addr, data, size); 00268 00269 _at.unlock(); 00270 00271 return ret_val; 00272 } 00273 00274 nsapi_size_or_error_t AT_CellularStack::socket_recv(nsapi_socket_t handle, void *data, unsigned size) 00275 { 00276 return socket_recvfrom(handle, NULL, data, size); 00277 } 00278 00279 nsapi_size_or_error_t AT_CellularStack::socket_recvfrom(nsapi_socket_t handle, SocketAddress *addr, void *buffer, unsigned size) 00280 { 00281 CellularSocket *socket = (CellularSocket *)handle; 00282 if (!socket) { 00283 return NSAPI_ERROR_DEVICE_ERROR ; 00284 } 00285 00286 nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK ; 00287 00288 if (!socket->created) { 00289 _at.lock(); 00290 00291 ret_val = create_socket_impl(socket); 00292 00293 _at.unlock(); 00294 if (ret_val != NSAPI_ERROR_OK ) { 00295 return ret_val; 00296 } 00297 } 00298 00299 _at.lock(); 00300 00301 ret_val = socket_recvfrom_impl(socket, addr, buffer, size); 00302 00303 _at.unlock(); 00304 00305 return ret_val; 00306 } 00307 00308 void AT_CellularStack::socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data) 00309 { 00310 CellularSocket *socket = (CellularSocket *)handle; 00311 if (!socket) { 00312 return; 00313 } 00314 socket->_cb = callback; 00315 socket->_data = data; 00316 }
Generated on Tue Jul 12 2022 18:18:27 by
