Import Mbed OS hard-float snapshot
This commit is contained in:
219
connectivity/drivers/cellular/UBLOX/AT/UBLOX_AT.cpp
Normal file
219
connectivity/drivers/cellular/UBLOX/AT/UBLOX_AT.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* 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 "UBLOX_AT.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
||||
#ifdef UBX_MDM_SARA_R41XM
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
AT_CellularNetwork::RegistrationModeDisable,// C_EREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_REG
|
||||
0, // AT_CGSN_WITH_TYPE
|
||||
0, // AT_CGDATA
|
||||
0, // AT_CGAUTH
|
||||
1, // AT_CNMI
|
||||
1, // AT_CSMP
|
||||
1, // AT_CMGF
|
||||
0, // AT_CSDH
|
||||
1, // PROPERTY_IPV4_STACK
|
||||
0, // PROPERTY_IPV6_STACK
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
0, // PROPERTY_NON_IP_PDP_TYPE
|
||||
1, // PROPERTY_AT_CGEREP
|
||||
1, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
7, // PROPERTY_SOCKET_COUNT
|
||||
1, // PROPERTY_IP_TCP
|
||||
1, // PROPERTY_IP_UDP
|
||||
0, // PROPERTY_AT_SEND_DELAY
|
||||
};
|
||||
#elif defined(UBX_MDM_SARA_U2XX) || defined(UBX_MDM_SARA_G3XX)
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
AT_CellularNetwork::RegistrationModeDisable,// C_EREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_REG
|
||||
#ifdef UBX_MDM_SARA_G3XX
|
||||
0, // AT_CGSN_WITH_TYPE
|
||||
#else
|
||||
1, // AT_CGSN_WITH_TYPE
|
||||
#endif
|
||||
1, // AT_CGDATA
|
||||
0, // AT_CGAUTH
|
||||
1, // AT_CNMI
|
||||
1, // AT_CSMP
|
||||
1, // AT_CMGF
|
||||
1, // AT_CSDH
|
||||
1, // PROPERTY_IPV4_STACK
|
||||
0, // PROPERTY_IPV6_STACK
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
0, // PROPERTY_NON_IP_PDP_TYPE
|
||||
1, // PROPERTY_AT_CGEREP
|
||||
1, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
7, // PROPERTY_SOCKET_COUNT
|
||||
1, // PROPERTY_IP_TCP
|
||||
1, // PROPERTY_IP_UDP
|
||||
0, // PROPERTY_AT_SEND_DELAY
|
||||
};
|
||||
#else
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
0, // C_EREG
|
||||
0, // C_GREG
|
||||
0, // C_REG
|
||||
0, // AT_CGSN_WITH_TYPE
|
||||
0, // AT_CGDATA
|
||||
0, // AT_CGAUTH
|
||||
0, // AT_CNMI
|
||||
0, // AT_CSMP
|
||||
0, // AT_CMGF
|
||||
0, // AT_CSDH
|
||||
0, // PROPERTY_IPV4_STACK
|
||||
0, // PROPERTY_IPV6_STACK
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
0, // PROPERTY_NON_IP_PDP_TYPE
|
||||
0, // PROPERTY_AT_CGEREP
|
||||
0, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
0, // PROPERTY_SOCKET_COUNT
|
||||
0, // PROPERTY_IP_TCP
|
||||
0, // PROPERTY_IP_UDP
|
||||
0, // PROPERTY_AT_SEND_DELAY
|
||||
};
|
||||
#endif
|
||||
|
||||
UBLOX_AT::UBLOX_AT(FileHandle *fh) : AT_CellularDevice(fh), ubx_context(0)
|
||||
{
|
||||
set_cellular_properties(cellular_properties);
|
||||
}
|
||||
|
||||
AT_CellularNetwork *UBLOX_AT::open_network_impl(ATHandler &at)
|
||||
{
|
||||
return new UBLOX_AT_CellularNetwork(at, *this);
|
||||
}
|
||||
|
||||
AT_CellularContext *UBLOX_AT::create_context_impl(ATHandler &at, const char *apn, bool cp_req, bool nonip_req)
|
||||
{
|
||||
ubx_context = new UBLOX_AT_CellularContext(at, this, apn, cp_req, nonip_req);
|
||||
return ubx_context;
|
||||
}
|
||||
|
||||
#if MBED_CONF_UBLOX_AT_PROVIDE_DEFAULT
|
||||
#include "drivers/BufferedSerial.h"
|
||||
CellularDevice *CellularDevice::get_default_instance()
|
||||
{
|
||||
static BufferedSerial serial(MBED_CONF_UBLOX_AT_TX, MBED_CONF_UBLOX_AT_RX, MBED_CONF_UBLOX_AT_BAUDRATE);
|
||||
#if defined (MBED_CONF_UBLOX_AT_RTS) && defined(MBED_CONF_UBLOX_AT_CTS)
|
||||
tr_debug("UBLOX_AT flow control: RTS %d CTS %d", MBED_CONF_UBLOX_AT_RTS, MBED_CONF_UBLOX_AT_CTS);
|
||||
serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_UBLOX_AT_RTS, MBED_CONF_UBLOX_AT_CTS);
|
||||
#endif
|
||||
static UBLOX_AT device(&serial);
|
||||
return &device;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsapi_error_t UBLOX_AT::init()
|
||||
{
|
||||
setup_at_handler();
|
||||
_at.lock();
|
||||
_at.flush();
|
||||
_at.at_cmd_discard("", "");
|
||||
|
||||
#if defined(UBX_MDM_SARA_U2XX) || defined(UBX_MDM_SARA_G3XX)
|
||||
nsapi_error_t err = _at.at_cmd_discard("E0", ""); // echo off
|
||||
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
_at.at_cmd_discard("+CMEE", "=1"); // verbose responses
|
||||
err = _at.at_cmd_discard("+CFUN", "=1"); // set full functionality
|
||||
}
|
||||
#elif defined(UBX_MDM_SARA_R41XM)
|
||||
nsapi_error_t err = _at.at_cmd_discard("+CFUN", "=", "%d", 4);
|
||||
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
_at.at_cmd_discard("E0", ""); // echo off
|
||||
_at.at_cmd_discard("+CMEE", "=1"); // verbose responses
|
||||
config_authentication_parameters();
|
||||
err = _at.at_cmd_discard("+CFUN", "=1"); // set full functionality
|
||||
}
|
||||
#else
|
||||
_at.unlock();
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
#endif
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT::config_authentication_parameters()
|
||||
{
|
||||
char *config = NULL;
|
||||
nsapi_error_t err;
|
||||
const char *apn;
|
||||
const char *uname;
|
||||
const char *pwd;
|
||||
CellularContext::AuthenticationType auth = CellularContext::NOAUTH;
|
||||
char imsi[MAX_IMSI_LENGTH + 1];
|
||||
|
||||
if (ubx_context->get_apn() == NULL) {
|
||||
err = get_imsi(imsi);
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
config = (char *)apnconfig(imsi);
|
||||
}
|
||||
ubx_context->get_next_credentials(&config);
|
||||
}
|
||||
|
||||
apn = ubx_context->get_apn();
|
||||
pwd = ubx_context->get_pwd();
|
||||
uname = ubx_context->get_uname();
|
||||
|
||||
if (*uname && *pwd) {
|
||||
auth = ubx_context->get_auth();
|
||||
}
|
||||
err = set_authentication_parameters(apn, uname, pwd, auth);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT::set_authentication_parameters(const char *apn,
|
||||
const char *username,
|
||||
const char *password,
|
||||
CellularContext::AuthenticationType auth)
|
||||
{
|
||||
int modem_security = ubx_context->nsapi_security_to_modem_security(auth);
|
||||
|
||||
nsapi_error_t err = _at.at_cmd_discard("+CGDCONT", "=", "%d%s%s", 1, "IP", apn);
|
||||
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
#ifdef UBX_MDM_SARA_R41XM
|
||||
if (modem_security == CellularContext::CHAP) {
|
||||
err = _at.at_cmd_discard("+UAUTHREQ", "=", "%d%d%s%s", 1, modem_security, password, username);
|
||||
} else if (modem_security == CellularContext::NOAUTH) {
|
||||
err = _at.at_cmd_discard("+UAUTHREQ", "=", "%d%d", 1, modem_security);
|
||||
} else {
|
||||
err = _at.at_cmd_discard("+UAUTHREQ", "=", "%d%d%s%s", 1, modem_security, username, password);
|
||||
}
|
||||
#else
|
||||
err = _at.at_cmd_discard("+UAUTHREQ", "=", "%d%d%s%s", 1, modem_security, username, password);
|
||||
#endif
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT::get_imsi(char *imsi)
|
||||
{
|
||||
//Special case: Command put in cmd_chr to make a 1 liner
|
||||
return _at.at_cmd_str("", "+CIMI", imsi, MAX_IMSI_LENGTH + 1);
|
||||
}
|
||||
69
connectivity/drivers/cellular/UBLOX/AT/UBLOX_AT.h
Normal file
69
connectivity/drivers/cellular/UBLOX/AT/UBLOX_AT.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 UBLOX_AT_H_
|
||||
#define UBLOX_AT_H_
|
||||
|
||||
#ifdef TARGET_FF_ARDUINO
|
||||
#ifndef MBED_CONF_UBLOX_AT_TX
|
||||
#define MBED_CONF_UBLOX_AT_TX D1
|
||||
#endif
|
||||
#ifndef MBED_CONF_UBLOX_AT_RX
|
||||
#define MBED_CONF_UBLOX_AT_RX D0
|
||||
#endif
|
||||
#endif /* TARGET_FF_ARDUINO */
|
||||
|
||||
#include "APN_db.h"
|
||||
#include "AT_CellularDevice.h"
|
||||
#include "AT_CellularContext.h"
|
||||
#include "UBLOX_AT_CellularNetwork.h"
|
||||
#include "UBLOX_AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_AT : public AT_CellularDevice {
|
||||
public:
|
||||
UBLOX_AT(FileHandle *fh);
|
||||
|
||||
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);
|
||||
public: // NetworkInterface
|
||||
void handle_urc(FileHandle *fh);
|
||||
|
||||
virtual nsapi_error_t init();
|
||||
|
||||
private:
|
||||
|
||||
UBLOX_AT_CellularContext *ubx_context;
|
||||
|
||||
/** Length of IMSI buffer.
|
||||
*/
|
||||
static const int MAX_IMSI_LENGTH = 15;
|
||||
|
||||
nsapi_error_t config_authentication_parameters();
|
||||
|
||||
nsapi_error_t set_authentication_parameters(const char *apn, const char *username, const char *password, CellularContext::AuthenticationType auth);
|
||||
|
||||
/** Read IMSI of modem.
|
||||
*/
|
||||
nsapi_error_t get_imsi(char *imsi);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // UBLOX_AT_H_
|
||||
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* 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 "UBLOX_AT_CellularContext.h"
|
||||
#include "UBLOX_AT_CellularStack.h"
|
||||
#include "APN_db.h"
|
||||
#include "CellularLog.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace mbed {
|
||||
|
||||
UBLOX_AT_CellularContext::UBLOX_AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
|
||||
AT_CellularContext(at, device, apn, cp_req, nonip_req)
|
||||
{
|
||||
// The authentication to use
|
||||
_auth = NOAUTH;
|
||||
}
|
||||
|
||||
UBLOX_AT_CellularContext::~UBLOX_AT_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
NetworkStack *UBLOX_AT_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 UBLOX_AT_CellularStack(_at, _cid, (nsapi_ip_stack_t)_pdp_type, *get_device());
|
||||
}
|
||||
|
||||
return _stack;
|
||||
}
|
||||
|
||||
void UBLOX_AT_CellularContext::do_connect()
|
||||
{
|
||||
_at.lock();
|
||||
_cb_data.error = NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
// Attempt to establish a connection
|
||||
#ifndef UBX_MDM_SARA_R41XM
|
||||
_cb_data.error = define_context();
|
||||
#elif UBX_MDM_SARA_R410M
|
||||
_at.cmd_start_stop("+CGACT", "?");
|
||||
_at.resp_start("+CGACT:");
|
||||
_cid = _at.read_int();
|
||||
_at.skip_param(1);
|
||||
_at.resp_stop();
|
||||
|
||||
_is_connected = true;
|
||||
_is_context_active = true;
|
||||
_is_context_activated = true;
|
||||
_cb_data.error = NSAPI_ERROR_OK;
|
||||
#elif UBX_MDM_SARA_R412M
|
||||
CellularNetwork::RadioAccessTechnology rat = read_radio_technology();
|
||||
if (rat == CellularNetwork::RadioAccessTechnology::RAT_EGPRS) {
|
||||
if (!_is_context_active) {
|
||||
_at.set_at_timeout(150s);
|
||||
_at.at_cmd_discard("+CGACT", "=", "%d%d", 1, 1);
|
||||
|
||||
_at.cmd_start_stop("+CGACT", "?");
|
||||
_at.resp_start("+CGACT:");
|
||||
_at.skip_param(1);
|
||||
_is_context_activated = _at.read_int();
|
||||
_at.resp_stop();
|
||||
_at.restore_at_timeout();
|
||||
if (_is_context_activated == true) {
|
||||
_cid = 1;
|
||||
_is_connected = true;
|
||||
_is_context_active = true;
|
||||
_cb_data.error = NSAPI_ERROR_OK;
|
||||
}
|
||||
}
|
||||
} else if (rat == CellularNetwork::RadioAccessTechnology::RAT_CATM1 || rat == CellularNetwork::RadioAccessTechnology::RAT_NB1) {
|
||||
_at.cmd_start_stop("+CGACT", "?");
|
||||
_at.resp_start("+CGACT:");
|
||||
_cid = _at.read_int();
|
||||
_at.skip_param(1);
|
||||
_at.resp_stop();
|
||||
|
||||
_is_connected = true;
|
||||
_is_context_active = true;
|
||||
_is_context_activated = true;
|
||||
_cb_data.error = NSAPI_ERROR_OK;
|
||||
}
|
||||
#endif
|
||||
if (_cb_data.error != NSAPI_ERROR_OK) {
|
||||
// If new PSD context was created and failed to activate, delete it
|
||||
if (_new_context_set) {
|
||||
disconnect_modem_stack();
|
||||
}
|
||||
_connect_status = NSAPI_STATUS_DISCONNECTED;
|
||||
} else {
|
||||
_connect_status = NSAPI_STATUS_GLOBAL_UP;
|
||||
}
|
||||
_at.unlock();
|
||||
|
||||
if (_status_cb) {
|
||||
_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _connect_status);
|
||||
}
|
||||
}
|
||||
#ifndef UBX_MDM_SARA_R41XM
|
||||
void UBLOX_AT_CellularContext::do_disconnect()
|
||||
{
|
||||
disconnect_modem_stack();
|
||||
AT_CellularContext::do_disconnect();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef UBX_MDM_SARA_R41XM
|
||||
nsapi_error_t UBLOX_AT_CellularContext::define_context()
|
||||
{
|
||||
bool success = false;
|
||||
int active = 0;
|
||||
char *config = NULL;
|
||||
nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION;
|
||||
char imsi[MAX_IMSI_LENGTH + 1];
|
||||
|
||||
// do check for stack to validate that we have support for stack
|
||||
_stack = get_stack();
|
||||
if (!_stack) {
|
||||
return err;
|
||||
}
|
||||
|
||||
_at.lock();
|
||||
_at.cmd_start_stop("+UPSND", "=", "%d%d", PROFILE, 8);
|
||||
_at.resp_start("+UPSND:");
|
||||
_at.skip_param(2);
|
||||
active = _at.read_int();
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
|
||||
if (active == 0) {
|
||||
// If the caller hasn't entered an APN, try to find it
|
||||
if (_apn == NULL) {
|
||||
err = get_imsi(imsi);
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
config = (char *)apnconfig(imsi);
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to connect
|
||||
do {
|
||||
get_next_credentials(&config);
|
||||
if (_uname && _pwd) {
|
||||
_auth = (*_uname && *_pwd) ? _authentication_type : NOAUTH;
|
||||
} else {
|
||||
_auth = NOAUTH;
|
||||
}
|
||||
success = activate_profile(_apn, _uname, _pwd, _auth);
|
||||
} while (!success && config && *config);
|
||||
} else {
|
||||
// If the profile is already active, we're good
|
||||
success = true;
|
||||
}
|
||||
|
||||
err = (_at.get_last_error() == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
bool UBLOX_AT_CellularContext::activate_profile(const char *apn,
|
||||
const char *username,
|
||||
const char *password,
|
||||
AuthenticationType auth)
|
||||
{
|
||||
bool activated = false;
|
||||
bool success = false;
|
||||
|
||||
// Set up the APN
|
||||
if (apn) {
|
||||
success = false;
|
||||
if (_at.at_cmd_discard("+UPSD", "=", "%d%d%s", PROFILE, 1, apn) == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
// Set up the UserName
|
||||
if (success && username) {
|
||||
success = false;
|
||||
if (_at.at_cmd_discard("+UPSD", "=", "%d%d%s", PROFILE, 2, username) == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
// Set up the Password
|
||||
if (success && password) {
|
||||
success = false;
|
||||
if (_at.at_cmd_discard("+UPSD", "=", "%d%d%s", PROFILE, 3, password) == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
_at.at_cmd_discard("+UPSD", "=", "%d%d%s", PROFILE, 7, "0.0.0.0");
|
||||
|
||||
if (_at.at_cmd_discard("+UPSD", "=", "%d%d%d", PROFILE, 6, nsapi_security_to_modem_security(auth)) == NSAPI_ERROR_OK) {
|
||||
// Activate, wait upto 30 seconds for the connection to be made
|
||||
_at.set_at_timeout(30s);
|
||||
|
||||
nsapi_error_t err = _at.at_cmd_discard("+UPSDA", "=", "%d%d", PROFILE, 3);
|
||||
|
||||
_at.restore_at_timeout();
|
||||
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
auto end_time = rtos::Kernel::Clock::now() + 3min;
|
||||
do {
|
||||
_at.lock();
|
||||
_at.cmd_start_stop("+UPSND", "=", "%d%d", PROFILE, 8);
|
||||
_at.resp_start("+UPSND:");
|
||||
_at.skip_param(2);
|
||||
_at.read_int() ? activated = true : activated = false;
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
|
||||
if (activated) { //If context is activated, exit while loop and return status
|
||||
break;
|
||||
}
|
||||
rtos::ThisThread::sleep_for(5s); //Wait for 5 seconds and then try again
|
||||
} while (rtos::Kernel::Clock::now() < end_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return activated;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Convert nsapi_security_t to the modem security numbers
|
||||
int UBLOX_AT_CellularContext::nsapi_security_to_modem_security(AuthenticationType nsapi_security)
|
||||
{
|
||||
int modem_security = 3;
|
||||
|
||||
switch (nsapi_security) {
|
||||
case NOAUTH:
|
||||
modem_security = 0;
|
||||
break;
|
||||
case PAP:
|
||||
modem_security = 1;
|
||||
break;
|
||||
case CHAP:
|
||||
modem_security = 2;
|
||||
break;
|
||||
#ifndef UBX_MDM_SARA_R41XM
|
||||
case AUTOMATIC:
|
||||
modem_security = 3;
|
||||
break;
|
||||
default:
|
||||
modem_security = 3;
|
||||
break;
|
||||
#else
|
||||
default:
|
||||
modem_security = 0;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return modem_security;
|
||||
}
|
||||
|
||||
// Disconnect the on board IP stack of the modem.
|
||||
bool UBLOX_AT_CellularContext::disconnect_modem_stack()
|
||||
{
|
||||
SocketAddress addr;
|
||||
if (get_ip_address(&addr) == NSAPI_ERROR_OK) {
|
||||
if (_at.at_cmd_discard("+UPSDA", "=", "%d%d", PROFILE, 4) == NSAPI_ERROR_OK) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularContext::get_imsi(char *imsi)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start_stop("+CIMI", "");
|
||||
_at.resp_start();
|
||||
_at.read_string(imsi, MAX_IMSI_LENGTH + 1);
|
||||
_at.resp_stop();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
// Get the next set of credentials, based on IMSI.
|
||||
void UBLOX_AT_CellularContext::get_next_credentials(char **config)
|
||||
{
|
||||
if (*config) {
|
||||
_apn = _APN_GET(*config);
|
||||
_uname = _APN_GET(*config);
|
||||
_pwd = _APN_GET(*config);
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularContext::get_gateway(SocketAddress *addr)
|
||||
{
|
||||
return get_ip_address(addr);
|
||||
}
|
||||
|
||||
const char *UBLOX_AT_CellularContext::get_apn()
|
||||
{
|
||||
return _apn;
|
||||
}
|
||||
|
||||
const char *UBLOX_AT_CellularContext::get_uname()
|
||||
{
|
||||
return _uname;
|
||||
}
|
||||
|
||||
const char *UBLOX_AT_CellularContext::get_pwd()
|
||||
{
|
||||
return _pwd;
|
||||
}
|
||||
|
||||
CellularContext::AuthenticationType UBLOX_AT_CellularContext::get_auth()
|
||||
{
|
||||
return _authentication_type;
|
||||
}
|
||||
|
||||
#ifdef UBX_MDM_SARA_R412M
|
||||
CellularNetwork::RadioAccessTechnology UBLOX_AT_CellularContext::read_radio_technology()
|
||||
{
|
||||
int act;
|
||||
CellularNetwork::RadioAccessTechnology rat;
|
||||
|
||||
_at.at_cmd_int("+URAT", "?", act);
|
||||
|
||||
switch (act) {
|
||||
case 0:
|
||||
rat = CellularNetwork::RadioAccessTechnology::RAT_GSM;
|
||||
break;
|
||||
case 1:
|
||||
rat = CellularNetwork::RadioAccessTechnology::RAT_GSM;
|
||||
break;
|
||||
case 2:
|
||||
rat = CellularNetwork::RadioAccessTechnology::RAT_UTRAN;
|
||||
break;
|
||||
case 7:
|
||||
rat = CellularNetwork::RadioAccessTechnology::RAT_CATM1;
|
||||
break;
|
||||
case 8:
|
||||
rat = CellularNetwork::RadioAccessTechnology::RAT_NB1;
|
||||
break;
|
||||
case 9:
|
||||
rat = CellularNetwork::RadioAccessTechnology::RAT_EGPRS;
|
||||
break;
|
||||
default:
|
||||
rat = CellularNetwork::RadioAccessTechnology::RAT_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return rat;
|
||||
}
|
||||
#endif // #ifdef UBX_MDM_SARA_R412M
|
||||
|
||||
} /* namespace mbed */
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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 UBLOX_AT_CELLULARCONTEXT_H_
|
||||
#define UBLOX_AT_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
#include "UBLOX_AT_CellularNetwork.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_AT_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
UBLOX_AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req = false, bool nonip_req = false);
|
||||
virtual ~UBLOX_AT_CellularContext();
|
||||
|
||||
virtual void do_connect();
|
||||
#ifndef UBX_MDM_SARA_R41XM
|
||||
virtual void do_disconnect();
|
||||
#endif
|
||||
virtual nsapi_error_t get_gateway(SocketAddress *addr);
|
||||
|
||||
const char *get_apn(void);
|
||||
const char *get_uname(void);
|
||||
const char *get_pwd(void);
|
||||
CellularContext::AuthenticationType get_auth(void);
|
||||
|
||||
/** Convert nsapi_security_t to the modem security numbers.
|
||||
*
|
||||
* @param nsapi_security Security protocol.
|
||||
* @return Modem security numbers.
|
||||
*/
|
||||
int nsapi_security_to_modem_security(AuthenticationType nsapi_security);
|
||||
|
||||
/** Get the next set of credentials from the database.
|
||||
*/
|
||||
void get_next_credentials(char **config);
|
||||
#ifdef UBX_MDM_SARA_R412M
|
||||
CellularNetwork::RadioAccessTechnology read_radio_technology(void);
|
||||
#endif
|
||||
protected:
|
||||
virtual NetworkStack *get_stack();
|
||||
|
||||
/** Connect the on board IP stack of the modem.
|
||||
*
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
#ifndef UBX_MDM_SARA_R41XM
|
||||
nsapi_error_t define_context();
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
/** Length of IMSI buffer.
|
||||
*/
|
||||
static const int MAX_IMSI_LENGTH = 15;
|
||||
|
||||
/** The type of authentication to use.
|
||||
*/
|
||||
AuthenticationType _auth;
|
||||
|
||||
/** Activate one of the on-board modem's connection profiles.
|
||||
*
|
||||
* @param apn The APN to use.
|
||||
* @param username The user name to use.
|
||||
* @param password The password to use.
|
||||
* @param auth The authentication method to use
|
||||
* (NOAUTH, PAP,
|
||||
* CHAP or AUTOMATIC).
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
#ifndef UBX_MDM_SARA_R41XM
|
||||
bool activate_profile(const char *apn, const char *username, const char *password, AuthenticationType auth);
|
||||
#endif
|
||||
|
||||
/** Disconnect the on board IP stack of the modem.
|
||||
*
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool disconnect_modem_stack();
|
||||
|
||||
/** Read IMSI of modem.
|
||||
*/
|
||||
nsapi_error_t get_imsi(char *imsi);
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // UBLOX_AT_CELLULARCONTEXT_H_
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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 "UBLOX_AT_CellularNetwork.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using namespace mbed;
|
||||
|
||||
UBLOX_AT_CellularNetwork::UBLOX_AT_CellularNetwork(ATHandler &atHandler, AT_CellularDevice &device) : AT_CellularNetwork(atHandler, device)
|
||||
{
|
||||
_op_act = RAT_UNKNOWN;
|
||||
}
|
||||
|
||||
UBLOX_AT_CellularNetwork::~UBLOX_AT_CellularNetwork()
|
||||
{
|
||||
if (_connection_status_cb) {
|
||||
_connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_ERROR_CONNECTION_LOST);
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat)
|
||||
{
|
||||
nsapi_error_t ret = NSAPI_ERROR_OK;
|
||||
CellularNetwork::AttachStatus status;
|
||||
|
||||
get_attach(status);
|
||||
if (status == Attached) {
|
||||
tr_debug("RAT should only be set in detached state");
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
_at.lock();
|
||||
switch (opRat) {
|
||||
case RAT_EGPRS:
|
||||
#if defined (UBX_MDM_SARA_R412M)
|
||||
_at.at_cmd_discard("+URAT", "=", "%d%d", 9, 8);
|
||||
break;
|
||||
#endif
|
||||
#if defined(UBX_MDM_SARA_U201)
|
||||
case RAT_GSM:
|
||||
_at.at_cmd_discard("+URAT", "=", "%d%d", 0, 0);
|
||||
break;
|
||||
case RAT_UTRAN:
|
||||
case RAT_HSDPA:
|
||||
case RAT_HSUPA:
|
||||
case RAT_HSDPA_HSUPA:
|
||||
_at.at_cmd_discard("+URAT", "=", "%d%d", 2, 2);
|
||||
break;
|
||||
#elif defined(UBX_MDM_SARA_R41XM)
|
||||
case RAT_CATM1:
|
||||
_at.at_cmd_discard("+URAT", "=", "%d%d", 7, 8);
|
||||
break;
|
||||
case RAT_NB1:
|
||||
_at.at_cmd_discard("+URAT", "=", "%d%d", 8, 7);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
_op_act = RAT_UNKNOWN;
|
||||
ret = NSAPI_ERROR_UNSUPPORTED;
|
||||
break;
|
||||
}
|
||||
_at.unlock();
|
||||
ubx_reboot();
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularNetwork::ubx_reboot()
|
||||
{
|
||||
_at.lock();
|
||||
_at.at_cmd_discard("+CFUN", "=15");
|
||||
|
||||
nsapi_error_t err = NSAPI_ERROR_OK;
|
||||
Timer t1;
|
||||
t1.start();
|
||||
while (!(t1.elapsed_time() >= 30s)) {
|
||||
err = _at.at_cmd_discard("E0", "");
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
break;
|
||||
} else {
|
||||
//Don't clear err here so that we get some error in case of failure
|
||||
_at.clear_error();
|
||||
rtos::ThisThread::sleep_for(1s);
|
||||
}
|
||||
}
|
||||
t1.stop();
|
||||
_at.unlock();
|
||||
return err;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 UBLOX_AT_CELLULAR_NETWORK_H_
|
||||
#define UBLOX_AT_CELLULAR_NETWORK_H_
|
||||
|
||||
#include "CellularLog.h"
|
||||
#include "drivers/Timer.h"
|
||||
#include "mbed_wait_api.h"
|
||||
#include "AT_CellularNetwork.h"
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_AT_CellularNetwork : public AT_CellularNetwork {
|
||||
public:
|
||||
UBLOX_AT_CellularNetwork(ATHandler &atHandler, AT_CellularDevice &device);
|
||||
virtual ~UBLOX_AT_CellularNetwork();
|
||||
|
||||
nsapi_error_t ubx_reboot();
|
||||
|
||||
protected:
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // UBLOX_AT_CELLULAR_NETWORK_H_
|
||||
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
* 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 "UBLOX_AT_CellularStack.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace mbed_cellular_util;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
UBLOX_AT_CellularStack::UBLOX_AT_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device) :
|
||||
AT_CellularStack(atHandler, cid, stack_type, device)
|
||||
{
|
||||
// URC handlers for sockets
|
||||
_at.set_urc_handler("+UUSORD:", callback(this, &UBLOX_AT_CellularStack::UUSORD_URC));
|
||||
_at.set_urc_handler("+UUSORF:", callback(this, &UBLOX_AT_CellularStack::UUSORF_URC));
|
||||
_at.set_urc_handler("+UUSOCL:", callback(this, &UBLOX_AT_CellularStack::UUSOCL_URC));
|
||||
_at.set_urc_handler("+UUPSDD:", callback(this, &UBLOX_AT_CellularStack::UUPSDD_URC));
|
||||
}
|
||||
|
||||
UBLOX_AT_CellularStack::~UBLOX_AT_CellularStack()
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularStack::socket_listen(nsapi_socket_t handle, int backlog)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// Callback for Socket Read URC.
|
||||
void UBLOX_AT_CellularStack::UUSORD_URC()
|
||||
{
|
||||
int a, b;
|
||||
CellularSocket *socket;
|
||||
|
||||
a = _at.read_int();
|
||||
b = _at.read_int();
|
||||
|
||||
socket = find_socket(a);
|
||||
if (socket != NULL) {
|
||||
socket->pending_bytes = b;
|
||||
// No debug prints here as they can affect timing
|
||||
// and cause data loss in BufferedSerial
|
||||
if (socket->_cb != NULL) {
|
||||
socket->_cb(socket->_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Callback for Socket Read From URC.
|
||||
void UBLOX_AT_CellularStack::UUSORF_URC()
|
||||
{
|
||||
int a, b;
|
||||
CellularSocket *socket;
|
||||
|
||||
a = _at.read_int();
|
||||
b = _at.read_int();
|
||||
|
||||
socket = find_socket(a);
|
||||
if (socket != NULL) {
|
||||
socket->pending_bytes = b;
|
||||
// No debug prints here as they can affect timing
|
||||
// and cause data loss in BufferedSerial
|
||||
if (socket->_cb != NULL) {
|
||||
socket->_cb(socket->_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Callback for Socket Close URC.
|
||||
void UBLOX_AT_CellularStack::UUSOCL_URC()
|
||||
{
|
||||
int a;
|
||||
CellularSocket *socket;
|
||||
|
||||
a = _at.read_int();
|
||||
socket = find_socket(a);
|
||||
clear_socket(socket);
|
||||
}
|
||||
|
||||
// Callback for UUPSDD.
|
||||
void UBLOX_AT_CellularStack::UUPSDD_URC()
|
||||
{
|
||||
int a;
|
||||
CellularSocket *socket;
|
||||
|
||||
a = _at.read_int();
|
||||
socket = find_socket(a);
|
||||
clear_socket(socket);
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularStack::create_socket_impl(CellularSocket *socket)
|
||||
{
|
||||
int sock_id = SOCKET_UNUSED;
|
||||
|
||||
nsapi_error_t err = NSAPI_ERROR_OK;
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
err = _at.at_cmd_int("+USOCR", "=17", sock_id);
|
||||
} else if (socket->proto == NSAPI_TCP) {
|
||||
err = _at.at_cmd_int("+USOCR", "=6", sock_id);
|
||||
} // Unsupported protocol is checked in socket_open()
|
||||
|
||||
if ((err != NSAPI_ERROR_OK) || (sock_id == -1)) {
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
|
||||
// Check for duplicate socket id delivered by modem
|
||||
for (int i = 0; i < _device.get_property(AT_CellularDevice::PROPERTY_SOCKET_COUNT); i++) {
|
||||
CellularSocket *sock = _socket[i];
|
||||
if (sock && sock != socket && sock->id == sock_id) {
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
socket->started = true;
|
||||
socket->id = sock_id;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &addr)
|
||||
{
|
||||
CellularSocket *socket = (CellularSocket *)handle;
|
||||
|
||||
if (socket) {
|
||||
if (socket->id == SOCKET_UNUSED) {
|
||||
nsapi_error_t err = create_socket_impl(socket);
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
nsapi_error_t err = _at.at_cmd_discard("+USOCO", "=", "%d%s%d", socket->id, addr.get_ip_address(), addr.get_port());
|
||||
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
socket->remoteAddress = addr;
|
||||
socket->connected = true;
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_NO_CONNECTION;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t UBLOX_AT_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
|
||||
const void *data, nsapi_size_t size)
|
||||
{
|
||||
MBED_ASSERT(socket->id != -1);
|
||||
|
||||
int sent_len = 0;
|
||||
uint8_t ch = 0;
|
||||
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
if (size > UBLOX_MAX_PACKET_SIZE) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
_at.cmd_start_stop("+USOST", "=", "%d%s%d%d", socket->id, address.get_ip_address(), address.get_port(), size);
|
||||
_at.resp_start("@", true);
|
||||
rtos::ThisThread::sleep_for(50ms);
|
||||
|
||||
_at.write_bytes((uint8_t *)data, size);
|
||||
|
||||
_at.resp_start("+USOST:");
|
||||
_at.skip_param(); // skip socket id
|
||||
sent_len = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
if ((_at.get_last_error() == NSAPI_ERROR_OK)) {
|
||||
return sent_len;
|
||||
}
|
||||
} else if (socket->proto == NSAPI_TCP) {
|
||||
bool success = true;
|
||||
const char *buf = (const char *) data;
|
||||
nsapi_size_t blk = UBLOX_MAX_PACKET_SIZE;
|
||||
nsapi_size_t count = size;
|
||||
|
||||
while ((count > 0) && success) {
|
||||
if (count < blk) {
|
||||
blk = count;
|
||||
}
|
||||
_at.cmd_start_stop("+USOWR", "=", "%d%d", socket->id, blk);
|
||||
_at.resp_start("@", true);
|
||||
rtos::ThisThread::sleep_for(50ms);
|
||||
|
||||
_at.write_bytes((uint8_t *)buf, blk);
|
||||
|
||||
_at.resp_start("+USOWR:");
|
||||
_at.skip_param(); // skip socket id
|
||||
sent_len = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
if ((sent_len >= (int) blk) &&
|
||||
(_at.get_last_error() == NSAPI_ERROR_OK)) {
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
|
||||
buf += blk;
|
||||
count -= blk;
|
||||
}
|
||||
|
||||
if (success && _at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
return size - count;
|
||||
}
|
||||
}
|
||||
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t UBLOX_AT_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
|
||||
void *buffer, nsapi_size_t size)
|
||||
{
|
||||
MBED_ASSERT(socket->id != -1);
|
||||
|
||||
nsapi_size_or_error_t nsapi_error_size = NSAPI_ERROR_DEVICE_ERROR;
|
||||
bool success = true;
|
||||
nsapi_size_t read_blk;
|
||||
nsapi_size_t count = 0;
|
||||
nsapi_size_t usorf_sz;
|
||||
char ipAddress[NSAPI_IP_SIZE];
|
||||
uint8_t ch = 0;
|
||||
int port = 0;
|
||||
Timer timer;
|
||||
|
||||
if (socket->pending_bytes == 0) {
|
||||
_at.process_oob();
|
||||
if (socket->pending_bytes == 0) {
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
timer.start();
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
bool packet_received = false;
|
||||
while (success && (size > 0 && !packet_received)) {
|
||||
read_blk = UBLOX_MAX_PACKET_SIZE;
|
||||
if (read_blk > size) {
|
||||
read_blk = size;
|
||||
}
|
||||
if (socket->pending_bytes > 0) {
|
||||
_at.cmd_start_stop("+USORF", "=", "%d%d", socket->id, read_blk);
|
||||
|
||||
_at.resp_start("+USORF:");
|
||||
_at.skip_param(); // receiving socket id
|
||||
_at.read_string(ipAddress, sizeof(ipAddress));
|
||||
port = _at.read_int();
|
||||
usorf_sz = _at.read_int();
|
||||
if (usorf_sz > size) {
|
||||
usorf_sz = size;
|
||||
} else {
|
||||
packet_received = true;
|
||||
}
|
||||
_at.read_bytes(&ch, 1);
|
||||
_at.read_bytes((uint8_t *)buffer + count, usorf_sz);
|
||||
_at.resp_stop();
|
||||
|
||||
// Must use what +USORF returns here as it may be less or more than we asked for
|
||||
if (usorf_sz > socket->pending_bytes) {
|
||||
socket->pending_bytes = 0;
|
||||
} else {
|
||||
socket->pending_bytes -= usorf_sz;
|
||||
}
|
||||
|
||||
if (usorf_sz > 0) {
|
||||
count += usorf_sz;
|
||||
size -= usorf_sz;
|
||||
} else {
|
||||
// read() should not fail
|
||||
success = false;
|
||||
}
|
||||
} else if (timer.elapsed_time() < SOCKET_TIMEOUT) {
|
||||
// Wait for URCs
|
||||
_at.process_oob();
|
||||
} else {
|
||||
if (count == 0) {
|
||||
// Timeout with nothing received
|
||||
success = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (socket->proto == NSAPI_TCP) {
|
||||
while (success && (size > 0)) {
|
||||
read_blk = UBLOX_MAX_PACKET_SIZE;
|
||||
if (read_blk > size) {
|
||||
read_blk = size;
|
||||
}
|
||||
if (socket->pending_bytes > 0) {
|
||||
_at.cmd_start_stop("+USORD", "=", "%d%d", socket->id, read_blk);
|
||||
|
||||
_at.resp_start("+USORD:");
|
||||
_at.skip_param(); // receiving socket id
|
||||
usorf_sz = _at.read_int();
|
||||
if (usorf_sz > size) {
|
||||
usorf_sz = size;
|
||||
}
|
||||
_at.read_bytes(&ch, 1);
|
||||
_at.read_bytes((uint8_t *)buffer + count, usorf_sz);
|
||||
_at.resp_stop();
|
||||
|
||||
// Must use what +USORD returns here as it may be less or more than we asked for
|
||||
if (usorf_sz > socket->pending_bytes) {
|
||||
socket->pending_bytes = 0;
|
||||
} else {
|
||||
socket->pending_bytes -= usorf_sz;
|
||||
}
|
||||
|
||||
if (usorf_sz > 0) {
|
||||
count += usorf_sz;
|
||||
size -= usorf_sz;
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
} else if (timer.elapsed_time() < SOCKET_TIMEOUT) {
|
||||
// Wait for URCs
|
||||
_at.process_oob();
|
||||
} else {
|
||||
if (count == 0) {
|
||||
// Timeout with nothing received
|
||||
success = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
timer.stop();
|
||||
|
||||
socket->pending_bytes = 0;
|
||||
if (!count || (_at.get_last_error() != NSAPI_ERROR_OK)) {
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
} else {
|
||||
nsapi_error_size = count;
|
||||
}
|
||||
|
||||
if (success && socket->proto == NSAPI_UDP && address) {
|
||||
address->set_ip_address(ipAddress);
|
||||
address->get_ip_address();
|
||||
address->set_port(port);
|
||||
}
|
||||
|
||||
return nsapi_error_size;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularStack::socket_close_impl(int sock_id)
|
||||
{
|
||||
return _at.at_cmd_discard("+USOCL", "=", "%d", sock_id);
|
||||
}
|
||||
|
||||
// Find or create a socket from the list.
|
||||
UBLOX_AT_CellularStack::CellularSocket *UBLOX_AT_CellularStack::find_socket(int id)
|
||||
{
|
||||
CellularSocket *socket = NULL;
|
||||
|
||||
for (unsigned int x = 0; (socket == NULL) && (x < _device.get_property(AT_CellularDevice::PROPERTY_SOCKET_COUNT)); x++) {
|
||||
if (_socket) {
|
||||
if (_socket[x]->id == id) {
|
||||
socket = (_socket[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
|
||||
// Clear out the storage for a socket
|
||||
void UBLOX_AT_CellularStack::clear_socket(CellularSocket *socket)
|
||||
{
|
||||
if (socket != NULL) {
|
||||
socket->id = SOCKET_UNUSED;
|
||||
socket->started = false;
|
||||
socket->pending_bytes = 0;
|
||||
socket->closed = true;
|
||||
if (socket->_cb) {
|
||||
socket->_cb(socket->_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef UBX_MDM_SARA_R41XM
|
||||
nsapi_error_t UBLOX_AT_CellularStack::get_ip_address(SocketAddress *address)
|
||||
{
|
||||
if (!address) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
_at.lock();
|
||||
|
||||
bool ipv4 = false, ipv6 = false;
|
||||
|
||||
_at.cmd_start_stop("+UPSND", "=", "%d%d", PROFILE, 0);
|
||||
_at.resp_start("+UPSND:");
|
||||
|
||||
if (_at.info_resp()) {
|
||||
_at.skip_param(2);
|
||||
|
||||
if (_at.read_string(_ip, PDP_IPV6_SIZE) != -1) {
|
||||
convert_ipv6(_ip);
|
||||
address->set_ip_address(_ip);
|
||||
|
||||
ipv4 = (address->get_ip_version() == NSAPI_IPv4);
|
||||
ipv6 = (address->get_ip_version() == NSAPI_IPv6);
|
||||
|
||||
// Try to look for second address ONLY if modem has support for dual stack(can handle both IPv4 and IPv6 simultaneously).
|
||||
// Otherwise assumption is that second address is not reliable, even if network provides one.
|
||||
if ((_device.get_property(AT_CellularDevice::PROPERTY_IPV4V6_PDP_TYPE) && (_at.read_string(_ip, PDP_IPV6_SIZE) != -1))) {
|
||||
convert_ipv6(_ip);
|
||||
address->set_ip_address(_ip);
|
||||
ipv6 = (address->get_ip_version() == NSAPI_IPv6);
|
||||
}
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
|
||||
if (ipv4 && ipv6) {
|
||||
_stack_type = IPV4V6_STACK;
|
||||
} else if (ipv4) {
|
||||
_stack_type = IPV4_STACK;
|
||||
} else if (ipv6) {
|
||||
_stack_type = IPV6_STACK;
|
||||
}
|
||||
|
||||
return (ipv4 || ipv6) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_ADDRESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularStack::gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version, const char *interface_name)
|
||||
{
|
||||
char ipAddress[NSAPI_IP_SIZE];
|
||||
nsapi_error_t err = NSAPI_ERROR_DNS_FAILURE;
|
||||
|
||||
_at.lock();
|
||||
if (address->set_ip_address(host)) {
|
||||
err = NSAPI_ERROR_OK;
|
||||
} else {
|
||||
#ifdef UBX_MDM_SARA_R41XM
|
||||
_at.set_at_timeout(70s);
|
||||
#else
|
||||
_at.set_at_timeout(120s);
|
||||
#endif
|
||||
// This interrogation can sometimes take longer than the usual 8 seconds
|
||||
_at.cmd_start_stop("+UDNSRN", "=0,", "%s", host);
|
||||
|
||||
_at.resp_start("+UDNSRN:");
|
||||
if (_at.info_resp()) {
|
||||
_at.read_string(ipAddress, sizeof(ipAddress));
|
||||
|
||||
if (address->set_ip_address(ipAddress)) {
|
||||
err = NSAPI_ERROR_OK;
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
_at.restore_at_timeout();
|
||||
}
|
||||
_at.unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
103
connectivity/drivers/cellular/UBLOX/AT/UBLOX_AT_CellularStack.h
Normal file
103
connectivity/drivers/cellular/UBLOX/AT/UBLOX_AT_CellularStack.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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 UBLOX_AT_CELLULARSTACK_H_
|
||||
#define UBLOX_AT_CELLULARSTACK_H_
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "AT_CellularStack.h"
|
||||
#include "CellularUtil.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
#include "drivers/Timer.h"
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_AT_CellularStack : public AT_CellularStack {
|
||||
public:
|
||||
UBLOX_AT_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device);
|
||||
virtual ~UBLOX_AT_CellularStack();
|
||||
|
||||
#ifndef UBX_MDM_SARA_R41XM
|
||||
virtual nsapi_error_t get_ip_address(SocketAddress *address);
|
||||
#endif
|
||||
|
||||
virtual nsapi_error_t gethostbyname(const char *host,
|
||||
SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC, const char *interface_name = NULL);
|
||||
|
||||
protected:
|
||||
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);
|
||||
|
||||
/** The profile to use (on board the modem).
|
||||
*/
|
||||
#define PROFILE 0
|
||||
|
||||
/** Socket "unused" value.
|
||||
*/
|
||||
static const int SOCKET_UNUSED = -1;
|
||||
|
||||
/** Socket timeout value in milliseconds.
|
||||
* Note: the sockets layer above will retry the
|
||||
* call to the functions here when they return NSAPI_ERROR_WOULD_BLOCK
|
||||
* and the user has set a larger timeout or full blocking.
|
||||
*/
|
||||
static constexpr seconds SOCKET_TIMEOUT = 1s;
|
||||
|
||||
/** The maximum number of bytes in a packet that can be write/read from
|
||||
* the AT interface in one go.
|
||||
*/
|
||||
static const int UBLOX_MAX_PACKET_SIZE = 1024;
|
||||
|
||||
virtual nsapi_error_t create_socket_impl(CellularSocket *socket);
|
||||
|
||||
virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address);
|
||||
|
||||
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);
|
||||
|
||||
virtual nsapi_error_t socket_close_impl(int sock_id);
|
||||
|
||||
private:
|
||||
// URC handlers
|
||||
void UUSORD_URC();
|
||||
void UUSORF_URC();
|
||||
void UUSOCL_URC();
|
||||
void UUPSDD_URC();
|
||||
|
||||
/** Find a socket from the list.
|
||||
*
|
||||
* @param id Socket ID.
|
||||
* @return Socket if True, otherwise NULL.
|
||||
*/
|
||||
CellularSocket *find_socket(int id = SOCKET_UNUSED);
|
||||
|
||||
/** Clear out the storage for a socket.
|
||||
*
|
||||
* @param id Cellular Socket.
|
||||
* @return None
|
||||
*/
|
||||
void clear_socket(CellularSocket *socket);
|
||||
};
|
||||
} // namespace mbed
|
||||
#endif /* UBLOX_AT_CELLULARSTACK_H_ */
|
||||
29
connectivity/drivers/cellular/UBLOX/AT/mbed_lib.json
Normal file
29
connectivity/drivers/cellular/UBLOX/AT/mbed_lib.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "UBLOX_AT",
|
||||
"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": 115200
|
||||
},
|
||||
"provide-default": {
|
||||
"help": "Provide as default CellularDevice [true/false]",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
}
|
||||
175
connectivity/drivers/cellular/UBLOX/N2XX/UBLOX_N2XX.cpp
Normal file
175
connectivity/drivers/cellular/UBLOX/N2XX/UBLOX_N2XX.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 "UBLOX_N2XX.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
||||
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
|
||||
0, // AT_CGDATA
|
||||
0, // AT_CGAUTH
|
||||
0, // AT_CNMI
|
||||
0, // AT_CSMP
|
||||
0, // AT_CMGF
|
||||
0, // AT_CSDH
|
||||
1, // PROPERTY_IPV4_STACK
|
||||
0, // PROPERTY_IPV6_STACK
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
1, // PROPERTY_NON_IP_PDP_TYPE
|
||||
0, // PROPERTY_AT_CGEREP
|
||||
1, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
7, // PROPERTY_SOCKET_COUNT
|
||||
0, // PROPERTY_IP_TCP
|
||||
1, // PROPERTY_IP_UDP
|
||||
0, // PROPERTY_AT_SEND_DELAY
|
||||
};
|
||||
|
||||
UBLOX_N2XX::UBLOX_N2XX(FileHandle *fh): AT_CellularDevice(fh)
|
||||
{
|
||||
set_cellular_properties(cellular_properties);
|
||||
memset(simstr, 0, sizeof(simstr));
|
||||
}
|
||||
|
||||
void UBLOX_N2XX::set_at_urcs_impl()
|
||||
{
|
||||
_at.set_urc_handler("+NPIN:", mbed::Callback<void()>(this, &UBLOX_N2XX::NPIN_URC));
|
||||
}
|
||||
|
||||
UBLOX_N2XX::~UBLOX_N2XX()
|
||||
{
|
||||
_at.set_urc_handler("+NPIN:", nullptr);
|
||||
}
|
||||
|
||||
// Callback for Sim Pin.
|
||||
void UBLOX_N2XX::NPIN_URC()
|
||||
{
|
||||
_at.read_string(simstr, sizeof(simstr));
|
||||
}
|
||||
|
||||
AT_CellularNetwork *UBLOX_N2XX::open_network_impl(ATHandler &at)
|
||||
{
|
||||
return new UBLOX_N2XX_CellularNetwork(at, *this);
|
||||
}
|
||||
|
||||
AT_CellularContext *UBLOX_N2XX::create_context_impl(ATHandler &at, const char *apn, bool cp_req, bool nonip_req)
|
||||
{
|
||||
return new UBLOX_N2XX_CellularContext(at, this, apn, cp_req, nonip_req);
|
||||
}
|
||||
|
||||
#if MBED_CONF_CELLULAR_USE_SMS
|
||||
AT_CellularSMS *UBLOX_N2XX::open_sms_impl(ATHandler &at)
|
||||
{
|
||||
return new UBLOX_N2XX_CellularSMS(at, *this);
|
||||
}
|
||||
#endif // MBED_CONF_CELLULAR_USE_SMS
|
||||
|
||||
nsapi_error_t UBLOX_N2XX::init()
|
||||
{
|
||||
setup_at_handler();
|
||||
|
||||
_at.lock();
|
||||
_at.flush();
|
||||
_at.at_cmd_discard("", "");
|
||||
|
||||
_at.at_cmd_discard("+CMEE", "=1"); // verbose responses
|
||||
|
||||
#ifdef MBED_CONF_NSAPI_DEFAULT_CELLULAR_SIM_PIN
|
||||
set_pin(MBED_CONF_NSAPI_DEFAULT_CELLULAR_SIM_PIN);
|
||||
#endif
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_N2XX::get_sim_state(SimState &state)
|
||||
{
|
||||
nsapi_error_t error = NSAPI_ERROR_DEVICE_ERROR;
|
||||
|
||||
_at.lock();
|
||||
_at.flush();
|
||||
//Special case: Command put in cmd_chr to make a 1 liner
|
||||
error = _at.at_cmd_str("", "+CFUN=1", simstr, sizeof(simstr));
|
||||
_at.unlock();
|
||||
|
||||
int len = strlen(simstr);
|
||||
if (len > 0 || error == NSAPI_ERROR_OK) {
|
||||
if (error == NSAPI_ERROR_OK) {
|
||||
state = SimStateReady;
|
||||
} else if (len >= 6 && memcmp(simstr, "ENTER PIN", 9) == 0) {
|
||||
state = SimStatePinNeeded;
|
||||
} else {
|
||||
simstr[len] = '\0';
|
||||
tr_error("Unknown SIM state %s", simstr);
|
||||
state = SimStateUnknown;
|
||||
}
|
||||
error = NSAPI_ERROR_OK;
|
||||
} else {
|
||||
tr_warn("SIM not readable.");
|
||||
state = SimStateUnknown; // SIM may not be ready yet or pin command may not be supported
|
||||
}
|
||||
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
switch (state) {
|
||||
case SimStatePinNeeded:
|
||||
tr_info("SIM PIN required");
|
||||
break;
|
||||
case SimStatePukNeeded:
|
||||
tr_error("SIM PUK required");
|
||||
break;
|
||||
case SimStateUnknown:
|
||||
tr_warn("SIM state unknown");
|
||||
break;
|
||||
default:
|
||||
tr_info("SIM is ready");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_N2XX::set_pin(const char *sim_pin)
|
||||
{
|
||||
// if SIM is already in ready state then settings the PIN
|
||||
// will return error so let's check the state before settings the pin.
|
||||
SimState state;
|
||||
if (get_sim_state(state) == NSAPI_ERROR_OK && state == SimStateReady) {
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
if (sim_pin == NULL) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
return _at.at_cmd_discard("+NPIN", "=", "%d%s", 0, sim_pin);
|
||||
}
|
||||
|
||||
#if MBED_CONF_UBLOX_N2XX_PROVIDE_DEFAULT
|
||||
#include "drivers/BufferedSerial.h"
|
||||
CellularDevice *CellularDevice::get_default_instance()
|
||||
{
|
||||
static BufferedSerial serial(MBED_CONF_UBLOX_N2XX_TX, MBED_CONF_UBLOX_N2XX_RX, MBED_CONF_UBLOX_N2XX_BAUDRATE);
|
||||
#if defined (MBED_CONF_UBLOX_N2XX_RTS) && defined(MBED_CONF_UBLOX_N2XX_CTS)
|
||||
tr_debug("UBLOX_N2XX flow control: RTS %d CTS %d", MBED_CONF_UBLOX_N2XX_RTS, MBED_CONF_UBLOX_N2XX_CTS);
|
||||
serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_UBLOX_N2XX_RTS, MBED_CONF_UBLOX_N2XX_CTS);
|
||||
#endif
|
||||
static UBLOX_N2XX device(&serial);
|
||||
return &device;
|
||||
}
|
||||
#endif
|
||||
76
connectivity/drivers/cellular/UBLOX/N2XX/UBLOX_N2XX.h
Normal file
76
connectivity/drivers/cellular/UBLOX/N2XX/UBLOX_N2XX.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 UBLOX_N2XX_H_
|
||||
#define UBLOX_N2XX_H_
|
||||
|
||||
#ifdef TARGET_FF_ARDUINO
|
||||
#ifndef MBED_CONF_UBLOX_N2XX_TX
|
||||
#define MBED_CONF_UBLOX_N2XX_TX D1
|
||||
#endif
|
||||
#ifndef MBED_CONF_UBLOX_N2XX_RX
|
||||
#define MBED_CONF_UBLOX_N2XX_RX D0
|
||||
#endif
|
||||
#endif /* TARGET_FF_ARDUINO */
|
||||
|
||||
#include "CellularLog.h"
|
||||
#include "AT_CellularDevice.h"
|
||||
#include "AT_CellularNetwork.h"
|
||||
#include "UBLOX_N2XX_CellularSMS.h"
|
||||
#include "UBLOX_N2XX_CellularContext.h"
|
||||
#include "UBLOX_N2XX_CellularNetwork.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_N2XX : public AT_CellularDevice {
|
||||
|
||||
public:
|
||||
|
||||
UBLOX_N2XX(FileHandle *fh);
|
||||
virtual ~UBLOX_N2XX();
|
||||
|
||||
virtual nsapi_error_t init();
|
||||
virtual nsapi_error_t get_sim_state(SimState &state);
|
||||
virtual nsapi_error_t set_pin(const char *sim_pin);
|
||||
|
||||
|
||||
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);
|
||||
#if MBED_CONF_CELLULAR_USE_SMS
|
||||
virtual AT_CellularSMS *open_sms_impl(ATHandler &at);
|
||||
#endif // MBED_CONF_CELLULAR_USE_SMS
|
||||
virtual void set_at_urcs_impl();
|
||||
|
||||
public: // NetworkInterface
|
||||
|
||||
void handle_urc(FileHandle *fh);
|
||||
|
||||
private:
|
||||
|
||||
static const int MAX_SIM_RESPONSE_LENGTH = 25;
|
||||
|
||||
// URC handlers
|
||||
void NPIN_URC();
|
||||
|
||||
char simstr[MAX_SIM_RESPONSE_LENGTH];
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // UBLOX_N2XX_H_
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 "UBLOX_N2XX_CellularContext.h"
|
||||
#include "UBLOX_N2XX_CellularStack.h"
|
||||
#include "CellularLog.h"
|
||||
#include "APN_db.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
UBLOX_N2XX_CellularContext::UBLOX_N2XX_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req):
|
||||
AT_CellularContext(at, device, apn, cp_req, nonip_req)
|
||||
{
|
||||
}
|
||||
|
||||
UBLOX_N2XX_CellularContext::~UBLOX_N2XX_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
NetworkStack *UBLOX_N2XX_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 UBLOX_N2XX_CellularStack(_at, _cid, (nsapi_ip_stack_t)_pdp_type, *get_device());
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *UBLOX_N2XX_CellularContext::get_nonip_context_type_str()
|
||||
{
|
||||
return "NONIP";
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 UBLOX_N2XX_CELLULARCONTEXT_H_
|
||||
#define UBLOX_N2XX_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_N2XX_CellularContext: public AT_CellularContext {
|
||||
|
||||
public:
|
||||
|
||||
UBLOX_N2XX_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req = false, bool nonip_req = false);
|
||||
virtual ~UBLOX_N2XX_CellularContext();
|
||||
|
||||
protected:
|
||||
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
virtual NetworkStack *get_stack();
|
||||
#endif
|
||||
|
||||
virtual const char *get_nonip_context_type_str();
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // UBLOX_N2XX_CELLULARCONTEXT_H_
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 "UBLOX_N2XX_CellularNetwork.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
UBLOX_N2XX_CellularNetwork::UBLOX_N2XX_CellularNetwork(ATHandler &atHandler, AT_CellularDevice &device) : AT_CellularNetwork(atHandler, device)
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_N2XX_CellularNetwork::clear()
|
||||
{
|
||||
nsapi_error_t err = AT_CellularNetwork::clear();
|
||||
#if MBED_CONF_CELLULAR_CONTROL_PLANE_OPT
|
||||
if (!err) {
|
||||
#ifdef MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN
|
||||
(void) _at.at_cmd_discard("+CGDCONT", "=", "%d%s%s", 1, "NONIP", MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN);
|
||||
#endif
|
||||
(void) _at.at_cmd_discard("+CIPCA", "=", "%d%d", 3, 1); // EPS Attach without PDN connection
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+NCONFIG=\"AUTOCONNECT\",\"FALSE\""); // disable auto connect to IP context
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.unlock();
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_N2XX_CellularNetwork::set_ciot_optimization_config(CIoT_Supported_Opt supported_opt,
|
||||
CIoT_Preferred_UE_Opt preferred_opt,
|
||||
Callback<void(CIoT_Supported_Opt)> network_support_cb)
|
||||
{
|
||||
_ciotopt_network_support_cb = network_support_cb;
|
||||
nsapi_error_t err = _at.at_cmd_discard("+CRTDCP", "=", "%d", 1);
|
||||
return err;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 UBLOX_N2XX_CELLULAR_NETWORK_H_
|
||||
#define UBLOX_N2XX_CELLULAR_NETWORK_H_
|
||||
|
||||
#include "AT_CellularNetwork.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_N2XX_CellularNetwork : public AT_CellularNetwork {
|
||||
public:
|
||||
UBLOX_N2XX_CellularNetwork(ATHandler &atHandler, AT_CellularDevice &device);
|
||||
virtual nsapi_error_t clear();
|
||||
virtual nsapi_error_t set_ciot_optimization_config(CIoT_Supported_Opt supported_opt,
|
||||
CIoT_Preferred_UE_Opt preferred_opt,
|
||||
Callback<void(CIoT_Supported_Opt)> network_support_cb);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // UBLOX_N2XX_CELLULAR_NETWORK_H_
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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.
|
||||
*/
|
||||
|
||||
#if MBED_CONF_CELLULAR_USE_SMS
|
||||
|
||||
#include "UBLOX_N2XX_CellularSMS.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
UBLOX_N2XX_CellularSMS::UBLOX_N2XX_CellularSMS(ATHandler &atHandler, AT_CellularDevice &device) : AT_CellularSMS(atHandler, device)
|
||||
{
|
||||
}
|
||||
|
||||
UBLOX_N2XX_CellularSMS::~UBLOX_N2XX_CellularSMS()
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_N2XX_CellularSMS::set_cpms(const char *memr, const char *memw, const char *mems)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t UBLOX_N2XX_CellularSMS::set_cscs(const char *chr_set)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t UBLOX_N2XX_CellularSMS::get_sms(char *buf, uint16_t len, char *phone_num, uint16_t phone_len,
|
||||
char *time_stamp, uint16_t time_len, int *buf_size)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_N2XX_CellularSMS::delete_all_messages()
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
#endif // MBED_CONF_CELLULAR_USE_SMS
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 UBLOX_N2XX_CELLULAR_SMS_H_
|
||||
#define UBLOX_N2XX_CELLULAR_SMS_H_
|
||||
|
||||
#include "AT_CellularSMS.h"
|
||||
|
||||
#if MBED_CONF_CELLULAR_USE_SMS
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_N2XX_CellularSMS : public AT_CellularSMS {
|
||||
|
||||
public:
|
||||
|
||||
UBLOX_N2XX_CellularSMS(ATHandler &atHandler, AT_CellularDevice &device);
|
||||
virtual ~UBLOX_N2XX_CellularSMS();
|
||||
|
||||
virtual nsapi_error_t set_cpms(const char *memr, const char *memw, const char *mems);
|
||||
|
||||
virtual nsapi_size_or_error_t set_cscs(const char *chr_set);
|
||||
|
||||
virtual nsapi_size_or_error_t get_sms(char *buf, uint16_t buf_len, char *phone_num, uint16_t phone_len,
|
||||
char *time_stamp, uint16_t time_len, int *buf_size);
|
||||
|
||||
virtual nsapi_error_t delete_all_messages();
|
||||
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // MBED_CONF_CELLULAR_USE_SMS
|
||||
|
||||
#endif // UBLOX_N2XX_CELLULAR_SMS_H_
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 "UBLOX_N2XX_CellularStack.h"
|
||||
#include "CellularUtil.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace mbed;
|
||||
using namespace mbed_cellular_util;
|
||||
|
||||
UBLOX_N2XX_CellularStack::UBLOX_N2XX_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device):
|
||||
AT_CellularStack(atHandler, cid, stack_type, device)
|
||||
{
|
||||
// URC handlers for sockets
|
||||
_at.set_urc_handler("+NSONMI:", callback(this, &UBLOX_N2XX_CellularStack::NSONMI_URC));
|
||||
}
|
||||
|
||||
UBLOX_N2XX_CellularStack::~UBLOX_N2XX_CellularStack()
|
||||
{
|
||||
_at.set_urc_handler("+NSONMI:", nullptr);
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_N2XX_CellularStack::socket_listen(nsapi_socket_t handle, int backlog)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_N2XX_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// Callback for Socket Read URC.
|
||||
void UBLOX_N2XX_CellularStack::NSONMI_URC()
|
||||
{
|
||||
int a, b;
|
||||
CellularSocket *socket;
|
||||
|
||||
a = _at.read_int();
|
||||
b = _at.read_int();
|
||||
|
||||
socket = find_socket(a);
|
||||
if (socket != NULL) {
|
||||
socket->pending_bytes = b;
|
||||
// No debug prints here as they can affect timing
|
||||
// and cause data loss in BufferedSerial
|
||||
if (socket->_cb != NULL) {
|
||||
socket->_cb(socket->_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_N2XX_CellularStack::create_socket_impl(CellularSocket *socket)
|
||||
{
|
||||
int sock_id = -1;
|
||||
int localport = socket->localAddress.get_port();
|
||||
|
||||
if (localport == 5683 || localport < 0 || localport > 65535) {
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
|
||||
_at.lock();
|
||||
_at.cmd_start_stop("+NSOCR", "=", "%s%d%d%d", "DGRAM", 17, localport, 1);
|
||||
|
||||
_at.resp_start();
|
||||
sock_id = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
if ((_at.get_last_error() != NSAPI_ERROR_OK) || (sock_id == -1)) {
|
||||
_at.unlock();
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
_at.unlock();
|
||||
|
||||
// Check for duplicate socket id delivered by modem
|
||||
for (int i = 0; i < _device.get_property(AT_CellularDevice::PROPERTY_SOCKET_COUNT); i++) {
|
||||
CellularSocket *sock = _socket[i];
|
||||
if (sock && sock != socket && sock->id == sock_id) {
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
socket->started = true;
|
||||
socket->id = sock_id;
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t UBLOX_N2XX_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
|
||||
const void *data, nsapi_size_t size)
|
||||
{
|
||||
MBED_ASSERT(socket->id != -1);
|
||||
|
||||
if (size > N2XX_MAX_PACKET_SIZE) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
int sent_len = 0;
|
||||
char *dataStr = new char [(size * 2) + 1]();
|
||||
if (!dataStr) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
char_str_to_hex_str((const char *)data, size, dataStr);
|
||||
|
||||
_at.cmd_start_stop("+NSOST", "=", "%d%s%d%d%s", socket->id, address.get_ip_address(),
|
||||
address.get_port(), size, dataStr);
|
||||
|
||||
_at.resp_start();
|
||||
_at.skip_param(); // skip socket id
|
||||
sent_len = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
delete[] dataStr;
|
||||
if ((_at.get_last_error() == NSAPI_ERROR_OK)) {
|
||||
return sent_len;
|
||||
}
|
||||
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t UBLOX_N2XX_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
|
||||
void *buffer, nsapi_size_t size)
|
||||
{
|
||||
MBED_ASSERT(socket->id != -1);
|
||||
|
||||
nsapi_size_or_error_t nsapi_error_size = NSAPI_ERROR_DEVICE_ERROR;
|
||||
nsapi_size_t read_blk, usorf_sz, count = 0, length = size;
|
||||
bool success = true;
|
||||
char ipAddress[NSAPI_IP_SIZE];
|
||||
int port = 0;
|
||||
Timer timer;
|
||||
|
||||
if (socket->pending_bytes == 0) {
|
||||
_at.process_oob();
|
||||
if (socket->pending_bytes == 0) {
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
timer.start();
|
||||
while (success && (length > 0)) {
|
||||
read_blk = N2XX_MAX_PACKET_SIZE;
|
||||
if (read_blk > length) {
|
||||
read_blk = length;
|
||||
}
|
||||
if (socket->pending_bytes > 0) {
|
||||
_at.cmd_start_stop("+NSORF", "=", "%d%d", socket->id, read_blk);
|
||||
|
||||
_at.resp_start();
|
||||
_at.skip_param(); // receiving socket id
|
||||
_at.read_string(ipAddress, sizeof(ipAddress));
|
||||
port = _at.read_int();
|
||||
usorf_sz = _at.read_int();
|
||||
if (usorf_sz > length) {
|
||||
usorf_sz = length;
|
||||
}
|
||||
_at.read_hex_string((char *)buffer + count, usorf_sz);
|
||||
_at.resp_stop();
|
||||
|
||||
// Must use what +NSORF returns here as it may be less or more than we asked for
|
||||
if (usorf_sz >= socket->pending_bytes) {
|
||||
socket->pending_bytes = 0;
|
||||
} else {
|
||||
socket->pending_bytes -= usorf_sz;
|
||||
}
|
||||
|
||||
if (usorf_sz > 0) {
|
||||
count += (usorf_sz);
|
||||
length -= (usorf_sz);
|
||||
} else {
|
||||
// read() should not fail
|
||||
success = false;
|
||||
}
|
||||
} else if (timer.elapsed_time() < SOCKET_TIMEOUT) {
|
||||
// Wait for URCs
|
||||
_at.process_oob();
|
||||
} else {
|
||||
if (count == 0) {
|
||||
// Timeout with nothing received
|
||||
nsapi_error_size = NSAPI_ERROR_WOULD_BLOCK;
|
||||
success = false;
|
||||
}
|
||||
length = 0; // This simply to cause an exit
|
||||
}
|
||||
}
|
||||
timer.stop();
|
||||
|
||||
socket->pending_bytes = 0;
|
||||
if (!count || (_at.get_last_error() != NSAPI_ERROR_OK)) {
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
if (success && socket->proto == NSAPI_UDP && address) {
|
||||
address->set_ip_address(ipAddress);
|
||||
address->get_ip_address();
|
||||
address->set_port(port);
|
||||
}
|
||||
|
||||
return nsapi_error_size = count;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_N2XX_CellularStack::socket_close_impl(int sock_id)
|
||||
{
|
||||
return _at.at_cmd_discard("+NSOCL", "=", "%d", sock_id);
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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 UBLOX_N2XX_CELLULARSTACK_H_
|
||||
#define UBLOX_N2XX_CELLULARSTACK_H_
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "AT_CellularStack.h"
|
||||
#include "CellularUtil.h"
|
||||
#include "mbed_wait_api.h"
|
||||
#include "drivers/Timer.h"
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_N2XX_CellularStack : public AT_CellularStack {
|
||||
|
||||
public:
|
||||
|
||||
UBLOX_N2XX_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device);
|
||||
virtual ~UBLOX_N2XX_CellularStack();
|
||||
|
||||
protected:
|
||||
|
||||
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);
|
||||
|
||||
protected:
|
||||
|
||||
/** Socket timeout value in milliseconds.
|
||||
* Note: the sockets layer above will retry the
|
||||
* call to the functions here when they return NSAPI_ERROR_WOULD_BLOCK
|
||||
* and the user has set a larger timeout or full blocking.
|
||||
*/
|
||||
static constexpr seconds SOCKET_TIMEOUT = 1s;
|
||||
|
||||
/** The maximum number of bytes in a packet that can be write/read from
|
||||
* the AT interface in one go.
|
||||
*/
|
||||
static const int N2XX_MAX_PACKET_SIZE = 512;
|
||||
|
||||
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);
|
||||
|
||||
virtual nsapi_error_t socket_close_impl(int sock_id);
|
||||
|
||||
private:
|
||||
|
||||
// URC handlers
|
||||
void NSONMI_URC();
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // UBLOX_N2XX_CELLULARSTACK_H_
|
||||
29
connectivity/drivers/cellular/UBLOX/N2XX/mbed_lib.json
Normal file
29
connectivity/drivers/cellular/UBLOX/N2XX/mbed_lib.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "UBLOX_N2XX",
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
121
connectivity/drivers/cellular/UBLOX/PPP/UBLOX_PPP.cpp
Normal file
121
connectivity/drivers/cellular/UBLOX/PPP/UBLOX_PPP.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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 "UBLOX_PPP.h"
|
||||
#include "AT_CellularNetwork.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
||||
#ifdef UBX_MDM_SARA_R41XM
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
AT_CellularNetwork::RegistrationModeDisable,// C_EREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_REG
|
||||
0, // AT_CGSN_WITH_TYPE
|
||||
0, // AT_CGDATA
|
||||
0, // AT_CGAUTH
|
||||
1, // AT_CNMI
|
||||
1, // AT_CSMP
|
||||
1, // AT_CMGF
|
||||
0, // AT_CSDH
|
||||
1, // PROPERTY_IPV4_STACK
|
||||
0, // PROPERTY_IPV6_STACK
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
0, // PROPERTY_NON_IP_PDP_TYPE
|
||||
1, // PROPERTY_AT_CGEREP
|
||||
1, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
0, // PROPERTY_SOCKET_COUNT
|
||||
0, // PROPERTY_IP_TCP
|
||||
0, // PROPERTY_IP_UDP
|
||||
0, // PROPERTY_AT_SEND_DELAY
|
||||
};
|
||||
#elif defined(UBX_MDM_SARA_U2XX) || defined(UBX_MDM_SARA_G3XX)
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
AT_CellularNetwork::RegistrationModeDisable,// C_EREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_REG
|
||||
#ifdef UBX_MDM_SARA_G3XX
|
||||
0, // AT_CGSN_WITH_TYPE
|
||||
#else
|
||||
1, // AT_CGSN_WITH_TYPE
|
||||
#endif
|
||||
1, // AT_CGDATA
|
||||
0, // AT_CGAUTH
|
||||
1, // AT_CNMI
|
||||
1, // AT_CSMP
|
||||
1, // AT_CMGF
|
||||
1, // AT_CSDH
|
||||
1, // PROPERTY_IPV4_STACK
|
||||
0, // PROPERTY_IPV6_STACK
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
0, // PROPERTY_NON_IP_PDP_TYPE
|
||||
1, // PROPERTY_AT_CGEREP
|
||||
1, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
0, // PROPERTY_SOCKET_COUNT
|
||||
0, // PROPERTY_IP_TCP
|
||||
0, // PROPERTY_IP_UDP
|
||||
0, // PROPERTY_AT_SEND_DELAY
|
||||
};
|
||||
#else
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
0, // C_EREG
|
||||
0, // C_GREG
|
||||
0, // C_REG
|
||||
0, // AT_CGSN_WITH_TYPE
|
||||
0, // AT_CGDATA
|
||||
0, // AT_CGAUTH
|
||||
0, // AT_CNMI
|
||||
0, // AT_CSMP
|
||||
0, // AT_CMGF
|
||||
0, // AT_CSDH
|
||||
0, // PROPERTY_IPV4_STACK
|
||||
0, // PROPERTY_IPV6_STACK
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
0, // PROPERTY_NON_IP_PDP_TYPE
|
||||
0, // PROPERTY_AT_CGEREP
|
||||
0, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
0, // PROPERTY_SOCKET_COUNT
|
||||
0, // PROPERTY_IP_TCP
|
||||
0, // PROPERTY_IP_UDP
|
||||
0, // PROPERTY_AT_SEND_DELAY
|
||||
};
|
||||
#endif
|
||||
|
||||
UBLOX_PPP::UBLOX_PPP(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
{
|
||||
set_cellular_properties(cellular_properties);
|
||||
}
|
||||
|
||||
#if MBED_CONF_UBLOX_PPP_PROVIDE_DEFAULT
|
||||
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
#error Must define lwip.ppp-enabled
|
||||
#endif
|
||||
|
||||
#include "drivers/BufferedSerial.h"
|
||||
CellularDevice *CellularDevice::get_default_instance()
|
||||
{
|
||||
static BufferedSerial serial(MBED_CONF_UBLOX_PPP_TX, MBED_CONF_UBLOX_PPP_RX, MBED_CONF_UBLOX_PPP_BAUDRATE);
|
||||
#if defined (MBED_CONF_UBLOX_PPP_RTS) && defined(MBED_CONF_UBLOX_PPP_CTS)
|
||||
tr_debug("UBLOX_PPP flow control: RTS %d CTS %d", MBED_CONF_UBLOX_PPP_RTS, MBED_CONF_UBLOX_PPP_CTS);
|
||||
serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_UBLOX_PPP_RTS, MBED_CONF_UBLOX_PPP_CTS);
|
||||
#endif
|
||||
static UBLOX_PPP device(&serial);
|
||||
return &device;
|
||||
}
|
||||
#endif
|
||||
41
connectivity/drivers/cellular/UBLOX/PPP/UBLOX_PPP.h
Normal file
41
connectivity/drivers/cellular/UBLOX/PPP/UBLOX_PPP.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 UBLOX_PPP_H_
|
||||
#define UBLOX_PPP_H_
|
||||
|
||||
#ifdef TARGET_FF_ARDUINO
|
||||
#ifndef MBED_CONF_UBLOX_PPP_TX
|
||||
#define MBED_CONF_UBLOX_PPP_TX D1
|
||||
#endif
|
||||
#ifndef MBED_CONF_UBLOX_PPP_RX
|
||||
#define MBED_CONF_UBLOX_PPP_RX D0
|
||||
#endif
|
||||
#endif /* TARGET_FF_ARDUINO */
|
||||
|
||||
#include "AT_CellularDevice.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_PPP : public AT_CellularDevice {
|
||||
public:
|
||||
UBLOX_PPP(FileHandle *fh);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // UBLOX_PPP_H_
|
||||
29
connectivity/drivers/cellular/UBLOX/PPP/mbed_lib.json
Normal file
29
connectivity/drivers/cellular/UBLOX/PPP/mbed_lib.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "UBLOX_PPP",
|
||||
"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": 115200
|
||||
},
|
||||
"provide-default": {
|
||||
"help": "Provide as default CellularDevice [true/false]",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
}
|
||||
27
connectivity/drivers/cellular/UBLOX/README.md
Normal file
27
connectivity/drivers/cellular/UBLOX/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
## Configuring Ublox Cellular Modems for custom targets
|
||||
|
||||
In order to use cellular APIs with custom targets, user needs to define ublox modem macros in `mbed_app.json` configuration file:
|
||||
```
|
||||
"target_overrides": {
|
||||
"*": {
|
||||
"mbed-trace.enable": true,
|
||||
"platform.stdio-convert-newlines": true,
|
||||
"platform.stdio-baud-rate": 115200,
|
||||
"platform.default-serial-baud-rate": 115200
|
||||
},
|
||||
"K64F": {
|
||||
"target.macros_add": ["UBX_MDM_SARA_R41XM", "UBX_MDM_SARA_R412M"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
List of supported ublox modems and their respective macros are as follow:
|
||||
|
||||
| Ublox mbed board | Modem Name | Family Macro | Modem Macro |
|
||||
| ----------- | :-----------: | :-------------: | :-------------: |
|
||||
| UBLOX_C027 | SARA-G350 | `UBX_MDM_SARA_G3XX` | `UBX_MDM_SARA_G350` |
|
||||
| UBLOX_C030_N211 | SARA-N211 | `UBX_MDM_SARA_N2XX` | `UBX_MDM_SARA_N211` |
|
||||
| UBLOX_C030_U201 | SARA-U201 | `UBX_MDM_SARA_U2XX` | `UBX_MDM_SARA_U201` |
|
||||
| UBLOX_C030_R410M | SARA-R410M | `UBX_MDM_SARA_R41XM` | `UBX_MDM_SARA_R410M` |
|
||||
| UBLOX_C030_R412M | SARA-R412M | `UBX_MDM_SARA_R41XM` | `UBX_MDM_SARA_R412M` |
|
||||
Reference in New Issue
Block a user