# Spécifications Techniques USB - Conformité Normative

## Vue d'ensemble

Ce document détaille l'implémentation conforme aux spécifications normatives USB pour la classification et l'analyse des périphériques dans Linux BenchTools.

## Mappings de Champs

### Champs Généraux (Formulaire)

Conformément aux spécifications USB :

| Champ BD | Source USB | Description | Exemple |
|----------|------------|-------------|---------|
| `marque` | **idVendor** | Identifiant hexadécimal du fabricant | `0x0781` (SanDisk) |
| `modele` | **iProduct** | Chaîne de description du produit | `"SanDisk 3.2Gen1"` |
| `fabricant` | **iManufacturer** | Nom du fabricant (chaîne texte) | `"SanDisk Corp."` |
| `numero_serie` | **iSerial** | Numéro de série unique | `"00E04C239987"` |

### Caractéristiques Spécifiques (JSON)

```json
{
  "vendor_id": "0x0781",              // idVendor
  "product_id": "0x55ab",             // idProduct
  "fabricant": "SanDisk Corp.",       // iManufacturer
  "usb_version_declared": "USB 3.20", // bcdUSB (déclaré, non définitif)
  "usb_type": "USB 3.0",              // Type RÉEL basé sur vitesse négociée
  "negotiated_speed": "SuperSpeed (5 Gbps)",
  "interface_classes": [              // CRITIQUE : bInterfaceClass
    {
      "code": 8,
      "name": "Mass Storage"
    }
  ],
  "device_class": "0",                // bDeviceClass (moins fiable)
  "requires_firmware": false,         // True si interface classe 255
  "max_power_ma": 896,                // MaxPower en mA
  "is_bus_powered": true,
  "is_self_powered": false,
  "power_sufficient": true            // Basé sur capacité normative du port
}
```

## Règles de Classification Normatives

### 1. Détection Mass Storage (CRITIQUE)

**❌ INCORRECT** : Utiliser `bDeviceClass`

```
bDeviceClass = 0 → [unknown]
```

**✅ CORRECT** : Utiliser `bInterfaceClass`

```
Interface 0:
  bInterfaceClass = 8 → Mass Storage
```

**Implémentation** :

```python
# Priorité 1 : Analyser bInterfaceClass (normative)
if device_info.get("interface_classes"):
    for interface in interface_classes:
        if interface["code"] == 8:
            return ("Stockage", "Clé USB")  # Raffiné ensuite

# Priorité 2 : Fallback sur bDeviceClass (moins fiable)
if device_info.get("device_class") == "08":
    return ("Stockage", "Clé USB")
```

### 2. Détection Firmware Requis

**Classe Vendor Specific (255)** indique que le périphérique :
- Expose une interface incomplète ou générique
- Attend un **pilote + microcode spécifique** pour fonctionner
- N'utilise pas de classe standard USB

**Exemple** : Adaptateur WiFi Realtek

```
Interface 0:
  bInterfaceClass = 255 → Vendor Specific
  requires_firmware = true
```

**Implémentation** :

```python
for interface in interface_classes:
    if interface["code"] == 255:
        device_info["requires_firmware"] = True
```

### 3. Type USB Basé sur Vitesse Négociée

**❌ INCORRECT** : Utiliser `bcdUSB`

```
bcdUSB = 3.20  # Ce que le périphérique DÉCLARE supporter
```

**✅ CORRECT** : Utiliser la vitesse négociée

```
Negotiated Speed = High Speed (480 Mbps) → USB 2.0
```

**Mappings Normatifs** :

| Vitesse Négociée | Débit | Type USB Réel |
|------------------|-------|---------------|
| Low Speed | 1.5 Mbps | **USB 1.1** |
| Full Speed | 12 Mbps | **USB 1.1** |
| High Speed | 480 Mbps | **USB 2.0** |
| SuperSpeed | 5 Gbps | **USB 3.0** (Gen 1) |
| SuperSpeed+ | 10 Gbps | **USB 3.1** (Gen 2) |
| SuperSpeed Gen 2x2 | 20 Gbps | **USB 3.2** |

**Implémentation** :

