You are here: CSP API Reference > 1 EXS & SwitchKit API Messages > MessageWrapper
Type
SwitchKit API message
Purpose
Use SK_MessageWrapper to provide the means to tunnel through the LLC. That is, the message to be tunneled is encapsulated inside the MessageWrapper. When the LLC receives a MessageWrapper, it extracts the payload message and delivers the extracted bytes to the proper node.
Payload
The payload is a message in CSP format which includes everything from the length up to, but not including, the checksum. Here is a Card Population Query as it would formatted as C-style code:
UBYTE CardPop[] = {00, 05, 00, 07, 00, 02, 01};
That is: length (00, 05), Message Type (00, 07), Reserved (00), Sequence Number (02), and LNI(01).
The only change LLC will make is to change the Sequence Number to a suitable value following the same rules as any other message. (In-use Sequence Numbers must be unique per message type per device.)
Tunneling through the LLC
Message Tunneling is a means of sending a message through the LLC to a device, without LLC attempting to process the message. A message enters the LLC and is delivered directly to the target node. When and if an acknowledgement is received, the LLC delivers to the originating application. Since LLC will not have to examine MessageWrappers for any special processing, the delivery time improves. Occasionally, a new message type is added to the CSP. Since the LLC does limited processing of tunneled messages, it doesn’t need to understand the message in order to send it.
Sent by
Applications
Arguments
The following table shows the arguments you can change:
Parameter |
Description |
---|---|
WaitForAck: |
Set this field to a non-zero value if an acknowledgement is expected for this message. Otherwise, set it to zero.
|
PayloadTimeout
|
If WaitForAck is non-zero, then LLC will wait at least PayloadTimeout seconds for an acknowledgment.
|
TargetNodeId |
The Logical Node ID of the device using this message.
|
PayloadSize |
The payload size in bytes. |
Payload |
A properly formatted CSP format message including everything from the length up to, but not including, the checksum.
|
Status Argument
The following are values that can be returned in the Status argument of MessageWrapperAck:
Value |
Description |
---|---|
TargetNodeId |
The Logical Node ID of the device using this message. |
PayloadSize |
The payload size in bytes. If this is a NACK, then PayloadSize is zero.
|
Payload |
The response from the CSP to the tunneled message.
|
0x10 |
If WaitForAck was non-zero, then this response value means that an ack was received within the specified timeout period. If WaitForAck was zero (do not wait) then 0x10 means the message was delivered to the device. A positive response does not imply that the tunneled message was successful, only that it was delivered successfully. The payload may contain a NACK. |
SK_INVALID_NODE |
TargetNodeId does not exist or is not LINK_UP |
SK_NO_ACK_FROM_SWITCH |
Timeout occurred while LLC was waiting for an acknowledgment to the tunneled message. |
C Structure
typedef struct {
BaseFields Base;
unsigned short TargetNodeId;
UBYTE WaitForAck;
UBYTE PayloadTimeout;
unsigned short PayloadSize;
UBYTE Payload[247];
} XL_MessageWrapper;
C Structure Response
C-Structure
typedef struct {
BaseFields Base;
unsigned short Status;
UBYTE reserved6[13];
unsigned short TargetNodeId;
unsigned short PayloadSize;
UBYTE Payload[247];
} XL_MessageWrapperAck;
C++ Class
class XLC_MessageWrapper: public XLC_OutboundMessage {
unsigned short getTargetNodeId() const;
void setTargetNodeId(unsigned short x);
UBYTE getWaitForAck() const;
void setWaitForAck(UBYTE x);
UBYTE getPayloadTimeout() const;
void setPayloadTimeout(UBYTE x);
unsigned short getPayloadSize() const;
void setPayloadSize(unsigned short x);
const UBYTE *getPayload() const;
UBYTE *getPayload();
void setPayload(UBYTE *x);
};
C++ Class Response
class XLC_MessageWrapperAck: public XLC_AcknowledgeMessage {
unsigned short getStatus() const;
void setStatus(unsigned short x);
unsigned short getTargetNodeId() const;
void setTargetNodeId(unsigned short x);
unsigned short getPayloadSize() const;
void setPayloadSize(unsigned short x);
const UBYTE *getPayload() const;
UBYTE *getPayload();
void setPayload(UBYTE *x);
};
Limitations
There is no way to tunnel to an application an unsolicited CSP message. The application must continue to register to receive these.
socket.log
In the socket.log, messages that have been tunneled will be displayed with an asterisk preceding the bytes.
Example of an outbound message:
Apr 01 2002 13:44:22 H->X2[10.10.158.16] * : 01 01 00 00 fe 00 02 52 02 00 02 53 04 00 20 00 01 02
Example of an inbound message:
Apr 01 2002 13:44:22 X2[10.10.158.16]->H * : 01 01 00 00 fe 00 10 00 02 52 02 00 02 53 04 00 20 00 01 07 00 05 00 02 00 03 00 08 00 02 01 01 00 07 00 02 00 01 00 0a 00 04 00 05 00 05 00 0c 00 06 0a 0a 9e 07 31 51 00 0d 00 06 00 00 00 00 00 00 00 0e 00 02 00 01
LLC message validation
The LLC will make no attempt to validate the contents of the payload. Since the CSP will not NACK ill formed messages (it generates an alarm instead) the likely response will be SK_NO_ACK_FROM_SWITCH.
Example Code
This code example sends an IP Signaling Series 3 Card Query message (0x101) to a device server with a node id of 0x02:
UBYTE sqbuf[] = {
0x00, 0x13, //length
0x01, 0x01, // tag
0x00, //reserved
0x00, // seq num
0xfe, // ELNI
0x00, // address method
0x02, // num address elelments
0x52, 0x02, 0x00, 0x02, // ELNI
0x53, 0x04, 0x00, 0x20, 0x00, 0x01, // ObInstId
0x02, // query type
0x00 //reserved
};
XLC_MessageWrapper sq(sizeof(sqbuf)+0x20);
sq.setPayloadSize(sizeof(sqbuf));
memcpy(sq.getPayload(), sqbuf, sizeof(sqbuf));
sq.setTargetNodeId(0x02);
sq.setWaitForAck(1);
sq.setPayloadTimeout(0x10);
sq.send();
This code example is from the handler function for this message:
CASEC_MessageWrapperAck(mwa)
{
cout << "ACK: " << hex << mwa->getStatus() << endl;
cout << " Payload size: " << mwa->getPayloadSize() << endl;
cout << " Payload: ";
if (mwa->getStatus() == 0x10)
{
for (int x = 0; x<mwa->getPayloadSize(); x++)
{
cout << hex << (int)mwa->getPayload()[x] << " ";
}
cout << endl;
}
return OK;
}