Skip to content

Commit e4956ce

Browse files
author
Teppo Järvelin
committed
Cellular: added setting of data carrier support for UART.
1 parent 60fe3c5 commit e4956ce

File tree

13 files changed

+137
-16
lines changed

13 files changed

+137
-16
lines changed

UNITTESTS/features/cellular/framework/AT/at_cellularcontext/unittest.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ set(unittest-test-sources
3636
stubs/randLIB_stub.cpp
3737
stubs/Semaphore_stub.cpp
3838
stubs/us_ticker_stub.cpp
39+
stubs/UARTSerial_stub.cpp
40+
stubs/SerialBase_stub.cpp
3941
)

UNITTESTS/stubs/AT_CellularContext_stub.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ AT_CellularContext::~AT_CellularContext()
4242
{
4343
}
4444

45+
void AT_CellularContext::set_file_handle(UARTSerial *serial, PinName dcd_pin, bool active_high)
46+
{
47+
}
48+
49+
void AT_CellularContext::enable_hup(bool enable)
50+
{
51+
}
52+
4553
void AT_CellularContext::set_file_handle(FileHandle *fh)
4654
{
4755
}

UNITTESTS/stubs/AT_CellularDevice_stub.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ void AT_CellularDevice::release_at_handler(ATHandler *at_handler)
4444
{
4545
}
4646

47-
CellularContext *create_context(FileHandle *fh = NULL, const char *apn = MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN)
47+
CellularContext *AT_CellularDevice::create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
48+
bool active_high)
49+
{
50+
}
51+
52+
CellularContext *create_context(FileHandle *fh, const char *apn)
4853
{
4954
}
5055

UNITTESTS/target_h/myCellularDevice.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ class myCellularDevice : public CellularDevice {
5252
return NSAPI_ERROR_OK;
5353
}
5454

