diff --git a/src/arvcamera.c b/src/arvcamera.c index 463c8eaa9..cb2d815d4 100644 --- a/src/arvcamera.c +++ b/src/arvcamera.c @@ -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); + + 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 + * @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 diff --git a/src/arvcamera.h b/src/arvcamera.h index 05966d136..c2c77e398 100644 --- a/src/arvcamera.h +++ b/src/arvcamera.h @@ -31,6 +31,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -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); diff --git a/src/arvgvcp.c b/src/arvgvcp.c index be9e3a1d5..c63498242 100644 --- a/src/arvgvcp.c +++ b/src/arvgvcp.c @@ -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) diff --git a/src/arvgvcpprivate.h b/src/arvgvcpprivate.h index 075fd7e10..af05c44e9 100644 --- a/src/arvgvcpprivate.h +++ b/src/arvgvcpprivate.h @@ -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) @@ -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); diff --git a/src/arvgvdevice.c b/src/arvgvdevice.c index 782e8e95f..0898dc239 100644 --- a/src/arvgvdevice.c +++ b/src/arvgvdevice.c @@ -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; +} + /** * arv_gv_device_take_control: * @gv_device: a #ArvGvDevice diff --git a/src/arvgvdevice.h b/src/arvgvdevice.h index 5cc42ba25..d657b55a8 100644 --- a/src/arvgvdevice.h +++ b/src/arvgvdevice.h @@ -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); + G_END_DECLS #endif