Hi, I'm Paul, but you can also call me Todd and I won't get upset.
Paul.Todd | 19 February, 2008 22:17
I know code examples have been slim at the moment, but unfortunatly I have been overcommited everyelse. However I dug out a golden oldie (for me anyway) - getting the IMEI number for any number of scenarios.
Many of the solutions for retrieving the IMEI on 3rd edition are fraught with problems.
Probably the biggest issue is using nested active schedulers.
Nesting active schedulers is singulary one of he most dangerous things to do in Symbian as it can lead to the case where different active schedulers are running different objects. This leads all sorts of race cases and eneral crashes tha are a nightmare to debug.
The easiest way without using nested schedulers (In my opinion anyway) to get the IMEI
is to just spawn a thread and use that to get the IMEI. When the thread completes just
resume the primary thread.
Note that the thread actually blocks the main/UI thread, however it is not a significant
amount of time and it makes the overall code much simpler whilst at the same time reducing
the complexity of the code, because there are no wierd interactions with this or a nested
scheduler issues to deal with.
The code in the spawned thead is simpler because it is more less the same that is covered
in the wiki or the Symbian SDK documentation.
So here is an active object to get the IMEI:
class CIMEILoader : public CActive
{
public:
CIMEILoader(TDes& aIMEI);
~CIMEILoader();
void ConstructL();
void Start();
void IMEI(TDes& aIMEI);
private:
void RunL();
void DoCancel();
private:
CTelephony* iTelephony;
TDes& iIMEI;
CTelephony::TPhoneIdV1 iId;
};
///////////////////////////////////////////////////////////////////////
CIMEILoader::CIMEILoader(TDes& aIMEI)
: CActive(EPriorityNormal),
iIMEI(aIMEI)
{
CActiveScheduler::Add(this);
}
CIMEILoader::~CIMEILoader()
{
Cancel();
delete iTelephony;
iTelephony = NULL;
}
void CIMEILoader::ConstructL()
{
iTelephony = CTelephony::NewL();
}
void CIMEILoader::Start()
{
CTelephony::TPhoneIdV1Pckg pkg(iId);
iTelephony->GetPhoneId(iStatus, pkg);
SetActive();
}
void CIMEILoader::RunL()
{
CActiveScheduler::Stop();
iIMEI.Copy(iId.iSerialNumber);
}
void CIMEILoader::DoCancel()
{
iTelephony->CancelAsync(CTelephony::EGetPhoneIdCancel);
}
///////////////////////////////////////////////////////////////
// Here is the code for the thread
LOCAL_C void TelephonyHandlerL(TDes& aIMEI)
{
CActiveScheduler* sched = new (ELeave) CActiveScheduler();
CleanupStack::PushL(sched);
CActiveScheduler::Install(sched);
CIMEILoader* loader = new (ELeave) CIMEILoader(aIMEI);
CleanupStack::PushL(loader);
loader->ConstructL();
loader->Start();
CActiveScheduler::Start();
// Make sure that if we completed it was successfully
User::LeaveIfError(loader->iStatus.Int());
// When loader completes the function resumes here
CleanupStack::PopAndDestroy(2, sched);
}
LOCAL_C TInt HandlerThreadProc(TAny* aAny)
{
__UHEAP_MARK; // Heap checking
CTrapCleanup* cleanup=CTrapCleanup::New();
TInt err=KErrNoMemory;
if (cleanup)
{
TRAP(err, TelephonyHandlerL(REINTERPRET_CAST(TDes&, *aAny)));
delete cleanup;
}
__UHEAP_MARKEND;
return err;
}
/////////////////////////////////////////////////////////////
// Finally the code to get the IMEI
const TInt KTelMinHeap = 0x1000;
const TInt KTelMaxHeap = 0x4000;
_LIT(KThreadName, "TelephonyHelper");
LOCAL_C TInt GetIMEI(TDes& aIMEI)
{
RThread theThread;
TInt err = theThread.Create(KThreadName, HandlerThreadProc, KDefaultStackSize, KTelMinHeap, KTelMaxHeap, &aIMEI);
if (err == KErrNone)
{
TRequestStatus status;
theThread.Logon(status);
theThread.Resume();
User::WaitForRequest(status);
theThread.Close();
err = status.Int();
}
return err;
}
There you have it, the code to get the IMEI number thats safe and almost reliable (More next time).
This is also one of the few cases where it is acceptable to use User::WaitForRequest
Hi, I'm Paul, but you can also call me Todd and I won't get upset.
RDF Facets:
qfnZtopicQUqfnTopicZcppQ
qfnZtypeQUqfnTypeZBlogContentQ
qfnZtypeQUqfnTypeZBlogE45ntryQ
qfnZtypeQUqfnTypeZCommunityContentQ
qfnZtypeQUqfnTypeZWebpageQ
qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX