دليل عمليات OmniCHF
جدول المحتويات
- نظرة عامة على المكونات
- دور 3GPP والمراجع الفنية
- نقاط نهاية SBI
- مرجع التكوين
- الإجراءات الرئيسية
- المراقبة
- القيود المعروفة
- استكشاف الأخطاء وإصلاحها
نظرة عامة على المكونات
يطبق OmniCHF وظيفة الشحن (CHF) المعرفة في 3GPP TS 32.291. توفر CHF شحنًا متقاربًا عبر الإنترنت وغير المتصل لجلسات PDU 5G عبر خدمة Nchf_ConvergedCharging. يقوم بتحويل طلبات الشحن 5G إلى استدعاءات JSON-RPC لـ CGRateS SessionS لتفويض الائتمان وإدارة الجلسات، وينتج سجلات تفاصيل المكالمات (CDRs) عند إنهاء الجلسة.
دورة حياة جلسة الشحن
تتوافق كل جلسة PDU مع جلسة شحن واحدة، يتم تتبعها بواسطة chargingDataRef (UUID). يتم الاحتفاظ بحالة الجلسة في وكيل في الذاكرة ولا يتم الاحتفاظ بها. يؤدي إعادة التشغيل إلى فقدان جميع حالات الجلسات النشطة.
| الحالة | الزناد | إجراء التخزين |
|---|---|---|
| تم الإنشاء | POST /chargingdata | تم إنشاء السياق، تم استدعاء CGRateS InitiateSession |
| تم التحديث | POST /chargingdata/:ref/update | تم تحديث السياق (تم تجميع الاستخدام، تم زيادة التسلسل) |
| تم الإفراج | POST /chargingdata/:ref/release | تم بناء CDR وتسجيله، تم استدعاء CGRateS TerminateSession، تم حذف السياق |
دور 3GPP والمراجع الفنية
| العنصر | المرجع |
|---|---|
| تعريف NF CHF | 3GPP TS 23.501 القسم 6.2.16 |
| خدمة Nchf_ConvergedCharging | 3GPP TS 32.291 |
| إجراء إنشاء بيانات الشحن | 3GPP TS 32.291 القسم 6.1.3.2.1 |
| إجراء تحديث بيانات الشحن | 3GPP TS 32.291 القسم 6.1.3.2.2 |
| إجراء إفراج بيانات الشحن | 3GPP TS 32.291 القسم 6.1.3.2.3 |
| نموذج بيانات ChargingDataRequest / Response | 3GPP TS 32.291 القسم 6.1.6 |
| تنسيق CDR لجلسات PDU 5G | 3GPP TS 32.290 |
| إطار عمل SBI المشترك | 3GPP TS 29.500 |
| تسجيل NF مع NRF | 3GPP TS 29.510 |
نقاط نهاية SBI
مسار القاعدة: /nchf-convergedcharging/v3
| الطريقة | المسار | الوصف | النجاح | الخطأ |
|---|---|---|---|---|
POST | /chargingdata | إنشاء جلسة شحن (طلب أولي). يخصص chargingDataRef، يبدأ جلسة CGRateS، ويعيد الوحدات الممنوحة. | 201 تم الإنشاء مع رأس Location | 500 خطأ في الخادم الداخلي |
POST | /chargingdata/{chargingDataRef}/update | تحديث جلسة شحن (طلب مؤقت). يبلغ عن الاستخدام الحالي ويطلب ائتمانًا إضافيًا. | 200 حسنًا | 404 غير موجود، 500 خطأ في الخادم الداخلي |
POST | /chargingdata/{chargingDataRef}/release | إفراج عن جلسة شحن (طلب نهائي). يبلغ عن الاستخدام النهائي، ينتج CDR، ينهي جلسة CGRateS. | 204 لا محتوى | 404 غير موجود، 500 خطأ في الخادم الداخلي |
ChargingDataRequest — الحقول الرئيسية
| الحقل | النوع | مستخدم في | الوصف |
|---|---|---|---|
subscriberIdentifier | string | إنشاء، تحديث، إفراج | SUPI (على سبيل المثال، imsi-999700000000001). يستخدم كمعرف حساب CGRateS. |
nfConsumerIdentification | object | إنشاء | معلومات مستهلك NF. مصدر احتياطي لـ SUPI إذا كان subscriberIdentifier غائبًا. |
pDUSessionChargingInformation | object | إنشاء، تحديث، إفراج | تفاصيل جلسة PDU: DNN، S-NSSAI، نوع RAT، QoS، معرف ونوع جلسة PDU. |
multipleUnitUsage | array | تحديث، إفراج | حاويات الاستخدام المبلغ عنها. يتم استخدام usedUnitContainer لعنصر الأول لاستخراج الحجم والمدة. |
requestType | string | الكل | INITIAL_REQUEST، UPDATE_REQUEST، أو TERMINATION_REQUEST. |
ChargingDataResponse — الحقول الرئيسية
| الحقل | النوع | موجود | الوصف |
|---|---|---|---|
invocationSequenceNumber | integer | إنشاء، تحديث | رقم التسلسل لهذه الاستجابة. ثابت على 1 عند الإنشاء (انظر CHF-M1). يتم زيادته في كل تحديث. |
invocationResult | object | إنشاء، تحديث | دائمًا {"resultCode": "SUCCESS"} في المسار السعيد. |
sessionId | string | إنشاء، تحديث | chargingDataRef (UUID) المخصص لهذه الجلسة. |
multipleUnitInformation | array | إنشاء، تحديث | الوحدات الممنوحة. تحتوي على إدخال واحد مع resultCode، grantedUnit (totalVolume، time)، وratingGroup (ثابت على 1، انظر CHF-L2). |
مرجع التكوين
يتم تعيين جميع المعلمات عبر بيئة التطبيق (عادةً config/runtime.exs).
config :omnichf,
sbi_scheme: "http",
sbi_addr: "127.0.0.14",
sbi_port: 7777,
nrf_uri: "http://127.0.0.10:7777",
mcc: "999",
mnc: "70",
heartbeat_interval: 10_000,
cgrates_enabled: false,
cgrates_url: "http://localhost:2080/jsonrpc",
cgrates_tenant: "cgrates.org",
cgrates_timeout: 5000
جدول المعلمات
| المعلمة | الافتراضي | النوع | الوصف |
|---|---|---|---|
sbi_scheme | "http" | string | مخطط النقل لمستمع SBI. |
sbi_addr | "127.0.0.14" | string | عنوان IP الذي يرتبط به خادم HTTP SBI. |
sbi_port | 7777 | integer | منفذ TCP الذي يستمع عليه خادم HTTP SBI. |
nrf_uri | "http://127.0.0.10:7777" | string | URI الأساسي لـ NRF المستخدم لتسجيل NF وheartbeat. |
mcc | "999" | string | رمز الدولة المحمول. يستخدم في ملف NF المقدم إلى NRF وفي اسم الشبكة الخدمية. |
mnc | "70" | string | رمز الشبكة المحمولة. يستخدم في ملف NF المقدم إلى NRF وفي اسم الشبكة الخدمية. |
heartbeat_interval | 10_000 | integer (ms) | الفاصل الزمني بين طلبات heartbeat NRF. |
cgrates_enabled | false | boolean | مفتاح رئيسي لتكامل CGRateS. عندما يكون false، يتم تخطي جميع استدعاءات CGRateS ويتم إرجاع منحة افتراضية قدرها 86,400 وحدة. يجب تعيينه إلى true في الإنتاج عند توفر مثيل CGRateS. |
cgrates_url | "http://localhost:2080/jsonrpc" | string | عنوان URL لنقطة نهاية JSON-RPC لمثيل CGRateS. يستخدم فقط عندما يكون cgrates_enabled هو true. |
cgrates_tenant | "cgrates.org" | string | اسم مستأجر CGRateS. يتم تمريره في جميع استدعاءات API SessionS كحقل Tenant. يجب أن يتطابق مع المستأجر المكون في CGRateS. |
cgrates_timeout | 5000 | integer (ms) | مهلة طلب HTTP لاستدعاءات JSON-RPC لـ CGRateS. تستخدم استدعاءات التحقق من الصحة min(cgrates_timeout, 3000) لتجنب حظر نقطة النهاية الصحية. |
ملاحظات تكامل CGRateS
عندما يكون cgrates_enabled هو false، يعمل OmniCHF في وضع التجاوز: يتم قبول جميع طلبات الشحن ومنح 86,400 وحدة (وقت أو حجم) دون أي تقييم أو تفويض. هذا مناسب للاختبار في المختبر والتكامل عندما لا يتوفر CGRateS.
تستخدم اتصالات CGRateS عميل HTTP المدمج في Erlang :httpc (انظر القيود CHF-M5). لا يدعم هذا العميل تجميع الاتصالات. تحت الحمل العالي، يفتح كل طلب CGRateS اتصال HTTP جديد ويغلقه، مما قد يصبح عنق زجاجة.
الإجراءات الرئيسية
إنشاء جلسة الشحن (الأولية)
تحديث جلسة الشحن (المؤقت)
إفراج عن جلسة الشحن (النهائي)
تخطيط أحداث CGRateS
يقوم OmniCHF بتخطيط حقول الشحن 5G إلى حقول أحداث CGRateS SessionS كما يلي:
| حقل CGRateS | المصدر | ملاحظات |
|---|---|---|
Account | subscriberIdentifier (SUPI) | يتراجع إلى nfConsumerIdentification.supi |
Subject | subscriberIdentifier (SUPI) | نفس الشيء كـ Account |
Destination | pduSessionInformation.dnnId أو .dnn | اسم الشبكة البيانات |
ToR | pduSessionInformation.pduType | دائمًا *data لجلسات PDU |
RequestType | requestType | دائمًا يتم تخطيطه إلى *prepaid |
Usage | usedUnitContainer.totalVolume أو مجموع uplink+downlink أو time | أول قيمة غير صفرية تفوز |
OriginID | chargingDataRef | UUID فريد لكل جلسة |
OriginHost | ثابت "OmniCHF" | |
SUPI | subscriberIdentifier | حقل امتداد 5G |
DNN | pduSessionInformation.dnnId | حقل امتداد 5G |
S-NSSAI_SST | pduSessionInformation.sNSSAI.sst | حقل امتداد 5G |
S-NSSAI_SD | pduSessionInformation.sNSSAI.sd | حقل امتداد 5G |
5QI | pduSessionInformation.qoSInformation.5qI | حقل امتداد 5G |
RATType | pduSessionInformation.ratType | الافتراضي: "NR" |
PDUSessionID | pduSessionInformation.pduSessionID | حقل امتداد 5G |
PDUSessionType | pduSessionInformation.pduType | الافتراضي: "IPV4" |
حقول CDR
يتم بناء CDRs عند الإفراج عنها ويتم إصدارها إلى سجل التطبيق على مستوى INFO. تحتوي خريطة CDR على:
| الحقل | المصدر |
|---|---|
record_type | ثابت: "5G_PDU_SESSION" |
supi | سياق الشحن |
dnn | pduSessionInformation.dnnId أو .dnn |
snssai | {sst, sd} من pduSessionInformation.sNSSAI |
qos_5qi | pduSessionInformation.qoSInformation.5qI |
rat_type | pduSessionInformation.ratType |
pdu_session_id | سياق الشحن |
pdu_session_type | pduSessionInformation.pduType |
volume_uplink | usedUnitContainer.uplinkVolume |
volume_downlink | usedUnitContainer.downlinkVolume |
volume_total | usedUnitContainer.totalVolume (أو uplink+downlink) |
duration | usedUnitContainer.time (أو فرق الساعة إذا كانت صفر) |
start_time | طابع زمني created_at للجلسة |
end_time | الساعة عند وقت الإفراج |
charging_data_ref | UUID للجلسة |
المراقبة
أحداث القياس
| الحدث | القياسات | العلامات | الوصف |
|---|---|---|---|
[:omnichf, :charging, :initial] | count | supi | يتم إطلاقه في كل طلب إنشاء |
[:omnichf, :charging, :update] | count | ref | يتم إطلاقه في كل طلب تحديث |
[:omnichf, :charging, :release] | count | ref | يتم إطلاقه في كل طلب إفراج |
[:omnichf, :charging, :creates] | count | result (success/failure) | نتيجة عملية الإنشاء |
[:omnichf, :charging, :updates] | count | result | نتيجة عملية التحديث |
[:omnichf, :charging, :releases] | count | result | نتيجة عملية الإفراج |
[:omnichf, :cgrates, :request] | count, duration_ms | operation, result | لكل استدعاء JSON-RPC لـ CGRateS |
[:omnichf, :cgrates, :health] | status (1/0) | — | صحة الاتصال بـ CGRateS |
[:omnichf, :sessions, :active] | count | — | مقياس: الجلسات النشطة للشحن |
[:omni5g, :nrf, :registration] | status (1/0) | nf_type | حالة تسجيل NRF |
مقاييس Prometheus
مقاييس الشحن
| المقياس | النوع | العلامات | الوصف |
|---|---|---|---|
omni_chf.charging.initial.count | counter | supi | إنشاء جلسات الشحن |
omni_chf.charging.update.count | counter | ref | تحديث جلسات الشحن |
omni_chf.charging.release.count | counter | ref | إفراج عن جلسات الشحن |
omni_chf.charging.creates.total | counter | result | إجمالي إنشاء جلسات الشحن |
omni_chf.charging.updates.total | counter | result | إجمالي تحديث جلسات الشحن |
omni_chf.charging.releases.total | counter | result | إجمالي إفراج عن جلسات الشحن |
omni_chf.sessions.active.count | gauge | -- | عدد جلسات الشحن النشطة |
مقاييس CGRateS
| المقياس | النوع | العلامات | الوصف |
|---|---|---|---|
omni_chf.cgrates.calls.count | counter | method, result | استدعاءات JSON-RPC لـ CGRateS |
omni_chf.cgrates.latency.milliseconds | gauge | -- | زمن استجابة استدعاء CGRateS |
omni_chf.cgrates.health | gauge | -- | صحة الاتصال بـ CGRateS (1=متصل، 0=غير متصل) |
omni_chf.cgrates.requests.total | counter | operation, result | إجمالي طلبات JSON-RPC لـ CGRateS |
omni_chf.cgrates.request.duration_ms | distribution | operation | مدة طلب CGRateS بالمللي ثانية (الأقسام: 5، 10، 25، 50، 100، 250، 500، 1000، 2500) |
مقاييس NRF
| المقياس | النوع | العلامات | الوصف |
|---|---|---|---|
omni_chf.nrf.registration.status | gauge | nf_type | حالة تسجيل NRF (1=مسجل، 0=غير مسجل) |
مقاييس BEAM VM
| المقياس | النوع | الوصف |
|---|---|---|
beam.memory.total | gauge | إجمالي ذاكرة BEAM بالبايت |
beam.memory.processes | gauge | الذاكرة المستخدمة من قبل عمليات Erlang |
beam.memory.processes_used | gauge | الذاكرة المستخدمة فعليًا من قبل العمليات |
beam.memory.system | gauge | ذاكرة النظام |
beam.memory.atom | gauge | إجمالي ذاكرة الذرات |
beam.memory.atom_used | gauge | ذاكرة الذرات المستخدمة |
beam.memory.binary | gauge | ذاكرة ثنائية |
beam.memory.code | gauge | ذاكرة الشيفرة |
beam.memory.ets | gauge | ذاكرة جدول ETS |
beam.processes.count | gauge | عدد عمليات Erlang |
beam.ports.count | gauge | عدد منافذ Erlang |
beam.atom.count | gauge | عدد الذرات |
beam.vm.uptime | gauge | وقت تشغيل VM بالثواني |
أنماط السجل
| المستوى | النمط | المعنى |
|---|---|---|
info | CHF Create: ref=<UUID> supi=<SUPI> pdu_session=<N> | تم بدء إنشاء ناجح |
info | CHF Update: ref=<UUID> | تم استلام طلب التحديث |
info | CHF Release: ref=<UUID> | تم استلام طلب الإفراج |
info | CHF CDR: %{...} | تم إصدار CDR عند الإفراج |
info | Initiating CGRateS session for <ref>, account: <SUPI> | تم إرسال CGRateS InitiateSession |
info | CGRateS authorized <N> units for session <ref> | تم منح الائتمان |
info | CGRateS session <ref> terminated successfully | تم إنهاء CGRateS TerminateSession بنجاح |
warning | CGRateS integration disabled, returning default authorization | وضع التجاوز نشط |
warning | CHF Update: unknown ref=<UUID> | تحديث لجلسة غير موجودة |
warning | CHF Release: unknown ref=<UUID> | إفراج لجلسة غير موجودة |
error | CHF Create failed: <reason> | فشل عملية الإنشاء |
error | CHF Update failed: <reason> | فشل عملية التحديث |
error | CGRateS InitiateSession failed for <ref>: <reason> | خطأ CGRateS عن�� الإنشاء |
error | CGRateS HTTP error <status>: <body> | غير 200 من CGRateS |
error | CGRateS HTTP request failed: <reason> | خطأ في الشبكة إلى CGRateS |
القيود المعروفة
| المعرف | الشدة | الوصف |
|---|---|---|
| CHF-M1 | متوسط | invocationSequenceNumber ثابت على 1 في استجابة الإنشاء (الأولية). وفقًا لـ TS 32.291 يجب أن يبدأ رقم التسلسل من 1 ويزداد في الاستجابات اللاحقة، وهو ما يحدث في التحديث. المشكلة هي أنه إذا أرسل مستهلك إنشاء مع invocationSequenceNumber في الطلب، فإن تلك القيمة لا يتم فحصها أو التحقق منها. |
| CHF-M3 | متوسط | invocationTimeStamp غائب من ChargingDataResponse. وفقًا لـ TS 32.291، هذا الحقل إلزامي في جسم الاستجابة. سيحصل المستهلكون الصارمون الذين يتطلبون هذا الحقل على استجابة غير مكتملة. |
| CHF-M5 | متوسط | يستخدم عميل CGRateS عميل HTTP :httpc في Erlang بدلاً من Finch. لا يدعم :httpc تجميع الاتصالات؛ يفتح كل استدعاء JSON-RPC اتصال TCP جديد ويغلقه. تحت الحم�� (العديد من جلسات الشحن المتزامنة)، ستزداد زمن استجابة استدعاءات CGRateS وتصبح تكاليف إعداد الاتصال كبيرة. راقب omni_chf.cgrates.request.duration_ms. |
| CHF-L1 | منخفض | لا يتم تضمين حقل triggers في ChargingDataResponse. وفقًا لـ TS 32.291، يمكن أن instruct SMF لإرسال تحديث مؤقت عند أحداث معينة (حد حجم، حد زمن، تغيير QoS). بدون المحفزات، يستخدم SMF سياسته المحلية لتحديد متى يجب إرسال التحديثات. |
| CHF-L2 | منخفض | ratingGroup في multipleUnitInformation ثابت على 1. عادةً ما تحتوي النشر الفعلي على مجموعات تقييم متعددة لكل جلسة PDU (واحدة لكل تدفق بيانات خدمة). يتم نسب جميع الاستخدامات إلى مجموعة التقييم 1 بغض النظر عن قيم ratingGroup في multipleUnitUsage في الطلب. |
| CHF-L3 | منخفض | لا يتم إنشاء chargingId في تنسيق 3GPP. وفقًا لـ TS 32.290، يجب أن تحمل سجلات الشحن chargingId الذي يتوافق مع معرف جلسة PDU المعين بواسطة SMF. يتم استخدام UUID charging_data_ref بدلاً من ذلك، مما قد يسبب مشاكل في الارتباط في أنظمة الفوترة السفلية التي تتوقع تنسيق chargingId 3GPP. |
| CHF-L4 | منخفض | سجل CDR مفقود الحقول chargingID وrecordingEntity المطلوبة من قبل TS 32.290. ستحتاج أنظمة الوساطة أو الفوترة السفلية التي تتوقع هذه الحقول إلى تحمل غيابها أو تكوينها لتعتبرها اختيارية. |
| CHF-L5 | منخفض | لم يتم تنفيذ الشحن غير المتصل وإخراج ملف CDR. يتم إصدار CDRs فقط إلى سجل التطبيق عبر Logger.info. لا يوجد إخراج CDR قائم على الملفات، ولا ترميز ASN.1، ولا نقل إلى بوابة مجال الفوترة. من أجل الشحن غير المتصل في الإنتاج، يجب على شاحن السجل (مثل Fluentd، Vector) جمع خطوط سجل CDR لـ CHF وتحويلها لنظام الفوترة. |
استكشاف الأخطاء وإصلاحها
404 عند التحديث أو الإفراج
لا يتطابق chargingDataRef مع أي جلسة نشطة في الذاكرة. الأسباب:
- تم إعادة تشغيل OmniCHF بين الإنشاء والتحديث/الإفراج - جميع حالات ا��جلسات في الذاكرة وتفقد عند إعادة التشغيل.
- أرسل SMF
chargingDataRefغير صحيح في المسار. - تم إرسال إفراج سابق عن هذه الجلسة، مما أدى إلى حذف السياق.
تحقق من السجلات لـ CHF Update: unknown ref= أو CHF Release: unknown ref= للتأكيد.
500 عند الإنشاء مع تمكين CGRateS
فشل استدعاء CGRateS. تحقق من:
- هل
cgrates_urlيشير إلى مثيل CGRateS يمكن الوصول إليه؟ - هل
cgrates_tenantصحيح؟ تسبب أسماء المستأجر غير المتطابقة في عودة CGRateS باستجابة خطأ. - تحقق من مقياس
omni_chf.cgrates.health(1=متصل، 0=غير متصل). - راجع السجلات لـ
CGRateS InitiateSession failed for <ref>: <reason>- ستكون السبب واحدًا من:{:cgrates_error, message}،{:http_error, status}، أو{:http_error, reason}. - تحقق من أن خدمة CGRateS
SessionSv1مفعلة في تكوين CGRateS.
فشل التحقق من صحة CGRateS ولكن الخدمة تعمل
يستخدم التحقق من الصحة (عبر SessionSv1.GetActiveSessions) مهلة محددة بـ 3 ثوانٍ. إذا كانت CGRateS بطيئة في الاستجابة، فقد يفشل التحقق من الصحة بينما تكون الخدمة متاحة تقنيًا. تحقق من cgrates_timeout - الحد هو min(cgrates_timeout, 3000). أيضًا تأكد من أن cgrates_url يستخدم HTTP (ليس HTTPS) ما لم يتم تكوين TLS.
عدم ظهور CDRs أو عدم اكتمالها
يتم كتابة CDRs إلى سجل التطبيق على مستوى INFO (انظر القيود CHF-L5). لالتقاط CDRs:
- تأكد من أن مستوى سجل التطبيق مضبوط على
infoأو أقل. - قم بتصفية خطوط السجل التي تحتوي على
"CHF CDR:"للمعالجة اللاحقة. - لاحظ أن CDRs تفتقر إلى
chargingID،recordingEntity(CHF-L4)، وستحتوي علىratingGroup: 1لجميع تدفقات بيانات الخدمة (CHF-L2).
ارتفاع زمن استجابة استدعاءات CGRateS
نظرًا لأن CGRateS يستخدم :httpc بدون تجميع الاتصالات (CHF-M5)، يزداد الزمن تحت الحمل. لتشخيص:
- تحقق من مخطط
omni_chf.cgrates.request.duration_msلزمن الاستجابة في النسبة المئوية 99. - إذا كان الزمن مرتفعًا تحت الحمل المتزام��، قلل من عدد جلسات الشحن المتزامنة أو اعتبر نشر OmniCHF خلف موازن تحميل مع عدة مثيلات.
- كحل مؤقت، قم بتعيين
cgrates_timeoutإلى قيمة أقل من الزمن المتوقع الأسوأ لاستجابة CGRateS لمنع استدعاءات CGRateS البطيئة من حظر مجموعة عمليات Elixir.
عدم انخفاض عدد الجلسات النشطة بعد الإفراج
إذا ظل omni_chf.sessions.active.count مرتفعًا بعد أن كان يجب الإفراج عن الجلسات:
- تحقق من استجابات 404 على استدعاءات الإفراج - إذا تلقى SMF 404، فقد لا يعيد المحاولة ويعتبر SMF الجلسة قد أفرج عنها بينما قد لا يزال لدى OmniCHF السياق.
- في الحالة العكسية، إذا أعيد تشغيل OmniCHF وفقد حالة الجلسة، فإن السياقات قد اختفت ولكن قد لا يزال SMF يرسل طلبات تحديث/إفراج تؤدي إلى 404. هذا سلوك متوقع.
عدم الحفاظ على تسجيل NRF
تحقق من مقياس omni_chf.nrf.registration.status. إذا كان يقرأ 0:
- تحقق من أن
nrf_uriصحيح وأن NRF يمكن الوصول إليه منsbi_addrلـ OmniCHF. - تحقق من أن
mccوmncيتطابقان مع تكوين PLMN الخاص بـ NRF. - راجع سجلات التطبيق عند بدء التشغيل للبحث عن أخطاء تسجيل NRF.