Samples

Code examples.

z/OS samples provided

On z/OS®, examples can also be found in the SCYTSAMP file, as described in Table 1.

Table 1. Samples in the SCYTSAMP library
Language Member Description
HLASM CYTAASM Sample HLASM program to send events.
CYTAINIT Macro to call the CYTA_init function.
CYTATRAK Macro to call the CYTA_track function.
CYTATOK Macro to call the CYTA_token function.
CYTAEVNT Macro to map an event.
CYTACFG Macro to map a Configuration Block.
CYTANVAL Macro to map a Name/Value pair entry.
CYTANV Macro to create a Name/Value pair entry.
CYTADFV Macro to create Name/Value pairs to specify the minimal Vertical Context for an event.
COBOL CYTABCFG COBOL definitions for a Configuration Block.
CYTABCON COBOL constants required to use the Transaction Tracking API.
CYTABEVT COBOL definitions for an event.
CYTABNV COBOL definitions for a Name/Value pair entry.
CYTABSMP Sample COBOL program to send events.
C CYTACSMP Sample C program to send events. C header file definitions are in the SCYTH dataset.
Java™ CYTAJSMP Sample Java program to send events.
PL/I CYTAPCFG PL/I definitions for a Configuration Block.
CYTAPEVT PL/I definitions for an event.
CYTAPNV PL/I definitions for a Name/Value pair entry.
CYTAPSMP Sample PL/I program to send events.
All CYTASIDE Binder Side Deck required by dynamic callers.

C

/*================================================================
  Includes  
  ===============================================================*/ 
