[dvblast-devel] [PATCH 1/6] comm: Allow command answer to be split in multiple packets

Georgi Chorbadzhiyski gf at unixsol.org
Mon Aug 29 10:36:44 CEST 2011


---
 comm.c       |   25 +++++++++++++++++++++----
 comm.h       |    4 +++-
 dvblastctl.c |   18 ++++++++++++++++--
 3 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/comm.c b/comm.c
index 171aead..a0f1a2c 100644
--- a/comm.c
+++ b/comm.c
@@ -41,7 +41,7 @@ int i_comm_fd = -1;
  *****************************************************************************/
 void comm_Open( void )
 {
-    int i_size = 65535;
+    int i_size = COMM_MAX_MSG_CHUNK;
     struct sockaddr_un sun_server;
 
     if ( (i_comm_fd = socket( AF_UNIX, SOCK_DGRAM, 0 )) == -1 )
@@ -164,10 +164,27 @@ void comm_Read( void )
     p_answer[1] = i_answer;
     p_answer[2] = 0;
     p_answer[3] = 0;
+    uint32_t *p_size = (uint32_t *)&p_answer[4];
+    *p_size = i_answer_size + COMM_HEADER_SIZE;
+
     msg_Dbg( NULL, "answering %d to %d with size %zd", i_answer, i_command,
              i_answer_size );
 
-    if ( sendto( i_comm_fd, p_answer, i_answer_size + COMM_HEADER_SIZE, 0,
-                 (struct sockaddr *)&sun_client, sun_length ) < 0 )
-        msg_Err( NULL, "cannot send comm socket (%s)", strerror(errno) );
+#define min(a, b) (a < b ? a : b)
+    ssize_t i_sended = 0;
+    ssize_t i_to_send = i_answer_size + COMM_HEADER_SIZE;
+    do {
+        ssize_t i_sent = sendto( i_comm_fd, p_answer + i_sended,
+                     min(i_to_send, COMM_MAX_MSG_CHUNK), 0,
+                     (struct sockaddr *)&sun_client, sun_length );
+
+        if ( i_sent < 0 ) {
+            msg_Err( NULL, "cannot send comm socket (%s)", strerror(errno) );
+            break;
+        }
+
+        i_sended += i_sent;
+        i_to_send -= i_sent;
+    } while ( i_to_send > 0 );
+#undef min
 }
diff --git a/comm.h b/comm.h
index 017a96d..67ba003 100644
--- a/comm.h
+++ b/comm.h
@@ -19,10 +19,12 @@
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/ca.h>
 
-#define COMM_BUFFER_SIZE 4096
 #define COMM_HEADER_SIZE 4
+#define COMM_BUFFER_SIZE (COMM_HEADER_SIZE + ((PSI_PRIVATE_MAX_SIZE + PSI_HEADER_SIZE) * (PSI_TABLE_MAX_SECTIONS / 2)))
 #define COMM_HEADER_MAGIC 0x48
 
+#define COMM_MAX_MSG_CHUNK 65535
+
 #define CMD_RELOAD 1
 #define CMD_SHUTDOWN 2
 #define CMD_FRONTEND_STATUS 3
diff --git a/dvblastctl.c b/dvblastctl.c
index 2d5099e..1ecef0b 100644
--- a/dvblastctl.c
+++ b/dvblastctl.c
@@ -59,7 +59,7 @@ int main( int i_argc, char **ppsz_argv )
     char *client_socket_tmpl = "dvblastctl.clientsock.XXXXXX";
     char *psz_srv_socket = NULL;
     int i_fd;
-    int i = 65535;
+    int i = COMM_MAX_MSG_CHUNK;
     ssize_t i_size;
     struct sockaddr_un sun_client, sun_server;
     uint8_t p_buffer[COMM_BUFFER_SIZE];
@@ -239,7 +239,21 @@ int main( int i_argc, char **ppsz_argv )
         exit(255);
     }
 
-    i_size = recv( i_fd, p_buffer, COMM_BUFFER_SIZE, 0 );
+    uint32_t i_packet_size = 0, i_received = 0;
+    do {
+        i_size = recv( i_fd, p_buffer + i_received, COMM_MAX_MSG_CHUNK, 0 );
+        if ( i_size == -1 )
+            break;
+        if ( !i_packet_size ) {
+            i_packet_size = *((uint32_t *)&p_buffer[4]);
+            if ( i_packet_size > COMM_BUFFER_SIZE ) {
+                i_size = -1;
+                break;
+            }
+        }
+        i_received += i_size;
+    } while ( i_received < i_packet_size );
+
     close( i_fd );
     unlink( psz_client_socket );
     if ( i_size < COMM_HEADER_SIZE )
-- 
1.7.5.1



More information about the dvblast-devel mailing list