mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Major Refactoring & extensions
For keep supporting external APIs with the same name (supposedly there are a larger
number of users of those APIs), BufferedSerial and ATParser are being renamed.
BufferedSerial becomes UARTSerial, will complement a  future USBSerial etc.
ATParser becomes ATCmdParser.
* UARTSerial moves to /drivers
* APN_db.h is moved from platform to cellular/util/.
* Original CellularInterface is restored for backward compatability (again, supposedly there
  are users of that).
* A new file, CellularBase is added which will now servce as the base class for all
  upcoming drivers.
* Special restructuring for the driver has been undertaken. This makes a clear cut distinction
  between an on-board or an off-board implementation.
  	- PPPCellularInterface is a generic network interface that works with a generic FileHandle
          and PPP. A derived class is needed to pass that FileHandle.
        - PPPCellularInterface provides some base functionality like network registration, AT setup,
          PPP connection etc. Lower level job is delegated to the derived classes and various modem
          specific APIs are provided which are supposed to be overridden.
        - UARTCellularInterface is derived from PPPCellularInterface. It constructs a FileHandle and
          passes it back to PPPCellularInterface as well as provides modem hangupf functionality.
          In future we could proive a USBInterface that would derive from PPPCellularInterface and could
          pass the FileHandle back.
	- OnboardCellularInterface is derived from UARTCellularInterfae and provides hooks to
          the target provided implementation of onbard_modem_api.h. An off-board modem, i.e, a modem on
          a shield has to override the modem_init(), modem_power_up() etc as it cannot use
          onboard_modem_api.h.
			
			
				pull/4119/head
			
			
		
							parent
							
								
									b51fbe817b
								
							
						
					
					
						commit
						24de27c989
					
				| 
						 | 
				
			
			@ -17,68 +17,68 @@
 | 
			
		|||
#if DEVICE_SERIAL
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include "platform/BufferedSerial.h"
 | 
			
		||||
#include "UARTSerial.h"
 | 
			
		||||
#include "platform/mbed_poll.h"
 | 
			
		||||
#include "platform/mbed_wait_api.h"
 | 
			
		||||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
 | 
			
		||||
BufferedSerial::BufferedSerial(PinName tx, PinName rx, int baud) :
 | 
			
		||||
