Cellular: added setting of data carrier support for UART.

pull/9472/head
Teppo Järvelin 2018-12-04 14:58:59 +02:00 committed by Ari Parkkila
parent 725e14d15f
commit 84e5013a2d
13 changed files with 137 additions and 15 deletions

View File

@ -38,4 +38,6 @@ set(unittest-test-sources
stubs/randLIB_stub.cpp
stubs/Semaphore_stub.cpp
stubs/us_ticker_stub.cpp
stubs/UARTSerial_stub.cpp
stubs/SerialBase_stub.cpp
)

View File

@ -42,6 +42,14 @@ AT_CellularContext::~AT_CellularContext()
{
}
void AT_CellularContext::set_file_handle(UARTSerial *serial, PinName dcd_pin, bool active_high)
{
}
void AT_CellularContext::enable_hup(bool enable)
{
}
void AT_CellularContext::set_file_handle(FileHandle *fh)
{
}

View File

@ -64,7 +64,12 @@ nsapi_error_t AT_CellularDevice::release_at_handler(ATHandler *at_handler)
}
}
CellularContext *create_context(FileHandle *fh = NULL, const char *apn = MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN)
CellularContext *AT_CellularDevice::create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
bool active_high)
{
}
CellularContext *create_context(FileHandle *fh, const char *apn)
{
}

View File

@ -52,6 +52,12 @@ public:
return NSAPI_ERROR_OK;
}
virtual CellularContext *create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
bool active_high)
{
return NULL;
}
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL)
{
EventQueue que;

View File

@ -107,7 +107,6 @@ protected:
// friend of CellularDevice, so it's the only way to close or delete this class.
friend class CellularDevice;
virtual ~CellularContext() {}
public: // from NetworkInterface
virtual nsapi_error_t set_blocking(bool blocking) = 0;
virtual NetworkStack *get_stack() = 0;
@ -227,6 +226,15 @@ public: // from NetworkInterface
*/
virtual void set_file_handle(FileHandle *fh) = 0;
/** Set the UART serial used to communicate with the modem. Can be used to change default file handle.
* File handle set with this method will use data carrier detect to be able to detect disconnection much faster in PPP mode.
*
* @param serial UARTSerial used in communication to modem. If null then the default file handle is used.
* @param dcd_pin Pin used to set data carrier detect on/off for the given UART
* @param active_high a boolean set to true if DCD polarity is active low
*/
virtual void set_file_handle(UARTSerial *serial, PinName dcd_pin = NC, bool active_high = false) = 0;
protected: // Device specific implementations might need these so protected
enum ContextOperation {
OP_INVALID = -1,
@ -245,6 +253,15 @@ protected: // Device specific implementations might need these so protected
*/
virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr) = 0;
/** Enable or disable hang-up detection
*
* When in PPP data pump mode, it is helpful if the FileHandle will signal hang-up via
* POLLHUP, e.g., if the DCD line is deasserted on a UART. During command mode, this
* signaling is not desired. enable_hup() controls whether this function should be
* active.
*/
virtual void enable_hup(bool enable) = 0;
// member variables needed in target override methods
NetworkStack *_stack; // must be pointer because of PPP
nsapi_ip_stack_t _ip_stack_type;
@ -259,6 +276,8 @@ protected: // Device specific implementations might need these so protected
const char *_apn;
const char *_uname;
const char *_pwd;
PinName _dcd_pin;
bool _active_high;
};
/**

View File

@ -22,6 +22,7 @@
#include "CellularStateMachine.h"
#include "Callback.h"
#include "ATHandler.h"
#include "UARTSerial.h"
namespace mbed {
@ -102,6 +103,21 @@ public:
*/
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL) = 0;
/** Creates a new CellularContext interface. This API should be used if serial is UART and PPP mode used.
* CellularContext created will use data carrier detect to be able to detect disconnection much faster in PPP mode.
* UARTSerial usually is the same which was given for the CellularDevice.
*
* @param serial UARTSerial used in communication to modem. If null then the default file handle is used.
* @param apn access point to use with context, can be null.
* @param dcd_pin Pin used to set data carrier detect on/off for the given UART
* @param active_high a boolean set to true if DCD polarity is active low
*
* @return new instance of class CellularContext or NULL in case of failure
*
*/
virtual CellularContext *create_context(UARTSerial *serial, const char *apn, PinName dcd_pin = NC,
bool active_high = false) = 0;
/** Deletes the given CellularContext instance
*
* @param context CellularContext to delete
@ -113,6 +129,12 @@ public:
*/
void stop();
/** Get the current FileHandle item used when communicating with the modem.
*
* @return reference to FileHandle
*/
FileHandle &get_file_handle() const;
/** Get event queue that can be chained to main event queue.
* @return event queue
*/

