There are many posts on this forum and other Symbian developer forums about getting the location string as shown on the Phone application. So I set myself with
a mission to retrieve the location string [1].
So in this article we will see the following things:
Basics explained : What is a Cell,Cell Broadcast Message (CBM) and the GSM-CBM format?
Advanced telephony libraries?
Demo application.
Conclusion.
Basics explained : What is a Cell,Cell Broadcast Message (CBM) and the GSM-CBM format?
As I had studied Mobile Communications during my Engineering course so it was clear from
the start itself that the Cell Broadcast Message is passing on the location information. As some
of the developers had assumed that there is some Mapping table on the SIM is not correct.
But the contents sent inside the CBM would depend on the carrier in question. As I had read from a
online doc that in Germany a certain carrier used to send the coordinates of the location
which could then be mapped against a fixed table to get the location string. But in India
I have checked for two major carriers they send the location string. And that is the thing
we are hunting for, right.
Lets see some Mobile Communication basics:
A cell is a circular region at the center of which lies the base station to which
Mobile equipment connects to. A Cell can have a coverage radius from 0-70 km. This varies
from place to place.
Cell is usually hexagonal and its span depends totally on the number of users within
the cell span. More the users lesser the span and vice versa.
When ever a mobile enters a cell it registers itself with the Base station.
CBM are broadcast by the Base station to defined geographical areas called cell broadcast areas
and which may span more than one cell.
CBM can be used to convey useful information to all subscribers at the same time.
Okay enough of the theory lets finally see the GSM-CBM Format:
The CBM received is of 88 bytes and has the following structure:
Octet No.| Field
--------------------------
1-2 | Serial number
3-4 | Message identifier
5 | Data Coding Scheme
6 | Page parameter
7-88 | content of message
For our purpose we are ignoring the first 6 bytes as they do not serve out purpose.
So moving on, from byte 7 to byte 88 we have the message which is in GSM 7-bit alphabet
but coded in 8-bit format. So each seven bit is packed into a 8-bit byte as follows:
8 Original 7-bit message
b06 b05 b04 b03 b02 b01 b00
b16 b15 b14 b13 b12 b11 b10
b26 b25 b24 b23 b22 b21 b20
b36 b35 b34 b33 b32 b31 b30
b46 b45 b44 b43 b42 b41 b40
b56 b55 b54 b53 b52 b51 b50
b66 b65 b64 b63 b62 b61 b60
b76 b75 b74 b73 b72 b71 b70
Encoded(Packed) into 7 8-bit bytes as follows(| - marker not part of message) :
b10 | b06 b05 b04 b03 b02 b01 b00
b21 b20 | b16 b15 b14 b13 b12 b11
b32 b31 b30 | b26 b25 b24 b23 b22
b43 b42 b41 b40 | b36 b35 b34 b33
b54 b53 b52 b51 b50 | b46 b45 b44
b65 b64 b63 b62 b61 b60 | b56 b55
b76 b75 b74 b73 b72 b71 b70 | b66
So you need a proper decoder for this which converts the remaining 82 8- bits into ASCII 7-bit data.
Remember the decoding has to be done only for byte no 7 to 88, the first 6 bytes or octets are to be ignored.
Once decoded its contents are totally dependent on the carrier.The padding is done using ASCII CR (Carriage Return).
So all the valid data will be upto CR.
Advanced telephony libraries?
Now getting this location information in Symbian is not possible with the Public SDK. so some
great soul gave us the etelmm libraries which could be used to get such advanced information.
While there is no official documentation available it was left for me to scour the long headers
and make some sense out of them and then find the appropriate class that could give me the
required information.
I first tried to get the location information but to no avail , and then I noticed the RMobileBroadcastMessaging
class.
Having the information that we could get the location string from the Cell broadcast message I just had to test
if it was really present or not.
From here starts the complex code , but first the simple logic:
So first we need to make a RMobilePhone connection.
Wait for a CBM to be received .
Once you have the CBM just decode it and voila there you have the location string.
RTelServer iServer;
RMobilePhone iPhone;
RTelServer::TPhoneInfo iPhoneInfo;
TRequestStatus iReqStatus;
RMobileBroadcastMessaging iBroadcastMsg;
//GSM CBM's length is 88 bytes
TBuf8<88> iGsmMsgdata;
_LIT(KGsmModuleName, "phonetsy.tsy");
iServer.Connect();
iServer.LoadPhoneModule( KGsmModuleName );
TInt enumphone;
User::LeaveIfError(iServer.EnumeratePhones(enumphone));
if (enumphone < 1) {
User::Leave(KErrNotFound);
}
//Initialise the phone object
User::LeaveIfError(iServer.GetPhoneInfo(0, iPhoneInfo));
User::LeaveIfError(iPhone.Open(iServer, iPhoneInfo.iName));
iBroadcastMsg.Open(iPhone);
RMobileBroadcastMessaging::TMobileBroadcastAttributesV1 iAttrInfo;
TPckg<RMobileBroadcastMessaging::TMobileBroadcastAttributesV1> iDes(iAttrInfo);
//Wait for the CBM
iBroadcastMsg.ReceiveMessage(iReqStatus,iGsmMsgdata,iDes);
User::WaitForRequest(iReqStatus);
if(iReqStatus.Int()==KErrNone){//show the CBM retrieved
//first write the 88 bytes of CBm into a file
//I am doing this as I will be using C
//code to decode the data
RFs fs;
fs.Connect();
RFile file;
TBuf<32> aFileName = _L("C:\\log.txt");
fs.Delete(aFileName);
file.Replace(fs,aFileName,EFileWrite);
file.Write(iGsmMsgdata);
file.Close();
fs.Close();
//here starts the decoding code
//Credits : Vikram K.
FILE* fp;
fp = fopen("c:\\log.txt","rb");
char locationString[94];
char cbuf;
int char_cnt=0;
unsigned int bb = 0;
/*8-bit to 7-bit conversion*/
unsigned char ur,curr,prev = 0;
int cnt = 0;
for(cnt = 0;cnt <6;cnt++)
fread(&cbuf,1,1,fp);
while(fread(&cbuf,1,1,fp)){
unsigned char aa = (1 << (7 - bb%7)) - 1;
ur = cbuf & aa;
ur = (ur << (bb)) | prev;
curr = cbuf & (0xff ^ aa);
curr = curr >> (7 - bb);
prev = curr;
if(ur == 0xd)
{
break;
}
locationString[char_cnt] = ur;
bb = ++bb % 7;
char_cnt++;
if(bb==0)
{
locationString[char_cnt++] = prev;
prev =0;
}
}
locationString[char_cnt] = '\0';
fclose(fp);
//decoding ends here now just
//convert the C string to TBuf (Symbian format)
int len=0;
while(locationString[len] != NULL)
len++;
// Create empty descriptor
HBufC* nameHeap = HBufC::NewLC(len);
TPtr namePtr(nameHeap->Des());
// Copy contents
for(int i=0; i<len; i++)
namePtr.Append((TChar)locationString[i]);
//now you have the location string
//do whatever you want here..
// Pop descriptor from cleanup stack
CleanupStack::PopAndDestroy( nameHeap);
}
}
else{//panic
}
iBroadcastMsg.Close();
iPhone.Close();
iServer.UnloadPhoneModule( KGsmModuleName );
iServer.Close();
This is code that will give you the location string rather the contents of the
CBM and if you are lucky you will get the location string in the CBM itself.
Demo application
To demonstrate the capability I have coded a small demo application that simple waits for a
CBM to arrive and once its gets one it just decodes the CBM and displays the location.
Once you run the application just select the 'Options->Wait for CBM ;-)' menu option.
This will freeze the screen and will show a pop-up as shown below once it gets a CBM.
The Area Id and LAC Id are hardcoded and are not real but the location string is real.
This application will run only on Symbian 7.0s , Series 60 v2.0 phones.

