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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
UBLOX_N2XX_CellularStack.cpp
00001 /* 00002 * Copyright (c) 2019, 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 "UBLOX_N2XX_CellularStack.h" 00019 #include "CellularUtil.h" 00020 #include <stdlib.h> 00021 00022 using namespace mbed; 00023 using namespace mbed_cellular_util; 00024 00025 UBLOX_N2XX_CellularStack::UBLOX_N2XX_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device): 00026 AT_CellularStack(atHandler, cid, stack_type, device) 00027 { 00028 // URC handlers for sockets 00029 _at.set_urc_handler("+NSONMI:", callback(this, &UBLOX_N2XX_CellularStack::NSONMI_URC)); 00030 } 00031 00032 UBLOX_N2XX_CellularStack::~UBLOX_N2XX_CellularStack() 00033 { 00034 _at.set_urc_handler("+NSONMI:", NULL); 00035 } 00036 00037 nsapi_error_t UBLOX_N2XX_CellularStack::socket_listen(nsapi_socket_t handle, int backlog) 00038 { 00039 return NSAPI_ERROR_UNSUPPORTED ; 00040 } 00041 00042 nsapi_error_t UBLOX_N2XX_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr) 00043 { 00044 return NSAPI_ERROR_UNSUPPORTED ; 00045 } 00046 00047 // Callback for Socket Read URC. 00048 void UBLOX_N2XX_CellularStack::NSONMI_URC() 00049 { 00050 int a, b; 00051 CellularSocket *socket; 00052 00053 a = _at.read_int(); 00054 b = _at.read_int(); 00055 00056 socket = find_socket(a); 00057 if (socket != NULL) { 00058 socket->pending_bytes = b; 00059 // No debug prints here as they can affect timing 00060 // and cause data loss in UARTSerial 00061 if (socket->_cb != NULL) { 00062 socket->_cb(socket->_data); 00063 } 00064 } 00065 } 00066 00067 int UBLOX_N2XX_CellularStack::get_max_socket_count() 00068 { 00069 return N2XX_MAX_SOCKET; 00070 } 00071 00072 bool UBLOX_N2XX_CellularStack::is_protocol_supported(nsapi_protocol_t protocol) 00073 { 00074 return (protocol == NSAPI_UDP ); 00075 } 00076 00077 nsapi_error_t UBLOX_N2XX_CellularStack::create_socket_impl(CellularSocket *socket) 00078 { 00079 int sock_id = -1; 00080 int localport = socket->localAddress.get_port(); 00081 00082 if (localport == 5683 || localport < 0 || localport > 65535) { 00083 return NSAPI_ERROR_NO_SOCKET ; 00084 } 00085 00086 _at.lock(); 00087 _at.cmd_start_stop("+NSOCR", "=", "%s%d%d%d", "DGRAM", 17, localport, 1); 00088 00089 _at.resp_start(); 00090 sock_id = _at.read_int(); 00091 _at.resp_stop(); 00092 00093 if ((_at.get_last_error() != NSAPI_ERROR_OK ) || (sock_id == -1)) { 00094 _at.unlock(); 00095 return NSAPI_ERROR_NO_SOCKET ; 00096 } 00097 _at.unlock(); 00098 00099 // Check for duplicate socket id delivered by modem 00100 for (int i = 0; i < N2XX_MAX_SOCKET; i++) { 00101 CellularSocket *sock = _socket[i]; 00102 if (sock && sock != socket && sock->id == sock_id) { 00103 return NSAPI_ERROR_NO_SOCKET ; 00104 } 00105 } 00106 00107 socket->started = true; 00108 socket->id = sock_id; 00109 00110 return NSAPI_ERROR_OK ; 00111 } 00112 00113 nsapi_size_or_error_t UBLOX_N2XX_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, 00114 const void *data, nsapi_size_t size) 00115 { 00116 MBED_ASSERT(socket->id != -1); 00117 00118 if (size > N2XX_MAX_PACKET_SIZE) { 00119 return NSAPI_ERROR_PARAMETER ; 00120 } 00121 00122 int sent_len = 0; 00123 char *dataStr = new char [(size * 2) + 1](); 00124 if (!dataStr) { 00125 return NSAPI_ERROR_NO_MEMORY ; 00126 } 00127 char_str_to_hex_str((const char *)data, size, dataStr); 00128 00129 _at.cmd_start_stop("+NSOST", "=", "%d%s%d%d%s", socket->id, address.get_ip_address(), 00130 address.get_port(), size, dataStr); 00131 00132 _at.resp_start(); 00133 _at.skip_param(); // skip socket id 00134 sent_len = _at.read_int(); 00135 _at.resp_stop(); 00136 00137 delete[] dataStr; 00138 if ((_at.get_last_error() == NSAPI_ERROR_OK )) { 00139 return sent_len; 00140 } 00141 00142 return _at.get_last_error(); 00143 } 00144 00145 nsapi_size_or_error_t UBLOX_N2XX_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, 00146 void *buffer, nsapi_size_t size) 00147 { 00148 MBED_ASSERT(socket->id != -1); 00149 00150 nsapi_size_or_error_t nsapi_error_size = NSAPI_ERROR_DEVICE_ERROR ; 00151 nsapi_size_t read_blk, usorf_sz, count = 0, length = size; 00152 bool success = true; 00153 char ipAddress[NSAPI_IP_SIZE]; 00154 int port = 0; 00155 Timer timer; 00156 00157 if (socket->pending_bytes == 0) { 00158 _at.process_oob(); 00159 if (socket->pending_bytes == 0) { 00160 return NSAPI_ERROR_WOULD_BLOCK ; 00161 } 00162 } 00163 00164 timer.start(); 00165 while (success && (length > 0)) { 00166 read_blk = N2XX_MAX_PACKET_SIZE; 00167 if (read_blk > length) { 00168 read_blk = length; 00169 } 00170 if (socket->pending_bytes > 0) { 00171 _at.cmd_start_stop("+NSORF", "=", "%d%d", socket->id, read_blk); 00172 00173 _at.resp_start(); 00174 _at.skip_param(); // receiving socket id 00175 _at.read_string(ipAddress, sizeof(ipAddress)); 00176 port = _at.read_int(); 00177 usorf_sz = _at.read_int(); 00178 if (usorf_sz > length) { 00179 usorf_sz = length; 00180 } 00181 _at.read_hex_string((char *)buffer + count, usorf_sz); 00182 _at.resp_stop(); 00183 00184 // Must use what +NSORF returns here as it may be less or more than we asked for 00185 if (usorf_sz >= socket->pending_bytes) { 00186 socket->pending_bytes = 0; 00187 } else { 00188 socket->pending_bytes -= usorf_sz; 00189 } 00190 00191 if (usorf_sz > 0) { 00192 count += (usorf_sz); 00193 length -= (usorf_sz); 00194 } else { 00195 // read() should not fail 00196 success = false; 00197 } 00198 } else if (timer.read_ms() < SOCKET_TIMEOUT) { 00199 // Wait for URCs 00200 _at.process_oob(); 00201 } else { 00202 if (count == 0) { 00203 // Timeout with nothing received 00204 nsapi_error_size = NSAPI_ERROR_WOULD_BLOCK ; 00205 success = false; 00206 } 00207 length = 0; // This simply to cause an exit 00208 } 00209 } 00210 timer.stop(); 00211 00212 socket->pending_bytes = 0; 00213 if (!count || (_at.get_last_error() != NSAPI_ERROR_OK )) { 00214 return NSAPI_ERROR_WOULD_BLOCK ; 00215 } 00216 00217 if (success && socket->proto == NSAPI_UDP && address) { 00218 address->set_ip_address(ipAddress); 00219 address->get_ip_address(); 00220 address->set_port(port); 00221 } 00222 00223 return nsapi_error_size = count; 00224 } 00225 00226 nsapi_error_t UBLOX_N2XX_CellularStack::socket_close_impl(int sock_id) 00227 { 00228 return _at.at_cmd_discard("+NSOCL", "=", "%d", sock_id); 00229 }
Generated on Tue Jul 12 2022 13:55:01 by
