[aravis/wip/emmanuel/pending_ack] gv_device: add support for PENDING_ACK packets.



commit c3c9c755f2c6fb59da7a5dec71b4bfb1992da7df
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Sat Mar 17 18:03:26 2012 +0100

    gv_device: add support for PENDING_ACK packets.

 docs/reference/aravis/aravis-sections.txt |    1 +
 src/arvgvdevice.c                         |  207 +++++++++++++++++-----------
 src/arvgvdevice.h                         |   11 +-
 3 files changed, 133 insertions(+), 86 deletions(-)
---
diff --git a/docs/reference/aravis/aravis-sections.txt b/docs/reference/aravis/aravis-sections.txt
index a7fdeff..4d21836 100644
--- a/docs/reference/aravis/aravis-sections.txt
+++ b/docs/reference/aravis/aravis-sections.txt
@@ -749,6 +749,7 @@ ARV_GV_DEVICE_GET_CLASS
 <SUBSECTION Private>
 ARV_GV_DEVICE_GVCP_N_RETRIES_DEFAULT
 ARV_GV_DEVICE_GVCP_TIMEOUT_MS_DEFAULT
+ARV_GV_DEVICE_GVCP_PENDING_TIMEOUT_MS_DEFAULT
 ARV_GV_DEVICE_GVSP_PACKET_SIZE_DEFAULT
 ARV_GV_DEVICE_HEARTBEAT_PERIOD_US
 ARV_GV_DEVICE_HEARTBEAT_RETRY_DELAY_US
diff --git a/src/arvgvdevice.c b/src/arvgvdevice.c
index 77c35e4..40240b9 100644
--- a/src/arvgvdevice.c
+++ b/src/arvgvdevice.c
@@ -62,6 +62,7 @@ typedef struct {
 
        unsigned int gvcp_n_retries;
        unsigned int gvcp_timeout_ms;
+       unsigned int gvcp_pending_timeout_ms;
 
        gboolean is_controller;
 } ArvGvDeviceIOData;
@@ -119,6 +120,9 @@ _read_memory (ArvGvDeviceIOData *io_data, guint32 address, guint32 size, void *b
                                                      0, &packet_size);
 
        do {
+               gboolean pending_ack;
+               unsigned int timeout_ms = io_data->gvcp_timeout_ms;
+
                io_data->packet_id = arv_gvcp_next_packet_id (io_data->packet_id);
                arv_gvcp_packet_set_packet_id (packet, io_data->packet_id);
 
@@ -128,30 +132,38 @@ _read_memory (ArvGvDeviceIOData *io_data, guint32 address, guint32 size, void *b
                                  (const char *) packet, packet_size,
                                  NULL, NULL);
 
-               if (g_poll (&io_data->poll_in_event, 1, io_data->gvcp_timeout_ms) > 0) {
-                       count = g_socket_receive (io_data->socket, io_data->buffer,
-                                                 ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL);
-                       if (count >= answer_size) {
-                               ArvGvcpPacket *ack_packet = io_data->buffer;
-                               ArvGvcpPacketType packet_type;
-                               ArvGvcpCommand command;
-                               guint16 packet_id;
-
-                               arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG);
-
-                               packet_type = arv_gvcp_packet_get_packet_type (ack_packet);
-                               command = arv_gvcp_packet_get_command (ack_packet);
-                               packet_id = arv_gvcp_packet_get_packet_id (ack_packet);
-
-                               if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
-                                   command == ARV_GVCP_COMMAND_READ_MEMORY_ACK &&
-                                   packet_id == io_data->packet_id) {
-                                       memcpy (buffer, arv_gvcp_packet_get_read_memory_ack_data 
(ack_packet), size);
-                                       success = TRUE;
-                               } else
-                                       arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING);
-                       }
-               }
+               do {
+                       pending_ack = FALSE;
+
+                       if (g_poll (&io_data->poll_in_event, 1, timeout_ms) > 0) {
+                               count = g_socket_receive (io_data->socket, io_data->buffer,
+                                                         ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL);
+                               if (count >= answer_size) {
+                                       ArvGvcpPacket *ack_packet = io_data->buffer;
+                                       ArvGvcpPacketType packet_type;
+                                       ArvGvcpCommand command;
+                                       guint16 packet_id;
+
+                                       arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG);
+
+                                       packet_type = arv_gvcp_packet_get_packet_type (ack_packet);
+                                       command = arv_gvcp_packet_get_command (ack_packet);
+                                       packet_id = arv_gvcp_packet_get_packet_id (ack_packet);
+
+                                       if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
+                                           command == ARV_GVCP_COMMAND_PENDING_ACK) {
+                                               pending_ack = TRUE;
+                                               timeout_ms = io_data->gvcp_pending_timeout_ms;
+                                       } else if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
+                                                  command == ARV_GVCP_COMMAND_READ_MEMORY_ACK &&
+                                                  packet_id == io_data->packet_id) {
+                                               memcpy (buffer, arv_gvcp_packet_get_read_memory_ack_data 
(ack_packet), size);
+                                               success = TRUE;
+                                       } else
+                                               arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING);
+                               }
+                       } 
+               } while (pending_ack);
 
                n_retries++;
 
@@ -197,6 +209,9 @@ _write_memory (ArvGvDeviceIOData *io_data, guint32 address, guint32 size, void *
        memcpy (arv_gvcp_packet_get_write_memory_cmd_data (packet), buffer, size);
 
        do {
+               gboolean pending_ack;
+               unsigned int timeout_ms = io_data->gvcp_timeout_ms;
+
                io_data->packet_id = arv_gvcp_next_packet_id (io_data->packet_id);
                arv_gvcp_packet_set_packet_id (packet, io_data->packet_id);
 
@@ -206,29 +221,37 @@ _write_memory (ArvGvDeviceIOData *io_data, guint32 address, guint32 size, void *
                                  (const char *) packet, packet_size,
                                  NULL, NULL);
 
-               if (g_poll (&io_data->poll_in_event, 1, io_data->gvcp_timeout_ms) > 0) {
-                       count = g_socket_receive (io_data->socket, io_data->buffer,
-                                                 ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL);
-                       if (count >= arv_gvcp_packet_get_write_memory_ack_size ()) {
-                               ArvGvcpPacket *ack_packet = io_data->buffer;
-                               ArvGvcpPacketType packet_type;
-                               ArvGvcpCommand command;
-                               guint16 packet_id;
-
-                               arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG);
-
-                               packet_type = arv_gvcp_packet_get_packet_type (ack_packet);
-                               command = arv_gvcp_packet_get_command (ack_packet);
-                               packet_id = arv_gvcp_packet_get_packet_id (ack_packet);
-
-                               if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
-                                   command == ARV_GVCP_COMMAND_WRITE_MEMORY_ACK &&
-                                   packet_id == io_data->packet_id)
-                                       success = TRUE;
-                               else
-                                       arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING);
+               do {
+                       pending_ack = FALSE;
+
+                       if (g_poll (&io_data->poll_in_event, 1, timeout_ms) > 0) {
+                               count = g_socket_receive (io_data->socket, io_data->buffer,
+                                                         ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL);
+                               if (count >= arv_gvcp_packet_get_write_memory_ack_size ()) {
+                                       ArvGvcpPacket *ack_packet = io_data->buffer;
+                                       ArvGvcpPacketType packet_type;
+                                       ArvGvcpCommand command;
+                                       guint16 packet_id;
+
+                                       arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG);
+
+                                       packet_type = arv_gvcp_packet_get_packet_type (ack_packet);
+                                       command = arv_gvcp_packet_get_command (ack_packet);
+                                       packet_id = arv_gvcp_packet_get_packet_id (ack_packet);
+
+                                       if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
+                                           command == ARV_GVCP_COMMAND_PENDING_ACK) {
+                                               pending_ack = TRUE;
+                                               timeout_ms = io_data->gvcp_pending_timeout_ms;
+                                       } else if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
+                                                  command == ARV_GVCP_COMMAND_WRITE_MEMORY_ACK &&
+                                                  packet_id == io_data->packet_id)
+                                               success = TRUE;
+                                       else
+                                               arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING);
+                               }
                        }
-               }
+               } while (pending_ack);
 
                n_retries++;
 
