Skip to content

GVCP support - #1357

Open
tigercosmos wants to merge 4 commits into
seladb:devfrom
tigercosmos:gvcp_0410
Open

tigercosmos wants to merge 4 commits into
seladb:devfrom
tigercosmos:gvcp_0410

Conversation

@tigercosmos

@tigercosmos tigercosmos commented Apr 12, 2024 •

Copy link
Copy Markdown
Collaborator

Related to #1321

This PR adds a layer for the GigE Vision Control Protocol (GVCP). The layer supports parsing, creation and editing of GVCP messages on UDP port 3956.

Design

  • GvcpRequestLayer and GvcpAcknowledgeLayer represent all messages. Discovery and Force IP messages have their own layer classes.
  • A layer holds the GVCP header and the message fields that its class knows. parseNextLayer() puts the rest of the message in a PayloadLayer.
  • computeCalculateFields() sets the data size field to the size of the data after the header.
  • The header and body structs are protected or private members of the layer classes.
  • The request and acknowledge constructors throw std::invalid_argument for a value of the wrong kind. Command values are even, and acknowledge values are odd.
  • GvcpDiscoveryRequestLayer exposes the allow-broadcast-acknowledge flag.
  • operator<< prints commands and statuses by name. Values that the spec does not define map to Unknown.
  • UdpLayer falls back to PayloadLayer if the data is not valid GVCP.
  • The protocol type is 65, because GTPv2 uses 57.

Tests

The tests cover parsing, creation, editing and malformed data.

@tigercosmos
tigercosmos requested a review from seladb as a code owner April 12, 2024 09:31
@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
tigercosmos marked this pull request as ready for review August 9, 2024 02:25
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/src/GvcpLayer.cpp Outdated
Comment thread Packet++/src/GvcpLayer.cpp Outdated
@Dimi1010 Dimi1010 linked an issue Aug 9, 2024 that may be closed by this pull request
@tigercosmos

Copy link
Copy Markdown
Collaborator Author

@seladb The PR is ready. Please take a look.

@codecov

codecov Bot commented Aug 12, 2024 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.33193% with 73 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.82%. Comparing base (ad344a8) to head (b17ec4a).
⚠️ Report is 3 commits behind head on dev.

Files with missing lines Patch % Lines
Packet++/src/GvcpLayer.cpp 87.07% 72 Missing ⚠️
Packet++/header/GvcpLayer.h 98.71% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1357      +/-   ##
==========================================
+ Coverage   82.61%   82.82%   +0.21%     
==========================================
  Files         339      342       +3     
  Lines       61875    62972    +1097     
  Branches    13036    12947      -89     
==========================================
+ Hits        51115    52159    +1044     
- Misses       9877     9930      +53     
  Partials      883      883              
