private void ProcessApdu(BacnetAddress adr, BacnetPduTypes type, byte[] buffer, int offset, int length)
{
switch (type & BacnetPduTypes.PDU_TYPE_MASK)
{
case BacnetPduTypes.PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST:
{
BacnetUnconfirmedServices service;
int apdu_header_len = APDU.DecodeUnconfirmedServiceRequest(buffer, offset, out type, out service);
offset += apdu_header_len;
length -= apdu_header_len;
ProcessUnconfirmedServiceRequest(adr, type, service, buffer, offset, length);
}
break;
case BacnetPduTypes.PDU_TYPE_SIMPLE_ACK:
{
BacnetConfirmedServices service;
byte invoke_id;
int apdu_header_len = APDU.DecodeSimpleAck(buffer, offset, out type, out service, out invoke_id);
offset += apdu_header_len;
length -= apdu_header_len;
ProcessSimpleAck(adr, type, service, invoke_id, buffer, offset, length);
}
break;
case BacnetPduTypes.PDU_TYPE_COMPLEX_ACK:
{
BacnetConfirmedServices service;
byte invoke_id;
byte sequence_number;
byte proposed_window_number;
int apdu_header_len = APDU.DecodeComplexAck(buffer, offset, out type, out service, out invoke_id, out sequence_number, out proposed_window_number);
offset += apdu_header_len;
length -= apdu_header_len;
if ((type & BacnetPduTypes.SEGMENTED_MESSAGE) == 0) //don't process segmented messages here
{
ProcessComplexAck(adr, type, service, invoke_id, buffer, offset, length);
}
else
{
ProcessSegment(adr, type, service, invoke_id, BacnetMaxSegments.MAX_SEG0, BacnetMaxAdpu.MAX_APDU50, false, sequence_number, proposed_window_number, buffer, offset, length);
}
}
break;
case BacnetPduTypes.PDU_TYPE_SEGMENT_ACK:
{
byte original_invoke_id;
byte sequence_number;
byte actual_window_size;
int apdu_header_len = APDU.DecodeSegmentAck(buffer, offset, out type, out original_invoke_id, out sequence_number, out actual_window_size);
offset += apdu_header_len;
length -= apdu_header_len;
m_last_segment_ack.Set(adr, original_invoke_id, sequence_number, actual_window_size);
ProcessSegmentAck(adr, type, original_invoke_id, sequence_number, actual_window_size, buffer, offset, length);
}
break;
case BacnetPduTypes.PDU_TYPE_ERROR:
{
BacnetConfirmedServices service;
byte invoke_id;
int apdu_header_len = APDU.DecodeError(buffer, offset, out type, out service, out invoke_id);
offset += apdu_header_len;
length -= apdu_header_len;
ProcessError(adr, type, service, invoke_id, buffer, offset, length);
}
break;
case BacnetPduTypes.PDU_TYPE_REJECT:
case BacnetPduTypes.PDU_TYPE_ABORT:
{
byte invoke_id;
byte reason;
int apdu_header_len = APDU.DecodeAbort(buffer, offset, out type, out invoke_id, out reason);
offset += apdu_header_len;
length -= apdu_header_len;
ProcessAbort(adr, type, invoke_id, reason, buffer, offset, length);
}
break;
case BacnetPduTypes.PDU_TYPE_CONFIRMED_SERVICE_REQUEST:
{
BacnetConfirmedServices service;
BacnetMaxSegments max_segments;
BacnetMaxAdpu max_adpu;
byte invoke_id;
byte sequence_number;
byte proposed_window_number;
int apdu_header_len = APDU.DecodeConfirmedServiceRequest(buffer, offset, out type, out service, out max_segments, out max_adpu, out invoke_id, out sequence_number, out proposed_window_number);
offset += apdu_header_len;
length -= apdu_header_len;
if ((type & BacnetPduTypes.SEGMENTED_MESSAGE) == 0) //don't process segmented messages here
{
ProcessConfirmedServiceRequest(adr, type, service, max_segments, max_adpu, invoke_id, buffer, offset, length);
}
else
{
ProcessSegment(adr, type, service, invoke_id, max_segments, max_adpu, true, sequence_number, proposed_window_number, buffer, offset, length);
}
}
break;
default:
Trace.TraceWarning("Something else arrived: " + type);
break;
}
}