2009年4月20日星期一

控制信道(CCH)传输各种信令信息

控制信道(CCH)传输各种信令信息

控制信道分为三类:

1)广播信息(BCH)是一种“一点对多点”的单方向控制信道,用于基站向所有移 动台广播公用信息。传输的内容是移动台入网和呼叫建立所需要的各种信息。其中又分 为:

a、频率校正信道(FCCH):传输供移动台校正其工作频率的信息;

b、同步信道(SCH):传输供移动台进行同步和对基站进行识别的信息;

c、广播控制信道(BCCH):传输通用信息,用于移动台测量信号强度和识别小区 标志等。

2)公共控制信道(CCCH)是一种“一点对多点”的双向控制信道,其用途是在呼 叫接续阶段,传输链路连接所需要的控制信令与信息。其中又分为:

a、寻呼信道(PCH):传输基站寻呼移动台的信息;

b、随机接入信道(RACH):移动台申请入网时,向基站发送入网请求信息;

c、准许接入信道(AGCH):基站在呼叫接续开始时,向移动台发送分配专用控制 信道的信令。

3)专用控制信道(DCCH)是一种“点对点”的双向控制信道,其用途是在呼叫接 续阶段和在通信进行当中,在移动台和基站之间传输必需的控制信息。其中又分为:
a、独立专用控制信道(SDCCH):传输移动台和基站连接和信道分配的信令;

b、慢速辅助控制信道(SACCH):在移动台和基站之间,周期地传输一些特定的信 息,如功率调整、帧调整和测量数据等信息;SACCH是安排在业务信道和有关的控制信 道中,以复接方式传输信息。安排在业务信道时,以SACCH/T表示,安排在控制信道时, 以SACCH/C表示,SACCH/常与SDCCH联合使用。

c、快速辅助控制信道(FACCH):传送与SDCCH相同的信息。使用时要中断业务信 息(4帧),把FACCH插入,不过,只有在没有分配SDCCH的情况下,才使用这种控制信 道。这种控制信道的传输速率较快,每次占用4帧时间,约18.5ms。

由此可见,GSM通信系统为了传输所需的各种信令,设置了多种专门的控制信道。 这样做,除因为数字传输为设置多各逻辑信道提供了可能外,主要是为了增强系统的控 制功能(比如后面将要提到的,为提高过境切换的速度而采用移动台辅助切换技术), 也为了保证话音通信质量,在模拟蜂窝系统中,要在通话进行过程中,进行控制信息的 传输,必须中断话音信息的传输(100ms),这就是所谓的“中断一猝发”的控制方式。 信道中断100ms,会使话音产生可以听得到的喀喇声。如果这种中断过于频繁,势必明 显地降低话音质量,因此,模拟蜂窝系统必须限制在通话过程中传输控制信息的容量。 与此不同,GSM蜂窝系统采用专用控制信道传输控制信息,除去FACCH外,不在通信过 程中中断话音信息,因而能保证话音的传输质量。其中FACCH虽然也采取“中断一猝发” 控制方式,但是只在特定场合下才使用,而且占用的时间短(18.5ms),其影响明显 减小。GSM蜂窝系统还采用信息处理技术,来估计并补偿这种因为插入FACCH而被删除 的话音。

BSIC

