Import Mbed OS hard-float snapshot
This commit is contained in:
127
connectivity/drivers/cellular/QUECTEL/BC95/QUECTEL_BC95.cpp
Normal file
127
connectivity/drivers/cellular/QUECTEL/BC95/QUECTEL_BC95.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "QUECTEL_BC95_CellularNetwork.h"
|
||||
#include "QUECTEL_BC95_CellularContext.h"
|
||||
#include "QUECTEL_BC95_CellularInformation.h"
|
||||
#include "QUECTEL_BC95.h"
|
||||
#include "CellularLog.h"
|
||||
|
||||
#define CONNECT_DELIM "\r\n"
|
||||
#define CONNECT_BUFFER_SIZE (1280 + 80 + 80) // AT response + sscanf format
|
||||
#define CONNECT_TIMEOUT 8000
|
||||
|
||||
using namespace events;
|
||||
using namespace mbed;
|
||||
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_EREG
|
||||
AT_CellularNetwork::RegistrationModeDisable, // C_GREG
|
||||
AT_CellularNetwork::RegistrationModeDisable, // C_REG
|
||||
1, // AT_CGSN_WITH_TYPE
|
||||
1, // AT_CGDATA
|
||||
0, // AT_CGAUTH, BC95_AT_Commands_Manual_V1.9
|
||||
1, // AT_CNMI
|
||||
1, // AT_CSMP
|
||||
1, // AT_CMGF
|
||||
1, // AT_CSDH
|
||||
1, // PROPERTY_IPV4_STACK
|
||||
1, // PROPERTY_IPV6_STACK
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
1, // PROPERTY_NON_IP_PDP_TYPE
|
||||
0, // PROPERTY_AT_CGEREP,
|
||||
0, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
7, // PROPERTY_SOCKET_COUNT
|
||||
1, // PROPERTY_IP_TCP
|
||||
1, // PROPERTY_IP_UDP
|
||||
0, // PROPERTY_AT_SEND_DELAY
|
||||
};
|
||||
|
||||
QUECTEL_BC95::QUECTEL_BC95(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
{
|
||||
set_cellular_properties(cellular_properties);
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BC95::get_sim_state(SimState &state)
|
||||
{
|
||||
_at.lock();
|
||||
_at.flush();
|
||||
nsapi_error_t err = _at.at_cmd_discard("+NCCID", "?");
|
||||
_at.unlock();
|
||||
|
||||
state = SimStateReady;
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
tr_warn("SIM not readable.");
|
||||
state = SimStateUnknown;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
AT_CellularNetwork *QUECTEL_BC95::open_network_impl(ATHandler &at)
|
||||
{
|
||||
return new QUECTEL_BC95_CellularNetwork(at, *this);
|
||||
}
|
||||
|
||||
AT_CellularContext *QUECTEL_BC95::create_context_impl(ATHandler &at, const char *apn, bool cp_req, bool nonip_req)
|
||||
{
|
||||
return new QUECTEL_BC95_CellularContext(at, this, apn, cp_req, nonip_req);
|
||||
}
|
||||
|
||||
AT_CellularInformation *QUECTEL_BC95::open_information_impl(ATHandler &at)
|
||||
{
|
||||
return new QUECTEL_BC95_CellularInformation(at, *this);
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BC95::init()
|
||||
{
|
||||
setup_at_handler();
|
||||
|
||||
_at.lock();
|
||||
_at.flush();
|
||||
nsapi_error_t err = _at.at_cmd_discard("", ""); //Send AT
|
||||
if (!err) {
|
||||
err = _at.at_cmd_discard("+CMEE", "=1"); // verbose responses
|
||||
}
|
||||
if (!err) {
|
||||
err = _at.at_cmd_discard("+CFUN", "=", "%d", 1);
|
||||
}
|
||||
if (!err) {
|
||||
err = _at.get_last_error();
|
||||
}
|
||||
_at.unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BC95::set_baud_rate_impl(int baud_rate)
|
||||
{
|
||||
return _at.at_cmd_discard("+NATSPEED", "=", "%d%d%d%d%d%d%d", baud_rate, 30, 0, 2, 1, 0, 0);
|
||||
}
|
||||
|
||||
#if MBED_CONF_QUECTEL_BC95_PROVIDE_DEFAULT
|
||||
#include "drivers/BufferedSerial.h"
|
||||
CellularDevice *CellularDevice::get_default_instance()
|
||||
{
|
||||
static BufferedSerial serial(MBED_CONF_QUECTEL_BC95_TX, MBED_CONF_QUECTEL_BC95_RX, MBED_CONF_QUECTEL_BC95_BAUDRATE);
|
||||
#if defined(MBED_CONF_QUECTEL_BC95_RTS) && defined(MBED_CONF_QUECTEL_BC95_CTS)
|
||||
tr_debug("QUECTEL_BC95 flow control: RTS %d CTS %d", MBED_CONF_QUECTEL_BC95_RTS, MBED_CONF_QUECTEL_BC95_CTS);
|
||||
serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_QUECTEL_BC95_RTS, MBED_CONF_QUECTEL_BC95_CTS);
|
||||
#endif
|
||||
static QUECTEL_BC95 device(&serial);
|
||||
return &device;
|
||||
}
|
||||
#endif
|
||||
52
connectivity/drivers/cellular/QUECTEL/BC95/QUECTEL_BC95.h
Normal file
52
connectivity/drivers/cellular/QUECTEL/BC95/QUECTEL_BC95.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef QUECTEL_BC95_H_
|
||||
#define QUECTEL_BC95_H_
|
||||
|
||||
#ifdef TARGET_FF_ARDUINO
|
||||
#ifndef MBED_CONF_QUECTEL_BC95_TX
|
||||
#define MBED_CONF_QUECTEL_BC95_TX D1
|
||||
#endif
|
||||
#ifndef MBED_CONF_QUECTEL_BC95_RX
|
||||
#define MBED_CONF_QUECTEL_BC95_RX D0
|
||||
#endif
|
||||
#endif /* TARGET_FF_ARDUINO */
|
||||
|
||||
#include "AT_CellularDevice.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class QUECTEL_BC95 : public AT_CellularDevice {
|
||||
public:
|
||||
QUECTEL_BC95(FileHandle *fh);
|
||||
|
||||
public: // AT_CellularDevice
|
||||
virtual nsapi_error_t get_sim_state(SimState &state);
|
||||
|
||||
protected: // AT_CellularDevice
|
||||
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn, bool cp_req = false, bool nonip_req = false);
|
||||
virtual AT_CellularInformation *open_information_impl(ATHandler &at);
|
||||
virtual nsapi_error_t set_baud_rate_impl(int baud_rate);
|
||||
virtual nsapi_error_t init();
|
||||
|
||||
public: // NetworkInterface
|
||||
void handle_urc(FileHandle *fh);
|
||||
};
|
||||
} // namespace mbed
|
||||
#endif // QUECTEL_BC95_H_
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "QUECTEL_BC95_CellularContext.h"
|
||||
#include "QUECTEL_BC95_CellularStack.h"
|
||||
#include "CellularLog.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
QUECTEL_BC95_CellularContext::QUECTEL_BC95_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
|
||||
AT_CellularContext(at, device, apn, cp_req, nonip_req)
|
||||
{
|
||||
}
|
||||
|
||||
QUECTEL_BC95_CellularContext::~QUECTEL_BC95_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
NetworkStack *QUECTEL_BC95_CellularContext::get_stack()
|
||||
{
|
||||
if (_pdp_type == NON_IP_PDP_TYPE || _cp_in_use) {
|
||||
tr_error("Requesting stack for NON-IP context! Should request control plane netif: get_cp_netif()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_stack) {
|
||||
_stack = new QUECTEL_BC95_CellularStack(_at, _cid, (nsapi_ip_stack_t)_pdp_type, *get_device());
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
#endif // #if !NSAPI_PPP_AVAILABLE
|
||||
|
||||
const char *QUECTEL_BC95_CellularContext::get_nonip_context_type_str()
|
||||
{
|
||||
return "NONIP";
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef QUECTEL_BC95_CELLULARCONTEXT_H_
|
||||
#define QUECTEL_BC95_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class QUECTEL_BC95_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
QUECTEL_BC95_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req = false, bool nonip_req = false);
|
||||
virtual ~QUECTEL_BC95_CellularContext();
|
||||
|
||||
protected:
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
virtual NetworkStack *get_stack();
|
||||
#endif // #if !NSAPI_PPP_AVAILABLE
|
||||
virtual const char *get_nonip_context_type_str();
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // QUECTEL_BC95_CELLULARCONTEXT_H_
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "QUECTEL_BC95_CellularInformation.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
QUECTEL_BC95_CellularInformation::QUECTEL_BC95_CellularInformation(ATHandler &at, AT_CellularDevice &device) : AT_CellularInformation(at, device)
|
||||
{
|
||||
}
|
||||
|
||||
QUECTEL_BC95_CellularInformation::~QUECTEL_BC95_CellularInformation()
|
||||
{
|
||||
}
|
||||
|
||||
// According to BC95_AT_Commands_Manual_V1.9
|
||||
nsapi_error_t QUECTEL_BC95_CellularInformation::get_iccid(char *buf, size_t buf_size)
|
||||
{
|
||||
return _at.at_cmd_str("+NCCID", "?", buf, buf_size);
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef QUECTEL_BC95_CELLULARINFORMATION_H_
|
||||
#define QUECTEL_BC95_CELLULARINFORMATION_H_
|
||||
|
||||
#include "AT_CellularInformation.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class QUECTEL_BC95_CellularInformation : public AT_CellularInformation {
|
||||
public:
|
||||
QUECTEL_BC95_CellularInformation(ATHandler &at, AT_CellularDevice &device);
|
||||
virtual ~QUECTEL_BC95_CellularInformation();
|
||||
|
||||
public:
|
||||
virtual nsapi_error_t get_iccid(char *buf, size_t buf_size);
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif /* QUECTEL_BC95_CELLULARINFORMATION_H_ */
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "QUECTEL_BC95_CellularNetwork.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
QUECTEL_BC95_CellularNetwork::QUECTEL_BC95_CellularNetwork(ATHandler &atHandler, AT_CellularDevice &device) : AT_CellularNetwork(atHandler, device)
|
||||
{
|
||||
_op_act = RAT_NB1;
|
||||
}
|
||||
|
||||
QUECTEL_BC95_CellularNetwork::~QUECTEL_BC95_CellularNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BC95_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat)
|
||||
{
|
||||
if (opRat != RAT_NB1) {
|
||||
// only rat that is supported by this modem
|
||||
_op_act = RAT_NB1;
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BC95_CellularNetwork::clear()
|
||||
{
|
||||
nsapi_error_t err = AT_CellularNetwork::clear();
|
||||
#if MBED_CONF_CELLULAR_CONTROL_PLANE_OPT
|
||||
if (!err) {
|
||||
err = _at.at_cmd_discard("+CGDCONT", "=", "%d", 0);
|
||||
#ifdef MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN
|
||||
err = _at.at_cmd_discard("+CGDCONT", "=", "%d%s%s", 1, "NONIP", MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN);
|
||||
#endif
|
||||
if (!err) {
|
||||
err = _at.at_cmd_discard("+CIPCA", "=", "%d%d", 3, 1); // EPS Attach without PDN connection
|
||||
}
|
||||
if (!err) {
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+NCONFIG=\"AUTOCONNECT\",\"TRUE\""); // disable auto connect to IP context
|
||||
_at.cmd_stop_read_resp();
|
||||
err = _at.unlock_return_error();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef QUECTEL_BC95_CELLULAR_NETWORK_H_
|
||||
#define QUECTEL_BC95_CELLULAR_NETWORK_H_
|
||||
|
||||
#include "AT_CellularNetwork.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class QUECTEL_BC95_CellularNetwork : public AT_CellularNetwork {
|
||||
public:
|
||||
QUECTEL_BC95_CellularNetwork(ATHandler &atHandler, AT_CellularDevice &device);
|
||||
virtual ~QUECTEL_BC95_CellularNetwork();
|
||||
|
||||
protected:
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
|
||||
virtual nsapi_error_t clear();
|
||||
};
|
||||
} // namespace mbed
|
||||
#endif // QUECTEL_BC95_CELLULAR_NETWORK_H_
|
||||
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "mbed_error.h"
|
||||
#include "platform/mbed_atomic.h"
|
||||
#include "events/EventQueue.h"
|
||||
#include "events/mbed_shared_queues.h"
|
||||
|
||||
#include "QUECTEL_BC95_CellularStack.h"
|
||||
#include "CellularUtil.h"
|
||||
#include "CellularLog.h"
|
||||
|
||||
#define PACKET_SIZE_MAX 1358
|
||||
#define TXFULL_EVENT_TIMEOUT 1s
|
||||
|
||||
#define AT_UPLINK_BUSY 159
|
||||
#define AT_UART_BUFFER_ERROR 536
|
||||
#define AT_BACK_OFF_TIMER 537
|
||||
|
||||
using namespace std::chrono;
|
||||
using namespace mbed;
|
||||
using namespace mbed_cellular_util;
|
||||
|
||||
QUECTEL_BC95_CellularStack::QUECTEL_BC95_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device) :
|
||||
AT_CellularStack(atHandler, cid, stack_type, device), _event_queue(mbed_event_queue()), _txfull_event_id(0)
|
||||
{
|
||||
_at.set_urc_handler("+NSONMI:", mbed::Callback<void()>(this, &QUECTEL_BC95_CellularStack::urc_nsonmi));
|
||||
_at.set_urc_handler("+NSOCLI:", mbed::Callback<void()>(this, &QUECTEL_BC95_CellularStack::urc_nsocli));
|
||||
}
|
||||
|
||||
QUECTEL_BC95_CellularStack::~QUECTEL_BC95_CellularStack()
|
||||
{
|
||||
if (_txfull_event_id) {
|
||||
_event_queue->cancel(_txfull_event_id);
|
||||
}
|
||||
|
||||
_at.set_urc_handler("+NSONMI:", nullptr);
|
||||
_at.set_urc_handler("+NSOCLI:", nullptr);
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BC95_CellularStack::socket_listen(nsapi_socket_t handle, int backlog)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BC95_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BC95_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &address)
|
||||
{
|
||||
CellularSocket *socket = (CellularSocket *)handle;
|
||||
|
||||
_at.lock();
|
||||
if (socket->id == -1) {
|
||||
const nsapi_error_t error_create = create_socket_impl(socket);
|
||||
if (error_create != NSAPI_ERROR_OK) {
|
||||
return error_create;
|
||||
}
|
||||
}
|
||||
|
||||
_at.cmd_start("AT+NSOCO=");
|
||||
_at.write_int(socket->id);
|
||||
_at.write_string(address.get_ip_address(), false);
|
||||
_at.write_int(address.get_port());
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
_at.unlock();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
socket->remoteAddress = address;
|
||||
socket->connected = true;
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_NO_CONNECTION;
|
||||
}
|
||||
|
||||
void QUECTEL_BC95_CellularStack::urc_nsonmi()
|
||||
{
|
||||
int sock_id = _at.read_int();
|
||||
|
||||
for (int i = 0; i < _device.get_property(AT_CellularDevice::PROPERTY_SOCKET_COUNT); i++) {
|
||||
CellularSocket *sock = _socket[i];
|
||||
if (sock && sock->id == sock_id) {
|
||||
if (sock->_cb) {
|
||||
sock->_cb(sock->_data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QUECTEL_BC95_CellularStack::urc_nsocli()
|
||||
{
|
||||
int sock_id = _at.read_int();
|
||||
|
||||
const nsapi_error_t err = _at.get_last_error();
|
||||
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
CellularSocket *sock = find_socket(sock_id);
|
||||
|
||||
if (sock) {
|
||||
sock->closed = true;
|
||||
if (sock->_cb) {
|
||||
sock->_cb(sock->_data);
|
||||
}
|
||||
tr_info("Socket closed %d", sock_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsapi_error_t QUECTEL_BC95_CellularStack::socket_close_impl(int sock_id)
|
||||
{
|
||||
CellularSocket *sock = find_socket(sock_id);
|
||||
|
||||
if (sock && sock->closed) {
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
sock->txfull_event = false;
|
||||
|
||||
nsapi_error_t err = _at.at_cmd_discard("+NSOCL", "=", "%d", sock_id);
|
||||
|
||||
tr_info("Close socket: %d error: %d", sock_id, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BC95_CellularStack::create_socket_impl(CellularSocket *socket)
|
||||
{
|
||||
int sock_id = -1;
|
||||
bool socketOpenWorking = false;
|
||||
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
_at.cmd_start_stop("+NSOCR", "=DGRAM,", "%d%d%d%s", 17, socket->localAddress.get_port(), 1, ((_ip_ver_sendto == NSAPI_IPv4) ? "AF_INET" : "AF_INET6"));
|
||||
} else if (socket->proto == NSAPI_TCP) {
|
||||
_at.cmd_start_stop("+NSOCR", "=STREAM,", "%d%d%d%s", 6, socket->localAddress.get_port(), 1, ((_ip_ver_sendto == NSAPI_IPv4) ? "AF_INET" : "AF_INET6"));
|
||||
} else {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
_at.resp_start();
|
||||
sock_id = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
socketOpenWorking = (_at.get_last_error() == NSAPI_ERROR_OK);
|
||||
|
||||
if (!socketOpenWorking || (sock_id == -1)) {
|
||||
tr_error("Socket create failed!");
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
|
||||
tr_info("Socket create id: %d", sock_id);
|
||||
|
||||
socket->id = sock_id;
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
|
||||
const void *data, nsapi_size_t size)
|
||||
{
|
||||
//AT_CellularStack::socket_sendto(...) will create a socket on modem if it wasn't
|
||||
// open already.
|
||||
MBED_ASSERT(socket->id != -1);
|
||||
|
||||
if (_ip_ver_sendto != address.get_ip_version()) {
|
||||
_ip_ver_sendto = address.get_ip_version();
|
||||
socket_close_impl(socket->id);
|
||||
create_socket_impl(socket);
|
||||
}
|
||||
|
||||
int sent_len = 0;
|
||||
|
||||
if (size > PACKET_SIZE_MAX) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
int retry = 0;
|
||||
retry_send:
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
_at.cmd_start("AT+NSOST=");
|
||||
_at.write_int(socket->id);
|
||||
_at.write_string(address.get_ip_address(), false);
|
||||
_at.write_int(address.get_port());
|
||||
_at.write_int(size);
|
||||
} else if (socket->proto == NSAPI_TCP) {
|
||||
_at.cmd_start("AT+NSOSD=");
|
||||
_at.write_int(socket->id);
|
||||
_at.write_int(size);
|
||||
} else {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
_at.write_hex_string((char *)data, size);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
// skip socket id
|
||||
_at.skip_param();
|
||||
sent_len = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
return sent_len;
|
||||
}
|
||||
|
||||
// check for network congestion
|
||||
device_err_t err = _at.get_last_device_error();
|
||||
if (err.errType == DeviceErrorTypeErrorCME &&
|
||||
(err.errCode == AT_UART_BUFFER_ERROR || err.errCode == AT_BACK_OFF_TIMER) || err.errCode == AT_UPLINK_BUSY) {
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
if (retry < 3) {
|
||||
retry++;
|
||||
tr_warn("Socket %d sendto EAGAIN", socket->id);
|
||||
rtos::ThisThread::sleep_for(30ms);
|
||||
_at.clear_error();
|
||||
goto retry_send;
|
||||
}
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
_socket_mutex.lock();
|
||||
if (!socket->txfull_event && !_txfull_event_id) {
|
||||
tr_warn("socket %d tx full", socket->id);
|
||||
socket->txfull_event = true;
|
||||
_txfull_event_id = _event_queue->call_in(TXFULL_EVENT_TIMEOUT, callback(this, &QUECTEL_BC95_CellularStack::txfull_event_timeout));
|
||||
if (!_txfull_event_id) {
|
||||
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
|
||||
"QUECTEL_BC95_CellularStack::socket_sendto_impl(): unable to add event to queue. Increase \"events.shared-eventsize\"\n");
|
||||
_socket_mutex.unlock();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
_socket_mutex.unlock();
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
|
||||
void *buffer, nsapi_size_t size)
|
||||
{
|
||||
//AT_CellularStack::socket_recvfrom(...) will create a socket on modem if it wasn't
|
||||
// open already.
|
||||
MBED_ASSERT(socket->id != -1);
|
||||
|
||||
nsapi_size_or_error_t recv_len = 0;
|
||||
int port;
|
||||
char ip_address[NSAPI_IP_SIZE];
|
||||
|
||||
_at.cmd_start_stop("+NSORF", "=", "%d%d", socket->id, size < PACKET_SIZE_MAX ? size : PACKET_SIZE_MAX);
|
||||
|
||||
_at.resp_start();
|
||||
// receiving socket id
|
||||
_at.skip_param();
|
||||
_at.read_string(ip_address, sizeof(ip_address));
|
||||
port = _at.read_int();
|
||||
recv_len = _at.read_int();
|
||||
int hexlen = _at.read_hex_string((char *)buffer, recv_len);
|
||||
// remaining length
|
||||
_at.skip_param();
|
||||
_at.resp_stop();
|
||||
|
||||
if (!recv_len || (recv_len == -1) || (_at.get_last_error() != NSAPI_ERROR_OK)) {
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
if (address) {
|
||||
address->set_ip_address(ip_address);
|
||||
address->set_port(port);
|
||||
}
|
||||
|
||||
if (recv_len != hexlen) {
|
||||
tr_error("Not received as much data as expected. Should receive: %d bytes, received: %d bytes", recv_len, hexlen);
|
||||
}
|
||||
return recv_len;
|
||||
}
|
||||
|
||||
void QUECTEL_BC95_CellularStack::txfull_event_timeout()
|
||||
{
|
||||
_socket_mutex.lock();
|
||||
_txfull_event_id = 0;
|
||||
for (int i = 0; i < _device.get_property(AT_CellularDevice::PROPERTY_SOCKET_COUNT); i++) {
|
||||
CellularSocket *sock = _socket[i];
|
||||
if (sock && sock->_cb && sock->txfull_event) {
|
||||
sock->txfull_event = false;
|
||||
sock->_cb(sock->_data);
|
||||
}
|
||||
}
|
||||
_socket_mutex.unlock();
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef QUECTEL_BC95_CELLULARSTACK_H_
|
||||
#define QUECTEL_BC95_CELLULARSTACK_H_
|
||||
|
||||
#include "AT_CellularStack.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class QUECTEL_BC95_CellularStack : public AT_CellularStack {
|
||||
public:
|
||||
QUECTEL_BC95_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device);
|
||||
virtual ~QUECTEL_BC95_CellularStack();
|
||||
|
||||
protected: // NetworkStack
|
||||
|
||||
virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog);
|
||||
|
||||
virtual nsapi_error_t socket_accept(nsapi_socket_t server,
|
||||
nsapi_socket_t *handle, SocketAddress *address = 0);
|
||||
|
||||
virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address);
|
||||
|
||||
protected: // AT_CellularStack
|
||||
|
||||
virtual nsapi_error_t socket_close_impl(int sock_id);
|
||||
|
||||
virtual nsapi_error_t create_socket_impl(CellularSocket *socket);
|
||||
|
||||
virtual nsapi_size_or_error_t socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
|
||||
const void *data, nsapi_size_t size);
|
||||
|
||||
virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
|
||||
void *buffer, nsapi_size_t size);
|
||||
|
||||
private:
|
||||
// URC handlers
|
||||
void urc_nsonmi();
|
||||
void urc_nsocli();
|
||||
|
||||
events::EventQueue *_event_queue;
|
||||
int _txfull_event_id;
|
||||
void txfull_event_timeout();
|
||||
};
|
||||
} // namespace mbed
|
||||
#endif /* QUECTEL_BC95_CELLULARSTACK_H_ */
|
||||
29
connectivity/drivers/cellular/QUECTEL/BC95/mbed_lib.json
Normal file
29
connectivity/drivers/cellular/QUECTEL/BC95/mbed_lib.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "QUECTEL_BC95",
|
||||
"config": {
|
||||
"tx": {
|
||||
"help": "TX pin for serial connection. D1 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.",
|
||||
"value": null
|
||||
},
|
||||
"rx": {
|
||||
"help": "RX pin for serial connection. D0 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.",
|
||||
"value": null
|
||||
},
|
||||
"rts": {
|
||||
"help": "RTS pin for serial connection",
|
||||
"value": null
|
||||
},
|
||||
"cts": {
|
||||
"help": "CTS pin for serial connection",
|
||||
"value": null
|
||||
},
|
||||
"baudrate" : {
|
||||
"help": "Serial connection baud rate",
|
||||
"value": 9600
|
||||
},
|
||||
"provide-default": {
|
||||
"help": "Provide as default CellularDevice [true/false]",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user