| /* |
| * Copyright 2019-present Infosys Limited |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /****************************************************************************** |
| * |
| * This is an auto generated file. |
| * Please do not edit this file. |
| * All edits to be made through template source file |
| * <TOP-DIR/scripts/GtpV2StackCodeGen/tts/stacktemplate.cpp.tt> |
| ******************************************************************************/ |
| #include <cstring> |
| #include <stdint.h> |
| #include "gtpV2Stack.h" |
| #include "msgClasses/gtpV2MsgFactory.h" |
| #include "msgClasses/manual/gtpV2Message.h" |
| [% FOREACH msg IN tempdata.msgList -%] |
| #include "msgClasses/[% msg.msgFileName %].h" |
| [% END -%] |
| |
| cmn::utils::Debug errorStream; |
| |
| GtpV2Stack::GtpV2Stack () |
| { |
| // TODO Auto-generated constructor stub |
| |
| } |
| |
| GtpV2Stack::~GtpV2Stack () |
| { |
| // TODO Auto-generated destructor stub |
| } |
| |
| bool |
| GtpV2Stack::encodeMessage (GtpV2MessageHeader & msgHeader, |
| MsgBuffer & buffer, void *data_p) |
| { |
| |
| //Clear the global errorStream |
| errorStream.clearStream (); |
| bool rc = false; |
| GtpV2Message & msg = |
| GtpV2MsgFactory::getInstance ().getMsgObject (msgHeader.msgType); |
| |
| uint16_t gtpHeaderStartIdx = buffer.getCurrentIndex(); |
| // Encode the header |
| GtpV2Message::encodeHeader (buffer, msgHeader); |
| |
| Uint16 startIndex = buffer.getCurrentIndex(); |
| |
| switch (msgHeader.msgType) |
| { |
| [% FOREACH msg IN tempdata.msgList -%] |
| case [% msg.className %]Type: |
| { |
| if (data_p != NULL) |
| { |
| rc = |
| dynamic_cast< |
| [% msg.className %] & >(msg). |
| encode[% msg.className %](buffer, |
| *(([% msg.className %]Data *) |
| data_p)); |
| } |
| else |
| { |
| // Application has filled the data structure provided by the stack |
| rc = |
| dynamic_cast< |
| [% msg.className %] & >(msg). |
| encode[% msg.className %] (buffer, |
| [% msg.dataMember %]); |
| } |
| break; |
| } |
| [% END -%] |
| } |
| |
| Uint16 endIndex = buffer.getCurrentIndex (); |
| |
| Uint16 messageLength = (endIndex - startIndex)+8; |
| |
| buffer.goToIndex (gtpHeaderStartIdx + 2); // 2 is where length is encoded in a gtp message TODO remove hardcoding |
| buffer.writeUint16 (messageLength, false); |
| buffer.goToIndex (endIndex); |
| return rc; |
| } |
| |
| bool |
| GtpV2Stack::decodeGtpMessageHeader(GtpV2MessageHeader& msgHeader, MsgBuffer& buffer) |
| { |
| return GtpV2Message::decodeHeader (buffer, msgHeader); |
| } |
| |
| |
| bool |
| GtpV2Stack::decodeMessage (GtpV2MessageHeader& msgHeader, |
| MsgBuffer& buffer,void* data_p) |
| { |
| errorStream.clearStream(); |
| // First decode the message header |
| bool rc = false; |
| |
| |
| |
| Uint16 msgDataLength = msgHeader.msgLength; |
| |
| if (msgHeader.teidPresent) |
| { |
| msgDataLength = msgDataLength - 8; //teid and sequence number |
| } |
| else |
| { |
| msgDataLength = msgDataLength - 4; //only sequence number |
| } |
| |
| // Validate the length before proceeding |
| if (msgDataLength != buffer.lengthLeft() ) |
| { |
| // Encoded message length does not match the number of bytes left in the message |
| errorStream.add ((char *)"Message length does not match bytes in buffer\n"); |
| errorStream.add ((char *)"Computed Message length: "); |
| errorStream.add (msgDataLength); |
| errorStream.add ((char *)" Bytes Left in buffer: "); |
| errorStream.add (buffer.lengthLeft()); |
| errorStream.endOfLine (); |
| return false; |
| } |
| |
| GtpV2Message& msg = |
| GtpV2MsgFactory::getInstance ().getMsgObject (msgHeader.msgType); |
| |
| switch (msgHeader.msgType){ |
| [% FOREACH msg IN tempdata.msgList -%] |
| case [% msg.className %]Type: |
| { |
| if (data_p != NULL) |
| { |
| rc = |
| dynamic_cast< |
| [% msg.className %] & >(msg). |
| decode[% msg.className %](buffer, |
| *([% msg.className %]Data*) |
| data_p, msgDataLength); |
| } |
| else |
| { |
| // Application wants to use the data structure provided by the stack |
| // let us first clear any data present in the internal data structure |
| memset (&[% msg.dataMember %], 0, |
| sizeof ([% msg.className %]Data)); |
| rc = |
| dynamic_cast< |
| [% msg.className %] & >(msg). |
| decode[% msg.className %](buffer, |
| [% msg.dataMember %], |
| msgDataLength); |
| } |
| break; |
| } |
| [% END -%] |
| } |
| return rc; |
| } |
| |
| void |
| GtpV2Stack::display_v(Uint8 msgType, Debug& stream, void* data_p) |
| { |
| // Display the messageType |
| stream.add ((char *)"MessageType: "); |
| stream.add (msgType); |
| stream.endOfLine (); |
| |
| GtpV2Message& msg = GtpV2MsgFactory::getInstance ().getMsgObject (msgType); |
| |
| switch (msgType){ |
| [% FOREACH msg IN tempdata.msgList -%] |
| case [% msg.className %]Type: |
| { |
| stream.add ((char *)"Message: [% msg.className %]"); |
| stream.endOfLine (); |
| if (data_p != NULL) |
| { |
| dynamic_cast< |
| [% msg.className %] & >(msg). |
| display[% msg.className %]Data_v (* |
| (([% msg.className %]Data*) data_p), stream); |
| } |
| else |
| { |
| // Application wants to use the data structure provided by the stack |
| dynamic_cast< |
| [% msg.className %] & >(msg). |
| display[% msg.className %]Data_v |
| ([% msg.dataMember %], stream); |
| } |
| break; |
| } |
| [% END -%] |
| } |
| } |