Related
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...
Ok, when I'm in my office I have poor signal issues that drain my battery and miss calls. If I switch to Roaming Only in my phone settings, then everything is just peachy. Problem is, its a lot of menus to click through every single time I come in to my office (Start, settings, phone, services, roaming, get settings, roaming only).
And then when I'm leaving, I want to turn the romaing settings back to automatic, once again its a lot of clicking.
I would imagine it would not be too difficult to write an app that could toggle that setting. Then it could be one click, or someone could even map the app to a hardware button for the ultimate ease of use.
I'm sure there are others who can see how useful such an app would be. Many of us do something like this all the time.
So, what do you think? Anyone willing to help develop this?
Sounds like a do-able program that would be very useful even for people not in your situation. Of course, I don't know how to, I'm just endorsing this idea.
In for this
GREAT!
Now, who can actually help figuring out how to code this? Can that sort of data even be accessed from standard APIs?
MortScript
Ok folks, until I have the time to find out what actually goes on behind the scenes when roaming settings are changed, I think our best bet is to write a script of keypresses/mouseclicks using mortscript.
Mortscript, in case you didn't know, is a simple batch process program, which lets you assign a series of commands to a script, sort of like a macro.
This will essentially be a script to go through the menus and click through options to do what we would do by hand. It will speed things up a bit, but it won't be as simple as a standalone app.
playing with mortscript now, I'll keep you guys posted.
EDIT: Anyone who wants to take a crack at this as well, by all means, mortscript is free! I'm just learning how to use it now, but if anyone has any experience with it, hit me up with suggestions! Or better yet, write a script and show me how it works!
Can anyone tell me what registry changes are made when you switch from roaming to automatic?
I can't seem to compare registry backups taken with PHM RegEdit (some propietary format, and no export to text option!)
Mortscript to the rescue....
This is still not the most ideal solution, but it works for me.
I wrote two Mortscript scripts that simulate the key taps automatically. The downside to this is that you can't toggle it on/off, you need to run one program to force roam, and another one to put it back to automatic.
USE THESE AT YOUR OWN RISK!
If you have any bugs/questions/comments, let me know.
Requirements
MortScript:
You need to install the mortscript interpreter first.
http://www.sto-helit.de/downloads/mortscript/MortScript-4.0.zip
The zip file attached below contains two .mscr files:
Roam
Roam-NO
Pretty self explanatory what does what. You can rename them if you want, this just works for me.
Dishe said:
I wrote two Mortscript scripts that simulate the key taps automatically. The downside to this is that you can't toggle it on/off, you need to run one program to force roam, and another one to put it back to automatic.
Click to expand...
Click to collapse
If you wanted to, you could write a temp file or reg key to check if the setting is on or off. In fact, the file wouldn't even need any data in it, you could just check for it's existence. That way you only need one script. Hope that helps you out.
I havent been able to find (or pull) the ril.dll file from a Mogul Wm6 installation, but once you have that file, you should be able to dump the exports and use the RIL_* functions by ordinal. This has been done on GSM phones.
I haven't had time yet, but I believe someone has dumped the files from the newest update rom.
Dishe,
I took your script and applied my suggestion to it. I also wrapped it up in a standalone package, so if anyone else wants to run it, they won't need MortScript installed as the exe is in here. If you already have MortScript installed, you can just run the .mscr file instead of the .exe of the same name.
What it will do is run the prog, then check for the existence of the file "roam" in the script path. If it's not there, it will run your roam function and then create the file. If it already exists (meaning you turned on roaming only), then it run your function to turn off roaming and delete the temp file. Hope it helps you out.
EDIT: If for some reason the key presses do the wrong thing, you can just set your phone back to automatic and delete the "roam" file in the script path if it's there, then you're back in business.
EDIT2: Added a longer wait time (5 secs) for the Comm Manager, should allow it to work with more graphic intensive Comm Managers (like the Kaiser 10-button, tested).
Vinny75 said:
I havent been able to find (or pull) the ril.dll file from a Mogul Wm6 installation, but once you have that file, you should be able to dump the exports and use the RIL_* functions by ordinal. This has been done on GSM phones.
I haven't had time yet, but I believe someone has dumped the files from the newest update rom.
Click to expand...
Click to collapse
I know, qouting myself, but.. you don't need the ordinal, you can get the function by name from the dll, so far I am able to use RIL_Initialize and RIL_GetRoamingMode to call my pfResultCallback, but the value I am getting in reutrn isn't making sense, so have to figure that out. I am using a modified tstril util. I can post the changes if anyone wants to take a look.
Got the following for RIL_GetRoaming Mode
Mode Value
Sprint Only 0x00000001
Automatic 0x000000FF
Roaming Only 0x000000FE
Now using RIL_SetRoamingMode, I can set the Sprint Only mode, the other two throw a 0x80004005 HRESULT, I can use 0x00000002 and 0x0000003 (constants defined if you search the internet), and they don't throw an error, but they dont actually change any settings...
You can get tstril from here:
http://wiki.xda-developers.com/index.php?pagename=RIL
Expanded ril.h (not sure how accurate):
http://www.xs4all.nl/~itsme/projects/xda/ril/ril.h
Replace the DoRIL function in tstril.cpp with this code to test:
Code:
typedef HRESULT (*pfnRIL_Initialize)(DWORD, RILRESULTCALLBACK, RILNOTIFYCALLBACK, DWORD, DWORD, HRIL*);
typedef HRESULT (*pfnRIL_GetRoamingMode)(HRIL);
typedef HRESULT (*pfnRIL_SetRoamingMode)(HRIL, DWORD);
//HRIL g_hRIL;
HINSTANCE g_hDLL;
HRESULT g_hResult;
DWORD
DoRIL(LPVOID lpvoid)
{
HRESULT result;
DWORD dwNotificationClasses = 0xFF0000;
LRESULT lresult;
TCHAR szString[256];
SendMessage(g_hwndEdit, LB_RESETCONTENT, 0, 0);
lresult = SendMessage(g_hwndEdit, LB_GETHORIZONTALEXTENT, 0, 0);
SendMessage(g_hwndEdit, LB_SETHORIZONTALEXTENT, 1000, 0);
//result = RIL_Initialize(1, ResultCallback, NotifyCallback,
// dwNotificationClasses, g_dwParam, &g_hRil);
//wsprintf(szString, L"RIL Handle: %08X, result %08X", g_hRil, result);
//SendMessage(g_hwndEdit, LB_ADDSTRING, 0, (LPARAM) szString);
g_hRil = NULL;
g_hDLL = LoadLibrary(L"ril.dll");
//HRESULT hResult = 0;
if (g_hDLL != NULL)
{
pfnRIL_Initialize lpfnRIL_Initialize = (pfnRIL_Initialize)GetProcAddress(g_hDLL, L"RIL_Initialize");
if (lpfnRIL_Initialize)
{
result = (lpfnRIL_Initialize)(1, ResultCallback, NULL /*NotifyCallback*/, 0 /*dwNotificationClasses*/, 0 /*g_dwParam*/, &g_hRil);
if (result == S_OK)
{
wsprintf(szString, L"Initialize RIL Handle: %08X, result %08X", g_hRil, result);
SendMessage(g_hwndEdit, LB_ADDSTRING, 0, (LPARAM) szString);
pfnRIL_GetRoamingMode lpfnRIL_GetRoamingMode = (pfnRIL_GetRoamingMode)GetProcAddress(g_hDLL, L"RIL_GetRoamingMode");
if (lpfnRIL_GetRoamingMode)
{
g_hResult = (lpfnRIL_GetRoamingMode)(g_hRil);
wsprintf(szString, L"GetRoamingMode RIL Handle: %08X, g_hResult %08X", g_hRil, g_hResult);
SendMessage(g_hwndEdit, LB_ADDSTRING, 0, (LPARAM) szString);
}
//pfnRIL_SetRoamingMode lpfnRIL_SetRoamingMode = (pfnRIL_SetRoamingMode)GetProcAddress(g_hDLL, L"RIL_SetRoamingMode");
//if (lpfnRIL_SetRoamingMode)
//{
// g_hResult = (lpfnRIL_SetRoamingMode)(g_hRil, 254);
// wsprintf(szString, L"SetRoamingMode RIL Handle: %08X, g_hResult %08X", g_hRil, g_hResult);
// SendMessage(g_hwndEdit, LB_ADDSTRING, 0, (LPARAM) szString);
//}
}
}
//FreeLibrary(g_hDLL);
}
// while(1) {
// Sleep(100);
//// wsprintf(szString, L"%s",L"...");
//// SendMessage(g_hwndEdit, LB_ADDSTRING, 0, (LPARAM) szString);
// }
return 0;
}
Thanks for the work on those Mort Scripts!
Thank you!
wow, I haven't checked this thread in a while...
Vinny75, I haven't had time to play with this, but it looks like you've been making some progress... how far have you gotten with this?
The following values you should work for the second parameter of the RIL_GetRoamingMode and RIL_SetRoamingMode functions... they appeared to work on my phone
Mode RIL_GetRoamingMode RIL_SetRoamingMode
Sprint Only 0x00000001 0x00000001
Automatic 0x000000FF 0x00000004
Roaming Only 0x000000FE 0x00000005
I found the RIL_SetRoamingMode value in the following Registry Key
[HKEY_LOCAL_MACHINE\SOFTWARE\OEM\PhoneSetting\NetworkService]
Vinny75 said:
The following values you should work for the second parameter of the RIL_GetRoamingMode and RIL_SetRoamingMode functions... they appeared to work on my phone
Mode RIL_GetRoamingMode RIL_SetRoamingMode
Sprint Only 0x00000001 0x00000001
Automatic 0x000000FF 0x00000004
Roaming Only 0x000000FE 0x00000005
I found the RIL_SetRoamingMode value in the following Registry Key
[HKEY_LOCAL_MACHINE\SOFTWARE\OEM\PhoneSetting\NetworkService]
Click to expand...
Click to collapse
So would editing the registry be sufficient to change the roaming mode of the phone?
Did you compile an app to do this?
slightly off topic, but i think vinny75 might know the answer. id like to modify my alltel-based rom to give sprint only, automatic, roaming only options (alltel gives home only and automatic.) is ril.dll all that is needed from the sprint rom?
Dishe said:
So would editing the registry be sufficient to change the roaming mode of the phone?
Did you compile an app to do this?
Click to expand...
Click to collapse
I just compiled a quick and dirty app to test the values... the source is in my previous posts
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.
Hello all! I'm somewhat new to Android development, I'm using eclipse to do all of my development. Right now I am working on an "away message text" application. I am having trouble with database query returning a string of the first index of data. Here is my code where i am trying to pull data from the database. This is being done inside my ReceiveText class, which extends BroadcastReceiver.
mDbHelper = new TextsDbAdapter(context);
mDbHelper.open();
getText = mDbHelper.fetchText(0);
message = getText.getString(getText.getColumnIndex(mDbHelper.KEY_BODY)).toString();
The error that I am getting is Cursor index out of bounds...any recommendations? Thanks!
you always start out of bounds.... you have to moveToFirst() first...
Thanks. Would I moveToFirst() before I fetchText()?
you're probably going to have to change how the fetchText method is implemented.
you'll probably want something like
Code:
public String fetchText(int id){
Cursor c = getContentResolver().query( uri,
new String[] { <name_of_text_column> } ,
"_id == " + id, null, null);
String text = null;
if( c != null ){
if( c.moveToFirst() ){
text = c.getString( c.getColumnIndex( <name_of_text_column> ) );
}
c.close();
}
return text;
}
Thanks. The method I have for fetchText returns a Cursor, however I made another method that returns a string, similar to what you recommended. For some reason, there is something wrong with the rowid sending in, I want to just get the first one, if I'm not mistaken, wouldn't it be 0? I have a seperate ReceiveText.java class, which extends Broadcast Receiver. The part where the messages are stored into the database is very similar to androids notepad demo. When a text is received, I want the ReceiveText class to query the database and just pull the first text that was actually stored into the database. I have 3 columns, KEY_ROWID, KEY_TITLE, and KEY_BODY. For some reason there is an issue when trying to query the database from the ReceiveText class. Any ideas that would make better sense or be easier to implement? Any help is much appreciated.
oh, right. I wasn't paying attention and for some reason I thought it was returning a string. I see now that it's obviously a cursor..
what you are doing sounds fine but you sure really look at the database on the phone/emulator.
open up adb and type
Code:
sqlite3 /data/data/<name_of_app>/databases/<name_of_db>
then you can do
Code:
select * from <name_of_table>
personally, I find it way easier to read if you change the mode with a ".mode line" command(the dot is important).
that should give you a good idea of why it is not working properly.
How do I open up the adb? I looked online, and it says i can run it through command line, or terminal since I use ubuntu, but I'm not sure exactly how to open it. Apologies for my noobness with android development i'm trying to learn!
if you're running it on a phone/tablet, you'll have to set up the adb drivers
but if you're just using the emulator, you're fine
Code:
cd /<path_to_sdk>/platform-tools/
./adb devices ##this should list the device. if not you have a problem.
./adb shell
and now you can execute commands on the device, like sqlite3
Awesome, I got that to work, and i can see the three "texts" that i've added to the database...looks like this...
1|Sleeping|Sleeping...text you when I wake up.
2|Driving|Driving right now...text you when I'm done.
3|Xbox|Playing xbox...text you later.
So this means that my database works. The numbers 1,2, and 3 are the KEY_ROWID, sleeping, driving, and xbox are the KEY_TITLE, and the third part is the KEY_BODY.
For some reason the ReceiveText class is having trouble pulling this information from the database, I really think it has something to do with when i Query the database, it asks for a columnindex, and i am putting a 0 as the parameter. Any ideas? Thanks again for all your help. It's a great learning process.
yeah, there doesn't seem to be a column with _id == 0
that is strange. when you defined it did you use "integer primary key autoincrement"? This should start at 0, I believe.. maybe you deleted your first entry at some point?
try it with 1 and see if that works.
Man, thanks so much for your help...it works! Here is how I did it from the ReceiveText class.
mDbHelper = new TextsDbAdapter(context);
mDbHelper.open();
getText = mDbHelper.fetchText(1);
message = getText.getString(2).toString();
getText is a Cursor type, and message is a String type.
I really appreciate the help, I understand a lot more now. My next step is to set the text to use without having to specify from the ReceiveText class...any suggestions? I was thinking adding another column in the database that would hold either a 1 or 0, and if it is selected, it updates the database and changes that field to a 1, then the ReceiveText class will query the database to return the field that has the 1...make sense? lol
Just to clear this up a bit for those still a little fuzzy:
Code:
Cursor c = db.query(TABLE_NAME3, new String[] {NAMESHORT, LAPTIME, LAPNUMBER}, null ,null, null, null, orderBy);
The column indexes are what you have in the "new String[]" area whether you have 1 or 50 items. So, NAMESHORT is index 0, LAPTIME is index 1 and LAPNUMPER is index 2. It's NOT the column number of where it is in the table
Just a personal preference of mine, but I code all this in the database methods and return what I need from there. Seeing hard-coded numbers in a program always bothers me. Instead of returning cursors I'll return a StringBuilder or ArrayList or whatever. Just sayn'
I'm a very accomplished coder when using interpreted languages, but this low-level memory management stuff is proving hard for me to get my head around.
I'm trying to work through the OpenGL ES sample code on the official developer site and I cannot understand why they create a ByteBuffer for the vertex list and then immediately turn around and create a FloatBuffer from the ByteBuffer. Why not just allocate and reference the FloatBuffer directly? Aren't there now two sets of data that basically refer to the same set of numbers? Here's the snippet to which I am directly referring (perhaps the reason lies elsewhere in the code, though?):
public class Triangle {
private FloatBuffer vertexBuffer;
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
static float triangleCoords[] = { // in counterclockwise order:
0.0f, 0.622008459f, 0.0f, // top
-0.5f, -0.311004243f, 0.0f, // bottom left
0.5f, -0.311004243f, 0.0f // bottom right
};
....
public Triangle() {
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
// (number of coordinate values * 4 bytes per float)
triangleCoords.length * 4);
// use the device hardware's native byte order
bb.order(ByteOrder.nativeOrder());
// create a floating point buffer from the ByteBuffer
vertexBuffer = bb.asFloatBuffer();
// add the coordinates to the FloatBuffer
vertexBuffer.put(triangleCoords);
// set the buffer to read the first coordinate
vertexBuffer.position(0);
}
}
It is basicallly due to the way Java uses data types. In the language of gods (C) we can just cast types and all is good.
What is happening there is a workaround basically.. machines have a word order (not sure if you have ever heard of the term back-words or byte ordering before) the ByteBuffer has a method which shuffles data to put it into the CPU byte order (ByteOrder.nativeOrder()) which can then be sent to the GPU.
Imagine the value 0xFFEE on an Intel CPU that would be stored as the 2 bytes 0xEE 0xFF or "backwards" if you will, it is called a Little endian CPU. An ARM CPU may store it is 0xFF 0xEE in memory as it is Big Endian
Since Java has it's own convention that it always uses, the ByteBuffer is there to provide a method to re-order it to whatever the CPU needs.
Hope my explanation is not more confusing! I am half-asleep and was just heading to bed :-S