Flag Coverage Δ
23.11.6 6.95% <0.15%> (-0.15%) ⬇️
24.11.5 6.93% <0.15%> (-0.14%) ⬇️
25.11.1 6.93% <0.15%> (-0.17%) ⬇️
alpine320 76.84% <85.46%> (+0.26%) ⬆️
fedora42 76.37% <84.43%> (+0.23%) ⬆️
macos-15 82.58% <94.46%> (+0.24%) ⬆️
macos-26 82.59% <94.46%> (+0.25%) ⬆️
macos-26-intel 82.51% <94.46%> (+0.24%) ⬆️
mingw32 71.16% <73.41%> (+0.09%) ⬆️
mingw64 70.84% <73.56%> (+0.32%) ⬆️
npcap ?
rhel94 76.18% <84.43%> (+0.26%) ⬆️
ubuntu2204 76.19% <84.40%> (+0.22%) ⬆️
ubuntu2404 76.47% <84.40%> (+0.21%) ⬆️
ubuntu2604 76.46% <84.37%> (+0.24%) ⬆️
ubuntu2604-arm64 76.33% <84.75%> (+0.25%) ⬆️
ubuntu2604-icpx 59.15% <66.32%> (+0.14%) ⬆️
unittest 82.82% <92.33%> (+0.21%) ⬆️
windows-2022 85.67% <92.13%> (+0.32%) ⬆️
windows-2025 85.37% <91.21%> (+0.28%) ⬆️
winpcap 85.72% <92.13%> (+0.43%) ⬆️
xdp 54.27% <84.40%> (+0.57%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tigercosmos

Copy link
Copy Markdown
Collaborator Author

Don't know why the fuzz tests failed?

@seladb seladb left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I just started reviewing this PR because I still need to learn this protocol. But here are a few general comments

Comment thread Packet++/header/GvcpLayer.h Outdated

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

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I think we can move all implementations that use netToHost16 to GvcpLayer.cpp so we don't expose SystemUtils.h in the header file

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Since it's one line function, I think it's clearer to be in the header. I forward declare the function, so we don't need to include the whole header file.

Copy link
Copy Markdown
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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

fixed.

Comment thread Packet++/src/UdpLayer.cpp Outdated
Comment thread README.md Outdated
Comment thread Tests/Packet++Test/PacketExamples/gvcp_discovery_ack.pcap Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated

@seladb seladb left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@tigercosmos here is my suggestion of the structure we can use, which follows ideas implemented in other PcapPlusPlus layers. This code snippet is just the high level interface and doesn't include all the methods, implementation and lower level details, but it's mostly to demonstrate my suggestion.

Please let me know what you think and we can discuss it further.

struct gvcp_command_header
{
	uint8_t gcvpCommand = 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;
};

struct gvcp_ack_header
{
	uint16_t status = 0;
	uint16_t command = 0;
	uint16_t dataSize = 0;
	uint16_t ackId = 0;
};

struct gvcp_discovery_message : public gvcp_command_header
{
};

struct gvcp_discovery_ack_message : public gvcp_ack_header
{
	uint16_t versionMajor = 0;
	uint16_t versionMinor = 0;
	uint32_t deviceMode = 0;
	uint16_t reserved = 0;
	uint8_t macAddress[6] = { 0 };
	uint32_t supportedIpConfigOptions = 0;
	uint32_t ipConfigCurrent = 0;
	uint8_t reserved2[12] = { 0 };
	uint32_t ipAddress = 0;
	uint8_t reserved3[12];
	uint32_t subnetMask = 0;
	uint8_t reserved4[12] = { 0 };
	uint32_t defaultGateway = 0;
	char manufacturerName[32] = { 0 };
	char modelName[32] = { 0 };
	char deviceVersion[32] = { 0 };
	char manufacturerSpecificInformation[48] = { 0 };
	char serialNumber[16] = { 0 };
	char userDefinedName[16] = { 0 };
};

class GvcpLayer : public Layer
{
public:
	GvcpLayer() = delete;

	static bool isGvcpPort(uint16_t port);
	static GvcpLayer* parseGvcpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);

	// implement Layer's abstract methods
	void parseNextLayer() override;
	void computeCalculateFields() override;
	OsiModelLayer getOsiModelLayer() const override;
};

class GvcpRequestLayer : public GvcpLayer
{
public:
	GvcpRequestLayer() = delete;

	static bool isDataValid(const uint8_t* data, size_t dataLen);

	GvcpFlag getFlag() const;
	void setFlag(const GvcpFlag flag);

	GvcpCommand getCommand() const;

	uint16_t getLength() const;

	uint16_t getRequestId() const;
	void setRequestId(uint16_t requestId);
};

class GvcpAckLayer : public GvcpLayer
{
public:
	GvcpAckLayer() = delete;

	static bool isDataValid(const uint8_t* data, size_t dataLen);

	GvcpResponseStatus getStatus() const;
	void setStatus(GvcpResponseStatus status);

	GvcpCommand getCommand() const;

	uint16_t getLength() const;

	uint16_t getAckId() const;
	void setAckId(uint16_t ackId);
};

class GvcpDiscoveryRequestLayer : public GvcpRequestLayer
{
public:
	// constructors

	GvcpDiscoveryRequestLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
	GvcpDiscoveryRequestLayer();

	// implement Layer's abstract methods

	std::string toString() const override;
	size_t getHeaderLen() const override;
};

class GvcpDiscoveryAckLayer : public GvcpAckLayer
{
	// constructors

	GvcpDiscoveryAckLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
	GvcpDiscoveryAckLayer(/** a list of all params: uint16_t majorVersion, uint16_t minorVersion, uint32_t deviceMode, ...*/);

	// getters and setters

	std::pair<uint16_t, uint16_t> getVersion() const;

	pcpp::MacAddress getMacAddress() const;
	void setMacAddress(const pcpp::MacAddress macAddress);

	// ...

	// implement Layer's abstract methods

	std::string toString() const override;
	size_t getHeaderLen() const override;
};

class GvcpForceIpRequestLayer : public GvcpRequestLayer
{
	// ...
};

class GvcpForceIpAcktLayer : public GvcpAckLayer
{
	// ...
};

@tigercosmos

Copy link
Copy Markdown
Collaborator Author

