diff --git a/features/cellular/framework/AT/AT_CellularStack.cpp b/features/cellular/framework/AT/AT_CellularStack.cpp index 333a88cb84..ecd59d6498 100644 --- a/features/cellular/framework/AT/AT_CellularStack.cpp +++ b/features/cellular/framework/AT/AT_CellularStack.cpp @@ -193,15 +193,21 @@ nsapi_error_t AT_CellularStack::socket_bind(nsapi_socket_t handle, const SocketA } if (addr) { - socket->localAddress.set_addr(addr.get_addr()); - } - - if (addr.get_port()) { - socket->localAddress.set_port(addr.get_port()); + return NSAPI_ERROR_UNSUPPORTED; } _at.lock(); + uint16_t port = addr.get_port(); + if (port != socket->localAddress.get_port()) { + if (port && (get_socket_index_by_port(port) == -1)) { + socket->localAddress.set_port(port); + } else { + _at.unlock(); + return NSAPI_ERROR_PARAMETER; + } + } + if (!socket->created) { create_socket_impl(socket); } @@ -335,3 +341,14 @@ void AT_CellularStack::socket_attach(nsapi_socket_t handle, void (*callback)(voi socket->_cb = callback; socket->_data = data; } + +int AT_CellularStack::get_socket_index_by_port(uint16_t port) +{ + int max_socket_count = get_max_socket_count(); + for (int i = 0; i < max_socket_count; i++) { + if (_socket[i]->localAddress.get_port() == port) { + return i; + } + } + return -1; +} diff --git a/features/cellular/framework/AT/AT_CellularStack.h b/features/cellular/framework/AT/AT_CellularStack.h index 2c25da1579..8ce5764665 100644 --- a/features/cellular/framework/AT/AT_CellularStack.h +++ b/features/cellular/framework/AT/AT_CellularStack.h @@ -184,6 +184,8 @@ protected: private: int find_socket_index(nsapi_socket_t handle); + 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 PlatformMutex _socket_mutex; }; diff --git a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.cpp b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.cpp index 8d79fa6c74..4a71a87e0d 100644 --- a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.cpp +++ b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.cpp @@ -62,6 +62,10 @@ nsapi_error_t QUECTEL_BG96_CellularStack::socket_connect(nsapi_socket_t handle, handle_open_socket_response(modem_connect_id, err); if ((_at.get_last_error() == NSAPI_ERROR_OK) && err) { + if (err == BG96_SOCKET_BIND_FAIL) { + socket->created = false; + return NSAPI_ERROR_PARAMETER; + } _at.cmd_start("AT+QICLOSE="); _at.write_int(modem_connect_id); _at.cmd_stop(); @@ -178,6 +182,10 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc handle_open_socket_response(modem_connect_id, err); if ((_at.get_last_error() == NSAPI_ERROR_OK) && err) { + if (err == BG96_SOCKET_BIND_FAIL) { + socket->created = false; + return NSAPI_ERROR_PARAMETER; + } _at.cmd_start("AT+QICLOSE="); _at.write_int(modem_connect_id); _at.cmd_stop_read_resp(); @@ -206,6 +214,10 @@ nsapi_error_t QUECTEL_BG96_CellularStack::create_socket_impl(CellularSocket *soc handle_open_socket_response(modem_connect_id, err); if ((_at.get_last_error() == NSAPI_ERROR_OK) && err) { + if (err == BG96_SOCKET_BIND_FAIL) { + socket->created = false; + return NSAPI_ERROR_PARAMETER; + } _at.cmd_start("AT+QICLOSE="); _at.write_int(modem_connect_id); _at.cmd_stop_read_resp(); diff --git a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.h b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.h index 1b8e547530..f5de062ac4 100644 --- a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.h +++ b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularStack.h @@ -25,6 +25,7 @@ namespace mbed { #define BG96_SOCKET_MAX 12 #define BG96_CREATE_SOCKET_TIMEOUT 150000 //150 seconds #define BG96_CLOSE_SOCKET_TIMEOUT 20000 // TCP socket max timeout is >10sec +#define BG96_SOCKET_BIND_FAIL 556 class QUECTEL_BG96_CellularStack : public AT_CellularStack { public: