JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
ToolTalk User's Guide
search filter icon
search icon

Document Information

Preface

1.  Introducing the ToolTalk Service

2.  An Overview of the ToolTalk Service

3.  Message Patterns

4.  Setting Up and Maintaining the ToolTalk Processes

5.  Maintaining Application Information

6.  Maintaining Files and Objects Referenced in ToolTalk Messages

7.  Participating in ToolTalk Sessions

8.  Sending Messages

How the ToolTalk Service Routes Messages

Sending Notices

Sending Requests

Sending Offers

Changes in State of Sent Message

Message Attributes

Address Attribute

Scope Attributes

File Scope

File-based Scoping in Patterns

File-based Scoping in Messages

Session Scope

File-In-Session Scope

Serialization of Structured Data

ToolTalk Message Delivery Algorithm

Process-Oriented Message Delivery

Example

Object-Oriented Message Delivery

Example

Otype Addressing

Modifying Applications to Send ToolTalk Messages

Creating Messages

Using the General-Purpose Function to Create ToolTalk Messages

Class

Address

Scope

Op

Args

Creating Process-Oriented Messages

Creating and Completing Object-Oriented Messages

Adding Message Callbacks

Sending a Message

Examples

9.  Dynamic Message Patterns

10.  Static Message Patterns

11.  Receiving Messages

12.  Objects

13.  Managing Information Storage

14.  Handling Errors

A.  Migrating from the Classing Engine to the ToolTalk Types Database

B.  A Simple Demonstration of How the ToolTalk Service Works

C.  The ToolTalk Standard Message Sets

D.  Frequently Asked Questions

Glossary

Index

Modifying Applications to Send ToolTalk Messages

To send ToolTalk messages, your application must perform several operations: it must be able to create and complete ToolTalk messages; it must be able to add message callback routines; and it must be able to send the completed message.

Creating Messages

The ToolTalk service provides three methods to create and complete messages:

  1. General-purpose function

    • tt_message_create()

  2. Process-oriented notice and request functions

    • tt_pnotice_create()

    • tt_prequest_create()

  3. Object-oriented notice and request functions

    • tt_onotice_create()

    • tt_orequest_create()

The process- and object-oriented notice and request functions make message creation simpler for the common cases. They are functionally identical to strings of other tt_message_create() and tt_message_ attribute__set() calls, but are easier to write and read. and list the ToolTalk functions that are used to create and complete message

Table 8-4 Functions Used to Create Messages

ToolTalk Function
Description
tt_onotice_create(const char *objid, const char *op)
Creates an object-oriented notice.
tt_orequest_create(const char *objid, const char *op)
Creates an object-oriented request.
tt_pnotice_create(Tt_scope scope, const char *op)
Creates a process-oriented notice.
tt_prequest_create(Tt_scope scope, const char *op)
Creates a process-oriented request.
tt_message_create(void)
Creates a message. This function is the ToolTalk general purpose function to create messages.

Note - The return type for all the create functions is Tt_message.


Table 8-5 Functions Used to Complete Messages

