65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Windows Mobile 上制作呼叫拦截器应用程序

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (1投票)

2012年5月7日

CPOL

7分钟阅读

viewsIcon

33938

downloadIcon

809

Windows Mobile 上的黑名单应用程序(拦截器应用程序)

引言

大多数时候,我们会在深夜或工作时间接到烦人的电话。

那么,我们该如何处理这种情况呢?我们可以从商店购买应用程序来解决,但等等,如果你可以自己开发自定义应用程序,为什么还要花钱呢?

背景

在此应用程序中,我将重点介绍 RIL(无线电接口层)。

无线电接口层 (RIL) 提供了一个处理 CellCore 系统软件和无线电硬件之间通信的接口。RIL 提供了一个抽象层,使您能够创建单个驱动程序,该驱动程序可以在不同的无线电上实现。RIL 抽象了设备中硬件相关组件的详细信息,使 OEM 能够将各种调制解调器集成到他们的设备中,从而提供产品差异化的机会。这个单一的驱动程序随后允许所有无线电在单一的 CellCore 组件集下工作。

RIL 概述

RIL 在系统软件和驻留在调制解调器内的无线电堆栈之间提供接口。系统软件包括操作系统、Windows Mobile 的所有元素,例如:TAPI / ExTAPI、SIM 管理器、SMS 管理器、拨号器等,以及客户/第三方应用程序。RIL 服务于无线电功能的系统请求,例如:语音、数据、SMS 等,并提供系统变化的异步通知,例如:信号强度、覆盖范围、来电、收到的 SMS 消息。Windows Mobile 中的电话服务由操作系统定义,每个功能或服务理想情况下应独立于调制解调器和调制解调器/应用程序处理器接口。RIL 的架构使得 Windows Mobile 提供了一个标准的接口、API 集和回调机制,这些机制可跨不同平台使用,而具体细节则对系统的其余部分隐藏。

平台实现

RIL 源代码通常基于 Microsoft 在适应工具包下的 <platform root folder>\public\cellcore\ril\driver 中提供的示例 RIL,该示例 RIL 提供了支持标准 AT 命令调制解调器所需的所有机制。对于非 AT 命令调制解调器,重新设计 RIL 可能更有效。示例 RIL 支持西门子、TI 和 TTPCom 调制解调器,因此,如果 RIL 不是基于上述之一的调制解调器,则需要进行修改以适应所选的调制解调器。尽管大多数调制解调器都符合 GSM 或 CDMA 规范,但大多数制造商的实现方式相似但不完全相同,因此,尽管 AT 命令可能相同,但命令的实际行为可能不同。例如,在某些调制解调器上,AT+COPS=0 会一直阻塞直到调制解调器在网络上注册(或注册失败),而其他调制解调器则立即响应并在后台注册。Logo 测试套件假定调制解调器具有特定的行为,因此,某些调制解调器需要修改 RIL 以匹配预期的行为。针对每个调制解调器和/或平台需要修改的最常见区域是

电源管理

无线电的电源管理是调制解调器特定和平台特定方法的结合,例如:调制解调器可能支持通过 AT 命令的省电模式,或者平台可能为调制解调器提供硬件电源控制。这两种方法各自都有需要 RIL 驱动程序解决的问题。

音频管理

RIL 负责调整调制解调器语音信号的音量,并选择当前使用的音频设备。这通常是通过 AT 命令来调整调制解调器设置来完成的,但是,某些平台可能具有外部音频硬件来进行这些更改,在这种情况下,RIL 需要直接访问硬件,或者最好是访问另一个设备驱动程序。

SMS 处理

示例 RIL 支持 GSM SMS 阶段 2 模式 2,但如果调制解调器不支持,则需要修改 SMS 消息的处理。

SIM 工具包

示例 RIL 中的 SIM 工具包支持是围绕 Condat 和 TTPCom AT 命令集设计的。许多调制解调器制造商实现了自己的专有 AT 命令扩展来处理 SIM 工具包命令,因此,可能需要一些工作来将无线电命令转换为 OS 所期望的内容。如果调制解调器实现的 SIM 工具包功能差异很大,这可能会非常复杂,因为需要在 RIL 中添加大量的命令解析更改。

自己的号码

许多调制解调器不支持 +CNUM AT 命令,这在 OS

尝试获取调制解调器自身电话号码时可能会导致问题,因为电话控制面板小程序将显示“不可用”。为避免这种情况,可以通过选择“自己的号码”电话簿来修改 RIL,以便从 SIM 电话簿获取自己的号码,但这取决于 SIM/网络运营商,因此,某些 SIM 卡在此电话簿中可能不包含任何条目。

RIL 调制解调器接口

RIL 通过接受来自上层(主要是 TAPI 和 ExTAPI)的服务请求来实现硬件抽象,并将这些请求转换为调制解调器支持的命令,通过调制解调器/主机处理器接口交换信息。追溯到 30 多年前的原始调制解调器系统设计提供了一个单一的通信通道,用于路由 AT 命令和数据,这需要一个耗时的命令模式和数据模式之间的切换机制,本质上一次只允许一个进程处于活动状态。网络(例如 2.5G 和 3G)的进步现在提供了多个并发服务,例如:用于浏览网页的数据连接、发送/接收电子邮件、发送/接收 SMS 消息、发起/接听语音电话、轮询信号强度等。网络进步的程度已经远远超过了调制解调器接口的进步,以至于有必要花费精力来最大化吞吐量,例如:支持多路复用设备驱动程序和 RIL 本身的多路复用支持。网络进步需要调制解调器架构的演进,以至于通常有必要在调制解调器接口上投入精力。某些调制解调器提供其他接口,例如:高速 UART、USB、共享内存。高速 UART 和 USB 端口的原理相同,访问调制解调器仍然是通过标准的设备驱动程序(串行或 USB),没有特定的 RIL 或 MUX 相关功能。共享内存