```python
speed_patterns = [
    (r'1\.5\s*Mb/s|Low\s+Speed', 'Low Speed', 'USB 1.1'),
    (r'12\s*Mb/s|Full\s+Speed', 'Full Speed', 'USB 1.1'),
    (r'480\s*Mb/s|High\s+Speed', 'High Speed', 'USB 2.0'),
    (r'5\s*Gb/s|SuperSpeed(?:\s+Gen\s*1)?', 'SuperSpeed', 'USB 3.0'),
    (r'10\s*Gb/s|SuperSpeed\+|Gen\s*2', 'SuperSpeed+', 'USB 3.1'),
    (r'20\s*Gb/s|Gen\s*2x2', 'SuperSpeed Gen 2x2', 'USB 3.2'),
]
```

### 4. Analyse de Puissance Normative

**Extraction** :

- `MaxPower` : Puissance maximale requise (en mA)
- `bmAttributes` : Attributs de configuration
  - Bit 6 : Self Powered (auto-alimenté)
  - Bit 5 : Remote Wakeup

**Capacités Normatives des Ports** :

| Type USB | Capacité Normative | Calcul |
|----------|-------------------|---------|
| USB 2.0 | **500 mA @ 5V** | = 2,5 W |
| USB 3.x | **900 mA @ 5V** | = 4,5 W |

**Analyse de Suffisance** :

```python
max_power_ma = 896  # MaxPower extrait
usb_type = "USB 3.0"  # Déterminé depuis vitesse négociée

if "USB 3" in usb_type:
    port_capacity = 900  # USB 3.x
else:
    port_capacity = 500  # USB 2.0

power_sufficient = (max_power_ma <= port_capacity)
# True : Le port peut alimenter le périphérique
# False : Risque d'alimentation insuffisante
```

**Modes d'Alimentation** :

```python
# bmAttributes = 0x80 → Bus Powered uniquement
is_bus_powered = True
is_self_powered = False

# bmAttributes = 0xC0 → Self Powered + Bus Powered
is_bus_powered = True
is_self_powered = True  # Bit 6 = 1
```

## Exemples de Classification

### Exemple 1 : Clé USB SanDisk USB 3.0

**Sortie lsusb** :

```
Bus 004 Device 005: ID 0781:55ab SanDisk Corp.
  bcdUSB               3.20
  bDeviceClass            0 [unknown]
  iManufacturer           1 SanDisk Corp.
  iProduct                2 SanDisk 3.2Gen1
  iSerial                 3 00E04C239987
  MaxPower              896mA
  bmAttributes         0x80
    (Bus Powered)

  Interface 0:
    bInterfaceClass         8 Mass Storage
    bInterfaceSubClass      6 SCSI
    bInterfaceProtocol     80 Bulk-Only
```

**Analyse** :

```json
{
  "marque": "0x0781",                    // idVendor
  "modele": "SanDisk 3.2Gen1",           // iProduct
  "fabricant": "SanDisk Corp.",          // iManufacturer
  "usb_version_declared": "USB 3.20",    // bcdUSB (déclaré)
  "usb_type": "USB 3.0",                 // Basé sur SuperSpeed 5 Gbps
  "negotiated_speed": "SuperSpeed (5 Gbps)",
  "interface_classes": [
    {"code": 8, "name": "Mass Storage"}  // NORMATIVE pour détection
  ],
  "device_class": "0",                   // Classe device = unknown
  "requires_firmware": false,            // Pas de classe 255
  "max_power_ma": 896,                   // MaxPower
  "is_bus_powered": true,                // Bit 6 = 0 dans bmAttributes
  "is_self_powered": false,
  "power_sufficient": true               // 896 mA ≤ 900 mA (USB 3.x)
}
```

**Classification Finale** :

- `type_principal` = **"Stockage"** (interface classe 8)
- `sous_type` = **"Clé USB"** (raffiné par mots-clés : "sandisk", "flash")

### Exemple 2 : Adaptateur WiFi Realtek (Firmware Requis)

**Sortie lsusb** :

```
Bus 002 Device 005: ID 0bda:8176 Realtek Semiconductor Corp.
  bcdUSB               2.00
  bDeviceClass            0
  iManufacturer           1 Realtek
  iProduct                2 802.11n WLAN Adapter
  MaxPower              500mA
  bmAttributes         0x80
    (Bus Powered)

  Interface 0:
    bInterfaceClass       255 Vendor Specific Class
    bInterfaceSubClass    255
    bInterfaceProtocol    255
```

**Analyse** :

