diff --git a/features/cellular/TESTS/socket/udp/main.cpp b/features/cellular/TESTS/socket/udp/main.cpp index d8013ab846..00efa7083c 100644 --- a/features/cellular/TESTS/socket/udp/main.cpp +++ b/features/cellular/TESTS/socket/udp/main.cpp @@ -162,7 +162,7 @@ static void udp_network_stack() cellular.set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN); #ifdef MBED_CONF_APP_APN CellularNetwork *network = cellular.get_network(); - TEST_ASSERT(network->set_credentials(MBED_CONF_APP_APN) == NSAPI_ERROR_OK); + TEST_ASSERT(network->set_credentials(MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == NSAPI_ERROR_OK); #endif cellular_target_state = CellularConnectionFSM::STATE_CONNECTED; TEST_ASSERT(cellular.continue_to_state(cellular_target_state) == NSAPI_ERROR_OK); diff --git a/features/cellular/framework/API/CellularNetwork.h b/features/cellular/framework/API/CellularNetwork.h index fed04d257e..6600c17167 100644 --- a/features/cellular/framework/API/CellularNetwork.h +++ b/features/cellular/framework/API/CellularNetwork.h @@ -390,7 +390,7 @@ public: * * @return NSAPI_ERROR_OK on success * NSAPI_ERROR_NO_CONNECTION if fails to find suitable context to activate or activation failed (if not already activated) - * NSAPI_ERROR_UNSUPPORTED if NetworkStack was not found + * NSAPI_ERROR_UNSUPPORTED if NetworkStack was not found or cellular device does not support authentication * NSAPI_ERROR_AUTH_FAILURE if password and username were provided and authentication to network failed * Also if PPP mode * NSAPI_ERROR_DEVICE_ERROR on failure and check more error from nsapi_ppp_connect(...) diff --git a/features/cellular/framework/AT/AT_CellularBase.h b/features/cellular/framework/AT/AT_CellularBase.h index e5098e1f28..d4ef52d272 100644 --- a/features/cellular/framework/AT/AT_CellularBase.h +++ b/features/cellular/framework/AT/AT_CellularBase.h @@ -51,6 +51,7 @@ public: enum SupportedFeature { AT_CGSN_WITH_TYPE, // AT+CGSN without type is likely always supported similar to AT+GSN AT_CGDATA, // alternative is to support only ATD*99***# + AT_CGAUTH, // APN authentication AT commands supported SUPPORTED_FEATURE_END_MARK // must be last element in the array of features }; static void set_unsupported_features(const SupportedFeature *unsupported_features); diff --git a/features/cellular/framework/AT/AT_CellularNetwork.cpp b/features/cellular/framework/AT/AT_CellularNetwork.cpp index 6168eb5df6..09aaa15877 100644 --- a/features/cellular/framework/AT/AT_CellularNetwork.cpp +++ b/features/cellular/framework/AT/AT_CellularNetwork.cpp @@ -210,6 +210,9 @@ nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn, } if (username && (len = strlen(username)) > 0) { + if (!is_supported(AT_CGAUTH)) { // APN authentication is needed with username/password + return NSAPI_ERROR_UNSUPPORTED; + } _uname = (char *)malloc(len * sizeof(char) + 1); if (_uname) { memcpy(_uname, username, len + 1); @@ -279,10 +282,7 @@ nsapi_error_t AT_CellularNetwork::activate_context() nsapi_error_t err = NSAPI_ERROR_OK; // try to find or create context with suitable stack - if (get_context()) { - // try to authenticate user before activating or modifying context - err = do_user_authentication(); - } else { + if (!get_context()) { err = NSAPI_ERROR_NO_CONNECTION; } @@ -315,6 +315,12 @@ nsapi_error_t AT_CellularNetwork::activate_context() _at.resp_stop(); if (!_is_context_active) { + // authenticate before activating or modifying context + if (do_user_authentication() != NSAPI_ERROR_OK) { + tr_error("Cellular authentication failed!"); + return _at.unlock_return_error(); + } + tr_info("Activate PDP context %d", _cid); _at.cmd_start("AT+CGACT=1,"); _at.write_int(_cid); @@ -509,6 +515,9 @@ nsapi_error_t AT_CellularNetwork::do_user_authentication() { // if user has defined user name and password we need to call CGAUTH before activating or modifying context if (_pwd && _uname) { + if (!is_supported(AT_CGAUTH)) { + return NSAPI_ERROR_UNSUPPORTED; + } _at.cmd_start("AT+CGAUTH="); _at.write_int(_cid); _at.write_int(_authentication_type); diff --git a/features/cellular/framework/AT/AT_CellularNetwork.h b/features/cellular/framework/AT/AT_CellularNetwork.h index 3e01f4db46..80b5665b83 100644 --- a/features/cellular/framework/AT/AT_CellularNetwork.h +++ b/features/cellular/framework/AT/AT_CellularNetwork.h @@ -146,6 +146,12 @@ protected: */ virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat); + /** APN user authentication + * + * @return NSAPI_ERROR_OK on success + * NSAPI_ERROR_UNSUPPORTED on authentication not supported by cellular device + * NSAPI_ERROR_AUTH_FAILURE on authentication to network failed + */ virtual nsapi_error_t do_user_authentication(); private: // "NO CARRIER" urc diff --git a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95.cpp b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95.cpp index 94b6b635c1..85a6c2c34a 100644 --- a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95.cpp +++ b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95.cpp @@ -31,8 +31,14 @@ using namespace events; using namespace mbed; +static const AT_CellularBase::SupportedFeature unsupported_features[] = { + AT_CellularBase::AT_CGAUTH, // BC95_AT_Commands_Manual_V1.9 + AT_CellularBase::SUPPORTED_FEATURE_END_MARK +}; + QUECTEL_BC95::QUECTEL_BC95(EventQueue &queue) : AT_CellularDevice(queue) { + AT_CellularBase::set_unsupported_features(unsupported_features); } QUECTEL_BC95::~QUECTEL_BC95() diff --git a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.cpp b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.cpp index 5a5140725b..6ed0bbd9e8 100644 --- a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.cpp +++ b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.cpp @@ -111,3 +111,24 @@ nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(RadioAcce return _at.unlock_return_error(); } + +nsapi_error_t QUECTEL_BG96_CellularNetwork::do_user_authentication() +{ + if (_pwd && _uname) { + _at.cmd_start("AT+QICSGP="); + _at.write_int(_cid); + _at.write_int(1); // IPv4 + _at.write_string(_apn); + _at.write_string(_uname); + _at.write_string(_pwd); + _at.write_int(_authentication_type); + _at.cmd_stop(); + _at.resp_start(); + _at.resp_stop(); + if (_at.get_last_error() != NSAPI_ERROR_OK) { + return NSAPI_ERROR_AUTH_FAILURE; + } + } + + return NSAPI_ERROR_OK; +} diff --git a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h index 1504b9d1c5..292bcaf193 100644 --- a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h +++ b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h @@ -33,6 +33,8 @@ protected: virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat); virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack); + + virtual nsapi_error_t do_user_authentication(); }; } // namespace mbed diff --git a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910.cpp b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910.cpp index 8e317b4d69..d478b5161e 100644 --- a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910.cpp +++ b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910.cpp @@ -24,6 +24,7 @@ using namespace events; static const AT_CellularBase::SupportedFeature unsupported_features[] = { AT_CellularBase::AT_CGSN_WITH_TYPE, // HE910/UE910/UL865/UE866 AT Commands Reference Guide Rev. 11-2006-10-14 + AT_CellularBase::AT_CGAUTH, // HE910/UE910/UL865/UE866 AT Commands Reference Guide Rev. 11-2006-10-14 AT_CellularBase::SUPPORTED_FEATURE_END_MARK };