Hi everybody,
I'm trying to comunicate with my SIM, which supports SIM application tookit, using the RIL API.
In order to do that I think I need:
- Send Command to the SIM (Envelope)
- Receive Response from the SIM (Fetch)
- Send Command Response to the SIM (Terminal Response)
At this moment I can do only the first two things.
I can send command using RIL_SendSimToolkitEnvelopeCmd function and using, as input, a well formed string as defined in the specification GSM 11.14; for example, in order to select the second item of the SIM Application Menu, I use this code:
BYTE envcmd[9];
envcmd[0] = 0xd3; // Menu selection tag
envcmd[1] = 0x07; // Length
envcmd[2] = 0x02; // Device Identity Tag
envcmd[3] = 0x02; // Device Identity length
envcmd[4] = 0x82; // Source: ME
envcmd[5] = 0x81; // Destination: SIM
envcmd[6] = 0x10; // Item Identifier tag
envcmd[7] = 0x01; // Item Identifier length
envcmd[8] = 0x02; // Item chosen
hres = RIL_SendSimToolkitEnvelopeCmd(m_hRil, envcmd, 9);
The response for this command is trapped in the notify handler (second thing I can do).
After the notification I need to send a Command Response to the SIM and to do that I think I need to use RIL_SendSimToolkitCmdResponse using, as input parameter, a well formed string as specified in the GSM 11.14; something like this:
// Response for DISPLAY TEXT
response[0x00] = 0x81;
response[0x01] = 0x03;
response[0x02] = 0x01;
response[0x03] = 0x21;
response[0x04] = 0x81;
response[0x05] = 0x02;
response[0x06] = 0x02;
response[0x07] = 0x82;
response[0x08] = 0x81;
response[0x09] = 0x03;
response[0x0a] = 0x01;
response[0x0b] = 0x00;
hres = RIL_SendSimToolkitCmdResponse(m_hRil, response, 12);
But the result (hres) is always 0x80070057 (E_INVALIDARG).
Could anyone help me?
Thanks in advance.
Sektor
P.S.: please note that the response I send is the same as that I sniffed using a Season logger which can intercept all traffic between SIM and PDA.
Although I can't help, I've got a question: Once you're finished - could this then be used to implement Bluetooth SIM Access Profile?
No.
In order to implement SAP, we need a "flat" access to the SIM and to do that the radio module has to export a commad like AT+CSIM (GSM 07.07).
If the radio module implements that command, using the RIL_SendSimCmd we can send all possible commands to the SIM and so we could develope a SAP layer.
Unfortunally, as I know, there is no radio module that permits a complete access to the SIM.
Before to take the SAT street I tryed to use SendSimCmd on my JasJar but the reult was always E_NOTIMPL.
Bye
Sektor
SendSimCmd is implemented on the Wizard, at least (I'm using it ) - but it'll only be useful if you want to access a specific application on the card (if you're trying to talk to the GSM application on channel 0 you're out of luck)
Regarding SendSimToolkitEnvelopeCmd I've got mixed results according to the devices - working on some, and failing on others with this return code, and do not know why, yet. But here since you're failling on the SendSimToolkitCmdResponse, that seems different. Even if I never used this function before (I always let the handset provide its own Terminal Reponse) I think it's badly formatted. The response to a Display Text should only include a General Result (0x03 0x01 0x00).
What do you mean when you say "...to access a specific application on the card"?
What kind of PDU are you able to send to the SIM? And how can you specify which channel you want to open?
BTW, in order to implement SAP, we need to access to channel 0 for sending GSM commands.
Regarding RIL_SendSimToolkitCmdResponse, I tryed also to send General Result (0x03 0x01 0x00), as you suggested, but with no luck.
I think SendSimToolkitCmdResponse wants a specific struct as input parameter (something like specified in this document http://www.intrinsyc.com/whitepapers/RIL_whitepaper_MS_Intrinsyc_June2004.pdf).
I tryed with the struct specified in that document and the resut is changed: 0x8007000e (E_OUTOFMEMORY) :-(
Any ideas?
I have a JasJar with WM 5.0.
Bye
Sektor
What do you mean when you say "...to access a specific application on the card"?
Click to expand...
Click to collapse
I mean access a SIM card application located by its AID
What kind of PDU are you able to send to the SIM? And how can you specify which channel you want to open?
Click to expand...
Click to collapse
Basically you'll need to open a channel to your application with an ISO 7816-4 Open Channel command, then you are in your own world
BTW, in order to implement SAP, we need to access to channel 0 for sending GSM commands.
Click to expand...
Click to collapse
OK, then it's going to be difficult I think. Unless you have a 3G card and a multi-selectable USIM application that you could select on another channel to send your APDUs, but I don't know if this is supported by any card (never tested it).
Any ideas?
Click to expand...
Click to collapse
I did a small project some years ago that can be used to install a dummy driver that'll record everything. I think you can use it for RIL and try to dump the structure that's sent to understand it better (and publish the results here )
http://arisme.free.fr/hacks/binaries/XBridge.zip
Arisme, your application is very cool
With your driver I can see all traffic between RIL.dll and rilgsm.dll and so I can see the commands sent by STK_Service.dll (SIM Application Toolkit layer in the JasJar) to the rilgsm.dll via ril.dll.
The structure used by the RIL.dll to communicate with rilgsm.dll in the function RIL_SendSimToolkitCmdResponse is:
typedef struct rilsimtoolkitrsp_tag
{
DWORD cbSize; // Structure and text size in bytes
DWORD dwParams; // Indicates valid parameters
DWORD dwId; // ID number of command
DWORD dwTag; // Command tag (with comprehension bit)
DWORD dwType; // Type of command (DISPLAY TEXT, etc.)
DWORD dwQualifier; // Command details qualifier
DWORD dwResponse; // Command result from SIM toolkit layer
DWORD dwAdditionalInfo; // Additional command result information.
} RILSIMTOOLKITRSP;
as defined in the document linked in my previous post.
I used the same structure as parameter for RIL_SendSimToolkitCmdResponse, but the question is: is it correct?
That structure is used between RIL.dll and rilgsm.dll and not between my application and RIL.dll.
BTW I tryed to fill the fields with the info logged with your driver and the result is always the same: 0x8007000e (E_OUTOFMEMORY).
I think I need to intercept the call that STK_Service.dll makes to RIL.dll.
Now I'll try to bypass RIL.dll using RIL1: device and DeviceIoControl.
Bye
Sektor
Did you check if the info passed in the IOControl associated to this RIL function (you'll have to find which one it is first ) logged by the bridge matches this structure ?
Yes, I did and the structure matches the info logged.
But I am not sure that the same structure can be used from my application.
When I use that structure as parameter for RIL_SendSimToolkitCmdResponse the response is always bad, as I said.
But I have good news: using RIL1: device and DeviceIoControl I can send a command response; here the code.
#define RIL_SEND_STK_ENVELOPE_RESPONSE 0x300018CL
RILSIMTOOLKITRSP rsp;
memset(&rsp, sizeof(RILSIMTOOLKITRSP), 0);
rsp.cbSize = 0x20;
rsp.dwParams = 0x1f;
rsp.dwId = 0x01;
rsp.dwTag = 0x81;
rsp.dwType = 0x21;
rsp.dwQualifier = 0x81;
rsp.dwResponse = 0x00;
rsp.dwAdditionalInfo = 0x00;
BYTE *b = (BYTE *)&rsp;
int s = rsp.cbSize;
DWORD rildevresult = 0;
DWORD nReturned = 0;
HANDLE m_hRilDev= CreateFile(L"RIL1:", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
if (!DeviceIoControl(m_hRilDev, RIL_SEND_STK_ENVELOPE_RESPONSE, b, s, &rildevresult, sizeof(rildevresult), &nReturned,0))
{
rildevresult = GetLastError();
debug("Error: %08lx\n", rildevresult);
}
debug("DeviceIoControl(RIL_SEND_STK_ENVELOPE_RESPONSE): %08lx\n", rildevresult);
BTW I prefer to find the correct structure for RIL_SendSimToolkitCmdResponse.
Bye.
Sektor
that's a good step forward already 8)
I found the solution
The function prototype in the ril.h is NOT correct!
In ril.h RIL_SendSimToolkitCmdResponse is defined as:
HRESULT RIL_SendSimToolkitCmdResponse(HRIL hRil,const BYTE* lpbResponse, DWORD dwSize);
The correct definition for my ril.dll is:
HRESULT RIL_SendSimToolkitCmdResponse(HRIL hRil, const RILSIMTOOLKITRSP* pRsp, const LPBYTE pDetails, DWORD dwDetailsSize);
where RILSIMTOOLKITRSP is
typedef struct rilsimtoolkitrsp_tag
{
DWORD cbSize; // Structure and text size in bytes
DWORD dwParams; // Indicates valid parameters
DWORD dwId; // ID number of command
DWORD dwTag; // Command tag (with comprehension bit)
DWORD dwType; // Type of command (DISPLAY TEXT, etc.)
DWORD dwQualifier; // Command details qualifier
DWORD dwResponse; // Command result from SIM toolkit layer
DWORD dwAdditionalInfo; // Additional command result information.
} RILSIMTOOLKITRSP;
and pDetails is a buffer with the data needed to complete the response, e.g.:
BYTE details[3];
details[0] = 0x90;
details[1] = 0x01;
details[2] = 0x0b;
in order to select the item "0x0b" in response to a "select item" proactive command, or
BYTE details[14];
details[0] = 0x8d;
details[1] = 0x0c;
details[2] = 0x04;
details[3] = 0x74;
details[4] = 0x65;
details[5] = 0x6c;
details[6] = 0x65;
details[7] = 0x76;
details[8] = 0x69;
details[9] = 0x73;
details[10] = 0x69;
details[11] = 0x6f;
details[12] = 0x6e;
details[13] = 0x65;
in order to give an input data ("televisione" in this example) in response to a "get input" proactive command.
I don't know if the parameters for that function depend on the ril version, however I give you the details about my device:
I-Mate JasJar
ROM: 1.13.46 ITA (09/23/05)
Radio: 1.03.01
Protocol: 42.36.P8
ExtRom: 1.13.126 ITA
Windows Mobile 5.0
Bye
Sektor
Thanks, good to know 8)
Many thanks for this topic, it was my guide to RIL_STK programming. I've spent some time developing automatic Multi-SIM switcher application, and would like to share some information (ohh, I'm ETEN M600 owner, so this info could be wrong for other devices).
1. In my case RIL_SendSimToolkitCmdResponse takes DWORD details data, not the BYTE one Sector described in previous post. Information it should contain also differs, it looks like regular RIL structure, not like the GSM standart described Terminal Response. Example of SelectItem response data:
DWORD details[3];
details[0] = sizeof(details);
details[1] = 0x01;
details[2] = selectedItem;
2. The only documentation about RIL structures I had was the Sector links to some PDF's describing RILSIMTOOLKITRSP and RILSIMTOOLKITCMD. I needed however to decode incoming notifications, so I've reversed structures coming from SIM in SelectItem case (lpData points to RILSIMTOOLKITCMD, +dwDetailsOffset you get RILSIMTOOLKITSELECTITEM, +dwOffsetAlpha = menu caption, at +dwOffsetItems you could get dwNumItems looking like RILSIMTOOLKITITEMDESC:
typedef struct rilsimtoolkitselectitem_tag
{
DWORD cbSize;
DWORD dwNull0;
DWORD dwNull1;
DWORD dwNull2;
DWORD dwSizeAlpha;
DWORD dwOffsetAlpha;
DWORD dwNumItems;
DWORD dwSizeItems;
DWORD dwOffsetItems;
} RILSIMTOOLKITSELECTITEM;
typedef struct rilsimtoolkititemdesc_tag
{
DWORD cbSize;
DWORD dwNull0;
DWORD dwItemID;
DWORD dwNull1;
DWORD dwNull2;
DWORD dwSizeAlpha;
DWORD dwOffsetAlpha;
} RILSIMTOOLKITITEMDESC;
3. In overal it seems RIL of my M600 encodes all commands and notifications to such structures and requires similar structures for STK commands, altrough that is not obvious while reading this topic and available documentation.
wbr, Nik.
P.S. ETEN M600, fw 216.
P.P.S. Sorry for interferring with not HTC-clone device, just couldn't found another such usefull WM developers forum.
Hi,
I'm a newbie to the RIL API.
So, first of all, thx to all of you for giving me good info on this in your discussions.
I'm having no success with the RIL_SendSimToolkitEnvelopeCmd function.
Just for testing, I'm sending the same test command as above:
BYTE envcmd[9];
envcmd[0] = 0xd3; // Menu selection tag
envcmd[1] = 0x07; // Length
envcmd[2] = 0x02; // Device Identity Tag
envcmd[3] = 0x02; // Device Identity length
envcmd[4] = 0x82; // Source: ME
envcmd[5] = 0x81; // Destination: SIM
envcmd[6] = 0x10; // Item Identifier tag
envcmd[7] = 0x01; // Item Identifier length
envcmd[8] = 0x02; // Item chosen
hres = RIL_SendSimToolkitEnvelopeCmd(m_hRil, envcmd, 9);
In the result callback, I'm getting dwCode == RIL_RESULT_ERROR and lpData points to E_FAIL (0x80004005).
Now, I've enabled logging and my celog shows that the RIL driver is getting the folowing command.
0:02:47.449.538 : DEBUGMSG: PID:0x805d8dc0 TID:0x834a576c [RETAIL]RilDrv: Sending cmd: AT+SATE=0,D30702028281100102
The response is also shown as:
0:02:47.484.606 : DEBUGMSG: PID:0x805d8dc0 TID:0x8349d974 [RETAIL]RilDrv: Accumulated response: +SATE: 0F00006F008169B4ECAA19CDF41D6A35C8<cr><lf>
I was expecting to recieve the response "6F00" in the result callback.
Any ideas?
If you can give me any other command to test the envelope command, that would help.
Thanks,
-R.
Arisme said:
I mean access a SIM card application located by its AID
Basically you'll need to open a channel to your application with an ISO 7816-4 Open Channel command, then you are in your own world
OK, then it's going to be difficult I think. Unless you have a 3G card and a multi-selectable USIM application that you could select on another channel to send your APDUs, but I don't know if this is supported by any card (never tested it).
I did a small project some years ago that can be used to install a dummy driver that'll record everything. I think you can use it for RIL and try to dump the structure that's sent to understand it better (and publish the results here )
Click to expand...
Click to collapse
Hi:
I've been researching in XDA forums with no success so far. A few days ago I found this thread that you participated in a long time ago. Actually, my problem is I don't know how to access in Windows Mobile an applet application located by means of its AID... I've tried to send selection command:
Code:
00 A4 04 04 10 D2760001180002FF34004F8908010D09
thorugh RIL_SendSimCmd, but it didn't work (response=0x01 0x05 0x00 0x81).
Would you, please, give me a hand? I'm absolutely lost and desperated.
Thanks in advance...
I found the solution:
We must use logic channels. 0 Channel is reserved for GSM/USIM, other channel, usually #1, is used for applets.
APDU's sequence is:
Manage Channel (Open)
00 70 00 00 01
Respose
0x 90 00 (Where "x" indicates the logic channel assigned by the smartcard. Usually the respose is "01 90 00", being "01" channel number one).
Select Local APP
0x A4 04 04 10 <AID> (Substitute "x" for channel number assigned in Manage Channel (Open) command response ("1" in the case of our example).
Response
90 00
COMMAND INVOCATION
From now on if we want to send commands to the app, we just have to indicate the channel in CLASS byte (i.e. "9x" being "x=1", hence 91[INS][...])
Manage Channel (Close)
00 70 80 0x 00, where "0x" indicates the channel number we want to close. ("1" in our example).
Thanks anyway...
Hi,
I have a problem running a Direct3D app on full screen on a HTC Diamond: no matter which way I create the Direct3D device, by making a window that covers the full screen, or by creating a fullscreen device, all I see is the background of the window. Nothing rendered in Direct3D is shown.
If I use a window that is, for example, one pixel shorter than the full screen - everything works fine, but "real" full screen doesn't.
The Direct3D examples from the WM6 SDK, which also create a full screen window, fail exactly the same way both on my phone and on another Diamond I've tested, so I assume it's not a problem with my configuration or ROM, but a common one. Also I've found a few similar questions on other forums, mentioning phones like the Touch Pro, but no answers.
To create a fullscreen window I do the following:
g_screenWidth = GetSystemMetrics(SM_CXSCREEN);
g_screenHeight = GetSystemMetrics(SM_CYSCREEN);
g_hWndMain = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
0, 0, g_screenWidth, g_screenHeight, NULL, NULL, hInstance, NULL);
SHFullScreen(g_hWndMain, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON);
/* ... */
D3DMPRESENT_PARAMETERS presentParameters;
memset(&presentParameters, 0, sizeof presentParameters);
presentParameters.SwapEffect = D3DMSWAPEFFECT_DISCARD;
presentParameters.Windowed = true;
HRESULT hr = g_d3d->CreateDevice(D3DMADAPTER_DEFAULT, D3DMDEVTYPE_DEFAULT, g_hWndMain, NULL,
&presentParameters, &g_dev);
All the functions succeed, however, nothing gets drawn on the screen besides the background of the window.
The same thing happens when I create a fullscreen device, like below:
// The same window creation stuff...
// ....
presentParameters.BackBufferWidth = g_screenWidth;
presentParameters.BackBufferHeight = g_screenHeight;
presentParameters.BackBufferFormat = D3DMFMT_UNKNOWN;
presentParameters.BackBufferCount = 1;
presentParameters.SwapEffect = D3DMSWAPEFFECT_DISCARD;
presentParameters.Windowed = false;
presentParameters.FullScreen_PresentationInterval = D3DMPRESENT_INTERVAL_DEFAULT;
HRESULT hr = g_d3d->CreateDevice(D3DMADAPTER_DEFAULT, D3DMDEVTYPE_DEFAULT, g_hWndMain, NULL,
&presentParameters, &g_dev);
Again, all the calls seem to succeed, but nothing is visible on the screen. I've tried setting the pixel format explicitly - still nothing is drawn.
But if I change the window in the first example to be one pixel less than the size of the screen, everything is displayed correctly.
Does anyone know why this is happening and whether some solutions for running the app full-screen are possible? As far as I understand, VSync is available only in fullscreen mode, so I'd like to get it working - although one missing line of pixels isn't really visible on the Diamond screen.
And yet another unrelated question: does the graphics chip in the Diamond support render-to-texture? It seems to be not available in Direct3D, but it might still be exposed in OpenGL ES in that case...
It has been a while since I wrote a program for the last time, and when I got my Desire I decided it would be a good moment to start again.
After a few very simple test programs I decided to go a little further and try to access the sensors.
With a little research I found out I had to use public static float[] getOrientation (float[] R, float[] values) . This is what I found in the documentation:
float[] android.hardware.SensorManager.getOrientation(float[] R, float[] values)
public static float[] getOrientation (float[] R, float[] values)
Since: API Level 3
Computes the device's orientation based on the rotation matrix.
When it returns, the array values is filled with the result:
values[0]: azimuth, rotation around the Z axis.
values[1]: pitch, rotation around the X axis.
values[2]: roll, rotation around the Y axis.
All three angles above are in radians and positive in the counter-clockwise direction.
Parameters
R rotation matrix see getRotationMatrix(float[], float[], float[], float[]).
values an array of 3 floats to hold the result.
Returns
The array values passed as argument.
Click to expand...
Click to collapse
I didn't understand the use of float[] R part, so I decided to just give null as argument
Code:
float[] values = new float[3];
SensorManager.getOrientation(null, values);
TextView xText = (TextView) findViewById(R.id.TextView02);
TextView yText = (TextView) findViewById(R.id.TextView03);
TextView zText = (TextView) findViewById(R.id.TextView04);
xText.setText(String.valueOf(values[0]));
yText.setText(String.valueOf(values[1]));
zText.setText(String.valueOf(values[2]));
But my program fails when it comes to the line where I call getOrientation, so my guess is I shouldn't give null as argument. How should I use getOrientation()?
I have a edit able text box that is next to a button lets say onclick of the button it will take the text from the editable text box and converted to an integer so it can be subracted by.. oh lets say 32 so my first method was this.
number = EText.getText();
textOutcome.setText(number - 32);
this gave me an error of
The operator - is undefined for the argument type(s) Editable, int
my second attempt was
textOutcome.setText((Integer.parseInt(EText.getText().toString()) - 32));
This gave me no errors and it ran fine untill i clicked the button which causes the command above to run. and it force closed my application.
Does any one have any ideas i can do, or any sample code?
Thanks,
Blue.
Bumping the topic.
Please can anyone help me with this..!
Have you tried stepping through the code with the debugger? Otherwise, the code you posted looks fine. There is probably something else at play here.
Basicall it force closes whea subtraction is made..
Sent from my Samsung Epic 4g.
Ahh the debugger found something early in the code thanks for the idea !
You have to do any mathematical arithmetic with the integer type, not with string, So when you extract the number from the EditText you have to convert the string into a integer, or whatever type of number it may be.
WHen you have the integer then you can apply the arithmetic.
when this is done you then have to convert the total into a string type again.
Hope this helps.
So basically im going to write a little of code off the top of my head which obviously can have errors. Since im not testing it.
EditText txbox = (EditText)findViewById(R.id.EditText01);
String txdata = txbox.getText().toString();
int txval = Integer.ParseInt(txdata);
//you should make sure that the value is an integer, if not i think //Integer.ParseInt() will just cut off the rest if its irrational.
//Now you can do arithmetic//
int b = 2;
int t;
t = txval - b;
//The total value is in variable t.
So lets convert this into a string and put it back into an object like edittext or textview
txbox.setText(String.valueOf(t));
//Thats all, hope that helps.