基站识别码 Base Station Identity Code
  包括PLMN色码和基站色码。用于区分不同运营者或同一运营者广播控制信道频率相同的不同小区。
  BSIC用於移动台识别相同载频的不同基站,特别用於区别在不同国家的边界地区采用相同载频且相临的基站,BSIC为一个6bit编码:BSIC=NCC(3bit)+BCC(3bit)
  NCC:PLMN色码,用来识别相临的PLMN网
  BCC:BTS色码,用来识别相同载频的不同的基站.
  BSIC的4个作用
  移动台收到SCH后,即认为已同步于该小区。但为了正确地译出下行公共信令信道上的信息,移动台还必须知道公共信令信道所采用的训练序列码(TSC)。按照GSM规范的规定,训练序列码有八种固定的格式,分别用序号0~7表示。每个小区的公共信令信道所采用的TSC序列号由该小区的BCC决定。因此BSIC的作用之一是通知移动台本小区公共信令信道所采用的训练序列号。
  由于BSIC参与了随机接入信道(RACH)的译码过程,因此它可以用来避免基站将移动台发往相邻小区的RACH误译为本小区的接入信道。
  当移动台在连接模式下(通话过程中),它必须根据BCCH上有关邻区表的规定,对邻区BCCH载频的电平进行测量并报告给基站。同时在上行的测量报告中对每一个频率点,移动台必须给出它所测量到的该载频的BSIC。当在某种特定的环境下,即某小区的邻区中包含两个或两个以上的小区采用相同的BCCH载频时,基站可以依靠BSIC来区分这些小区,从而避免错误的切换,甚至切换失败。
  移动台在连接模式下(通话过程中)必须测量邻区的信号,并将测量结果报告给网络。由于移动台每次发送的测量报告中只能包含六个邻区的内容,因此必须控制移动台仅报告与当前小区确实有切换关系的小区情况。BSIC中的高三位(即NCC)用于实现上述目的。网络运营者可以通过广播参数"允许的NCC"控制移动台只报告NCC在允许范围内的邻区情况。

2009年4月13日星期一

实战DeviceIoControl 之一:通过API访问设备驱动程序

Q 在NT/2000/XP中,我想用VC编写应用程序访问硬件设备,如获取磁盘参数、读写绝对扇区数据、测试光驱实际速度等,该从哪里入手呢?
A 在NT/2000/XP中,应用程序可以通过API函数DeviceIoControl来实现对设备的访问—获取信息,发送命令,交换数据等。利用该接口函数向指定的设备驱动发送正确的控制码及数据,然后分析它的响应,就可以达到我们的目的。
DeviceIoControl的函数原型为
BOOL DeviceIoControl(     HANDLE hDevice,              // 设备句柄     DWORD dwIoControlCode,       // 控制码     LPVOID lpInBuffer,           // 输入数据缓冲区指针     DWORD nInBufferSize,         // 输入数据缓冲区长度     LPVOID lpOutBuffer,          // 输出数据缓冲区指针     DWORD nOutBufferSize,        // 输出数据缓冲区长度     LPDWORD lpBytesReturned,     // 输出数据实际长度单元长度     LPOVERLAPPED lpOverlapped    // 重叠操作结构指针 ); 
设备句柄用来标识你所访问的设备。
发送不同的控制码,可以调用设备驱动程序的不同类型的功能。在头文件winioctl.h中,预定义的标准设备控制码,都以IOCTL或FSCTL开头。例如,IOCTL_DISK_GET_DRIVE_GEOMETRY是对物理驱动器取结构参数(介质类型、柱面数、每柱面磁道数、每磁道扇区数等)的控制码,FSCTL_LOCK_VOLUME是对逻辑驱动器的卷加锁的控制码。
输入输出数据缓冲区是否需要,是何种结构,以及占多少字节空间,完全由不同设备的不同操作类型决定。在头文件winioctl.h中,已经为标准设备预定义了一些输入输出数据结构。重叠操作结构指针设置为NULL,DeviceIoControl将进行阻塞调用;否则,应在编程时按异步操作设计。
Q 设备句柄是从哪里获得的?
A 设备句柄可以用API函数CreateFile获得。它的原型为
HANDLE CreateFile(     LPCTSTR lpFileName,                         // 文件名/设备路径     DWORD dwDesiredAccess,                      // 访问方式     DWORD dwShareMode,                          // 共享方式     LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全描述符指针     DWORD dwCreationDisposition,                // 创建方式     DWORD dwFlagsAndAttributes,                 // 文件属性及标志     HANDLE hTemplateFile                        // 模板文件的句柄 ); 
CreateFile这个函数用处很多,这里我们用它“打开”设备驱动程序,得到设备的句柄。操作完成后用CloseHandle关闭设备句柄。
与普通文件名有所不同,设备驱动的“文件名”(常称为“设备路径”)形式固定为“\\.\DeviceName”(注意在C程序中该字符串写法为“\\\\.\\DeviceName”),DeviceName必须与设备驱动程序内定义的设备名称一致。
一般地,调用CreateFile获得设备句柄时,访问方式参数设置为0或GENERIC_READ|GENERIC_WRITE,共享方式参数设置为FILE_SHARE_READ|FILE_SHARE_WRITE,创建方式参数设置为OPEN_EXISTING,其它参数设置为0或NULL。
Q 可是,我怎么知道设备名称是什么呢?
A 一些存储设备的名称是微软定义好的,不可能有什么变化。大体列出如下
软盘驱动器A:, B:
硬盘逻辑分区C:, D:, E:, ...
物理驱动器PHYSICALDRIVEx
CD-ROM, DVD/ROMCDROMx
磁带机TAPEx
其中,物理驱动器不包括软驱和光驱。逻辑驱动器可以是IDE/SCSI/PCMCIA/USB接口的硬盘分区(卷)、光驱、MO、CF卡等,甚至是虚拟盘。x=0,1,2 ……
其它的设备名称需通过驱动接口的GUID调用设备管理函数族取得,这里暂不讨论。
Q 请举一个简单的例子说明如何通过DeviceIoControl访问设备驱动程序。
A 这里有一个从MSDN上摘抄来的demo程序,演示在NT/2000/XP中如何通过DeviceIoControl获取硬盘的基本参数。
/* The code of interest is in the subroutine GetDriveGeometry. The    code in main shows how to interpret the results of the IOCTL call. */    #include  #include     BOOL GetDriveGeometry(DISK_GEOMETRY *pdg) {     HANDLE hDevice;               // handle to the drive to be examined     BOOL bResult;                 // results flag     DWORD junk;                   // discard results        hDevice = CreateFile("\\\\.\\PhysicalDrive0",  // drive to open                     0,                // no access to the drive                     FILE_SHARE_READ | // share mode                     FILE_SHARE_WRITE,                     NULL,             // default security attributes                     OPEN_EXISTING,    // disposition                     0,                // file attributes                     NULL);            // do not copy file attributes        if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive     {         return (FALSE);     }        bResult = DeviceIoControl(hDevice,     // device to be queried         IOCTL_DISK_GET_DRIVE_GEOMETRY,     // operation to perform                     NULL, 0,               // no input buffer                     pdg, sizeof(*pdg),     // output buffer                     &junk,                 // # bytes returned                     (LPOVERLAPPED) NULL);  // synchronous I/O        CloseHandle(hDevice);        return (bResult); }    int main(int argc, char *argv[]) {     DISK_GEOMETRY pdg;            // disk drive geometry structure     BOOL bResult;                 // generic results flag     ULONGLONG DiskSize;           // size of the drive, in bytes        bResult = GetDriveGeometry (&pdg);        if (bResult)     {         printf("Cylinders = %I64d\n", pdg.Cylinders);         printf("Tracks per cylinder = %ld\n", (ULONG) pdg.TracksPerCylinder);         printf("Sectors per track = %ld\n", (ULONG) pdg.SectorsPerTrack);         printf("Bytes per sector = %ld\n", (ULONG) pdg.BytesPerSector);            DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *             (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;         printf("Disk size = %I64d (Bytes) = %I64d (Mb)\n", DiskSize,             DiskSize / (1024 * 1024));     }     else     {         printf("GetDriveGeometry failed. Error %ld.\n", GetLastError());     }        return ((int)bResult); } 
Q 如果将设备名换成“A:”就可以取A盘参数,换成“CDROM0”就可以取CDROM参数,是这样吗?
A 这个问题暂不做回答。请动手试一下。
现在我们总结一下通过DeviceIoControl访问设备驱动程序的“三步曲”:首先用CreateFile取得设备句柄,然后用DeviceIoControl与设备进行I/O,最后别忘记用CloseHandle关闭设备句柄。

2009年4月9日星期四

在文件右键菜单添加项

修改右键菜单应该在注册表中,具体的说,是在HKEY_CLASSES_ROOT根键下(这里可是右键菜单中所有命令的根源哦!)。展开该根键,其下的子键主要有两种:扩展名键(.+扩展名)和类定义键(如图1)。一般地说,只要是在windows系统中已注册过的扩展名,在HKEY_CLASSES_ROOT下均有“·该扩展名”子键 ,记录该扩展名的一些信息,对某种特定类型的文件的右键菜单的修改,便是在该键或“扩展名file”键下的操作。

一、在所有的文件右键菜单中加入命令

如果你的系统上安装有Winzip、UltraEdit等,当你对任一文件点右键时,都会有“Add to zip”、“UltraEdit-32”等命令(当然,Winzip稍有不同,我将在后面讲到)。它的添加方法是:

1.打开“HKEY_CLASSES_ROOT\*”;
2.在其下新建“shell\命令\command”分支,再将command的键值设为执行该命令时所用的可执行程序的绝对路径,并在其后加“%1”即可。

例:在“HKEY_CLASSES_ROOT\*"下新建“shell\Open with SlickEdit 2009\command”子键,将command的键值设为“x:\xxxxx\SlickEdit 2009\win\vs.exe %1”,就会在右键菜单中出现“用写字板打开”的命令了。

说明:
1. 要删除该类命令,只需将“命令”子键删除即可;
2. 有的人或许会问他按我写的去做,但是得到的为何与我的有一些不同,这就是我的命令里有快捷键(N),只要在“Open with SlickEdit 2009”后加入“(&O)”即可。

二、在特定文件类型的右键菜单中加入命令

刚才说到了Winzip这个软件,对普通的文件类型,它的右键菜单中有“Add to zip”,但是对它所支持的压缩文件类型,如*.zip、*.cab、*.rar在其右键菜单中有“Open with Winzip”、“Extract to”、“Extract to folder”、“Create Self-Extractor(.EXE)” 等命令,对于自解压性安装文件(如OICQ99b),其右键菜单中有“Run with Winzip”命令。下面是特定文件类型的右键菜单的命令添加方法(以在mp3文件的右键菜单中加入Play with winamp为例):

1.打开“HKEY_CLASSES_ROOT\mp3_auto_file”主键;
2.在其下新建“shell\Play with Winamp(&P)\command”,将command的键值设为“C:\Program files\winamp\winamp.exe %1” 。

说明:当有多个软件可以播放mp3文件时,我们可以在右键菜单中添加多条命令,如加入“Play with Unreal”等命令,但是我们如何将某一条命令定义为默认操作(即右键菜单中的黑体命令)呢?

你一定会说,很简单的事情吗!将mouse移向一mp3文件,在按右键的同时按shift,在右键菜单中选“打开方式“便可更改,但是这是错误的,不信你试试看,这样只有在右键菜单中选“打开”时才会用你所选择的程序来打开它,否则,它仍旧一如继往。因为它的默认操作不是“打开“这条命令。真正的方法是将shell的默认键值改为你所想执行的命令,例如将shell的键值改为“Winamp”。

2009年4月8日星期三

QXDM-Messages View

HOW DO I OBTAIN THE DEFINITIONS OF EACH DEBUG OR EVENT MESSAGE?
The Messages view displays debug and event messages received by the mobile. (it can also be configured to display log packets and strings). These messages are not specific to QXDM, are used primarily by QUALCOMM for developing ASIC software, change frequently, and are not documented.

Debug Messages (labeled as Message Packets in QXDM) are software-specific printf strings created by the AMSS developer to help debug the AMSS itself. They are not documented beyond the source code itself. There are no QXDM user guides or addendums that define frequently used debug messages.

Event Reports are a debugging mechanism that summarizes activity by the software. The events are not implementation-specific or internal strings like debug messages, but are typically indicators of common, industry standard terms that are easier to understand and follow when compared to debug messages.

QXDM does not generate the messages that are displayed on the Messages view, which is why they are not documented in the QXDM user guide. QXDM only logs or displays the messages as they are provided by the mobile. The software in the test handset provides debug messages to QXDM as part of the MESSAGE RESPONSE MESSAGE (A Diagnostic command response), CMD_CODE(31), and Event Reports as part of the EVENT REPORT MESSAGE (CMD_CODE 96). QXDM does not need to be enhanced or changed to support debug messages for technologies in development. All such devices provide the debug text across the same transport described above, without the need to QXDM at all. Event Reports need a database update, as the Event ID and payload needs to be parsed for the Event Report to have meaning. Event Reports are not ASCII text strings like Debug Messages.

The debug messages consist of fixed text that is determined at compile time by the handset manufacturer. Most of the debug messages are inherited from the ASIC code that QUALCOMM provides to the handset manufactuer, while others are introduced by the handset manufacturer as they develop their product. The messages are used as a diagnostic aid to provide handset software developers with some insight into the behavior of the handset software program. The list of potential debug messages is very extensive, and are constantly changing from build to build. They are used for development purposes only, and will never be documented beyond the source code.

To find the definitions of any particular debug message that is generated from a commercial phone that uses the QUALCOMM chips, we have to refer to the handset manufacturer who modifies the debug messages according to their development needs. In most cases, this information is proprietary and of no real use to anyone else but the handset manufacturer's development teams. Our group does not have access to the manufacturer's source code files, so we cannot offer any additional information. ASIC licensees that have questions about the debug message definitions used in the distributed code can send their requests to "support.cdmatech@qualcomm.com". For debug messages from QCTest and Deployment Products, we can investigate each request for definitions (or, to solve the problem reported) on a case-by-case basis with a binary log sample and problem description provided.

To find the definitions of any particular Event Report, use the QXDM Database Editor, which is included with QXDM and shown in the "QXDM Professional" Windows program group. Select the ITEM/CATEGORY TABLES tab, then select the EVENTS sub-tab. Select or double-click on the Event ID you need a definition for, and the DESCRIPTION FIELD will display. To see enumerated list of variables, select the PARSE/DISPLAY TABLES tab and locate the same Event ID and double-click and press the [VIEW...] button. Then, press [VIEW ENUM...] to see the possible enum entries for that Event ID. This will tell you the possible values for the Event ID's payload.


HOW TO COLLECT A DEBUG MESSAGE AND EVENT REPORT LOG
  • Select FILTERED VIEW (F12)
  • Right click and choose CONFIG
  • Select MESSAGES PACKETS
  • Enable FILTERED/REGISTER ON TARGET FOR ITEMS
  • Select KNOWN MESSAGES
  • Select EVENT REPORTS
  • Enable FILTERED/REGISTER ON TARGET FOR ITEMS
  • Select KNOWN EVENTS
  • Use the FILE->NEW ITEMS to restart logging
  • Use the FILE->SAVE ITEMS to save the logging session

How QXDM Configures the Target for Debug Message Logging

The debug message mechanism in DIAG is extremely broad and covers many systems and subsystems. There are many generations of debug messages that have different filtering capabilities on target. This filtering allows the target to only send the debug messages at a particular level (LOW, MEDIUM, HIGH, ERROR or FATAL, which is coded in the software for each message) and in later versions of debug messages (Extended Debug Messages) have not only levels but subsystem IDs (SSIDs) that allow you to filter messages both level, subsystem or combinations of both). QXDM can control the target to send debug messages based on matching criteria. This configuration is sent by QXDM and obeyed by the target in real time as the debug messages are sent to QXDM for display. Filtering on the QXDM side is essentially the same thing as configuring the target to send according to the level\SSID settings you choose on the MESSAGES VIEW in QXDM.


ONLY ERROR MESSAGES ARE SEEN OR LOGGED
It is entirely possible that the handset manufacturer has only implemented debug messages of ERROR level. The other possibility is that you have filtered out everything lower than the ERROR level in QXDM's Mobile Messages screen. Do this:

  • Select FILTERED VIEW (F12)
  • Right click and choose CONFIG
  • Select MESSAGES PACKETS
  • Enable FILTERED/REGISTER ON TARGET FOR ITEMS
  • Select KNOWN MESSAGES
  • Use the FILE->NEW ITEMS to restart logging
  • Use the FILE->SAVE ITEMS to save the logging session

If you still get only ERROR level messages, then this is a phone software issue. The handset manufaturer has implemented only ERROR level debug messages.


MSG_LEVEL
Legacy Debug Messages have message levels that are set in the source code of the D\AMSS and are used as a maximum level the mobile must provide during a logging session. QXDM allows you to pick and choose for display pleasure only on the Mobile Messages screen, but the logging mechanism still takes the level into account, and the D\AMSS provides everything at the lowest level and above.

Think of them as a filtering mechanism.

The message levels are as follows...

  • NONE (This level disables debug messages entirely)
  • FATAL (This logs FATAL level messages only)
  • ERROR (This logs FATAL and ERROR level messages only)
  • HIGH (This logs FATAL, ERROR and HIGH level messages only)
  • MED (This logs FATAL, ERROR, HIGH and MED level messages only)
  • LOW (This logs FATAL, ERROR, HIGH, MED and LOW level messages)

If you set the message level to HIGH, then you have instructed the phone to only send debug messages that are tagged at compile-time as HIGH, ERROR or FATAL. If you change the message level to LOW, then this tells the phone to send *ALL* debug messages across the serial link (LOW, MED, HIGH, ERROR and FATAL). Again, QXDM can filter out the levels you only want to see on the Messages view, but that is not exactly how the logging mechanism works.

For example, say you have all levels visible on the Messages view, and your phone is constantly providing MED and HIGH level messages. You configure QXDM to display just MED messages. Then, you begin logging. Although you only saw MED level messages in QXDM, the mobile provided MED and above messages across the DIAG link, and all of those were logged. BUT, your configuration of QXDM only displayed the MED ones.

Legacy Debug Messages have been made obsolete by the Extended Debug Messages, which are filterable further by specific subsystem, which makes post-processing and real-time filtering even more powerful and further defined by category.


DROPPED MESSAGES
There is a field in the Message Response Message (which holds the debug messages from the mobile that are displayed on the Mobile Messages screen) called DROP_CNT. The DMSS\AMSS can keep track of how many Debug Messages are dropped between the current message and the previous one. You can see this number on the Mobile Messages screen's status bar. This value is also logged by QXDM in the binary log file. It is a 4-byte value, starting at the 5th byte of the payload.

If the DMSS\AMSS generates the debug messages to fast for the DIAG tool to log, the DMSS\AMSS uses this field to track how many newly arrived messages are dropped.

This counter has nothing to do with other log packets or diagnostic commands.

QXDM only displays the most recently received dropped messages count in the status bar of the Mobile Messages window. There is no flag or indicator on the Mobile Messages screen that indicates when the counter suddenly changes to a non-zero value for a particular message. Furthermore, the contents of the Mobile Messages displays does not have a column for the dropped messages counter, so you cannot pause and scroll back to see what the count was at any particular message's time stamp. However, this can be easily done with a post-processor.


What Does LEGACY Contain?
Legacy category contains all subsystems prior to the creation of SSIDs (Extended Message). It is kept in QXDM for backwards compatibility.


WHAT DOES "KEY PRESSED = (number)" MEAN?
The "Key pressed = 81" appears to be a message generated by the user interface key handler. The number 81 is the decimal ASCII code that represents the key that was pressed. For example, [1] = 49, [2] = 50, [3] = 51, etc. All keys are mapped to specific characters. The Message Response Message also provides the source code filename and line number for each Debug Message.


WHAT DOES "EMPTY PAGE" MEAN?
Empty pages are normal. In slotted paging mode, the mobile wakes up to inspect General Page Messages. Sometimes by reading a GPM, the mobile will know that there are going to be no pages for itself in this slot. That is when this message get printed out to the debug screen. The MORE_PAGES bit tells the mobile if there are more page messages in the same slot. The phone cannot go back to sleep unless it sees the MORE_PAGES = 0, or the slot ends. The empty page message should not be causing the mobile to lose CDMA.



Mobile Station Maintained List
The mobile software's internally maintained lists are typically exposed through the DIAG interface by way of Mobile Debug Messages on the MESSAGES view within QXDM. If the DMSS does not already support debug messages that display this information, or if the handset manufacturer has not implemented them, then it is not possible.
(Example, showing which PN's the mobile has put in it's ACCESS_HO_LIST)

2009年4月7日星期二

用AT命令拨打CS call

有关AT命令的标准协议参见:
3GPP 27007

1. "AT+CREG?" --查询网络注册状态(关于此命令说明见另一篇文章)
2. "AT+CBST"-- Select bearer service type (用途?)
3. "ATDXXXXX;" -- 拨号(XXXXX为号码,在命令最后有一分号)
(拨号之前注意语音功能是否被屏蔽)

关于手动搜索网络(+COPS)超时

发送AT命令+COPS=?进行手动搜网时,整个搜网过程要在2min之内完成,如果在2min之内无法完成,则此次搜索就会abort,+COPS命令返回+CME ERROR: operation not allowed(可用网络列表的长度为-1)

启动定时器代码位置在:
//rrccsp.c
void rrccsp_update_bplmn_srch_vars( wtow_bplmn_srch_status_type status, sys_network_selection_mode_e_type nw_sel_mode)
{
...
rrctmr_start_timer(RRCTMR_BPLMN_GUARD_SRCH_TIMER, RRCTMR_BPLMN_GUARD_SRCH_TIMER_IN_MS);
...
}

RRCTMR_BPLMN_GUARD_SRCH_TIMER定义在:
//rrctmr.h
typedef enum
{
RRCTMR_T_300_TIMER, /* T300 Timer from SIB 1 */
RRCTMR_T_308_TIMER, /* T308 Timer from SIB 1 */
RRCTMR_WAIT_TIME_TIMER, /* Wait Time Timer from RRC Connection Reject
Message */
RRCTMR_UE_TO_CAMP_ON_TIMER, /* Timer for UE to camp on, if not already */
RRCTMR_RRC_CON_DELAY_TIMER, /* Timer for UE to delay RRC Conn Release */
RRCTMR_RCE_L2ACK_TIMER, /* Timer to receive L2 ACK in acknowledged
mode transmission for RCE procedure */
RRCTMR_RCR_L2ACK_TIMER, /* Timer to receive L2 ACK in acknowledged
mode transmission for RCR procedure */
RRCTMR_T_304_TIMER, /* T304 Timer from SIB 1 */
RRCTMR_RSSI_BER_TIMER, /* Timer to periodically report RSSI & BER
to CM */
RRCTMR_SIB_WAIT_TIMER, /* Timer for maximum time to wait for SIBs
in a cell */
RRCTMR_T_302_TIMER, /* T302 timer for CELL UPDATE retransmission */
RRCTMR_T_305_TIMER, /* T305 timer for periodic CELL UPDATE */
RRCTMR_T_316_TIMER, /* T316 Timer for Out of Service Area in
CELL_PCH and URA_PCH state */
RRCTMR_T_317_TIMER, /* T317 Timer for Out of service Area in
CELL_FACH state */
RRCTMR_T_307_TIMER, /* T307 Timer is max time for UE to get into
In Service after T305 is expired */
RRCTMR_T_314_TIMER, /* T314 Re-establish timer */
RRCTMR_T_315_TIMER, /* T315 Re-establish timer */
RRCTMR_SIB7_EXP_TIMER, /* Timer for SIB7 Expiration */
RRCTMR_IGNORE_BCCH_MOD_TIMER, /* Timer to Ignore BCCH Modifcation Info IE
if RRC is already processing one */
RRCTMR_DCH_FACH_CELL_SELECTION_TIMER, /* Timer started during cell selection
going DCH->FACH
*/
#ifdef FEATURE_RRC_FREQ_REDIRECTION_THRU_RB_AND_CU
RRCTMR_FACH_TO_FACH_PCH_CELL_SELECTION_TIMER, /* Timer started during cell selection
going FACH->FACH/PCH
*/
#endif /* FEATURE_RRC_FREQ_REDIRECTION_THRU_RB_AND_CU */
RRCTMR_L1_DEADLOCK_DETECT_TIMER, /* Timer to detect L1 deadlocks */
RRCTMR_DELAY_ERR_FATAL_TIMER, /* Timer to delay ERR_FATAL */
RRCTMR_DCH_PCH_CELL_SELECTION_TIMER, /* Timer started during cell selection
going DCH->CELL_PCH or DCH->URA_PCH*/
RRCTMR_T_3174_TIMER, /* T3174 GTOW PCCO timer */
RRCTMR_FREQ_SCAN_TIMER, /* Timer indicating if FREQ_SCAN should be
initiated or not */
RRCTMR_T_OOS_TIMER, /* Timer indicating if UE can not select a cell
after OOS detection */
RRCTMR_PHY_CHAN_FAILURE_TIMER, /* Phy Chan Failure timer used when initiating Cell Selec when
we get a phy_chan_failure after a rrc conn setup */
RRCTMR_DEEP_SLEEP_NO_SVC_TIMER, /* Time duration for which no service should be
returned to NAS */
RRCTMR_BPLMN_SRCH_TIMER, /* Timer for background PLMN search from 2G->3G */
RRCTMR_BPLMN_FREQ_SCAN_TIMER, /* Timer indicating if FULL FREQ SCAN should be
initiated or not for a 2G->3G BPLMN srch request */
#ifdef FEATURE_MANUAL_SEARCH_FREQ_SCAN_SKIP_TIMER
RRCTMR_MANUAL_PLMN_FREQ_SCAN_TIMER, /* Timer indicating if FULL FREQ SCAN
should be done or not for a Manual PLMN search */
#endif
RRCTMR_FREQ_REDIRECT_WAIT_TIMER, /* Timer for inter frequency redirection */
RRCTMR_CONN_MODE_OOS_TIMER, /* Timer for OOS in Connected Mode */
RRCTMR_WTOW_BPLMN_DRX_SRCH_TIMER, /* Timer for 3G->3G BPLMN DRX tmr expiry*/
RRCTMR_BPLMN_GUARD_SRCH_TIMER /* Max Timer to complete 3G->3G, 2G BPLMN search */

#ifdef FEATURE_INACTIVITY_HANDLING

, RRCTMR_INACTIVITY_TIMER /* Timer for inactivity handling */

#endif /* FEATURE_INTACTIVITY_HANDLING */

#ifdef FEATURE_SIX_HRS_SIB_CLEAN_UP
,RRCTMR_SIXHR_SIB_UPDATE_TIMER /* Timer for six hr sib clean up*/
#endif

#ifdef FEATURE_UMTS_UNIFORM_OOS_HANDLING
, RRCTMR_UNIFORM_OOS_SEARCH_TIMER
#endif

#ifdef FEATURE_DEEP_SLEEP_REL6_OUT_OF_SERVICE_ENHANCEMENT
, RRCTMR_CONN_MODE_OOS_INITIAL_NO_DS_TIMER
, RRCTMR_CONN_MODE_OOS_DS_TIMER
#endif

,RRC_SIB_CHANGE_GUARD_TIMER /* Timer for sib change guard handling */
,RRC_BCCH_MODIFICATION_TIMER /* Timer for BCCH Modification timer handling */

#ifdef FEATURE_MODEM_MBMS
#error code not present
#endif

#ifdef FEATURE_GTOW_REDIRECTION_AFTER_CONN_RELEASE
#error code not present
#endif
}

RRCTMR_BPLMN_GUARD_SRCH_TIMER_IN_MS定义在:
//rrccspi.h
/* Maximum time allowed for completing background PLMN search */
#define RRCTMR_BPLMN_GUARD_SRCH_TIMER_IN_MS 120000UL //ms

RRCTMR_BPLMN_GUARD_SRCH_TIMER定时器的启动和终止:
rrccsp_update_bplmn_srch_vars
{
...
switch(status) {
case WTOW_SEARCH_START:
MSG_HIGH("WTOW: BPLMN srch vars init to start BPLMN search", 0, 0, 0);
...
rrctmr_start_timer(RRCTMR_BPLMN_GUARD_SRCH_TIMER, RRCTMR_BPLMN_GUARD_SRCH_TIMER_IN_MS);
rrc_csp_int_data.bplmn_guard_srch_tmr_expired = FALSE;
...
break;

...

case WTOW_SEARCH_STOP:
case WTOW_SEARCH_ABORT:
MSG_HIGH("WTOW: Aborting/Stopping BPLMN search", 0, 0, 0);
...
if (!rrc_csp_int_data.bplmn_srch_tmr_expired) {
rrctmr_stop_timer(RRCTMR_WTOW_BPLMN_DRX_SRCH_TIMER);
rrc_csp_int_data.bplmn_srch_tmr_expired = TRUE;
}
if (!rrc_csp_int_data.bplmn_guard_srch_tmr_expired) {
rrctmr_stop_timer(RRCTMR_BPLMN_GUARD_SRCH_TIMER);
rrc_csp_int_data.bplmn_guard_srch_tmr_expired = TRUE;
}
...
break;
...
}

在QXDM LOG中查找是否有此定义器超时发生,可以搜索:
expired timer:35
如下所示:
Day 0   00:12:11.504 [4A]       0x1FEB Extended Debug Message         
rrctmr.c        591     H       Expired timer:35           Drop count = 0