UARTSerial::UARTSerial(PinName tx, PinName rx, int baud) :
 | 
			
		||||
        SerialBase(tx, rx, baud),
 | 
			
		||||
        _blocking(true),
 | 
			
		||||
        _tx_irq_enabled(false),
 | 
			
		||||
        _dcd(NULL)
 | 
			
		||||
        _dcd_irq(NULL)
 | 
			
		||||
{
 | 
			
		||||
    /* Attatch IRQ routines to the serial device. */
 | 
			
		||||
    SerialBase::attach(callback(this, &BufferedSerial::rx_irq), RxIrq);
 | 
			
		||||
    SerialBase::attach(callback(this, &UARTSerial::rx_irq), RxIrq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BufferedSerial::~BufferedSerial()
 | 
			
		||||
UARTSerial::~UARTSerial()
 | 
			
		||||
{
 | 
			
		||||
    delete _dcd;
 | 
			
		||||
    delete _dcd_irq;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BufferedSerial::DCD_IRQ()
 | 
			
		||||
void UARTSerial::dcd_irq()
 | 
			
		||||
{
 | 
			
		||||
    wake();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BufferedSerial::set_data_carrier_detect(PinName DCD_pin, bool active_high)
 | 
			
		||||
void UARTSerial::set_data_carrier_detect(PinName dcd_pin, bool active_high)
 | 
			
		||||
{
 | 
			
		||||
    delete _dcd;
 | 
			
		||||
    _dcd = NULL;
 | 
			
		||||
     delete _dcd_irq;
 | 
			
		||||
    _dcd_irq = NULL;
 | 
			
		||||
 | 
			
		||||
    if (DCD_pin != NC) {
 | 
			
		||||
        _dcd = new InterruptIn(DCD_pin);
 | 
			
		||||
    if (dcd_pin != NC) {
 | 
			
		||||
        _dcd_irq = new InterruptIn(dcd_pin);
 | 
			
		||||
        if (active_high) {
 | 
			
		||||
            _dcd->fall(callback(this, &BufferedSerial::DCD_IRQ));
 | 
			
		||||
            _dcd_irq->fall(callback(this, &UARTSerial::dcd_irq));
 | 
			
		||||
        } else {
 | 
			
		||||
            _dcd->rise(callback(this, &BufferedSerial::DCD_IRQ));
 | 
			
		||||
            _dcd_irq->rise(callback(this, &UARTSerial::dcd_irq));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int BufferedSerial::close()
 | 
			
		||||
int UARTSerial::close()
 | 
			
		||||
{
 | 
			
		||||
    /* Does not let us pass a file descriptor. So how to close ?
 | 
			
		||||
     * Also, does it make sense to close a device type file descriptor*/
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int BufferedSerial::isatty()
 | 
			
		||||
int UARTSerial::isatty()
 | 
			
		||||
{
 | 
			
		||||
    return 1;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
off_t BufferedSerial::seek(off_t offset, int whence)
 | 
			
		||||
off_t UARTSerial::seek(off_t offset, int whence)
 | 
			
		||||
{
 | 
			
		||||
    /*XXX lseek can be done theoratically, but is it sane to mark positions on a dynamically growing/shrinking
 | 
			
		||||
     * buffer system (from an interrupt context) */
 | 
			
		||||
    return -ESPIPE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int BufferedSerial::sync()
 | 
			
		||||
int UARTSerial::sync()
 | 
			
		||||
{
 | 
			
		||||
    lock();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ int BufferedSerial::sync()
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BufferedSerial::sigio(Callback<void()> func) {
 | 
			
		||||
void UARTSerial::sigio(Callback<void()> func) {
 | 
			
		||||
    core_util_critical_section_enter();
 | 
			
		||||
    _sigio_cb = func;
 | 
			
		||||
    if (_sigio_cb) {
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ void BufferedSerial::sigio(Callback<void()> func) {
 | 
			
		|||
    core_util_critical_section_exit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ssize_t BufferedSerial::write(const void* buffer, size_t length)
 | 
			
		||||
ssize_t UARTSerial::write(const void* buffer, size_t length)
 | 
			
		||||
{
 | 
			
		||||
    size_t data_written = 0;
 | 
			
		||||
    const char *buf_ptr = static_cast<const char *>(buffer);
 | 
			
		||||
| 
						 | 
				
			
			@ -130,9 +130,9 @@ ssize_t BufferedSerial::write(const void* buffer, size_t length)
 | 
			
		|||
 | 
			
		||||
    core_util_critical_section_enter();
 | 
			
		||||
    if (!_tx_irq_enabled) {
 | 
			
		||||
        BufferedSerial::tx_irq();                // only write to hardware in one place
 | 
			
		||||
        UARTSerial::tx_irq();                // only write to hardware in one place
 | 
			
		||||
        if (!_txbuf.empty()) {
 | 
			
		||||
            SerialBase::attach(callback(this, &BufferedSerial::tx_irq), TxIrq);
 | 
			
		||||
            SerialBase::attach(callback(this, &UARTSerial::tx_irq), TxIrq);
 | 
			
		||||
            _tx_irq_enabled = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +143,7 @@ ssize_t BufferedSerial::write(const void* buffer, size_t length)
 | 
			
		|||
    return data_written;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ssize_t BufferedSerial::read(void* buffer, size_t length)
 | 
			
		||||
ssize_t UARTSerial::read(void* buffer, size_t length)
 | 
			
		||||
{
 | 
			
		||||
    size_t data_read = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -171,19 +171,19 @@ ssize_t BufferedSerial::read(void* buffer, size_t length)
 | 
			
		|||
    return data_read;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BufferedSerial::hup() const
 | 
			
		||||
bool UARTSerial::hup() const
 | 
			
		||||
{
 | 
			
		||||
    return _dcd && _dcd->read() != 0;
 | 
			
		||||
    return _dcd_irq && _dcd_irq->read() != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BufferedSerial::wake()
 | 
			
		||||
void UARTSerial::wake()
 | 
			
		||||
{
 | 
			
		||||
    if (_sigio_cb) {
 | 
			
		||||
        _sigio_cb();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
short BufferedSerial::poll(short events) const {
 | 
			
		||||
short UARTSerial::poll(short events) const {
 | 
			
		||||
 | 
			
		||||
    short revents = 0;
 | 
			
		||||
    /* Check the Circular Buffer if space available for writing out */
 | 
			
		||||
| 
						 | 
				
			
			@ -205,17 +205,17 @@ short BufferedSerial::poll(short events) const {
 | 
			
		|||
    return revents;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BufferedSerial::lock(void)
 | 
			
		||||
void UARTSerial::lock(void)
 | 
			
		||||
{
 | 
			
		||||
    _mutex.lock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BufferedSerial::unlock(void)
 | 
			
		||||
void UARTSerial::unlock(void)
 | 
			
		||||
{
 | 
			
		||||
    _mutex.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BufferedSerial::rx_irq(void)
 | 
			
		||||
void UARTSerial::rx_irq(void)
 | 
			
		||||
{
 | 
			
		||||
    bool was_empty = _rxbuf.empty();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +237,7 @@ void BufferedSerial::rx_irq(void)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// Also called from write to start transfer
 | 
			
		||||
void BufferedSerial::tx_irq(void)
 | 
			
		||||
void UARTSerial::tx_irq(void)
 | 
			
		||||
{
 | 
			
		||||
    bool was_full = _txbuf.full();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,198 @@
 | 
			
		|||
/* mbed Microcontroller Library
 | 
			
		||||
 * Copyright (c) 2006-2017 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef MBED_UARTSERIAL_H
 | 
			
		||||
#define MBED_UARTSERIAL_H
 | 
			
		||||
 | 
			
		||||
#include "platform/platform.h"
 | 
			
		||||
 | 
			
		||||
#if DEVICE_SERIAL
 | 
			
		||||
 | 
			
		||||
#include "FileHandle.h"
 | 
			
		||||
#include "SerialBase.h"
 | 
			
		||||
#include "InterruptIn.h"
 | 
			
		||||
#include "PlatformMutex.h"
 | 
			
		||||
#include "serial_api.h"
 | 
			
		||||
#include "CircularBuffer.h"
 | 
			
		||||
 | 
			
		||||
#ifndef MBED_CONF_DRIVERS_UART_SERIAL_RXBUF_SIZE
 | 
			
		||||
#define MBED_CONF_DRIVERS_UART_SERIAL_RXBUF_SIZE  256
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef MBED_CONF_DRIVERS_UART_SERIAL_TXBUF_SIZE
 | 
			
		||||
#define MBED_CONF_DRIVERS_UART_SERIAL_TXBUF_SIZE  256
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
 | 
			
		||||
class UARTSerial : private SerialBase, public FileHandle {
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    /** Create a UARTSerial port, connected to the specified transmit and receive pins, with a particular baud rate.
 | 
			
		||||
     *  @param tx Transmit pin
 | 
			
		||||
     *  @param rx Receive pin
 | 
			
		||||
     *  @param baud The baud rate of the serial port (optional, defaults to MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE)
 | 
			
		||||
     */
 | 
			
		||||
    UARTSerial(PinName tx, PinName rx, int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
 | 
			
		||||
    virtual ~UARTSerial();
 | 
			
		||||
 | 
			
		||||
    /** Equivalent to POSIX poll(). Derived from FileHandle.
 | 
			
		||||
     *  Provides a mechanism to multiplex input/output over a set of file handles.
 | 
			
		||||
     */
 | 
			
		||||
    virtual short poll(short events) const;
 | 
			
		||||
 | 
			
		||||
    /** Write the contents of a buffer to a file
 | 
			
		||||
     *
 | 
			
		||||
     *  @param buffer   The buffer to write from
 | 
			
		||||
     *  @param size     The number of bytes to write
 | 
			
		||||
     *  @return         The number of bytes written, negative error on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual ssize_t write(const void* buffer, size_t length);
 | 
			
		||||
 | 
			
		||||
    /** Read the contents of a file into a buffer
 | 
			
		||||
     *
 | 
			
		||||
     *  Follows POSIX semantics:
 | 
			
		||||
     *
 | 
			
		||||
     *  * if no data is available, and non-blocking set return -EAGAIN
 | 
			
		||||
     *  * if no data is available, and blocking set, wait until data is available
 | 
			
		||||
     *  * If any data is available, call returns immediately
 | 
			
		||||
     *
 | 
			
		||||
     *  @param buffer   The buffer to read in to
 | 
			
		||||
     *  @param size     The number of bytes to read
 | 
			
		||||
     *  @return         The number of bytes read, 0 at end of file, negative error on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual ssize_t read(void* buffer, size_t length);
 | 
			
		||||
 | 
			
		||||
    /** Acquire mutex */
 | 
			
		||||
    virtual void lock(void);
 | 
			
		||||
 | 
			
		||||
    /** Release mutex */
 | 
			
		||||
    virtual void unlock(void);
 | 
			
		||||
 | 
			
		||||
    /** Close a file
 | 
			
		||||
     *
 | 
			
		||||
     *  @return         0 on success, negative error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual int close();
 | 
			
		||||
 | 
			
		||||
    /** Check if the file in an interactive terminal device
 | 
			
		||||
     *
 | 
			
		||||
     *  @return         True if the file is a terminal
 | 
			
		||||
     *  @return         False if the file is not a terminal
 | 
			
		||||
     *  @return         Negative error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual int isatty();
 | 
			
		||||
 | 
			
		||||
    /** Move the file position to a given offset from from a given location
 | 
			
		||||
     *
 | 
			
		||||
     * Not valid for a device type FileHandle like UARTSerial.
 | 
			
		||||
     * In case of UARTSerial, returns ESPIPE
 | 
			
		||||
     *
 | 
			
		||||
     *  @param offset   The offset from whence to move to
 | 
			
		||||
     *  @param whence   The start of where to seek
 | 
			
		||||
     *      SEEK_SET to start from beginning of file,
 | 
			
		||||
     *      SEEK_CUR to start from current position in file,
 | 
			
		||||
     *      SEEK_END to start from end of file
 | 
			
		||||
     *  @return         The new offset of the file, negative error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual off_t seek(off_t offset, int whence);
 | 
			
		||||
 | 
			
		||||
    /** Flush any buffers associated with the file
 | 
			
		||||
     *
 | 
			
		||||
     *  @return         0 on success, negative error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual int sync();
 | 
			
		||||
 | 
			
		||||
    /** Set blocking or non-blocking mode
 | 
			
		||||
     *  The default is blocking.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param blocking true for blocking mode, false for non-blocking mode.
 | 
			
		||||
     */
 | 
			
		||||
    virtual int set_blocking(bool blocking)
 | 
			
		||||
    {
 | 
			
		||||
        _blocking = blocking;
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Register a callback on state change of the file.
 | 
			
		||||
     *
 | 
			
		||||
     *  The specified callback will be called on state changes such as when
 | 
			
		||||
     *  the file can be written to or read from.
 | 
			
		||||
     *
 | 
			
		||||
     *  The callback may be called in an interrupt context and should not
 | 
			
		||||
     *  perform expensive operations.
 | 
			
		||||
     *
 | 
			
		||||
     *  Note! This is not intended as an attach-like asynchronous api, but rather
 | 
			
		||||
     *  as a building block for constructing  such functionality.
 | 
			
		||||
     *
 | 
			
		||||
     *  The exact timing of when the registered function
 | 
			
		||||
     *  is called is not guaranteed and susceptible to change. It should be used
 | 
			
		||||
     *  as a cue to make read/write/poll calls to find the current state.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param func     Function to call on state change
 | 
			
		||||
     */
 | 
			
		||||
    virtual void sigio(Callback<void()> func);
 | 
			
		||||
 | 
			
		||||
    /** Setup interrupt handler for DCD line
 | 
			
		||||
     *
 | 
			
		||||
     *  If DCD line is connected, an IRQ handler will be setup.
 | 
			
		||||
     *  Does nothing if DCD is NC, i.e., not connected.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param dcd_pin         Pin-name for DCD
 | 
			
		||||
     *  @param active_high     a boolean set to true if DCD polarity is active low
 | 
			
		||||
     */
 | 
			
		||||
    void set_data_carrier_detect(PinName dcd_pin, bool active_high = false);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    /** Software serial buffers
 | 
			
		||||
     *  By default buffer size is 256 for TX and 256 for RX. Configurable through mbed_app.json
 | 
			
		||||
     */
 | 
			
		||||
    CircularBuffer<char, MBED_CONF_DRIVERS_UART_SERIAL_RXBUF_SIZE> _rxbuf;
 | 
			
		||||
    CircularBuffer<char, MBED_CONF_DRIVERS_UART_SERIAL_TXBUF_SIZE> _txbuf;
 | 
			
		||||
 | 
			
		||||
    PlatformMutex _mutex;
 | 
			
		||||
 | 
			
		||||
    Callback<void()> _sigio_cb;
 | 
			
		||||
 | 
			
		||||
    bool _blocking;
 | 
			
		||||
    bool _tx_irq_enabled;
 | 
			
		||||
    InterruptIn *_dcd_irq;
 | 
			
		||||
 | 
			
		||||
    /** Device Hanged up
 | 
			
		||||
     *  Determines if the device hanged up on us.
 | 
			
		||||
     *
 | 
			
		||||
     *  @return True, if hanged up
 | 
			
		||||
     */
 | 
			
		||||
    bool hup() const;
 | 
			
		||||
 | 
			
		||||
    /** ISRs for serial
 | 
			
		||||
     *  Routines to handle interrupts on serial pins.
 | 
			
		||||
     *  Copies data into Circular Buffer.
 | 
			
		||||
     *  Reports the state change to File handle.
 | 
			
		||||
     */
 | 
			
		||||
    void tx_irq(void);
 | 
			
		||||
    void rx_irq(void);
 | 
			
		||||
 | 
			
		||||
    void wake(void);
 | 
			
		||||
 | 
			
		||||
    void dcd_irq(void);
 | 
			
		||||
};
 | 
			
		||||
} //namespace mbed
 | 
			
		||||
 | 
			
		||||
#endif //DEVICE_SERIAL
 | 
			
		||||
#endif //MBED_UARTSERIAL_H
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
{
 | 
			
		||||
    "name": "drivers",
 | 
			
		||||
    "config": {
 | 
			
		||||
        "uart-serial-txbuf-size": {
 | 
			
		||||
            "help": "Default TX buffer size for a UARTSerial instance (unit Bytes))",
 | 
			
		||||
            "value": 256
 | 
			
		||||
        },
 | 
			
		||||
        "uart-serial-rxbuf-size": {
 | 
			
		||||
            "help": "Default RX buffer size for a UARTSerial instance (unit Bytes))",
 | 
			
		||||
            "value": 256
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -605,11 +605,8 @@ void ppp_print_string(const u_char *p, int len, void (*printer) (void *, const c
 | 
			
		|||
 * ppp_logit - does the hard work for fatal et al.
 | 
			
		||||
 */
 | 
			
		||||
static void ppp_logit(int level, const char *fmt, va_list args) {
 | 
			
		||||
#ifdef PPP_LOGIT_BUFSIZE
 | 
			
		||||
    char buf[PPP_LOGIT_BUFSIZE];
 | 
			
		||||
#else
 | 
			
		||||
    char buf[1024];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    char buf[256];
 | 
			
		||||
 | 
			
		||||
    ppp_vslprintf(buf, sizeof(buf), fmt, args);
 | 
			
		||||
    ppp_log_write(level, buf);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,12 +104,12 @@
 | 
			
		|||
 | 
			
		||||
// Thread stack size for private PPP thread
 | 
			
		||||
#ifndef MBED_CONF_LWIP_PPP_THREAD_STACKSIZE
 | 
			
		||||
#define MBED_CONF_LWIP_PPP_THREAD_STACKSIZE    300
 | 
			
		||||
#define MBED_CONF_LWIP_PPP_THREAD_STACKSIZE    512
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if LWIP_DEBUG
 | 
			
		||||
#define DEFAULT_THREAD_STACKSIZE    MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2
 | 
			
		||||
#define PPP_THREAD_STACK_SIZE       MBED_CONF_LWIP_PPP_THREAD_STACKSIZE*4
 | 
			
		||||
#define PPP_THREAD_STACK_SIZE       MBED_CONF_LWIP_PPP_THREAD_STACKSIZE*2
 | 
			
		||||
#else
 | 
			
		||||
#define DEFAULT_THREAD_STACKSIZE    MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE
 | 
			
		||||
#define PPP_THREAD_STACK_SIZE       MBED_CONF_LWIP_PPP_THREAD_STACKSIZE
 | 
			
		||||
| 
						 | 
				
			
			@ -265,15 +265,15 @@
 | 
			
		|||
#if MBED_CONF_LWIP_ETHERNET_ENABLED
 | 
			
		||||
#define LWIP_ARP                    1
 | 
			
		||||
#define LWIP_ETHERNET               1
 | 
			
		||||
#define LWIP_CHECKSUM_ON_COPY       1
 | 
			
		||||
#define LWIP_DHCP                   LWIP_IPV4
 | 
			
		||||
#else
 | 
			
		||||
#define LWIP_ARP                    0
 | 
			
		||||
#define LWIP_ETHERNET               0
 | 
			
		||||
#define LWIP_CHECKSUM_ON_COPY       0
 | 
			
		||||
#endif // MBED_CONF_LWIP_ETHERNET_ENABLED
 | 
			
		||||
 | 
			
		||||
#if MBED_CONF_LWIP_PPP_ENABLED
 | 
			
		||||
// Note generic macro name used rather than MBED_CONF_LWIP_PPP_ENABLED
 | 
			
		||||
// to allow users like PPPCellularInterface to detect that nsapi_ppp.h is available.
 | 
			
		||||
#if NSAPI_PPP_AVAILABLE
 | 
			
		||||
#define PPP_SUPPORT                 1
 | 
			
		||||
#define CHAP_SUPPORT                1
 | 
			
		||||
#define PPP_INPROC_IRQ_SAFE         1
 | 
			
		||||
| 
						 | 
				
			
			@ -281,7 +281,6 @@
 | 
			
		|||
#define PAP_SUPPORT                 0
 | 
			
		||||
#define VJ_SUPPORT                  0
 | 
			
		||||
#define PRINTPKT_SUPPORT            0
 | 
			
		||||
#define PPP_LOGIT_BUFSIZE           512
 | 
			
		||||
 | 
			
		||||
// Broadcast
 | 
			
		||||
#define IP_SOF_BROADCAST            0
 | 
			
		||||
| 
						 | 
				
			
			@ -289,7 +288,7 @@
 | 
			
		|||
 | 
			
		||||
#define MAXNAMELEN                  64     /* max length of hostname or name for auth */
 | 
			
		||||
#define MAXSECRETLEN                64
 | 
			
		||||
#endif // MBED_CONF_LWIP_PPP_ENABLED
 | 
			
		||||
#endif // NSAPI_PPP_AVAILABLE
 | 
			
		||||
 | 
			
		||||
// Make sure we default these to off, so
 | 
			
		||||
// LWIP doesn't default to on
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,8 @@
 | 
			
		|||
        },
 | 
			
		||||
        "ppp-enabled": {
 | 
			
		||||
            "help": "Enable support for PPP interfaces",
 | 
			
		||||
            "value": false
 | 
			
		||||
            "value": false,
 | 
			
		||||
            "macro_name": "NSAPI_PPP_AVAILABLE"
 | 
			
		||||
        },
 | 
			
		||||
        "use-mbed-trace": {
 | 
			
		||||
            "help": "Use mbed trace for debug, rather than printf",
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +68,7 @@
 | 
			
		|||
        },
 | 
			
		||||
        "ppp-thread-stacksize": {
 | 
			
		||||
            "help": "Thread stack size for PPP",
 | 
			
		||||
            "value": 300
 | 
			
		||||
            "value": 512
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,108 @@
 | 
			
		|||
/* Copyright (c) 2017 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CELLULAR_BASE_H
 | 
			
		||||
#define CELLULAR_BASE_H
 | 
			
		||||
 | 
			
		||||
#include "netsocket/NetworkInterface.h"
 | 
			
		||||
 | 
			
		||||
/** CellularBase class
 | 
			
		||||
 *
 | 
			
		||||
 *  Common interface that is shared between Cellular interfaces
 | 
			
		||||
 */
 | 
			
		||||
class CellularBase: public NetworkInterface {
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    /** Set the Cellular network credentials
 | 
			
		||||
     *
 | 
			
		||||
     *  Please check documentation of connect() for default behaviour of APN settings.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param apn      Access point name
 | 
			
		||||
     *  @param uname    optionally, Username
 | 
			
		||||
     *  @param pwd      optionally, password
 | 
			
		||||
     */
 | 
			
		||||
    virtual void set_credentials(const char *apn, const char *uname = 0,
 | 
			
		||||
                                 const char *pwd = 0) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Set the pin code for SIM card
 | 
			
		||||
     *
 | 
			
		||||
     *  @param sim_pin      PIN for the SIM card
 | 
			
		||||
     */
 | 
			
		||||
    virtual void set_sim_pin(const char *sim_pin) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Start the interface
 | 
			
		||||
     *
 | 
			
		||||
     *  Attempts to connect to a Cellular network.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param sim_pin     PIN for the SIM card
 | 
			
		||||
     *  @param apn         optionally, access point name
 | 
			
		||||
     *  @param uname       optionally, Username
 | 
			
		||||
     *  @param pwd         optionally, password
 | 
			
		||||
     *  @return            NSAPI_ERROR_OK on success, or negative error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0,
 | 
			
		||||
                                  const char *uname = 0,
 | 
			
		||||
                                  const char *pwd = 0) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Start the interface
 | 
			
		||||
     *
 | 
			
		||||
     *  Attempts to connect to a Cellular network.
 | 
			
		||||
     *  If the SIM requires a PIN, and it is not set/invalid, NSAPI_ERROR_AUTH_ERROR is returned.
 | 
			
		||||
     *
 | 
			
		||||
     *  @return            NSAPI_ERROR_OK on success, or negative error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_error_t connect() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Stop the interface
 | 
			
		||||
     *
 | 
			
		||||
     *  @return         0 on success, or error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_error_t disconnect() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Check if the connection is currently established or not
 | 
			
		||||
     *
 | 
			
		||||
     * @return true/false   If the cellular module have successfully acquired a carrier and is
 | 
			
		||||
     *                      connected to an external packet data network using PPP, isConnected()
 | 
			
		||||
     *                      API returns true and false otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    virtual bool is_connected() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Get the local IP address
 | 
			
		||||
     *
 | 
			
		||||
     *  @return         Null-terminated representation of the local IP address
 | 
			
		||||
     *                  or null if no IP address has been received
 | 
			
		||||
     */
 | 
			
		||||
    virtual const char *get_ip_address() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Get the local network mask
 | 
			
		||||
     *
 | 
			
		||||
     *  @return         Null-terminated representation of the local network mask
 | 
			
		||||
     *                  or null if no network mask has been received
 | 
			
		||||
     */
 | 
			
		||||
    virtual const char *get_netmask() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Get the local gateways
 | 
			
		||||
     *
 | 
			
		||||
     *  @return         Null-terminated representation of the local gateway
 | 
			
		||||
     *                  or null if no network mask has been received
 | 
			
		||||
     */
 | 
			
		||||
    virtual const char *get_gateway() = 0;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //CELLULAR_BASE_H
 | 
			
		||||
 | 
			
		||||
/** @}*/
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,7 @@
 | 
			
		|||
/* Copyright (c) 2017 ARM Limited
 | 
			
		||||
/** \addtogroup netsocket */
 | 
			
		||||
/** @{*/
 | 
			
		||||
/* CellularInterface
 | 
			
		||||
 * Copyright (c) 2015 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
| 
						 | 
				
			
			@ -18,95 +21,54 @@
 | 
			
		|||
 | 
			
		||||
#include "netsocket/NetworkInterface.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** CellularInterface class
 | 
			
		||||
 *
 | 
			
		||||
 *  Common interface that is shared between Cellular interfaces
 | 
			
		||||
 *  Common interface that is shared between ethernet hardware
 | 
			
		||||
 */
 | 
			
		||||
class CellularInterface: public NetworkInterface {
 | 
			
		||||
 | 
			
		||||
class CellularInterface : public NetworkInterface
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    /** CellularInterface lifetime
 | 
			
		||||
     */
 | 
			
		||||
    //virtual ~CellularInterface() {};
 | 
			
		||||
    virtual ~CellularInterface() {};
 | 
			
		||||
 | 
			
		||||
    /** Set the Cellular network credentials
 | 
			
		||||
    /** Set the cellular network APN and credentials
 | 
			
		||||
     *
 | 
			
		||||
     *  Please check documentation of connect() for default behaviour of APN settings.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param apn      Access point name
 | 
			
		||||
     *  @param uname    optionally, Username
 | 
			
		||||
     *  @param pwd      optionally, password
 | 
			
		||||
     *  @param apn      Optional name of the network to connect to
 | 
			
		||||
     *  @param user     Optional username for the APN
 | 
			
		||||
     *  @param pass     Optional password fot the APN
 | 
			
		||||
     *  @return         0 on success, negative error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual void set_credentials(const char *apn,
 | 
			
		||||
                                 const char *uname = 0,
 | 
			
		||||
                                 const char *pwd = 0) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Set the pin code for SIM card
 | 
			
		||||
     *
 | 
			
		||||
     *  @param sim_pin      PIN for the SIM card
 | 
			
		||||
     */
 | 
			
		||||
    virtual void set_sim_pin(const char *sim_pin) = 0;
 | 
			
		||||
    virtual nsapi_error_t set_credentials(const char *apn,
 | 
			
		||||
            const char *username = 0, const char *password = 0) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Start the interface
 | 
			
		||||
     *
 | 
			
		||||
     *  Attempts to connect to a Cellular network.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param sim_pin     PIN for the SIM card
 | 
			
		||||
     *  @param apn         optionally, access point name
 | 
			
		||||
     *  @param uname       optionally, Username
 | 
			
		||||
     *  @param pwd         optionally, password
 | 
			
		||||
     *  @return            NSAPI_ERROR_OK on success, or negative error code on failure
 | 
			
		||||
     *  @param apn      Optional name of the network to connect to
 | 
			
		||||
     *  @param username Optional username for your APN
 | 
			
		||||
     *  @param password Optional password for your APN
 | 
			
		||||
     *  @return         0 on success, negative error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0,
 | 
			
		||||
                                  const char *uname = 0,
 | 
			
		||||
                                  const char *pwd = 0) = 0;
 | 
			
		||||
    virtual nsapi_error_t connect(const char *apn,
 | 
			
		||||
            const char *username = 0, const char *password = 0) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Start the interface
 | 
			
		||||
     *
 | 
			
		||||
     *  Attempts to connect to a Cellular network.
 | 
			
		||||
     *  If the SIM requires a PIN, and it is not set/invalid, NSAPI_ERROR_AUTH_ERROR is returned.
 | 
			
		||||
     *  Attempts to connect to a cellular network based on supplied credentials
 | 
			
		||||
     *
 | 
			
		||||
     *  @return            NSAPI_ERROR_OK on success, or negative error code on failure
 | 
			
		||||
     *  @return         0 on success, negative error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_error_t connect() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Stop the interface
 | 
			
		||||
        *
 | 
			
		||||
        *  @return         0 on success, or error code on failure
 | 
			
		||||
        */
 | 
			
		||||
     *
 | 
			
		||||
     *  @return         0 on success, negative error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_error_t disconnect() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Check if the connection is currently established or not
 | 
			
		||||
     *
 | 
			
		||||
     * @return true/false   If the cellular module have successfully acquired a carrier and is
 | 
			
		||||
     *                      connected to an external packet data network using PPP, isConnected()
 | 
			
		||||
     *                      API returns true and false otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    virtual bool is_connected() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Get the local IP address
 | 
			
		||||
     *
 | 
			
		||||
     *  @return         Null-terminated representation of the local IP address
 | 
			
		||||
     *                  or null if no IP address has been recieved
 | 
			
		||||
     */
 | 
			
		||||
    virtual const char *get_ip_address() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Get the local network mask
 | 
			
		||||
     *
 | 
			
		||||
     *  @return         Null-terminated representation of the local network mask
 | 
			
		||||
     *                  or null if no network mask has been recieved
 | 
			
		||||
     */
 | 
			
		||||
    virtual const char *get_netmask() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Get the local gateways
 | 
			
		||||
     *
 | 
			
		||||
     *  @return         Null-terminated representation of the local gateway
 | 
			
		||||
     *                  or null if no network mask has been recieved
 | 
			
		||||
     */
 | 
			
		||||
    virtual const char *get_gateway() = 0;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @}*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
/* Copyright (c) 2017 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include "OnboardCellularInterface.h"
 | 
			
		||||
 | 
			
		||||
#if MODEM_ON_BOARD && MODEM_ON_BOARD_UART && NSAPI_PPP_AVAILABLE
 | 
			
		||||
 | 
			
		||||
#include "onboard_modem_api.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * OnboardCellularInterface is an on-board specific implementation.
 | 
			
		||||
 */
 | 
			
		||||
OnboardCellularInterface::OnboardCellularInterface(bool debug) :
 | 
			
		||||
                                                      UARTCellularInterface(MDMTXD, MDMRXD, MDMDCD, MDMRTS,
 | 
			
		||||
                                                                            MDMCTS, MDMRI, MDMDTR, MDMDSR,
 | 
			
		||||
                                                                            MBED_CONF_PPP_CELL_IFACE_BAUD_RATE, MDM_PIN_POLARITY, debug)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OnboardCellularInterface::~OnboardCellularInterface()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OnboardCellularInterface::modem_init()
 | 
			
		||||
{
 | 
			
		||||
    ::onboard_modem_init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OnboardCellularInterface::modem_deinit()
 | 
			
		||||
{
 | 
			
		||||
    ::onboard_modem_deinit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OnboardCellularInterface::modem_power_up()
 | 
			
		||||
{
 | 
			
		||||
    ::onboard_modem_power_up();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OnboardCellularInterface::modem_power_down()
 | 
			
		||||
{
 | 
			
		||||
    ::onboard_modem_power_down();
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
/* Copyright (c) 2017 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ONBOARD_CELLULAR_INTERFACE_
 | 
			
		||||
#define ONBOARD_CELLULAR_INTERFACE_
 | 
			
		||||
 | 
			
		||||
#if MODEM_ON_BOARD && MODEM_ON_BOARD_UART && NSAPI_PPP_AVAILABLE
 | 
			
		||||
 | 
			
		||||
#include "UARTCellularInterface.h"
 | 
			
		||||
 | 
			
		||||
/** OnboardCellularInterface class
 | 
			
		||||
 *
 | 
			
		||||
 *  This interface serves as the controller/driver for an
 | 
			
		||||
 *  onboard modem implementing onboard_modem_api.h.
 | 
			
		||||
 *
 | 
			
		||||
 *  Depending on the type of on-board modem, OnboardCellularInterface
 | 
			
		||||
 *  could be derived from different implementation classes.
 | 
			
		||||
 *  Portable applications should only rely on it being a CellularBase.
 | 
			
		||||
 */
 | 
			
		||||
class OnboardCellularInterface : public UARTCellularInterface {
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    OnboardCellularInterface(bool debug = false);
 | 
			
		||||
 | 
			
		||||
    virtual ~OnboardCellularInterface();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    /** Sets the modem up for powering on
 | 
			
		||||
     *
 | 
			
		||||
     *  modem_init() is equivalent to plugging in the device, e.g., attaching power and serial port.
 | 
			
		||||
     *  Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void modem_init();
 | 
			
		||||
 | 
			
		||||
    /** Sets the modem in unplugged state
 | 
			
		||||
     *
 | 
			
		||||
     *  modem_deinit() will be equivalent to pulling the plug off of the device, i.e., detaching power
 | 
			
		||||
     *  and serial port. This puts the modem in lowest power state.
 | 
			
		||||
     *  Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void modem_deinit();
 | 
			
		||||
 | 
			
		||||
    /** Powers up the modem
 | 
			
		||||
     *
 | 
			
		||||
     *  modem_power_up() is equivalent to pressing the soft power button.
 | 
			
		||||
     *  The driver may repeat this if the modem is not responsive to AT commands.
 | 
			
		||||
     *  Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void modem_power_up();
 | 
			
		||||
 | 
			
		||||
    /** Powers down the modem
 | 
			
		||||
     *
 | 
			
		||||
     *  modem_power_down() is equivalent to turning off the modem by button press.
 | 
			
		||||
     *  Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void modem_power_down();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //MODEM_ON_BOARD && MODEM_ON_BOARD_UART && NSAPI_PPP_AVAILABLE
 | 
			
		||||
#endif //ONBOARD_CELLULAR_INTERFACE_
 | 
			
		||||
| 
						 | 
				
			
			@ -12,15 +12,15 @@
 | 
			
		|||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include "ReferenceCellularDriver.h"
 | 
			
		||||
#include "PPPCellularInterface.h"
 | 
			
		||||
 | 
			
		||||
#if NSAPI_PPP_AVAILABLE
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "modem_api.h"
 | 
			
		||||
#include "platform/BufferedSerial.h"
 | 
			
		||||
#include "nsapi_ppp.h"
 | 
			
		||||
#if MBED_CONF_REF_CELL_DRV_APN_LOOKUP
 | 
			
		||||
#include "APN_db.h"
 | 
			
		||||
#endif //MBED_CONF_REF_CELL_DRV_APN_LOOKUP
 | 
			
		||||
#if MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
 | 
			
		||||
#include "utils/APN_db.h"
 | 
			
		||||
#endif //MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
 | 
			
		||||
#if defined(FEATURE_COMMON_PAL)
 | 
			
		||||
#include "mbed_trace.h"
 | 
			
		||||
#define TRACE_GROUP "UCID"
 | 
			
		||||
| 
						 | 
				
			
			@ -30,8 +30,6 @@
 | 
			
		|||
#define tr_error(...) (void(0)) //dummies if feature common pal is not added
 | 
			
		||||
#endif //defined(FEATURE_COMMON_PAL)
 | 
			
		||||
 | 
			
		||||
#define BAUD_RATE   115200
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PDP (packet data profile) Context
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -42,31 +40,30 @@
 | 
			
		|||
 */
 | 
			
		||||
#define OUTPUT_ENTER_KEY  "\r"
 | 
			
		||||
 | 
			
		||||
#if MBED_CONF_REF_CELL_DRV_AT_PARSER_BUFFER_SIZE
 | 
			
		||||
#define AT_PARSER_BUFFER_SIZE   MBED_CONF_REF_CELL_DRV_AT_PARSER_BUFFER_SIZE //bytes
 | 
			
		||||
#if MBED_CONF_PPP_CELL_IFACE_AT_PARSER_BUFFER_SIZE
 | 
			
		||||
#define AT_PARSER_BUFFER_SIZE   MBED_CONF_PPP_CELL_IFACE_AT_PARSER_BUFFER_SIZE //bytes
 | 
			
		||||
#else
 | 
			
		||||
#define AT_PARSER_BUFFER_SIZE   256 //bytes
 | 
			
		||||
#endif //MMBED_CONF_REF_CELL_DRV_AT_PARSER_BUFFER_SIZE
 | 
			
		||||
#endif //MBED_CONF_PPP_CELL_IFACE_AT_PARSER_BUFFER_SIZE
 | 
			
		||||
 | 
			
		||||
#if MBED_CONF_REF_CELL_DRV_AT_PARSER_TIMEOUT
 | 
			
		||||
#define AT_PARSER_TIMEOUT       MBED_CONF_REF_CELL_DRV_AT_PARSER_TIMEOUT
 | 
			
		||||
#if MBED_CONF_PPP_CELL_IFACE_AT_PARSER_TIMEOUT
 | 
			
		||||
#define AT_PARSER_TIMEOUT       MBED_CONF_PPP_CELL_IFACE_AT_PARSER_TIMEOUT
 | 
			
		||||
#else
 | 
			
		||||
#define AT_PARSER_TIMEOUT       8*1000 //miliseconds
 | 
			
		||||
#endif //MBED_CONF_REF_CELL_DRV_AT_PARSER_TIMEOUT
 | 
			
		||||
#endif //MBED_CONF_PPP_CELL_IFACE_AT_PARSER_TIMEOUT
 | 
			
		||||
 | 
			
		||||
static bool initialized;
 | 
			
		||||
static bool set_credentials_api_used;
 | 
			
		||||
static bool set_sim_pin_check_request;
 | 
			
		||||
static bool change_pin;
 | 
			
		||||
static device_info dev_info;
 | 
			
		||||
static modem_t mdm_object;
 | 
			
		||||
 | 
			
		||||
static void parser_abort(ATParser *at)
 | 
			
		||||
static void parser_abort(ATCmdParser *at)
 | 
			
		||||
{
 | 
			
		||||
    at->abort();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool get_CCID(ATParser *at)
 | 
			
		||||
static bool get_CCID(ATCmdParser *at)
 | 
			
		||||
{
 | 
			
		||||
    // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card.
 | 
			
		||||
    // ICCID is a serial number identifying the SIM.
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +72,7 @@ static bool get_CCID(ATParser *at)
 | 
			
		|||
    return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool get_IMSI(ATParser *at)
 | 
			
		||||
static bool get_IMSI(ATCmdParser *at)
 | 
			
		||||
{
 | 
			
		||||
    // International mobile subscriber identification
 | 
			
		||||
    bool success = at->send("AT+CIMI") && at->recv("%15[^\n]\nOK\n", dev_info.imsi);
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +80,7 @@ static bool get_IMSI(ATParser *at)
 | 
			
		|||
    return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool get_IMEI(ATParser *at)
 | 
			
		||||
static bool get_IMEI(ATCmdParser *at)
 | 
			
		||||
{
 | 
			
		||||
    // International mobile equipment identifier
 | 
			
		||||
    bool success = at->send("AT+CGSN") && at->recv("%15[^\n]\nOK\n", dev_info.imei);
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +88,7 @@ static bool get_IMEI(ATParser *at)
 | 
			
		|||
    return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool get_MEID(ATParser *at)
 | 
			
		||||
static bool get_MEID(ATCmdParser *at)
 | 
			
		||||
{
 | 
			
		||||
    // Mobile equipment identifier
 | 
			
		||||
    bool success = at->send("AT+GSN")
 | 
			
		||||
| 
						 | 
				
			
			@ -100,7 +97,7 @@ static bool get_MEID(ATParser *at)
 | 
			
		|||
    return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool set_CMGF(ATParser *at)
 | 
			
		||||
static bool set_CMGF(ATCmdParser *at)
 | 
			
		||||
{
 | 
			
		||||
    // Preferred message format
 | 
			
		||||
    // set AT+CMGF=[mode] , 0 PDU mode, 1 text mode
 | 
			
		||||
| 
						 | 
				
			
			@ -108,7 +105,7 @@ static bool set_CMGF(ATParser *at)
 | 
			
		|||
    return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool set_CNMI(ATParser *at)
 | 
			
		||||
static bool set_CNMI(ATCmdParser *at)
 | 
			
		||||
{
 | 
			
		||||
    // New SMS indication configuration
 | 
			
		||||
    // set AT+CMTI=[mode, index] , 0 PDU mode, 1 text mode
 | 
			
		||||
| 
						 | 
				
			
			@ -117,7 +114,7 @@ static bool set_CNMI(ATParser *at)
 | 
			
		|||
    return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void CMTI_URC(ATParser *at)
 | 
			
		||||
static void CMTI_URC(ATCmdParser *at)
 | 
			
		||||
{
 | 
			
		||||
    // our CMGF = 1, i.e., text mode. So we expect response in this format:
 | 
			
		||||
    //+CMTI: <mem>,<index>,
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +123,7 @@ static void CMTI_URC(ATParser *at)
 | 
			
		|||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void CMT_URC(ATParser *at)
 | 
			
		||||
static void CMT_URC(ATCmdParser *at)
 | 
			
		||||
{
 | 
			
		||||
    // our CMGF = 1, i.e., text mode. So we expect response in this format:
 | 
			
		||||
    //+CMT: <oa>,[<alpha>],<scts>[,<tooa>,
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +139,7 @@ static void CMT_URC(ATParser *at)
 | 
			
		|||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool set_atd(ATParser *at)
 | 
			
		||||
static bool set_atd(ATCmdParser *at)
 | 
			
		||||
{
 | 
			
		||||
    bool success = at->send("ATD*99***"CTX"#") && at->recv("CONNECT");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -152,7 +149,7 @@ static bool set_atd(ATParser *at)
 | 
			
		|||
/**
 | 
			
		||||
 * Enables or disables SIM pin check lock
 | 
			
		||||
 */
 | 
			
		||||
static nsapi_error_t do_sim_pin_check(ATParser *at, const char *pin)
 | 
			
		||||
static nsapi_error_t do_sim_pin_check(ATCmdParser *at, const char *pin)
 | 
			
		||||
{
 | 
			
		||||
    bool success;
 | 
			
		||||
    if (set_sim_pin_check_request) {
 | 
			
		||||
| 
						 | 
				
			
			@ -171,7 +168,7 @@ static nsapi_error_t do_sim_pin_check(ATParser *at, const char *pin)
 | 
			
		|||
/**
 | 
			
		||||
 * Change the pin code for the SIM card
 | 
			
		||||
 */
 | 
			
		||||
static nsapi_error_t do_change_sim_pin(ATParser *at, const char *old_pin, const char *new_pin)
 | 
			
		||||
static nsapi_error_t do_change_sim_pin(ATCmdParser *at, const char *old_pin, const char *new_pin)
 | 
			
		||||
{
 | 
			
		||||
    /* changes the SIM pin */
 | 
			
		||||
       bool success = at->send("AT+CPWD=\"SC\",\"%s\",\"%s\"", old_pin, new_pin) && at->recv("OK");
 | 
			
		||||
| 
						 | 
				
			
			@ -255,43 +252,58 @@ static bool is_registered_psd()
 | 
			
		|||
            (dev_info.reg_status_psd == PSD_REGISTERED_ROAMING);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReferenceCellularDriver::ReferenceCellularDriver(PinName tx, PinName rx, int baud, bool debugOn)
 | 
			
		||||
PPPCellularInterface::PPPCellularInterface(FileHandle *fh, bool debug)
 | 
			
		||||
{
 | 
			
		||||
    _new_pin = NULL;
 | 
			
		||||
    _pin = NULL;
 | 
			
		||||
    _at = NULL;
 | 
			
		||||
    _dcd = NULL;
 | 
			
		||||
    _apn = "internet";
 | 
			
		||||
    _uname = NULL;
 | 
			
		||||
    _pwd = NULL;
 | 
			
		||||
    _debug_trace_on = false;
 | 
			
		||||
 | 
			
		||||
    // Set up File Handle
 | 
			
		||||
    _fh = new BufferedSerial(tx, rx, BAUD_RATE);
 | 
			
		||||
 | 
			
		||||
    if (debugOn) {
 | 
			
		||||
         _debug_trace_on = true;
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
    _fh = fh;
 | 
			
		||||
    _debug_trace_on = debug;
 | 
			
		||||
    dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING;
 | 
			
		||||
    dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING;
 | 
			
		||||
    dev_info.ppp_connection_up = false;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReferenceCellularDriver::~ReferenceCellularDriver()
 | 
			
		||||
 | 
			
		||||
PPPCellularInterface::~PPPCellularInterface()
 | 
			
		||||
{
 | 
			
		||||
    delete _fh;
 | 
			
		||||
    delete _at;
 | 
			
		||||
    delete _dcd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ReferenceCellularDriver::modem_debug_on(bool on)
 | 
			
		||||
void PPPCellularInterface::enable_hup(bool)
 | 
			
		||||
{
 | 
			
		||||
    //meant to be overridden
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PPPCellularInterface::modem_init()
 | 
			
		||||
{
 | 
			
		||||
    //meant to be overridden
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PPPCellularInterface::modem_deinit()
 | 
			
		||||
{
 | 
			
		||||
    //meant to be overridden
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PPPCellularInterface::modem_power_up()
 | 
			
		||||
{
 | 
			
		||||
    //meant to be overridden
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PPPCellularInterface::modem_power_down()
 | 
			
		||||
{
 | 
			
		||||
    //meant to be overridden
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PPPCellularInterface::modem_debug_on(bool on)
 | 
			
		||||
{
 | 
			
		||||
    _debug_trace_on = on;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ReferenceCellularDriver::connection_status_cb(Callback<void(nsapi_error_t)> cb)
 | 
			
		||||
void PPPCellularInterface::connection_status_cb(Callback<void(nsapi_error_t)> cb)
 | 
			
		||||
{
 | 
			
		||||
    _connection_status_cb = cb;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -300,7 +312,7 @@ void ReferenceCellularDriver::connection_status_cb(Callback<void(nsapi_error_t)>
 | 
			
		|||
 * Public API. Sets up the flag for the driver to enable or disable SIM pin check
 | 
			
		||||
 * at the next boot.
 | 
			
		||||
 */
 | 
			
		||||
void ReferenceCellularDriver::set_sim_pin_check(bool check)
 | 
			
		||||
void PPPCellularInterface::set_sim_pin_check(bool check)
 | 
			
		||||
{
 | 
			
		||||
    set_sim_pin_check_request = check;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -308,13 +320,13 @@ void ReferenceCellularDriver::set_sim_pin_check(bool check)
 | 
			
		|||
/**
 | 
			
		||||
 * Public API. Sets up the flag for the driver to change pin code for SIM card
 | 
			
		||||
 */
 | 
			
		||||
void ReferenceCellularDriver::set_new_sim_pin(const char *new_pin)
 | 
			
		||||
void PPPCellularInterface::set_new_sim_pin(const char *new_pin)
 | 
			
		||||
{
 | 
			
		||||
    change_pin = true;
 | 
			
		||||
    _new_pin = new_pin;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ReferenceCellularDriver::nwk_registration(uint8_t nwk_type)
 | 
			
		||||
bool PPPCellularInterface::nwk_registration(uint8_t nwk_type)
 | 
			
		||||
{
 | 
			
		||||
    bool success = false;
 | 
			
		||||
     bool registered = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -383,13 +395,13 @@ bool ReferenceCellularDriver::nwk_registration(uint8_t nwk_type)
 | 
			
		|||
     return registered;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ReferenceCellularDriver::is_connected()
 | 
			
		||||
bool PPPCellularInterface::is_connected()
 | 
			
		||||
{
 | 
			
		||||
    return dev_info.ppp_connection_up;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get the SIM card going.
 | 
			
		||||
nsapi_error_t ReferenceCellularDriver::initialize_sim_card()
 | 
			
		||||
nsapi_error_t PPPCellularInterface::initialize_sim_card()
 | 
			
		||||
{
 | 
			
		||||
    nsapi_error_t nsapi_error = NSAPI_ERROR_AUTH_FAILURE;
 | 
			
		||||
    int retry_count = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -426,12 +438,12 @@ nsapi_error_t ReferenceCellularDriver::initialize_sim_card()
 | 
			
		|||
    return nsapi_error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ReferenceCellularDriver::set_sim_pin(const char *pin) {
 | 
			
		||||
void PPPCellularInterface::set_sim_pin(const char *pin) {
 | 
			
		||||
    /* overwrite the default pin by user provided pin */
 | 
			
		||||
    _pin = pin;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_error_t ReferenceCellularDriver::setup_context_and_credentials()
 | 
			
		||||
nsapi_error_t PPPCellularInterface::setup_context_and_credentials()
 | 
			
		||||
{
 | 
			
		||||
    bool success;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -463,7 +475,7 @@ retry_without_ipv6:
 | 
			
		|||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void  ReferenceCellularDriver::set_credentials(const char *apn, const char *uname,
 | 
			
		||||
void  PPPCellularInterface::set_credentials(const char *apn, const char *uname,
 | 
			
		||||
                                                               const char *pwd)
 | 
			
		||||
{
 | 
			
		||||
    _apn = apn;
 | 
			
		||||
| 
						 | 
				
			
			@ -474,13 +486,13 @@ void  ReferenceCellularDriver::set_credentials(const char *apn, const char *unam
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ReferenceCellularDriver::setup_at_parser()
 | 
			
		||||
void PPPCellularInterface::setup_at_parser()
 | 
			
		||||
{
 | 
			
		||||
    if (_at) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _at = new ATParser(_fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE, AT_PARSER_TIMEOUT,
 | 
			
		||||
    _at = new ATCmdParser(_fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE, AT_PARSER_TIMEOUT,
 | 
			
		||||
                         _debug_trace_on ? true : false);
 | 
			
		||||
 | 
			
		||||
    /* Error cases, out of band handling  */
 | 
			
		||||
| 
						 | 
				
			
			@ -494,13 +506,13 @@ void ReferenceCellularDriver::setup_at_parser()
 | 
			
		|||
    _at->oob("+CMTI", callback(CMTI_URC, _at));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ReferenceCellularDriver::shutdown_at_parser()
 | 
			
		||||
void PPPCellularInterface::shutdown_at_parser()
 | 
			
		||||
{
 | 
			
		||||
    delete _at;
 | 
			
		||||
    _at = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_error_t ReferenceCellularDriver::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd)
 | 
			
		||||
nsapi_error_t PPPCellularInterface::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd)
 | 
			
		||||
{
 | 
			
		||||
    if (!sim_pin) {
 | 
			
		||||
        return NSAPI_ERROR_PARAMETER;
 | 
			
		||||
| 
						 | 
				
			
			@ -523,7 +535,7 @@ nsapi_error_t ReferenceCellularDriver::connect(const char *sim_pin, const char *
 | 
			
		|||
    return connect();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_error_t ReferenceCellularDriver::connect()
 | 
			
		||||
nsapi_error_t PPPCellularInterface::connect()
 | 
			
		||||
{
 | 
			
		||||
    nsapi_error_t retcode;
 | 
			
		||||
    bool success;
 | 
			
		||||
| 
						 | 
				
			
			@ -533,141 +545,131 @@ nsapi_error_t ReferenceCellularDriver::connect()
 | 
			
		|||
        return NSAPI_ERROR_IS_CONNECTED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if MBED_CONF_REF_CELL_DRV_APN_LOOKUP && !set_credentials_api_used
 | 
			
		||||
    const char *apn_config;
 | 
			
		||||
    do {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
retry_init:
 | 
			
		||||
 | 
			
		||||
    /* setup AT parser */
 | 
			
		||||
    setup_at_parser();
 | 
			
		||||
 | 
			
		||||
    if (!initialized) {
 | 
			
		||||
 | 
			
		||||
        /* If we are using serial interface, we want to make sure that DCD line is
 | 
			
		||||
         * not connected as long as we are using ATParser.
 | 
			
		||||
         * As soon as we get into data mode, we would like to attach an interrupt line
 | 
			
		||||
         * to DCD line.
 | 
			
		||||
         * Here, we detach the line */
 | 
			
		||||
        BufferedSerial *serial = static_cast<BufferedSerial *>(_fh);
 | 
			
		||||
        serial->set_data_carrier_detect(NC);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if (!power_up_modem()) {
 | 
			
		||||
            return NSAPI_ERROR_DEVICE_ERROR;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        retcode = initialize_sim_card();
 | 
			
		||||
        if (retcode != NSAPI_ERROR_OK) {
 | 
			
		||||
            return retcode;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        success =  nwk_registration(PACKET_SWITCHED) //perform network registration
 | 
			
		||||
                && get_CCID(_at) //get integrated circuit ID of the SIM
 | 
			
		||||
                && get_IMSI(_at) //get international mobile subscriber information
 | 
			
		||||
                && get_IMEI(_at) //get international mobile equipment identifier
 | 
			
		||||
                && get_MEID(_at) //its same as IMEI
 | 
			
		||||
                && set_CMGF(_at) //set message format for SMS
 | 
			
		||||
                && set_CNMI(_at); //set new SMS indication
 | 
			
		||||
 | 
			
		||||
        if (!success) {
 | 
			
		||||
            return NSAPI_ERROR_NO_CONNECTION;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Check if user want skip SIM pin checking on boot up */
 | 
			
		||||
        if (set_sim_pin_check_request) {
 | 
			
		||||
            retcode = do_sim_pin_check(_at, _pin);
 | 
			
		||||
            if (retcode != NSAPI_ERROR_OK) {
 | 
			
		||||
                return retcode;
 | 
			
		||||
            }
 | 
			
		||||
            /* set this request to false, as it is unnecessary to repeat in case of retry */
 | 
			
		||||
            set_sim_pin_check_request = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* check if the user requested a sim pin change */
 | 
			
		||||
        if (change_pin) {
 | 
			
		||||
            retcode = do_change_sim_pin(_at, _pin, _new_pin);
 | 
			
		||||
            if (retcode != NSAPI_ERROR_OK) {
 | 
			
		||||
                return retcode;
 | 
			
		||||
            }
 | 
			
		||||
            /* set this request to false, as it is unnecessary to repeat in case of retry */
 | 
			
		||||
            change_pin = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#if MBED_CONF_REF_CELL_DRV_APN_LOOKUP && !set_credentials_api_used
 | 
			
		||||
    const char *apn_config = NULL;
 | 
			
		||||
#if MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
 | 
			
		||||
    if (!set_credentials_api_used) {
 | 
			
		||||
        apn_config = apnconfig(dev_info.imsi);
 | 
			
		||||
        if (apn_config) {
 | 
			
		||||
            _apn    = _APN_GET(apn_config);
 | 
			
		||||
            _uname  = _APN_GET(apn_config);
 | 
			
		||||
            _pwd    = _APN_GET(apn_config);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        _apn    = _apn     ?  _apn    : NULL;
 | 
			
		||||
        _uname  = _uname   ?  _uname  : NULL;
 | 
			
		||||
        _pwd    = _pwd     ?  _pwd    : NULL;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        //sets up APN and IP protocol for external PDP context
 | 
			
		||||
        retcode = setup_context_and_credentials();
 | 
			
		||||
        if (retcode != NSAPI_ERROR_OK) {
 | 
			
		||||
            return retcode;
 | 
			
		||||
    do {
 | 
			
		||||
        retry_init:
 | 
			
		||||
 | 
			
		||||
        /* setup AT parser */
 | 
			
		||||
        setup_at_parser();
 | 
			
		||||
 | 
			
		||||
        if (!initialized) {
 | 
			
		||||
 | 
			
		||||
            /* If we have hangup (eg DCD) detection, we don't want it active
 | 
			
		||||
             * as long as we are using ATCmdParser.
 | 
			
		||||
             * As soon as we get into data mode, we will turn it back on. */
 | 
			
		||||
            enable_hup(false);
 | 
			
		||||
 | 
			
		||||
            if (!power_up()) {
 | 
			
		||||
                return NSAPI_ERROR_DEVICE_ERROR;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            retcode = initialize_sim_card();
 | 
			
		||||
            if (retcode != NSAPI_ERROR_OK) {
 | 
			
		||||
                return retcode;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            success = nwk_registration(PACKET_SWITCHED) //perform network registration
 | 
			
		||||
            && get_CCID(_at)//get integrated circuit ID of the SIM
 | 
			
		||||
            && get_IMSI(_at)//get international mobile subscriber information
 | 
			
		||||
            && get_IMEI(_at)//get international mobile equipment identifier
 | 
			
		||||
            && get_MEID(_at)//its same as IMEI
 | 
			
		||||
            && set_CMGF(_at)//set message format for SMS
 | 
			
		||||
            && set_CNMI(_at);//set new SMS indication
 | 
			
		||||
 | 
			
		||||
            if (!success) {
 | 
			
		||||
                return NSAPI_ERROR_NO_CONNECTION;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Check if user want skip SIM pin checking on boot up */
 | 
			
		||||
            if (set_sim_pin_check_request) {
 | 
			
		||||
                retcode = do_sim_pin_check(_at, _pin);
 | 
			
		||||
                if (retcode != NSAPI_ERROR_OK) {
 | 
			
		||||
                    return retcode;
 | 
			
		||||
                }
 | 
			
		||||
                /* set this request to false, as it is unnecessary to repeat in case of retry */
 | 
			
		||||
                set_sim_pin_check_request = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* check if the user requested a sim pin change */
 | 
			
		||||
            if (change_pin) {
 | 
			
		||||
                retcode = do_change_sim_pin(_at, _pin, _new_pin);
 | 
			
		||||
                if (retcode != NSAPI_ERROR_OK) {
 | 
			
		||||
                    return retcode;
 | 
			
		||||
                }
 | 
			
		||||
                /* set this request to false, as it is unnecessary to repeat in case of retry */
 | 
			
		||||
                change_pin = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
#if MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
 | 
			
		||||
            if (apn_config) {
 | 
			
		||||
                _apn = _APN_GET(apn_config);
 | 
			
		||||
                _uname = _APN_GET(apn_config);
 | 
			
		||||
                _pwd = _APN_GET(apn_config);
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            //sets up APN and IP protocol for external PDP context
 | 
			
		||||
            retcode = setup_context_and_credentials();
 | 
			
		||||
            if (retcode != NSAPI_ERROR_OK) {
 | 
			
		||||
                return retcode;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!success) {
 | 
			
		||||
                shutdown_at_parser();
 | 
			
		||||
                return NSAPI_ERROR_NO_CONNECTION;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            initialized = true;
 | 
			
		||||
            did_init = true;
 | 
			
		||||
        } else {
 | 
			
		||||
            /* If we were already initialized, we expect to receive NO_CARRIER response
 | 
			
		||||
             * from the modem as we were kicked out of Data mode */
 | 
			
		||||
            _at->recv("NO CARRIER");
 | 
			
		||||
            success = _at->send("AT") && _at->recv("OK");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Attempt to enter data mode */
 | 
			
		||||
        success = set_atd(_at); //enter into Data mode with the modem
 | 
			
		||||
        if (!success) {
 | 
			
		||||
            power_down();
 | 
			
		||||
            initialized = false;
 | 
			
		||||
 | 
			
		||||
            /* if we were previously initialized , i.e., not in this particular attempt,
 | 
			
		||||
             * we want to re-initialize */
 | 
			
		||||
            if (!did_init) {
 | 
			
		||||
                goto retry_init;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* shutdown AT parser before notifying application of the failure */
 | 
			
		||||
            shutdown_at_parser();
 | 
			
		||||
 | 
			
		||||
            return NSAPI_ERROR_NO_CONNECTION;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        initialized = true;
 | 
			
		||||
        did_init = true;
 | 
			
		||||
    } else {
 | 
			
		||||
        /* If we were already initialized, we expect to receive NO_CARRIER response
 | 
			
		||||
         * from the modem as we were kicked out of Data mode */
 | 
			
		||||
        _at->recv("NO CARRIER");
 | 
			
		||||
        success = _at->send("AT") && _at->recv("OK");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Attempt to enter data mode */
 | 
			
		||||
    success = set_atd(_at); //enter into Data mode with the modem
 | 
			
		||||
    if (!success) {
 | 
			
		||||
        power_down_modem();
 | 
			
		||||
        initialized = false;
 | 
			
		||||
 | 
			
		||||
        /* if we were previously initialized , i.e., not in this particular attempt,
 | 
			
		||||
         * we want to re-initialize */
 | 
			
		||||
        if (!did_init) {
 | 
			
		||||
            goto retry_init;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* shutdown AT parser before notifying application of the failure */
 | 
			
		||||
        /* This is the success case.
 | 
			
		||||
         * Save RAM, discard AT Parser as we have entered Data mode. */
 | 
			
		||||
        shutdown_at_parser();
 | 
			
		||||
 | 
			
		||||
        return NSAPI_ERROR_NO_CONNECTION;
 | 
			
		||||
    }
 | 
			
		||||
        /* We now want hangup (e.g., DCD) detection if available */
 | 
			
		||||
        enable_hup(true);
 | 
			
		||||
 | 
			
		||||
    /* This is the success case.
 | 
			
		||||
     * Save RAM, discard AT Parser as we have entered Data mode. */
 | 
			
		||||
    shutdown_at_parser();
 | 
			
		||||
        /* Initialize PPP
 | 
			
		||||
         * mbed_ppp_init() is a blocking call, it will block until
 | 
			
		||||
         * connected, or timeout after 30 seconds*/
 | 
			
		||||
        retcode = nsapi_ppp_connect(_fh, _connection_status_cb, _uname, _pwd);
 | 
			
		||||
        if (retcode == NSAPI_ERROR_OK) {
 | 
			
		||||
            dev_info.ppp_connection_up = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    /* Here we would like to attach an interrupt line to DCD pin
 | 
			
		||||
     * We cast back the serial interface from the file handle and set
 | 
			
		||||
     * the DCD line. */
 | 
			
		||||
    BufferedSerial *serial = static_cast<BufferedSerial *>(_fh);
 | 
			
		||||
    serial->set_data_carrier_detect(MDMDCD, MDMDCD_POLARITY);
 | 
			
		||||
    }while(!dev_info.ppp_connection_up && apn_config && *apn_config);
 | 
			
		||||
 | 
			
		||||
    /* Initialize PPP
 | 
			
		||||
     * mbed_ppp_init() is a blocking call, it will block until
 | 
			
		||||
     * connected, or timeout after 30 seconds*/
 | 
			
		||||
    retcode = nsapi_ppp_connect(_fh, _connection_status_cb, _uname, _pwd);
 | 
			
		||||
    if (retcode == NSAPI_ERROR_OK) {
 | 
			
		||||
        dev_info.ppp_connection_up = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if MBED_CONF_REF_CELL_DRV_APN_LOOKUP && !set_credentials_api_used
 | 
			
		||||
    } while(!dev_info.ppp_connection_up && apn_config && *apn_config);
 | 
			
		||||
#endif
 | 
			
		||||
     return retcode;
 | 
			
		||||
    return retcode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -676,7 +678,7 @@ retry_init:
 | 
			
		|||
 * Disconnects from PPP connection only and brings down the underlying network
 | 
			
		||||
 * interface
 | 
			
		||||
 */
 | 
			
		||||
nsapi_error_t ReferenceCellularDriver::disconnect()
 | 
			
		||||
nsapi_error_t PPPCellularInterface::disconnect()
 | 
			
		||||
{
 | 
			
		||||
    nsapi_error_t ret = nsapi_ppp_disconnect(_fh);
 | 
			
		||||
    if (ret == NSAPI_ERROR_OK) {
 | 
			
		||||
| 
						 | 
				
			
			@ -687,27 +689,27 @@ nsapi_error_t ReferenceCellularDriver::disconnect()
 | 
			
		|||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *ReferenceCellularDriver::get_ip_address()
 | 
			
		||||
const char *PPPCellularInterface::get_ip_address()
 | 
			
		||||
{
 | 
			
		||||
    return nsapi_ppp_get_ip_addr(_fh);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *ReferenceCellularDriver::get_netmask()
 | 
			
		||||
const char *PPPCellularInterface::get_netmask()
 | 
			
		||||
{
 | 
			
		||||
    return nsapi_ppp_get_netmask(_fh);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *ReferenceCellularDriver::get_gateway()
 | 
			
		||||
const char *PPPCellularInterface::get_gateway()
 | 
			
		||||
{
 | 
			
		||||
    return nsapi_ppp_get_ip_addr(_fh);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Power down modem
 | 
			
		||||
 *  Uses AT command to do it */
 | 
			
		||||
void ReferenceCellularDriver::power_down_modem()
 | 
			
		||||
void PPPCellularInterface::power_down()
 | 
			
		||||
{
 | 
			
		||||
    modem_power_down(&mdm_object);
 | 
			
		||||
    modem_deinit(&mdm_object);
 | 
			
		||||
    modem_power_down();
 | 
			
		||||
    modem_deinit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -715,10 +717,10 @@ void ReferenceCellularDriver::power_down_modem()
 | 
			
		|||
 *
 | 
			
		||||
 * Enables the GPIO lines to the modem and then wriggles the power line in short pulses.
 | 
			
		||||
 */
 | 
			
		||||
bool ReferenceCellularDriver::power_up_modem()
 | 
			
		||||
bool PPPCellularInterface::power_up()
 | 
			
		||||
{
 | 
			
		||||
    /* Initialize GPIO lines */
 | 
			
		||||
    modem_init(&mdm_object);
 | 
			
		||||
    modem_init();
 | 
			
		||||
    /* Give modem a little time to settle down */
 | 
			
		||||
    wait(0.25);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -726,7 +728,7 @@ bool ReferenceCellularDriver::power_up_modem()
 | 
			
		|||
 | 
			
		||||
    int retry_count = 0;
 | 
			
		||||
    while (true) {
 | 
			
		||||
        modem_power_up(&mdm_object);
 | 
			
		||||
        modem_power_up();
 | 
			
		||||
        /* Modem tends to spit out noise during power up - don't confuse the parser */
 | 
			
		||||
        _at->flush();
 | 
			
		||||
        /* It is mandatory to avoid sending data to the serial port during the first 200 ms
 | 
			
		||||
| 
						 | 
				
			
			@ -771,8 +773,9 @@ failure:
 | 
			
		|||
/**
 | 
			
		||||
 * Get a pointer to the underlying network stack
 | 
			
		||||
 */
 | 
			
		||||
NetworkStack *ReferenceCellularDriver::get_stack()
 | 
			
		||||
NetworkStack *PPPCellularInterface::get_stack()
 | 
			
		||||
{
 | 
			
		||||
    return nsapi_ppp_get_stack();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // NSAPI_PPP_AVAILABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -13,16 +13,14 @@
 | 
			
		|||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef REFERENCE_CELLULAR_DRIVER_
 | 
			
		||||
#define REFERENCE_CELLULAR_DRIVER_
 | 
			
		||||
#ifndef PPP_CELLULAR_INTERFACE_
 | 
			
		||||
#define PPP_CELLULAR_INTERFACE_
 | 
			
		||||
 | 
			
		||||
#include "CellularBase.h"
 | 
			
		||||
#include "platform/ATCmdParser.h"
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
#include "nsapi.h"
 | 
			
		||||
#include "rtos.h"
 | 
			
		||||
#include "FileHandle.h"
 | 
			
		||||
#include "InterruptIn.h"
 | 
			
		||||
#include "ATParser.h"
 | 
			
		||||
#include "PinNames.h"
 | 
			
		||||
 | 
			
		||||
#if NSAPI_PPP_AVAILABLE
 | 
			
		||||
 | 
			
		||||
// Forward declaration
 | 
			
		||||
class NetworkStack;
 | 
			
		||||
| 
						 | 
				
			
			@ -93,16 +91,27 @@ typedef struct {
 | 
			
		|||
    nwk_registration_status_psd reg_status_psd;
 | 
			
		||||
} device_info;
 | 
			
		||||
 | 
			
		||||
/** ReferenceCellularDriver class
 | 
			
		||||
/** PPPCellularInterface class
 | 
			
		||||
 *
 | 
			
		||||
 *  This interface serves as the controller/driver for the Cellular
 | 
			
		||||
 *  modems (tested with UBLOX_C027 and MTS_DRAGONFLY_F411RE).
 | 
			
		||||
 *
 | 
			
		||||
 *  The driver will work with any generic FileHandle, and can be
 | 
			
		||||
 *  derived from in order to provide forms for specific interfaces, as well as
 | 
			
		||||
 *  adding extra power and reset controls alongside the FileHandle.
 | 
			
		||||
 */
 | 
			
		||||
class ReferenceCellularDriver : public CellularInterface {
 | 
			
		||||
class PPPCellularInterface : public CellularBase {
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    ReferenceCellularDriver(PinName tx = MDMTXD, PinName rx = MDMRXD, int baud = MBED_CONF_REF_CELL_DRV_BAUD_RATE, bool debugOn = false);
 | 
			
		||||
    ~ReferenceCellularDriver();
 | 
			
		||||
 | 
			
		||||
    /** Constructor for a generic modem, using a single FileHandle for commands and PPP data.
 | 
			
		||||
     *
 | 
			
		||||
     * The file handle pointer is not accessed within the constructor, only recorded for later
 | 
			
		||||
     * use - this permits a derived class to pass a pointer to a not-yet-constructed member object.
 | 
			
		||||
     */
 | 
			
		||||
    PPPCellularInterface(FileHandle *fh, bool debug = false);
 | 
			
		||||
 | 
			
		||||
    virtual ~PPPCellularInterface();
 | 
			
		||||
 | 
			
		||||
    /** Set the Cellular network credentials
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +148,6 @@ public:
 | 
			
		|||
    virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0,
 | 
			
		||||
                                  const char *uname = 0, const char *pwd = 0);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /** Attempt to connect to the Cellular network
 | 
			
		||||
     *
 | 
			
		||||
     *  Brings up the network interface. Connects to the Cellular Radio
 | 
			
		||||
| 
						 | 
				
			
			@ -148,12 +156,12 @@ public:
 | 
			
		|||
     *
 | 
			
		||||
     *  If the SIM requires a PIN, and it is not set/invalid, NSAPI_ERROR_AUTH_ERROR is returned.
 | 
			
		||||
     *  For APN setup, default behaviour is to use 'internet' as APN string and assuming no authentication
 | 
			
		||||
     *  is required, i.e., username and password are no set. Optionally, a database lookup can be requested
 | 
			
		||||
     *  by turning on the APN database lookup feature. In order to do so, add 'MBED_REF_CELL_DRV_APN_LOOKUP'
 | 
			
		||||
     *  is required, i.e., username and password are not set. Optionally, a database lookup can be requested
 | 
			
		||||
     *  by turning on the APN database lookup feature. In order to do so, add 'MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP'
 | 
			
		||||
     *  in your mbed_app.json. APN database is by no means exhaustive. It contains a short list of some public
 | 
			
		||||
     *  APNs with publicly available usernames and passwords (if required) in some particular countries only.
 | 
			
		||||
     *  Lookup is done using IMSI (International mobile subscriber identifier).
 | 
			
		||||
     *  Please note that even if 'MBED_REF_CELL_DRV_APN_LOOKUP' config option is set, 'set_credentials()' api still
 | 
			
		||||
     *  Please note that even if 'MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP' config option is set, 'set_credentials()' api still
 | 
			
		||||
     *  gets the precedence. If the aforementioned API is not used and the config option is set but no match is found in
 | 
			
		||||
     *  the lookup table then the driver tries to resort to default APN settings.
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			@ -237,8 +245,7 @@ public:
 | 
			
		|||
 | 
			
		||||
private:
 | 
			
		||||
    FileHandle *_fh;
 | 
			
		||||
    ATParser *_at;
 | 
			
		||||
    InterruptIn *_dcd;
 | 
			
		||||
    ATCmdParser *_at;
 | 
			
		||||
    const char *_new_pin;
 | 
			
		||||
    const char *_pin;
 | 
			
		||||
    const char *_apn;
 | 
			
		||||
| 
						 | 
				
			
			@ -246,14 +253,72 @@ private:
 | 
			
		|||
    const char *_pwd;
 | 
			
		||||
    bool _debug_trace_on;
 | 
			
		||||
    Callback<void(nsapi_error_t)> _connection_status_cb;
 | 
			
		||||
    void base_initialization();
 | 
			
		||||
    void setup_at_parser();
 | 
			
		||||
    void shutdown_at_parser();
 | 
			
		||||
    nsapi_error_t initialize_sim_card();
 | 
			
		||||
    nsapi_error_t setup_context_and_credentials();
 | 
			
		||||
    bool power_up_modem();
 | 
			
		||||
    void power_down_modem();
 | 
			
		||||
    bool power_up();
 | 
			
		||||
    void power_down();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    /** 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.
 | 
			
		||||
     *
 | 
			
		||||
     * Meant to be overridden.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void enable_hup(bool enable);
 | 
			
		||||
 | 
			
		||||
    /** Sets the modem up for powering on
 | 
			
		||||
     *
 | 
			
		||||
     *  modem_init() is equivalent to plugging in the device, e.g., attaching power and serial port.
 | 
			
		||||
     *  It is meant to be overridden.
 | 
			
		||||
     *  If the modem is on-board, an implementation of onboard_modem_api.h
 | 
			
		||||
     *  will override this.
 | 
			
		||||
     *  If the the modem is a plugged-in device (i.e., a shield type component), the driver deriving from this
 | 
			
		||||
     *  class will override.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void modem_init();
 | 
			
		||||
 | 
			
		||||
    /** Sets the modem in unplugged state
 | 
			
		||||
     *
 | 
			
		||||
     *  modem_deinit() will be equivalent to pulling the plug off of the device, i.e., detaching power
 | 
			
		||||
     *  and serial port. This puts the modem in lowest power state.
 | 
			
		||||
     *  It is meant to be overridden.
 | 
			
		||||
     *  If the modem is on-board, an implementation of onboard_modem_api.h
 | 
			
		||||
     *  will override this.
 | 
			
		||||
     *  If the the modem is a plugged-in device (i.e., a shield type component), the driver deriving from this
 | 
			
		||||
     *  class will override.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void modem_deinit();
 | 
			
		||||
 | 
			
		||||
    /** Powers up the modem
 | 
			
		||||
     *
 | 
			
		||||
     *  modem_power_up() is equivalent to pressing the soft power button.
 | 
			
		||||
     *  The driver may repeat this if the modem is not responsive to AT commands.
 | 
			
		||||
     *  It is meant to be overridden.
 | 
			
		||||
     *  If the modem is on-board, an implementation of onboard_modem_api.h
 | 
			
		||||
     *  will override this.
 | 
			
		||||
     *  If the the modem is a plugged-in device (i.e., a shield type component), the driver deriving from this
 | 
			
		||||
     *  class will override.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void modem_power_up();
 | 
			
		||||
 | 
			
		||||
    /** Powers down the modem
 | 
			
		||||
     *
 | 
			
		||||
     *  modem_power_down() is equivalent to turning off the modem by button press.
 | 
			
		||||
     *  It is meant to be overridden.
 | 
			
		||||
     *  If the modem is on-board, an implementation of onboard_modem_api.h
 | 
			
		||||
     *  will override this.
 | 
			
		||||
     *  If the the modem is a plugged-in device (i.e., a shield type component), the driver deriving from this
 | 
			
		||||
     *  class will override.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void modem_power_down();
 | 
			
		||||
 | 
			
		||||
    /** Provide access to the underlying stack
 | 
			
		||||
     *
 | 
			
		||||
     *  @return The underlying network stack
 | 
			
		||||
| 
						 | 
				
			
			@ -274,4 +339,6 @@ protected:
 | 
			
		|||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //REFERENCE_CELLULAR_DRIVER_
 | 
			
		||||
#endif //NSAPI_PPP_AVAILABLE
 | 
			
		||||
 | 
			
		||||
#endif //PPP_CELLULAR_INTERFACE_
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
/* Copyright (c) 2017 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include "UARTCellularInterface.h"
 | 
			
		||||
 | 
			
		||||
#if NSAPI_PPP_AVAILABLE
 | 
			
		||||
 | 
			
		||||
UARTCellularInterface::UARTCellularInterface(PinName txd, PinName rxd, PinName dcd, PinName rts, PinName cts, PinName ri,
 | 
			
		||||
                                             PinName dtr, PinName dsr, int baud, bool active_high, bool debug) :
 | 
			
		||||
                                                      PPPCellularInterface(&_serial, debug),
 | 
			
		||||
                                                      _serial(txd, rxd, baud)
 | 
			
		||||
{
 | 
			
		||||
    _dcd_pin = dcd;
 | 
			
		||||
    _active_high = active_high;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UARTCellularInterface::~UARTCellularInterface()
 | 
			
		||||
{
 | 
			
		||||
    //do nothing
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UARTCellularInterface::enable_hup(bool enable)
 | 
			
		||||
{
 | 
			
		||||
    _serial.set_data_carrier_detect(enable ? _dcd_pin : NC, _active_high);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // NSAPI_PPP_AVAILABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
/* Copyright (c) 2017 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef UART_CELLULAR_INTERFACE_
 | 
			
		||||
#define UART_CELLULAR_INTERFACE_
 | 
			
		||||
 | 
			
		||||
#include "PPPCellularInterface.h"
 | 
			
		||||
#include "UARTSerial.h"
 | 
			
		||||
 | 
			
		||||
#if NSAPI_PPP_AVAILABLE
 | 
			
		||||
 | 
			
		||||
/** UARTCellularInterface class
 | 
			
		||||
 *
 | 
			
		||||
 *  This interface serves as the controller/driver for Cellular
 | 
			
		||||
 *  modems attached via a UART (tested with UBLOX_C027 and MTS_DRAGONFLY_F411RE).
 | 
			
		||||
 *
 | 
			
		||||
 *  It constructs a FileHandle and passes it back to its base class as well as overrides
 | 
			
		||||
 *  enable_hup() in the base class.
 | 
			
		||||
 */
 | 
			
		||||
class UARTCellularInterface : public PPPCellularInterface {
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    UARTCellularInterface(PinName tx, PinName rx, PinName dcd = NC, PinName rts = NC, PinName cts = NC, PinName ri = NC,
 | 
			
		||||
                             PinName dtr = NC, PinName dsr = NC, int baud = MBED_CONF_PPP_CELL_IFACE_BAUD_RATE,
 | 
			
		||||
                             bool active_high = false,
 | 
			
		||||
                             bool debug = false);
 | 
			
		||||
 | 
			
		||||
    virtual ~UARTCellularInterface();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    UARTSerial _serial;
 | 
			
		||||
    PinName _dcd_pin;
 | 
			
		||||
    bool _active_high;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    /** 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);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //NSAPI_PPP_AVAILABLE
 | 
			
		||||
 | 
			
		||||
#endif //UART_CELLULAR_INTERFACE_
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +1,9 @@
 | 
			
		|||
{
 | 
			
		||||
	"name": "ref-cell-drv", 
 | 
			
		||||
	"name": "ppp-cell-iface", 
 | 
			
		||||
		"config": {
 | 
			
		||||
			"baud-rate": 115200,
 | 
			
		||||
			"apn-lookup": false,
 | 
			
		||||
			"at-parser-buffer-size": 256,
 | 
			
		||||
			"at-parser-timeout": 8000
 | 
			
		||||
	},
 | 
			
		||||
	"target_overrides": {
 | 
			
		||||
		"*": {
 | 
			
		||||
			"target.features_add": ["COMMON_PAL"]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -14,42 +14,33 @@
 | 
			
		|||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ONBOARD_MODEM_API_H_
 | 
			
		||||
#define ONBOARD_MODEM_API_H_
 | 
			
		||||
 | 
			
		||||
#ifndef MODEM_API_H_
 | 
			
		||||
#define MODEM_API_H_
 | 
			
		||||
 | 
			
		||||
/** modem_api is a standardizing API for Modem type devices under mbed-os.
 | 
			
		||||
/** onboard_modem_api is a standardizing API for Modem type devices under mbed-os.
 | 
			
		||||
 * It provides a simple hardware abstraction layer on top of the modem drivers
 | 
			
		||||
 * written for mbed-os.
 | 
			
		||||
 *
 | 
			
		||||
 * It is required from the engineers porting any modem type device (e.g., Cellular or Wifi)
 | 
			
		||||
 * It is required from the engineers porting any modem type device (e.g., Cellular)
 | 
			
		||||
 * to provide an implementation of this API in their respective target folder as well as
 | 
			
		||||
 * usage of standard PinNames (in PinNames.h) is highly encouraged. For example,
 | 
			
		||||
 * usage of standard PinNames (in PinNames.h) is required. For example,
 | 
			
		||||
 *
 | 
			
		||||
 *   MDMTXD = P0_15, // Transmit Data
 | 
			
		||||
 *   MDMRXD = P0_16, // Receive Data
 | 
			
		||||
 *   MDMCTS = P0_17, // Clear to Send
 | 
			
		||||
 *   MDMDCD = P0_18, // Data Carrier Detect
 | 
			
		||||
 *   MDMDSR = P0_19, // Data Set Ready
 | 
			
		||||
 *   MDMDTR = P0_20, // Data Terminal Ready (set high or use handshake)
 | 
			
		||||
 *   MDMRI  = P0_21, // Ring Indicator
 | 
			
		||||
 *   MDMRTS = P0_22, // Request to Send (set high or use handshake)
 | 
			
		||||
 *   MDMTXD = P0_15,    // Transmit Data
 | 
			
		||||
 *   MDMRXD = P0_16,    // Receive Data
 | 
			
		||||
 *   MDMCTS = P0_17,    // Clear to Send
 | 
			
		||||
 *   MDMDCD = P0_18,    // Data Carrier Detect
 | 
			
		||||
 *   MDMDSR = P0_19,    // Data Set Ready
 | 
			
		||||
 *   MDMDTR = P0_20,    // Data Terminal Ready (set high or use handshake)
 | 
			
		||||
 *   MDMRI  = P0_21,    // Ring Indicator
 | 
			
		||||
 *   MDMRTS = P0_22,    // Request to Send (set high or use handshake)
 | 
			
		||||
 *
 | 
			
		||||
 *   MDM_PIN_POLARITY must also be defined as 0 (active low) or 1 (active high).
 | 
			
		||||
 *
 | 
			
		||||
 *   NOTE: This API should only be used when the modem exists on-board, i.e., the modem is
 | 
			
		||||
 *         NOT a plugged-in component.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef DEVICE_MODEM
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    POWER_READY=1,
 | 
			
		||||
    POWERED_ON,
 | 
			
		||||
    POWERED_OFF,
 | 
			
		||||
    LOWEST_POWER_STATE
 | 
			
		||||
} modem_state;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * modem_s is defined in objects.h inside the TARGET folder
 | 
			
		||||
 */
 | 
			
		||||
typedef struct modem_s modem_t;
 | 
			
		||||
#if MODEM_ON_BOARD
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
| 
						 | 
				
			
			@ -59,30 +50,30 @@ extern "C" {
 | 
			
		|||
 *  modem_init() will be equivalent to plugging in the device, i.e.,
 | 
			
		||||
 *  attaching power and serial port.
 | 
			
		||||
 */
 | 
			
		||||
void modem_init(modem_t *obj);
 | 
			
		||||
void onboard_modem_init(void);
 | 
			
		||||
 | 
			
		||||
/** Sets the modem in unplugged state
 | 
			
		||||
 *  modem_deinit() will be equivalent to pulling the plug off of the device, i.e.,
 | 
			
		||||
 *  detaching power and serial port.
 | 
			
		||||
 *  This puts the modem in lowest power state.
 | 
			
		||||
 */
 | 
			
		||||
void modem_deinit(modem_t *obj);
 | 
			
		||||
void onboard_modem_deinit(void);
 | 
			
		||||
 | 
			
		||||
/** Powers up the modem
 | 
			
		||||
 *  modem_power_up() will be equivalent to pressing the soft power button.
 | 
			
		||||
 *  The driver may repeat this if the modem is not responsive to AT commands.
 | 
			
		||||
 | 
			
		||||
 */
 | 
			
		||||
void modem_power_up(modem_t *obj);
 | 
			
		||||
void onboard_modem_power_up(void);
 | 
			
		||||
 | 
			
		||||
/** Powers down the modem
 | 
			
		||||
 *  modem_power_down() will be equivalent to turning off the modem by button press.
 | 
			
		||||
 */
 | 
			
		||||
void modem_power_down(modem_t *obj);
 | 
			
		||||
void onboard_modem_power_down(void);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* DEVICE_MODEM*/
 | 
			
		||||
#endif /* MODEM_API_H_ */
 | 
			
		||||
#endif /* MODEM_ON_BOARD*/
 | 
			
		||||
#endif /* ONBOARD_MODEM_API_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -125,6 +125,7 @@ static const APN_t apnlut[] = {
 | 
			
		|||
    { /* Vodafone */ "234-15",  _APN("internet","web","web")          /* contract */
 | 
			
		||||
                                _APN("pp.vodafone.co.uk","wap","wap")  /* pre-pay */ },
 | 
			
		||||
    { /* Three */    "234-20",  _APN("three.co.uk",,) },
 | 
			
		||||
    { /* Jersey */   "234-50",  _APN("jtm2m",,) /* as used on u-blox C030 U201 boards */ },
 | 
			
		||||
 | 
			
		||||
// 310 United States of America - US
 | 
			
		||||
    { /* T-Mobile */ "310-026,260,490",
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +18,7 @@
 | 
			
		|||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "ATParser.h"
 | 
			
		||||
#include "ATCmdParser.h"
 | 
			
		||||
#include "mbed_poll.h"
 | 
			
		||||
#include "mbed_debug.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +37,7 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
// getc/putc handling with timeouts
 | 
			
		||||
int ATParser::putc(char c)
 | 
			
		||||
int ATCmdParser::putc(char c)
 | 
			
		||||
{
 | 
			
		||||
    pollfh fhs;
 | 
			
		||||
    fhs.fh = _fh;
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +51,7 @@ int ATParser::putc(char c)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ATParser::getc()
 | 
			
		||||
int ATCmdParser::getc()
 | 
			
		||||
{
 | 
			
		||||
    pollfh fhs;
 | 
			
		||||
    fhs.fh = _fh;
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +66,7 @@ int ATParser::getc()
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ATParser::flush()
 | 
			
		||||
void ATCmdParser::flush()
 | 
			
		||||
{
 | 
			
		||||
    while (_fh->readable()) {
 | 
			
		||||
        unsigned char ch;
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ void ATParser::flush()
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
// read/write handling with timeouts
 | 
			
		||||
int ATParser::write(const char *data, int size)
 | 
			
		||||
int ATCmdParser::write(const char *data, int size)
 | 
			
		||||
{
 | 
			
		||||
    int i = 0;
 | 
			
		||||
    for ( ; i < size; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ int ATParser::write(const char *data, int size)
 | 
			
		|||
    return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ATParser::read(char *data, int size)
 | 
			
		||||
int ATCmdParser::read(char *data, int size)
 | 
			
		||||
{
 | 
			
		||||
    int i = 0;
 | 
			
		||||
    for ( ; i < size; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +102,7 @@ int ATParser::read(char *data, int size)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
// printf/scanf handling
 | 
			
		||||
int ATParser::vprintf(const char *format, va_list args)
 | 
			
		||||
int ATCmdParser::vprintf(const char *format, va_list args)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    if (vsprintf(_buffer, format, args) < 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ int ATParser::vprintf(const char *format, va_list args)
 | 
			
		|||
    return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ATParser::vscanf(const char *format, va_list args)
 | 
			
		||||
int ATCmdParser::vscanf(const char *format, va_list args)
 | 
			
		||||
{
 | 
			
		||||
    // Since format is const, we need to copy it into our buffer to
 | 
			
		||||
    // add the line's null terminator and clobber value-matches with asterisks.
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +181,7 @@ int ATParser::vscanf(const char *format, va_list args)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
// Command parsing with line handling
 | 
			
		||||
bool ATParser::vsend(const char *command, va_list args)
 | 
			
		||||
bool ATCmdParser::vsend(const char *command, va_list args)
 | 
			
		||||
{
 | 
			
		||||
    // Create and send command
 | 
			
		||||
    if (vsprintf(_buffer, command, args) < 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -205,7 +205,7 @@ bool ATParser::vsend(const char *command, va_list args)
 | 
			
		|||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ATParser::vrecv(const char *response, va_list args)
 | 
			
		||||
bool ATCmdParser::vrecv(const char *response, va_list args)
 | 
			
		||||
{
 | 
			
		||||
restart:
 | 
			
		||||
    _aborted = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -329,7 +329,7 @@ restart:
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// Mapping to vararg functions
 | 
			
		||||
int ATParser::printf(const char *format, ...)
 | 
			
		||||
int ATCmdParser::printf(const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start(args, format);
 | 
			
		||||
| 
						 | 
				
			
			@ -338,7 +338,7 @@ int ATParser::printf(const char *format, ...)
 | 
			
		|||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ATParser::scanf(const char *format, ...)
 | 
			
		||||
int ATCmdParser::scanf(const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start(args, format);
 | 
			
		||||
| 
						 | 
				
			
			@ -347,7 +347,7 @@ int ATParser::scanf(const char *format, ...)
 | 
			
		|||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ATParser::send(const char *command, ...)
 | 
			
		||||
bool ATCmdParser::send(const char *command, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start(args, command);
 | 
			
		||||
| 
						 | 
				
			
			@ -356,7 +356,7 @@ bool ATParser::send(const char *command, ...)
 | 
			
		|||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ATParser::recv(const char *response, ...)
 | 
			
		||||
bool ATCmdParser::recv(const char *response, ...)
 | 
			
		||||
{
 | 
			
		||||
    va_list args;
 | 
			
		||||
    va_start(args, response);
 | 
			
		||||
| 
						 | 
				
			
			@ -366,7 +366,7 @@ bool ATParser::recv(const char *response, ...)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// oob registration
 | 
			
		||||
void ATParser::oob(const char *prefix, Callback<void()> cb)
 | 
			
		||||
void ATCmdParser::oob(const char *prefix, Callback<void()> cb)
 | 
			
		||||
{
 | 
			
		||||
    struct oob *oob = new struct oob;
 | 
			
		||||
    oob->len = strlen(prefix);
 | 
			
		||||
| 
						 | 
				
			
			@ -376,7 +376,7 @@ void ATParser::oob(const char *prefix, Callback<void()> cb)
 | 
			
		|||
    _oobs = oob;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ATParser::abort()
 | 
			
		||||
void ATCmdParser::abort()
 | 
			
		||||
{
 | 
			
		||||
    _aborted = true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,297 @@
 | 
			
		|||
/* Copyright (c) 2017 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * @section DESCRIPTION
 | 
			
		||||
 *
 | 
			
		||||
 * Parser for the AT command syntax
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#ifndef MBED_ATCMDPARSER_H
 | 
			
		||||
#define MBED_ATCMDPARSER_H
 | 
			
		||||
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
#include <cstdarg>
 | 
			
		||||
#include "Callback.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parser class for parsing AT commands
 | 
			
		||||
 *
 | 
			
		||||
 * Here are some examples:
 | 
			
		||||
 * @code
 | 
			
		||||
 * ATCmdParser at = ATCmdParser(serial, "\r\n");
 | 
			
		||||
 * int value;
 | 
			
		||||
 * char buffer[100];
 | 
			
		||||
 *
 | 
			
		||||
 * at.send("AT") && at.recv("OK");
 | 
			
		||||
 * at.send("AT+CWMODE=%d", 3) && at.recv("OK");
 | 
			
		||||
 * at.send("AT+CWMODE?") && at.recv("+CWMODE:%d\r\nOK", &value);
 | 
			
		||||
 * at.recv("+IPD,%d:", &value);
 | 
			
		||||
 * at.read(buffer, value);
 | 
			
		||||
 * at.recv("OK");
 | 
			
		||||
 * @endcode
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
 | 
			
		||||
class ATCmdParser
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
    // File handle
 | 
			
		||||
    // Not owned by ATCmdParser
 | 
			
		||||
    FileHandle *_fh;
 | 
			
		||||
 | 
			
		||||
    int _buffer_size;
 | 
			
		||||
    char *_buffer;
 | 
			
		||||
    int _timeout;
 | 
			
		||||
 | 
			
		||||
    // Parsing information
 | 
			
		||||
    const char *_output_delimiter;
 | 
			
		||||
    int _output_delim_size;
 | 
			
		||||
    char _in_prev;
 | 
			
		||||
    bool _dbg_on;
 | 
			
		||||
    bool _aborted;
 | 
			
		||||
 | 
			
		||||
    struct oob {
 | 
			
		||||
        unsigned len;
 | 
			
		||||
        const char *prefix;
 | 
			
		||||
        mbed::Callback<void()> cb;
 | 
			
		||||
        oob *next;
 | 
			
		||||
    };
 | 
			
		||||
    oob *_oobs;
 | 
			
		||||
 | 
			
		||||
    // Prohibiting use of of copy constructor
 | 
			
		||||
    ATCmdParser(const ATCmdParser &);
 | 
			
		||||
    // Prohibiting copy assignment Operator
 | 
			
		||||
    ATCmdParser &operator=(const ATCmdParser &);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor
 | 
			
		||||
     *
 | 
			
		||||
     * @param serial         serial interface to use for AT commands
 | 
			
		||||
     * @param buffer_size    size of internal buffer for transaction
 | 
			
		||||
     * @param timeout        timeout of the connection
 | 
			
		||||
     * @param debug          turns on/off debug output for AT commands
 | 
			
		||||
     */
 | 
			
		||||
    ATCmdParser(FileHandle *fh, const char *output_delimiter = "\r",
 | 
			
		||||
             int buffer_size = 256, int timeout = 8000, bool debug = false)
 | 
			
		||||
            : _fh(fh), _buffer_size(buffer_size), _in_prev(0), _oobs(NULL)
 | 
			
		||||
    {
 | 
			
		||||
        _buffer = new char[buffer_size];
 | 
			
		||||
        set_timeout(timeout);
 | 
			
		||||
        set_delimiter(output_delimiter);
 | 
			
		||||
        debug_on(debug);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Destructor
 | 
			
		||||
     */
 | 
			
		||||
    ~ATCmdParser()
 | 
			
		||||
    {
 | 
			
		||||
        while (_oobs) {
 | 
			
		||||
            struct oob *oob = _oobs;
 | 
			
		||||
            _oobs = oob->next;
 | 
			
		||||
            delete oob;
 | 
			
		||||
        }
 | 
			
		||||
        delete[] _buffer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Allows timeout to be changed between commands
 | 
			
		||||
     *
 | 
			
		||||
     * @param timeout timeout of the connection
 | 
			
		||||
     */
 | 
			
		||||
    void set_timeout(int timeout)
 | 
			
		||||
    {
 | 
			
		||||
        _timeout = timeout;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * For backwards compatibility.
 | 
			
		||||
     *
 | 
			
		||||
     * Please use set_timeout(int) API only from now on.
 | 
			
		||||
     * Allows timeout to be changed between commands
 | 
			
		||||
     *
 | 
			
		||||
     * @param timeout timeout of the connection
 | 
			
		||||
     */
 | 
			
		||||
    MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with set_timeout for consistency")
 | 
			
		||||
    void setTimeout(int timeout)
 | 
			
		||||
    {
 | 
			
		||||
        set_timeout(timeout);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets string of characters to use as line delimiters
 | 
			
		||||
     *
 | 
			
		||||
     * @param delimiter string of characters to use as line delimiters
 | 
			
		||||
     */
 | 
			
		||||
    void set_delimiter(const char *output_delimiter)
 | 
			
		||||
    {
 | 
			
		||||
        _output_delimiter = output_delimiter;
 | 
			
		||||
        _output_delim_size = strlen(output_delimiter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * For backwards compatibility.
 | 
			
		||||
     *
 | 
			
		||||
     * Please use set_delimiter(const char *) API only from now on.
 | 
			
		||||
     * Sets string of characters to use as line delimiters
 | 
			
		||||
     *
 | 
			
		||||
     * @param delimiter string of characters to use as line delimiters
 | 
			
		||||
     */
 | 
			
		||||
    MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with set_delimiter for consistency")
 | 
			
		||||
    void setDelimiter(const char *output_delimiter)
 | 
			
		||||
    {
 | 
			
		||||
        set_delimiter(output_delimiter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Allows traces from modem to be turned on or off
 | 
			
		||||
     *
 | 
			
		||||
     * @param on set as 1 to turn on traces and vice versa.
 | 
			
		||||
     */
 | 
			
		||||
    void debug_on(uint8_t on)
 | 
			
		||||
    {
 | 
			
		||||
        _dbg_on = (on) ? 1 : 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * For backwards compatibility.
 | 
			
		||||
     *
 | 
			
		||||
     * Allows traces from modem to be turned on or off
 | 
			
		||||
     *
 | 
			
		||||
     * @param on set as 1 to turn on traces and vice versa.
 | 
			
		||||
     */
 | 
			
		||||
    MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with debug_on for consistency")
 | 
			
		||||
    void debugOn(uint8_t on)
 | 
			
		||||
    {
 | 
			
		||||
        debug_on(on);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sends an AT command
 | 
			
		||||
     *
 | 
			
		||||
     * Sends a formatted command using printf style formatting
 | 
			
		||||
     * @see ::printf
 | 
			
		||||
     *
 | 
			
		||||
     * @param command printf-like format string of command to send which
 | 
			
		||||
     *                is appended with a newline
 | 
			
		||||
     * @param ... all printf-like arguments to insert into command
 | 
			
		||||
     * @return true only if command is successfully sent
 | 
			
		||||
     */
 | 
			
		||||
    bool send(const char *command, ...) MBED_PRINTF_METHOD(1,2);
 | 
			
		||||
 | 
			
		||||
    bool vsend(const char *command, va_list args);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Receive an AT response
 | 
			
		||||
     *
 | 
			
		||||
     * Receives a formatted response using scanf style formatting
 | 
			
		||||
     * @see ::scanf
 | 
			
		||||
     *
 | 
			
		||||
     * Responses are parsed line at a time.
 | 
			
		||||
     * Any received data that does not match the response is ignored until
 | 
			
		||||
     * a timeout occurs.
 | 
			
		||||
     *
 | 
			
		||||
     * @param response scanf-like format string of response to expect
 | 
			
		||||
     * @param ... all scanf-like arguments to extract from response
 | 
			
		||||
     * @return true only if response is successfully matched
 | 
			
		||||
     */
 | 
			
		||||
    bool recv(const char *response, ...) MBED_SCANF_METHOD(1,2);
 | 
			
		||||
 | 
			
		||||
    bool vrecv(const char *response, va_list args);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Write a single byte to the underlying stream
 | 
			
		||||
     *
 | 
			
		||||
     * @param c The byte to write
 | 
			
		||||
     * @return The byte that was written or -1 during a timeout
 | 
			
		||||
     */
 | 
			
		||||
    int putc(char c);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a single byte from the underlying stream
 | 
			
		||||
     *
 | 
			
		||||
     * @return The byte that was read or -1 during a timeout
 | 
			
		||||
     */
 | 
			
		||||
    int getc();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Write an array of bytes to the underlying stream
 | 
			
		||||
     *
 | 
			
		||||
     * @param data the array of bytes to write
 | 
			
		||||
     * @param size number of bytes to write
 | 
			
		||||
     * @return number of bytes written or -1 on failure
 | 
			
		||||
     */
 | 
			
		||||
    int write(const char *data, int size);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read an array of bytes from the underlying stream
 | 
			
		||||
     *
 | 
			
		||||
     * @param data the destination for the read bytes
 | 
			
		||||
     * @param size number of bytes to read
 | 
			
		||||
     * @return number of bytes read or -1 on failure
 | 
			
		||||
     */
 | 
			
		||||
    int read(char *data, int size);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Direct printf to underlying stream
 | 
			
		||||
     * @see ::printf
 | 
			
		||||
     *
 | 
			
		||||
     * @param format format string to pass to printf
 | 
			
		||||
     * @param ... arguments to printf
 | 
			
		||||
     * @return number of bytes written or -1 on failure
 | 
			
		||||
     */
 | 
			
		||||
    int printf(const char *format, ...) MBED_PRINTF_METHOD(1,2);
 | 
			
		||||
 | 
			
		||||
    int vprintf(const char *format, va_list args);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Direct scanf on underlying stream
 | 
			
		||||
     * @see ::scanf
 | 
			
		||||
     *
 | 
			
		||||
     * @param format format string to pass to scanf
 | 
			
		||||
     * @param ... arguments to scanf
 | 
			
		||||
     * @return number of bytes read or -1 on failure
 | 
			
		||||
     */
 | 
			
		||||
    int scanf(const char *format, ...) MBED_SCANF_METHOD(1,2);
 | 
			
		||||
 | 
			
		||||
    int vscanf(const char *format, va_list args);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attach a callback for out-of-band data
 | 
			
		||||
     *
 | 
			
		||||
     * @param prefix string on when to initiate callback
 | 
			
		||||
     * @param func callback to call when string is read
 | 
			
		||||
     * @note out-of-band data is only processed during a scanf call
 | 
			
		||||
     */
 | 
			
		||||
    void oob(const char *prefix, mbed::Callback<void()> func);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Flushes the underlying stream
 | 
			
		||||
     */
 | 
			
		||||
    void flush();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Abort current recv
 | 
			
		||||
     *
 | 
			
		||||
     * Can be called from oob handler to interrupt the current
 | 
			
		||||
     * recv operation.
 | 
			
		||||
     */
 | 
			
		||||
    void abort();
 | 
			
		||||
};
 | 
			
		||||
} //namespace mbed
 | 
			
		||||
 | 
			
		||||
#endif //MBED_ATCMDPARSER_H
 | 
			
		||||
| 
						 | 
				
			
			@ -1,290 +0,0 @@
 | 
			
		|||
/* Copyright (c) 2017 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * @section DESCRIPTION
 | 
			
		||||
 *
 | 
			
		||||
 * Parser for the AT command syntax
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#ifndef MBED_ATPARSER_H
 | 
			
		||||
#define MBED_ATPARSER_H
 | 
			
		||||
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
#include <cstdarg>
 | 
			
		||||
#include "BufferedSerial.h"
 | 
			
		||||
#include "Callback.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* Parser class for parsing AT commands
 | 
			
		||||
*
 | 
			
		||||
* Here are some examples:
 | 
			
		||||
* @code
 | 
			
		||||
* ATParser at = ATParser(serial, "\r\n");
 | 
			
		||||
* int value;
 | 
			
		||||
* char buffer[100];
 | 
			
		||||
*
 | 
			
		||||
* at.send("AT") && at.recv("OK");
 | 
			
		||||
* at.send("AT+CWMODE=%d", 3) && at.recv("OK");
 | 
			
		||||
* at.send("AT+CWMODE?") && at.recv("+CWMODE:%d\r\nOK", &value);
 | 
			
		||||
* at.recv("+IPD,%d:", &value);
 | 
			
		||||
* at.read(buffer, value);
 | 
			
		||||
* at.recv("OK");
 | 
			
		||||
* @endcode
 | 
			
		||||
*/
 | 
			
		||||
class ATParser
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
    // File handle
 | 
			
		||||
    // Not owned by ATParser
 | 
			
		||||
    FileHandle *_fh;
 | 
			
		||||
 | 
			
		||||
    int _buffer_size;
 | 
			
		||||
    char *_buffer;
 | 
			
		||||
    int _timeout;
 | 
			
		||||
 | 
			
		||||
    // Parsing information
 | 
			
		||||
    const char *_output_delimiter;
 | 
			
		||||
    int _output_delim_size;
 | 
			
		||||
    char _in_prev;
 | 
			
		||||
    bool _dbg_on;
 | 
			
		||||
    bool _aborted;
 | 
			
		||||
 | 
			
		||||
    struct oob {
 | 
			
		||||
        unsigned len;
 | 
			
		||||
        const char *prefix;
 | 
			
		||||
        mbed::Callback<void()> cb;
 | 
			
		||||
        oob *next;
 | 
			
		||||
    };
 | 
			
		||||
    oob *_oobs;
 | 
			
		||||
 | 
			
		||||
    // Prohibiting use of of copy constructor
 | 
			
		||||
    ATParser(const ATParser &);
 | 
			
		||||
    // Prohibiting copy assignment Operator
 | 
			
		||||
    ATParser &operator=(const ATParser &);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    /**
 | 
			
		||||
    * Constructor
 | 
			
		||||
    *
 | 
			
		||||
    * @param serial         serial interface to use for AT commands
 | 
			
		||||
    * @param buffer_size    size of internal buffer for transaction
 | 
			
		||||
    * @param timeout        timeout of the connection
 | 
			
		||||
    * @param debug          turns on/off debug output for AT commands
 | 
			
		||||
    */
 | 
			
		||||
    ATParser(FileHandle *fh, const char *output_delimiter="\r", int buffer_size = 256, int timeout = 8000, bool debug = false) :
 | 
			
		||||
        _fh(fh),
 | 
			
		||||
        _buffer_size(buffer_size),
 | 
			
		||||
        _in_prev(0),
 | 
			
		||||
        _oobs(NULL) {
 | 
			
		||||
        _buffer = new char[buffer_size];
 | 
			
		||||
        set_timeout(timeout);
 | 
			
		||||
        set_delimiter(output_delimiter);
 | 
			
		||||
        debug_on(debug);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Destructor
 | 
			
		||||
    */
 | 
			
		||||
    ~ATParser() {
 | 
			
		||||
        while (_oobs) {
 | 
			
		||||
            struct oob *oob = _oobs;
 | 
			
		||||
            _oobs = oob->next;
 | 
			
		||||
            delete oob;
 | 
			
		||||
        }
 | 
			
		||||
        delete [] _buffer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Allows timeout to be changed between commands
 | 
			
		||||
    *
 | 
			
		||||
    * @param timeout timeout of the connection
 | 
			
		||||
    */
 | 
			
		||||
    void set_timeout(int timeout) {
 | 
			
		||||
        _timeout = timeout;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * For backwards compatibility.
 | 
			
		||||
    *
 | 
			
		||||
    * Please use set_timeout(int) API only from now on.
 | 
			
		||||
    * Allows timeout to be changed between commands
 | 
			
		||||
    *
 | 
			
		||||
    * @param timeout timeout of the connection
 | 
			
		||||
    */
 | 
			
		||||
    MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with set_timeout for consistency")
 | 
			
		||||
    void setTimeout(int timeout) {
 | 
			
		||||
        set_timeout(timeout);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets string of characters to use as line delimiters
 | 
			
		||||
     *
 | 
			
		||||
     * @param delimiter string of characters to use as line delimiters
 | 
			
		||||
     */
 | 
			
		||||
    void set_delimiter(const char *output_delimiter)
 | 
			
		||||
    {
 | 
			
		||||
        _output_delimiter = output_delimiter;
 | 
			
		||||
        _output_delim_size = strlen(output_delimiter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * For backwards compatibility.
 | 
			
		||||
     *
 | 
			
		||||
     * Please use set_delimiter(const char *) API only from now on.
 | 
			
		||||
     * Sets string of characters to use as line delimiters
 | 
			
		||||
     *
 | 
			
		||||
     * @param delimiter string of characters to use as line delimiters
 | 
			
		||||
     */
 | 
			
		||||
    MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with set_delimiter for consistency")
 | 
			
		||||
    void setDelimiter(const char *output_delimiter)
 | 
			
		||||
    {
 | 
			
		||||
        set_delimiter(output_delimiter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Allows echo to be on or off
 | 
			
		||||
     *
 | 
			
		||||
     * @param echo 1 for echo and 0 turns it off
 | 
			
		||||
     */
 | 
			
		||||
    void debug_on(uint8_t on) {
 | 
			
		||||
        _dbg_on = (on) ? 1 : 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * For backwards compatibility.
 | 
			
		||||
     *
 | 
			
		||||
     * Allows echo to be on or off
 | 
			
		||||
     *
 | 
			
		||||
     * @param echo 1 for echo and 0 turns it off
 | 
			
		||||
     */
 | 
			
		||||
    MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with debug_on for consistency")
 | 
			
		||||
    void debugOn(uint8_t on) {
 | 
			
		||||
        debug_on(on);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Sends an AT command
 | 
			
		||||
    *
 | 
			
		||||
    * Sends a formatted command using printf style formatting
 | 
			
		||||
    * @see ::printf
 | 
			
		||||
    *
 | 
			
		||||
    * @param command printf-like format string of command to send which
 | 
			
		||||
    *                is appended with a newline
 | 
			
		||||
    * @param ... all printf-like arguments to insert into command
 | 
			
		||||
    * @return true only if command is successfully sent
 | 
			
		||||
    */
 | 
			
		||||
    bool send(const char *command, ...) MBED_PRINTF_METHOD(1,2);
 | 
			
		||||
 | 
			
		||||
    bool vsend(const char *command, va_list args);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Receive an AT response
 | 
			
		||||
    *
 | 
			
		||||
    * Receives a formatted response using scanf style formatting
 | 
			
		||||
    * @see ::scanf
 | 
			
		||||
    *
 | 
			
		||||
    * Responses are parsed line at a time.
 | 
			
		||||
    * Any received data that does not match the response is ignored until
 | 
			
		||||
    * a timeout occurs.
 | 
			
		||||
    *
 | 
			
		||||
    * @param response scanf-like format string of response to expect
 | 
			
		||||
    * @param ... all scanf-like arguments to extract from response
 | 
			
		||||
    * @return true only if response is successfully matched
 | 
			
		||||
    */
 | 
			
		||||
    bool recv(const char *response, ...) MBED_SCANF_METHOD(1,2);
 | 
			
		||||
 | 
			
		||||
    bool vrecv(const char *response, va_list args);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Write a single byte to the underlying stream
 | 
			
		||||
    *
 | 
			
		||||
    * @param c The byte to write
 | 
			
		||||
    * @return The byte that was written or -1 during a timeout
 | 
			
		||||
    */
 | 
			
		||||
    int putc(char c);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Get a single byte from the underlying stream
 | 
			
		||||
    *
 | 
			
		||||
    * @return The byte that was read or -1 during a timeout
 | 
			
		||||
    */
 | 
			
		||||
    int getc();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Write an array of bytes to the underlying stream
 | 
			
		||||
    *
 | 
			
		||||
    * @param data the array of bytes to write
 | 
			
		||||
    * @param size number of bytes to write
 | 
			
		||||
    * @return number of bytes written or -1 on failure
 | 
			
		||||
    */
 | 
			
		||||
    int write(const char *data, int size);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Read an array of bytes from the underlying stream
 | 
			
		||||
    *
 | 
			
		||||
    * @param data the destination for the read bytes
 | 
			
		||||
    * @param size number of bytes to read
 | 
			
		||||
    * @return number of bytes read or -1 on failure
 | 
			
		||||
    */
 | 
			
		||||
    int read(char *data, int size);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Direct printf to underlying stream
 | 
			
		||||
    * @see ::printf
 | 
			
		||||
    *
 | 
			
		||||
    * @param format format string to pass to printf
 | 
			
		||||
    * @param ... arguments to printf
 | 
			
		||||
    * @return number of bytes written or -1 on failure
 | 
			
		||||
    */
 | 
			
		||||
    int printf(const char *format, ...) MBED_PRINTF_METHOD(1,2);
 | 
			
		||||
 | 
			
		||||
    int vprintf(const char *format, va_list args);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Direct scanf on underlying stream
 | 
			
		||||
    * @see ::scanf
 | 
			
		||||
    *
 | 
			
		||||
    * @param format format string to pass to scanf
 | 
			
		||||
    * @param ... arguments to scanf
 | 
			
		||||
    * @return number of bytes read or -1 on failure
 | 
			
		||||
    */
 | 
			
		||||
    int scanf(const char *format, ...) MBED_SCANF_METHOD(1,2);
 | 
			
		||||
 | 
			
		||||
    int vscanf(const char *format, va_list args);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Attach a callback for out-of-band data
 | 
			
		||||
    * 
 | 
			
		||||
    * @param prefix string on when to initiate callback
 | 
			
		||||
    * @param func callback to call when string is read
 | 
			
		||||
    * @note out-of-band data is only processed during a scanf call
 | 
			
		||||
    */
 | 
			
		||||
    void oob(const char *prefix, mbed::Callback<void()> func);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Flushes the underlying stream
 | 
			
		||||
    */
 | 
			
		||||
    void flush();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Abort current recv
 | 
			
		||||
    *
 | 
			
		||||
    * Can be called from oob handler to interrupt the current
 | 
			
		||||
    * recv operation.
 | 
			
		||||
    */
 | 
			
		||||
    void abort();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //MBED_ATPARSER_H
 | 
			
		||||
| 
						 | 
				
			
			@ -1,111 +0,0 @@
 | 
			
		|||
/* mbed Microcontroller Library
 | 
			
		||||
 * Copyright (c) 2006-2017 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef MBED_BUFFEREDSERIAL_H
 | 
			
		||||
#define MBED_BUFFEREDSERIAL_H
 | 
			
		||||
 | 
			
		||||
#include "platform/platform.h"
 | 
			
		||||
 | 
			
		||||
#if DEVICE_SERIAL
 | 
			
		||||
 | 
			
		||||
#include "FileHandle.h"
 | 
			
		||||
#include "SerialBase.h"
 | 
			
		||||
#include "InterruptIn.h"
 | 
			
		||||
#include "PlatformMutex.h"
 | 
			
		||||
#include "serial_api.h"
 | 
			
		||||
#include "CircularBuffer.h"
 | 
			
		||||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
class BufferedSerial : private SerialBase, public FileHandle {
 | 
			
		||||
public:
 | 
			
		||||
    /** Create a BufferedSerial port, connected to the specified transmit and receive pins, with a particular baud rate.
 | 
			
		||||
     *  @param tx Transmit pin
 | 
			
		||||
     *  @param rx Receive pin
 | 
			
		||||
     *  @param baud The baud rate of the serial port (optional, defaults to MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE)
 | 
			
		||||
     */
 | 
			
		||||
    BufferedSerial(PinName tx, PinName rx, int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
 | 
			
		||||
    virtual ~BufferedSerial();
 | 
			
		||||
 | 
			
		||||
    /** Equivalent to POSIX poll(). Derived from FileHandle.
 | 
			
		||||
     *  Provides a mechanism to multiplex input/output over a set of file handles.
 | 
			
		||||
     */
 | 
			
		||||
    virtual short poll(short events) const;
 | 
			
		||||
 | 
			
		||||
    virtual ssize_t write(const void* buffer, size_t length);
 | 
			
		||||
 | 
			
		||||
    virtual ssize_t read(void* buffer, size_t length);
 | 
			
		||||
 | 
			
		||||
    /** Acquire mutex */
 | 
			
		||||
    virtual void lock(void);
 | 
			
		||||
 | 
			
		||||
    /** Release mutex */
 | 
			
		||||
    virtual void unlock(void);
 | 
			
		||||
 | 
			
		||||
    virtual int close();
 | 
			
		||||
 | 
			
		||||
    virtual int isatty();
 | 
			
		||||
 | 
			
		||||
    virtual off_t seek(off_t offset, int whence);
 | 
			
		||||
 | 
			
		||||
    virtual int sync();
 | 
			
		||||
 | 
			
		||||
    virtual int set_blocking(bool blocking) { _blocking = blocking; return 0; }
 | 
			
		||||
 | 
			
		||||
    virtual void sigio(Callback<void()> func);
 | 
			
		||||
 | 
			
		||||
    void set_data_carrier_detect(PinName DCD_pin, bool active_high=false);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    /** Software serial buffers
 | 
			
		||||
     *  By default buffer size is 256 for TX and 256 for RX. Configurable through mbed_app.json
 | 
			
		||||
     */
 | 
			
		||||
    CircularBuffer<char, MBED_CONF_PLATFORM_BUFFERED_SERIAL_RXBUF_SIZE> _rxbuf;
 | 
			
		||||
    CircularBuffer<char, MBED_CONF_PLATFORM_BUFFERED_SERIAL_TXBUF_SIZE> _txbuf;
 | 
			
		||||
 | 
			
		||||
    PlatformMutex _mutex;
 | 
			
		||||
 | 
			
		||||
    Callback<void()> _sigio_cb;
 | 
			
		||||
 | 
			
		||||
    bool _blocking;
 | 
			
		||||
    bool _tx_irq_enabled;
 | 
			
		||||
    InterruptIn *_dcd;
 | 
			
		||||
 | 
			
		||||
    /** Device Hanged up
 | 
			
		||||
     *  Determines if the device hanged up on us.
 | 
			
		||||
     *
 | 
			
		||||
     *  @return True, if hanged up
 | 
			
		||||
     */
 | 
			
		||||
    bool hup() const;
 | 
			
		||||
 | 
			
		||||
    /** ISRs for serial
 | 
			
		||||
     *  Routines to handle interrupts on serial pins.
 | 
			
		||||
     *  Copies data into Circular Buffer.
 | 
			
		||||
     *  Reports the state change to File handle.
 | 
			
		||||
     */
 | 
			
		||||
    void tx_irq(void);
 | 
			
		||||
    void rx_irq(void);
 | 
			
		||||
 | 
			
		||||
    void wake(void);
 | 
			
		||||
 | 
			
		||||
    void DCD_IRQ(void);
 | 
			
		||||
};
 | 
			
		||||
} //namespace mbed
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif //DEVICE_SERIAL
 | 
			
		||||
#endif /* MBED_BUFFEREDSERIAL_H */
 | 
			
		||||
| 
						 | 
				
			
			@ -19,14 +19,6 @@
 | 
			
		|||
        "default-serial-baud-rate": {
 | 
			
		||||
            "help": "Default baud rate for a Serial or RawSerial instance (if not specified in the constructor)",
 | 
			
		||||
            "value": 9600
 | 
			
		||||
        },
 | 
			
		||||
        "buffered-serial-txbuf-size": {
 | 
			
		||||
            "help": "Default TX buffer size for a BufferedSerial instance (unit Bytes))",
 | 
			
		||||
            "value": 256
 | 
			
		||||
        },
 | 
			
		||||
        "buffered-serial-rxbuf-size": {
 | 
			
		||||
            "help": "Default RX buffer size for a BufferedSerial instance (unit Bytes))",
 | 
			
		||||
            "value": 256
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "target_overrides": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -124,6 +124,9 @@ static void init_serial() {
 | 
			
		|||
/**
 | 
			
		||||
 * Sets errno when file opening fails.
 | 
			
		||||
 * Wipes out the filehandle too.
 | 
			
		||||
 *
 | 
			
		||||
 * @param error is a negative error code returned from an mbed function and
 | 
			
		||||
 *              will be negated to store a positive error code in errno
 | 
			
		||||
 */
 | 
			
		||||
static int handle_open_errors(int error, unsigned filehandle_idx) {
 | 
			
		||||
    errno = -error;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -165,7 +165,7 @@ typedef enum {
 | 
			
		|||
#define ACTIVE_HIGH_POLARITY    1
 | 
			
		||||
#define ACTIVE_LOW_POLARITY     0
 | 
			
		||||
 | 
			
		||||
#define MDMDCD_POLARITY            ACTIVE_LOW_POLARITY
 | 
			
		||||
#define MDM_PIN_POLARITY            ACTIVE_LOW_POLARITY
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    PullUp = 0,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,13 +14,16 @@
 | 
			
		|||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "modem_api.h"
 | 
			
		||||
#if MBED_CONF_NSAPI_PRESENT
 | 
			
		||||
 | 
			
		||||
#include "cellular/onboard_modem_api.h"
 | 
			
		||||
#include "ublox_low_level_api.h"
 | 
			
		||||
#include "gpio_api.h"
 | 
			
		||||
#include "platform/mbed_wait_api.h"
 | 
			
		||||
#include "PinNames.h"
 | 
			
		||||
 | 
			
		||||
#if DEVICE_MODEM
 | 
			
		||||
#if MODEM_ON_BOARD
 | 
			
		||||
 | 
			
		||||
static void press_power_button(int time_ms)
 | 
			
		||||
{
 | 
			
		||||
    gpio_t gpio;
 | 
			
		||||
| 
						 | 
				
			
			@ -30,32 +33,30 @@ static void press_power_button(int time_ms)
 | 
			
		|||
    gpio_write(&gpio, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void modem_init(modem_t *obj)
 | 
			
		||||
void onboard_modem_init()
 | 
			
		||||
{
 | 
			
		||||
    //currently USB is not supported, so pass 0 to disable USB
 | 
			
		||||
    //This call does everything except actually pressing the power button
 | 
			
		||||
    ublox_mdm_powerOn(0);
 | 
			
		||||
    obj->state = POWER_READY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void modem_deinit(modem_t *obj)
 | 
			
		||||
void onboard_modem_deinit()
 | 
			
		||||
{
 | 
			
		||||
    ublox_mdm_powerOff();
 | 
			
		||||
    obj->state = LOWEST_POWER_STATE;
 | 
			
		||||
}
 | 
			
		||||
void modem_power_up(modem_t *obj)
 | 
			
		||||
 | 
			
		||||
void onboard_modem_power_up()
 | 
			
		||||
{
 | 
			
		||||
    /* keep the power line low for 150 milisecond */
 | 
			
		||||
    press_power_button(150);
 | 
			
		||||
    /* give modem a little time to respond */
 | 
			
		||||
    wait_ms(100);
 | 
			
		||||
    obj->state = POWERED_ON;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void modem_power_down(modem_t *obj)
 | 
			
		||||
void onboard_modem_power_down()
 | 
			
		||||
{
 | 
			
		||||
    /* keep the power line low for 1 second */
 | 
			
		||||
    press_power_button(1000);
 | 
			
		||||
    obj->state = POWERED_OFF;
 | 
			
		||||
}
 | 
			
		||||
#endif //DEVICE_MODEM
 | 
			
		||||
#endif //MODEM_ON_BOARD
 | 
			
		||||
#endif //MBED_CONF_NSAPI_PRESENT
 | 
			
		||||
| 
						 | 
				
			
			@ -195,7 +195,7 @@ typedef enum {
 | 
			
		|||
#define ACTIVE_HIGH_POLARITY    1
 | 
			
		||||
#define ACTIVE_LOW_POLARITY     0
 | 
			
		||||
 | 
			
		||||
#define MDMDCD_POLARITY            ACTIVE_HIGH_POLARITY
 | 
			
		||||
#define MDM_PIN_POLARITY        ACTIVE_HIGH_POLARITY
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,10 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct modem_s {
 | 
			
		||||
    uint32_t state;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "common_objects.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,12 +13,16 @@
 | 
			
		|||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include "modem_api.h"
 | 
			
		||||
 | 
			
		||||
#if MBED_CONF_NSAPI_PRESENT
 | 
			
		||||
 | 
			
		||||
#include "cellular/onboard_modem_api.h"
 | 
			
		||||
#include "gpio_api.h"
 | 
			
		||||
#include "platform/mbed_wait_api.h"
 | 
			
		||||
#include "PinNames.h"
 | 
			
		||||
 | 
			
		||||
#if DEVICE_MODEM
 | 
			
		||||
#if MODEM_ON_BOARD
 | 
			
		||||
 | 
			
		||||
static void press_power_button(int time_ms)
 | 
			
		||||
{
 | 
			
		||||
    gpio_t gpio;
 | 
			
		||||
| 
						 | 
				
			
			@ -29,27 +33,24 @@ static void press_power_button(int time_ms)
 | 
			
		|||
    gpio_write(&gpio, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void modem_init(modem_t *obj)
 | 
			
		||||
void onboard_modem_init()
 | 
			
		||||
{
 | 
			
		||||
   //does nothing at the moment, TODO: MultiTech to add hardware initialization stuff if needed
 | 
			
		||||
    obj->state = POWER_READY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void modem_deinit(modem_t *obj)
 | 
			
		||||
void onboard_modem_deinit()
 | 
			
		||||
{
 | 
			
		||||
    //does nothing at the moment, TODO: MultiTech to add hardware de-initialization stuff if needed
 | 
			
		||||
    obj->state = LOWEST_POWER_STATE;
 | 
			
		||||
}
 | 
			
		||||
void modem_power_up(modem_t *obj)
 | 
			
		||||
void onboard_modem_power_up()
 | 
			
		||||
{
 | 
			
		||||
    /* keep the power line low for 200 milisecond */
 | 
			
		||||
    press_power_button(200);
 | 
			
		||||
    /* give modem a little time to respond */
 | 
			
		||||
    wait_ms(100);
 | 
			
		||||
    obj->state = POWERED_ON;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void modem_power_down(modem_t *obj)
 | 
			
		||||
void onboard_modem_power_down()
 | 
			
		||||
{
 | 
			
		||||
    gpio_t gpio;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -59,6 +60,6 @@ void modem_power_down(modem_t *obj)
 | 
			
		|||
     * place, Due to the network disconnect, shut-off can take up to 30 seconds. However, we wait for 10
 | 
			
		||||
     * seconds only   */
 | 
			
		||||
    wait_ms(10*1000);
 | 
			
		||||
    obj->state = POWERED_OFF;
 | 
			
		||||
}
 | 
			
		||||
#endif //DEVICE_MODEM
 | 
			
		||||
#endif //MODEM_ON_BOARD
 | 
			
		||||
#endif //MBED_CONF_NSAPI_PRESENT
 | 
			
		||||
| 
						 | 
				
			
			@ -248,10 +248,22 @@
 | 
			
		|||
        "supported_form_factors": ["ARDUINO"],
 | 
			
		||||
        "core": "Cortex-M3",
 | 
			
		||||
        "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "GCC_CR", "IAR"],
 | 
			
		||||
        "extra_labels": ["NXP", "LPC176X", "FLASH_CMSIS_ALGO", "UBLOX_MODEM_GENERIC", "GENERIC_MODEM"],
 | 
			
		||||
        "extra_labels": ["NXP", "LPC176X", "FLASH_CMSIS_ALGO", "UBLOX_MODEM_GENERIC"],
 | 
			
		||||
        "config": {
 | 
			
		||||
            "modem_is_on_board": {
 | 
			
		||||
                "help": "Value: Tells the build system that the modem is on-board as oppose to a plug-in shield/module.",
 | 
			
		||||
                "value": 1,
 | 
			
		||||
                "macro_name": "MODEM_ON_BOARD" 
 | 
			
		||||
            },
 | 
			
		||||
            "modem_data_connection_type": {
 | 
			
		||||
                "help": "Value: Defines how the modem is wired up to the MCU, e.g., data connection can be a UART or USB and so forth.",
 | 
			
		||||
                "value": 1,
 | 
			
		||||
                "macro_name": "MODEM_ON_BOARD_UART" 
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "macros": ["TARGET_LPC1768"],
 | 
			
		||||
        "inherits": ["LPCTarget"],
 | 
			
		||||
        "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "DEBUG_AWARENESS", "ERROR_RED", "ETHERNET", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "FLASH", "MODEM"],
 | 
			
		||||
        "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "DEBUG_AWARENESS", "ERROR_RED", "ETHERNET", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "FLASH"],
 | 
			
		||||
        "release_versions": ["2", "5"],
 | 
			
		||||
        "features": ["LWIP"],
 | 
			
		||||
        "device_name": "LPC1768"
 | 
			
		||||
| 
						 | 
				
			
			@ -1337,13 +1349,25 @@
 | 
			
		|||
        "inherits": ["Target"],
 | 
			
		||||
        "core": "Cortex-M4F",
 | 
			
		||||
        "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"],
 | 
			
		||||
        "extra_labels": ["STM", "STM32F4", "STM32F411RE", "DRAGONFLY_MODEM", "GENERIC_MODEM"],
 | 
			
		||||
        "extra_labels": ["STM", "STM32F4", "STM32F411RE"],
 | 
			
		||||
        "config": {
 | 
			
		||||
            "modem_is_on_board": {
 | 
			
		||||
                "help": "Value: Tells the build system that the modem is on-board as oppose to a plug-in shield/module.",
 | 
			
		||||
                "value": 1,
 | 
			
		||||
                "macro_name": "MODEM_ON_BOARD" 
 | 
			
		||||
            },
 | 
			
		||||
            "modem_data_connection_type": {
 | 
			
		||||
                "help": "Value: Defines how an on-board modem is wired up to the MCU, e.g., data connection can be a UART or USB and so forth.",
 | 
			
		||||
                "value": 1,
 | 
			
		||||
                "macro_name": "MODEM_ON_BOARD_UART" 
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "macros": ["HSE_VALUE=26000000", "VECT_TAB_OFFSET=0x08010000","TRANSACTION_QUEUE_SIZE_SPI=2", "RTC_LSI=1"],
 | 
			
		||||
        "post_binary_hook": {
 | 
			
		||||
            "function": "MTSCode.combine_bins_mts_dragonfly",
 | 
			
		||||
            "toolchains": ["GCC_ARM", "ARM_STD", "ARM_MICRO"]
 | 
			
		||||
        },
 | 
			
		||||
        "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "MODEM"],
 | 
			
		||||
        "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"],
 | 
			
		||||
        "release_versions": ["2", "5"],
 | 
			
		||||
        "device_name": "STM32F411RE"
 | 
			
		||||
    },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue