Skip to content

Commit 84e5013

Browse files
Teppo JärvelinAri Parkkila
authored andcommitted
Cellular: added setting of data carrier support for UART.
1 parent 725e14d commit 84e5013

File tree

13 files changed

+137
-15
lines changed

13 files changed

+137
-15
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
@@ -38,4 +38,6 @@ set(unittest-test-sources
3838
stubs/randLIB_stub.cpp
3939
stubs/Semaphore_stub.cpp
4040
stubs/us_ticker_stub.cpp
41+
stubs/UARTSerial_stub.cpp
42+
stubs/SerialBase_stub.cpp
4143
)

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
@@ -64,7 +64,12 @@ nsapi_error_t AT_CellularDevice::release_at_handler(ATHandler *at_handler)
6464
}
6565
}
6666

67-
CellularContext *create_context(FileHandle *fh = NULL, const char *apn = MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN)
67+
CellularContext *AT_CellularDevice::create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
68+
bool active_high)
69+
{
70+
}
71+
72+
CellularContext *create_context(FileHandle *fh, const char *apn)
6873
{
6974
}
7075

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
@@ -107,7 +107,6 @@ class CellularContext : public CellularBase {
107107
// friend of CellularDevice, so it's the only way to close or delete this class.
108108
friend class CellularDevice;
109109
virtual ~CellularContext() {}
110-
111110
public: // from NetworkInterface
112111
virtual nsapi_error_t set_blocking(bool blocking) = 0;
113112
virtual NetworkStack *get_stack() = 0;
@@ -227,6 +226,15 @@ class CellularContext : public CellularBase {
227226
*/
228227
virtual void set_file_handle(FileHandle *fh) = 0;
229228

229+
/** Set the UART serial used to communicate with the modem. Can be used to change default file handle.
230+
* File handle set with this method will use data carrier detect to be able to detect disconnection much faster in PPP mode.
231+
*
232+
* @param serial UARTSerial used in communication to modem. If null then the default file handle is used.
233+
* @param dcd_pin Pin used to set data carrier detect on/off for the given UART
234+
* @param active_high a boolean set to true if DCD polarity is active low
235+
*/
236+
virtual void set_file_handle(UARTSerial *serial, PinName dcd_pin = NC, bool active_high = false) = 0;
237+
230238
protected: // Device specific implementations might need these so protected
231239
enum ContextOperation {
232240
OP_INVALID = -1,
@@ -245,6 +253,15 @@ class CellularContext : public CellularBase {
245253
*/
246254
virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr) = 0;
247255

256+
/** Enable or disable hang-up detection
257+
*
258+
* When in PPP data pump mode, it is helpful if the FileHandle will signal hang-up via
259+
* POLLHUP, e.g., if the DCD line is deasserted on a UART. During command mode, this
260+
* signaling is not desired. enable_hup() controls whether this function should be
261+
* active.
262+
*/
263+
virtual void enable_hup(bool enable) = 0;
264+
248265
// member variables needed in target override methods
249266
NetworkStack *_stack; // must be pointer because of PPP
250267
nsapi_ip_stack_t _ip_stack_type;
@@ -259,6 +276,8 @@ class CellularContext : public CellularBase {
259276
const char *_apn;
260277
const char *_uname;
261278
const char *_pwd;
279+
PinName _dcd_pin;
280+
bool _active_high;
262281
};
263282

264283
/**

features/cellular/framework/API/CellularDevice.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "CellularStateMachine.h"
2323
#include "Callback.h"
2424
#include "ATHandler.h"
25+
#include "UARTSerial.h"
2526

2627
namespace mbed {
2728

@@ -102,6 +103,21 @@ class CellularDevice {
102103
*/
103104
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL) = 0;
104105

106+
/** Creates a new CellularContext interface. This API should be used if serial is UART and PPP mode used.
107+
* CellularContext created will use data carrier detect to be able to detect disconnection much faster in PPP mode.
108+
* UARTSerial usually is the same which was given for the CellularDevice.
109+
*
110+
* @param serial UARTSerial used in communication to modem. If null then the default file handle is used.
111+
* @param apn access point to use with context, can be null.
112+
* @param dcd_pin Pin used to set data carrier detect on/off for the given UART
113+
* @param active_high a boolean set to true if DCD polarity is active low
114+
*
115+
* @return new instance of class CellularContext or NULL in case of failure
116+
*
117+
*/
118+
virtual CellularContext *create_context(UARTSerial *serial, const char *apn, PinName dcd_pin = NC,
119+
bool active_high = false) = 0;
120+
105121
/** Deletes the given CellularContext instance
106122
*
107123
* @param context CellularContext to delete
@@ -113,6 +129,12 @@ class CellularDevice {
113129
*/
114130
void stop();
115131

132+
/** Get the current FileHandle item used when communicating with the modem.
133+
*
134+
* @return reference to FileHandle
135+
*/
136+
FileHandle &get_file_handle() const;
137+
116138
/** Get event queue that can be chained to main event queue.
117139
* @return event queue
118140
*/

features/cellular/framework/AT/ATHandler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ void ATHandler::set_file_handle(FileHandle *fh)
154154
void ATHandler::set_is_filehandle_usable(bool usable)
155155
{
156156
_is_fh_usable = usable;
157+
if (usable) {
158+
// set file handle sigio and blocking mode back
159+
set_file_handle(_fileHandle);
160+
}
157161
}
158162

159163
void ATHandler::set_urc_handler(const char *prefix, 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");
@@ -595,18 +614,25 @@ nsapi_error_t AT_CellularContext::open_data_channel()
595614
}
596615

597616
_at.set_is_filehandle_usable(false);
598-
617+
enable_hup(true);
599618
/* Initialize PPP
600619
* If blocking: mbed_ppp_init() is a blocking call, it will block until
601620
connected, or timeout after 30 seconds*/
602-
return nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularContext::ppp_status_cb), _uname, _pwd, _ip_stack_type);
621+
nsapi_error_t err = nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularContext::ppp_status_cb), _uname, _pwd, _ip_stack_type);
622+
if (err) {
623+
ppp_disconnected();
624+
}
625+
626+
return err;
603627
}
604628