#pragma runopts(POSIX(ON)) 
#pragma runopts(TRAP(ON,SPIE))  
#include <cytapi.h> 
#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 
#include <unistd.h>  
/*================================================================  
Mainline Code  
================================================================ */ 
int main(int argc, char **argv) 
{
    /* ---------------------------------------------------------------
       Variables
       --------------------------------------------------------------- */
      int rc;                            /* Return code from functions  */
      int hlink1;                        /* Store numeric Hor Link IDs  */
      /* --- Area for Communications Configuration Block -------------- */
     cyta_config_t configblk;           /* Configuration block         */
      /* --- Area for Event Block ------------------------------------- */
     cyta_event_t eventblk;             /* Event block                 */
      /* --- Area for 'Standard' Vertical Context Name/Value Pairs ---- */
     cyta_values_list_t vert1, vert2, vert3, vert4; /* Vertical Context*/
     /* ---------------------------------------------------------------
       Put together 'standard' Vertical Contexts
       
			These are the minimum Vertical Context needed to display
       event in ITCAM for Txns workspaces. We need:
          HOST - Host Name. Normally Sysplex/SMFID
          COMPONENT - Component - what we are running under -eg.
             BATCH, STC, IMS, CICS, WAS, TSO.
          APPLICATION - Usually Job or Started Task Name
          TRANSACTION - The transaction we are running

       In your program, you will modify the values to suit your
       installation, however the names of the name/value pairs should
       not be changed
       --------------------------------------------------------------- */
    /* --- Hostname -------------------------------------------------- */
     memset(&vert1, 0, sizeof(vert1));
     static char *server = "Sysplex/Host";
     static char *server_lbl = "ServerName";
     vert1.name = server_lbl;
     vert1.value = server;
     vert1.size = strlen(server);
     /* --- ComponentName---------------------------------------------- */
     memset(&vert2, 0, sizeof(vert2));
     static char *component = "STC";
     static char *component_lbl = "ComponentName";
     vert1.next = &vert2;
     vert2.name = component_lbl;
     vert2.value = component;
     vert2.size = strlen(component);
     /* --- ApplicationName ------------------------------------------- */
     memset(&vert3, 0, sizeof(vert3));
     static char *application = "Application";
     static char *application_lbl = "ApplicationName";
     vert2.next = &vert3;
     vert3.name = application_lbl;
     vert3.value = application;
     vert3.size = strlen(application);
     /* --- Transaction (no EBCDIC -> ASCII Translation) -------------- */
     memset(&vert4, 0, sizeof(vert4));
     static int transaction = 254;      /* Value is a number: 254      */
     static char *transaction_lbl = "TransactionName";
     vert3.next = &vert4;
     vert4.name = transaction_lbl;
     vert4.value = &transaction;
     vert4.size = sizeof(transaction);
     vert4.flags = CYTA_VALUELIST_FLAG_VALUE_RAW;/* No translation     */
     /* ---------------------------------------------------------------
       Get Configuration Token
          The server field specifies where the ITCAM for Transactions
          events are to be sent. It must be of the form:
             SSN:sub
          Where sub is the 4 character subsystem name used by the ITCAM
          for Transactions Collector Started Task
       --------------------------------------------------------------- */
     memset(&configblk, 0, sizeof(configblk));  /* Zero config block   */
     configblk.server = "SSN:CYTZ";     /* Send events to CYTZ subsys  */
     rc = CYTA_init(&configblk);        /* Get the token               */
     printf("(CYTACSMP) CYTAINIT Return Code=%d\n", rc);
     /* ---------------------------------------------------------------
       Send a 'Started' Event
          We don't specify a timestamp, so the time now is automatically
          inserted.
       --------------------------------------------------------------- */
     memset(&eventblk, 0, sizeof(eventblk));  /* Zero event block      */
     eventblk.type = CYTA_STARTED_EVENT;      /* Started Event         */
     eventblk.vertical_context = &vert1;      /* Vertical Context Addr */
     eventblk.vertical_id.link_id = "CYTACSMP";  /* Vertical Link ID   */
     eventblk.vertical_id.link_id_size = 8;   /* Link ID Length        */
     rc = CYTA_track(&configblk, &eventblk);  /* Send the event        */
     printf("(CYTACSMP) STARTED Event Return Code=%d\n", rc);
     /* ---------------------------------------------------------------
       Send an Outbound Event
       (we only need to specify changed fields - all other fields remain
       from the Started event)
       --------------------------------------------------------------  */
     eventblk.type = CYTA_OUTBOUND_EVENT;     /* Started Event         */
     eventblk.horizontal_id.link_id = "Hlink Value";/* Horizontal ID   */
     eventblk.horizontal_id.link_id_size = 11;/* Link ID Length        */
     rc = CYTA_track(&configblk, &eventblk);  /* Send the event        */
     printf("(CYTACSMP) OUTBOUND Event Return Code=%d\n", rc);
     /* ---------------------------------------------------------------
       Send an Inbound Finished Event
       We change the Horizontal Link to the incoming Link ID - this
        is the ID specified by the application sending the response
        in its OUTBOUND event. In this case, the Link ID is a number,
        so we MUST set the flag so it is NOT translated from EBCDIC to
        ASCII.
       --------------------------------------------------------------  */
     eventblk.type = CYTA_INBOUND_FINISHED_EVENT;   /* Event Type      */
     hlink1 = 56;                       /* Horizontal Link ID=56       */
     eventblk.horizontal_id.link_id = &hlink1 /* Horizontal ID         */
     eventblk.horizontal_id.link_id_size = 4; /* Link ID Length        */
     eventblk.horizontal_id.flags = CYTA_ASSOCIATION_FLAG_LINK_RAW;
                                        /* Do NOT xlate from EBCDIC    */
     rc = CYTA_track(&configblk, &eventblk);  /* Send the event        */
     printf("(CYTACSMP) INBOUND FINISHED Event Return Code=%d\n", rc);
 }                                      /* main                        */ 

COBOL

