Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers QUECTEL_BC95_CellularStack.cpp Source File

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 }