دليل عمليات OmniCHF
جدول المحتويات
- نظرة عامة
- دورة حياة جلسة الشحن
- مرجع دور 3GPP والمواصفات
- نقاط نهاية SBI
- تكامل CGRateS
- الإجراءات الرئيسية
نظرة عامة
تنفذ OmniCHF وظيفة الشحن (CHF) من الجيل الخامس. يوفر CHF شحنًا متقاربًا عبر الإنترنت وغير متصل لجلسات PDU من الجيل الخامس من خلال خدمة Nchf_ConvergedCharging (3GPP TS 32.290 / TS 32.291 / TS 32.255).
ينشئ مستهلك الشحن، عادةً SMF، جلسة شحن لكل جلسة PDU، ويبلغ عن الاستخدام على مدار عمر تلك الجلسة، وأخيرًا يحررها. تقوم OmniCHF بترجمة كل طلب شحن من الجيل الخامس ��لى استدعاء JSON-RPC لجلسة CGRateS للحصول على تفويض الائتمان في الوقت الحقيقي (الشحن عبر الإنترنت / إدارة الحصص) وتولد سجل بيانات الشحن (CDR) عند تحرير الجلسة (الشحن غير المتصل).
تكون كل جلسة شحن مملوكة لـ ChargingWorker GenServer مخصص تحت DynamicSupervisor (بنية عملية لكل جلسة). يتم الاحتفاظ بجميع الحالة لجلسة واحدة (SUPI، DNN، S-NSSAI، الحجم/المدة المتراكمة، مجموعة التصنيف، حالة جلسة CGRateS، معرف الشحن) في عملية العامل تلك. لا تؤثر انهيارات جلسة واحدة على الأخرى. يتم الاحتفاظ بحالة الجلسة في الذاكرة ويتم إعادة بنائها عندما ينشئ المستهلكون جلسات شحن جديدة بعد إعادة التشغيل.
المسؤوليات الأساسية:
- خدمة
nchf-convergedcharging/v3على SBI. - تخصيص
chargingDataRefلكل جلسة وإدارة دورة حياتها INITIAL → UPDATE → TERMINATE. - منح وحدات الخدمة (GSU) استجابة لوحدات الخدمة المطلوبة (RSU)، وإرجاع الحجم/الوقت الممنوحين ��المحفزات لإدارة الحصص إلى المستهلك.
- الربط مع CGRateS لإدارة التصنيف والتوازن (الشحن عبر الإنترنت).
- إصدار CDRs إلى سجل التطبيق و، اختياريًا، إلى ملفات الشحن غير المتصلة اليومية.
- التسجيل مع NRF والحفاظ على نبض القلب.
دورة حياة جلسة الشحن
تتوافق كل جلسة PDU مع جلسة شحن واحدة، يتم تتبعها بواسطة chargingDataRef (UUID).
| الحالة | الزناد | الإجراء |
|---|---|---|
| تم الإنشاء | POST /chargingdata | تم إنشاء ChargingWorker، تم استدعاء CGRateS InitiateSession، تم منح الحصة الأولية |
| تم التحديث | POST /chargingdata/{ref}/update | تم استدعاء CGRateS UpdateSession، تم تجميع الاستخدام، تم زيادة رقم التسلسل، تم منح حصة جديدة |
| تم التحرير | POST /chargingdata/{ref}/release | تم استدعاء CGRateS TerminateSession، تم بناء وإصدار CDR، تم إيقاف العامل |
تخزين الجلسة ورؤية الإدارة
تحافظ OmniCHF على حالة الجلسة النشطة في مخزنين في الذاكرة يتم الاحت��اظ بهما في تناغم، بحيث ترى واجهات الإدارة وتستطيع التصرف بناءً على كل جلسة حية:
| المخزن | الدعم | يحتفظ بـ | الدور |
|---|---|---|---|
| سجل العامل | ChargingWorker GenServer لكل جلسة تحت DynamicSupervisor، مفاتيح في Registry | الحالة الكاملة لكل جلسة (الحجم/المدة المتراكمة، رقم التسلسل، حالة CGRateS) | مصدر الحقيقة لجلسة حية. الإنشاء يولد عاملاً؛ التحديث والتحرير يحلان العامل أولاً |
| مخزن السياق | خريطة Agent واحدة في الذاكرة مفاتيحها chargingDataRef | مرآة لنفس سمات الجلسة | نموذج قراءة للرؤية وواجهات OAM |
على SBI، الإنشاء دائمًا يولد عاملاً، والتحديث والتحرير يحلان ذلك العامل أولاً، والرجوع إلى مخزن السياق فقط إذا لم يتم العثور على عامل (على سبيل المثال بعد انقطاع مشرف). يتم عكس كل جلسة عامل حية إلى مخزن السياق عند الإنشاء وعند كل تحديث، ويتم إزالتها منه عندما يتوقف العامل (ا��إفراج العادي، الإلغاء، أو الانهيار). تستفسر واجهات الإدارة عن سجل العامل أولاً وتعود إلى السياق، لذا يقدم كلا المخزنين عرضًا متسقًا.
عمليًا يعني هذا:
- الجلسة التي تم إنشاؤها بشكل طبيعي مرئية بالكامل من خلال واجهات الإدارة: تظهر في
GET /api/sessionsوفي إجماليات الإحصائيات، ويمكن إلغاؤها (POST /api/oam/charging_session) وإفراغ CDR (POST /api/oam/cdr/flush) من خلال نقاط نهاية OAM أثناء وجودها. - تعكس مقياس الجلسة النشطة والإحصائيات وقوائم الجلسات مجموعة الجلسات الحية الحقيقية، وليس مجرد مجموعة احتياطية.
- يتم الاحتفاظ بكلا المخزنين في الذاكرة ويتم إعادة ملئهما عندما ينشئ المستهلكون جلسات جديدة بعد إعادة التشغيل. نظرًا لأن الجلسات محتفظ بها في سجل محلي، فإن
chargingDataRefمملوك من قبل المثيل الذي أنشأه.
تؤكد مقياس omni_chf_sessions_active_count والعدادات omni_chf_charging_creates_total / omni_chf_charging_releases_total عدد الجلسات الحية المبلغ عنها بواسطة GET /api/sessions.
مرجع دور 3GPP والمواصفات
| المواصفة | الصلة |
|---|---|
| TS 23.501 | هندسة نظام الجيل الخامس: دور CHF، مفهوم الشحن المتقارب |
| TS 32.240 | هندسة الشحن والمبادئ |
| TS 32.290 | هندسة الشحن في نظام الجيل الخامس وتدفقات الرسائل |
| TS 32.291 | شحن نظام الجيل الخامس: واجهة برمجة تطبيقات خدمة Nchf_ConvergedCharging (HTTP/2 SBI)، نموذج بيانات ChargingDataRequest/Response |
| TS 32.255 | شحن مجال الاتصال بالبيانات في الجيل الخامس (شحن جلسة PDU) |
| TS 32.251 | تنسيق معرف الشحن (chargingId)، الفقرة 5.2.1.6 من TS 32.251 |
| TS 32.298 | أوصاف ومعالجة معلمات CDR |
| TS 29.500 / 29.501 | إطار عمل مشترك API وتصميم SBI للجيل الخامس |
| TS 29.510 | تسجيل NF ونبض القلب مع NRF |
مراجع إجراء Nchf_ConvergedCharging (TS 32.291):
| الإجراء | الفقرة |
|---|---|
| إنشاء بيانات الشحن (INITIAL) | 6.1.3.2.1 |
| تحديث بيانات الشحن (UPDATE) | 6.1.3.2.2 |
| تحرير بيانات الشحن (TERMINATE) | 6.1.3.2.3 |
| إشعار الشحن (REAUTHORIZATION / ABORT_CHARGING) | 6.1.6.2 |
نقاط نهاية SBI
تُخدم جميع نقاط نهاية Nchf تحت عنوان URL الأساسي {sbi_scheme}://{sbi_addr}:{sbi_port} والمسار الأساسي /nchf-convergedcharging/v3.
| الطريقة | المسار | الوصف | النجاح | الأخطاء |
|---|---|---|---|---|
POST | /chargingdata | إنشاء جلسة شحن (INITIAL). يخصص chargingDataRef، يبدأ جلسة CGRateS، يمنح حصة أولية. | 201 Created مع رأس Location | 400 (IE إلزامي مفقود)، 500 |
POST | /chargingdata/{chargingDataRef}/update | تحديث جلسة شحن (UPDATE). يبلغ عن الاستخدام ويطلب حصة إضافية. | 200 OK | 400، 404، 500 |
POST | /chargingdata/{chargingDataRef}/release | تحرير جلسة شحن (TERMINATE). يبلغ عن الاستخدام النهائي، يولد CDR، ينهي جلسة CGRateS. | 204 No Content | 400، 404، 500 |
POST | /notify | إشعار شحن استدعاء. يأمر OmniCHF بإرسال إشعار REAUTHORIZATION أو ABORT_CHARGING إلى notifyUri المخزنة للمستهلك. | 204 No Content | 400 (نوع notificationType غير صالح)، 404، 500 |
عند التحرير، يتم إرجاع 500 (السبب SYSTEM_FAILURE، العنوان "فشل إنهاء الشحن") عندما تفشل جلسة CGRateS TerminateSession. لا يزال يتم إنهاء CDR وكتابته، ولكن يتم عرض الفشل حتى لا يتم إخفاء عدم التناسق في الخلفية الفوترة (جلسة CGRateS مفتوحة). انظر إصدار يعود 500.
التحقق من الطلب
يتم التحقق من كل جسم طلب للحقائق المعلوماتية الإلزامية التالية قبل المعالجة. يؤدي IE المفقود إلى إرجاع 400 Bad Request مع السبب MANDATORY_IE_MISSING:
| IE الإلزامي | النوع |
|---|---|
nfConsumerIdentification | كائن |
invocationTimeStamp | سلسلة (ISO 8601) |
invocationSequenceNumber | عدد صحيح |
ChargingDataRequest: الحقول الرئيسية المستخدمة
| الحقل | النوع | المستخدم في | الوصف |
|---|---|---|---|
subscriberIdentifier | سلسلة | الكل | SUPI (مثل imsi-999700000000001). يستخدم كـ Account في CGRateS. يعود إلى nfConsumerIdentification.supi إذا كان غائبًا. |
notifyUri | سلسلة | الإنشاء | URI الاستدعاء المخزنة لإشعار الشحن لاحقًا (REAUTHORIZATION / ABORT_CHARGING). |
pDUSessionChargingInformation | كائن | الكل | تفاصيل جلسة PDU: pduSessionInformation (DNN، معرف جلسة PDU، نوع PDU، نوع RAT، qoSInformation، networkSlicingInfo.sNSSAI). |
multipleUnitUsage | مصفوفة | التحديث، التحرير | حاويات الاستخدام المبلغ عنها. يتم جمع إدخالات usedUnitContainer لكل عنصر للحجم/المدة المتراكمة. يحمل أيضًا مجموعة التصنيف المطلوبة. |
requestType | سلسلة | الكل | INITIAL_REQUEST، UPDATE_REQUEST، أو TERMINATION_REQUEST. |
ChargingDataResponse: الحقول الرئيسية المعادة
| الحقل | النوع | الوصف |
|---|---|---|
invocationSequenceNumber | عدد صحيح | 1 عند الإنشاء؛ يتم زيادته في كل تحديث. |
invocationTimeStamp | سلسلة | طابع زمني ISO 8601 للاستجابة. |
multipleUnitInformation | مصفوفة | الوحدات الممنوحة: إدخال واحد مع resultCode: "SUCCESS"، grantedUnit (totalVolume، time) ومجموعة التصنيف المح��ولة. |
triggers | مصفوفة | محفزات إدارة الحصص التي تعلم المستهلك متى يعود: QUOTA_THRESHOLD (IMMEDIATE_REPORT عند نصف الحجم الممنوح) وTIME_LIMIT (DEFERRED_REPORT عند 3600 ثانية). |
تكامل CGRateS
CGRateS هو محرك التصنيف والتوازن الخارجي. تعمل OmniCHF كعميل لجلسة SessionS، حيث تقوم بتعيين كل عملية شحن Nchf إلى طريقة JSON-RPC لجلسة:
| عملية Nchf | طريقة CGRateS SessionS |
|---|---|
| الإنشاء (INITIAL) | SessionSv1.InitiateSession |
| التحديث (UPDATE) | SessionSv1.UpdateSession |
| التحرير (TERMINATE) | SessionSv1.TerminateSession |
| التحقق من الصحة | SessionSv1.GetActiveSessions (حد 1) |
تُمرر قيمة MaxUsage التي تعيدها CGRateS مباشرة إلى المستهلك كـ grantedUnit (كلا من totalVolume و time).
السلوك الممكّن مقابل المعطّل
| الجانب | cgrates_enabled: true | cgrates_enabled: false (وضع التجاوز) |
|---|---|---|
| تفويض الائتمان | حقيقي: تقوم CGRateS بتصنيف الحساب وإرجاع MaxUsage | لا شيء: يتم إرجاع منحة ثابتة قدرها 86400 وحدة لكل من الإنشاء والتحديث |
| تأثير الرصيد | يتم خصم/حجز رصيد المشترك في CGRateS | لا يتم لمس أي رصيد |
| إنهاء | TerminateSession ينهي جلسة CGRateS و CDR | لا شيء |
| التحقق من الصحة | تحقق حي ضد cgrates_url | دائمًا يُبلغ reachable: false، cgrates_url: "disabled" |
| توقيع السجل | Initiating CGRateS session for ... | CGRateS integration disabled, returning default authorization (تحذير) |
| حالة الاستخدام | الشحن عبر الإنترنت في الإنتاج | اختبار المعاملات / التكامل بدون محرك تصنيف |
في وضع التجاوز، لا تزال OmniCHF تخصص
chargingDataRefs، وتتبع الجلسات، وتزيد أرقام التسلسل، وتصدر المحفزات، وتولد CDRs؛ فقط التحكم في الائتمان هو الذي تم تخطيه. هذا يجعل من الآمن ممارسة التدفق الكامل SMF↔CHF دون نشر CGRateS.
تم توثيق تكوين تكامل CGRateS (cgrates_enabled، cgrates_url، cgrates_tenant، cgrates_timeout) في مرجع التكوين.
رسم أحداث 5G إلى CGRateS
يحمل كل استدعاء لجل��ة Event خريطة مبنية من ChargingDataRequest:
| حقل حدث CGRateS | المصدر | ملاحظات |
|---|---|---|
Account / Subject | subscriberIdentifier (SUPI) | يعود إلى nfConsumerIdentification.supi، أو "unknown" إذا لم يكن موجودًا. |
Destination / DNN | pduSessionInformation.dnnId (أو .dnn) | اسم شبكة البيانات. |
ToR | مشتق من pduType | دائمًا *data لجلسات PDU. |
RequestType | requestType | يتم تعيينه إلى *prepaid. |
Category | ثابت | "data". |
Usage | usedUnitContainer | أول قيمة غير صفرية من totalVolume، ثم uplinkVolume + downlinkVolume، ثم time. |
OriginID | chargingDataRef | فريد لكل جلسة. |
OriginHost | ثابت | "OmniCHF". |
SUPI | subscriberIdentifier | حقل امتداد 5G. |
S-NSSAI_SST / S-NSSAI_SD | pduSessionInformation.sNSSAI | الافتراضات: SST 1، SD "". |
5QI | qoSInformation.5qI (أو fiveQI) | الافتراض 9. |
RATType | pduSessionInformation.ratType | الافتراض "NR". |
PDUSessionID | pduSessionInformation.pduSessionID | الافتراض 0. |
PDUSessionType | pduSessionInformation.pduType | الافتراض "IPV4". |
ChargingOperation | العملية | Initial / Update / Final. |
الإجراءات الرئيسية
جلسة الشحن المتقاربة (INITIAL → UPDATE → TERMINATE)
إذا فشلت CGRateS
TerminateSessionعند التحرير، لا تزال OmniCHF تنهي وتكتب CDR، لذا لا يتم فقدان السجل غير المتصل. يتلقى المستهلك بعد ذلك500(السببSYSTEM_FAILURE) بدلاً من204زائف، لأن جلسة CGRateS قد تظل مفتوحة وقد تحتاج الخلفية الفوترة إلى التسوية. عند إنهاء ناجح، يتلقى المسته��ك204 No Content.
إدارة الحصص (RSU / GSU والمحفزات)
وفقًا لـ TS 32.291، يرسل المستهلك وحدات الخدمة المطلوبة (RSU) وتعيد OmniCHF وحدات الخدمة الممنوحة (GSU) بالإضافة إلى المحفزات التي تخبر المستهلك متى يعود:
يعيد المستهلك التفويض (يرسل تحديثًا) عندما يصل إلى حد الحجم أو حد الوقت. يمكن أيضًا لـ OmniCHF دفع إعادة التفويض أو الإنهاء بشكل استباقي عبر نقطة النهاية /notify (REAUTHORIZATION / ABORT_CHARGING)، التي تنشر إلى notifyUri المقدم في الطلب الأولي.
إشعار الشحن (REAUTHORIZATION / ABORT_CHARGING)
وفقًا للفقرة 6.1.6.2 من TS 32.291، تدفع OmniCHF ChargingNotifyRequest إلى notifyUri المخزنة للمستهلك. المحفز هو نقطة النهاية التي تواجه المشغل POST /nchf-convergedcharging/v3/notify، التي يحمل جسمها chargingDataRef المستهدف وnotificationType. تبحث OmniCHF عن الجلسة، وتحل notifyUri الخاصة بها، وتنشر الإشعار إلى المستهلك.
الإشعار هو جهد أفضل نحو واجهة المشغل: يتم تسجيل
notifyUriالمرفوض أو غير القابل للوصول ولكن لا يغير نتيجة/notifyبمجرد حل الجلسة وnotifyUri. تؤدي الجلسة التي لا تحتوي علىnotifyUriمخزنة إلى خطأ داخليno_notify_uri.
حقول CDR
يتم بناء CDR عند التحرير، ويتم تسجيله في INFO (CHF CDR: %{...})، وعندما يكون offline_charging_enabled هو true، يتم إضافته كسطر JSON واحد إلى cdr_YYYYMMDD.json:
| الحقل | المصدر |
|---|---|
record_type | ثابت "5G_PDU_SESSION" |
supi | سياق الجلسة |
dnn | سياق الجلسة / pduSessionInformation |
snssai | {sst, sd} |
qos_5qi | qoSInformation.5qI (الافتراض 9) |
rat_type | pduSessionInformation.ratType (الافتراض "NR") |
pdu_session_id / pdu_session_type | سياق الجلسة / الطلب |
volume_uplink / volume_downlink / volume_total | يتم جمعها من جميع usedUnitContainers |
duration | الوقت المبلغ عنه، وإلا الفرق الزمني |
start_time / end_time | طوابع زمنية لإنشاء الجلسة / التحرير |
charging_data_ref | UUID للجلسة |
charging_id | معرف الشحن 32 بت من 3GPP (TS 32.251) |
recording_entity | عنوان URL الأساسي لـ OmniCHF SBI |
rating_group | تم حله من خريطة DNN |
يتم تكوين مخرجات CDR غير المتصلة (offline_charging_enabled، cdr_output_dir) وتركيب معرف ا��شحن (node_id) في مرجع التكوين.
تشغيل الشحن غير المتصل
لإلتقاط CDRs إلى ملف للوساطة / الفوترة:
- قم بتعيين
offline_charging_enabled: trueوأشر إلىcdr_output_dirإلى دليل قابل للكتابة. - تتراكم CDRs ككائن JSON واحد لكل سطر في ملف يومي يسمى
cdr_YYYYMMDD.json(التاريخ هو تاريخ الإصدار UTC). يتم فتح ملف جديد كل يوم UTC؛ لا يوجد تدوير تلقائي أو احتفاظ يتجاوز تقسيم اسم الملف اليومي، لذا قم بإخراج الملفات القديمة بنفسك. - كل جلسة تم تحريرها تضيف بالضبط CDR واحد. تحتفظ الجلسات الجارية باستخدامها في العامل / السياق حتى التحرير؛ لا يتم كتابتها إلى الملف حتى ذلك الحين.
إذا كان offline_charging_enabled هو false، لا تزال CDRs تُبنى وتُسجل في INFO كـ CHF CDR: %{...}؛ يتم تخطي كتابة الملف فقط. لالتقاط CDRs بدون إخراج ملف، قم بشحن تلك الأسطر المسجلة مع خط أنابيب السجل الخاص بك. انظر CDRs مفقودة من الملفات غير المتصلة.
تحديد موقع والبحث عن CDRs
تقوم واجهة إدارة API بتعريض GET /api/oam/cdr للبحث في ملفات CDR المكتوبة. تقرأ كل ملف cdr_*.json تحت cdr_output_dir وتقوم بتصفية المعلمات الاستعلام المقدمة (جميعها اختيارية، مجمعة مع AND):
| معلمة الاستعلام | تطابق | التنسيق |
|---|---|---|
supi | CDR supi بالضبط | مثل imsi-999700000000001 |
dnn | CDR dnn بالضبط | مثل internet |
date_from | تاريخ ملف CDR >= هذا التاريخ | YYYY-MM-DD (الشرطات اختيارية) |
date_to | تاريخ ملف CDR <= هذا التاريخ | YYYY-MM-DD (الشرطات اختيارية) |
تُطبق عوامل تصفية التاريخ على تاريخ اسم الملف، وليس على طوابع زمنية السجلات الفردية، لذا يتم تضمين أو استبعاد الملف بالكامل ليوم واحد كوحدة. بدون معلمات، ترجع نقطة النهاية كل CDR على القرص. نظرًا لأنها تقرأ الملفات، فإن GET /api/oam/cdr ترجع السجلات فقط عندما كان offline_charging_enabled مفعلًا عند وقت الإصدار.
تفريغ CDR بالقوة (OAM)
في التشغيل العادي، يتم إنتاج CDR فقط عندما يتم تحرير جلسة. يتيح POST /api/oam/cdr/flush لمشغل إصدار CDR مبكرًا لأي جلسة حية (انظر تخزين الجلسة ورؤية الإدارة)، على سبيل المثال لإغلاق الجلسات التي لم يحررها المستهلك أبدًا:
| جسم الطلب | التأثير |
|---|---|
{"charging_data_ref": "<ref>"} | بناء وكتابة CDR لتلك الجلسة الواحدة، ثم إنهائها. 404 إذا لم يتم العثور على المرجع. |
{} أو {"charging_data_ref": "all"} | تفريغ كل جلسة يتم تتبعها حاليًا. |
يبني التفريغ CDR من الاستخدام المتراكم للجلسة بالإضافة إلى آخر ChargingDataRequest ويعيد استخدام نفس كاتب CDR كالإفراج؛ لا يستدعي TerminateSession من CGRateS. تقارير الاستجابة write_result و offline_charging_enabled لكل جلسة. إذا كان الشحن غير المتصل معطلاً، يتم بناء CDR ويتم إنهاء الجلسة، ولكن لا يتم كت��بة أي شيء إلى الملف (write_result: "ok" بدون إخراج ملف). كل تفريغ يزيد من omni_chf_charging_releases_total{result="oam_flush"}.