@@ -269,6 +292,9 @@ _read_register (ArvGvDeviceIOData *io_data, guint32 address, guint32 *value_plac
        packet = arv_gvcp_packet_new_read_register_cmd (address, 0, &packet_size);
 
        do {
+               gboolean pending_ack;
+               unsigned int timeout_ms = io_data->gvcp_timeout_ms;
+
                io_data->packet_id = arv_gvcp_next_packet_id (io_data->packet_id);
                arv_gvcp_packet_set_packet_id (packet, io_data->packet_id);
 
@@ -278,14 +304,16 @@ _read_register (ArvGvDeviceIOData *io_data, guint32 address, guint32 *value_plac
                                  (const char *) packet, packet_size,
                                  NULL, NULL);
 
-               if (g_poll (&io_data->poll_in_event, 1, io_data->gvcp_timeout_ms) > 0) {
-                       count = g_socket_receive (io_data->socket, io_data->buffer,
-                                                 ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL);
-                       if (count > 0) {
-                               ArvGvcpPacket *ack_packet = io_data->buffer;
-                               ArvGvcpPacketType packet_type;
-                               ArvGvcpCommand command;
-                               guint16 packet_id;
+               do {
+                       pending_ack = FALSE;
+                       if (g_poll (&io_data->poll_in_event, 1, timeout_ms) > 0) {
+                               count = g_socket_receive (io_data->socket, io_data->buffer,
+                                                         ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL);
+                               if (count > 0) {
+                                       ArvGvcpPacket *ack_packet = io_data->buffer;
+                                       ArvGvcpPacketType packet_type;
+                                       ArvGvcpCommand command;
+                                       guint16 packet_id;
 
                                arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG);
 
@@ -294,14 +322,19 @@ _read_register (ArvGvDeviceIOData *io_data, guint32 address, guint32 *value_plac
                                packet_id = arv_gvcp_packet_get_packet_id (ack_packet);
 
                                if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
-                                   command == ARV_GVCP_COMMAND_READ_REGISTER_ACK &&
-                                   packet_id == io_data->packet_id) {
+                                   command == ARV_GVCP_COMMAND_PENDING_ACK) {
+                                       pending_ack = TRUE;
+                                       timeout_ms = io_data->gvcp_pending_timeout_ms;
+                               } else if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
+                                          command == ARV_GVCP_COMMAND_READ_REGISTER_ACK &&
+                                          packet_id == io_data->packet_id) {
                                        *value_placeholder = arv_gvcp_packet_get_read_register_ack_value 
(ack_packet);
                                        success = TRUE;
                                } else
                                        arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING);
+                               }
                        }
-               }
+               } while (pending_ack);
 
                n_retries++;
 
