國
立
交
通
大
學
網路工程研究所
碩
士
論
文
手 機 之 自 動 以 事 件 驅 動 指 定 轉 接 機 制
Automatic Event-Triggered Call Forwarding
Mechanism for Mobile Phones
研 究 生:吳政翰
指導教授:林一平 教授
手 機 之 自 動 以 事 件 驅 動 指 定 轉 接 機 制
Automatic Event-Triggered Call Forwarding
Mechanism for Mobile Phones
研 究 生:吳政翰 Student:Zheng-Han Wu
指導教授:林一平 博士 Advisor:Dr. Yi-Bing Lin
國 立 交 通 大 學
網 路 工 程 研 究 所
碩 士 論 文
A Thesis
Submitted to Institute of Network Engineering
College of Computer Science
National Chiao Tung University
in partial Fulfillment of the Requirements
for the Degree of
Master
in
Computer Science
July 2011
Hsinchu, Taiwan, Republic of China
手機之自動以事件驅動指定轉接機制
指
立
通
網路
程
指定轉接 (Call Forwarding) 電信 用 手機來電轉接 電話 指定轉接 用 手動 定啟用 取消 用 論文 手機 自動 指定轉接演算法 (Call Forwarding Algorithm CFA) 手機 CFA
事件 手機 電 機 自動啟用指定轉接
手機 電 機 以自動取消指定轉接
分析 測 來 指定轉接演算法
指 指定轉接演算法 以 用 用
Automatic Event-Triggered Call Forwarding
Mechanism for Mobile Phones
Student: Zheng-Han Wu
Advisor: Dr. Yi-Bing Lin
Institute of Network Engineering
National Chiao Tung University
ABSTRACT
Call forwarding is a traditional telecom service that allows a user to forward incoming calls to another telephone number. This service requires the user to manually activate and deactivate the feature, and therefore may not be very convenient. This paper proposes an automatic Call Forwarding Algorithm (CFA) for mobile phones. By installing a software in a smartphone, call forwarding is automatically triggered (e.g., when the phone is plugged in a charger or is turned off) or disabled (e.g., when the phone is unplugged from the charger or is turned on). We also investigate the performance of CFA through analytic analysis, simulation, and measurement. Our study indicates that CFA is very feasible for commercial usage.
誌
謝
謝 指 以 法 事 指 論 文 接 謝 建 謝 謝 指 建 謝 之 論文文 · · · · i ABSTRACT · · · · ii 誌謝 · · · iii · · · · iv · · · · vi · · · vii 章 · · · · 1 1.1 指定轉接演算法 (CFA) 之概念 . . . 1 1.2 執行 CFA 之電信網路環境 . . . 2 1.3 論文章節架構 . . . 3
章 CFA 之 程 (Message Flow) · · · · 4
2.1 CFA 啟用程序 (Activation Procedure) . . . 4
2.2 來電通話建立程序 (Incoming Call Setup Procedure) . . . 5
2.3 CFA 取消程序 (Deactivation Procedure) . . . 7
2.4 CFA 延遲分析 . . . 8
章 CFA 通知 (Notification) 失敗 (Failure) 偵測 · · · 12
3.1 CFA 通知程序 (Notification Procedure) . . . 12
3.2 CFA 啟用程序之失敗偵測 (Failure Detection) . . . 14
章 論 來 · · · 21
文 · · · 22
A 程 · · · 23
1.1 指定轉接之網路架構 . . . 3 2.1 CFA 啟用程序 . . . 5 2.2 來電通話建立程序 . . . 6 2.3 CFA 取消程序 . . . 7 2.4 pc之 . . . 8 2.5 E[tc]/E[ta] Va pc (tc 指 分 ) . . . 11 3.1 CFA 通知程序 . . . 13 3.2 α m ps (E[ta] = 7.88266 Va = 0.0139717E[ta]2) . . . 17 3.3 α Va ps (m = 20) . . . . 18 B.1 CFA 用之 . . . 55 B.2 轉接 . . . 56 B.3 轉接 取 . . . 57 B.4 轉接 取 . . . 57 B.5 啟用 偵測電 . . . 58 B.6 偵測 電 啟用指定轉接 . . . 59 B.7 偵測 電 取消指定轉接 . . . 59
tc 通話 (inter-call arrival time) ta CFA 啟用程序之延遲 τc CFA 執行啟用程序 通來電 pc τc< ta 機 T ps ta < T 機
章
手機用 手機 (User Equipment UE) 機
電 用 手機 接電話 來 電話 自動 轉接 機電話 分機 以 用 手機 接 電話 電信 指定轉接 用 手動 定啟用 手動 定 程序 用 指定轉接 取消指定轉接 定 手機 法 接 來電通話 自動以事件 之指定轉接演算法 (Call
Forwarding Algorithm CFA) 用 以 手機
法 動 電信網路
1.1
指定轉接演算法 (CFA) 之概念
CFA 概念以 Microsoft Windows CE (WinCE) CFA
法 CFA 法 以 分 Part 1. 偵測 事件: 手機 機 手機 電 事件 CFA 程 自 動 偵 測 事 件 啟 用 指 定 轉 接 用 WinCE RegistryNotifyCallback [1] 來 測電 以 自動偵測 事件 手機 事件 ( 章 以 ) Part 2. 轉接 ( 手機來電 轉接 電話 ): 偵測 事件 手 機 轉接 (forwarded-to number)
Global Positioning System (GPS) 定 手機 以 Assisted GPS (A-GPS) 知 來 轉接 測 定 定 (location ambiguity) 手機 以 來 轉接 手機 用 用 取 以 轉接 定 手機 以自動 轉接 用 Part 3. 啟用指定轉接 轉接 之 手機 以自動 電信網路執行 指定轉接 程序 用 WinCE lineForward [1] 來 Part 4. 取消指定轉接 啟用指定轉接 事件消失 取消指定轉接 手機 電 手機 自動 電信網路執行 指定轉接 程序來取消指定轉接 Part 3 用 lineForward 來 取消指定轉接
1.2
執行 CFA 之電信網路環境
用 Universal Mobile Telecommunications System (UMTS) 網路架構來
指 定 轉 接 [2][3] 1.1 架 構 手 機
用 (UE1 1.1 (1)) 通 serving Mobile Switching Center
(MSC)/Visitor Location Register (VLR 1.1 (2)) 接 以接 電信 MSC VLR
分 通話程序 (call processing) 行動 (mobility management) 手機
指 E.164 行動電話 ( UE1 0911111111)
Gateway Mobile Switching Center (GMSC 1.1 (3)) 話 通 UE1 電話 UE1 GMSC Home Location Register
(HLR 1.1 (4)) 以 手機 用 MSC/VLR
MSC/GMSC 接 電話網路 (Public Switched Telephone Network PSTN 1.1 (5)) PSTN Service Switching Points (SSPs 1.1 (6) (7)) 通話程序
電話 機
架構 用 電信 件指定轉接 (call forwarding
(2)
MSC/
VLR
(3)
GMSC
(1) UE1
0911111111
(5) PSTN
(8) Phone1
031111111
(6) SSP1
(7) SSP2
(9) Phone2
(4) HLR
1.1: 指定轉接之網路架構1.3
論文章節架構
論 文 手 機 自 動 指 定 轉 接 演 算 法 (Call ForwardingAlgorithm CFA) 法 手機 CFA 事件
手機 電 機 自動啟用指定轉接 手機
電 機 以自動取消指定轉接 分析
測 來 指定轉接演算法 指 指
定轉接演算法 以 用 用 論文章節架構
1. 章 CFA 之 程 (message flow) 以 分析 CFA 之延遲
2. 章 CFA 通知程序 CFA 啟用程序之失敗偵測 接 以 分析
3. 章 CFA (Telematics) 之 用
章 CFA 之
程 (Message Flow)
章節 CFA 啟用程序 (activation procedure) 來電通話建立程序 (incoming call
setup procedure) 取消程序 (deactivation procedure) 程 UE1 (user 1
UE) CFA Phone1 (user 1 機 1.1 (8)) 031111111
轉接 啟用指定轉接 之 UE1 來電 Phone1 接
CFA 啟用程序 來電 機 以 CFA
2.1
CFA 啟用程序 (Activation Procedure)
user 1 UE1 電 UE1 CFA 程 偵測 電 電
接 CFA 啟用程序 自動執行 3rd Generation Partnership Project (3GPP) 指定
轉接 程序 [3][4] 2.1 來 CFA 啟用程序
Step A.1. WinCE RegistryNotifyCallback 偵測 電 CFA 自動
**21*031111111# 21 電信 件指定轉接
031111111 轉接 電信 指定轉接
MSC/VLR ( 1.1 (2)) Signaling System Number 7 (SS7) 信
MAP REGISTER SS request HLR ( 1.1 (4)) 指定轉接 指
UE1 啟用 件指定轉接 轉接 定 031111111
Step A.2. HLR UE1 啟用指定轉接 HLR 轉
接 SS7 MAP REGISTER SS response 通知 MSC/VLR 程序
HLR
HLR
A.1 SS7 MAP_REGISTER_SS request
A.2 SS7 MAP_REGISTER_SS response
MSC/
VLR
0911111111
031111111
A.2 Call Forwarding Mapping
UE1
0911111111
2.1: CFA 啟用程序
2.2
來電通話建立程序 (Incoming Call Setup Procedure)
user 1 啟用 指定轉接 之 user 2 ( 2.2 (9)) user 1 手機
091111111 通話建立程序 2.2
Step B.1. SSP2 ( 1.1 (7)) SS7 信 Initial Address Message (IAM) 091111111
(UE1) GMSC ( 1.1 (3))
Step B.2. GMSC SS7 MAP SEND ROUTING INFORMATION request HLR
通通話 路 (routing)
Step B.3. HLR SS7 MAP SEND ROUTING INFORMATION response 轉接 031111111 (Phone1) SSP1 routing number (SS7 )
Step B.4. GMSC SS7 IAM 轉 SPP1
Step B.5. SSP1 Phone1 SS7 Address Complete Message (ACM)
Step B.6. user 1 接 Phone1 SSP1 SS7 Answer Message (ANM) GMSC SSP2
Step B.6 user 1 user 2 電話 接通 話
B.1 SS7 IAM
B.4 SS7 IAM
B.3 SS7 MAP_SEND_ROUTING
_INFOMATION response
B.5 SS7 ACM
B.5 SS7 ACM
B.6 SS7 ANM
B.6 SS7 ANM
Conversation
B.2 SS7 MAP_SEND_ROUTING
_INFOMATION request
SSP2
GMSC
SSP1
0911111111
031111111
Call Forwarding Mapping
HLR
Phone2
Phone1
031111111
2.3
CFA 取消程序 (Deactivation Procedure)
user 1 UE1 電 UE1 CFA 程 偵測 事件 自動執行
CFA 取消程序 CFA 取消程序 3GPP 指定轉接 程序 [3][4] 來取消指定轉
接 以 2.3 以 來 CFA 取消程序
Step C.1. Step A.1 WinCE RegistryNotifyCallback 偵測 UE1 電
事件 UE1 CFA 程 自動 ##21# 接 MSC/
VLR SS7 MAP ERASE SS request HLR 指 UE1 取消指定轉接
Step C.2. HLR UE1 轉接 SS7 MAP ERASE SS response 知 程序
CFA 取消 UE1 來電 轉接 Phone1 UE1
C.1 SS7 MAP_ERASE_SS request
C.2 SS7 MAP_ERASE_SS response
HLR
MSC/
VLR
UE1
0911111111
2.3: CFA 取消程序2.4
CFA 延遲分析
User 1 UE1 電 之 UE1 來電 轉接 Phone1
來電 CFA 啟用程序 UE1 user 1
來電 Phone1 通 UE1 來電 user 1 UE1
電 接 通電話 以 分析 接來電 機 以 以 用 通知機制 (notification mechanism) 來 章 以 通知機制 pc 來電 CFA 啟用程序執行 ( 3GPP 指定轉接 程序 ) UE1 機 用 來 pc
t
cCall arrives
Call arrives
CFA activation starts
CFA activation ends
t
atime
τ
c2.4: pc之
2.4 pc tc 通話 (inter-call arrival time)
ta CFA 啟用程序 ( 2.1 Step A.1-A.2) 之延遲 τc CFA 執行啟用程
序 通來電 τc 通話 (excess
life) pc τc < ta 機
tc (mean) 1/λ 指 分 (exponential distribution) 來電
程 (Poisson process) ta 機分 (arbitrary distribution)
(density function) 轉 (Laplace transform) 分 fa(·) fa∗(s) 指
以 pc pc = P r[τc< ta] = ∫ ∞ ta=0 fa(ta) ∫ ta τc=0 λe−λτcdτ cdta = 1− fa∗(λ) (2.1)
ta 機 (Gamma random variable) 轉 fa∗(s) =
(
µ s + µ
)k
k (shape parameter) µ (rate parameter)
程 (2.1) 以 pc= 1− ( µ λ + µ )k (2.2)
用 分 (Gamma distribution) 分 電信 (telecom modeling)
用 ( [5][6] 文 ) 用 法 (Monte Carlo
simulation) 來 程 (2.2) 法 延遲 τc ta 延
遲 來 pc 程 (2.2) 0.2%
以
測 電信 用 UMTS ta CHT 9110
Microsoft Windows Mobile 6.0 手機 CFA 執行 3000
以 CFA 啟用程序來 延遲 ta ta E[ta] = 7.88266
(variance) Va= E[t2a]− E[ta]2 = 0.0139717E[ta]2
測 E[ta] ( 7.88266 ) 100E[ta]≤ E[tc] ≤ 1000E[ta]
( 通話 13 分 2.18 ) 2.5 E[tc]/E[ta] Va
pc (來電 CFA 啟用程序 UE1 機 )
E[tc]/E[ta] pc Va
pc 以 以 定
Va pc
測 電信網路 Va 0.1% 1% 來電 CFA 啟用
程序 UE1 來電 CFA 執行啟用程序 8 以
user 1 UE1 user 1 以 手機 接
電話 以 電信網路 Va Va ta
ta 來電 user 1 UE1 之 ( CFA
啟用程序 之 ) UE1 用
手機 接 電話 ( 2.5 機 pc < 0.2%)
0
0.002
0.004
0.006
0.008
0.01
p
c10
−410
−310
−210
−110
010
110
210
310
4V
a(unit: E[t
a]
2)
•: E[t
c] = 100E[t
a]
⊳: E[t
c] = 400E[t
a]
⋆: E[t
c] = 700E[t
a]
×: E[t
c] = 1000E[t
a]
...•
•
•
•
•
•
•
•
•
...⊳
⊳
⊳
⊳
⊳
⊳
⊳
⊳
⊳
...⋆
⋆
⋆
⋆
⋆
⋆
⋆
⋆
⋆
...×
×
×
×
×
×
×
×
×
2.5: E[tc]/E[ta] Va pc (tc 指 分 )章 CFA 通知 (Notification)
失敗 (Failure)
偵測
User 1 UE1 電 動 ( 動 )
用 CFA 啟用程序 之 知 CFA 程 啟用指定轉接
來電轉接 機 章節 CFA 通知程序 (notification procedure) 來
用 CFA 啟用程序 以 程序 用
(timer) T 機制 (threshold mechanism) 來通知 user 1 指定轉接啟用程序執行失
敗 CFA 通知程序 以用來 知 uesr 1 指定轉接啟用程序 執行 失敗 ( T
)
3.1
CFA 通知程序 (Notification Procedure)
以 3.1 CFA 通知程序
Step D.1. UE1 CFA 程 自動 轉接 031111111 建立 Phone1 通話
接 MSC/VLR SS7 IAM 信 SSP1
Step D.2. SSP1 Phone1 SS7 ACM 信 MSC/VLR MSC/VLR 通 知 UE1 Phone1
Step D.3. user 1 接 Phone1 之 SSP1 SS7 ANM 信 MSC/VLR
通 (voice announcement) UE1 CFA 程 知 user 1 指定轉接 啟用
來電 CFA 啟用程序執行 UE1
程 0.1% 1% UE1 來電 ( 2.4 章節) 通知 user 1
通 user 1 ( 1 ) 來 知指定轉接啟用
1 程 取消指定轉接
Step D.4. user1 Phone1 之 SSP1 SS7 Release (REL) 信 MSC/VLR
以 通話
Step D.5. MSC/VLR SS7 Release Complete (RLC) 信 SSP1 程序
啟用指定轉接 之 UE1 電 UE
UE1 程序之 機 user 1 Step D.3 指定轉接
啟用
D.1 SS7 IAM
D.2 SS7 ACM
D.5 SS7 RLC
D.4 SS7 REL
D.3 SS7 ANM
Voice Announcement
MSC/
VLR
SSP1
UE1
0911111111
Phone1
031111111
3.1: CFA 通知程序3.2
CFA 啟用程序之失敗偵測 (Failure Detection)
CFA 啟用程序之失敗偵測 用 T 來 算
CFA 啟用程序執行 程 測 執行 ta UE1 CFA 程
m ta ta,i i ta UE1 CFA 程 執行 CFA 啟
用程序 T 算 T = α ( m ∑ i=1 ta,i ) m (3.1) α > 1 用來 T ta CFA 啟用程序 T ( CFA 程 T HLR )
CFA 啟用程序執行失敗 CFA 通知程序 知 user 1 指定轉接 啟用
失敗 程 (3) α 定 CFA 程 啟用 指定轉接 定取 消 α 定 程 法 偵測 CFA 啟用程序 失敗 α 以 分析 電信網 路環境 α = 1.5 以 用 CFA 啟用程序之失敗偵測 Va(ta ) 之 CFA 啟用程序之失敗偵測 ps = P r[ta < T ] CFA 啟用程序 T 執行 機 ps CFA 啟用程序之失敗偵測
ta 機 (random variable) (density function)
轉 (Laplace transform) 分 fa(·) fa∗(s) T 機 轉 分 fT(·) fT∗(s) 程 (3.1) T = m ∑ i=1 ( αta,i m ) T 分 轉 fT∗(s) = [ fa∗ (αs m )]m (3.2)
ta 機 (Erlang random variable) (shape parameter) (rate parameter) 分 k µ 轉 分 fa(ta) = µktk−1 a e−µta (k− 1)! f ∗ a(s) = ( µ s + µ )k (3.3) 程 (3.3) 程 (3.2) 以 fT∗(s) = αsµ m + µ km = ( mµ αs + mµ )km (3.4) 分 分 分 (hyper-Erlang distribution) 分 測 來 分 法 [7][8] 程 (3.3) 程 (3.4) 以 ps ps = P r[ta < T ] = ∫ ∞ T =0 fT(T ) ∫ T ta=0 fa(ta)dtadT = ∫ ∞ T =0 fT(T ) [ 1− k−1 ∑ i=0 e−µT(µT )i i! ] dT = 1− k−1 ∑ i=0 [ µi(−1)i i! ] [ dif∗ T(s) dsi s=µ ] = 1− k−1 ∑ i=0 ( α α + m )i[ (km + i− 1)! i!(km− 1)! ] ( m α + m )km (3.5) 程 (3.5) 用來 ( 2.4 章節 法) 分析 ( 程 (3.5)) 0.1% 以 論文 分 用 來 CFA 啟用程序之失敗偵測
ta分 (Erlang ta distribution) ta分 (Gamma tadistribution) 接 用 ta 分 E[ta] = 7.88266 Va = 0.0139717E[ta]2 來 電信 網路環境 測 ( 2.4 章節 ) 測 ta 3.2 α m 分 ps α ps 3.2 (a) α (α ≤ 1.3) 測
(lower bounds) α (α ≥ 1.5) 測 (upper
bounds) ta分 測 ps α (α≥ 1.5) ps 接 3.2 (b) m ≥ 20 ps m 之 動 話 CFA 20 ta 以用來 算 程 (3.1) T m = 20 α ≥ 1.5 測 ps 0.5% 以 3.2 電信網路環境 α (α = 1.5) 以 ps ( ps > 0.99) Va 電信網路環境 3.3 Va (ta 分 ) ps 以 以 Va ( Va< E[ta]2) Va ta ta ta ps Va ( Va > 10E[ta]2) Va ta ta ta ta 以 ps α = 4.5 ( E[T ] = 35.47197 ) 論 Va ps 0.9
0.5
0.6
0.7
0.8
0.9
1
p
s1
1.2
1.4
1.6
1.8
2.0
α
Dashed: Measurement
Solid: Simulation
•: m = 1
⊳: m = 10
⋆: m = 20
. . ...•
•
•
•
•
•
•
•
•
•
•
. . . ...⊳
⊳
⊳
⊳
⊳
⊳
⊳
⊳
⊳
⊳
⊳
. ...⋆
⋆
⋆
⋆
⋆
⋆
⋆
⋆
⋆
⋆
⋆
. . . . . . . ... . . . . . . . . . . . . . . . . . . . . . . . . . . ... . . . . ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... . . . ... . . . . . . . . . . . . . . . . . . ... . . . . . ... ... . . . . ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...•
•
•
•
•
•
•
•
•
•
•
. . . . . . . . ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... . . . . . . . . . . ... . . . . . . . ... . . . . . ... . . . . . . . . . .... . . . . . . ... . . . . . . . . . . . . . . . . . . . ... . . . . . . . . . .... . . . ... . ... . . . ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...⊳
⊳
⊳
⊳
⊳
⊳
⊳
⊳
⊳
⊳
⊳
. . . . . . . . ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... . . . . . . . . . .... . . . . . . ... . . . ... . . . . . . ... . . . . ... . . . . . . . . . .... . . . . . . . ... . . . ... . . . . . ... . . ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...⋆
⋆
⋆
⋆
⋆
⋆
⋆
⋆
⋆
⋆
⋆
(a) α0.95
0.96
0.97
0.98
0.99
1
1
5
10
15
20
25
m
Dashed: Measurement
Solid: Simulation
•: α = 1.5
⊳: α = 2
. . ...•
•
•
•
•
•
. ...⊳
⊳
⊳
⊳
⊳
⊳
. ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...•
•
•
•
•
•
. ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ..⊳
⊳
⊳
⊳
⊳
⊳
(b) m 3.2: α m ps (E[ta] = 7.88266 Va = 0.0139717E[ta]2)0.75
0.8
0.85
0.9
0.95
1
p
s10
−410
−310
−210
−110
010
110
210
3V
a(unit: E[t
a]
2)
•: α = 1.5
⊳: α = 2.5
⋆: α = 3.5
×: α = 4.5
...•
•
•
•
•
•
•
•
...⊳
⊳
⊳
⊳
⊳
⊳
⊳
⊳
...⋆
⋆
⋆
⋆
⋆
⋆
⋆
⋆
...×
×
×
×
×
×
×
×
3.3: α Va ps (m = 20)章 CFA
(Telematics) 之
用
用 用 (Personal Navigation Device PND) GPS 定 行動通 ( GSM GPRS UMTS) 用 手 電話 用 啟 PND 之 來電 轉接 PND 來電 用 用手 接電話 ( 之 用 電話 PND 電話) 手 電話 分 (wire-line) (bluetooth) 法 法 用 手動 行動電話 通 接 user 1 PND 偵測 事件 PND 啟 CFA 程 自動指定轉接 用 PND 電信 偵測 事件PND UE1 以啟用 取消指定轉接 CFA 程 執行 user 1
啟 PND 之 以 執行
Step E.1. PND GPS 接 取 UE1 PND
GPS 以啟用指定轉接 來電轉接 PND 電話
Step E.2. UE1 之 UE1 CFA 程 用 A-GPS 機制
UE1 PND 接
( 10 以 ) CFA 程 UE1 通知 user 1 以
用 啟用指定轉接 User 1 以接 (
) 指定轉接啟用 接 程 執行 CFA 啟用程序 ( 2.1 章節 )
Step E.3. UE1 CFA 程 PND 知 CFA 啟用程序執行 接
PND 通 (voice announcement) 知 user 1
程 GPS 接 UE1 CFA 程 取 GPS GPS
接 以 手機 電 消
user 1 PND ( ) 指定轉接 自動 取消
Step F.1. 機 PND UE1 以取消指定轉接
Step F.2. 接 PND 來 UE1 CFA 程 執行 CFA 取消程序 ( 2.3 章
節 )
用 PND 用
PND 以定 執行 E.1 E.3 以 UE1 GPS
章
論
來
論文 手機 自動 指定轉接演算法 (Call Forwarding
Algo-rithm CFA) 定 機 手動啟用指定轉接 用 來 程序 事件 手機 電 電 機 ... 偵測 事件 CFA 程 自動啟用指定轉接 CFA 程 用 指定轉接啟用 取消程序 論程序 執 行 CFA 程 執行 知 用 T CFA 程 T 知 用 執行 電信網路環境 測 CFA 程 以 用 用 手機 CFA 電信網路環境
手 IBM WebSphere software for Telecom (WsT) IBM WsT Next Generation Network (NGN) / IP Multimedia Subsystem (IMS) 網路
知 網路
用程 (Application Programming Interfaces APIs) 知
網路 IBM WsT 電信 NGN / IMS 接 電信 指定轉接 用 用 手機啟用指定轉接 來電轉接 電話 ( 電話 ... ) 用 手機取消指 定轉接 用 自動 用 手機啟 用指定轉接 自動取消指定轉接 IBM WsT 行指定轉接 用 以 指定轉接 用
文
[1] MSDN library. Available: http://msdn.microsoft.com/en-us/default.aspx
[2] Yi-Bing Lin and Ai-Chun Pang, Wireless and Mobile All-IP Networks. John Wiley & Sons, Inc., 2005.
[3] 3GPP. 3rd Generation Partnership Project; Technical Specification Group Core Network and Terminals; Call Forwarding (CF) supplementary services; Stage 3. Technical Specifi-cation 3G TS 24.082 version 9.0.0 (2009-12), 2009.
[4] 3GPP. 3rd Generation Partnership Project; Technical Specification Group Core Network and Terminals; Mobile Application Part (MAP) specification. Technical Specification 3G TS 29.002 version 9.2.0 (2010-06), 2010.
[5] Shun-Ren Yang, Dynamic power saving mechanism for 3G UMTS system, ACM/ Springer Mobile Networks and Applications, 12(1): 5-14, 2007.
[6] Yen-Cheng Lai, Phone Lin, Yuguang Fang, Wei-Hao Chen, Channel allocation for UMTS multimedia broadcasting and multicasting, IEEE Transactions on Wireless Com-munications, 7(11): 4375-4383, 2008.
[7] Yuguang Fang and Imrich Chlamtac, Teletraffic analysis and mobility modeling of PCS networks, IEEE Transactions on Communications, 47(7):1062-1072, July 1999.
A
程
程 A.1: my Call Forwarding testing.h
1 // my_Call_Forwarding_testing .h : PROJECT_NAME 用程 2 // 3 4 # pragma once 5 6 # ifndef __AFXWIN_H__ 7 # error " PCH 'stdafx .h'" 8 #endif 9 10 #ifdef POCKETPC2003_UI_MODEL 11 # include " resourceppc .h" 12 #endif 13 14 // //////////////////////////////////////////////////////////// 15 # include <regext .h> 16 # include <snapi.h> 17 # include <tapi.h> 18
19 typedef struct __CALLFORWARDING_INFO_TAG__
20 { 21 DWORD dwMode ; 22 int nSeconds ; 23 // CString strNumber ; 24 TCHAR strNumber [32]; 25 } CALLFORWARDING_INFO , * PCALLFORWARDING_INFO ;
26 // //////////////////////////////////////////////////////////// 27 28 // Cmy_Call_Forwarding_testingApp : 29 // my_Call_Forwarding_testing .cpp 30 // 31
32 class Cmy_Call_Forwarding_testingApp : public CWinApp
33 { 34 public : 35 Cmy_Call_Forwarding_testingApp (); 36 37 // 38 public :
39 virtual BOOL InitInstance ();
40
41 // 程
42 protected :
43 CString str_dir_path ; 44
45 public : // battery state changing
46 HRESULT register_app (); // register notification for
battery state changing
47 HRESULT unregister_app (); // unregister notification 48 CString get_dir_path ();
49
50 public : // call forwarding
51 long initialize_TAPI ();
52 void shutdown_TAPI ();
53 DWORD GetCellularLineId ();
54 HLINE OpenTAPILine (DWORD dw_line_id ); 55 DWORD ProcessCallForwarding (TCHAR * tmpPtr );
56 LPLINEFORWARDLIST AllocateCallForwardList ( PCALLFORWARDING_INFO
pInfo ,int nEntries );
58 void test_func () { MessageBox (NULL , TEXT("test test"), TEXT(" title "), MB_OK); } 59 60 DECLARE_MESSAGE_MAP () 61 }; 62
程 A.2: my Call Forwarding testingDlg.h 1 // my_Call_Forwarding_testingDlg .h : 2 // 3 4 # pragma once 5 # include " afxwin .h" 6 7 // Cmy_Call_Forwarding_testingDlg 話
8 class Cmy_Call_Forwarding_testingDlg : public CDialog
9 {
10 // 建構
11 public :
12 Cmy_Call_Forwarding_testingDlg (CWnd* pParent = NULL); // 建
構
13
14 // 話
15 enum { IDD = IDD_MY_CALL_FORWARDING_TESTING_DIALOG };
16
17 protected :
18 virtual void DoDataExchange ( CDataExchange * pDX); // DDX/DDV
19
20 protected :
21 virtual void OnOK ();
22 23 // 程 24 protected : 25 HICON m_hIcon ; 26 27 //
28 virtual BOOL OnInitDialog ();
29 #if defined ( _DEVICE_RESOLUTION_AWARE ) && ! defined ( WIN32_PLATFORM_WFSP
)
31 #endif
32 DECLARE_MESSAGE_MAP () 33
34 public :
35 BOOL update_state (); // update window info & do call
forwarding
36 afx_msg void OnEnChangeEditAddPhone (); 37 afx_msg void OnBnClickedButtonStart (); 38 afx_msg void OnBnClickedButtonDelete (); 39 afx_msg void OnBnClickedButtonAdd (); 40 afx_msg void OnBnClickedButtonQuit (); 41
42 private : // read or write saved data (phone number & comment )
43 HRESULT register_callback (); 44 HRESULT unregister_callback (); 45 bool write_phone_data (); 46 bool write_state_data (); 47 48 protected :
49 // System . Windows .Forms.Timer obj_timer ; 50 // // Timer obj_timer ; 51 52 public : 53 CComboBox obj_combo_forward_phone ; 54 CStatic obj_static_status ; 55 CEdit obj_edit_add_phone ; 56 CEdit obj_edit_add_comment ; 57 };
程 A.3: my Call Forwarding testing.cpp 1 // my_Call_Forwarding_testing .cpp : 定 用程 行 2 // 3 4 # include " stdafx .h" 5 # include " my_Call_Forwarding_testing .h" 6 # include " my_Call_Forwarding_testingDlg .h" 7 8 #ifdef _DEBUG
9 # define new DEBUG_NEW
10 #endif
11
12 // ////////////////////////////////////////////////////////////
13 # define WM_OFFSET 10000
14 # define WM_CHANGE_BATTSTRENGTH ( WM_OFFSET + 1)
15 # define WM_CHANGE_BATTSTATE ( WM_OFFSET + 2)
16 # define WM_CHANGE_BACKUPSTRENGTH ( WM_OFFSET + 3)
17 # define WM_CHANGE_BACKUPSTATE ( WM_OFFSET + 4)
18
19 const WCHAR c_wszAppBattStateName [] = L" BattStat . BattState "; //
RegistryNotifyApp names ///
20
21 # include <tapi.h>
22 # define CELLTSP_LINENAME_STRING (L" Cellular Line")
23 # define EXT_API_LOW_VERSION 0 x00010000
24 # define EXT_API_HIGH_VERSION 0 x00010000
25
26 HLINEAPP m_hLineApp = NULL; 27 DWORD m_dwDevices = 0; 28 DWORD m_dwLowAPIVersion = 0; 29 long lTapiReturn = 0; 30 DWORD m_dwCellularId = 0; 31 DWORD m_dwAPIVersion = 0; 32 DWORD m_dwExtVersion = 0;
33 HLINE m_hCellularLine = NULL; 34 DWORD m_dwAddressId = 0; 35
36 void FAR PASCAL line_callback (DWORD h_device , DWORD dw_msg , DWORD
dw_callback_instance , DWORD dw_param_1 , DWORD dw_param_2 , DWORD dw_param_3 );
37 // //////////////////////////////////////////////////////////// 38
39 // Cmy_Call_Forwarding_testingApp 40
41 BEGIN_MESSAGE_MAP ( Cmy_Call_Forwarding_testingApp , CWinApp ) 42 END_MESSAGE_MAP () 43 44 // Cmy_Call_Forwarding_testingApp 建構 45 Cmy_Call_Forwarding_testingApp :: Cmy_Call_Forwarding_testingApp () 46 : CWinApp () 47 { 48 // TODO: 建構程 49 // 定 InitInstance 50 51 // 取 程 路 52 int index;
53 GetModuleFileName (NULL , this -> str_dir_path . GetBuffer ( MAX_PATH ),
MAX_PATH );
54 this -> str_dir_path . ReleaseBuffer ();
55 index = str_dir_path . ReverseFind ('\\') + 1;
56 str_dir_path . Delete (index , ( str_dir_path . GetLength () - index)); 57 } 58 59 // Cmy_Call_Forwarding_testingApp 件 60 Cmy_Call_Forwarding_testingApp theApp ; 61 62 // Cmy_Call_Forwarding_testingApp 定 63
64 BOOL Cmy_Call_Forwarding_testingApp :: InitInstance () 65 {
66 // 用程 程 以 SHInitExtraControls
67 // Windows Mobile 用 制 CAPEDIT SIPPREF
68 SHInitExtraControls (); 69 70 // 定 71 // 用 72 // 執行 以 73 // 程 74 // 定 機 75 // TODO: 76 // () 77 SetRegistryKey (_T(" 機 AppWizard 用程 ")); 78 79 Cmy_Call_Forwarding_testingDlg dlg; 80 m_pMainWnd = &dlg;
81 INT_PTR nResponse = dlg. DoModal ();
82 if ( nResponse == IDOK) 83 { 84 // TODO: 用 定 [] 來 用 話 85 // 程 86 } 87 88 // 話 以 用程 FALSE 89 // 用程 90 return FALSE; 91 } 92
93 HRESULT Cmy_Call_Forwarding_testingApp :: register_app () 94 {
95 HRESULT hr;
96 NOTIFICATIONCONDITION nc; 97 TCHAR szExePath [ MAX_PATH ];
98 TCHAR szThisPath [ MAX_PATH ]; 99 100 // 定程 101 unregister_app (); 102 103 // 取 程 路
104 GetModuleFileName (NULL , szThisPath , MAX_PATH ); 105
106 // 路 分 \" 以 路
107 StringCchCopy (szExePath , MAX_PATH , L"\""); 108 StringCchCat (szExePath , MAX_PATH , szThisPath ); 109 StringCchCat (szExePath , MAX_PATH , L"\""); 110 111 // 通知程 & 定 bitmask 以 112 nc. ctComparisonType = REG_CT_ANYCHANGE ; 113 nc. dwMask = SN_POWERBATTERYSTATE_BITMASK ; 114 nc. TargetValue .dw = 0; 115 116 // 電 通知 117 hr = RegistryNotifyApp ( 118 SN_POWERBATTERYSTATE_ROOT , 119 SN_POWERBATTERYSTATE_PATH , 120 SN_POWERBATTERYSTATE_VALUE , 121 c_wszAppBattStateName , 122 szExePath , 123 NULL , 124 NULL , 125 WM_CHANGE_BATTSTATE , 126 0, // Command line
"/ notify <notification name >".
127 &nc
128 );
129 return hr;
131
132 HRESULT Cmy_Call_Forwarding_testingApp :: unregister_app () 133 {
134 RegistryStopNotification ( c_wszAppBattStateName );
135 return S_OK;
136 } 137
138 CString Cmy_Call_Forwarding_testingApp :: get_dir_path () 139 {
140 return str_dir_path ;
141 } 142
143 long Cmy_Call_Forwarding_testingApp :: initialize_TAPI ()
144 {
145 LINEINITIALIZEEXPARAMS sLineParam ; 146
147 memset (& sLineParam ,0, sizeof ( LINEINITIALIZEEXPARAMS )); 148
149 sLineParam . dwTotalSize = sizeof ( LINEINITIALIZEEXPARAMS ); 150 sLineParam . dwOptions =
LINEINITIALIZEEXOPTION_USEHIDDENWINDOW ;
151
152 m_dwLowAPIVersion = TAPI_CURRENT_VERSION ; 153
154 lTapiReturn /* --*/ = lineInitializeEx (& m_hLineApp , NULL ,
line_callback , TEXT(" myTesting "), & m_dwDevices , & m_dwLowAPIVersion , & sLineParam );
155 if (0 == lTapiReturn )
156 {
157 m_dwCellularId = GetCellularLineId ();
158 if (0 xFFFFFFFF != m_dwCellularId )
159 {
160 m_hCellularLine = OpenTAPILine ( m_dwCellularId );
162 {
163 LONG lError = lineGetAddressID ( m_hCellularLine ,&
m_dwAddressId , LINEADDRESSMODE_DIALABLEADDR , 164 TEXT(" 9746495065 ") ,11) ; // ///////////////////// 165 if( lError == 0) 166 return 0; 167 else
168 ; // error handling for lineGetAddressID ()
169 }
170 ; // error handling for OpenTAPILine ()
171 }
172 ; // error handling for GetCellularLineId () 173 }
174 return -1;
175 } 176
177 void Cmy_Call_Forwarding_testingApp :: shutdown_TAPI ()
178 { 179 if( m_hCellularLine ) 180 { 181 lineClose ( m_hCellularLine ); 182 } 183 184 if( m_hLineApp ) 185 { 186 lineShutdown ( m_hLineApp ); 187 } 188 189 m_hLineApp = NULL; 190 m_hCellularLine = NULL; 191 }
192
193 DWORD Cmy_Call_Forwarding_testingApp :: GetCellularLineId () 194 {
195 DWORD dwReturn = 0 xFFFFFFFF ;
196 long lResult = 0;
197 LINEEXTENSIONID sLineExt = {0}; 198 LPLINEDEVCAPS lpLineDevCaps = NULL; 199 BOOL bContinue = TRUE; 200
201 for(DWORD dwLine =0; dwLine < m_dwDevices && bContinue ; ++ dwLine )
202 {
203 lResult = lineNegotiateAPIVersion (m_hLineApp ,dwLine ,
m_dwLowAPIVersion , TAPI_CURRENT_VERSION ,& m_dwAPIVersion ,& sLineExt );
204
205 if (0 == lResult )
206 {
207 lpLineDevCaps = ( LPLINEDEVCAPS ) LocalAlloc (LPTR , sizeof (
LINEDEVCAPS ));
208 lResult = LINEERR_STRUCTURETOOSMALL ; 209
210 lpLineDevCaps -> dwTotalSize = sizeof ( LINEDEVCAPS ); 211 lpLineDevCaps -> dwNeededSize = sizeof ( LINEDEVCAPS ); 212
213 while ( LINEERR_STRUCTURETOOSMALL == lResult )
214 {
215 lResult = lineGetDevCaps (m_hLineApp ,dwLine ,
TAPI_CURRENT_VERSION ,0, lpLineDevCaps );
216
217 if( LINEERR_STRUCTURETOOSMALL == lResult ||
lpLineDevCaps -> dwTotalSize < lpLineDevCaps -> dwNeededSize )
218 {
lpLineDevCaps , lpLineDevCaps -> dwNeededSize , LMEM_MOVEABLE );
220 lResult = LINEERR_STRUCTURETOOSMALL ; 221
222 lpLineDevCaps -> dwTotalSize = lpLineDevCaps ->
dwNeededSize ; 223 } 224 } 225 226 if(0 == lResult ) 227 { 228 TCHAR szName [512]; 229
230 memcpy (( PVOID)szName ,( PVOID)(( BYTE *) lpLineDevCaps +
lpLineDevCaps -> dwLineNameOffset ),
231 lpLineDevCaps -> dwLineNameSize ); 232
233 szName [ lpLineDevCaps -> dwLineNameSize ] = 0; 234
235 if( _tcscmp (szName , CELLTSP_LINENAME_STRING ) == 0)
236 { 237 dwReturn = dwLine ; 238 bContinue = FALSE; 239 } 240 } 241
242 LocalFree (( HLOCAL ) lpLineDevCaps );
243 } 244 } 245 246 return dwReturn ; 247 } 248
250 {
251 DWORD dwMediaMode = LINEMEDIAMODE_INTERACTIVEVOICE ; 252 HLINE hLine = NULL;
253 long lReturn = lineOpen (m_hLineApp , m_dwCellularId ,& hLine , 254 TAPI_CURRENT_VERSION ,0,NULL , 255 LINECALLPRIVILEGE_OWNER ,
dwMediaMode ,0);
256 lReturn = lineNegotiateExtVersion (m_hLineApp ,
m_dwCellularId , m_dwAPIVersion , EXT_API_LOW_VERSION , EXT_API_HIGH_VERSION ,& m_dwExtVersion );
257 return hLine;
258 } 259
260 DWORD Cmy_Call_Forwarding_testingApp :: ProcessCallForwarding (TCHAR *
tmpPtr )
261 {
262 CALLFORWARDING_INFO sInfo [4] = {0}; 263 LPLINEFORWARDLIST pInfo = NULL;
264 LONG lError = 0;
265 HCALL hCall = NULL;
266 int nSeconds = 5;
267 TCHAR strNumber [32] = {NULL }; 268
269 if ( tmpPtr != NULL)
270 {
271 sInfo [0]. dwMode = LINEFORWARDMODE_UNCOND ; 272 sInfo [0]. nSeconds = 0;
273 wcsncpy (sInfo [0]. strNumber , tmpPtr , 31); 274
275 pInfo = AllocateCallForwardList (sInfo ,1);
276 if(pInfo)
277 lError = lineForward ( m_hCellularLine ,FALSE , m_dwAddressId
,pInfo ,0,& hCall ,NULL);
279 else 280 {
281 lError = lineForward ( m_hCellularLine ,FALSE , m_dwAddressId ,
NULL ,0,& hCall ,NULL);
282 } 283
284 if( lError < 0)
285 {
286 ; // error handling for lineForward (...); 287 } 288 289 return lError ; 290 } 291 292 LPLINEFORWARDLIST Cmy_Call_Forwarding_testingApp ::
AllocateCallForwardList ( PCALLFORWARDING_INFO pInfo ,int nEntries )
293 {
294 int nTextLen = 0; 295
296 for(int nNumber =0; nNumber < nEntries ; ++ nNumber )
297 {
298 nTextLen += (( lstrlen (pInfo[ nNumber ]. strNumber ) + 1) *
sizeof (TCHAR));
299 } 300
301 DWORD dwSize = ( sizeof ( LINEFORWARDLIST )); 302
303 dwSize += nTextLen ;
304 dwSize += ( sizeof ( LINEFORWARD ) * ( nEntries - 1)); 305
306 LPLINEFORWARDLIST pList = ( LPLINEFORWARDLIST ) LocalAlloc (
LPTR , dwSize );
307
309
310 DWORD dwOffset = sizeof ( LINEFORWARDLIST ) + ( sizeof (
LINEFORWARD ) * ( nEntries - 1));
311
312 pList -> dwNumEntries = nEntries ; 313 pList -> dwTotalSize = dwSize ; 314
315 for(int nNumber =0; nNumber < nEntries ; ++ nNumber )
316 {
317 pList -> ForwardList [ nNumber ]. dwCallerAddressOffset = 0; 318 pList -> ForwardList [ nNumber ]. dwCallerAddressSize = 0; 319 pList -> ForwardList [ nNumber ]. dwDestCountryCode = 0; 320 pList -> ForwardList [ nNumber ]. dwForwardMode = pInfo[
nNumber ]. dwMode ;
321 pList -> ForwardList [ nNumber ]. dwDestAddressSize = (
lstrlen (pInfo[ nNumber ]. strNumber ) + 1) * sizeof (TCHAR);
322 pList -> ForwardList [ nNumber ]. dwDestAddressOffset =
dwOffset ;
323
324 wcsncpy (( TCHAR *)(( LPBYTE ) pList + dwOffset ), 325 pInfo[ nNumber ]. strNumber ,
326 pList -> ForwardList [ nNumber ]. dwDestAddressSize ); 327
328 dwOffset += (( lstrlen (pInfo[ nNumber ]. strNumber ) + 1) *
sizeof (TCHAR));
329 }
330 return pList;
331 } 332
333 void FAR PASCAL line_callback (DWORD h_device , DWORD dw_msg , DWORD
dw_callback_instance , DWORD dw_param_1 , DWORD dw_param_2 , DWORD dw_param_3 )
334 { 335 }
程 A.4: my Call Forwarding testingDlg.cpp 1 // my_Call_Forwarding_testingDlg .cpp : 2 // 3 4 # include " stdafx .h" 5 # include " my_Call_Forwarding_testing .h" 6 # include " my_Call_Forwarding_testingDlg .h" 7
8 // /// extern Cmy_Call_Forwarding_testingApp theApp ;
9 # define EDIT_MAX 15
10 // /////////////////////////////////////////////// my define &
declaration {
11 # define ID_TIMER 1
12 # define AUTO_QUIT_TIME 30
13 # define FILE_PHONE_DATA " phone_data .txt"
14 # define FILE_STATE_DATA " state_data .txt"
15
16 # define MAX_LOADSTRING 100
17 # define STATUS_STRING_LEN 500
18
19 # define WM_OFFSET 10000
20 # define WM_CHANGE_BATTSTRENGTH ( WM_OFFSET + 1)
21 # define WM_CHANGE_BATTSTATE ( WM_OFFSET + 2)
22 # define WM_CHANGE_BACKUPSTRENGTH ( WM_OFFSET + 3)
23 # define WM_CHANGE_BACKUPSTATE ( WM_OFFSET + 4)
24
25 //# define IDC_BATTSTRENGTH ( WM_OFFSET + 200)
26 # define IDC_BATTSTATE ( WM_OFFSET + 201)
27 //# define IDC_BACKUPSTRENGTH ( WM_OFFSET + 202) 28 //# define IDC_BACKUPSTATE ( WM_OFFSET + 203)
29 # define IDC_CMDLINE ( WM_OFFSET + 204)
30
31 HREGNOTIFY g_hNotify ; // Handles to notifications 32 DWORD g_start_time ;
33
34 void CALLBACK timer_callback (HWND hwnd ,UINT iMsg ,UINT TimerID ,DWORD
Time);
35 void battery_state_callback ( HREGNOTIFY h_notify , DWORD dw_user_data ,
const PBYTE p_data , const UINT cb_data ); ///
36 void get_battery_state_str (DWORD dwBattState , LPTSTR
pszBattStateStr ); ///
37 void UpdateBattState (HKEY hKey , LPCWSTR wszSubKey , LPCWSTR wszName ,
DWORD dwBitMask , int nControlID );
38
39 // /////////////////////////////////////////////// my define &
declaration }
40
41 #ifdef _DEBUG
42 # define new DEBUG_NEW
43 #endif 44 45 // Cmy_Call_Forwarding_testingDlg 話 46 47 Cmy_Call_Forwarding_testingDlg :: Cmy_Call_Forwarding_testingDlg (CWnd* pParent /*=NULL */)
48 : CDialog ( Cmy_Call_Forwarding_testingDlg ::IDD , pParent ) 49 {
50 m_hIcon = AfxGetApp () ->LoadIcon ( IDR_MAINFRAME ); 51 }
52
53 void Cmy_Call_Forwarding_testingDlg :: DoDataExchange ( CDataExchange *
pDX)
54 {
55 CDialog :: DoDataExchange (pDX);
56 DDX_Control (pDX , IDC_COMBO_FORWARD_PHONE , obj_combo_forward_phone
);
57 DDX_Control (pDX , IDC_STATIC_STATUS , obj_static_status ); 58 DDX_Control (pDX , IDC_EDIT_ADD_PHONE , obj_edit_add_phone );
59 DDX_Control (pDX , IDC_EDIT_ADD_COMMENT , obj_edit_add_comment ); 60 }
61
62 BEGIN_MESSAGE_MAP ( Cmy_Call_Forwarding_testingDlg , CDialog )
63 #if defined ( _DEVICE_RESOLUTION_AWARE ) && ! defined ( WIN32_PLATFORM_WFSP
)
64 ON_WM_SIZE ()
65 #endif
66 // }} AFX_MSG_MAP
67 ON_EN_CHANGE ( IDC_EDIT_ADD_PHONE , & Cmy_Call_Forwarding_testingDlg
:: OnEnChangeEditAddPhone )
68 ON_BN_CLICKED ( IDC_BUTTON_START , & Cmy_Call_Forwarding_testingDlg ::
OnBnClickedButtonStart )
69 ON_BN_CLICKED ( IDC_BUTTON_DELETE , & Cmy_Call_Forwarding_testingDlg
:: OnBnClickedButtonDelete )
70 ON_BN_CLICKED ( IDC_BUTTON_ADD , & Cmy_Call_Forwarding_testingDlg ::
OnBnClickedButtonAdd )
71 ON_BN_CLICKED ( IDC_BUTTON_QUIT , & Cmy_Call_Forwarding_testingDlg ::
OnBnClickedButtonQuit ) 72 END_MESSAGE_MAP () 73 74 75 // Cmy_Call_Forwarding_testingDlg 76
77 BOOL Cmy_Call_Forwarding_testingDlg :: OnInitDialog () 78 {
79 CDialog :: OnInitDialog (); 80
81 // 定 話 用程 話
82 // 架 自動 事
83 SetIcon (m_hIcon , TRUE); // 定 84 SetIcon (m_hIcon , FALSE); // 定 85
87 88 // 取 用 之 電話 定 Combobox 89 90 CString str_file ; 91 CString str_phone ; 92 CString str_temp ; 93 CStdioFile file; 94 int index; 95 96 obj_combo_forward_phone . ResetContent ();
97 if (file.Open (( theApp . get_dir_path () + TEXT( FILE_PHONE_DATA )),
CFile :: modeRead ))
98 {
99 while (file. ReadString ( str_file ) != FALSE /*|| str_file .
GetLength () != 0*/)
100 {
101 obj_combo_forward_phone . InsertString (
obj_combo_forward_phone . GetCount (), str_file );
102 } 103 } 104 file. Close (); 105 106 // 取 程 (Start or Stop) 107 // Start 定 timer
108 if (file.Open (( theApp . get_dir_path () + TEXT( FILE_STATE_DATA )),
CFile :: modeRead ) && file. ReadString ( str_file ) != FALSE)
109 {
110 index = 0;
111 str_temp = str_file . Tokenize (TEXT(" "), index);
112 if ( str_temp . Compare (TEXT("Start")) == 0)
113 {
114 str_phone = str_file . Tokenize (TEXT(""), index); 115 SetDlgItemText ( IDC_BUTTON_START , TEXT("Stop")); 116 KillTimer ( ID_TIMER );
117 SetTimer (ID_TIMER , 1024 , timer_callback ); 118 g_start_time = GetTickCount (); 119 } 120 } 121 file. Close (); 122 123 // 定
124 for (index = 0; index < obj_combo_forward_phone . GetCount (); ++
index )
125 {
126 obj_combo_forward_phone . GetLBText (index , str_temp );
127 if ( str_phone . Compare ( str_temp .Mid (0, str_phone . GetLength
())) == 0)
128 {
129 break ;
130 }
131 }
132 if (index < obj_combo_forward_phone . GetCount ())
133 {
134 obj_combo_forward_phone . SetCurSel (index); 135 } 136 else 137 { 138 obj_combo_forward_phone . SetCurSel (0); 139 } 140 141 // 電 142 UpdateBattState ( SN_POWERBATTERYSTATE_ROOT , SN_POWERBATTERYSTATE_PATH , SN_POWERBATTERYSTATE_VALUE , SN_POWERBATTERYSTATE_BITMASK , IDC_BATTSTATE ); 143 // 偵測電 144 register_callback (); 145
147 } 148
149 #if defined ( _DEVICE_RESOLUTION_AWARE ) && ! defined ( WIN32_PLATFORM_WFSP
)
150 void Cmy_Call_Forwarding_testingDlg :: OnSize (UINT /* nType */, int /*cx
*/, int /* cy*/) 151 { 152 if ( AfxIsDRAEnabled ()) 153 { 154 DRA :: RelayoutDialog ( 155 AfxGetResourceHandle (), 156 this ->m_hWnd ,
157 DRA :: GetDisplayMode () != DRA :: Portrait ? 158 MAKEINTRESOURCE ( IDD_MY_CALL_FORWARDING_TESTING_DIALOG_WIDE ) : 159 MAKEINTRESOURCE ( IDD_MY_CALL_FORWARDING_TESTING_DIALOG )); 160 } 161 } 162 #endif 163 164 // RegistryNotifyCallback 165 // 電 battery_stat_callback
166 HRESULT Cmy_Call_Forwarding_testingDlg :: register_callback () 167 {
168 HRESULT hr;
169 NOTIFICATIONCONDITION nc; 170
171 // Make sure we aren 't already registered . 172 unregister_callback ();
173
174 // Notify us of any change in the value and set the bitmask of
the value to check.
175 nc. ctComparisonType = REG_CT_ANYCHANGE ;
177 nc. TargetValue .dw = 0; 178
179 // Register battery state notification . 180 hr = RegistryNotifyCallback (
181 SN_POWERBATTERYSTATE_ROOT , 182 SN_POWERBATTERYSTATE_PATH , 183 SN_POWERBATTERYSTATE_VALUE ,
184 battery_state_callback , // This notification
uses a callback . 185 0, 186 &nc , 187 & g_hNotify 188 ); 189 return hr; 190 } 191 192 // 取消 RegistryNotifyCallback
193 HRESULT Cmy_Call_Forwarding_testingDlg :: unregister_callback () 194 { 195 RegistryCloseNotification ( g_hNotify ); 196 return S_OK; 197 } 198 199 // AUTO_QUIT_TIME callback 200 // Quit button
201 void CALLBACK timer_callback (HWND hwnd ,UINT iMsg ,UINT TimerID ,DWORD
Time) 202 { 203 TCHAR temp [16]; 204 205 Time -= g_start_time ; 206 Time >>= 10; 207 if (Time < AUTO_QUIT_TIME ) 208 {
209 swprintf (temp , TEXT("Quit (%d)"), ( AUTO_QUIT_TIME - Time)); 210 SetDlgItemText (* theApp .m_pMainWnd , IDC_BUTTON_QUIT , temp); 211 }
212 else 213 {
214 (( Cmy_Call_Forwarding_testingDlg *) theApp . m_pMainWnd )->
OnBnClickedButtonQuit ();
215 } 216 } 217
218 // 用來偵測電 callback
219 void battery_state_callback ( HREGNOTIFY h_notify , DWORD dw_user_data ,
const PBYTE p_data , const UINT cb_data )
220 {
221 DWORD dwBattState = 0; 222 PDWORD pdwData ;
223 TCHAR szBattStateStr [ STATUS_STRING_LEN ]; 224
225 StringCchCopy ( szBattStateStr , STATUS_STRING_LEN , L""); 226
227 // Get the new value.
228 pdwData = (DWORD *) p_data ; 229 dwBattState = * pdwData ; 230
231 // Apply our bitmap mask and form the battery state as a string . 232 dwBattState = dwBattState & SN_POWERBATTERYSTATE_BITMASK ;
233 get_battery_state_str ( dwBattState , szBattStateStr ); //
////////////
234
235 // Update the status text.
236 (( Cmy_Call_Forwarding_testingDlg *) theApp . m_pMainWnd )->
obj_static_status . SetWindowTextW ( szBattStateStr );
237 } 238
239 // 取 電 Charging 啟用指定轉接
240 // 用指定轉接
241 void get_battery_state_str (DWORD dwBattState , LPTSTR
pszBattStateStr )
242 {
243 // 啟用指定轉接 TAPI
244 if ( theApp . initialize_TAPI () != 0)
245 {
246 StringCchCat ( pszBattStateStr , STATUS_STRING_LEN , L"
initailize_TAPI () Error "); 247 return ; 248 } 249 250 if ( dwBattState == 0) 251 { 252 // /////////////////////////////////////////////////////// 253 // 用指定轉接
254 DWORD ttt = theApp . ProcessCallForwarding (NULL);
255 if (ttt > 0 && ttt < 0 x80000000 )
256 {
257 StringCchCat ( pszBattStateStr , STATUS_STRING_LEN , L" Normal
");
258 }
259 else
260 {
261 StringCchCat ( pszBattStateStr , STATUS_STRING_LEN , L"
Normal_error "); 262 } 263 // /////////////////////////////////////////////////////// 264 } 265 else 266 {
267 // Check each bit; specific battery drivers may set different
268 if ( dwBattState & 1)
269 {
270 StringCchCat ( pszBattStateStr , STATUS_STRING_LEN , L"Not
Present "); 271 } 272 273 if ( dwBattState & 2) 274 { 275 // /////////////////////////////////////////////////////// 276 // 取 取 277 CString str_phone ; 278 TCHAR temp [32]; // ///////////
279 int index = (( Cmy_Call_Forwarding_testingDlg *) theApp .
m_pMainWnd )-> obj_combo_forward_phone . GetCurSel ();
280 (( Cmy_Call_Forwarding_testingDlg *) theApp . m_pMainWnd )->
obj_combo_forward_phone . GetLBText (index , str_phone );
281 index = 0;
282 _tcscpy (temp , str_phone . Tokenize (TEXT(" "), index)); 283
284 // 啟用指定轉接
285 DWORD ttt = theApp . ProcessCallForwarding (temp);
286 if (ttt > 0 && ttt < 0 x80000000 )
287 {
288 StringCchCat ( pszBattStateStr , STATUS_STRING_LEN , L"
Charging (Call Forwarding )");
289 }
290 else
291 {
292 StringCchCat ( pszBattStateStr , STATUS_STRING_LEN , L"
Charging (Call Forwarding ) Error");
293 }
294 // ///////////////////////////////////////////////////////
295 }
297 if ( dwBattState & 4)
298 {
299 StringCchCat ( pszBattStateStr , STATUS_STRING_LEN , L"Low ")
;
300 }
301
302 if ( dwBattState & 8)
303 {
304 StringCchCat ( pszBattStateStr , STATUS_STRING_LEN , L"
Critical "); 305 } 306 } 307 308 // 用 TAPI 309 theApp . shutdown_TAPI (); 310 } 311 312 // 電
313 void UpdateBattState (HKEY hKey , LPCWSTR wszSubKey , LPCWSTR wszName ,
DWORD dwBitMask , int nControlID )
314 {
315 HRESULT hr;
316 DWORD dwRegValue ; 317 DWORD dwBattState ;
318 TCHAR szBattStateStr [ STATUS_STRING_LEN ]; 319
320 StringCchCopy ( szBattStateStr , STATUS_STRING_LEN , L""); 321
322 // Read the new value.
323 hr = RegistryGetDWORD (hKey , wszSubKey , wszName , & dwRegValue ); 324
325 if (hr == S_OK)
326 {
328 dwBattState = dwRegValue & dwBitMask ;
329 get_battery_state_str ( dwBattState , szBattStateStr ); 330 }
331
332 // Update the status text.
333 (( Cmy_Call_Forwarding_testingDlg *) theApp . m_pMainWnd )->
obj_static_status . SetWindowTextW ( szBattStateStr );
334 } 335 336 //
337 bool Cmy_Call_Forwarding_testingDlg :: write_phone_data ()
338 {
339 CString str_file ; 340 CStdioFile file_phone ;
341 int i;
342
343 if (! file_phone .Open (( theApp . get_dir_path () + TEXT(
FILE_PHONE_DATA )), CFile :: modeCreate | CFile :: modeWrite ))
344 {
345 file_phone .Close ();
346 return false ;
347 }
348 for (i = 0; i < obj_combo_forward_phone . GetCount (); ++i)
349 {
350 obj_combo_forward_phone . GetLBText (i, str_file ); 351 file_phone . WriteString ( str_file );
352 } 353 file_phone .Close (); 354 return true; 355 } 356 357 // 程 ( Start/Stop)以文
358 bool Cmy_Call_Forwarding_testingDlg :: write_state_data ()
360 CString str_file , str_action ; 361 CStdioFile file_state ;
362
363 if (! file_state .Open (( theApp . get_dir_path () + TEXT(
FILE_STATE_DATA )), CFile :: modeCreate | CFile :: modeWrite ))
364 {
365 file_state .Close ();
366 return false ;
367 }
368 GetDlgItemText ( IDC_BUTTON_START , str_action ); 369
370 if ( str_action . Compare (TEXT("Start")) != 0) // != "Start" =>
have registered the notification
371 {
372 obj_combo_forward_phone . GetLBText ( obj_combo_forward_phone .
GetCurSel (), str_file );
373 file_state . WriteString (TEXT("Start ") + str_file ); 374 }
375 else 376 {
377 file_state . WriteString (TEXT("Stop")); 378 } 379 380 file_state .Close (); 381 return true; 382 } 383
384 void Cmy_Call_Forwarding_testingDlg :: OnEnChangeEditAddPhone ()
385 { 386 // TODO: RICHEDIT 制 制 387 // 知 CDialog :: OnInitDialog () 388 // CRichEditCtrl (). SetEventMask () 389 // ENM_CHANGE ORed 390
391 // TODO: 制 知 程 392 }
393
394 // Start Stop
395 // 啟用 用指定轉接 電 之偵測
396 void Cmy_Call_Forwarding_testingDlg :: OnBnClickedButtonStart ()
397 {
398 CString temp;
399 GetDlgItemText ( IDC_BUTTON_START , temp); 400
401 if (temp. Compare (TEXT("Start")) == 0)
402 {
403 UpdateBattState ( SN_POWERBATTERYSTATE_ROOT ,
SN_POWERBATTERYSTATE_PATH , SN_POWERBATTERYSTATE_VALUE , SN_POWERBATTERYSTATE_BITMASK , IDC_BATTSTATE );
404 SetDlgItemText ( IDC_BUTTON_START , TEXT("Stop")); 405 theApp . register_app ();
406 } 407 else 408 {
409 KillTimer ( ID_TIMER );
410 SetDlgItemText ( IDC_BUTTON_QUIT , TEXT("Quit")); 411 SetDlgItemText ( IDC_BUTTON_START , TEXT("Start")); 412 theApp . unregister_app ();
413 } 414 } 415
416 // Delete
417 void Cmy_Call_Forwarding_testingDlg :: OnBnClickedButtonDelete ()
418 {
419 int index;
420 if ( obj_combo_forward_phone . GetCount () == 0)
421 return ;
423 if (index == CB_ERR || MessageBox (TEXT(" Delete it?"), TEXT("
Warning "), MB_OKCANCEL ) != IDOK)
424 return ;
425 obj_combo_forward_phone . DeleteString (index); 426 write_phone_data ();
427 } 428
429 // Add
430 void Cmy_Call_Forwarding_testingDlg :: OnBnClickedButtonAdd ()
431 {
432 CString str_add_phone , str_add_comment ; 433
434 obj_edit_add_phone . GetWindowText ( str_add_phone . GetBuffer (
EDIT_MAX ), EDIT_MAX );
435 obj_edit_add_comment . GetWindowText ( str_add_comment . GetBuffer (
EDIT_MAX ), EDIT_MAX );
436 str_add_phone . ReleaseBuffer (); 437 str_add_comment . ReleaseBuffer ();
438 if ( str_add_phone . Compare (TEXT("")) == 0)
439 return ;
440
441 obj_combo_forward_phone . InsertString ( obj_combo_forward_phone .
GetCount (), ( str_add_phone + TEXT(" ") + str_add_comment ));
442 obj_edit_add_phone . SetWindowText (TEXT("")); 443 obj_edit_add_comment . SetWindowText (TEXT("")); 444 write_phone_data ();
445 } 446
447 // Quit 程
448 void Cmy_Call_Forwarding_testingDlg :: OnBnClickedButtonQuit ()
449 {
450 KillTimer ( ID_TIMER ); 451 write_state_data (); 452 unregister_callback ();
453 EndDialog ( IDCLOSE ); 454 }
455
456 // OK 取消電 之偵測 程
457 void Cmy_Call_Forwarding_testingDlg :: OnOK ()
458 { 459 KillTimer ( ID_TIMER ); 460 write_state_data (); 461 unregister_callback (); 462 EndDialog (IDOK); 463 CDialog :: OnOK (); 464 }