mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #12083 from AriParkkila/cell-bc95-congestion
Cellular: Add check for network congestion in BC95 driverpull/12619/head
commit
1623b1430d
|
@ -100,7 +100,9 @@ void UDPSOCKET_ECHOTEST_BURST()
|
|||
if (check_oversized_packets(sent, tx_buffers[x].len)) {
|
||||
TEST_IGNORE_MESSAGE("This device does not handle oversized packets");
|
||||
}
|
||||
TEST_ASSERT_EQUAL(tx_buffers[x].len, sent);
|
||||
if (sent != NSAPI_ERROR_NO_MEMORY) {
|
||||
TEST_ASSERT_EQUAL(tx_buffers[x].len, sent);
|
||||
}
|
||||
}
|
||||
|
||||
bt_total = 0;
|
||||
|
|
|
@ -233,8 +233,10 @@ nsapi_error_t AT_CellularStack::socket_close(nsapi_socket_t handle)
|
|||
tr_info("Socket %d close (id %d, started %d, error %d)", index, sock_id, socket->started, err);
|
||||
}
|
||||
|
||||
_socket_mutex.lock();
|
||||
_socket[index] = NULL;
|
||||
delete socket;
|
||||
_socket_mutex.unlock();
|
||||
|
||||
_at.unlock();
|
||||
|
||||
|
|
|
@ -114,7 +114,8 @@ protected:
|
|||
started(false),
|
||||
tx_ready(false),
|
||||
tls_socket(false),
|
||||
pending_bytes(0)
|
||||
pending_bytes(0),
|
||||
txfull_event(false)
|
||||
{
|
||||
}
|
||||
// Socket identifier, generally it will be the socket ID assigned by the
|
||||
|
@ -132,6 +133,7 @@ protected:
|
|||
bool tx_ready; // socket is ready for sending on modem stack
|
||||
bool tls_socket; // socket uses modem's internal TLS socket functionality
|
||||
nsapi_size_t pending_bytes; // The number of received bytes pending
|
||||
bool txfull_event; // socket event after wouldblock
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -231,10 +233,10 @@ private:
|
|||
|
||||
int get_socket_index_by_port(uint16_t port);
|
||||
|
||||
// mutex for write/read to a _socket array, needed when multiple threads may open sockets simultaneously
|
||||
protected:
|
||||
// mutex for write/read to a _socket array, needed when multiple threads may use sockets simultaneously
|
||||
PlatformMutex _socket_mutex;
|
||||
|
||||
protected:
|
||||
ATHandler &_at;
|
||||
|
||||
AT_CellularDevice &_device;
|
||||
|
|
|
@ -15,17 +15,28 @@
|
|||
* 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 (1 * 1000) // ms
|
||||
|
||||
#define AT_UPLINK_BUSY 159
|
||||
#define AT_UART_BUFFER_ERROR 536
|
||||
#define AT_BACK_OFF_TIMER 537
|
||||
|
||||
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)
|
||||
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));
|
||||
|
@ -33,6 +44,10 @@ QUECTEL_BC95_CellularStack::QUECTEL_BC95_CellularStack(ATHandler &atHandler, int
|
|||
|
||||
QUECTEL_BC95_CellularStack::~QUECTEL_BC95_CellularStack()
|
||||
{
|
||||
if (_txfull_event_id) {
|
||||
_event_queue->cancel(_txfull_event_id);
|
||||
}
|
||||
|
||||
_at.set_urc_handler("+NSONMI:", NULL);
|
||||
_at.set_urc_handler("+NSOCLI:", NULL);
|
||||
}
|
||||
|
@ -130,6 +145,9 @@ nsapi_error_t QUECTEL_BC95_CellularStack::socket_close_impl(int 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);
|
||||
|
@ -186,6 +204,8 @@ nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_sendto_impl(CellularSoc
|
|||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
int retry = 0;
|
||||
retry_send:
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
_at.cmd_start("AT+NSOST=");
|
||||
_at.write_int(socket->id);
|
||||
|
@ -212,6 +232,36 @@ nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_sendto_impl(CellularSoc
|
|||
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(30);
|
||||
_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();
|
||||
}
|
||||
|
||||
|
@ -234,7 +284,7 @@ nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_recvfrom_impl(CellularS
|
|||
_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, size);
|
||||
int hexlen = _at.read_hex_string((char *)buffer, recv_len);
|
||||
// remaining length
|
||||
_at.skip_param();
|
||||
_at.resp_stop();
|
||||
|
@ -253,3 +303,17 @@ nsapi_size_or_error_t QUECTEL_BC95_CellularStack::socket_recvfrom_impl(CellularS
|
|||
}
|
||||
return recv_len;
|
||||
}
|
||||
|
||||
void QUECTEL_BC95_CellularStack::txfull_event_timeout()
|
||||
{
|
||||
_socket_mutex.lock();
|
||||
_txfull_event_id = 0;
|
||||
for (int i = 0; i < get_max_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();
|
||||
}
|
||||
|
|
|
@ -58,6 +58,10 @@ 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_ */
|
||||
|
|
Loading…
Reference in New Issue