summaryrefslogtreecommitdiff
path: root/SDL_Core/src/components/protocol_handler/src/protocol_packet.cc
diff options
context:
space:
mode:
Diffstat (limited to 'SDL_Core/src/components/protocol_handler/src/protocol_packet.cc')
-rw-r--r--SDL_Core/src/components/protocol_handler/src/protocol_packet.cc304
1 files changed, 304 insertions, 0 deletions
diff --git a/SDL_Core/src/components/protocol_handler/src/protocol_packet.cc b/SDL_Core/src/components/protocol_handler/src/protocol_packet.cc
new file mode 100644
index 000000000..0dfb1e7d2
--- /dev/null
+++ b/SDL_Core/src/components/protocol_handler/src/protocol_packet.cc
@@ -0,0 +1,304 @@
+/**
+ * \file ProtocolPacket.cpp
+ * \brief ProtocolPacket class source file.
+ *
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdint.h>
+#include <memory.h>
+#include "protocol_handler/protocol_packet.h"
+#include "utils/macro.h"
+
+namespace protocol_handler {
+
+ProtocolPacket::ProtocolPacket()
+ : packet_(0),
+ total_packet_size_(0),
+ data_offset_(0),
+ packet_id_(0),
+ connection_key_(0) {
+}
+
+ProtocolPacket::ProtocolPacket(uint8_t connection_key,
+ uint8_t version, bool compress,
+ uint8_t frameType,
+ uint8_t serviceType,
+ uint8_t frameData, uint8_t sessionID,
+ uint32_t dataSize, uint32_t messageID,
+ const uint8_t* data,
+ uint32_t packet_id)
+ : packet_(0),
+ total_packet_size_(0),
+ data_offset_(0),
+ packet_id_(packet_id),
+ connection_key_(connection_key) {
+ RESULT_CODE result = serializePacket(version, compress, frameType, serviceType, frameData,
+ sessionID, dataSize, messageID, data);
+ if (result != RESULT_OK) {
+ NOTREACHED();
+ }
+}
+
+ProtocolPacket::ProtocolPacket(uint8_t connection_key, uint8_t* data_param,
+ uint32_t data_size)
+ : packet_(0),
+ total_packet_size_(0),
+ data_offset_(0),
+ packet_id_(0),
+ connection_key_(connection_key) {
+ RESULT_CODE result = deserializePacket(data_param, data_size);
+ if (result != RESULT_OK) {
+ NOTREACHED();
+ }
+}
+
+ProtocolPacket::~ProtocolPacket() {
+ packet_ = 0;
+ total_packet_size_ = 0;
+ packet_id_ = 0;
+ if (packet_data_.data) {
+ delete packet_data_.data;
+ packet_data_.data = 0;
+ }
+}
+
+// Serialization
+RESULT_CODE ProtocolPacket::serializePacket(uint8_t version,
+ bool compress,
+ uint8_t frameType,
+ uint8_t serviceType,
+ uint8_t frameData,
+ uint8_t sessionID,
+ uint32_t dataSize,
+ uint32_t messageID,
+ const uint8_t* data) {
+
+ if (packet_) {
+ delete[] packet_;
+ packet_ = 0;
+ total_packet_size_ = 0;
+ }
+
+ uint8_t offset = 0;
+ uint8_t compressF = 0x0;
+ packet_ = new uint8_t[MAXIMUM_FRAME_DATA_SIZE];
+ if (compress) {
+ compressF = 0x1;
+ }
+ uint8_t firstByte = ((version << 4) & 0xF0) | ((compressF << 3) & 0x08)
+ | (frameType & 0x07);
+
+ packet_[offset++] = firstByte;
+ packet_[offset++] = serviceType;
+ packet_[offset++] = frameData;
+ packet_[offset++] = sessionID;
+
+ packet_[offset++] = dataSize >> 24;
+ packet_[offset++] = dataSize >> 16;
+ packet_[offset++] = dataSize >> 8;
+ packet_[offset++] = dataSize;
+
+ if (version == PROTOCOL_VERSION_2) {
+ packet_[offset++] = messageID >> 24;
+ packet_[offset++] = messageID >> 16;
+ packet_[offset++] = messageID >> 8;
+ packet_[offset++] = messageID;
+ }
+
+ total_packet_size_ = offset;
+
+ if (data) {
+ if ((offset + dataSize) <= MAXIMUM_FRAME_DATA_SIZE) {
+ memcpy(packet_ + offset, data, dataSize);
+ total_packet_size_ += dataSize;
+ } else {
+ delete[] packet_;
+ packet_ = 0;
+ total_packet_size_ = 0;
+ return RESULT_FAIL;
+ }
+ }
+
+ return RESULT_OK;
+}
+
+uint8_t * ProtocolPacket::packet() const {
+ return packet_;
+}
+
+uint32_t ProtocolPacket::packet_size() const {
+ return total_packet_size_;
+}
+
+uint32_t ProtocolPacket::packet_id() const {
+ return packet_id_;
+}
+
+RESULT_CODE ProtocolPacket::appendData(uint8_t* chunkData,
+ uint32_t chunkDataSize) {
+ if (data_offset_ + chunkDataSize <= packet_data_.totalDataBytes) {
+ if (chunkData) {
+ if (packet_data_.data) {
+ memcpy(packet_data_.data + data_offset_, chunkData, chunkDataSize);
+ data_offset_ += chunkDataSize;
+ return RESULT_OK;
+ }
+ }
+ }
+
+ return RESULT_FAIL;
+}
+
+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_.compress = true;
+ } else {
+ packet_header_.compress = false;
+ }
+
+ 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_2) {
+ 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;
+
+ uint32_t dataPayloadSize = 0;
+ if ((offset < messageSize) &&
+ packet_header_.frameType != FRAME_TYPE_FIRST) {
+ dataPayloadSize = messageSize - offset;
+ }
+
+ uint8_t * data = 0;
+ if (dataPayloadSize) {
+ data = new uint8_t[dataPayloadSize];
+ if (data) {
+ memcpy(data, message + offset, dataPayloadSize);
+ data_offset_ = dataPayloadSize;
+ } else {
+ return RESULT_FAIL;
+ }
+ }
+
+ if (packet_header_.frameType == FRAME_TYPE_FIRST) {
+ data_offset_ = 0;
+ const uint8_t* data = message + offset;
+ uint32_t total_data_bytes = data[0] << 24;
+ total_data_bytes |= data[1] << 16;
+ total_data_bytes |= data[2] << 8;
+ total_data_bytes |= data[3];
+ set_total_data_bytes(total_data_bytes);
+ } else {
+ packet_data_.data = data;
+ }
+
+ return RESULT_OK;
+}
+
+uint8_t ProtocolPacket::protocol_version() const {
+ return packet_header_.version;
+}
+
+bool ProtocolPacket::is_compress() const {
+ return packet_header_.compress;
+}
+
+uint8_t ProtocolPacket::frame_type() const {
+ return packet_header_.frameType;
+}
+
+uint8_t ProtocolPacket::service_type() const {
+ return packet_header_.serviceType;
+}
+
+uint8_t ProtocolPacket::frame_data() const {
+ return packet_header_.frameData;
+}
+
+uint8_t ProtocolPacket::session_id() const {
+ return packet_header_.sessionId;
+}
+
+uint32_t ProtocolPacket::data_size() const {
+ return packet_header_.dataSize;
+}
+
+uint32_t ProtocolPacket::message_id() const {
+ return packet_header_.messageId;
+}
+
+uint8_t* ProtocolPacket::data() const {
+ return packet_data_.data;
+}
+
+void ProtocolPacket::set_total_data_bytes(uint32_t dataBytes) {
+ if (dataBytes) {
+ if (packet_data_.data) {
+ delete[] packet_data_.data;
+ packet_data_.data = 0;
+ }
+ packet_data_.data = new uint8_t[dataBytes];
+ packet_data_.totalDataBytes = dataBytes;
+ }
+}
+
+uint32_t ProtocolPacket::total_data_bytes() const {
+ return packet_data_.totalDataBytes;
+}
+
+uint8_t ProtocolPacket::connection_key() const {
+ return connection_key_;
+}
+
+// End of Deserialization
+} // namespace protocol_handler