/****************************************************************************
**
** This file is part of the Qt Extended Opensource Package.
**
** Copyright (C) 2009 Trolltech ASA.
**
** Contact: Qt Extended Information (info@qtextended.org)
**
** This file may be used under the terms of the GNU General Public License
** version 2.0 as published by the Free Software Foundation and appearing
** in the file LICENSE.GPL included in the packaging of this file.
**
** Please review the following information to ensure GNU General Public
** Licensing requirements will be met:
**     http://www.fsf.org/licensing/licenses/info/GPLv2.html.
**
**
****************************************************************************/

#include <qsimcommand.h>
#include <qatutils.h>
#include <qsmsmessage.h>
#include <qgsmcodec.h>
#include <qvarlengtharray.h>

static QString textToHtml(const QString& text, const QByteArray& attrs);

class QSimMenuItemPrivate
{
public:
    QSimMenuItemPrivate()
    {
        identifier = 0;
        iconId = 0;
        hasHelp = false;
        iconSelfExplanatory = false;
        nextAction = 0;
    }

    uint identifier;
    QString label;
    QByteArray labelAttribute;
    uint iconId;
    bool hasHelp;
    bool iconSelfExplanatory;
    uint nextAction;
};


class QSimCommandPrivate
{
public:
    QSimCommandPrivate()
    {
        ref = 1;
        commandNumber = 1;
        type = QSimCommand::NoCommand;
        sourceDevice = QSimCommand::SIM;
        destinationDevice = QSimCommand::ME;
        flags = 0;
        minimumLength = 0;
        maximumLength = 255;
        callClass = QSimCommand::Voice;
        tone = QSimCommand::ToneNone;
        duration = 0;
        defaultItem = 0;
        iconId = 0;
        otherIconId = 0;
        timerId = 0;
        device = -1;
        qualifier = 0;
        bufferSize = 0;
        dataLength = 0;
    }
    QSimCommandPrivate( QSimCommandPrivate *other )
    {
        ref = 1;
        commandNumber = other->commandNumber;
        type = other->type;
        sourceDevice = other->sourceDevice;
        destinationDevice = other->destinationDevice;
        flags = other->flags;
        text = other->text;
        textAttribute = other->textAttribute;
        otherText = other->otherText;
        otherTextAttribute = other->otherTextAttribute;
        defaultText = other->defaultText;
        minimumLength = other->minimumLength;
        maximumLength = other->maximumLength;
        number = other->number;
        subAddress = other->subAddress;
        callClass = other->callClass;
        tone = other->tone;
        duration = other->duration;
        title = other->title;
        titleAttribute = other->titleAttribute;
        defaultItem = other->defaultItem;
        menuItems = other->menuItems;
        url = other->url;
        language = other->language;
        iconId = other->iconId;
        otherIconId = other->otherIconId;
        timerId = other->timerId;
        device = other->device;
        qualifier = other->qualifier;
        extensionData = other->extensionData;
        bearerDesc = other->bearerDesc;
        bufferSize = other->bufferSize;
        dataLength = other->dataLength;
        apn = other->apn;
        uti = other->uti;
        userLogin = other->userLogin;
        userPassword = other->userPassword;
        destAddress = other->destAddress;
        localAddress = other->localAddress;
    }

    bool flag( int bit ) const
    {
        return ( ( flags & bit ) != 0 );
    }

    void setFlag( int bit, bool value )
    {
        if ( value )
            flags |= bit;
        else
            flags &= ~bit;
    }

    bool qualifierBit( int bit ) const
    {
        return ( ( qualifier & bit ) != 0 );
    }

    void setQualifierBit( int bit, bool value )
    {
        if ( value )
            qualifier |= bit;
        else
            qualifier &= ~bit;
    }

    #define SC_ImmediateResponse    (1<<0)
    #define SC_IconSelfExplanatory  (1<<1)
    #define SC_IconSelfExplanatory2 (1<<2)
    #define SC_SuppressUserFeedback (1<<3)

    QAtomicInt ref;
    int commandNumber;
    QSimCommand::Type type;
    QSimCommand::Device sourceDevice;
    QSimCommand::Device destinationDevice;
    int flags;
    QString text;
    QByteArray textAttribute;
    QString otherText;
    QByteArray otherTextAttribute;
    QString defaultText;
    uint minimumLength;
    uint maximumLength;
    QString number;
    QString subAddress;
    QSimCommand::CallClass callClass;
    QSimCommand::Tone tone;
    uint duration;
    QString title;
    QByteArray titleAttribute;
    uint defaultItem;
    QList<QSimMenuItem> menuItems;
    QString url;
    QString language;
    uint iconId;
    uint otherIconId;
    uint timerId;
    int device;
    int qualifier;
    QByteArray extensionData;
    QByteArray bearerDesc;
    ushort bufferSize;
    uint dataLength;
    QByteArray apn;
    QByteArray uti;
    QString userLogin;
    QString userPassword;
    QByteArray destAddress;
    QByteArray localAddress;
};


/*!
    \class QSimMenuItem
    \inpublicgroup QtTelephonyModule

    \brief The QSimMenuItem class provides information about a menu item within a SIM toolkit application

    \ingroup telephony
    \sa QSimCommand, QSimToolkit
*/

/*!
    Construct a new menu item with default parameters.
*/
QSimMenuItem::QSimMenuItem()
{
    d = new QSimMenuItemPrivate();
}


/*!
    Construct a new menu item as a copy of \a value.
*/
QSimMenuItem::QSimMenuItem( const QSimMenuItem& value )
{
    d = new QSimMenuItemPrivate();
    d->identifier = value.d->identifier;
    d->label = value.d->label;
    d->labelAttribute = value.d->labelAttribute;
    d->iconId = value.d->iconId;
    d->hasHelp = value.d->hasHelp;
    d->iconSelfExplanatory = value.d->iconSelfExplanatory;
    d->nextAction = value.d->nextAction;
}


/*!
    Destruct a menu item.
*/
QSimMenuItem::~QSimMenuItem()
{
    delete d;
}


/*!
    Returns the menu item's numeric identifier.

    \sa setIdentifier()
*/
uint QSimMenuItem::identifier() const
{
    return d->identifier;
}


/*!
    Sets the menu item's numeric identifier to \a value.

    \sa identifier()
*/
void QSimMenuItem::setIdentifier( uint value )
{
    d->identifier = value;
}


/*!
    Returns the menu item's label.

    \sa setLabel()
*/
QString QSimMenuItem::label() const
{
    return d->label;
}


/*!
    Sets the menu item's label to \a value.

    \sa label()
*/
void QSimMenuItem::setLabel( const QString& value )
{
    d->label = value;
}


/*!
    Returns the menu item's text attributes for formatting label().
    Returns an empty QByteArray if the label() is not formatted.

    \sa setLabelAttribute(), label(), labelHtml()
    \since 4.4
*/
QByteArray QSimMenuItem::labelAttribute() const
{
    return d->labelAttribute;
}


/*!
    Sets the menu item's text attributes for formatting label() to \a value.
    If \a value is an empty QByteArray, then label() is not formatted.

    \sa labelAttribute(), label(), labelHtml()
    \since 4.4
*/
void QSimMenuItem::setLabelAttribute( const QByteArray& value )
{
    d->labelAttribute = value;
}


/*!
    Returns the menu item's label() as a HTML string.  If the menu
    item has labelAttribute(), then they will be used to format
    the label() appropriately.

    \sa label(), labelAttribute()
    \since 4.4
*/
QString QSimMenuItem::labelHtml() const
{
    return textToHtml( d->label, d->labelAttribute );
}


/*!
    Returns true if this menu item has help available; otherwise returns false.

    \sa setHasHelp()
*/
bool QSimMenuItem::hasHelp() const
{
    return d->hasHelp;
}


/*!
    Sets the flag that indicates if this menu item has help
    available to \a value.

    \sa hasHelp()
*/
void QSimMenuItem::setHasHelp( bool value )
{
    d->hasHelp = value;
}


/*!
    Returns the icon identifier associated with this menu item.
    Returns zero if there is no icon.

    \sa setIconId()
*/
uint QSimMenuItem::iconId() const
{
    return d->iconId;
}


/*!
    Sets the icon identifier associated with this menu item to \a value.

    \sa iconId()
*/
void QSimMenuItem::setIconId( uint value )
{
    d->iconId = value;
}


/*!
    Returns true if the icon specified by iconId() is self-explanatory
    without the display of label().  If this function returns false,
    then label() should be displayed next to the icon.  If iconId()
    returns zero, then iconSelfExplanatory() should be ignored.

    \sa setIconSelfExplanatory()
*/
bool QSimMenuItem::iconSelfExplanatory() const
{
    return d->iconSelfExplanatory;
}


/*!
    Sets the self-explanatory flag to \a value.

    \sa iconSelfExplanatory()
*/
void QSimMenuItem::setIconSelfExplanatory( bool value )
{
    d->iconSelfExplanatory = value;
}


/*!
    Returns the next action indicator for this menu item.  Next action indicators
    have the same values as command types from the QSimCommand::Type list.
    The default value is zero, indicating no next action indicator for this menu item.

    \sa setNextAction()
*/
uint QSimMenuItem::nextAction() const
{
    return d->nextAction;
}


/*!
    Sets the next action indicator for this menu item to \a value.  Next action
    indicators have the same values as command types from the QSimCommand::Type list.
    The value zero indicates that there is no next action indicator for this menu item.

    \sa nextAction()
*/
void QSimMenuItem::setNextAction( uint value )
{
    d->nextAction = value;
}


/*!
    Make a copy of \a value.
*/
QSimMenuItem& QSimMenuItem::operator=( const QSimMenuItem & value )
{
    d->identifier = value.d->identifier;
    d->label = value.d->label;
    d->labelAttribute = value.d->labelAttribute;
    d->iconId = value.d->iconId;
    d->hasHelp = value.d->hasHelp;
    d->iconSelfExplanatory = value.d->iconSelfExplanatory;
    d->nextAction = value.d->nextAction;
    return *this;
}

/*!
    \class QSimCommand
    \inpublicgroup QtTelephonyModule

    \brief The QSimCommand class specifies the details of a SIM toolkit command message.

    Applications that run within a SIM send commands to the host program
    to interact with the user.  These commands might entail choosing an
    item from a menu, asking if it is OK to dial a phone number, asking
    for a line of input, displaying text messages, etc.

    The QSimCommand class encapsulates a single SIM toolkit command,
    containing all of the information about it.  QSimCommand objects
    are delivered to the host program by way of the QSimToolkit::command() signal.

    In Qtopia, the host program is \c simapp.

    \ingroup telephony
    \sa QSimToolkit, QSimMenuItem, QSimTerminalResponse
*/

/*!
    \enum QSimCommand::Type
    This enum defines the type of a SIM toolkit message within a
    QSimCommand object.

    \value NoCommand No command type currently set.
    \value Timeout Indicate that an operation has timed out.
    \value Refresh Notification of a SIM refresh.
    \value MoreTime The SIM toolkit application is asking for more time.
           This command type is handled automatically by the modem or the
           modem vendor plugin, so client applications will not see this
           command type via QSimToolkit::command().
    \value PollInterval The SIM toolkit application is setting the polling interval
           for new commands.  This command type is handled automatically by the
           modem or the modem vendor plugin, so client applications will not see this
           command type via QSimToolkit::command().
    \value PollingOff This SIM toolkit application is asking for polling to be turned off.
           This command type is handled automatically by the modem or the
           modem vendor plugin, so client applications will not see this
           command type via QSimToolkit::command().
    \value SetupEventList Set up the list of events to be reported to the
           SIM toolkit application.
    \value SetupCall Set up a phone call to a specific number.
    \value SendSS Notification that the application is sending a SS message.
    \value SendSMS Notification that the application is sending a SMS message.
    \value SendUSSD Notification that the application is sending a USSD message.
    \value SendDTMF Notification that the application is sending a DTMF tone.
    \value LaunchBrowser Launch a Web browser on a URL.
    \value PlayTone Play a tone to the user.
    \value DisplayText Display a text message.
    \value GetInkey Get a single key of input.
    \value GetInput Get a line of input.
    \value SelectItem Process a submenu within a SIM toolkit application.
    \value SetupMenu Process the main menu of a SIM toolkit application.
    \value ProvideLocalInformation The SIM toolkit application is asking for local
           information to be supplied.  This command type is handled automatically
           by the modem or the modem vendor plugin, so client applications will
           not see this command type via QSimToolkit::command().
    \value TimerManagement The SIM toolkit application is activating or deactivating
           timers.  This command type is handled automatically by the modem or the
           modem vendor plugin, so client applications will not see this
           command type via QSimToolkit::command().
    \value SetupIdleModeText Set the text to be displayed when the phone is idle.
    \value PerformCardAPDU Send an APDU to the additional card reader.
           This command type is handled automatically by the modem or the
           modem vendor plugin, so client applications will not see this
           command type via QSimToolkit::command().
    \value PowerOnCard Power on an additional card reader.
           This command type is handled automatically by the modem or the
           modem vendor plugin, so client applications will not see this
           command type via QSimToolkit::command().
    \value PowerOffCard Power off an additional card reader.
           This command type is handled automatically by the modem or the
           modem vendor plugin, so client applications will not see this
           command type via QSimToolkit::command().
    \value GetReaderStatus Get the status of an additional card reader.
           This command type is handled automatically by the modem or the
           modem vendor plugin, so client applications will not see this
           command type via QSimToolkit::command().
    \value RunATCommand Run an AT command against the modem
    \value LanguageNotification Inform the user about the language the SIM
           toolkit application will be displaying messages in.
    \value OpenChannel Open a data channel.
    \value CloseChannel Close a data channel.
    \value ReceiveData Receive data on a data channel.
    \value SendData Send data on a data channel.
    \value GetChannelStatus Get the current status of a data channel.
    \value ServiceSearch Search for the availability of a service in the
           environment of the terminal.  Since Qtopia 4.4.  Compliant
           with ETSI TS 102 223.
    \value GetServiceInformation Get the complete service record related
           to a service.  Since Qtopia 4.4.  Compliant with ETSI TS 102 223.
    \value DeclareService Declare a service that is provided by the SIM.
           Since Qtopia 4.4.  Compliant with ETSI TS 102 223.
    \value SetFrames Divide the screen into multiple, scrollable rectangular
           regions in order to present multiple information at once.
           Since Qtopia 4.4.  Compliant with ETSI TS 102 223.
    \value GetFramesStatus Get the status on the frames supported by the SIM.
           Since Qtopia 4.4.  Compliant with ETSI TS 102 223.
    \value RetrieveMultimediaMessage Retrieve a multimedia message from
           the network.  Since Qtopia 4.4.  Compliant with ETSI TS 102 223.
    \value SubmitMultimediaMessage Submit a multimedia message to the network.
           Since Qtopia 4.4.  Compliant with ETSI TS 102 223.
    \value DisplayMultimediaMessage Display a multimedia message.
           Since Qtopia 4.4.  Compliant with ETSI TS 102 223.
    \value EndSession Indicate that the SIM toolkit session has ended
    \value SetupMainMenu Alias for SetupMenu, provided for backwards compatiblity.
    \value SetupSubMenu Alias for SelectItem, provided for backwards compatiblity.
*/

/*!
    \enum QSimCommand::Disposition
    This enum defines the disposition of other calls when a \c SetupCall
    command is executed by the SIM toolkit application.

    \value IfNoOtherCalls Perform the setup only if there are no other calls.
    \value PutOnHold Put other calls on hold when the new call is setup.
    \value Disconnect Disconnect other calls when the new call is setup.
*/

/*!
    \enum QSimCommand::CallClass
    This enum defines the class of call that is being created by a
    \c SetupCall command.

    \value Voice Voice call
    \value Data Data call
    \value Fax Fax call
*/

/*!
    \enum QSimCommand::Tone
    This enum defines the tones that can be played by a \c PlayTone command.

    \value ToneNone No tone specified.
    \value ToneDial Currently dialing
    \value ToneBusy Called party is busy
    \value ToneCongestion Network is congested
    \value ToneRadioAck Radio acknowledged
    \value ToneDropped Connection has been dropped
    \value ToneError An error occurred
    \value ToneCallWaiting An incoming call is waiting
    \value ToneRinging Ring to indicate and incoming call
    \value ToneGeneralBeep A general beep tone
    \value TonePositiveBeep A beep indicating a positive outcome
    \value ToneNegativeBeep A beep indicating a negative outcome

*/

/*!
    \enum QSimCommand::RefreshType
    This enum defines the type of refresh that was performed by the SIM.

    \value InitAndFullFileChange SIM initialization and full file
           change notification.
    \value FileChange File change notification.
    \value InitAndFileChange SIM initialization and file change notification.
    \value Initialization SIM initialization.
    \value Reset SIM reset.
    \value NaaApplicationReset NAA application reset.  This is only applicable
           for a 3G platform.  Since Qtopia 4.4.  Compliant with ETSI TS 102 223.
    \value NaaSessionReset NAA session reset.  This is only applicable
           for a 3G platform.  Since Qtopia 4.4.  Compliant with ETSI TS 102 223.
*/

/*!
    \enum QSimCommand::Event
    This enum defines the types of events that the SIM expects to be reported.

    \value NoEvent No event type specified.
    \value IdleScreen Report an event when the system is idle.
    \value UserActivity Report an event when there is user activity.
    \value Both Report for both system idle and user activity.
    \value Cancel Cancel event reporting.
*/

/*!
    \enum QSimCommand::BrowserLaunchMode
    This enum defines the launch mode to use when displaying web pages in the browser.

    \value IfNotAlreadyLaunched Launch browser, if not already launched.
    \value UseExisting Use the existing browser, but not if it is running
           a secured session.
    \value CloseExistingAndLaunch Close the existing browser session
           and launch a new browser session.
*/

/*!
    \enum QSimCommand::MenuPresentation
    This enum defines the type of presentation to use for SIM toolkit menus.

    \value AnyPresentation The user interface may use any presentation it wishes.
    \value DataValuesPresentation The user interface should present the menu as
           a choice of several data values.
    \value NavigationOptionsPresentation The user interface should present the menu
           as a choice of several navigation options.
*/

/*!
    \enum QSimCommand::Device
    This enum defines the source or destination device for a SIM command, according
    to 3GPP TS 11.14, section 12.7.
    
    \value Keypad Keypad device
    \value Display Display device
    \value Earpiece Earpiece device
    \value CardReader0 Additional card reader 0
    \value CardReader1 Additional card reader 1
    \value CardReader2 Additional card reader 2
    \value CardReader3 Additional card reader 3
    \value CardReader4 Additional card reader 4
    \value CardReader5 Additional card reader 5
    \value CardReader6 Additional card reader 6
    \value CardReader7 Additional card reader 7
    \value Channel1 Data channel 1
    \value Channel2 Data channel 2
    \value Channel3 Data channel 3
    \value Channel4 Data channel 4
    \value Channel5 Data channel 5
    \value Channel6 Data channel 6
    \value Channel7 Data channel 7
    \value SIM SIM device
    \value ME ME (mobile equipment) device
    \value Network Source or destination is the network
*/

/*!
    Construct a new SIM toolkit command object with default parameters.
*/
QSimCommand::QSimCommand()
{
    d = new QSimCommandPrivate();
}


/*!
    Construct a new SIM toolkit command object as a copy of \a value.
*/
QSimCommand::QSimCommand( const QSimCommand& value )
{
    d = value.d;
    d->ref.ref();
}


/*!
    Destruct a SIM toolkit command object.
*/
QSimCommand::~QSimCommand()
{
    if ( !d->ref.deref() )
        delete d;
}


/*!
    Returns the SIM command number.  The default value is 1.  The command number
    may be something other than 1 if more than one SIM command is being processed
    simultaneously, but this is a fairly rare occurence.  The main use for
    command numbers is to match commands and responses.

    Applies to: all commands

    \sa setCommandNumber()
*/
int QSimCommand::commandNumber() const
{
    return d->commandNumber;
}


/*!
    Sets the SIM command number to \a value.  The usual value for the command
    number is 1.  The command number may be set to something other than 1 if more
    than one SIM command is being processed simultaneously, but this is a fairly
    rare occurence.  The main use for command numbers is to match commands and responses.

    Applies to: all commands

    \sa commandNumber()
*/
void QSimCommand::setCommandNumber( int value )
{
    dwrite()->commandNumber = value;
}


/*!
    Returns the type of this command.  The default value is \c NoCommand.

    Applies to: all commands.

    \sa setType()
*/
QSimCommand::Type QSimCommand::type() const
{
    return d->type;
}


/*!
    Sets the type of this command to \a value.

    Applies to: all commands.

    \sa type()
*/
void QSimCommand::setType( QSimCommand::Type value )
{
    dwrite()->type = value;
}


/*!
    Returns the source device that originated the command.  The default value is \c SIM.

    Applies to: all commands.

    \sa setSourceDevice()
*/
QSimCommand::Device QSimCommand::sourceDevice() const
{
    return d->sourceDevice;
}


/*!
    Sets the source device that originated the command to \a value.  Usually this
    is \c SIM.

    Applies to: all commands.

    \sa sourceDevice()
*/
void QSimCommand::setSourceDevice( QSimCommand::Device value )
{
    dwrite()->sourceDevice = value;
}


/*!
    Returns the destination device for the command.  The default value is \c ME.

    Applies to: all commands.

    \sa setDestinationDevice()
*/
QSimCommand::Device QSimCommand::destinationDevice() const
{
    return d->destinationDevice;
}


/*!
    Sets the destination device for the command to \a value.

    Applies to: all commands.

    \sa destinationDevice()
*/
void QSimCommand::setDestinationDevice( QSimCommand::Device value )
{
    dwrite()->destinationDevice = value;
}


/*!
    Returns true if there is help available for this command; otherwise returns false.
    The help flag is the most significant bit of the qualifier() byte.

    Applies to: \c SetupMenu, \c GetInkey, \c GetInput, \c SelectItem.

    \sa setHasHelp()
*/
bool QSimCommand::hasHelp() const
{
    if ( d->type == QSimCommand::GetInkey ||
         d->type == QSimCommand::GetInput ||
         d->type == QSimCommand::SelectItem ||
         d->type == QSimCommand::SetupMenu )
        return d->qualifierBit( 0x80 );
    else
        return false;
}


/*!
    Sets the flag that determines if there is help available
    for this command to \a value.  The help flag is the most significant bit
    of the qualifier() byte.

    Applies to: \c SetupMenu, \c GetInkey, \c GetInput, \c SelectItem.

    \sa hasHelp()
*/
void QSimCommand::setHasHelp( bool value )
{
    if ( d->type == QSimCommand::GetInkey ||
         d->type == QSimCommand::GetInput ||
         d->type == QSimCommand::SelectItem ||
         d->type == QSimCommand::SetupMenu )
        dwrite()->setQualifierBit( 0x80, value );
}


/*!
    Returns the text to be displayed as either a message, a prompt, or an SMS.

    Applies to: \c DisplayText, \c GetInkey, \c GetInput, \c SendSS, \c SendSMS,
    \c SendUSSD, \c PlayTone, \c ServiceSearch, \c GetServiceInformation,
    \c RetrieveMultimediaMessage, \c SubmitMultimediaMessage, \c RunATCommand,
    \c SendDTMF, \c LaunchBrowser, \c SetupIdleModeText, \c SetupCall.

    \sa setText()
*/
QString QSimCommand::text() const
{
    return d->text;
}


/*!
    Sets the text to be displayed by this command to \a value.

    Applies to: \c DisplayText, \c GetInkey, \c GetInput, \c SendSS, \c SendSMS,
    \c SendUSSD, \c PlayTone, \c ServiceSearch, \c GetServiceInformation,
    \c RetrieveMultimediaMessage, \c SubmitMultimediaMessage, \c RunATCommand,
    \c SendDTMF, \c LaunchBrowser, \c SetupIdleModeText, \c SetupCall.

    \sa text()
*/
void QSimCommand::setText( const QString& value )
{
    dwrite()->text = value;
}


/*!
    Returns the text attributes to be applied to text() for formatting.

    Applies to: \c DisplayText, \c GetInkey, \c GetInput, \c SendSS, \c SendSMS,
    \c SendUSSD, \c PlayTone, \c ServiceSearch, \c GetServiceInformation,
    \c RetrieveMultimediaMessage, \c SubmitMultimediaMessage.

    \sa setTextAttribute(), text()
    \since 4.4
*/
QByteArray QSimCommand::textAttribute() const
{
    return d->textAttribute;
}


/*!
    Sets the text attributes to be applied to text() for formatting to \a value.

    Applies to: \c DisplayText, \c GetInkey, \c GetInput, \c SendSS, \c SendSMS,
    \c SendUSSD, \c PlayTone, \c ServiceSearch, \c GetServiceInformation,
    \c RetrieveMultimediaMessage, \c SubmitMultimediaMessage.

    \sa textAttribute(), text(), textHtml()
    \since 4.4
*/
void QSimCommand::setTextAttribute( const QByteArray& value )
{
    dwrite()->textAttribute = value;
}


/*!
    Returns text() formatted as HTML according to the attributes
    in textAttribute().

    Applies to: \c DisplayText, \c GetInkey, \c GetInput, \c SendSS, \c SendSMS,
    \c SendUSSD, \c PlayTone, \c ServiceSearch, \c GetServiceInformation,
    \c RetrieveMultimediaMessage, \c SubmitMultimediaMessage.

    \sa text(), textAttribute()
    \since 4.4
*/
QString QSimCommand::textHtml() const
{
    return textToHtml( d->text, d->textAttribute );
}


/*!
    Returns true if user feedback should be suppressed.  The default value is false.

    This option controls what should happen when text() is an empty string for
    the \c SendSS, \c SendSMS, \c SendUSSD, and \c PlayTone commands.  If
    suppressUserFeedback() returns true, then the command should be performed
    without any notification to the user.  If suppressUserFeedback() is false,
    then generic feedback should be provided to the user to indicate that a
    command is being performed.

    Applies to: \c SendSS, \c SendSMS, \c SendUSSD, \c PlayTone.

    \sa setSuppressUserFeedback(), text()
*/
bool QSimCommand::suppressUserFeedback() const
{
    return d->flag( SC_SuppressUserFeedback );
}


/*!
    Sets the user feedback suppression flag to \a value.

    This option controls what should happen when text() is an empty string for
    the \c SendSS, \c SendSMS, \c SendUSSD, and \c PlayTone commands.  If
    \a value is true, then the command should be performed without any notification
    to the user.  If \a value is false, then generic feedback should be provided to
    the user to indicate that a command is being performed.

    Applies to: \c SendSS, \c SendSMS, \c SendUSSD, \c PlayTone.

    \sa suppressUserFeedback(), text()
*/
void QSimCommand::setSuppressUserFeedback( bool value )
{
    dwrite()->setFlag( SC_SuppressUserFeedback, value );
}


/*!
    Returns the other text to be displayed as a message.  This is typically used
    with \c SetupCall commands to specify the text to be displayed during the call setup
    phase, when text() is used for the user confirmation phase.

    Applies to: \c SetupCall

    \sa setOtherText()
*/
QString QSimCommand::otherText() const
{
    return d->otherText;
}


/*!
    Sets the other text to be displayed to \a value.  This is typically used
    with \c SetupCall commands to specify the text to be displayed during the call setup
    phase, when text() is used for the user confirmation phase.

    Applies to: \c SetupCall

    \sa otherText()
*/
void QSimCommand::setOtherText( const QString& value )
{
    dwrite()->otherText = value;
}


