- Fix state machine start timing: don't call start() in startStateMachine, let the CPE's first empty body trigger the state machine via continue(). This ensures GPN is sent at the correct point in the TR-069 session. - Add unit tests for reclassifyDeviceFromCatalog (10 tests) - Add unit tests for MainStateMachine transitions and GPN callbacks (11 tests) - Test both scenarios: Huawei (GPN supported) and Livebox (GPN unsupported + fallback) - Fix tr069_trace_service test path assertion (config/ → data/) - Update steering doc with Livebox bootstrap command
198 lines
6.6 KiB
Markdown
198 lines
6.6 KiB
Markdown
# Debug: Reclassification Properties → Parameters
|
|
|
|
## Contexte du problème
|
|
|
|
Les paramètres `Device.ManagementServer.PeriodicInformInterval` et `Device.DeviceInfo.ProvisioningCode` apparaissent comme **properties** (read-only) dans l'interface alors qu'ils devraient être des **parameters** (writable).
|
|
|
|
Le catalogue `config/tr181-catalog.json` les marque bien comme `writable: true`.
|
|
La fonction `reclassifyDeviceFromCatalog()` dans `app/services/parameter_writability.ts` est censée les déplacer de properties vers parameters quand `gpnStatus === 'unsupported'`.
|
|
|
|
Le dernier log de debug montre : `[Reclassify] properties=9, reclassified=0, catalogSize=2953` — la fonction est appelée mais ne reclassifie rien malgré les paths présents dans le catalogue.
|
|
|
|
## Fichiers impliqués
|
|
|
|
- `app/services/parameter_writability.ts` — contient `reclassifyDeviceFromCatalog()` et `normalizePath()`
|
|
- `app/services/cwmp/device_action_executor.ts` — appelle la reclassification quand GPN échoue
|
|
- `app/services/cwmp/main_state_machine.ts` — `CompletedState` appelle aussi la reclassification
|
|
- `app/controllers/cwmp_controller.ts` — `handleInform()` appelle la reclassification si `gpnStatus === 'unsupported'`
|
|
- `app/domain/device/device.ts` — `updateFromValues()` stocke les nouveaux params comme properties par défaut
|
|
- `config/tr181-catalog.json` — référentiel de writabilité TR-181
|
|
|
|
## Procédure de test complète
|
|
|
|
### 1. Faire la modification de code
|
|
|
|
Modifier le fichier concerné, puis vérifier la compilation :
|
|
|
|
```bash
|
|
npx tsc --noEmit
|
|
```
|
|
|
|
### 2. Build et relance Docker
|
|
|
|
```bash
|
|
docker compose build app
|
|
docker compose up -d app
|
|
```
|
|
|
|
Attendre que l'app soit healthy :
|
|
|
|
```bash
|
|
docker compose logs app --tail 5
|
|
```
|
|
|
|
### 3. Supprimer le device Sagemcom de l'ACS
|
|
|
|
```bash
|
|
curl -s -X DELETE http://localhost:8080/api/v1/devices/2e933565b8fc09f34f42531e
|
|
```
|
|
|
|
### 4. Supprimer le device du simulateur (home-device-simulator)
|
|
|
|
```bash
|
|
curl -s -X DELETE "http://localhost:9898/api/v1/device-simulator/delete-devices" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '["F8:B7:FF:00:11:22"]'
|
|
```
|
|
|
|
### 5. Recréer le device dans le simulateur
|
|
|
|
```bash
|
|
curl -s -X PUT "http://localhost:9898/api/v1/device-simulator/create-devices?noOfDevices=1&autoGenerate=false&ipAddressType=ipv4" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{
|
|
"manufacturer": "Sagemcom",
|
|
"oui": "F8B7FF",
|
|
"productClass": "Livebox 4",
|
|
"serialNumber": "LB4-TEST-001",
|
|
"macaddress": "F8:B7:FF:00:11:22",
|
|
"parameters": [
|
|
{"type": "Manufacturer", "model": "Device.DeviceInfo.Manufacturer", "value": "Sagemcom"},
|
|
{"type": "ManufacturerOUI", "model": "Device.DeviceInfo.ManufacturerOUI", "value": "F8B7FF"},
|
|
{"type": "ModelName", "model": "Device.DeviceInfo.ModelName", "value": "Livebox 4"},
|
|
{"type": "ProductClass", "model": "Device.DeviceInfo.ProductClass", "value": "Livebox 4"},
|
|
{"type": "SerialNumber", "model": "Device.DeviceInfo.SerialNumber", "value": "LB4-TEST-001"},
|
|
{"type": "HardwareVersion", "model": "Device.DeviceInfo.HardwareVersion", "value": "SR40_sip-fr-4.62.0"},
|
|
{"type": "SoftwareVersion", "model": "Device.DeviceInfo.SoftwareVersion", "value": "SR40_sip-fr-4.62.0"}
|
|
]
|
|
}'
|
|
```
|
|
|
|
### 6. Déclencher le bootstrap Inform
|
|
|
|
Le simulateur ne fait PAS d'Inform automatiquement après la création. Il faut le déclencher manuellement :
|
|
|
|
```bash
|
|
sleep 3
|
|
curl -s -X POST "http://localhost:9898/api/v1/device-simulator/device-request" \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"actions":[{"macaddress":"F8:B7:FF:00:11:22","event":{"0":"BOOTSTRAP"}}]}'
|
|
```
|
|
|
|
### 7. Attendre l'Inform (30s max) puis vérifier
|
|
|
|
```bash
|
|
sleep 30
|
|
```
|
|
|
|
Vérifier la classification :
|
|
|
|
```bash
|
|
curl -s "http://localhost:8080/api/v1/devices/2e933565b8fc09f34f42531e" | \
|
|
python3 -c "
|
|
import sys,json
|
|
d=json.load(sys.stdin)
|
|
print('gpnStatus:', d.get('gpnStatus'))
|
|
props = [p['name'] for p in d.get('properties',[]) if 'PeriodicInform' in p['name'] or 'ProvisioningCode' in p['name']]
|
|
params = [p['name'] for p in d.get('parameters',[]) if 'PeriodicInform' in p['name'] or 'ProvisioningCode' in p['name']]
|
|
print('Dans properties (MAUVAIS):', props)
|
|
print('Dans parameters (BON):', params)
|
|
"
|
|
```
|
|
|
|
### 8. Regarder les logs de reclassification
|
|
|
|
```bash
|
|
docker compose logs app --tail 50 2>&1 | grep -i "reclassify\|Reclassify"
|
|
```
|
|
|
|
## Résultat attendu
|
|
|
|
**Sagemcom Livebox 4** (GPN unsupported, reclassification via catalogue) :
|
|
```
|
|
gpnStatus: unsupported
|
|
properties: 7
|
|
parameters: 2 (PeriodicInformInterval + ProvisioningCode)
|
|
```
|
|
|
|
**Huawei BM632w** (GPN supported, classification via GPN response) :
|
|
```
|
|
gpnStatus: supported
|
|
properties: 16
|
|
parameters: 15
|
|
compliance: compliant
|
|
```
|
|
|
|
## Identifiants du device de test
|
|
|
|
| Champ | Valeur |
|
|
|-------|--------|
|
|
| ACS identifier | `2e933565b8fc09f34f42531e` |
|
|
| Manufacturer | Sagemcom |
|
|
| OUI | F8B7FF |
|
|
| Product Class | Livebox 4 |
|
|
| Serial Number | LB4-TEST-001 |
|
|
| MAC (simulateur) | F8:B7:FF:00:11:22 |
|
|
| Data Model | tr-181 |
|
|
|
|
## Device Huawei (genieacs-sim)
|
|
|
|
| Champ | Valeur |
|
|
|-------|--------|
|
|
| ACS identifier | `f9747826c5545b0e49db7967` |
|
|
| Manufacturer | Huawei Technologies Co., Ltd. |
|
|
| OUI | 202BC1 |
|
|
| Product Class | BM632w |
|
|
| Serial Number | 000000 |
|
|
| Data Model | tr-098 (InternetGatewayDevice.*) |
|
|
| Container | `adam-acs-genieacs-sim-1` |
|
|
|
|
### Procédure de test Huawei
|
|
|
|
Le Huawei est simulé par le container `genieacs-sim` (défini dans `docker-compose.yml` avec le profile `test`). Il se crée automatiquement au démarrage du container.
|
|
|
|
**Supprimer le device :**
|
|
```bash
|
|
docker stop adam-acs-genieacs-sim-1 && docker rm adam-acs-genieacs-sim-1
|
|
curl -s -X DELETE http://localhost:8080/api/v1/devices/f9747826c5545b0e49db7967
|
|
```
|
|
|
|
**Recréer le device (relancer le container) :**
|
|
```bash
|
|
docker compose --profile test up -d genieacs-sim
|
|
```
|
|
|
|
Le container fait un Inform automatiquement au démarrage vers `http://app:8080/cwmp10`.
|
|
|
|
**Vérifier :**
|
|
```bash
|
|
sleep 15
|
|
curl -s "http://localhost:8080/api/v1/devices/f9747826c5545b0e49db7967" | python3 -c "
|
|
import sys,json
|
|
d=json.load(sys.stdin)
|
|
print('gpnStatus:', d.get('gpnStatus'))
|
|
print('dataModel:', d.get('dataModel'))
|
|
print('Properties:', len(d.get('properties',[])))
|
|
print('Parameters:', len(d.get('parameters',[])))
|
|
"
|
|
```
|
|
|
|
- Base URL : `http://localhost:9898/api/v1/device-simulator`
|
|
- Swagger : `http://localhost:9898/swagger/`
|
|
- Suppression par MAC : `DELETE /delete-devices` body `["MAC"]`
|
|
- Création : `PUT /create-devices?noOfDevices=1&autoGenerate=false&ipAddressType=ipv4`
|
|
|
|
## Trace TR-069
|
|
|
|
Le device est déjà dans la config de trace (`data/tr069-trace.json` dans le volume Docker `app_tr069_data`). Les logs SOAP sont visibles sur `http://localhost:8080/tr069-trace`.
|