55+
virtual CellularContext *create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
56+
bool active_high)
57+
{
58+
return NULL;
59+
}
60+
5561
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL)
5662
{
5763
EventQueue que;

features/cellular/framework/API/CellularContext.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ class CellularContext : public CellularBase {
101101
// friend of CellularDevice so that it's the only way to close/delete this class.
102102
friend class CellularDevice;
103103
virtual ~CellularContext() {}
104-
105104
public: // from NetworkInterface
106105
virtual nsapi_error_t set_blocking(bool blocking) = 0;
107106
virtual NetworkStack *get_stack() = 0;
@@ -211,6 +210,15 @@ class CellularContext : public CellularBase {
211210
*/
212211
virtual void set_file_handle(FileHandle *fh) = 0;
213212

213+
/** Set the UART serial used to communicate with the modem. Can be used to change default file handle.
214+
* File handle set with this method will use data carrier detect to be able to detect disconnection much faster in PPP mode.
215+
*
216+
* @param serial UARTSerial used in communication to modem. If null then the default file handle is used.
217+
* @param dcd_pin Pin used to set data carrier detect on/off for the given UART
218+
* @param active_high a boolean set to true if DCD polarity is active low
219+
*/
220+
virtual void set_file_handle(UARTSerial *serial, PinName dcd_pin = NC, bool active_high = false) = 0;
221+
214222
protected: // Device specific implementations might need these so protected
215223
enum ContextOperation {
216224
OP_INVALID = -1,
@@ -230,6 +238,15 @@ class CellularContext : public CellularBase {
230238
*/
231239
virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr) = 0;
232240

241+
/** Enable or disable hang-up detection
242+
*
243+
* When in PPP data pump mode, it is helpful if the FileHandle will signal hang-up via
244+
* POLLHUP, e.g., if the DCD line is deasserted on a UART. During command mode, this
245+
* signaling is not desired. enable_hup() controls whether this function should be
246+
* active.
247+
*/
248+
virtual void enable_hup(bool enable) = 0;
249+
233250
// member variables needed in target override methods
234251
NetworkStack *_stack; // must be pointer because of PPP
235252
nsapi_ip_stack_t _ip_stack_type;
@@ -244,6 +261,8 @@ class CellularContext : public CellularBase {
244261
const char *_apn;
245262
const char *_uname;
246263
const char *_pwd;
264+
PinName _dcd_pin;
265+
bool _active_high;
247266
};
248267

249268
} // namespace mbed

features/cellular/framework/API/CellularDevice.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "CellularTargets.h"
2222
#include "CellularStateMachine.h"
2323
#include "Callback.h"
24+
#include "UARTSerial.h"
2425

2526
namespace mbed {
2627

@@ -29,7 +30,6 @@ class CellularSMS;
2930
class CellularInformation;
3031
class CellularNetwork;
3132
class CellularContext;
32-
class FileHandle;
3333

3434
const int MAX_PIN_SIZE = 8;
3535
const int MAX_PLMN_SIZE = 16;
@@ -96,6 +96,21 @@ class CellularDevice {
9696
*/
9797
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL) = 0;
9898

99+
/** Creates a new CellularContext interface. This API should be used if serial is UART and PPP mode used.
100+
* CellularContext created will use data carrier detect to be able to detect disconnection much faster in PPP mode.
101+
* UARTSerial usually is the same which was given for the CellularDevice.
102+
*
103+
* @param serial UARTSerial used in communication to modem. If null then the default file handle is used.
104+
* @param apn access point to use with context, can be null.
105+
* @param dcd_pin Pin used to set data carrier detect on/off for the given UART
106+
* @param active_high a boolean set to true if DCD polarity is active low
107+
*
108+
* @return new instance of class CellularContext or NULL in case of failure
109+
*
110+
*/
111+
virtual CellularContext *create_context(UARTSerial *serial, const char *apn, PinName dcd_pin = NC,
112+
bool active_high = false) = 0;
113+
99114
/** Deletes the given CellularContext instance
100115
*
101116
* @param context CellularContext to delete
@@ -107,6 +122,12 @@ class CellularDevice {
107122
*/
108123
void stop();
109124

125+
/** Get the current FileHandle item used when communicating with the modem.
126+
*
127+
* @return reference to FileHandle
128+
*/
129+
FileHandle &get_file_handle() const;
130+
110131
/** Get event queue that can be chained to main event queue.
111132
* @return event queue
112133
*/

features/cellular/framework/AT/ATHandler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ void ATHandler::set_file_handle(FileHandle *fh)
158158
void ATHandler::set_is_filehandle_usable(bool usable)
159159
{
160160
_is_fh_usable = usable;
161+
if (usable) {
162+
// set file handle sigio and blocking mode back
163+
set_file_handle(_fileHandle);
164+
}
161165
}
162166

163167
nsapi_error_t ATHandler::set_urc_handler(const char *prefix, mbed::Callback<void()> callback)

features/cellular/framework/AT/AT_CellularContext.cpp

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co
5959
_cid = -1;
6060
_new_context_set = false;
6161
_next = NULL;
62+
_dcd_pin = NC;
63+
_active_high = false;
6264
}
6365

6466
AT_CellularContext::~AT_CellularContext()
6567
{
66-
tr_info("Delete CellularContext %s (%p)", _apn ? _apn : "", this);
68+
tr_info("Delete CellularContext with apn: [%s] (%p)", _apn ? _apn : "", this);
6769

6870
(void)disconnect();
6971

@@ -79,6 +81,23 @@ void AT_CellularContext::set_file_handle(FileHandle *fh)
7981
_at.set_file_handle(_fh);
8082
}
8183

84+
void AT_CellularContext::set_file_handle(UARTSerial *serial, PinName dcd_pin, bool active_high)
85+
{
86+
tr_info("CellularContext serial %p", serial);
87+
_dcd_pin = dcd_pin;
88+
_active_high = active_high;
89+
_fh = serial;
90+
_at.set_file_handle(static_cast<FileHandle *>(serial));
91+
enable_hup(false);
92+
}
93+
94+
void AT_CellularContext::enable_hup(bool enable)
95+
{
96+
if (_dcd_pin != NC) {
97+
static_cast<UARTSerial *>(_fh)->set_data_carrier_detect(enable ? _dcd_pin : NC, _active_high);
98+
}
99+
}
100+
82101
nsapi_error_t AT_CellularContext::connect()
83102
{
84103
tr_info("CellularContext connect");
@@ -592,18 +611,25 @@ nsapi_error_t AT_CellularContext::open_data_channel()
592611
}
593612

594613
_at.set_is_filehandle_usable(false);
595-
614+
enable_hup(true);
596615
/* Initialize PPP
597616
* If blocking: mbed_ppp_init() is a blocking call, it will block until
598617
connected, or timeout after 30 seconds*/
599-
return nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularContext::ppp_status_cb), _uname, _pwd, _ip_stack_type);
618+
nsapi_error_t err = nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularContext::ppp_status_cb), _uname, _pwd, _ip_stack_type);
619+
if (err) {
620+
ppp_disconnected();
621+
}
622+
623+
return err;
600624
}
601625

602626
void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
603627
{
604628
tr_debug("ppp_status_cb: event %d, ptr %d", ev, ptr);
605629
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_GLOBAL_UP) {
606630
_is_connected = true;
631+
} else if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_DISCONNECTED) {
632+
ppp_disconnected();
607633
} else {
608634
_is_connected = false;
609635
}
@@ -614,6 +640,20 @@ void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
614640
_device->cellular_callback(ev, ptr);
615641
}
616642

643+
void AT_CellularContext::ppp_disconnected()
644+
{
645+
enable_hup(false);
646+
647+
// after ppp disconnect if we wan't to use same at handler we need to set filehandle again to athandler so it
648+
// will set the correct sigio and nonblocking
649+
_at.lock();
650+
_at.set_is_filehandle_usable(true);
651+
if (!_at.sync(AT_SYNC_TIMEOUT)) { // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
652+
tr_error("AT sync failed after PPP Disconnect");
653+
}
654+
_at.unlock();
655+
}
656+
617657
#endif //#if NSAPI_PPP_AVAILABLE
618658

