gmyth-stream/client/src/gmyth-stream-client.c
author melunko
Wed May 16 16:33:23 2007 +0100 (2007-05-16)
branchtrunk
changeset 669 fbda74f25b90
parent 534 cb1c3e2988b9
permissions -rw-r--r--
[svn r675] Some fixes to reopen file transfer
     1 #ifdef HAVE_CONFIG_H
     2 #include "config.h"
     3 #endif
     4 
     5 #include <sys/types.h>
     6 #include <sys/socket.h>
     7 #include <arpa/inet.h>
     8 #include <netdb.h>
     9 #include <netinet/in.h>
    10 #include <unistd.h>
    11 #include <glib.h>
    12 #include <glib/gprintf.h>
    13 #include <string.h>
    14 #include <stdlib.h>
    15 
    16 #include "gmyth-stream-client.h"
    17 
    18 #define BUFFER_SIZE 1024
    19 
    20 #define GMYTH_STREAM_CLIENT_GET_PRIVATE(obj) \
    21     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_TYPE_STREAM_CLIENT,\
    22  GMythStreamClientPrivate))
    23 
    24 
    25 typedef struct _sock _socket;
    26 struct _sock
    27 {
    28     gint fd;
    29     struct sockaddr_in addr;
    30 };
    31 
    32 
    33 typedef struct _GMythStreamClientPrivate GMythStreamClientPrivate;
    34 struct _GMythStreamClientPrivate
    35 {
    36     const gchar *host;
    37     _socket* sock;
    38     _socket* sock_stream;
    39     gboolean connected;
    40 };
    41 
    42 
    43 static void gmyth_stream_client_class_init (GMythStreamClientClass *klass);
    44 static void gmyth_stream_client_init	   (GMythStreamClient *object);
    45 static void gmyth_stream_client_dispose    (GObject *object);
    46 static void gmyth_stream_client_finalize   (GObject *object);
    47 
    48 
    49 G_DEFINE_TYPE(GMythStreamClient, gmyth_stream_client, G_TYPE_OBJECT)
    50 
    51 
    52 static _socket*
    53 create_socket (const gchar* hostname, gint port)
    54 {
    55     _socket* sock = (_socket*)g_malloc(sizeof(_socket));
    56 
    57     sock->fd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
    58     if (sock->fd == -1) {
    59         g_debug ("Fail to create sock");
    60         g_free(sock);
    61         return NULL;
    62     }
    63 
    64     sock->addr.sin_family = AF_INET;
    65     sock->addr.sin_addr.s_addr = inet_addr(hostname);
    66     sock->addr.sin_port = htons(port);
    67 
    68     if (connect (sock->fd, (struct sockaddr *) &(sock->addr), \
    69                  sizeof (sock->addr)) == -1) {
    70         g_debug ("Fail to connect with server");
    71         g_free(sock);
    72         return NULL;
    73     }
    74 
    75     return sock;
    76 }
    77 
    78 static gint
    79 read_message (int socket)
    80 {
    81     gint64 total_read = 0;
    82     gint result = -1;
    83     gchar buffer[BUFFER_SIZE];
    84     gchar** response;
    85 
    86     total_read = recv(socket, buffer, BUFFER_SIZE, 0);
    87 
    88     if (total_read > 0) {
    89         response = g_strsplit_set(buffer, " +\n", 8);
    90 
    91         if ( g_ascii_strcasecmp(response[0], "OK") == 0 ) {
    92 
    93             int payload = atoi(response[1]);
    94 
    95             if (payload == 0)
    96                 result = 0;
    97 
    98             else if (payload == 1) {
    99                 total_read = recv(socket, buffer, BUFFER_SIZE, 0);
   100 
   101                 response = g_strsplit_set(buffer, "+\n", 8);
   102                 result = atoi(response[1]);
   103             }
   104 
   105         }
   106 
   107         g_strfreev(response);
   108     }
   109 
   110     return result;
   111 }
   112 
   113 
   114 static void
   115 gmyth_stream_client_class_init (GMythStreamClientClass *klass)
   116 {
   117     GObjectClass *gobject_class;
   118     gobject_class = (GObjectClass *) klass;
   119 
   120     g_type_class_add_private (klass, sizeof (GMythStreamClientPrivate));
   121     gobject_class->dispose  = gmyth_stream_client_dispose;
   122     gobject_class->finalize = gmyth_stream_client_finalize;
   123 }
   124 
   125 static void
   126 gmyth_stream_client_init (GMythStreamClient *self)
   127 {
   128     GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   129     priv->sock = NULL;
   130     priv->sock_stream = NULL;
   131 }
   132 
   133 static void
   134 gmyth_stream_client_dispose (GObject *object)
   135 {
   136     gmyth_stream_client_disconnect (GMYTH_STREAM_CLIENT (object));
   137 }
   138 
   139 
   140 static void
   141 gmyth_stream_client_finalize (GObject *object)
   142 {
   143 }
   144 
   145 GMythStreamClient*
   146 gmyth_stream_client_new ()
   147 {
   148     return GMYTH_STREAM_CLIENT (g_object_new (GMYTH_TYPE_STREAM_CLIENT, NULL));
   149 }
   150 
   151 gboolean
   152 gmyth_stream_client_connect (GMythStreamClient *self, const gchar *server, guint port)
   153 {
   154     GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   155     g_return_val_if_fail (priv->connected == FALSE, TRUE);
   156 
   157     priv->host = server;
   158     priv->sock = create_socket (server, port);
   159     if (priv->sock == NULL) return FALSE;
   160 
   161     priv->connected = TRUE;
   162     return TRUE;
   163 }
   164 
   165 void
   166 gmyth_stream_client_disconnect (GMythStreamClient *self)
   167 {
   168     GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   169 
   170     g_return_if_fail (priv->connected == TRUE);
   171 
   172     close (priv->sock->fd);
   173     //shutdown (priv->sock->fd, SHUT_RDWR);
   174     g_free(priv->sock);
   175     priv->sock = NULL;
   176     priv->connected = FALSE;
   177 }
   178 
   179 gint
   180 gmyth_stream_client_open_stream (GMythStreamClient *self,
   181                                  const gchar* file_name,
   182                                  const gchar* mux,
   183                                  const gchar* vcodec,
   184                                  guint vbitrate,
   185                                  gdouble fps,
   186                                  const gchar* acodec,
   187                                  guint abitrate,
   188                                  guint width, guint height,
   189                                  const gchar* opt)
   190 {
   191     gchar *cmd;
   192     GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   193 
   194     g_return_val_if_fail (priv->connected == TRUE, FALSE);
   195     g_return_val_if_fail (file_name != NULL, FALSE);
   196 
   197     cmd = g_strdup_printf ("SETUP %s %s %s %d %f %s %d %d %d %s\n",
   198                            file_name,
   199                            (mux == NULL ? "X" : mux),
   200                            (vcodec == NULL ? "X" : vcodec),
   201                            vbitrate,
   202                            fps,
   203                            (acodec == NULL ? "X" : acodec),
   204                            abitrate,
   205                            width, height,
   206                            (opt == NULL ? "X" : opt) );
   207 
   208     if (send (priv->sock->fd, cmd, strlen (cmd), MSG_CONFIRM) == -1) {
   209         g_free (cmd);
   210         return -1;
   211     }
   212     g_free (cmd);
   213 
   214     read_message(priv->sock->fd);
   215 
   216     return 0;
   217 }
   218 
   219 
   220 gint
   221 gmyth_stream_client_play_stream (GMythStreamClient *self)
   222 {
   223     GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   224 
   225     g_return_val_if_fail (priv->connected == TRUE, FALSE);
   226 
   227     if (send (priv->sock->fd, "PLAY\n", 5, 0) == -1) {
   228         return -1;
   229     }
   230 
   231     gint port = read_message(priv->sock->fd);
   232     priv->sock_stream = create_socket(priv->host, port);
   233 
   234     return priv->sock_stream->fd;
   235 }
   236 
   237 void
   238 gmyth_stream_client_close_stream (GMythStreamClient *self)
   239 {
   240     GMythStreamClientPrivate *priv = GMYTH_STREAM_CLIENT_GET_PRIVATE (self);
   241     g_return_if_fail (priv->connected == TRUE);
   242 
   243     if (send (priv->sock->fd, "STOP\n", 5, 0) == -1) {
   244         return;
   245     }
   246 
   247     read_message(priv->sock->fd);
   248 
   249     close(priv->sock_stream->fd);
   250     g_free(priv->sock_stream);
   251     priv->sock_stream = NULL;
   252 }