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.
QUECTEL_BG96_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 "QUECTEL/BG96/QUECTEL_BG96_CellularStack.h" 00019 #include "CellularLog.h" 00020 00021 using namespace mbed; 00022 00023 QUECTEL_BG96_CellularStack::QUECTEL_BG96_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type) : AT_CellularStack(atHandler, cid, stack_type) 00024 { 00025 _at.set_urc_handler("+QIURC:", mbed::Callback<void()>(this, &QUECTEL_BG96_CellularStack::urc_qiurc)); 00026 } 00027 00028 QUECTEL_BG96_CellularStack::~QUECTEL_BG96_CellularStack() 00029 { 00030 } 00031 00032 nsapi_error_t QUECTEL_BG96_CellularStack::socket_listen(nsapi_socket_t handle, int backlog) 00033 { 00034 return NSAPI_ERROR_UNSUPPORTED ; 00035 } 00036 00037 nsapi_error_t QUECTEL_BG96_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr) 00038 { 00039 return NSAPI_ERROR_UNSUPPORTED ; 00040 } 00041 00042 void QUECTEL_BG96_CellularStack::urc_qiurc() 00043 { 00044 int sock_id=0; 00045 00046 _at.lock(); 00047 (void) _at.skip_param(); 00048 sock_id = _at.read_int(); 00049 _at.unlock(); 00050 00051 for (int i = 0; i < get_max_socket_count(); i++) { 00052 CellularSocket *sock = _socket[i]; 00053 if (sock && sock->id == sock_id) { 00054 if (sock->_cb) { 00055 sock->_cb(sock->_data); 00056 } 00057 break; 00058 } 00059 } 00060 } 00061 00062 int QUECTEL_BG96_CellularStack::get_max_socket_count() 00063 { 00064 return BG96_SOCKET_MAX; 00065 } 00066 00067 int QUECTEL_BG96_CellularStack::get_max_packet_size() 00068 { 00069 return BG96_MAX_PACKET_SIZE; 00070 } 00071 00072 bool QUECTEL_BG96_CellularStack::is_protocol_supported(nsapi_protocol_t protocol) 00073 { 00074 return (protocol == NSAPI_UDP ); 00075 } 00076 00077 nsapi_error_t QUECTEL_BG96_CellularStack::socket_close_impl(int sock_id) 00078 { 00079 _at.cmd_start("AT+QICLOSE="); 00080 _at.write_int(sock_id); 00081 _at.cmd_stop(); 00082 _at.resp_start(); 00083 _at.resp_stop(); 00084 00085 return _at.get_last_error(); 00086 } 00087 00088 void QUECTEL_BG96_CellularStack::handle_open_socket_response(int &modem_connect_id, int &err) 00089 { 00090 // OK 00091 _at.resp_start(); 00092 _at.resp_stop(); 00093 // QIOPEN -> should be handled as URC? 00094 _at.set_at_timeout(BG96_CREATE_SOCKET_TIMEOUT); 00095 _at.resp_start("+QIOPEN:"); 00096 _at.restore_at_timeout(); 00097 modem_connect_id = _at.read_int(); 00098 err = _at.read_int(); 00099 } 00100 nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *socket) 00101 { 00102 int modem_connect_id; 00103 int request_connect_id = socket->id; 00104 int remote_port = 0; 00105 int err = -1; 00106 00107 if (socket->proto == NSAPI_UDP && !socket->connected) { 00108 _at.cmd_start("AT+QIOPEN="); 00109 _at.write_int(_cid); 00110 _at.write_int(request_connect_id); 00111 _at.write_string("UDP SERVICE"); 00112 _at.write_string("127.0.0.1"); 00113 _at.write_int(remote_port); 00114 _at.write_int(socket->localAddress.get_port()); 00115 _at.write_int(0); 00116 _at.cmd_stop(); 00117 00118 handle_open_socket_response(modem_connect_id, err); 00119 00120 if ((_at.get_last_error() == NSAPI_ERROR_OK ) && err) { 00121 _at.cmd_start("AT+QICLOSE="); 00122 _at.write_int(modem_connect_id); 00123 _at.cmd_stop(); 00124 _at.resp_start(); 00125 _at.resp_stop(); 00126 00127 _at.cmd_start("AT+QIOPEN="); 00128 _at.write_int(_cid); 00129 _at.write_int(request_connect_id); 00130 _at.write_string("UDP SERVICE"); 00131 _at.write_string("127.0.0.1"); 00132 _at.write_int(remote_port); 00133 _at.write_int(socket->localAddress.get_port()); 00134 _at.write_int(0); 00135 _at.cmd_stop(); 00136 00137 handle_open_socket_response(modem_connect_id, err); 00138 } 00139 } else if (socket->proto == NSAPI_UDP && socket->connected) { 00140 _at.cmd_start("AT+QIOPEN="); 00141 _at.write_int(_cid); 00142 _at.write_int(request_connect_id); 00143 _at.write_string("UDP"); 00144 _at.write_string(socket->remoteAddress.get_ip_address()); 00145 _at.write_int(socket->remoteAddress.get_port()); 00146 _at.cmd_stop(); 00147 00148 handle_open_socket_response(modem_connect_id, err); 00149 00150 if ((_at.get_last_error() == NSAPI_ERROR_OK ) && err) { 00151 _at.cmd_start("AT+QICLOSE="); 00152 _at.write_int(modem_connect_id); 00153 _at.cmd_stop(); 00154 _at.resp_start(); 00155 _at.resp_stop(); 00156 00157 _at.cmd_start("AT+QIOPEN="); 00158 _at.write_int(_cid); 00159 _at.write_int(request_connect_id); 00160 _at.write_string("UDP"); 00161 _at.write_string(socket->remoteAddress.get_ip_address()); 00162 _at.write_int(socket->remoteAddress.get_port()); 00163 _at.cmd_stop(); 00164 00165 handle_open_socket_response(modem_connect_id, err); 00166 } 00167 } 00168 00169 // If opened successfully BUT not requested one, close it 00170 if (!err && (modem_connect_id != request_connect_id)) { 00171 _at.cmd_start("AT+QICLOSE="); 00172 _at.write_int(modem_connect_id); 00173 _at.cmd_stop(); 00174 _at.resp_start(); 00175 _at.resp_stop(); 00176 } 00177 00178 nsapi_error_t ret_val = _at.get_last_error(); 00179 00180 socket->created = ((ret_val == NSAPI_ERROR_OK ) && (modem_connect_id == request_connect_id)); 00181 00182 return ret_val; 00183 } 00184 00185 nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, 00186 const void *data, nsapi_size_t size) 00187 { 00188 int sent_len = 0; 00189 int sent_len_before = 0; 00190 int sent_len_after = 0; 00191 00192 // Get the sent count before sending 00193 _at.cmd_start("AT+QISEND="); 00194 _at.write_int(socket->id); 00195 _at.write_int(0); 00196 _at.cmd_stop(); 00197 00198 _at.resp_start("+QISEND:"); 00199 sent_len_before = _at.read_int(); 00200 _at.resp_stop(); 00201 00202 // Send 00203 _at.cmd_start("AT+QISEND="); 00204 _at.write_int(socket->id); 00205 _at.write_int(size); 00206 _at.write_string(address.get_ip_address()); 00207 _at.write_int(address.get_port()); 00208 _at.cmd_stop(); 00209 00210 _at.resp_start(">"); 00211 _at.write_bytes((uint8_t*)data, size); 00212 _at.resp_start(); 00213 _at.set_stop_tag("\r\n"); 00214 _at.resp_stop(); 00215 00216 // Get the sent count after sending 00217 _at.cmd_start("AT+QISEND="); 00218 _at.write_int(socket->id); 00219 _at.write_int(0); 00220 _at.cmd_stop(); 00221 00222 _at.resp_start("+QISEND:"); 00223 sent_len_after = _at.read_int(); 00224 _at.resp_stop(); 00225 00226 if (_at.get_last_error() == NSAPI_ERROR_OK ) { 00227 sent_len = sent_len_after - sent_len_before; 00228 return sent_len; 00229 } 00230 00231 return _at.get_last_error(); 00232 } 00233 00234 nsapi_size_or_error_t QUECTEL_BG96_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, 00235 void *buffer, nsapi_size_t size) 00236 { 00237 nsapi_size_or_error_t recv_len=0; 00238 int port; 00239 char ip_address[NSAPI_IP_SIZE + 1]; 00240 00241 _at.cmd_start("AT+QIRD="); 00242 _at.write_int(socket->id); 00243 _at.cmd_stop(); 00244 00245 _at.resp_start("+QIRD:"); 00246 recv_len = _at.read_int(); 00247 _at.read_string(ip_address, sizeof(ip_address)); 00248 port = _at.read_int(); 00249 _at.read_bytes((uint8_t*)buffer, recv_len); 00250 _at.resp_stop(); 00251 00252 if (!recv_len || (_at.get_last_error() != NSAPI_ERROR_OK )) { 00253 return NSAPI_ERROR_WOULD_BLOCK ; 00254 } 00255 00256 if (address) { 00257 address->set_ip_address(ip_address); 00258 address->set_port(port); 00259 } 00260 00261 return recv_len; 00262 }
Generated on Tue Jul 12 2022 14:24:32 by