实现需要对 RIL 进行大量更改,并且超出了本文档的范围。

 

Using the Code

在开始编写代码之前,我建议先了解一下无线电接口层 RIL

这个库非常有用,您可以在这里查看一些著名的函数,例如:

  • RIL_Dial:此函数负责拨打语音和数据电话。
  • RIL_GetCellTowerInfo:此函数检索有关手机当前使用的基站的信息。
  • RIL_GetCurrentOperator:此函数检索设备当前注册的运营商。
  • RIL_GetMinimumQualityOfServiceList:此函数获取所有上下文的最低服务质量配置文件。
  • RIL_AddCallForwarding:此函数添加一个呼叫转移规则。
  • RIL_AddPreferredOperator:此函数将指定运营商添加到首选运营商列表中。
  • RIL_Answer:此函数由 RIL 驱动程序实现。它负责接听当前提供的呼叫。
  • RIL_CancelSupServiceDataSession:此函数取消当前补充服务数据会话。
  • RIL_ChangeCallBarringPassword:此函数更改指定类型的呼叫等待密码。
  • RIL_ChangeLockingPassword:此函数更改指定设施的锁定密码。
  • RIL_ClearCCBSRegistration:此函数清除呼叫忙时完成(CCBS)索引的注册。
  • RIL_Deinitialize:此函数初始化 RIL。此函数是同步的。
  • RIL_DeleteGPRSContext:此函数删除一个特定的 GPRS 上下文。
  • RIL_Dial:此函数负责拨打语音和数据电话。
  • RIL_DisableNotifications:此函数禁用客户端的通知类别。此函数是同步的。
  • RIL_EnableNotifications:此函数为客户端启用其他通知类别。此函数是同步的。
  • RIL_EnterGPRSDataMode:此函数进入 GPRS 数据状态。
  • RIL_FetchSimToolkitCmd:此函数从 SIM 卡获取 SIM 工具包命令。
  • RIL_GetAllOperatorsList:此函数检索所有已知运营商的内置列表。
  • RIL_GetATR:此函数从 SIM 卡获取“重置应答”(ATR) 字符串。
  • RIL_GetAudioDevices:此函数检索当前的发送和接收音频设备。
  • RIL_GetAudioGain:此函数检索音频增益信息。
  • RIL_GetAudioMuting:此函数由 RIL 驱动程序实现。它负责查询无线电的静音状态。
 更多功能 
HRESULT hRes; 
DWORD dwNotificationClasses = 0xffff0000;  
hRes = RIL_Initialize(1, RILResultCallBack, RILNotifyCallBack, dwNotificationClasses, 0x55AA55AA, &g_hRil); 
{ 
if (g_hRil == NULL) 
	 
RIL_Deinitialize(g_hRil); 
return 0; 
}//

RIL_Initialize:此函数初始化 RIL 以供客户端使用,dwNotificationClasses 0xffff0000 指定我们通知的类别,在我们的例子中,我们将实现 CALL_RING。

case RIL_NCLASS_CALLCTRL:
		{
			 switch (dwCode) {   
				 case RIL_NOTIFY_CALLPROGRESSINFO:
					 {
					
						callInfo = (RILCALLINFO*) pData;
						raAddress = callInfo->raAddress;//Phone Number

					 }break;
				 case RIL_NOTIFY_RING:
					{
						KillCProg();//End Call
					}break; 
            }   
            break;

CallBack 函数,当您接到电话时会触发。

RIL_NOTIFY_CALLPROGRESSINFO:它接收一些来电者的信息,例如电话号码。

RIL_NOTIFY_RING:当收到响铃通知时运行。

// Take a snapshot of all modules in the specified process.
		hProcesses = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
		if (INVALID_HANDLE_VALUE == hProcesses) { 
		dwError = ::GetLastError(); 
		} 
		pe.dwSize = sizeof(pe); 

		// Retrieve information about the first module,
		  // and exit if unsuccessful	
		for (bVal = ::Process32First(hProcesses, &pe); bVal; bVal = 
		::Process32Next(hProcesses, &pe)) 
		{ 
		if (!_tcscmp(TEXT("cprog.exe"), pe.szExeFile)) 
		{ 
			  hProc = ::OpenProcess(0, FALSE, pe.th32ProcessID); 
			::TerminateProcess(hProc, 0); 
			::CloseHandle(hProc); 
		break; 
		} 
		} 
		::CloseToolhelp32Snapshot(hProcesses);

现在我们要进入进程视图来终止 cprog.exe

cprog.exe:用于拨打或接听电话的电话应用程序。

hProcesses = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

// 捕获指定进程中的所有模块的快照。

::Process32First(hProcesses, &pe);
		// Retrieve information about the first module, and exit if unsuccessful

当我们捕获到 cprog.exe 时,如果 !_tcscmp(TEXT("cprog.exe"), pe.szExeFile),我们可以终止它,& 烦人的故事就结束了。

© . All rights reserved.