[PATCH v2] sim: add +CNUM support for HFP emulator
by Frédéric Danis
---
src/sim.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 66 insertions(+), 0 deletions(-)
diff --git a/src/sim.c b/src/sim.c
index 98d4cc4..af7a715 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -106,6 +106,7 @@ struct ofono_sim {
const struct ofono_sim_driver *driver;
void *driver_data;
struct ofono_atom *atom;
+ unsigned int hfp_watch;
};
struct msisdn_set_request {
@@ -2445,6 +2446,13 @@ void ofono_sim_driver_unregister(const struct ofono_sim_driver *d)
g_drivers = g_slist_remove(g_drivers, (void *) d);
}
+static void emulator_remove_handler(struct ofono_atom *atom, void *data)
+{
+ struct ofono_emulator *em = __ofono_atom_get_data(atom);
+
+ ofono_emulator_remove_handler(em, data);
+}
+
static void sim_unregister(struct ofono_atom *atom)
{
DBusConnection *conn = ofono_dbus_get_connection();
@@ -2452,6 +2460,13 @@ static void sim_unregister(struct ofono_atom *atom)
const char *path = __ofono_atom_get_path(atom);
struct ofono_sim *sim = __ofono_atom_get_data(atom);
+ __ofono_modem_foreach_registered_atom(modem,
+ OFONO_ATOM_TYPE_EMULATOR_HFP,
+ emulator_remove_handler,
+ "+CNUM");
+
+ __ofono_modem_remove_atom_watch(modem, sim->hfp_watch);
+
__ofono_watchlist_free(sim->state_watches);
sim->state_watches = NULL;
@@ -2519,6 +2534,53 @@ struct ofono_sim *ofono_sim_create(struct ofono_modem *modem,
return sim;
}
+static void emulator_cnum_cb(struct ofono_emulator *em,
+ struct ofono_emulator_request *req, void *userdata)
+{
+ struct ofono_sim *sim = userdata;
+ struct ofono_error result;
+ GSList *l;
+ const char *phone;
+ /*
+ * '+CNUM: ,"+",,,4' + phone number + phone type on 3 digits max
+ * + terminating null
+ */
+ char buf[OFONO_MAX_PHONE_NUMBER_LENGTH + 18 + 1];
+
+ result.error = 0;
+
+ switch (ofono_emulator_request_get_type(req)) {
+ case OFONO_EMULATOR_REQUEST_TYPE_COMMAND_ONLY:
+ for (l = sim->own_numbers; l; l = l->next) {
+ struct ofono_phone_number *ph = l->data;
+
+ phone = phone_number_to_string(ph);
+ sprintf(buf, "+CNUM: ,\"%s\",%d,,4", phone, ph->type);
+ ofono_emulator_send_info(em, buf, l->next == NULL ?
+ TRUE : FALSE);
+ }
+
+ result.type = OFONO_ERROR_TYPE_NO_ERROR;
+ ofono_emulator_send_final(em, &result);
+ break;
+
+ default:
+ result.type = OFONO_ERROR_TYPE_FAILURE;
+ ofono_emulator_send_final(em, &result);
+ };
+}
+
+static void emulator_hfp_watch(struct ofono_atom *atom,
+ enum ofono_atom_watch_condition cond,
+ void *data)
+{
+ struct ofono_emulator *em = __ofono_atom_get_data(atom);
+
+ if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED)
+ ofono_emulator_add_handler(em, "+CNUM", emulator_cnum_cb, data,
+ NULL);
+}
+
void ofono_sim_register(struct ofono_sim *sim)
{
DBusConnection *conn = ofono_dbus_get_connection();
@@ -2545,6 +2607,10 @@ void ofono_sim_register(struct ofono_sim *sim)
if (sim->state > OFONO_SIM_STATE_NOT_PRESENT)
sim_initialize(sim);
+
+ sim->hfp_watch = __ofono_modem_add_atom_watch(modem,
+ OFONO_ATOM_TYPE_EMULATOR_HFP,
+ emulator_hfp_watch, sim, NULL);
}
void ofono_sim_remove(struct ofono_sim *sim)
--
1.7.1
9 years, 9 months
[PATCH v2 2/2] simapplication: Add a new SIM applet dedicated to BIP commands
by Philippe Nunes
---
src/simapplication.cpp | 161 ++++++++++++++++++++++++++++++++++++++++++++++++
src/simapplication.h | 2 +
2 files changed, 163 insertions(+), 0 deletions(-)
diff --git a/src/simapplication.cpp b/src/simapplication.cpp
index 14fa8c0..f64da16 100644
--- a/src/simapplication.cpp
+++ b/src/simapplication.cpp
@@ -291,6 +291,7 @@ const QString DemoSimApplication::getName()
#define MainMenu_Timers 16
#define MainMenu_Refresh 17
#define MainMenu_LocalInfo 18
+#define MainMenu_BIP 19
#define SportsMenu_Chess 1
#define SportsMenu_Painting 2
@@ -349,6 +350,12 @@ const QString DemoSimApplication::getName()
#define LocalInfoMenu_Time 1
#define LocalInfoMenu_Lang 2
+#define BIPMenu_OpenChannel 1
+#define BIPMenu_CloseChannel 2
+#define BIPMenu_ReceiveData 3
+#define BIPMenu_SendData 4
+#define BIPMenu_GetChannelStatus 5
+
enum SendSMSMenuItems {
SendSMS_Unpacked = 1,
SendSMS_Packed,
@@ -448,6 +455,10 @@ void DemoSimApplication::mainMenu()
item.setLabel( "Provide Local Information" );
items += item;
+ item.setIdentifier( MainMenu_BIP );
+ item.setLabel( "BIP commands" );
+ items += item;
+
cmd.setMenuItems( items );
command( cmd, 0, 0 );
@@ -590,6 +601,12 @@ void DemoSimApplication::mainMenuSelection( int id )
}
break;
+ case MainMenu_BIP:
+ {
+ sendBIPMenu();
+ }
+ break;
+
default:
{
// Don't know what this item is, so just re-display the main menu.
@@ -2351,3 +2368,147 @@ void DemoSimApplication::localInfoMenu( const QSimTerminalResponse& resp )
endSession();
}
}
+
+void DemoSimApplication::BIPMenu( const QSimTerminalResponse& resp )
+{
+ QSimCommand cmd;
+
+ if ( resp.result() == QSimTerminalResponse::Success ) {
+ switch ( resp.menuItem() ) {
+
+ case BIPMenu_OpenChannel:
+ {
+ QByteArray bearerDesc;
+ QByteArray uti;
+ QByteArray destAddress;
+ QByteArray apn;
+
+ bearerDesc += 0x02;
+ bearerDesc += 0x03;
+ bearerDesc += 0x04;
+ bearerDesc += 0x03;
+ bearerDesc += 0x04;
+ bearerDesc += 0x1F;
+ bearerDesc += 0x02;
+
+ uti += 0x01;
+ uti += 0xAD;
+ uti += 0x9C;
+
+ destAddress += 0x21;
+ destAddress += 0x01;
+ destAddress += 0x01;
+ destAddress += 0x01;
+ destAddress += 0x01;
+
+ apn += 0x06;
+ apn += 0x54;
+ apn += 0x65;
+ apn += 0x73;
+ apn += 0x74;
+ apn += 0x47;
+ apn += 0x70;
+ apn += 0x02;
+ apn += 0x72;
+ apn += 0x73;
+
+ cmd.setType( QSimCommand::OpenChannel );
+ cmd.setQualifier( QSimCommand::OpenchannelImmediate );
+ cmd.setText("Open ID");
+ cmd.setBearerDesc(bearerDesc);
+ cmd.setBufferSize(1400);
+ cmd.setApn(apn);
+ cmd.setUserLogin("UserLog");
+ cmd.setUserPassword("UserPwd");
+ cmd.setUti(uti);
+ cmd.setDestAddress(destAddress);
+ command( cmd, this, SLOT(sendBIPMenu()) );
+ }
+ break;
+
+ case BIPMenu_ReceiveData:
+ {
+ cmd.setType( QSimCommand::ReceiveData );
+ cmd.setDestinationDevice( QSimCommand::Channel1 );
+ cmd.setText("Receive Data 1");
+ cmd.setDataLength(200);
+ command( cmd, this, SLOT(sendBIPMenu()) );
+ }
+ break;
+
+ case BIPMenu_SendData:
+ {
+ QByteArray data;
+
+ data += 0x01;
+ data += 0x02;
+ data += 0x03;
+ data += 0x04;
+ data += 0x05;
+
+ cmd.setType( QSimCommand::SendData );
+ cmd.setDestinationDevice( QSimCommand::Channel1 );
+ cmd.setText("Send Data 1");
+ cmd.addExtensionField( 0x36, data );
+ command( cmd, this, SLOT(sendBIPMenu()) );
+ }
+ break;
+
+ case BIPMenu_CloseChannel:
+ {
+ cmd.setType( QSimCommand::CloseChannel );
+ cmd.setDestinationDevice( QSimCommand::Channel1 );
+ cmd.setText("Close ID 1");
+ command( cmd, this, SLOT(sendBIPMenu()) );
+ }
+ break;
+
+ case BIPMenu_GetChannelStatus:
+ {
+ cmd.setType( QSimCommand::GetChannelStatus );
+ command( cmd, this, SLOT(sendBIPMenu()) );
+ }
+ break;
+
+ default:
+ endSession();
+ break;
+ }
+ } else {
+ endSession();
+ }
+}
+
+void DemoSimApplication::sendBIPMenu()
+{
+ QSimCommand cmd;
+ QSimMenuItem item;
+ QList<QSimMenuItem> items;
+
+ cmd.setType( QSimCommand::SelectItem );
+ cmd.setTitle( "BIP commands Menu" );
+
+ item.setIdentifier( BIPMenu_OpenChannel );
+ item.setLabel( "Open channel" );
+ items += item;
+
+ item.setIdentifier( BIPMenu_CloseChannel );
+ item.setLabel( "Close channel" );
+ items += item;
+
+ item.setIdentifier( BIPMenu_ReceiveData );
+ item.setLabel( "Receive data" );
+ items += item;
+
+ item.setIdentifier( BIPMenu_SendData );
+ item.setLabel( "Send data" );
+ items += item;
+
+ item.setIdentifier( BIPMenu_GetChannelStatus );
+ item.setLabel( "Get channel status" );
+ items += item;
+
+ cmd.setMenuItems( items );
+
+ command( cmd, this, SLOT(BIPMenu(QSimTerminalResponse)) );
+}
diff --git a/src/simapplication.h b/src/simapplication.h
index 61250e5..b41c781 100644
--- a/src/simapplication.h
+++ b/src/simapplication.h
@@ -130,6 +130,8 @@ protected slots:
void refreshMenuResp( const QSimTerminalResponse& resp );
void sendLocalInfoMenu();
void localInfoMenu( const QSimTerminalResponse& resp );
+ void sendBIPMenu();
+ void BIPMenu( const QSimTerminalResponse& resp );
private:
int sticksLeft;
--
1.7.1
9 years, 9 months
[PATCH v2 1/2] qsimcommand: Add properties and TLV builders to support BIP commands
by Philippe Nunes
---
src/qsimcommand.cpp | 204 +++++++++++++++++++++++++++++++++++++++++++++++++--
src/qsimcommand.h | 37 +++++++++
2 files changed, 235 insertions(+), 6 deletions(-)
diff --git a/src/qsimcommand.cpp b/src/qsimcommand.cpp
index ecdf43f..f5dbdf2 100644
--- a/src/qsimcommand.cpp
+++ b/src/qsimcommand.cpp
@@ -69,6 +69,8 @@ public:
timerId = 0;
device = -1;
qualifier = 0;
+ bufferSize = 0;
+ dataLength = 0;
}
QSimCommandPrivate( QSimCommandPrivate *other )
{
@@ -102,6 +104,15 @@ public:
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
@@ -165,7 +176,15 @@ public:
int device;
int qualifier;
QByteArray extensionData;
-
+ QByteArray bearerDesc;
+ ushort bufferSize;
+ uint dataLength;
+ QByteArray apn;
+ QByteArray uti;
+ QString userLogin;
+ QString userPassword;
+ QByteArray destAddress;
+ QByteArray localAddress;
};
@@ -2202,6 +2221,96 @@ 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.
*/
@@ -3045,6 +3154,64 @@ void _qtopiaphone_writeTimerValue( QByteArray& data, uint value )
}
#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().
@@ -3324,21 +3491,46 @@ QByteArray QSimCommand::toPdu( QSimCommand::ToPduOptions options ) const
if ( !text().isEmpty() || ( options & QSimCommand::EncodeEmptyStrings ) != 0 )
writeEFADN( data, text(), options, 0x05 );
writeIcon( data, iconId(), iconSelfExplanatory(), true );
- if ( !number().isEmpty() )
- writeEFADNNumber( data, number() );
- if ( !subAddress().isEmpty() )
- writeSubAddress( data, subAddress() );
+ 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 CloseChannel:
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;
diff --git a/src/qsimcommand.h b/src/qsimcommand.h
index eadd768..ea7f17a 100644
--- a/src/qsimcommand.h
+++ b/src/qsimcommand.h
@@ -215,6 +215,16 @@ public:
Network = 0x83
};
+ enum OpenChannelQualifier {
+ OpenchannelOnDemand = 0x00,
+ OpenchannelImmediate = 0x01,
+ };
+
+ enum SendDataQualifier {
+ SendDataStoreData = 0x00,
+ SendDataImmediately = 0x01,
+ };
+
int commandNumber() const;
void setCommandNumber( int value );
@@ -362,6 +372,33 @@ public:
int qualifier() const;
void setQualifier( int value );
+ QByteArray bearerDesc() const;
+ void setBearerDesc( const QByteArray& value );
+
+ ushort bufferSize() const;
+ void setBufferSize( ushort value );
+
+ uint dataLength() const;
+ void setDataLength( uint value );
+
+ QByteArray apn() const;
+ void setApn( const QByteArray& value );
+
+ QByteArray destAddress() const;
+ void setDestAddress( const QByteArray& value );
+
+ QByteArray localAddress() const;
+ void setLocalAddress( const QByteArray& value );
+
+ QString userLogin() const;
+ void setUserLogin( const QString& value );
+
+ QString userPassword() const;
+ void setUserPassword( const QString& value );
+
+ QByteArray uti() const;
+ void setUti( const QByteArray& value );
+
QByteArray extensionData() const;
void setExtensionData( QByteArray value );
--
1.7.1
9 years, 9 months
[PATCH v3 1/2] stkutil: Complete the TLV parsing/builder to support BIP commands
by Philippe Nunes
---
src/stkutil.c | 278 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
src/stkutil.h | 131 ++++++++++++++++++++++-----
2 files changed, 370 insertions(+), 39 deletions(-)
diff --git a/src/stkutil.c b/src/stkutil.c
index 3418b4b..89721e7 100644
--- a/src/stkutil.c
+++ b/src/stkutil.c
@@ -1264,8 +1264,20 @@ static gboolean parse_dataobj_bearer_description(
data = comprehension_tlv_iter_get_data(iter);
bd->type = data[0];
- bd->len = len - 1;
- memcpy(bd->pars, data + 1, bd->len);
+
+ /* Parse only the packet data service bearer parameters */
+ if (bd->type != STK_BEARER_TYPE_GPRS_UTRAN)
+ return FALSE;
+
+ if (len < 7)
+ return FALSE;
+
+ bd->gprs.precedence = data[1];
+ bd->gprs.delay = data[2];
+ bd->gprs.reliability = data[3];
+ bd->gprs.peak = data[4];
+ bd->gprs.mean = data[5];
+ bd->gprs.pdp_type = data[6];
return TRUE;
}
@@ -1355,8 +1367,16 @@ static gboolean parse_dataobj_other_address(
return FALSE;
data = comprehension_tlv_iter_get_data(iter);
+
+ if (data[0] != STK_ADDRESS_IPV4 && data[0] != STK_ADDRESS_IPV6)
+ return FALSE;
+
oa->type = data[0];
- memcpy(&oa->addr, data + 1, len - 1);
+
+ if (oa->type == STK_ADDRESS_IPV4)
+ memcpy(&oa->addr.ipv4, data + 1, 4);
+ else
+ memcpy(&oa->addr.ipv6, data + 1, 16);
return TRUE;
}
@@ -1604,16 +1624,42 @@ static gboolean parse_dataobj_esn(struct comprehension_tlv_iter *iter,
static gboolean parse_dataobj_network_access_name(
struct comprehension_tlv_iter *iter, void *user)
{
- struct stk_network_access_name *nan = user;
+ char **apn = user;
const unsigned char *data;
unsigned int len = comprehension_tlv_iter_get_length(iter);
+ unsigned char label_size;
+ unsigned char offset = 0;
+ char decoded_apn[100];
- if (len == 0)
+ if (len == 0 || len > 100)
return FALSE;
data = comprehension_tlv_iter_get_data(iter);
- nan->len = len;
- memcpy(nan->name, data, len);
+ /*
+ * As specified in TS 23 003 Section 9
+ * The APN consists of one or more labels. Each label is coded as
+ * a one octet length field followed by that number of octets coded
+ * as 8 bit ASCII characters
+ */
+
+ while (len) {
+ label_size = *data;
+
+ if (label_size > (len-1))
+ return FALSE;
+
+ memcpy(decoded_apn + offset, data + 1, label_size);
+
+ data += label_size + 1;
+ offset += label_size;
+ len -= label_size + 1;
+
+ if (len)
+ decoded_apn[offset++] = '.';
+ }
+
+ decoded_apn[offset] = '\0';
+ *apn = g_strdup(decoded_apn);
return TRUE;
}
@@ -3274,7 +3320,69 @@ static enum stk_command_parse_result parse_launch_browser(
STK_DATA_OBJECT_TYPE_INVALID);
}
-/* TODO: parse_open_channel */
+static void destroy_open_channel(struct stk_command *command)
+{
+ g_free(command->open_channel.alpha_id);
+ g_free(command->open_channel.apn);
+ g_free(command->open_channel.text_usr);
+ g_free(command->open_channel.text_passwd);
+}
+
+static enum stk_command_parse_result parse_open_channel(
+ struct stk_command *command,
+ struct comprehension_tlv_iter *iter)
+{
+ struct stk_command_open_channel *obj = &command->open_channel;
+ enum stk_command_parse_result status;
+
+ if (command->qualifier >= 0x08)
+ return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
+
+ if (command->src != STK_DEVICE_IDENTITY_TYPE_UICC)
+ return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
+
+ if (command->dst != STK_DEVICE_IDENTITY_TYPE_TERMINAL)
+ return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
+
+ command->destructor = destroy_open_channel;
+
+ /*
+ * parse the Open Channel data objects related to packet data service
+ * bearer
+ */
+ status = parse_dataobj(iter,
+ STK_DATA_OBJECT_TYPE_ALPHA_ID, 0,
+ &obj->alpha_id,
+ STK_DATA_OBJECT_TYPE_ICON_ID, 0,
+ &obj->icon_id,
+ STK_DATA_OBJECT_TYPE_BEARER_DESCRIPTION,
+ DATAOBJ_FLAG_MANDATORY | DATAOBJ_FLAG_MINIMUM,
+ &obj->bearer_desc,
+ STK_DATA_OBJECT_TYPE_BUFFER_SIZE,
+ DATAOBJ_FLAG_MANDATORY | DATAOBJ_FLAG_MINIMUM,
+ &obj->buf_size,
+ STK_DATA_OBJECT_TYPE_NETWORK_ACCESS_NAME, 0,
+ &obj->apn,
+ STK_DATA_OBJECT_TYPE_OTHER_ADDRESS, 0,
+ &obj->local_addr,
+ STK_DATA_OBJECT_TYPE_TEXT, 0,
+ &obj->text_usr,
+ STK_DATA_OBJECT_TYPE_TEXT, 0,
+ &obj->text_passwd,
+ STK_DATA_OBJECT_TYPE_UICC_TE_INTERFACE, 0,
+ &obj->uti,
+ STK_DATA_OBJECT_TYPE_OTHER_ADDRESS, 0,
+ &obj->data_dest_addr,
+ STK_DATA_OBJECT_TYPE_TEXT_ATTRIBUTE, 0,
+ &obj->text_attr,
+ STK_DATA_OBJECT_TYPE_FRAME_ID, 0,
+ &obj->frame_id,
+ STK_DATA_OBJECT_TYPE_INVALID);
+
+ CHECK_TEXT_AND_ICON(obj->alpha_id, obj->icon_id.id);
+
+ return status;
+}
static void destroy_close_channel(struct stk_command *command)
{
@@ -3291,7 +3399,8 @@ static enum stk_command_parse_result parse_close_channel(
if (command->src != STK_DEVICE_IDENTITY_TYPE_UICC)
return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
- if (command->dst != STK_DEVICE_IDENTITY_TYPE_TERMINAL)
+ if ((command->dst < STK_DEVICE_IDENTITY_TYPE_CHANNEL_1) ||
+ (command->dst > STK_DEVICE_IDENTITY_TYPE_CHANNEL_7))
return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
command->destructor = destroy_close_channel;
@@ -3363,6 +3472,9 @@ static enum stk_command_parse_result parse_send_data(
struct stk_command_send_data *obj = &command->send_data;
enum stk_command_parse_result status;
+ if (command->qualifier > STK_SEND_DATA_IMMEDIATELY)
+ return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
+
if (command->src != STK_DEVICE_IDENTITY_TYPE_UICC)
return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
@@ -3737,6 +3849,8 @@ static enum stk_command_parse_result parse_command_body(
return parse_language_notification(command, iter);
case STK_COMMAND_TYPE_LAUNCH_BROWSER:
return parse_launch_browser(command, iter);
+ case STK_COMMAND_TYPE_OPEN_CHANNEL:
+ return parse_open_channel(command, iter);
case STK_COMMAND_TYPE_CLOSE_CHANNEL:
return parse_close_channel(command, iter);
case STK_COMMAND_TYPE_RECEIVE_DATA:
@@ -4752,12 +4866,35 @@ static gboolean build_dataobj_bearer_description(struct stk_tlv_builder *tlv,
const struct stk_bearer_description *bd = data;
unsigned char tag = STK_DATA_OBJECT_TYPE_BEARER_DESCRIPTION;
- if (bd->type == 0x00)
+ if (bd->type != STK_BEARER_TYPE_GPRS_UTRAN)
return TRUE;
return stk_tlv_builder_open_container(tlv, cr, tag, FALSE) &&
stk_tlv_builder_append_byte(tlv, bd->type) &&
- stk_tlv_builder_append_bytes(tlv, bd->pars, bd->len) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.precedence) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.delay) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.reliability) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.peak) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.mean) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.pdp_type) &&
+ stk_tlv_builder_close_container(tlv);
+}
+
+/* Described in TS 102.223 Section 8.53 */
+static gboolean build_dataobj_channel_data(struct stk_tlv_builder *tlv,
+ const void *data, gboolean cr)
+{
+ const struct stk_common_byte_array *cd = data;
+ unsigned char tag = STK_DATA_OBJECT_TYPE_CHANNEL_DATA;
+
+ return stk_tlv_builder_open_container(tlv, cr, tag, TRUE) &&
+ stk_tlv_builder_append_bytes(tlv, cd->array, cd->len) &&
stk_tlv_builder_close_container(tlv);
}
@@ -4766,7 +4903,7 @@ static gboolean build_dataobj_channel_data_length(
struct stk_tlv_builder *tlv,
const void *data, gboolean cr)
{
- const unsigned int *length = data;
+ const unsigned short *length = data;
unsigned char tag = STK_DATA_OBJECT_TYPE_CHANNEL_DATA_LENGTH;
return stk_tlv_builder_open_container(tlv, cr, tag, FALSE) &&
@@ -4774,15 +4911,50 @@ static gboolean build_dataobj_channel_data_length(
stk_tlv_builder_close_container(tlv);
}
+/* Described in TS 102.223 Section 8.55 */
+static gboolean build_dataobj_buffer_size(struct stk_tlv_builder *tlv,
+ const void *data, gboolean cr)
+{
+ const unsigned short *buf_size = data;
+ unsigned char tag = STK_DATA_OBJECT_TYPE_BUFFER_SIZE;
+
+ return stk_tlv_builder_open_container(tlv, cr, tag, FALSE) &&
+ stk_tlv_builder_append_short(tlv, *buf_size) &&
+ stk_tlv_builder_close_container(tlv);
+}
+
/* Described in TS 102.223 Section 8.56 */
static gboolean build_dataobj_channel_status(struct stk_tlv_builder *tlv,
const void *data, gboolean cr)
{
+ const struct stk_channel *channel = data;
unsigned char tag = STK_DATA_OBJECT_TYPE_CHANNEL_STATUS;
+ unsigned char byte[2];
+
+ switch (channel->status) {
+ case STK_CHANNEL_PACKET_DATA_SERVICE_NOT_ACTIVATED:
+ case STK_CHANNEL_TCP_IN_CLOSED_STATE:
+ byte[0] = channel->id;
+ byte[1] = 0x00;
+ break;
+ case STK_CHANNEL_PACKET_DATA_SERVICE_ACTIVATED:
+ case STK_CHANNEL_TCP_IN_ESTABLISHED_STATE:
+ byte[0] = channel->id | 0x80;
+ byte[1] = 0x00;
+ break;
+ case STK_CHANNEL_TCP_IN_LISTEN_STATE:
+ byte[0] = channel->id | 0x40;
+ byte[1] = 0x00;
+ break;
+ case STK_CHANNEL_LINK_DROPPED:
+ byte[0] = channel->id;
+ byte[1] = 0x05;
+ break;
+ }
return stk_tlv_builder_open_container(tlv, cr, tag, FALSE) &&
- stk_tlv_builder_append_bytes(tlv, data, 2) &&
- stk_tlv_builder_close_container(tlv);
+ stk_tlv_builder_append_bytes(tlv, byte, 2) &&
+ stk_tlv_builder_close_container(tlv);
}
/* Described in TS 102.223 Section 8.58 */
@@ -5454,6 +5626,63 @@ static gboolean build_local_info(struct stk_tlv_builder *builder,
return FALSE;
}
+static gboolean build_open_channel(struct stk_tlv_builder *builder,
+ const struct stk_response *response)
+{
+ const struct stk_response_open_channel *open_channel =
+ &response->open_channel;
+
+ /* insert channel identifier only in case of success */
+ if (response->result.type == STK_RESULT_TYPE_SUCCESS) {
+ if (build_dataobj(builder, build_dataobj_channel_status,
+ 0, &open_channel->channel,
+ NULL) != TRUE)
+ return FALSE;
+ }
+
+ return build_dataobj(builder,
+ build_dataobj_bearer_description,
+ 0, &open_channel->bearer_desc,
+ build_dataobj_buffer_size,
+ 0, &open_channel->buf_size,
+ NULL);
+}
+
+static gboolean build_receive_data(struct stk_tlv_builder *builder,
+ const struct stk_response *response)
+{
+ const struct stk_response_receive_data *receive_data =
+ &response->receive_data;
+
+ if (response->result.type != STK_RESULT_TYPE_SUCCESS)
+ return TRUE;
+
+ if (receive_data->rx_data.len) {
+ if (build_dataobj(builder, build_dataobj_channel_data,
+ DATAOBJ_FLAG_CR,
+ &response->receive_data.rx_data,
+ NULL) != TRUE)
+ return FALSE;
+ }
+
+ return build_dataobj(builder, build_dataobj_channel_data_length,
+ DATAOBJ_FLAG_CR,
+ &response->receive_data.rx_remaining,
+ NULL);
+}
+
+static gboolean build_send_data(struct stk_tlv_builder *builder,
+ const struct stk_response *response)
+{
+ if (response->result.type != STK_RESULT_TYPE_SUCCESS)
+ return TRUE;
+
+ return build_dataobj(builder, build_dataobj_channel_data_length,
+ DATAOBJ_FLAG_CR,
+ &response->send_data.tx_avail,
+ NULL);
+}
+
const unsigned char *stk_pdu_from_response(const struct stk_response *response,
unsigned int *out_length)
{
@@ -5582,6 +5811,7 @@ const unsigned char *stk_pdu_from_response(const struct stk_response *response,
case STK_COMMAND_TYPE_SEND_DTMF:
case STK_COMMAND_TYPE_LANGUAGE_NOTIFICATION:
case STK_COMMAND_TYPE_LAUNCH_BROWSER:
+ case STK_COMMAND_TYPE_CLOSE_CHANNEL:
break;
case STK_COMMAND_TYPE_SEND_USSD:
ok = build_dataobj(&builder,
@@ -5590,6 +5820,22 @@ const unsigned char *stk_pdu_from_response(const struct stk_response *response,
&response->send_ussd.text,
NULL);
break;
+ case STK_COMMAND_TYPE_OPEN_CHANNEL:
+ ok = build_open_channel(&builder, response);
+ break;
+ case STK_COMMAND_TYPE_RECEIVE_DATA:
+ ok = build_receive_data(&builder, response);
+ break;
+ case STK_COMMAND_TYPE_SEND_DATA:
+ ok = build_send_data(&builder, response);
+ break;
+ case STK_COMMAND_TYPE_GET_CHANNEL_STATUS:
+ ok = build_dataobj(&builder,
+ build_dataobj_channel_status,
+ DATAOBJ_FLAG_CR,
+ &response->channel_status.channel,
+ NULL);
+ break;
default:
return NULL;
};
@@ -5738,7 +5984,7 @@ static gboolean build_envelope_event_download(struct stk_tlv_builder *builder,
return build_dataobj(builder,
build_dataobj_channel_status,
DATAOBJ_FLAG_CR,
- &evt->data_available.channel_status,
+ &evt->data_available.channel,
build_dataobj_channel_data_length,
DATAOBJ_FLAG_CR,
&evt->data_available.channel_data_len,
@@ -5747,7 +5993,7 @@ static gboolean build_envelope_event_download(struct stk_tlv_builder *builder,
return build_dataobj(builder,
build_dataobj_channel_status,
DATAOBJ_FLAG_CR,
- &evt->channel_status.status,
+ &evt->channel_status.channel,
build_dataobj_bearer_description,
DATAOBJ_FLAG_CR,
&evt->channel_status.bearer_desc,
diff --git a/src/stkutil.h b/src/stkutil.h
index 1b38dec..dd45bc2 100644
--- a/src/stkutil.h
+++ b/src/stkutil.h
@@ -425,14 +425,19 @@ enum stk_browser_termination_cause {
STK_BROWSER_ERROR_TERMINATION = 0x01
};
+/* Defined in TS 31.111 Section 8.52 */
enum stk_bearer_type {
+ STK_BEARER_TYPE_CS = 0x01,
+ STK_BEARER_TYPE_GPRS_UTRAN = 0x02,
STK_BEARER_TYPE_DEFAULT = 0x03,
STK_BEARER_TYPE_INDEPENDENT = 0x04,
STK_BEARER_TYPE_BLUETOOTH = 0x05,
STK_BEARER_TYPE_IRDA = 0x06,
STK_BEARER_TYPE_RS232 = 0x07,
- STK_BEARER_TYPE_PACKET_DATA_SERVICE = 0x08,
- STK_BEARER_TYPE_I_WLAN = 0x0a,
+ STK_BEARER_TYPE_TIA_EIA_IS_820 = 0x08,
+ STK_BEARER_TYPE_UTRAN_WITH_EXT_PARAMS = 0x09,
+ STK_BEARER_TYPE_I_WLAN = 0x0A,
+ STK_BEARER_TYPE_EUTRAN_MAPPED_UTRAN = 0x0B,
STK_BEARER_TYPE_USB = 0x10
};
@@ -587,6 +592,39 @@ enum stk_img_scheme {
STK_IMG_SCHEME_TRANSPARENCY = 0x22,
};
+/* Defined in TS 102.223 Section 8.6 */
+enum stk_qualifier_open_channel {
+ STK_OPEN_CHANNEL_FLAG_IMMEDIATE = 0x01,
+ STK_OPEN_CHANNEL_FLAG_AUTO_RECONNECT = 0x02,
+ STK_OPEN_CHANNEL_FLAG_BACKGROUND = 0x04,
+};
+
+/* Defined in TS 102.223 Section 8.6 */
+enum stk_qualifier_send_data {
+ STK_SEND_DATA_STORE_DATA = 0x00,
+ STK_SEND_DATA_IMMEDIATELY = 0x01,
+};
+
+/* Defined in TS 102.223 Section 8.56 */
+enum stk_channel_status {
+ STK_CHANNEL_PACKET_DATA_SERVICE_NOT_ACTIVATED = 0x00,
+ STK_CHANNEL_PACKET_DATA_SERVICE_ACTIVATED = 0x01,
+ STK_CHANNEL_TCP_IN_CLOSED_STATE = 0x02,
+ STK_CHANNEL_TCP_IN_LISTEN_STATE = 0x03,
+ STK_CHANNEL_TCP_IN_ESTABLISHED_STATE = 0x04,
+ STK_CHANNEL_LINK_DROPPED = 0x05,
+};
+
+/* Defined in TS 102.223 Section 8.59 */
+enum stk_transport_protocol_type {
+ STK_TRANSPORT_PROTOCOL_UDP_CLIENT_REMOTE = 0x01,
+ STK_TRANSPORT_PROTOCOL_TCP_CLIENT_REMOTE = 0x02,
+ STK_TRANSPORT_PROTOCOL_TCP_SERVER = 0x03,
+ STK_TRANSPORT_PROTOCOL_UDP_CLIENT_LOCAL = 0x04,
+ STK_TRANSPORT_PROTOCOL_TCP_CLIENT_LOCAL = 0x05,
+ STK_TRANSPORT_PROTOCOL_DIRECT = 0x06,
+};
+
/* For data object that only has a byte array with undetermined length */
struct stk_common_byte_array {
unsigned char *array;
@@ -849,16 +887,20 @@ struct stk_timing_advance {
unsigned char advance;
};
-/*
- * According to 102.223 Section 8.52 the length of CTLV is 1 byte. This means
- * that the maximum size is 127 according to the rules of CTLVs. This size also
- * includes bearer type for 1 byte, so the maxmimum size of bearer parameters
- * is 126.
- */
+/* Bearer parameters for GPRS/UTRAN Packet Service/E-UTRAN */
+struct stk_gprs_bearer_parameters {
+ unsigned char precedence;
+ unsigned char delay;
+ unsigned char reliability;
+ unsigned char peak;
+ unsigned char mean;
+ unsigned char pdp_type;
+};
+
+/* Defined in TS 31.111 Section 8.52 */
struct stk_bearer_description {
- unsigned char type;
- unsigned char pars[126];
- unsigned int len;
+ enum stk_bearer_type type;
+ struct stk_gprs_bearer_parameters gprs;
};
/*
@@ -885,7 +927,7 @@ struct stk_other_address {
/* Defined in TS 102.223 Section 8.59 */
struct stk_uicc_te_interface {
- unsigned char protocol;
+ enum stk_transport_protocol_type protocol;
unsigned short port;
};
@@ -950,15 +992,6 @@ struct stk_remote_entity_address {
};
/*
- * According to 102.223 Section 8.70 the length of CTLV is 1 byte. This means
- * that the maximum size is 127 according to the rules of CTLVs.
- */
-struct stk_network_access_name {
- unsigned char name[127];
- unsigned char len;
-};
-
-/*
* According to 102.223 Section 8.72 the length of text attribute CTLV is 1
* byte. This means that the maximum size is 127 according to the rules
* of CTLVs. Empty attribute options will have len of 0.
@@ -1250,6 +1283,21 @@ struct stk_command_launch_browser {
char *text_passwd;
};
+struct stk_command_open_channel {
+ char *alpha_id;
+ struct stk_icon_id icon_id;
+ struct stk_bearer_description bearer_desc;
+ unsigned short buf_size;
+ char *apn;
+ struct stk_other_address local_addr;
+ char *text_usr;
+ char *text_passwd;
+ struct stk_uicc_te_interface uti;
+ struct stk_other_address data_dest_addr;
+ struct stk_text_attribute text_attr;
+ struct stk_frame_id frame_id;
+};
+
struct stk_command_close_channel {
char *alpha_id;
struct stk_icon_id icon_id;
@@ -1368,6 +1416,7 @@ struct stk_command {
struct stk_command_send_dtmf send_dtmf;
struct stk_command_language_notification language_notification;
struct stk_command_launch_browser launch_browser;
+ struct stk_command_open_channel open_channel;
struct stk_command_close_channel close_channel;
struct stk_command_receive_data receive_data;
struct stk_command_send_data send_data;
@@ -1406,6 +1455,19 @@ struct stk_ussd_text {
int len;
};
+struct stk_channel {
+ unsigned char id;
+ enum stk_channel_status status;
+};
+
+struct stk_channel_data {
+ struct stk_common_byte_array data;
+ union {
+ unsigned short rx_remaining;
+ unsigned short tx_avail;
+ };
+};
+
struct stk_response_get_inkey {
struct stk_answer_text text;
struct stk_duration duration;
@@ -1481,6 +1543,25 @@ struct stk_response_send_ussd {
struct stk_ussd_text text;
};
+struct stk_response_open_channel {
+ struct stk_channel channel;
+ struct stk_bearer_description bearer_desc;
+ unsigned short buf_size;
+};
+
+struct stk_response_receive_data {
+ struct stk_common_byte_array rx_data;
+ unsigned short rx_remaining;
+};
+
+struct stk_response_send_data {
+ unsigned short tx_avail;
+};
+
+struct stk_response_channel_status {
+ struct stk_channel channel;
+};
+
struct stk_response {
unsigned char number;
unsigned char type;
@@ -1511,6 +1592,10 @@ struct stk_response {
struct stk_response_generic language_notification;
struct stk_response_generic launch_browser;
struct stk_response_send_ussd send_ussd;
+ struct stk_response_open_channel open_channel;
+ struct stk_response_receive_data receive_data;
+ struct stk_response_send_data send_data;
+ struct stk_response_channel_status channel_status;
};
void (*destructor)(struct stk_response *response);
@@ -1596,11 +1681,11 @@ struct stk_envelope_event_download {
enum stk_browser_termination_cause cause;
} browser_termination;
struct {
- unsigned char channel_status[2];
+ struct stk_channel channel;
unsigned int channel_data_len;
} data_available;
struct {
- unsigned char status[2];
+ struct stk_channel channel;
struct stk_bearer_description bearer_desc;
struct stk_other_address address;
} channel_status;
--
1.7.1
9 years, 9 months
[PATCH v3 2/2] test-stkutil: Add unit tests for BIP commands
by Philippe Nunes
---
unit/test-stkutil.c | 1170 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 1153 insertions(+), 17 deletions(-)
diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c
index aa62aac..03d4a2c 100644
--- a/unit/test-stkutil.c
+++ b/unit/test-stkutil.c
@@ -470,6 +470,59 @@ static void check_provisioning_file_references(GSList *command,
g_assert(test[i].len == 0);
}
+/* Defined in TS 102.223 Section 8.52 */
+static void check_bearer_desc(const struct stk_bearer_description *command,
+ const struct stk_bearer_description *test)
+{
+ g_assert(command->type == test->type);
+
+ if (test->type == STK_BEARER_TYPE_GPRS_UTRAN) {
+
+ check_common_byte(command->gprs.precedence,
+ test->gprs.precedence);
+ check_common_byte(command->gprs.delay,
+ test->gprs.delay);
+ check_common_byte(command->gprs.reliability,
+ test->gprs.reliability);
+ check_common_byte(command->gprs.peak,
+ test->gprs.peak);
+ check_common_byte(command->gprs.mean,
+ test->gprs.mean);
+ check_common_byte(command->gprs.pdp_type,
+ test->gprs.pdp_type);
+ return;
+ }
+}
+
+/* Defined in TS 102.223 Section 8.53 */
+static inline void check_channel_data(
+ const struct stk_common_byte_array *command,
+ const struct stk_common_byte_array *test)
+{
+ check_common_byte_array(command, test);
+}
+
+/* Defined in TS 102.223 Section 8.58 */
+static inline void check_other_address(
+ const struct stk_other_address *command,
+ const struct stk_other_address *test)
+{
+ check_common_byte(command->type, test->type);
+
+ if (test->type == STK_ADDRESS_IPV4)
+ g_assert(command->addr.ipv4 == test->addr.ipv4);
+ else
+ g_assert(g_mem_equal(command->addr.ipv6, test->addr.ipv6, 16));
+}
+
+/* Defined in TS 102.223 Section 8.59 */
+static void check_uicc_te_interface(const struct stk_uicc_te_interface *command,
+ const struct stk_uicc_te_interface *test)
+{
+ check_common_byte(command->protocol, test->protocol);
+ g_assert(command->port == test->port);
+}
+
/* Defined in TS 102.223 Section 8.60 */
static inline void check_aid(const struct stk_aid *command,
const struct stk_aid *test)
@@ -477,6 +530,13 @@ static inline void check_aid(const struct stk_aid *command,
g_assert(g_mem_equal(command->aid, test->aid, test->len));
}
+/* Defined in TS 102.223 Section 8.70 */
+static inline void check_network_access_name(const char *command,
+ const char *test)
+{
+ check_common_text(command, test);
+}
+
/* Defined in TS 102.223 Section 8.71 */
static inline void check_cdma_sms_tpdu(
const struct stk_common_byte_array *command,
@@ -16913,6 +16973,639 @@ static void test_launch_browser(gconstpointer data)
stk_command_free(command);
}
+struct open_channel_test {
+ const unsigned char *pdu;
+ unsigned int pdu_len;
+ unsigned char qualifier;
+ char *alpha_id;
+ struct stk_icon_id icon_id;
+ struct stk_bearer_description bearer_desc;
+ unsigned short buf_size;
+ char *apn;
+ struct stk_other_address local_addr;
+ char *text_usr;
+ char *text_passwd;
+ struct stk_uicc_te_interface uti;
+ struct stk_other_address data_dest_addr;
+ struct stk_text_attribute text_attr;
+ struct stk_frame_id frame_id;
+};
+
+static unsigned char open_channel_211[] = { 0xD0, 0x36, 0x81, 0x03, 0x01, 0x40,
+ 0x01, 0x82, 0x02, 0x81, 0x82,
+ 0x35, 0x07, 0x02, 0x03, 0x04,
+ 0x03, 0x04, 0x1F, 0x02, 0x39,
+ 0x02, 0x05, 0x78, 0x0D, 0x08,
+ 0xF4, 0x55, 0x73, 0x65, 0x72,
+ 0x4C, 0x6F, 0x67, 0x0D, 0x08,
+ 0xF4, 0x55, 0x73, 0x65, 0x72,
+ 0x50, 0x77, 0x64, 0x3C, 0x03,
+ 0x01, 0xAD, 0x9C, 0x3E, 0x05,
+ 0x21, 0x01, 0x01, 0x01, 0x01 };
+
+static unsigned char open_channel_221[] = { 0xD0, 0x42, 0x81, 0x03, 0x01, 0x40,
+ 0x01, 0x82, 0x02, 0x81, 0x82,
+ 0x35, 0x07, 0x02, 0x03, 0x04,
+ 0x03, 0x04, 0x1F, 0x02, 0x39,
+ 0x02, 0x05, 0x78, 0x47, 0x0A,
+ 0x06, 0x54, 0x65, 0x73, 0x74,
+ 0x47, 0x70, 0x02, 0x72, 0x73,
+ 0x0D, 0x08, 0xF4, 0x55, 0x73,
+ 0x65, 0x72, 0x4C, 0x6F, 0x67,
+ 0x0D, 0x08, 0xF4, 0x55, 0x73,
+ 0x65, 0x72, 0x50, 0x77, 0x64,
+ 0x3C, 0x03, 0x01, 0xAD, 0x9C,
+ 0x3E, 0x05, 0x21, 0x01, 0x01,
+ 0x01, 0x01 };
+
+static unsigned char open_channel_231[] = { 0xD0, 0x4B, 0x81, 0x03, 0x01, 0x40,
+ 0x01, 0x82, 0x02, 0x81, 0x82,
+ 0x05, 0x07, 0x4F, 0x70, 0x65,
+ 0x6E, 0x20, 0x49, 0x44, 0x35,
+ 0x07, 0x02, 0x03, 0x04, 0x03,
+ 0x04, 0x1F, 0x02, 0x39, 0x02,
+ 0x05, 0x78, 0x47, 0x0A, 0x06,
+ 0x54, 0x65, 0x73, 0x74, 0x47,
+ 0x70, 0x02, 0x72, 0x73, 0x0D,
+ 0x08, 0xF4, 0x55, 0x73, 0x65,
+ 0x72, 0x4C, 0x6F, 0x67, 0x0D,
+ 0x08, 0xF4, 0x55, 0x73, 0x65,
+ 0x72, 0x50, 0x77, 0x64, 0x3C,
+ 0x03, 0x01, 0xAD, 0x9C, 0x3E,
+ 0x05, 0x21, 0x01, 0x01, 0x01,
+ 0x01 };
+
+static unsigned char open_channel_241[] = { 0xD0, 0x44, 0x81, 0x03, 0x01, 0x40,
+ 0x01, 0x82, 0x02, 0x81, 0x82,
+ 0x05, 0x00, 0x35, 0x07, 0x02,
+ 0x03, 0x04, 0x03, 0x04, 0x1F,
+ 0x02, 0x39, 0x02, 0x05, 0x78,
+ 0x47, 0x0A, 0x06, 0x54, 0x65,
+ 0x73, 0x74, 0x47, 0x70, 0x02,
+ 0x72, 0x73, 0x0D, 0x08, 0xF4,
+ 0x55, 0x73, 0x65, 0x72, 0x4C,
+ 0x6F, 0x67, 0x0D, 0x08, 0xF4,
+ 0x55, 0x73, 0x65, 0x72, 0x50,
+ 0x77, 0x64, 0x3C, 0x03, 0x01,
+ 0xAD, 0x9C, 0x3E, 0x05, 0x21,
+ 0x01, 0x01, 0x01, 0x01 };
+
+static unsigned char open_channel_511[] = { 0xD0, 0x53, 0x81, 0x03, 0x01, 0x40,
+ 0x01, 0x82, 0x02, 0x81, 0x82,
+ 0x05, 0x09, 0x4F, 0x70, 0x65,
+ 0x6E, 0x20, 0x49, 0x44, 0x20,
+ 0x31, 0x35, 0x07, 0x02, 0x03,
+ 0x04, 0x03, 0x04, 0x1F, 0x02,
+ 0x39, 0x02, 0x05, 0x78, 0x47,
+ 0x0A, 0x06, 0x54, 0x65, 0x73,
+ 0x74, 0x47, 0x70, 0x02, 0x72,
+ 0x73, 0x0D, 0x08, 0xF4, 0x55,
+ 0x73, 0x65, 0x72, 0x4C, 0x6F,
+ 0x67, 0x0D, 0x08, 0xF4, 0x55,
+ 0x73, 0x65, 0x72, 0x50, 0x77,
+ 0x64, 0x3C, 0x03, 0x01, 0xAD,
+ 0x9C, 0x3E, 0x05, 0x21, 0x01,
+ 0x01, 0x01, 0x01, 0xD0, 0x04,
+ 0x00, 0x09, 0x00, 0xB4 };
+
+static struct open_channel_test open_channel_data_211 = {
+ /*
+ * OPEN CHANNEL, immediate link establishment, GPRS, no local address
+ * no alpha identifier, no network access name
+ */
+ .pdu = open_channel_211,
+ .pdu_len = sizeof(open_channel_211),
+ .qualifier = STK_OPEN_CHANNEL_FLAG_IMMEDIATE,
+ .bearer_desc = {
+ .type = STK_BEARER_TYPE_GPRS_UTRAN,
+ .gprs = {
+ .precedence = 3,
+ .delay = 4,
+ .reliability = 3,
+ .peak = 4,
+ .mean = 31,
+ .pdp_type = 2,
+ },
+ },
+ .buf_size = 1400,
+ .text_usr = "UserLog",
+ .text_passwd = "UserPwd",
+ .uti = {
+ .protocol = STK_TRANSPORT_PROTOCOL_UDP_CLIENT_REMOTE,
+ .port = 44444,
+ },
+ .data_dest_addr = {
+ .type = STK_ADDRESS_IPV4,
+ .addr = {
+ .ipv4 = 0x01010101,
+ },
+ },
+};
+
+static struct open_channel_test open_channel_data_221 = {
+ /*
+ * OPEN CHANNEL, immediate link establishment GPRS,
+ * no alpha identifier, with network access name
+ */
+ .pdu = open_channel_221,
+ .pdu_len = sizeof(open_channel_221),
+ .qualifier = STK_OPEN_CHANNEL_FLAG_IMMEDIATE,
+ .bearer_desc = {
+ .type = STK_BEARER_TYPE_GPRS_UTRAN,
+ .gprs = {
+ .precedence = 3,
+ .delay = 4,
+ .reliability = 3,
+ .peak = 4,
+ .mean = 31,
+ .pdp_type = 2,
+ },
+ },
+ .buf_size = 1400,
+ .apn = "TestGp.rs",
+ .text_usr = "UserLog",
+ .text_passwd = "UserPwd",
+ .uti = {
+ .protocol = STK_TRANSPORT_PROTOCOL_UDP_CLIENT_REMOTE,
+ .port = 44444,
+ },
+ .data_dest_addr = {
+ .type = STK_ADDRESS_IPV4,
+ .addr = {
+ .ipv4 = 0x01010101,
+ },
+ },
+};
+
+static struct open_channel_test open_channel_data_231 = {
+ /*
+ * OPEN CHANNEL, immediate link establishment, GPRS
+ * with alpha identifier
+ */
+ .pdu = open_channel_231,
+ .pdu_len = sizeof(open_channel_231),
+ .qualifier = STK_OPEN_CHANNEL_FLAG_IMMEDIATE,
+ .alpha_id = "Open ID",
+ .bearer_desc = {
+ .type = STK_BEARER_TYPE_GPRS_UTRAN,
+ .gprs = {
+ .precedence = 3,
+ .delay = 4,
+ .reliability = 3,
+ .peak = 4,
+ .mean = 31,
+ .pdp_type = 2,
+ },
+ },
+ .buf_size = 1400,
+ .apn = "TestGp.rs",
+ .text_usr = "UserLog",
+ .text_passwd = "UserPwd",
+ .uti = {
+ .protocol = STK_TRANSPORT_PROTOCOL_UDP_CLIENT_REMOTE,
+ .port = 44444,
+ },
+ .data_dest_addr = {
+ .type = STK_ADDRESS_IPV4,
+ .addr = {
+ .ipv4 = 0x01010101,
+ },
+ },
+};
+
+static struct open_channel_test open_channel_data_241 = {
+ /*
+ * OPEN CHANNEL, immediate link establishment, GPRS,
+ * with null alpha identifier
+ */
+ .pdu = open_channel_241,
+ .pdu_len = sizeof(open_channel_241),
+ .qualifier = STK_OPEN_CHANNEL_FLAG_IMMEDIATE,
+ .alpha_id = "",
+ .bearer_desc = {
+ .type = STK_BEARER_TYPE_GPRS_UTRAN,
+ .gprs = {
+ .precedence = 3,
+ .delay = 4,
+ .reliability = 3,
+ .peak = 4,
+ .mean = 31,
+ .pdp_type = 2,
+ },
+ },
+ .buf_size = 1400,
+ .apn = "TestGp.rs",
+ .text_usr = "UserLog",
+ .text_passwd = "UserPwd",
+ .uti = {
+ .protocol = STK_TRANSPORT_PROTOCOL_UDP_CLIENT_REMOTE,
+ .port = 44444,
+ },
+ .data_dest_addr = {
+ .type = STK_ADDRESS_IPV4,
+ .addr = {
+ .ipv4 = 0x01010101,
+ },
+ },
+};
+
+static struct open_channel_test open_channel_data_511 = {
+ /*
+ * OPEN CHANNEL, immediate link establishment, GPRS
+ * Text Attribute – Left Alignment
+ */
+ .pdu = open_channel_511,
+ .pdu_len = sizeof(open_channel_511),
+ .qualifier = STK_OPEN_CHANNEL_FLAG_IMMEDIATE,
+ .alpha_id = "Open ID 1",
+ .bearer_desc = {
+ .type = STK_BEARER_TYPE_GPRS_UTRAN,
+ .gprs = {
+ .precedence = 3,
+ .delay = 4,
+ .reliability = 3,
+ .peak = 4,
+ .mean = 31,
+ .pdp_type = 2,
+ },
+ },
+ .buf_size = 1400,
+ .apn = "TestGp.rs",
+ .text_usr = "UserLog",
+ .text_passwd = "UserPwd",
+ .uti = {
+ .protocol = STK_TRANSPORT_PROTOCOL_UDP_CLIENT_REMOTE,
+ .port = 44444,
+ },
+ .data_dest_addr = {
+ .type = STK_ADDRESS_IPV4,
+ .addr = {
+ .ipv4 = 0x01010101,
+ },
+ },
+ .text_attr = {
+ .len = 4,
+ .attributes = { 0x00, 0x09, 0x00, 0xB4 }
+ },
+};
+
+static void test_open_channel(gconstpointer data)
+{
+ const struct open_channel_test *test = data;
+ struct stk_command *command;
+
+ command = stk_command_new_from_pdu(test->pdu, test->pdu_len);
+
+ g_assert(command);
+ g_assert(command->status == STK_PARSE_RESULT_OK);
+
+ g_assert(command->number == 1);
+ g_assert(command->type == STK_COMMAND_TYPE_OPEN_CHANNEL);
+ g_assert(command->qualifier == test->qualifier);
+
+ g_assert(command->src == STK_DEVICE_IDENTITY_TYPE_UICC);
+ g_assert(command->dst == STK_DEVICE_IDENTITY_TYPE_TERMINAL);
+
+ check_alpha_id(command->open_channel.alpha_id, test->alpha_id);
+ check_icon_id(&command->open_channel.icon_id, &test->icon_id);
+ check_bearer_desc(&command->open_channel.bearer_desc,
+ &test->bearer_desc);
+ g_assert(command->open_channel.buf_size == test->buf_size);
+ check_network_access_name(command->open_channel.apn, test->apn);
+ check_other_address(&command->open_channel.local_addr,
+ &test->local_addr);
+ check_text(command->open_channel.text_usr, test->text_usr);
+ check_text(command->open_channel.text_passwd, test->text_passwd);
+ check_uicc_te_interface(&command->open_channel.uti, &test->uti);
+ check_other_address(&command->open_channel.data_dest_addr,
+ &test->data_dest_addr);
+ check_text_attr(&command->open_channel.text_attr, &test->text_attr);
+ check_frame_id(&command->open_channel.frame_id, &test->frame_id);
+
+ stk_command_free(command);
+}
+
+struct close_channel_test {
+ const unsigned char *pdu;
+ unsigned int pdu_len;
+ unsigned char qualifier;
+ enum stk_device_identity_type dst;
+ char *alpha_id;
+ struct stk_icon_id icon_id;
+ struct stk_text_attribute text_attr;
+ struct stk_frame_id frame_id;
+};
+
+static unsigned char close_channel_111[] = { 0xD0, 0x09, 0x81, 0x03, 0x01, 0x41,
+ 0x00, 0x82, 0x02, 0x81, 0x21 };
+
+static struct close_channel_test close_channel_data_111 = {
+ .pdu = close_channel_111,
+ .pdu_len = sizeof(close_channel_111),
+ .qualifier = 0x00,
+ .dst = STK_DEVICE_IDENTITY_TYPE_CHANNEL_1,
+};
+
+static unsigned char close_channel_211[] = { 0xD0, 0x1B, 0x81, 0x03, 0x01, 0x41,
+ 0x00, 0x82, 0x02, 0x81, 0x21,
+ 0x85, 0x0A, 0x43, 0x6C, 0x6F,
+ 0x73, 0x65, 0x20, 0x49, 0x44,
+ 0x20, 0x31, 0xD0, 0x04, 0x00,
+ 0x0A, 0x00, 0xB4,
+ };
+
+static struct close_channel_test close_channel_data_211 = {
+ .pdu = close_channel_211,
+ .pdu_len = sizeof(close_channel_211),
+ .qualifier = 0x00,
+ .dst = STK_DEVICE_IDENTITY_TYPE_CHANNEL_1,
+ .alpha_id = "Close ID 1",
+ .text_attr = {
+ .len = 4,
+ .attributes = { 0x00, 0x0A, 0x00, 0xB4 }
+ },
+};
+
+static void test_close_channel(gconstpointer data)
+{
+ const struct close_channel_test *test = data;
+ struct stk_command *command;
+
+ command = stk_command_new_from_pdu(test->pdu, test->pdu_len);
+
+ g_assert(command);
+ g_assert(command->status == STK_PARSE_RESULT_OK);
+
+ g_assert(command->number == 1);
+ g_assert(command->type == STK_COMMAND_TYPE_CLOSE_CHANNEL);
+ g_assert(command->qualifier == test->qualifier);
+
+ g_assert(command->src == STK_DEVICE_IDENTITY_TYPE_UICC);
+ g_assert(command->dst == test->dst);
+
+ check_alpha_id(command->close_channel.alpha_id, test->alpha_id);
+ check_icon_id(&command->close_channel.icon_id, &test->icon_id);
+ check_text_attr(&command->close_channel.text_attr, &test->text_attr);
+ check_frame_id(&command->close_channel.frame_id, &test->frame_id);
+
+ stk_command_free(command);
+}
+
+struct receive_data_test {
+ const unsigned char *pdu;
+ unsigned int pdu_len;
+ unsigned char qualifier;
+ enum stk_device_identity_type dst;
+ char *alpha_id;
+ struct stk_icon_id icon_id;
+ unsigned char data_len;
+ struct stk_text_attribute text_attr;
+ struct stk_frame_id frame_id;
+};
+
+static unsigned char receive_data_111[] = { 0xD0, 0x0C, 0x81, 0x03, 0x01, 0x42,
+ 0x00, 0x82, 0x02, 0x81, 0x21,
+ 0xB7, 0x01, 0xC8 };
+
+static struct receive_data_test receive_data_data_111 = {
+ .pdu = receive_data_111,
+ .pdu_len = sizeof(receive_data_111),
+ .qualifier = 0x00,
+ .dst = STK_DEVICE_IDENTITY_TYPE_CHANNEL_1,
+ .data_len = 200,
+};
+
+static unsigned char receive_data_211[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x42,
+ 0x00, 0x82, 0x02, 0x81, 0x21,
+ 0x85, 0x0E, 0x52, 0x65, 0x63,
+ 0x65, 0x69, 0x76, 0x65, 0x20,
+ 0x44, 0x61, 0x74, 0x61, 0x20,
+ 0x31, 0xB7, 0x01, 0xC8, 0xD0,
+ 0x04, 0x00, 0x0E, 0x00, 0xB4 };
+
+static struct receive_data_test receive_data_data_211 = {
+ .pdu = receive_data_211,
+ .pdu_len = sizeof(receive_data_211),
+ .qualifier = 0x00,
+ .dst = STK_DEVICE_IDENTITY_TYPE_CHANNEL_1,
+ .data_len = 200,
+ .alpha_id = "Receive Data 1",
+ .text_attr = {
+ .len = 4,
+ .attributes = { 0x00, 0x0E, 0x00, 0xB4 }
+ },
+};
+
+
+static void test_receive_data(gconstpointer data)
+{
+ const struct receive_data_test *test = data;
+ struct stk_command *command;
+
+ command = stk_command_new_from_pdu(test->pdu, test->pdu_len);
+
+ g_assert(command);
+ g_assert(command->status == STK_PARSE_RESULT_OK);
+
+ g_assert(command->number == 1);
+ g_assert(command->type == STK_COMMAND_TYPE_RECEIVE_DATA);
+ g_assert(command->qualifier == test->qualifier);
+
+ g_assert(command->src == STK_DEVICE_IDENTITY_TYPE_UICC);
+ g_assert(command->dst == test->dst);
+
+ check_alpha_id(command->receive_data.alpha_id, test->alpha_id);
+ check_icon_id(&command->receive_data.icon_id, &test->icon_id);
+ check_common_byte(command->receive_data.data_len, test->data_len);
+ check_text_attr(&command->receive_data.text_attr, &test->text_attr);
+ check_frame_id(&command->receive_data.frame_id, &test->frame_id);
+
+ stk_command_free(command);
+}
+
+struct send_data_test {
+ const unsigned char *pdu;
+ unsigned int pdu_len;
+ unsigned char qualifier;
+ enum stk_device_identity_type dst;
+ char *alpha_id;
+ struct stk_icon_id icon_id;
+ struct stk_common_byte_array data;
+ struct stk_text_attribute text_attr;
+ struct stk_frame_id frame_id;
+};
+
+static unsigned char send_data_111[] = { 0xD0, 0x13, 0x81, 0x03, 0x01, 0x43,
+ 0x01, 0x82, 0x02, 0x81, 0x21,
+ 0xB6, 0x08, 0x00, 0x01, 0x02,
+ 0x03, 0x04, 0x05, 0x06, 0x07 };
+
+static struct send_data_test send_data_data_111 = {
+ .pdu = send_data_111,
+ .pdu_len = sizeof(send_data_111),
+ .qualifier = STK_SEND_DATA_IMMEDIATELY,
+ .dst = STK_DEVICE_IDENTITY_TYPE_CHANNEL_1,
+ .data = {
+ .array = (unsigned char[8]) {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+ },
+ .len = 8,
+ },
+};
+
+static unsigned char send_data_121[] = {
+ 0xD0, 0x81, 0xD4, 0x81, 0x03, 0x01, 0x43, 0x00,
+ 0x82, 0x02, 0x81, 0x21, 0xB6, 0x81, 0xC8, 0x00,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
+ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
+ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+ 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
+ 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
+ 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
+ 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0,
+ 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
+ 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
+ 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
+ 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
+ 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 };
+
+static struct send_data_test send_data_data_121 = {
+ .pdu = send_data_121,
+ .pdu_len = sizeof(send_data_121),
+ .qualifier = STK_SEND_DATA_STORE_DATA,
+ .dst = STK_DEVICE_IDENTITY_TYPE_CHANNEL_1,
+ .data = {
+ .array = (unsigned char[200]) {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ },
+ .len = 200,
+ },
+};
+static unsigned char send_data_211[] = {
+ 0xD0, 0x26, 0x81, 0x03, 0x01, 0x43, 0x01, 0x82,
+ 0x02, 0x81, 0x21, 0x85, 0x0B, 0x53, 0x65, 0x6E,
+ 0x64, 0x20, 0x44, 0x61, 0x74, 0x61, 0x20, 0x31,
+ 0xB6, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0xD0, 0x04, 0x00, 0x0B, 0x00, 0xB4,
+ };
+
+static struct send_data_test send_data_data_211 = {
+ .pdu = send_data_211,
+ .pdu_len = sizeof(send_data_211),
+ .qualifier = STK_SEND_DATA_IMMEDIATELY,
+ .dst = STK_DEVICE_IDENTITY_TYPE_CHANNEL_1,
+ .alpha_id = "Send Data 1",
+ .data = {
+ .array = (unsigned char[8]) {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+ },
+ .len = 8,
+ },
+ .text_attr = {
+ .len = 4,
+ .attributes = { 0x00, 0x0B, 0x00, 0xB4 }
+ },
+};
+
+static void test_send_data(gconstpointer data)
+{
+ const struct send_data_test *test = data;
+ struct stk_command *command;
+
+ command = stk_command_new_from_pdu(test->pdu, test->pdu_len);
+
+ g_assert(command);
+ g_assert(command->status == STK_PARSE_RESULT_OK);
+
+ g_assert(command->number == 1);
+ g_assert(command->type == STK_COMMAND_TYPE_SEND_DATA);
+ g_assert(command->qualifier == test->qualifier);
+
+ g_assert(command->src == STK_DEVICE_IDENTITY_TYPE_UICC);
+ g_assert(command->dst == test->dst);
+
+ check_alpha_id(command->send_data.alpha_id, test->alpha_id);
+ check_icon_id(&command->send_data.icon_id, &test->icon_id);
+ check_channel_data(&command->send_data.data, &test->data);
+ check_text_attr(&command->send_data.text_attr, &test->text_attr);
+ check_frame_id(&command->send_data.frame_id, &test->frame_id);
+
+ stk_command_free(command);
+}
+
+struct get_channel_status_test {
+ const unsigned char *pdu;
+ unsigned int pdu_len;
+ unsigned char qualifier;
+};
+
+static unsigned char get_channel_status_111[] = { 0xD0, 0x09, 0x81, 0x03, 0x01,
+ 0x44, 0x00, 0x82, 0x02,
+ 0x81, 0x82 };
+
+static struct get_channel_status_test get_channel_status_data_111 = {
+ .pdu = get_channel_status_111,
+ .pdu_len = sizeof(get_channel_status_111),
+ .qualifier = 0x00,
+};
+
+static void test_get_channel_status(gconstpointer data)
+{
+ const struct get_channel_status_test *test = data;
+ struct stk_command *command;
+
+ command = stk_command_new_from_pdu(test->pdu, test->pdu_len);
+
+ g_assert(command);
+ g_assert(command->status == STK_PARSE_RESULT_OK);
+
+ g_assert(command->number == 1);
+ g_assert(command->type == STK_COMMAND_TYPE_GET_CHANNEL_STATUS);
+ g_assert(command->qualifier == test->qualifier);
+
+ g_assert(command->src == STK_DEVICE_IDENTITY_TYPE_UICC);
+ g_assert(command->dst == STK_DEVICE_IDENTITY_TYPE_TERMINAL);
+
+ stk_command_free(command);
+}
+
struct terminal_response_test {
const unsigned char *pdu;
unsigned int pdu_len;
@@ -20884,6 +21577,366 @@ static const struct terminal_response_test launch_browser_response_data_411b = {
},
};
+static const unsigned char open_channel_response_211[] = {
+ 0x81, 0x03, 0x01, 0x40, 0x01, 0x82, 0x02, 0x82, 0x81, 0x83,
+ 0x01, 0x00, 0x38, 0x02, 0x81, 0x00, 0x35, 0x07, 0x02, 0x03,
+ 0x04, 0x03, 0x04, 0x1F, 0x02, 0x39, 0x02, 0x05, 0x78,
+};
+
+static const struct terminal_response_test open_channel_response_data_211 = {
+ .pdu = open_channel_response_211,
+ .pdu_len = sizeof(open_channel_response_211),
+ .response = {
+ .number = 1,
+ .type = STK_COMMAND_TYPE_OPEN_CHANNEL,
+ .qualifier = STK_OPEN_CHANNEL_FLAG_IMMEDIATE,
+ .src = STK_DEVICE_IDENTITY_TYPE_TERMINAL,
+ .dst = STK_DEVICE_IDENTITY_TYPE_UICC,
+ .result = {
+ .type = STK_RESULT_TYPE_SUCCESS,
+ },
+ { .open_channel = {
+ .channel = {
+ .id = 1,
+ .status = STK_CHANNEL_PACKET_DATA_SERVICE_ACTIVATED,
+ },
+ .bearer_desc = {
+ .type = STK_BEARER_TYPE_GPRS_UTRAN,
+ .gprs = {
+ .precedence = 3,
+ .delay = 4,
+ .reliability = 3,
+ .peak = 4,
+ .mean = 31,
+ .pdp_type = 2,
+ },
+ },
+ .buf_size = 1400,
+ } },
+ },
+};
+
+static const unsigned char open_channel_response_271[] = {
+ 0x81, 0x03, 0x01, 0x40, 0x01, 0x82, 0x02, 0x82, 0x81, 0x83,
+ 0x01, 0x22, 0x35, 0x07, 0x02, 0x03, 0x04, 0x03, 0x04, 0x1F,
+ 0x02, 0x39, 0x02, 0x05, 0x78,
+};
+
+static const struct terminal_response_test open_channel_response_data_271 = {
+ .pdu = open_channel_response_271,
+ .pdu_len = sizeof(open_channel_response_271),
+ .response = {
+ .number = 1,
+ .type = STK_COMMAND_TYPE_OPEN_CHANNEL,
+ .qualifier = STK_OPEN_CHANNEL_FLAG_IMMEDIATE,
+ .src = STK_DEVICE_IDENTITY_TYPE_TERMINAL,
+ .dst = STK_DEVICE_IDENTITY_TYPE_UICC,
+ .result = {
+ .type = STK_RESULT_TYPE_USER_REJECT,
+ },
+ { .open_channel = {
+ .bearer_desc = {
+ .type = STK_BEARER_TYPE_GPRS_UTRAN,
+ .gprs = {
+ .precedence = 3,
+ .delay = 4,
+ .reliability = 3,
+ .peak = 4,
+ .mean = 31,
+ .pdp_type = 2,
+ },
+ },
+ .buf_size = 1400,
+ } },
+ },
+};
+
+static const unsigned char close_channel_response_121[] = {
+ 0x81, 0x03, 0x01, 0x41, 0x00, 0x82, 0x02, 0x82, 0x81, 0x83,
+ 0x02, 0x3A, 0x03,
+};
+
+static const struct terminal_response_test close_channel_response_data_121 = {
+ .pdu = close_channel_response_121,
+ .pdu_len = sizeof(close_channel_response_121),
+ .response = {
+ .number = 1,
+ .type = STK_COMMAND_TYPE_CLOSE_CHANNEL,
+ .qualifier = 0x00,
+ .src = STK_DEVICE_IDENTITY_TYPE_TERMINAL,
+ .dst = STK_DEVICE_IDENTITY_TYPE_UICC,
+ .result = {
+ .type = STK_RESULT_TYPE_BIP_ERROR,
+ .additional_len = 1, /* Channel identifier not valid */
+ .additional = (unsigned char[1]) { 0x03 },
+ },
+ },
+};
+
+static const unsigned char close_channel_response_131[] = {
+ 0x81, 0x03, 0x01, 0x41, 0x00, 0x82, 0x02, 0x82, 0x81, 0x83,
+ 0x02, 0x3A, 0x02,
+};
+
+static const struct terminal_response_test close_channel_response_data_131 = {
+ .pdu = close_channel_response_131,
+ .pdu_len = sizeof(close_channel_response_131),
+ .response = {
+ .number = 1,
+ .type = STK_COMMAND_TYPE_CLOSE_CHANNEL,
+ .qualifier = 0x00,
+ .src = STK_DEVICE_IDENTITY_TYPE_TERMINAL,
+ .dst = STK_DEVICE_IDENTITY_TYPE_UICC,
+ .result = {
+ .type = STK_RESULT_TYPE_BIP_ERROR,
+ .additional_len = 1, /* Channel already closed */
+ .additional = (unsigned char[1]) { 0x02 },
+ },
+ },
+};
+
+static const unsigned char receive_data_response_111[] = {
+ 0x81, 0x03, 0x01, 0x42, 0x00, 0x82, 0x02, 0x82, 0x81, 0x83,
+ 0x01, 0x00, 0xB6, 0x81, 0xC8, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
+ 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0,
+ 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+ 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4,
+ 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
+ 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
+ 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
+ 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
+ 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
+ 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44,
+ 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
+ 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62,
+ 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
+ 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
+ 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80,
+ 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,
+ 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0xB7, 0x01, 0xFF,
+};
+
+static const struct terminal_response_test receive_data_response_data_111 = {
+ .pdu = receive_data_response_111,
+ .pdu_len = sizeof(receive_data_response_111),
+ .response = {
+ .number = 1,
+ .type = STK_COMMAND_TYPE_RECEIVE_DATA,
+ .qualifier = 0x00,
+ .src = STK_DEVICE_IDENTITY_TYPE_TERMINAL,
+ .dst = STK_DEVICE_IDENTITY_TYPE_UICC,
+ .result = {
+ .type = STK_RESULT_TYPE_SUCCESS,
+ },
+ { .receive_data = {
+ .rx_data = {
+ .array = (unsigned char[200]) {
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd,
+ 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3,
+ 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
+ 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5,
+ 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
+ 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1,
+ 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd,
+ 0xfe, 0xff, 0x00, 0x01, 0x02, 0x03,
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+ 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
+ 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+ 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
+ 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
+ 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
+ 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
+ 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d,
+ 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
+ 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+ 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b,
+ 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81,
+ 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d,
+ 0x8e, 0x8f,
+ },
+ .len = 200,
+ },
+ .rx_remaining = 0xFF,
+ } },
+ },
+};
+
+static const unsigned char send_data_response_111[] = {
+ 0x81, 0x03, 0x01, 0x43, 0x01, 0x82, 0x02, 0x82, 0x81, 0x83,
+ 0x01, 0x00, 0xB7, 0x01, 0xFF,
+};
+
+static const struct terminal_response_test send_data_response_data_111 = {
+ .pdu = send_data_response_111,
+ .pdu_len = sizeof(send_data_response_111),
+ .response = {
+ .number = 1,
+ .type = STK_COMMAND_TYPE_SEND_DATA,
+ .qualifier = STK_SEND_DATA_IMMEDIATELY,
+ .src = STK_DEVICE_IDENTITY_TYPE_TERMINAL,
+ .dst = STK_DEVICE_IDENTITY_TYPE_UICC,
+ .result = {
+ .type = STK_RESULT_TYPE_SUCCESS,
+ },
+ { .send_data = {
+ /* More than 255 bytes of space available */
+ .tx_avail = 0xFF,
+ } },
+ },
+};
+
+static const unsigned char send_data_response_121[] = {
+ 0x81, 0x03, 0x01, 0x43, 0x00, 0x82, 0x02, 0x82, 0x81, 0x83,
+ 0x01, 0x00, 0xB7, 0x01, 0xFF,
+};
+
+static const struct terminal_response_test send_data_response_data_121 = {
+ .pdu = send_data_response_121,
+ .pdu_len = sizeof(send_data_response_121),
+ .response = {
+ .number = 1,
+ .type = STK_COMMAND_TYPE_SEND_DATA,
+ .qualifier = STK_SEND_DATA_STORE_DATA,
+ .src = STK_DEVICE_IDENTITY_TYPE_TERMINAL,
+ .dst = STK_DEVICE_IDENTITY_TYPE_UICC,
+ .result = {
+ .type = STK_RESULT_TYPE_SUCCESS,
+ },
+ { .send_data = {
+ /* More than 255 bytes of space available */
+ .tx_avail = 0xFF,
+ } },
+ },
+};
+
+static const unsigned char send_data_response_151[] = {
+ 0x81, 0x03, 0x01, 0x43, 0x01, 0x82, 0x02, 0x82, 0x81, 0x83,
+ 0x02, 0x3A, 0x03,
+};
+
+static const struct terminal_response_test send_data_response_data_151 = {
+ .pdu = send_data_response_151,
+ .pdu_len = sizeof(send_data_response_151),
+ .response = {
+ .number = 1,
+ .type = STK_COMMAND_TYPE_SEND_DATA,
+ .qualifier = STK_SEND_DATA_IMMEDIATELY,
+ .src = STK_DEVICE_IDENTITY_TYPE_TERMINAL,
+ .dst = STK_DEVICE_IDENTITY_TYPE_UICC,
+ .result = {
+ .type = STK_RESULT_TYPE_BIP_ERROR,
+ .additional_len = 1, /* Channel identifier not valid */
+ .additional = (unsigned char[1]) { 0x03 },
+ },
+ },
+};
+
+static const unsigned char get_channel_status_response_111[] = {
+ 0x81, 0x03, 0x01, 0x44, 0x00, 0x82, 0x02, 0x82, 0x81, 0x83,
+ 0x01, 0x00, 0xB8, 0x02, 0x00, 0x00,
+};
+
+static const struct terminal_response_test
+ get_channel_status_response_data_111 = {
+ .pdu = get_channel_status_response_111,
+ .pdu_len = sizeof(get_channel_status_response_111),
+ .response = {
+ .number = 1,
+ .type = STK_COMMAND_TYPE_GET_CHANNEL_STATUS,
+ .qualifier = 0x00,
+ .src = STK_DEVICE_IDENTITY_TYPE_TERMINAL,
+ .dst = STK_DEVICE_IDENTITY_TYPE_UICC,
+ .result = {
+ .type = STK_RESULT_TYPE_SUCCESS,
+ },
+ { .channel_status = {
+ /*
+ * No Channel available, link not established or
+ * PDP context not activated
+ */
+ .channel = {
+ .id = 0,
+ .status =
+ STK_CHANNEL_PACKET_DATA_SERVICE_NOT_ACTIVATED,
+ }
+ } },
+ },
+};
+
+static const unsigned char get_channel_status_response_121[] = {
+ 0x81, 0x03, 0x01, 0x44, 0x00, 0x82, 0x02, 0x82, 0x81, 0x83,
+ 0x01, 0x00, 0xB8, 0x02, 0x81, 0x00,
+};
+
+static const struct terminal_response_test
+ get_channel_status_response_data_121 = {
+ .pdu = get_channel_status_response_121,
+ .pdu_len = sizeof(get_channel_status_response_121),
+ .response = {
+ .number = 1,
+ .type = STK_COMMAND_TYPE_GET_CHANNEL_STATUS,
+ .qualifier = 0x00,
+ .src = STK_DEVICE_IDENTITY_TYPE_TERMINAL,
+ .dst = STK_DEVICE_IDENTITY_TYPE_UICC,
+ .result = {
+ .type = STK_RESULT_TYPE_SUCCESS,
+ },
+ { .channel_status = {
+ /* Channel 1 open, link established or PDP context activated */
+ .channel = {
+ .id = 1,
+ .status =
+ STK_CHANNEL_PACKET_DATA_SERVICE_ACTIVATED,
+ },
+ } },
+ },
+};
+
+static const unsigned char get_channel_status_response_131[] = {
+ 0x81, 0x03, 0x01, 0x44, 0x00, 0x82, 0x02, 0x82, 0x81, 0x83,
+ 0x01, 0x00, 0xB8, 0x02, 0x01, 0x05,
+};
+
+static const struct terminal_response_test
+ get_channel_status_response_data_131 = {
+ .pdu = get_channel_status_response_131,
+ .pdu_len = sizeof(get_channel_status_response_131),
+ .response = {
+ .number = 1,
+ .type = STK_COMMAND_TYPE_GET_CHANNEL_STATUS,
+ .qualifier = 0x00,
+ .src = STK_DEVICE_IDENTITY_TYPE_TERMINAL,
+ .dst = STK_DEVICE_IDENTITY_TYPE_UICC,
+ .result = {
+ .type = STK_RESULT_TYPE_SUCCESS,
+ },
+ { .channel_status = {
+ /* Channel 1, link dropped */
+ .channel = {
+ .id = 1,
+ .status = STK_CHANNEL_LINK_DROPPED,
+ },
+ } },
+
+ },
+};
+
struct envelope_test {
const unsigned char *pdu;
unsigned int pdu_len;
@@ -22428,16 +23481,20 @@ static const struct envelope_test event_download_data_available_data_111 = {
.type = STK_EVENT_TYPE_DATA_AVAILABLE,
{ .data_available = {
/* Channel 1 open, Link established */
- .channel_status = { 0x81, 0x00 },
+ .channel = {
+ .id = 1,
+ .status =
+ STK_CHANNEL_PACKET_DATA_SERVICE_ACTIVATED,
+ },
.channel_data_len = 255,
- }},
- }},
+ } },
+ } },
},
};
static const unsigned char event_download_data_available_211[] = {
0xd6, 0x0e, 0x99, 0x01, 0x09, 0x82, 0x02, 0x82,
- 0x81, 0xb8, 0x02, 0x81, 0x01, 0xb7, 0x01, 0xff,
+ 0x81, 0xb8, 0x02, 0x81, 0x00, 0xb7, 0x01, 0xff,
};
static const struct envelope_test event_download_data_available_data_211 = {
@@ -22451,10 +23508,14 @@ static const struct envelope_test event_download_data_available_data_211 = {
.type = STK_EVENT_TYPE_DATA_AVAILABLE,
{ .data_available = {
/* Channel 1 open, Link established */
- .channel_status = { 0x81, 0x01 },
+ .channel = {
+ .id = 1,
+ .status =
+ STK_CHANNEL_PACKET_DATA_SERVICE_ACTIVATED,
+ },
.channel_data_len = 255,
- }},
- }},
+ } },
+ } },
},
};
@@ -22474,9 +23535,12 @@ static const struct envelope_test event_download_channel_status_data_131 = {
.type = STK_EVENT_TYPE_CHANNEL_STATUS,
{ .channel_status = {
/* Channel 1, Link dropped */
- .status = { 0x01, 0x05 },
- }},
- }},
+ .channel = {
+ .id = 1,
+ .status = STK_CHANNEL_LINK_DROPPED,
+ },
+ } },
+ } },
},
};
@@ -22500,15 +23564,18 @@ static const struct envelope_test event_download_channel_status_data_211 = {
.type = STK_EVENT_TYPE_CHANNEL_STATUS,
{ .channel_status = {
/* Channel 1, TCP in LISTEN state */
- .status = { 0x41, 0x00 },
- }},
- }},
+ .channel = {
+ .id = 1,
+ .status = STK_CHANNEL_TCP_IN_LISTEN_STATE,
+ },
+ } },
+ } },
},
};
static const unsigned char event_download_channel_status_221[] = {
0xd6, 0x0b, 0x99, 0x01, 0x0a, 0x82, 0x02, 0x82,
- 0x81, 0xb8, 0x02, 0x81, 0x01,
+ 0x81, 0xb8, 0x02, 0x81, 0x00,
/*
* Byte 10 changed to 0xb8 (Comprehension Required should be
* set according to TS 102 223 7.5.11.2)
@@ -22526,9 +23593,13 @@ static const struct envelope_test event_download_channel_status_data_221 = {
.type = STK_EVENT_TYPE_CHANNEL_STATUS,
{ .channel_status = {
/* Channel 1 open, TCP Link established */
- .status = { 0x81, 0x01 },
- }},
- }},
+ .channel = {
+ .id = 1,
+ .status =
+ STK_CHANNEL_PACKET_DATA_SERVICE_ACTIVATED,
+ },
+ } },
+ } },
},
};
@@ -24790,6 +25861,71 @@ int main(int argc, char **argv)
&launch_browser_response_data_411b,
test_terminal_response_encoding);
+
+ g_test_add_data_func("/teststk/Open channel 2.1.1",
+ &open_channel_data_211, test_open_channel);
+ g_test_add_data_func("/teststk/Open channel 2.2.1",
+ &open_channel_data_221, test_open_channel);
+ g_test_add_data_func("/teststk/Open channel 2.3.1",
+ &open_channel_data_231, test_open_channel);
+ g_test_add_data_func("/teststk/Open channel 2.4.1",
+ &open_channel_data_241, test_open_channel);
+ g_test_add_data_func("/teststk/Open channel 5.1.1",
+ &open_channel_data_511, test_open_channel);
+ g_test_add_data_func("/teststk/Open channel response 2.1.1",
+ &open_channel_response_data_211,
+ test_terminal_response_encoding);
+ g_test_add_data_func("/teststk/Open channel response 2.7.1",
+ &open_channel_response_data_271,
+ test_terminal_response_encoding);
+
+ g_test_add_data_func("/teststk/Close channel 1.1.1",
+ &close_channel_data_111, test_close_channel);
+ g_test_add_data_func("/teststk/Close channel 2.1.1",
+ &close_channel_data_211, test_close_channel);
+ g_test_add_data_func("/teststk/Close channel response 1.2.1",
+ &close_channel_response_data_121,
+ test_terminal_response_encoding);
+ g_test_add_data_func("/teststk/Close channel response 1.3.1",
+ &close_channel_response_data_131,
+ test_terminal_response_encoding);
+
+ g_test_add_data_func("/teststk/Receive data 1.1.1",
+ &receive_data_data_111, test_receive_data);
+ g_test_add_data_func("/teststk/Receive data 2.1.1",
+ &receive_data_data_211, test_receive_data);
+ g_test_add_data_func("/teststk/Receive data response 1.1.1",
+ &receive_data_response_data_111,
+ test_terminal_response_encoding);
+
+ g_test_add_data_func("/teststk/Send data 1.1.1",
+ &send_data_data_111, test_send_data);
+ g_test_add_data_func("/teststk/Send data 1.2.1",
+ &send_data_data_121, test_send_data);
+ g_test_add_data_func("/teststk/Send data 2.1.1",
+ &send_data_data_211, test_send_data);
+ g_test_add_data_func("/teststk/Send data response 1.1.1",
+ &send_data_response_data_111,
+ test_terminal_response_encoding);
+ g_test_add_data_func("/teststk/Send data response 1.2.1",
+ &send_data_response_data_121,
+ test_terminal_response_encoding);
+ g_test_add_data_func("/teststk/Send data response 1.5.1",
+ &send_data_response_data_151,
+ test_terminal_response_encoding);
+
+ g_test_add_data_func("/teststk/Get Channel status 1.1.1",
+ &get_channel_status_data_111, test_get_channel_status);
+ g_test_add_data_func("/teststk/Get Channel status response 1.1.1",
+ &get_channel_status_response_data_111,
+ test_terminal_response_encoding);
+ g_test_add_data_func("/teststk/Get Channel status response 1.2.1",
+ &get_channel_status_response_data_121,
+ test_terminal_response_encoding);
+ g_test_add_data_func("/teststk/Get Channel status response 1.3.1",
+ &get_channel_status_response_data_131,
+ test_terminal_response_encoding);
+
g_test_add_data_func("/teststk/SMS-PP data download 1.6.1",
&sms_pp_data_download_data_161,
test_envelope_encoding);
--
1.7.1
9 years, 9 months
[PATCH 03/18] gathdlc: add mechansim to detect '+++' escape sequence
by Guillaume Zajac
---
gatchat/gathdlc.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 114 insertions(+), 0 deletions(-)
diff --git a/gatchat/gathdlc.c b/gatchat/gathdlc.c
index 7c45454..21e4533 100644
--- a/gatchat/gathdlc.c
+++ b/gatchat/gathdlc.c
@@ -50,6 +50,13 @@
#define HDLC_FCS(fcs, c) crc_ccitt_byte(fcs, c)
+/* Amount of fiftieths of second to detect '+++'.
+ * Range is 0 to 0xff.
+ */
+#define ESC_TIME 0x32
+
+#define GUARD_TIMEOUTS 1000 /* Pause time before and after '+++' sequence */
+
struct _GAtHDLC {
gint ref_count;
GAtIO *io;
@@ -68,6 +75,12 @@ struct _GAtHDLC {
gboolean in_read_handler;
gboolean destroyed;
gboolean no_carrier_detect;
+ GAtSuspendFunc suspend_func;
+ gpointer suspend_data;
+ guint cmpt;
+ guint suspend_timeout;
+ guint pause_timeout;
+ gboolean paused;
};
static void hdlc_record(int fd, gboolean in, guint8 *data, guint16 length)
@@ -130,6 +143,47 @@ guint32 g_at_hdlc_get_recv_accm(GAtHDLC *hdlc)
return hdlc->recv_accm;
}
+void g_at_hdlc_set_suspend_function(GAtHDLC *hdlc, GAtSuspendFunc func,
+ gpointer user_data)
+{
+ if (hdlc == NULL)
+ return;
+
+ hdlc->suspend_func = func;
+ hdlc->suspend_data = user_data;
+}
+
+static gboolean paused_timeout_cb(gpointer user_data)
+{
+ GAtHDLC *hdlc = user_data;
+
+ hdlc->paused = TRUE;
+
+ return FALSE;
+}
+
+static gboolean susp_timeout_cb(gpointer user_data)
+{
+ GAtHDLC *hdlc = user_data;
+
+ hdlc->cmpt = 0;
+
+ return FALSE;
+}
+
+static gboolean hdlc_suspend(gpointer user_data)
+{
+ GAtHDLC *hdlc = user_data;
+
+ g_at_io_set_write_handler(hdlc->io, NULL, NULL);
+ g_at_io_set_read_handler(hdlc->io, NULL, NULL);
+
+ if (hdlc->suspend_func)
+ hdlc->suspend_func(hdlc->suspend_data);
+
+ return FALSE;
+}
+
static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
{
GAtHDLC *hdlc = user_data;
@@ -142,6 +196,13 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
hdlc->in_read_handler = TRUE;
+ /*
+ * We delete the the paused_timeout_cb or hdlc_suspend as soons as
+ * we read a data.
+ */
+ if (hdlc->pause_timeout > 0)
+ g_source_remove(hdlc->pause_timeout);
+
while (pos < len) {
/*
* We try to detect NO CARRIER conditions here. We
@@ -153,6 +214,21 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
hdlc->decode_offset == 0 && *buf == '\r')
break;
+ /*
+ * If there was no character for 1 second we try to detect
+ * the '+' character to suspend data call if 3 '+' are
+ * detected in less than 20 * ESC_TIME milliseconds.
+ */
+ if (*buf == '+' && hdlc->paused) {
+ if (hdlc->cmpt == 0)
+ hdlc->suspend_timeout = g_timeout_add (20 * ESC_TIME,
+ susp_timeout_cb, hdlc);
+ hdlc->cmpt++;
+ } else {
+ hdlc->cmpt = 0;
+ hdlc->paused = FALSE;
+ }
+
if (hdlc->decode_escape == TRUE) {
unsigned char val = *buf ^ HDLC_TRANS;
@@ -190,6 +266,9 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
}
}
+ if (hdlc->cmpt == 3)
+ goto suspend;
+
out:
ring_buffer_drain(rbuf, pos);
@@ -197,6 +276,37 @@ out:
if (hdlc->destroyed)
g_free(hdlc);
+
+ /*
+ * If there were no data pause for GUARD_TIMEOUTS ms,
+ * we try again to check it.
+ */
+ if (!hdlc->paused)
+ hdlc->pause_timeout = g_timeout_add (GUARD_TIMEOUTS,
+ paused_timeout_cb,
+ hdlc);
+
+ return;
+
+suspend:
+ /*
+ * If the suspend timeout still exists,
+ * delete it.
+ */
+ if (hdlc->suspend_timeout > 0)
+ g_source_remove(hdlc->suspend_timeout);
+
+ /*
+ * Restart the counter and reset the ring buffer.
+ */
+ hdlc->cmpt = 0;
+ ring_buffer_reset(rbuf);
+
+ /*
+ * Wait for another pause of GUARD_TIMEOUTS ms before returning to command mode.
+ */
+ hdlc->paused = FALSE;
+ hdlc->pause_timeout = g_timeout_add (GUARD_TIMEOUTS, hdlc_suspend, hdlc);
}
GAtHDLC *g_at_hdlc_new_from_io(GAtIO *io)
@@ -245,6 +355,10 @@ GAtHDLC *g_at_hdlc_new_from_io(GAtIO *io)
hdlc->io = g_at_io_ref(io);
g_at_io_set_read_handler(hdlc->io, new_bytes, hdlc);
+ hdlc->cmpt = 0;
+
+ hdlc->paused = FALSE;
+
return hdlc;
error:
--
1.7.1
9 years, 9 months
[PATCH 18/18] gsmdial: implement mechanism to send +++ -> ATO0 -> +++ -> ATH0
by Guillaume Zajac
---
gatchat/gsmdial.c | 164 ++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 138 insertions(+), 26 deletions(-)
diff --git a/gatchat/gsmdial.c b/gatchat/gsmdial.c
index 92a7ff2..f1b485e 100644
--- a/gatchat/gsmdial.c
+++ b/gatchat/gsmdial.c
@@ -40,6 +40,8 @@
#define IFCONFIG_PATH "/sbin/ifconfig"
+#define GUARD_TIMEOUTS 1500
+
static const char *none_prefix[] = { NULL };
static const char *cfun_prefix[] = { "+CFUN:", NULL };
static const char *creg_prefix[] = { "+CREG:", NULL };
@@ -238,32 +240,6 @@ static gboolean execute(const char *cmd)
return TRUE;
}
-static void ppp_connect(const char *iface, const char *local, const char *peer,
- const char *dns1, const char *dns2,
- gpointer user_data)
-{
- char buf[512];
-
- /* print out the negotiated address and dns server */
- g_print("Network Device: %s\n", iface);
- g_print("IP Address: %s\n", local);
- g_print("Peer IP Address: %s\n", peer);
- g_print("Primary DNS Server: %s\n", dns1);
- g_print("Secondary DNS Server: %s\n", dns2);
-
- if (getuid() != 0) {
- g_print("Need root privilege to config PPP interface\n");
- return;
- }
-
- snprintf(buf, sizeof(buf), "%s %s up", IFCONFIG_PATH, iface);
- execute(buf);
-
- snprintf(buf, sizeof(buf), "%s %s %s pointopoint %s", IFCONFIG_PATH,
- iface, local, peer);
- execute(buf);
-}
-
static void no_carrier_notify(GAtResult *result, gpointer user_data)
{
char buf[64];
@@ -294,6 +270,142 @@ static void ppp_disconnect(GAtPPPDisconnectReason reason, gpointer user_data)
g_at_chat_resume(modem);
}
+static void power_down_ppp(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ if (!ok)
+ return;
+
+ g_at_ppp_unref(ppp);
+ ppp = NULL;
+}
+
+static gboolean send_ATH0(gpointer user_data)
+{
+ /* Resume AT chat to send ATH0 */
+ g_at_chat_resume(modem);
+ g_at_chat_send(modem, "ATH0", none_prefix, power_down_ppp, NULL, NULL);
+
+ return FALSE;
+}
+
+static gboolean suspend_and_close(gpointer user_data)
+{
+ g_print("Send +++\n");
+ /* Send the escape sequence to suspend PPP server*/
+ g_at_io_write(g_at_chat_get_io(modem), "+++", 3);
+
+ /*
+ * Wait GUARD_TIMEOUTS ms before sending ATH0 cmd
+ * according to guard timeouts
+ */
+ g_timeout_add(GUARD_TIMEOUTS, send_ATH0, NULL);
+
+ return FALSE;
+}
+
+static void ppp_suspend_close(gpointer data)
+{
+ /* Delete the write done CB */
+ g_at_io_set_write_done(g_at_chat_get_io(modem), NULL, NULL);
+
+ /*
+ * We are sure there are no more PPP packets to be written,
+ * we can suspend PPP client
+ */
+ g_at_ppp_suspend(ppp);
+
+ /* Wait GUARD_TIMEOUTS ms before sending escape sequence */
+ g_timeout_add(GUARD_TIMEOUTS, suspend_and_close, NULL);
+}
+
+static void suspend_gat_chat(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ /*
+ * As soon as the command is treated by AT server
+ * we can suspend AT chat and resume PPP client
+ */
+ g_at_chat_suspend(modem);
+ g_at_ppp_resume(ppp);
+
+ /*
+ * We wait for another PPP packet to be written
+ * to suspend again PPP server and close it
+ */
+ g_at_io_set_write_done(g_at_chat_get_io(modem), ppp_suspend_close, NULL);
+}
+
+static gboolean send_ATO0(gpointer user_data)
+{
+ /* Resume AT chat to send ATO0 */
+ g_at_chat_resume(modem);
+ g_at_chat_send(modem, "ATO0", none_prefix, suspend_gat_chat, NULL, NULL);
+
+ return FALSE;
+}
+
+static gboolean suspend_resume(gpointer user_data)
+{
+ g_print("Send +++\n");
+ /* Send the escape sequence to suspend PPP server*/
+ g_at_io_write(g_at_chat_get_io(modem), "+++", 3);
+
+ /*
+ * Wait GUARD_TIMEOUTS ms before sending ATO0 cmd
+ * according to guard timeouts
+ */
+ g_timeout_add(GUARD_TIMEOUTS, send_ATO0, NULL);
+
+ return FALSE;
+}
+
+static void ppp_suspend_resume(gpointer data)
+{
+ /* Delete the write done CB */
+ g_at_io_set_write_done(g_at_chat_get_io(modem), NULL, NULL);
+
+ /*
+ * We are sure there are no more PPP packets to be written,
+ * we can suspend PPP client
+ */
+ g_at_ppp_suspend(ppp);
+
+ /* Wait GUARD_TIMEOUTS ms before sending escape sequence */
+ g_timeout_add(GUARD_TIMEOUTS, suspend_resume, NULL);
+}
+
+static void ppp_connect(const char *iface, const char *local, const char *peer,
+ const char *dns1, const char *dns2,
+ gpointer user_data)
+{
+ char buf[512];
+
+ /* print out the negotiated address and dns server */
+ g_print("Network Device: %s\n", iface);
+ g_print("IP Address: %s\n", local);
+ g_print("Peer IP Address: %s\n", peer);
+ g_print("Primary DNS Server: %s\n", dns1);
+ g_print("Secondary DNS Server: %s\n", dns2);
+
+ if (getuid() != 0) {
+ g_print("Need root privilege to config PPP interface\n");
+ return;
+ }
+
+ snprintf(buf, sizeof(buf), "%s %s up", IFCONFIG_PATH, iface);
+ execute(buf);
+
+ snprintf(buf, sizeof(buf), "%s %s %s pointopoint %s", IFCONFIG_PATH,
+ iface, local, peer);
+ execute(buf);
+
+ /*
+ * As soon as a PPP packet is written by the client, we try to send the escape sequence
+ * and resume PPP server using ATO0 cmd
+ */
+ if (option_esc)
+ g_at_io_set_write_done(g_at_chat_get_io(modem), ppp_suspend_resume, NULL);
+}
+
static void connect_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
GAtIO *io;
--
1.7.1
9 years, 9 months
[PATCH v2 1/2] stkutil: Complete the TLV parsing/builder to support BIP commands
by Philippe Nunes
---
src/stkutil.c | 287 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
src/stkutil.h | 132 ++++++++++++++++++++++-----
2 files changed, 380 insertions(+), 39 deletions(-)
diff --git a/src/stkutil.c b/src/stkutil.c
index c64cb7a..94be192 100644
--- a/src/stkutil.c
+++ b/src/stkutil.c
@@ -1264,8 +1264,20 @@ static gboolean parse_dataobj_bearer_description(
data = comprehension_tlv_iter_get_data(iter);
bd->type = data[0];
- bd->len = len - 1;
- memcpy(bd->pars, data + 1, bd->len);
+
+ /* Parse only the packet data service bearer parameters */
+ if (bd->type != STK_BEARER_TYPE_GPRS_UTRAN)
+ return FALSE;
+
+ if (len < 7)
+ return FALSE;
+
+ bd->gprs.precedence = data[1];
+ bd->gprs.delay = data[2];
+ bd->gprs.reliability = data[3];
+ bd->gprs.peak = data[4];
+ bd->gprs.mean = data[5];
+ bd->gprs.pdp_type = data[6];
return TRUE;
}
@@ -1355,8 +1367,16 @@ static gboolean parse_dataobj_other_address(
return FALSE;
data = comprehension_tlv_iter_get_data(iter);
+
+ if (data[0] != STK_ADDRESS_IPV4 && data[0] != STK_ADDRESS_IPV6)
+ return FALSE;
+
oa->type = data[0];
- memcpy(&oa->addr, data + 1, len - 1);
+
+ if (oa->type == STK_ADDRESS_IPV4)
+ memcpy(&oa->addr.ipv4, data + 1, 4);
+ else
+ memcpy(&oa->addr.ipv6, data + 1, 16);
return TRUE;
}
@@ -1604,16 +1624,48 @@ static gboolean parse_dataobj_esn(struct comprehension_tlv_iter *iter,
static gboolean parse_dataobj_network_access_name(
struct comprehension_tlv_iter *iter, void *user)
{
- struct stk_network_access_name *nan = user;
+ char **apn = user;
const unsigned char *data;
unsigned int len = comprehension_tlv_iter_get_length(iter);
+ unsigned char label_size;
+ unsigned char offset = 0;
+ char decoded_apn[100];
- if (len == 0)
+ if (len == 0 || len > 100)
return FALSE;
data = comprehension_tlv_iter_get_data(iter);
- nan->len = len;
- memcpy(nan->name, data, len);
+ /*
+ * As specified in TS 23 003 Section 9
+ * The APN consists of one or more labels. Each label is coded as
+ * a one octet length field followed by that number of octets coded
+ * as 8 bit ASCII characters
+ */
+
+ while (len) {
+ label_size = *data;
+
+ if (label_size > (len-1))
+ return FALSE;
+
+ memcpy(decoded_apn + offset, data + 1, label_size);
+
+ data += label_size + 1;
+ offset += label_size;
+
+ len -= label_size + 1;
+ if (len) {
+ decoded_apn[offset] = '.';
+ offset += 1;
+ }
+ }
+
+ *apn = g_try_malloc(offset + 1);
+ if (*apn == NULL)
+ return FALSE;
+
+ memcpy(*apn, decoded_apn, offset);
+ (*apn)[offset] = '\0';
return TRUE;
}
@@ -3274,7 +3326,68 @@ static enum stk_command_parse_result parse_launch_browser(
STK_DATA_OBJECT_TYPE_INVALID);
}
-/* TODO: parse_open_channel */
+static void destroy_open_channel(struct stk_command *command)
+{
+ g_free(command->open_channel.alpha_id);
+ g_free(command->open_channel.text_usr);
+ g_free(command->open_channel.text_passwd);
+}
+
+static enum stk_command_parse_result parse_open_channel(
+ struct stk_command *command,
+ struct comprehension_tlv_iter *iter)
+{
+ struct stk_command_open_channel *obj = &command->open_channel;
+ enum stk_command_parse_result status;
+
+ if (command->qualifier >= 0x08)
+ return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
+
+ if (command->src != STK_DEVICE_IDENTITY_TYPE_UICC)
+ return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
+
+ if (command->dst != STK_DEVICE_IDENTITY_TYPE_TERMINAL)
+ return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
+
+ command->destructor = destroy_open_channel;
+
+ /*
+ * parse the Open Channel data objects related to packet data service
+ * bearer
+ */
+ status = parse_dataobj(iter,
+ STK_DATA_OBJECT_TYPE_ALPHA_ID, 0,
+ &obj->alpha_id,
+ STK_DATA_OBJECT_TYPE_ICON_ID, 0,
+ &obj->icon_id,
+ STK_DATA_OBJECT_TYPE_BEARER_DESCRIPTION,
+ DATAOBJ_FLAG_MANDATORY | DATAOBJ_FLAG_MINIMUM,
+ &obj->bearer_desc,
+ STK_DATA_OBJECT_TYPE_BUFFER_SIZE,
+ DATAOBJ_FLAG_MANDATORY | DATAOBJ_FLAG_MINIMUM,
+ &obj->buf_size,
+ STK_DATA_OBJECT_TYPE_NETWORK_ACCESS_NAME, 0,
+ &obj->apn,
+ STK_DATA_OBJECT_TYPE_OTHER_ADDRESS, 0,
+ &obj->local_addr,
+ STK_DATA_OBJECT_TYPE_TEXT, 0,
+ &obj->text_usr,
+ STK_DATA_OBJECT_TYPE_TEXT, 0,
+ &obj->text_passwd,
+ STK_DATA_OBJECT_TYPE_UICC_TE_INTERFACE, 0,
+ &obj->uti,
+ STK_DATA_OBJECT_TYPE_OTHER_ADDRESS, 0,
+ &obj->data_dest_addr,
+ STK_DATA_OBJECT_TYPE_TEXT_ATTRIBUTE, 0,
+ &obj->text_attr,
+ STK_DATA_OBJECT_TYPE_FRAME_ID, 0,
+ &obj->frame_id,
+ STK_DATA_OBJECT_TYPE_INVALID);
+
+ CHECK_TEXT_AND_ICON(obj->alpha_id, obj->icon_id.id);
+
+ return status;
+}
static void destroy_close_channel(struct stk_command *command)
{
@@ -3291,7 +3404,8 @@ static enum stk_command_parse_result parse_close_channel(
if (command->src != STK_DEVICE_IDENTITY_TYPE_UICC)
return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
- if (command->dst != STK_DEVICE_IDENTITY_TYPE_TERMINAL)
+ if ((command->dst < STK_DEVICE_IDENTITY_TYPE_CHANNEL_1) ||
+ (command->dst > STK_DEVICE_IDENTITY_TYPE_CHANNEL_7))
return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
command->destructor = destroy_close_channel;
@@ -3363,6 +3477,9 @@ static enum stk_command_parse_result parse_send_data(
struct stk_command_send_data *obj = &command->send_data;
enum stk_command_parse_result status;
+ if (command->qualifier > STK_SEND_DATA_IMMEDIATELY)
+ return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
+
if (command->src != STK_DEVICE_IDENTITY_TYPE_UICC)
return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
@@ -3737,6 +3854,8 @@ static enum stk_command_parse_result parse_command_body(
return parse_language_notification(command, iter);
case STK_COMMAND_TYPE_LAUNCH_BROWSER:
return parse_launch_browser(command, iter);
+ case STK_COMMAND_TYPE_OPEN_CHANNEL:
+ return parse_open_channel(command, iter);
case STK_COMMAND_TYPE_CLOSE_CHANNEL:
return parse_close_channel(command, iter);
case STK_COMMAND_TYPE_RECEIVE_DATA:
@@ -4752,12 +4871,35 @@ static gboolean build_dataobj_bearer_description(struct stk_tlv_builder *tlv,
const struct stk_bearer_description *bd = data;
unsigned char tag = STK_DATA_OBJECT_TYPE_BEARER_DESCRIPTION;
- if (bd->type == 0x00)
+ if (bd->type != STK_BEARER_TYPE_GPRS_UTRAN)
return TRUE;
return stk_tlv_builder_open_container(tlv, cr, tag, FALSE) &&
stk_tlv_builder_append_byte(tlv, bd->type) &&
- stk_tlv_builder_append_bytes(tlv, bd->pars, bd->len) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.precedence) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.delay) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.reliability) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.peak) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.mean) &&
+ stk_tlv_builder_append_byte(tlv,
+ bd->gprs.pdp_type) &&
+ stk_tlv_builder_close_container(tlv);
+}
+
+/* Described in TS 102.223 Section 8.53 */
+static gboolean build_dataobj_channel_data(struct stk_tlv_builder *tlv,
+ const void *data, gboolean cr)
+{
+ const struct stk_common_byte_array *cd = data;
+ unsigned char tag = STK_DATA_OBJECT_TYPE_CHANNEL_DATA;
+
+ return stk_tlv_builder_open_container(tlv, cr, tag, TRUE) &&
+ stk_tlv_builder_append_bytes(tlv, cd->array, cd->len) &&
stk_tlv_builder_close_container(tlv);
}
@@ -4766,7 +4908,7 @@ static gboolean build_dataobj_channel_data_length(
struct stk_tlv_builder *tlv,
const void *data, gboolean cr)
{
- const unsigned int *length = data;
+ const unsigned short *length = data;
unsigned char tag = STK_DATA_OBJECT_TYPE_CHANNEL_DATA_LENGTH;
return stk_tlv_builder_open_container(tlv, cr, tag, FALSE) &&
@@ -4774,15 +4916,50 @@ static gboolean build_dataobj_channel_data_length(
stk_tlv_builder_close_container(tlv);
}
+/* Described in TS 102.223 Section 8.55 */
+static gboolean build_dataobj_buffer_size(struct stk_tlv_builder *tlv,
+ const void *data, gboolean cr)
+{
+ const unsigned short *buf_size = data;
+ unsigned char tag = STK_DATA_OBJECT_TYPE_BUFFER_SIZE;
+
+ return stk_tlv_builder_open_container(tlv, cr, tag, FALSE) &&
+ stk_tlv_builder_append_short(tlv, *buf_size) &&
+ stk_tlv_builder_close_container(tlv);
+}
+
/* Described in TS 102.223 Section 8.56 */
static gboolean build_dataobj_channel_status(struct stk_tlv_builder *tlv,
const void *data, gboolean cr)
{
+ const struct stk_channel *channel = data;
unsigned char tag = STK_DATA_OBJECT_TYPE_CHANNEL_STATUS;
+ unsigned char byte[2];
+
+ switch (channel->status) {
+ case STK_CHANNEL_PACKET_DATA_SERVICE_NOT_ACTIVATED:
+ case STK_CHANNEL_TCP_IN_CLOSED_STATE:
+ byte[0] = channel->id;
+ byte[1] = 0x00;
+ break;
+ case STK_CHANNEL_PACKET_DATA_SERVICE_ACTIVATED:
+ case STK_CHANNEL_TCP_IN_ESTABLISHED_STATE:
+ byte[0] = channel->id | 0x80;
+ byte[1] = 0x00;
+ break;
+ case STK_CHANNEL_TCP_IN_LISTEN_STATE:
+ byte[0] = channel->id | 0x40;
+ byte[1] = 0x00;
+ break;
+ case STK_CHANNEL_LINK_DROPPED:
+ byte[0] = channel->id;
+ byte[1] = 0x05;
+ break;
+ }
return stk_tlv_builder_open_container(tlv, cr, tag, FALSE) &&
- stk_tlv_builder_append_bytes(tlv, data, 2) &&
- stk_tlv_builder_close_container(tlv);
+ stk_tlv_builder_append_bytes(tlv, byte, 2) &&
+ stk_tlv_builder_close_container(tlv);
}
/* Described in TS 102.223 Section 8.58 */
@@ -5454,6 +5631,67 @@ static gboolean build_local_info(struct stk_tlv_builder *builder,
return FALSE;
}
+static gboolean build_open_channel(struct stk_tlv_builder *builder,
+ const struct stk_response *response)
+{
+ const struct stk_response_open_channel *open_channel =
+ &response->open_channel;
+
+ /* insert channel identifier only in case of success */
+ if (response->result.type == STK_RESULT_TYPE_SUCCESS) {
+ if (build_dataobj(builder, build_dataobj_channel_status,
+ 0, &open_channel->channel,
+ NULL) != TRUE)
+ return FALSE;
+ }
+
+ return build_dataobj(builder,
+ build_dataobj_bearer_description,
+ 0, &open_channel->bearer_desc,
+ build_dataobj_buffer_size,
+ 0, &open_channel->buf_size,
+ NULL);
+}
+
+static gboolean build_receive_data(struct stk_tlv_builder *builder,
+ const struct stk_response *response)
+{
+ const struct stk_response_receive_data *receive_data =
+ &response->receive_data;
+
+ if (response->result.type == STK_RESULT_TYPE_SUCCESS) {
+ if (receive_data->rx_data.len) {
+ if (build_dataobj(builder, build_dataobj_channel_data,
+ DATAOBJ_FLAG_CR,
+ &response->receive_data.rx_data,
+ NULL) != TRUE)
+ return FALSE;
+ }
+
+ return build_dataobj(builder,
+ build_dataobj_channel_data_length,
+ DATAOBJ_FLAG_CR,
+ &response->receive_data.rx_remaining,
+ NULL);
+ }
+
+ return TRUE;
+}
+
+static gboolean build_send_data(struct stk_tlv_builder *builder,
+ const struct stk_response *response)
+{
+ if (response->result.type == STK_RESULT_TYPE_SUCCESS) {
+ return build_dataobj(builder,
+ build_dataobj_channel_data_length,
+ DATAOBJ_FLAG_CR,
+ &response->send_data.tx_avail,
+ NULL);
+ }
+
+ return TRUE;
+}
+
const unsigned char *stk_pdu_from_response(const struct stk_response *response,
unsigned int *out_length)
{
@@ -5582,6 +5820,7 @@ const unsigned char *stk_pdu_from_response(const struct stk_response *response,
case STK_COMMAND_TYPE_SEND_DTMF:
case STK_COMMAND_TYPE_LANGUAGE_NOTIFICATION:
case STK_COMMAND_TYPE_LAUNCH_BROWSER:
+ case STK_COMMAND_TYPE_CLOSE_CHANNEL:
break;
case STK_COMMAND_TYPE_SEND_USSD:
ok = build_dataobj(&builder,
@@ -5590,6 +5829,22 @@ const unsigned char *stk_pdu_from_response(const struct stk_response *response,
&response->send_ussd.text,
NULL);
break;
+ case STK_COMMAND_TYPE_OPEN_CHANNEL:
+ ok = build_open_channel(&builder, response);
+ break;
+ case STK_COMMAND_TYPE_RECEIVE_DATA:
+ ok = build_receive_data(&builder, response);
+ break;
+ case STK_COMMAND_TYPE_SEND_DATA:
+ ok = build_send_data(&builder, response);
+ break;
+ case STK_COMMAND_TYPE_GET_CHANNEL_STATUS:
+ ok = build_dataobj(&builder,
+ build_dataobj_channel_status,
+ DATAOBJ_FLAG_CR,
+ &response->channel_status.channel,
+ NULL);
+ break;
default:
return NULL;
};
@@ -5738,7 +5993,7 @@ static gboolean build_envelope_event_download(struct stk_tlv_builder *builder,
return build_dataobj(builder,
build_dataobj_channel_status,
DATAOBJ_FLAG_CR,
- &evt->data_available.channel_status,
+ &evt->data_available.channel,
build_dataobj_channel_data_length,
DATAOBJ_FLAG_CR,
&evt->data_available.channel_data_len,
@@ -5747,7 +6002,7 @@ static gboolean build_envelope_event_download(struct stk_tlv_builder *builder,
return build_dataobj(builder,
build_dataobj_channel_status,
DATAOBJ_FLAG_CR,
- &evt->channel_status.status,
+ &evt->channel_status.channel,
build_dataobj_bearer_description,
DATAOBJ_FLAG_CR,
&evt->channel_status.bearer_desc,
diff --git a/src/stkutil.h b/src/stkutil.h
index f2df23f..7dfb9a6 100644
--- a/src/stkutil.h
+++ b/src/stkutil.h
@@ -425,14 +425,19 @@ enum stk_browser_termination_cause {
STK_BROWSER_ERROR_TERMINATION = 0x01
};
+/* Defined in TS 31.111 Section 8.52 */
enum stk_bearer_type {
+ STK_BEARER_TYPE_CS = 0x01,
+ STK_BEARER_TYPE_GPRS_UTRAN = 0x02,
STK_BEARER_TYPE_DEFAULT = 0x03,
STK_BEARER_TYPE_INDEPENDENT = 0x04,
STK_BEARER_TYPE_BLUETOOTH = 0x05,
STK_BEARER_TYPE_IRDA = 0x06,
STK_BEARER_TYPE_RS232 = 0x07,
- STK_BEARER_TYPE_PACKET_DATA_SERVICE = 0x08,
- STK_BEARER_TYPE_I_WLAN = 0x0a,
+ STK_BEARER_TYPE_TIA_EIA_IS_820 = 0x08,
+ STK_BEARER_TYPE_UTRAN_WITH_EXT_PARAMS = 0x09,
+ STK_BEARER_TYPE_I_WLAN = 0x0A,
+ STK_BEARER_TYPE_EUTRAN_MAPPED_UTRAN = 0x0B,
STK_BEARER_TYPE_USB = 0x10
};
@@ -587,6 +592,40 @@ enum stk_img_scheme {
STK_IMG_SCHEME_TRANSPARENCY = 0x22,
};
+/* Defined in TS 102.223 Section 8.6 */
+enum stk_qualifier_open_channel {
+ STK_OPEN_CHANNEL_ON_DEMAND = 0x00,
+ STK_OPEN_CHANNEL_IMMEDIATE = 0x01,
+ STK_OPEN_CHANNEL_AUTOMATIC_RECONNECTION = 0x02,
+ STK_OPEN_CHANNEL_IMMEDIATE_IN_BACKGROUND_MODE = 0x04,
+};
+
+/* Defined in TS 102.223 Section 8.1 */
+enum stk_qualifier_send_data {
+ STK_SEND_DATA_STORE_DATA = 0x00,
+ STK_SEND_DATA_IMMEDIATELY = 0x01,
+};
+
+/* Defined in TS 102.223 Section 8.56 */
+enum stk_channel_status {
+ STK_CHANNEL_PACKET_DATA_SERVICE_NOT_ACTIVATED = 0x00,
+ STK_CHANNEL_PACKET_DATA_SERVICE_ACTIVATED = 0x01,
+ STK_CHANNEL_TCP_IN_CLOSED_STATE = 0x02,
+ STK_CHANNEL_TCP_IN_LISTEN_STATE = 0x03,
+ STK_CHANNEL_TCP_IN_ESTABLISHED_STATE = 0x04,
+ STK_CHANNEL_LINK_DROPPED = 0x05,
+};
+
+/* Defined in TS 102.223 Section 8.59 */
+enum stk_transport_protocol_type {
+ STK_TRANSPORT_PROTOCOL_UDP_CLIENT_REMOTE = 0x01,
+ STK_TRANSPORT_PROTOCOL_TCP_CLIENT_REMOTE = 0x02,
+ STK_TRANSPORT_PROTOCOL_TCP_SERVER = 0x03,
+ STK_TRANSPORT_PROTOCOL_UDP_CLIENT_LOCAL = 0x04,
+ STK_TRANSPORT_PROTOCOL_TCP_CLIENT_LOCAL = 0x05,
+ STK_TRANSPORT_PROTOCOL_DIRECT = 0x06,
+};
+
/* For data object that only has a byte array with undetermined length */
struct stk_common_byte_array {
unsigned char *array;
@@ -849,16 +888,20 @@ struct stk_timing_advance {
unsigned char advance;
};
-/*
- * According to 102.223 Section 8.52 the length of CTLV is 1 byte. This means
- * that the maximum size is 127 according to the rules of CTLVs. This size also
- * includes bearer type for 1 byte, so the maxmimum size of bearer parameters
- * is 126.
- */
+/* Bearer parameters for GPRS/UTRAN Packet Service/E-UTRAN */
+struct stk_gprs_bearer_parameters {
+ unsigned char precedence;
+ unsigned char delay;
+ unsigned char reliability;
+ unsigned char peak;
+ unsigned char mean;
+ unsigned char pdp_type;
+};
+
+/* Defined in TS 31.111 Section 8.52 */
struct stk_bearer_description {
- unsigned char type;
- unsigned char pars[126];
- unsigned int len;
+ enum stk_bearer_type type;
+ struct stk_gprs_bearer_parameters gprs;
};
/*
@@ -885,7 +928,7 @@ struct stk_other_address {
/* Defined in TS 102.223 Section 8.59 */
struct stk_uicc_te_interface {
- unsigned char protocol;
+ enum stk_transport_protocol_type protocol;
unsigned short port;
};
@@ -950,15 +993,6 @@ struct stk_remote_entity_address {
};
/*
- * According to 102.223 Section 8.70 the length of CTLV is 1 byte. This means
- * that the maximum size is 127 according to the rules of CTLVs.
- */
-struct stk_network_access_name {
- unsigned char name[127];
- unsigned char len;
-};
-
-/*
* According to 102.223 Section 8.72 the length of text attribute CTLV is 1
* byte. This means that the maximum size is 127 according to the rules
* of CTLVs. Empty attribute options will have len of 0.
@@ -1250,6 +1284,21 @@ struct stk_command_launch_browser {
char *text_passwd;
};
+struct stk_command_open_channel {
+ char *alpha_id;
+ struct stk_icon_id icon_id;
+ struct stk_bearer_description bearer_desc;
+ unsigned short buf_size;
+ char *apn;
+ struct stk_other_address local_addr;
+ char *text_usr;
+ char *text_passwd;
+ struct stk_uicc_te_interface uti;
+ struct stk_other_address data_dest_addr;
+ struct stk_text_attribute text_attr;
+ struct stk_frame_id frame_id;
+};
+
struct stk_command_close_channel {
char *alpha_id;
struct stk_icon_id icon_id;
@@ -1368,6 +1417,7 @@ struct stk_command {
struct stk_command_send_dtmf send_dtmf;
struct stk_command_language_notification language_notification;
struct stk_command_launch_browser launch_browser;
+ struct stk_command_open_channel open_channel;
struct stk_command_close_channel close_channel;
struct stk_command_receive_data receive_data;
struct stk_command_send_data send_data;
@@ -1406,6 +1456,19 @@ struct stk_ussd_text {
int len;
};
+struct stk_channel {
+ unsigned char id;
+ enum stk_channel_status status;
+};
+
+struct stk_channel_data {
+ struct stk_common_byte_array data;
+ union {
+ unsigned short rx_remaining;
+ unsigned short tx_avail;
+ };
+};
+
struct stk_response_get_inkey {
struct stk_answer_text text;
struct stk_duration duration;
@@ -1481,6 +1544,25 @@ struct stk_response_send_ussd {
struct stk_ussd_text text;
};
+struct stk_response_open_channel {
+ struct stk_channel channel;
+ struct stk_bearer_description bearer_desc;
+ unsigned short buf_size;
+};
+
+struct stk_response_receive_data {
+ struct stk_common_byte_array rx_data;
+ unsigned char rx_remaining;
+};
+
+struct stk_response_send_data {
+ unsigned char tx_avail;
+};
+
+struct stk_response_channel_status {
+ struct stk_channel channel;
+};
+
struct stk_response {
unsigned char number;
unsigned char type;
@@ -1511,6 +1593,10 @@ struct stk_response {
struct stk_response_generic language_notification;
struct stk_response_generic launch_browser;
struct stk_response_send_ussd send_ussd;
+ struct stk_response_open_channel open_channel;
+ struct stk_response_receive_data receive_data;
+ struct stk_response_send_data send_data;
+ struct stk_response_channel_status channel_status;
};
void (*destructor)(struct stk_response *response);
@@ -1596,11 +1682,11 @@ struct stk_envelope_event_download {
enum stk_browser_termination_cause cause;
} browser_termination;
struct {
- unsigned char channel_status[2];
+ struct stk_channel channel;
unsigned int channel_data_len;
} data_available;
struct {
- unsigned char status[2];
+ struct stk_channel channel;
struct stk_bearer_description bearer_desc;
struct stk_other_address address;
} channel_status;
--
1.7.1
9 years, 9 months
isimodem: remove atoms that fail to probe
by Mika Liljeberg
Hi,
Here's a patch to immediately free any atoms that failed
to probe.
Br,
MikaL
[PATCH 1/1] isimodem: remove atoms that fail to probe
drivers/isimodem/audio-settings.c | 4 +++-
drivers/isimodem/call-barring.c | 4 +++-
drivers/isimodem/call-forwarding.c | 4 +++-
drivers/isimodem/call-settings.c | 4 +++-
drivers/isimodem/cbs.c | 5 ++++-
drivers/isimodem/devinfo.c | 4 +++-
drivers/isimodem/gprs-context.c | 6 ++++--
drivers/isimodem/gprs.c | 1 +
drivers/isimodem/network-registration.c | 7 +++----
drivers/isimodem/phonebook.c | 4 +++-
drivers/isimodem/radio-settings.c | 4 +++-
drivers/isimodem/sim.c | 1 +
drivers/isimodem/sms.c | 5 ++++-
drivers/isimodem/ussd.c | 4 +++-
drivers/isimodem/voicecall.c | 4 +++-
15 files changed, 44 insertions(+), 17 deletions(-)
9 years, 9 months