A communication protocol for GEM applications XAcc

Contents Classic XAcc Example: no|Link's XAcc protocol

3 Extended XAcc

This chapter describes developments of the XAcc protocol after "Classic XAcc" (11/28/92). Last changes have been made on June 15, 1995.

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:

das MailMerge-Protokoll

Der eigentliche Seriendruck (MailMerge) des TW wird über dieses Protokoll abgehandelt.

das Remote-Mailmerge-Protokoll

Ermöglicht es einer Applikation, von sich aus einen Seriendruck im TW zu initiieren.

das Inquiery-Protokoll

Dient der Ermittlung von Informationen über den Aufbau einer Datenbank.

das Request/Reply-Protokoll

Dient dem allgemeinen Datenaustausch zwischen Applikationen.

3.1 MailMerge protocol

Dieses Protokoll arbeitet aus historischen Gründen mit ACC_TEXT-Messages. Das TW schickt dem TA zuerst eine ACC_TEXT-Messages mit einem String, der mit "#I" beginnt und nach dem 'I' den SDF-Formatstring beinhaltet, der dem TA sagt, welche Teile eines Adreßdatensatzes übertragen werden sollen.

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 ".

3.2 Remote-Mailmerge protocol

Für dieses Protokoll gibt es zwei neue XAcc-message Typen, nämlich:


#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";

XMM
MailMerge

XSU
Suchwortübergabe (optional mit anschließendem '?')

XDI
Inquiery-Protokoll

XRM
Remote-MailMerge

3.3 Inquiery protocol

Im Prinzip läuft das ganze Inquiery-Protokoll in 2 Stufen ab. Zuerst werden die Daten der verfügbaren Datenbanken ermittelt, und anschließend (zeitlich voneinander völlig unabhängig) werden die einzelnen Felder einer ausgewählten Datenbank erfragt.

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:

ACC_GETDSI

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)

ACC_DSINFO

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)

ACC_FILEINFO

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

Wenn dieser erste Teil des Inquiery-Protokolls erfolgreich beendet wurde, dann kann die anfragende Applikation dem Anwender die Liste der verfügbaren Datenbanken und deren Information 'auf die Nase knallen' und ihn eine Auswahl treffen lassen.

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:

ACC_GETFIELDS

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

ACC_FIELDINFO

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

In That's / no| Address wurden im Moment die Feldtypen FT_CHAR, FT_DATE und FT_TIME implementiert.

3.4 Request/Reply protocol

Es werden zwei weitere Message-Typen eingeführt, um einen allgemeinen Datenaustausch zu ermöglichen:


#define ACC_REQUEST		0x480
#define ACC_REPLY		0x481

ACC_REQUEST

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:

ACC_REPLY

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]:

Applikationen, die oben beschriebene Protokollelemente unterstützen, müssen in ihrer XDSC-Beschreibung das Extended-Feature "RQ" enthalten haben.


Contents Classic XAcc Example: no|Link's XAcc protocol