Home · All Namespaces · All Classes · Grouped Classes · Modules · Functions codeless banner

Tutorial: Writing a Multiplexer Plug-in

Introduction

GSM 07.10 multiplexing is a common source of problems when integrating a GSM module with Qt Extended. During initial testing multiplexing can be disabled by setting the QTOPIA_PHONE_MUX environment variable to no. Qt Extended will still function, but you will be unable to make GPRS calls without multiplexing support.

This tutorial describes how to write several types of multiplexer plug-in, that you will need to properly support the Qt Extended requirements. Existing plug-in examples can be found in the source code under <qt-extended-root-dir>/src/plugins/multiplexers.

The QTOPIA_PHONE_VENDOR macro in custom.h is used to select the multiplexer plug-in. For example, setting QTOPIA_PHONE_VENDOR to wavecom will instruct Qt Extended to load libwavecommultiplex.so as its multiplexer implementation. The QTOPIA_PHONE_VENDOR environment variable can also be used for this purpose.

If QTOPIA_PHONE_VENDOR is not set, Qt Extended will attempt to use 3GPP TS 07.10 in the default Basic mode with a frame size of 31. If that attempt fails, it will fall back to non-multiplexing mode.

General Structure of a Multiplexer Plug-in

A multiplexer plug-in inherits from the QSerialIODeviceMultiplexerPlugin class and implements the two methods :

    class FooMultiplexer : public QSerialIODeviceMultiplexerPlugin
    {
        Q_OBJECT
    public:
        FooMultiplexer( QObject *parent = 0 )
            : QSerialIODeviceMultiplexerPlugin( parent ) {}

        bool detect( QSerialIODevice *device );
        QSerialIODeviceMultiplexer *create( QSerialIODevice *device );
    };

The detect() method determines if the plug-in can be used with the specified serial device. It can issue AT commands with QSerialIODeviceMultiplexer::chat() to determine if the GSM module supports the multiplexing method, or it can merely return true.

The serial device that is passed to the multiplexer is specified by the QTOPIA_PHONE_DEVICE setting.

If the detect() method returns true, Qt Extended will then call create() to create an instance of QSerialIODeviceMultiplexer. The plug-in will typically define a subclass of QSerialIODeviceMultiplexer to implement the multiplexing details for the GSM module.

GSM 07.10 with Modified Parameters

Qt Extended has a built-in implementation of GSM 07.10 that it will use if there isn't an explicit multiplexer plug-in provided. The default parameters are GSM 07.10 in Basic mode with a frame size of 31. The vendor can change these defaults by writing a multiplexer plug-in. The following example increases the frame size to 256:

    class ModifiedGsm0710MultiplexerPlugin : public QSerialIODeviceMultiplexerPlugin
    {
        Q_OBJECT
    public:
        ModifiedGsm0710MultiplexerPlugin( QObject *parent = 0 )
            : QSerialIODeviceMultiplexerPlugin( parent ) {}

        bool detect( QSerialIODevice *device );
        QSerialIODeviceMultiplexer *create( QSerialIODevice *device );
    };

    bool ModifiedGsm0710MultiplexerPlugin::detect( QSerialIODevice *device )
    {
        // Determine if the module supports a frame size of 256.
        return QGsm0710Multiplexer::cmuxChat( device, 256 );
    }

    QSerialIODeviceMultiplexer *ModifiedGsm0710MultiplexerPlugin::create
            ( QSerialIODevice *device )
    {
        // Create the GSM 07.10 multiplexer with a frame size of 256.
        return new QGsm0710Multiplexer( device, 256 );
    }

    QTOPIA_EXPORT_PLUGIN( ModifiedGsm0710MultiplexerPlugin )

Once the plug-in has been compiled as libmodifiedgsm0710multiplex.so, the vendor can set the QTOPIA_PHONE_VENDOR environment variable to modifiedgsm0710 to enable the multiplexer plug-in.

Multiplexers That Use Multiple Serial Ports

Some GSM modules use multiple serial ports, one per channel. The QMultiPortMultiplexer class can be used to support such modules. As an example, consider a module with the following serial ports:

To support such a module, first set QTOPIA_PHONE_DEVICE to /dev/mux0 in the custom.h file for the platform. Then the detect() and create() methods would be implemented as follows:

    class MultiPortMultiplexerPlugin : public QSerialIODeviceMultiplexerPlugin
    {
        Q_OBJECT
    public:
        MultiPortMultiplexerPlugin( QObject *parent = 0 )
            : QSerialIODeviceMultiplexerPlugin( parent ) {}

        bool detect( QSerialIODevice *device );
        QSerialIODeviceMultiplexer *create( QSerialIODevice *device );
    };

    bool MultiPortMultiplexerPlugin::detect( QSerialIODevice * )
    {
        return true;
    }

    QSerialIODeviceMultiplexer *MultiPortMultiplexerPlugin::create( QSerialIODevice *device )
    {
        // The primary AT command device, /dev/mux0, is configured
        // in the custom.h file as QTOPIA_PHONE_DEVICE and then passed
        // down to us in the "device" parameter.
        QMultiPortMultiplexer *mux = new QMultiPortMultiplexer( device );

        // Add the secondary channel.
        QSerialPort *secondary = QSerialPort::create( "/dev/mux1" );
        mux->addChannel( "secondary", secondary );

        // Add the data channel.
        QSerialPort *data = QSerialPort::create( "/dev/mux2" );
        mux->addChannel( "data", data );

        // Add the data setup channel, which is the same as "data".
        mux->addChannel( "datasetup", data );
        return mux;
    }

    QTOPIA_EXPORT_PLUGIN( MultiPortMultiplexerPlugin )

The first parameter to QMultiPortMultiplexer::addChannel() is the name of the channel that is being set. It may be one of the following standard names:

Other channel names are possible. Refer to the documentation for QSerialIODeviceMultiplexer for further details.

Some modules only have one AT command channel, not two. For such modules, both primary and secondary should be set to the same value:

    QMultiPortMultiplexer *mux = new QMultiPortMultiplexer( device );
    mux->addChannel( "secondary", device );

Some modules require that GPRS setup commands such as AT+CGDCONT and ATD must be sent on the primary AT command channel, not the data channel. For such modules, datasetup should be set to the same value as primary.

Complex Multiplexing Over a Single Serial Port

The most complex kind of multiplexer is one which is neither a GSM 07.10 variant, nor a multi-port setup. The Wavecom multiplexer is an example of this kind of multiplexer.

Refer to the source code under <qt-extended-root-dir>/src/plugins/multiplexers/wavecom if you need to write a multiplexer of this kind. The source code for QGsm0710Multiplexer might also provide some clues as to how to handle this case.


Copyright © 2009 Trolltech Trademarks
Qt Extended 4.4.3