@seladb Reading your sample code, basically I got your intention. So "Discovery" and "ForceIP" have their own layer, and for other commands, they will fall back to general GVCPRequestLayer and GvcpAcknowledgeLayer. I don't see a problem for now, and I will try to refactor the PR based on this and see if I encounter any issues.

@seladb

seladb commented Aug 18, 2024

Copy link
Copy Markdown
Owner

@seladb Reading your sample code, basically I got your intention. So "Discovery" and "ForceIP" have their own layer, and for other commands, they will fall back to general GVCPRequestLayer and GvcpAcknowledgeLayer. I don't see a problem for now, and I will try to refactor the PR based on this and see if I encounter any issues.

Yes, other messages should fall under GvcpRequestLayer or GvcpAckLayer. In that way we can create specific layers for more messages in the future

@tigercosmos
tigercosmos marked this pull request as draft August 23, 2024 09:08
@tigercosmos tigercosmos removed this from the September 2024 Release milestone Sep 25, 2024
@tigercosmos
tigercosmos marked this pull request as ready for review September 26, 2024 01:52
@tigercosmos

Copy link
Copy Markdown
Collaborator Author

@seladb The code has been updated, could you take a look?

@tigercosmos

Copy link
Copy Markdown
Collaborator Author

@seladb ping.

@seladb

seladb commented Oct 2, 2024

Copy link
Copy Markdown
Owner

@seladb ping.

Sorry for the delay, I'll review it soon

Comment thread Common++/header/Logger.h Outdated
Comment thread Packet++/header/ProtocolType.h Outdated
Comment thread Tests/Packet++Test/PacketExamples/gvcp_discovery_ack.pcap Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
@seladb

seladb commented Oct 2, 2024

Copy link
Copy Markdown
Owner

@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
Copy Markdown
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.

Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated

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

