Add design spec for kydriv Kyocera 3505ci Apple Silicon driver

This commit is contained in:
Oliver Hofmann 2026-06-02 10:30:43 +02:00
commit 49ad65435e

View File

@ -0,0 +1,164 @@
# kydriv — Kyocera 3505ci Treiber für Apple Silicon
## Kontext
Der Kyocera/TA 3505ci Multifunktionsdrucker erfordert zur Nutzung einen Abteilungscode (Kostenstelle). Der bisherige Intel-Mac-Treiber bot dafür ein Textfeld im Druckdialog. Der aktuelle Apple-Silicon-Treiber von Kyocera hat diese Funktion nicht. Dieses Projekt entwickelt einen Ersatztreiber für macOS auf Apple Silicon, der die fehlenden Funktionen — insbesondere die Kostenstelle — wiederherstellt.
## Ursachenanalyse
Der alte Intel-Treiber bestand aus drei Schichten:
1. **APDialogExtension-Plugins** (`.plugin`-Bundles) — Objective-C/Cocoa-Panels im Druckdialog. Intel-only, von Apple deprecated. Zuständig für die UI (Textfelder, Checkboxen).
2. **CUPS-Filter** (`kyoprefilter_E`, `kyofilter_E`) — kompilierte Intel-Binaries. Zuständig für PostScript-Verarbeitung und Einschleusen von Gerätebefehlen.
3. **PPD-Datei** — Textdatei, architekturunabhängig.
Auf Apple Silicon fehlen die Punkte 1 und 2. Der neue Kyocera-Treiber hat nur eine abgespeckte PPD ohne die Plugin-Mechanismen.
## Lösungsansatz
**PPD + Python CUPS-Filter**, verteilt als signiertes `.pkg`.
- Die APDialogExtension-Plugins werden nicht ersetzt (deprecated API). Stattdessen werden Kostenstellen als benannte Optionen in der PPD geführt und per Preset gespeichert.
- Die Intel-Filter werden durch ein Python-Script ersetzt, das architekturunabhängig ist.
- Der Kyocera-Treiber wird vollständig umgangen — die Lösung ist eigenständig.
## Komponenten
```
kydriv/
├── ppd/
│ └── TA3505ci_AS.ppd # modifizierte PPD
├── filter/
│ └── kyofilter # Python CUPS-Filter
├── installer/
│ ├── root/ # Dateisystem-Abbild für pkgbuild
│ │ ├── Library/Printers/PPDs/Contents/Resources/TA3505ci_AS.ppd
│ │ └── usr/libexec/cups/filter/kyofilter
│ ├── scripts/
│ │ └── postinstall
│ └── build.sh
└── docs/superpowers/specs/
```
**Datenfluss:**
```
macOS App (PDF) → CUPS pdftops → PostScript → kyofilter (Python) → Drucker
```
## PPD-Datei (`TA3505ci_AS.ppd`)
Basis: `TA3505ci.PPD` (Intel-Treiber, Version 8.6006).
**Entfernt:**
- Alle 11 `*APDialogExtension:`-Zeilen
- `*cupsPreFilter: "application/pdf 0 kyoprefilter_E"`
**Geändert:**
```diff
- *cupsFilter: "application/vnd.cups-postscript 0 kyofilter_E"
+ *cupsFilter: "application/vnd.cups-postscript 0 kyofilter"
```
**KmManagment-Sektion** (ersetzt die alte Liste 0000000000000030):
```ppd
*% Kostenstelle (5-stellig) direkt eintragen — keine führenden Nullen nötig.
*% Zeile kopieren und Zahl ersetzen:
*% *KmManagment MG12345/Code 12345: ""
*OpenUI *KmManagment/Job Accounting: PickOne
*DefaultKmManagment: Default
*OrderDependency: 60 AnySetup *KmManagment
*KmManagment Default/Aus: ""
*KmManagment MG12345/Code 12345: ""
*?KmManagment: ""
*End
*CloseUI: *KmManagment
```
Der PPD-Wert bleibt leer (`""`), da der Filter die PostScript-Injection übernimmt.
**Unverändert:** alle anderen Optionen — InputSlot, PageSize, KCStaple, OutputBin, Duplex, Farbe etc.
## Python CUPS-Filter (`kyofilter`)
**Installationspfad:** `/usr/libexec/cups/filter/kyofilter`
**Rechte:** 755, root:wheel
**Interpreter:** `/usr/bin/python3` (macOS vorinstalliert)
**CUPS-Schnittstelle:**
```
kyofilter <job-id> <user> <title> <copies> <options> [filename]
```
- Eingabe: PostScript (stdin oder Datei)
- Ausgabe: PostScript (stdout)
- Logs: stderr → CUPS error_log
**Logik:**
1. `argv[5]` parsen → Key=Value-Dict
2. `KmManagment`-Wert lesen
3. Startet mit `MG` und ist numerisch → Code extrahieren, auf 8 Stellen zero-padden
4. Sonst → reiner Passthrough
5. PostScript-Stream zeilenweise lesen:
- Vor `%%EndSetup`: `(XXXXXXXX) statusdict /setmanagementnumber get exec` injizieren
- Alle anderen Zeilen unverändert weiterleiten
6. Fallback: falls kein `%%EndSetup` gefunden → vor erstem `%%Page:` injizieren, Warning ins Log
**Beispiel:** Kostenstelle `12345``(00012345) statusdict /setmanagementnumber get exec`
## Installer (`.pkg`)
**Gebaut mit:** `pkgbuild` + Developer ID Installer Zertifikat
**Bundle-ID:** `de.kydriv.driver`
```bash
pkgbuild \
--root installer/root \
--scripts installer/scripts \
--identifier "de.kydriv.driver" \
--version "1.0.0" \
--sign "Developer ID Installer: NAME (TEAM-ID)" \
kydriv-driver-1.0.0.pkg
```
**postinstall-Script:**
```bash
#!/bin/bash
chmod 755 /usr/libexec/cups/filter/kyofilter
chown root:wheel /usr/libexec/cups/filter/kyofilter
launchctl kickstart -k system/org.cups.cupsd
```
**Notarisierung** (einmalig pro Release):
```bash
xcrun notarytool submit kydriv-driver-1.0.0.pkg \
--apple-id EMAIL --team-id TEAM-ID --password APP-PASSWORT --wait
xcrun stapler staple kydriv-driver-1.0.0.pkg
```
Notarisierte `.pkg`-Dateien bleiben dauerhaft gültig, auch nach Ablauf des Entwicklerzertifikats.
## Benutzer-Workflow nach Installation
1. Kostenstelle in PPD eintragen (einmalig, Texteditor)
2. `.pkg` installieren
3. Drucker in Systemeinstellungen hinzufügen → `TA3505ci_AS.ppd` auswählen
4. Druckdialog → Job Accounting → eigene Kostenstelle wählen
5. Preset speichern
6. Ab sofort: Preset auswählen → drucken
## Testing
| Stufe | Methode | Erfolgskriterium |
|-------|---------|-----------------|
| 1 | Filter mit Beispiel-PS über stdin aufrufen | Injection vor `%%EndSetup` im Output |
| 2 | `cupstestppd ppd/TA3505ci_AS.ppd` | Ausgabe: PASS |
| 3 | Manuelle Installation, Testseite drucken | Seite kommt raus |
| 4 | CUPS-Log + Kyocera-Webinterface Job-Log | Kostenstelle korrekt erfasst |
| 5 | `.pkg` auf frischem System installieren | End-to-End-Workflow funktioniert |
## Offene Fragen / Nächste Schritte
- Genaue Kostenstellen-Codes für die PPD erfragen und eintragen
- Verifizieren, dass `setmanagementnumber` auf dem 3505ci die Kostenstelle korrekt bucht (Stufe 4)
- Ggf. weitere Kyocera-spezifische PPD-Optionen aus dem alten Treiber übernehmen