/*!
    Returns the text attributes to use to format otherText().

    Applies to: \c SetupCall

    \sa setOtherTextAttribute(), otherText(), otherTextHtml()
    \since 4.4
*/
QByteArray QSimCommand::otherTextAttribute() const
{
    return d->otherTextAttribute;
}


/*!
    Sets the text attributes to use to format otherText() to \a value.

    Applies to: \c SetupCall

    \sa otherTextAttribute(), otherText(), otherTextHtml()
    \since 4.4
*/
void QSimCommand::setOtherTextAttribute( const QByteArray& value )
{
    dwrite()->otherTextAttribute = value;
}


/*!
    Returns otherText() formatted as HTML according to the attributes
    in otherTextAttribute().

    Applies to: \c SetupCall

    \sa otherText(), otherTextAttribute()
    \since 4.4
*/
QString QSimCommand::otherTextHtml() const
{
    return textToHtml( d->otherText, d->otherTextAttribute );
}


/*!
    Returns the default text for \c GetInput commands.

    Applies to: \c GetInput

    \sa setDefaultText()
*/
QString QSimCommand::defaultText() const
{
    return d->defaultText;
}


/*!
    Sets the default text for \c GetInput commands to \a value.

    Applies to: \c GetInput

    \sa defaultText()
*/
void QSimCommand::setDefaultText( const QString& value )
{
    dwrite()->defaultText = value;
}


/*!
    Returns true if a DisplayText command should attempt to display
    the text as high priority (true) or normal priority (false).
    The default value is false.

    Applies to: \c DisplayText, \c DisplayMultimediaMessage.

    \sa setHighPriority()
*/
bool QSimCommand::highPriority() const
{
    if ( d->type == QSimCommand::DisplayText ||
         d->type == QSimCommand::DisplayMultimediaMessage)
        return d->qualifierBit( 0x01 );
    else
        return false;
}


/*!
    Sets the high priority text display flag to \a value.  If type() is not \c DisplayText
    or \c DisplayMultimediaMessage, then the request is ignored.

    Applies to: \c DisplayText, \c DisplayMultimediaMessage.

    \sa highPriority()
*/
void QSimCommand::setHighPriority( bool value )
{
    if ( d->type == QSimCommand::DisplayText ||
         d->type == QSimCommand::DisplayMultimediaMessage)
        dwrite()->setQualifierBit( 0x01, value );
}


/*!
    Returns true if the text should be automatically cleared after
    a small delay (usually 3 seconds); otherwise returns false.  If this is false, then
    the client must call QSimToolkit::clearText() to move on to
    the next SIM application state.  The default value is true.

    Applies to: \c DisplayText, \c DisplayMultimediaMessage.

    Note: in Qtopia 4.3 and newer, the default value is true.  If Qtopia 4.2 and older,
    the default value was false.  The change was due to the introduction of the
    qualifier() value.

    \sa setClearAfterDelay()
*/
bool QSimCommand::clearAfterDelay() const
{
    if ( d->type == QSimCommand::DisplayText ||
         d->type == QSimCommand::DisplayMultimediaMessage)
        return !d->qualifierBit( 0x80 );
    else
        return true;
}


/*!
    Sets the clear after delay flag for text display to \a value.  If type() is not
    \c DisplayText or \c DisplayMultimediaMessage, the request is ignored.

    Applies to: \c DisplayText, \c DisplayMultimediaMessage.

    \sa clearAfterDelay()
*/
void QSimCommand::setClearAfterDelay( bool value )
{
    if ( d->type == QSimCommand::DisplayText ||
         d->type == QSimCommand::DisplayMultimediaMessage)
        dwrite()->setQualifierBit( 0x80, !value );
}


/*!
    Returns true if a \c DisplayText or \c DisplayMultimediaMessage command
    should result in an immediate response to the SIM without asking the
    user to confirm the text first; or false if the user should confirm,
    or the response should be sent after the usual delay if clearAfterDelay()
    is set.  The default value is false.

    Applies to: \c DisplayText, \c DisplayMultimediaMessage

    \sa setImmediateResponse(), clearAfterDelay()
*/
bool QSimCommand::immediateResponse() const
{
    return d->flag( SC_ImmediateResponse );
}


/*!
    Sets the immediate response flag to \a value.  If \a value is true, then the
    \c DisplayText or \c DisplayMultimediaMessage command should result in an
    immediate response to the SIM without asking the user to confirm the text first.
    If \a value is false, the user should confirm, or the response should be sent
    after the usual delay if clearAfterDelay() is set.

    Applies to: \c DisplayText, \c DisplayMultimediaMessage

    \sa immediateResponse(), clearAfterDelay()
*/
void QSimCommand::setImmediateResponse( bool value )
{
    dwrite()->setFlag( SC_ImmediateResponse, value );
}


/*!
    Returns true if the \c GetInkey and \c GetInput commands should return UCS2
    input strings to the SIM; false if the commands should return strings in the
    default SMS alphabet instead.  The default value is false.

    This setting is ignored if either wantYesNo() returns true, and this setting
    always overrides packedInput().

    Applies to: \c GetInkey, \c GetInput

    \sa setUcs2Input(), wantYesNo(), packedInput()
*/
bool QSimCommand::ucs2Input() const
{
    if ( d->type == QSimCommand::GetInkey || d->type == QSimCommand::GetInput )
        return d->qualifierBit( 0x02 );
    else
        return false;
}


/*!
    Sets the UCS2 input flag to \a value.  If \a value is true, then the
    \c GetInkey and \c GetInput commands should send UCS2 input strings to the SIM.
    If \a value is false, then the commands should send strings in the
    default SMS alphabet instead.

    This setting is ignored if either wantYesNo() returns true, and this setting
    always overrides packedInput().

    \sa ucs2Input(), wantYesNo(), packedInput()
*/
void QSimCommand::setUcs2Input( bool value )
{
    if ( d->type == QSimCommand::GetInkey || d->type == QSimCommand::GetInput )
        dwrite()->setQualifierBit( 0x02, value );
}


/*!
    Returns true if the \c GetInput command should return packed
    7-bit input strings to the SIM; false if the commands should return strings in the
    unpacked 8-bit alphabet instead.  The default value is false.

    This setting is ignored if either wantYesNo() or ucs2Input() returns true.

    Applies to: \c GetInput

    \sa setPackedInput(), wantYesNo(), ucs2Input()
*/
bool QSimCommand::packedInput() const
{
    if ( d->type == QSimCommand::GetInput )
        return d->qualifierBit( 0x08 );
    else
        return false;
}


/*!
    Sets the packed input flag to \a value.  If \a value is true, then the
    \c GetInput command should send packed 7-bit input strings to the SIM.
    If \a value is false, then the commands should send strings in the
    unpacked 8-bit alphabet instead.

    This setting is ignored if either wantYesNo() or ucs2Input() returns true,
    of if type() is not \c GetInput.

    Applies to: \c GetInput

    \sa packedInput(), wantYesNo(), ucs2Input()
*/
void QSimCommand::setPackedInput( bool value )
{
    if ( d->type == QSimCommand::GetInput )
        dwrite()->setQualifierBit( 0x08, value );
}


/*!
    Returns true if \c GetInkey or \c GetInput wants input that consists
    only of digits (true), or any character combination (false).
    The allowable digits are 0-9, #, *, and +.  The default value is true.

    Applies to: \c GetInkey, \c GetInput.

    Note: in Qtopia 4.3 and newer, the default value is true.  If Qtopia 4.2 and older,
    the default value was false.  The change was due to the introduction of the
    qualifier() value.

    \sa setWantDigits()
*/
bool QSimCommand::wantDigits() const
{
    if ( d->type == QSimCommand::GetInkey || d->type == QSimCommand::GetInput )
        return !d->qualifierBit( 0x01 );
    else
        return true;
}


/*!
    Sets the flag that determines if \c GetInkey or \c GetInput wants
    input that consists only of digits (true), or any character
    combination (false), to \a value.

    Applies to: \c GetInkey, \c GetInput.

    \sa wantDigits()
*/
void QSimCommand::setWantDigits( bool value )
{
    if ( d->type == QSimCommand::GetInkey || d->type == QSimCommand::GetInput )
        dwrite()->setQualifierBit( 0x01, !value );
}


/*!
    Returns true if \c GetInkey wants input that consists of a \c Yes or
    \c No answer.  The default value is false.

    Applies to: \c GetInkey

    \sa setWantYesNo()
*/
bool QSimCommand::wantYesNo() const
{
    if ( d->type == QSimCommand::GetInkey )
        return d->qualifierBit( 0x04 );
    else
        return false;
}


/*!
    Sets the flag that determines if \c GetInkey wants input that
    consists of a \c Yes or \c No answer, to \a value.

    Applies to: \c GetInkey

    \sa wantYesNo()
*/
void QSimCommand::setWantYesNo( bool value )
{
    if ( d->type == QSimCommand::GetInkey )
        dwrite()->setQualifierBit( 0x04, value );
}


/*!
    Returns true if \c GetInkey wants that the response is immediately sent
    after key press.  The default value is false.

    Applies to: \c GetInkey

    \sa setWantImmediateResponse()
*/
bool QSimCommand::wantImmediateResponse() const
{
    if ( d->type == QSimCommand::GetInkey )
        return d->qualifierBit( 0x08 );
    else
        return false;
}

/*!
    Sets the flag that determines if \c GetInkey wants that
    the response is immediately sent after key press.

    Applies to: \c GetInkey

    \sa wantImmediateResponse()
*/
void QSimCommand::setWantImmediateResponse( bool value )
{
    if ( d->type == QSimCommand::GetInkey )
        dwrite()->setQualifierBit( 0x08, value );
}

/*!
    Returns the minimum text length for input.  The default value is 0.

    Applies to: \c GetInput.

    \sa setMinimumLength()
*/
uint QSimCommand::minimumLength() const
{
    return d->minimumLength;
}


/*!
    Sets the minimum text length for input to \a value.

    Applies to: \c GetInput.

    \sa minimumLength()
*/
void QSimCommand::setMinimumLength( uint value )
{
    dwrite()->minimumLength = value;
}


/*!
    Returns the maximum text length for input.  The default value is 255, which
    indicates that the text is unlimited in length.

    Applies to: \c GetInput.

    \sa setMaximumLength()
*/
uint QSimCommand::maximumLength() const
{
    return d->maximumLength;
}


/*!
    Sets the maximum text length for input to \a value.

    Applies to: \c GetInput.

    \sa maximumLength()
*/
void QSimCommand::setMaximumLength( uint value )
{
    dwrite()->maximumLength = value;
}


/*!
    Returns true if input should be echoed; otherwise returns false.
    The default value is true.

    Applies to: \c GetInput.

    Note: in Qtopia 4.3 and newer, the default value is true.  If Qtopia 4.2 and older,
    the default value was false.  The change was due to the introduction of the
    qualifier() value.

    \sa setEcho()
*/
bool QSimCommand::echo() const
{
    if ( d->type == QSimCommand::GetInput )
        return !d->qualifierBit( 0x04 );
    else
        return true;
}


/*!
    Sets the flag that determines if input should be echoed to \a value.

    Applies to: \c GetInput.

    \sa echo()
*/
void QSimCommand::setEcho( bool value )
{
    if ( d->type == QSimCommand::GetInput )
        dwrite()->setQualifierBit( 0x04, !value );
}


/*!
    Returns the disposition of other calls when a call setup occurs.
    The default value is \c IfNoOtherCalls.

    Applies to: \c SetupCall.

    \sa setDisposition()
*/
QSimCommand::Disposition QSimCommand::disposition() const
{
    if ( d->type == QSimCommand::SetupCall )
        return (QSimCommand::Disposition)(d->qualifier >> 1);
    else
        return IfNoOtherCalls;
}


/*!
    Sets the disposition of other calls when a call setup occurs to \a value.

    Applies to: \c SetupCall.

    \sa disposition()
*/
void QSimCommand::setDisposition( QSimCommand::Disposition value )
{
    if ( d->type == QSimCommand::SetupCall )
        dwrite()->qualifier = (((int)value) << 1) | (d->qualifier & 0x01);
}


/*!
    Returns true if with-redial modifier is set for call setup disposition();
    otherwise returns false.  The default value is false.

    Applies to: \c SetupCall.

    \sa setWithRedial()
*/
bool QSimCommand::withRedial() const
{
    if ( d->type == QSimCommand::SetupCall )
        return d->qualifierBit( 0x01 );
    else
        return false;
}

/*!
    Sets the with-redial modifier for call setup disposition to \a value.

    Applies to: \c SetupCall.

    \sa withRedial()
*/
void QSimCommand::setWithRedial( bool value )
{
    if ( d->type == QSimCommand::SetupCall )
        dwrite()->setQualifierBit( 0x01, value );
}

/*!
    Returns the phone number for \c SetupCall, address for \c SendSMS, the
    supplementary service string for \c SendSS, the unstructured supplementary
    service string for \c SendUSSD, or the sequence of DTMF digits for \c SendDTMF.

    Applies to: \c SetupCall, \c SendSMS, \c SendSS, \c SendUSSD, \c SendDTMF.

    \sa setNumber()
*/
QString QSimCommand::number() const
{
    return d->number;
}


/*!
    Sets the phone number for \c SetupCall, address for \c SendSMS, the
    supplementary service string for \c SendSS, unstructured supplementary service
    string for \c SendUSSD, to \a value, or the sequence of DTMF digits for \c SendDTMF.

    Applies to: \c SetupCall, \c SendSMS, \c SendSS, \c SendUSSD, \c SendDTMF.

    \sa number()
*/
void QSimCommand::setNumber( const QString& value )
{
    dwrite()->number = value;
}


/*!
    Returns the sub-address (e.g. extension) for a call setup.

    Applies to: \c SetupCall.

    \sa setSubAddress()
*/
QString QSimCommand::subAddress() const
{
    return d->subAddress;
}


/*!
    Sets the sub-address (e.g. extension) for a call setup to \a value.

    Applies to: \c SetupCall.

    \sa subAddress()
*/
void QSimCommand::setSubAddress( const QString& value )
{
    dwrite()->subAddress = value;
}


/*!
    Returns the class of call to be setup (Voice, Data, or Fax).
    The default value is \c Voice.

    Applies to: \c SetupCall.

    \sa setCallClass()
*/
QSimCommand::CallClass QSimCommand::callClass() const
{
    return d->callClass;
}


/*!
    Sets the class of call to be setup (Voice, Data, or Fax) to \a value.

    Applies to: \c SetupCall.

    \sa callClass()
*/
void QSimCommand::setCallClass( QSimCommand::CallClass value )
{
    dwrite()->callClass = value;
}


/*!
    Returns the tone to be played by a \c PlayTone command.  The default
    value is \c ToneNone.

    Applies to: \c PlayTone

    \sa setTone(), duration()
*/
QSimCommand::Tone QSimCommand::tone() const
{
    return d->tone;
}


/*!
    Sets the tone to be played by a \c PlayTone command to \a value.

    Applies to: \c PlayTone

    \sa tone(), duration()
*/
void QSimCommand::setTone( QSimCommand::Tone value )
{
    dwrite()->tone = value;
}


/*!
    Returns the number of milliseconds to play a tone.  The default value is zero,
    indicating that the default duration for the tone should be used.

    Applies to: \c PlayTone.

    Note: this function is obsoleted by duration(), and will return the same value
    as duration().

    \sa duration(), setToneTime(), tone()
*/
uint QSimCommand::toneTime() const
{
    return d->duration;
}


/*!
    Sets the number of milliseconds to play a tone to \a value.

    Applies to: \c PlayTone.

    Note: this function is obsoleted by setDuration().

    \sa setDuration(), toneTime(), tone()
*/
void QSimCommand::setToneTime( uint value )
{
    dwrite()->duration = value;
}


/*!
    Returns the number of milliseconds to play a tone or the poll interval.
    The default value is zero, indicating that the default duration should be used.

    Applies to: \c PlayTone, \c PollInterval.

    \sa setDuration(), tone()
*/
uint QSimCommand::duration() const
{
    return d->duration;
}

/*!
    Sets the duration of a poll interval or to play a tone to \a value milliseconds.

    Applies to: \c PlayTone, \c PollInterval.

    \sa duration(), tone()
*/
void QSimCommand::setDuration( uint value )
{
    dwrite()->duration = value;
}

/*!
    Returns true if icons for menu items should be displayed on the device's soft keys
    if the number of icons is less than or equal to the number of soft keys.  If there are
    more icons than soft keys, then regular menu selection should be used.  Returns false
    for regular menu selection.  The default value is false.

    Applies to: \c SetupMenu, \c SelectItem.

    \sa setSoftKeysPreferred(), menuPresentation()
*/
bool QSimCommand::softKeysPreferred() const
{
    if ( d->type == QSimCommand::SetupMenu )
        return d->qualifierBit( 0x01 );
    else if ( d->type == QSimCommand::SelectItem )
        return d->qualifierBit( 0x04 );
    else
        return false;
}

/*!
    Sets the soft key preferred option to \a value.  If \a value is true then the
    icons for menu items should be displayed on the device's soft keys if the number
    of icons is less than or equal to the number of soft keys.  If there are more
    icons than soft keys, then regular menu selection should be used.  If \a value
    is false, then regular menu selection is always used.

    Applies to: \c SetupMenu, \c SelectItem.

    \sa softKeysPreferred(), menuPresentation()
*/
void QSimCommand::setSoftKeysPreferred( bool value )
{
    if ( d->type == QSimCommand::SetupMenu )
        dwrite()->setQualifierBit( 0x01, value );
    else if ( d->type == QSimCommand::SelectItem )
        dwrite()->setQualifierBit( 0x04, value );
}

/*!
    Returns the menu presentation type to use for \c SelectItem commands.
    The default value is \c AnyPresentation.

    Applies to: \c SelectItem.

    \sa setMenuPresentation(), softKeysPreferred()
*/
QSimCommand::MenuPresentation QSimCommand::menuPresentation() const
{
    if ( d->type == QSimCommand::SelectItem && d->qualifierBit( 0x01 ) != 0 ) {
        if ( d->qualifierBit( 0x02 ) != 0 )
            return NavigationOptionsPresentation;
        else
            return DataValuesPresentation;
    } else {
        return AnyPresentation;
    }
}

/*!
    Sets the menu presentation type to use for \c SelectItem commands
    to \a value.

    Applies to: \c SelectItem.

    \sa menuPresentation(), softKeysPreferred()
*/
void QSimCommand::setMenuPresentation( QSimCommand::MenuPresentation value )
{
    if ( d->type == QSimCommand::SelectItem ) {
        if ( value == NavigationOptionsPresentation ) {
            dwrite()->setQualifierBit( 0x01, true );
            dwrite()->setQualifierBit( 0x02, true );
        } else if ( value == DataValuesPresentation ) {
            dwrite()->setQualifierBit( 0x01, true );
            dwrite()->setQualifierBit( 0x02, false );
        } else {
            dwrite()->setQualifierBit( 0x01, false );
            dwrite()->setQualifierBit( 0x02, false );
        }
    }
}

/*!
    Returns the title to be displayed on a menu.

    Applies to: \c SetupMenu, \c SelectItem.

    \sa setTitle()
*/
QString QSimCommand::title() const
{
    return d->title;
}


/*!
    Sets the title to be displayed on a menu to \a value.

    Applies to: \c SetupMenu, \c SelectItem.

    \sa title()
*/
void QSimCommand::setTitle( const QString& value )
{
    dwrite()->title = value;
}


/*!
    Returns the text attribute to use to format title().

    Applies to: \c SetupMenu, \c SelectItem.

    \sa setTitleAttribute(), title(), titleHtml()
    \since 4.4
*/
QByteArray QSimCommand::titleAttribute() const
{
    return d->titleAttribute;
}


/*!
    Sets the text attribute to use to format title() to \a value.

    Applies to: \c SetupMenu, \c SelectItem.

    \sa titleAttribute(), title(), titleHtml()
    \since 4.4
*/
void QSimCommand::setTitleAttribute( const QByteArray& value )
{
    dwrite()->titleAttribute = value;
}


/*!
    Returns title() formatted as HTML according to the attributes
    in titleAttribute().

    Applies to: \c SetupMenu, \c SelectItem.

    \sa title(), titleAttribute()
    \since 4.4
*/
QString QSimCommand::titleHtml() const
{
    return textToHtml( d->title, d->titleAttribute );
}


/*!
    Returns the index of the default item in the menu, or zero if no default.

    Applies to: \c SelectItem.

    \sa setDefaultItem()
*/
uint QSimCommand::defaultItem() const
{
    return d->defaultItem;
}


/*!
    Sets the index of the default item in the menu, or zero if no default,
    to \a value.

    Applies to: \c SelectItem.

    \sa defaultItem()
*/
void QSimCommand::setDefaultItem( uint value )
{
    dwrite()->defaultItem = value;
}


/*!
    Returns the list of menu items in the menu.

    Applies to: \c SetupMenu, \c SelectItem.

    \sa setMenuItems()
*/
QList<QSimMenuItem> QSimCommand::menuItems() const
{
    return d->menuItems;
}


/*!
    Sets the list of menu items in the menu to \a value.

    Applies to: \c SetupMenu, \c SelectItem.

    \sa menuItems()
*/
void QSimCommand::setMenuItems( const QList<QSimMenuItem>& value )
{
    dwrite()->menuItems = value;
}


/*!
    Returns the type of refresh to that was performed by the SIM.
    The default value is InitAndFullFileChange.

    Applies to: \c Refresh.

    \sa setRefreshType()
*/
QSimCommand::RefreshType QSimCommand::refreshType() const
{
    if ( d->type == QSimCommand::Refresh )
        return (QSimCommand::RefreshType)(d->qualifier);
    else
        return InitAndFullFileChange;
}


/*!
    Sets the type of refresh to that was performed by the SIM to \a value.
    The request is ignored if type() is not \c Refresh.

    Applies to: \c Refresh.

    \sa refreshType()
*/
void QSimCommand::setRefreshType( QSimCommand::RefreshType value )
{
    if ( d->type == QSimCommand::Refresh )
        setQualifier( (int)value );
}


/*!
    Returns the events to be reported.

    Applies to: \c SetupEventList.

    Note: this function can only return information about \c IdleScreen and \c UserActivity
    events.  To access information about all SIM toolkit events in the command,
    use extensionField() with a tag value of 0x99.

    \sa setEvents()
*/
QSimCommand::Event QSimCommand::events() const
{
    if ( d->type != QSimCommand::SetupEventList )
        return NoEvent;
    if ( d->extensionData.isEmpty() )
        return NoEvent;
    QByteArray evdata = extensionField( 0x99 );
    if ( evdata.isEmpty() ) {
        return Cancel;      // Field is present, but empty, which means "Cancel".
    } else if ( evdata.contains( (char)0x05 ) ) {
        if ( evdata.contains( (char)0x04 ) )
            return Both;
        else
            return IdleScreen;
    } else if ( evdata.contains( (char)0x04 ) ) {
        return UserActivity;
    } else {
        return NoEvent;
    }
}


/*!
    Sets the events to be reported to \a value.

    Applies to: \c SetupEventList.

    Note: this function can only set information about \c IdleScreen and \c UserActivity
    events.  To set information about other SIM toolkit events, use setExtensionField()
    with a tag value of 0x99.

    \sa events()
*/
void QSimCommand::setEvents( QSimCommand::Event value )
{
    if ( d->type == QSimCommand::SetupEventList ) {
        dwrite()->extensionData = QByteArray();
        switch ( value ) {

            case NoEvent:       break;

            case IdleScreen:
            {
                d->extensionData += (char)0x99;
                d->extensionData += (char)0x01;
                d->extensionData += (char)0x05;
            }
            break;

            case UserActivity:
            {
                d->extensionData += (char)0x99;
                d->extensionData += (char)0x01;
                d->extensionData += (char)0x04;
            }
            break;

            case Both:
            {
                d->extensionData += (char)0x99;
                d->extensionData += (char)0x02;
                d->extensionData += (char)0x04;
                d->extensionData += (char)0x05;
            }
            break;

            case Cancel:
            {
                d->extensionData += (char)0x99;
                d->extensionData += (char)0x00;
            }
            break;
        }
    }
}


/*!
    Returns the browser launch mode.  The default value is IfNotAlreadyLaunched.

    Applies to: \c LaunchBrowser.

    \sa setBrowserLaunchMode()
*/
QSimCommand::BrowserLaunchMode QSimCommand::browserLaunchMode() const
{
    if ( d->type == QSimCommand::LaunchBrowser )
        return (QSimCommand::BrowserLaunchMode)(d->qualifier);
    else
        return IfNotAlreadyLaunched;
}

/*!
    Sets the browser launch mode to \a value.

    Applies to: \c LaunchBrowser.

    \sa browserLaunchMode()
*/
void QSimCommand::setBrowserLaunchMode( QSimCommand::BrowserLaunchMode value )
{
    if ( d->type == QSimCommand::LaunchBrowser )
        setQualifier( (int)value );
}

/*!
    Returns the URL to launch in the browser.

    Applies to: \c LaunchBrowser.

    \sa setUrl()
*/
QString QSimCommand::url() const
{
    return d->url;
}

/*!
    Sets the URL to launch in the browser to \a value.

    Applies to: \c LaunchBrowser.

    \sa url()
*/
void QSimCommand::setUrl( const QString& value )
{
    dwrite()->url = value;
}

/*!
    Returns the language that will be used for any text string within
    proactive commands or envelope command responses.

    Applies to: \c LanguageNotification.

    \sa setLanguage()
*/
QString QSimCommand::language() const
{
    return d->language;
}

/*!
    Sets the language that will be used for any text string within
    proactive commands or envelope command responses to \a value.

    Applies to: \c LanguageNotification.

    \sa language()
*/
void QSimCommand::setLanguage( const QString& value )
{
    dwrite()->language = value;
}

/*!
    Returns the icon identifier associated with this command.
    Returns zero if there is no icon.

    Applies to: \c DisplayText, \c GetInkey, \c GetInput, \c PlayTone, \c SelectItem,
    \c SendSMS, \c SendSS, \c SetupCall, \c SetupMenu, \c LaunchBrowser,
    \c SetupIdleModeText, \c ServiceSearch, \c GetServiceInformation,
    \c RetrieveMultimediaMessage, \c SubmitMultimediaMessage

    \sa setIconId()
*/
uint QSimCommand::iconId() const
{
    return d->iconId;
}

/*!
    Sets the icon identifier associated with this menu item to \a value.

    Applies to: \c DisplayText, \c GetInkey, \c GetInput, \c PlayTone, \c SelectItem,
    \c SendSMS, \c SendSS, \c SetupCall, \c SetupMenu, \c LaunchBrowser,
    \c SetupIdleModeText, \c ServiceSearch, \c GetServiceInformation,
    \c RetrieveMultimediaMessage, \c SubmitMultimediaMessage

    \sa iconId()
*/
void QSimCommand::setIconId( uint value )
{
    dwrite()->iconId = value;
}

/*!
    Returns true if the icon specified by iconId() is self-explanatory
    without the display of text().  If this function returns false,
    then text() should be displayed next to the icon.  If iconId()
    returns zero, then iconSelfExplanatory() should be ignored.

    Applies to: \c DisplayText, \c GetInkey, \c GetInput, \c PlayTone, \c SelectItem,
    \c SendSMS, \c SendSS, \c SetupCall, \c SetupMenu, \c LaunchBrowser,
    \c SetupIdleModeText, \c ServiceSearch, \c GetServiceInformation,
    \c RetrieveMultimediaMessage, \c SubmitMultimediaMessage

    \sa setIconSelfExplanatory()
*/
bool QSimCommand::iconSelfExplanatory() const
{
    return d->flag( SC_IconSelfExplanatory );
}

/*!
    Sets the self-explanatory flag to \a value.

    Applies to: \c DisplayText, \c GetInkey, \c GetInput, \c PlayTone, \c SelectItem,
    \c SendSMS, \c SendSS, \c SetupCall, \c SetupMenu, \c LaunchBrowser,
    \c SetupIdleModeText, \c ServiceSearch, \c GetServiceInformation,
    \c RetrieveMultimediaMessage, \c SubmitMultimediaMessage

    \sa iconSelfExplanatory()
*/
void QSimCommand::setIconSelfExplanatory( bool value )
{
    dwrite()->setFlag( SC_IconSelfExplanatory, value );
}

/*!
    Returns the other icon identifier associated with this command.
    Returns zero if there is no icon.  This is typically used
    with \c SetupCall commands to specify the icon to be displayed during the call setup
    phase, when iconId() is used for the user confirmation phase.

    Applies to: \c SetupCall

    \sa setOtherIconId()
*/
uint QSimCommand::otherIconId() const
{
    return d->otherIconId;
}


/*!
    Sets the other icon identifier associated with this menu item to \a value.
    This is typically used with \c SetupCall commands to specify the icon to be
    displayed during the call setup phase, when iconId() is used for the user
    confirmation phase.

    Applies to: \c SetupCall

    \sa otherIconId()
*/
void QSimCommand::setOtherIconId( uint value )
{
    dwrite()->otherIconId = value;
}


/*!
    Returns true if the icon specified by otherIconId() is self-explanatory
    without the display of otherText().  If this function returns false,
    then otherText() should be displayed next to the icon.  If otherIconId()
    returns zero, then otherIconSelfExplanatory() should be ignored.

    Applies to: \c SetupCall

    \sa setOtherIconSelfExplanatory()
*/
bool QSimCommand::otherIconSelfExplanatory() const
{
    return d->flag( SC_IconSelfExplanatory2 );
}


/*!
    Sets the self-explanatory flag for the icon specified by otherIconId to \a value.

    Applies to: \c SetupCall

    \sa otherIconSelfExplanatory()
*/
void QSimCommand::setOtherIconSelfExplanatory( bool value )
{
    dwrite()->setFlag( SC_IconSelfExplanatory2, value );
}


/*!
    Returns true if SMS packing should be performed when sending an SMS message
    for the \c SendSMS command; or false if packing is not required.  The default
    value is false.

    Many modems or modem vendor plugins will consume this value and remove it
    from the SIM command before it reaches the client application layer.  Client
    applications should not rely upon this value being present.

    Applies to: \c SendSMS

    \sa setSmsPacking()
*/
bool QSimCommand::smsPacking() const
{
    if ( d->type == QSimCommand::SendSMS )
        return d->qualifierBit( 0x01 );
    else
        return false;
}

/*!
    Sets the SMS packing flag to \a value.  If \a value is true, then SMS packing
    should be performed when sending an SMS message for the \c SendSMS command.
    If \a value is false, then no packing is required.

    Many modems or modem vendor plugins will consume this value and remove it
    from the SIM command before it reaches the client application layer.  Client
    applications should not rely upon this value being present.

    Applies to: \c SendSMS

    \sa smsPacking()
*/
void QSimCommand::setSmsPacking( bool value )
{
    if ( d->type == QSimCommand::SendSMS )
        dwrite()->setQualifierBit( 0x01, value );
}

/*!
    Returns the number of the timer to which a Timer Management command is
    addressed.

    Applies to: \c TimerManagement

    \sa setTimerId()
*/
int QSimCommand::timerId() const
{
    return d->timerId;
}

/*!
    Sets the identifier of the timer to which the Timer Management command
    is being sent.  \a id should be between 1 and 8 to address one of the
    eight timers available.

    Applies to: \c TimerManagement

    \sa timerId()
*/
void QSimCommand::setTimerId( int id )
{
    dwrite()->timerId = id;
}

ushort QSimCommand::bufferSize() const
{
    return d->bufferSize;
}

void QSimCommand::setBufferSize( ushort value )
{
    dwrite()->bufferSize = value;
}

uint QSimCommand::dataLength() const
{
    return d->dataLength;
}

void QSimCommand::setDataLength( uint value )
{
    dwrite()->dataLength = value;
}

QString QSimCommand::userLogin() const
{
    return d->userLogin;
}

void QSimCommand::setUserLogin( const QString& value )
{
    dwrite()->userLogin = value;
}

QString QSimCommand::userPassword() const
{
    return d->userPassword;
}

void QSimCommand::setUserPassword( const QString& value )
{
    dwrite()->userPassword = value;
}

QByteArray QSimCommand::uti() const
{
    return d->uti;
}

void QSimCommand::setUti( const QByteArray& value )
{
    dwrite()->uti = value;
}

QByteArray QSimCommand::bearerDesc() const
{
    return d->bearerDesc;
}

void QSimCommand::setBearerDesc( const QByteArray& value )
{
    dwrite()->bearerDesc = value;
}

QByteArray QSimCommand::localAddress() const
{
    return d->localAddress;
}

void QSimCommand::setLocalAddress( const QByteArray& value )
{
    dwrite()->localAddress = value;
}

QByteArray QSimCommand::destAddress() const
{
    return d->destAddress;
}

void QSimCommand::setDestAddress( const QByteArray& value )
{
    dwrite()->destAddress = value;
}

QByteArray QSimCommand::apn() const
{
    return d->apn;
}

void QSimCommand::setApn( const QByteArray& value )
{
    dwrite()->apn = value;
}

/*!
    Copy the QSimCommand object \a value.
*/
QSimCommand& QSimCommand::operator=( const QSimCommand & value )
{
    if ( d == value.d )
        return *this;

    if ( !d->ref.deref() )
        delete d;

    d = value.d;
    d->ref.ref();

    return *this;
}

// Read BER tag and length information from a QByteArray.
// We also need to export this to qsimterminalresponse.cpp and qsimenvelope.cpp.
void _qtopiaphone_readBer( const QByteArray& binary, uint& posn, uint& tag, uint& length )
{
    if ( posn < (uint)binary.size() ) {
        tag = (uint)(binary[posn] & 0xFF);
        ++posn;
    } else {
        tag = (uint)(-1);
    }
    if ( posn < (uint)binary.size() ) {
        length = (uint)(binary[posn] & 0xFF);
        ++posn;
        if ( length == 0x81 ) {
            // Two-byte length value.
            if ( posn < (uint)binary.size() ) {
                length = (uint)(binary[posn] & 0xFF);
                ++posn;
            } else {
                length = 0;
            }
        } else if ( length == 0x82 ) {
            // Three-byte length value.
            if ( ( posn + 1 ) < (uint)binary.size() ) {
                length = (((uint)(binary[posn] & 0xFF)) << 8) |
                         (uint)(binary[posn + 1] & 0xFF);
                posn += 2;
            } else {
                length = 0;
                posn = (uint)binary.size();
            }
        }
    } else {
        length = 0;
    }
}
#define readBer _qtopiaphone_readBer

// Decode an EFADN string from a BER field.  GSM 11.11, section 10.5.1.
// Exported to qsimcontrolevent.cpp.
QString _qtopiaphone_decodeEFADN( const QByteArray& binary, uint posn, uint length )
{
    uint num, page, ch;
    QString temp;
    QTextCodec *codec = QAtUtils::codec( "gsm" );
    if ( length == 0 )
        return QString("");
    else if ( binary[posn] == (char)0x80 ) {
        // UCS-2 coding.
        ++posn;
        --length;
        while ( length >= 2 ) {
            ch = (((uint)((binary[posn]) & 0xFF)) << 8) |
                  ((uint)(binary[posn + 1] & 0xFF));
            if ( ch != 0xFFFF )
                temp += (QChar)ch;
            posn += 2;
            length -= 2;
        }
        return temp;
    } else if ( binary[posn] == (char)0x81 ) {
        // 8-bit half page index coding.
        if ( length < 3 )
            return QString("");
        num = ((uint)(binary[posn + 1] & 0xFF));
        page = ((uint)(binary[posn + 2] & 0xFF)) << 7;
        posn += 3;
        length -= 3;
    } else if ( binary[posn] == (char)0x82 ) {
        // 16-bit half page index coding.
        if ( length < 4 )
            return QString("");
        num = ((uint)(binary[posn + 1] & 0xFF));
        page = (((uint)(binary[posn + 2] & 0xFF)) << 8) |
                ((uint)(binary[posn + 3] & 0xFF));
        posn += 4;
        length -= 4;
    } else {
        // 7-bit GSM default alphabet coding.
        while ( length > 0 && binary[posn + length - 1] == (char)0xFF ) {
            // Strip 0xFF bytes from the end of the string first.
            --length;
        }
        return codec->toUnicode( binary.data() + posn, (int)length );
    }
    while ( num > 0 && length > 0 ) {
        ch = ((uint)(binary[posn] & 0xFF));
        if ( ch < 0x80 ) {
            temp += QGsmCodec::singleToUnicode( (char)ch );
        } else {
            temp += (QChar)( page + (ch & 0x7F) );
        }
        ++posn;
        --length;
        --num;
    }
    return temp;
}
#define decodeEFADN _qtopiaphone_decodeEFADN

// Decode an EFADN number from a BER field.  GSM 11.11, section 10.5.1.
static QString decodeEFADNNumber( const QByteArray& binary,
                                  uint posn, uint length )
{
    static char const digits[] = "0123456789*#pDE";
    QString temp;
    uint ch;
    while ( length > 0 ) {
        ch = ((uint)(binary[posn] & 0xFF));
        if ( ( ch & 0x0F ) == 0x0F )
            break;
        temp += (QChar)( digits[ch & 0x0F] );
        if ( ( ch & 0xF0 ) == 0xF0 )
            break;
        temp += (QChar)( digits[(ch >> 4) & 0x0F] );
        ++posn;
        --length;
    }
    return temp;
}

// Write an EFADN number to a BER field.
static void writeEFADNNumber( QByteArray& data, const QString& number, int tag = 0x86,
                              int localTag = 129 )
{
    QString num = QAtUtils::stripNumber( number );
    if ( tag == 0xAC ) {
        // DTMF strings don't have a type prefix.
        data += (char)tag;
        data += (char)((num.length() + 1) / 2);
    } else if ( num.startsWith( QChar('+') ) ) {
        num = num.mid(1);
        data += (char)tag;
        data += (char)(1 + ((num.length() + 1) / 2));
        data += (char)145;
    } else {
        data += (char)tag;
        data += (char)(1 + ((num.length() + 1) / 2));
        data += (char)localTag;
    }
    int byte = 0;
    int nibble = 0;
    for ( int index = 0; index < num.length(); ++index ) {
        int ch = num[index].unicode();
        switch ( ch ) {
            case '0': case '1': case '2': case '3': case '4':
            case '5': case '6': case '7': case '8': case '9':   ch -= '0'; break;

            case '*':           ch = 10; break;
            case '#':           ch = 11; break;
            case 'p': case 'P': case ',':
                                ch = 12; break;
            case 'D': case 'd': ch = 13; break;
            case 'E': case 'e': ch = 14; break;

            default:            ch = 10; break;
        }
        if ( nibble ) {
            data += (char)(byte | (ch << 4));
            nibble = 0;
        } else {
            byte = ch;
            nibble = 1;
        }
    }
    if ( nibble ) {
        data += (char)(byte | 0xF0);
    }
}

// Decode a coded string, GSM 11.14, section 12.15.
QString _qtopiaphone_decodeCodedString( const QByteArray& binary, uint posn, uint length )
{
    QString temp;
    uint ch, byte, bitCount;
    if ( length == 0 )
        return QString("");
    ch = (uint)(binary[posn++] & 0x0C);
    --length;
    if ( ch == QSMS_DefaultAlphabet ) {
        ch = 0;
        bitCount = 0;
        while ( length > 0 ) {
            byte = binary[posn++];
            --length;
            for ( int i = 0; i < 8; i++ ) {
                // test the bit and shift it down again, as i doesn't mark
                // where we are in the current char, but bitCount does
                ch |= ( ( byte & (1 << i) ) >> i) << bitCount;
                bitCount++;
                if ( bitCount == 7 ) {
                    bitCount = 0;
                    temp += QGsmCodec::singleToUnicode( (char)ch );
                    ch = 0;
                }
            }
        }
        if ( bitCount == 0 && temp.length() > 0 &&
             temp[temp.length() - 1] == (char)0x0D ) {
            // CR used as a padding character in the last byte - strip it.
            temp = temp.left( temp.length() - 1 );
        }
        return temp;
    } else if ( ch == QSMS_UCS2Alphabet ) {
        while ( length >= 2 ) {
            ch = (((uint)((binary[posn]) & 0xFF)) << 8) |
                  ((uint)(binary[posn + 1] & 0xFF));
            temp += (QChar)ch;
            posn += 2;
            length -= 2;
        }
        return temp;
    } else {
        return decodeEFADN( binary, posn, length );
    }
}
#define decodeCodedString _qtopiaphone_decodeCodedString

