Windows Mobile: programmatically intercepting phone calls

  • Supported?? Expectations about cprog.exe
  • How Communicator Mobile works with “Work Phone calls
  • Sample code to “extend” the State&Notification Broker for IGNORED phone calls

I recently worked with some ISVs asking support about this, then also answered to a MSDN Forum thread about the same, so I’d say it may be worth to mention it here as well for Community reference. This happens to be one of those common questions that fall under the umbrella of the “not supported as OEM-dependent” or “not supported as it’s not meant to work that way”. I’ve talked about this some times on my blog, for example regarding Wireless programming, Drivers, Kiosk applications, Hooks

The issue is about “intercepting” incoming phone calls and prevent the native UI dialog provided by OS application cprog.exe to take care of it: there are some OEMs that customized the user interface for this phone application, so ISVs may think this could be a common task to achieve? One could say: “Wouldn’t be sufficient to kill cprog.exe?”. Or, in any case, is there a way for ISV Application Developers to programmatically control incoming and outgoing calls *before* or *instead* the Operating System itself?

The answer is no, but you may possibly find “creative” ways to achieve the same visual effect your application’s final users may look for. The main point is that interfering with the OS Native Phone application (cprog.exe) is not supported for ISV Application Developers, contrarily to Device Manufacturers (OEMs) who actually build their own OS based on the Windows Mobile platform and therefore can develop and include whatever they want on their Operating Systems, as long as they fulfill the “Windows Mobile Logo Test Kit” (so that their OS is certified as “Windows Mobile”).

As an example, a thing that the Windows Mobile platform doesn’t test or even consider is killing cprog.exe, which is the process underlying the Phone UI Application. Once the device is booted, cprog.exe executes and even when there is a Out-Of-Memory condition (so that the Shell starts asking every application to shut down, accordingly to this old post from WinMo Dev Team), cprog.exe is not terminated. So the current OS design does not expect it to be killed forcefully.

In some cases, to meet this requirement you would need to cooperate with the Device OEM\OEMs so that he\they can sponsor you as their “Windows Mobile In-ROM ISV”. By doing so, you would have access to all the tools a Device Manufacturer has, including the knowledge on the RIL Driver (Radio Interface Layer), developed by the OEM, that is responsible to handle every radio-related communication of the device (phone call, GPRS data session, …). So, to intercept phone calls before cprog.exe does it, you should do it at RIL Driver level, and Microsoft has no idea about how the OEM implemented it.

In other cases, you can let cprog.exe do its work, and play with Windows APIs to hide its window and take control of the phone call via TAPI (Telephony API): that is the “supported” way.

 

You may ask: then how does Microsoft’s Communicator Mobile 2007 R2 implement "Work Phone calls”? How can it intercept phone calls, if this is OEM-dependent? Well, actually it doesn’t. CoMo is not working with the RIL to intercept phone-voice calls. Documentation is available through the following Microsoft Office Communications Server 2007 R2 – Technical Reference (section “Outside Voice Control”):

[…] For inbound calls, Office Communications Server 2007 R2 sends a SIP Invite to all registered SIP endpoints of the user including the user’s Communicator Mobile (2007 R2 release) client running on the phone, over the data channel. Office Communications Server 2007 R2 subsequently initiates an outbound PSTN/mobile network call through Office Communications Server 2007 R2 Mediation Server to the user’s mobile phone number.

So as you can see, when dealing with “Communicator phone-calls” we’re not precisely working with “Voice-Phone calls”: it’s about SIP requests sent over the Data Channel, not the Voice-one.

 

Among the “supported” ways to deal with phone calls, developers can rely on the State&Notification Broker states like PhoneCallTalking and PhoneIncomingCall: a state that may be missing is about the last call being ignored. Here it is a managed sample code showing a possible way to achieve this (to be tested… as usual! Smile):

 

 public Form1()
 {
     InitializeComponent();
     _PhoneIncomingCall.Changed += new ChangeEventHandler(_PhoneIncomingCall_Changed);
 }
  
 bool bTalking = false;
 bool bIncoming = false;
 bool bIgnoring = false;
  
 SystemState _PhoneCallTalking = new SystemState(SystemProperty.PhoneCallTalking);
 SystemState _PhoneIncomingCall = new SystemState(SystemProperty.PhoneIncomingCall);
  
  
 void _PhoneCallTalking_Changed(object sender, ChangeEventArgs args)
 {
     bTalking = (0 != (int)args.NewValue);
  
     //_PhoneIncomingCall.Changed += new ChangeEventHandler(_PhoneIncomingCall_Changed);
     _PhoneCallTalking.Changed -= _PhoneCallTalking_Changed;
 }
  
 void _PhoneIncomingCall_Changed(object sender, ChangeEventArgs args)
 {
     bIncoming = (0 != (int)args.NewValue);
     if (bIncoming)
     {
         //_PhoneIncomingCall.Changed -= _PhoneIncomingCall_Changed;
         _PhoneCallTalking.Changed += new ChangeEventHandler(_PhoneCallTalking_Changed);
     }
     else
     {
         //answered: bTalking = true
         //ignored: bTalking = false
         bIgnoring = !bTalking;
         MessageBox.Show(string.Format("IgnoredCall: {0}", bIgnoring.ToString()));
  
         //reset vars
         bIncoming = false;
         bIgnoring = false;
         bTalking = false;
     }
 }

 

Cheers,

~raffaele