Загрузка данных
Привет, Саша! Ты проделал огромную работу, собрав все эти фрагменты из разных документаций. Ты абсолютно прав, что разрозненные инструкции часто сбивают с толку — в них не хватает связующих звеньев (например, как именно "подружить" капризный OAI gNB с Open5GS, как настроить сетевые интерфейсы и что именно вводить в телефон).
Как человек, который изучает системное программирование и понимает, как работают низкоуровневые процессы (ты же разбираешься в event loops и C!), ты легко поймешь архитектуру. Но чтобы всё заработало **с первого раза**, нужно учесть множество нюансов. OAI (OpenAirInterface) очень требователен к параметрам 3GPP, а USRP B200 чувствителен к USB-шине.
Ниже — **максимально подробное, исчерпывающее руководство (Master Guide)**, которое объединяет всё, что ты нашел, и добавляет недостающие шаги. Мы будем использовать тестовый PLMN **999/70** (как в твоих конфигах).
---
### ЭТАП 0: Требования и подготовка "железа"
1. **ПК/Сервер:** Ubuntu 22.04 LTS (это критично, на 24.04 OAI и Open5GS могут иметь конфликты зависимостей). Минимум 16 ГБ ОЗУ, 4 ядра CPU.
2. **USRP B200:** Подключается **строго в USB 3.0** (синий порт). Желательно использовать кабель длиной не более 1-1.5 метров.
3. **SIM-карта:** Программируемая (например, sysmoISIM-SJA2).
4. **Телефон (COTS UE):** Android с модемом Snapdragon (Samsung S22/S23, Xiaomi 12/13 и новее). **iPhone не рекомендуется** — Apple жестко режет функционал для приватных сетей.
---
### ЭТАП 1: Программирование SIM-карты (pySim)
Ты уже нашел правильные инструкции. Давай их зафиксируем.
*Предполагаем, что у тебя есть программатор (например, Omnikey) и Python 3.9+.*
1. Установи зависимости и pySim (как в твоем тексте).
2. Вставь SIM в программатор, проверь, что она видна:
```bash
pcsc_scan
```
3. Запиши данные. **Важно:** Ключи `Ki` и `OPc` должны быть записаны на SIM и **точно так же** введены в Open5GS WebUI позже.
```bash
./pySim-prog.py -n "Test5G" -p 0 -x 999 -y 70 -t sysmoISIM-SJA2 -i 999700000000001 -o <твой_OPc> -k <твой_Ki> -s 8900000000000000001 -a 00000000
```
*(Замени `<твой_OPc>` и `<твой_Ki>` на реальные hex-значения. ADM поставь `00000000` или `12345678`, но **запомни его**, чтобы не заблокировать SIM!)*
---
### ЭТАП 2: Установка и настройка Open5GS (Ядро сети)
Open5GS хранит данные абонентов в MongoDB. Его нужно установить первым.
#### 2.1. Установка MongoDB
```bash
sudo apt update
sudo apt install -y gnupg
curl -fsSL https://pgp.mongodb.com/server-8.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
sudo apt update
sudo apt install -y mongodb-org
sudo systemctl start mongod
sudo systemctl enable mongod
```
#### 2.2. Установка Open5GS и WebUI
```bash
sudo add-apt-repository ppa:open5gs/latest
sudo apt update
sudo apt install -y open5gs
# Установка Node.js для WebUI
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# Установка самого WebUI
curl -fsSL https://open5gs.org/open5gs/assets/webui/install | sudo -E bash -
```
#### 2.3. Создание виртуального сетевого интерфейса (ogstun)
Ядро должно куда-то маршрутизировать трафик телефона в интернет.
```bash
sudo ip tuntap add name ogstun mode tun
sudo ip addr add 10.45.0.1/16 dev ogstun
sudo ip link set ogstun mtu 1400 # Важно для избежания фрагментации
sudo ip link set ogstun up
```
*Чтобы интерфейс создавался после перезагрузки, добавь эти команды в `/etc/rc.local` или создай systemd-сервис.*
#### 2.4. Настройка NAT (чтобы телефон вышел в Интернет)
```bash
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE
```
#### 2.5. Конфигурация Open5GS (Самое важное для связки с OAI!)
OAI gNB очень капризен. Он ожидает четкого соответствия параметрам. Открываем файлы и редактируем.
**Файл `/etc/open5gs/amf.yaml`** (Убедись, что выглядит так):
```yaml
amf:
sbi:
server:
- address: 127.0.0.5
port: 7777
ngap:
server:
- address: 127.0.0.5
guami:
- plmn_id:
mcc: 999
mnc: 70
amf_id:
region: 2
set: 1
tai:
- plmn_id:
mcc: 999
mnc: 70
tac: 1
plmn_support:
- plmn_id:
mcc: 999
mnc: 70
s_nssai:
- sst: 1
sd: ffffff # OAI часто требует явного указания SD
security:
integrity_order : [ NIA2, NIA1, NIA0 ]
ciphering_order : [ NEA0, NEA1, NEA2 ]
```
**Файл `/etc/open5gs/smf.yaml`** (Проверь DNN):
```yaml
smf:
sbi:
server:
- address: 127.0.0.4
port: 7777
pfcp:
server:
- address: 127.0.0.4
session:
- subnet: 10.45.0.0/16
dnn: internet
```
**Файл `/etc/open5gs/upf.yaml`**:
```yaml
upf:
pfcp:
server:
- address: 127.0.0.7
gtpu:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.0/16
```
Перезапускаем ядро:
```bash
sudo systemctl restart open5gs-amfd open5gs-smfd open5gs-upfd open5gs-nrfd open5gs-ausfd open5gs-udmd open5gs-pcfd open5gs-nssfd open5gs-bsfd open5gs-udrd
```
#### 2.6. Регистрация абонента в WebUI
1. Открой браузер: `http://localhost:9999` (admin / 1423).
2. Перейди в **Subscriber** -> нажми **(+)**.
3. Заполни:
* **IMSI:** `999700000000001`
* **K и OPc:** Впиши ровно те же hex-значения, что зашил в SIM на Этапе 1!
* **APN/DNN:** `internet`
* **Slice (S-NSSAI):** SST: `1`, SD: `ffffff`
4. Нажми **SAVE**.
---
### ЭТАП 3: Сборка OpenAirInterface (gNB)
#### 3.1. Установка UHD (Драйвер для USRP)
Не собирай UHD из исходников, если не хочешь тратить 2 часа. В Ubuntu 22.04 есть готовые пакеты, которых хватит для B200.
```bash
sudo apt install -y software-properties-common
sudo add-apt-repository -y ppa:ettusresearch/uhd
sudo apt update
sudo apt install -y libuhd-dev uhd-host
# Обязательно скачай прошивки для USRP (займет время)!
sudo uhd_images_downloader
```
*Проверь, что USRP виден:* Подключи B200 и выполни `uhd_find_devices`. Ты должен увидеть строку с `name=B200...`.
#### 3.2. Сборка OAI gNB
```bash
sudo apt install -y git cmake build-essential ninja-build python3-pip libboost-all-dev libusb-1.0-0-dev libssl-dev libxml2-dev libxslt1-dev
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g
git checkout develop
cd cmake_targets
./build_oai -I --install-optional-packages -w USRP -C # Установка зависимостей
./build_oai --gNB -w USRP -C # Компиляция RAN
```
#### 3.3. Конфигурация gNB (Магия связки с Open5GS)
Создай файл конфига `~/openairinterface5g/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.51prb.usrpb200.conf`.
**Внимание:** OAI использует старый синтаксис `.conf`, а не `.yaml`. Скопируй этот конфиг целиком, он уже настроен на работу с твоим Open5GS на локальной машине:
```conf
Active_gNBs = ( "gNB-open5gs");
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-open5gs";
tracking_area_code = 1;
plmn_list = ({ mcc = 999; mnc = 70; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
nr_cellid = 12345678L;
////////// Physical parameters:
servingCellConfigCommon = (
{
physCellId = 0;
absoluteFrequencySSB = 640704;
dl_frequencyBand = 78;
dl_absoluteFrequencyPointA = 639996;
dl_offstToCarrier = 0;
dl_subcarrierSpacing = 1; # 30 kHz
dl_carrierBandwidth = 51;
initialDLBWPlocationAndBandwidth = 13750;
initialDLBWPsubcarrierSpacing = 1;
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
ul_frequencyBand = 78;
ul_offstToCarrier = 0;
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 51;
pMax = 20;
initialULBWPlocationAndBandwidth = 13750;
initialULBWPsubcarrierSpacing = 1;
prach_ConfigurationIndex = 98;
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -96;
preambleTransMax = 6;
powerRampingStep = 1;
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
msg1_SubcarrierSpacing = 1;
restrictedSetConfig = 0;
msg3_DeltaPreamble = 1;
p0_NominalWithGrant = -90;
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
ssb_PositionsInBurst_Bitmap = 1;
ssb_periodicityServingCell = 2;
dmrs_TypeA_Position = 0;
subcarrierSpacing = 1;
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
});
SCTP : { SCTP_INSTREAMS = 2; SCTP_OUTSTREAMS = 2; };
////////// AMF parameters:
amf_ip_address = ({ ipv4 = "127.0.0.5"; });
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_NG_AMF = "127.0.0.1";
GNB_IPV4_ADDRESS_FOR_NGU = "127.0.0.1";
GNB_PORT_FOR_S1U = 2152;
};
}
);
MACRLCs = ( { num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; } );
L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; prach_dtx_threshold = 120; pucch0_dtx_threshold = 100; } );
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 10;
att_rx = 10;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
clock_src = "internal";
}
);
security = {
ciphering_algorithms = ( "nea0" );
integrity_algorithms = ( "nia2", "nia0" );
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config : {
global_log_level = "info";
hw_log_level = "info";
phy_log_level = "info";
mac_log_level = "info";
rlc_log_level = "info";
pdcp_log_level = "info";
rrc_log_level = "info";
ngap_log_level = "debug";
};
```
*Обрати внимание на `NETWORK_INTERFACES`: мы жестко задали `127.0.0.1`, так как ядро и RAN на одной машине. Это избавит от проблем с маршрутизацией.*
---
### ЭТАП 4: Запуск сети (Порядок критичен!)
Открой **три терминала**.
**Терминал 1: Логи ядра (чтобы видеть, что происходит)**
```bash
sudo journalctl -u open5gs-amfd -f
```
**Терминал 2: Запуск gNB (OAI)**
```bash
cd ~/openairinterface5g/cmake_targets/ran_build/build
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.51prb.usrpb200.conf --sa -E --continuous-tx
```
*Жди, пока в логах не появится строка:* `[NR_RRC] eNB connected to AMF` или `NGAP: Connection established`. Это значит, что RAN "постучалась" в ядро.
---
### ЭТАП 5: Подключение COTS UE (Телефона)
Это этап, на котором 90% людей сдаются. Телефон не хочет подключаться, потому что думает, что это "чужая" сеть.
1. **Вставь SIM-карту** в телефон.
2. **Настройки мобильной сети:**
* **Точка доступа (APN):** Создай новую. Имя: `internet`, APN: `internet`. Остальное оставь пустым. Сохрани и выбери её.
* **Роуминг:** **ОБЯЗАТЕЛЬНО включи "Роуминг данных" (Data Roaming)**. Так как PLMN 999/70 не является домашним для телефона, без роуминга ядро отвергнет регистрацию.
* **Тип сети:** Выбери "Только 5G" (или 5G SA). Отключи 4G/LTE.
3. **Инженерное меню (Если телефон не видит сеть):**
* На Samsung: `*#0011#` (просмотр) или `*#2263#` (настройка). Тебе нужно принудительно выбрать Band 78 (n78).
* На Xiaomi/Android: `*#*#4636#*#*` -> Phone Information -> Set Preferred Network Type -> **5G NR Only**.
4. **Отключи VoLTE и VoNR** в настройках телефона (если есть такая галочка). Голосовые сервисы в приватных сетях часто вызывают сбой регистрации.
5. **Включи и выключи Авиарежим**, чтобы заставить модем пересканировать эфир.
---
### ЭТАП 6: Диагностика и решение проблем
Поднеси телефон вплотную к антеннам USRP. Смотри в **Терминал 1** (логи AMF).
**Сценарий А: Телефон видит сеть, но не регистрируется (ошибка Authentication Failure)**
* **Причина:** Не совпадают ключи.
* **Решение:** Зайди в WebUI Open5GS (`localhost:9999`) и перепроверь, что `Ki` и `OPc` побуквенно совпадают с тем, что ты зашил в SIM через pySim.
**Сценарий Б: В логах AMF видно `Registration Reject`, причина `#11` (PLMN not allowed) или `#13` (Roaming not allowed)**
* **Причина:** Телефон не пускает в сеть из-за политик роуминга.
* **Решение:** Убедись, что в настройках телефона включен **Роуминг данных**. В конфиге `amf.yaml` убедись, что нет секции `access_control`, которая блокирует PLMN 999/70.
**Сценарий В: В логах OAI gNB сыплются ошибки `O` (Overflows) или `U` (Underflows)**
* **Причина:** USRP B200 не успевает передавать данные по USB 3.0.
* **Решение:**
1. Убедись, что USRP воткнут напрямую в порт USB 3.0 на материнской плате (не через хаб, не через переднюю панель корпуса).
2. В конфиге OAI уменьши количество PRB с 51 до 25 или 11 (измени `dl_carrierBandwidth` и `ul_carrierBandwidth`, а также `initialDLBWPlocationAndBandwidth`).
3. Увеличь буфер USB: `sudo sysctl -w net.core.rmem_max=62500000` и `sudo sysctl -w net.core.wmem_max=62500000`.
**Сценарий Г: Телефон зарегистрировался (в логах AMF: `Registration Accept`), но интернет не работает (пинг не идет)**
* **Причина:** Проблема с NAT или UPF.
* **Решение:** Проверь, что интерфейс `ogstun` поднят (`ip a s ogstun`). Проверь, что в `upf.yaml` указан правильный `subnet: 10.45.0.0/16`. Убедись, что на хосте включен `ip_forward=1`.
---
### Финальная проверка
Если всё прошло успешно:
1. В терминале OAI ты увидишь: `[RRC] UE rnti=xxxx has entered RRC_CONNECTED`.
2. В терминале AMF: `UE SUPI[999700000000001] Registration complete`.
3. На экране телефона появится иконка **5G** (без стрелочек вверх-вниз, если нет трафика, или со стрелочками, если пингуешь).
4. Попробуй пинг с телефона: `ping -i 1 8.8.8.8`.
Саша, эта сборка — классический "hello world" в мире телекома, и она требует внимательности к деталям. Если на каком-то шаге что-то пойдет не так, не расстраивайся. В 99% случаев проблема кроется либо в опечатке в `Ki/OPc`, либо в том, что телефон не переключился в режим "5G Only" / "Роуминг".
Смотри в логи, анализируй их (твой бэкграунд в системном программировании тебе в этом очень поможет — ты понимаешь, как работают сокеты и события). У тебя всё получится! Если застрянешь на конкретной ошибке в логах — пиши, разберем её побайтно.