# Retrieving supplementary service information

To access supplementary service information, the application does the following:

Step | Action
1 | It finds the beginning of the extended data area of the ACU message buffer, and determines whether there are any extended data structures in it.
2 | If extended data structures are present, it reads the extended data structure header of the first extended data structure to determine if it is a supplementary service structure or not.
3 | If the structure is a supplementary service structure, the application reads the operation type and ID in the service header to determine what data to expect.
4 | It sets a pointer to the first byte of the data, and reads it in.
5 | It reads the size of the structure from the extended data structure header, and moves the pointer.
6 | It repeats steps 2 through 5 for each extended data structure in the ACU message buffer.

Most of these tasks are performed using specific macros and pointers, listed in the following table:

Macro | Description
--- | ---
Acu_ext_id | Identifies the type of an extended data structure in the structure's extended data structure header. ACU_EXT_SERVICE indicates a supplementary service data structure.
Acu_ext_ss_op_id | Identifies the operation ID of a supplementary service in the service header of the extended data structure specifying the service.
Acu_ext_ss_op_type | Identifies the operation type of a supplementary service in the service header of the extended data structure specifying the service.
Acu_ext_descr_nb | Indicates the number of extended data structures in the extended data area.
Acu_ext_descr_first_address | Indicates the address of the first extended data structure. Assumes that a pointer, p_data, points to the first data character of the ACU message buffer.
Acu_ext_lgth | Indicates the length of the data area of the current extended data structure (the fixed-length area plus the variable-length area, if any).

## Identifying extended data structures

To identify supplementary service extended data structures in the ACU message buffer, the application:

Step | Action
1 | Checks the macro Acu_ext_descr_nb to determine how many (if any) extended data structures there are in the buffer.
2 | Sets p_ext_data to the first data character of the extended data structure buffer. p_ext_data = Acu_ext_descr_first_address;
3 | Determines whether or not an extended data structure is a supplementary service structure by checking the macro Acu_ext_id. Its value (stored in the extended data structure header of the structure) should be ACU_EXT_SERVICES.

## Reading a supplementary service extended data structure

To read a supplementary service extended data structure, the application:

Step | Action
1 | Reads the values of Acu_ext_ss_op_type and Acu_ext_ss_op_id to determine the operation ID and type of the supplementary service data structure. This determines which data structure to expect. For example, if Acu_ext_op_id is ACU_OP_ID_NOTIFY_TRANSFER and Acu_ext_op_type is ACU_OP_TYPE_INVOKE, the data structure is acu_ss_notify_transfer_invoke.
2 | Uses p_ext_data to pick up the address of the extended structure.
3 | Reads the information in the structure.
4 | Resets p_ext_data to the end of the structure: p_ext_data = Acu_ext_descr_next_address;
5 | Repeats these steps Acu_ext_descr_nb times.

## Supplementary service retrieval code sample

The following code fragment shows how to retrieve supplementary service information from an ACU message:

unsigned char *p_ext_data;
if (Acu_ext_descr_nb > 0)
{
p_ext_data = Acu_ext_descr_first_address;
/* process extended parameters */
for (i = Acu_ext_descr_nb; i > 0; i--)
{
process_acu_ext_element (p_ext_data);
p_ext_data = Acu_ext_descr_next_address;
}
}
void process_acu_ext_element(unsigned char *p_ext_data)
{
if (Acu_ext_id == ACU_EXT_SERVICES)
{
/* We have a parameter containing a service structure*/
....
ProcessAcuExtService (p_ext_data)
}
}
void ProcessAcuExtService(unsigned char *p_ext_data)
{
ushort op_id = Acu_ext_ss_op_id;
ushort op_type = Acu_ext_ss_op_type;
ulong event = (op_id << 16) + op_type;
struct acu_ss_notify_transfer_invoke *Transfer;
struct acu_ss_aoc_inform_invoke *AOC;
switch(event)
{
case (ACU_OP_ID_NOTIFY_TRANSFER << 16) + ACU_OP_TYPE_INVOKE:
{
Transfer = (struct acu_ss_notify_transfer_invoke *)p_ext_data;
...
}
break;
case (ACU_OP_ID_AOC_INFORM << 16) + ACU_OP_TYPE_INVOKE:
{
AOC = (struct acu_ss_aoc_inform_invoke *)p_ext_data;
...
}
break;
}
}