WWill Greenbergapply review feedback
787d589f创建于 9月17日历史提交
use chrono::{DateTime, FixedOffset};

use telcom_parser::lte_rrc::{BCCH_DL_SCH_MessageType, BCCH_DL_SCH_MessageType_c1};

use super::analyzer::{Analyzer, AnalyzerMetadata, Event, EventType};
use super::information_element::{InformationElement, LteInformationElement};
use deku::bitvec::*;

pub struct TestAnalyzer {}

impl Analyzer for TestAnalyzer {
    fn metadata() -> AnalyzerMetadata {
        AnalyzerMetadata {
            key: "test_analyzer".into(),
            default_enabled: false,
            name: "Test Analyzer".into(),
            description: "This is an analyzer which can be used to test that your rayhunter \
                         is working. It will generate an alert for every SIB1 message \
                         (a beacon from the cell tower) that it sees. Do not leave this on \
                         when you are hunting or it will be very noisy."
                .into(),
            version: 1,
        }
    }

    fn analyze_information_element(
        &mut self,
        ie: &InformationElement,
        _packet_num: usize,
        _timestamp: DateTime<FixedOffset>,
    ) -> Option<Event> {
        if let InformationElement::LTE(lte_ie) = ie
            && let LteInformationElement::BcchDlSch(sch_msg) = &**lte_ie
            && let BCCH_DL_SCH_MessageType::C1(c1) = &sch_msg.message
            && let BCCH_DL_SCH_MessageType_c1::SystemInformationBlockType1(sib1) = c1
        {
            let cid = sib1
                .cell_access_related_info
                .cell_identity
                .0
                .as_bitslice()
                .load_be::<u32>();
            let tac = sib1
                .cell_access_related_info
                .tracking_area_code
                .0
                .as_bitslice()
                .load_be::<u32>();
            let plmn = &sib1.cell_access_related_info.plmn_identity_list.0;
            let mcc_string: String;

            // MCC are always 3 digits
            if let Some(mcc) = &plmn[0].plmn_identity.mcc {
                mcc_string = format!("{}{}{}", mcc.0[0].0, mcc.0[1].0, mcc.0[2].0);
            } else {
                mcc_string = "nomcc".to_string();
            }
            let mnc = &plmn[0].plmn_identity.mnc;

            // MNC can be 2 or 3 digits
            let mnc_string: String = if mnc.0.len() == 3 {
                format!("{}{}{}", mnc.0[0].0, mnc.0[1].0, mnc.0[2].0)
            } else if mnc.0.len() == 2 {
                format!("{}{}", mnc.0[0].0, mnc.0[1].0)
            } else {
                format!("{:?}", mnc.0)
            };

            return Some(Event {
                event_type: EventType::Low,
                message: format!(
                    "SIB1 received CID: {}, TAC: {}, PLMN: {}-{}",
                    cid, tac, mcc_string, mnc_string
                ),
            });
        }
        None
    }
}