Seit der letzten offiziellen Dokumentationen zum XAcc-Protokoll haben sich einige Erweiterungen ergeben, die nun zusammengefaßt worden sind. Einige der Erweiterungen sind aus speziellen Formen des Datenaustauschs zwischen der Textverarbeitung That's Write und der Adreßverwaltung That's Address bzw. dessen Nachfolger no|Address hervorgegangen. Trotzdem sind diese Erweiterungen auch beliebigen anderen Applikationen zugänglich und die Verwendung dieser Applikationsnamen in der folgenden Dokumentation hat nur beispielhaften Charakter (That's Address = TA und That's Write = TW). Bei den Erweiterungen handelt es sich um:
Der eigentliche Seriendruck (MailMerge) des TW wird über dieses Protokoll abgehandelt.
Ermöglicht es einer Applikation, von sich aus einen Seriendruck im TW zu initiieren.
Dient der Ermittlung von Informationen über den Aufbau einer Datenbank.
Dient dem allgemeinen Datenaustausch zwischen Applikationen.
Beispiel: "#IA1,A2,A3,A4,T1" (die ersten 4 Adreßfelder und die 1. Telefonnr.).
Bei erfolgreichem Empfang dieser Nachricht wird dem TW eine ACC_TEXT-Message mit dem String "0" zurückgesendet, ansonsten ein Leerstring ".
Nun kann TW beginnen, die einzelnen Adreßdaten mittels der ACC_TEXT- Message "#N" anzufordern. Bei Empfang einer solchen Nachricht schickt TA für jedes Adreßfeld einer Adresse eine ACC_TEXT-Message und zum Abschluß eines Datensatzes einen Leerstring ".
#define ACC_FORCESDF 0x520 #define ACC_GETSDF 0x521
TA sendet dem TW ein ACC_FORCESDF, wenn eine Adresse oder eine Adreßliste an das TW geschickt werden soll. Im Falle, daß es sich nur um eine Adresse handelt, steht in msgbuff[4]+[5] ein Pointer auf das Suchwort der Adresse, bei einer Adreßliste steht in msgbuff[4]+[5] ein Pointer auf "#L". Die ACC_FORCESDF-message muß mit einem ACC_ACK bestätigt werden (msgbuff[3]==1 -> OK und msgbuff[3]==0 -> ERROR).
Wenn TW ein "#L" bekommst, dann fährt TW ein ganz normales MailMerge- Protokoll (eingangs erklärt). Wenn TW ein Suchwort bekommt (max. 20 Zeichen lang), dann fordert TW beim TA diese Adresse mittels ACC_GETSDF an. Die ACC_GETSDF-message muß in msgbuff[4]+[5] einen Pointer auf einen Buffer haben, in dem zuerst das Suchwort mit abschließendem '\0' steht und dann der XDF-Formatstring steht (Bsp.: "JÖRG\0A1,A2,A3\0").
Wenn TA die ACC_GETSDF-message verstehen kann, dann schickt es ein ACC_ACK mit msgbuff[3]==1, ansonsten ein ACC_ACK mit msgbuff[3]==0. Anschließend bekommt TW die Daten dieser einen Adresse wie beim normalen MailMerge- Protokoll.
TW muß in seinem XDSC-String ein "XRM" zu stehen haben, damit TA von sich aus ein Remote-Mailmerge-Protokoll startet.
TA hat jetzt folgende XDSC-Features (Bsp. ACC):
const char ta2Ident[] = "That's Address ACC\0XDSC\0" "1Adressverwaltung\0" "2DB\0" "XMM\0XSU\0XDI\0XRM\0NnoAddress ACC\0";
Also Part 1 (am Beispiel von TA und TW):
TA | TW --------------------------------+------------------------------------ ACC_GETDSI <---------------------------------------- ACC_DSINFO ----------------------------------------> ACC_ACK <---------------------------------------- { ACC_FILEINFO ----------------------------------------> ACC_ACK <---------------------------------------- } /* <n> mal, wobei <n> bei ACC_DSINFO übertragen wurde */
Erklärung der einzelnen Protokollelemente:
Hiermit wird das Inquiery-Protokoll initiiert. Diese Message enthält einen Pointer auf eine Variable des Typs Xacc_Dsi_Request, in dem codiert wird, welche Felder welchen Typs gewünscht sind.
msgbuf[0] = ACC_GETDSI msgbuf[1] = application id msgbuf[4] und msgbuf[5] = Pointer auf die gewünschten Feld-Typen (siehe XACC.H)
Auf ein ACC_GETDSI antwortet die angefragte Applikation mit dieser Message. Hierbei wird ein Pointer auf eine Variable des Typs Xacc_Dsinfo, wenn die Anfrage beantwortet werden kann, oder ein NULL-Pointer, wenn die Anfrage nicht beantwortet werden kann, der anfragenden Applikation übergeben.
msgbuf[0] = ACC_DSINFO; msgbuf[4] und msgbuf[5] = Pointer auf Xacc_Dsinfo Struktur (siehe XACC.H) oder NULL
Die anfragende Applikation beantwortet alle Replys seinerseits mit einer ACC_ACK Message: ACC_ACK:
msgbuf[0] = ACC_ACK msgbuf[3] = 1 wenn alles OK ist = 0 wenn ein Fehler aufgetreten ist (Abbruch des Protokolls)
Wenn die ACC_DSINFO Message von der anfragenden Applikation bestätigt wurde, so wird für jede verfügbare Datei eine ACC_FILEINFO-Message mit einem Pointer auf eine Variable des Typs Xacc_File_Info, oder ein NULL-Pointer bei einem Fehler, an die anfragende Applikation gesendet.
Jede dieser Messages muß, wie oben erwähnt, mit einer ACC_ACK von der anfragenden Applikation bestätigt werden.
msgbuf[0] = ACC_FILEINFO; msgbuf[4] und msgbuf[5] = Pointer auf Xacc_File_Info Struktur (siehe XACC.H) oder NULL
Tut der Anwender dies, so läuft der 2. Part des Inquiery-Protokolls los (wieder am Beispiel von TA und TW):
TA | TW --------------------------------+------------------------------------ ACC_GETFIELDS <---------------------------------------- { ACC_FIELDINFO ----------------------------------------> ACC_ACK <---------------------------------------- } /* <n> mal, wobei <n> bei ACC_FILEINFO übertragen wurde */
Erklärung der einzelnen Protokollelemente:
Hiermit wird von der anfragenden Applikation eine Datenbank ausgewählt (die entsprechende Datenbank-ID hat sie ja bei der ACC_FILEINFO Message in der Struktur Xacc_File_Info empfangen) und gibt der angefragten Applikation bekannt, daß nun die einzelnen Feldinformationen übertragen werden sollen.
msgbuf[0] = ACC_GETFIELDS msgbuf[1] = application id msgbuf[3] = ID der gewünschte Datenbank
Wenn die ACC_GETFIELDS Message von der anfragenden Applikation bestätigt wurde, so wird für jedes Feld eine ACC_FIELDINFO Message mit einem Pointer auf eine Variable des Typs Xacc_Field_Info, oder ein NULL-Pointer bei einem Fehler, an die anfragende Applikation gesendet.
Jede dieser Messages muß, wie oben erwähnt, mit einer ACC_ACK von der anfragenden Applikation bestätigt werden.
msgbuf[0] = ACC_FIELDINFO; msgbuf[4] und msgbuf[5] = Pointer auf Xacc_Field_Info Struktur (siehe XACC.H) oder NULL
#define ACC_REQUEST 0x480 #define ACC_REPLY 0x481
Mittels dieser Nachricht fordert man bei einer anderen Applikation einen Dienst an. Der Aufbau dieser Nachricht ist folgendermaßen:
msgbuff[0]: ACC_REQUEST (0x480) msgbuff[1]: Application-ID des Senders msgbuff[2]: 0 msgbuff[3]: Das high-Byte ist frei für Applikationsspezifische Informationen und im low-Byte ist der Typ der Daten codiert, die mit dieser Nachricht verschickt werden: 0x01 String, d.h. msgbuff[4]+msgbuff[5] ist ein Pointer auf den String 0x02 Env-String, d.h msgbuff[4]+msgbuff[5] ist ein Pointer auf den Env-String (mehrere durch '\0' getrennte Strings mit abschließenden doppelten '\0'-Bytes) 0x03 binär-Daten, d.h. msgbuff[4]+msgbuff[5] ist ein Pointer auf die binär-Daten. In diesem Fall muß der Empfänger natürlich über die Struktur Bescheid wissen! (lokale Typunterscheidung ist z.B. mittels des high-Bytes möglich) 0x04 code, d.h. msgbuff[4] bis msgbuff[7] enthalten direkt die Daten (sinnvoll bei der Übertragung von Datenmengen bis 8 Byte) msgbuff[4,5]: Pointer auf die Daten (außer Typ 0x04) msgbuff[6,7]: Länge des Datenbereichs incl. eventueller '\0'-Bytes (außer Typ 0x04)
Es existieren zwei verschiedene Möglichkeiten, diese Nachricht zu beantworten:
Mittels dieser Nachricht wird eine ACC_REQUEST Anforderung erfolgreich beantwortet. Der Aufbau dieser Nachricht ist folgendermaßen:
msgbuff[0]: ACC_REPLY (0x481) msgbuff[1]: . . siehe ACC_REQUEST! . msgbuff[7]: