This chapter:
The supplementary services portion of the AG ISDN API is modeled as a protocol element separate from the call control protocol element. The call control element of a message is used to manage the basic call state, while the supplementary services element of a primitive manages the supplementary service states.
In order for these two elements to work together, but retain separation, the AG ISDN API basic call control buffer format allows for supplementary service information to be carried with the basic call control primitives, in separate structures. In most cases, the structures are attached to ACU_FACILITY_RQ or ACU_FACILITY_IN messages, as explicit control signaling for supplementary services. However, there are cases where extended data structures containing supplementary service information are attached to basic call control primitives such as ACU_CONN_RQ.
A single ACU message can carry multiple supplementary service structures. Each supplementary service structure contains information pertaining to a specific supplementary service.
To send a message to the AG ISDN protocol stack, the application builds two main structures, and then calls isdnSendMessage in the AG ISDN Messaging API library. The structures specified in the function call are:
The application assigns values to the fields in the ACU message structure using macros. These macros are defined in isdnacu.h. See your AG ISDN Messaging API Developer's Reference Manual for more information about message primitives and macros.
Figure 4 illustrates the content and meaning of each of the arguments sent in an isdnSendMessage function call:

Figure 4: isdnSendMessage Data Structures
When the ACU data structures reach the ISDN protocol stack, the stack rearranges the data into several Q.931 information elements (IEs), builds a complete Q.931 message with the IEs, and sends it to the network.
When an AG ISDN protocol stack message is received, an ISDNEVN_RCV_MESSAGE event occurs, using the standard CT Access event handling mechanism. buffer in the CT Access event structure is a pointer to an ISDN_PACKET structure. This structure contains:
Figure 5 illustrates the structure of this message packet:

Figure 5: Receiving Protocol Stack Messages
The ACU data buffer sent or received from the stack is made up of several blocks of information. These include:
The following diagram illustrates the components of an ACU data buffer:

Figure 6: ACU Data Buffer Components
Within the extended data area, one or more supplementary service structures appear, one after the other. Each structure contains:
The structures for each supplementary service can be found in isdnacu.h. Each structure is a standard C structure that can be accessed through a pointer cast to the appropriate type.
In some cases, there is no additional data, so there is no fixed structure or variable length information beyond the header.
The following diagram illustrates the extended data area of an ACU message buffer:

Figure 7: Supplementary Service Data Structures
Each supplementary service structure contains:
The structures for each valid combination can be found in isdnacu.h. Each structure is a standard C structure that can be accessed through a pointer cast to the appropriate type.
The following is a list of the extended data structures used to specify supplementary services in the extended data area of an ACU message. For a detailed description of each structure, see Appendix B.
Various substructures are used to contain data for fields in these structures. For more information, see Section 3.8.
Many fields in these structures are filled using predefined constants. For a list of the constants available for a field, see Appendix C: Constants.
|
Extended Data Structure |
Use |
acu_ss_act_divert_invoke |
Request activation of Call Diversion service |
acu_ss_act_divert_ret_error |
Error in Call Diversion service activation request |
acu_ss_act_divert_ret_result |
Call Diversion service activation request successful |
acu_ss_activate_deflect_invoke |
Request activation of Call Deflection service |
acu_ss_activate_deflect_ret_result |
Call Deflection service activation request successful |
acu_ss_aoc_inform_invoke |
Information returned by Advice of Charge service |
acu_ss_aoc_request_invoke |
Request activation of Advice of Charge service |
acu_ss_aoc_request_ret_error |
Error in Advice of Charge service activation request |
acu_ss_aoc_request_ret_result |
Advice of Charge service activation request successful |
acu_ss_bridge_calls_invoke |
Request invocation of Bridge Calls service |
acu_ss_bridge_calls_ ret_result |
Bridge Calls service invocation successful |
acu_ss_deact_divert_invoke |
Request deactivation of Call Diversion service |
acu_ss_deact_divert_ret_error |
Error in Call Diversion service deactivation request |
acu_ss_deact_divert_ret_result |
Call Diversion service deactivation request successful |
acu_ss_deactivate_deflect_invoke |
Request deactivation of Call Deflection service |
acu_ss_deactivate_deflect_ret_result |
Call Deflection service deactivation request successful |
acu_ss_deflect_invoke |
Request to invoke Call Deflection for a call |
acu_ss_deflect_ret_error |
Error in Call Deflection attempt |
acu_ss_deflect_ret_result |
Successful Call Deflection attempt |
acu_ss_divert_invoke |
Request to forward a call (Call Diversion) |
acu_ss_divert_ret_error |
Successful Call Diversion |
acu_ss_divert_ret_result |
Error in Call Diversion attempt |
acu_ss_enquire_divert_invoke |
Attempt to invoke Enquire Diversion (enquire the network for users' Call Diversion service status) |
acu_ss_enquire_divert_ret_error |
Error in Enquire Diversion invocation |
acu_ss_enquire_divert_ret_result |
Successful invocation of Enquire Diversion service |
acu_ss_hold_invoke |
Invoke Call Hold service |
acu_ss_hold_ret_result |
Successful Call Hold (call is on hold) |
acu_ss_notify_diversion_invoke |
Invoke Notify Diversion service |
acu_ss_notify_diversion_ret_result |
Successful Notify Diversion |
acu_ss_notify_hold_invoke |
Invoke Notify Hold service |
acu_ss_notify_retrieve_invoke |
Invoke Notify Retrieve service |
acu_ss_notify_transfer_invoke |
Invoke Notify Transfer service |
acu_ss_notify_transfer_ret_result |
Successful Notify Transfer invocation |
acu_ss_reject |
Generic rejection message (see Section 3.9) |
acu_ss_reminder_diversion_invoke |
Invoke Remind Diversion service |
acu_ss_retrieve_invoke |
Invoke Call Retrieve service |
acu_ss_retrieve_ret_result |
Successful Call Retrieve service invocation |
acu_ss_transfer_invoke |
Invoke Explicit Call Transfer for a call |
acu_ss_transfer_ret_err |
Error in Explicit Call Transfer |
acu_ss_transfer_ret_result |
Successful Explicit Call Transfer |
An operation id is included in each supplementary service operation call. The id indicates which supplementary service operation the structure pertains to.
Note: Identification supplementary services (CLIP, CONP, COLP, COLR, CONP and CLIR) do not have operation ids. They are accessed using fields in the basic call control primitives. (See Chapter 9.)
The following is a list of valid operation ids:
|
Supplementary Service Operation |
Operation Id |
Documented In |
|
Invoke Bridge Calls |
ACU_OP_ID_BRIDGE_CALLS |
Chapter 4 |
|
Invoke Call Hold |
ACU_OP_ID_HOLD |
Chapter 5 |
|
Invoke Call Retrieve |
ACU_OP_ID_RETRIEVE |
Chapter 5 |
|
Notify Hold |
ACU_OP_ID_NOTIFY_HOLD |
Chapter 5 |
|
Notify Retrieve |
ACU_OP_ID_NOTIFY_RETRIEVE |
Chapter 5 |
|
Explicit Call Transfer |
ACU_OP_ID_TRANSFER |
Chapter 6 |
|
Notify Transfer |
ACU_OP_ID_NOTIFY_TRANSFER |
Chapter 6 |
|
Invoke Call Diversion |
ACU_OP_ID_DIVERSION |
Chapter 7 |
|
Activate Diversion |
ACU_OP_ID_ACTIVATE_DIVERSION |
Chapter 7 |
|
Deactivate Diversion |
ACU_OP_ID_DEACTIVATE_DIVERSION |
Chapter 7 |
|
Enquire Diversion |
ACU_OP_ID_ENQUIRE_DIVERSION |
Chapter 7 |
|
Remind Diversion |
ACU_OP_ID_REMIND_DIVERSION |
Chapter 7 |
|
Notify Diversion |
ACU_OP_ID_NOTIFY_DIVERSION |
Chapter 7 |
|
Invoke Call Deflection |
ACU_OP_ID_DEFLECTION |
Chapter 7 |
|
Activate Deflection |
ACU_OP_ID_ACTIVATE_DEFLECTION |
Chapter 7 |
|
Deactivate Deflection |
ACU_OP_ID_DEACTIVATE_DEFLECTION |
Chapter 7 |
|
Advice of Charge Request |
ACU_OP_ID_AOC_REQUEST |
Chapter 8 |
|
Advice of Charge Inform |
ACU_OP_ID_AOC_INFORM |
Chapter 8 |
|
Calling Name Identification Presentation (CNIP) |
None. |
Chapter 9 |
|
Connected Name Identifi- |
None. |
Chapter 9 |
|
Calling Line Identification Presentation (CLIP) |
None. |
Chapter 9 |
|
Calling Line Identification Restriction (CLIR) |
None. |
Chapter 9 |
|
Connected Line Identification Presentation (COLP) |
None. |
Chapter 9 |
|
Connected Line Identification Restriction (COLR) |
None. |
Chapter 9 |
An operation type identifier (optype) is included in each supplementary service operation call. The optype indicates what the supplementary service message means: why the message is being sent or received.
There are four valid operation types:
|
Operation Type |
Meaning |
|
The message is a request to invoke the supplementary service operation. | |
|
The message indicates rejection of a request to invoke the operation. (See Section 3.9.) | |
|
The message indicates successful completion of the operation. | |
|
The message indicates unsuccessful completion of the operation. |
To specify supplementary services, the application performs the following tasks:
Most of these tasks are performed using specific macros and pointers. These are listed in the following sections.
To begin specifying supplementary services, the application finds the end of the fixed and variable-length argument areas of the ACU message buffer, and sets a specific pointer there. The following table lists the pointers and macros used for these tasks:
To initialize the extended data area:
The AG ISDN Messaging API Developer's Reference Manual describes how to do this.
Note: The extended data area can be filled only when the rest of the ACU data buffer has been completed.
Note: If you are building a Q.SIG application, the PINX node address is specified in your initial call to isdnStartProtocol. For more information, see Section 3.10.
unsigned char *p_ext_data;
Acu_facility_code = ACU_FAC_EXT_SERVICE;
This macro need not be set if any other ACU primitive is used.
Acu_ext_descr_offset = Acu_facility_rq_start_ext_data;
Note: These macros assume that a pointer, p_data, points to the first character of the buffer.
When these tasks are complete, the application can begin filling extended data structures and adding them to this area, one after the other. See Section 3.5.2.
To fill in an extended data structure for a supplementary service, the application first fills in the structure's service header, identifying the structure as a supplementary service structure, and specifying the type and operation of the service. It then fills the data structure for the service.
If additional data structures are required (i.e. the application is specifying more than one supplementary service in the message), the pointer p_ext_data is set to the end of the structure just filled, and a new one is added. The macro Acu_ext_ss_build_end facilitates this procedure.
The following table lists the macros used for these tasks:
|
Macro |
Description |
|
Initializes a new supplementary service data structure. Sets p_ext_data to the beginning of the extended data structure, and stores the service operation type and id in the service structure header. opid is one of the operation ids listed in Section 3.4.1. optype is one of the operation type identifiers listed in Section 3.4.2. | |
|
Called to indicate that building of an extended data structure is complete. p_end is a pointer to the byte after the last byte of the current extended data structure. If this structure includes variable-length data, p_end points to the first byte after the last data element. This macro calculates the length of the extended data area and of the new supplementary service structure and stores these values in the header. It also counts the number of supplementary service structures in this specification, and stores this value in the header. |
To fill an extended data structure for a supplementary service:
Acu_ext_ss_build_begin(ACU_OP_ID_DEFLECTION,ACU_OP_TYPE_INVOKE);
The macro sets p_ext_data to the beginning of the extended data structure, and stores the service operation type and id in the service structure header.
For example, for a Call Deflection invocation operation, the application would use the acu_ss_deflect_invoke data structure (defined in isdnacu.h):
struct acu_ss_deflect_invoke
{
struct acu_ext_hdr ext_hdr; /*Extension header */
struct acu_ss_hdr ss_hdr; /*Supp. services header */
struct acu_address deflect_to; /*No. to direct call to */
struct acu_ss_association charge_association; /*Optional, used when */
}; /*AOC-E service has been invoked */
The following line shows how the application would set a pointer to this data structure:
DeflectInvoke = (struct acu_ss_deflect_invoke *)p_ext_data;
Note: If any optional strings are added, p_end must be adjusted for that string length.
The extended data structure for each operation id / operation type combination is listed in Section 3.4.
p_end += sizeof(struct acu_ss_deflect_invoke);
Acu_ext_ss_build_end (p_end);
p_end is a pointer to the byte after the last byte of the current extended data structure. If this structure includes variable-length data, p_end points to the first byte after the last data element.
This macro calculates the length of the extended data area and of the new supplementary service structure and stores these values in the header. It also counts the number of supplementary service structures in this specification, and stores this value in the header.
The following code fragment shows how to create a supplementary service specification:
char *number;
unsigned char *p_end;
unsigned char *p_ext_data;
unsigned char JoinedConnID;
struct acu_facility *p_data;
struct acu_ss_notify_transfer_invoke *NotifyTransfer;
/* Fill in the fixed portion of the facility message */
p_data = (struct acu_facility *)MsgBuffer; /* Initialize p_data */
/* First zero out the entire buffer */
memset(p_data, OFF, ISDN_BUFFER_DATA_LGTH); /* Zero the structure */
/* Tell the stack we are using supplementary services. Needed only if */
/* supp. service is sent in ACU_FACILITY_RQ. */
Acu_facility_code = ACU_FAC_EXT_SERVICE; /* Supp. service */
/* There is no more to do in the fixed structure except fill in header */
Acu_ext_descr_offset = Acu_facility_start_ext_data;
/* Start supplementary service extended data structure, to invoke */
/* Notify Transfer supplementary service */
Acu_ext_ss_build_begin(ACU_OP_ID_NOTIFY_TRANSFER,ACU_OP_TYPE_INVOKE);
/* Set the structure pointer... */
NotifyTransfer = (struct acu_ss_notify_transfer_invoke *)p_ext_data;
/* Calculate the address of where the data will go... */
p_end += sizeof(struct acu_ss_notify_transfer_invoke);
/* FILL IN THE EXTENDED DATA STRUCTURE... */
/* Some data fields follow */
NotifyTransfer->charge_id.invoke = 0;
NotifyTransfer->call_status = ACU_SS_CALL_STATUS_ANSWERED;
NotifyTransfer->end_designation = ACU_SS_END_DESIGNATION_PRIMARY;
/* Redirecting number information */
NotifyTransfer->redir_nb.invoke = 1;
NotifyTransfer->redir_nb.presentation_restricted = 0;
NotifyTransfer->redir_nb.number_plan = ACU_SS_NUMBER_PLAN_PRIVATE_LEVEL_1_REGIONAL;
NotifyTransfer->redir_nb.screen_ind = ACU_SS_SCREEN_USER_PROV_VERIFIED;
/* Copy in a number to the data area */
number = "1234567"; /* Dummy data */
/*Calculate offset, store length, store the data, advance the pointer */
NotifyTransfer->redir_nb.offset =
(unsigned char)(p_end - (unsigned char *)&NotifyTransfer->redir_nb);
NotifyTransfer->redir_nb.len = strlen(number); /* Length of data */
strcpy((char *)p_end, number); /* Copy extended data */
p_end += strlen(number);
NotifyTransfer->joined_conn_id.board = BoardNumber;
NotifyTransfer->joined_conn_id.nai = NAI;
NotifyTransfer->joined_conn_id.conn_num = JoinedConnID;
/* Field not used in this direction... */
NotifyTransfer->response_rq = 0;
/* No sub-address information. */
NotifyTransfer->redir_sub.invoke = 0;
NotifyTransfer->redir_sub.pad = 0;
NotifyTransfer->redir_sub.type = 0;
NotifyTransfer->redir_sub.odd_even_ind = 0;
NotifyTransfer->redir_sub.offset = 0;
NotifyTransfer->redir_sub.len = 0;
/* Finished with this supp. service */
Acu_ext_ss_build_end(p_end)
To access supplementary service information, the application does the following:
Most of these tasks are performed using specific macros and pointers. These are listed in the table below:
To identify supplementary service extended data structures in the ACU message buffer, the application:
p_ext_data = Acu_ext_descr_first_address;
To read a supplementary service extended data structure, the application:
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.
p_ext_data = Acu_ext_descr_next_address;
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;
}
}
The relationship between the ACU primitive type and the supplementary service operation that is carried can be divided into one of the three categories:
Tightly coupled services and primitives require that the supplementary service operation identifier and operation type be associated with a specific ACU primitive. For example, invocation of the Advice of Charge Request supplementary service must always be done within an ACU_CONN_RQ primitive.
When a service is tightly coupled with an ACU primitive, the service description in this document will list the primitive to use. If the application sends the service request in the wrong primitive, then the stack will return ACU_OP_TYPE_REJECT with a local cause of ACU_SS_REJECT_LOCAL_INVALID_STATE in response.
Loosely coupled services and primitives share the same connection id. In other words, the service applies to the same connection as the basic primitive. However, these services can be carried in any type of basic primitive.
When a loosely coupled service structure must be sent over the interface, and a basic call control primitive is also being sent, then the two can be combined into a single buffer. If there is no basic call primitive, then the ACU_FACILITY_RQ/IN/CO primitive can be used as a "NULL" basic call message and the service structure can be attached to it. For example, invocation of the Advice of Charge Inform service can be carried in any of the basic call primitives (e.g. ACU_ALERTING_IN, ACU_CLEAR_IN), or it may be in an ACU_FACILITY_IN.
While it is true that the primitive and the service are loosely coupled, it is still possible that the call state may prohibit the successful invocation of the service. For example, the Explicit Call Transfer (ECT) service can not be invoked on an inbound call that has not been answered. However, the service request can be sent in the ACU_CONN_RS primitive or a subsequent ACU_FACILITY_IN primitive.
Most supplementary services are loosely coupled with the primitive that carries them. The application must not assume which primitive type will carry a loosely coupled service.
Connection-independent services are not associated with a call in any way. An example of a connection-independent service is the Activate Diversion supplementary service.
Because there is no connection number associated with this service, a different mechanism is used to allow the discrimination between connection-oriented and connection-independent signaling. The sapi field is used for this purpose.
The sapi field of a connection-oriented message (e.g. ACU_CONN_RQ) is set to ACU_SAPI. The sapi field of a connection-independent message is set to ACU_SAPI_MGT. The ACU_FACILITY_RQ/IN/CO are the only primitives used to carry connection-independent service structures.
When the application constructs a connection-independent service structure, it should attach it to an ACU_FACILITY_RQ and set the value of the sapi field to ACU_SAPI_MGT. The application's discrimination function must not use the connection id field of the message when the sapi field indicates a connection-independent message.
Various substructures (listed below) are referenced in the supplementary service extended data structures listed in Section 3.4. They are used to contain particular types of information in the extended data structures, such as address or subaddress information, etc.
Each of these structures contains an invoke field. The invoke field is used to indicate the presence or absence of useful data in the structure. If the field is set to ON, then the stack uses the information in the structure. Otherwise, the information in the structure is ignored. If the successful invocation of the service requires the inclusion of the parameter, and the invoke field is OFF, then the service request is rejected.
Some structures contain a reference to a string location and string length. The string location is specified using the offset field in the structure. This offset value is calculated from the address of the structure containing the offset field.
The len field in the structure contains the length of the data. If you null-terminate the field, the length field must not include the null terminator.
Note: Structures sent from the stack do not include null terminations.
|
Substructure |
Description |
acu_address |
Specifies the full address and subaddress of a party. |
acu_conn_id |
Specifies the connection information of a party. |
acu_party_name |
Specifies the name information of a party. |
acu_party_num |
Specifies the presentation indicator, numbering plan, and screen indicator of a party. |
acu_party_subaddress |
Specifies the subaddress of a party. |
acu_ss_association |
Contains a charge id and charged number, for tracking charging information on transferred or forwarded calls. See Sections 8.3.4 and 8.3.5. |
acu_ss_chan |
Specifies the channel information for a party. |
If a stack or network error occurs when an attempt is made to invoke or activate a service, the acu_ss_reject substructure is returned in an ACU indication or confirmation message (such as ACU_FACILITY_IN or ACU_CLEAR_CO). The service header to this structure contains:
The following is a listing of the acu_ss_reject extended data structure:
struct acu_ss_reject
{
struct acu_ext_hdr ext_hdr; /* Extension header */
struct acu_ss_hdr ss_hdr; /* Supp. services header */
uchar local_cause; /* From SS_REJECT_LOCAL_ constants */
uchar network_cause; /* From SS_REJECT_NETWORK_constants */
pad6
};
The local_cause and network_cause fields in this structure indicate the cause for the rejection. The possible values for these fields are listed in Appendix C.
If you are building a Q.SIG application using supplementary services, you must specify the address of the Q.SIG node when your application starts the stack. To do so, specify the address number and type in the ISDN_PROTOCOL_PARMS_Q931CC structure referenced in the isdnStartProtocol call. The following fields specify the address:
For more information about these fields (including a list of possible values), see your AG ISDN Messaging API Developer's Reference Manual.
Natural MicroSystems, Inc.
100 Crossing Boulevard
Framingham, MA 01702