```json
{
  "marque": "0x0bda",
  "modele": "802.11n WLAN Adapter",
  "fabricant": "Realtek",
  "usb_version_declared": "USB 2.00",
  "usb_type": "USB 2.0",
  "negotiated_speed": "High Speed (480 Mbps)",
  "interface_classes": [
    {"code": 255, "name": "Vendor Specific Class"}  // ⚠️ Firmware requis
  ],
  "requires_firmware": true,                         // Classe 255 détectée
  "max_power_ma": 500,
  "is_bus_powered": true,
  "power_sufficient": true                           // 500 mA ≤ 500 mA (USB 2.0)
}
```

**Classification Finale** :

- `type_principal` = **"USB"** (classe 255 = générique, raffiné par mots-clés)
- `sous_type` = **"Adaptateur WiFi"** (mots-clés : "802.11n", "wlan", "realtek")
- `requires_firmware` = **true** → Nécessite pilote + firmware Realtek

### Exemple 3 : Disque Dur Externe WD My Passport

**Sortie lsusb** :

```
Bus 001 Device 007: ID 1058:25a2 Western Digital Technologies, Inc.
  bcdUSB               3.00
  bDeviceClass            0
  iManufacturer           1 Western Digital
  iProduct                2 My Passport 25A2
  iSerial                 3 575832314435394542433331
  MaxPower              896mA
  bmAttributes         0x80
    (Bus Powered)

  Interface 0:
    bInterfaceClass         8 Mass Storage
    bInterfaceSubClass      6 SCSI
    bInterfaceProtocol     80 Bulk-Only
```

**Analyse** :

```json
{
  "marque": "0x1058",
  "modele": "My Passport 25A2",
  "fabricant": "Western Digital",
  "usb_type": "USB 3.0",
  "interface_classes": [
    {"code": 8, "name": "Mass Storage"}
  ],
  "max_power_ma": 896,
  "power_sufficient": true
}
```

**Classification Finale** :

- `type_principal` = **"Stockage"** (interface classe 8)
- `sous_type` = **"Disque dur externe"** (raffiné par mots-clés : "my passport", "external")

## Stratégies de Classification (Ordre de Priorité)

1. **Interface Class** (NORMATIVE) - `bInterfaceClass`
   - Analyse de toutes les interfaces du périphérique
   - Détection Mass Storage (08), HID (03), Video (0e), etc.
   - Détection firmware requis (255)

2. **Device Class** (FALLBACK) - `bDeviceClass`
   - Utilisé si `bInterfaceClass` non disponible ou `bDeviceClass != 0`
   - Moins fiable pour Mass Storage

3. **Vendor/Product Analysis**
   - Analyse des IDs (`idVendor`, `idProduct`)
   - Analyse des chaînes (`iManufacturer`, `iProduct`)
   - Matching de patterns connus (SanDisk, Realtek, etc.)

4. **Keyword Matching**
   - Analyse du contenu CLI complet
   - Patterns regex pour types spécifiques (WiFi, Bluetooth, etc.)
   - Scoring pour sélectionner le meilleur match

5. **Markdown Content** (si import .md)
   - Analyse du contenu markdown
   - Extraction d'informations textuelles

## Fichiers Implémentant la Conformité

### Backend

1. **[backend/app/utils/lsusb_parser.py](../backend/app/utils/lsusb_parser.py)**
   - `parse_device_info()` : Extraction complète avec `interface_classes[]`
   - Détection vitesse négociée → `usb_type`
   - Analyse puissance → `power_sufficient`
   - Détection firmware → `requires_firmware`

2. **[backend/app/utils/device_classifier.py](../backend/app/utils/device_classifier.py)**
   - `USB_INTERFACE_CLASS_MAPPING` : Mappings normatifs par interface
   - `detect_from_usb_interface_class()` : Classification par interface (prioritaire)
   - `detect_from_usb_device_class()` : Fallback sur device class
   - `classify_device()` : Orchestration des stratégies

3. **[backend/app/utils/usb_info_parser.py](../backend/app/utils/usb_info_parser.py)**
   - `parse_structured_usb_info()` : Parser texte structuré
   - `extract_interfaces()` : Extraction `bInterfaceClass` en int
   - Détection vitesse → `usb_type`
   - Analyse puissance → `power_sufficient`

