diff --git a/include/request.h b/include/request.h index e3597a3..355648a 100644 --- a/include/request.h +++ b/include/request.h @@ -11,6 +11,10 @@ #include #include +namespace osdev { +namespace components { +namespace modbus { + /// The response based on the \ref Request made. struct Response { @@ -33,6 +37,7 @@ public: /// We only support a small subset of the ModBus Standard. enum class FunctionCode { + FC_UNKNOWN, READ_COILS, READ_DISCRETE_INPUTS, READ_HOLDING_REGISTERS, @@ -44,6 +49,13 @@ public: WRITE_FILE_RECORD, }; + explicit Request() + : m_functionCode(Request::FunctionCode::FC_UNKNOWN) + , m_slaveId(0) + , m_startAddress(0x00) + , m_numberOfRegisters(0x00) + {} + /// Constructor taking all necessary information to create a request. /// /// @param functionCode - The code of the action this request wants to perform. @@ -51,34 +63,53 @@ public: /// @param startAddress - Register number to start reading from or writing to. /// @param numberOfItems - Number of items to read or write from start_address. /// @param callback - Function to call when this request returns a response. - Request(Request::FunctionCode functionCode, - int slaveId, - int startAddress, - int numberOfItems, + Request(Request::FunctionCode function_code, + int slave_id, + int start_address, + int num_of_regs, std::function callback) - : m_functionCode(functionCode) - , m_slaveId(slaveId) - , m_startAddress(startAddress) - , m_numberOfItems(numberOfItems) + : m_functionCode(function_code) + , m_slaveId(slave_id) + , m_startAddress(start_address) + , m_numberOfRegisters(num_of_regs) { callbacks.push_back(callback); } + // Begin Getters and setters. + /// Sets the functioncode for this request + /// @param function_code - The functioncode enum. + void setFunctionCode(FunctionCode function_code) {m_functionCode = function_code;} + /// @return The functioncode this request handles. - FunctionCode GetFunctionCode() const {return m_functionCode;} + FunctionCode getFunctionCode() const {return m_functionCode;} + + /// Sets the slaveId of the device this request is intended for. + /// @param slave_id - The slave Id of the device. + void setSlaveId(const int slave_id) {m_slaveId = slave_id;} /// @return The slaveID of the device this request is intended for. - int GetSlaveId() const {return m_slaveId;} + uint8_t getSlaveId() const {return m_slaveId;} + + /// Sets the start address of the register(s) we want to read from. + /// @param start_address - The start address + void setStartAddress(const uint8_t start_address) {m_startAddress = start_address;} /// @return The start Address of the register(s) we're reading. - int GetStartAddress() const {return m_startAddress;} + uint8_t getStartAddress() const {return m_startAddress;} + + /// Sets the number of registers we want to read from the start address. + /// @param num_of_regs - The number of registers to read from the start address + void setNumberOfRegisters(const uint8_t num_of_regs) {m_numberOfRegisters = num_of_regs;} /// @return The number of registers we read from the \ref m_startAddress. - int GetNumberOfItems() const {return m_numberOfItems;} + uint8_t getNumberOfRegisters() const {return m_numberOfRegisters;} + + // End Getters and setters. /// @return The values read from, or to be written to, the device. /// @note never change the length of this vector. - std::vector GetDataBuffer() const {return m_dataBuffer;} + std::vector getDataBuffer() const {return m_dataBuffer;} /// @return Callbacks registered to call when new data is available. /// @note Functionn pointer returns False if the device state is OFFLINE. True, otherwise. @@ -86,17 +117,22 @@ public: private: /// Function code of this request. - FunctionCode m_functionCode; + FunctionCode m_functionCode; /// SlaveID of this request. - int m_slaveId; + uint8_t m_slaveId; /// Start address of the register for this request - int m_startAddress; + uint8_t m_startAddress; /// Amount of registers to read/write in this request - int m_numberOfItems; + uint8_t m_numberOfRegisters; /// Data to send to the device; must be the same size as \ref m_numberOfItems. - std::vector m_dataBuffer; + std::vector m_dataBuffer; }; + +} /* End namespace modbus */ +} /* End namespace components */ +} /* End namespace osdev */ + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c51b292..bb6c95c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,6 +5,7 @@ # **************************************************************** add_executable(modbustest connectionconfigtest.cpp + requesttest.cpp ) target_include_directories(modbustest PRIVATE diff --git a/tests/requesttest.cpp b/tests/requesttest.cpp new file mode 100644 index 0000000..fb84021 --- /dev/null +++ b/tests/requesttest.cpp @@ -0,0 +1,120 @@ +/**************************************************************** + * Copyright (c)2022 Peter M. Groen + * This file is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + ****************************************************************/ + +#include +#include + +#include "request.h" + +using namespace osdev::components::modbus; + +TEST(RequestTest, RequestDefaults) +{ + Request oRequest; + + // Check for all the default values + EXPECT_EQ(oRequest.getFunctionCode(), Request::FunctionCode::FC_UNKNOWN); + EXPECT_EQ(oRequest.getSlaveId(), 0x00); + EXPECT_EQ(oRequest.getStartAddress(), 0x00); + EXPECT_EQ(oRequest.getNumberOfRegisters(), 0x00); + +} + +TEST(RequestTest, RequestSlaveId) +{ + Request oRequest; + oRequest.setSlaveId(1); + + EXPECT_EQ(oRequest.getSlaveId(), 1); +} + +TEST(RequestTest, RequestStartAddress) +{ + Request oRequest; + oRequest.setStartAddress(0x04); + + EXPECT_EQ(oRequest.getStartAddress(), 0x04); +} + +TEST(RequestTest, RequestNumberOfRegisters) +{ + Request oRequest; + oRequest.setNumberOfRegisters(0x02); + + EXPECT_EQ(oRequest.getNumberOfRegisters(), 0x02); +} + +TEST(RequestTest, RequestReadCoils) +{ + Request oRequest; + oRequest.setFunctionCode(Request::FunctionCode::READ_COILS); + + EXPECT_EQ(oRequest.getFunctionCode(), Request::FunctionCode::READ_COILS); +} + +TEST(RequestTest, RequestReadDiscreteInputs) +{ + Request oRequest; + oRequest.setFunctionCode(Request::FunctionCode::READ_DISCRETE_INPUTS); + + EXPECT_EQ(oRequest.getFunctionCode(), Request::FunctionCode::READ_DISCRETE_INPUTS); +} + +TEST(RequestTest, RequestReadHoldingRegisters) +{ + Request oRequest; + oRequest.setFunctionCode(Request::FunctionCode::READ_HOLDING_REGISTERS); + + EXPECT_EQ(oRequest.getFunctionCode(), Request::FunctionCode::READ_HOLDING_REGISTERS); +} + +TEST(RequestTest, RequestReadInputRegisters) +{ + Request oRequest; + oRequest.setFunctionCode(Request::FunctionCode::READ_INPUT_REGISTERS); + + EXPECT_EQ(oRequest.getFunctionCode(), Request::FunctionCode::READ_INPUT_REGISTERS); +} + +TEST(RequestTest, RequestWriteSingleCoil) +{ + Request oRequest; + oRequest.setFunctionCode(Request::FunctionCode::WRITE_SINGLE_COIL); + + EXPECT_EQ(oRequest.getFunctionCode(), Request::FunctionCode::WRITE_SINGLE_COIL); +} + +TEST(RequestTest, RequestWriteSingleRegister) +{ + Request oRequest; + oRequest.setFunctionCode(Request::FunctionCode::WRITE_SINGLE_REGISTER); + + EXPECT_EQ(oRequest.getFunctionCode(), Request::FunctionCode::WRITE_SINGLE_REGISTER); +} + +TEST(RequestTest, RequestWriteMultipleCoils) +{ + Request oRequest; + oRequest.setFunctionCode(Request::FunctionCode::WRITE_MULTIPLE_COILS); + + EXPECT_EQ(oRequest.getFunctionCode(), Request::FunctionCode::WRITE_MULTIPLE_COILS); +} + +TEST(RequestTest, RequestWriteMultipleRegisters) +{ + Request oRequest; + oRequest.setFunctionCode(Request::FunctionCode::WRITE_MULTIPLE_REGISTERS); + + EXPECT_EQ(oRequest.getFunctionCode(), Request::FunctionCode::WRITE_MULTIPLE_REGISTERS); +} + +TEST(RequestTest, RequestWriteFileRecord) +{ + Request oRequest; + oRequest.setFunctionCode(Request::FunctionCode::WRITE_FILE_RECORD); + + EXPECT_EQ(oRequest.getFunctionCode(), Request::FunctionCode::WRITE_FILE_RECORD); +}