Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GVCP support #1357

Open
wants to merge 72 commits into
base: dev
Choose a base branch
from
Open

GVCP support #1357

wants to merge 72 commits into from

Conversation

tigercosmos
Copy link
Collaborator

@tigercosmos tigercosmos commented Apr 12, 2024

Per #1321

This PR supported the GVCP protocol, including the GVCP request and GVCP acknowledgment.

Also, the PR added the most common commands of GVCP: Discovery command, ForceIP command, Read register Command, and Write register command.

@tigercosmos tigercosmos marked this pull request as draft April 12, 2024 09:31
@egecetin egecetin added this to the Augest 2024 Release milestone Jun 5, 2024
@tigercosmos
Copy link
Collaborator Author

@seladb ping.

@seladb
Copy link
Owner

seladb commented Oct 2, 2024

@seladb ping.

Sorry for the delay, I'll review it soon

Common++/header/Logger.h Outdated Show resolved Hide resolved
Packet++/header/ProtocolType.h Outdated Show resolved Hide resolved
Tests/Packet++Test/PacketExamples/gvcp_discovery_ack.pcap Outdated Show resolved Hide resolved
Packet++/header/GvcpLayer.h Outdated Show resolved Hide resolved
Packet++/header/GvcpLayer.h Outdated Show resolved Hide resolved
Packet++/header/GvcpLayer.h Outdated Show resolved Hide resolved
@seladb
Copy link
Owner

seladb commented Oct 2, 2024

@tigercosmos I didn't review the entire PR because this comment wasn't addressed yet. Can you please address this and I'll review the rest of the PR?

@tigercosmos
Copy link
Collaborator Author

@tigercosmos I didn't review the entire PR because this comment wasn't addressed yet. Can you please address this and I'll review the rest of the PR?

@seladb What do you mean not changed? I have changed all layers. Or do you mean putting the header definition inside the layer? I don't do that because the layer will be too big.

Packet++/header/GvcpLayer.h Show resolved Hide resolved
Packet++/header/GvcpLayer.h Outdated Show resolved Hide resolved

