mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Cellular: added setting of data carrier support for UART.
							parent
							
								
									725e14d15f
								
							
						
					
					
						commit
						84e5013a2d
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
     */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue