-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
499 lines (232 loc) · 92.1 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>hpng</title>
<link href="http://nikohpng.github.io/atom.xml" rel="self"/>
<link href="http://nikohpng.github.io/"/>
<updated>2024-03-17T11:51:25.994Z</updated>
<id>http://nikohpng.github.io/</id>
<author>
<name>hpng</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>除却巫山不是云</title>
<link href="http://nikohpng.github.io/2024/03/17/memory/%E9%99%A4%E5%8D%B4%E5%B7%AB%E5%B1%B1%E4%B8%8D%E6%98%AF%E4%BA%91/"/>
<id>http://nikohpng.github.io/2024/03/17/memory/%E9%99%A4%E5%8D%B4%E5%B7%AB%E5%B1%B1%E4%B8%8D%E6%98%AF%E4%BA%91/</id>
<published>2024-03-17T11:43:32.000Z</published>
<updated>2024-03-17T11:51:25.994Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><center style="font-weight: 800">离思</center><center style="font-weight:200">元稹</center><center>曾经沧海难为水,除却巫山不是云。</center><center>取次花丛懒回顾,半缘修道半缘君。</center><br/><br/><br/><p><img src= "/img/loading.gif" data-lazy-src="../../../../../../images/memory/family.jpg" alt="bloom"></p>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="Memory" scheme="http://nikohpng.github.io/categories/Memory/"/>
<category term="hz" scheme="http://nikohpng.github.io/tags/hz/"/>
</entry>
<entry>
<title>欲得周郎顾时时误抚琴</title>
<link href="http://nikohpng.github.io/2024/03/14/memory/%E6%AC%B2%E5%BE%97%E5%91%A8%E9%83%8E%E9%A1%BE%E6%97%B6%E6%97%B6%E8%AF%AF%E6%8A%9A%E7%90%B4/"/>
<id>http://nikohpng.github.io/2024/03/14/memory/%E6%AC%B2%E5%BE%97%E5%91%A8%E9%83%8E%E9%A1%BE%E6%97%B6%E6%97%B6%E8%AF%AF%E6%8A%9A%E7%90%B4/</id>
<published>2024-03-14T12:06:44.000Z</published>
<updated>2024-03-14T12:11:21.122Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><center style="font-weight: 800">国风·郑风·子衿</center><center style="font-weight:200">诗经</center><center>鸣筝金粟柱,素手玉房前。</center><center>欲得周郎顾,时时误拂弦。</center><br/><br/><br/><p><img src= "/img/loading.gif" data-lazy-src="../../../../../../images/memory/sakura.jpg" alt="bloom"></p>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="Memory" scheme="http://nikohpng.github.io/categories/Memory/"/>
<category term="hz" scheme="http://nikohpng.github.io/tags/hz/"/>
</entry>
<entry>
<title>纵我不往子宁不嗣音</title>
<link href="http://nikohpng.github.io/2024/03/14/memory/%E7%BA%B5%E6%88%91%E4%B8%8D%E5%BE%80%E5%AD%90%E5%AE%81%E4%B8%8D%E5%97%A3%E9%9F%B3/"/>
<id>http://nikohpng.github.io/2024/03/14/memory/%E7%BA%B5%E6%88%91%E4%B8%8D%E5%BE%80%E5%AD%90%E5%AE%81%E4%B8%8D%E5%97%A3%E9%9F%B3/</id>
<published>2024-03-14T11:57:26.000Z</published>
<updated>2024-03-14T12:05:32.582Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><center style="font-weight: 800">国风·郑风·子衿</center><center style="font-weight:200">诗经</center><center>青青子衿,悠悠我心。纵我不往,子宁不嗣音?</center><center>青青子佩,悠悠我思。纵我不往,子宁不来?</center><center>挑兮达兮,在城阙兮。一日不见,如三月兮。</center><br/><br/><br/><p><img src= "/img/loading.gif" data-lazy-src="../../../../../../images/memory/plum_blossom.jpg" alt="bloom"></p>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="Memory" scheme="http://nikohpng.github.io/categories/Memory/"/>
<category term="hz" scheme="http://nikohpng.github.io/tags/hz/"/>
</entry>
<entry>
<title>那人却在灯火阑珊处</title>
<link href="http://nikohpng.github.io/2024/02/25/memory/%E9%82%A3%E4%BA%BA%E5%8D%B4%E5%9C%A8%E7%81%AF%E7%81%AB%E9%98%91%E7%8F%8A%E5%A4%84/"/>
<id>http://nikohpng.github.io/2024/02/25/memory/%E9%82%A3%E4%BA%BA%E5%8D%B4%E5%9C%A8%E7%81%AF%E7%81%AB%E9%98%91%E7%8F%8A%E5%A4%84/</id>
<published>2024-02-25T11:10:34.000Z</published>
<updated>2024-02-25T11:20:26.427Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><center style="font-weight: 800">青玉案 元夕</center><center style="font-weight:200">辛弃疾</center><center>东风夜放花千树,更吹落,星如雨。</center><center>宝马雕车香满路。</center><center>凤箫声动,玉壶光转,一夜鱼龙舞。</center><center>蛾儿雪柳黄金缕,笑语盈盈暗香去。</center><center>众里寻他千百度,蓦然回首,那人却在,灯火阑珊处。</center><br/><br/><br/><p><img src= "/img/loading.gif" data-lazy-src="../../../../../../images/memory/fireworks.jpg" alt="bloom"></p>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="Memory" scheme="http://nikohpng.github.io/categories/Memory/"/>
<category term="hz" scheme="http://nikohpng.github.io/tags/hz/"/>
</entry>
<entry>
<title>为伊消得人憔悴</title>
<link href="http://nikohpng.github.io/2024/02/24/memory/%E4%B8%BA%E4%BC%8A%E6%B6%88%E5%BE%97%E4%BA%BA%E6%86%94%E6%82%B4/"/>
<id>http://nikohpng.github.io/2024/02/24/memory/%E4%B8%BA%E4%BC%8A%E6%B6%88%E5%BE%97%E4%BA%BA%E6%86%94%E6%82%B4/</id>
<published>2024-02-24T11:28:11.000Z</published>
<updated>2024-02-24T11:48:55.424Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><center>蝶恋花</center><center style="font-weight:200">柳永</center><center>伫倚危楼风细细,望极春愁,黯黯生天际。草色烟光残照里,无言谁会凭阑意。</center><center>拟把疏狂图一醉,对酒当歌,强乐还无味。衣带渐宽终不悔,为伊消得人憔悴</center><br/><br/><br/><p><img src= "/img/loading.gif" data-lazy-src="../../../../../../images/memory/haggard.jpg" alt="bloom"></p>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="Memory" scheme="http://nikohpng.github.io/categories/Memory/"/>
<category term="hz" scheme="http://nikohpng.github.io/tags/hz/"/>
</entry>
<entry>
<title>待到山花烂漫时</title>
<link href="http://nikohpng.github.io/2024/02/24/memory/%E5%BE%85%E5%88%B0%E5%B1%B1%E8%8A%B1%E7%83%82%E6%BC%AB%E6%97%B6/"/>
<id>http://nikohpng.github.io/2024/02/24/memory/%E5%BE%85%E5%88%B0%E5%B1%B1%E8%8A%B1%E7%83%82%E6%BC%AB%E6%97%B6/</id>
<published>2024-02-24T02:48:55.000Z</published>
<updated>2024-02-24T11:26:27.313Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><center style="font-weight: 800">卜算子.咏梅</center><center>风雨送春归,飞雪迎春到。</center><center>已是悬崖百丈冰,犹有花枝俏。</center><center>俏也不争春,只把春来报。</center><center>待到山花烂漫时,她在丛中笑。</center><br/><br/><br/><p><img src= "/img/loading.gif" data-lazy-src="../../../../../../images/memory/bloom.jpg" alt="bloom"></p>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="Memory" scheme="http://nikohpng.github.io/categories/Memory/"/>
<category term="hz" scheme="http://nikohpng.github.io/tags/hz/"/>
</entry>
<entry>
<title>阅读SIP协议观后感</title>
<link href="http://nikohpng.github.io/2024/01/01/freeswitch/%E9%98%85%E8%AF%BBSIP%E5%8D%8F%E8%AE%AE%E8%A7%82%E5%90%8E%E6%84%9F/"/>
<id>http://nikohpng.github.io/2024/01/01/freeswitch/%E9%98%85%E8%AF%BBSIP%E5%8D%8F%E8%AE%AE%E8%A7%82%E5%90%8E%E6%84%9F/</id>
<published>2024-01-01T03:25:57.000Z</published>
<updated>2024-01-28T09:41:48.446Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>本文主要记录阅读 SIP rfc3261 文档的一些所思所考,不会对其进行整理分类,并且存在跳跃性</p><h2 id="生成-SIP-响应"><a href="#生成-SIP-响应" class="headerlink" title="生成 SIP 响应"></a>生成 SIP 响应</h2><ul><li>8.2.6</li><li>除了 invite 外需要生成临时响应,其它响应应该立即响应</li><li>生成的临时响应,请求中的时间戳应该直接复制到响应中。如果响应慢就需要将延迟时间以 s 为单位,将时间生成在响应中</li><li>响应的 Call-ID、CSeq、VIA的顺序必须相同。除了 100,其它响应的 uri 内容必须相同,并且需要添加一个 tag,用于 dialog。</li></ul><h2 id="事务的解读"><a href="#事务的解读" class="headerlink" title="事务的解读"></a>事务的解读</h2><p>事务的分为客户端事务与服务器事务,客户端事务发送请求,服务器事务发送响应。</p><p>无状态代理不包含客户端事务或服务器事务。</p><ul><li>200(Ok)的ack作用:主要为了确保 200ok 能够正常发送到 UAC。如果后续不发送 ACK,那么服务端会不断发送,并且在三分钟后断开连接<ul><li>疑问:为啥 200 ok 的 ack 作为自己单独的事务?</li><li>解答:这样设计的原因是保证送达到UAC,并且如果没有回复 ACK,那么 UAS 将会重传</li></ul></li><li>客户端事务:客户端事务的主要负责将接收到的响应传递给 TU, 并过滤重传与不允许的传递。对于 invite 的请求,用于生成 ACK<ul><li>疑问:TU 与客户端事务有什么区别吗</li><li>解答:客户端是TU 与 传输层的中间层</li></ul></li><li>服务器事务:服务器事务的目的是接收来自传输层的请求并将其传递给TU,服务器事务过滤来自网络的任何请求重传。<br>服务器事务接受来自TU的响应,并将它们传递到传输层,以便通过网络进行传输。在INVITE事务的情况下,它会吸收除2xx响应之外的任何最终响应的ACK请求。</li><li>200ok与ack的生成: 都由 UA 核心来处理<ul><li>疑问:前面说客户端事务生成ack,现在又说 UA 核心来处理,不明白</li><li>解释:这里的由核心来处理指的是重传由核心处理。</li></ul></li><li>on-INVITE client transaction:这是没有 ack 的事务。如果需要 ack 的话,需要 tu 直接生成一个 ack?</li></ul><h3 id="客户端事务"><a href="#客户端事务" class="headerlink" title="客户端事务"></a>客户端事务</h3><ul><li>客户端事务状态机: invite 客户端事务与非 invite 客户端事务<ul><li>特点:invite 客户端事务发送延迟长,需要三方握手;非 invite 事务需要立即响应</li><li>注意:如果 TU 希望发送 ACK,它将一个 ACK 直接传递给传输层进行传输</li></ul></li></ul><h4 id="invite-客户端事务"><a href="#invite-客户端事务" class="headerlink" title="invite 客户端事务"></a>invite 客户端事务</h4><p>invite 事务由发送 invite、服务器事务响应、客户端事务响应ack组成。<br>其中 invite 发出后在 t1(默认值:500ms) 重发,除非接受到 1xx 响应,否则就增加两倍的 t1 进行重传。<br>最终,服务器事务发出最终响应,并有客户端事务发送 ack 用于终止重传</p><ul><li>形式描述<ul><li>invite 的客户端事务初始状态为 “Calling”<ul><li>不可靠传输启动定时器 A(t1),可靠传输不需要启动。事务启动定时器 B(64*t1) 控制事务超时</li><li>超时后重传必须在 “calling” 状态下进行,并且传输时间是 2*t1</li><li>如果定时器 B 触发后任然处于 “calling”, 则通知 TU 超时,并不生成 ack,然后进入 “Terminated” 状态</li></ul></li><li>当接收到临时响应是,状态改为 “Proceeding”。后续的临时响应需要传递给 TU<ul><li>当处于 “Calling” 或 “Proceeding” 状态下,接收到 300-699 响应必须转换为 “Completed”</li><li>接收到服务器事务的响应后,生成 ack 并传输到原始请求发送到的相同的地址、端口和 transport</li><li>当进入 “Completed” 时,启动定时器 D, 对于不可靠传输值至少为 32 秒,可靠传输置为 0。这个值等于服务器事务定时器 H(64*T1)</li><li>新接收到的重新响应不能传递给 TU</li></ul></li><li>定时器 D 在客户端事务处于 “Completed” 状态时触发,客户端事务必须移动到 “Terminated”<ul><li>当处于 “Calling” 或 “Proceeding” 状态下,接收 2xx 响应必须导致客户端事务进入 “Terminated” 状态,并且必须将响应传递到TU</li><li>Proxy 响应 200 为传递给下一跳,客户端事务生成 ack</li><li>客户端事务必须在进入 “Terminated” 状态的瞬间被销毁。</li><li>注意:如何没匹配到合适的客户端事务,则传递到 core</li></ul></li></ul></li><li>ack 的构造<ul><li>Call-ID、From 和 Request-URI 必须和原始请求相同</li><li>To 必须等于被确定的响应中的 To 字段</li><li>ACK 必须包含单一的 Via 报头字段,这个字段必须等于原始的顶部 Via 报头字段</li><li>如果 2xx 中有 Route 字段,则这些也要出现在 ACK 报头中</li><li>注意:invite 响应 415,则可以在 ACK 中放置 body 内容</li></ul></li></ul><h4 id="非-INVITE-客户端事务"><a href="#非-INVITE-客户端事务" class="headerlink" title="非 INVITE 客户端事务"></a>非 INVITE 客户端事务</h4><p>非 INVITE 客户端事务超时 t1 后重传,但是在接受到临时或最终响应后,以 t2 为间隔继续传输消息。</p><blockquote><p>疑问:按照标准文档,按照 t2 继续传输消息,是为了确保交付最后响应。服务器发送了一个请求后,传输在终止?</p></blockquote><p>非 INVITE 客户端事务的 200ok 不会响应 ACK。</p><ul><li>形式描述:<ul><li>发起事务请求,进入 “Trying” 状态<ul><li>启动定时器 F(64<em>T1) 。如果是不可靠传输,客户端事务必须设置定时器 E(T1),以MIN(2</em>T1,T2),T2 默认为 4s</li><li>如果定时器 F 触发,仍处于 “Trying”,通知 TU 超时,然后进入 “Terminated” 状态</li><li>如果在 “Trying” 状态下收到最终响应(200-699),则传递给 TU,事务转换为 “Completed” 状态</li></ul></li><li>当在 “Trying” 状态下收到临时响应,则转为 “Proceeding” 状态<ul><li>如果定时器 E 在 “Proceeding” 状态下被触发,请求需要被重传,定时器 E 重置为 T2 秒</li><li>如果定时器 F 在 “Proceeding” 状态下被触发,通知 TU 超时,然后进入 “Terminated” 状态</li><li>如果在 “Proceeding” 状态下收到最终响应(200-699),则传递给 TU,事务转换为 “Completed” 状态</li></ul></li><li>当进入 “Completed” 时,启动定时器 K, 对于不可靠传输值 T4 秒,可靠传输置为 0。<ul><li>T4表示网络清除客户机和服务器事务之间的消息所需的时间。缺省值为5s</li><li>如果定时器 K 在此状态下触发,客户端事务必须转换到 “Terminated” 状态。</li></ul></li></ul></li><li>匹配响应给对应客户端事务<ul><li>响应消息的 Via 头字段的 Branch 参数相同,则匹配</li><li>CSeq报头字段中的方法参数与创建事务的请求的方法匹配。用于 CANCEL,CANCEL 会新生成一个事务</li></ul></li><li>异常处理<ul><li>当传输发送错误时,立即想 TU 响应错误,并直接切换到 “Terminated” 状态</li></ul></li></ul><h3 id="服务器事务"><a href="#服务器事务" class="headerlink" title="服务器事务"></a>服务器事务</h3><p>服务器事务是在接收到请求时由核心创建。</p><h4 id="INVITE-服务器事务"><a href="#INVITE-服务器事务" class="headerlink" title="INVITE 服务器事务"></a>INVITE 服务器事务</h4><ul><li><p>形式描述:</p><ul><li><p>Proceeding 收到重传请求,那么需要获取 TU 给的最新的 trying 进行重传</p><ul><li>Proceeding 状态下 TU 向服务器事务传递 2xx 响应,服务器事务必须传出去,当然重传由 TU 负责,服务器事务状态转为 Terminated</li><li>Proceeding 状态下 TU 向服务器事务传递 300-699,必须传出去,服务器事务状态转为 Completed。不可靠传输定时器 G(T1) 触发,可靠传输,定时器不触发。</li></ul></li><li><p>Completed 进入后,定时器 H(64*T1) 必须启动,此定时器决定了重传超时时间。</p><ul><li>如果定时器 G 触发,则将继续重传,定时器 G 时间为 MIN(2*T1, T2)</li><li>Completed 状态下,接收到重传请求应该进行重传</li><li>Completed 状态下,收到了 ACK,则转为 Confirmed。并且定时器 G 被忽略,任何重传都会停止</li><li>Completed 状态下,定时器 H 被激活,则服务器事务转为 Terminated 状态,并通知 TU 事务失败。</li></ul></li><li><p>Confirmed 主要用于吸收多余的 ACK。</p><ul><li>当进入该状态时,定时器 I 在 T4 秒内触发,对于不可靠的传输,定时器 I 为 0 秒。</li><li>一旦定时器触发,则转为 Terminated 状态</li></ul></li><li><p>一旦事务处于“终止”状态,它必须立即销毁。与客户端事务一样,这需要确保对INVITE的2xx响应的可靠性。</p></li></ul></li></ul><h4 id="非-INVITE-服务器事务"><a href="#非-INVITE-服务器事务" class="headerlink" title="非 INVITE 服务器事务"></a>非 INVITE 服务器事务</h4><ul><li>形式描述:<ul><li>Trying 状态下,初始化走这个状态并且任何重传都将丢弃<ul><li>TU 向服务器事务传输响应,则转为 Proceeding 状态</li></ul></li><li>Proceeding 状态下,所有 TU 传输过来的内容,都需要全部通过传输层传输出去<ul><li>Proceeding 接收到请求的重传,则必须将最新发送临时响应重传出去</li><li>Proceeding 状态下,TU 向服务器事务传递最终响应(200-699), 则事务必须进入 Completed 状态</li></ul></li><li>Completed 状态必须启动定时器 J(64*T1),不可靠为 0 秒<ul><li>TU 传递给服务器事务的任何其他最终响应必须在处于 Completed 状态时丢弃</li><li>服务器事务保持这个状态,直到定时器 J 触发,转为 Terminated 状态</li></ul></li><li>服务器事务必须在进入 Terminated 状态的瞬间被销毁。</li></ul></li></ul><h3 id="事务的的匹配"><a href="#事务的的匹配" class="headerlink" title="事务的的匹配"></a>事务的的匹配</h3><p>在 VIA 中有 z9hG4bK 字符,通过魔法字符进行匹配。没有就采用 Request-URI, To tag, From tag, Call-ID, CSeq, and top Via header<br>匹配对应的 事务。</p>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="freeswitch" scheme="http://nikohpng.github.io/categories/freeswitch/"/>
<category term="sip" scheme="http://nikohpng.github.io/tags/sip/"/>
</entry>
<entry>
<title>Sip协议中的一些概念</title>
<link href="http://nikohpng.github.io/2023/12/24/freeswitch/Sip%E5%8D%8F%E8%AE%AE%E4%B8%AD%E7%9A%84%E4%B8%80%E4%BA%9B%E6%A6%82%E5%BF%B5/"/>
<id>http://nikohpng.github.io/2023/12/24/freeswitch/Sip%E5%8D%8F%E8%AE%AE%E4%B8%AD%E7%9A%84%E4%B8%80%E4%BA%9B%E6%A6%82%E5%BF%B5/</id>
<published>2023-12-24T03:13:54.000Z</published>
<updated>2023-12-24T03:18:23.179Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>本文主要介绍 SIP 协议中的一些缩写字符的含义,这些缩写在阅读 Sofia-sip 的代码时常有出现</p><h2 id="Sip-缩写字符"><a href="#Sip-缩写字符" class="headerlink" title="Sip 缩写字符"></a>Sip 缩写字符</h2><ul><li><p>线性空白(Linear White Space,简称LWS): 位于文本字符序列中的空白字符,包括空格、制表符和换行符等。<br>在计算机编程中,线性空白通常用来描述文本中字符之间的间距,包括但不限于字母、数字、标点符号等。<br>线性空白与非线性空白(Non-Linear White Space,简称NLWS)相对,非线性空白一般指符号或标点之间的间距,如句子结束的标点符号与下一句的起始字母之间的间隔</p></li><li><p>CRLF: 换行符</p></li></ul>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="freeswitch" scheme="http://nikohpng.github.io/categories/freeswitch/"/>
<category term="Sip" scheme="http://nikohpng.github.io/tags/Sip/"/>
</entry>
<entry>
<title>Sofia中的一些概念</title>
<link href="http://nikohpng.github.io/2023/12/23/freeswitch/Sofia%E4%B8%AD%E7%9A%84%E4%B8%80%E4%BA%9B%E6%A6%82%E5%BF%B5/"/>
<id>http://nikohpng.github.io/2023/12/23/freeswitch/Sofia%E4%B8%AD%E7%9A%84%E4%B8%80%E4%BA%9B%E6%A6%82%E5%BF%B5/</id>
<published>2023-12-23T13:36:32.000Z</published>
<updated>2023-12-23T13:42:27.455Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>本文主要对 Sofia 中的一些概念进行分析与解释,方便进行源码阅读。</p><h2 id="Sofia-概念"><a href="#Sofia-概念" class="headerlink" title="Sofia 概念"></a>Sofia 概念</h2><h3 id="事件循环Event-loop-与根对象-root-object"><a href="#事件循环Event-loop-与根对象-root-object" class="headerlink" title="事件循环Event loop 与根对象 root object"></a>事件循环Event loop 与根对象 root object</h3><ul><li>NUA以事件反应器模式(也称为分发及通知模式)驱动事件系统(请参考[Using Design Patterns to Develop Reusable Object-oriented Communication Software, D.C. Schmidt, CACM October ‘95, 38(10): 65-74]一书)。<br>Sofia以任务作为编程模型的基本执行单元。根据编程模型,程序可以请求事件循环在特定事件触发时调用回调函数。具体事件包括I/O激活,定时器或其它任务传递的异步消息。</li><li>root 对象是应用软件中描述一个任务的句柄。<ul><li>透视事件的另一种方式是:root对象描述任务的主事件循环。通过root对象,任务代码可以访问它的上下文信息(magic)和线程同步,比如说等待对象、定时器,消息。</li></ul></li><li>使用NUA服务的应用必须创建一个root对象,并设置处理NUA事件的回调函数。<ul><li>调用 <code>su_root_create()</code>创建root对象,调用<code>nua_create()</code>函数注册回调函数。root 对象的数据类型是 su_root_t。</li></ul></li></ul><h3 id="Magic"><a href="#Magic" class="headerlink" title="Magic"></a>Magic</h3><ul><li>magic 是一种描述上下文指针的术语,应用程序可以把它绑定到Sofia栈的各种对象上(比如说root对象和操作句柄)。当主事件循环调用注册的回调函数时,上下文指针会回传给应用层代码。<br>Sofia栈保留回调函数调用之间的上下文信息。应用层可以利用上下文信息存储处理事件所需要的任何信息</li></ul><h3 id="内存处理"><a href="#内存处理" class="headerlink" title="内存处理"></a>内存处理</h3><ul><li>给定的任务需要分配许多小块内存时,使用home-based内存管理机制会很便利。内存通过home对象分配,它维护所有内存块的引用信息。当home对象释放时,所有相关内存一并释放。这个机制简化了应用逻辑,因为应用层代码不需要跟踪内存块的分配记录,也不需要独立释放每一个内存块。<br>使用NUA服务的应用程序可以使用SU库提供的内存管理服务,但这不是强制要求的。</li></ul><h2 id="引用"><a href="#引用" class="headerlink" title="引用"></a>引用</h2><ul><li><a href="https://blog.csdn.net/yetyongjin/article/details/105839864">Sofia “nua”模块–高层UA库</a></li></ul>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="freeswitch" scheme="http://nikohpng.github.io/categories/freeswitch/"/>
<category term="Sofia" scheme="http://nikohpng.github.io/tags/Sofia/"/>
</entry>
<entry>
<title>Sofia发送subscriber的源码解析</title>
<link href="http://nikohpng.github.io/2023/12/23/freeswitch/Sofia%E5%8F%91%E9%80%81subscriber%E7%9A%84%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90/"/>
<id>http://nikohpng.github.io/2023/12/23/freeswitch/Sofia%E5%8F%91%E9%80%81subscriber%E7%9A%84%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90/</id>
<published>2023-12-23T12:48:25.000Z</published>
<updated>2023-12-23T13:35:20.713Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>本文将对 sofia 发送 subscriber 这个信令进行源码分析其中会对一些涉及到的其它源码进行解析,用以后续学习</p><h2 id="Sofia-的-handle"><a href="#Sofia-的-handle" class="headerlink" title="Sofia 的 handle"></a>Sofia 的 handle</h2><p>这里对 handle 进行一定的解释。这个 handle 用于管理向谁发送什么样的数据,这个谁一般指定 uac 。 一个 handle 会生成一个新的 call-id,产生一个新的 session。</p><ul><li><code>nua_handle_destroy()</code>: 用于销毁这个 handle。<ul><li>小知识:FreeSWITCH 一般在创建后 <code>nua_handle_bind(fnh, &mod_sofia_globals.destroy_private)</code>,后续不用后会自动销毁, 这个销毁主要依赖于 our_sofia_event_callback<br>中的以下代码:<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> ((sofia_private && sofia_private == &mod_sofia_globals.destroy_private)) {</span><br><span class="line"> nua_handle_bind(nh, <span class="literal">NULL</span>);</span><br><span class="line"> nua_handle_destroy(nh);</span><br><span class="line"> nh = <span class="literal">NULL</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul></li><li><code>nua_handle_bind</code>: 绑定给回调函数一个上下文。在发生 sip 的状态机变化的时候,nua_create 注册的回调函数会回调,其中的会带有这个绑定的值。解绑传值为 NULL</li><li><code>nua_handle_ref</code>: 增加了 handle 的 sub_ref, 未知</li><li><code>nua_handle_unref</code>: 减少了 handle 的 sub_ref,未知<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nua.c:304 </span><br></pre></td></tr></table></figure><h2 id="Sofia-的-subscribe-流程"><a href="#Sofia-的-subscribe-流程" class="headerlink" title="Sofia 的 subscribe 流程"></a>Sofia 的 subscribe 流程</h2></li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">nua.c:701 nua_subscribe NUA_SIGNAL(nh, nua_r_subscribe, tag, value)</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="freeswitch" scheme="http://nikohpng.github.io/categories/freeswitch/"/>
<category term="Sofia" scheme="http://nikohpng.github.io/tags/Sofia/"/>
</entry>
<entry>
<title>cmake的使用记录</title>
<link href="http://nikohpng.github.io/2023/07/11/C_Learn/cmake%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AE%B0%E5%BD%95/"/>
<id>http://nikohpng.github.io/2023/07/11/C_Learn/cmake%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AE%B0%E5%BD%95/</id>
<published>2023-07-11T12:55:30.000Z</published>
<updated>2023-07-11T13:12:18.508Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>cmake 在 win 中的编译需要使用的一些配置,主要是记录曾经使用情况</p><h2 id="Release-生成PDB"><a href="#Release-生成PDB" class="headerlink" title="Release 生成PDB"></a>Release 生成PDB</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")</span><br><span class="line">set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")</span><br><span class="line">set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")</span><br></pre></td></tr></table></figure><p>cmake原生中的配置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")</span><br><span class="line">set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")</span><br><span class="line">set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")</span><br></pre></td></tr></table></figure><ul><li><p><code>CMAKE_CXX_FLAGS_RELEASE</code>: <code>/MD /O2 /Ob2 /DNDBUG </code></p></li><li><p><code>CMAKE_CXX_FLAGS_RELWITHDEBINFO</code>: <code>/MD /O2 /Ob1 /DNDBUG /Zi </code></p></li><li><p><code>CMAKE_SHARED_LINKER_FLAGS_RELEASE</code>: <code>/INCREMENTAL:NO</code></p></li><li><p><code>CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO</code>: <code>/debug /INCREMENTAL</code></p></li><li><p><code>/Zi</code>: 调试信息不包含在对象文件或可执行文件中,这使得这些文件最小</p></li><li><p><code>/MD</code>: 动态运行时依赖库, /MT 是静态运行时库</p></li><li><p><code>/O2</code>: O2 会尝试更多的寄存器级的优化以及指令级的优化,它会在编译期间占用更多的内存的编译时间</p></li><li><p><code>/O1</code>: O1 优化会消耗少得多的编译时间。主要对代码的分支,常量以及表达式等进行优化</p></li><li><p><code>/O3</code>: 在 O2 基础上进行更多的优化,例如使用伪寄存器网络,普通函数的内联以及针对循环的更多优化</p></li><li><p><code>/O0</code>: 不做任何优化,默认编译选项</p></li><li><p><code>/OPT:REF</code>: 清除从未引用的函数和数据</p></li><li><p><code>/OPT:ICF</code>: 从链接器中删除冗余的 COMAT</p></li><li><p><code>/INCREMENTAL</code>: debug 的情况下默认是这个选项</p></li></ul>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="cmake" scheme="http://nikohpng.github.io/categories/cmake/"/>
<category term="cmake" scheme="http://nikohpng.github.io/tags/cmake/"/>
</entry>
<entry>
<title>powershell安装配置内容</title>
<link href="http://nikohpng.github.io/2023/06/22/system/powershell%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE%E5%86%85%E5%AE%B9/"/>
<id>http://nikohpng.github.io/2023/06/22/system/powershell%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE%E5%86%85%E5%AE%B9/</id>
<published>2023-06-22T13:03:32.000Z</published>
<updated>2023-06-22T14:44:52.974Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><h2 id="PowerShell-配置脚本"><a href="#PowerShell-配置脚本" class="headerlink" title="PowerShell 配置脚本"></a>PowerShell 配置脚本</h2><figure class="highlight ps"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Import-Module</span> DirColors</span><br><span class="line"><span class="built_in">Set-Alias</span> bb <span class="string">"busybox"</span> </span><br><span class="line"><span class="built_in">Set-Alias</span> vim <span class="string">"nvim"</span></span><br><span class="line"><span class="built_in">Set-Alias</span> vi <span class="string">"nvim"</span></span><br><span class="line"><span class="built_in">Set-Alias</span> open <span class="string">"explorer.exe"</span></span><br><span class="line"><span class="built_in">Set-Alias</span> which <span class="string">"gcm"</span></span><br><span class="line"><span class="built_in">Set-Alias</span> vscode <span class="string">"code"</span></span><br><span class="line"><span class="built_in">Set-Alias</span> ll <span class="string">"ls"</span></span><br><span class="line"><span class="built_in">Set-Alias</span> android <span class="string">"D:\Install\IDE\Android Studio\bin\studio64.exe"</span></span><br><span class="line"><span class="built_in">Set-Alias</span> yd <span class="string">"C:\Users\heping\Documents\WindowsPowerShell\yd.ps1"</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">locate</span></span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="variable">$args</span>[<span class="number">0</span>].StartsWith(<span class="string">"-"</span>)) {</span><br><span class="line"> D:\Install\Manager\Everything\Everything.exe <span class="variable">$args</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> D:\Install\Manager\Everything\Everything.exe <span class="literal">-s</span> <span class="variable">$args</span>[<span class="number">0</span>]</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="安装的软件"><a href="#安装的软件" class="headerlink" title="安装的软件"></a>安装的软件</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">scoop install busybox</span><br><span class="line">scoop install sudo</span><br></pre></td></tr></table></figure><h2 id="配置内容"><a href="#配置内容" class="headerlink" title="配置内容"></a>配置内容</h2><ul><li>busybox 软链接配置<figure class="highlight bat"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> <span class="variable">%%i</span> <span class="keyword">in</span> (ar, arch, ash, awk, base64, basename, bash, bunzip2, bzcat, bzip2, cal, cat, chmod, cksum, ^</span><br><span class="line"> clear, cmp, comm, cp, cpio, cut, <span class="built_in">date</span>, dc, dd, df, diff, dirname, dos2unix, dpkg, dpkg-deb, du, <span class="built_in">echo</span>, ed,^</span><br><span class="line"> egrep, env, expand, expr, factor, false, fgrep, <span class="built_in">find</span>, fold, fsync, ftpget, ftpput, getopt, grep, groups,^</span><br><span class="line"> gunzip, gzip, hd, head, hexdump, iconv, id, ipcalc, kill, killall, less, link, ln, logname, ls, lzcat, lzma,^</span><br><span class="line"> lzop, lzopcat, man, md5sum, <span class="built_in">mkdir</span>, mktemp, mv, nc, nl, od, paste, patch, pgrep, pidof, pipe_progress, pkill,^</span><br><span class="line"> printenv, printf, ps, pwd, readlink, realpath, reset, rev, rm, <span class="built_in">rmdir</span>, rpm, rpm2cpio, sed, seq, sh, sha1sum,^</span><br><span class="line"> sha256sum, sha3sum, sha512sum, shred, shuf, sleep, <span class="built_in">sort</span>, split, ssl_client, stat, strings, su, sum, tac, tail,^</span><br><span class="line"> tar, tee, test, timeout, touch, tr, true, truncate, ts, ttysize, uname, uncompress, unexpand, uniq, unix2dos,^</span><br><span class="line"> unlink, unlzma, unlzop, unxz, unzip, usleep, uudecode, uuencode, vi, watch, wc, wget, which, whoami, whois,^</span><br><span class="line"> xargs, xxd, xz, xzcat, yes, zcat)^</span><br><span class="line"> <span class="keyword">do</span> mklink C:\Windows\System32\<span class="variable">%%i</span>.exe C:\Windows\System32\busybox.exe</span><br><span class="line"><span class="keyword">for</span> <span class="variable">%%i</span> <span class="keyword">in</span> (ar, arch, ash, awk, base64, basename, bash, bunzip2, bzcat, bzip2, cal, cat, chmod, cksum, ^</span><br><span class="line"> clear, cmp, comm, cp, cpio, cut, <span class="built_in">date</span>, dc, dd, df, diff, dirname, dos2unix, dpkg, dpkg-deb, du, <span class="built_in">echo</span>, ed,^</span><br><span class="line"> egrep, env, expand, expr, factor, false, fgrep, <span class="built_in">find</span>, fold, fsync, ftpget, ftpput, getopt, grep, groups,^</span><br><span class="line"> gunzip, gzip, hd, head, hexdump, iconv, id, ipcalc, kill, killall, less, link, ln, logname, ls, lzcat, lzma,^</span><br><span class="line"> lzop, lzopcat, man, md5sum, <span class="built_in">mkdir</span>, mktemp, mv, nc, nl, od, paste, patch, pgrep, pidof, pipe_progress, pkill,^</span><br><span class="line"> printenv, printf, ps, pwd, readlink, realpath, reset, rev, rm, <span class="built_in">rmdir</span>, rpm, rpm2cpio, sed, seq, sh, sha1sum,^</span><br><span class="line"> sha256sum, sha3sum, sha512sum, shred, shuf, sleep, <span class="built_in">sort</span>, split, ssl_client, stat, strings, su, sum, tac, tail,^</span><br><span class="line"> tar, tee, test, timeout, touch, tr, true, truncate, ts, ttysize, uname, uncompress, unexpand, uniq, unix2dos,^</span><br><span class="line"> unlink, unlzma, unlzop, unxz, unzip, usleep, uudecode, uuencode, vi, watch, wc, wget, which, whoami, whois,^</span><br><span class="line"> xargs, xxd, xz, xzcat, yes, zcat)^</span><br><span class="line">rm C:\Windows\System32\b<span class="variable">%%i</span>.exe</span><br></pre></td></tr></table></figure></li></ul>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="Shell" scheme="http://nikohpng.github.io/categories/Shell/"/>
<category term="PowerShell" scheme="http://nikohpng.github.io/tags/PowerShell/"/>
</entry>
<entry>
<title>FreeSWITCH问题分析</title>
<link href="http://nikohpng.github.io/2023/04/27/freeswitch/FreeSWITCH%E9%97%AE%E9%A2%98%E5%88%86%E6%9E%90/"/>
<id>http://nikohpng.github.io/2023/04/27/freeswitch/FreeSWITCH%E9%97%AE%E9%A2%98%E5%88%86%E6%9E%90/</id>
<published>2023-04-27T12:47:49.000Z</published>
<updated>2023-12-23T12:47:17.067Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>本文主要讲解在实际运维过程中容易出现的问题现象以及导致其出现问题的根本原因,可能附带有解决方法</p><h2 id="30s挂断"><a href="#30s挂断" class="headerlink" title="30s挂断"></a>30s挂断</h2><p>呼叫通没问题,但是会出现 30s 挂断。一般原因有以下几个方面:</p><ul><li>外网端口与内网端口没有一对一映射:端口错误,导致客户端与 FS 的沟通出现网络无法连接问题,可能是 ACK 问题。<ul><li>解决方案:将接口一对一映射</li></ul></li></ul><h2 id="FS与opensip使用tls对接时,2分钟-tcp-断连"><a href="#FS与opensip使用tls对接时,2分钟-tcp-断连" class="headerlink" title="FS与opensip使用tls对接时,2分钟 tcp 断连"></a>FS与opensip使用tls对接时,2分钟 tcp 断连</h2><p>opensips 本身有个参数 <code>tcp_connection_lifetime</code> 用于控制 tcp 的存活时长,此存活时长只能通过与服务端发送数据来延长时间,无法通过 tcp 本身的 <code>keepalive</code> 来进行保活。</p><p>最后,必须通过 fs 端发送 option 来延长 tcp 的存活时间。<br>想要实现在通话中发送 option,那么必须使用 gateway ,并在 gateway 中配置 <code>ping</code> 来发送 option。</p><p>其中,option 存在问题还没开始通话就有 option 进行发送,其中的端口与通话的端口有什么关系呢?根据抓包发现:当前没通话,有新的呼叫创建情况下,有option,那就直接用option的端口。因而网关的option没通话时的option与新来通话后的option是同一个端口。</p><blockquote><p>注意:目前仅仅测试通过了 fs 作为 fresher 进行刷新保活,服务器作为 refresher 时,其 update 无法发送到 fs</p></blockquote><h2 id="修改FS的contact"><a href="#修改FS的contact" class="headerlink" title="修改FS的contact"></a>修改FS的contact</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><param name="apply-nat-acl" value="nat.auto"/></span><br><span class="line"><action application="export" data="sip_contact_user=${sip_from_user}" /></span><br></pre></td></tr></table></figure><h2 id="FS-修改由客户端刷新-session"><a href="#FS-修改由客户端刷新-session" class="headerlink" title="FS 修改由客户端刷新 session"></a>FS 修改由客户端刷新 session</h2><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">param</span> <span class="attr">name</span>=<span class="string">"enable-timer"</span> <span class="attr">value</span>=<span class="string">"true"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">param</span> <span class="attr">name</span>=<span class="string">"session-timeout"</span> <span class="attr">value</span>=<span class="string">"1800"</span>/></span></span><br></pre></td></tr></table></figure><h2 id="FS-修改语音舒适噪音问题"><a href="#FS-修改语音舒适噪音问题" class="headerlink" title="FS 修改语音舒适噪音问题"></a>FS 修改语音舒适噪音问题</h2><p>防止hold后一直播放铃音,导致无法unhold。sdp 中也有 cng 相关配置,具体请看 sdp</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">param</span> <span class="attr">name</span>=<span class="string">"suppress-cng"</span> <span class="attr">value</span>=<span class="string">"true"</span>/></span></span><br></pre></td></tr></table></figure><h2 id="FS-回复指定的SIP错误信息"><a href="#FS-回复指定的SIP错误信息" class="headerlink" title="FS 回复指定的SIP错误信息"></a>FS 回复指定的SIP错误信息</h2><pre><code class="lua">local response_code = "500" -- 响应码为500,表示Internal Server Errorlocal reason_phrase = "Internal Server Error" -- 响应原因短语session:execute("respond", response_code .. " " .. reason_phrase)···</code></pre>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="FreeSWTICH" scheme="http://nikohpng.github.io/categories/FreeSWTICH/"/>
<category term="Question" scheme="http://nikohpng.github.io/tags/Question/"/>
</entry>
<entry>
<title>WebRTC问题分析内容</title>
<link href="http://nikohpng.github.io/2023/04/25/webrtc/WebRTC%E9%97%AE%E9%A2%98%E5%88%86%E6%9E%90%E5%86%85%E5%AE%B9/"/>
<id>http://nikohpng.github.io/2023/04/25/webrtc/WebRTC%E9%97%AE%E9%A2%98%E5%88%86%E6%9E%90%E5%86%85%E5%AE%B9/</id>
<published>2023-04-25T12:41:53.000Z</published>
<updated>2023-04-25T12:50:37.819Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>WebRTC 的问题分析分析主要记录一些使用 WebRTC 过程中出现的问题,并且当前没有成体系的内容用于总结,简单的零散分析</p><h2 id="WebRTC-的-oncandidate-时候失败,导致-setLocalDescription-耗时增加"><a href="#WebRTC-的-oncandidate-时候失败,导致-setLocalDescription-耗时增加" class="headerlink" title="WebRTC 的 oncandidate 时候失败,导致 setLocalDescription 耗时增加"></a>WebRTC 的 oncandidate 时候失败,导致 setLocalDescription 耗时增加</h2><ul><li>问题:如标题所诉,由于在收集本地网络环境的,一些网卡(虚拟网卡等)的 ip,不具有连接网络的能力,导致在收集 IP 的时候会出现失败。</li><li>解决方案:监听来自 oncandidate 的事件,检测到有 relay 或 srly 的就可以直接调用 complete <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">session.on(<span class="string">"icecandidate"</span>, <span class="function"><span class="keyword">function</span> (<span class="params">event</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (event.candidate.type === <span class="string">"srflx"</span> &&</span><br><span class="line"> event.candidate.relatedAddress !== <span class="literal">null</span> &&</span><br><span class="line"> event.candidate.relatedPort !== <span class="literal">null</span>) {</span><br><span class="line"> event.ready();</span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure></li><li>查看错误:通过 <code>chrome://webrtc-internals</code> 即可查看 ice 收集失败的时候,对应的 ip 是多少</li></ul><h2 id="引用"><a href="#引用" class="headerlink" title="引用"></a>引用</h2><ul><li><a href="https://stackoverflow.com/questions/61253322/a-40-sec-delay-of-sip-call-initiation-using-jssip-webrtc">A 40 sec delay of SIP call initiation using JSSIP / WebRTC</a></li></ul>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="WebRTC" scheme="http://nikohpng.github.io/categories/WebRTC/"/>
<category term="Question" scheme="http://nikohpng.github.io/tags/Question/"/>
</entry>
<entry>
<title>WebRTC源码中文件的作用</title>
<link href="http://nikohpng.github.io/2023/03/30/webrtc/WebRTC%E6%BA%90%E7%A0%81%E4%B8%AD%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%9C%E7%94%A8/"/>
<id>http://nikohpng.github.io/2023/03/30/webrtc/WebRTC%E6%BA%90%E7%A0%81%E4%B8%AD%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%9C%E7%94%A8/</id>
<published>2023-03-30T13:03:54.000Z</published>
<updated>2023-03-30T13:09:29.983Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>本文主要讲解在 WebRTC 中一些文件的作用,并且其用途在编译过程中的一些用途。当然这些文件主要是一些配置文件,不包括源码文件</p><h2 id="src-中源码"><a href="#src-中源码" class="headerlink" title="src 中源码"></a>src 中源码</h2><ul><li><code>BUILD.gn</code>:本文件主要包含了各种需要编译的各种源码,其中配置了编译 SDK 时,需要编译的源码。</li><li><code>DEPS</code>:主要包含的是一些依赖文件,例如:openh264、ffmpeg等这类依赖文件</li></ul>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="WebRTC" scheme="http://nikohpng.github.io/categories/WebRTC/"/>
<category term="Source" scheme="http://nikohpng.github.io/tags/Source/"/>
</entry>
<entry>
<title>WebRTC在Mac中的编译</title>
<link href="http://nikohpng.github.io/2023/03/30/webrtc/WebRTC%E5%9C%A8Mac%E4%B8%AD%E7%9A%84%E7%BC%96%E8%AF%91/"/>
<id>http://nikohpng.github.io/2023/03/30/webrtc/WebRTC%E5%9C%A8Mac%E4%B8%AD%E7%9A%84%E7%BC%96%E8%AF%91/</id>
<published>2023-03-30T12:26:21.000Z</published>
<updated>2023-03-30T12:27:21.197Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><h1 id="webrtc-在-mac-编译-Mac-与-IOS"><a href="#webrtc-在-mac-编译-Mac-与-IOS" class="headerlink" title="webrtc 在 mac 编译 Mac 与 IOS"></a>webrtc 在 mac 编译 Mac 与 IOS</h1><p>本文将会讲解在 mac 中从拉取代码到打包成 xcframework 的所有步骤,包中包括了ios 与 mac 的所有包。</p><h2 id="设置代理"><a href="#设置代理" class="headerlink" title="设置代理"></a>设置代理</h2><p>编译 WebRTC 全程需要代理软件,所以建议设置好代理软件。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">export http_porxy="http://127.0.0.1:21087"</span><br><span class="line">export https_porxy="https://127.0.0.1:21087"</span><br></pre></td></tr></table></figure><blockquote><p>注意:即使在 MAC 中开启全局代理,仍然需要设置代理。本人编译时,没配置这个有时候出现无法下载外网资源,即使开了全局代理也没用。</p></blockquote><h2 id="安装-depot-tools"><a href="#安装-depot-tools" class="headerlink" title="安装 depot_tools"></a>安装 depot_tools</h2><p>depot_tools 是一套 Google 用来编译 WebRTC 的构建工具,获取 depot_tools 前,请先开启 VPN。</p><p>下载 <a href="https://storage.googleapis.com/chrome-infra/depot_tools.zip">depot_tools</a> 解压到某个目录,然后配置系统环境</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">export PATH=$PWD/depot_tools:$PATH</span><br></pre></td></tr></table></figure><h2 id="获取源代码"><a href="#获取源代码" class="headerlink" title="获取源代码"></a>获取源代码</h2><p>获取源代码<strong>不能使用官网的源代码</strong>,必须到 <a href="https://github.com/webrtc-sdk/webrtc">webrtc-sdk</a> 中获取专门为 <a href="https://github.com/flutter-webrtc/flutter-webrtc">flutter-webrtc</a>修改过的源码。<br>获取源码步骤如下所示:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">mkdir webrtc</span><br><span class="line">cd webrtc</span><br><span class="line">touch .gclient</span><br><span class="line">echo "solutions = [</span><br><span class="line"> {</span><br><span class="line"> "name": "src",</span><br><span class="line"> "url": "https://github.com/webrtc-sdk/webrtc.git",</span><br><span class="line"> "deps_file": "DEPS",</span><br><span class="line"> "managed": False,</span><br><span class="line"> "custom_deps": {},</span><br><span class="line"> },</span><br><span class="line">]</span><br><span class="line">target_os = ['ios']" > .gclient</span><br><span class="line">sudo gclient sync</span><br></pre></td></tr></table></figure><h2 id="生成示例代码"><a href="#生成示例代码" class="headerlink" title="生成示例代码"></a>生成示例代码</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gn gen out/ios --args='target_os="ios" target_cpu="arm64" is_component_build=false' --ide=xcode </span><br></pre></td></tr></table></figure><h2 id="替换本地编译-Frameworks"><a href="#替换本地编译-Frameworks" class="headerlink" title="替换本地编译 Frameworks"></a>替换本地编译 Frameworks</h2><p>在 flutter-webrtc 的 IOS 目录下面创建 Frameworks 目录,然后修改 podfile 如下所示:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"># s.dependency 'WebRTC-SDK', '104.5112.02'</span><br><span class="line"> s.ios.vendored_frameworks = 'Frameworks/WebRTC.xcframework'</span><br><span class="line"> s.vendored_frameworks = 'WebRTC.xcframework'</span><br></pre></td></tr></table></figure><h2 id="异常问题"><a href="#异常问题" class="headerlink" title="异常问题"></a>异常问题</h2><p>在拉取源代码的时候、获取依赖或者编译时可能出现各种奇奇怪怪的问题,下面会对一些奇怪问题进行解释与给出解决方法。</p><ul><li><p>:fatal: early EOF fatal: index-pack failed</p><ul><li>原因:此问题说拉取代码时,容量不够</li><li>解决方法:未知原因导致其存储在缓存空间,只要使用 sudo 权限去执行 gclient sync 即可解决问题</li></ul></li><li><p>下载某个资源时出现 ssl 验证错误。好像是更新 gclient 的时候。</p><ul><li>原因:由于我们挂了代理,不知什么原因导致了 ssl 验证失败</li><li>解决方法:需要 python 安装一个如下所示的内容,建议直接全局搜索 <code>Certificates.command</code> 这个文件所在位置 <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">where python3</span><br><span class="line">sudo python3 install Certificates.command</span><br></pre></td></tr></table></figure></li></ul></li><li><p>Failed to fetch file gs://chromiumxxxx</p><ul><li>原因:不知道啥原因,反正没法下载,只能自己手动下载了</li><li>解决方法:将其中的 <code>gs://</code> 替换为 <code>https://storage.googleapis.com/</code> 直接下载,然后将其改名为具体文件,放到指定位置下面就行。</li><li>补充:MAC 这边一共有 <code>clang</code>、<code>clang-format</code>、<code>test-fonts.tar.gz</code> 这几个文件没法下载,手动下载即可。其中 <code>test-fonts.tar.gz</code> 下载下来会是个<code>**.tar</code> 文件,只需要改成 <code>test-fonts.tar</code> 放入指定文件夹即可。</li></ul></li><li><p>error at <code>xtest_module_target="//test:google_test_runner_objc"</code></p><ul><li>原因:目前不知道原因</li><li>解决方法:直接去对应位置注释掉这行依赖,仍然可以使用</li></ul></li><li><p>cpid更新失败代理新的配置方案</p><ul><li>原因:配置了 https 代理的情况下,会对 ssl 进行验证,而由于我们开了代理,这个验证基本会失败</li><li>解决方法:将 https 代理设置成 http 代理就不会出现问题了。<code>export https_porxy="http://127.0.0.1:21087"</code></li></ul></li><li><p>可能碰到编译错误——fatal error: ‘libavutil/avconfig.h’ file not found:</p><ul><li>原因:目前不知道原因</li><li>解决方法:在 src/third_party/ffmpeg/libavutil/avconfig.h 中创建此文件,并填入如下内容: <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* Generated by ffconf */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifndef</span> AVUTIL_AVCONFIG_H</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> AVUTIL_AVCONFIG_H</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> AV_HAVE_BIGENDIAN 0</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> AV_HAVE_FAST_UNALIGNED 0</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span> <span class="comment">/* AVUTIL_AVCONFIG_H */</span></span></span><br></pre></td></tr></table></figure></li></ul></li></ul><h2 id="引用"><a href="#引用" class="headerlink" title="引用"></a>引用</h2><p><a href="https://blog.csdn.net/anyRTC/article/details/121225296">IOS技术分享| WebRTC iOS源码下载&编译</a><br><a href="https://juejin.cn/post/7119027229824122888">记录一次WebRTC iOS的源码编译过程</a><br><a href="https://www.cnblogs.com/elesos/p/9914766.html">在windows上编译chrome浏览器Building Chromium for Windows</a><br><a href="https://blog.csdn.net/xzy565143480/article/details/103194085">MacOS Python3.7 出现SSL: CERTIFICATE_VERIFY_FAILED报错解决方案</a><br><a href="https://hackmd.io/@eDUv2-UvT0mEwZSnPiH3Rg/ByYCr2_sL">Build WebRTC library for iOS</a><br><a href="http://myblog.emhct.net.cn/index.php/archives/2016">【webrtc、gclient】cpid更新失败代理新的配置方案</a><br><a href="https://blog.csdn.net/m0_37671478/article/details/100567535">Flutter插件开发,ios添加本地第三方framework</a></p>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="WebRTC" scheme="http://nikohpng.github.io/categories/WebRTC/"/>
<category term="WebRTC编译" scheme="http://nikohpng.github.io/tags/WebRTC%E7%BC%96%E8%AF%91/"/>
</entry>
<entry>
<title>WebRTC在ubuntu中编译android</title>
<link href="http://nikohpng.github.io/2023/03/30/webrtc/WebRTC%E5%9C%A8ubuntu%E4%B8%AD%E7%BC%96%E8%AF%91android/"/>
<id>http://nikohpng.github.io/2023/03/30/webrtc/WebRTC%E5%9C%A8ubuntu%E4%B8%AD%E7%BC%96%E8%AF%91android/</id>
<published>2023-03-30T11:59:43.000Z</published>
<updated>2023-03-30T12:18:59.815Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>本文将会讲解在 ubuntu 中拉取代码 flutter 中的 <a href="https://github.com/webrtc-sdk/webrtc.git">WebRTC</a> 并打包成 android 可以使用的 aar。</p><blockquote><p>注意:编译 Android 的时候,建议在国外的服务器上编译,否则可能出现无法获取各种依赖文件的问题</p></blockquote><h2 id="系统选择"><a href="#系统选择" class="headerlink" title="系统选择"></a>系统选择</h2><p>注意:在编译 android 端的 WebRTC 的时候必须选择 ubuntu,其中最好是采用以下版本</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Ubuntu 14.04 LTS (trusty with EoL April 2022)</span><br><span class="line">Ubuntu 16.04 LTS (xenial with EoL April 2024)</span><br><span class="line">Ubuntu 18.04 LTS (bionic with EoL April 2028)</span><br><span class="line">Ubuntu 20.04 LTS (focal with Eol April 2030)</span><br><span class="line">Ubuntu 20.10 (groovy) </span><br><span class="line">Debian 10 (buster) or later</span><br></pre></td></tr></table></figure><p>如果不是,那么可能遇到一些环境问题,需要手动修改源码</p><h2 id="设置代理"><a href="#设置代理" class="headerlink" title="设置代理"></a>设置代理</h2><p>拉取 WebRTC 全程需要代理软件,所以请先设置好代理软件</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">export http_proxy=http://192.168.101.21:7890</span><br><span class="line">export https_proxy=http://192.168.101.21:7890</span><br></pre></td></tr></table></figure><h2 id="安装-depot-tools"><a href="#安装-depot-tools" class="headerlink" title="安装 depot_tools"></a>安装 depot_tools</h2><p>depot_tools 是一套 Google 用来编译 WebRTC 的构建工具,获取 depot_tools 前,请先开启 VPN。</p><p>下载 <a href="https://storage.googleapis.com/chrome-infra/depot_tools.zip">depot_tools</a> 解压到某个目录,然后配置系统环境</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">echo "export PATH=$PWD/depot_tools:$PATH" > $HOME/.bashrc</span><br><span class="line">source $HOME/.bashrc</span><br></pre></td></tr></table></figure><h2 id="获取源码"><a href="#获取源码" class="headerlink" title="获取源码"></a>获取源码</h2><p>获取源代码不能使用官网的源代码,必须到 <a href="https://github.com/webrtc-sdk/webrtc">webrtc-sdk</a> 中获取专门为 <a href="https://github.com/flutter-webrtc/flutter-webrtc">flutter-webrtc</a> 修改过的源码。<br>获取源码步骤如下所示:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">mkdir webrtc</span><br><span class="line">cd webrtc</span><br><span class="line">touch .gclient</span><br><span class="line">echo "solutions = [</span><br><span class="line"> {</span><br><span class="line"> 'name': 'src',</span><br><span class="line"> 'url': 'https://github.com/webrtc-sdk/webrtc.git',</span><br><span class="line"> 'deps_file': 'DEPS',</span><br><span class="line"> 'managed': False,</span><br><span class="line"> 'custom_deps': {},</span><br><span class="line"> },</span><br><span class="line">]</span><br><span class="line">target_os = ['android']" > .gclient</span><br><span class="line">gclient sync --nohooks --no-history</span><br></pre></td></tr></table></figure><h2 id="源码编译"><a href="#源码编译" class="headerlink" title="源码编译"></a>源码编译</h2><ul><li><p>安装编译依赖:</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">gclient runhooks</span><br><span class="line">./src/build/install-build-deps.sh</span><br><span class="line">./src/build/install-build-deps-android.sh</span><br></pre></td></tr></table></figure></li><li><p>编译 aar 文件:</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vpython3 ./tools_webrtc/android/build_aar.py --build-dir webrtc_android --output ./webrtc_android/libwebrtc.aar --arch armeabi-v7a arm64-v8a x86_64 x86 --extra-gn-args 'is_java_debug=false rtc_include_tests=false rtc_use_h264=false is_component_build=false use_rtti=true rtc_build_examples=false treat_warnings_as_errors=false'</span><br></pre></td></tr></table></figure><h2 id="异常问题"><a href="#异常问题" class="headerlink" title="异常问题"></a>异常问题</h2></li></ul><p>拉取代码、安装依赖或者编译的时候可能出现一些奇怪的问题,此处将对遇到的问题进行分析以及提出相应的解决方案</p><ul><li>执行<code>./src/build/install-build-deps.sh</code>, 系统版本不适配(即没有按照步骤中的系统版本进行安装)<ul><li>原因:可能你使用的系统版本过高,过低那就没法了,至少要比上诉第一条中系统最低版本高</li><li>解决方案:通过 <code>lsb_release --codename --short</code> 查询系统 <strong>short name</strong>,加入到<code>./src/build/install-build-deps.sh</code>文件下的<code>supported_codenames</code> 变量中即可</li></ul></li><li>编译代码时可能出现缺少 LASTCHANGE 和 LASTCHANGE.committime 文件<ul><li>解决方案:直接前往内网 svn 获取 <a href="svn://10.10.0.1/svnrepos/%E8%81%94%E9%80%9A/WebRTC/Dependency/M92/Win">LASTCHANGE 和 LASTCHANGE.committime</a>即可</li></ul></li><li>编译时出现 <code>Mission sysroot</code> 错误<ul><li>原因:已经很明显,少 sysroot,并且提示里面要求 <strong>run: build/linux/sysroot_scripts/install-sysroot.py –arch=amd64</strong></li><li>解决方案:运行这个脚本即可,注意打开全局代理。如果还不行就手动下载,解压后放到<code>/usr/local/sysroot</code> 目录下,配置下 <code>/etc/profile</code> 指向 <code>sysroot</code> 这个文件夹<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"> mkdir -p sysroot</span><br><span class="line">tar -xvf debian_bullseye_amd64_sysroot.tar.xz -C sysroot</span><br></pre></td></tr></table></figure></li></ul></li><li>编译时缺少 <strong>llvm-build</strong> 文件夹<ul><li>原因:不知道什么原因就是无法同步下来</li><li>解决方案:在国外服务器上同步下来后,把 <code>llvm-build</code> 文件拷贝下来即可。也可以用点击 <a href="">llvm-build</a>下载</li></ul></li></ul>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="WebRTC" scheme="http://nikohpng.github.io/categories/WebRTC/"/>
<category term="WebRTC编译" scheme="http://nikohpng.github.io/tags/WebRTC%E7%BC%96%E8%AF%91/"/>
</entry>
<entry>
<title>FreeSWITCH中xml_rpc的使用技巧</title>
<link href="http://nikohpng.github.io/2023/03/27/freeswitch/FreeSWITCH%E4%B8%ADxml-rpc%E7%9A%84%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7/"/>
<id>http://nikohpng.github.io/2023/03/27/freeswitch/FreeSWITCH%E4%B8%ADxml-rpc%E7%9A%84%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7/</id>
<published>2023-03-27T13:12:18.000Z</published>
<updated>2023-03-27T13:19:12.802Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>本文主要讲解在实际开发中,可能遇到的使用 xml_rpc 命令过程中的一些内容</p><h2 id="查询-api-的命令"><a href="#查询-api-的命令" class="headerlink" title="查询 api 的命令"></a>查询 api 的命令</h2><p>查看 xml_rpc 中的命令通过如下方式即可,在浏览器中打开如下链接:<code>http://127.0.0.1:8080/webapi/help</code></p><h2 id="调试命令"><a href="#调试命令" class="headerlink" title="调试命令"></a>调试命令</h2><ul><li>通过 curl 调用 lua 程序,并传递参数,其中空格需要用 %20 替换 <figure class="highlight shell"><figcaption><span>script</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl --user yw:yw@123 http://127.0.0.1:7652/webapi/luarun?call_phone.lua%20var</span><br></pre></td></tr></table></figure></li><li></li></ul>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="FreeSWTICH" scheme="http://nikohpng.github.io/categories/FreeSWTICH/"/>
<category term="xml_rpc" scheme="http://nikohpng.github.io/tags/xml-rpc/"/>
</entry>
<entry>
<title>FreeSWITCH中mod的状态变化</title>
<link href="http://nikohpng.github.io/2023/03/23/freeswitch/FreeSWITCH%E4%B8%ADmod%E7%9A%84%E7%8A%B6%E6%80%81%E5%8F%98%E5%8C%96/"/>
<id>http://nikohpng.github.io/2023/03/23/freeswitch/FreeSWITCH%E4%B8%ADmod%E7%9A%84%E7%8A%B6%E6%80%81%E5%8F%98%E5%8C%96/</id>
<published>2023-03-23T13:05:32.000Z</published>
<updated>2023-03-23T13:06:04.132Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>本文主要讲述在 endpoint 的 mod 在启动关闭与呼叫、挂断等其中的状态变化内容</p><h2 id="mod-的启动关闭"><a href="#mod-的启动关闭" class="headerlink" title="mod 的启动关闭"></a>mod 的启动关闭</h2><p>此处的状态变化最为简单,只有两个回调函数,分别如下所示:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SWITCH_MODULE_LOAD_FUNCTION(mod_test_load);</span><br><span class="line">SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_test_shutdown);</span><br><span class="line">SWITCH_MODULE_DEFINITION(mod_test, mod_test_load, mod_test_shutdown, <span class="literal">NULL</span>); <span class="comment">// mod_test_runtime</span></span><br></pre></td></tr></table></figure><p>一般 runtime 都没用,暂时不明白作用。有个这个定义后,再实现相应的启动关闭函数,如下所示:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SWITCH_MODULE_LOAD_FUNCTION(mod_test_load) {</span><br><span class="line"> <span class="comment">/// 你想要实现内容,宏展开后有如下参数</span></span><br><span class="line"> <span class="comment">/// switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool</span></span><br><span class="line">}</span><br><span class="line">SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_janus_shutdown) {</span><br><span class="line"> <span class="comment">/// 你想要实现内容,宏展开后是个 void,没有参数值</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="channel-的状态变化"><a href="#channel-的状态变化" class="headerlink" title="channel 的状态变化"></a>channel 的状态变化</h2><p>channel 的状态变化较为复杂,此处先沿着外呼的流程走一遍所有流程,并会标明调用什么函数发生状态变化,以及状态变化涉及的含义。</p><p>此处先展示所有涉及的状态以及它们分别所属结构体</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">switch_state_handler_table_t</span> test_state_handlers = {</span><br><span class="line"> <span class="comment">/*.on_init */</span> channel_on_init,</span><br><span class="line"> <span class="comment">/*.on_routing */</span> channel_on_routing,</span><br><span class="line"> <span class="comment">/*.on_execute */</span> channel_on_execute,</span><br><span class="line"> <span class="comment">/*.on_hangup */</span> channel_on_hangup,</span><br><span class="line"> <span class="comment">/*.on_exchange_media */</span> channel_on_exchange_media,</span><br><span class="line"> <span class="comment">/*.on_soft_execute */</span> channel_on_soft_execute,</span><br><span class="line"> <span class="comment">/*.on_consume_media */</span> <span class="literal">NULL</span>,</span><br><span class="line"> <span class="comment">/*.on_hibernate */</span> <span class="literal">NULL</span>,</span><br><span class="line"> <span class="comment">/*.on_reset */</span> <span class="literal">NULL</span>,</span><br><span class="line"> <span class="comment">/*.on_park */</span> <span class="literal">NULL</span>,</span><br><span class="line"> <span class="comment">/*.on_reporting */</span> <span class="literal">NULL</span>,</span><br><span class="line"> <span class="comment">/*.on_destroy */</span> channel_on_destroy};</span><br><span class="line"></span><br><span class="line"><span class="keyword">switch_io_routines_t</span> test_io_routines = {</span><br><span class="line"> <span class="comment">/*.outgoing_channel */</span> channel_outgoing_channel,</span><br><span class="line"> <span class="comment">/*.read_frame */</span> channel_read_frame,</span><br><span class="line"> <span class="comment">/*.write_frame */</span> channel_write_frame,</span><br><span class="line"> <span class="comment">/*.kill_channel */</span> channel_kill_channel,</span><br><span class="line"> <span class="comment">/*.send_dtmf */</span> channel_send_dtmf,</span><br><span class="line"> <span class="comment">/*.receive_message */</span> channel_receive_message,</span><br><span class="line"> <span class="comment">/*.receive_event */</span> channel_receive_event};</span><br><span class="line"></span><br><span class="line"><span class="comment">//...</span></span><br><span class="line"></span><br><span class="line">test_endpoint_interface->io_routines = &test_io_routines;</span><br><span class="line">test_endpoint_interface->state_handler = &test_state_handlers;</span><br></pre></td></tr></table></figure><ul><li><p>外呼 –> channel_outgoing_channel:</p><ul><li><p>参数如下所示:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">switch_call_cause_t</span> <span class="title">channel_outgoing_channel</span><span class="params">(<span class="keyword">switch_core_session_t</span> *session, <span class="keyword">switch_event_t</span> *var_event,</span></span></span><br><span class="line"><span class="function"><span class="params"> <span class="keyword">switch_caller_profile_t</span> *outbound_profile,</span></span></span><br><span class="line"><span class="function"><span class="params"> <span class="keyword">switch_core_session_t</span> **new_session, <span class="keyword">switch_memory_pool_t</span> **pool,</span></span></span><br><span class="line"><span class="function"><span class="params"> <span class="keyword">switch_originate_flag_t</span> flags, <span class="keyword">switch_call_cause_t</span> *cancel_cause)</span> </span>{</span><br><span class="line"></span><br><span class="line"> }</span><br></pre></td></tr></table></figure></li><li><p>作用:创建媒体流、创建channel、初始化参数等</p></li><li><p>状态变化函数:<code>switch_channel_set_state(channel, CS_INIT);</code></p></li><li><p>未知作用函数:<code>switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);</code></p></li></ul></li><li><p>channel_outgoing_channel –> channel_on_init:</p><ul><li><p>参数如下所示:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">switch_status_t</span> <span class="title">channel_on_init</span><span class="params">(<span class="keyword">switch_core_session_t</span> *session)</span></span></span><br></pre></td></tr></table></figure></li><li><p>作用:一般用户初始化该通呼叫所需要的一些初始化参数</p></li><li><p>返回值:状态值为 <code>SWITCH_STATUS_SUCCESS</code> 将自动进入下个状态,否则将跳过该此呼叫</p></li><li><p>状态变化函数:无</p></li><li><p>未知作用函数:<code>switch_set_flag_locked(tech_pvt, TFLAG_IO);</code></p></li></ul></li><li><p>channel_on_init –> channel_on_routing:</p><ul><li><p>参数如下所示:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">switch_status_t</span> <span class="title">channel_on_routing</span><span class="params">(<span class="keyword">switch_core_session_t</span> *session)</span></span></span><br></pre></td></tr></table></figure></li><li><p>作用:一般在此处进行路由相关处理,准备编解码器、创建媒体流端口、生成sdp并与被叫方建立连接等工作</p></li><li><p>返回值:状态值为 <code>SWITCH_STATUS_SUCCESS</code> 将自动进入下个状态,否则将跳过该此呼叫</p></li><li><p>状态变化函数:<code>switch_channel_pre_answer(channel)</code> 和 <code>switch_channel_answer(channel)</code></p></li><li><p>未知作用函数:<code>switch_channel_set_flag(channel, CF_AUDIO);</code></p></li></ul></li><li><p>channel_on_routing –> channel_on_execute: (可略)</p></li><li><p>channel_on_hangup:</p><ul><li><p>参数如下所示:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">switch_status_t</span> <span class="title">channel_on_hangup</span><span class="params">(<span class="keyword">switch_core_session_t</span> *session)</span></span></span><br></pre></td></tr></table></figure></li><li><p>作用:呼叫中断的时候,此处的函数就会被回调,无论是 a-leg 还是 b-leg, 一般用于销毁信令上的一些内容</p></li><li><p>返回值:状态值为 <code>SWITCH_STATUS_SUCCESS</code> 将自动进入下个状态,否则将跳过该此呼叫</p></li><li><p>状态变化函数:<code>switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);</code></p></li></ul></li><li><p>channel_on_hangup –> channel_on_destroy:</p><ul><li><p>参数如下所示:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">switch_status_t</span> <span class="title">channel_on_destroy</span><span class="params">(<span class="keyword">switch_core_session_t</span> *session)</span></span></span><br></pre></td></tr></table></figure></li><li><p>作用:在呼叫被 hangup 完成后被回调,用于销毁初始化的媒体流、端口等</p></li><li><p>返回值:状态值为 <code>SWITCH_STATUS_SUCCESS</code> 将自动进入下个状态,否则将跳过该此呼叫</p></li></ul></li></ul>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="FreeSWTICH" scheme="http://nikohpng.github.io/categories/FreeSWTICH/"/>
<category term="channels" scheme="http://nikohpng.github.io/tags/channels/"/>
</entry>
<entry>
<title>FreeSWITCH在Linux下编译模块编译</title>
<link href="http://nikohpng.github.io/2023/03/22/freeswitch/FreeSWITCH%E5%9C%A8Linux%E4%B8%8B%E7%BC%96%E8%AF%91%E6%A8%A1%E5%9D%97%E7%BC%96%E8%AF%91/"/>
<id>http://nikohpng.github.io/2023/03/22/freeswitch/FreeSWITCH%E5%9C%A8Linux%E4%B8%8B%E7%BC%96%E8%AF%91%E6%A8%A1%E5%9D%97%E7%BC%96%E8%AF%91/</id>
<published>2023-03-22T13:21:15.000Z</published>
<updated>2023-12-23T12:44:50.741Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="\assets\js\Meting.min.js"></script><p>本文主要讲解在 Linux 环境下编译 FreeSWITCH 模块时的配置以及所遇到的问题</p><h2 id="Linux-下编译-MOD-的配置"><a href="#Linux-下编译-MOD-的配置" class="headerlink" title="Linux 下编译 MOD 的配置"></a>Linux 下编译 MOD 的配置</h2><ul><li>在 configure.ac 中配置需要编译模块的 makefile文件,例如:src/mod/endpoints/mod_verto/Makefile <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">PKG_CHECK_MODULES([HIREDIS], [hiredis >= 0.10.0],[</span><br><span class="line">AM_CONDITIONAL([HAVE_HIREDIS],[true])],[</span><br><span class="line">AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_HIREDIS],[false])])</span><br><span class="line"></span><br><span class="line">PKG_CHECK_MODULES([REDIS_PLUS], [redis++ >= 1.3.10],[</span><br><span class="line">AM_CONDITIONAL([HAVE_REDIS_PLUS],[true])],[</span><br><span class="line">AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_REDIS_PLUS],[false])])</span><br><span class="line"></span><br><span class="line">src/mod/applications/mod_redis_plus/Makefile</span><br></pre></td></tr></table></figure></li><li>在 modules.conf 中配置允许编译的模块,例如:endpoints/mod_verto</li><li>运行 <code>autoreconf -fiv</code> 重新生成 m4 文件</li><li>通过 rebootstrap.sh or bootstrap.sh 重新生成 configure 编译文件</li></ul><h2 id="关于-Linux-下模块的-Makefile-am-编写事项"><a href="#关于-Linux-下模块的-Makefile-am-编写事项" class="headerlink" title="关于 Linux 下模块的 Makefile.am 编写事项"></a>关于 Linux 下模块的 Makefile.am 编写事项</h2><h2 id="失败问题总结"><a href="#失败问题总结" class="headerlink" title="失败问题总结"></a>失败问题总结</h2><ul><li>无法生成 Makefile.in 文件<ul><li>注意模块位置不要写错了,否则无法生成</li></ul></li></ul>]]></content>
<summary type="html"><link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" cla</summary>
<category term="FreeSWTICH" scheme="http://nikohpng.github.io/categories/FreeSWTICH/"/>
<category term="mod" scheme="http://nikohpng.github.io/tags/mod/"/>
</entry>
</feed>