// Decode a subaddress, GSM 11.14, section 12.3.  The actual encoding
// is specified in GSM 24.008, Annex E.
static QString decodeSubAddress( const QByteArray& pdu, uint posn, uint length )
{
    // Verify that this looks like a BCD-encoded IA5 NSAP subaddress.
    if ( length < 2 || pdu[posn] != (char)0x80 || pdu[posn + 1] != (char)0x50 )
        return QString();
    QString result;
    posn += 2;
    length -= 2;
    while ( length > 0 ) {
        int bcd = (pdu[posn++] & 0xFF);
        result += QChar( (bcd >> 4) * 10 + (bcd & 0x0F) + 32 );
        --length;
    }
    return result;
}

/*!
    Decode a SIM command from its raw binary \a pdu form, as according
    to 3GPP TS 11.14.  The binary data is assumed to be in BER form,
    starting with the command tag.  If the data starts with a
    "Proactive SIM" BER command wrapper, it will be skipped.
    Returns the decoded SIM command.

    \sa toPdu()
*/
QSimCommand QSimCommand::fromPdu( const QByteArray& pdu )
{
    QSimCommand sc;
    uint posn = 0;
    uint newPosn;
    uint tag, length;
    QList<QSimMenuItem> items;
    bool seenText = false;
    bool seenTextAttribute = false;
    bool seenIcon = false;

    // Read the first BER blob, which should be the command details.
    readBer( pdu, posn, tag, length );
    if ( tag == 0xD0 ) {
        // There appears to be a "Proactive SIM" wrapper on the front
        // of the command details.  Skip over it.
        readBer( pdu, posn, tag, length );
    }
    if ( (tag & 0x7F) != 0x01 ) {
        // This doesn't appear to be a SIM command at all.
        return sc;
    }

    // Process the contents of the SIM command, tag by tag.
    for (;;) {
        if ( ( posn + length ) > (uint)pdu.size() ) {
            break;
        }
        newPosn = posn + length;
        switch ( tag & 0x7F ) {

            case 0x01:
            {
                // Main command details blob, GSM 11.14, section 12.6.
                if ( length < 3 )
                    break;
                sc.setCommandNumber( pdu[posn] & 0xFF );
                sc.setType( (QSimCommand::Type)(pdu[posn + 1] & 0xFF) );
                sc.setQualifier( pdu[posn + 2] & 0xFF );
            }
            break;

            case 0x02:
            {
                // Device identities, GSM 11.14, section 12.7.
                if ( length >= 2 ) {
                    sc.setSourceDevice( (QSimCommand::Device)( pdu[posn] & 0xFF ) );
                    sc.setDestinationDevice( (QSimCommand::Device)( pdu[posn + 1] & 0xFF ) );
                }
            }
            break;

            case 0x04:
            {
                // Duration for a PlayTone or PollInterval command, GSM 11.14, section 12.8.
                if ( sc.type() == QSimCommand::OpenChannel ) {
                    // This is actually part of the network setup parameters,
                    // so add it to the extension data.
                    sc.addExtensionField( tag, pdu.mid( posn, length ) );
                    break;
                }
                if ( length < 2 )
                    break;
                uint multiplier = 60000;            // Minutes.
                if ( pdu[posn] == 0x01 )         // Seconds.
                    multiplier = 1000;
                else if ( pdu[posn] == 0x02 )    // Tenths of a second.
                    multiplier = 100;
                sc.setDuration( multiplier * ( pdu[posn + 1] & 0xFF ) );
            }
            break;

            case 0x05:
            {
                // Title to display with a menu, or alpha identifier for other commands.
                // GSM 11.14, section 12.2.
                if ( sc.type() == SetupMenu || sc.type() == SelectItem ) {
                    sc.setTitle( decodeEFADN( pdu, posn, length ) );
                } else if ( seenText ) {
                    sc.setOtherText( decodeEFADN( pdu, posn, length ) );
                } else {
                    sc.setText( decodeEFADN( pdu, posn, length ) );
                    seenText = true;
                    if ( length == 0 )
                        sc.setSuppressUserFeedback( true );
                }
            }
            break;

            case 0x06:
            case 0x09:
            {
                // Address for SetupCall and SendSMS, GSM 11.14, section 12.1.
                // SS string for SendSS command, GSM 11.14, section 12.14.
                if ( length < 1 )
                    break;
                if ( pdu[posn] == (char)145 ) {
                    sc.setNumber
                        ( "+" + decodeEFADNNumber
                                    ( pdu, posn + 1, length - 1 ) );
                } else {
                    sc.setNumber( decodeEFADNNumber
                                    ( pdu, posn + 1, length - 1 ) );
                }
            }
            break;

            case 0x08:
            {
                // Sub-address for SetupCall, GSM 11.14, section 12.3.
                sc.setSubAddress( decodeSubAddress( pdu, posn, length ) );
            }
            break;

            case 0x0D:
            {
                // Text string for command, GSM 11.14, section 12.15.
                if ( sc.type() == QSimCommand::LaunchBrowser ||
                     sc.type() == QSimCommand::OpenChannel ) {
                    // This is actually part of the network setup parameters,
                    // so add it to the extension data.
                    sc.addExtensionField( tag, pdu.mid( posn, length ) );
                } else {
                    sc.setText( decodeCodedString( pdu, posn, length ) );
                }
            }
            break;

            case 0x0A:
            {
                // USSD string, GSM 11.14, section 12.17.
                sc.setNumber( decodeCodedString( pdu, posn, length ) );
            }
            break;

            case 0x11:
            {
                // Response length, GSM 11.14, section 12.11.
                if ( length >= 2 ) {
                    sc.setMinimumLength( pdu[posn] & 0xFF );
                    sc.setMaximumLength( pdu[posn + 1] & 0xFF );
                }
            }
            break;

            case 0x17:
            {
                // Default text string for GET INPUT command, GSM 11.14, section 12.23.
                sc.setDefaultText( decodeCodedString( pdu, posn, length ) );
            }
            break;

            case 0x18:
            {
                // Next action indicator list, GSM 11.14, section 12.24.
                int index = 0;
                while ( length > 0 && index < items.size() ) {
                    uint action = (uint)(pdu[posn++] & 0xFF);
                    items[index].setNextAction( action );
                    --length;
                    ++index;
                }
            }
            break;

            case 0x0E:
            {
                // Tone code for a PlayTone command, GSM 11.14, section 12.16.
                if ( length > 0 )
                    sc.setTone( (QSimCommand::Tone)(pdu[posn] & 0xFF) );
            }
            break;

            case 0x0F:
            {
                // Menu item for command, GSM 11.14 section, 12.9.
                if ( !length )
                    break;      // Zero-length items indicate empty menu.
                QSimMenuItem item;
                if ( length > 0 ) {
                    item.setIdentifier( (uint)(pdu[posn] & 0xFF) );
                    ++posn;
                    --length;
                }
                item.setLabel( decodeEFADN( pdu, posn, length ) );
                item.setHasHelp( sc.hasHelp() );
                items.append( item );
            }
            break;

            case 0x10:
            {
                // Default menu item identifier, GSM 11.14, section 12.10.
                if ( length > 0 )
                    sc.setDefaultItem( (uint)(pdu[posn] & 0xFF) );
            }
            break;

            case 0x1E:
            {
                // Icon identifier, GSM 11.14, section 12.31.
                if ( length >= 2 ) {
                    if ( seenIcon ) {
                        sc.setOtherIconSelfExplanatory( (pdu[posn] & 0x01) == 0 );
                        sc.setOtherIconId( (uint)(pdu[posn + 1] & 0xFF) );
                    } else {
                        sc.setIconSelfExplanatory( (pdu[posn] & 0x01) == 0 );
                        sc.setIconId( (uint)(pdu[posn + 1] & 0xFF) );
                        seenIcon = true;
                    }
                }
            }
            break;

            case 0x1F:
            {
                // Item icon identifier list, GSM 11.14, section 12.32.
                int index = 0;
                bool selfExplanatory = true;
                if ( length > 0 ) {
                    if ( (pdu[posn] & 0x01) != 0 )
                        selfExplanatory = false;
                    ++posn;
                    --length;
                }
                while ( length > 0 && index < items.size() ) {
                    uint iconId = (uint)(pdu[posn++] & 0xFF);
                    items[index].setIconId( iconId );
                    items[index].setIconSelfExplanatory( selfExplanatory );
                    --length;
                    ++index;
                }
            }
            break;

            case 0x24:
            {
                // Timer identifier.
                sc.setTimerId( pdu[posn] );
            }
            break;

            case 0x25:
            {
                // Timer value.
                int secs = 0;
                secs += ((unsigned char) pdu[posn + 0] >> 4) * 3600;
                secs += ((unsigned char) pdu[posn + 0] & 15) * 36000;
                secs += ((unsigned char) pdu[posn + 1] >> 4) * 60;
                secs += ((unsigned char) pdu[posn + 1] & 15) * 600;
                secs += ((unsigned char) pdu[posn + 2] >> 4) * 1;
                secs += ((unsigned char) pdu[posn + 2] & 15) * 10;
                sc.setDuration( secs * 1000 );
            }
            break;

            case 0x2B:
            {
                // Immediate response block.
                sc.setImmediateResponse(true);
            }
            break;

            case 0x2C:
            {
                // DTMF digits for SendDTMF command, GSM 11.14, section 12.44.
                sc.setNumber( decodeEFADNNumber( pdu, posn, length ) );
            }
            break;

            case 0x31:
            {
                // URL for LaunchBrowser command, GSM 11.14, section 12.48.
                sc.setUrl( decodeEFADN( pdu, posn, length ) );
            }
            break;

            case 0x50:
            {
                // Text attribute, ETSI TS 102 223, section 8.72.
                if ( sc.type() == SetupMenu || sc.type() == SelectItem ) {
                    sc.setTitleAttribute( pdu.mid( posn, length ) );
                } else if ( seenTextAttribute ) {
                    sc.setOtherTextAttribute( pdu.mid( posn, length ) );
                } else {
                    sc.setTextAttribute( pdu.mid( posn, length ) );
                    seenTextAttribute = true;
                }
            }
            break;

            case 0x51:
            {
                // Item text attribute list, ETSI TS 102 223, section 8.73.
                int index = 0;
                while ( length >= 4 && index < items.size() ) {
                    items[index].setLabelAttribute( pdu.mid( posn, 4 ) );
                    length -= 4;
                    posn += 4;
                    ++index;
                }
            }
            break;

            default:
            {
                // Don't know what this is, so add it as an extension field.
                sc.addExtensionField( tag, pdu.mid( posn, length ) );
            }
            break;
        }
        posn = newPosn;
        if ( posn >= (uint)pdu.size() ) {
            break;
        }
        readBer( pdu, posn, tag, length );
    }

    sc.setMenuItems( items );
    return sc;
}

// Write a BER length value.  Exported to qsimterminalresponse.cpp and qsimenvelope.cpp.
void _qtopiaphone_writeBerLength( QByteArray& binary, int length )
{
    int size = binary.size();
    if ( length < 128 ) {
        binary.resize( size + 1 );
        binary[size] = (char)length;
    } else if ( length < 256 ) {
        binary.resize( size + 2 );
        binary[size] = (char)0x81;
        binary[size + 1] = (char)length;
    } else {
        binary.resize( size + 3 );
        binary[size] = (char)0x82;
        binary[size + 1] = (char)( length >> 8 );
        binary[size + 2] = (char)length;
    }
}
#define writeBerLength _qtopiaphone_writeBerLength

// Write a string, encoded in the best possible data coding scheme.
// We also need to export this to qsimterminalresponse.cpp.
void _qtopiaphone_writeTextString( QByteArray& binary, const QString& str,
                                   QSimCommand::ToPduOptions options, int tag = 0x8D );
void _qtopiaphone_writeTextString( QByteArray& binary, const QString& str,
                                   QSimCommand::ToPduOptions options, int tag )
{
    if ( str.isNull() ) {
        binary += (char)tag;
        binary += (char)0x00;
        return;
    }
    if ( str.isEmpty() && ( options & QSimCommand::EncodeEmptyStrings ) == 0 ) {
        // Special form for empty strings.
        binary += (char)tag;
        binary += (char)0x01;
        binary += (char)0x00;
        return;
    }
    int schemeMask = ((tag & 0xFF00) >> 8);     // For USSD string output.
    if ( ( options & QSimCommand::UCS2Strings ) == 0 ) {
        QTextCodec *gsm = QAtUtils::codec( "gsm-noloss" );
        if ( gsm->canEncode( str ) ) {
            if ( ( options & QSimCommand::PackedStrings ) != 0 ) {
                // Use the packed 7-bit GSM alphabet to encode the string.
                QByteArray packed;
                int bitCount = 0;
                int bits = 0;
                for ( int u = 0; u < str.length(); u++ ) {
                    unsigned short c = QGsmCodec::twoByteFromUnicode( str[u].unicode() );
                    if ( c >= 256 ) {
                        // Encode a two-byte sequence.
                        for ( int i = 0; i < 7; i++ ) {
                            if ( bitCount == 8 ) {
                                bitCount = 0;
                                packed += (char)bits;
                                bits = 0;
                            }
                            if ( ((1 << (i+8)) & c) != 0 )
                                bits |= (1 << bitCount);
                            ++bitCount;
                        }
                    }
                    for ( int i = 0; i < 7; i++ ) {
                        if ( bitCount == 8 ) {
                            bitCount = 0;
                            packed += (char)bits;
                            bits = 0;
                        }
                        if ( ((1 << i) & c) != 0 )
                            bits |= (1 << bitCount);
                        ++bitCount;
                    }
                }
                if ( bitCount != 0 ) {
                    packed += (char)bits;
                }
                binary += (char)tag;
                writeBerLength( binary, packed.length() + 1 );
                binary += (char)(QSMS_DefaultAlphabet | schemeMask);
                binary += packed;
            } else {
                // Use the unpacked 8-bit GSM alphabet to encode the string.
                QByteArray unpacked = gsm->fromUnicode( str );
                binary += (char)tag;
                writeBerLength( binary, unpacked.length() + 1 );
                binary += (char)(QSMS_8BitAlphabet | schemeMask);
                binary += unpacked;
            }
            return;
        }
    }

    // If we get here, we must use UCS-2 to encode the text string.
    QByteArray ucs2;
    const ushort *data = str.utf16();
    int len = str.length();
    while ( len-- > 0 ) {
        ushort ch = *data++;
        ucs2 += (char)(ch >> 8);
        ucs2 += (char)ch;
    }
    binary += (char)tag;
    writeBerLength( binary, ucs2.length() + 1 );
    binary += (char)(QSMS_UCS2Alphabet | schemeMask);
    binary += ucs2;
}
#define writeTextString _qtopiaphone_writeTextString

// Write an EFADN string as a BER field.  GSM 11.11, section 10.5.1.
// Exported to qsimcontrolevent.cpp.
void _qtopiaphone_writeEFADN( QByteArray& binary, const QString& str,
                              QSimCommand::ToPduOptions options, int tag = 0x85 );
void _qtopiaphone_writeEFADN( QByteArray& binary, const QString& str,
                              QSimCommand::ToPduOptions options, int tag )
{
    // Determine if we can encode the string in the unpacked GSM alphabet encoding.
    if ( ( options & QSimCommand::UCS2Strings ) == 0 ) {
        QTextCodec *gsm = QAtUtils::codec( "gsm-noloss" );
        if ( gsm->canEncode( str ) ) {
            QByteArray unpacked = gsm->fromUnicode( str );
            if ( tag != -1 ) {
                binary += (char)tag;
                writeBerLength( binary, unpacked.length() );
            }
            binary += unpacked;
            return;
        }
    }

    // If we get here, we must use UCS-2 to encode the text string.
    QByteArray ucs2;
    const ushort *data = str.utf16();
    int len = str.length();
    while ( len-- > 0 ) {
        ushort ch = *data++;
        ucs2 += (char)(ch >> 8);
        ucs2 += (char)ch;
    }
    if ( tag != -1 ) {
        binary += (char)tag;
        writeBerLength( binary, ucs2.length() + 1 );
    }
    binary += (char)0x80;
    binary += ucs2;
}
#define writeEFADN _qtopiaphone_writeEFADN

// Write icon details.
static void writeIcon( QByteArray& binary, uint iconId, bool selfExplanatory, bool mandatory )
{
    if ( iconId ) {
        binary += (char)( mandatory ? 0x9E : 0x1E );
        binary += (char)0x02;
        binary += (char)( selfExplanatory ? 0 : 1 );
        binary += (char)iconId;
    }
}

// Write duration information.  Needs to be exported to qsimterminalresponse.cpp.
void _qtopiaphone_writeDuration( QByteArray& data, uint time )
{
    if ( time != 0 ) {
        data += (char)0x84;
        data += (char)0x02;
        if ( ( time % 1000 ) != 0 && time <= 25500 ) {
            // Encode in tenths of a second.
            data += (char)0x02;
            data += (char)(time / 100);
        } else if ( ( time % 60000 ) != 0 && time <= 255000 ) {
            // Encode in seconds.
            data += (char)0x01;
            data += (char)(time / 1000);
        } else if ( time <= 255 * 6000 ) {
            // Encode in minutes.
            data += (char)0x00;
            data += (char)(time / 60000);
        } else {
            // Encode maximum time value.
            data += (char)0x00;
            data += (char)0xFF;
        }
    }
}
#define writeDuration _qtopiaphone_writeDuration

// Write a subaddress, GSM 11.14, section 12.3.  The actual encoding
// is specified in GSM 24.008, Annex E.
static void writeSubAddress( QByteArray& data, const QString& value )
{
    data += (char)0x88;
    writeBerLength( data, value.length() + 2 );
    data += (char)0x80;     // NSAP address type
    data += (char)0x50;     // NSAP address is BCD-encoded IA5 characters
    foreach ( QChar ch, value ) {
        int val = ch.unicode() - 32;
        if ( val > 127 )
            val = 0;
        data += (char)(((val / 10) << 4) + (val % 10));
    }
}

// Extract an extension field named "tag" from "extData" and write it to "data".
// The field will be removed from "extData".  Returns false if no such field.
// Exported to qsimcontrolevent.cpp.
bool _qtopiaphone_extractAndWriteExtField( QByteArray& data, QByteArray& extData, int tag )
{
    uint startposn;
    uint posn = 0;
    uint currentTag, length;
    while ( posn < (uint)( extData.length() ) ) {
        startposn = posn;
        readBer( extData, posn, currentTag, length );
        if ( ( currentTag & 0x7F ) == (uint)( tag & 0x7F ) ) {
            data += extData.mid( startposn, (posn + length) - startposn );
            extData = extData.left( startposn ) + extData.mid( posn + length );
            return true;
        }
        posn += length;
    }
    return false;
}
#define extractAndWriteExtField _qtopiaphone_extractAndWriteExtField

// Write a text attribute field.
static void writeTextAttribute( QByteArray& data, const QByteArray& attr )
{
    if ( !attr.isEmpty() ) {
        data += (char)0xD0;
        writeBerLength( data, attr.length() );
        data += attr;
    }
}

// Write a Timer Id field.
void _qtopiaphone_writeTimerId( QByteArray& data, uint timerId )
{
    data += 0xa4;
    data += 0x01;
    data += (char) timerId;
}
#define writeTimerId _qtopiaphone_writeTimerId

// Write a Timer Value field.
void _qtopiaphone_writeTimerValue( QByteArray& data, uint value )
{
    if (!value)
        return;

    data += 0xa5;
    data += 0x03;
#define TO_BCD(bin) (char) ((((bin) / 10) & 0xf) | (((bin) % 10) << 4))
    data += TO_BCD(value / 3600);
    data += TO_BCD((value / 60) % 60);
    data += TO_BCD(value % 60);
#undef TO_BCD
}
#define writeTimerValue _qtopiaphone_writeTimerValue

// Write a Bearer description field.
static void writeBearerDesc( QByteArray& data, const QByteArray& bearerDesc )
{
    if ( !bearerDesc.isEmpty() ) {
        data += (char)0x35;
        writeBerLength( data, bearerDesc.length() );
        data += bearerDesc;
    }
}

// Write a Network Access Name field as specified in TS 23.003
static void writeApn( QByteArray& data, const QByteArray& apn )
{
    if ( !apn.isEmpty() ) {
        data += (char)0x47;
        writeBerLength( data, apn.length() );
        data += apn;
    }
}

// Write a Buffer size field.
static void writeBufferSize( QByteArray& data, ushort size )
{
    if ( size ) {
        data += 0x39;
        data += 0x02;
        data += (char)(size >> 8);
        data += (char)size;
    }
}

// Write a data length field.
static void writeDataLength( QByteArray& data, uint value )
{
    data += 0x37;
    data += 0x01;
    data += (char)value;
}

// Write a UICC/terminal interface transport level field
static void writeUti( QByteArray& data, const QByteArray& uti )
{
    if ( !uti.isEmpty() ) {
        data += (char)0x3C;
        writeBerLength( data, uti.length() );
        data += uti;
    }
}

// Write the Address information field
static void writeOtherAddress( QByteArray& data, const QByteArray& otherAddress )
{
    if ( !otherAddress.isEmpty() ) {
        data += (char)0x3E;
        writeBerLength( data, otherAddress.length() );
        data += otherAddress;
    }
}
/*!
    \enum QSimCommand::ToPduOptions
    This enum defines additional options to use when encoding SIM commands with QSimCommand::toPdu().

    \value NoPduOptions No additional options.
    \value NoBerWrapper Do not include the outermost BER wrapper around the command parameters.
    \value PackedStrings Encode text strings in the packed 7-bit GSM alphabet instead
                         of the unpacked 8-bit GSM alphabet.  If a text string cannot
                         be encoded with the GSM alphabet, UCS-2 will be used.
    \value UCS2Strings Encode text strings in the UCS-2 alphabet, even if it could
                       otherwise be encoded in the packed 7-bit or unpacked 8-bit
                       GSM alphabet.
    \value EncodeEmptyStrings Encode empty strings in the actual character set, instead
                       of using the shorthand encoding.
*/

/*!
    Encode a SIM command into its raw binary PDU form, as described
    in 3GPP TS 11.14.  The resulting PDU form may be modified by the
    supplied \a options.

    \sa fromPdu()
*/
QByteArray QSimCommand::toPdu( QSimCommand::ToPduOptions options ) const
{
    QByteArray data;

    // Output the command details.
    QSimCommand::Type cmd = type();
    if ( cmd == NoCommand || cmd == Timeout )
        return QByteArray();
    int qualifier = d->qualifier;
    if ( cmd == GetInkey && wantYesNo() ) {
        // Make sure the "wantDigits" bit is unset if using Yes/No.
        qualifier &= ~0x01;
    }
    data += (char)0x81;
    data += (char)0x03;
    data += (char)commandNumber();
    data += (char)cmd;
    data += (char)qualifier;

    // Output the device identities (SIM to Display/Keypad/Earpiece/etc).
    data += (char)0x82;
    data += (char)0x02;
    data += (char)sourceDevice();
    data += (char)destinationDevice();

    // If user feedback suppression is on, then encode empty strings.
    if ( suppressUserFeedback() )
        options = (QSimCommand::ToPduOptions)( options | EncodeEmptyStrings );

    // Add the command parameters.
    QByteArray extData = extensionData();
    switch ( type() ) {
        case DisplayText:
        {
            writeTextString( data, text(), options );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            if ( immediateResponse() ) {
                data += (char)0xAB;
                data += (char)0x00;
            }
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case GetInkey:
        {
            writeTextString( data, text(), options );
            writeIcon( data, iconId(), iconSelfExplanatory(), false );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case GetInput:
        {
            writeTextString( data, text(), options );
            if ( minimumLength() != 0 || maximumLength() != 255 ) {
                data += (char)0x91;
                data += (char)0x02;
                data += (char)minimumLength();
                data += (char)maximumLength();
            }
            if ( !defaultText().isEmpty() ) {
                writeTextString( data, defaultText(), QSimCommand::NoPduOptions, 0x17 );
            }
            writeIcon( data, iconId(), iconSelfExplanatory(), false );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case PlayTone:
        {
            if ( !text().isEmpty() )
                writeEFADN( data, text(), options );
            if ( tone() != ToneNone ) {
                data += (char)0x8E;
                data += (char)0x01;
                data += (char)tone();
            }
            writeDuration( data, duration() );
            writeIcon( data, iconId(), iconSelfExplanatory(), false );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case PollInterval:
        {
            writeDuration( data, duration() );
        }
        break;

        case SetupMenu:
        case SelectItem:
        {
            if ( type() == SetupMenu || !title().isEmpty() )
                writeEFADN( data, title(), options );
            bool hasIcons = false;
            int attrLen = 0;
            bool hasNextActions = false;
            bool selfExplanatory = false;
            if ( menuItems().size() == 0 ) {
                data += (char)0x8F;
                data += (char)0x00;
            }
            foreach ( QSimMenuItem item, menuItems() ) {
                QByteArray contents;
                contents += (char)item.identifier();
                writeEFADN( contents, item.label(), options, -1 );
                data += (char)0x8F;
                writeBerLength( data, contents.size() );
                data += contents;
                if ( item.iconId() != 0 )
                    hasIcons = true;
                if ( item.nextAction() != 0 )
                    hasNextActions = true;
                if ( item.iconSelfExplanatory() )
                    selfExplanatory = true;
                attrLen += item.labelAttribute().size();
            }
            if ( hasNextActions ) {
                data += (char)0x18;
                data += (char)menuItems().size();
                foreach ( QSimMenuItem item, menuItems() )
                    data += (char)item.nextAction();
            }
            if ( type() == SelectItem && defaultItem() != 0 ) {
                data += (char)0x90;
                data += (char)0x01;
                data += (char)defaultItem();
            }
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            if ( hasIcons ) {
                data += (char)0x9F;
                data += (char)(menuItems().size() + 1);
                data += (char)(selfExplanatory ? 0x00 : 0x01);
                foreach ( QSimMenuItem item, menuItems() )
                    data += (char)item.iconId();
            }
            writeTextAttribute( data, titleAttribute() );
            if ( attrLen != 0 ) {
                data += (char)0xD1;
                writeBerLength( data, attrLen );
                foreach ( QSimMenuItem item, menuItems() ) {
                    data += item.labelAttribute();
                }
            }
        }
        break;

        case SendSMS:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options );
            if ( !number().isEmpty() )
                writeEFADNNumber( data, number() );
            extractAndWriteExtField( data, extData, 0x8B );
            writeIcon( data, iconId(), iconSelfExplanatory(), iconSelfExplanatory() );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case SendSS:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options );
            writeEFADNNumber( data, number(), 0x89, 255 );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case SendUSSD:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), QSimCommand::NoPduOptions );
            if ( ( options & QSimCommand::PackedStrings ) != 0 )
                writeTextString( data, number(), options, 0xF08A );
            else if ( ( options & QSimCommand::UCS2Strings ) != 0 )
                writeTextString( data, number(), options, 0x488A );
            else // 8-Bit USSD
                writeTextString( data, number(), options, 0x448A );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case SetupCall:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), QSimCommand::NoPduOptions );
            writeEFADNNumber( data, number() );
            extractAndWriteExtField( data, extData, 0x87 );
            if ( !subAddress().isEmpty() )
                writeSubAddress( data, subAddress() );
            writeDuration( data, duration() );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            if ( !otherText().isEmpty() )
                writeEFADN( data, otherText(), QSimCommand::NoPduOptions );
            writeIcon( data, otherIconId(), otherIconSelfExplanatory(), true );
            writeTextAttribute( data, textAttribute() );
            writeTextAttribute( data, otherTextAttribute() );
        }
        break;

        case TimerManagement:
        {
            writeTimerId( data, timerId() );
            writeTimerValue( data, duration() / 1000 );
        }
        break;

        case SetupIdleModeText:
        {
            writeTextString( data, text(), options );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case RunATCommand:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), QSimCommand::NoPduOptions );
            extractAndWriteExtField( data, extData, 0xA8 );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case SendDTMF:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options );
            writeEFADNNumber( data, number(), 0xAC );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case LaunchBrowser:
        {
            extractAndWriteExtField( data, extData, 0x30 ); // Browser id
            writeEFADN( data, url(), QSimCommand::NoPduOptions, 0x31 );
            data += extData;        // Add all network setup parameters before the text.
            extData = QByteArray();
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options, 0x05 );
            writeIcon( data, iconId(), iconSelfExplanatory(), false );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case OpenChannel:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options, 0x05 );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            writeBearerDesc( data, bearerDesc() );
            writeBufferSize( data, bufferSize() );
            writeApn( data, apn() );
            writeOtherAddress( data, localAddress() );
            if ( !userLogin().isEmpty() )
                writeTextString( data, userLogin(), QSimCommand::NoPduOptions, 0x0D );
            if ( !userPassword().isEmpty() )
                writeTextString( data, userPassword(), QSimCommand::NoPduOptions, 0x0D );
            writeUti( data, uti() );
            writeOtherAddress( data, destAddress() );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case ReceiveData:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options, 0x05 );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            writeDataLength( data, dataLength() );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case SendData:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options, 0x05 );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            data += extData;
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case CloseChannel:
        case GetChannelStatus:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options, 0x05 );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case ServiceSearch:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options, 0x05 );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            extractAndWriteExtField( data, extData, 0xC3 ); // Service search
            extractAndWriteExtField( data, extData, 0xC2 ); // Device filter
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case GetServiceInformation:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options, 0x05 );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            extractAndWriteExtField( data, extData, 0xC4 ); // Attribute information
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case RetrieveMultimediaMessage:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options, 0x05 );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            extractAndWriteExtField( data, extData, 0xEA ); // Multimedia message reference
            extractAndWriteExtField( data, extData, 0x92 ); // MMS reception file
            extractAndWriteExtField( data, extData, 0xEE ); // Content identifier
            extractAndWriteExtField( data, extData, 0xEB ); // Message identifier
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case SubmitMultimediaMessage:
        {
            if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
                writeEFADN( data, text(), options, 0x05 );
            writeIcon( data, iconId(), iconSelfExplanatory(), true );
            extractAndWriteExtField( data, extData, 0x92 ); // MMS submission file
            extractAndWriteExtField( data, extData, 0xEB ); // Message identifier
            writeTextAttribute( data, textAttribute() );
        }
        break;

        case DisplayMultimediaMessage:
        {
            extractAndWriteExtField( data, extData, 0x92 ); // MMS submission file
            extractAndWriteExtField( data, extData, 0xEB ); // Message identifier
            if ( immediateResponse() ) {
                data += (char)0xAB;
                data += (char)0x00;
            }
        }
        break;

        case LanguageNotification:
        {
            if ( !language().isEmpty() && language().length() == 2 ) {
                data += (char)0xAD;
                data += (char)0x02;
                data += language();
            }
        }
        break;

        default: break;
    }

    // Add any remaining extension data that is specified.
    data += extData;

    // Add the "Proactive SIM" BER command wrapper if required.
    if ( ( options & NoBerWrapper ) == 0 ) {
        QByteArray ber;
        ber += (char)0xD0;
        writeBerLength( ber, data.size() );
        ber += data;
        return ber;
    } else {
        return data;
    }
}