GvcpCommand getCommand() const
{
return static_cast<GvcpCommand>(netToHost16(command));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's a good practice to put this in the header file, I vote we don't forward declare and move the implementation to the cpp file

Comment on lines 118 to 123
GvcpRequestHeader() = default;

GvcpRequestHeader(GvcpFlag flag, GvcpCommand command, uint16_t dataSize, uint16_t requestId)
: flag(flag), command(hostToNet16(static_cast<uint16_t>(command))), dataSize(hostToNet16(dataSize)),
requestId(hostToNet16(requestId))
{}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need c'tors for a struct? 🤔

What we usually do is declare all properties as public and then we don't need c'tors.
These structs are internal to the GVCP layers classes and shouldn't be exposed outside, so it doesn't matter if their properties are public.

If you want you can move these structs as protected inside of the GVCP layer classes

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a constructor for it because the byte order will change, and it's better to handle it by the constructor. In addition, GvcpRequestHeader is public in purpose here. Users are free to get the raw header if they want, so there is also a public function getGvcpHeader() in the layers. I don't think we should stop users from getting the header.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I mentioned it in some comments, but I'm not sure.... In my opinion there is no need to expose both getGvcpHeader() and getters/setters for each property, that will create a somewhat confusing API.

In older protocols we used to only expose the "raw header" (like getGvcpHeader()), but in newer protocols we usually expose getters and setters which I think provides a cleaner API. We also got feedback from users that they prefer the getters/setters over the "raw header"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, let me not expose it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are under internal now

Packet++/header/GvcpLayer.h Outdated Show resolved Hide resolved
*/
GvcpCommand getCommand() const
{
return static_cast<GvcpCommand>(netToHost16(getGvcpHeader()->command));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do:

return getGvcpHeader()->getCommand();

* @param[in] data A pointer to the data including the header and the payload
* @param[in] dataSize The size of the data in bytes
*/
GvcpAcknowledgeLayer(const uint8_t* data, size_t dataSize);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto: why do we need this c'tor if we have the c'tor below?

Comment on lines 426 to 429
GvcpAckHeader* getGvcpHeader() const
{
return reinterpret_cast<GvcpAckHeader*>(m_Data); // the header is at the beginning of the data
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto: this method can be private/protected

*/
GvcpResponseStatus getStatus() const
{
return static_cast<GvcpResponseStatus>((netToHost16(getGvcpHeader()->status)));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should handle cases where getGvcpHeader()->status is an unexpected value and return GvcpResponseStatus::Unknown

*/
GvcpCommand getCommand() const
{
return static_cast<GvcpCommand>(netToHost16(getGvcpHeader()->command));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto: we can do:

return getGvcpHeader()->getCommand();

@seladb
Copy link
Owner

seladb commented Oct 23, 2024

@tigercosmos a gentle reminder to address the PR comments ☝️

@tigercosmos
Copy link
Collaborator Author

@tigercosmos a gentle reminder to address the PR comments ☝️

Thanks. I will continue on this after October. Quite busy these days.


using GvcpFlag = uint8_t; // flag bits are specified by each command

/// @brief Gvcp command defines the command values and the corresponding acknowledge values
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. nit: let's use GVCP (capital letters) instead of Gvcp in the doxygen documentation (not in class names etc).
    Please search and replace other instances of Gvcp in this file and replace them too
  2. In order to keep the convention we have everywhere else, maybe use this format for doxygen comments?
    /**
     * comment...
     */

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure fixed.

Comment on lines 119 to 133
uint8_t magicNumber = internal::kGvcpMagicNumber; // always fixed
uint8_t flag = 0; // 0-3 bits are specified by each command, 4-6 bits are reserved, 7 bit is acknowledge
uint16_t command = 0;
uint16_t dataSize = 0;
uint16_t requestId = 0;

// ------------- methods --------------
gvcp_request_header() = default;

gvcp_request_header(GvcpFlag flag, GvcpCommand command, uint16_t dataSize, uint16_t requestId)
: flag(flag), command(hostToNet16(static_cast<uint16_t>(command))), dataSize(hostToNet16(dataSize)),
requestId(hostToNet16(requestId))
{}

GvcpCommand getCommand() const
Copy link
Owner

@seladb seladb Oct 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we decide to keep this struct and the other structs public, we should add doxygen documentation for each public member and public method.

If we move them to be private/protected then no doxygen documentation is needed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the struct is now under internal.


/// @brief GVCP response status can be returned in an acknowledge message or a GVSP header.
/// See more in the spec "Table 19-1: List of Standard Status Codes"
enum class GvcpResponseStatus : uint16_t
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This enum has doxygen documentation for its values but GvcpCommand doesn't. I think we should be consistent - either we add doxygen to all values in all enums, or we don't...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some enums in the spec have explanations but some don't. I will add the comments for the enum values as long as the spec has the sentences for the values.

Comment on lines 88 to 91
LocalProblem = 0x8008, // deprecated
MsgMismatch = 0x8009, // deprecated
InvalidProtocol = 0x800A, // deprecated
NoMsg = 0x800B, // deprecated
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These // deprecated comments are not in the doxygen format so these values won't appear in the API documentation. We should change them to ///< deprecated.

Same for other // deprecated comments below

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

Comment on lines 118 to 123
GvcpRequestHeader() = default;

GvcpRequestHeader(GvcpFlag flag, GvcpCommand command, uint16_t dataSize, uint16_t requestId)
: flag(flag), command(hostToNet16(static_cast<uint16_t>(command))), dataSize(hostToNet16(dataSize)),
requestId(hostToNet16(requestId))
{}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I mentioned it in some comments, but I'm not sure.... In my opinion there is no need to expose both getGvcpHeader() and getters/setters for each property, that will create a somewhat confusing API.

In older protocols we used to only expose the "raw header" (like getGvcpHeader()), but in newer protocols we usually expose getters and setters which I think provides a cleaner API. We also got feedback from users that they prefer the getters/setters over the "raw header"

@tigercosmos
Copy link
Collaborator Author

Still WIP, not ready yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Introduce GigE Vision Control Protocol (GVCP) protocol
4 participants