# HG changeset patch # User melunko # Date 1164404584 0 # Node ID a99f881ed02fba42596d93d6e568845f5ddb0053 # Parent dfa72795bd32c7f8143ed80c80fefd18e43287a3 [svn r113] A lot of changes at gmyth_socket.c and gmyth_filetransfer. From now on, file transfer dont handle the monitor socket, and the QUERY_RECORDER messages - dont call spawn livetv, dont call get_file_position, is_recording, etc. These are gmyth_livetv responsibility. File transfer now has the _new, _open, _seek, and _close methods, just like gnomevfs does. diff -r dfa72795bd32 -r a99f881ed02f gmyth/src/gmyth_file_transfer.c --- a/gmyth/src/gmyth_file_transfer.c Fri Nov 24 21:19:49 2006 +0000 +++ b/gmyth/src/gmyth_file_transfer.c Fri Nov 24 21:43:04 2006 +0000 @@ -50,8 +50,7 @@ #include #include -#define GMYTHTV_QUERY_HEADER "QUERY_FILETRANSFER" -#define GMYTHTV_RECORDER_HEADER "QUERY_RECORDER" +#define GMYTHTV_QUERY_HEADER "QUERY_FILETRANSFER " /* default values to the file transfer parameters */ #define GMYTHTV_USER_READ_AHEAD TRUE @@ -75,8 +74,6 @@ #define GMYTHTV_ENABLE_DEBUG 1 #endif -static guint wait_to_transfer = 0; - static gboolean has_io_access = TRUE; enum myth_sock_types { @@ -100,7 +97,7 @@ static void gmyth_file_transfer_dispose (GObject *object); static void gmyth_file_transfer_finalize (GObject *object); -static GMythSocket *gmyth_connect_to_transfer_backend( GMythFileTransfer **transfer, guint sock_type ); +static gboolean gmyth_connect_to_backend (GMythFileTransfer *transfer); static gboolean myth_init_io_watchers( GMythFileTransfer *transfer ); void gmyth_file_transfer_close( GMythFileTransfer *transfer ); @@ -111,29 +108,6 @@ G_DEFINE_TYPE(GMythFileTransfer, gmyth_file_transfer, G_TYPE_OBJECT) -#if 0 -static guint64 -mmyth_util_decode_long_long( GMythStringList *strlist, guint offset ) -{ - - guint64 ret_value = 0LL; - - g_return_val_if_fail( strlist != NULL, ret_value ); - - if ( offset < gmyth_string_list_length( strlist )) - g_printerr( "[%s] Offset is lower than the GMythStringList (offset = %d)!\n", __FUNCTION__, offset ); - g_return_val_if_fail( offset < gmyth_string_list_length( strlist ), ret_value ); - - gint l1 = gmyth_string_list_get_int( strlist, offset ); - gint l2 = gmyth_string_list_get_int( strlist, offset + 1 ); - - ret_value = ((guint64)(l2) & 0xffffffffLL) | ((guint64)(l1) << 32); - - return ret_value; - -} -#endif - static void gmyth_file_transfer_class_init (GMythFileTransferClass *klass) { @@ -145,11 +119,24 @@ gobject_class->finalize = gmyth_file_transfer_finalize; } - static void -gmyth_file_transfer_init (GMythFileTransfer *gmyth_file_transfer) +static void +gmyth_file_transfer_init (GMythFileTransfer *transfer) { - g_return_if_fail( gmyth_file_transfer != NULL ); - gmyth_file_transfer->mythtv_version = GMYTHTV_VERSION; + g_return_if_fail( transfer != NULL ); + + //transfer->card_id = num; + //transfer->rec_id = -1; + //transfer->recordernum = num; + + transfer->readposition = 0; + transfer->filesize = GMYTHTV_FILE_SIZE; + //transfer->timeoutisfast = FALSE; + + //transfer->userreadahead = GMYTHTV_USER_READ_AHEAD; + //transfer->retries = GMYTHTV_RETRIES; + + transfer->control_sock = NULL; + transfer->sock = NULL; /* it is used for signalizing the event socket consumer thread */ io_watcher_cond = g_cond_new(); @@ -163,8 +150,6 @@ { GMythFileTransfer *gmyth_file_transfer = GMYTH_FILE_TRANSFER(object); - gmyth_file_transfer_close( gmyth_file_transfer ); - G_OBJECT_CLASS (gmyth_file_transfer_parent_class)->dispose (object); } @@ -176,80 +161,34 @@ G_OBJECT_CLASS (gmyth_file_transfer_parent_class)->finalize (object); } - GMythFileTransfer* -gmyth_file_transfer_new (gint num, GString *uri_str, gshort port, gint mythtv_version) +// fixme: do we need the card_id???? +GMythFileTransfer* +gmyth_file_transfer_new () { GMythFileTransfer *transfer = GMYTH_FILE_TRANSFER ( g_object_new ( GMYTH_FILE_TRANSFER_TYPE, FALSE )); - transfer->mythtv_version = MYTHTV_CANNOT_NEGOTIATE_VERSION; - - transfer->card_id = num; - - transfer->rec_id = -1; - - transfer->recordernum = num; - transfer->uri = gmyth_uri_new ( uri_str->str ); - - transfer->hostname = g_string_new( gmyth_uri_gethost(transfer->uri) ); - g_print( "\t--> transfer->hostname = %s\n", transfer->hostname->str ); - - if ( port >= 0 ) - transfer->port = port; - else - transfer->port = gmyth_uri_getport( transfer->uri ); - - g_print( "\t--> transfer->port = %d\n", transfer->port ); - - transfer->readposition = 0; - transfer->filesize = GMYTHTV_FILE_SIZE; - transfer->timeoutisfast = FALSE; - - transfer->userreadahead = GMYTHTV_USER_READ_AHEAD; - transfer->retries = GMYTHTV_RETRIES; - - transfer->live_tv = FALSE; - - transfer->backend_msgs = g_hash_table_new( g_int_hash, g_int_equal ); - - transfer->query = g_string_new( GMYTHTV_QUERY_HEADER ); - g_string_append_printf ( transfer->query, " %d", transfer->recordernum ); - g_print( "\t--> transfer->query = %s\n", transfer->query->str ); - - transfer->control_sock = NULL; - transfer->event_sock = NULL; - transfer->sock = NULL; - return transfer; } gboolean -gmyth_file_transfer_livetv_setup( GMythFileTransfer **transfer, GMythSocket *live_socket ) +gmyth_file_transfer_open (GMythFileTransfer *transfer, GString *uri_str) { - (*transfer)->sock = live_socket; - g_object_ref( live_socket ); - - return TRUE; -} - -gboolean -gmyth_file_transfer_playback_setup( GMythFileTransfer **transfer, gboolean live_tv ) -{ - gboolean ret = TRUE; - (*transfer)->live_tv = live_tv; + transfer->uri = gmyth_uri_new ( uri_str->str ); + transfer->hostname = g_string_new( gmyth_uri_gethost(transfer->uri) ); + transfer->port = gmyth_uri_getport( transfer->uri ); - printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" ); - + g_debug ("[%s] URI: %s\n", __FUNCTION__, uri_str->str); + g_debug ("hostname: %s, port %d\n", transfer->hostname->str, transfer->port); + /* configure the control socket */ - if ((*transfer)->control_sock == NULL) { - - if ( gmyth_connect_to_transfer_backend ( transfer, GMYTH_PLAYBACK_TYPE ) == NULL ) { + if (transfer->control_sock == NULL) { + if ( !gmyth_connect_to_backend (transfer)) { g_printerr( "Connection to backend failed (Control Socket).\n" ); ret = FALSE; } - } else { g_warning("Remote transfer control socket already created.\n"); } @@ -258,38 +197,45 @@ } -gboolean -gmyth_file_transfer_setup( GMythFileTransfer **transfer, gboolean live_tv ) +static gboolean +gmyth_connect_to_backend (GMythFileTransfer *transfer) { - GMythStringList *strlist = NULL; + GString *base_str = g_string_new( "" ); + GString *hostname = NULL; + GMythStringList *strlist; - gboolean ret = TRUE; + g_return_val_if_fail (transfer != NULL, FALSE ); + g_return_val_if_fail (transfer->uri != NULL, FALSE ); + g_return_val_if_fail (transfer->hostname != NULL, FALSE); + g_return_val_if_fail (transfer->port > 0, FALSE); - (*transfer)->live_tv = live_tv; + gchar *path_dir = gmyth_uri_getpath (transfer->uri); - printf("[%s] Running config to the %s...\n", __FUNCTION__, live_tv ? "LiveTV" : "FileTransfer" ); + /* Creates the control socket */ + transfer->control_sock = gmyth_socket_new(); - /* configure the control socket */ - if ((*transfer)->event_sock == NULL) { + // Connects the socket, send Mythtv ANN command and verify Mythtv protocol version + if (!gmyth_socket_connect_to_backend (transfer->control_sock, + transfer->hostname->str, transfer->port, TRUE)) { - if ( gmyth_connect_to_transfer_backend ( transfer, GMYTH_MONITOR_TYPE ) == NULL ) { - g_printerr( "Connection to backend failed (Event Socket).\n" ); - ret = FALSE; - } + g_object_unref (transfer->control_sock); + transfer->control_sock = NULL; + return FALSE; + } + + /* Creates the data socket */ + transfer->sock = gmyth_socket_new (); + gmyth_socket_connect (transfer->sock, transfer->hostname->str, transfer->port); - } else { - g_warning("Remote transfer control socket already created.\n"); - } + strlist = gmyth_string_list_new(); + hostname = gmyth_socket_get_local_hostname(); + g_string_printf( base_str, "ANN FileTransfer %s 1 -1", hostname->str); - /* configure the socket */ - if ( (*transfer)->sock == NULL ) { + gmyth_string_list_append_string (strlist, base_str ); + gmyth_string_list_append_char_array (strlist, path_dir ); - //if ( live_tv == FALSE ) { - - if ( gmyth_connect_to_transfer_backend ( transfer, GMYTH_FILETRANSFER_TYPE ) == NULL ) { - g_printerr ("Connection to backend failed (Raw Transfer Socket).\n"); - ret = FALSE; - } + gmyth_socket_write_stringlist (transfer->sock, strlist ); + gmyth_socket_read_stringlist (transfer->sock, strlist ); GIOChannel* io_channel = (*transfer)->sock->sd_io_ch, *io_channel_control = (*transfer)->control_sock->sd_io_ch; @@ -337,337 +283,108 @@ } } - if ( /*!(*transfer)->live_tv && */ (*transfer)->control_sock != NULL ) { - strlist = gmyth_string_list_new(); - g_string_printf ( (*transfer)->query, "%s %d", GMYTHTV_QUERY_HEADER, (*transfer)->recordernum ); + /* file identification used in future file transfer requests to backend */ + transfer->file_id = gmyth_string_list_get_int( strlist, 1 ); - gmyth_string_list_append_string( strlist, (*transfer)->query ); - gmyth_string_list_append_char_array( strlist, "IS_OPEN" ); + /* Myth URI stream file size - decoded using two 8-bytes sequences (64 bits/long long types) */ + transfer->filesize = gmyth_util_decode_long_long( strlist, 2 ); - gmyth_socket_write_stringlist( (*transfer)->control_sock, strlist ); - gmyth_socket_read_stringlist( (*transfer)->control_sock, strlist ); + g_debug ( "[%s] ***** Received: recordernum = %d, filesize = %" G_GUINT64_FORMAT "\n", __FUNCTION__, + transfer->file_id, transfer->filesize ); - if ( strlist!=NULL && gmyth_string_list_get_int( strlist, 0 ) == 1 ) { - g_print( "[%s] Remote Myth FileTransfer socket is open!\n", __FUNCTION__ ); - } else { - g_print( "[%s] Remote Myth FileTransfer socket is CLOSED! See the MythTV Server Backend for configuration details...\n", __FUNCTION__ ); - ret = FALSE; - } - } - - } else { - g_warning("Remote transfer (raw) socket already created.\n"); + if (transfer->filesize < 0 ) { + g_print( "[%s] Got filesize equals to %llu is lesser than 0 [invalid stream file]\n", __FUNCTION__, transfer->filesize ); + g_object_unref(transfer->sock); + transfer->sock = NULL; + return FALSE; } - - return ret; -} - -static GMythSocket * -gmyth_connect_to_transfer_backend( GMythFileTransfer **transfer, guint sock_type ) -{ - GMythSocket *sock = NULL; - - g_return_val_if_fail( transfer != NULL && *transfer != NULL, NULL ); - g_return_val_if_fail( (*transfer)->uri != NULL, NULL ); - - //myth_control_acquire_context (TRUE); - - gchar *path_dir = gmyth_uri_getpath( (*transfer)->uri ); - - gchar *stype = g_strdup( "" ); - - sock = gmyth_socket_new(); - - gmyth_socket_connect( &sock, (*transfer)->hostname->str, (*transfer)->port ); - -#ifdef GMYTHTV_ENABLE_DEBUG - - g_print( "[%s] --> Creating socket... (%s, %d)\n", __FUNCTION__, (*transfer)->hostname->str, (*transfer)->port ); -#endif - - GMythStringList *strlist = NULL; - - GString *hostname = g_string_new( gmyth_uri_gethost( (*transfer)->uri ) ); - GString *base_str = g_string_new( "" ); - - if ( (*transfer)->mythtv_version != MYTHTV_CANNOT_NEGOTIATE_VERSION || - ( (*transfer)->mythtv_version = gmyth_socket_check_protocol_version_number (sock, - MYTHTV_VERSION_DEFAULT ) ) != MYTHTV_CANNOT_NEGOTIATE_VERSION ) { - - if (sock == NULL) { - stype = (sock_type==GMYTH_PLAYBACK_TYPE) ? "control socket" : "file data socket"; - g_printerr( "FileTransfer, open_socket(%s): \n" - "\t\t\tCould not connect to server \"%s\" @ port %d\n", stype, - (*transfer)->hostname->str, (*transfer)->port ); - g_object_unref(sock); - //myth_control_release_context( ); - return NULL; - } - - hostname = gmyth_socket_get_local_hostname(); - - g_print( "[%s] local hostname = %s\n", __FUNCTION__, hostname->str ); - - if ( sock_type == GMYTH_PLAYBACK_TYPE ) - { - (*transfer)->control_sock = sock; - - g_string_printf( base_str, "ANN Playback %s %d", hostname->str, FALSE ); - - gmyth_socket_send_command( (*transfer)->control_sock, base_str ); - GString *resp = gmyth_socket_receive_response( (*transfer)->control_sock ); - g_print( "[%s] Got Playback response from %s: %s\n", __FUNCTION__, base_str->str, resp->str ); - //myth_init_io_watchers ( (*transfer) ); - } - else if ( sock_type == GMYTH_MONITOR_TYPE ) - { - (*transfer)->event_sock = sock; - g_string_printf( base_str, "ANN Monitor %s %d", hostname->str, TRUE ); - - gmyth_socket_send_command( (*transfer)->event_sock, base_str ); - GString *resp = gmyth_socket_receive_response( (*transfer)->event_sock ); - g_print( "[%s] Got Monitor response from %s: %s\n", __FUNCTION__, base_str->str, resp->str ); - //g_thread_create( myth_init_io_watchers, (void*)(*transfer), FALSE, NULL ); - //g_thread_create( myth_init_io_watchers, (*transfer), FALSE, NULL ); - - g_printerr( "[%s] Watch listener function to the IO control channel on thread %p.\n", - __FUNCTION__, g_thread_self() ); - - } - else if ( sock_type == GMYTH_FILETRANSFER_TYPE ) - { - (*transfer)->sock = sock; - strlist = gmyth_string_list_new(); - - if ( (*transfer)->mythtv_version > 26 ) - g_string_printf( base_str, "ANN FileTransfer %s %d %d", hostname->str, - (*transfer)->userreadahead, (*transfer)->retries ); - else - g_string_printf( base_str, "ANN FileTransfer %s", hostname->str ); - - gmyth_string_list_append_string( strlist, base_str ); - gmyth_string_list_append_char_array( strlist, path_dir ); - - gmyth_socket_write_stringlist( (*transfer)->sock, strlist ); - gmyth_socket_read_stringlist( (*transfer)->sock, strlist ); - - /* socket number, where all the stream data comes from - got from the MythTV remote backend */ - (*transfer)->recordernum = gmyth_string_list_get_int( strlist, 1 ); - - /* Myth URI stream file size - decoded using two 8-bytes sequences (64 bits/long long types) */ - (*transfer)->filesize = gmyth_util_decode_long_long( strlist, 2 ); - - printf( "[%s] ***** Received: recordernum = %d, filesize = %" G_GUINT64_FORMAT "\n", __FUNCTION__, - (*transfer)->recordernum, (*transfer)->filesize ); - - if ( (*transfer)->filesize <= 0 ) { - g_print( "[%s] Got filesize equals to %llu is lesser than 0 [invalid stream file]\n", __FUNCTION__, (*transfer)->filesize ); - g_object_unref(sock); - sock = NULL; - } - } - else if ( sock_type == GMYTH_RINGBUFFER_TYPE ) - { - (*transfer)->sock = sock; - //gmyth_file_transfer_spawntv( (*transfer), NULL ); - - strlist = gmyth_string_list_new(); - g_string_printf( base_str, "ANN RingBuffer %s %d", hostname->str, (*transfer)->card_id ); - - gmyth_socket_send_command( (*transfer)->sock, base_str ); - GString *resp = gmyth_socket_receive_response( (*transfer)->sock ); - g_print( "[%s] Got RingBuffer response from %s: %s\n", __FUNCTION__, base_str->str, resp->str ); - - } - - } - - printf("[%s] ANN %s sent: %s\n", (sock_type==GMYTH_PLAYBACK_TYPE) ? "Playback" : (sock_type==GMYTH_FILETRANSFER_TYPE) ? "FileTransfer" : "Monitor", __FUNCTION__, base_str->str); + if ( strlist != NULL ) g_object_unref( strlist ); - //myth_control_release_context( ); + g_string_free (base_str, TRUE); + g_string_free (hostname, TRUE); - return sock; + return TRUE; } -void -gmyth_file_transfer_spawntv ( GMythFileTransfer *file_transfer, - GString *tvchain_id ) +gboolean +gmyth_file_transfer_is_open (GMythFileTransfer *transfer) { - GMythStringList *str_list; + GMythStringList *strlist; + GString *query; - g_debug ("gmyth_file_transfer_spawntv.\n"); + g_return_val_if_fail (transfer->control_sock != NULL, FALSE); + g_return_val_if_fail (transfer->sock != NULL, FALSE); - str_list = gmyth_string_list_new (); + strlist = gmyth_string_list_new(); + query = g_string_new (GMYTHTV_QUERY_HEADER); + g_string_append_printf (query, "%d", transfer->file_id ); - g_string_printf( file_transfer->query, "%s %d", GMYTHTV_RECORDER_HEADER, - file_transfer->card_id ); - gmyth_string_list_append_string (str_list, file_transfer->query); - gmyth_string_list_append_string (str_list, g_string_new ("SPAWN_LIVETV")); - if (tvchain_id!=NULL) { - gmyth_string_list_append_string (str_list, tvchain_id); - gmyth_string_list_append_int (str_list, FALSE); // PIP = FALSE (0) - } + gmyth_string_list_append_string (strlist, query ); + gmyth_string_list_append_char_array( strlist, "IS_OPEN" ); - gmyth_socket_sendreceive_stringlist ( file_transfer->sock, str_list ); + gmyth_socket_write_stringlist( transfer->control_sock, strlist ); + gmyth_socket_read_stringlist( transfer->control_sock, strlist ); - //GString *str = NULL; + g_string_free (query, TRUE); + g_object_unref (strlist); - //if (str_list!=NULL && (str = gmyth_string_list_get_string( str_list, 0 )) != NULL && strcasecmp( str->str, "ok" ) != 0 ) { - // g_print( "[%s]\t\tSpawnLiveTV is OK!\n", __FUNCTION__ ); - //} - if (str_list!=NULL) - g_object_unref (str_list); - + return ( strlist != NULL && gmyth_string_list_get_int( strlist, 0 ) == 1 ); } -gint64 -gmyth_file_transfer_get_file_position ( GMythFileTransfer *file_transfer ) -{ - gint64 pos = 0; - - GMythStringList *str_list = gmyth_string_list_new (); - - g_debug ( "[%s]\n", __FUNCTION__ ); - myth_control_acquire_context (TRUE); - - g_string_printf( file_transfer->query, "%s %d", GMYTHTV_RECORDER_HEADER, - file_transfer->rec_id >= 0 ? file_transfer->rec_id : file_transfer->card_id ); - - gmyth_string_list_append_string (str_list, file_transfer->query); - gmyth_string_list_append_string (str_list, g_string_new ("GET_FILE_POSITION")); - - gmyth_socket_sendreceive_stringlist ( file_transfer->control_sock, str_list ); - - if ( str_list != NULL && gmyth_string_list_length(str_list) > 0 ) - { - GString *str = NULL; - if ( ( str = gmyth_string_list_get_string( str_list, 0 ) ) != NULL && strstr ( str->str, "bad" ) == NULL ) - pos = gmyth_util_decode_long_long( str_list, 0 ); - } - myth_control_release_context( ); - -#ifndef GMYTHTV_ENABLE_DEBUG - - g_print( "[%s] Got file position = %lld\n", __FUNCTION__, pos ); -#endif - if (str_list!=NULL) - g_object_unref (str_list); - - return pos; - -} - - glong -gmyth_file_transfer_get_recordernum( GMythFileTransfer *transfer ) -{ - return transfer->recordernum; -} - - glong -gmyth_file_transfer_get_filesize( GMythFileTransfer *transfer ) -{ - return transfer->filesize; -} - - gboolean -gmyth_file_transfer_isopen( GMythFileTransfer *transfer ) -{ - return (transfer->sock != NULL && transfer->control_sock != NULL); -} - - void +void gmyth_file_transfer_close( GMythFileTransfer *transfer ) { GMythStringList *strlist; + GString *query; - if (transfer->control_sock == NULL) - return; + g_return_if_fail (transfer->control_sock != NULL); strlist = gmyth_string_list_new( ); + query = g_string_new (GMYTHTV_QUERY_HEADER); + g_string_append_printf( query, "%d", transfer->file_id); - g_string_printf( transfer->query, "%s %d", GMYTHTV_QUERY_HEADER, - transfer->recordernum ); - gmyth_string_list_append_string( strlist, transfer->query ); + gmyth_string_list_append_string( strlist, query ); gmyth_string_list_append_char_array( strlist, "DONE" ); - - if ( gmyth_socket_sendreceive_stringlist(transfer->control_sock, strlist) <= 0 ) - { + if ( gmyth_socket_sendreceive_stringlist(transfer->control_sock, strlist) <= 0 ) { + // fixme: time out??? g_printerr( "Remote file timeout.\n" ); } - if (transfer->sock) - { + g_string_free (query, TRUE); + g_object_unref (strlist); + + if (transfer->sock) { g_object_unref( transfer->sock ); transfer->sock = NULL; } - if (transfer->control_sock) - { + if (transfer->control_sock) { g_object_unref( transfer->control_sock ); transfer->control_sock = NULL; } } - void -gmyth_file_transfer_reset_controlsock( GMythFileTransfer *transfer ) -{ - if (transfer->control_sock == NULL) - { - g_printerr( "gmyth_file_transfer_reset_controlsock(): Called with no control socket" ); - return; - } - - GString *str = gmyth_socket_receive_response( transfer->control_sock ); - - g_string_free( str, TRUE ); -} - -void -gmyth_file_transfer_reset_sock( GMythFileTransfer *transfer ) -{ - if ( transfer->sock == NULL ) - { - g_printerr( "gmyth_file_transfer_reset_sock(): Called with no raw socket" ); - return; - } - - GString *str = gmyth_socket_receive_response( transfer->sock ); - - g_string_free( str, TRUE ); -} - -void -gmyth_file_transfer_reset( GMythFileTransfer *transfer ) -{ - gmyth_file_transfer_reset_controlsock( transfer ); - gmyth_file_transfer_reset_sock( transfer ); -} - gint64 gmyth_file_transfer_seek(GMythFileTransfer *transfer, guint64 pos, gint whence) { - if (transfer->sock == NULL) - { - g_printerr( "[%s] gmyth_file_transfer_seek(): Called with no socket", __FUNCTION__ ); - return 0; - } + GMythStringList *strlist = gmyth_string_list_new(); + GString *query; - if (transfer->control_sock == NULL) - return 0; + g_return_val_if_fail (transfer->sock != NULL, -1); + g_return_val_if_fail (transfer->control_sock != NULL, -1); - // if (!controlSock->isOpen() || controlSock->error()) - // return 0; + strlist = gmyth_string_list_new(); + query = g_string_new (GMYTHTV_QUERY_HEADER); + g_string_append_printf (query, "%d", transfer->file_id); myth_control_acquire_context( TRUE ); - GMythStringList *strlist = gmyth_string_list_new(); - g_string_printf (transfer->query, "%s %d", GMYTHTV_QUERY_HEADER, transfer->recordernum); - gmyth_string_list_append_string( strlist, transfer->query ); + gmyth_string_list_append_string( strlist, query ); gmyth_string_list_append_char_array( strlist, "SEEK" ); gmyth_string_list_append_uint64( strlist, pos ); @@ -740,122 +457,15 @@ } -static gboolean -myth_control_sock_listener( GIOChannel *io_channel, GIOCondition condition, gpointer data ) -{ - - GIOStatus io_status; - GError *error = NULL; - GIOCondition io_cond; - gchar *trash = g_new0( gchar, GMYTHTV_BUFFER_SIZE*10 ); - guint recv = 0; - - myth_control_acquire_context (TRUE); - - gsize len = 0; - if (condition & G_IO_HUP) - g_print ("Read end of pipe died!\n"); - - if ( ( condition & G_IO_IN ) != 0 ) { - io_status = g_io_channel_set_encoding( io_channel, NULL, &error ); - do - { - //trash = g_new0( gchar, GMYTHTV_BUFFER_SIZE ); - - io_status = g_io_channel_read_chars( io_channel, trash + recv, - GMYTHTV_BUFFER_SIZE, &len, &error); - - g_print( "[%s] Received data buffer from IO binary channel... %d bytes gone!\n", - __FUNCTION__, len ); - - recv += len; - - //msg = g_strconcat( msg, g_strdup(trash), NULL ); - - //if ( trash != NULL ) - // g_free( trash ); - - io_cond = g_io_channel_get_buffer_condition( io_channel ); - - } while ( ( io_cond & G_IO_IN ) != 0 && ( io_status != G_IO_STATUS_ERROR ) ); - } - //ret = g_io_channel_read_chars ( source, &msg, &len, NULL, &err); - if ( io_status == G_IO_STATUS_ERROR ) - g_print ("[%s] Error reading: %s\n", __FUNCTION__, error != NULL ? error->message : "" ); - g_print ("\n[%s]\tEVENT: Read %d bytes: %s\n\n", __FUNCTION__, len, trash != NULL ? trash : "[no event data]" ); - - myth_control_release_context( ); - - return TRUE; - -} - -static gboolean -myth_init_io_watchers( GMythFileTransfer *transfer ) -{ - io_watcher_context = g_main_context_default(); - //GMainLoop *loop = g_main_loop_new( io_watcher_context, FALSE ); - - GSource *source; - - if ( transfer->event_sock->sd_io_ch != NULL ) - source = g_io_create_watch( transfer->event_sock->sd_io_ch, G_IO_IN | G_IO_HUP ); - else - goto cleanup; - - g_source_set_callback ( source, (GSourceFunc)myth_control_sock_listener, NULL, NULL ); - - g_source_attach( source, io_watcher_context ); - - if (source==NULL) { - g_printerr( "[%s] Error adding watch listener function to the IO control channel!\n", __FUNCTION__ ); - goto cleanup; - } - - g_print( "[%s]\tOK! Starting listener on the MONITOR event socket...\n", __FUNCTION__ ); - - //g_main_loop_run( loop ); - -cleanup: - if ( source != NULL ) - g_source_unref( source ); - - return TRUE; -} - -static gboolean -gmyth_file_transfer_is_backend_message( GMythFileTransfer *transfer, - GMythStringList* strlist ) -{ - gboolean found_backend_msg = FALSE; - GString *back_msg = NULL; - - back_msg = gmyth_string_list_get_string( strlist, 0 ); - if ( back_msg != NULL && back_msg->str != NULL && - strstr( back_msg->str, "BACKEND" ) != NULL ) - { - found_backend_msg = TRUE; - if ( transfer->backend_msgs != NULL ) { - - g_hash_table_insert ( transfer->backend_msgs, - &(transfer->readposition), back_msg ); - - } - } - - return found_backend_msg; - -} - gint gmyth_file_transfer_read(GMythFileTransfer *transfer, GByteArray *data, gint size, gboolean read_unlimited) { - gint recv = 0; + gsize bytes_sent = 0; gsize bytes_read = 0; - gint sent = 0; - guint remaining = 0; - gboolean response = FALSE; - + gsize total_read = 0; + + GError *error = NULL; + GIOChannel *io_channel; GIOChannel *io_channel_control; @@ -864,20 +474,10 @@ GIOStatus io_status = G_IO_STATUS_NORMAL, io_status_control = G_IO_STATUS_NORMAL; GMythStringList *strlist = NULL; - GError *error = NULL; - - gchar *data_buffer = NULL; - - gchar *trash = g_strdup(""); + GString *query; g_return_val_if_fail ( data != NULL, -2 ); - myth_control_acquire_context (FALSE); - - /* gets the size of the entire file, if the size requested is lesser than 0 */ - if ( size <= 0 ) - size = transfer->filesize; - io_channel = transfer->sock->sd_io_ch; io_channel_control = transfer->control_sock->sd_io_ch; @@ -888,201 +488,91 @@ io_cond = g_io_channel_get_buffer_condition( io_channel ); io_cond_control = g_io_channel_get_buffer_condition( io_channel ); - - if ( transfer->sock == NULL || ( io_status == G_IO_STATUS_ERROR ) ) - { + if ( transfer->sock == NULL || ( io_status == G_IO_STATUS_ERROR ) ) { g_printerr( "gmyth_file_transfer_read(): Called with no raw socket.\n" ); - recv = -1; - goto cleanup; + exit(0); // fixme remove this + return -1; } - if ( transfer->control_sock == NULL || ( io_status_control == G_IO_STATUS_ERROR ) ) - { + if ( transfer->control_sock == NULL || ( io_status_control == G_IO_STATUS_ERROR ) ) { g_printerr( "gmyth_file_transfer_read(): Called with no control socket.\n" ); - recv = -1; - goto cleanup; + exit(0); // fixme remove this + return -1; } - wait_to_transfer = 0; - - g_string_printf ( transfer->query, "%s %d", GMYTHTV_QUERY_HEADER, - transfer->recordernum ); // transfer->recordernum - g_print( "\t[%s] Transfer_query = %s\n", __FUNCTION__, transfer->query->str ); + query = g_string_new (GMYTHTV_QUERY_HEADER); + g_string_append_printf ( query, "%d", transfer->file_id ); + g_debug ("[%s] Transfer_query = %s\n", __FUNCTION__, query->str ); - sent = size; - remaining = size - recv; - - while ( recv < size && !response ) - { + while (total_read == 0) { strlist = gmyth_string_list_new(); - gmyth_string_list_append_char_array( strlist, transfer->query->str ); + + gmyth_string_list_append_char_array( strlist, query->str ); gmyth_string_list_append_char_array( strlist, "REQUEST_BLOCK" ); - gmyth_string_list_append_int( strlist, remaining ); - gmyth_socket_write_stringlist( transfer->control_sock, strlist ); - - /* see the number of bytes transferred by the MythTV backend */ + gmyth_string_list_append_int( strlist, size ); + + // Request the block to the backend + gmyth_socket_write_stringlist( transfer->control_sock, strlist ); + + // Receives the backand answer gmyth_socket_read_stringlist( transfer->control_sock, strlist ); - if ( strlist != NULL && gmyth_string_list_length( strlist ) > 0 ) - { - sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error - g_print( "[%s] got SENT buffer message = %d\n", __FUNCTION__, sent ); - if ( sent != 0 ) - { - g_print( "[%s]\t received = %d bytes, backend says %d bytes sent, "\ - "io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__, - recv, sent, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" ); - if ( sent == remaining ) - { - g_print( "[%s]\t\tsent %d, which is equals to requested size = %d\n\n", - __FUNCTION__, sent, remaining ); - } - else - { - g_print( "[%s]\t\tsent %d, which is NOT equals to requested size = %d\n\n", - __FUNCTION__, sent, remaining ); - size = remaining = sent; - if ( sent < 0 ) { - goto cleanup; - } - } - } else { - //continue; - goto cleanup; - } // if - } + if ( strlist != NULL && gmyth_string_list_length( strlist ) > 0 ) { + bytes_sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error - guint count_bytes = 0; - - bytes_read = 0; - - data_buffer = g_new0( gchar, remaining ); + g_print( "[%s] got SENT buffer message = %d\n", __FUNCTION__, bytes_sent ); + if ( bytes_sent != 0 ) { + while (total_read != bytes_sent) { - io_status = g_io_channel_read_chars( io_channel, data_buffer, - remaining, &bytes_read, &error ); + io_status = g_io_channel_read_chars( io_channel, data + total_read, + (gsize) bytes_sent, // buffer_len + &bytes_read, &error ); - if ( bytes_read > 0 ) - { - recv += bytes_read; - count_bytes += bytes_read; - remaining -= bytes_read; - - /* append new data to the increasing byte array */ - data = g_byte_array_append ( data, g_memdup( data_buffer, bytes_read ), bytes_read ); - - g_print( "[%s] Reading buffer (bytes read = %d, remaining = %d)\n", __FUNCTION__, bytes_read, remaining ); - if ( remaining == 0 ) { - response = TRUE; - break; - } + total_read += bytes_read; + printf ("Total file transfer data read: %d\n", total_read); + } + } + } + } - } else { - if ( io_status == G_IO_STATUS_EOF ) { - g_print( "[%s] got EOS!", __FUNCTION__ ); - } else if ( io_status == G_IO_STATUS_ERROR ) { - g_print( "[%s] gmyth_file_transfer_read(): socket error.\n", __FUNCTION__ ); - } - break; + g_object_unref( strlist ); + g_string_free (query, TRUE); + + + if ( error != NULL ) { + g_printerr( "Cleaning-up ERROR: %s [msg = %s, code = %d]\n", __FUNCTION__, error->message, + error->code ); + g_error_free( error ); } + + transfer->readposition += total_read; - g_print( "[%s]\t io_cond %s prepared for reading! (G_IO_IN) !!!\n\n", __FUNCTION__, - ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" ); - - if ( ( io_cond_control & G_IO_IN ) != 0 ) { - g_print( "[%s] Finishind reading function: cleaning all data on the I/O control socket...\n", __FUNCTION__ ); - while ( gmyth_socket_read_stringlist( transfer->control_sock, strlist ) > 0 ) - { - if ( strlist != NULL && gmyth_string_list_length(strlist) > 0 ) - { - gint backend_code = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error - g_print( "[%s]\t backend code = %d -\t"\ - "[%s prepared for reading]! (G_IO_IN) !!!\n\n", __FUNCTION__, - backend_code, ( ( io_cond & G_IO_IN ) != 0 ) ? "IS" : "IS NOT" ); - } - } - } - g_io_channel_flush( io_channel_control, NULL ); - - } // while - -cleanup: - myth_control_release_context (mutex); - - if ( data_buffer != NULL ) - g_free( data_buffer ); - - if ( trash != NULL ) - g_free( trash ); - - if ( strlist != NULL ) - g_object_unref( strlist ); - - g_print( "gmyth_file_transfer_read(): reqd=%d, rcvd=%d, rept=%d, "\ - "(rcvd and rept MUST be the same!)\n", size, - recv, sent ); - - if ( error != NULL ) { - g_printerr( "Cleaning-up ERROR: %s [msg = %s, code = %d]\n", __FUNCTION__, error->message, - error->code ); - g_error_free( error ); - } - - if ( !response ) { - recv = GMYTHTV_FILE_TRANSFER_READ_ERROR; - } else { - transfer->readposition += recv; - } - - return recv; + return total_read; } -void +gboolean gmyth_file_transfer_settimeout( GMythFileTransfer *transfer, gboolean fast ) { GMythStringList *strlist = NULL; - if ( transfer->timeoutisfast == fast ) - return; + g_return_val_if_fail (transfer->sock != NULL, FALSE); + g_return_val_if_fail (transfer->control_sock != NULL, FALSE); - if ( transfer->sock == NULL ) - { - g_printerr( "gmyth_file_transfer_settimeout(): Called with no socket" ); - return; - } - - if ( transfer->control_sock == NULL ) - return; +// if ( transfer->timeoutisfast == fast ) +// return; strlist = gmyth_string_list_new(); - gmyth_string_list_append_string( strlist, transfer->query ); + gmyth_string_list_append_char_array( strlist, GMYTHTV_QUERY_HEADER ); gmyth_string_list_append_char_array( strlist, "SET_TIMEOUT" ); gmyth_string_list_append_int( strlist, fast ); gmyth_socket_write_stringlist( transfer->control_sock, strlist ); gmyth_socket_read_stringlist( transfer->control_sock, strlist ); - transfer->timeoutisfast = fast; +// transfer->timeoutisfast = fast; + return TRUE; } -#ifdef DO_TESTING - - int -main( int argc, char *argv[] ) -{ - g_type_init(); - - GMythFileTransfer *file_transfer = gmyth_file_transfer_new( 1, - g_string_new("myth://192.168.1.109:6543/jshks.nuv"), -1, GMYTHTV_VERSION ); - gmyth_file_transfer_setup( &file_transfer ); - gchar *data = g_strdup(""); - - gint num = gmyth_file_transfer_read( file_transfer, data, -1 ); - - return 0; - -} - -#endif diff -r dfa72795bd32 -r a99f881ed02f gmyth/src/gmyth_file_transfer.h --- a/gmyth/src/gmyth_file_transfer.h Fri Nov 24 21:19:49 2006 +0000 +++ b/gmyth/src/gmyth_file_transfer.h Fri Nov 24 21:43:04 2006 +0000 @@ -78,47 +78,45 @@ /* socket descriptors */ GMythSocket *control_sock; - GMythSocket *event_sock; GMythSocket *sock; gint64 readposition; guint64 filesize; - gboolean timeoutisfast; - gboolean userreadahead; - gboolean live_tv; - gint retries; + //gboolean timeoutisfast; + //gboolean userreadahead; + //gint retries; - GString *query; - - gint rec_id; - gint recordernum; - gint card_id; + gint file_id; + //gint rec_id; + //gint recordernum; + //gint card_id; GString *hostname; gint port; /* stores the messages coming from the backend */ - GHashTable *backend_msgs; + //GHashTable *backend_msgs; }; GType gmyth_file_transfer_get_type (void); -GMythFileTransfer* gmyth_file_transfer_new (gint num, GString *hostname, gshort port, gint mythtv_version ); +//GMythFileTransfer* gmyth_file_transfer_new (gint num, GString *hostname, gshort port, gint mythtv_version ); +GMythFileTransfer* gmyth_file_transfer_new ( ); -gint gmyth_file_transfer_read(GMythFileTransfer *transfer, GByteArray *data, gint size, gboolean read_unlimited); +gboolean gmyth_file_transfer_open (GMythFileTransfer *transfer, GString *uri_str); +void gmyth_file_transfer_close (GMythFileTransfer *transfer); +gboolean gmyth_file_transfer_is_open (GMythFileTransfer *transfer); +gint gmyth_file_transfer_read(GMythFileTransfer *transfer, void *data, gint size, gboolean read_unlimited); gint64 gmyth_file_transfer_seek(GMythFileTransfer *transfer, guint64 pos, gint whence); +gboolean gmyth_file_transfer_settimeout( GMythFileTransfer *transfer, gboolean fast); -gboolean gmyth_file_transfer_playback_setup( GMythFileTransfer **transfer, gboolean live_tv ); -gboolean gmyth_file_transfer_setup( GMythFileTransfer **transfer, gboolean live_tv ); - -gboolean gmyth_file_transfer_livetv_setup( GMythFileTransfer **transfer, GMythSocket *live_sock ); - -void gmyth_file_transfer_spawntv ( GMythFileTransfer *file_transfer, GString *tvchain_id ); - -gboolean gmyth_file_transfer_is_recording( GMythFileTransfer *file_transfer ); - -gint64 gmyth_file_transfer_get_file_position( GMythFileTransfer *file_transfer ); +//gboolean gmyth_file_transfer_playback_setup( GMythFileTransfer **transfer, gboolean live_tv ); +//gboolean gmyth_file_transfer_setup( GMythFileTransfer **transfer, gboolean live_tv ); +//gboolean gmyth_file_transfer_livetv_setup( GMythFileTransfer **transfer, GMythSocket *live_sock ); +//void gmyth_file_transfer_spawntv ( GMythFileTransfer *file_transfer, GString *tvchain_id ); +//gboolean gmyth_file_transfer_is_recording( GMythFileTransfer *file_transfer ); +//gint64 gmyth_file_transfer_get_file_position( GMythFileTransfer *file_transfer ); #define G_END_DECLS diff -r dfa72795bd32 -r a99f881ed02f gmyth/src/gmyth_socket.c --- a/gmyth/src/gmyth_socket.c Fri Nov 24 21:19:49 2006 +0000 +++ b/gmyth/src/gmyth_socket.c Fri Nov 24 21:43:04 2006 +0000 @@ -474,7 +474,7 @@ * @return TRUE if success, FALSE if error. */ gboolean -gmyth_socket_connect (GMythSocket **gmyth_socket, +gmyth_socket_connect (GMythSocket *gmyth_socket, gchar *hostname, gint port) { struct addrinfo *addr_info_data = NULL, *addr_info0 = NULL; @@ -490,22 +490,22 @@ g_return_val_if_fail( addr_info_data != NULL, FALSE ); /* store hostname and port number */ - (*gmyth_socket)->hostname = g_strdup( hostname ); - (*gmyth_socket)->port = port; + gmyth_socket->hostname = g_strdup( hostname ); + gmyth_socket->port = port; for ( addr_info0 = addr_info_data; addr_info0; addr_info0 = addr_info_data->ai_next ) { struct sockaddr_in *sa = (struct sockaddr_in*)addr_info0->ai_addr; /* init socket descriptor */ - (*gmyth_socket)->sd = socket( addr_info0->ai_family, addr_info0->ai_socktype, + gmyth_socket->sd = socket( addr_info0->ai_family, addr_info0->ai_socktype, addr_info0->ai_protocol ); - if ( (*gmyth_socket)->sd < 0 ) + if ( gmyth_socket->sd < 0 ) continue; g_debug( "[%s] hostname = %s, sock_fd = %d, addr = %s, addr_len = %d, \ ai_family = %d, ai_protocol = %d\n", - __FUNCTION__, hostname, (*gmyth_socket)->sd, inet_ntoa( sa->sin_addr ), + __FUNCTION__, hostname, gmyth_socket->sd, inet_ntoa( sa->sin_addr ), addr_info0->ai_addrlen, addr_info0->ai_family, addr_info0->ai_protocol ); struct timeval *timeout = g_new0( struct timeval, 1 ); @@ -514,7 +514,7 @@ timeout->tv_sec = 40; timeout->tv_usec = 0; - if ( gmyth_socket_try_connect( (*gmyth_socket)->sd, (struct sockaddr *)addr_info0->ai_addr, + if ( gmyth_socket_try_connect( gmyth_socket->sd, (struct sockaddr *)addr_info0->ai_addr, addr_info0->ai_addrlen, timeout, &ret_code ) < 0 ) { g_printerr( "[%s] Error connecting to backend!\n", __FUNCTION__ ); @@ -530,7 +530,7 @@ } - (*gmyth_socket)->sd_io_ch = g_io_channel_unix_new( (*gmyth_socket)->sd ); + gmyth_socket->sd_io_ch = g_io_channel_unix_new( gmyth_socket->sd ); ret = ( ret_code == 0 ) ? TRUE : FALSE ; @@ -687,7 +687,7 @@ gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket, gchar *hostname_backend, int port, gboolean blocking_client) { - if (!gmyth_socket_connect (&gmyth_socket, hostname_backend, port)) { + if (!gmyth_socket_connect (gmyth_socket, hostname_backend, port)) { g_warning ("[%s] Could not open socket to backend machine", __FUNCTION__); return FALSE; } @@ -719,10 +719,9 @@ return TRUE; } else { - g_warning ("[%s] GMythSocket could not connect to the backend", __FUNCTION__); - return FALSE; - } - + g_warning ("[%s] GMythSocket could not connect to the backend", __FUNCTION__); + return FALSE; + } } /** Closes the socket connection to the backend. @@ -780,7 +779,7 @@ g_print( "[%s] got MythTV version = %s.\n", __FUNCTION__, new_version ); mythtv_version = (gint)g_ascii_strtoull( g_strdup( new_version ), NULL, 10 ); /* do reconnection to the socket (socket is closed if the MythTV version was wrong) */ - gmyth_socket_connect( &gmyth_socket, gmyth_socket->hostname, gmyth_socket->port ); + gmyth_socket_connect( gmyth_socket, gmyth_socket->hostname, gmyth_socket->port ); /* g_free( new_version ); */ if ( --max_iterations > 0 ) goto try_new_version; diff -r dfa72795bd32 -r a99f881ed02f gmyth/src/gmyth_socket.h --- a/gmyth/src/gmyth_socket.h Fri Nov 24 21:19:49 2006 +0000 +++ b/gmyth/src/gmyth_socket.h Fri Nov 24 21:43:04 2006 +0000 @@ -92,10 +92,10 @@ gboolean gmyth_socket_send_command (GMythSocket *gmyth_socket, GString *command); GString * gmyth_socket_receive_response (GMythSocket *gmyth_socket); -int gmyth_socket_sendreceive_stringlist (GMythSocket * gmyth_socket, +int gmyth_socket_sendreceive_stringlist (GMythSocket *gmyth_socket, GMythStringList *str_list); -gboolean gmyth_socket_connect (GMythSocket **gmyth_socket, +gboolean gmyth_socket_connect (GMythSocket *gmyth_socket, gchar *hostname, gint port); gboolean gmyth_socket_connect_to_backend (GMythSocket *gmyth_socket, gchar *hostname_backend, int port,