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

camera: action API support #468

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions src/arvcamera.c
Original file line number Diff line number Diff line change
Expand Up @@ -2739,6 +2739,114 @@ arv_camera_gv_set_packet_size_adjustment (ArvCamera *camera, ArvGvPacketSizeAdju
arv_gv_device_set_packet_size_adjustment (ARV_GV_DEVICE (priv->device), adjustment);
}

/**
* arv_camera_gv_configure_action_command:
* @camera: a #ArvCamera
* @command_name: the action command that will be configured (1-based)
* @device_key: a user defined 'password' that will be used to authorize action commands
* @group_key: a user defined group that will have to match for an action command
* @group_mask: a bit field that gets matched to a mask in the action command
* @error: a #GError placeholder, %NULL to ignore
*
* Configure a camera to accept action commands
*
* Since: 0.8.7
*/

void
arv_camera_gv_configure_action_command (ArvCamera *camera, const char *command_name,
guint32 device_key, guint32 group_key, guint32 group_mask, GError **error)
{
GError *local_error = NULL;

g_return_if_fail (arv_camera_is_gv_device (camera));

if (error == NULL)
arv_camera_set_string (camera, "ActionSelector", command_name, &local_error);
if (error == NULL)
arv_camera_set_integer (camera, "ActionDeviceKey", device_key, &local_error);
if (error == NULL)
arv_camera_set_integer (camera, "ActionGroupKey", group_key, &local_error);
if (error == NULL)
arv_camera_set_integer (camera, "ActionGroupMask", group_key, &local_error);
Comment on lines +2764 to +2771
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should test local_error, not error


if (local_error != NULL)
g_propagate_error (error, local_error);
}

/**
* arv_camera_gv_get_available_action_commands:
* @camera: a #ArvCamera
* @n_commands: (out): number of action commands
* @error: a #GError placeholder, %NULL to ignore
*
* Returns: (array length=n_commands) (transfer container): a newly allocated array of strings, which must be freed
* using g_free().
*
* Since: 0.8.7
*/

const char **
arv_camera_gv_get_available_action_commands (ArvCamera *camera, guint *n_commands, GError **error)
{
return arv_camera_dup_available_enumerations_as_strings (camera, "ActionSelector", n_commands, error);
}

/**
* arv_camera_gv_issue_action_command:
* @device_key: a user defined 'password' that will be used to authorize action commands
* @group_key: a user defined group that will have to match for an action command
* @group_mask: a bit field that gets matched to a mask in the action command
* @broadcast_address: the address the action command is sent to
* @inet_addresses: (out): a placeholder for an array of acknowledge IP adresses
* @n_acknowledges: (out): a placeholder for the number of ackowledges
Comment on lines +2801 to +2802
Copy link
Contributor Author

Choose a reason for hiding this comment

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

API: we should handle devices by using #ArvDevice instances here, not by their IP addresses.

* @error: a GError placeholder, %NULL to ignore
*
* Issue action command
*
* Returns: %TRUE if successfull
*
* Since: 0.8.7
*/

gboolean
arv_camera_gv_issue_action_command (guint32 device_key, guint32 group_key, guint32 group_mask,
GInetAddress *broadcast_address,
GInetAddress **inet_addresses, guint *n_acknowledges, GError **error)
{
return arv_gv_device_issue_scheduled_action_command (device_key, group_key, group_mask,
0, broadcast_address,
inet_addresses, n_acknowledges, error);
}

/**
* arv_camera_gv_issue_scheduled_action_command:
* @device_key: a user defined 'password' that will be used to authorize action commands
* @group_key: a user defined group that will have to match for an action command
* @group_mask: a bit field that gets matched to a mask in the action command
* @timestamp_ns: action time, in nanosecond
* @broadcast_address: the address the action command is sent to
* @inet_addresses: (out): a placeholder for an array of acknowledge IP adresses
* @n_acknowledges: (out): a placeholder for the number of ackowledges
* @error: a GError placeholder, %NULL to ignore
*
* Issue action command
*
* Returns: %TRUE if successfull
*
* Since: 0.8.7
*/

gboolean
arv_camera_gv_issue_scheduled_action_command (guint32 device_key, guint32 group_key, guint32 group_mask,
guint64 timestamp_ns, GInetAddress *broadcast_address,
GInetAddress **inet_addresses, guint *n_acknowledges, GError **error)
{
return arv_gv_device_issue_scheduled_action_command (device_key, group_key, group_mask,
timestamp_ns, broadcast_address,
inet_addresses, n_acknowledges, error);
}