View File

@ -154,6 +154,10 @@ void ATHandler::set_file_handle(FileHandle *fh)
void ATHandler::set_is_filehandle_usable(bool usable)
{
_is_fh_usable = usable;
if (usable) {
// set file handle sigio and blocking mode back
set_file_handle(_fileHandle);
}
}
void ATHandler::set_urc_handler(const char *prefix, Callback<void()> callback)

View File

@ -59,11 +59,13 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co
_cid = -1;
_new_context_set = false;
_next = NULL;
_dcd_pin = NC;
_active_high = false;
}
AT_CellularContext::~AT_CellularContext()
{
tr_info("Delete CellularContext %s (%p)", _apn ? _apn : "", this);
tr_info("Delete CellularContext with apn: [%s] (%p)", _apn ? _apn : "", this);
(void)disconnect();
@ -79,6 +81,23 @@ void AT_CellularContext::set_file_handle(FileHandle *fh)
_at.set_file_handle(_fh);
}
void AT_CellularContext::set_file_handle(UARTSerial *serial, PinName dcd_pin, bool active_high)
{
tr_info("CellularContext serial %p", serial);
_dcd_pin = dcd_pin;
_active_high = active_high;
_fh = serial;
_at.set_file_handle(static_cast<FileHandle *>(serial));
enable_hup(false);
}
void AT_CellularContext::enable_hup(bool enable)
{
if (_dcd_pin != NC) {
static_cast<UARTSerial *>(_fh)->set_data_carrier_detect(enable ? _dcd_pin : NC, _active_high);
}
}
nsapi_error_t AT_CellularContext::connect()
{
tr_info("CellularContext connect");
@ -595,11 +614,16 @@ nsapi_error_t AT_CellularContext::open_data_channel()
}
_at.set_is_filehandle_usable(false);
enable_hup(true);
/* Initialize PPP
* If blocking: mbed_ppp_init() is a blocking call, it will block until
connected, or timeout after 30 seconds*/
return nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularContext::ppp_status_cb), _uname, _pwd, _ip_stack_type);
nsapi_error_t err = nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularContext::ppp_status_cb), _uname, _pwd, _ip_stack_type);
if (err) {
ppp_disconnected();
}
return err;
}
void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
@ -607,6 +631,8 @@ void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
tr_debug("ppp_status_cb: event %d, ptr %d", ev, ptr);
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_GLOBAL_UP) {
_is_connected = true;
} else if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_DISCONNECTED) {
ppp_disconnected();
} else {
_is_connected = false;
}
@ -617,6 +643,20 @@ void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
_device->cellular_callback(ev, ptr);
}
void AT_CellularContext::ppp_disconnected()
{
enable_hup(false);
// after ppp disconnect if we wan't to use same at handler we need to set filehandle again to athandler so it
// will set the correct sigio and nonblocking
_at.lock();
_at.set_is_filehandle_usable(true);
if (!_at.sync(AT_SYNC_TIMEOUT)) { // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
tr_error("AT sync failed after PPP Disconnect");
}
_at.unlock();
}
#endif //#if NSAPI_PPP_AVAILABLE
nsapi_error_t AT_CellularContext::disconnect()
@ -631,15 +671,7 @@ nsapi_error_t AT_CellularContext::disconnect()
tr_error("CellularContext disconnect failed!");
// continue even in failure due to ppp disconnect in any case releases filehandle
}
// after ppp disconnect if we wan't to use same at handler we need to set filehandle again to athandler so it
// will set the correct sigio and nonblocking
_at.lock();
_at.set_file_handle(_at.get_file_handle());
_at.set_is_filehandle_usable(true);
if (!_at.sync(AT_SYNC_TIMEOUT)) { // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
tr_error("AT sync failed after PPP Disconnect");
}
_at.unlock();
ppp_disconnected();
#endif // NSAPI_PPP_AVAILABLE
_at.lock();

