Die RPG-Quellen und Include-Dateien liegen derzeit bewusst in einem gemeinsamen Verzeichnis. Serviceprogramm Das Serviceprogramm heißt: MEDDFNSRV Es besteht derzeit aus den Modulen: MEDDFNSRV MEDDFNBLD Die öffentlichen Exporte werden über die Binder-Source MEDDFNSRVB definiert. Die öffentlichen Prozeduren sind: MD_CreateMediaDefinition MD_DeleteMediaDefinition MD_RetrieveMediaDefinition Builder Der Builder erzeugt die Daten für eine Media Definition. Aktuell wird das Format TAPE0200 unterstützt. Der Builder kann bereits Media Definitions mit: mehreren Devices mehreren Media Files mehreren Volume Identifiers erzeugen. Parser Der Parser befindet sich in: meddfnprs.rpgle Ziel des Parsers ist es, die von QSRRTVMD gelieferten TAPE0200-Daten wieder in eine MD_MediaDefinition_T zu überführen. Die Parserentwicklung erfolgt schrittweise. Testprogramm Das Testprogramm heißt: MEDDFNTSTP Das Testprogramm wird verwendet, um Media Definitions zu erzeugen und anschließend deren Inhalt wieder auszulesen. Die bevorzugte Teststrategie ist ein Roundtrip: MD_MediaDefinition_T │ ▼ MD_CreateMediaDefinition │ ▼ *MEDDFN │ ▼ MD_RetrieveMediaDefinition │ ▼ Parser │ ▼ MD_MediaDefinition_T Damit können die vom Parser gelieferten Werte mit den ursprünglich erzeugten Werten verglichen werden. Status Der Builder für TAPE0200 ist funktionsfähig. Das Erzeugen einer Media Definition mit mehreren Devices und mehreren Volumes wurde erfolgreich getestet. Ein realer paralleler Save auf eine Tape Library mit zwei Drives wurde ebenfalls erfolgreich getestet. Die Parser-Implementierung befindet sich derzeit in Entwicklung. --- # 2. `DESIGN.md` ```markdown # MEDDFN – Design ## 1. Zweck MEDDFN soll eine wiederverwendbare RPGLE-Schnittstelle für die Arbeit mit IBM i Media Definitions (`*MEDDFN`) bereitstellen. Der aktuelle Schwerpunkt liegt auf dem Format: ```text TAPE0200 Das Projekt besteht aus einem Builder, einem Parser und einem Serviceprogramm. 2. Architektur MEDDFN │ ├── meddfn_h.rpgle │ └── Allgemeine Datenstrukturen und Konstanten │ ├── meddfnap_h.rpgle │ └── Datenstrukturen und Prototypen für IBM i API-Aufrufe │ ├── meddfnbld.rpgle │ └── Builder │ ├── meddfnprs.rpgle │ └── Parser │ ├── meddfnsrv.rpgle │ └── Öffentliche Serviceprogramm-Prozeduren │ ├── meddfnsrvb.rpgle │ └── Binder-Source │ └── meddfntstp.rpgle └── Testprogramm 3. Öffentliche Schnittstelle Das Serviceprogramm MEDDFNSRV stellt drei öffentliche Prozeduren bereit. MD_CreateMediaDefinition Erzeugt eine *MEDDFN-Media-Definition aus einer MD_MediaDefinition_T. MD_DeleteMediaDefinition Löscht eine vorhandene Media Definition. MD_RetrieveMediaDefinition Liest eine vorhandene Media Definition über die IBM i API und wandelt die zurückgegebenen Daten wieder in eine MD_MediaDefinition_T um. 4. IBM i APIs Für das Projekt werden unter anderem folgende IBM i APIs verwendet: QSRCRTMD QSRRTVMD QSRRSLMD QMHSNDPM Die API-spezifischen Strukturen und Prototypen befinden sich in: meddfnap_h.rpgle Allgemeine MEDDFN-Datenstrukturen und Konstanten befinden sich in: meddfn_h.rpgle 5. TAPE0200 Der aktuelle Builder erzeugt das Format: TAPE0200 Der grundsätzliche Aufbau ist: TAPE0200 Header │ ├── Device Definition │ │ │ ├── Media File Definition │ │ │ │ │ └── Volume Identifier Array │ │ │ └── weitere Media Files │ └── weitere Device Definitions 6. TAPE0200 Header Die RPG-Struktur ist: MD_Tape0200Header_T Sie enthält unter anderem: Maximum parallel device resources Minimum parallel device resources Offset zur ersten Device Definition Anzahl der Device Definitions Länge des Headers Device Allocation Save Format 7. Device Definition Die RPG-Struktur ist: MD_Tape0200DeviceDefinition_T Eine Device Definition beschreibt ein Gerät bzw. eine Ressource, beispielsweise: TAPMLB01 TAPMLB02 Sie enthält unter anderem: Offset zur nächsten Device Definition Device Name Offset zur ersten Media File Definition Anzahl der Media File Definitions Länge der Device Definition 8. Media File Definition Die RPG-Struktur ist: MD_Tape0200MediaFileDefinition_T Sie enthält unter anderem: Offset zur nächsten Media File Definition Sequence Number Offset zum Volume Identifier Array Anzahl der Volume Identifier Länge eines Volume Identifiers Starting Volume Array Element Länge der Media File Definition Starting Position in File 9. Volume Identifier Volume Identifier haben derzeit eine feste Länge von: 6 Bytes Die Konstante dafür ist: MD_VOLUME_ID_LENGTH Beispiele: VOL001 VOL002 VOL003 Die Volume Identifier werden nach der zugehörigen Media File Definition im Builder-Buffer abgelegt. 10. Alignment Daten werden auf 4-Byte-Grenzen ausgerichtet. Dafür wird verwendet: MD_AlignLength() Beispiele: 6 -> 8 12 -> 12 13 -> 16 11. Builder Context Der Builder verwendet: MD_BuilderContext_T Der Builder schreibt die erzeugten Strukturen schrittweise in einen gemeinsamen Buffer. Aktuelle Builder-Prozeduren: MD_BuildCreateBuffer MD_BuildTape0200Header MD_BuildTape0200Device MD_BuildTape0200Media MD_BuildTape0200VolumeArray 12. Builder-Reihenfolge Der Aufbau eines TAPE0200 Buffers erfolgt in dieser Reihenfolge: MD_BuildCreateBuffer │ ├── MD_BuildTape0200Header │ └── für jedes Device │ └── MD_BuildTape0200Device │ ├── MD_BuildTape0200Media │ ├── MD_BuildTape0200VolumeArray │ └── weitere Media Files 13. Offset-Berechnung Die TAPE0200-Strukturen enthalten relative Offsets. Die Offsets werden beim Aufbau des Buffers anhand der aktuellen Bufferposition und der Größe der jeweiligen Strukturen berechnet. Besonders wichtig ist die korrekte Behandlung von: Device Definitions Media File Definitions Volume Identifier Arrays 4-Byte-Alignment 14. StartingPositionInFile Derzeit wird: *ALL'0' verwendet. Beispiel: Media0200.StartingPositionInFile = *ALL'0'; Die Business-Datenstruktur stellt derzeit noch nicht alle möglichen API-Optionen für dieses Feld zur Verfügung. 15. Device Allocation Die Konstanten befinden sich in: meddfn_h.rpgle Aktuell: MD_DeviceAllocateAll MD_DeviceAllocateOne MD_DeviceAllocateMinimum 16. Save Format Die Konstanten befinden sich ebenfalls in: meddfn_h.rpgle Aktuell: MD_SaveFormatAuto MD_SaveFormatSerial MD_SaveFormatParallel Für einen parallelen Save wird verwendet: MediaDefinition.SaveFormat = MD_SaveFormatParallel; 17. Fehlerbehandlung API-Fehler werden über: MD_APIError_T behandelt. Die zentrale Prüfung erfolgt über: MD_CheckApiError() Nachrichten werden über: MD_SendMessage() MD_SendEscape() an den Aufrufer weitergegeben. MD_SendEscape() verwendet intern MD_SendMessage() mit dem Message Type Escape. 18. Parser Der Parser befindet sich in: meddfnprs.rpgle Seine Aufgabe ist es, die von QSRRTVMD gelieferten Daten wieder in die fachliche Struktur: MD_MediaDefinition_T zu überführen. Der Parser soll die API-Daten anhand ihrer Header, Devices, Media Files und Volume Arrays interpretieren. Grundprinzip: QSRRTVMD Receiver Buffer │ ▼ TAPE0200 Header │ ▼ Device Definitions │ ▼ Media File Definitions │ ▼ Volume Identifier Arrays │ ▼ MD_MediaDefinition_T 19. Parser-Teststrategie Der Parser wird zunächst mit Media Definitions getestet, die durch den eigenen Builder erzeugt wurden. Teststufe 1 1 Device └── 1 Media File └── 1 Volume Teststufe 2 1 Device └── 1 Media File ├── VOL001 └── VOL002 Teststufe 3 1 Device ├── Media File 1 │ ├── VOL001 │ └── VOL002 │ └── Media File 2 ├── VOL003 └── VOL004 Teststufe 4 2 Devices TAPMLB01 └── Media File 1 ├── VOL001 └── VOL002 TAPMLB02 └── Media File 1 ├── VOL003 └── VOL004 Teststufe 5 Test mit einer realen Tape Library und mehreren Drives. Ein paralleler Save auf zwei Tapes wurde erfolgreich getestet. Dabei wurde festgestellt, dass ein installierter BRMS Exit Point QIBM_QTA_TAPE_TMS mit dem Exit-Programm Q1ARTMS das Verhalten beeinflussen kann. Nach temporärem Entfernen des Exit Points konnte der parallele Save auf zwei Tapes erfolgreich durchgeführt werden. 20. Serviceprogramm Das Serviceprogramm heißt: MEDDFNSRV Aktuell werden folgende Module eingebunden: MEDDFNSRV MEDDFNBLD Die Binder-Source heißt: MEDDFNSRVB Die Binder-Source exportiert: MD_CreateMediaDefinition MD_DeleteMediaDefinition MD_RetrieveMediaDefinition Beim Erstellen des Serviceprogramms wird: TGTRLS(*CURRENT) verwendet. 21. Entwicklungsumgebung Das Projekt wird aktuell auf PUB400.com entwickelt. Verwendet werden: VS Code Code for IBM i IFS Git Gitea Die Quellen liegen im IFS als UTF-8-Dateien vor. Die RPG-Compile-Actions verwenden: TGTCCSID(*JOB) und: TGTRLS(*CURRENT) Die Include-Dateien liegen derzeit im selben Verzeichnis wie die RPG-Quellen. Sie werden beispielsweise über: /COPY './meddfn_h.rpgle' /COPY './meddfnap_h.rpgle' eingebunden. 22. Entwicklungsgrundsätze Bestehende Strukturen wiederverwenden Neue Funktionen sollen nach Möglichkeit die vorhandenen Datenstrukturen und Prozeduren verwenden. Keine parallelen Varianten derselben Datenstruktur ohne Notwendigkeit. Öffentliche Schnittstelle klein halten Das Serviceprogramm stellt nur die benötigten öffentlichen Prozeduren bereit. Interne Builder- und Parser-Prozeduren werden nicht unnötig exportiert. Builder und Parser getrennt halten Der Builder erzeugt API-Daten. Der Parser interpretiert API-Daten. Beide Komponenten sollen unabhängig voneinander bleiben. API-Strukturen und Business-Strukturen trennen Die API-Strukturen in meddfnap_h.rpgle beschreiben die IBM-i-API. Die fachlichen Strukturen in meddfn_h.rpgle beschreiben das interne Datenmodell. Diese Trennung soll erhalten bleiben. Git als gemeinsame Quelle Der aktuelle Code im Git-Repository ist die technische Quelle der Wahrheit. Architekturentscheidungen und wichtige Besonderheiten werden in dieser Datei dokumentiert, damit sie auch bei der Verwendung von Codex in VS Code verfügbar sind.