ToolTalk Function
Description
tt_message_address_set(Tt_message m, Tt_address p)
Sets addressing mode (for example, point-to-point).
tt_message_arg_add(Tt_message m, Tt_mode n, const char *vtype, const char *value)
Adds a null-terminated string argument.
tt_message_arg_bval_set(Tt_message m, int n, const unsigned char *value, int len)
Sets an argument's value to the specified byte array.
tt_message_arg_ival_set(Tt_message m, int n, int value)
Sets an argument's value to the specified integer.
tt_message_arg_val_set(Tt_message m, int n, const char *value)
Sets an argument's value to the specified null-terminated string.
tt_message_barg_add(Tt_message m, Tt_mode n, const char *vtype, const unsigned char *value, int len)
Adds a byte array argument.
tt_message_iarg_add(Tt_message m, Tt_mode n, const char *vtype, int value)
Adds an integer argument.
tt_message_context_bval(Tt_message m, const char *slotname, unsigned char **value, int *len);
Gets a context's value to the specified byte array.
tt_message_context_ival(Tt_message m, const char *slotname, int *value);
Gets a context's value to the specified integer.
tt_message_context_val(Tt_message m, const char *slotname);
Gets a context's value to the specified string.
tt_message_icontext_set(Tt_message m, const char *slotname, int value);
Sets a context to the specified integer.
tt_message_bcontext_set(Tt_message m, const char *slotname, unsigned char *value, int length);
Sets a context to the specified byte array.
tt_message_context_set(Tt_message m, const char *slotname, const char *value);
Sets a context to the specified null-terminated string.
tt_message_class_set(Tt_message m, Tt_class c)
Sets the type of message (either notice or request)
tt_message_file_set(Tt_message m, const char *file)
Sets the file to which the message is scoped.
tt_message_handler_ptype_set(Tt_message m, const char *ptid)
Sets the ptype that is to receive the message.
tt_message_handler_set(Tt_message m, const char *procid)
Sets the procid that is to receive the message.
tt_message_object_set(Tt_message m, const char *objid)
Sets the object that is to receive the message.
tt_message_op_set(Tt_message m, const char *opname)
Sets the operation that is to receive the message.
tt_message_otype_set(Tt_message m, const char *otype)
Sets the object type that is to receive the message.
tt_message_scope_set(Tt_message m, Tt_scope s)
Sets the recipients who are to receive the message (file, session, both).
tt_message_sender_ptype_set(Tt_message m, const char *ptid)
Sets the ptype of the application that is sending the message.
tt_message_session_set(Tt_message m, const char *sessid)
Sets the session to which the message is scoped.
tt_message_status_set(Tt_message m, int status)
Sets the status of the message; this status is seen by the receiving application.
tt_message_status_string_set(Tt_message m, const char *status_str)
Sets the text that describes the status of the message; this text is seen be the receiving application.
tt_message_user_set(Tt_message m, int key, void *v)
Sets a message that is internal to the sending application. This internal message is opaque data that is not seen by the receiving application.
tt_message_abstainer(Tt_message m, int n)
Returns the procid of the n'th abstainer of the specified message.
tt_message_abstainers_count(Tt_message m)
Returns a count of the procids that are recorded in the TT_OFFER m as having abstained from it.
tt_message_accepter(Tt_message m,int n)
Returns the procid of the n'th accepter of the specified message.
tt_message_accepters_count(Tt_message m)
Returns a count of the procids that are recorded in the TT_OFFER m as having accepted it.
tt_message_rejecter(Tt_message m,int n)
Returns the procid of the n'th rejector of the specified message.
tt_message_rejecters_count(Tt_message m)

Returns a count of the procids that are recorded in the TT_OFFER m as having rejected it.

Note - The return type for all the functions used to complete messages is Tt_status


Using the General-Purpose Function to Create ToolTalk Messages

You can use the general-purpose function tt_message_create() to create and complete ToolTalk messages. If you create a process- or object-oriented message with tt_message_create(), use the tt_message_attribute_set() calls to set the attributes.

Class
Address

Note - Offers can only be sent with address TT_PROCEDURE. Attempting to send an Offer with any other address will generate an error of TT_ERR_ADDRESS.


Scope

Fill in the scope of the message delivery. Potential recipients could be joined to:

Depending on the scope, the ToolTalk service will add the default session or file, or both to the message.

Note that Offers can only be sent in TT_SESSION scope.

Op

Fill in the operation that describes the notification or request that you are making. To determine the operation name, consult the ptype definition for the target recipient or the message protocol definition.

Args

Fill in any arguments specific to the operation. Use the function that best suits your argument's data type:

For each argument you add (regardless of the value type), specify:


Note - It is very important that senders and receivers define particular vtype names so that a receiver does not attempt to retrieve a value that was stored in another fashion; for example, a value stored as an integer but retrieved as a string.


Creating Process-Oriented Messages

You can easily create process-oriented notices and requests. To get a handle or opaque pointer to a new message object for a procedural notice or request, use the tt_pnotice_create or tt_prequest_create function. You can then use this handle on succeeding calls to reference the message.

When you create a message with tt_pnotice_create or tt_prequest_create, you must supply the following two attributes as arguments:

  1. Scope

    Fill in the scope of the message delivery. Potential recipients could be joined to:

    • TT_SESSION

    • TT_FILE

    • TT_BOTH

    • TT_FILE_IN_SESSION

    Depending on the scope, the ToolTalk service fills in the default session or file (or both).

  2. Op

    Fill in the operation that describes the notice or request you are making. To determine the operation name, consult the ptype definition for the target process or other protocol definition.

You use the tt_message_attribute_set calls to complete other message attributes such as operation arguments.

Creating and Completing Object-Oriented Messages

You can easily create object-oriented notices and requests. To get a handle or opaque pointer to a new message object for a object-oriented notice or request, use the tt_onotice_create or tt_orequest_create function. You can then use this handle on succeeding calls to reference the message.

When you create a message with tt_onotice_create or tt_orequest_create, you must supply the following two attributes as arguments:

  1. Objid

    Fill in the unique object identifier.

  2. Op

    Fill in the operation that describes the notice or request you are making. To determine the operation name, consult the ptype definition for the target process or other protocol definition.

You use the tt_message_attribute_set calls to complete other message attributes such as operation arguments.

Adding Message Callbacks

When a request contains a message callback routine, the callback routine is automatically called when the reply is received to examine the results of the reply and take appropriate actions.


Note - Callbacks are called in reverse order of registration (for example, the most recently added callback is called first).


You use tt_message_callback_add to add the callback routine to your request. When the reply comes back and the reply message has been processed through the callback routine, the reply message must be destroyed before the callback function returns TT_CALLBACK_PROCESSED. To destroy the reply message, use tt_message_destroy, as illustrated in .

Example 8-4 Destroying a Message

Tt_callback_action
sample_msg_callback(Tt_message m, Tt_pattern p)
{
    ... process the reply msg ...

    tt_message_destroy(m);
    return TT_CALLBACK_PROCESSED;
}

The following code sample is a callback routine, cntl_msg_callback, that examines the state field of the reply and takes action if the state is started, handled, or failed.

/*
 * Default callback for all the ToolTalk messages we send.
 */

Tt_callback_action
cntl_msg_callback(m, p)
     Tt_message m;
     Tt_pattern p;
{
    int        mark;
    char        msg[255];
    char        *errstr;


    mark = tt_mark();
    switch (tt_message_state(m)) {
          case TT_STARTED:
            xv_set(cntl_ui_base_window, FRAME_LEFT_FOOTER,
               "Starting editor...", NULL);
            break;
          case TT_HANDLED:
            xv_set(cntl_ui_base_window, FRAME_LEFT_FOOTER, "", NULL);
            break;
          case TT_FAILED:
            errstr = tt_message_status_string(m);
            if (tt_pointer_error(errstr) == TT_OK && errstr) {
            sprintf(msg,"%s failed: %s", tt_message_op(m), errstr);
            } else if (tt_message_status(m) == TT_ERR_NO_MATCH) {
            sprintf(msg,"%s failed: Couldn't contact editor",
                tt_message_op(m),
                tt_status_message(tt_message_status(m)));
            } else {
            sprintf(msg,"%s failed: %s",
                tt_message_op(m),
                tt_status_message(tt_message_status(m)));
            }
            xv_set(cntl_ui_base_window, FRAME_LEFT_FOOTER, msg, NULL);
            break;
          default:
            break;
    }
    /*
     * no further action required for this message. Destroy it
     * and return TT_CALLBACK_PROCESSED so no other callbacks will
     * be run for the message.
     */
    tt_message_destroy(m);
    tt_release(mark);
    return TT_CALLBACK_PROCESSED;
}

You can also add callbacks to static patterns by attaching a callback to the opnum of a signature in a ptype. When a message is delivered because it matched a static pattern with an opnum, the ToolTalk service checks for any callbacks attached to the opnum and runs them.

Sending a Message

When you have completed your message, use tt_message_send to send it.

If the ToolTalk service returns TT_WRN_STALE_OBJID, it has found a forwarding pointer in the ToolTalk database that indicates the object mentioned in the message has been moved. However, the ToolTalk service will send the message with the new objid. You can then use tt_message_object to retrieve the new objid from the message and put it into your internal data structure.

If you will not need the message in the future (for example, if the message was a notice), you can use tt_message_destroy to delete the message and free storage space.


Note - If you are expecting a reply to the message, do not destroy the message until you have handled the reply.