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_BC95_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_BC95_CellularStack.h" 00019 #include "CellularUtil.h" 00020 00021 using namespace mbed; 00022 using namespace mbed_cellular_util; 00023 00024 QUECTEL_BC95_CellularStack::QUECTEL_BC95_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type) : AT_CellularStack(atHandler, cid, stack_type) 00025 { 00026 _at.set_urc_handler("+NSONMI:", mbed::Callback<void()>(this, &QUECTEL_BC95_CellularStack::urc_nsonmi)); 00027 } 00028 00029 QUECTEL_BC95_CellularStack::~QUECTEL_BC95_CellularStack() 00030 { 00031 } 00032 00033 nsapi_error_t QUECTEL_BC95_CellularStack::socket_listen(nsapi_socket_t handle, int backlog) 00034 { 00035 return NSAPI_ERROR_UNSUPPORTED ; 00036 } 00037 00038 nsapi_error_t QUECTEL_BC95_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr) 00039 { 00040 return NSAPI_ERROR_UNSUPPORTED ; 00041 } 00042 00043 void QUECTEL_BC95_CellularStack::urc_nsonmi() 00044 { 00045 int sock_id =_at.read_int(); 00046 00047 for (int i = 0; i < get_max_socket_count(); i++) { 00048 CellularSocket *sock = _socket[i]; 00049 if (sock && sock->id == sock_id) { 00050 if (sock->_cb) { 00051 sock->_cb(sock->_data); 00052 } 00053 break; 00054 } 00055 } 00056 } 00057 00058 int QUECTEL_BC95_CellularStack::get_max_socket_count() 00059 { 00060 return BC95_SOCKET_MAX; 00061 } 00062 00063 int QUECTEL_BC95_CellularStack::get_max_packet_size() 00064 { 00065 return BC95_MAX_PACKET_SIZE; 00066 } 00067 00068 bool QUECTEL_BC95_CellularStack::is_protocol_supported(nsapi_protocol_t protocol) 00069 { 00070 return (protocol == NSAPI_UDP ); 00071 } 00072 00073 nsapi_error_t QUECTEL_BC95_CellularStack::socket_close_impl(int sock_id) 00074 { 00075 _at.cmd_start("AT+NSOCL="); 00076 _at.write_int(sock_id); 00077 _at.cmd_stop(); 00078 _at.resp_start(); 00079 _at.resp_stop(); 00080 00081 return _at.get_last_error(); 00082 } 00083 00084 nsapi_error_t QUECTEL_BC95_CellularStack::create_socket_impl(CellularSocket *socket) 00085 { 00086 int sock_id; 00087 bool socketOpenWorking = false; 00088 00089 if (socket->proto == NSAPI_UDP ) { 00090 00091 _at.cmd_start("AT+NSOCR=DGRAM,17,"); 00092 _at.write_int(socket->localAddress.get_port()); 00093 _at.write_int(1); 00094 _at.cmd_stop(); 00095 _at.resp_start(); 00096 sock_id = _at.read_int(); 00097 _at.resp_stop(); 00098 00099 socketOpenWorking = (_at.get_last_error() == NSAPI_ERROR_OK ); 00100 00101 if (!socketOpenWorking) { 00102 _at.cmd_start("AT+NSOCL=0"); 00103 _at.cmd_stop(); 00104 _at.resp_start(); 00105 _at.resp_stop(); 00106 00107 _at.cmd_start("AT+NSOCR=DGRAM,17,"); 00108 _at.write_int(socket->localAddress.get_port()); 00109 _at.write_int(1); 00110 _at.cmd_stop(); 00111 _at.resp_start(); 00112 sock_id = _at.read_int(); 00113 _at.resp_stop(); 00114 00115 socketOpenWorking = (_at.get_last_error() == NSAPI_ERROR_OK ); 00116 } 00117 } 00118 00119 if (!socketOpenWorking) { 00120 return NSAPI_ERROR_NO_SOCKET ; 00121 } 00122 00123 // Check for duplicate socket id delivered by modem 00124 for (int i = 0; i < BC95_SOCKET_MAX; i++) { 00125 CellularSocket *sock = _socket[i]; 00126 if (sock && sock->created && sock->id == sock_id) { 00127 return NSAPI_ERROR_NO_SOCKET ; 00128 } 00129 } 00130 00131 socket->id = sock_id; 00132 socket->created = true; 00133 00134 return NSAPI_ERROR_OK ; 00135 } 00136 00137 nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address, 00138 const void *data, nsapi_size_t size) 00139 { 00140 int sent_len = 0; 00141 00142 char hexstr[BC95_MAX_PACKET_SIZE*2 + 1] = {0}; 00143 char_str_to_hex_str((const char*)data, size, hexstr); 00144 00145 _at.cmd_start("AT+NSOST="); 00146 _at.write_int(socket->id); 00147 _at.write_string(address.get_ip_address(), false); 00148 _at.write_int(address.get_port()); 00149 _at.write_int(size); 00150 _at.write_string(hexstr, false); 00151 _at.cmd_stop(); 00152 _at.resp_start(); 00153 // skip socket id 00154 _at.skip_param(); 00155 sent_len = _at.read_int(); 00156 _at.resp_stop(); 00157 00158 if (_at.get_last_error() == NSAPI_ERROR_OK ) { 00159 return sent_len; 00160 } 00161 00162 return _at.get_last_error(); 00163 } 00164 00165 nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, 00166 void *buffer, nsapi_size_t size) 00167 { 00168 nsapi_size_or_error_t recv_len=0; 00169 int port; 00170 char ip_address[NSAPI_IP_SIZE]; 00171 char hexstr[BC95_MAX_PACKET_SIZE*2 + 1]; 00172 00173 _at.cmd_start("AT+NSORF="); 00174 _at.write_int(socket->id); 00175 _at.write_int(size); 00176 _at.cmd_stop(); 00177 _at.resp_start(); 00178 // receiving socket id 00179 _at.skip_param(); 00180 _at.read_string(ip_address, sizeof(ip_address)); 00181 port = _at.read_int(); 00182 recv_len = _at.read_int(); 00183 _at.read_string(hexstr, sizeof(hexstr)); 00184 // remaining length 00185 _at.skip_param(); 00186 _at.resp_stop(); 00187 00188 if (!recv_len || (recv_len == -1) || (_at.get_last_error() != NSAPI_ERROR_OK )) { 00189 return NSAPI_ERROR_WOULD_BLOCK ; 00190 } 00191 00192 if (address) { 00193 address->set_ip_address(ip_address); 00194 address->set_port(port); 00195 } 00196 00197 if (recv_len > 0) { 00198 hex_str_to_char_str((const char*) hexstr, recv_len*2, (char*)buffer); 00199 } 00200 00201 return recv_len; 00202 }
Generated on Tue Jul 12 2022 14:24:32 by