CBL   RENT,PGMNAME(LM),LIB,NODYNAM,NODLL
      * =============================================================
      *
      * Identification Division
      *
      * =============================================================
       IDENTIFICATION DIVISION.

       PROGRAM-ID. "CYTABSMP".

      * =============================================================
      *
      * Environment Division
      *
      * =============================================================
       ENVIRONMENT DIVISION.

      * =============================================================
      *
      * Data Division
      *
      * =============================================================
       DATA DIVISION.
       Working-Storage Section.
      * -------------------------------------------------------------
      * Constants Needed to Use the ITCAM for Txns API
      * -------------------------------------------------------------
       COPY CYTABCON.

      * -------------------------------------------------------------
      * Area to hold our event block
      * -------------------------------------------------------------
       COPY CYTABEVT.

      * -------------------------------------------------------------
      * Area to hold our Configuration Block
      * -------------------------------------------------------------
       COPY CYTABCFG.

      * -------------------------------------------------------------
      * Area for 'Standard' 4 Vertical Context Name/Value pairs.
      *    These are the minimum Vertical Context needed to display
      *    event in ITCAM for Txns workspaces
      *       HOST - Host Name. Normally Sysplex/SMFID
      *       COMPONENT - Component - what we are running under -eg.
      *          BATCH, STC, IMS, CICS, WAS, TSO.
      *       APPLICATION - Usually Job or Started Task Name
      *       TRANSACTION - The transaction we are running
      *
      *    Each has three variables:
      *       xxx-LBL - the label of the Name/Value Pair, ending in
      *                 nulls.
      *       xxx     - area to hold the actual value
      *       xxx-NV  - area to hold the name/value pair
      *
      *    In your program, you will modify the values to suit your
      *    installation, however the labels should not be changed
      * -------------------------------------------------------------
       01  HOST-LBL               pic x(11) value z"ServerName".
       01  HOST                   pic x(12) value "Sysplex/Host".
       01  HOST-NV                pic x(16).

       01  COMPONENT-LBL          pic x(14) value z"ComponentName".
       01  COMPONENT              pic x(3)  value "STC".
       01  COMPONENT-NV           pic x(16).

       01  APPLICATION-LBL        pic x(16) value z"ApplicationName".
       01  APPLICATION            pic x(11) value "Application". 
       