619659
nsapi_error_t AT_CellularContext::disconnect()
@@ -628,15 +668,7 @@ nsapi_error_t AT_CellularContext::disconnect()
628668
tr_error("CellularContext disconnect failed!");
629669
// continue even in failure due to ppp disconnect in any case releases filehandle
630670
}
631-
// after ppp disconnect if we wan't to use same at handler we need to set filehandle again to athandler so it
632-
// will set the correct sigio and nonblocking
633-
_at.lock();
634-
_at.set_file_handle(_at.get_file_handle());
635-
_at.set_is_filehandle_usable(true);
636-
if (!_at.sync(AT_SYNC_TIMEOUT)) { // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
637-
tr_error("AT sync failed after PPP Disconnect");
638-
}
639-
_at.unlock();
671+
ppp_disconnected();
640672
#endif // NSAPI_PPP_AVAILABLE
641673
_at.lock();
642674

features/cellular/framework/AT/AT_CellularContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class AT_CellularContext : public CellularContext, public AT_CellularBase {
5757
virtual nsapi_error_t register_to_network();
5858
virtual nsapi_error_t attach_to_network();
5959
virtual void set_file_handle(FileHandle *fh);
60+
virtual void set_file_handle(UARTSerial *serial, PinName dcd_pin = NC, bool active_high = false);
61+
virtual void enable_hup(bool enable);
6062

6163
protected:
6264
virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr);
@@ -99,6 +101,7 @@ class AT_CellularContext : public CellularContext, public AT_CellularBase {
99101
#if NSAPI_PPP_AVAILABLE
100102
nsapi_error_t open_data_channel();
101103
void ppp_status_cb(nsapi_event_t ev, intptr_t ptr);
104+
void ppp_disconnected();
102105
#endif // #if NSAPI_PPP_AVAILABLE
103106
nsapi_error_t do_activate_context();
104107
bool set_new_context(int cid);

features/cellular/framework/AT/AT_CellularDevice.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,17 @@ CellularContext *AT_CellularDevice::get_context_list() const
197197
return _context_list;
198198
}
199199

200+
CellularContext *AT_CellularDevice::create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
201+
bool active_high)
202+
{
203+
// Call FileHandle base version - explict upcast to avoid recursing into ourselves
204+
CellularContext *ctx = create_context(static_cast<FileHandle *>(serial), apn);
205+
if (serial) {
206+
ctx->set_file_handle(serial, dcd_pin, active_high);
207+
}
208+
return ctx;
209+
}
210+
200211
CellularContext *AT_CellularDevice::create_context(FileHandle *fh, const char *apn)
201212
{
202213
ATHandler *atHandler = get_at_handler(fh);

features/cellular/framework/AT/AT_CellularDevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class AT_CellularDevice : public CellularDevice {
4646

4747
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL);
4848

49+
virtual CellularContext *create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin = NC, bool active_high = false);
50+
4951
virtual void delete_context(CellularContext *context);
5052

5153
virtual CellularNetwork *open_network(FileHandle *fh = NULL);

features/cellular/framework/device/CellularContext.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ MBED_WEAK CellularContext *CellularContext::get_default_instance()
2626
return NULL;
2727
}
2828
static CellularContext *context = dev->create_context();
29+
#if defined(MDMDCD) && defined(MDM_PIN_POLARITY)
30+
context->set_file_handle(static_cast<UARTSerial *>(&dev->get_file_handle()), MDMDCD, MDM_PIN_POLARITY);
31+
#endif // #if defined(MDMDCD) && defined(MDM_PIN_POLARITY)
2932
return context;
3033
}
3134
#else

features/cellular/framework/device/CellularDevice.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "CellularLog.h"
2222
#include "CellularTargets.h"
2323
#include "EventQueue.h"
24-
#include "UARTSerial.h"
2524

2625
#ifdef CELLULAR_DEVICE
2726
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
@@ -52,6 +51,7 @@ MBED_WEAK CellularDevice *CellularDevice::get_default_instance()
5251
CellularDevice::CellularDevice(FileHandle *fh) : _network_ref_count(0), _sms_ref_count(0), _power_ref_count(0),
5352
_info_ref_count(0), _fh(fh), _queue(5 * EVENTS_EVENT_SIZE), _state_machine(0), _nw(0), _status_cb(0)
5453
{
54+
MBED_ASSERT(fh);
5555
set_sim_pin(NULL);
5656
set_plmn(NULL);
5757
}
@@ -66,6 +66,11 @@ void CellularDevice::stop()
6666
_state_machine->stop();
6767
}
6868

69+
FileHandle &CellularDevice::get_file_handle() const
70+
{
71+
return *_fh;
72+
}
73+
6974
events::EventQueue *CellularDevice::get_queue()
7075
{
7176
return &_queue;

0 commit comments

Comments
 (0)