Copy link
Copy Markdown
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 thread Packet++/header/GvcpLayer.h Outdated
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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

Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
*/
GvcpCommand getCommand() const
{
return static_cast<GvcpCommand>(netToHost16(getGvcpHeader()->command));

Copy link
Copy Markdown
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();

Comment thread Packet++/header/GvcpLayer.h Outdated
* @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
Copy Markdown
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 thread Packet++/header/GvcpLayer.h Outdated
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
Copy Markdown
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

Comment thread Packet++/header/GvcpLayer.h Outdated
*/
GvcpResponseStatus getStatus() const
{
return static_cast<GvcpResponseStatus>((netToHost16(getGvcpHeader()->status)));

Copy link
Copy Markdown
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

Comment thread Packet++/header/GvcpLayer.h Outdated
*/
GvcpCommand getCommand() const
{
return static_cast<GvcpCommand>(netToHost16(getGvcpHeader()->command));

Copy link
Copy Markdown
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

seladb commented Oct 23, 2024

Copy link
Copy Markdown
Owner

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

@tigercosmos

Copy link
Copy Markdown
Collaborator Author

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

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

@tigercosmos

Copy link
Copy Markdown
Collaborator Author

Ops, I didn't notice this. Changed.

Comment thread Packet++/header/ProtocolType.h Outdated
Comment thread Packet++/src/GvcpLayer.cpp Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
@seladb

seladb commented Mar 20, 2025

Copy link
Copy Markdown
Owner

@tigercosmos this PR is open for a long time, do you plan to continue working on it or should we close it?

@tigercosmos

Copy link
Copy Markdown
Collaborator Author

Let's close it.

@tigercosmos tigercosmos reopened this Sep 17, 2026
tigercosmos added a commit to tigercosmos/PcapPlusPlus that referenced this pull request Sep 17, 2026
Rework of seladb#1357 on top of the current dev branch, addressing the open
review comments:

- Keep the wire structs plain (no constructors/methods) under
  pcpp::internal and move all byte-order handling to GvcpLayer.cpp.
- Drop the raw-buffer copy constructors; layers are built either from a
  parsed packet or from typed arguments.
- getHeaderLen() covers the whole GVCP message since GVCP is always the
  last layer; message data is exposed via getPayloadData().
- getCommand()/getStatus() map unexpected values to Unknown using a
  switch instead of a global unordered_set.
- parseGvcpLayer() validates the data, passes prevLayer/packet to every
  layer it creates and UdpLayer falls back to PayloadLayer.
- Use protocol type 65 (57 is taken by GTPv2).
- Fix getVersion() byte order and the unbounded reads of the fixed-size
  string fields of the discovery acknowledge.
- Add setters and typed constructors for Discovery and Force IP
  messages, and creation / edit / malformed-data tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
tigercosmos added a commit to tigercosmos/PcapPlusPlus that referenced this pull request Sep 17, 2026
Rework of seladb#1357 on top of the current dev branch, addressing the open
review comments:

- Keep the wire structs plain (no constructors/methods) under
  pcpp::internal and move all byte-order handling to GvcpLayer.cpp.
- Drop the raw-buffer copy constructors; layers are built either from a
  parsed packet or from typed arguments.
- getHeaderLen() covers the whole GVCP message since GVCP is always the
  last layer; message data is exposed via getPayloadData().
- getCommand()/getStatus() map unexpected values to Unknown using a
  switch instead of a global unordered_set.
- parseGvcpLayer() validates the data, passes prevLayer/packet to every
  layer it creates and UdpLayer falls back to PayloadLayer.
- Use protocol type 65 (57 is taken by GTPv2).
- Fix getVersion() byte order and the unbounded reads of the fixed-size
  string fields of the discovery acknowledge.
- Add setters and typed constructors for Discovery and Force IP
  messages, and creation / edit / malformed-data tests.
@tigercosmos tigercosmos self-assigned this Sep 17, 2026
@tigercosmos
tigercosmos marked this pull request as ready for review September 17, 2026 10:24

@tigercosmos tigercosmos left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@seladb @Dimi1010 I have reworked this PR and addressed all issues above. Please help review, thanks!

@Dimi1010 Dimi1010 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM code wise. Tho, I haven't gone in depth into the actual spec.

Comment thread Packet++/src/GvcpLayer.cpp
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h
Comment thread Packet++/src/GvcpLayer.cpp Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/src/GvcpLayer.cpp Outdated
Comment thread Packet++/src/GvcpLayer.cpp Outdated
Comment thread Packet++/header/GvcpLayer.h
Comment thread Packet++/src/GvcpLayer.cpp Outdated
@tigercosmos
tigercosmos force-pushed the gvcp_0410 branch 2 times, most recently from 3c87bd8 to 5027426 Compare September 27, 2026 04:11
@tigercosmos

Copy link
Copy Markdown
Collaborator Author

@seladb All issues fixed. Please take a look, thanks

Comment thread Packet++/src/GvcpLayer.cpp
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h Outdated
Comment thread Packet++/header/GvcpLayer.h
Add parsing, creation and editing of GVCP messages on UDP port 3956.

- GvcpRequestLayer and GvcpAcknowledgeLayer represent all messages.
  Discovery and Force IP messages have their own layer classes.
- A layer holds the GVCP header and the message fields that its class
  knows. parseNextLayer() puts the rest of the message in a
  PayloadLayer, and computeCalculateFields() updates the data size.
- The header and body structs are protected or private members of the
  layer classes.
- The request and acknowledge constructors reject a value of the wrong
  kind. Command values are even, and acknowledge values are odd.
- GvcpDiscoveryRequestLayer exposes the allow-broadcast-acknowledge
  flag.
- The command and status enums are nested in GvcpLayer. They print by
  name, and values that the spec does not define map to Unknown.
- UdpLayer falls back to PayloadLayer if the data is not valid GVCP.
- The protocol type is 65, because GTPv2 uses 57.
@tigercosmos
tigercosmos requested a review from seladb September 30, 2026 04:34

@seladb seladb left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

A few small comments, otherwise LGTM

Comment thread Packet++/header/GvcpLayer.h Outdated
Comment on lines +23 to +29
struct GvcpVersion
{
/// The version major number
uint16_t major;
/// The version minor number
uint16_t minor;
};

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Why did we keep it outside of the layer class? It can be a public struct inside GvcpDiscoveryAcknowledgeLayer

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done, it's GvcpDiscoveryAcknowledgeLayer::GvcpVersion now.

Comment thread Packet++/header/GvcpLayer.h Outdated

/// 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
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This enum can move to GvcpAcknowledgeLayer

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done, it's GvcpAcknowledgeLayer::GvcpResponseStatus now.

Move GvcpResponseStatus into GvcpAcknowledgeLayer and GvcpVersion into
GvcpDiscoveryAcknowledgeLayer, the layers that own these fields.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Before you merge, can you also implement serializeLayer()?
You can see several examples of how to implement it in this PR: #2277

If you don't have time feel free to merge this PR as is and I'll add it later.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done, I added serializeLayer() to all the GVCP layers.

Implement serializeLayer() for the GVCP layers. Each layer writes its
fields after the fields of its parent class: the command and data size,
then the request or acknowledge header fields, then the Discovery or
Force IP fields. Command and status values are written as a number and
as a name.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Introduce GigE Vision Control Protocol (GVCP) protocol

4 participants