01  APPLICATION-NV         pic x(16).

       01  TRANSACTION-LBL        pic x(16) value z"TransactionName".
       01  TRANSACTION            pic s9(9) binary value 254.
       01  TRANSACTION-NV         pic x(16).

      * -------------------------------------------------------------
      * Outbound and Inbound Horizontal Link IDs
      *    For your organisation, specify unique values here. But
      *    for this example, constant values will be used
      *    HLINK-OUT - Outgoing Horizontal Link (string)
      *    HLINK-IN  - Incoming Horizontal Link (number)
      * -------------------------------------------------------------
       01  HLINK-OUT                   pic x(11) value 'HLINK VALUE'.
       01  HLINK-IN                    pic s9(9) binary value 56.

      * -------------------------------------------------------------
      * Vertical Link ID
      *    This value should be unique for every work unit. We will
      *    use a constant in this example.
      * -------------------------------------------------------------
       01  VLINK                       pic x(8) value 'CYTABSMP'.

      * -------------------------------------------------------------
      * String Specifying Destination for Events
      *    This must be of the form SSN:sub - sub is the ITCAM for
      *    Transactions Container subsystem.
      * -------------------------------------------------------------
       01  SERVER                      pic x(8) value 'SSN:CYTZ'.

      * -------------------------------------------------------------
      * Definition used to insert a one byte length field
      *    LINK-LEN - Halfword Link Name length
      *    LINK-LEN-BYTE - One byte Link Name length
      * -------------------------------------------------------------
       01  LINK-LEN                    pic s9(3) binary.
       01  LINK-LEN-STR                redefines LINK-LEN.
           02   filler                 pic x(1).
           02   LINK-LEN-BYTE          pic x(1).

      * -------------------------------------------------------------
      * Fullword to hold return code from CYTA_track
      * -------------------------------------------------------------
       01  RC                          pic S9(9) comp.

       Linkage Section.
      * -------------------------------------------------------------
      * Map Name/Value Pair Entry
      * -------------------------------------------------------------
       COPY CYTABNV.

      * =============================================================
      *
      * Procedure Division
      *
      * =============================================================
       PROCEDURE DIVISION.
           DISPLAY "(CYTABSMP) Entry".

      * -----------------------------------------------------------
      * Initialize Our Event Block
      * -----------------------------------------------------------
           INITIALIZE CYTA-EVENT REPLACING ALPHANUMERIC BY x"00".

      * -----------------------------------------------------------
      * Setup a Name/Value Pair for Host
      *    1. Address the Name/Value pair
      *    2. Initialise the Name/Value pair to nulls
      *    3. Set the Name pointer
      *    4. Set the Value pointer
      *    5. Set the Value length
      * -----------------------------------------------------------
           SET ADDRESS OF CYTA-NV-LIST TO ADDRESS OF HOST-NV.
           INITIALIZE CYTA-NV-LIST REPLACING ALPHANUMERIC BY x"00".
           SET CYTA-NV-NAME-POINTER TO ADDRESS OF HOST-LBL.
           SET CYTA-NV-VALUE-POINTER TO ADDRESS OF HOST.
           MOVE LENGTH OF HOST TO CYTA-NV-VALUE-LENGTH.

      * -----------------------------------------------------------
      * Setup a Name/Value Pair for Component
      *    1. Host Name/Value pair chains to Component Name/Value pair
      *    2. (steps as for Host Name/Value Pair)
      *    7. Stop EBCDIC->ASCII transaction of Department ID (as it
      *       is a number, not a string)
      * -----------------------------------------------------------
           SET CYTA-NV-NEXT-POINTER TO ADDRESS OF COMPONENT-NV.
           SET ADDRESS OF CYTA-NV-LIST TO ADDRESS OF COMPONENT-NV.
           INITIALIZE CYTA-NV-LIST REPLACING ALPHANUMERIC BY x"00".
           SET CYTA-NV-NAME-POINTER TO ADDRESS OF COMPONENT-LBL.
           SET CYTA-NV-VALUE-POINTER TO ADDRESS OF COMPONENT.
           MOVE LENGTH OF COMPONENT TO CYTA-NV-VALUE-LENGTH.

      * -----------------------------------------------------------
      * Setup a Name/Value Pair for Application
      * -----------------------------------------------------------
           SET CYTA-NV-NEXT-POINTER TO ADDRESS OF APPLICATION-NV.
           SET ADDRESS OF CYTA-NV-LIST TO ADDRESS OF APPLICATION-NV.
           INITIALIZE CYTA-NV-LIST REPLACING ALPHANUMERIC BY x"00".
           SET CYTA-NV-NAME-POINTER TO ADDRESS OF APPLICATION-LBL.
           SET CYTA-NV-VALUE-POINTER TO ADDRESS OF APPLICATION.
           MOVE LENGTH OF APPLICATION TO CYTA-NV-VALUE-LENGTH.

      * -----------------------------------------------------------
      * Setup a Name/Value Pair for Transaction
      *    Note that the Transaction Value is a number, so we
      *    set the flags so that NO EBCDIC to ASCII translation
      *    will be performed.
      * -----------------------------------------------------------
           SET CYTA-NV-NEXT-POINTER TO ADDRESS OF TRANSACTION-NV.
           SET ADDRESS OF CYTA-NV-LIST TO ADDRESS OF TRANSACTION-NV.
           INITIALIZE CYTA-NV-LIST REPLACING ALPHANUMERIC BY x"00".
           SET CYTA-NV-NAME-POINTER TO ADDRESS OF TRANSACTION-LBL.
           SET CYTA-NV-VALUE-POINTER TO ADDRESS OF TRANSACTION.
           MOVE LENGTH OF TRANSACTION TO CYTA-NV-VALUE-LENGTH.
           MOVE CYTA-DONT-TR-VALUE-FROM-EBCDIC TO CYTA-NV-FLAGS.

      * -----------------------------------------------------------
      * Call CYTA_init to get Configuration Token
      *    1. Specify server string - if this is omitted, the
      *       default is: SSN:CYTZ
      *    2. Call CYTA_init
      * -----------------------------------------------------------
           SET CYTA-CFG-SERVER TO ADDRESS OF SERVER.

           CALL "CYTA_init" USING CYTA-CFG-BLOCK RETURNING RC.
           DISPLAY "(CYTABSMP) CYTA_init Return Code=" RC.

      * -----------------------------------------------------------
      * Send a STARTED event
      *    1. Move in event type
      *    2. Move in Vertical link ID
      *    3. Move in Vertical link length
      *    4. (Don't specify time, so it is automatically inserted)
      *    5. Specify Vertical Context that we've built
      *    6. Call the API (statically linked).
      * -----------------------------------------------------------
           MOVE CYTA-STARTED TO CYTA-E-TYPE.
           SET CYTA-E-VERT-LINK-ID TO ADDRESS OF VLINK.
           MOVE LENGTH OF VLINK TO LINK-LEN.
           MOVE LINK-LEN-BYTE TO CYTA-E-VERT-LINK-LENGTH.
           SET CYTA-E-VERT-CONTEXT-LIST TO ADDRESS OF HOST-NV.

           CALL "CYTA_track" USING CYTA-CFG-BLOCK CYTA-EVENT
              RETURNING RC.
           DISPLAY "(CYTABSMP) STARTED Event Return Code=" RC.

      * -----------------------------------------------------------
      * Send an OUTBOUND event
      *    1. Move in event type
      *    2. (No need to change Vertical Link or Context)
      *    3. Specify Horizontal Link (program at other end will
      *       need to specify this on it's INBOUND event).
      *    4. Specify Horizontal Link length
      *    5. Call the API
      * -----------------------------------------------------------
           MOVE CYTA-OUTBOUND TO CYTA-E-TYPE.
           SET CYTA-E-HORZ-LINK-ID TO ADDRESS OF HLINK-OUT.
           MOVE LENGTH OF HLINK-OUT TO LINK-LEN.
           MOVE LINK-LEN-BYTE TO CYTA-E-HORZ-LINK-LENGTH.

           CALL "CYTA_track" USING CYTA-CFG-BLOCK CYTA-EVENT
              RETURNING RC.
           DISPLAY "(CYTABSMP) OUTBOUND Event Return Code=" RC.

      * -----------------------------------------------------------
      * Send an INBOUND FINISHED event
      *    1. Move in event type
      *    2. (No need to change Vertical Link or Context)
      *    3. Specify Horizontal Link (program at other end will
      *       need to specify this on it's OUTBOUND event).
      *    4. Specify Horizontal Link length
      *    5. As Horizontal Link is a number, stop conversion from
      *       EBCDIC
      *    6. Call the API
      * -----------------------------------------------------------
           MOVE CYTA-INBOUND-FINISHED TO CYTA-E-TYPE.
           SET CYTA-E-HORZ-LINK-ID TO ADDRESS OF HLINK-IN.
           MOVE LENGTH OF HLINK-IN TO LINK-LEN.
           MOVE LINK-LEN-BYTE TO CYTA-E-HORZ-LINK-LENGTH.
           MOVE CYTA-DONT-TR-FROM-EBCDIC TO CYTA-E-HORZ-LINK-FLAGS.

           CALL "CYTA_track" USING CYTA-CFG-BLOCK CYTA-EVENT
              RETURNING RC.
           DISPLAY "(CYTABSMP) INBOUND FINISHED Event Return Code=" RC.

      * -----------------------------------------------------------
      * And we're done
      * -----------------------------------------------------------

           GOBACK.

Java

import ttapi4j.ServerFactory;
import ttapi4j.Server;
import ttapi4j.Event;
import ttapi4j.InstanceID;

public class CYTAJSMP
{
    public static void main(String[] args) throws Exception
    {
        System.out.println("(CYTAJSMP) Entry");

        /* --- Get Configuration Token - Sending to Subsys CYTZ  ---- */
        Server s = ServerFactory.getServer("ssn:CYTZ");

        /* --- Create Started Event  -------------------------------- */
        Event e = s.createEvent();
        e.setType(Event.Type.STARTED);
        e.getVerticalID().setLinkID("CYTAJSMP");
        e.getVerticalContext().put("ServerName","Sysplex/Host");
        e.getVerticalContext().put("ComponentName", "USS Shell");
        e.getVerticalContext().put("ApplicationName", "Application");
        e.getVerticalContext().put("TransactionName", "CYTAJSMP");
        s.track(e);

        /* --- Create Outbound Event  ------------------------------- */
        e.getHorizontalID().setLinkID("Hlink Value");
        e.setType(Event.Type.OUTBOUND);
        s.track(e);

        /* --- Create Inbound Finished Event  ----------------------- */
        e.setType(Event.Type.INBOUND_FINISHED);
        s.track(e);

        /* --- Cleanup and Exit ------------------------------------- */
        s.close();
        System.out.println("(CYTAJSMP) Exit");
    }
}

PL/I

%PROCESS Limits(Extname(15)) Source Arch(1);
%PROCESS Default(Linkage(Optlink) Nullsys);
%PROCESS Margins(2,72) Rules(IBM) System(MVS);
 CYTAPSMP: Procedure Options(main);

 /*===================================================================

  Storage Definitions

  ====================================================================*/
 /* -----------------------------------------------------------------
    Include Structures for ITCAM for Transactions
    ----------------------------------------------------------------- */
 %include CYTAPEVT;
 %include CYTAPCFG;
 %include CYTAPNV;

 /* -----------------------------------------------------------------
    Declarations for 'Standard' 4 Vertical Context Name/Value pairs.
       These are the minimum Vertical Context needed to display
       an event in ITCAM for Txns workspaces:
          Host        - Host Name. Normally Sysplex/SMFID
          Component   - Component - what we are running under, like:
             BATCH, STC, IMS, CICS, WAS, or TSO.
          Application - Usually Job or Started Task Name
          Transaction - The transaction we are running

       We're defining three variables each:
          xxxlbl  - the label of the Name/Value Pair, ending in
                    nulls.
          xxxnam  - area to hold the actual value
          xxxaddr - address of name/value pair

       In your program, you will modify the values to suit your
       installation, however the labels should not be changed
    ----------------------------------------------------------------- */
 Dcl hostaddr    Pointer;
 Dcl hostlbl     Char(11) Varyingz Init('ServerName');
 Dcl hostnam     Char(12) Init('Sysplex/Host');

 Dcl compaddr    Pointer;
 Dcl complbl     Char(14) Varyingz Init('ComponentName');
 Dcl compnam     Char(3)  Init('STC');

 Dcl appladdr    Pointer;
 Dcl appllbl     Char(16) Varyingz Init('ApplicationName');
 Dcl applnam     Char(11) Init('Application');

 Dcl tranaddr    Pointer;
 Dcl tranlbl     Char(16) Varyingz Init('TransactionName');
 Dcl trannam     Fixed(32) Binary Unsigned Init(254);

 /* -----------------------------------------------------------------
    Outbound and Inbound Horizontal Link IDs
       For your organisation, specify unique values here. But
       for this example, constant values will be used
       hlinkout  - Outgoing Horizontal Link (string)
       hlinkin   - Incoming Horizontal Link (number)
    ----------------------------------------------------------------- */
 Dcl hlinkout    Char(11) Init("Hlink Value");
 Dcl hlinkin     Fixed(32) Binary Unsigned Init(56);

 /* -----------------------------------------------------------------
    Vertical Link ID
       This value should be unique for every work unit. We will
       use a constant in this example.
    ----------------------------------------------------------------- */
 Dcl vlink       Char(8) Init("CYTAPSMP");

 /* -----------------------------------------------------------------
    Communications Server
       This string specifies where the ITCAM for Transactions Events
       are to be sent. It must be of the form:
          SSN:sub
       Where sub is the 4 character subsystem name used by the ITCAM
       for Transactions Collector Started Task
    ----------------------------------------------------------------- */
 Dcl server      Char(8) Init("SSN:CYTZ");

 /* -----------------------------------------------------------------
    Area that will hold Event Block and all Name/Value Pairs
    ----------------------------------------------------------------- */
 Dcl stgarea     Area;                 /* stgarea is 1000 bytes long  */

 /*===================================================================

  Main Program

  ====================================================================*/

 /* -----------------------------------------------------------------
    Setup Name/Value Pair for Host
    ----------------------------------------------------------------- */
 Allocate cytanval In(stgarea);        /* Allocate storage            */
 hostaddr = cytanvalp;                 /* Save the address            */
 cytannam = Addr(hostlbl);             /* Name                        */
 cytanvl  = Addr(hostnam);             /* Value                       */
 cytanvll = Length(hostnam);           /* Value Length                */

 /* -----------------------------------------------------------------
    Setup Name/Value Pair for Component
    ----------------------------------------------------------------- */
 Allocate cytanval In(stgarea);        /* Allocate storage            */
 compaddr = cytanvalp;                 /* Save the address            */
 cytannam = Addr(complbl);             /* Name                        */
 cytanvl  = Addr(compnam);             /* Value                       */
 cytanvll = Length(compnam);           /* Value Length                */
 hostaddr->cytannxt = compaddr;        /* Chain off Host Pair         */

 /* -----------------------------------------------------------------
    Setup Name/Value Pair for Application
    ----------------------------------------------------------------- */
 Allocate cytanval In(stgarea);        /* Allocate storage            */
 appladdr = cytanvalp;                 /* Save the address            */
 cytannam = Addr(appllbl);             /* Name                        */
 cytanvl  = Addr(applnam);             /* Value                       */
 cytanvll = Length(applnam);           /* Value Length                */
 compaddr->cytannxt = appladdr;        /* Chain off Host Pair         */

 /* -----------------------------------------------------------------
    Setup Name/Value Pair for Transaction
    NB: Because Transaction is a number, we set the flag so that this
       value is NOT translated from EBCDIC to ASCII.
    ----------------------------------------------------------------- */
 Allocate cytanval In(stgarea);        /* Allocate storage            */
 tranaddr = cytanvalp;                 /* Save the address            */
 cytannam = Addr(tranlbl);             /* Name                        */
 cytanvl  = Addr(trannam);             /* Value                       */
 cytannvx = '1'B;                      /* Do NOT xlate Value          */
 cytanvll = 4;                         /* Value Length                */
 appladdr->cytannxt = tranaddr;        /* Chain off Host Pair         */

 /* -----------------------------------------------------------------
    Get our Configuration Token
    ----------------------------------------------------------------- */
 Allocate cytacfg In(stgarea);         /* Allocate stg for cfg block  */
 cytacsrv = Addr(server);              /* Server                      */
 Call CYTA_init(cytacfg);
 Display ('(CYTAPSMP) CYTAINIT Return Code=' || PLIRETV());

 /* -----------------------------------------------------------------
    Send a Started Event
    ----------------------------------------------------------------- */
 Allocate cytaevnt In(stgarea);        /* Allocate storage for event  */
 cytaetyp = cytaesta;                  /* Started Event Type          */
 cytaevli = Addr(vlink);               /* Vertical Link ID            */
 cytaevll = Length(vlink);             /* Vertical Link Length        */
 cytaevcn = hostaddr;                  /* Vertical Context Start      */
 Call CYTA_track(cytacfg, cytaevnt);
 Display ('(CYTAPSMP) STARTED Event Return Code=' || PLIRETV());

 /* -----------------------------------------------------------------
    Send an Outbound Event
    (we only need to specify changed fields - all other fields remain
    from the Started event)
    ----------------------------------------------------------------- */
 cytaetyp = cytaeob;                   /* Oubound Event Type          */
 cytaehli = Addr(hlinkout);            /* Horizontal Link ID          */
 cytaehll = Length(hlinkout);          /* Horizontal Link Length      */
 Call CYTA_track(cytacfg, cytaevnt);
 Display ('(CYTAPSMP) OUTBOUND Event Return Code=' || PLIRETV());

 /* -----------------------------------------------------------------
    Send an Inbound Finished Event
    ----------------------------------------------------------------- */
 cytaetyp = cytaeibf;                  /* Oubound Event Type          */
 cytaehli = Addr(hlinkin);             /* Horizontal Link ID          */
 cytaehll = 4;                         /* Horizontal Link Length      */
 cytaehnx = '1'b;                      /* Link ID is a number, so do  */
                                       /* NOT translate from EBCDIC.  */
 Call CYTA_track(cytacfg, cytaevnt);
 Display ('(CYTAPSMP) INBOUND FINISHED Event Return Code=' ||
         PLIRETV());

 /* -----------------------------------------------------------------
    Free up our storage
    ----------------------------------------------------------------- */
 stgarea = Empty();                    /* Free all storage            */

 End CYTAPSMP;

HLASM

*=====================================================================*
* Main Program
*=====================================================================*
CYTAASM  RSECT
CYTAASM  AMODE 31
CYTAASM  RMODE ANY
         BAKR  R14,0
         LR    R12,R15
         USING CYTAASM,R12

*---------------------------------------------------------------------*
* Setup workarea
*---------------------------------------------------------------------*
         STORAGE OBTAIN,LENGTH=@WORKL,ADDR=(R1)
         ST    R1,8(R13)               New savearea ptr back to caller
         ST    R13,4(R1)               Old save area ptr in new
         LR    R13,R1
         USING WORK,R13
         MVC   SAVEAREA+4,=C'F1SA'     Show we are using linkage stack

*---------------------------------------------------------------------*
* Setup Vertical Context
*    Your event needs some basic values here, so we use the CYTADFV
*    to fill them in. We chain these values of our own IDNum entry.
*    Note that IDNum is a number, so we don't translate it from EBCDIC
*    to ASCII before sending it down.
*---------------------------------------------------------------------*
         LA    R1,#IDNUM
         CYTANV NAME='IDNum',VALUE=(R1),LEN=#IDNUML,XLATEV=NO,         x
               MF=(E,NAMVALV1)
         CYTADFV TXN='CYTAASM',CHAINTO=NAMVALV1,MF=(E,NAMVALVC)

*---------------------------------------------------------------------*
* Get a Configuration Token - we will use the subsystem CYTZ.         *
*---------------------------------------------------------------------*
         CYTAINIT SUB='CYTZ'           Get Token
         LTR   R15,R15                 If successful
         BNZ   LEAVEX
         ST    R1,TTOKEN                  Save it

*---------------------------------------------------------------------*
* Always start with a STARTED Event
* The Vertical Link should be the same for all events in this work
* unit until a FINISHED event is sent.
* Set the entire event block to zeroes before filling it in.
*---------------------------------------------------------------------*
         XC    EVENTBLK(@EVENTBLK),EVENTBLK
         CYTATRAK STARTED,                                             X
               VCTXT=NAMVALV1,                                         X
               TOKEN=TTOKEN,                                           X
               VLINK='CYTAASM',                                        X
               MF=(E,EVENTBLK)
         LTR   R15,R15                 If not successful
         BNZ   LEAVEX                  Exit

*---------------------------------------------------------------------*
* Send an Outbound Event - this indicates that we've sent something
* to someone else.
* Remember we need a Horizontal Link and/or a Horizontal Stitch
* here - and the program on the other end also needs to specify the
* same link/stitch on their Inbound event.
* Remember also that this event remembers all the values from the
* previous CYTATRAK call. So we only need to specify the Event Type,
* and the values we are overriding (in this case, HLINK).
*---------------------------------------------------------------------*
         CYTATRAK OUTBOUND,HLINK='CYTAOUT',TOKEN=TTOKEN,MF=(E,EVENTBLK)
         LTR   R15,R15                 If not successful
         BNZ   LEAVEX                  Exit

*---------------------------------------------------------------------*
* (often a program would wait here for something to come back)
*---------------------------------------------------------------------*

*---------------------------------------------------------------------*
* Send an Inbound Finished Event - this is two events (Inbound and
* Finished) rolled into one.
* We also need a Horizontal Link and/or a Horizontal Stitch here, but
* not the one we sent - the one that the program at the other end has
* specified.
* Remember that we also finish with a FINISHED event.
*---------------------------------------------------------------------*
         CYTATRAK INBOUND_FIN,HLINK='CYTABACK',TOKEN=TTOKEN,           X
               MF=(E,EVENTBLK)
         LTR   R15,R15                 If not successful
         BNZ   LEAVEX                  Exit

*---------------------------------------------------------------------*
* Return to Caller
*---------------------------------------------------------------------*
LEAVE    DS    0H
         LR    R4,R15                  Save return code
         STORAGE RELEASE,LENGTH=@WORKL,ADDR=(R13) Release workarea
         LR    R15,R4
         PR                            Return to caller

*---------------------------------------------------------------------*
* Error Routine - Error occurred. Exit with return code
*---------------------------------------------------------------------*
LEAVEX   DS    0H
         B     LEAVE

*======================================================================
*
*  PROGRAM CONSTANTS AND LITERALS
*
*======================================================================
#IDNUM   DC    F'45'
#IDNUML  DC    AL2(L'#IDNUM)
         LTORG

*======================================================================
*
*  Mapping Macros and DSECTs
*
*======================================================================
*---------------------------------------------------------------------*
* Workarea
*---------------------------------------------------------------------*
WORK      DSECT
SAVEAREA  DS    18F                     Savearea
STCKTIME  DS    D                       STCK Timestamp

TTOKEN    DS    F                       Fullword for Config Token
NAMVALVC  CYTADFV MF=L                  Vertical Ctxt Nam/Val Pairs
NAMVALV1  CYTANV MF=L                   Extra Vert Context Nam/Val pair
EVENTBLK  CYTATRAK MF=L                 Event Block
@EVENTBLK EQU  *-EVENTBLK               Length of Event Block

@WORKL    EQU   *-WORK                  Length of Workarea

*---------------------------------------------------------------------*
* Register Equates
*---------------------------------------------------------------------*
R0        EQU   0
R1        EQU   1
R2        EQU   2
R3        EQU   3
R4        EQU   4
R5        EQU   5
R6        EQU   6
R7        EQU   7
R8        EQU   8
R9        EQU   9
R10       EQU   10
R11       EQU   11
R12       EQU   12
R13       EQU   13
R14       EQU   14
R15       EQU   15

          END