4. **[backend/app/api/endpoints/peripherals.py](../backend/app/api/endpoints/peripherals.py)**
   - Endpoint `/import/usb-cli/extract` : Passage `interface_classes` au classificateur
   - Endpoint `/import/usb-structured` : Idem avec données structurées
   - Enrichissement `caracteristiques_specifiques` avec tous les champs normatifs

## Tests de Conformité

### Test 1 : Mass Storage via bInterfaceClass

```bash
# Préparer une sortie lsusb avec bDeviceClass = 0 mais bInterfaceClass = 8
cat > /tmp/test_storage.txt << 'EOF'
Bus 004 Device 005: ID 0781:55ab SanDisk Corp.
  bDeviceClass            0 [unknown]
  Interface 0:
    bInterfaceClass         8 Mass Storage
EOF

# Importer via interface web
# Résultat attendu : type_principal = "Stockage", sous_type = "Clé USB"
```

**Vérification** : ✅ Détection correcte via `bInterfaceClass` (pas `bDeviceClass`)

### Test 2 : USB Type depuis Vitesse Négociée

```bash
cat > /tmp/test_usb_type.txt << 'EOF'
Bus 001 Device 003: ID 1234:5678 Test Device
  bcdUSB               3.20
  # Vitesse négociée : High Speed (480 Mbps)
EOF

# Résultat attendu : usb_type = "USB 2.0" (pas "USB 3.2" de bcdUSB)
```

**Vérification** : ✅ Type basé sur vitesse négociée, pas bcdUSB

### Test 3 : Firmware Requis (Classe 255)

```bash
cat > /tmp/test_firmware.txt << 'EOF'
Bus 002 Device 005: ID 0bda:8176 Realtek
  Interface 0:
    bInterfaceClass       255 Vendor Specific
EOF

# Résultat attendu : requires_firmware = true
```

**Vérification** : ✅ Détection correcte de classe 255

### Test 4 : Analyse de Puissance

```bash
cat > /tmp/test_power.txt << 'EOF'
Bus 001 Device 003: ID 1234:5678 Test Device
  MaxPower              900mA
  bmAttributes         0x80
  # Vitesse : SuperSpeed (5 Gbps) → USB 3.0
EOF

# Résultat attendu :
# - max_power_ma = 900
# - is_bus_powered = true
# - power_sufficient = true (900 ≤ 900)
```

**Vérification** : ✅ Calcul correct de suffisance

## Références Normatives

- **USB 2.0 Specification** : [USB.org](https://www.usb.org/document-library/usb-20-specification)
- **USB 3.2 Specification** : [USB.org](https://www.usb.org/document-library/usb-32-specification)
- **USB Class Codes** : [usb.org/defined-class-codes](https://www.usb.org/defined-class-codes)
- **USB Device Class Definitions** : bDeviceClass, bInterfaceClass distinction
- **USB Power Delivery** : Normative power limits (500 mA USB 2.0, 900 mA USB 3.x)

## Avantages de la Conformité

✅ **Précision** : Détection Mass Storage fiable via `bInterfaceClass`
✅ **Type USB Correct** : Basé sur vitesse négociée réelle, pas déclaration
✅ **Analyse Puissance** : Prévention problèmes d'alimentation insuffisante
✅ **Détection Firmware** : Indication claire des périphériques nécessitant pilotes
✅ **Mappings Clairs** : Champs cohérents avec terminologie USB normative
✅ **Extensible** : Ajout facile de nouvelles classes d'interface

## Limitations Connues

⚠️ **Périphériques Multi-Interface** : Si plusieurs interfaces avec classes différentes, seule la première trouvée est utilisée pour classification
⚠️ **Vitesse Non Mentionnée** : Si la vitesse négociée n'est pas dans la sortie lsusb, fallback sur bcdUSB
⚠️ **bmAttributes Absent** : Détection Bus/Self Powered basée sur `Mode d'alimentation` (texte)

## Améliorations Futures

1. **Multi-Interface Classification** : Détecter périphériques combinés (ex: Hub + Ethernet)
2. **USB4 Support** : Ajout patterns pour vitesses 40 Gbps et Thunderbolt
3. **Power Delivery (PD)** : Support USB-C PD avec puissances > 5V
4. **Alternative Modes** : Détection DisplayPort Alt Mode, Thunderbolt, etc.
5. **Logs de Conformité** : Afficher avertissements si détection non conforme
