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.resp_stop(); 00065 _at.unlock(); 00066 // no IPV4 address, return 00067 return NULL; 00068 } 00069 00070 // in case stack type is not IPV4 only, try to look also for IPV6 address 00071 if (_stack_type != IPV4_STACK) { 00072 (void)_at.read_string(_ip, PDP_IPV6_SIZE - 1); 00073 } 00074 } 00075 00076 _at.resp_stop(); 00077 _at.unlock(); 00078 00079 // we have at least IPV4 address 00080 convert_ipv6(_ip); 00081 00082 return _ip; 00083 } 00084 00085 nsapi_error_t AT_CellularStack::socket_stack_init() 00086 { 00087 return NSAPI_ERROR_OK ; 00088 } 00089 00090 nsapi_error_t AT_CellularStack::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) 00091 { 00092 if (!is_protocol_supported(proto) || !handle) { 00093 return NSAPI_ERROR_UNSUPPORTED ; 00094 } 00095 00096 int max_socket_count = get_max_socket_count(); 00097 00098 _socket_mutex.lock(); 00099 00100 if (!_socket) { 00101 if (socket_stack_init() != NSAPI_ERROR_OK ) { 00102 _socket_mutex.unlock(); 00103 return NSAPI_ERROR_NO_SOCKET ; 00104 } 00105 00106 _socket = new CellularSocket*[max_socket_count]; 00107 if (!_socket) { 00108 tr_error("No memory to open socket!"); 00109 _socket_mutex.unlock(); 00110 return NSAPI_ERROR_NO_SOCKET ; 00111 } 00112 _socket_count = max_socket_count; 00113 for (int i = 0; i < max_socket_count; i++) { 00114 _socket[i] = 0; 00115 } 00116 } 00117 00118 int index = -1; 00119 for (int i = 0; i < max_socket_count; i++) { 00120 if (!_socket[i]) { 00121 index = i; 00122 break; 00123 } 00124 } 00125 00126 if (index == -1) { 00127 tr_error("No socket found!"); 00128 _socket_mutex.unlock(); 00129 return NSAPI_ERROR_NO_SOCKET ; 00130 } 00131 00132 tr_info("Socket open index: %d", index); 00133 // create local socket structure, socket on modem is created when app calls sendto/recvfrom 00134 _socket[index] = new CellularSocket; 00135 CellularSocket *psock; 00136 psock = _socket[index]; 00137 memset(psock, 0, sizeof(CellularSocket)); 00138 SocketAddress addr(0, get_dynamic_ip_port()); 00139 psock->id = index; 00140 psock->localAddress = addr; 00141 psock->proto = proto; 00142 *handle = psock; 00143 00144 _socket_mutex.unlock(); 00145 00146 return NSAPI_ERROR_OK ; 00147 } 00148 00149 nsapi_error_t AT_CellularStack::socket_close(nsapi_socket_t handle) 00150 { 00151 int err = NSAPI_ERROR_DEVICE_ERROR ; 00152 00153 struct CellularSocket *socket = (struct CellularSocket *)handle; 00154 if (!socket) { 00155 return err; 00156 } 00157 int sock_id = socket->id; 00158 bool sock_created = socket->created; 00159 int max_socket_count = get_max_socket_count(); 00160 00161 int index = -1; 00162 for (int i = 0; i < max_socket_count; i++) { 00163 if (_socket[i] == socket) { 00164 index = i; 00165 break; 00166 } 00167 } 00168 00169 tr_info("Close socket index: %d id: %d created: %d", index, sock_id, socket->created); 00170 00171 if (index == -1) { 00172 tr_error("No socket found to be closed"); 00173 return err; 00174 } 00175 00176 err = NSAPI_ERROR_OK ; 00177 00178 // Close the socket on the modem if it was created 00179 _at.lock(); 00180 if (sock_created) { 00181 err = socket_close_impl(sock_id); 00182 } 00183 00184 _socket[index] = NULL; 00185 delete socket; 00186 00187 _at.unlock(); 00188 00189 return err; 00190 } 00191 00192 nsapi_error_t AT_CellularStack::socket_bind(nsapi_socket_t handle, const SocketAddress &addr) 00193 { 00194 struct CellularSocket *socket = (CellularSocket *)handle; 00195 if (!socket) { 00196 return NSAPI_ERROR_DEVICE_ERROR ; 00197 } 00198 00199 if (addr) { 00200 socket->localAddress.set_addr(addr.get_addr()); 00201 } 00202 00203 if (addr.get_port()) { 00204 socket->localAddress.set_port(addr.get_port()); 00205 } 00206 00207 _at.lock(); 00208 00209 if (!socket->created) { 00210 create_socket_impl(socket); 00211 } 00212 00213 return _at.unlock_return_error(); 00214 } 00215 00216 nsapi_error_t AT_CellularStack::socket_listen(nsapi_socket_t handle, int backlog) 00217 { 00218 return NSAPI_ERROR_UNSUPPORTED ;; 00219 } 00220 00221 nsapi_error_t AT_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &addr) 00222 { 00223 CellularSocket *socket = (CellularSocket *)handle; 00224 if (!socket) { 00225 return NSAPI_ERROR_DEVICE_ERROR ; 00226 } 00227 socket->remoteAddress = addr; 00228 socket->connected = true; 00229 00230 return NSAPI_ERROR_OK ; 00231 } 00232 00233 nsapi_error_t AT_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr) 00234 { 00235 return NSAPI_ERROR_UNSUPPORTED ;; 00236 } 00237 00238 nsapi_size_or_error_t AT_CellularStack::socket_send(nsapi_socket_t handle, const void *data, unsigned size) 00239 { 00240 CellularSocket *socket = (CellularSocket *)handle; 00241 if (!socket || !socket->connected) { 00242 return NSAPI_ERROR_DEVICE_ERROR ; 00243 } 00244 return socket_sendto(handle, socket->remoteAddress, data, size); 00245 } 00246 00247 nsapi_size_or_error_t AT_CellularStack::socket_sendto(nsapi_socket_t handle, const SocketAddress &addr, const void *data, unsigned size) 00248 { 00249 CellularSocket *socket = (CellularSocket *)handle; 00250 if (!socket) { 00251 return NSAPI_ERROR_DEVICE_ERROR ; 00252 } 00253 00254 nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK ; 00255 00256 if (!socket->created) { 00257 _at.lock(); 00258 00259 ret_val = create_socket_impl(socket); 00260 00261 _at.unlock(); 00262 if (ret_val != NSAPI_ERROR_OK ) { 00263 tr_error("Error creating socket to send to: %s error code: %d", addr.get_ip_address(), ret_val); 00264 return ret_val; 00265 } else { 00266 tr_info("Success creating socket to send to: %s", addr.get_ip_address()); 00267 } 00268 } 00269 00270 /* Check parameters */ 00271 if (addr.get_ip_version() == NSAPI_UNSPEC ) { 00272 return NSAPI_ERROR_DEVICE_ERROR ; 00273 } 00274 00275 _at.lock(); 00276 00277 ret_val = socket_sendto_impl(socket, addr, data, size); 00278 00279 if (ret_val > 0) { 00280 tr_info("Success sending %d Bytes to: %s", ret_val, addr.get_ip_address()); 00281 } else if (ret_val != NSAPI_ERROR_WOULD_BLOCK ) { 00282 tr_error("Error sending to: %s error code: %d", addr.get_ip_address(), ret_val); 00283 } 00284 00285 _at.unlock(); 00286 00287 return ret_val; 00288 } 00289 00290 nsapi_size_or_error_t AT_CellularStack::socket_recv(nsapi_socket_t handle, void *data, unsigned size) 00291 { 00292 return socket_recvfrom(handle, NULL, data, size); 00293 } 00294 00295 nsapi_size_or_error_t AT_CellularStack::socket_recvfrom(nsapi_socket_t handle, SocketAddress *addr, void *buffer, unsigned size) 00296 { 00297 CellularSocket *socket = (CellularSocket *)handle; 00298 if (!socket) { 00299 return NSAPI_ERROR_DEVICE_ERROR ; 00300 } 00301 00302 nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK ; 00303 00304 if (!socket->created) { 00305 _at.lock(); 00306 00307 ret_val = create_socket_impl(socket); 00308 00309 _at.unlock(); 00310 if (ret_val != NSAPI_ERROR_OK ) { 00311 return ret_val; 00312 } 00313 } 00314 00315 _at.lock(); 00316 00317 ret_val = socket_recvfrom_impl(socket, addr, buffer, size); 00318 00319 _at.unlock(); 00320 00321 return ret_val; 00322 } 00323 00324 void AT_CellularStack::socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data) 00325 { 00326 CellularSocket *socket = (CellularSocket *)handle; 00327 if (!socket) { 00328 return; 00329 } 00330 socket->_cb = callback; 00331 socket->_data = data; 00332 }
Generated on Tue Aug 9 2022 00:37:03 by
1.7.2