summaryrefslogtreecommitdiff
path: root/src/components/protocol_handler/src/protocol_packet.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/protocol_handler/src/protocol_packet.cc')
-rw-r--r--src/components/protocol_handler/src/protocol_packet.cc319
1 files changed, 87 insertions, 232 deletions
diff --git a/src/components/protocol_handler/src/protocol_packet.cc b/src/components/protocol_handler/src/protocol_packet.cc
index d40f13b5f0..19c73127cb 100644
--- a/src/components/protocol_handler/src/protocol_packet.cc
+++ b/src/components/protocol_handler/src/protocol_packet.cc
@@ -33,203 +33,55 @@
#include <stdint.h>
#include <memory.h>
#include <new>
-#include <cstring>
-#include <limits>
-
#include "protocol_handler/protocol_packet.h"
#include "utils/macro.h"
-#include "utils/byte_order.h"
namespace protocol_handler {
-ProtocolPacket::ProtocolData::ProtocolData()
- : data(NULL), totalDataBytes(0u) { }
-
-ProtocolPacket::ProtocolData::~ProtocolData() {
- delete[] data;
-}
-
-ProtocolPacket::ProtocolHeader::ProtocolHeader()
- : version(0x00),
- protection_flag(PROTECTION_OFF),
- frameType(0x00),
- serviceType(0x00),
- frameData(0x00),
- sessionId(0x00),
- dataSize(0x00),
- messageId(0x00) {
-}
-
-ProtocolPacket::ProtocolHeader::ProtocolHeader(
- uint8_t version, bool protection, uint8_t frameType, uint8_t serviceType,
- uint8_t frameData, uint8_t sessionID, uint32_t dataSize, uint32_t messageID)
- : version(version),
- protection_flag(protection),
- frameType(frameType),
- serviceType(serviceType),
- frameData(frameData),
- sessionId(sessionID),
- dataSize(dataSize),
- messageId(messageID) {
-}
-
-void ProtocolPacket::ProtocolHeader::deserialize(
- const uint8_t* message, const size_t messageSize) {
- if (messageSize < PROTOCOL_HEADER_V1_SIZE) {
- return;
- }
- // first 4 bits
- version = message[0] >> 4u;
- // 5th bit
- protection_flag = message[0] & 0x08u;
- // 6-8 bits
- frameType = message[0] & 0x07u;
-
- serviceType = message[1];
- frameData = message[2];
- sessionId = message[3];
-
- // FIXME(EZamakhov): usage for FirstFrame message
- const uint32_t data_size_be = *(reinterpret_cast<const uint32_t*>(message + 4));
- dataSize = BE_TO_LE32(data_size_be);
- switch (version) {
- case PROTOCOL_VERSION_2:
- case PROTOCOL_VERSION_3: {
- if (messageSize < PROTOCOL_HEADER_V2_SIZE) {
- return;
- }
- const uint32_t message_id_be =
- *(reinterpret_cast<const uint32_t*>(message + 8));
- messageId = BE_TO_LE32(message_id_be);
- }
- break;
- default:
- messageId = 0;
- break;
- }
-}
-
-ProtocolPacket::ProtocolHeaderValidator::ProtocolHeaderValidator()
- : max_payload_size_(std::numeric_limits<size_t>::max()) {}
-
-void ProtocolPacket::ProtocolHeaderValidator::set_max_payload_size(
- const size_t max_payload_size) {
- max_payload_size_ = max_payload_size;
-}
-
-size_t ProtocolPacket::ProtocolHeaderValidator::max_payload_size() const {
- return max_payload_size_;
-}
-
-RESULT_CODE ProtocolPacket::ProtocolHeaderValidator::validate(const ProtocolHeader& header) const {
- // Protocol version shall be from 1 to 3
- switch (header.version) {
- case PROTOCOL_VERSION_1:
- case PROTOCOL_VERSION_2:
- case PROTOCOL_VERSION_3:
- break;
- default:
- return RESULT_FAIL;
- }
- // ServiceType shall be equal 0x0 (Control), 0x07 (RPC), 0x0A (PCM), 0x0B (Video), 0x0F (Bulk)
- if (ServiceTypeFromByte(header.serviceType) == kInvalidServiceType) {
- return RESULT_FAIL;
- }
- // Check frame info for each frame type
- // Frame type shall be 0x00 (Control), 0x01 (Single), 0x02 (First), 0x03 (Consecutive)
- // For Control frames Frame info value shall be from 0x00 to 0x06 or 0xFE(Data Ack), 0xFF(HB Ack)
- // For Single and First frames Frame info value shall be equal 0x00
- switch (header.frameType) {
- case FRAME_TYPE_CONTROL : {
- switch (header.frameData) {
- case FRAME_DATA_HEART_BEAT:
- case FRAME_DATA_START_SERVICE:
- case FRAME_DATA_START_SERVICE_ACK:
- case FRAME_DATA_START_SERVICE_NACK:
- case FRAME_DATA_END_SERVICE:
- case FRAME_DATA_END_SERVICE_ACK:
- case FRAME_DATA_END_SERVICE_NACK:
- case FRAME_DATA_SERVICE_DATA_ACK:
- case FRAME_DATA_HEART_BEAT_ACK:
- break;
- default:
- return RESULT_FAIL;
- }
- break;
- }
- case FRAME_TYPE_SINGLE:
- if (header.frameData != FRAME_DATA_SINGLE) {
- return RESULT_FAIL;
- }
- break;
- case FRAME_TYPE_FIRST:
- if (header.frameData != FRAME_DATA_FIRST) {
- return RESULT_FAIL;
- }
- break;
- case FRAME_TYPE_CONSECUTIVE:
- // Could have any FrameInfo value
- break;
- default:
- // All other Frame type is invalid
- return RESULT_FAIL;
- }
- // For Control frames Data Size value shall be less than MTU header
- // For Single and Consecutive Data Size value shall be greater than 0x00
- // and shall be less than N (this value will be defined in .ini file)
- if (header.dataSize > max_payload_size_) {
- return RESULT_FAIL;
- }
- switch (header.frameType) {
- case FRAME_TYPE_SINGLE:
- case FRAME_TYPE_CONSECUTIVE:
- if (header.dataSize <= 0) {
- return RESULT_FAIL;
- }
- break;
- default:
- break;
- }
- // Message ID be equal or greater than 0x01 (not actual for 1 protocol version and Control frames)
- if (FRAME_TYPE_CONTROL != header.frameType && PROTOCOL_VERSION_1 != header.version
- && header.messageId <= 0) {
- // Message ID shall be greater than 0x00, but not implemented in SPT
- // TODO(EZamakhov): return on fix on mobile side - APPLINK-9990
- return RESULT_FAIL;
- }
- return RESULT_OK;
-}
-
-
ProtocolPacket::ProtocolPacket()
- : payload_size_(0), connection_id_(0) {
+ : payload_size_(0),
+ packet_id_(0),
+ connection_id_(0) {
}
-ProtocolPacket::ProtocolPacket(ConnectionID connection_id,
+ProtocolPacket::ProtocolPacket(uint8_t connection_id,
uint8_t version, bool protection,
uint8_t frameType,
uint8_t serviceType,
uint8_t frameData, uint8_t sessionID,
uint32_t dataSize, uint32_t messageID,
- const uint8_t *data)
+ const uint8_t *data,
+ uint32_t packet_id)
: packet_header_(version, protection, frameType, serviceType,
frameData, sessionID, dataSize, messageID),
- packet_data_(),
payload_size_(0),
+ packet_id_(packet_id),
connection_id_(connection_id) {
set_data(data, dataSize);
+ DCHECK(MAXIMUM_FRAME_DATA_SIZE >= dataSize);
}
-ProtocolPacket::ProtocolPacket(ConnectionID connection_id)
- : packet_header_(),
- packet_data_(),
- payload_size_(0),
+ProtocolPacket::ProtocolPacket(uint8_t connection_id, uint8_t *data_param,
+ uint32_t data_size)
+ : payload_size_(0),
+ packet_id_(0),
connection_id_(connection_id) {
+ RESULT_CODE result = deserializePacket(data_param, data_size);
+ if (result != RESULT_OK) {
+ //NOTREACHED();
+ }
+}
+
+ProtocolPacket::~ProtocolPacket() {
+ delete[] packet_data_.data;
}
// Serialization
RawMessagePtr ProtocolPacket::serializePacket() const {
- // TODO(EZamakhov): Move header serialization to ProtocolHeader
+ uint8_t *packet = new (std::nothrow) uint8_t[MAXIMUM_FRAME_DATA_SIZE];
+ if (!packet) {
+ return RawMessagePtr();
+ }
// version is low byte
const uint8_t version_byte = packet_header_.version << 4;
// protection is first bit of second byte
@@ -237,38 +89,30 @@ RawMessagePtr ProtocolPacket::serializePacket() const {
// frame type is last 3 bits of second byte
const uint8_t frame_type_byte = packet_header_.frameType & 0x07;
- uint8_t header[PROTOCOL_HEADER_V2_SIZE];
uint8_t offset = 0;
- header[offset++] = version_byte | protection_byte | frame_type_byte;
- header[offset++] = packet_header_.serviceType;
- header[offset++] = packet_header_.frameData;
- header[offset++] = packet_header_.sessionId;
+ packet[offset++] = version_byte | protection_byte | frame_type_byte;
+ packet[offset++] = packet_header_.serviceType;
+ packet[offset++] = packet_header_.frameData;
+ packet[offset++] = packet_header_.sessionId;
- header[offset++] = packet_header_.dataSize >> 24;
- header[offset++] = packet_header_.dataSize >> 16;
- header[offset++] = packet_header_.dataSize >> 8;
- header[offset++] = packet_header_.dataSize;
+ packet[offset++] = packet_header_.dataSize >> 24;
+ packet[offset++] = packet_header_.dataSize >> 16;
+ packet[offset++] = packet_header_.dataSize >> 8;
+ packet[offset++] = packet_header_.dataSize;
if (packet_header_.version != PROTOCOL_VERSION_1) {
- header[offset++] = packet_header_.messageId >> 24;
- header[offset++] = packet_header_.messageId >> 16;
- header[offset++] = packet_header_.messageId >> 8;
- header[offset++] = packet_header_.messageId;
- };
-
- size_t total_packet_size = offset + (packet_data_.data ? packet_data_.totalDataBytes : 0);
-#ifndef BUILD_TESTS // Remove DCHECK for PH tests
- DCHECK(total_packet_size <= MAXIMUM_FRAME_DATA_SIZE);
-#endif
-
- uint8_t *packet = new (std::nothrow) uint8_t[total_packet_size];
- if (!packet) {
- return RawMessagePtr();
+ packet[offset++] = packet_header_.messageId >> 24;
+ packet[offset++] = packet_header_.messageId >> 16;
+ packet[offset++] = packet_header_.messageId >> 8;
+ packet[offset++] = packet_header_.messageId;
}
- memcpy(packet, header, offset);
- if (packet_data_.data && packet_data_.totalDataBytes) {
+ DCHECK((offset + packet_data_.totalDataBytes) <= MAXIMUM_FRAME_DATA_SIZE);
+
+ size_t total_packet_size = offset;
+ if (packet_data_.data) {
memcpy(packet + offset, packet_data_.data, packet_data_.totalDataBytes);
+ total_packet_size += packet_data_.totalDataBytes;
}
const RawMessagePtr out_message(
@@ -280,10 +124,14 @@ RawMessagePtr ProtocolPacket::serializePacket() const {
return out_message;
}
+uint32_t ProtocolPacket::packet_id() const {
+ return packet_id_;
+}
+
RESULT_CODE ProtocolPacket::appendData(uint8_t *chunkData,
uint32_t chunkDataSize) {
if (payload_size_ + chunkDataSize <= packet_data_.totalDataBytes) {
- if (chunkData && chunkDataSize > 0) {
+ if (chunkData) {
if (packet_data_.data) {
memcpy(packet_data_.data + payload_size_, chunkData, chunkDataSize);
payload_size_ += chunkDataSize;
@@ -299,36 +147,39 @@ size_t ProtocolPacket::packet_size() const {
return packet_header_.dataSize;
}
-bool ProtocolPacket::operator==(const ProtocolPacket& other) const {
- if (connection_id_ == other.connection_id_ &&
- packet_header_.version == other.packet_header_.version &&
- packet_header_.protection_flag == other.packet_header_.protection_flag &&
- packet_header_.frameType == other.packet_header_.frameType &&
- packet_header_.serviceType == other.packet_header_.serviceType &&
- packet_header_.frameData == other.packet_header_.frameData &&
- packet_header_.sessionId == other.packet_header_.sessionId &&
- packet_header_.dataSize == other.packet_header_.dataSize &&
- packet_header_.messageId == other.packet_header_.messageId &&
- packet_data_.totalDataBytes == other.packet_data_.totalDataBytes) {
- if (other.packet_data_.totalDataBytes == 0) {
- return true;
- }
- // Compare payload data
- if (packet_data_.data && other.packet_data_.data &&
- 0 == memcmp(packet_data_.data, other.packet_data_.data,
- packet_data_.totalDataBytes)) {
- return true;
- }
+RESULT_CODE ProtocolPacket::deserializePacket(const uint8_t *message,
+ uint32_t messageSize) {
+ uint8_t offset = 0;
+ uint8_t firstByte = message[offset];
+ offset++;
+
+ packet_header_.version = firstByte >> 4u;
+
+ if (firstByte & 0x08u) {
+ packet_header_.protection_flag = true;
+ } else {
+ packet_header_.protection_flag = false;
}
- return false;
-}
-RESULT_CODE ProtocolPacket::deserializePacket(
- const uint8_t *message, const size_t messageSize) {
- packet_header_.deserialize(message, messageSize);
- const uint8_t offset =
- packet_header_.version == PROTOCOL_VERSION_1 ? PROTOCOL_HEADER_V1_SIZE
- : PROTOCOL_HEADER_V2_SIZE;
+ packet_header_.frameType = firstByte & 0x07u;
+
+ packet_header_.serviceType = message[offset++];
+ packet_header_.frameData = message[offset++];
+ packet_header_.sessionId = message[offset++];
+
+ packet_header_.dataSize = message[offset++] << 24u;
+ packet_header_.dataSize |= message[offset++] << 16u;
+ packet_header_.dataSize |= message[offset++] << 8u;
+ packet_header_.dataSize |= message[offset++];
+
+ if (packet_header_.version != PROTOCOL_VERSION_1) {
+ packet_header_.messageId = message[offset++] << 24u;
+ packet_header_.messageId |= message[offset++] << 16u;
+ packet_header_.messageId |= message[offset++] << 8u;
+ packet_header_.messageId |= message[offset++];
+ } else {
+ packet_header_.messageId = 0u;
+ }
packet_data_.totalDataBytes = packet_header_.dataSize;
@@ -338,14 +189,15 @@ RESULT_CODE ProtocolPacket::deserializePacket(
dataPayloadSize = messageSize - offset;
}
- uint8_t *data = NULL;
+ uint8_t *data = 0;
if (dataPayloadSize) {
data = new (std::nothrow) uint8_t[dataPayloadSize];
- if (!data) {
+ if (data) {
+ memcpy(data, message + offset, dataPayloadSize);
+ payload_size_ = dataPayloadSize;
+ } else {
return RESULT_FAIL;
}
- memcpy(data, message + offset, dataPayloadSize);
- payload_size_ = dataPayloadSize;
}
if (packet_header_.frameType == FRAME_TYPE_FIRST) {
@@ -360,7 +212,9 @@ RESULT_CODE ProtocolPacket::deserializePacket(
return RESULT_FAIL;
}
} else {
- delete[] packet_data_.data;
+ if (packet_data_.data) {
+ delete[] packet_data_.data;
+ }
packet_data_.data = data;
}
@@ -411,7 +265,8 @@ void ProtocolPacket::set_total_data_bytes(size_t dataBytes) {
if (dataBytes) {
delete[] packet_data_.data;
packet_data_.data = new (std::nothrow) uint8_t[dataBytes];
- packet_data_.totalDataBytes = packet_data_.data ? dataBytes : 0;
+ packet_data_.totalDataBytes =
+ packet_data_.data ? dataBytes : 0;
}
}