Previous | Contents | Index |
To end an active session, the desktop client program calls DBEnd as shown in Example 8-12.
Example 8-12 Calling DBEnd |
---|
short status; /* Status Variable */ long sessid1; /* Session Id */ status = DBEnd (sessid1, NULL); |
The DBEnd service also deletes a zombie session created by the DBInit service.
If an error status is returned on the DBEnd service, the session resources are still returned to the Macintosh system and any active connection is broken. You cannot call the DBGetErr service to obtain additional information about an error on the DBEnd service.
In the HyperCard implementation of AVERTZ, DBEnd is called by the ACMSEnd XFCN, invoked in the main stack script, as shown in Example 8-13.
Example 8-13 Calling ACMSEnd |
---|
on killSession sessionID . . . put ACMSEnd (sessionID) into stat . . . end killSession |
A desktop client program calling a TP Desktop Connector client service on the Macintosh typically expects a return status of NoErr.1 If the desktop client program receives an unexpected return status, it can usually call the DBGetErr service to retrieve additional information concerning the error condition. For the specified session identification, the DBGetErr service returns the information shown in Table 8-5.
Parameter | Information |
---|---|
err1 | TP Desktop Connector DDEV status value (--4000 range) |
err2 | ACMS system status value (--3000 range), status value from the communications toolbox in use by the session (--1 or 0 through 11), or other status values |
item1 | Symbol name for the status value returned in the err1 parameter |
item2 | Symbol name for the status value returned in the err2 parameter |
errorMsg | Symbol name for the status returned on the original TP Desktop Connector client service call |
Using information returned in the DBGetErr parameters, the desktop client program can decide how to handle the error condition. Depending on the error, the condition is possibly recoverable. For example, if the return status from the DBState service indicates that a requested task cannot be accessed for security reasons (ACMSDI_SECCHK is returned in the err2 parameter), the desktop client program can simply report the error to the user and allow another task selection without signing the user out of the ACMS system.
Many errors returned on TP Desktop Connector client services are not recoverable. If an unrecoverable error is specific to a particular sign-in, the desktop client program can simply terminate the session and continue processing for other sessions. If the error is more severe, the desktop client program can report the problem to the user, terminate all active sessions, and exit. Example 8-14 shows example code calling the DBGetErr service.
Example 8-14 Calling DBGetErr |
---|
/* * EXIT PROCEDURE - Call DBGetErr to see what happened */ my_exit (short status, long sessid1, char *msg ) { static long int error1; /* Error Declarations for DBGetErr */ static long int error2; static char item1[255]; static char item2[255]; static char errorMsg[255]; static long int error_status; printf ("\n Returned Status code is %d, Message is %s\n", status, msg ); if (sessid1) { error_status = DBGetErr(sessid1,&error1,&error2,&item1,&item2,&errorMsg,NULL); if (error_status != noErr) printf (" DBGetErr error code is %d\n", error_status); else { printf(" Primary Error Message is %s\n",&errorMsg[1]); printf(" Error Message one is %s\n",&item1[1]); printf(" Error Message two is %s\n",&item2[1]); printf(" Status code one is %d, Status code two is %d\n", error1, error2); } status = DBEnd (sessid1, NULL); if (status != noErr) printf (" DBEnd error code is %d\n", status); printf( "\n" ); } exit (0); } |
Because the DBGetErr service requires a valid session identification as a parameter, errors returned on the DBInit service require special handling. If an error occurs on a DBInit call, a session is established but no connection to the ACMS system is established. In most cases, a session identification and the bad return status are passed back to the desktop client program. The desktop client program should handle all errors on DBInit; if the desktop client program receives a bad return status and a session identification on the DBInit call, it must provide special handling for this session, known as a zombie session. The zombie session associated with this session identification differs from a normal session in the following ways:
A zombie session counts toward the maximum number of sessions supported by the TP Desktop Connector DDEV. Use the DBEnd service to remove a zombie session from the desktop system.
Two error conditions can cause a zero session identification to be returned on the DBInit service. These two error conditions are:
If a zero session identification is returned, no zombie session is allocated and no additional error information can be obtained by calling DBGetErr.
The DBGetErr service is called by the ACMSGetErr XFCN. Example 8-15 shows the call to the ACMSGetErr XFCN.
Some characters that can print only in a Macintosh environment are deleted from this example. Check the file supplied with TP Desktop Connector for the precise format. |
Example 8-15 Calling ACMSGetErr |
---|
function GetErr currentsession, cstring global gerr1, gerr2, gitem1, gitem2, gmsg global itemtext1,itemtext2,msgtext,errorfile,avertzlogfile put 0 into got1 put 0 into got2 put bg fld "error" into "gerr1" put ACMSGetErr (currentsession,"gerr1","gerr2","gitem1","gitem2", "gmsg") into status if status <> 0 then return status end if open file errorfile repeat forever read from file errorfile until return if it is empty then write "Error not found" &return to file avertzlogfile exit repeat else if it is return then next repeat end if if item 1 of it = gerr1 then put item 2 of it into errtext1 put 1 into got1 if got2 = 1 then exit repeat end if end if if item 1 of it = gerr2 then put item 2 of it into errtext2 put 1 into got2 if got1 = 1 then exit repeat end if end if end if end repeat close file errorfile if got1 <> 0 and got2 <> 0 then write "Error in "&cstring&" = "&errtext1&","&errtext2 &gitem1&gitem2&gmsg &" for session"¤tsession&return to file avertzlogfile end if if got1 <> 0 and got2 = 0 then write "Error in "&cstring&" = "&errtext1 &" for session"¤tsession&return to file avertzlogfile end if if got2 <> 0 and got1 = 0 then write "Error in "&cstring&" = "&errtext2 &" for session"¤tsession&return to file avertzlogfile end if if got1 = 0 and got2 = 0 then write "Error in "&cstring&" = "&gerr1&","&gerr2&" - text not found" &" for session"¤tsession&return to file avertzlogfile end if return status end GetErr |
You can cancel an active task on a Macintosh system with the DBBreak client service. You cannot use DBBreak while processing and exchange step request. If you call cancel while processing an exchange step request, TP Desktop Connector returns "ACMSDI_EXCHACTV" in DBGetErr. If you issue a cancel when another cancel is already in progress, TP Desktop Connector returns the message "ACMSDI_CANCELACTV".
If you issue a DBGetErr right after a DBBreak, you receive the status of the DBBreak, and not the task call. Issue the client services in the following sequence to receive the anticipated result:
If you are using HyperCard or 4th Dimension, you must write your own externals to cancel a session.
Because of limitations in the MacTCP transport, you cannot use DBBreak with this transport. |
TP Desktop Connector provides two programs on the Macintosh system to delete an orphaned session, a session that remains active even though the application that created it has terminated. Orphaned sessions usually occur during application development, when an application aborts for various reasons leaving the session attached on the gateway end. The two programs are:
1 DBState and DBGetItem are exceptions; they do not return the NoErr status. |
8.3 Exchange Step Support and Other Advanced Features
This section describes how to implement exchange steps in the TP
Desktop Connector Macintosh client using the DAM application
programming interface (API).
8.3.1 DAM Constraints
The DAM API assumes a strict client/server model wherein the desktop device always acts as the client requesting services of the back-end gateway. Sign In, Sign Out and CallTask are three services implemented with DAM using its client/server model. However, exchange steps change this model, reversing the roles of client and server. Thus, after a task is initiated, instead of receiving a response to the CallTask Request in the form of a CallTask Response (End Task) from the back end, the client can receive, instead, a request for services in the form of an exchange step.
The TP Desktop Connector portable API recognizes this reversal of roles by implementing special presentation procedures wherein the application running on the desktop device can play its role of gateway:
The DAM API does not allow for the implementation of presentation procedure callbacks. Therefore, every transmission from the back end must be treated as if it were a response to the previous transmission from the desktop. Thus, a CallTask Request from the desktop can receive any of the following responses:
The back end can send any of these responses (four of which are actually requests) in response to any transmission from the desktop. The desktop, however, must reply to each of these responses as shown in Table 8-6.
Transmission from the Back End | Required Transmission from the Desktop |
---|---|
CallTask response | None allowed |
Send request | Send response |
Receive request | Receive response |
Transceive request | Transceive response |
TDMS request | TDMS response |
During the processing of exchange steps, the desktop becomes the gateway, and must respond with predefined message types to the back-end requests. The DDEV can do very little to assure that the proper responses are received from the back end, except to assure that:
From the client application perspective, six message types are related to calling a task. Each message is a two-way message: request and response. See Table 8-7.
Message Type | Requestor | Respondent |
---|---|---|
CallTask | Desktop | Back end |
Enable | Back end | Desktop |
Send | Back end | Desktop |
Receive | Back end | Desktop |
Transceive | Back end | Desktop |
TDMS | Back end | Desktop |
The application identifies the message types using keywords.
Table 8-8 shows the keywords and corresponding message types.
Keyword | Message Type |
---|---|
CALLTASK | CallTask request/response |
ENABLE | Enable request/response |
SEND | Send request/response |
RECEIVE | Receive request/response |
TRANSCEIVE | Transceive request/response |
TDMS | TDMS request/response |
The desktop application program can both send all keywords to the DDEV and acquire all keywords from the DDEV. The CALLTASK keyword, when acquired, identifies a CallTask Response message (End Task) from the back end. When sent, CALLTASK identifies a CallTask Request message (Start Task). All the other keywords are associated with exchange steps and identify a request from the back end when acquired, and a response from the desktop when sent.
The following sections discuss how to send and acquire keywords.
8.3.3.1 CALLTASK
CALLTASK is passed to the DDEV by the first of a series of prescribed
DBSend or DBSendItem calls, which collectively pass all required
parameters for task initiation. You do not need to acquire the CALLTASK
keyword from the DDEV. If an application program knows that it is
dealing with a NO I/O task, you can immediately issue DBGetItems to get
workspace data. However, you can acquire the CALLTASK keyword from the
DDEV, if necessary. See Section 8.3.3.3 for the method to acquire the
CALLTASK keyword.
8.3.3.2 Keywords that Identify Messages Sent from the Back End
All keywords other than CALLTASK identify request messages from the
back end. When a desktop application program does not know what kind of
message it may be receiving from the back end, it needs to acquire the
message's keyword from the DDEV. See Section 8.3.3.3 for the method to
acquire a message's keyword.
8.3.3.3 Keyword Acquisition Using DBGetItem
After sending a message to the back end with DBExec, the application program issues a series of DBState calls until a status code other than rcDBExec is returned. The status code rcDBExec indicates that the transaction is executing on the back end. The two successful return statuses from DBState are:
In this context, data means workspaces with data.
When the application receives an rcDBNull or rcDBValue status, it knows it has received an error-free message from the back end. For NO I/O tasks (no exchange steps), the only message type it can receive is CallTask Response. However, with exchange steps, the application might not know what type of message has arrived.
To determine the type of message, the application issues a DBGetItem call to the DDEV to acquire the keyword. The DBGetItem has a special data type associated with it to identify the fact that it is meant to acquire a nonworkspace data item; that is, a data item that is not part of a workspace, such as the keyword. Nonworkspace data items are sometimes referred to as the message's header data.
Example 8-16 (written in C) shows how to issue a DBGetItem to acquire the message's keyword.
Example 8-16 Acquiring a Keyword with DBGetItem |
---|
/* ** ELEMENTS DEFINED IN acmsdi_mac.h */ #define maxKWsize 10 /* maximum keyword size */ #define typeHdrItem 'hdit' /* message header item data type */ /* ** PROGRAM CODE FOLLOWS */ unsigned short keyword_len; /* keyword length */ DBType dataType; /* data type for DBGetItem */ char keyword[maxKWsize]; /* keyword */ . . . dataType = typeHdrItem; /* data type is message header item */ keyword_len = maxKWsize; /* keyword field size */ status = DBGetItem (sessID, /* session ID */ NULL, &dataType, /* -> data type */ (short *) &keyword_len, /* -> length of longest keyword */ NULL, NULL, keyword, /* -> where keyword to be returned */ NULL); |
In Example 8-16, all arguments except session identifier are passed by reference, because they are potentially modifiable by the DDEV. This DDEV (acmsdi), however, does not modify the data type field.
Nonworkspace data items are discussed in Section 8.3.4. The first
nonworkspace data item in every logical message type is its keyword,
and Example 8-16 illustrates how to obtain it. However, there is no
requirement that the keyword be obtained. If you know what message type
has been returned, you can start issuing DBGetItems with no data type
specified to obtain workspace data.
8.3.4 Nonworkspace Data Items
Nonworkspace data items are data items that are not part of a workspace. For example, for a CallTask Request (Start Task), you must provide the task name and the application name. These parameters are not part of any workspace but are inserted into the header portion of the message. All messages have some kind of nonworkspace data that needs to be sent to the DDEV or, in some cases, acquired from the DDEV.
Figure 8-4 illustrates nonworkspace data.
Figure 8-4 Nonworkspace Data
A CallTask Request message has the following nonworkspace data items that must be sent from the application to the DDEV:
The four nonworkspace data items plus the keyword, to identify the message type, are sent to the DDEV by five prescribed DBSend or DBSendItem calls. This method is not restricted to CallTask Request messages. The nonworkspace data associated with the Enable, Send, Receive, Transceive, and TDMS Response messages must be sent to the DDEV in a series of DBSend or DBSendItem calls. The general rule is that you must send the keyword first, followed by each of the required nonworkspace data items in a prescribed order.
The Table 8-9 shows the items that must be sent with each message type and the prescribed order in which they must be sent.
Message | Items |
---|---|
CallTask request |
Keyword (CALLTASK)
Task name Application name Selection string Number of workspaces |
Enable response |
Keyword (ENABLE)
Desktop status Forms session ID |
Send response |
Keyword (SEND)
Desktop status Receive control text Receive control text count |
Receive response |
Keyword (RECEIVE)
Desktop status Receive control text Receive control text count Number of workspaces |
Transceive response |
Keyword (TRANSCEIVE)
Desktop status Receive control text Receive control text count Number of workspaces |
TDMS response |
Keyword (TDMS)
Desktop status Number of workspaces |
Previous | Next | Contents | Index |