605629
void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
606630
{
607631
tr_debug("ppp_status_cb: event %d, ptr %d", ev, ptr);
608632
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_GLOBAL_UP) {
609633
_is_connected = true;
634+
} else if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_DISCONNECTED) {
635+
ppp_disconnected();
610636
} else {
611637
_is_connected = false;
612638
}
@@ -617,6 +643,20 @@ void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
617643
_device->cellular_callback(ev, ptr);
618644
}
619645

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

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

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);
@@ -93,6 +95,7 @@ class AT_CellularContext : public CellularContext, public AT_CellularBase {
9395
#if NSAPI_PPP_AVAILABLE
9496
nsapi_error_t open_data_channel();
9597
void ppp_status_cb(nsapi_event_t ev, intptr_t ptr);
98+
void ppp_disconnected();
9699
#endif // #if NSAPI_PPP_AVAILABLE
97100
nsapi_error_t do_activate_context();
98101
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
@@ -167,6 +167,17 @@ CellularContext *AT_CellularDevice::get_context_list() const
167167
return _context_list;
168168
}
169169

170+
CellularContext *AT_CellularDevice::create_context(UARTSerial *serial, const char *const apn, PinName dcd_pin,
171+
bool active_high)
172+
{
173+
// Call FileHandle base version - explict upcast to avoid recursing into ourselves
174+
CellularContext *ctx = create_context(static_cast<FileHandle *>(serial), apn);
175+
if (serial) {
176+
ctx->set_file_handle(serial, dcd_pin, active_high);
177+
}
178+
return ctx;
179+
}
180+
170181
CellularContext *AT_CellularDevice::create_context(FileHandle *fh, const char *apn)
171182
{
172183
AT_CellularContext *ctx = create_context_impl(*get_at_handler(fh), apn);

0 commit comments

Comments
 (0)