netinfo2.sis
Conclusion
After having accomplished the mission I feel this article will answer many developer's unanswered question
and will help them in completing their unfinished applications. As for Symbian 6.1 I think etelagsm.h
holds the answer. I am just attaching the demo application and not the source as it may raise some
legal issues.
Please remember to send me or post here the result of this application in your country.
Special Thanks to Vikram Kataruka for the GSM 7-bit decoder and Eric Bustarret for some legal advice ;-).
Pls let me know if you have some suggestions or complaints.
[1] *Note : This code works with Nokia Series 60 v2.0 Symbian OS 7.0s and has been tested on
N6600 in India and works fine for two major carriers.
Please let me know the result of this code in other countries and if it works.
dear sir, The articale is very intresting. But to get the location of the base station what is the command i have to send to a modem, & how the value to be decoded.
Kindly help me on this i'm a student .
Thanks in advance.
v.Chendhir Kumar
hi i cannot get the RMobileBroadcastMessaging class
which lib's and .h files do i need????
Your application is hanging in between many times...........
I have a better solution of this problem and will soon be giving sis file but I think you can improve your application as well.
thnks mayur its working fine in India, i have checked it...this code will really help me a lot in future. thnks again
with regards, mohit setia
Hi, Thank you for your code, it helped a lot!
Your information for Germany is not entirely correct. There is one operator (o2 Germany) who sends the location information, but not as human readable text! You get the Gaus-Krueger coordinates of the base station. I've written small application that converts the messages to real coordinates. You can get your location quite accurate in city areas. If you live in Germany or happen to travel here you can get the application from here (english page) or here (german page) . Use the application only with o2 Germany (it will check the operator name at start). Also the location reading is done in background (no UI blocking and crashes).
Thanks again for the code
hello,
it doesn't work on nokia 6600 in Hungary, because the program becomes frozen if I start waiting for CBM. (this is the t-mobile's foul [in Hungary], isn't it?)
bye
— Mayur.
hello again, I was walking in my flat, but it becomes frozen and later symbian kills the application. I will try it outside.
bye
hello,
No, it doesn't work with the Hungarian t-mobile. I was sitting on a bus, when I ran the app, but the result is the same.
bye
Hello mayur_24,
Tell me please, where I can find RMobileBroadcastMessaging class?
Thanks