View File

@ -57,6 +57,8 @@ public:
virtual nsapi_error_t register_to_network();
virtual nsapi_error_t attach_to_network();
virtual void set_file_handle(FileHandle *fh);
virtual void set_file_handle(UARTSerial *serial, PinName dcd_pin = NC, bool active_high = false);
virtual void enable_hup(bool enable);
protected:
virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr);
@ -93,6 +95,7 @@ private:
#if NSAPI_PPP_AVAILABLE
nsapi_error_t open_data_channel();
void ppp_status_cb(nsapi_event_t ev, intptr_t ptr);
void ppp_disconnected();
#endif // #if NSAPI_PPP_AVAILABLE
nsapi_error_t do_activate_context();
bool set_new_context(int cid);

View File

@ -167,6 +167,17 @@ CellularContext *AT_CellularDevice::get_context_list() const
return _context_list;
}
CellularContext *AT_CellularDevice::create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
bool active_high)
{
// Call FileHandle base version - explict upcast to avoid recursing into ourselves
CellularContext *ctx = create_context(static_cast<FileHandle *>(serial), apn);
if (serial) {
ctx->set_file_handle(serial, dcd_pin, active_high);
}
return ctx;
}
CellularContext *AT_CellularDevice::create_context(FileHandle *fh, const char *apn)
{
AT_CellularContext *ctx = create_context_impl(*get_at_handler(fh), apn);

View File

@ -46,6 +46,8 @@ public:
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL);
virtual CellularContext *create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin = NC, bool active_high = false);
virtual void delete_context(CellularContext *context);
virtual CellularNetwork *open_network(FileHandle *fh = NULL);

View File

@ -26,6 +26,9 @@ MBED_WEAK CellularContext *CellularContext::get_default_instance()
return NULL;
}
static CellularContext *context = dev->create_context();
#if defined(MDMDCD) && defined(MDM_PIN_POLARITY)
context->set_file_handle(static_cast<UARTSerial *>(&dev->get_file_handle()), MDMDCD, MDM_PIN_POLARITY);
#endif // #if defined(MDMDCD) && defined(MDM_PIN_POLARITY)
return context;
}
#else

View File

@ -21,7 +21,6 @@
#include "CellularLog.h"
#include "CellularTargets.h"
#include "EventQueue.h"
#include "UARTSerial.h"
#ifdef CELLULAR_DEVICE
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
@ -52,6 +51,7 @@ MBED_WEAK CellularDevice *CellularDevice::get_default_instance()
CellularDevice::CellularDevice(FileHandle *fh) : _network_ref_count(0), _sms_ref_count(0), _power_ref_count(0),
_info_ref_count(0), _fh(fh), _queue(5 * EVENTS_EVENT_SIZE), _state_machine(0), _nw(0), _status_cb(0)
{
MBED_ASSERT(fh);
set_sim_pin(NULL);
set_plmn(NULL);
}
@ -66,6 +66,11 @@ void CellularDevice::stop()
_state_machine->stop();
}
FileHandle &CellularDevice::get_file_handle() const
{
return *_fh;
}
events::EventQueue *CellularDevice::get_queue()
{
return &_queue;