SEND MAP vectors
Include logic in your bridge application to interpret outbound SEND MAP request vectors.
An outbound SEND MAP vector can contain an application data structure (ADS) and an application data structure descriptor in short form (ADSD) or long form (ADSDL).
To interpret a SEND MAP vector, do the following (assuming that the message contains both an ADS and an ADSD or ADSDL):
- Get the message containing the SEND MAP vector from the bridge reply queue into a message buffer.
- Locate the start of the outbound SEND MAP vector in the message buffer. This is appended to the CIH, and so is at an offset equal to the length of the CIH from the start of the message buffer. We can use the following code fragment as a model:
/* #includes */ #include cmqc.h /* WebSphere MQ header */ #include dfhbrmqh.h /* Vector structures */ ⋮ /* #defines */ ⋮ MQCHAR * MsgBuffer ; /* Message buffer pointer */ brmq_send_map * pVector ; /* Vector pointer */ ⋮ /* Get message from reply queue */ ⋮ /* Set the vector pointer to the start of the vector */ pVector = MsgBuffer + ((MQCIH *) MsgBuffer)->StrucLength ;- Identify the starting addresses of the application data structure (ADS) and the application data structure descriptor (ADSD or ADSDL) from the SEND MAP vector.
The following diagram shows the structure of an outbound SEND MAP vector (assuming that you have set a pointer called pVector to address the start of the brmq_send_map vector, as in the code fragment above):
|---------------------------x'vvvvvvvv'-------------------------→| |---------------------x'zzzzzzzz'-------------------→| |----------------x'xxxxxxxx'------------→| |---------sizeof(brmq_send_map)---------→| --→ x'wwwwwwww' ←-- 1804 O --→ x'yyyyyyyy' ←-- -------------- ... ------------------------...---------...---- |vvvv|FFFF|D444| |wwww|xxxx|yyyy|zzzz| ADS | ADSD or | |vvvv|1804|6000| |wwww|xxxx|yyyy|zzzz| | ADSDL | -------------- ... ------------------------...---------...---- ↑ ↑ ↑ ↑ ↑ pVector | | | pVector->brmq_sm_adsd_offset | | pVector->brmq_sm_adsd_len | pVector->brmq_sm_data_offset pVector->brmq_sm_data_lenValues in the diagram shown like this:
ABCD 1234show hexadecimal values as you would see them in an ISPF editor with hex on. This is equivalent to the hexadecimal value X'A1B2C3D4'.Fields pVector->brmq_sm_data_offset and pVector->brmq_sm_data_len give the offset and length of the ADS, and fields pVector->brmq_sm_adsd_offset and pVector->brmq_sm_adsd_len give the offset and length of the ADSD or ADSDL.
Fields brmq_sm_adsd_offset and brmq_sm_adsd_len are both set to zero if no ADSD or ADSDL is included in the message.
- Identify the fields in the ADSD or ADSDL.
The ADSD and ADSDL are both mapped to structures that are defined in header file dfhbrarh.h, which is distributed in library <hlq>.SDFHC370 for CICS Transaction Server for OS/390 Version 1.2 or later. We can examine the structure definitions there to see how the fields are laid out. The fields of the ADSD are also described in the CICS Internet and External Interfaces Guide for CICS V1.2, or the CICS External Interfaces Guide for CICS V1.3..
To compile your bridge application on a workstation, copy file dfhbrarh.h to that environment.
Both the ADSD and the ADSDL are represented by two types of structure. The first structure is the descriptor, which occurs only once at the start of the ADSD or ADSDL. These types are defined as follows:
- ads_descriptor
- Descriptor for the ADSD (short form)
- ads_long_descriptor
- Descriptor for the ADSDL (long form)
The second structure is the field descriptor, which is repeated once for each field in the map. These types are defined as follows:
This can be shown diagrammatically like this for the ADSDL and the ADSD:
- ads_field_descriptor
- Field descriptor for the ADSD (short form)
- ads_long_field_descriptor
- Field descriptor for the ADSDL (long form)
The ADSDL:
------------------------------------------------------ ... | ADS Descriptor | field descriptor | field descriptor | ------------------------------------------------------ ... ↑ ↑ ↑ | | ads_long_field_descriptor | ads_long_field_descriptor ads_long_descriptorThe ADSD:
------------------------------------------------------ ... | ADS Descriptor | field descriptor | field descriptor | ------------------------------------------------------ ... ↑ ↑ ↑ | | ads_field_descriptor | ads_field_descriptor ads_descriptorFields adsd_field_count and adsdl_field_count in the descriptors identify the number of field descriptors in the ADSD and ADSDL.You can use the following code fragment to set pointers to the start of the ADSD or ADSDL structures and process the field descriptors sequentially. It is assumed that pVector already addresses the start of the brmq_send_map vector, and that you have an MQCIH structure named mqcih that contains the CIH from the inbound message.
/* #includes */ #include cmqc.h /* WebSphere MQ header */ #include dfhbrmqh.h /* Vector structures */ #include dfhbrarh.h /* ADSD structures */ ⋮ /* Ptr to ADSD descriptor */ ads_descriptor * pADSD_D ; /* Ptr to ADSDL descriptor */ ads_long_descriptor * pADSDL_D ; /* Ptr to ADSD field descriptor */ ads_field_descriptor * pADSD_FD ; /* Ptr to ADSDL field descriptor */ ads_long_field_descriptor * pADSDL_FD ; ⋮ /* Initialize the pointer to the ADSDL descriptor or the */ /* ADSD descriptor depending on mqcih.ADSDescriptor */ if (mqcih.ADSDescriptor && MQCADSD_MSGFORMAT) { pADSDL_D = pVector->brmq_sm_adsd_offset; /* Long form */ pADSDL_FD = pADSDL_D + sizeof(ads_long_descriptor) ; ⋮ /* Enter a loop where we process all field descriptors */ /* in the ADSDL sequentially */ do { /* Perform some processing */ ⋮ pADSDL_FD += sizeof(ads_long_field_descriptor) ; } while (pADSDL_FD < pADSDL_D->adsdl_length ) ; } else /* Short form */ { pADSD_D = pVector->brmq_sm_adsd_offset; /* Short form */ pADSD_FD = pADSD_D + sizeof(ads_descriptor) ; /* Enter a loop where we process all field descriptors */ /* in the ADSD sequentially */ do { /* Perform some processing */ ⋮ pADSD_FD += sizeof(ads_field_descriptor) ; } while (pADSD_FD < pADSD_D->adsd_length ) ; } ⋮- Identify the fields in the ADS.
The ADS is mapped to a structure that is generated when you assemble your map. If you include a keyword=parameter value of DSECT=ADSDL in your mapset definition macro, you get the long form of the ADS. The output from map assembly is a union of two structures: an input structure and an output structure. This example shows part of such a union (only the first field definition is shown for each structure, and the comments have been added following map assembly).
union { struct { char dfhms1[12]; /* 12 reserved bytes */ int dfhms2; /* Offset to next field */ int tranidl; /* Data length of this field */ int tranidf; /* Flag or attribute value */ int dfhms3[7]; /* Extended attributes array */ char tranidi[4]; /* Data value of field */ ... } bmstmp1i; /* Input structure */ struct { char dfhms56[12]; /* 12 reserved bytes */ int dfhms57; /* Offset to next field */ int dfhms58; /* Data length of this field */ int tranida; /* Flag or attribute value */ int tranidc; /* Extended attribute */ int tranidp; /* Extended attribute */ int tranidh; /* Extended attribute */ int tranidv; /* Extended attribute */ int tranidu; /* Extended attribute */ int tranidm; /* Extended attribute */ int tranidt; /* Extended attribute */ char tranido[4]; /* Data value of field */ ... } bmstmp1o; /* Output structure */ } bmstmp1; /* Union */The two structures are functionally identical, except that the input structure includes the extended attribute values in a seven–element array, and the output structure provides individually named fields.You can use the following code fragment to set pointers to the start of the ADS. The structure names shown in the example DSECT above are used for illustration. Two pointers are set, the first to address inbound data and the second to address outbound data. It is assumed that pVector already addresses the start of the brmq_send_map vector.
/* #includes */ #include cmqc.h /* WebSphere MQ header */ #include dfhbrmqh.h /* Vector structures */ #include dfhbrarh.h .. /* ADSD structures */ #include mydsect.h /* DSECT from map assembly */ ⋮ bmstmp1i * pADSI ; /* Pointer to the inbound ADS */ bmstmp1o * pADSO ; /* Pointer to the outbound ADS */ bmstmp1i * pADSI_An ; /* Inbound ADS Anchor */ bmstmp1o * pADSO_An ; /* Outbound ADS Anchor */ ⋮ /* We are dealing with an outbound vector, so we will */ /* initialize the outbound pointer to address the ADS */ pADSO = pVector->brmq_sm_adsd_offset ; /* Save initial value as anchor */ pADSO_An = pADSO ; /* Move to the start of the first field */ pADSO += pADSDL_FD->adsdl_field_offset ; /* Enter a loop where we process all fields in the ADS */ /* sequentially. It is assumed that the value of pADSDL_FD */ /* is being augmented to the next field descriptor in the */ /* ADSDL with every loop. A model for this is shown in a code*/ /* fragment above. Note that adsdl_field_offset contains */ /* the absolute offset of the field from the start of the */ /* ADS. */ do { /* Perform some processing */ ⋮ /* Add offset of next field to ADS Anchor value */ /* to address the next field */ pADSO = pADSO_An + pADSDL_FD->adsdl_field_offset ; } while (pADSDL_FD < pADSDL_D->adsd_length ) ; ⋮The general structures of the long and short forms of the ADS are given in CICS Transaction Server for OS/390 Version 1 Release 3: Web Support and 3270 Bridge, an IBM Redbooks publication.
Parent topic:
Interpreting outbound SEND MAP and RECEIVE MAP vectors
fg15620_