Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers QUECTEL_BG96_CellularStack.cpp Source File

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 }