> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# هواتف SIP المكتبية والتطبيقات: لماذا لا يرن الجوال النائم؟
- URL: https://arabroot.io/articles/هواتف-sip-المكتبية-والتطبيقات-والجوال/
- Published: 2026-10-19T07:30:00.000Z
- Updated: 2026-10-20T20:46:54.000Z
- Description: نجهز الهواتف المكتبية تلقائياً من سيرفر واحد ونؤمن ملفاتها، ونرى أزرار BLF من الداخل، ولماذا يحتاج تطبيق الجوال إشعارات Push حتى يرن.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, الاستضافة الذاتية والتطبيقات, الشبكات والوصول, تطبيقات لفريقك, الاستضافة الذاتية

عندما يصل إلى مكتبك صندوق فيه ثلاثون هاتفاً مكتبياً جديداً، فأمامك طريقان: أن تفتح واجهة الويب لكل هاتف وتكتب فيه رقم التحويلة وكلمة المرور وعنوان المقسم وتعيد ذلك ثلاثين مرة، أو أن تصل الهواتف بالشبكة فتجد إعداداتها وحدها وتسجل في المقسم قبل أن تنتهي من ترتيب الكراتين. والطريق الثاني له اسم هو التهيئة التلقائية Auto Provisioning، وهو ما تفعله كل شركة تدير أكثر من عشرة هواتف، وفيه أيضاً أكثر خطأ أمني يتكرر في هذا المجال: ملف فيه كلمة مرور كل تحويلة، على سيرفر يقرأ منه أي جهاز في الشبكة.

المواضيع في السلسلة:

- [مصطلحات الاتصالات الهاتفية VoIP للمبتدئين](https://arabroot.io/articles/%D9%85%D8%B5%D8%B7%D9%84%D8%AD%D8%A7%D8%AA-voip-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)
- [تتبع مكالمة SIP عبر الشبكة: لماذا يصل الصوت في اتجاه واحد؟](https://arabroot.io/articles/%D8%AA%D8%AA%D8%A8%D8%B9-%D9%85%D9%83%D8%A7%D9%84%D9%85%D8%A9-sip-%D8%B9%D8%A8%D8%B1-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-%D9%88%D8%A7%D9%84%D8%B5%D9%88%D8%AA-%D9%81%D9%8A-%D8%A7%D8%AA%D8%AC%D8%A7%D9%87-%D9%88%D8%A7%D8%AD%D8%AF/)
- [لماذا يتقطع الصوت في مكالمات VoIP؟ قياس Jitter وPacket Loss](https://arabroot.io/articles/%D9%84%D9%85%D8%A7%D8%B0%D8%A7-%D9%8A%D8%AA%D9%82%D8%B7%D8%B9-%D8%A7%D9%84%D8%B5%D9%88%D8%AA-%D9%81%D9%8A-%D9%85%D9%83%D8%A7%D9%84%D9%85%D8%A7%D8%AA-voip/)
- [ربط المقسم PBX بشبكة الهاتف عبر SIP Trunk والأرقام DID](https://arabroot.io/articles/%D8%B1%D8%A8%D8%B7-%D8%A7%D9%84%D9%85%D9%82%D8%B3%D9%85-%D8%A8%D8%B4%D8%A8%D9%83%D8%A9-%D8%A7%D9%84%D9%87%D8%A7%D8%AA%D9%81-%D8%B9%D8%A8%D8%B1-sip-trunk/)
- [دليل Asterisk العملي: من التحويلة Extension إلى الرد الآلي IVR](https://arabroot.io/articles/%D8%AF%D9%84%D9%8A%D9%84-asterisk-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A-%D9%85%D9%86-%D8%A7%D9%84%D8%AA%D8%AD%D9%88%D9%8A%D9%84%D8%A9-%D8%A7%D9%84%D9%89-%D8%A7%D9%84%D8%B1%D8%AF-%D8%A7%D9%84%D8%A7%D9%84%D9%8A/)
- [FreePBX: مقسم هاتف PBX كامل تديره من المتصفح](https://arabroot.io/articles/freepbx-%D9%85%D9%82%D8%B3%D9%85-%D9%87%D8%A7%D8%AA%D9%81-%D9%83%D8%A7%D9%85%D9%84-%D8%AA%D8%AF%D9%8A%D8%B1%D9%87-%D9%85%D9%86-%D8%A7%D9%84%D9%85%D8%AA%D8%B5%D9%81%D8%AD/)
- [FreeSWITCH للمنصات الكبيرة ومراكز الاتصال Contact Center](https://arabroot.io/articles/freeswitch-%D9%84%D9%84%D9%85%D9%86%D8%B5%D8%A7%D8%AA-%D8%A7%D9%84%D9%83%D8%A8%D9%8A%D8%B1%D8%A9-%D9%88%D9%85%D8%B1%D8%A7%D9%83%D8%B2-%D8%A7%D9%84%D8%A7%D8%AA%D8%B5%D8%A7%D9%84/)
- [3CX أم FreePBX أم FreeSWITCH؟ كيف تختار المقسم PBX](https://arabroot.io/articles/3cx-%D8%A7%D9%85-freepbx-%D8%A7%D9%85-freeswitch/)
- هواتف SIP المكتبية والتطبيقات: لماذا لا يرن الجوال النائم؟ (الموضوع الحالي)
- [مركز اتصال Call Center على Asterisk: الطابور وتقرير SLA](https://arabroot.io/articles/%D9%85%D8%B1%D9%83%D8%B2-%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-call-center-%D8%B9%D9%84%D9%89-asterisk/)
- [تأمين المقسم من الاحتيال على المكالمات Toll Fraud](https://arabroot.io/articles/%D8%AA%D8%A3%D9%85%D9%8A%D9%86-%D8%A7%D9%84%D9%85%D9%82%D8%B3%D9%85-%D9%85%D9%86-%D8%A7%D9%84%D8%A7%D8%AD%D8%AA%D9%8A%D8%A7%D9%84-%D8%B9%D9%84%D9%89-%D8%A7%D9%84%D9%85%D9%83%D8%A7%D9%84%D9%85%D8%A7%D8%AA/)
- [موازنة الحمل Load Balancing أمام خوادم Asterisk مع Kamailio](https://arabroot.io/articles/%D9%85%D9%88%D8%A7%D8%B2%D9%86%D8%A9-%D8%A7%D9%84%D8%AD%D9%85%D9%84-%D8%A3%D9%85%D8%A7%D9%85-%D8%AE%D9%88%D8%A7%D8%AF%D9%85-asterisk-%D9%85%D8%B9-kamailio/)

وقد شرحنا في [مقال المصطلحات](https://arabroot.io/articles/%D9%85%D8%B5%D8%B7%D9%84%D8%AD%D8%A7%D8%AA-voip-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/) ما هو SIP وRTP والمقسم PBX، وفي [تتبع مكالمة SIP عبر الشبكة](https://arabroot.io/articles/%D8%AA%D8%AA%D8%A8%D8%B9-%D9%85%D9%83%D8%A7%D9%84%D9%85%D8%A9-sip-%D8%B9%D8%A8%D8%B1-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-%D9%88%D8%A7%D9%84%D8%B5%D9%88%D8%AA-%D9%81%D9%8A-%D8%A7%D8%AA%D8%AC%D8%A7%D9%87-%D9%88%D8%A7%D8%AD%D8%AF/) كيف تمر المكالمة عبر NAT، فلن نعيد ذلك هنا، وإنما سوف ننتقل من المقسم إلى الطرف الآخر: الجهاز الذي يمسكه الموظف. وسوف نتناول في هذا المقال ما يلي:

- أنواع الهواتف: الجهاز المكتبي Desk Phone، والهاتف البرمجي Softphone، وتطبيق الجوال، ومتى تختار كل واحد.
- التهيئة التلقائية: كيف يجد الهاتف ملف إعداده عبر DHCP Option 66، وكيف تسمي Yealink وGrandstream وFanvil ملفاتها بحسب وثائقها.
- تجربة عملية في Docker: سيرفر DHCP وسيرفر HTTP للتهيئة ومقسم Asterisk وهاتف يجد إعداده وحده، ثم نسرق كلمة مروره من حاسوب آخر في الشبكة ونغلق الثغرة.
- الهواتف البرمجية: Linphone وZoiper وMicroSIP وbaresip، وتسجيل Linphone من سطر الأوامر.
- أزرار المراقبة BLF وكيف تعمل من الداخل برسائل SUBSCRIBE وNOTIFY.
- مشكلة الجوال النائم: لماذا لا يرن التطبيق عندما تكون الشاشة مطفأة، وكيف تحلها الإشعارات Push Notifications وخوادم مثل Flexisip.

## ثلاثة أنواع من الهواتف ومتى تختار كلاً منها

بالنسبة للمقسم لا يوجد فرق بين الأنواع الثلاثة، فكلها عملاء SIP تسجل بتحويلة وكلمة مرور وتستقبل INVITE، والفرق كله في المكان الذي يعيش فيه الهاتف ومن يتحكم في تشغيله، وفيما يلي المقارنة:

| النوع                     | متى يناسب                                                            | ما يجب أن تنتبه له                                                                                           |
| ------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| الهاتف المكتبي Desk Phone | الاستقبال، ومراكز الاتصال، وأي مكتب يرد على مكالمات كثيرة طوال اليوم | يحتاج كهرباء من الشبكة PoE، ويحتاج التهيئة التلقائية إذا زاد العدد، وتحديث البرنامج الثابت Firmware مسؤوليتك |
| الهاتف البرمجي Softphone  | الموظف الذي يعمل على الحاسوب بسماعة رأس Headset، والعمل عن بعد       | جودة الصوت تعتمد على السماعة وشبكة البيت، والحاسوب النائم لا يرن                                             |
| تطبيق الجوال              | المبيعات والفنيون في الميدان، ومن يريد تحويلته معه خارج المكتب       | نظام الجوال يوقف التطبيق في الخلفية، فلا يرن دون إشعارات Push، كما سنرى في آخر المقال                        |

والهاتف المكتبي يأخذ الكهرباء غالباً من كابل الشبكة نفسه عبر Power over Ethernet، واختصاراً PoE، فلا يحتاج محولاً على المكتب، والمعيار الأول 802.3af يعطي من ال Switch حتى 15.4 واط للمنفذ، وهو يكفي أغلب الهواتف المكتبية، أما الهواتف ذات الشاشات الكبيرة والكاميرات فقد تحتاج 802.3at. لذلك قبل أن تشتري ال Switch اجمع استهلاك الهواتف من ورقة مواصفات كل طراز Datasheet، وقارن المجموع بميزانية الطاقة PoE Budget في ال Switch، وليس بعدد منافذه، والسبب أن Switch فيه 24 منفذ PoE قد لا تكفي ميزانيته لتشغيل 24 هاتفاً معاً.

وبما أن الهاتف أصبح جهازاً على الشبكة، فالأفضل أن تضع الهواتف في شبكة صوت منفصلة Voice VLAN، فتعطيها أولوية في ال Switch، ولا يصل إليها حاسوب الضيف في الشبكة نفسها، وقد شرحنا ذلك في [تقسيم الشبكة Network Segmentation](https://arabroot.io/articles/%D8%AA%D9%82%D8%B3%D9%8A%D9%85-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-network-segmentation-vlan-%D9%88-vpc/)، وسوف ترى في التجربة لماذا يهم هذا الفصل.

## التهيئة التلقائية Auto Provisioning: كيف يجد الهاتف إعداده؟

الحل البسيط أن تدخل واجهة الويب لكل هاتف وتكتب إعداده بيدك، وهذا يصلح لخمسة هواتف، ولكنه غير مناسب إطلاقاً لخمسين، والسبب ليس الوقت فقط: فعندما تريد تغيير الترميز Codec أو عنوان المقسم أو كلمة مرور الإدارة في كل الهواتف، يجب أن تمر عليها واحداً واحداً، وستجد بعد شهر أن كل هاتف في المكتب يعمل بإعداد مختلف قليلاً. والطريقة الصحيحة أن يكون الإعداد ملفات نصية على سيرفر واحد، والهاتف يقرأها عند كل تشغيل، فتغير الملف مرة واحدة وتعيد تشغيل الهواتف.

ويبقى سؤال واحد: كيف يعرف هاتف خرج للتو من الكرتونة عنوان هذا السيرفر؟ والإجابة أن الهاتف يسأل عنه في أول خطوة يقوم بها على الشبكة، أي طلب العنوان من DHCP. فسيرفر DHCP يستطيع أن يرسل مع العنوان خيارات إضافية، والخيار 66 عرفه [RFC 2132](https://www.rfc-editor.org/rfc/rfc2132?ref=arabroot.io) في الأصل باسم «اسم سيرفر TFTP»، ولكن الهواتف اليوم تقبل فيه رابطاً كاملاً بعنوان HTTP أو HTTPS. والصورة التالية تبين الخطوات:

![هاتف مكتبي جديد يتصل بالشبكة فيطلب عنواناً من سيرفر DHCP ويستلم معه الخيار 66 وفيه رابط سيرفر التهيئة، ثم يطلب من سيرفر HTTP الملف المشترك common.cfg وملفاً باسم عنوان MAC الخاص به فيه التحويلة وكلمة المرور، ثم يسجل في المقسم Asterisk برسالة REGISTER ويستلم 200 OK](https://arabroot.io/content/images/2026/10/voip-phones-01-provisioning-flow.webp)

الهاتف يعرف من DHCP أين ملفاته، ويعرف من عنوان MAC أي ملف يخصه

ولاحظ أن الهاتف يطلب ملفين وليس ملفاً واحداً: ملف مشترك فيه ما يتشابه في كل الهواتف، مثل الترميز والتوقيت واللغة وكلمة مرور الإدارة، وملف يحمل اسم عنوان MAC الخاص بالهاتف، فيه التحويلة وكلمة مرورها. وهذا النمط تجده عند الشركات الثلاث الأكثر انتشاراً، مع اختلاف الأسماء، كما في وثائقها الرسمية:

| الشركة      | الملف المشترك                             | ملف الهاتف                           | كيف يجد الهاتف السيرفر                                                                                                                                                                                                                                                                             |
| ----------- | ----------------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Yealink     | y0000000000XX.cfg، و XX رقمان بحسب الطراز | <MAC>.cfg مثل 00156574b150.cfg       | بالترتيب: Zero Touch ثم PnP ثم خيارات DHCP (خيار مخصص ثم 66 ثم 43)، بحسب [دليل التهيئة التلقائية من Yealink](https://support-cdn.yealink.com/attachment/upload/attachment/2020-7-23/3/66fd3a79-9c6d-406b-8f03-4d130a469ae8/Yealink+SIP+IP+Phones+Auto+Provisioning+Guide+V1.1.pdf?ref=arabroot.io) |
| Grandstream | ملف للطراز مثل cfggrp2614.xml ثم cfg.xml  | cfg<MAC>.xml مثل cfg000b820102ab.xml | DHCP 66 أو 43، والإعدادات بأرقام تسمى P-values، بحسب [دليل التهيئة من Grandstream](https://documentation.grandstream.com/knowledge-base/sip-device-provisioning-guide/?ref=arabroot.io)                                                                                                            |
| Fanvil      | ملف للطراز مثل F0V00X600000.cfg           | <MAC>.cfg مثل 001565113af8.cfg       | بالترتيب: MDNS ثم FDPS ثم DHCP ثم TR069 ثم SIP، بحسب [وصف التهيئة من Fanvil](https://www.fanvil.com/Uploads/Temp/download/20191218/5df9dd9ce42f0.pdf?ref=arabroot.io)                                                                                                                              |

والكلمات Zero Touch وFDPS في الجدول هي خدمات سحابية تديرها الشركات المصنعة نفسها، وتسمى خدمات إعادة التوجيه Redirection Services: يسجل المورد رقم الهاتف التسلسلي أو عنوان MAC في حسابه عند الشركة، فيسأل الهاتف الجديد سيرفر الشركة عند أول تشغيل، فيوجهه إلى سيرفر التهيئة الخاص بك. وهي مفيدة للهاتف الذي يرسل إلى بيت موظف لا تتحكم في شبكته، ولكن تذكر أنها تضيف طرفاً ثالثاً في طريق إعداد هواتفك.

## التجربة: هاتف يجد إعداده وحده

سوف نبني في Docker ما يحدث في المكتب بالضبط: سيرفر DHCP بالبرنامج dnsmasq يرسل الخيار 66، وسيرفر Nginx يقدم ملفات التهيئة، ومقسم Asterisk، ثم «هاتف مكتبي» يبدأ من الصفر. ولأننا لا نملك هاتف Yealink داخل Container، سوف نستخدم الهاتف البرمجي baresip، ونكتب له سكربت تشغيل صغير يقوم بما يقوم به البرنامج الثابت في الهاتف الحقيقي: يطلب العنوان من DHCP، ويقرأ الخيار 66، ويطلب الملف المشترك وملف MAC، ثم يسجل. والملفات نفسها سوف تكون بصيغة baresip وليس بصيغة Yealink، ولكن الخطوات والأسماء والمخاطر هي نفسها.

![شبكة Docker باسم ard-vp-net على 10.88.60.0/24 فيها سيرفر DHCP على 10.88.60.2 وسيرفر التهيئة Nginx على 10.88.60.5 ومقسم Asterisk على 10.88.60.10، والهاتف المكتبي بعنوان MAC 02:ab:00:00:20:01 على 10.88.60.21، وLinphone على 10.88.60.22، وجهاز BLF على 10.88.60.23، والجوال على 10.88.60.24، وحاسوب في الشبكة نفسها على 10.88.60.40](https://arabroot.io/content/images/2026/10/voip-phones-02-lab-map.webp)

كل جهاز Container منفصل على شبكة Docker واحدة، دون أي منفذ مفتوح على جهازك

### ال Image وملفات المقسم

لا توجد Image رسمية لهذه الأدوات معاً، لذلك نبني Image واحدة من Ubuntu 24.04 ونثبت إصدار كل حزمة، كما فعلنا في [مقال تتبع المكالمة](https://arabroot.io/articles/%D8%AA%D8%AA%D8%A8%D8%B9-%D9%85%D9%83%D8%A7%D9%84%D9%85%D8%A9-sip-%D8%B9%D8%A8%D8%B1-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-%D9%88%D8%A7%D9%84%D8%B5%D9%88%D8%AA-%D9%81%D9%8A-%D8%A7%D8%AA%D8%AC%D8%A7%D9%87-%D9%88%D8%A7%D8%AD%D8%AF/#lab-image)، ونضيف إليها Linphone لسطر الأوامر، وSIPp لتقليد أزرار BLF، وNginx وdnsmasq وعميل DHCP:

```bash
FROM ubuntu:24.04
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
      asterisk=1:20.6.0~dfsg+~cs6.13.40431414-2build5 \
      asterisk-moh-opsound-gsm=2.03-1.1 \
      baresip-core=1.0.0-4build14 \
      linphone-cli=5.2.0-4.3ubuntu2 \
      sip-tester=1:3.7.2-1build3 \
      nginx=1.24.0-2ubuntu7.18 \
      dnsmasq-base=2.91-0ubuntu0.24.04.2 \
      isc-dhcp-client=4.4.3-P1-4ubuntu2 \
      tcpdump sngrep sox curl python3 iproute2 iptables iputils-ping procps \
 && rm -rf /var/lib/apt/lists/*
```

```bash
docker build -t ard-voip-tools:1 .
```

⚠️

حزمة Asterisk في Ubuntu 24.04 هي الإصدار 20.6.0، وهو قديم، ويناسب تجربة قصيرة فقط، لذلك لا تقم باستخدامه لمقسم حقيقي، وراجع [جدول إصدارات Asterisk](https://docs.asterisk.org/About-the-Project/Asterisk-Versions/?ref=arabroot.io) لتختار فرعاً مدعوماً.

والمقسم فيه ثلاث تحويلات: 2001 للهاتف المكتبي، و2002 لـ Linphone، و2003 لتطبيق الجوال، وكلها ترث من قالب واحد فيه خيارات NAT التي شرحناها في المقال السابق، والملف `asterisk/pjsip.conf` كاملاً:

```ini
[global]
type=global
user_agent=ArabRoot-Lab-PBX

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060

[phone](!)
type=endpoint
context=office
disallow=all
allow=ulaw,alaw
direct_media=no
rtp_symmetric=yes
force_rport=yes
rewrite_contact=yes
subscribe_context=office

[aor](!)
type=aor
max_contacts=1
remove_existing=yes
qualify_frequency=15

[2001](phone)
auth=2001
aors=2001
callerid="Reception" <2001>
[2001](aor)
[2001]
type=auth
auth_type=userpass
username=2001
password=Prov-2001-x9Kq

[2002](phone)
auth=2002
aors=2002
callerid="Linphone" <2002>
[2002](aor)
[2002]
type=auth
auth_type=userpass
username=2002
password=Lin-2002-p4Rt

[2003](phone)
auth=2003
aors=2003
callerid="Mobile" <2003>
[2003](aor)
[2003]
type=auth
auth_type=userpass
username=2003
password=Mob-2003-z7Wd
```

وخطة الاتصال في `asterisk/extensions.conf` قصيرة، والسطر الأول فيها هو التلميح Hint الذي سنحتاجه لأزرار BLF لاحقاً:

```ini
[office]
exten => _200X,hint,PJSIP/${EXTEN}
exten => _200X,1,NoOp(Call from ${CALLERID(num)} to ${EXTEN})
 same => n,Dial(PJSIP/${EXTEN},20)
 same => n,Hangup()
```

أما `rtp.conf` و`logger.conf` فهما كما في [المقال السابق](https://arabroot.io/articles/%D8%AA%D8%AA%D8%A8%D8%B9-%D9%85%D9%83%D8%A7%D9%84%D9%85%D8%A9-sip-%D8%B9%D8%A8%D8%B1-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-%D9%88%D8%A7%D9%84%D8%B5%D9%88%D8%AA-%D9%81%D9%8A-%D8%A7%D8%AA%D8%AC%D8%A7%D9%87-%D9%88%D8%A7%D8%AD%D8%AF/#lab-asterisk).

### سيرفر التهيئة وسيرفر DHCP

سيرفر التهيئة مجلد عادي على Nginx، فيه ملف مشترك `common.cfg` بصيغة إعداد baresip:

```text
# Shared by every phone in the office
poll_method      epoll
sip_listen       0.0.0.0:5060
audio_source     alsa,null
audio_player     alsa,null
audio_alert      alsa,null
rtp_ports        20000-20019
module_path      /usr/lib/baresip/modules
module           g711.so
module           aufile.so
module           menu.so
module_app       account.so
module           alsa.so
```

وملف للهاتف باسم عنوان MAC الخاص به دون النقطتين، أي `02ab00002001.cfg`، وفيه حساب التحويلة وكلمة مرورها:

```text
# Reception desk, MAC 02:ab:00:00:20:01
<sip:2001@10.88.60.10>;auth_pass=Prov-2001-x9Kq;answermode=auto
```

وإعداد Nginx في `prov/nginx-open.conf` يقدم المجلد كما هو، ويكتب في السجل عنوان كل جهاز طلب ملفاً والملف الذي طلبه، وسوف نحتاج هذا السجل كثيراً:

```nginx
events {}
http {
  log_format prov '$remote_addr "$request" $status $body_bytes_sent "$http_user_agent"';
  access_log /dev/stdout prov;
  server {
    listen 80;
    root /srv/www;
    default_type text/plain;
  }
}
```

وسيرفر DHCP يأخذ إعداده من `dhcp/dnsmasq.conf`، والسطر المهم هو الخيار 66:

```ini
port=0
interface=eth0
dhcp-range=10.88.60.100,10.88.60.150,255.255.255.0,1h
dhcp-option=option:router,10.88.60.1
dhcp-option=66,"http://10.88.60.5/prov/"
log-dhcp
```

و`port=0` يطفئ خدمة DNS في dnsmasq، لأننا نحتاج منه DHCP فقط. الآن نشغل الشبكة والسيرفرات الثلاثة، ونحن في Git Bash على Windows، لذلك نضع `MSYS_NO_PATHCONV=1` حتى لا يغير Git Bash المسارات داخل ال Container، ونأخذ مسار المجلد بصيغة Windows من `pwd -W`:

```bash
export MSYS_NO_PATHCONV=1
P=$(pwd -W)
docker network create --subnet 10.88.60.0/24 ard-vp-net

docker run -d --name ard-vp-pbx --network ard-vp-net --ip 10.88.60.10 \
  -v "$P/asterisk/pjsip.conf:/etc/asterisk/pjsip.conf" \
  -v "$P/asterisk/extensions.conf:/etc/asterisk/extensions.conf" \
  -v "$P/asterisk/rtp.conf:/etc/asterisk/rtp.conf" \
  -v "$P/asterisk/logger.conf:/etc/asterisk/logger.conf" \
  ard-voip-tools:1 asterisk -fvvv

docker run -d --name ard-vp-prov --network ard-vp-net --ip 10.88.60.5 \
  -v "$P/prov/nginx-open.conf:/etc/nginx/nginx.conf:ro" -v "$P/prov/www:/srv/www:ro" \
  ard-voip-tools:1 nginx -g 'daemon off;'

docker run -d --name ard-vp-dhcp --network ard-vp-net --ip 10.88.60.2 \
  --cap-add NET_ADMIN --cap-add NET_RAW \
  -v "$P/dhcp/dnsmasq.conf:/etc/dnsmasq.conf:ro" \
  ard-voip-tools:1 dnsmasq -k -C /etc/dnsmasq.conf --log-facility=-
```

💡

لاحظ أن الشبكة هنا شبكة Docker عادية وليست `--internal` كما في المقال السابق، والسبب أن Docker يسقط في الشبكة الداخلية الحزم الموجهة إلى خارج نطاقها، ومنها حزمة DHCP التي تذهب إلى العنوان العام 255.255.255.255، فإذا جربت DHCP على شبكة `--internal` فسوف ترى العميل يكرر `broadcasting discover` ولا يصل شيء إلى السيرفر.

### الهاتف يبدأ من الصفر

هذا هو سكربت التشغيل `phone-boot.sh` الذي يقلد البرنامج الثابت في الهاتف:

```bash
#!/bin/sh
# What a desk phone does at boot: DHCP, read option 66, fetch the common and per-MAC files, register
MAC=$(tr -d ':' < /sys/class/net/eth0/address)
echo "MAC: $MAC"
echo 'request subnet-mask, routers, tftp-server-name;' > /tmp/dhclient.conf
printf '#!/bin/sh\n[ -n "$new_tftp_server_name" ] && echo "$new_tftp_server_name" > /tmp/prov_url\nexit 0\n' > /tmp/hook.sh
chmod +x /tmp/hook.sh
dhclient -1 -sf /tmp/hook.sh -cf /tmp/dhclient.conf eth0
URL=$(cat /tmp/prov_url)
echo "Provisioning URL from DHCP option 66: $URL"
mkdir -p /conf
UA="ArabRoot-LabPhone/1.0 $MAC"
curl -fsS -A "$UA" "${URL}common.cfg" -o /conf/config || exit 1
curl -fsS -A "$UA" "${URL}${MAC}.cfg" | grep -v '^#' > /conf/accounts || exit 1
echo "Got $(grep -vc '^#' /conf/config) config lines and $(wc -l < /conf/accounts) account(s)"
exec baresip -f /conf
```

في السكربت أعلاه لاحظ التالي:

- عميل DHCP يطلب صراحة الخيار `tftp-server-name`، وهو اسم الخيار 66، والسكربت الصغير `hook.sh` يحفظ قيمته فقط ولا يغير عنوان ال Container، لأن Docker أعطاه عنواناً مسبقاً.
- عنوان MAC يأتي من كرت الشبكة نفسه، كما يفعل الهاتف الحقيقي، والملف يطلب بالحروف الصغيرة دون نقطتين.
- ال User-Agent يحمل عنوان MAC، وأغلب الهواتف الحقيقية تفعل شيئاً مشابهاً، فتعرف من سجل السيرفر أي هاتف طلب أي ملف.

ولاحظ أيضاً أننا استخدمنا isc-dhcp-client وليس عميل busybox الصغير udhcpc، والسبب أن udhcpc يتحقق من أن قيمة الخيار 66 اسم سيرفر صالح كما في المعيار، فيرفض الرابط ويطبع بدله الكلمة `bad`، وهذا يبين أن قبول رابط كامل في هذا الخيار عرف بين الهواتف وليس جزءاً من المعيار. الآن نشغل الهاتف بعنوان MAC محدد:

```bash
docker run -d --name ard-vp-desk --network ard-vp-net --ip 10.88.60.21 \
  --mac-address 02:ab:00:00:20:01 --cap-add NET_RAW --cap-add NET_ADMIN \
  -v "$P/phone-boot.sh:/boot.sh:ro" ard-voip-tools:1 sh /boot.sh
docker logs ard-vp-desk
```

والمخرج سوف يكون كما يلي، بعد أن حذفنا منه أسطر تحميل الوحدات:

```text
MAC: 02ab00002001
Provisioning URL from DHCP option 66: http://10.88.60.5/prov/
Got 12 config lines and 1 account(s)
baresip v1.0.0 Copyright (C) 2010 - 2020 Alfred E. Heggestad et al.
Local network address:  IPv4=eth0|10.88.60.21
Populated 1 account
baresip is ready.
2001@10.88.60.10: {0/UDP/v4} 200 OK (ArabRoot-Lab-PBX) [1 binding]
```

الهاتف سجل بالتحويلة 2001 دون أن نكتب فيه شيئاً. ولنرى ما حدث من جهة كل سيرفر، نقرأ سجل DHCP ثم سجل Nginx ثم جدول المقسم:

```bash
docker logs ard-vp-dhcp 2>&1 | grep -E "DHCP(DISCOVER|OFFER|REQUEST|ACK)|option: 66|requested options"
docker logs ard-vp-prov
docker exec ard-vp-pbx asterisk -rx 'pjsip show contacts'
```

والمخرج سوف يكون كما يلي، بعد أن حذفنا الأسطر المكررة من سجل DHCP:

```text
dnsmasq-dhcp[1]: 2794899461 DHCPDISCOVER(eth0) 02:ab:00:00:20:01
dnsmasq-dhcp[1]: 2794899461 DHCPOFFER(eth0) 10.88.60.150 02:ab:00:00:20:01
dnsmasq-dhcp[1]: 2794899461 requested options: 1:netmask, 3:router, 66:tftp-server
dnsmasq-dhcp[1]: 2794899461 sent size: 24 option: 66 tftp-server  http://10.88.60.5/prov/
dnsmasq-dhcp[1]: 2794899461 DHCPREQUEST(eth0) 10.88.60.150 02:ab:00:00:20:01
dnsmasq-dhcp[1]: 2794899461 DHCPACK(eth0) 10.88.60.150 02:ab:00:00:20:01

10.88.60.21 "GET /prov/common.cfg HTTP/1.1" 200 373 "ArabRoot-LabPhone/1.0 02ab00002001"
10.88.60.21 "GET /prov/02ab00002001.cfg HTTP/1.1" 200 104 "ArabRoot-LabPhone/1.0 02ab00002001"

  Contact:  2001/sip:2001-0x56431953f920@10.88.60.21:5060  7b7c213434 Avail         0.610
```

في المخرج أعلاه لاحظ التالي:

- الهاتف طلب في رسالته الخيار `66:tftp-server`، والسيرفر أرسله في العرض OFFER وفي التأكيد ACK، فالخيار يصل فقط لمن يطلبه، وهذا سبب شائع لهاتف لا يجد سيرفر التهيئة: الخيار مكتوب في السيرفر برقم آخر غير الذي يطلبه الهاتف.
- سجل Nginx فيه الطلبان بالترتيب: الملف المشترك ثم ملف MAC، وهذا السجل هو أول مكان تنظر فيه عندما لا يأخذ هاتف إعداده.
- المقسم يرى التحويلة `Avail`، أي أنها سجلت وترد على الفحص الدوري.

### هاتف لا يعرفه السيرفر

الآن نكسر الإعداد عمداً: نشغل هاتفاً ثانياً بعنوان MAC لم نجهز له ملفاً، وهذا ما يحدث في الواقع عندما يستبدل الفني هاتفاً معطلاً بآخر من المخزن دون أن يخبر من يدير المقسم:

```bash
docker run -d --name ard-vp-desk2 --network ard-vp-net --ip 10.88.60.25 \
  --mac-address 02:ab:00:00:20:99 --cap-add NET_RAW --cap-add NET_ADMIN \
  -v "$P/phone-boot.sh:/boot.sh:ro" ard-voip-tools:1 sh /boot.sh
docker logs ard-vp-desk2
docker logs ard-vp-prov 2>&1 | tail -2
```

والمخرج سوف يكون كما يلي:

```text
MAC: 02ab00002099
Provisioning URL from DHCP option 66: http://10.88.60.5/prov/
curl: (22) The requested URL returned error: 404
2026/10/20 08:16:13 [error] 8#8: *4 open() "/srv/www/prov/02ab00002099.cfg" failed (2: No such file or directory), client: 10.88.60.25, server: , request: "GET /prov/02ab00002099.cfg HTTP/1.1", host:
10.88.60.25 "GET /prov/02ab00002099.cfg HTTP/1.1" 404 162 "ArabRoot-LabPhone/1.0 02ab00002099"
```

الهاتف الحقيقي في هذه الحالة لا يتوقف كما توقف سكربتنا، وإنما يكمل بالملف المشترك وحده، فيظهر للموظف هاتف يعمل وشاشته مضيئة ولكن دون تحويلة. لذلك راقب في سجل سيرفر التهيئة طلبات 404 لملفات MAC، فكل سطر منها هاتف على مكتب أحدهم لا يرن.

## ملف التهيئة فيه كلمة المرور: من يستطيع قراءته؟

افتح ملف `02ab00002001.cfg` مرة أخرى، وستجد فيه كلمة مرور التحويلة كما هي، وفي الهواتف الحقيقية يحمل الملف المشترك أيضاً كلمة مرور واجهة الإدارة. والسؤال: من يستطيع طلب هذا الملف غير الهاتف؟ والإجابة في إعدادنا الحالي: أي جهاز يصل إلى السيرفر. وعناوين MAC ليست سراً، فأول ستة أرقام منها ثابتة لكل شركة مصنعة، ويكفي أن تعرف عنوان هاتف واحد في المكتب حتى تجرب ما حوله، لذلك نجرب من «حاسوب» في الشبكة نفسها أن يطلب 21 عنواناً متتالياً:

```bash
docker run --rm --name ard-vp-laptop --network ard-vp-net --ip 10.88.60.40 ard-voip-tools:1 sh -c '
for i in $(seq 1990 2010); do
  code=$(curl -s -o /tmp/f -w "%{http_code}" http://10.88.60.5/prov/02ab0000$i.cfg)
  [ "$code" = 200 ] && { echo "found 02ab0000$i.cfg:"; cat /tmp/f; }
done; echo "tried 21 addresses"'
```

والمخرج سوف يكون كما يلي:

```text
found 02ab00002001.cfg:
# Reception desk, MAC 02:ab:00:00:20:01
<sip:2001@10.88.60.10>;auth_pass=Prov-2001-x9Kq;answermode=auto
tried 21 addresses
```

وبهذا الشكل يحصل أي شخص في الشبكة على تحويلة الاستقبال وكلمة مرورها في أقل من ثانية، ويستطيع أن يسجل بها من حاسوبه ويجري مكالمات باسمها، وإذا كان سيرفر التهيئة مكشوفاً على الإنترنت حتى تصل إليه هواتف الموظفين في بيوتهم فالمشكلة أكبر بكثير، لأن المكالمات الخارجية على حسابك.

💡

قد يتساءل البعض: لماذا لا نشفر الملفات وتنتهي المشكلة؟ والإجابة أن التشفير يفيد فقط إذا بقي المفتاح سراً، ففي فبراير 2024 نشرت الثغرة [CVE-2024-24681](https://nvd.nist.gov/vuln/detail/CVE-2024-24681?ref=arabroot.io) عن أداة تشفير ملفات التهيئة من Yealink، والسبب أنها استخدمت مفتاحاً واحداً ثابتاً في كل التثبيتات عند كل العملاء، فمن يعرف هذا المفتاح يقرأ ملفات أي شركة. وفي أغسطس 2025 نشرت CISA [تنبيهاً عن خدمة RPS من Yealink](https://www.cisa.gov/news-events/ics-advisories/icsa-25-219-08?ref=arabroot.io) فيه أربع ثغرات، منها عدم تحديد عدد المحاولات عند التحقق من الرقم التسلسلي، مما يسمح بتخمينه، وقد أصلحتها الشركة في خدمتها السحابية.

والحل أن تجمع أكثر من طبقة، لأن كل طبقة وحدها يمكن تجاوزها:

- **شبكة الصوت المنفصلة Voice VLAN**: لا يصل إلى سيرفر التهيئة إلا أجهزة شبكة الهواتف، فلا يطلب حاسوب الضيف شيئاً.
- **اسم مستخدم وكلمة مرور على السيرفر**: الهاتف يرسلهما مع الطلب، ومن لا يعرفهما يستلم 401.
- **HTTPS**: حتى لا تمر كلمة مرور السيرفر وملفات الإعداد نصاً واضحاً في الشبكة.
- **سجل السيرفر**: راقب الطلبات المتتالية لعناوين MAC من عنوان IP واحد، فهي علامة واضحة على من يبحث.

ونطبق الآن الطبقة الثانية. نضيف كلمة مرور في `prov/prov.htpasswd` بالأمر `openssl passwd -apr1`، ونغير إعداد Nginx إلى `prov/nginx-locked.conf`:

```nginx
events {}
http {
  log_format prov '$remote_addr "$request" $status $body_bytes_sent "$http_user_agent"';
  access_log /dev/stdout prov;
  server {
    listen 80;
    root /srv/www;
    default_type text/plain;
    location /prov/ {
      # phones must send the provisioning password
      auth_basic "phones";
      auth_basic_user_file /etc/nginx/prov.htpasswd;
      # never list the folder
      autoindex off;
    }
  }
}
```

```bash
echo "prov:$(openssl passwd -apr1 'Prov-Lab-7Qe2')" > prov/prov.htpasswd
```

والهاتف يأخذ اسم المستخدم وكلمة المرور من الرابط نفسه في الخيار 66، فنكتب في `dhcp/dnsmasq-locked.conf`:

```ini
dhcp-option=66,"http://prov:Prov-Lab-7Qe2@10.88.60.5/prov/"
```

ثم نعيد تشغيل السيرفرين بالإعداد الجديد، ونجرب من الحاسوب ومن الهاتف:

```bash
docker rm -f ard-vp-prov ard-vp-dhcp ard-vp-desk ard-vp-desk2
docker run -d --name ard-vp-prov --network ard-vp-net --ip 10.88.60.5 \
  -v "$P/prov/nginx-locked.conf:/etc/nginx/nginx.conf:ro" \
  -v "$P/prov/prov.htpasswd:/etc/nginx/prov.htpasswd:ro" -v "$P/prov/www:/srv/www:ro" \
  ard-voip-tools:1 nginx -g 'daemon off;'
docker run -d --name ard-vp-dhcp --network ard-vp-net --ip 10.88.60.2 \
  --cap-add NET_ADMIN --cap-add NET_RAW \
  -v "$P/dhcp/dnsmasq-locked.conf:/etc/dnsmasq.conf:ro" \
  ard-voip-tools:1 dnsmasq -k -C /etc/dnsmasq.conf --log-facility=-

docker run --rm --network ard-vp-net --ip 10.88.60.40 ard-voip-tools:1 \
  curl -s -o /dev/null -w "laptop: %{http_code}\n" http://10.88.60.5/prov/02ab00002001.cfg
docker run -d --name ard-vp-desk --network ard-vp-net --ip 10.88.60.21 \
  --mac-address 02:ab:00:00:20:01 --cap-add NET_RAW --cap-add NET_ADMIN \
  -v "$P/phone-boot.sh:/boot.sh:ro" ard-voip-tools:1 sh /boot.sh
docker logs ard-vp-desk 2>&1 | grep -E "MAC|URL|Got|200 OK"
docker logs ard-vp-prov
```

والمخرج سوف يكون كما يلي:

```text
laptop: 401
MAC: 02ab00002001
Provisioning URL from DHCP option 66: http://prov:Prov-Lab-7Qe2@10.88.60.5/prov/
Got 12 config lines and 1 account(s)
2001@10.88.60.10: {0/UDP/v4} 200 OK (ArabRoot-Lab-PBX) [1 binding]
10.88.60.40 "GET /prov/02ab00002001.cfg HTTP/1.1" 401 188 "curl/8.5.0"
10.88.60.21 "GET /prov/common.cfg HTTP/1.1" 200 373 "ArabRoot-LabPhone/1.0 02ab00002001"
10.88.60.21 "GET /prov/02ab00002001.cfg HTTP/1.1" 200 104 "ArabRoot-LabPhone/1.0 02ab00002001"
```

الحاسوب استلم 401، والهاتف أخذ إعداده وسجل كما كان. ولكن انظر إلى السطر الثاني: كلمة مرور السيرفر نفسها تصل إلى الهاتف عبر DHCP، وDHCP يرسلها لأي جهاز يطلب عنواناً في الشبكة نفسها ويطلب الخيار 66، أي أن كلمة المرور هذه تحمي من الطلب العشوائي ومن الإنترنت، ولا تحمي من شخص في شبكة الهواتف نفسها يعرف ما يفعل. لذلك لا تقم بالاعتماد عليها وحدها، والسبب أن الحماية الحقيقية هنا هي فصل شبكة الصوت، ثم HTTPS، ثم مراقبة السجل، كما في القائمة أعلاه.

## الهواتف البرمجية Softphones: أيها تختار؟

الهاتف البرمجي برنامج يقوم بما يقوم به الهاتف المكتبي على الحاسوب أو الجوال، وفيما يلي أشهرها ممن يعمل مع أي مقسم SIP، مع ترخيص كل منها كما في صفحاته الرسمية عند كتابة المقال في أكتوبر 2026:

| البرنامج                                                                            | الأنظمة                             | الترخيص والسعر                                                                                                                                                                                                                                                                  | يناسب                                                                                 |
| ----------------------------------------------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| [Linphone](https://www.linphone.org/?ref=arabroot.io)                               | Windows وmacOS وLinux وiOS وAndroid | تطبيق [Linphone Desktop](https://github.com/BelledonneCommunications/linphone-desktop?ref=arabroot.io) بترخيص GPLv3، والمكتبة [liblinphone](https://github.com/BelledonneCommunications/liblinphone?ref=arabroot.io) بترخيص AGPLv3 أو ترخيص تجاري لمن يبني عليها تطبيقاً مغلقاً | من يريد برنامجاً واحداً مفتوح المصدر على كل الأنظمة، أو يبني تطبيق اتصال خاصاً بشركته |
| [Zoiper](https://www.zoiper.com/en/voip-softphone/download/current?ref=arabroot.io) | Windows وmacOS وLinux والجوال       | نسخة مجانية للاستخدام غير التجاري فقط، ونسخة Zoiper 5 Pro بشراء واحد ب €59.95 بحسب [صفحة الشراء](https://www.zoiper.com/en/shop/buy/zoiper5?ref=arabroot.io)، وفيها التهيئة التلقائية                                                                                           | الشركات التي تريد برنامجاً مغلقاً مدعوماً ومعروفاً عند المستخدمين                     |
| [MicroSIP](https://www.microsip.org/?ref=arabroot.io)                               | Windows فقط                         | مفتوح المصدر بترخيص GPL v2، ومجاني                                                                                                                                                                                                                                              | أجهزة Windows في المكاتب، وهو خفيف جداً                                               |
| [baresip](https://github.com/baresip/baresip?ref=arabroot.io)                       | Linux وغيره، من سطر الأوامر         | مفتوح المصدر بترخيص BSD                                                                                                                                                                                                                                                         | الاختبار والأجهزة المدمجة Embedded والتجارب مثل تجربتنا                               |

ولاحظ أن ترخيص Zoiper المجاني يمنع الاستخدام التجاري، فإذا وزعته على موظفي شركتك فأنت تحتاج النسخة المدفوعة، وهذا تفصيل يغفل عنه كثيرون عندما يرسلون رابط التحميل للموظفين.

### تسجيل Linphone من سطر الأوامر

Linphone له نسخة لسطر الأوامر اسمها linphonec، وهي مفيدة لاختبار مقسم من سيرفر دون واجهة رسومية، ولتجربة ما يحدث خلف الشاشة في التطبيق الرسومي، لأنهما يعتمدان على المكتبة نفسها liblinphone. والحساب يكتب في ملف إعداد بصيغة Linphone، ونضعه في `linphone/linphonerc`:

```ini
[sip]
sip_port=5060
default_proxy=0

[auth_info_0]
username=2002
passwd=Lin-2002-p4Rt
domain=10.88.60.10

[proxy_0]
reg_proxy=<sip:10.88.60.10;transport=udp>
reg_identity=sip:2002@10.88.60.10
reg_expires=600
reg_sendregister=1
```

وlinphonec برنامج تفاعلي يقرأ أوامره من لوحة المفاتيح، لذلك نشغله في Container يقرأ من ملف FIFO، فنرسل له الأوامر لاحقاً ب `docker exec`:

```bash
docker run -d --name ard-vp-linphone --network ard-vp-net --ip 10.88.60.22 \
  -v "$P/linphone:/conf:ro" ard-voip-tools:1 \
  sh -c 'cp /conf/linphonerc /root/.linphonerc; mkfifo /tmp/cmd; tail -f /tmp/cmd | linphonec -c /root/.linphonerc'
docker exec ard-vp-linphone sh -c 'echo "status register" > /tmp/cmd'
docker logs ard-vp-linphone 2>&1 | grep -E "database|registered"
```

والمخرج سوف يكون كما يلي:

```text
2026-10-20 08:16:52:920 liblinphone-error-Unable to open linphone database with uri "/root/.local/share/linphone/linphone.db" and backend Sqlite3
registered=-1
```

البرنامج يعمل ويرد على الأوامر، ولكنه لم يرسل أي رسالة REGISTER إلى المقسم، وقد تأكدنا من ذلك بالتقاط tcpdump على المقسم فلم نجد أي حزمة من 10.88.60.22\. والسبب في السطر الأول: liblinphone تحتاج مجلداً قابلاً للكتابة تحفظ فيه قاعدة بياناتها، والمجلد `~/.local/share/linphone` غير موجود في ال Container، ودون هذه القاعدة لا يكمل البرنامج تشغيل الحسابات. والحل أن ننشئ المجلد قبل التشغيل:

```bash
docker rm -f ard-vp-linphone
docker run -d --name ard-vp-linphone --network ard-vp-net --ip 10.88.60.22 \
  -v "$P/linphone:/conf:ro" ard-voip-tools:1 \
  sh -c 'mkdir -p /root/.local/share/linphone; cp /conf/linphonerc /root/.linphonerc; mkfifo /tmp/cmd; tail -f /tmp/cmd | linphonec -c /root/.linphonerc'
docker exec ard-vp-linphone sh -c 'echo "autoanswer enable" > /tmp/cmd; echo "status register" > /tmp/cmd'
docker logs ard-vp-linphone 2>&1 | grep -E "database|registered|Auto answer"
docker exec ard-vp-pbx asterisk -rx 'pjsip show contacts'
```

والمخرج سوف يكون كما يلي:

```text
Auto answer enabled.
registered, identity=sip:2002@10.88.60.10 duration=600

  Contact:  2001/sip:2001-0x5578b71ec920@10.88.60.21:5060  bf0f18ab82 Avail         0.672
  Contact:  2002/sip:2002@10.88.60.22:5060                 150deb6fcf Avail        35.938
```

والدرس هنا يتجاوز Linphone: عندما يقول البرنامج إنه يعمل ولا يظهر في المقسم، فلا تقم بتغيير كلمة المرور وعنوان السيرفر عشوائياً، وإنما التقط الحزم على المقسم أولاً، فإذا لم تصل أي رسالة REGISTER فالمشكلة في الجهاز نفسه وليست في المقسم ولا في الحساب.

## أزرار المراقبة BLF: كيف يعرف الهاتف أن زميلك في مكالمة؟

على هاتف موظف الاستقبال صف من الأزرار عليها أسماء الزملاء، وكل زر فيه ضوء: أخضر إذا كان الزميل متاحاً، وأحمر إذا كان في مكالمة، ويومض إذا كان هاتفه يرن، فيضغط الزر ليحول المكالمة أو ليرد عنه. وهذه الأزرار اسمها Busy Lamp Field، واختصاراً BLF، وهي من أهم أسباب اختيار الهاتف المكتبي على البرنامج في الاستقبال. والفكرة أن الهاتف لا يسأل عن حالة زميله كل ثانية، وإنما يشترك فيها مرة واحدة برسالة SUBSCRIBE، فيرسل له المقسم رسالة NOTIFY عند كل تغيير، وهذه الآلية هي حزمة الأحداث Event Package باسم `dialog` في [RFC 4235](https://www.rfc-editor.org/rfc/rfc4235?ref=arabroot.io).

![هاتف الاستقبال 2001 يرسل SUBSCRIBE بالحدث dialog للتحويلة 2002 إلى مقسم Asterisk، والمقسم يقرأ حالة الجهاز PJSIP/2002 من التلميح Hint ويرسل NOTIFY في كل تغيير: terminated عند الاشتراك ثم early عندما يرن ثم confirmed عند الرد ثم terminated عند الإغلاق، والضوء على الزر يتغير من أخضر إلى وامض إلى أحمر ثم أخضر](https://arabroot.io/content/images/2026/10/voip-phones-03-blf.webp)

اشتراك واحد، ثم إشعار عند كل تغيير في حالة الزميل

وفي Asterisk يربط التلميح Hint رقم التحويلة بحالة الجهاز الذي خلفها، وهو السطر الأول في خطة الاتصال: `exten => _200X,hint,PJSIP/${EXTEN}`، والخيار `subscribe_context=office` في القالب يحدد أين يبحث المقسم عن التلميح عندما يصله اشتراك، كما في [وثائق Asterisk للاشتراك في الحالة](https://docs.asterisk.org/Configuration/Channel-Drivers/SIP/Configuring-res%5Fpjsip/Configuring-res%5Fpjsip-for-Presence-Subscriptions/?ref=arabroot.io) و[شرح التلميحات](https://docs.asterisk.org/Fundamentals/Key-Concepts/States-and-Presence/Extension-State-and-Hints/?ref=arabroot.io). ولكي نرى الرسائل نفسها نقلد زر BLF واحداً بالأداة SIPp، وهي أداة لاختبار SIP تنفذ سيناريو مكتوباً بصيغة XML، وهذا هو السيناريو `blf.xml`:

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<!-- What a desk phone does for one BLF key: SUBSCRIBE to the dialog state of 2002 -->
<scenario name="blf">
  <send retrans="500">
    <![CDATA[
      SUBSCRIBE sip:2002@[remote_ip] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: <sip:2001@[remote_ip]>;tag=[pid]blf
      To: <sip:2002@[remote_ip]>
      Call-ID: [call_id]
      CSeq: 1 SUBSCRIBE
      Contact: <sip:2001@[local_ip]:[local_port]>
      Event: dialog
      Accept: application/dialog-info+xml
      Expires: 120
      Max-Forwards: 70
      Content-Length: 0
    ]]>
  </send>
  <recv response="401" auth="true"/>
  <send retrans="500">
    <![CDATA[
      SUBSCRIBE sip:2002@[remote_ip] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: <sip:2001@[remote_ip]>;tag=[pid]blf
      To: <sip:2002@[remote_ip]>
      Call-ID: [call_id]
      CSeq: 2 SUBSCRIBE
      Contact: <sip:2001@[local_ip]:[local_port]>
      [authentication username=2001 password=Prov-2001-x9Kq]
      Event: dialog
      Accept: application/dialog-info+xml
      Expires: 120
      Max-Forwards: 70
      Content-Length: 0
    ]]>
  </send>
  <recv response="200"/>
  <label id="wait"/>
  <recv request="NOTIFY" timeout="40000" ontimeout="stop"/>
  <send next="wait">
    <![CDATA[
      SIP/2.0 200 OK
      [last_Via:]
      [last_From:]
      [last_To:]
      [last_Call-ID:]
      [last_CSeq:]
      Content-Length: 0
    ]]>
  </send>
  <label id="stop"/>
</scenario>
```

في السيناريو أعلاه لاحظ التالي:

- الاشتراك يحتاج مصادقة مثل التسجيل، فالمقسم يرد أولاً ب 401، والسيناريو يعيد الطلب ببيانات التحويلة 2001، وإلا استطاع أي شخص أن يراقب حالة كل التحويلات.
- `Event: dialog` هو ما تطلبه أزرار BLF في الهواتف المكتبية، وAsterisk يدعم أيضاً الحدث `presence` الذي تستخدمه بعض البرامج لقائمة الأسماء.
- الحلقة بين `wait` و`stop` ترد على كل NOTIFY ب 200 OK، حتى يمر 40 ثانية دون إشعار جديد.

نشغل الاشتراك، ثم نتصل بالتحويلة 2002، أي Linphone الذي فعلنا فيه الرد التلقائي، من سطر أوامر المقسم، ونقرأ حالة التلميح أثناء المكالمة وبعدها:

```bash
docker run -d --name ard-vp-blf --network ard-vp-net --ip 10.88.60.23 \
  -v "$P/blf.xml:/blf.xml:ro" ard-voip-tools:1 \
  sh -c 'cd /tmp; sipp 10.88.60.10 -sf /blf.xml -m 1 -nostdin -trace_msg >/dev/null 2>&1; sleep 3600'
docker exec ard-vp-pbx asterisk -rx 'pjsip show subscriptions inbound'
docker exec ard-vp-pbx asterisk -rx 'channel originate PJSIP/2002 application Wait 6'
docker exec ard-vp-pbx asterisk -rx 'core show hints' | grep '2002@office'
docker exec ard-vp-blf sh -c 'grep -hE "^(NOTIFY|SUBSCRIBE|SIP/2.0)|<state|Subscription-State" /tmp/*_messages.log'
```

والمخرج سوف يكون كما يلي، وقد جمعنا فيه سطر التلميح أثناء المكالمة وبعدها:

```text
Endpoint: 2001/"Reception" <2001>
Resource: 2002/dialog
  Expiry:      114  1-7@10.88.60.23

1 active subscriptions
2002@office         : PJSIP/2002            State:InUse           Presence:not_set         Watchers  1
2002@office         : PJSIP/2002            State:Idle            Presence:not_set         Watchers  1
SUBSCRIBE sip:2002@10.88.60.10 SIP/2.0
SIP/2.0 401 Unauthorized
SUBSCRIBE sip:2002@10.88.60.10 SIP/2.0
SIP/2.0 200 OK
NOTIFY sip:2001@10.88.60.23:5060 SIP/2.0
Subscription-State: active;expires=119
  <state>terminated</state>
SIP/2.0 200 OK
NOTIFY sip:2001@10.88.60.23:5060 SIP/2.0
Subscription-State: active;expires=107
  <state>early</state>
SIP/2.0 200 OK
NOTIFY sip:2001@10.88.60.23:5060 SIP/2.0
Subscription-State: active;expires=107
  <state>confirmed</state>
SIP/2.0 200 OK
NOTIFY sip:2001@10.88.60.23:5060 SIP/2.0
Subscription-State: active;expires=101
  <state>terminated</state>
SIP/2.0 200 OK
```

في المخرج أعلاه لاحظ التالي:

- المقسم يعرف الاشتراك ومن صاحبه، و`Watchers 1` في التلميح تعني أن هاتفاً واحداً يراقب هذه التحويلة.
- أول NOTIFY يصل مباشرة بعد الاشتراك بالحالة الحالية `terminated`، أي لا توجد مكالمة، فيضيء الزر أخضر.
- ثم `early` عندما بدأ هاتف Linphone يرن، فيومض الزر، و`confirmed` بعد الرد، فيصبح أحمر، ثم `terminated` بعد انتهاء المكالمة بست ثوان.
- `expires` تتناقص، لأن الاشتراك مدته 120 ثانية، والهاتف الحقيقي يجدده قبل أن تنتهي، فإذا لم يجدده يتوقف الضوء عن التغير دون أي رسالة خطأ على الشاشة.

وجسم الرسالة NOTIFY نفسها بصيغة XML كما يعرفها المعيار، وهذا مثال من الالتقاط أثناء المكالمة:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<dialog-info xmlns="urn:ietf:params:xml:ns:dialog-info" version="2" state="full" entity="sip:2002@10.88.60.10">
 <dialog id="2002">
  <state>confirmed</state>
 </dialog>
</dialog-info>
```

ولاحظ أن كل زر BLF اشتراك منفصل يجدده الهاتف بشكل دوري، فهاتف استقبال عليه 40 زراً يعني 40 اشتراكاً، ومئة هاتف من هذا النوع تعني آلاف الاشتراكات على المقسم، لذلك عند تخطيط المقسم لمكتب كبير احسب الاشتراكات مع عدد الهواتف.

## لماذا لا يرن تطبيق الجوال وهو نائم؟

هذه أكثر شكوى تسمعها بعد أن توزع تطبيق SIP على الموظفين: «التطبيق يعمل عندما أفتحه، ولكن عندما تكون الشاشة مطفأة لا يرن، والمتصل يسمع أن لا أحد يرد». والسبب ليس في المقسم ولا في التطبيق، وإنما في نظام الجوال: فبعد أن ينتقل التطبيق إلى الخلفية يوقفه iOS أو Android لتوفير البطارية، ويقطع عنه الشبكة، فلا يوجد برنامج يستقبل رسالة INVITE. وصفحة Android عن وضع [Doze](https://developer.android.com/training/monitoring-device-state/doze-standby?ref=arabroot.io) تقول صراحة إنه يعلق وصول التطبيقات إلى الشبكة.

### نجرب ذلك: تطبيق متوقف وتسجيل ما زال صالحاً

لا نملك iPhone في Docker، ولكننا نستطيع تقليد ما يفعله النظام بالتطبيق بدقة: الأمر `docker pause` يجمد كل البرامج في ال Container دون أن يغلقها، فيبقى عنوانها ومنفذها ولكن لا يقرأ أحد الحزم، وهذا بالضبط حال التطبيق المعلق. نشغل تطبيق «الجوال» بالتحويلة 2003، ثم نجمده ونتصل به:

```bash
docker run -d --name ard-vp-mobile --network ard-vp-net --ip 10.88.60.24 \
  -v "$P/mobile:/conf:ro" ard-voip-tools:1 baresip -f /conf
docker exec ard-vp-pbx asterisk -rx 'pjsip show contacts' | grep 2003

docker pause ard-vp-mobile
docker exec -d ard-vp-pbx timeout 26 tcpdump -i eth0 -n -s0 -w /tmp/sleep.pcap host 10.88.60.24
docker exec ard-vp-pbx asterisk -rx 'channel originate Local/2003@office application Wait 1'
docker exec ard-vp-pbx sh -c 'tcpdump -r /tmp/sleep.pcap -n 2>/dev/null' | grep -E 'INVITE|CANCEL|OPTIONS'
docker exec ard-vp-pbx asterisk -rx 'pjsip show contacts' | grep 2003
```

والمجلد `mobile` فيه ملف `config` مثل الملف المشترك، وملف `accounts` فيه السطر `<sip:2003@10.88.60.10>;auth_pass=Mob-2003-z7Wd;answermode=auto;regint=600`. والمخرج سوف يكون كما يلي، بعد أن حذفنا بعض أسطر OPTIONS المكررة:

```text
  Contact:  2003/sip:2003-0x55f2115a2920@10.88.60.24:5060  4224f1287b Avail         1.210
08:18:03.112387 IP 10.88.60.10.5060 > 10.88.60.24.5060: SIP: INVITE sip:2003-0x55f2115a2920@10.88.60.24:5060 SIP/2.0
08:18:03.599420 IP 10.88.60.10.5060 > 10.88.60.24.5060: SIP: INVITE sip:2003-0x55f2115a2920@10.88.60.24:5060 SIP/2.0
08:18:04.600108 IP 10.88.60.10.5060 > 10.88.60.24.5060: SIP: INVITE sip:2003-0x55f2115a2920@10.88.60.24:5060 SIP/2.0
08:18:05.989404 IP 10.88.60.10.5060 > 10.88.60.24.5060: SIP: OPTIONS sip:2003-0x55f2115a2920@10.88.60.24:5060 SIP/2.0
08:18:06.599265 IP 10.88.60.10.5060 > 10.88.60.24.5060: SIP: INVITE sip:2003-0x55f2115a2920@10.88.60.24:5060 SIP/2.0
08:18:10.602064 IP 10.88.60.10.5060 > 10.88.60.24.5060: SIP: INVITE sip:2003-0x55f2115a2920@10.88.60.24:5060 SIP/2.0
08:18:18.599963 IP 10.88.60.10.5060 > 10.88.60.24.5060: SIP: INVITE sip:2003-0x55f2115a2920@10.88.60.24:5060 SIP/2.0
  Contact:  2003/sip:2003-0x55f2115a2920@10.88.60.24:5060  4224f1287b Unavail         nan
```

في المخرج أعلاه لاحظ التالي:

- المقسم أرسل INVITE ست مرات بالفواصل المتضاعفة نفسها التي رأيناها في المقال السابق، ولم يأت أي رد، ولا حتى `100 Trying`، ثم انتهت مهلة `Dial` بعد 20 ثانية.
- لا توجد رسالة CANCEL، والسبب أن [RFC 3261](https://www.rfc-editor.org/rfc/rfc3261?ref=arabroot.io) يمنع إرسال CANCEL قبل أن يصل أي رد مؤقت، فالمقسم يترك الطلب يموت وحده.
- التحويلة ما زالت في جدول المقسم لأن تسجيلها صالح لعشر دقائق، والذي كشف أن التطبيق لا يرد هو الفحص الدوري `qualify_frequency` فقط، فأصبحت `Unavail`. ودون هذا الفحص كانت ستبدو متاحة تماماً.

والأغرب ما يحدث عندما «يستيقظ» التطبيق، فنفك التجميد ونقرأ سجله:

```bash
docker unpause ard-vp-mobile
docker logs ard-vp-mobile 2>&1 | grep -E "call:|session closed"
```

```text
call: answering call on line 1 from sip:anonymous@anonymous.invalid with 200
sip:anonymous@anonymous.invalid: session closed: Connection reset by peer
```

التطبيق وجد رسالة INVITE قديمة تنتظره في ذاكرة الشبكة، فرد عليها تلقائياً، ولكن المقسم كان قد أنهى هذه المكالمة قبل دقيقة، فرفضها مباشرة. وفي الجوال الحقيقي يرى الموظف أحياناً شيئاً قريباً من هذا: مكالمة فائتة تظهر عندما يفتح الجوال، بعد أن يئس المتصل.

### الحل: إشعار Push يوقظ التطبيق قبل المكالمة

الحل البسيط أن تطلب من الموظف أن يمنع النظام من إيقاف التطبيق في إعدادات البطارية، وهذا لا يصلح، فبعض الأنظمة لا تسمح به أصلاً، والتطبيق الذي يبقى مستيقظاً يستنزف البطارية. والحل الذي تعتمده تطبيقات الاتصال كلها أن يوقظ أحد التطبيق عند وصول المكالمة، ولا يملك أحد أن يوقظ تطبيقاً معلقاً إلا خدمة الإشعارات في نظام الجوال نفسه: Apple Push Notification service في iOS، وFirebase Cloud Messaging في Android. وقد شرحنا كيف تعمل هذه الخدمات عموماً في [كيف تعمل الإشعارات الفورية Push Notifications](https://arabroot.io/articles/%D9%83%D9%8A%D9%81-%D8%AA%D8%B9%D9%85%D9%84-%D8%A7%D9%84%D8%A7%D8%B4%D8%B9%D8%A7%D8%B1%D8%A7%D8%AA-%D8%A7%D9%84%D9%81%D9%88%D8%B1%D9%8A%D8%A9-push-notifications/). والصورة التالية تبين ترتيب الخطوات:

![متصل يرسل INVITE إلى خادم SIP يدعم الإشعارات مثل Flexisip، والخادم يحتفظ بالمكالمة ويرسل إشعاراً إلى APNs أو FCM، والخدمة توقظ التطبيق على الجوال، فيظهر التطبيق شاشة المكالمة ويرسل REGISTER جديداً، ثم يمرر الخادم INVITE المحفوظ إلى التطبيق فيرن](https://arabroot.io/content/images/2026/10/voip-phones-04-push.webp)

الخادم يحتفظ بالمكالمة ثوان قليلة حتى يستيقظ التطبيق ويسجل من جديد

والمعيار الذي يصف هذا هو [RFC 8599](https://www.rfc-editor.org/rfc/rfc8599?ref=arabroot.io) الصادر في 2019، وفيه يضيف التطبيق عند التسجيل معاملات في ترويسة Contact تحمل معرف الإشعارات الخاص بالجهاز، فيعرف الخادم كيف يوقظه. ولكي يعمل هذا يحتاج الخادم أن يحتفظ بالمكالمة عنده بدل أن يرسلها مباشرة إلى عنوان لا يرد، ثم يمررها بعد أن يسجل التطبيق من جديد، وهذا ما لا يفعله المقسم العادي، لذلك يوضع أمامه خادم SIP يتولى الإشعارات، مثل [Flexisip](https://www.linphone.org/en/flexisip-sip-server/?ref=arabroot.io) من فريق Linphone، الذي يدعم RFC 8599 وخدمتي Apple وGoogle، وترخيصه AGPLv3 أو تجاري. والتطبيقات التجارية الكبيرة تفعل الشيء نفسه عبر خوادم الشركة المصنعة.

وهناك شرطان من أنظمة الجوال يجب أن تعرفهما قبل أن تختار تطبيقاً أو تبنيه:

- **iOS**: الإشعارات الخاصة بالمكالمات تأتي عبر PushKit، وتقول [وثائق Apple](https://developer.apple.com/documentation/pushkit/responding-to-voip-notifications-from-pushkit?ref=arabroot.io) إن التطبيقات المبنية بأدوات iOS 13 وما بعده يجب أن تبلغ عن كل إشعار من هذا النوع كمكالمة عبر CallKit، فتظهر شاشة المكالمة الأصلية، والتطبيق الذي لا يفعل ذلك يغلقه النظام، ومع التكرار يتوقف وصول إشعاراته.
- **Android**: يحتاج الإشعار أن يرسل بأولوية عالية حتى يوقظ التطبيق في وضع Doze، و[وثائق Firebase](https://firebase.google.com/docs/cloud-messaging/android/message-priority?ref=arabroot.io) تقول إن الرسائل عالية الأولوية التي لا ينتج عنها إشعار يراه المستخدم قد تخفض أولويتها.

والنتيجة العملية: إذا أردت تحويلات على جوالات الموظفين فلا تقم بتوزيع أي تطبيق SIP مجاني والاكتفاء بالمقسم، والسبب أنه سوف يرن فقط عندما يكون مفتوحاً، وإنما اختر تطبيقاً يدعم الإشعارات مع خادمه، أو خادم إشعارات مثل Flexisip أمام مقسمك، وجرب قبل التوزيع حالة واحدة: الجوال مقفل منذ عشر دقائق والشاشة مطفأة، ثم اتصل به.

## إزالة التجربة

نزيل ما أنشأناه بالاسم فقط:

```bash
docker rm -f ard-vp-pbx ard-vp-prov ard-vp-dhcp ard-vp-desk ard-vp-desk2 ard-vp-linphone ard-vp-blf ard-vp-mobile
docker network rm ard-vp-net
docker rmi ard-voip-tools:1
```

## جدول التشخيص السريع

| العرض                                     | السبب الأرجح                                                                       | أين تنظر                                                          |
| ----------------------------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| الهاتف الجديد لا يطلب أي ملف              | الخيار 66 لا يصله، أو يطلب خياراً آخر مثل 43                                       | سجل DHCP، وسطر requested options                                  |
| الهاتف يعمل وشاشته مضيئة ولكن دون تحويلة  | لا يوجد ملف باسم عنوان MAC الخاص به                                                | طلبات 404 في سجل سيرفر التهيئة                                    |
| كل الهواتف أخذت إعداداً قديماً            | غيرت الملف ولم تعد تشغيل الهواتف، أو يوجد ملف محلي في الهاتف يتقدم على ملف السيرفر | سجل السيرفر بعد إعادة التشغيل، ووثائق الشركة عن ترتيب الملفات     |
| البرنامج يقول إنه يعمل ولا يظهر في المقسم | البرنامج لم يرسل REGISTER أصلاً                                                    | tcpdump على المقسم قبل أي تغيير في الحساب                         |
| ضوء BLF لا يتغير                          | لا يوجد Hint للتحويلة، أو انتهى الاشتراك ولم يجدد                                  | core show hints وpjsip show subscriptions inbound                 |
| تطبيق الجوال لا يرن والشاشة مطفأة         | النظام علق التطبيق، ولا يوجد خادم إشعارات                                          | حالة التحويلة Unavail مع الفحص الدوري، وINVITE دون رد في الالتقاط |

## تدريب عملي

- أضف ملف MAC ثانياً للتحويلة 2003، وشغل هاتفاً جديداً بعنوان MAC الذي اخترته، ثم غير الترميز في الملف المشترك إلى `g711.so` فقط مع PCMA، وأعد تشغيل الهاتفين، وتأكد من سجل Nginx أن كليهما أخذ الملف الجديد.
- في سيناريو BLF غير `Event: dialog` إلى `Event: presence` و`Accept` إلى `application/pidf+xml`، وقارن جسم NOTIFY بما رأيته هنا.

## الخلاصة

- الهاتف المكتبي والبرنامج وتطبيق الجوال كلها عملاء SIP بالنسبة للمقسم، والفرق في مكان تشغيلها ومن يتحكم فيها: الكهرباء PoE للمكتبي، والسماعة للبرنامج، ونظام التشغيل للجوال.
- التهيئة التلقائية تبدأ من DHCP: الخيار 66 يعطي الهاتف رابط السيرفر، والهاتف يطلب ملفاً مشتركاً وملفاً باسم عنوان MAC الخاص به، وسجل السيرفر هو أول مكان للتشخيص.
- ملف MAC فيه كلمة مرور التحويلة، وعناوين MAC سهلة التخمين، لذلك افصل شبكة الصوت، وضع كلمة مرور وHTTPS على سيرفر التهيئة، وراقب الطلبات المتتالية.
- أزرار BLF اشتراكات SUBSCRIBE بالحدث `dialog` يرد عليها المقسم ب NOTIFY عند كل تغيير، وتحتاج تلميحاً Hint لكل تحويلة.
- تطبيق الجوال المعلق لا يرد على INVITE رغم أن تسجيله صالح، والحل خادم يحتفظ بالمكالمة ويوقظ التطبيق بإشعار Push كما في RFC 8599، مع CallKit في iOS والأولوية العالية في Android.

وفي المقال القادم بإذن الله سوف نبني على هذه الهواتف مركز اتصال كاملاً: طابوراً للمتصلين، ووكلاء يسجلون دخولهم، وتسجيلاً للمكالمات، وتقارير مستوى الخدمة SLA.

[![](https://arabroot.io/content/images/2026/10/voip-terms-cover-cover.webp)دليلمصطلحات الاتصالات الهاتفية VoIP للمبتدئينشرح مبسط لمصطلحات الهاتف عبر الإنترنت، وما يمر في الشبكة بين ضغط زر الاتصال ووصول الصوت إلى الطرف الآخر.](https://arabroot.io/articles/%D9%85%D8%B5%D8%B7%D9%84%D8%AD%D8%A7%D8%AA-voip-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)[![](https://arabroot.io/content/images/2026/10/voip-call-path-cover-cover.webp)دليلتتبع مكالمة SIP عبر الشبكة: لماذا يصل الصوت في اتجاه واحد؟نبني مقسماً وهاتفين خلف NAT في تجربة عملية، ونتتبع المكالمة حزمة بحزمة حتى نعرف لماذا يضيع الصوت وكيف نصلحه.](https://arabroot.io/articles/%D8%AA%D8%AA%D8%A8%D8%B9-%D9%85%D9%83%D8%A7%D9%84%D9%85%D8%A9-sip-%D8%B9%D8%A8%D8%B1-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-%D9%88%D8%A7%D9%84%D8%B5%D9%88%D8%AA-%D9%81%D9%8A-%D8%A7%D8%AA%D8%AC%D8%A7%D9%87-%D9%88%D8%A7%D8%AD%D8%AF/)[![](https://arabroot.io/content/images/2026/10/push-basics-cover-cover.webp)دليلكيف تعمل الإشعارات الفورية Push Notifications؟كيف يصل الإشعار إلى تطبيق مغلق عبر خدمات Apple وGoogle، وما الذي تراه هذه الخدمات من بيانات مستخدميك.](https://arabroot.io/articles/%D9%83%D9%8A%D9%81-%D8%AA%D8%B9%D9%85%D9%84-%D8%A7%D9%84%D8%A7%D8%B4%D8%B9%D8%A7%D8%B1%D8%A7%D8%AA-%D8%A7%D9%84%D9%81%D9%88%D8%B1%D9%8A%D8%A9-push-notifications/)[![](https://arabroot.io/content/images/2026/10/network-segmentation-cover-cover.webp)دليلتقسيم الشبكة Network Segmentation بال VLAN وال VPCلماذا تصل كاميرا مخترقة إلى قاعدة بياناتك، وكيف تمنع ذلك بتقسيم الشبكة إلى مناطق لا يمر بينها إلا ما تسمح به.](https://arabroot.io/articles/%D8%AA%D9%82%D8%B3%D9%8A%D9%85-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-network-segmentation-vlan-%D9%88-vpc/)

## سجل التحديثات

- أكتوبر 2026: كتابة المقال، وبناء التجربة على Asterisk 20.6.0 وbaresip 1.0.0 وLinphone 5.2.0 وSIPp 3.7.2 وNginx 1.24.0 وdnsmasq 2.91 من حزم Ubuntu 24.04 في Docker.