/*!
    Returns the qualifier byte from the header of the SIM command.  The qualifier byte
    contains flags that modify the behavior of the command from its default.  The default
    value is zero.

    Other functions such as hasHelp(), wantDigits(), highPriority(), etc provide a
    more convenient method to access the bits within the qualifier byte.

    Applies to: all commands.

    \sa setQualifier()
*/
int QSimCommand::qualifier() const
{
    return d->qualifier;
}

/*!
    Sets the qualifier byte in the header of the SIM command to \a value.
    The qualifier byte contains flags that modify the behavior of the command
    from its default.

    Other functions such as setHasHelp(), setWantDigits(), setHighPriority(), etc provide a
    more convenient method to set the bits within the qualifier byte.

    Applies to: all commands.

    \sa qualifier()
*/
void QSimCommand::setQualifier( int value )
{
    d->qualifier = value;
}

/*!
    Returns the extension data for this SIM command.  The extension data consists of
    zero or more BER tag-length-value fields for fields that are not otherwise handled
    by some other method in this class.

    Applies to: all commands.

    \sa setExtensionData(), extensionField()
*/
QByteArray QSimCommand::extensionData() const
{
    return d->extensionData;
}

/*!
    Sets the extension data for this SIM command to \a value.  The extension
    data consists of zero or more BER tag-length-value fields for fields that are
    not otherwise handled by some other method in this class.

    Applies to: all commands.

    \sa extensionData(), addExtensionField()
*/
void QSimCommand::setExtensionData( QByteArray value )
{
    d->extensionData = value;
}

/*!
    Returns the contents of an extension field.  The \a tag is an 8-bit value,
    from 3GPP TS 11.14, that specifies the particular field the caller is
    interested in.  The most significant bit of \a tag is ignored when searching
    for the field, as it contains the "must comprehend" status from 3GPP TS 11.14,
    and is not important for locating the desired field.

    This is a simpler method than extensionData() for accessing values within
    the extension data.  As an example, the following code extracts the
    "SMS TPDU" information from a \c SendSMS SIM command:

    \code
    QSimCommand cmd;
    ...
    QByteArray tpdu = cmd.extensionField(0x8B);
    \endcode

    Applies to: all commands.

    \sa addExtensionField()
*/
QByteArray QSimCommand::extensionField( int tag ) const
{
    uint posn = 0;
    uint currentTag, length;
    while ( posn < (uint)( d->extensionData.length() ) ) {
        readBer( d->extensionData, posn, currentTag, length );
        if ( ( currentTag & 0x7F ) == (uint)( tag & 0x7F ) )
            return d->extensionData.mid( posn, length );
        posn += length;
    }
    return QByteArray();
}

/*!
    Adds an extension field to the data from extensionData().  The field will have
    the specified \a tag and contents given by \a value.

    Applies to: all commands.

    \sa extensionField()
*/
void QSimCommand::addExtensionField( int tag, const QByteArray& value )
{
    d->extensionData += (char)tag;
    writeBerLength( d->extensionData, value.size() );
    d->extensionData += value;
}

// Get a writable copy of the shared data storage.
QSimCommandPrivate *QSimCommand::dwrite()
{
    // If we are the only user of the private object, return it as-is.
    if ( d->ref == 1 )
        return d;

    // Create a new private object and copy the current contents into it.
    QSimCommandPrivate *newd = new QSimCommandPrivate(d);
    if ( !d->ref.deref() )
        delete d;
    d = newd;
    return newd;
}

#define EMS_ALIGNMENT       0x03
#define EMS_LEFT            0x00
#define EMS_CENTER          0x01
#define EMS_RIGHT           0x02
#define EMS_NO_ALIGN        0x03
#define EMS_FONT_SIZE       0x0C
#define EMS_FONT_LARGE      0x04
#define EMS_FONT_SMALL      0x08
#define EMS_BOLD            0x10
#define EMS_ITALIC          0x20
#define EMS_UNDERLINE       0x40
#define EMS_STRIKE          0x80
#define EMS_NO_FORMAT       ((-1 << 8) | EMS_NO_ALIGN)

// Map an EMS color code into a HTML color value.
static QString mapEmsColor(int color)
{
    static const char * const colors[16] = {
        "#000000",      // Black
        "#808080",      // Dark Grey
        "#800000",      // Dark Red
        "#808000",      // Dark Yellow
        "#008000",      // Dark Green
        "#008080",      // Dark Cyan
        "#000080",      // Dark Blue
        "#800080",      // Dark Magenta
        "#C0C0C0",      // Grey
        "#FFFFFF",      // White
        "#FF0000",      // Bright Red
        "#FFFF00",      // Bright Yellow
        "#00FF00",      // Bright Green
        "#00FFFF",      // Bright Cyan
        "#0000FF",      // Bright Blue
        "#FF00FF"       // Bright Magenta
    };
    return QString::fromLatin1(colors[color & 0x0F]);
}

// Convert a text string into HTML, using the specified EMS attributes.
static QString textToHtml(const QString& text, const QByteArray& attrs)
{
    if (text.isEmpty())
        return text;

    // Scan the attribute array and build up the formatting
    // flags for every character in the text string.
    int len = text.length();
    QVarLengthArray<int> formats(len);
    for (int posn = 0; posn < len; ++posn) {
        formats[posn] = EMS_NO_FORMAT;
    }
    int bgcolor = -1;
    for (int index = 0; (index + 3) <= attrs.size(); index += 4) {
        // Extract the next formatting block.
        int start = attrs[index] & 0xFF;
        int end;
        if (attrs[index + 1])
            end = start + (attrs[index + 1] & 0xFF);
        else
            end = len;
        int format = attrs[index + 2] & 0xFF;
        int colors;
        if ((index + 4) <= attrs.size()) {    // This byte is optional.
            colors = attrs[index + 3] & 0xFF;
            if (bgcolor == -1)
                bgcolor = ((colors >> 4) & 0x0F);
        } else {
            colors = -1;
        }

        // Apply the formatting to all of the positions that need it.
        while (start < end && start < len) {
            formats[start] = (colors << 8) | format;
            ++start;
        }
    }

    // Convert the text string according to the instructions.
    QString result;
    int posn = 0;
    int format = EMS_NO_FORMAT;
    int newFormat;
    if (bgcolor != -1) {
        // Set the overall background color for the entire page based
        // on the background color for the first attribute block.
        // If there are no attribute blocks, or only one attribute block
        // with three bytes, then leave the background color as the
        // system default.
        result += QLatin1String("<body bgcolor=\"");
        result += mapEmsColor(bgcolor);
        result += QLatin1String("\">");
    }
    while (posn < len) {
        // Copy characters that have the same format as the previous one.
        while (posn < len && formats[posn] == format) {
            QChar ch = text[posn];
            if (ch.unicode() == '\n') {
                result += QLatin1String("<br>");
            } else if (ch.unicode() == '\r') {
                result += QLatin1String("<br>");
                if ((posn + 1) < len && text[posn + 1] == QChar('\n'))
                    ++posn;
            } else if (ch.unicode() == '<') {
                result += QLatin1String("&lt;");
            } else if (ch.unicode() == '>') {
                result += QLatin1String("&gt;");
            } else if (ch.unicode() == '&') {
                result += QLatin1String("&amp;");
            } else {
                result += ch;
            }
            ++posn;
        }

        // Adjust the format to match the new requirements.
        if (posn < len)
            newFormat = formats[posn];
        else
            newFormat = EMS_NO_FORMAT;
        int oldColor = (format >> 8);
        int newColor = (newFormat >> 8);
        if ((format & EMS_STRIKE) != 0)
            result += QLatin1String("</s>");
        if ((format & EMS_UNDERLINE) != 0)
            result += QLatin1String("</u>");
        if ((format & EMS_ITALIC) != 0)
            result += QLatin1String("</i>");
        if ((format & EMS_BOLD) != 0)
            result += QLatin1String("</b>");
        if ((format & EMS_FONT_SIZE) == EMS_FONT_SMALL)
            result += QLatin1String("</small>");
        else if ((format & EMS_FONT_SIZE) == EMS_FONT_LARGE)
            result += QLatin1String("</big>");
        if (oldColor != -1)
            result += QLatin1String("</font>");
        if ((format & EMS_ALIGNMENT) != (newFormat & EMS_ALIGNMENT)) {
            if ((format & EMS_ALIGNMENT) == EMS_LEFT)
                result += QLatin1String("</div>");
            else if ((format & EMS_ALIGNMENT) == EMS_RIGHT)
                result += QLatin1String("</div>");
            else if ((format & EMS_ALIGNMENT) == EMS_CENTER)
                result += QLatin1String("</center>");
            if ((newFormat & EMS_ALIGNMENT) == EMS_LEFT)
                result += QLatin1String("<div align=\"left\">");
            else if ((newFormat & EMS_ALIGNMENT) == EMS_RIGHT)
                result += QLatin1String("<div align=\"right\">");
            else if ((newFormat & EMS_ALIGNMENT) == EMS_CENTER)
                result += QLatin1String("<center>");
        }
        if (newColor != -1) {
            result += QLatin1String("<font");
            int back = ((newColor >> 4) & 0x0F);
            int fore = (newColor & 0x0F);
            if (back != bgcolor) {
                result += QLatin1String(" style=\"background-color: ");
                result += mapEmsColor(back);
                result += QLatin1String("\"");
            }
            result += QLatin1String(" color=\"");
            result += mapEmsColor(fore);
            result += QLatin1String("\">");
        }
        if ((newFormat & EMS_FONT_SIZE) == EMS_FONT_SMALL)
            result += QLatin1String("<small>");
        else if ((newFormat & EMS_FONT_SIZE) == EMS_FONT_LARGE)
            result += QLatin1String("<big>");
        if ((newFormat & EMS_BOLD) != 0)
            result += QLatin1String("<b>");
        if ((newFormat & EMS_ITALIC) != 0)
            result += QLatin1String("<i>");
        if ((newFormat & EMS_UNDERLINE) != 0)
            result += QLatin1String("<u>");
        if ((newFormat & EMS_STRIKE) != 0)
            result += QLatin1String("<s>");

        // Switch to the new format.
        format = newFormat;
    }
    if (bgcolor != -1) {
        // Terminate the outer background color declaration.
        result += QLatin1String("</body>");
    }

    return result;
}
