review and dynamic alloc (#3)

* Review fixes. Changed apn, username and password to be dynamically allocated.
pull/6082/head
Teppo Järvelin 2018-02-20 13:17:47 +02:00 committed by Ari Parkkila
parent 4457e361ac
commit ef14aef823
6 changed files with 172 additions and 70 deletions

View File

@ -503,11 +503,7 @@ CellularNetwork* CellularConnectionUtil::get_network()
CellularDevice* CellularConnectionUtil::get_device()
{
if (_cellularDevice) {
return _cellularDevice;
} else {
return NULL;
}
return _cellularDevice;
}
NetworkStack *CellularConnectionUtil::get_stack()

View File

@ -35,7 +35,7 @@
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
namespace mbed {
const int PIN_SIZE = 8;
/** CellularConnectionUtil class
@ -80,7 +80,7 @@ public:
* @param status_callback function to call on state changes
*/
void set_callback(mbed::Callback<bool(int, int)> status_callback);
/** Get event queue that can be chained to main event queue (or use start_dispatch)
* @return event queue
*/
@ -94,7 +94,7 @@ public:
/** Stop event queue dispatching and close cellular interfaces
*/
void stop();
/** Get cellular network interface
* @return network interface, NULL on failure
*/

View File

@ -31,11 +31,6 @@
namespace mbed {
static CellularConnectionUtil cellularConnection;
static rtos::Semaphore cellularSemaphore(0);
static UARTSerial cellularSerial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
bool EasyCellularConnection::cellular_status(int state, int next_state)
{
tr_info("cellular_status %d=>%d", state, next_state);
@ -45,7 +40,7 @@ bool EasyCellularConnection::cellular_status(int state, int next_state)
} else {
_is_connected = false;
}
MBED_ASSERT(cellularSemaphore.release() == osOK);
MBED_ASSERT(_cellularSemaphore.release() == osOK);
return false;
}
else {
@ -54,28 +49,35 @@ bool EasyCellularConnection::cellular_status(int state, int next_state)
return true;
}
EasyCellularConnection::EasyCellularConnection() : _is_connected(false), _target_state(CellularConnectionUtil::STATE_POWER_ON)
EasyCellularConnection::EasyCellularConnection() : _is_connected(false), _is_initialized(false),
_target_state(CellularConnectionUtil::STATE_POWER_ON),
_cellularSerial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE),
_cellularSemaphore(0), _cellularConnectionUtil(), _credentials_err(NSAPI_ERROR_OK)
{
tr_info("EasyCellularConnection()");
}
EasyCellularConnection::~EasyCellularConnection()
{
cellularConnection.stop();
_cellularConnectionUtil.stop();
}
nsapi_error_t EasyCellularConnection::init()
{
nsapi_error_t err = NSAPI_ERROR_OK;
if (!_is_initialized) {
#if defined (MDMRTS) && defined (MDMCTS)
cellularSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
_cellularSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
#endif
cellularConnection.set_serial(&cellularSerial);
cellularConnection.set_callback(callback(this, &EasyCellularConnection::cellular_status));
_cellularConnectionUtil.set_serial(&_cellularSerial);
_cellularConnectionUtil.set_callback(callback(this, &EasyCellularConnection::cellular_status));
nsapi_error_t err = cellularConnection.init();
err = _cellularConnectionUtil.init();
if (err == NSAPI_ERROR_OK) {
err = cellularConnection.start_dispatch();
if (err == NSAPI_ERROR_OK) {
err = _cellularConnectionUtil.start_dispatch();
}
_is_initialized = true;
}
return err;
@ -83,9 +85,14 @@ nsapi_error_t EasyCellularConnection::init()
void EasyCellularConnection::set_credentials(const char *apn, const char *uname, const char *pwd)
{
CellularNetwork * network = cellularConnection.get_network();
_credentials_err = init();
if (_credentials_err) {
return;
}
CellularNetwork * network = _cellularConnectionUtil.get_network();
if (network) {
network->set_credentials(apn, uname, pwd);
_credentials_err = network->set_credentials(apn, uname, pwd);
} else {
tr_error("NO Network...");
}
@ -93,22 +100,59 @@ void EasyCellularConnection::set_credentials(const char *apn, const char *uname,
void EasyCellularConnection::set_sim_pin(const char *sim_pin)
{
cellularConnection.set_sim_pin(sim_pin);
if (sim_pin) {
_cellularConnectionUtil.set_sim_pin(sim_pin);
}
}
nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd)
{
cellularConnection.set_sim_pin(sim_pin);
cellularConnection.get_network()->set_credentials(apn, uname, pwd);
nsapi_error_t err = check_connect();
if (err) {
return err;
}
if (sim_pin) {
_cellularConnectionUtil.set_sim_pin(sim_pin);
}
err = _cellularConnectionUtil.get_network()->set_credentials(apn, uname, pwd);
if (err) {
return err;
}
return connect();
}
nsapi_error_t EasyCellularConnection::check_connect()
{
if (_is_connected) {
return NSAPI_ERROR_IS_CONNECTED;
}
nsapi_error_t err = init();
if (err) {
return err;
}
return NSAPI_ERROR_OK;
}
nsapi_error_t EasyCellularConnection::connect()
{
// there was an error while setting credentials but it's a void function so check error here...
if (_credentials_err) {
return _credentials_err;
}
nsapi_error_t err = check_connect();
if (err) {
return err;
}
_target_state = CellularConnectionUtil::STATE_CONNECTED;
nsapi_error_t err = cellularConnection.continue_to_state(_target_state);
err = _cellularConnectionUtil.continue_to_state(_target_state);
if (err == NSAPI_ERROR_OK) {
int ret_wait = cellularSemaphore.wait(10*60*1000); // cellular network searching may take several minutes
int ret_wait = _cellularSemaphore.wait(10*60*1000); // cellular network searching may take several minutes
if (ret_wait != 1) {
tr_info("No cellular connection");
err = NSAPI_ERROR_NO_CONNECTION;
@ -120,11 +164,12 @@ nsapi_error_t EasyCellularConnection::connect()
nsapi_error_t EasyCellularConnection::disconnect()
{
_credentials_err = NSAPI_ERROR_OK;
_is_connected = false;
if (!cellularConnection.get_network()) {
if (!_cellularConnectionUtil.get_network()) {
return NSAPI_ERROR_NO_CONNECTION;
}
return cellularConnection.get_network()->disconnect();
return _cellularConnectionUtil.get_network()->disconnect();
}
bool EasyCellularConnection::is_connected()
@ -134,27 +179,36 @@ bool EasyCellularConnection::is_connected()
const char *EasyCellularConnection::get_ip_address()
{
CellularNetwork * network = cellularConnection.get_network();
if (network) {
return cellularConnection.get_network()->get_ip_address();
} else {
CellularNetwork *network = _cellularConnectionUtil.get_network();
if (!network) {
return NULL;
}
return _cellularConnectionUtil.get_network()->get_ip_address();
}
const char *EasyCellularConnection::get_netmask()
{
return cellularConnection.get_network()->get_netmask();
CellularNetwork *network = _cellularConnectionUtil.get_network();
if (!network) {
return NULL;
}
return network->get_netmask();
}
const char *EasyCellularConnection::get_gateway()
{
return cellularConnection.get_network()->get_gateway();
CellularNetwork *network = _cellularConnectionUtil.get_network();
if (!network) {
return NULL;
}
return network->get_gateway();
}
void EasyCellularConnection::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
{
CellularNetwork * network = cellularConnection.get_network();
CellularNetwork *network = _cellularConnectionUtil.get_network();
if (network) {
network->attach(status_cb);
}
@ -162,11 +216,7 @@ void EasyCellularConnection::attach(mbed::Callback<void(nsapi_event_t, intptr_t)
NetworkStack *EasyCellularConnection::get_stack()
{
#if NSAPI_PPP_AVAILABLE
return nsapi_ppp_get_stack();
#else
return cellularConnection.get_stack();
#endif // #if NSAPI_PPP_AVAILABLE
return _cellularConnectionUtil.get_stack();
}
} // namespace

View File

@ -36,12 +36,6 @@ public:
virtual ~EasyCellularConnection();
public:
/** Create cellular power and start dispatcher
* @remark Must be called before any other methods
* @return see nsapi_error_t, 0 on success
*/
nsapi_error_t init();
/** Set the Cellular network credentials
*
* Please check documentation of connect() for default behaviour of APN settings.
@ -137,9 +131,18 @@ private:
* @return true to continue state machine
*/
bool cellular_status(int state, int next_state);
nsapi_error_t init();
nsapi_error_t check_connect();
bool _is_connected;
bool _is_initialized;
CellularConnectionUtil::CellularState _target_state;
UARTSerial _cellularSerial;
rtos::Semaphore _cellularSemaphore;
CellularConnectionUtil _cellularConnectionUtil;
nsapi_error_t _credentials_err;
};
} // namespace

View File

@ -37,19 +37,32 @@ static const at_reg_t at_reg[] = {
};
AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(atHandler),
_stack(NULL), _uname(NULL), _pwd(NULL), _ip_stack_type_requested(DEFAULT_STACK), _ip_stack_type(DEFAULT_STACK), _cid(-1),
_stack(NULL), _apn(NULL), _uname(NULL), _pwd(NULL), _ip_stack_type_requested(DEFAULT_STACK), _ip_stack_type(DEFAULT_STACK), _cid(-1),
_connection_status_cb(NULL), _op_act(operator_t::RAT_UNKNOWN), _authentication_type(CHAP), _last_reg_type(C_REG),
_connect_status(NSAPI_STATUS_DISCONNECTED)
{
_at.set_urc_handler("NO CARRIER", callback(this, &AT_CellularNetwork::urc_no_carrier));
memset(_apn, 0, MAX_ACCESSPOINT_NAME_LENGTH);
}
AT_CellularNetwork::~AT_CellularNetwork()
{
free_credentials();
}
void AT_CellularNetwork::free_credentials()
{
if (_uname) {
free(_uname);
}
if (_pwd) {
free(_pwd);
}
if (_apn) {
free(_apn);
}
}
void AT_CellularNetwork::urc_no_carrier()
@ -63,9 +76,36 @@ void AT_CellularNetwork::urc_no_carrier()
nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn,
const char *username, const char *password)
{
strncpy(_apn, apn, MAX_ACCESSPOINT_NAME_LENGTH);
_uname = username;
_pwd = password;
size_t len;
if (apn) {
len = strlen(apn);
_apn = (char*)malloc(len*sizeof(char)+1);
if (_apn) {
memcpy(_apn, apn, len);
} else {
return NSAPI_ERROR_NO_MEMORY;
}
}
if (username) {
len = strlen(username);
_uname = (char*)malloc(len*sizeof(char)+1);
if (_uname) {
memcpy(_uname, username, len);
} else {
return NSAPI_ERROR_NO_MEMORY;
}
}
if (password) {
len = strlen(password);
_pwd = (char*)malloc(len*sizeof(char)+1);
if (_pwd) {
memcpy(_pwd, password, len);
} else {
return NSAPI_ERROR_NO_MEMORY;
}
}
return NSAPI_ERROR_OK;
}
@ -73,9 +113,11 @@ nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn,
nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn,
AuthenticationType type, const char *username, const char *password)
{
strncpy(_apn, apn, MAX_ACCESSPOINT_NAME_LENGTH);
_uname = username;
_pwd = password;
nsapi_error_t err = set_credentials(apn, username, password);
if (err) {
return err;
}
_authentication_type = type;
return NSAPI_ERROR_OK;
@ -84,9 +126,10 @@ nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn,
nsapi_error_t AT_CellularNetwork::connect(const char *apn,
const char *username, const char *password)
{
strncpy(_apn, apn, MAX_ACCESSPOINT_NAME_LENGTH);
_uname = username;
_pwd = password;
nsapi_error_t err = set_credentials(apn, username, password);
if (err) {
return err;
}
return connect();
}
@ -335,7 +378,7 @@ bool AT_CellularNetwork::get_context(nsapi_ip_stack_t requested_stack)
_at.resp_start("+CGDCONT:");
_cid = -1;
int cid_max = 0; // needed when creating new context
char apn[MAX_ACCESSPOINT_NAME_LENGTH] = {0};
char apn[MAX_ACCESSPOINT_NAME_LENGTH];
int apn_len = 0;
while (_at.info_resp()) {
@ -348,7 +391,7 @@ bool AT_CellularNetwork::get_context(nsapi_ip_stack_t requested_stack)
if (pdp_type_len > 0) {
apn_len = _at.read_string(apn, sizeof(apn) - 1);
if (apn_len >= 0) {
if (strlen(_apn) && strcmp(apn, _apn) != 0 ) {
if (_apn && strcmp(apn, _apn) != 0 ) {
continue;
}
nsapi_ip_stack_t pdp_stack = string_to_stack_type(pdp_type_from_context);
@ -390,8 +433,13 @@ bool AT_CellularNetwork::get_context(nsapi_ip_stack_t requested_stack)
}
// save the apn
if (apn_len > 0 && !strlen(_apn)) {
strncpy(_apn, apn, MAX_ACCESSPOINT_NAME_LENGTH);
if (apn_len > 0 && !_apn) {
_apn = (char*)malloc(apn_len*sizeof(char)+1);
if (_apn) {
memcpy(_apn, apn, apn_len);
} else {
return false;
}
}
tr_debug("Context id %d", _cid);
@ -591,7 +639,7 @@ nsapi_error_t AT_CellularNetwork::get_backoff_time(int &backoffTime)
_at.lock();
// If apn is set
if (strlen(_apn)) {
if (_apn) {
_at.cmd_start("AT+CABTRDP=");
_at.write_string(_apn);
_at.cmd_stop();

View File

@ -38,6 +38,8 @@ public:
AT_CellularNetwork(ATHandler &atHandler);
virtual ~AT_CellularNetwork();
// declare friend so it can access stack
friend class AT_CellularDevice;
public: // NetworkInterface
@ -84,6 +86,7 @@ public: // NetworkInterface
*/
virtual nsapi_error_t disconnect();
protected:
/** Provide access to the NetworkStack object
*
* @return The underlying NetworkStack object
@ -290,6 +293,8 @@ private:
nsapi_error_t set_context_to_be_activated();
nsapi_ip_stack_t string_to_stack_type(const char* pdp_type);
void free_credentials();
nsapi_error_t open_data_channel();
bool get_context(nsapi_ip_stack_t supported_stack);
bool set_new_context(nsapi_ip_stack_t stack, int cid);
@ -300,9 +305,9 @@ private:
protected:
NetworkStack *_stack;
char _apn[MAX_ACCESSPOINT_NAME_LENGTH];
const char *_uname;
const char *_pwd;
char *_apn;
char *_uname;
char *_pwd;
nsapi_ip_stack_t _ip_stack_type_requested;
nsapi_ip_stack_t _ip_stack_type;
int _cid;