mirror of https://github.com/ARMmbed/mbed-os.git
UBLOX cellular api's for UDP and TCP
parent
b170e1c44d
commit
a8abeccdac
|
@ -98,6 +98,7 @@ protected:
|
|||
bool started; // socket has been opened on modem stack
|
||||
bool tx_ready; // socket is ready for sending on modem stack
|
||||
bool rx_avail; // socket has data for reading on modem stack
|
||||
volatile nsapi_size_t pending_bytes; // The number of received bytes pending
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,7 +30,11 @@ namespace mbed {
|
|||
#elif TARGET_MTB_MTS_DRAGONFLY
|
||||
#define CELLULAR_DEVICE TELIT_HE910
|
||||
#elif TARGET_UBLOX_C030
|
||||
#ifdef TARGET_UBLOX_C030_N211
|
||||
#define CELLULAR_DEVICE UBLOX_AT
|
||||
#else
|
||||
#define CELLULAR_DEVICE UBLOX_PPP
|
||||
#endif
|
||||
#elif TARGET_UBLOX_C027
|
||||
#define CELLULAR_DEVICE UBLOX_PPP
|
||||
#else
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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_AT.h"
|
||||
#include "UBLOX_AT_CellularNetwork.h"
|
||||
#include "UBLOX_AT_CellularPower.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
||||
UBLOX_AT::UBLOX_AT(EventQueue &queue) : AT_CellularDevice(queue)
|
||||
{
|
||||
}
|
||||
|
||||
UBLOX_AT::~UBLOX_AT()
|
||||
{
|
||||
}
|
||||
|
||||
CellularNetwork *UBLOX_AT::open_network(FileHandle *fh)
|
||||
{
|
||||
if (!_network) {
|
||||
ATHandler *atHandler = get_at_handler(fh);
|
||||
if (atHandler) {
|
||||
_network = new UBLOX_AT_CellularNetwork(*atHandler);
|
||||
if (!_network) {
|
||||
release_at_handler(atHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _network;
|
||||
}
|
||||
|
||||
CellularPower *UBLOX_AT::open_power(FileHandle *fh)
|
||||
{
|
||||
if (!_power) {
|
||||
ATHandler *atHandler = get_at_handler(fh);
|
||||
if (atHandler) {
|
||||
_power = new UBLOX_AT_CellularPower(*atHandler);
|
||||
if (!_power) {
|
||||
release_at_handler(atHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _power;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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_AT_H_
|
||||
#define UBLOX_AT_H_
|
||||
|
||||
#include "AT_CellularDevice.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_AT : public AT_CellularDevice
|
||||
{
|
||||
|
||||
public:
|
||||
UBLOX_AT(events::EventQueue &queue);
|
||||
virtual ~UBLOX_AT();
|
||||
|
||||
public: // CellularDevice
|
||||
virtual CellularNetwork *open_network(FileHandle *fh);
|
||||
virtual CellularPower *open_power(FileHandle *fh);
|
||||
|
||||
public: // NetworkInterface
|
||||
void handle_urc(FileHandle *fh);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // UBLOX_AT_H_
|
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
* 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_AT_CellularNetwork.h"
|
||||
#include "UBLOX_AT_CellularStack.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
UBLOX_AT_CellularNetwork::UBLOX_AT_CellularNetwork(ATHandler &atHandler) : AT_CellularNetwork(atHandler)
|
||||
{
|
||||
_op_act = RAT_UNKNOWN;
|
||||
// The authentication to use
|
||||
_auth = NSAPI_SECURITY_UNKNOWN;
|
||||
}
|
||||
|
||||
UBLOX_AT_CellularNetwork::~UBLOX_AT_CellularNetwork()
|
||||
{
|
||||
if (_connection_status_cb) {
|
||||
_connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_ERROR_CONNECTION_LOST);
|
||||
}
|
||||
}
|
||||
|
||||
NetworkStack *UBLOX_AT_CellularNetwork::get_stack()
|
||||
{
|
||||
if (!_stack) {
|
||||
_stack = new UBLOX_AT_CellularStack(_at, _cid, _ip_stack_type);
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
|
||||
bool UBLOX_AT_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
return requested_stack == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
bool UBLOX_AT_CellularNetwork::has_registration(RegistrationType reg_type)
|
||||
{
|
||||
return (reg_type == C_REG || reg_type == C_GREG);
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat)
|
||||
{
|
||||
switch(opRat) {
|
||||
#if defined(TARGET_UBLOX_C030_U201) || defined(TARGET_UBLOX_C027)
|
||||
case RAT_GSM:
|
||||
case RAT_GSM_COMPACT:
|
||||
break;
|
||||
case RAT_EGPRS:
|
||||
break;
|
||||
#elif defined(TARGET_UBLOX_C030_U201)
|
||||
case RAT_UTRAN:
|
||||
break;
|
||||
case RAT_HSDPA:
|
||||
break;
|
||||
case RAT_HSUPA:
|
||||
break;
|
||||
case RAT_HSDPA_HSUPA:
|
||||
break;
|
||||
#elif defined(TARGET_UBLOX_C030_R410M)
|
||||
case RAT_CATM1:
|
||||
break;
|
||||
#elif defined(TARGET_UBLOX_C030_R410M) || defined(TARGET_UBLOX_C030_N211)
|
||||
case RAT_NB1:
|
||||
break;
|
||||
#endif
|
||||
default: {
|
||||
_op_act = RAT_UNKNOWN;
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularNetwork::connect()
|
||||
{
|
||||
_at.lock();
|
||||
nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
// Attempt to establish a connection
|
||||
#ifdef TARGET_UBLOX_C030_R410M
|
||||
err = NSAPI_ERROR_OK;
|
||||
#else
|
||||
err = open_data_channel();
|
||||
#endif
|
||||
if (err != 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 (_connection_status_cb) {
|
||||
_connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _connect_status);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularNetwork::open_data_channel()
|
||||
{
|
||||
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.cmd_start("AT+UPSND=" PROFILE ",8");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+UPSND:");
|
||||
_at.read_int();
|
||||
_at.read_int();
|
||||
active = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
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) ? _auth : NSAPI_SECURITY_NONE;
|
||||
} else {
|
||||
_auth = NSAPI_SECURITY_NONE;
|
||||
}
|
||||
success = activate_profile(_apn, _uname, _pwd);
|
||||
} 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_CellularNetwork::activate_profile(const char* apn,
|
||||
const char* username,
|
||||
const char* password)
|
||||
{
|
||||
bool activated = false;
|
||||
bool success = false;
|
||||
|
||||
// Set up the APN
|
||||
if (apn) {
|
||||
success = false;
|
||||
_at.cmd_start("AT+UPSD=0,1,");
|
||||
_at.write_string(apn);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
// Set up the UserName
|
||||
if (success && username) {
|
||||
success = false;
|
||||
_at.cmd_start("AT+UPSD=" PROFILE ",2,");
|
||||
_at.write_string(username);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
// Set up the Password
|
||||
if (success && password) {
|
||||
success = false;
|
||||
_at.cmd_start("AT+UPSD=" PROFILE ",3,");
|
||||
_at.write_string(password);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
_at.cmd_start("AT+UPSD=" PROFILE ",7,\"0.0.0.0\"");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
// Set up the authentication protocol
|
||||
// 0 = none
|
||||
// 1 = PAP (Password Authentication Protocol)
|
||||
// 2 = CHAP (Challenge Handshake Authentication Protocol)
|
||||
for (int protocol = nsapi_security_to_modem_security(NSAPI_SECURITY_NONE);
|
||||
success && (protocol <= nsapi_security_to_modem_security(NSAPI_SECURITY_CHAP)); protocol++) {
|
||||
if ((_auth == NSAPI_SECURITY_UNKNOWN) || (nsapi_security_to_modem_security(_auth) == protocol)) {
|
||||
_at.cmd_start("AT+UPSD=0,6,");
|
||||
_at.write_int(protocol);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
// Activate, wait upto 30 seconds for the connection to be made
|
||||
_at.set_at_timeout(30000);
|
||||
_at.cmd_start("AT+UPSDA=0,3");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.restore_at_timeout();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
activated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return activated;
|
||||
}
|
||||
|
||||
// Convert nsapi_security_t to the modem security numbers
|
||||
int UBLOX_AT_CellularNetwork::nsapi_security_to_modem_security(nsapi_security_t nsapi_security)
|
||||
{
|
||||
int modem_security = 3;
|
||||
|
||||
switch (nsapi_security)
|
||||
{
|
||||
case NSAPI_SECURITY_NONE:
|
||||
modem_security = 0;
|
||||
break;
|
||||
case NSAPI_SECURITY_PAP:
|
||||
modem_security = 1;
|
||||
break;
|
||||
case NSAPI_SECURITY_CHAP:
|
||||
modem_security = 2;
|
||||
break;
|
||||
case NSAPI_SECURITY_UNKNOWN:
|
||||
modem_security = 3;
|
||||
break;
|
||||
default:
|
||||
modem_security = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
return modem_security;
|
||||
}
|
||||
|
||||
// Disconnect the on board IP stack of the modem.
|
||||
bool UBLOX_AT_CellularNetwork::disconnect_modem_stack()
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (get_ip_address() != NULL) {
|
||||
_at.cmd_start("AT+UPSDA=" PROFILE ",4");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularNetwork::get_imsi(char* imsi)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CIMI");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
int len = _at.read_string(imsi, MAX_IMSI_LENGTH);
|
||||
if (len > 0) {
|
||||
imsi[len] = '\0';
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
// Get the next set of credentials, based on IMSI.
|
||||
void UBLOX_AT_CellularNetwork::get_next_credentials(char ** config)
|
||||
{
|
||||
if (*config) {
|
||||
_apn = _APN_GET(*config);
|
||||
_uname = _APN_GET(*config);
|
||||
_pwd = _APN_GET(*config);
|
||||
}
|
||||
}
|
||||
|
||||
const char *UBLOX_AT_CellularNetwork::get_gateway()
|
||||
{
|
||||
return get_ip_address();
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularNetwork::detach()
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CGATT=0");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
|
||||
// wait added to process CGREG and UUPSDD URC, which comes after detach.
|
||||
wait_ms(50);
|
||||
|
||||
return _at.get_last_error();
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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_AT_CELLULAR_NETWORK_H_
|
||||
#define UBLOX_AT_CELLULAR_NETWORK_H_
|
||||
|
||||
#include "AT_CellularNetwork.h"
|
||||
#include "APN_db.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_AT_CellularNetwork : public AT_CellularNetwork
|
||||
{
|
||||
public:
|
||||
UBLOX_AT_CellularNetwork(ATHandler &atHandler);
|
||||
virtual ~UBLOX_AT_CellularNetwork();
|
||||
|
||||
virtual nsapi_error_t connect();
|
||||
|
||||
virtual const char *get_gateway();
|
||||
|
||||
virtual nsapi_error_t detach();
|
||||
protected:
|
||||
virtual NetworkStack *get_stack();
|
||||
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
|
||||
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
|
||||
|
||||
virtual bool has_registration(RegistrationType rat);
|
||||
|
||||
private:
|
||||
|
||||
/** The profile to use (on board the modem).
|
||||
*/
|
||||
#define PROFILE "0"
|
||||
|
||||
/** Length of IMSI buffer.
|
||||
*/
|
||||
#define MAX_IMSI_LENGTH 15
|
||||
|
||||
/** The type of authentication to use.
|
||||
*/
|
||||
nsapi_security_t _auth;
|
||||
|
||||
/** Connect the on board IP stack of the modem.
|
||||
*
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
nsapi_error_t open_data_channel();
|
||||
|
||||
/** 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
|
||||
* (NSAPI_SECURITY_NONE, NSAPI_SECURITY_PAP,
|
||||
* NSAPI_SECURITY_CHAP or NSAPI_SECURITY_UNKNOWN).
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool activate_profile(const char* apn, const char* username, const char* password);
|
||||
|
||||
/** Convert nsapi_security_t to the modem security numbers.
|
||||
*
|
||||
* @param nsapi_security Security protocol.
|
||||
* @return Modem security numbers.
|
||||
*/
|
||||
int nsapi_security_to_modem_security(nsapi_security_t nsapi_security);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** Get the next set of credentials from the database.
|
||||
*/
|
||||
void get_next_credentials(char ** config);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // UBLOX_AT_CELLULAR_NETWORK_H_
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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_AT_CellularPower.h"
|
||||
|
||||
#include "onboard_modem_api.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
UBLOX_AT_CellularPower::UBLOX_AT_CellularPower(ATHandler &atHandler) : AT_CellularPower(atHandler)
|
||||
{
|
||||
}
|
||||
|
||||
UBLOX_AT_CellularPower::~UBLOX_AT_CellularPower()
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularPower::on()
|
||||
{
|
||||
#if MODEM_ON_BOARD
|
||||
::onboard_modem_init();
|
||||
::onboard_modem_power_up();
|
||||
#endif
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularPower::off()
|
||||
{
|
||||
#if MODEM_ON_BOARD
|
||||
::onboard_modem_power_down();
|
||||
#endif
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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_AT_CELLULARPOWER_H_
|
||||
#define UBLOX_AT_CELLULARPOWER_H_
|
||||
|
||||
#include "AT_CellularPower.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_AT_CellularPower : public AT_CellularPower
|
||||
{
|
||||
public:
|
||||
UBLOX_AT_CellularPower(ATHandler &atHandler);
|
||||
virtual ~UBLOX_AT_CellularPower();
|
||||
|
||||
public: //from CellularPower
|
||||
|
||||
virtual nsapi_error_t on();
|
||||
|
||||
virtual nsapi_error_t off();
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // UBLOX_AT_CELLULARPOWER_H_
|
|
@ -0,0 +1,582 @@
|
|||
/*
|
||||
* 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_AT_CellularStack.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace mbed_cellular_util;
|
||||
|
||||
UBLOX_AT_CellularStack::UBLOX_AT_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type) : AT_CellularStack(atHandler, cid, stack_type)
|
||||
{
|
||||
// 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->rx_avail = true;
|
||||
socket->pending_bytes = b;
|
||||
// No debug prints here as they can affect timing
|
||||
// and cause data loss in UARTSerial
|
||||
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->rx_avail = true;
|
||||
socket->pending_bytes = b;
|
||||
// No debug prints here as they can affect timing
|
||||
// and cause data loss in UARTSerial
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
int UBLOX_AT_CellularStack::get_max_socket_count()
|
||||
{
|
||||
return UBLOX_MAX_SOCKET;
|
||||
}
|
||||
|
||||
int UBLOX_AT_CellularStack::get_max_packet_size()
|
||||
{
|
||||
return UBLOX_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
bool UBLOX_AT_CellularStack::is_protocol_supported(nsapi_protocol_t protocol)
|
||||
{
|
||||
return (protocol == NSAPI_UDP || protocol == NSAPI_TCP);
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularStack::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
|
||||
{
|
||||
if (!is_protocol_supported(proto) || !handle) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int max_socket_count = get_max_socket_count();
|
||||
|
||||
if (!_socket) {
|
||||
_socket = new CellularSocket*[max_socket_count];
|
||||
if (!_socket) {
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
_socket_count = max_socket_count;
|
||||
for (int i = 0; i < max_socket_count; i++) {
|
||||
_socket[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int index = -1;
|
||||
for (int i = 0; i < max_socket_count; i++) {
|
||||
if (!_socket[i]) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
|
||||
// create local socket structure, socket on modem is created when app calls sendto/recvfrom
|
||||
_socket[index] = new CellularSocket;
|
||||
CellularSocket *psock;
|
||||
psock = _socket[index];
|
||||
memset(psock, 0, sizeof(CellularSocket));
|
||||
SocketAddress addr(0, get_dynamic_ip_port());
|
||||
psock->id = index;
|
||||
psock->localAddress = addr;
|
||||
psock->proto = proto;
|
||||
nsapi_error_t err = create_socket_impl(psock);
|
||||
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
*handle = psock;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularStack::create_socket_impl(CellularSocket *socket)
|
||||
{
|
||||
int sock_id = 0;
|
||||
bool socketOpenWorking = false;
|
||||
|
||||
_at.lock();
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
_at.cmd_start("AT+USOCR=17");
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+USOCR:");
|
||||
sock_id = _at.read_int();
|
||||
_at.resp_stop();
|
||||
} else if(socket->proto == NSAPI_TCP) {
|
||||
_at.cmd_start("AT+USOCR=6");
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+USOCR:");
|
||||
sock_id = _at.read_int();
|
||||
_at.resp_stop();
|
||||
} // Unsupported protocol is checked in "is_protocol_supported" function
|
||||
_at.unlock();
|
||||
|
||||
socketOpenWorking = (_at.get_last_error() == NSAPI_ERROR_OK);
|
||||
if (!socketOpenWorking) {
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
|
||||
// Check for duplicate socket id delivered by modem
|
||||
for (int i = 0; i < UBLOX_MAX_SOCKET; i++) {
|
||||
CellularSocket *sock = _socket[i];
|
||||
if (sock && sock->created && sock->id == sock_id) {
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
socket->id = sock_id;
|
||||
socket->created = true;
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &addr)
|
||||
{
|
||||
CellularSocket *socket = (CellularSocket *)handle;
|
||||
|
||||
if (!socket) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+USOCO=");
|
||||
_at.write_int(socket->id);
|
||||
_at.write_string(addr.get_ip_address(), true);
|
||||
_at.write_int(addr.get_port());
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
|
||||
if (_at.get_last_error() == 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)
|
||||
{
|
||||
int sent_len = 0;
|
||||
uint8_t ch = 0;
|
||||
|
||||
_at.lock();
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
if (size > (nsapi_size_t) get_max_packet_size()) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
_at.cmd_start("AT+USOST=");
|
||||
_at.write_int(socket->id);
|
||||
_at.write_string(address.get_ip_address(), true);
|
||||
_at.write_int(address.get_port());
|
||||
_at.write_int(size);
|
||||
_at.cmd_stop();
|
||||
wait_ms(50);
|
||||
while (ch != '@') {
|
||||
_at.read_bytes(&ch, 1);
|
||||
}
|
||||
_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 {
|
||||
socket->rx_avail = false;
|
||||
}
|
||||
} 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("AT+USOWR=");
|
||||
_at.write_int(socket->id);
|
||||
_at.write_int(blk);
|
||||
_at.cmd_stop();
|
||||
wait_ms(50);
|
||||
while (ch != '@') {
|
||||
_at.read_bytes(&ch, 1);
|
||||
}
|
||||
_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) {
|
||||
socket->rx_avail = false;
|
||||
return size - count;
|
||||
}
|
||||
}
|
||||
_at.unlock();
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
_at.lock();
|
||||
timer.start();
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
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("AT+USORF=");
|
||||
_at.write_int(socket->id);
|
||||
_at.write_int(read_blk);
|
||||
_at.cmd_stop();
|
||||
|
||||
_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();
|
||||
|
||||
// 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 > size) {
|
||||
usorf_sz = size;
|
||||
}
|
||||
_at.read_bytes(&ch, 1);
|
||||
_at.read_bytes((uint8_t *)buffer + count , usorf_sz);
|
||||
_at.resp_stop();
|
||||
|
||||
if (usorf_sz > 0) {
|
||||
count += usorf_sz;
|
||||
size -= usorf_sz;
|
||||
} else {
|
||||
// read() should not fail
|
||||
success = false;
|
||||
}
|
||||
} else if (timer.read_ms() < 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;
|
||||
}
|
||||
size = 0; // This simply to cause an exit
|
||||
}
|
||||
}
|
||||
} 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("AT+USORD=");
|
||||
_at.write_int(socket->id);
|
||||
_at.write_int(read_blk);
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+USORD:");
|
||||
_at.skip_param(); // receiving socket id
|
||||
usorf_sz = _at.read_int();
|
||||
|
||||
// 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 > size) {
|
||||
usorf_sz = size;
|
||||
}
|
||||
_at.read_bytes(&ch, 1);
|
||||
_at.read_bytes((uint8_t *)buffer + count , usorf_sz);
|
||||
_at.resp_stop();
|
||||
|
||||
if (usorf_sz > 0) {
|
||||
count += usorf_sz;
|
||||
size -= usorf_sz;
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
} else if (timer.read_ms() < 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;
|
||||
}
|
||||
size = 0; // This simply to cause an exit
|
||||
}
|
||||
}
|
||||
}
|
||||
timer.stop();
|
||||
_at.unlock();
|
||||
|
||||
|
||||
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_size_or_error_t UBLOX_AT_CellularStack::socket_sendto(nsapi_socket_t handle, const SocketAddress &addr, const void *data, unsigned size)
|
||||
{
|
||||
CellularSocket *socket = (CellularSocket *)handle;
|
||||
if (!socket || !socket->created) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t ret_val = NSAPI_ERROR_OK;
|
||||
|
||||
/* Check parameters */
|
||||
if (addr.get_ip_version() == NSAPI_UNSPEC) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
_at.lock();
|
||||
|
||||
ret_val = socket_sendto_impl(socket, addr, data, size);
|
||||
|
||||
_at.unlock();
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularStack::socket_close_impl(int sock_id)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+USOCL=");
|
||||
_at.write_int(sock_id);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
// 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 < UBLOX_MAX_SOCKET); 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->rx_avail = 0;
|
||||
socket->_cb = NULL;
|
||||
socket->_data = NULL;
|
||||
socket->created = false;
|
||||
}
|
||||
}
|
||||
|
||||
const char * UBLOX_AT_CellularStack::get_ip_address()
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+UPSND=" PROFILE ",0");
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+UPSND:");
|
||||
if (_at.info_resp()) {
|
||||
_at.skip_param();
|
||||
_at.skip_param();
|
||||
int len = _at.read_string(_ip, NSAPI_IPv4_SIZE-1);
|
||||
if (len == -1) {
|
||||
_ip[0] = '\0';
|
||||
_at.unlock();
|
||||
// no IPV4 address, return
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// in case stack type is not IPV4 only, try to look also for IPV6 address
|
||||
if (_stack_type != IPV4_STACK) {
|
||||
len = _at.read_string(_ip, PDP_IPV6_SIZE-1);
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
|
||||
// we have at least IPV4 address
|
||||
convert_ipv6(_ip);
|
||||
|
||||
return _ip;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularStack::gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version)
|
||||
{
|
||||
char ipAddress[NSAPI_IP_SIZE];
|
||||
nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
_at.lock();
|
||||
if (address->set_ip_address(host)) {
|
||||
err = NSAPI_ERROR_OK;
|
||||
} else {
|
||||
// This interrogation can sometimes take longer than the usual 8 seconds
|
||||
_at.cmd_start("AT+UDNSRN=0,");
|
||||
_at.write_string(host, true);
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.set_at_timeout(60000);
|
||||
_at.resp_start("+UDNSRN:");
|
||||
if (_at.info_resp()) {
|
||||
_at.read_string(ipAddress, sizeof(ipAddress));
|
||||
_at.resp_stop();
|
||||
|
||||
if (address->set_ip_address(ipAddress)) {
|
||||
err = NSAPI_ERROR_OK;
|
||||
}
|
||||
}
|
||||
_at.restore_at_timeout();
|
||||
}
|
||||
_at.unlock();
|
||||
|
||||
return err;
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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_AT_CELLULARSTACK_H_
|
||||
#define UBLOX_AT_CELLULARSTACK_H_
|
||||
|
||||
#include "AT_CellularStack.h"
|
||||
#include "CellularUtil.h"
|
||||
#include "mbed_wait_api.h"
|
||||
#include "drivers/Timer.h"
|
||||
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_AT_CellularStack : public AT_CellularStack
|
||||
{
|
||||
public:
|
||||
UBLOX_AT_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type);
|
||||
virtual ~UBLOX_AT_CellularStack();
|
||||
|
||||
virtual const char *get_ip_address();
|
||||
|
||||
virtual nsapi_error_t gethostbyname(const char *host,
|
||||
SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC);
|
||||
|
||||
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: // AT_CellularStack
|
||||
|
||||
/** Socket "unused" value.
|
||||
*/
|
||||
#define SOCKET_UNUSED -1
|
||||
|
||||
/** The profile to use (on board the modem).
|
||||
*/
|
||||
#define PROFILE "0"
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
#define SOCKET_TIMEOUT 5000
|
||||
|
||||
/** Maximum allowed sockets.
|
||||
*/
|
||||
#define UBLOX_MAX_SOCKET 7
|
||||
|
||||
/** The maximum number of bytes in a packet that can be write/read from
|
||||
* the AT interface in one go.
|
||||
*/
|
||||
#define UBLOX_MAX_PACKET_SIZE 1024
|
||||
|
||||
virtual int get_max_socket_count();
|
||||
|
||||
virtual int get_max_packet_size();
|
||||
|
||||
virtual bool is_protocol_supported(nsapi_protocol_t protocol);
|
||||
|
||||
virtual nsapi_error_t socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto);
|
||||
|
||||
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_size_or_error_t socket_sendto(nsapi_socket_t handle, const SocketAddress &address,
|
||||
const void *data, 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_ */
|
|
@ -75,8 +75,10 @@ void onboard_modem_power_down()
|
|||
press_power_button(1500000);
|
||||
#else
|
||||
/* keep the power line low for 1 seconds */
|
||||
press_power_button(1000000);
|
||||
press_power_button(1500000);
|
||||
#endif
|
||||
/* wait for modem to power off properly*/
|
||||
wait(10);
|
||||
}
|
||||
|
||||
#endif //MODEM_ON_BOARD
|
||||
|
|
Loading…
Reference in New Issue