Version


Figure 4. isdnSendMessage Data Structures
Figure 5. Receiving Protocol Stack Messages

Figure 6. ACU Data Buffer Components

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.
Figure 7. Supplementary Service Data Structures




2. In this area, it fills the structure for a supplementary service.
3. It finds the end of the structure just filled, adds another supplementary service substructure if necessary, and so on.

The NMS 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 2.10. 2. The application declares the p_ext_data pointer. This pointer will indicate the beginning of the extended data structure currently being filled.
unsigned char *p_ext_data;
3. If the supplementary service specification is to be sent with an ACU_FACILITY_RQ primitive, the application sets the Acu_facility_code macro to ACU_FAC_EXT_SERVICE to indicate that the extended data area is to be used.
Acu_facility_code = ACU_FAC_EXT_SERVICE;
This macro need not be set if any other ACU primitive is used.
4. The application sets the macro, Acu_ext_descr_offset, to indicate the beginning of the extended data area of the buffer. Each fixed data structure contains a macro that specifies the start of the extended data area.
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.

- opid is one of the operation IDs listed in Section 2.4.1.
- optype is one of the operation type identifiers listed in Section 2.4.2.
Acu_ext_ss_build_begin(ACU_OP_ID_DEFLECTION,ACU_OP_TYPE_INVOKE);
4. The application calculates the end of the supplementary services data structure.

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)

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.

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.

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 steps 1 through 4 Acu_ext_descr_nb times.

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;
}
}






{
struct acu_ext_hdr ext_hdr; /* Extension header */
struct acu_ss_hdr ss_hdr; /* Supplementary services header */
uchar local_cause; /* From SS_REJECT_LOCAL_ constants */
uchar network_cause; /* From SS_REJECT_NETWORK_constants*/
pad6
};

Version