نظام الشحن عبر الإنترنت (OCS) التكامل
دليل شامل لتكامل OmniTAS مع أنظمة الشحن عبر الإنترنت عبر واجهة Diameter Ro، بما في ذلك التحكم في الائتمان في الوقت الحقيقي، واستخراج AVP، وتعيين متغيرات FreeSWITCH.
جدول المحتويات
- نظرة عامة على الهيكل
- ما الذي يتحكم فيما إذا كان سيتم شحن مكالمة
- تدفق التحكم في الائتمان
- تحليل AVP وتعيين المتغيرات
- التكوين
- تكامل FreeSWITCH
- إشعارات الرد والانتهاء
- رسائل Diameter
- المقاييس
- استكشاف الأخطاء وإصلاحها
- المرجع
نظرة عامة على الهيكل
تقوم OmniTAS بتنفيذ واجهة Diameter Ro وفقًا لـ 3GPP TS 32.299 للشحن عبر الإنترنت في الوقت الحقيقي. يقوم النظام بتفويض المكالمات من خلال طلب الائتمان من OCS قبل إعداد المكالمة، ويراقب الائتمان أثناء المكالمة، ويبلغ عن الاستخدام النهائي عند الانتهاء.
المكونات الرئيسية
طلب التحكم في الائتمان (CCR):
- CCR-Initial (النوع 1): يتم إرساله قبل إعداد المكالمة لطلب تفويض الائتمان الأولي
- CCR-Update (النوع 2): يتم إرساله أثناء المكالمات النشطة لإعادة التفويض أو التحديثات المؤقتة
- CCR-Terminate (النوع 3): يتم إرساله عند إنهاء المكالمة مع الإبلاغ عن الاستخدام النهائي
إجابة التحكم في الائتمان (CCA):
- تحتوي على وحدات الخدمة الممنوحة (حصة الوقت بالثواني)
- تشمل AVPs محددة من البائع مع بيانات شحن إضافية
- توفر معلومات التوجيه، تفاصيل الطرف الذي تم شحنه، ومعرفات الخدمة
ما الذي يتحكم فيما إذا كان سيتم شحن مكالمة
تنتج المكالمة CCRs من Diameter فقط إذا كانت جميع الشروط الثلاثة التالية صحيحة. يتم تقييمها عندما يقوم OmniTAS ببناء خطة الاتصال للمكالمات التي تبدأ من الهاتف المحمول (MO):
- تم تمكين الشحن عبر الإنترنت:
online_charging.enabledهوtrue. عندما يكونfalse، يقوم OmniTAS بتفويض كل مكالمة محليًا ولا يتصل أبدًا بـ OCS. - المكالمة هي من الهاتف المحمول (MO): يتم شحن الجانب MO فقط. المكالمات التي تنتهي على الهاتف المحمول (MT) لا يتم شحنها أبدًا: لا يقوم مسار MT بتفويض OCS، لذا لا يتم إنشاء جلسة التحكم في الائتمان لها.
- الوجهة ليست معفاة: الرقم الذي تم الاتصال به لا يتطابق مع أي نمط في
skipped_regex(مثل أرقام الطوارئ، رموز الخدمة).
إذا كانت جميع الشروط الثلاثة صحيحة، يقوم OmniTAS بإرسال CCR-Initial ويفتح جلسة التحكم في الائتمان المرتبطة بـ SIP Call-ID. من تلك النقطة، يتم دفع CCR-Update و CCR-Terminate بواسطة أحداث الرد والانتهاء (انظر إشعارات الرد والانتهاء) ولا يتم إنشاؤها إلا للأطراف التي لديها جلسة مفتوحة. لذلك، لا تنتج الأطراف MT، والأطراف B الموصولة، والمكالمات المعفاة CCRs أبدًا.
ملاحظة: الوصول إلى OCS لا يضمن اتصال المكالمة. تفويض ناجح مع صفر وحدات ممنوحة يمنع المكالمة. انظر استنفاد الائتمان ومنع المكالمات. يحدث المنع بعد إرسال CCR؛ وهو مختلف عن الشروط المذكورة أعلاه، التي تحدد ما إذا كان سيتم إرسال CCR على الإطلاق.
تصنيف مسار من خطة الاتصال
skipped_regex يزيل وجهة من الشحن تمامًا - لا جلسة، لا CCR-I، وبالتالي لا تحقق من الائتمان. هذا هو السلوك الصحيح لأرقام الط��ارئ، ولكن ليس لمسار تريد الاستمرار في تفويضه بينما لا تقوم بالفوترة (مكالمات مجانية داخل الشبكة، نطاقات الهاتف المجاني، وجهات ترويجية، أرقام اختبار).
لذلك، قم بتعيين المتغير القنوي tas_zero_rate=true في خطة الاتصال:
<action application="set" data="tas_zero_rate=true"/>
يتم قراءة المتغير من القناة عند أحداث الرد والانتهاء، لذا يمكن تعيينه من أي امتداد، ضد أي شرط - فهو لا يحمل أي معرفة عن لماذا المسار مجاني.
بحلول الوقت الذي يقوم فيه FreeSWITCH بتنفيذ خطة الاتصال، تم إرسال CCR-Initial بالفعل (يقوم OmniTAS بتفويض المكالمة أثناء بناء خطة الاتصال)، لذا يتم التحقق من الائتمان للمشترك ولا يزال المتصل الذي نفد رصيده ممنوعًا. ما يقوم العلم بإخفائه هو الإبلاغ عن الاستخدام:
| المسار العادي | tas_zero_rate=true | |
|---|---|---|
| CCR-Initial (التفويض) | تم الإرسال | تم الإرسال |
| CCR-Update عند الرد | تم ا��إرسال | لم يتم الإرسال |
| CCR-Update دوري | تم الإرسال | لم يتم الإرسال |
| قطع منتصف المكالمة عند استنفاد الائتمان | ينطبق | لا ينطبق |
| CCR-Terminate | تم الإرسال، يبلّغ عن CC-Time المستهلك | تم الإرسال، يبلّغ عن CC-Time 0 |
| التأثير الصافي على الرصيد | تم خصمه للمكالمة | غير متأثر |
كل شيء آخر في CCR-T يبقى صحيحًا - الطوابع الزمنية، Cause-Code، Service-Information - لذا لا يزال OCS يسجل CDR دقيق للمكالمة، بدون رسوم، ويحرر حجز CCR-Initial بالكامل.
ملاحظة: لأنه لا يتم إرسال CCR-Update، يحتفظ OCS بحجز CCR-Initial طوال المكالمة ويحرره فقط عند CCR-Terminate. في مكالمة طويلة بدون رسوم، قد يبدو المشترك قصير الائتمان للمكالمات المتزامنة حتى يتم مسحها.
priv/templates/mo_dialplan.xml يحتوي على امتداد Zero-Rated-Routes مع أمثلة مشروحة (داخل الشبكة، وسابقة الوجهة). يتم إيقاف تصنيف الرسوم افتراضيًا - قم بإلغاء تعليق أو إضافة الش��وط التي تريدها. على سبيل المثال، لجعل المكالمات داخل الشبكة مجانية، باستخدام متغير on_net_status الذي يقوم OmniTAS بتعيينه من بحث Sh عن الرقم الذي تم الاتصال به:
<extension name="Zero-Rated-Routes" continue="true">
<condition field="${on_net_status}" expression="^true$" break="never">
<action application="set" data="tas_zero_rate=true"/>
</condition>
</extension>
تدفق التحكم في الائتمان
تسلسل تفويض المكالمات
استنفاد الائتمان ومنع المكالمات
منع المكالمات عند الإعداد. إذا أعاد OCS CCA ناجحة (رمز النتيجة 2001) ولكن مع صفر وحدات ممنوحة (أو رفض صريح مثل 4012 (DIAMETER_CREDIT_LIMIT_REACHED) أو 4010 (DIAMETER_END_USER_SERVICE_DENIED))، يعامل OmniTAS المكالمة على أنها بدون ائتمان ويمنعها بسبب سبب الانتهاء OUTGOING_CALL_BARRED. لا يتصل المشترك أبدًا. هذه هي النتيجة المتوقعة لمشترك غير مزود أو نفد رصيده.
استنفاد منتصف المكالمة. إذا تم منح الائتمان عند الإعداد ولكن نفد لاحقًا (تعود CCR-Update الدورية بصفر وحدات أو خطأ حد الائتمان)، يقوم OmniTAS بإنهاء المكالمة الجارية. مع تكوين credit_exhaustion_announcement، ينق�� المتصل إلى إعلان قبل الانتهاء؛ وإلا فإنه ينهي المكالمة مباشرة.
يتم تشغيل CCR-Terminate في لحظة الاستنفاد، قبل أي تنظيف. عندما يتم استنفاد الرصيد، يرسل OmniTAS CCR-Terminate على الفور (إجابة مشحونة→استنفاد)، ثم يقوم بتشغيل إعلان نفاد الائتمان أو ينهي المكالمة. هذا مقصود: الوقت الذي يقضيه المشترك في الاستماع إلى "لقد نفد رصيدك" ليس قابلًا للشحن، لذا يجب أن تنتهي CDR عندما نفد الائتمان، وليس عندما ينهي المستخدم المكالمة من التسجيل. تنتهي الجلسة في تلك النقطة، لذا فإن إنهاء FreeSWITCH النهائي للمكالمة لا يجد أي جلسة ولا يرسل شيئًا (غير متكرر، لا CCR-T ثانية). هذا ينطبق سواء كان التنظيف هو نقل إلى إعلان أو إنهاء مباشر، لذا فهو لا يعتمد على سبب إنهاء FreeSWITCH.
يدعم OmniTAS آليات متعددة للتعامل مع استنفاد الائتمان، مع تكامل تلقائي بين إنهاءات المجدولة وإعلانات استنفاد الائتمان.
إنهاء مجدول مع إعادة جدولة ديناميكية
عندما يتم تمكين schedule_hangup_auth، يقوم OmniTAS بجدولة مؤقت FreeSWITCH الذي ينهي المكالمات تلقائيًا عندما تنتهي فترة الائتمان الممنوحة. يتم إعادة جدولة هذا المؤقت ديناميكيًا في كل مرة يتم فيها منح ائتمان جديد عبر استجابات CCR-Update.
كيف يعمل:
منطق التخزين المؤقت:
يرسل OmniTAS رسائل CCR-Update قبل انتهاء فترة الائتمان الممنوحة لضمان الخدمة المستمرة. يتم تكوين وقت التخزين المؤقت عبر ccr_update_buffer_seconds (افتراضي: 2 ثانية).
جدول زمني مثال:
- T+0s: تم الرد على المكالمة، OCS يمنح 10s، مؤقت مجدول لـ T+10s
- T+8s: تم إرسال CCR-U (10s - 2s buffer)
- T+8.1s: OCS يمنح 10s، مؤقت مجدول إلى T+18.1s (10s من الآن)
- T+16.1s: تم إرسال CCR-U
- T+16.2s: OCS يمنح 10s، مؤقت مجدول إلى T+26.2s
- تستمر المكالمة طالما أن OCS يستمر في منح الائتمان
السجلات التي يجب مراقبتها:
[OCS HANGUP RESCHEDULE] Found UUID <uuid> for call <id> - rescheduling timer to 10s from now
[SCHED TRANSFER] Scheduling transfer to credit_exhausted dialplan for <uuid> in 10s
[OCS HANGUP RESCHEDULE] Successfully rescheduled timer for call <id> (UUID: <uuid>)
التكامل: schedule_hangup_auth + credit_exhaustion_announcement
عندما يتم تمكين كلا الميزتين، يستخدم OmniTAS تلقائيًا التحويلات المجدولة بدلاً من إنهاءات مباشرة، مما يسمح للمتصل بسماع إعلان قبل إنهاء المكالمة.
بدون إعلان مُعد:
config :tas, :online_charging,
schedule_hangup_auth: true,
credit_exhaustion_announcement: nil
→ يستخدم sched_hangup - إنهاء مباشر عند انتهاء الائتمان
مع إعلان مُعد:
config :tas, :online_charging,
schedule_hangup_auth: true,
credit_exhaustion_announcement: "${base_dir}/sounds/en/us/callie/misc/8000/credit_exhausted.wav"
→ يستخدم sched_transfer - ينقل إلى خطة الاتصال credit_exhausted التي تشغل الإعلان ثم تنهي المكالمة
كيف يعمل التحويل:
- يقوم OmniTAS بتعيين متغير القناة
tas_call_reason=credit_exhausted - يحدد تحويلًا إلى امتداد
credit_exhaustedفي سياق خطة الاتصالims_as - عندما ينطلق المؤقت:
- يقوم FreeSWITCH بنقل الطرف A إلى خطة الاتصال credit_exhausted
- ينكسر الجسر تلقائيًا، ويتلقى الطرف B BYE
- تشغل خطة الاتصال الإعلان للطرف A
- تنتهي المكالمة بعد الإعلان
الفوائد:
- يسمع المتصل إعلانًا احترافيًا بدلاً من قطع مفاجئ
- الطرف B (الطرف المتصل) لا يسمع الإعلان
- يتم إرسال CCR-T مع الاستخدام الفعلي
- مسار الإعلان: يجب أن يكون نسبيًا إلى دليل FreeSWITCH الأساسي (استخدم متغير
${base_dir})
استنفاد الائتمان الفوري أثناء CCR-Update
إذا رفض OCS الائتمان أو أعاد صفر ثواني أثناء CCR-Update، يقوم OmniTAS على الفور بتفعيل معالجة استنفاد الائتمان، متجاوزًا أي مؤقت مجدول.
سيناريوهات استجابة OCS:
رموز الأخطاء المعالجة:
| استجابة OCS | الإجراء | السجلات |
|---|---|---|
{:ok, 0} (صفر ثواني) | إنهاء استنفاد الائتمان الفوري | Credit exhausted (zero seconds allocated) - triggering immediate hangup |
{:error, 4012} (CREDIT_LIMIT_REACHED) | إنهاء استنفاد الائتمان الفوري | Credit exhausted (4012 CREDIT_LIMIT_REACHED) - triggering immediate hangup |
{:error, 4010} (END_USER_SERVICE_DENIED) | إنهاء استنفاد الائتمان الفوري | Service denied (4010 END_USER_SERVICE_DENIED) - triggering immediate hangup |
{:error, reason} (أخطاء أخرى) | إيقاف وظيفة CCR الدورية، المؤقت المجدول ينطلق | Periodic CCR failed with error <reason> - Stopping job |
{:ok, N} حيث N > 0 | إعادة ��دولة المؤقت إلى +N ثواني | Periodic CCA allocated Ns, will send next CCR-U in (N-buffer)s |
الأولوية: معالجة استنفاد الائتمان الفوري تفوز على المؤقت المجدول. إذا رفض OCS الائتمان في T+8s ولكن تم جدولة المؤقت في T+10s، تحدث إنهاء فوري في T+8s وتصبح المؤقت المجدول غير ذي صلة.
جدول زمني مثال مع رفض الائتمان منتصف المكالمة:
T+0s: تم الرد على المكالمة
T+0.1s: OCS يمنح 10s → مؤقت مجدول لـ T+10.1s
T+8s: تم إرسال CCR-U (buffer = 2s)
T+8.1s: OCS يعود بصفر ثواني → نقل فوري إلى خطة الاتصال credit_exhausted
T+8.2s: يتم تشغيل الإعلان للمتصل
T+10s: تنتهي المكالمة (المؤقت المجدول غير ذي صلة)
السجلات لاستنفاد الائتمان الفوري:
[warning] Credit exhausted (zero seconds allocated) - triggering immediate hangup
[warning] Hanging up call <id> (UUID: <uuid>) due to credit exhaustion
[info] Credit exhaustion announcement config: "${base_dir}/sounds/..."
[info] Playing announcement before hangup: ...
[info] Setting tas_call_reason=credit_exhausted for <uuid>
[info] Transferring to credit exhausted dialplan: uuid_transfer <uuid> credit_exhausted XML ims_as
ملخص: آليات استنفاد الائتمان
يوفر OmniTAS آليتين تكميليتين:
-
المؤقت المجدول (
schedule_hangup_auth):- إنهاء تلقائي/تحويل عند انتهاء الائتمان الممنوح
- إعادة جدولة ديناميكية عند كل استجابة CCR-U
- يستخدم منطق التخزين المؤقت لإرسال CCR-U قبل انتهاء الفترة
- يتكامل مع ميزة الإعلان
-
معالجة الاستنفاد الفوري:
- يتم تفعيلها عندما يرفض OCS الائتمان أثناء CCR-U
- تتجاوز المؤقت المجدول
- تدعم تشغيل الإعلان
- تتعامل مع رموز خطأ Diameter المحددة
تلتزم كلتا الآليتين بتكوين credit_exhaustion_announcement وستقوم بتشغيل الصوت المكون قبل إنهاء المكالمات عند تكوينها.
تحليل AVP وتعيين المتغيرات
نظرة عامة
تقوم OmniTAS تلقائيًا باستخراج أزواج القيمة-الخاصية (AVPs) من رسائل إجابة التحكم في الائتمان (CCA) وتجعلها متاحة ل�� FreeSWITCH كمتغيرات قناة. يتيح ذلك لمنطق خطة الاتصال استخدام البيانات المقدمة من OCS لقرارات التوجيه، أو أغراض الفوترة، أو معالجة المكالمات.
أنواع AVP المدعومة:
- قيم بسيطة (UTF8String، Unsigned32، Integer32)
- AVPs مجمعة مع هياكل متداخلة
- AVPs محددة من البائع (مثل معلومات الخدمة 3GPP)
اتفاقية تسمية المتغيرات:
يتم تسطيح AVPs إلى متغيرات قناة بتدوين النقاط مع بادئة CCA:
CCA.<اسم-AVP>.<اسم-AVP-متداخل>.<اسم-AVP-القيمة> = "value"
تعيينات AVP الشائعة
AVP معلومات الخدمة (3GPP)
تحتوي AVP معلومات الخدمة المجمعة (رمز AVP 873، معرف البائع 10415) على تفاصيل الشحن الخاصة بـ IMS:
استجابة OCS مثال:
Service-Information
├── IMS-Information
│ ├── Carrier-Select-Routing-Information: "1408"
│ └── Node-Functionality: 6
└── Alternate-Charged-Party-Address: "NickTest"
المتغيرات الناتجة في FreeSWITCH:
CCA.Service-Information.Carrier-Select-Routing-Information = "1408"
CCA.Service-Information.Alternate-Charged-Party-Address = "NickTest"
الوصول في خطة الاتصال: تستخدم المتغيرات تدوين النقاط والشرطات كما هو موضح أعلاه:
<action application="log" data="INFO Carrier: ${CCA.Service-Information.Carrier-Select-Routing-Information}"/>
عرض باستخدام uuid_dump:
في وحدة التحكم FreeSWITCH أو ESL، تظهر المتغيرات مع بادئة variable_:
variable_CCA.Service-Information.Carrier-Select-Routing-Information: 1408
variable_CCA.Service-Information.Alternate-Charged-Party-Address: NickTest
ملاحظة: يحتفظ FreeSWITCH بالنقاط والشرطات في أسماء المتغيرات. تعمل المتغيرات في جميع سياقات وخطط الاتصال.
AVP وحدة الخدمة الممنوحة
يتم استخراج حصص الوقت وجعلها متاحة:
استجابة OCS:
Granted-Service-Unit
└── CC-Time: 600
المتغير:
allocated_time = 600
منطق معالجة AVP
قواعد المعالجة:
- AVPs المجمعة تضيف مستوى إلى تسلسل أسماء المتغيرات ولكن ليس لها قيمة خاصة بها
- AVPs البسيطة يتم تعيينها إلى المتغيرات مع مسارها الكامل بالنقاط
- AVPs المحددة من البائع تتم معالجتها بنفس طريقة AVPs القياسية
- AVPs غير المعروفة يتم تخطيها بأمان دون أخطاء
مثال: التداخل متعدد المستويات
هيكل OCS CCA:
Service-Information (Grouped)
├── IMS-Information (Grouped)
│ ├── Node-Functionality: 6
│ ├── Role-Of-Node: 1
│ ├── Calling-Party-Address: "tel:+313380000000670"
│ └── Time-Stamps (Grouped)
│ ├── SIP-Request-Timestamp: "2026-01-24T22:40:18Z"
│ └── SIP-Response-Timestamp: "2026-01-24T22:40:18Z"
└── IN-Information (Grouped)
└── Real-Called-Number: "15551234567"
المتغيرات التي تم إنشاؤها في FreeSWITCH:
CCA.Service-Information.IMS-Information.Node-Functionality = "6"
CCA.Service-Information.IMS-Information.Role-Of-Node = "1"
CCA.Service-Information.IMS-Information.Calling-Party-Address = "tel:+313380000000670"
CCA.Service-Information.IMS-Information.Time-Stamps.SIP-Request-Timestamp = "2026-01-24T22:40:18Z"
CCA.Service-Information.IMS-Information.Time-Stamps.SIP-Response-Timestamp = "2026-01-24T22:40:18Z"
CCA.Service-Information.IN-Information.Real-Called-Number = "15551234567"
التكوين
معلمات الشحن عبر الإنترنت
| المعلمة | النوع | مطلوب | الافتراضي | الوصف |
|---|---|---|---|---|
enabled | Boolean | لا | false | مفتاح رئيسي للشحن عبر الإنترنت. عندما يكون false، جميع المكالمات تتجاوز تفويض OCS (لا يتم إرسال CCRs). انظر ما الذي يتحكم فيما إذا كانت المكالمة مشحونة. |
requested_units_seconds | Integer | لا | 0 | وقت الحديث (بالثواني) المطلوب لكل حجز في Requested-Service-Unit من CCR-Initial/Update. 0 (افتراضي) يرسل RSU فارغ (AVP موجود ولكنه لا يحمل CC-Time)، مما يسمح لـ OCS باختيار المنح. هذا يتطابق مع Nokia TAS مقابل OCS CGRateS الخاص بالمشغل، الذي يتجاهل الوحدات المطلوبة ويحسب منحته الخاصة. قم بتعيين قيمة موجبة لحجز CC-Time محدد لكل RFC 4006 لــ OCS المعايير الذي يقيم على الطلب. |
report_and_reserve | Boolean | لا | false | تقرير استخدام SCUR من 3GPP، يتطابق مع Nokia TAS. عندما يكون true، يحمل كل من CCR-Update و CCR-Terminate Used-Service-Unit الذي يبلغ عن CC-Time المستهلك منذ آخر تقرير (تزايدي)، بالإضافة إلى 3GPP-Reporting-Reason: RATING_CONDITION_CHANGE (6) على تحديث الإجابة، QUOTA_EXHAUSTED (3) على التحديثات الدورية، FINAL (2) عند الانتهاء. يقوم OCS بخصم كل زيادة ويستقر ذيل المنحة الأخيرة غير المستخدمة عند الانتهاء. عندما يكون false، فقط CCR-T يبلغ عن الاستخدام (تراكمي من الإجابة، بدون سبب). مجموع CC-Time التزايدي خلال مكالمة يساوي مدة الإجابة. |
service_identifier | Integer | لا | 1 | معرف الخدمة الثابت، المجهز (AVP 439) المرسل في كل CCR. يقوم OCS بمفتاح التقييم على {Service-Context-Id + Service-Identifier}، لذا يجب أن تكون هذه قيمة ثابتة، وليست عشوائية. |
periodic_ccr_time_seconds | Integer | لا | 10 | فترة احتياطية بالثواني بين رسائل CCR-Update عندما لا يعيد OCS منحة قابلة للاس��خدام. في التشغيل العادي، يتم توقيت CCR-U التالي ديناميكيًا من الائتمان الممنوح (allocated_time - ccr_update_buffer_seconds). |
ccr_update_buffer_seconds | Integer | لا | 2 | حافة أمان بالثواني قبل انتهاء الائتمان الممنوح. يرسل OmniTAS CCR-U التالي عند (allocated_time - buffer) حتى يتم تمديد الائتمان قبل نفاده. موصى به: 2-5 ثواني. |
schedule_hangup_auth | Boolean | لا | false | تمكين إيقاف المكالمة/التحويل التلقائي عند انتهاء الائتمان الممنوح. عندما يكون true، يقوم OmniTAS بجدولة مؤقت FreeSWITCH بناءً على allocated_time من كل CCA ويعيد جدولته عند كل استجابة CCR-U. يعمل مع credit_exhaustion_announcement. |
credit_exhaustion_announcement | String | لا | nil | مسار ملف الصوت لإعلان نفاد الائتمان. عند تكوينه مع schedule_hangup_auth، يستخدم التحويل المجدول لتشغيل الإعلان قبل الإيقاف. عند تكوينه بمفرده، يقوم بتشغيل الإعلان عند نفاد الائتمان على الفور فقط. يجب أن يستخدم المسار ش��ل متغير FreeSWITCH: "${base_dir}/sounds/...". قم بتعيينه إلى nil للإيقاف المباشر بدون إعلان. |
skipped_regex | List[String] | لا | [] | قائمة أنماط regex المطابقة ضد رقم الوجهة. تتجاوز الوجهات المطابقة OCS تمامًا (لا جلسة، لا CCRs، لا تحقق من الائتمان). مفيد لأرقام الطوارئ ورموز الخدمة (مثل، "^911$", "^000$"). للحفاظ على تفويض وجهة ولكن عدم محاسبتها، استخدم متغير tas_zero_rate في خطة الاتصال بدلاً من ذلك - انظر تقييم صفر لمسار من خطة الاتصال. |
معلمات اتصال Diameter
| المعلمة | النوع | مطلوب | الافتراضي | الوصف |
|---|---|---|---|---|
origin_host | String | نعم | - | هوية OmniTAS Diameter (FQDN). يجب أن تكون فريدة عبر شبكة Diameter الخاصة بك. مثال: "tas01.epc.mnc123.mcc456.3gppnetwork.org". |
origin_realm | String | نعم | - | مجال OmniTAS Diameter. يستخدم لقرارات التوجيه. مثال: "epc.mnc123.mcc456.3gppnetwork.org". |
destination_realm | String | نعم | - | مجال OCS Diameter. يتم توجيه الطلبات إلى الأقران في هذا المجال. |
destination_host | String | لا | nil | هوية Diameter OCS المحددة. عندما يكون nil، يتم التوجيه بناءً على destination_realm فقط. استخدم عندما يكون التوجيه المباشر إلى مثيل OCS محدد مطلوبًا. |
مثال على التكوين
config :tas, :online_charging,
# مفتاح رئيسي
enabled: true,
# 0 = RSU فارغ، دع OCS يقرر المنحة (يتطابق مع Nokia TAS / CGRateS).
# قم بتعيين قيمة موجبة فقط لـ OCS المعايير الذي يقيم على الوحدات المطلوبة.
requested_units_seconds: 0,
# معرف الخدمة الثابت المجهز
service_identifier: 1,
# فترة إعادة المصادقة الاحتياطية (التوقيت العادي ديناميكي من المنحة)
periodic_ccr_time_seconds: 10,
# إعادة التفويض قبل انتهاء الائتمان الممنوح بـ 2 ثانية
ccr_update_buffer_seconds: 2,
# جدولة الإيقاف بناءً على الائتمان الممنوح
schedule_hangup_auth: true,
# تشغيل الإعلان قبل إيقاف نفاد الائتمان
credit_exhaustion_announcement: "ivr/ivr-account_balance_low.wav",
# تخطي OCS للمكالمات الطارئة والبريد الصوتي
skipped_regex: [
"^911$", # طوارئ (الولايات المتحدة)
"^000$", # طوارئ (أستراليا)
"^\*86$" # الوصول إلى البريد الصوتي
]
config :tas, :diameter,
# هوية الخدمة
origin_host: "tas01.epc.mnc001.mcc001.3gppnetwork.org",
origin_realm: "epc.mnc001.mcc001.3gppnetwork.org",
# توجيه OCS
destination_realm: "epc.mnc001.mcc001.3gppnetwork.org",
destination_host: nil # توجيه بناءً على المجال
كيف يعمل:
عند استلام مكالمة:
- يتم التحقق من رقم الوجهة ضد أنماط
skipped_regex - إذا تم المطابقة، تتجاوز المكالمة OCS (مفيد لخدمات الطوارئ)
- إذا لم يتم المطابقة، يتم إرسال CCR-Initial إلى OCS في
destination_realm - يتم تحليل استجابة CCA للوحدات الممنوحة و AVPs
- يتم تعيين AVPs إلى متغيرات FreeSWITCH (انظر تعيين AVP)
- تستمر المكالمة مع توفر
allocated_timeوبيانات AVP - ي��م إرسال CCR-Update كل
periodic_ccr_time_secondsخلال المكالمة - إذا تم تمكين
schedule_hangup_auth، يتم الإيقاف التلقائي عند انتهاء الائتمان - يتم إرسال CCR-Terminate عند انتهاء المكالمة
حالات الاستخدام:
- OCS الأساسية: تمكين مع الافتراضات للتحكم القياسي في الائتمان
- المكالمات عالية القيمة: تقليل
periodic_ccr_time_secondsإلى 30 ثانية لإعادة المصادقة المتكررة - الخدمة المدفوعة مسبقًا: تمكين
schedule_hangup_authوتعيينcredit_exhaustion_announcement - الامتثال للطوارئ: إضافة أرقام الطوارئ إلى
skipped_regexلضمان الاتصال دائمًا
تكامل FreeSWITCH
الوصول إلى متغيرات AVP في خطة الاتصال
بيانات AVP المستخرجة من رسائل CCA متاحة كمتغيرات قناة في خطة الاتصال FreeSWITCH:
<extension name="Route_with_OCS_Data">
<condition field="destination_number" expression="^(.+)$">
<!-- الوصول إلى معلومات توجيه الناقل من OCS -->
<action application="log"
data="INFO Carrier Code: ${CCA.Service-Information.Carrier-Select-Routing-Information}"/>
<!-- الوصول إلى الطرف المشحون من OCS -->
<action application="log"
data="INFO Charged Party: ${CCA.Service-Information.Alternate-Charged-Party-Address}"/>
<!-- الوصول إلى الوقت الممنوح -->
<action application="log"
data="INFO Allocated Time: ${allocated_time} seconds"/>
<!-- التوجيه بناءً على رمز الناقل -->
<action application="set"
data="carrier_code=${CCA.Service-Information.Carrier-Select-Routing-Information}"/>
<action application="bridge"
data="sofia/external/$1@carrier-${carrier_code}.sip.example.com"/>
</condition>
</extension>
توفر المتغيرات
التوقيت:
- يتم تعيين المتغيرات قبل إعداد مكالمة FreeSWITCH
- متاحة طوال مدة المكالمة
- تستمر عبر تحويلات المكالمات والتحديثات
النطاق:
- نطاق القناة (محدد لكل ساق مكالمة فردية)
- غير موروثة من الساقين المربوطة/المحولة
- آمنة للاستخدام في جميع تطبيقات خطة الاتصال
حالات الاس��خدام المثال
1. اختيار الناقل بناءً على بيانات OCS
استخدم رمز الناقل المقدم من OCS لتوجيه المكالمات:
<extension name="Carrier_Selection">
<condition field="${CCA.Service-Information.Carrier-Select-Routing-Information}" expression="^(.+)$">
<action application="bridge"
data="sofia/external/${destination_number}@carrier-$1.example.com"/>
</condition>
<!-- احتياطي إذا لم يتم تحديد ناقل -->
<condition field="${CCA.Service-Information.Carrier-Select-Routing-Information}" expression="^$">
<action application="bridge"
data="sofia/external/${destination_number}@default-carrier.example.com"/>
</condition>
</extension>
كيف يعمل: تعيد OCS رمز الناقل "1408" في AVP معلومات الخدمة. يقوم FreeSWITCH بتوجيه المكالمة إلى بوابة carrier-1408.example.com بناءً على هذه البيانات.
2. طرف بديل للفوترة
توجيه الفوترة إلى طرف مختلف بناءً على استجابة OCS:
<extension name="Alternate_Billing">
<condition field="${CCA.Service-Information.Alternate-Charged-Party-Address}" expression="^(.+)$">
<!-- تس��يل الطرف المفوتر لـ CDRs -->
<action application="set"
data="billed_party=$1"/>
<action application="export"
data="billed_party=$1"/>
<!-- تضمين في رؤوس SIP -->
<action application="set"
data="sip_h_X-Billed-Party=$1"/>
<action application="bridge"
data="sofia/external/${destination_number}@trunk.example.com"/>
</condition>
</extension>
كيف يعمل: تحدد OCS الطرف المفوتر البديل (مثل، الحساب المؤسسي). يستخرج OmniTAS "NickTest" من AVP ويجعله متاحًا لخطة الاتصال لتسجيل CDR وإدراج رأس SIP.
3. مكالمات محدودة زمنياً مع تحذيرات
توفير تحذيرات قبل انتهاء الائتمان:
<extension name="Credit_Warnings">
<condition field="destination_number" expression="^(.+)$">
<!-- جدولة تحذير قبل 30 ثانية من الإيقاف -->
<action application="set"
data="warning_time=${expr(${allocated_time} - 30)}"/>
<action application="sched_hangup"
data="+${allocated_time} ALLOTTED_TIMEOUT"/>
<action application="sched_broadcast"
data="+${warning_time} playback::ivr/ivr-account_balance_low.wav"/>
<action application="bridge"
data="sofia/external/$1@trunk.example.com"/>
</condition>
</extension>
كيف يعمل: يستخدم allocated_time من OCS لجدولة الإيقاف التلقائي ويشغل إعلان التحذير قبل 30 ثانية من الانفصال.
إشعارات الإجابة والإيقاف
بعد أن يقوم CCR-Initial بتفويض مكالمة، لا يزال OmniTAS بحاجة إلى معرفة متى تم الإجابة على المكالمة (لبدء القياس وإرسال CCR-Update) و متى تنتهي (لإرسال CCR-Terminate). يتم الحصول على هذه الأحداث من FreeSWITCH عبر طبقة مقبس الحدث (ESL).
كيف يعمل:
- يحتفظ OmniTAS باتصال ESL دائم وارد إلى FreeSWITCH المحلي ويشترك في
CHANNEL_ANSWERوCHANNEL_HANGUP_COMPLETE. - عند
CHANNEL_ANSWER، يقرأ SIP Call-ID ووقت الإجابة الحقيقي ويرسل CCR-Update الذي يبدأ القياس. - عند
CHANNEL_HANGUP_COMPLETE، يقرأ SIP Call-ID وسبب الإيقاف في FreeSWITCH ويرسل CCR-Terminate مع الوقت المستخدم النهائي. - يتم مطابقة الأحداث مع جلسة التحكم في الائتمان بواسطة SIP Call-ID. يتم تجاهل الأحداث للساقين المكالمات بدون جلسة (الساقين MT، الساقين B المربوطة، المكالمات المعفاة). هذا هو ما يمنع المكالمات غير المشحونة من إنتاج CCRs.
- الإجابة المكررة هي غير متغيرة. كلا الساقين من المكالمة المربوطة تطلق
CHANNEL_ANSWERويمكن أن تحل إلى نفس Call-ID؛ فقط الأول يرسل CCR-Update ويبدأ المرسل الدوري، بينما يتم تجاهل البقية (وإلا ستحصل على CCR-Us مكررة ومرسلين دوريين مزدوجين). - التحويل ينهي الجلسة المشحونة. يتم التعامل مع إيقاف
BLIND_TRANSFER/ATTENDED_TRANSFERكإيقاف عادي → CCR-Terminate (المتصل المشحون قد غادر المكالمة، أو تم تحويل المكالمة إلى إعلان نفاد الائتمان). بمجرد انتهاء الجلسة، أي إيقاف لاحق لنفس Call-ID لا يجد جلسة ولا يرسل شيئًا.
يعمل CallEventListener دائمًا (تحتوي النشر الحقيقي دائمًا على FreeSWITCH المتواجد في نفس المكان؛ يتم تخطيه فقط تحت test_mode). ليس محجوزًا بواسطة مفتاح منفصل. يتم اتخاذ قرار إرسال CCR لكل حدث بواسطة online_charging.enabled. مع الشحن مغلق، لا يزال المستمع يتلقى ويسجل CHANNEL_ANSWER/CHANNEL_HANGUP_COMPLETE في وضع التصحيح ولكن لا يرسل أي CCR. (كان هناك في الإصدارات السابقة مفتاح منفصل esl_notifications؛ تمت إزالته لأنه كان يجب أن يتفق مع online_charging.enabled وكسر الشحن بصمت. كان يرسل فقط CCR-Initial، لا CCR-U/CCR-T، عندما كان الشحن مفعلًا ولكن كان المفت��ح غائبًا.)
ملغى: نقطة نهاية HTTP /call_event
كانت الإصدارات السابقة تكشف عن الإجابة/الإيقاف عبر curl في خطة الاتصال التي قامت بإرسال POST إلى نقطة نهاية HTTP /call_event على OmniTAS. تم إلغاء هذه الآلية. تمت إزالة خطط الاتصال، وأصبح ESL الآن مصدر الإشعار.
لا تزال نقطة نهاية /call_event موجودة وتعيد 200 OK حتى لا تتسبب أي مراجع متبقية في خطة الاتصال في حدوث خطأ، ولكنها لا تقوم بأي إجراء شحن. يجب على المشغلين الذين يقومون بالترقية من إصدار أقدم التأكد من أن خطط الاتصال الخاصة بهم لم تعد تعتمد عليها.
رسائل Diameter
CCR-Initial (نوع الطلب 1)
ترسل قبل إعداد المكالمة لطلب التفويض وتخصيص الائتمان الأولي.
AVPs الرئيسية المرسلة:
| AVP | الرمز | النوع | الوصف |
|---|---|---|---|
| Session-Id | 263 | UTF8String | معرف الجلسة، ثابت طوال جلسة التحكم في الائتمان (CCR-I/U/T تشترك فيه). مشتق بشكل حتمي من SIP Call-ID. |
| Auth-Application-Id | 258 | Unsigned32 | القيمة 4 لتطبيق التحكم في الائتمان Diameter وفقًا لـ RFC 4006 |
| Service-Context-Id | 461 | UTF8String | "000.000.12.32260@3gpp.org" لشحن IMS وفقًا لـ TS 32.299 |
| CC-Request-Type | 416 | Enumerated | القيمة 1 (INITIAL_REQUEST) |
| CC-Request-Number | 415 | Unsigned32 | رقم التسلسل: 0 لــ INITIAL_REQUEST، ثم 1، 2، ... للطلبات اللاحقة في الجلسة وفقًا لـ RFC 4006 §8.2 |
| Service-Identifier | 439 | Unsigned32 | معرف الخدمة الثابت المجهز (service_identifier config) |
| Subscription-Id | 443 | Grouped | MSISDN أو IMSI المشترك |
| Requested-Service-Unit | 437 | Grouped | طلب الحجز: CC-Time = requested_units_seconds |
| Service-Information | 873 | Grouped | تفاصيل المكالمة الخاصة بـ IMS (الطرف المتصل/المتصل به، Role-Of-Node، الطوابع الزمنية) |
مثال CCR-I:
Session-Id: "tas01.example.org;1463927445;1744753804"
Auth-Application-Id: 4
CC-Request-Type: 1 (INITIAL_REQUEST)
CC-Request-Number: 0
Subscription-Id:
- Subscription-ID-Type: 0 (END_USER_E164)
Subscription-ID-Data: "313380000000670"
Multiple-Services-Credit-Control:
- Service-Identifier: 1
Requested-Service-Unit:
- CC-Time: 300 (طلب الحجز)
Service-Information:
- IMS-Information:
- Role-Of-Node: 0 (ORIGINATING_ROLE)
- Node-Functionality: 6 (AS)
- Calling-Party-Address: "tel:+313380000000670"
- Called-Party-Address: "tel:+15551234567"
يحمل
Requested-Service-Unitحجزًا حقيقيًا (ليس صفرًا). يقرر OCS المنحة الفعلية ويعيدها فيGranted-Service-Unitمن CCA.
CCA (Credit-Control-Answer)
استجابة من OCS مع قرار التفويض والائتمان الممنوح.
AVPs الرئيسية المستلمة:
| AVP | الرمز | النوع | الوصف |
|---|---|---|---|
| Result-Code | 268 | Unsigned32 | 2001 للنجاح. انظر رموز النتائج لقيم الأخطاء. |
| Granted-Service-Unit | 431 | Grouped | الائتمان المخصص (الوقت بالثواني) |
| Service-Information | 873 | Grouped | بيانات الشحن الإضافية (معلومات الناقل، الطرف المشحون، إلخ) |
مثال CCA مع AVPs:
Session-Id: "tas01.example.org;1769294418268;8a078232"
Result-Code: 2001 (DIAMETER_SUCCESS)
CC-Request-Type: 1
CC-Request-Number: 1
Granted-Service-Unit:
- CC-Time: 600 (10 دقائق ممنوحة)
Service-Information:
- IMS-Information:
- Carrier-Select-Routing-Information: "1408"
- Alternate-Charged-Party-Address: "NickTest"
المتغيرات الناتجة:
allocated_time = 600
CCA.Service-Information.Carrier-Select-Routing-Information = "1408"
CCA.Service-Information.Alternate-Charged-Party-Address = "NickTest"
CCR-Update (نوع الطلب 2)
ترسل خلال المكالمات النشطة لإعادة التفويض الدورية أو تقارير الاستخدام المؤقت.
متى ترسل:
- عند إجابة المكالمة (
CHANNEL_ANSWERمن ESL):CC-Request-Number=1، مع الوقت الحقيقي للإجابة فيSIP-Response-Timestamp - بشكل دوري خلال المكالمة النشطة، مؤقتة ديناميكيًا كـ
allocated_time - ccr_update_buffer_secondsمن كل منحة (تتراجع إلىperiodic_ccr_time_seconds)
الاختلافات الرئيسية عن CCR-I:
CC-Request-Type:2(UPDATE_REQUEST)CC-Request-Number:1عند الإجابة، ثم يزيد مع كل إعادة تفويض دوريةRequested-Service-Unit: الحجز التالي (requested_units_seconds)- نفس
Session-Idالثابت مثل CCR-Initial
يتم الإبلاغ عن الوقت المستهلك في CCR-Terminate (
Used-Service-Unit)، وليس في CCR-Updates المؤقتة. التحديثات المؤقتة تمد الحجز؛ يتم تسوية الاستخدام النهائي عند الانتهاء.
CCR-Terminate (نوع الطلب 3)
ترسل عند إيقاف المكالمة (CHANNEL_HANGUP_COMPLETE من ESL) مع تقرير الاستخدام النهائي.
AVPs الرئيسية:
CC-Request-Type:3(TERMINATION_REQUEST)CC-Request-Number: التالي في التسلسل (مثل2)Used-Service-Unit: إجمالي وقت الحديث المستهلك (CC-Time، الثواني منذ الإجابة)Termination-Cause:1(DIAMETER_LOGOUT) وفقًا لـ RFC 6733 §8.15Cause-Code(AVP 861، IMS-Information):0لمكالمة تمت الإجابة عنها وإطلاقها بشكل طبيعي،2لإعداد جلسة غير ناجحة، وفقًا لـ TS 32.299
رموز النتائج
| الرمز | الاسم | الوصف | إجراء OmniTAS |
|---|---|---|---|
| 2001 | DIAMETER_SUCCESS | تم الموافقة على الطلب | تحليل AVPs، إعداد المكالمة |
| 4010 | DIAMETER_END_USER_SERVICE_DENIED | تم رفض الخدمة للمشترك | رفض المكالمة مع CALL_REJECTED |
| 4012 | DIAMETER_CREDIT_LIMIT_REACHED | رصيد غير كافٍ | رفض المكالمة مع OUTGOING_CALL_BARRED |
| 5003 | DIAMETER_AUTHORIZATION_REJECTED | سياسة OCS تم رفضها | رفض المكالمة مع CALL_REJECTED |
| 5xxx | أخطاء دائمة | تكوين OCS أو خطأ في النظام | رفض المكالمة، تسجيل الخطأ |
مرجع: RFC 6733 §7.1 و 3GPP TS 32.299
المقاييس
راجع docs/metrics.md للحصول على كتالوج المقاييس الكامل. المقاييس أدناه هي تلك المتعلقة بالشحن عبر الإنترنت.
مقاييس طلب / استجابة Diameter
تُقسم CCRs حسب نوع الطلب عبر علامة command بحيث يمكن تتبع CCR-Initial (الإعداد)، CCR-Update (إعادة المصادقة المؤقتة) و CCR-Terminate (إنهاء) بشكل مستقل. ثم يكون من الممكن رؤية ارتفاع في التحديثات المؤقتة الفاشلة بمفردها.
المقياس: diameter_requests_total (عداد): الطلبات المرسلة عبر Diameter
المقياس: diameter_responses_total (عداد): الاستجابات المستلمة عبر Diameter
المقياس: diameter_response_duration_milliseconds (هيستوجرام): وقت الجولة للطلب
العلامات:
application-ro(الشحن عبر الإنترنت) أوsh(بيانات المشترك)command-ccr_i،ccr_u،ccr_t(Ro) أوudr(Sh)result_code- (الاستجابات فقط) رمز نتيجة Diameter:2001،4012، إلخ؛0= مهلة / رد غير قابل للتحليلresult- (المدة فقط)success،nocredit،error
استعلامات مثال:
# معدل CCR حسب نوع الطلب
sum by (command) (rate(diameter_requests_total{application="ro"}[5m]))
# معدل أخطاء CCR، حسب نوع الطلب (أي شيء ليس 2001)
sum by (command) (rate(diameter_responses_total{application="ro", result_code!="2001"}[5m]))
# رفض حدود الائتمان (4012)
rate(diameter_responses_total{application="ro", result_code="4012"}[5m])
# تأخر CCR في النسبة المئوية 95 حسب نوع الطلب
histogram_quantile(0.95,
sum by (le, command) (rate(diameter_response_duration_milliseconds_bucket{application="ro"}[5m]))
)
مقاييس حصة التحكم في الائتمان
المقياس: ro_charging_quota_seconds
النوع: هيستوجرام
الوصف: الحصة (بالثواني) الملاحظة على كل CCR، للتحقق من صحة الشحن
العلامات:
request_type-ccr_i،ccr_u،ccr_tkind-requested(CC-Time في Requested-Service-Unit)،granted(Granted-Service-Unit،0= لا ائتمان)،used(Used-Service-Unit عند الإنه��ء)
استعلامات مثال:
# الوسيط الممنوح عند إعداد المكالمة
histogram_quantile(0.5, rate(ro_charging_quota_seconds_bucket{request_type="ccr_i", kind="granted"}[5m]))
# منح بدون ائتمان (تخصيصات صفرية) في الثانية
rate(ro_charging_quota_seconds_bucket{kind="granted", le="0"}[5m])
# إجمالي الثواني المستخدمة المبلغ عنها عند الإنهاء في الثانية (فحص عقلاني ضد الدقائق المفوترة)
rate(ro_charging_quota_seconds_sum{kind="used"}[5m])
مقاييس تفويض OCS والأحداث
المقياس: ocs_authorization_attempts_total (عداد)
العلامات: result (success، nocredit، timeout، error)، skipped (true إذا تم تجاوزها عبر regex، وإلا false)
المقياس: online_charging_events_total (عداد): أحداث دورة الحياة
العلامات: event_type (authorize، answer، reauth، hangup، credit_exhaustion_hangup، hangup_rescheduled)، result (success، nocredit، timeout، error، triggered)
استعلامات مثال:
# معدل نجاح التفويض (باستثناء المتجاوزات)
sum(rate(ocs_authorization_attempts_total{result="success", skipped="false"}[5m]))
/ sum(rate(ocs_authorization_attempts_total{skipped="false"}[5m]))
# المكالمات التي تم إنهاؤها أثناء المكالمة بسبب نفاد الائتمان
rate(online_charging_events_total{event_type="credit_exhaustion_hangup"}[5m])
استكشاف الأخطاء وإصلاحها
متغيرات AVP غير متاحة في FreeSWITCH
الأعراض:
- لا يمكن لخطة الاتصال في FreeSWITCH الوصول إلى متغيرات
${CCA.Service-Information.*} - تظهر المتغيرات كفارغة أو غير معرفة
الأسباب المحتملة:
- OCS لا تعيد AVPs معلومات الخدمة في CCA
- فشل تحليل AVP بسبب هيكل غير متوقع
- المتغيرات غير مصدرة إلى قناة FreeSWITCH
الحل:
-
تحقق من أن استجابة OCS تحتوي على AVPs
تحقق من سجلات OmniTAS لرسالة CCA:
[debug] Credit Control Answer: {:diameter_packet, ...}
[debug] Parsed AVP variables: %{
"CCA.Service-Information.Carrier-Select-Routing-Information" => "1408",
"CCA.Service-Information.Alternate-Charged-Party-Address" => "NickTest"
}إذا كانت "Parsed AVP variables" فارغة
%{}، فإن OCS لا تعيد AVPs المتوقعة. -
تحقق من أخطاء تحليل AVP
ابحث عن تحذيرات في السجلات:
[warning] got back another type of reply: {...}يشير هذا إلى أن هيكل AVP لا يتطابق مع التنسيق المتوقع. تحقق من هيكل حزمة Diameter.
-
تحقق من تصدير متغير FreeSWITCH
في وحدة التحكم FreeSWITCH أو ESL:
freeswitch> uuid_dump <call-uuid>ابحث عن المتغيرات التي تحتوي على بادئة
variable_وCCA.في الاسم:variable_CCA.Service-Information.Carrier-Select-Routing-Information: 1408
variable_CCA.Service-Information.Alternate-Charged-Party-Address: NickTest
variable_CCA.Auth-Application-Id: 4
variable_CCA.Result-Code: 2001ملاحظة: يحتفظ FreeSWITCH بالنقاط والشرطات في أسماء المتغيرات. تعمل بشكل صحيح في خطة الاتصال:
<action application="log" data="Carrier: ${CCA.Service-Information.Carrier-Select-Routing-Information}"/>
تم رفض المكالمة مع خطأ "غير معالج"
الأعراض:
- تظهر السجلات:
[warning] Could not authorize call: :unhandled - يتم رفض استجابات CCA الصالحة (رمز النتيجة 2001)
- تفشل المكالمات على الرغم من موافقة OCS عليها
الأسباب المحتملة:
- لا يتط��بق هيكل رسالة CCA مع النمط المتوقع
- AVPs محددة من البائع في مواقع غير متوقعة
- عدم تطابق فهرس موقع AVP
الحل:
كانت هذه مشكلة معروفة تم إصلاحها في الإصدارات الأخيرة. تأكد من أنك تستخدم الإصدار الحالي.
السلوك السابق: تطلب مطابقة النمط:
- AVP Granted-Service-Unit في الموقع 7 بالضبط
- قائمة AVP محددة من البائع فارغة
[]
السلوك الحالي: تقبل مطابقة النمط:
- AVP Granted-Service-Unit في أي موقع
- قوائم AVP محددة من البائع غير فارغة
إذا استمرت المشكلة:
- التقاط هيكل حزمة CCA من السجلات
- تحقق مما إذا كانت AVPs في تنسيق Diameter المتوقع
- تحقق من أن رمز النتيجة هو 2001
انتهاء مهلة OCS على جميع الطلبات
الأعراض:
- جميع طلبات CCR تنتهي مهلة
- تظهر السجلات:
[debug] Got back response for authorize: {:error, :timeout} - لم يتم استلام CCA خلال 5 ثوانٍ
الأسباب المحتملة:
- الاتصال الشبكي بـ OCS/DRA
- جدار الحماية يحظر منفذ Diameter (3868)
destination_realmأوdestination_hostغير صحيح- OCS لا تستجيب للطلبات
الحل:
-
تحقق من الاتصال الشبكي
اختبر اتصال TCP بـ OCS:
telnet ocs.example.com 3868يجب أن يتصل بنجاح. إذا تم رفض الاتصال أو انتهاء المهلة، تحقق من قواعد جدار الحماية.
-
تحقق من تكوين Diameter
تحقق من أن
destination_realmيتطابق مع تكوين OCS:config :tas, :diameter,
destination_realm: "epc.mnc001.mcc001.3gppnetwork.org" # يجب أن يتطابق مع مجال OCS -
راجع سجلات OCS
تحقق من OCS لرسائل CCR الواردة. إذا تلقت OCS الطلبات ولكنها لا تستجيب:
- تحقق من أن
origin_hostفي OmniTAS معترف به من قبل OCS - تحقق من أن تكوين نظير OCS يسمح بالاتصالات من OmniTAS
- تحقق من أن Service-Context-Id و Application-Id تتطابق مع توقعات OCS
- تحقق من أن
نفاد الائتمان لا يقطع المكالمات
الأعراض:
- تستمر المكالمات بعد الوقت الممنوح للائتمان
- لا يوجد قطع تلقائي عند انتهاء
allocated_time - تم تمكين
schedule_hangup_authولكن لا يعمل
الأسباب المحتملة:
- لم يتم تكوين قطع FreeSWITCH المجدول
schedule_hangup_authهوfalse- حالة المكالمة لا يتم تتبعها بشكل صحيح
الحل:
-
تحقق من التكوين
تأكد من تمكين
schedule_hangup_auth:config :tas, :online_charging,
schedule_hangup_auth: true -
تحقق من اتصال FreeSWITCH ESL
تحقق من أن OmniTAS يمكنها إرسال الأوامر إلى FreeSWITCH:
[debug] Schedule Hangup Response: {:ok, "+OK"}إذا كان هناك خطأ أو لا توجد استجابة، تحقق من تكوين مقبس أحداث FreeSWITCH.
-
راقب حالة المكالمة
تحقق من أن UUID المكالمة يتم تتبعه في حالة المكالمة:
[debug] Setting Scheduled Hangup for call in 600 secondsإذا لم يتم العثور على UUID، فقد تكون هناك مشكلات في تتبع حالة المكالمة.
تجاوز regex غير متجاوز لـ OCS
الأعراض:
- لا تزال المكالمات الطارئة (911، 000) تمر عبر تفويض OCS
- الأرقام التي تطابق أنماط
skipped_regexلا يتم تجاوزها - تأخيرات في المكا��مات الطارئة
الأسباب المحتملة:
- خطأ في بناء جملة نمط regex
- عدم تطابق تنسيق رقم الوجهة
- عدم هروب regex بشكل صحيح
الحل:
-
تحقق من أنماط regex
اختبر تجميع regex:
Regex.compile("^911$") # يجب أن تعيد {:ok, ~r/^911$/}الأخطاء الشائعة:
- الفواصل المفقودة: استخدم
^911$وليس911 - الهروب: استخدم
\*لنجمة حرفية، وليس\*
- الفواصل المفقودة: استخدم
-
تحقق من تنسيق الرقم
تحقق من أن تنسيق رقم الوجهة يتطابق مع النمط:
[debug] Checking if dialled number "911" matches skipped regex...إذا كان الرقم بتنسيق "+1911" ولكن النمط هو "^911$"، فلن يتطابق.
-
أنماط المثال
config :tas, :online_charging,
skipped_regex: [
"^911$", # الطوارئ في الولايات المتحدة
"^000$", # الطوارئ في أستراليا
"^112$", # الطوارئ الدولية
"^\*86$", # البريد الصوتي (نجمة هاربة)
"^1?800\d{7}$" # الأرقام المجانية
]
المرجع
مواصفات 3GPP
| المواصفة | العنوان | الأقسام ذات الصلة |
|---|---|---|
| TS 32.299 | تطبيقات الشحن عبر Diameter | §6.3 (واجهة Ro)، §7.2 (تعريفات AVP) |
| TS 32.240 | بنية الشحن والمبادئ | §5 (الشحن عبر الإنترنت) |
| TS 29.229 | واجهات Cx و Dx | استخدام AVP معلومات الخدمة في IMS |
RFCs IETF
| RFC | العنوان | الأقسام ذات الصلة |
|---|---|---|
| RFC 6733 | بروتوكول Diameter الأساسي | §3 (نظرة عامة على البروتوكول)، §7 (معالجة الأخطاء) |
| RFC 4006 | تطبيق التحكم في الائتمان Diameter | §8 (رسائل التحكم في الائتمان) |
مرجع رموز AVP
Vendor-ID 0 = IETF الأساسي (RFC 6733 /
RFC 4006)؛ Vendor-ID 10415 = 3GPP
(TS 32.299).
الهيكل الكامل لـ CCR (مكالمة صوتية)
كل AVP تتضمنه OmniTAS في طلب التحكم في الائتمان، مع التجميع الموضح:
Credit-Control-Request (Command 272, App 4)
├─ Session-Id (263)
├─ Origin-Host (264)
├─ Origin-Realm (296)
├─ Destination-Realm (283)
├─ Destination-Host (293) [فقط إذا تم تكوينه]
├─ Auth-Application-Id (258) = 4
├─ Service-Context-Id (461) = 000.000.12.32260@3gpp.org
├─ CC-Request-Type (416)
├─ CC-Request-Number (415)
├─ Event-Timestamp (55)
├─ User-Name (1) [فقط إذا تم تعيين اسم المستخدم]
├─ Termination-Cause (295) [CCR-T فقط]
├─ Subscription-Id (443)
│ ├─ Subscription-Id-Type (450) = 0 (END_USER_E164)
│ └─ Subscription-Id-Data (444) = رقم MSISDN للمشترك
├─ Multiple-Services-Credit-Control (456)
│ ├─ Service-Identifier (439)
│ ├─ Requested-Service-Unit (437) [CCR-I، CCR-U]
│ │ └─ CC-Time (420)
│ └─ Used-Service-Unit (446) [CCR-T]
│ └─ CC-Time (420)
└─ Service-Information (873, v10415)
├─ IN-Information [امتداد المشغل]
│ └─ Real-Called-Number
└─ IMS-Information (876, v10415)
├─ Role-Of-Node (829) = 0 (ORIGINATING_ROLE)
├─ Node-Functionality (862) = 6 (AS)
├─ User-Session-Id (830) = SIP Call-ID
├─ Calling-Party-Address (831)
├─ Called-Party-Address (832)
├─ Requested-Party-Address (1251)
├─ Time-Stamps (833)
│ ├─ SIP-Request-Timestamp (834)
│ ├─ SIP-Request-Timestamp-Fraction (2301)
│ ├─ SIP-Response-Timestamp (835) [عند الرد]
│ └─ SIP-Response-Timestamp-Fraction (2302) [عند الرد]
└─ Cause-Code (861) [CCR-T]
AVPs المرسلة من OmniTAS (CCR)
تظهر In أي أنواع الطلبات تحمل AVP: I = CCR-Initial، U = CCR-Update، T = CCR-Terminate.
| AVP | الرمز | البائع | النوع | في | القيمة / المصدر |
|---|---|---|---|---|---|
| Session-Id | 263 | 0 | UTF8String | I U T | ثابت لكل مكالمة (مشتق من SIP Call-ID)؛ متطابق عبر I/U/T |
| Origin-Host | 264 | 0 | DiameterIdentity | I U T | هوية Diameter لـ OmniTAS (origin_host.origin_realm) |
| Origin-Realm | 296 | 0 | DiameterIdentity | I U T | origin_realm |
| Destination-Realm | 283 | 0 | DiameterIdentity | I U T | مجال OCS |
| Destination-Host | 293 | 0 | DiameterIdentity | I U T | موجود فقط إذا تم تكوين مضيف OCS محدد |
| Auth-Application-Id | 258 | 0 | Unsigned32 | I U T | 4 (تطبيق التحكم في الائتمان Diameter) |
| Service-Context-Id | 461 | 0 | UTF8String | I U T | 000.000.12.32260@3gpp.org |
| CC-Request-Type | 416 | 0 | Enumerated | I U T | 1=Initial، 2=Update، 3=Terminate |
| CC-Request-Number | 415 | 0 | Unsigned32 | I U T | 0 للطلب الأول، ثم 1، 2، … |
| Event-Timestamp | 55 | 0 | Time | I U T | الوقت الذي تم فيه إنشاء الطلب |
| User-Name | 1 | 0 | UTF8String | I U T | اختياري؛ فقط إذا تم تقديم اسم مستخدم/IMSI |
| Termination-Cause | 295 | 0 | Enumerated | T | 1 (DIAMETER_LOGOUT) |
| Subscription-Id | 443 | 0 | Grouped | I U T | هوية المشترك (انظر الأطفال) |
| → Subscription-Id-Type | 450 | 0 | Enumerated | I U T | 0 (END_USER_E164) |
| → Subscription-Id-Data | 444 | 0 | UTF8String | I U T | رقم MSISDN للمشترك |
| Multiple-Services-Credit-Control | 456 | 0 | Grouped | I U T | حاوية التحكم في الائتمان (انظر الأطفال) |
| → Service-Identifier | 439 | 0 | Unsigned32 | I U T | service_identifier (مستقر، موفر) |
| → Requested-Service-Unit | 437 | 0 | Grouped | I U | طلب حجز |
| → → CC-Time | 420 | 0 | Unsigned32 | I U | requested_units_seconds |
| → Used-Service-Unit | 446 | 0 | Grouped | T | الاستهلاك النهائي |
| → → CC-Time | 420 | 0 | Unsigned32 | T | الثواني المستهلكة منذ الرد |
| Service-Information | 873 | 10415 | Grouped | I U T | حاوية الخدمة 3GPP |
| → IN-Information | - | 10415 | Grouped | I U T | امتداد المشغل الذي يحمل الرقم الحقيقي الذي تم طلبه |
| → → Real-Called-Number | - | 10415 | UTF8String | I U T | الرقم الذي تم طلبه |
| → IMS-Information | 876 | 10415 | Grouped | I U T | تفاصيل الشحن IMS |
| → → Role-Of-Node | 829 | 10415 | Enumerated | I U T | 0 (ORIGINATING_ROLE): MO هو الساق الذي يتم تحصيله |
| → → Node-Functionality | 862 | 10415 | Enumerated | I U T | 6 (AS) |
| → → User-Session-Id | 830 | 10415 | UTF8String | I U T | SIP Call-ID (مفتاح ارتباط OCS) |
| → → Calling-Party-Address | 831 | 10415 | UTF8String | I U T | tel:+<calling MSISDN> |
| → → Called-Party-Address | 832 | 10415 | UTF8String | I U T | tel:+<called number> |
| → → Requested-Party-Address | 1251 | 10415 | UTF8String | I U T | tel:+<called number> |
| → → Time-Stamps | 833 | 10415 | Grouped | I U T | أوقات طلب/است��ابة SIP |
| → → → SIP-Request-Timestamp | 834 | 10415 | Time | I U T | وقت INVITE (بالثواني الكاملة) |
| → → → SIP-Request-Timestamp-Fraction | 2301 | 10415 | Unsigned32 | I U T | وقت INVITE (بالملي ثانية) |
| → → → SIP-Response-Timestamp | 835 | 10415 | Time | U T | وقت الرد (200 OK): فقط عند الرد |
| → → → SIP-Response-Timestamp-Fraction | 2302 | 10415 | Unsigned32 | U T | وقت الرد (بال��لي ثانية): فقط عند الرد |
| → → Cause-Code | 861 | 10415 | Integer32 | T | 0 تحرير عادي / 2 إعداد غير ناجح |
الرموز المعروضة كـ
-هي امتدادات مشغل/بائع تحمل تحتService-Information؛ ليس لديها رمز معين من 3GPP وتعريفها في قاموس Diameter الخاص بـ OmniTAS.
AVPs المستلمة من OCS (CCA)
| AVP | الرمز | البائع | النوع | الوصف |
|---|---|---|---|---|
| Result-Code | 268 | 0 | Unsigned32 | 2001 = النجاح؛ انظر رموز النتائج |
| Granted-Service-Unit | 431 | 0 | Grouped | الائتمان المخصص |
| → CC-Time | 420 | 0 | Unsigned32 | الثواني الممنوحة (allocated_time). 0 ⇒ لا ائتمان ⇒ حظر/قطع |
| Service-Information | 873 | 10415 | Grouped | بيانات الشحن الاختيارية التي تعيدها OCS |
| → Carrier-Select-Routing-Information | 2023 | 10415 | UTF8String | رمز توجيه الناقل (مُعين إلى متغير FreeSWITCH) |
| → Alternate-Charged-Party-Address | 1280 | 10415 | UTF8String | معرف الطرف الذي يتم محاسبته (مُعين إلى متغير FreeSWITCH) |
يتم تسطيح جميع AVPs الفرعية لـ Service-Information التي تم إرجاعها في CCA إلى متغيرات قناة FreeSWITCH. انظر تحليل AVP وتعيين المتغيرات و
متغيرات قناة FreeSWITCH.
متغيرات قناة FreeSWITCH
جميع بيانات AVP المستخرجة متاحة كمتغيرات قناة FreeSWITCH:
| اسم المتغير | المصدر | مثال على القيمة | الوصف |
|---|---|---|---|
${allocated_time} | Granted-Service-Unit / CC-Time | 600 | الوقت المخصص بالثواني |
${CCA.Session-Id} | AVP Session-Id | omni-as01.epc...;1769299669873;325e2f2e | معرف جلسة Diameter |
${CCA.Result-Code} | AVP Result-Code | 2001 | نتيجة CCA (2001 = نجاح) |
${CCA.Auth-Application-Id} | AVP Auth-Application-Id | 4 | تطبيق Diameter (4 = CC) |
${CCA.CC-Request-Type} | AVP CC-Request-Type | 1 | نوع الطلب (1=Initial) |
${CCA.CC-Request-Number} | AVP CC-Request-Number | 1 | رقم التسلسل |
${CCA.CC-Time} | AVP CC-Time (إذا كان موجودًا) | 600 | حصة الوقت الممنوحة |
${CCA.Origin-Host} | AVP Origin-Host | ocs01.epc.mnc001.mcc001.3gppnetwork.org | معرف مضيف OCS |
${CCA.Origin-Realm} | AVP Origin-Realm | epc.mnc001.mcc001.3gppnetwork.org | مجال OCS |
${CCA.Service-Information.Carrier-Select-Routing-Information} | Service-Information → Carrier-Select-Routing-Information | 1408 | رمز توجيه الناقل من OCS |
${CCA.Service-Information.Alternate-Charged-Party-Address} | Service-Information → Alternate-Charged-Party-Address | NickTest | الطرف البديل للمحاسبة |
تنسيق المتغير:
- جميع AVPs CCA تستخدم بادئة
CCA. - تستخدم AVPs المتداخلة تدوين النقاط:
CCA.Parent.Child - يتم الاحتفاظ بالنقاط والشرطات في أسماء المتغيرات
- في uuid_dump، تظهر المتغيرات مع بادئة
variable_
مثال على مخرجات uuid_dump:
variable_allocated_time: 600
variable_CCA.Service-Information.Carrier-Select-Routing-Information: 1408
variable_CCA.Service-Information.Alternate-Charged-Party-Address: NickTest
variable_CCA.Result-Code: 2001