@@ -344,6 +377,9 @@ _write_register (ArvGvDeviceIOData *io_data, guint32 address, guint32 value, GEr
        packet = arv_gvcp_packet_new_write_register_cmd (address, value, io_data->packet_id, &packet_size);
 
        do {
+               gboolean pending_ack;
+               unsigned int timeout_ms = io_data->gvcp_timeout_ms;
+
                io_data->packet_id = arv_gvcp_next_packet_id (io_data->packet_id);
                arv_gvcp_packet_set_packet_id (packet, io_data->packet_id);
 
@@ -352,31 +388,39 @@ _write_register (ArvGvDeviceIOData *io_data, guint32 address, guint32 value, GEr
                g_socket_send_to (io_data->socket, io_data->device_address, (const char *) packet, 
packet_size,
                                  NULL, NULL);
 
-               if (g_poll (&io_data->poll_in_event, 1, io_data->gvcp_timeout_ms) > 0) {
-                       count = g_socket_receive (io_data->socket, io_data->buffer,
-                                                 ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL);
-                       if (count > 0) {
-                               ArvGvcpPacket *ack_packet = io_data->buffer;
-                               ArvGvcpPacketType packet_type;
-                               ArvGvcpCommand command;
-                               guint16 packet_id;
-
-                               arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG);
-
-                               packet_type = arv_gvcp_packet_get_packet_type (ack_packet);
-                               command = arv_gvcp_packet_get_command (ack_packet);
-                               packet_id = arv_gvcp_packet_get_packet_id (ack_packet);
-
-                               arv_log_gvcp ("%d, %d, %d", packet_type, command, packet_id);
-
-                               if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
-                                   command == ARV_GVCP_COMMAND_WRITE_REGISTER_ACK &&
-                                   packet_id == io_data->packet_id)
-                                       success = TRUE;
-                               else
-                                       arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING);
+               do {
+                       pending_ack = FALSE;
+
+                       if (g_poll (&io_data->poll_in_event, 1, timeout_ms) > 0) {
+                               count = g_socket_receive (io_data->socket, io_data->buffer,
+                                                         ARV_GV_DEVICE_BUFFER_SIZE, NULL, NULL);
+                               if (count > 0) {
+                                       ArvGvcpPacket *ack_packet = io_data->buffer;
+                                       ArvGvcpPacketType packet_type;
+                                       ArvGvcpCommand command;
+                                       guint16 packet_id;
+
+                                       arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_LOG);
+
+                                       packet_type = arv_gvcp_packet_get_packet_type (ack_packet);
+                                       command = arv_gvcp_packet_get_command (ack_packet);
+                                       packet_id = arv_gvcp_packet_get_packet_id (ack_packet);
+
+                                       arv_log_gvcp ("%d, %d, %d", packet_type, command, packet_id);
+
+                                       if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
+                                           command == ARV_GVCP_COMMAND_PENDING_ACK) {
+                                               pending_ack = TRUE;
+                                               timeout_ms = io_data->gvcp_pending_timeout_ms;
+                                       } else if (packet_type == ARV_GVCP_PACKET_TYPE_ACK &&
+                                                  command == ARV_GVCP_COMMAND_WRITE_REGISTER_ACK &&
+                                                  packet_id == io_data->packet_id)
+                                               success = TRUE;
+                                       else
+                                               arv_gvcp_packet_debug (ack_packet, ARV_DEBUG_LEVEL_WARNING);
+                               }
                        }
-               }
+               } while (pending_ack);
 
                n_retries++;
 
@@ -914,6 +958,7 @@ arv_gv_device_new (GInetAddress *interface_address, GInetAddress *device_address
        io_data->buffer = g_malloc (ARV_GV_DEVICE_BUFFER_SIZE);
        io_data->gvcp_n_retries = ARV_GV_DEVICE_GVCP_N_RETRIES_DEFAULT;
        io_data->gvcp_timeout_ms = ARV_GV_DEVICE_GVCP_TIMEOUT_MS_DEFAULT;
+       io_data->gvcp_pending_timeout_ms = ARV_GV_DEVICE_GVCP_PENDING_TIMEOUT_MS_DEFAULT;
        io_data->poll_in_event.fd = g_socket_get_fd (io_data->socket);
        io_data->poll_in_event.events =  G_IO_IN;
        io_data->poll_in_event.revents = 0;
diff --git a/src/arvgvdevice.h b/src/arvgvdevice.h
index c04735a..2db93e6 100644
--- a/src/arvgvdevice.h
+++ b/src/arvgvdevice.h
@@ -29,11 +29,12 @@
 
 G_BEGIN_DECLS
 
-#define        ARV_GV_DEVICE_GVCP_N_RETRIES_DEFAULT    5
-#define        ARV_GV_DEVICE_GVCP_TIMEOUT_MS_DEFAULT   500
-#define        ARV_GV_DEVICE_HEARTBEAT_PERIOD_US       1000000
-#define        ARV_GV_DEVICE_HEARTBEAT_RETRY_DELAY_US  10000
-#define        ARV_GV_DEVICE_HEARTBEAT_RETRY_TIMEOUT_S 5.0             /* FIXME */
+#define        ARV_GV_DEVICE_GVCP_N_RETRIES_DEFAULT            5
+#define        ARV_GV_DEVICE_GVCP_TIMEOUT_MS_DEFAULT           500
+#define        ARV_GV_DEVICE_GVCP_PENDING_TIMEOUT_MS_DEFAULT   2000
+#define        ARV_GV_DEVICE_HEARTBEAT_PERIOD_US               1000000
+#define        ARV_GV_DEVICE_HEARTBEAT_RETRY_DELAY_US          10000
+#define        ARV_GV_DEVICE_HEARTBEAT_RETRY_TIMEOUT_S         5.0             /* FIXME */
 
 #define ARV_GV_DEVICE_GVSP_PACKET_SIZE_DEFAULT 1500
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]