# Sending and receiving transparent messages

The transparent message sending and receiving feature is supported by the 4ESS, DMS, ETSI, QSIG, and NI2 variants.

This feature allows an application to include raw Q.931 data in one or more custom-built information elements (IEs) in messages sent to the stack. These information elements, called transparent IEs, are inserted in the Q.931 message generated by the stack exactly as specified by the user.

An application can also read the raw data in an incoming Q.931 message.

## Sending transparent messages

To send a transparent message, the application invokes nccSendCallMessage. In the function invocation, the message argument must point to an NCC_ISDN_TRANSPARENT_BUFFER_INVOKE structure specifying the message. The size argument must be set to the size of this structure. The structure is:

typedef struct
{
NCC_ISDN_SEND_CALL_MESSAGE hdr;
unsigned char isdn_message; /* ISDN message */
unsigned char size; /* Size of the buffer */
char buffer[1]; /* Buffer, attached to the msg */
} NCC_ISDN_TRANSPARENT_BUFFER_INVOKE;

The structure's header contains:

- hdr.message_id: NCC_ISDN_TRANSPARENT_BUFFER

- hdr.message_type: 0

The isdn_message field in the structure contains the ISDN message:

isdn_message value | Description
--- | ---
NCC_ISDN_FACILITY | ISDN FACILITY message.
NCC_ISDN_NOTIFY | ISDN NOTIFY message.
NCC_ISDN_INFO | ISDN INFORMATION message.

The buffer field is a buffer containing the raw transparent message data supplied by the application in hexadecimal format. The size field contains the size of the buffer.

The following code sample shows how to create and send a raw FACILITY message using the transparent message send/receive feature:

void CreateRawFacility(NCC_CALLHD callhd)
{
NCC_ISDN_TRANSPARENT_BUFFER_INVOKE * p_call_message;
unsigned size; /* Size of message */
unsigned char buffer_size; /* Size of a transparent buffer */
char buffer[] /* Example of transparent buffer */
{ 0x1c , 0x06 , 0x91 , 0xa2 , 0x03 , 0x02 , 0x01 , 0x03};
buffer_size = sizeof( buffer );
/* Calculate the size of the message */
size = sizeof( NCC_ISDN_TRANSPARENT_BUFFER_INVOKE ) + buffer_size;
p_call_message = (NCC_ISDN_TRANSPARENT_BUFFER_INVOKE *) malloc ( size );
memset (p_call_message, 0, size); /* First zero out the entire buffer */
p_call_message->hdr.message_id = NCC_ISDN_TRANSPARENT_BUFFER;
p_call_message->isdn_message = NCC_ISDN_FACILITY;
p_call_message->size = buffer_size;
memcpy(p_call_message->buffer, buffer, p_call_message->size);
if ( nccSendCallMessage( callhd, p_call_message, size ) != SUCCESS )
printf( nccSendCallMessage failed \n );
free( p_call_message );
}

To use transparent IEs, the application must disable the stack's syntax checking mechanism. To do this, set the NS_IE_RELAY_BEHAVIOUR bit in the ns_behaviour sub-structure referenced in the ISDN_PROTOCOL_PARMS_CHANNELIZED structure passed to isdnStartProtocol. By default, this bit is 0 (zero).

The ISDN daemon isdncta has a command-line switch (-N) that sets the NS_IE_RELAY_BEHAVIOUR bit.

## Receiving transparent messages

To receive FACILITY messages that are not recognized by the stack, the application must enable the ACU_SEND_UNKNOWN_FACILITY bit in the acu_behaviour sub-structure contained in the ISDN_PROTOCOL_PARMS_CHANNELIZED structure. By default, this bit is 0 (zero).

By setting this behavior bit, the bit NS_ACCEPT_UNKNOWN_FAC_IE is implicitly enabled. The ISDN daemon (isdncta) has a command-line switch (-A) that sets the ACU_SEND_UNKNOWN_FACILITY bit.

When the stack receives an unknown FACILITY message, an NCCEVN_PROTOCOL_EVENT is generated and sent to the application. The buffer field (returned with the event ID in the CTA_EVENT structure) points to an NCC_ISDN_TRANSPARENT_BUFFER_RETURN_RESULT structure. This structure has its own buffer containing the FACILITY message. The structure is:

typedef struct
{
NCC_ISDN_SEND_CALL_MESSAGE hdr;
unsigned char isdn_message; /* ISDN message */
unsigned char size; /* Size of the buffer */
char buffer[1]; /* Buffer, attached to the msg */
} NCC_ISDN_TRANSPARENT_BUFFER_RETURN_RESULT;

The structure's header contains:

- hdr.message_id: NCC_ISDN_TRANSPARENT_BUFFER

- hdr.message_type: NCC_ISDN_RETURN_RESULT

The isdn_message field is set to NCC_ISDN_FACILITY.

The size field contains the size of the Q931 message.

The buffer field contains the Q931 message.

The application is responsible for freeing the event buffer returned in the NCC_ISDN_TRANSPARENT_BUFFER_RETURN_RESULT structure. To do so, the application can invoke ctaFreeBuffer.

The following code sample shows how to receive and process transparent messages:

CTA_EVENT event = {0};
for (;;)
{
ctaWaitEvent( ctaqueuehd, &event, 100);
ProcessEvent(&event)
/* If the CTA_INTERNAL_BUFFER bit is set in the size field, the
application is responsible for freeing the memory that it did not
allocate. */
if ( event.size & CTA_INTERNAL_BUFFER )
ctaFreeBuffer( event.buffer ); /* Release Natural Access buffers */
}
void ProcessEvent(CTA_EVENT *event)
{
switch( event->id )
{
case NCCEVN_PROTOCOL_EVENT:
switch ( event->value )
{
case ISDN_CALL_MESSAGE_SENT:
{
NCC_ISDN_SEND_CALL_MESSAGE *hdr;
if ( event->size == 0 )
{
printf( "Failed to receive buffer with ISDN_CALL_MESSAGE_SENT\n");
break;
}
if ( (hdr->message_id == NCC_ISDN_TRANSPARENT_BUFFER) &&
(hdr->message_type == NCC_ISDN_RETURN_RESULT) )
{
NCC_ISDN_TRANSPARENT_BUFFER_RETURN_RESULT *retres;
retres = (NCC_ISDN_TRANSPARENT_BUFFER_RETURN_RESULT *)event->buffer;
if ( retres->isdn_message == NCC_ISDN_FACILITY )
printf( Received Facility message with unknown Facility IE\n );
}
}
break; /* End of case ISDN_CALL_MESSAGE_SENT */
default:
break;
} /* End of switch ( event->value ) */
break; /* End of case NCCEVN_PROTOCOL_EVENT */
...
default:
break;
} /* End of switch( event->id ) */
}