/**
* arv_camera_is_uv_device:
* @camera: a #ArvCamera
Expand Down
13 changes: 13 additions & 0 deletions src/arvcamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <arvstream.h>
#include <arvgvstream.h>
#include <arvgvdevice.h>
#include <gio/gio.h>

G_BEGIN_DECLS

Expand Down Expand Up @@ -191,6 +192,18 @@ void arv_camera_gv_set_packet_size_adjustment (ArvCamera *camera,

void arv_camera_gv_set_stream_options (ArvCamera *camera, ArvGvStreamOption options);

void arv_camera_gv_configure_action_command (ArvCamera *camera, const char *command_name,
guint32 device_key, guint32 group_key, guint32 group_mask,
GError **error);
const char ** arv_camera_gv_get_available_action_commands (ArvCamera *camera, guint *n_commands, GError **error);
gboolean arv_camera_gv_issue_action_command (guint32 device_key, guint32 group_key, guint32 group_mask,
GInetAddress *broadcast_address,
GInetAddress **inet_addresses, guint *n_acknowledges,
GError **error);
gboolean arv_camera_gv_issue_scheduled_action_command (guint32 device_key, guint32 group_key, guint32 group_mask,
guint64 timestamp_ns, GInetAddress *broadcast_address,
GInetAddress **inet_addresses, guint *n_acknowledges, GError **error);

/* USB3Vision specific API */

gboolean arv_camera_is_uv_device (ArvCamera *camera);
Expand Down
44 changes: 44 additions & 0 deletions src/arvgvcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,50 @@ arv_gvcp_packet_new_packet_resend_cmd (guint64 frame_id,
return packet;
}

/**
* arv_gvcp_packet_new_action_cmd: (skip)
* @device_key: device key
* @group_key: group key
* @group_mask: group mask
* @timestamp: optional timestamp (<=0 if not used)
*
* Create a gvcp packet for an action command.
*
* Return value: (transfer full): a new #ArvGvcpPacket
*/

ArvGvcpPacket *
arv_gvcp_packet_new_action_cmd (guint16 packet_id,
guint32 device_key, guint32 group_key,
guint32 group_mask, gint64 timestamp,
size_t *packet_size)
{
ArvGvcpPacket *packet;
guint32 *data;

*packet_size = sizeof (ArvGvcpHeader) + 3 * sizeof (guint32);
if (timestamp <= 0)
*packet_size += sizeof (gint64);

packet = g_malloc (*packet_size);

packet->header.packet_type = ARV_GVCP_PACKET_TYPE_CMD;
packet->header.packet_flags = 0;
packet->header.command = g_htons (ARV_GVCP_COMMAND_ACTION_CMD);
packet->header.size = g_htons (*packet_size - sizeof (ArvGvcpHeader));
packet->header.id = g_htons (packet_id);

data = (guint32 *) &packet->data;

data[0] = g_htonl (device_key);
data[1] = g_htonl (group_key);
data[2] = g_htonl (group_mask);
if (timestamp <=0)
*((gint64 *)&data[3]) = GINT64_TO_BE(timestamp);

return packet;
}

static const char *
arv_enum_to_string (GType type,
guint enum_value)
Expand Down
8 changes: 7 additions & 1 deletion src/arvgvcpprivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,9 @@ typedef enum {
ARV_GVCP_COMMAND_READ_MEMORY_ACK = 0x0085,
ARV_GVCP_COMMAND_WRITE_MEMORY_CMD = 0x0086,
ARV_GVCP_COMMAND_WRITE_MEMORY_ACK = 0x0087,
ARV_GVCP_COMMAND_PENDING_ACK = 0x0089
ARV_GVCP_COMMAND_PENDING_ACK = 0x0089,
ARV_GVCP_COMMAND_ACTION_CMD = 0x0100,
ARV_GVCP_COMMAND_ACTION_ACK = 0x0101
} ArvGvcpCommand;

#pragma pack(push,1)
Expand Down Expand Up @@ -359,6 +361,10 @@ ArvGvcpPacket * arv_gvcp_packet_new_packet_resend_cmd (guint64 frame_id,
guint32 first_block, guint32 last_block,
gboolean extended_ids,
guint16 packet_id, size_t *packet_size);
ArvGvcpPacket * arv_gvcp_packet_new_action_cmd (guint16 packet_id,
guint32 device_key, guint32 group_key,
guint32 group_mask, gint64 timestamp,
size_t *packet_size);

const char * arv_gvcp_packet_type_to_string (ArvGvcpPacketType value);
const char * arv_gvcp_command_to_string (ArvGvcpCommand value);
Expand Down
9 changes: 9 additions & 0 deletions src/arvgvdevice.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,15 @@ arv_gv_device_heartbeat_thread (void *data)

/* ArvGvDevice implemenation */

gboolean
arv_gv_device_issue_scheduled_action_command (guint32 device_key, guint32 group_key, guint32 group_mask,
guint64 timestamp_ns, GInetAddress *broadcast_address,
GInetAddress **inet_addresses, guint *n_acknowledges,
GError **error)
{
return FALSE;
}

Comment on lines +431 to +438
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO: actual implementation

/**
* arv_gv_device_take_control:
* @gv_device: a #ArvGvDevice
Expand Down
5 changes: 5 additions & 0 deletions src/arvgvdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ void arv_gv_device_set_stream_options (ArvGvDevice *gv_device, ArvGvStreamO

gboolean arv_gv_device_is_controller (ArvGvDevice *gv_device);

gboolean arv_gv_device_issue_scheduled_action_command (guint32 device_key, guint32 group_key, guint32 group_mask,
guint64 timestamp_ns, GInetAddress *broadcast_address,
GInetAddress **inet_addresses, guint *n_acknowledges,
GError **error);

Comment on lines +83 to +87
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO: actual implementation

G_END_DECLS

#endif