diff options
Diffstat (limited to 'mnsl/mns_message.c')
-rw-r--r-- | mnsl/mns_message.c | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/mnsl/mns_message.c b/mnsl/mns_message.c new file mode 100644 index 0000000..33a0673 --- /dev/null +++ b/mnsl/mns_message.c @@ -0,0 +1,331 @@ +/* + * MOST NetServices "Light" V3.2.7.0.1796 MultiInstance Patch + * + * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * You may also obtain this software under a propriety license from Microchip. + * Please contact Microchip for further information. + * + */ + +/*! + * \file + * \brief Implementation of class message + * + * \cond MNS_INTERNAL_DOC + * \addtogroup G_MESSAGE + * @{ + */ + +/*------------------------------------------------------------------------------------------------*/ +/* Includes */ +/*------------------------------------------------------------------------------------------------*/ +#include "mns_message.h" +#include "mns_misc.h" + +/*------------------------------------------------------------------------------------------------*/ +/* Internal constants */ +/*------------------------------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------------------------------*/ +/* Implementation */ +/*------------------------------------------------------------------------------------------------*/ +/*! \brief Constructor of common MOST message class + * \param self The instance + */ +void Msg_Ctor(CMessage *self) +{ + MISC_MEM_SET(self, 0, sizeof(*self)); + + Dln_Ctor(&self->node, self); + + self->rsvd_memory.allocator_ptr = NULL; + self->rsvd_memory.mem_info_ptr = NULL; + self->rsvd_memory.public_buffer.next_buffer_ptr = NULL; + self->rsvd_memory.public_buffer.data_ptr = &self->rsvd_buffer[0]; + self->rsvd_memory.public_buffer.data_size = MSG_SIZE_RSVD_BUFFER; + self->rsvd_memory.public_buffer.total_size = MSG_SIZE_RSVD_BUFFER; + + self->start_ptr = &self->rsvd_buffer[0]; + self->pb_msg.tel.tel_data_ptr = &self->rsvd_buffer[0]; +/* self->pb_msg.tel.tel_id = 0U; + self->pb_msg.tel.tel_cnt = 0U; + self->pb_msg.tel.tel_len = 0U; */ + + self->pb_msg.opts.llrbc = MSG_LLRBC_DEFAULT; + +/* self->header_rsvd_sz = 0U; + self->header_curr_idx = 0U; + self->header_curr_sz = 0U; + self->ref_ptr = NULL; */ +} + +/*! \brief Prepares the message for re-usage + * \details In future this function has to take care that external memory + * has to be reinitialize properly. + * \param self The instance + */ +void Msg_Cleanup(CMessage *self) +{ + void *handle = self->lld_handle_ptr; /* restore associated LLD message object */ + void *pool_ptr = self->pool_ptr; /* restore associated pool reference */ + + Msg_Ctor(self); /* simply call constructor now */ + + self->lld_handle_ptr = handle; + self->pool_ptr = pool_ptr; +} + +/*! \brief Adds external message payload to the message + * \details The internally reserved message payload is no longer in in use. + * \param self The instance + * \param payload_ptr Pointer to externally allocated payload + * \param payload_sz Size of externally allocated payload + * \param mem_info_ptr Reference to additional memory information + */ +void Msg_SetExtPayload(CMessage *self, uint8_t *payload_ptr, uint8_t payload_sz, void* mem_info_ptr) +{ + self->pb_msg.tel.tel_data_ptr = payload_ptr; + self->pb_msg.tel.tel_len = payload_sz; + + self->ext_memory.allocator_ptr = NULL; + self->ext_memory.mem_info_ptr = mem_info_ptr; + self->ext_memory.public_buffer.data_ptr = payload_ptr; + self->ext_memory.public_buffer.data_size = payload_sz; + self->ext_memory.public_buffer.total_size = payload_sz; + self->ext_memory.public_buffer.next_buffer_ptr = NULL; +} + +/*! \brief Initially defines a header space in front of the data body + * \details Ensure that \c start_ptr is assigned correctly before calling + * this functions. + * \param self The instance + * \param header_sz Size of the header + */ +void Msg_ReserveHeader(CMessage *self, uint8_t header_sz) +{ + /* self->start_ptr stays */ + self->header_rsvd_sz = header_sz; + self->header_curr_idx = header_sz; + self->header_curr_sz = 0U; + + self->pb_msg.tel.tel_data_ptr = &self->start_ptr[header_sz]; +} + +/*! \brief Adds a defined header space in front of the current header + * \param self The instance + * \param header_sz Size of the header + */ +void Msg_PullHeader(CMessage *self, uint8_t header_sz) +{ +/* MNS_ASSERT(header_sz <= self->curr_header_sz); */ + +/* self->pb_msg.tel.tel_data_ptr = &self->rsvd_buffer[MSG_SIZE_RSVD_HEADER];*/ + self->header_curr_idx -= header_sz; + self->header_curr_sz += header_sz; +} + +/*! \brief Undoes a message header of a defined size + * \param self The instance + * \param header_sz Size of the header + */ +void Msg_PushHeader(CMessage *self, uint8_t header_sz) +{ + self->header_curr_idx += header_sz; + self->header_curr_sz -= header_sz; +} + +/*------------------------------------------------------------------------------------------------*/ +/* Class Properties (get/set) */ +/*------------------------------------------------------------------------------------------------*/ +/*! \brief Retrieves the reference to the containing MOST Telegrams structure + * \param self The instance + * \return Pointer to the internal MOST Telegram structure + */ +Msg_MostTel_t* Msg_GetMostTel(CMessage *self) +{ + return &self->pb_msg; +} + +/*! \brief Retrieves the start of the current message header + * \param self The instance + * \return Pointer to the current header start + */ +uint8_t* Msg_GetHeader(CMessage *self) +{ + return &(self->rsvd_buffer[self->header_curr_idx]); +} + +/*! \brief Retrieves the size of the current message header + * \param self The instance + * \return Size of the current header in bytes + */ +uint8_t Msg_GetHeaderSize(CMessage * self) +{ + return (self->header_curr_sz); +} + +/*! \brief Retrieves the message buffer as memory structure + * \param self The instance + * \return Reference to the message memory structure + */ +Mns_Mem_Buffer_t* Msg_GetMemTx(CMessage *self) +{ + self->rsvd_memory.public_buffer.data_ptr = &(self->rsvd_buffer[self->header_curr_idx]); + + if (self->ext_memory.public_buffer.data_size == 0U) + { + self->rsvd_memory.public_buffer.next_buffer_ptr = NULL; + self->rsvd_memory.public_buffer.data_size = (uint16_t)self->header_curr_sz + (uint16_t)self->pb_msg.tel.tel_len; + self->rsvd_memory.public_buffer.total_size = (uint16_t)self->header_curr_sz + (uint16_t)self->pb_msg.tel.tel_len; + } + else + { + self->rsvd_memory.public_buffer.next_buffer_ptr = &self->ext_memory.public_buffer; + self->rsvd_memory.public_buffer.data_size = (uint16_t)self->header_curr_sz; /* only header is enclosed */ + self->rsvd_memory.public_buffer.total_size = self->rsvd_memory.public_buffer.data_size + + self->ext_memory.public_buffer.data_size; + } + + return &self->rsvd_memory.public_buffer; +} + +/*! \brief Assigns a message status handler which is called as soon as the message is processed + * \param self The instance + * \param callback_fptr Reference to the status callback function + * \param inst_ptr The instance which implements the status callback + */ +void Msg_SetTxStatusHandler(CMessage *self, Msg_TxStatusCb_t callback_fptr, void *inst_ptr) +{ + self->tx_status_inst = inst_ptr; + self->tx_status_fptr = callback_fptr; +} + +/*! \brief Marks the message as occupied by the LLD + * \param self The instance + * \param active Set to \c true if the message is occupied by the LLD, otherwise \c false. + */ +void Msg_SetTxActive(CMessage *self, bool active) +{ + self->tx_active = active; +} + +/*! \brief Checks if the message as occupied by the LLD + * \param self The instance + * \return Returns \c true if the message is occupied by the LLD, otherwise \c false. + */ +bool Msg_IsTxActive(CMessage *self) +{ + return self->tx_active; +} + +/*! \brief Marks the message as bypass message + * \param self The instance + * \param bypass Set to \c true if the message is supposed to be a bypass message, otherwise \c false. + */ +void Msg_SetTxBypass(CMessage *self, bool bypass) +{ + self->tx_bypass = bypass; +} + +/*! \brief Checks if the message is marked as bypass message + * \param self The instance + * \return Returns \c true if the message is marked as bypass message, otherwise \c false. + */ +bool Msg_IsTxBypass(CMessage *self) +{ + return self->tx_bypass; +} + +/*! \brief Fires a status notification for the message object + * \param self The instance + * \param status The transmission status + */ +void Msg_NotifyTxStatus(CMessage *self, Mns_MsgTxStatus_t status) +{ + if (self->tx_status_fptr != NULL) + { + self->tx_status_fptr(self->tx_status_inst, &self->pb_msg, status); + } +} + +/*! \brief Assigns a low-level driver message + * \param self The instance + * \param handle The reference to a low-level driver message object (Tx or Rx) + */ +void Msg_SetLldHandle(CMessage *self, void *handle) +{ + self->lld_handle_ptr = handle; +} + +/*! \brief Retrieves the reference to a low-level driver message + * \param self The instance + * \return The reference to a low-level driver message object or \c NULL + * if no message is assigned. + */ +void *Msg_GetLldHandle(CMessage *self) +{ + return self->lld_handle_ptr; +} + +/*! \brief Assigns a reference for the owning pool + * \param self The instance + * \param pool_ptr The reference to the owning pool + */ +void Msg_SetPoolReference(CMessage *self, void *pool_ptr) +{ + self->pool_ptr = pool_ptr; +} + +/*! \brief Retrieves a reference for the owning pool + * \param self The instance + * \return The reference to the owning pool or \c NULL + * if no pool is assigned. + */ +void *Msg_GetPoolReference(CMessage *self) +{ + return self->pool_ptr; +} + +/*! \brief Retrieves the reference to the internal node member + * \param self The instance + * \return The reference the internal list node + */ +CDlNode *Msg_GetNode(CMessage *self) +{ + return &self->node; +} + +/*! \brief Performs checks on length payload length + * \param self The instance + * \return Returns \c true if the verification succeeded. Otherwise \c false. + */ +bool Msg_VerifyContent(CMessage *self) +{ + bool success = (self->pb_msg.tel.tel_len <= MSG_MAX_SIZE_PAYLOAD) ? true : false; + + return success; +} + +/*! + * @} + * \endcond + */ + +/*------------------------------------------------------------------------------------------------*/ +/* End of file */ +/*------------------------------------------------------------------------------------------------*/ + |