# HG changeset patch # User rosfran # Date 1179261544 -3600 # Node ID ad1457d65f7400c52abe19859711d9f9a723eed9 # Parent 76b9c97faada8f47c7b02ac8ef8815d96fe57c93 [svn r661] Fixed starvation loop when reading an unlimited-size buffer (LiveTV) from the FileTransfer; MonitorHandler is a GThread now. diff -r 76b9c97faada -r ad1457d65f74 gmyth/src/gmyth_file_transfer.c --- a/gmyth/src/gmyth_file_transfer.c Tue May 15 20:16:26 2007 +0100 +++ b/gmyth/src/gmyth_file_transfer.c Tue May 15 21:39:04 2007 +0100 @@ -9,28 +9,28 @@ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia. * @author Rosfran Lins Borges * - *//* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * GStreamer MythTV plug-in properties: - * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv] - * - path (qurl - remote file to be opened) - * - port number * - */ - + *//* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * GStreamer MythTV plug-in properties: + * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv] + * - path (qurl - remote file to be opened) + * - port number * + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -61,44 +61,46 @@ #define GMYTH_FILE_TRANSFER_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferPrivate)) -enum myth_sock_types { - GMYTH_PLAYBACK_TYPE = 0, - GMYTH_MONITOR_TYPE, - GMYTH_FILETRANSFER_TYPE, - GMYTH_RINGBUFFER_TYPE -}; +enum myth_sock_types + { + GMYTH_PLAYBACK_TYPE = 0, + GMYTH_MONITOR_TYPE, + GMYTH_FILETRANSFER_TYPE, + GMYTH_RINGBUFFER_TYPE + }; -struct _GMythFileTransferPrivate { - GMythRecorder *recorder; - - gboolean do_next_program_chain; - gboolean disposed; - gboolean livetv_wait; +struct _GMythFileTransferPrivate + { + GMythRecorder *recorder; - /* MythTV version number */ - gint mythtv_version; + gboolean do_next_program_chain; + gboolean disposed; + gboolean livetv_wait; - /* socket descriptors */ - GMythSocket *control_sock; - GMythSocket *sock; - GMutex *mutex; - gint file_id; -}; + /* MythTV version number */ + gint mythtv_version; -static void gmyth_file_transfer_class_init (GMythFileTransferClass *klass); -static void gmyth_file_transfer_init (GMythFileTransfer *object); -static void gmyth_file_transfer_dispose (GObject *object); -static void gmyth_file_transfer_finalize (GObject *object); -static void _file_transfer_program_info_changed(GMythFileTransfer *transfer, - gint msg_code, gpointer livetv_recorder); -static gboolean _connect_to_backend (GMythFileTransfer *transfer); -static gboolean _control_acquire_context (GMythFileTransfer *transfer, gboolean do_wait); -static gboolean _control_release_context (GMythFileTransfer *transfer); + /* socket descriptors */ + GMythSocket *control_sock; + GMythSocket *sock; + GMutex *mutex; + gint file_id; + }; -G_DEFINE_TYPE(GMythFileTransfer, gmyth_file_transfer, GMYTH_FILE_TYPE) +static void gmyth_file_transfer_class_init (GMythFileTransferClass * klass); +static void gmyth_file_transfer_init (GMythFileTransfer * object); +static void gmyth_file_transfer_dispose (GObject * object); +static void gmyth_file_transfer_finalize (GObject * object); +static void _file_transfer_program_info_changed (GMythFileTransfer * transfer, + gint msg_code, + gpointer livetv_recorder); +static gboolean _connect_to_backend (GMythFileTransfer * transfer); +static gboolean _control_acquire_context (GMythFileTransfer * transfer, + gboolean do_wait); +static gboolean _control_release_context (GMythFileTransfer * transfer); -static void -gmyth_file_transfer_class_init (GMythFileTransferClass *klass) +G_DEFINE_TYPE (GMythFileTransfer, gmyth_file_transfer, GMYTH_FILE_TYPE) + static void gmyth_file_transfer_class_init (GMythFileTransferClass * klass) { GObjectClass *gobject_class; GMythFileTransferClass *gtransfer_class; @@ -106,88 +108,89 @@ gobject_class = (GObjectClass *) klass; gtransfer_class = (GMythFileTransferClass *) gobject_class; - gobject_class->dispose = gmyth_file_transfer_dispose; + gobject_class->dispose = gmyth_file_transfer_dispose; gobject_class->finalize = gmyth_file_transfer_finalize; - + g_type_class_add_private (gobject_class, sizeof (GMythFileTransferPrivate)); - - gtransfer_class->program_info_changed_handler = _file_transfer_program_info_changed; - - gtransfer_class->program_info_changed_handler_signal_id = - g_signal_new ("program-info-changed", - G_TYPE_FROM_CLASS (gtransfer_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, - NULL, - NULL, - gmyth_marshal_VOID__INT_POINTER, - G_TYPE_NONE, - 2, - G_TYPE_INT, - G_TYPE_POINTER ); + + gtransfer_class->program_info_changed_handler = + _file_transfer_program_info_changed; + + gtransfer_class->program_info_changed_handler_signal_id = + g_signal_new ("program-info-changed", + G_TYPE_FROM_CLASS (gtransfer_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | + G_SIGNAL_NO_HOOKS, 0, NULL, NULL, + gmyth_marshal_VOID__INT_POINTER, G_TYPE_NONE, 2, + G_TYPE_INT, G_TYPE_POINTER); } static void -gmyth_file_transfer_init (GMythFileTransfer *transfer) -{ - g_return_if_fail( transfer != NULL ); +gmyth_file_transfer_init (GMythFileTransfer * transfer) +{ + g_return_if_fail (transfer != NULL); - transfer->priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer); - transfer->priv->mutex = g_mutex_new(); - - g_signal_connect ( G_OBJECT (transfer), "program-info-changed", - (GCallback)(GMYTH_FILE_TRANSFER_GET_CLASS(transfer)->program_info_changed_handler), - NULL ); + transfer->priv = GMYTH_FILE_TRANSFER_GET_PRIVATE (transfer); + transfer->priv->mutex = g_mutex_new (); + + g_signal_connect (G_OBJECT (transfer), "program-info-changed", + (GCallback) (GMYTH_FILE_TRANSFER_GET_CLASS (transfer)-> + program_info_changed_handler), NULL); } static void -gmyth_file_transfer_dispose (GObject *object) -{ +gmyth_file_transfer_dispose (GObject * object) +{ GMythFileTransferPrivate *priv; - GMythFileTransfer *transfer = GMYTH_FILE_TRANSFER (object); + GMythFileTransfer *transfer = GMYTH_FILE_TRANSFER (object); - g_return_if_fail( transfer != NULL ); + g_return_if_fail (transfer != NULL); - priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer); + priv = GMYTH_FILE_TRANSFER_GET_PRIVATE (transfer); - if (priv->disposed) { + if (priv->disposed) + { /* If dispose did already run, return. */ return; } - + /* Make sure dispose does not run twice. */ priv->disposed = TRUE; - - if (priv->mutex != NULL ) { - g_mutex_free (priv->mutex ); + + if (priv->mutex != NULL) + { + g_mutex_free (priv->mutex); priv->mutex = NULL; } - if (priv->control_sock != NULL ) { - g_object_unref (priv->control_sock ); + if (priv->control_sock != NULL) + { + g_object_unref (priv->control_sock); priv->control_sock = NULL; - } + } - if (priv->sock != NULL ) { + if (priv->sock != NULL) + { g_object_unref (priv->sock); priv->sock = NULL; } - if (priv->recorder != NULL ) { - g_object_unref (priv->recorder ); + if (priv->recorder != NULL) + { + g_object_unref (priv->recorder); priv->recorder = NULL; } - + G_OBJECT_CLASS (gmyth_file_transfer_parent_class)->dispose (object); } static void -gmyth_file_transfer_finalize (GObject *object) +gmyth_file_transfer_finalize (GObject * object) { - g_signal_handlers_destroy (object); + g_signal_handlers_destroy (object); - G_OBJECT_CLASS (gmyth_file_transfer_parent_class)->finalize (object); + G_OBJECT_CLASS (gmyth_file_transfer_parent_class)->finalize (object); } /** @@ -198,28 +201,30 @@ * * @return a new instance of the File Transfer. */ -GMythFileTransfer* -gmyth_file_transfer_new (GMythBackendInfo *backend_info) +GMythFileTransfer * +gmyth_file_transfer_new (GMythBackendInfo * backend_info) { - GMythFileTransfer *transfer = g_object_new (GMYTH_FILE_TRANSFER_TYPE, - "backend-info", backend_info, NULL); + GMythFileTransfer *transfer = g_object_new (GMYTH_FILE_TRANSFER_TYPE, + "backend-info", backend_info, + NULL); //GValue val = {0,}; //backend_info = g_object_ref( backend_info ); - gmyth_debug( "Creating FileTransfer BackendInfo hostname = %s", gmyth_backend_info_get_hostname(backend_info) ); + gmyth_debug ("Creating FileTransfer BackendInfo hostname = %s", + gmyth_backend_info_get_hostname (backend_info)); //GMythBackendInfo *backend_info = gmyth_backend_info_new_with_uri (uri_str); //g_value_init (&val, G_TYPE_OBJECT); //g_value_set_object (&val, backend_info); //g_object_set (G_OBJECT (transfer), "backend-info", &val, NULL); - + return transfer; } -gchar* -gmyth_file_transfer_get_file_name (GMythFileTransfer *transfer) +gchar * +gmyth_file_transfer_get_file_name (GMythFileTransfer * transfer) { gchar *filename; - - g_object_get( G_OBJECT(transfer), "filename", &filename, NULL ); + + g_object_get (G_OBJECT (transfer), "filename", &filename, NULL); return filename; } @@ -231,16 +236,17 @@ * * @return a new instance of the File Transfer. */ -GMythFileTransfer* -gmyth_file_transfer_new_with_uri (const gchar* uri_str) +GMythFileTransfer * +gmyth_file_transfer_new_with_uri (const gchar * uri_str) { - GMythFileTransfer *transfer = GMYTH_FILE_TRANSFER (g_object_new (GMYTH_FILE_TRANSFER_TYPE, NULL)); - gmyth_debug( "URI str = %s", uri_str ); + GMythFileTransfer *transfer = + GMYTH_FILE_TRANSFER (g_object_new (GMYTH_FILE_TRANSFER_TYPE, NULL)); + gmyth_debug ("URI str = %s", uri_str); //GMythBackendInfo *backend_info = gmyth_backend_info_new_with_uri (uri_str); - GValue val = {0,}; + GValue val = { 0, }; g_value_init (&val, G_TYPE_OBJECT); g_value_set_object (&val, gmyth_backend_info_new_with_uri (uri_str)); - g_object_set(G_OBJECT (transfer), "backend-info", &val, NULL); + g_object_set (G_OBJECT (transfer), "backend-info", &val, NULL); return transfer; } @@ -254,32 +260,37 @@ * @return true, if the connection opening had been done successfully. */ gboolean -gmyth_file_transfer_open (GMythFileTransfer *transfer, const gchar* filename) +gmyth_file_transfer_open (GMythFileTransfer * transfer, const gchar * filename) { gboolean ret = TRUE; GMythFileTransferPrivate *priv; - + g_return_val_if_fail (transfer != NULL, FALSE); - g_return_val_if_fail (filename != NULL && strlen(filename) > 0, FALSE); + g_return_val_if_fail (filename != NULL && strlen (filename) > 0, FALSE); priv = GMYTH_FILE_TRANSFER_GET_PRIVATE (transfer); - + //if ( ) - gmyth_debug( "Opening the FileTransfer... (%s)", filename ); - - g_object_set( GMYTH_FILE(transfer), "filename", filename, NULL ); + gmyth_debug ("Opening the FileTransfer... (%s)", filename); + + g_object_set (GMYTH_FILE (transfer), "filename", filename, NULL); /* configure the control socket */ - if (priv->control_sock == NULL) { - if (!_connect_to_backend (transfer)) { + if (priv->control_sock == NULL) + { + if (!_connect_to_backend (transfer)) + { gmyth_debug ("Connection to backend failed (Control Socket)."); ret = FALSE; } - } else { - gmyth_debug("Remote transfer control socket already created."); } - - gmyth_debug ("Got file with size = %lld.\n", gmyth_file_get_filesize(GMYTH_FILE(transfer))); + else + { + gmyth_debug ("Remote transfer control socket already created."); + } + + gmyth_debug ("Got file with size = %lld.\n", + gmyth_file_get_filesize (GMYTH_FILE (transfer))); return ret; } @@ -292,95 +303,108 @@ * @return true, if the connection had been configured successfully. */ static gboolean -_connect_to_backend (GMythFileTransfer *transfer) +_connect_to_backend (GMythFileTransfer * transfer) { GString *base_str = NULL; GString *hostname = NULL; - GMythStringList *strlist = NULL; + GMythStringList *strlist = NULL; gboolean ret = TRUE; GMythFileTransferPrivate *priv; GMythBackendInfo *backend_info; - g_return_val_if_fail (transfer != NULL, FALSE ); - - g_object_get( GMYTH_FILE(transfer), "backend-info", &backend_info, NULL ); + g_return_val_if_fail (transfer != NULL, FALSE); + + g_object_get (GMYTH_FILE (transfer), "backend-info", &backend_info, NULL); priv = GMYTH_FILE_TRANSFER_GET_PRIVATE (transfer); _control_acquire_context (transfer, TRUE); /* Creates the control socket */ - if (priv->control_sock != NULL) { + if (priv->control_sock != NULL) + { g_object_unref (priv->control_sock); priv->control_sock = NULL; } base_str = g_string_new (""); - - priv->control_sock = gmyth_socket_new(); + + priv->control_sock = gmyth_socket_new (); // Connects the socket, send Mythtv ANN command and verify Mythtv protocol version - if (!gmyth_socket_connect_to_backend (priv->control_sock, - backend_info->hostname, backend_info->port, TRUE)) { - - g_object_unref (priv->control_sock); - priv->control_sock = NULL; - return FALSE; + if (!gmyth_socket_connect_to_backend (priv->control_sock, + backend_info->hostname, + backend_info->port, TRUE)) + { + + g_object_unref (priv->control_sock); + priv->control_sock = NULL; + return FALSE; } - + /* Creates the data socket */ - if (priv->sock != NULL) { + if (priv->sock != NULL) + { g_object_unref (priv->sock); priv->sock = NULL; - } + } priv->sock = gmyth_socket_new (); - gmyth_socket_connect (priv->sock, backend_info->hostname, backend_info->port); - gmyth_debug ("Connecting file transfer... (%s, %d)", backend_info->hostname, backend_info->port); - - strlist = gmyth_string_list_new(); - hostname = gmyth_socket_get_local_hostname(); - gmyth_debug( "[%s] MythTV version (from backend) = %d.\n", __FUNCTION__, priv->control_sock->mythtv_version ); - if (priv->control_sock->mythtv_version > 26 ) - g_string_printf (base_str, "ANN FileTransfer %s 1 -1", hostname->str); - 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, gmyth_file_get_file_name(GMYTH_FILE(transfer))); - - gmyth_socket_write_stringlist (priv->sock, strlist ); - gmyth_socket_read_stringlist (priv->sock, strlist ); - - /* file identification used in future file transfer requests to backend */ - priv->file_id = gmyth_string_list_get_int (strlist, 1); - - /* Myth URI stream file size - decoded using two 8-bytes sequences (64 bits/long long types) */ - gmyth_file_set_filesize( GMYTH_FILE(transfer), gmyth_util_decode_long_long (strlist, 2) ); - - gmyth_debug ( "***** Received: recordernum = %d, filesize = %" G_GUINT64_FORMAT "\n", - priv->file_id, gmyth_file_get_filesize(GMYTH_FILE(transfer)) ); - - if ( gmyth_file_get_filesize(GMYTH_FILE(transfer)) < 0 ) { - gmyth_debug ( "Got filesize equals to %llu is lesser than 0 [invalid stream file]\n", - gmyth_file_get_filesize(GMYTH_FILE(transfer)) ); - g_object_unref (priv->sock); - priv->sock = NULL; - ret = FALSE; + gmyth_socket_connect (priv->sock, backend_info->hostname, + backend_info->port); + gmyth_debug ("Connecting file transfer... (%s, %d)", backend_info->hostname, + backend_info->port); + + strlist = gmyth_string_list_new (); + hostname = gmyth_socket_get_local_hostname (); + gmyth_debug ("[%s] MythTV version (from backend) = %d.\n", __FUNCTION__, + priv->control_sock->mythtv_version); + if (priv->control_sock->mythtv_version > 26) + g_string_printf (base_str, "ANN FileTransfer %s 1 -1", hostname->str); + 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, + gmyth_file_get_file_name (GMYTH_FILE + (transfer))); + + gmyth_socket_write_stringlist (priv->sock, strlist); + gmyth_socket_read_stringlist (priv->sock, strlist); + + /* file identification used in future file transfer requests to backend */ + priv->file_id = gmyth_string_list_get_int (strlist, 1); + + /* Myth URI stream file size - decoded using two 8-bytes sequences (64 bits/long long types) */ + gmyth_file_set_filesize (GMYTH_FILE (transfer), + gmyth_util_decode_long_long (strlist, 2)); + + gmyth_debug ("***** Received: recordernum = %d, filesize = %" + G_GUINT64_FORMAT "\n", priv->file_id, + gmyth_file_get_filesize (GMYTH_FILE (transfer))); + + if (gmyth_file_get_filesize (GMYTH_FILE (transfer)) < 0) + { + gmyth_debug + ("Got filesize equals to %llu is lesser than 0 [invalid stream file]\n", + gmyth_file_get_filesize (GMYTH_FILE (transfer))); + g_object_unref (priv->sock); + priv->sock = NULL; + ret = FALSE; } - - _control_release_context( transfer ); + + _control_release_context (transfer); if (strlist != NULL) g_object_unref (strlist); - + if (base_str != NULL) - g_string_free (base_str, TRUE); - - if (hostname != NULL ) - g_string_free (hostname, TRUE); + g_string_free (base_str, TRUE); + + if (hostname != NULL) + g_string_free (hostname, TRUE); return ret; -} +} /** * Receives a GObject signal coming from a LiveTV instance, all the time a @@ -391,15 +415,14 @@ * @param live_tv A pointer to the LiveTV instance. * */ void -gmyth_file_transfer_emit_program_info_changed_signal ( GMythFileTransfer *transfer, gint msg_code, - gpointer live_tv_recorder ) +gmyth_file_transfer_emit_program_info_changed_signal (GMythFileTransfer * + transfer, gint msg_code, + gpointer live_tv_recorder) { - gmyth_debug( "Calling signal handler... [FILE_TRANSFER]" ); + gmyth_debug ("Calling signal handler... [FILE_TRANSFER]"); - g_signal_emit ( transfer, - GMYTH_FILE_TRANSFER_GET_CLASS (transfer)->program_info_changed_handler_signal_id, - 0, /* details */ - msg_code, live_tv_recorder); + g_signal_emit (transfer, GMYTH_FILE_TRANSFER_GET_CLASS (transfer)->program_info_changed_handler_signal_id, 0, /* details */ + msg_code, live_tv_recorder); } @@ -411,7 +434,7 @@ * @return true, if the File Transfer connection is opened. */ gboolean -gmyth_file_transfer_is_open (GMythFileTransfer *transfer) +gmyth_file_transfer_is_open (GMythFileTransfer * transfer) { GMythStringList *strlist; GMythFileTransferPrivate *priv; @@ -425,16 +448,16 @@ _control_acquire_context (transfer, TRUE); - strlist = gmyth_string_list_new(); + strlist = gmyth_string_list_new (); query = g_string_new (GMYTHTV_QUERY_HEADER); - g_string_append_printf (query, "%d", priv->file_id ); + g_string_append_printf (query, "%d", priv->file_id); - gmyth_string_list_append_string (strlist, query ); + gmyth_string_list_append_string (strlist, query); gmyth_string_list_append_char_array (strlist, "IS_OPEN"); - gmyth_socket_write_stringlist (priv->control_sock, strlist ); - gmyth_socket_read_stringlist (priv->control_sock, strlist ); - + gmyth_socket_write_stringlist (priv->control_sock, strlist); + gmyth_socket_read_stringlist (priv->control_sock, strlist); + _control_release_context (transfer); g_string_free (query, TRUE); @@ -449,7 +472,7 @@ * @param transfer The actual File Transfer instance. */ void -gmyth_file_transfer_close (GMythFileTransfer *transfer ) +gmyth_file_transfer_close (GMythFileTransfer * transfer) { GMythStringList *strlist; GMythFileTransferPrivate *priv; @@ -471,23 +494,26 @@ gmyth_string_list_append_string (strlist, query); gmyth_string_list_append_char_array (strlist, "DONE"); - if (gmyth_socket_sendreceive_stringlist (priv->control_sock, strlist) <= 0 ) { + if (gmyth_socket_sendreceive_stringlist (priv->control_sock, strlist) <= 0) + { // fixme: time out??? - gmyth_debug ( "Remote file timeout.\n" ); + gmyth_debug ("Remote file timeout.\n"); } g_string_free (query, TRUE); g_object_unref (strlist); - if (priv->sock) { - g_object_unref (priv->sock ); + if (priv->sock) + { + g_object_unref (priv->sock); priv->sock = NULL; } - if (priv->control_sock) { - g_object_unref (priv->control_sock ); + if (priv->control_sock) + { + g_object_unref (priv->control_sock); priv->control_sock = NULL; - } + } _control_release_context (transfer); } @@ -502,9 +528,10 @@ * @return The actual position on the remote file (after seek has been done). */ gint64 -gmyth_file_transfer_seek (GMythFileTransfer *transfer, guint64 pos, gint whence) +gmyth_file_transfer_seek (GMythFileTransfer * transfer, guint64 pos, + gint whence) { - GMythStringList *strlist = gmyth_string_list_new(); + GMythStringList *strlist = gmyth_string_list_new (); GMythFileTransferPrivate *priv; GString *query; @@ -514,7 +541,7 @@ g_return_val_if_fail (priv->sock != NULL, -1); g_return_val_if_fail (priv->control_sock != NULL, -1); - strlist = gmyth_string_list_new(); + strlist = gmyth_string_list_new (); query = g_string_new (GMYTHTV_QUERY_HEADER); g_string_append_printf (query, "%d", priv->file_id); @@ -524,18 +551,21 @@ gmyth_string_list_append_char_array (strlist, "SEEK"); gmyth_string_list_append_uint64 (strlist, pos); - gmyth_string_list_append_int (strlist, whence); + gmyth_string_list_append_int (strlist, whence); - if (pos > 0 ) + if (pos > 0) gmyth_string_list_append_uint64 (strlist, pos); else - gmyth_string_list_append_uint64 (strlist, gmyth_file_get_offset( GMYTH_FILE(transfer) ) ); + gmyth_string_list_append_uint64 (strlist, + gmyth_file_get_offset (GMYTH_FILE + (transfer))); gmyth_socket_sendreceive_stringlist (priv->control_sock, strlist); gint64 retval = gmyth_string_list_get_int64 (strlist, 0); - gmyth_file_set_offset( GMYTH_FILE(transfer), retval ); - gmyth_debug ( "Got reading position pointer from the streaming = %lld\n", retval ); + gmyth_file_set_offset (GMYTH_FILE (transfer), retval); + gmyth_debug ("Got reading position pointer from the streaming = %lld\n", + retval); g_object_unref (strlist); g_string_free (query, TRUE); @@ -553,16 +583,16 @@ * * @return true, if the acquire had been got. */ -static gboolean -_control_acquire_context( GMythFileTransfer *transfer, gboolean do_wait ) +static gboolean +_control_acquire_context (GMythFileTransfer * transfer, gboolean do_wait) { - gboolean ret = TRUE; + gboolean ret = TRUE; GMythFileTransferPrivate *priv; g_return_val_if_fail (transfer != NULL, FALSE); priv = GMYTH_FILE_TRANSFER_GET_PRIVATE (transfer); - g_mutex_lock (priv->mutex); + g_mutex_lock (priv->mutex); return ret; } @@ -573,17 +603,17 @@ * * @return true, if the socket read/write permissions had been releaseds. */ -static gboolean -_control_release_context( GMythFileTransfer *transfer ) +static gboolean +_control_release_context (GMythFileTransfer * transfer) { - gboolean ret = TRUE; + gboolean ret = TRUE; GMythFileTransferPrivate *priv; g_return_val_if_fail (transfer != NULL, FALSE); priv = GMYTH_FILE_TRANSFER_GET_PRIVATE (transfer); - - g_mutex_unlock (priv->mutex ); - + + g_mutex_unlock (priv->mutex); + return ret; } @@ -600,8 +630,9 @@ * @return The actual block size (in bytes) returned by REQUEST_BLOCK message, * or the error code. */ -GMythFileReadResult -gmyth_file_transfer_read(GMythFileTransfer *transfer, GByteArray *data, gint size, gboolean read_unlimited) +GMythFileReadResult +gmyth_file_transfer_read (GMythFileTransfer * transfer, GByteArray * data, + gint size, gboolean read_unlimited) { gint bytes_sent = 0; gsize bytes_read = 0; @@ -629,41 +660,48 @@ priv = GMYTH_FILE_TRANSFER_GET_PRIVATE (transfer); - strlist = gmyth_string_list_new(); + strlist = gmyth_string_list_new (); io_channel = priv->sock->sd_io_ch; io_channel_control = priv->control_sock->sd_io_ch; - io_status = g_io_channel_set_encoding( io_channel, NULL, &error ); - if ( io_status == G_IO_STATUS_NORMAL ) - gmyth_debug ( "[%s] Setting encoding to binary data socket).\n", __FUNCTION__ ); + io_status = g_io_channel_set_encoding (io_channel, NULL, &error); + if (io_status == G_IO_STATUS_NORMAL) + gmyth_debug ("[%s] Setting encoding to binary data socket).\n", + __FUNCTION__); - io_cond = g_io_channel_get_buffer_condition( io_channel ); + io_cond = g_io_channel_get_buffer_condition (io_channel); - io_cond_control = g_io_channel_get_buffer_condition( io_channel ); - if (priv->sock == NULL || ( io_status == G_IO_STATUS_ERROR ) ) { - g_printerr( "gmyth_file_transfer_read(): Called with no raw socket.\n" ); + io_cond_control = g_io_channel_get_buffer_condition (io_channel); + if (priv->sock == NULL || (io_status == G_IO_STATUS_ERROR)) + { + g_printerr ("gmyth_file_transfer_read(): Called with no raw socket.\n"); return GMYTH_FILE_READ_ERROR; } - if (priv->control_sock == NULL || ( io_status_control == G_IO_STATUS_ERROR ) ) { - g_printerr( "gmyth_file_transfer_read(): Called with no control socket.\n" ); + if (priv->control_sock == NULL || (io_status_control == G_IO_STATUS_ERROR)) + { + g_printerr + ("gmyth_file_transfer_read(): Called with no control socket.\n"); return GMYTH_FILE_READ_ERROR; } query = g_string_new (GMYTHTV_QUERY_HEADER); - g_string_append_printf ( query, "%d", priv->file_id ); - gmyth_debug ("[%s] Transfer_query = %s\n", __FUNCTION__, query->str ); + g_string_append_printf (query, "%d", priv->file_id); + gmyth_debug ("[%s] Transfer_query = %s\n", __FUNCTION__, query->str); - _control_acquire_context (transfer, TRUE ); + _control_acquire_context (transfer, TRUE); //Do Read - gmyth_string_list_append_char_array (strlist, query->str ); - gmyth_string_list_append_char_array (strlist, "REQUEST_BLOCK" ); + gmyth_string_list_append_char_array (strlist, query->str); + gmyth_string_list_append_char_array (strlist, "REQUEST_BLOCK"); gmyth_string_list_append_int (strlist, size - total_read); - do { + guint iter_count = 3; + + do + { bytes_sent = 0; - + // Request the block to the backend gmyth_socket_write_stringlist (priv->control_sock, strlist); @@ -673,27 +711,34 @@ ret_strlist = gmyth_string_list_new (); // Receives the backand answer gmyth_socket_read_stringlist (priv->control_sock, ret_strlist); - - if (ret_strlist != NULL && gmyth_string_list_length (ret_strlist) > 0) { - bytes_sent = gmyth_string_list_get_int (ret_strlist, 0); // -1 on backend error - gmyth_debug ( "[%s] got SENT buffer message = %d\n", __FUNCTION__, bytes_sent ); - } - if (read_unlimited && (bytes_sent == 0)) { + if (ret_strlist != NULL && gmyth_string_list_length (ret_strlist) > 0) + { + bytes_sent = gmyth_string_list_get_int (ret_strlist, 0); // -1 on backend error + gmyth_debug ("[%s] got SENT buffer message = %d\n", __FUNCTION__, + bytes_sent); + } + + if (read_unlimited && (bytes_sent == 0)) + { g_usleep (300); } - } while (read_unlimited && (bytes_sent == 0)); + --iter_count; - if (bytes_sent > 0) { + } + while (read_unlimited && (bytes_sent == 0) && iter_count > 0); + + if (bytes_sent > 0) + { gchar *data_buffer = g_new0 (gchar, bytes_sent); - io_status = g_io_channel_read_chars (io_channel, + io_status = g_io_channel_read_chars (io_channel, data_buffer, (gsize) bytes_sent, - &bytes_read, - &error); + &bytes_read, &error); - if (io_status != G_IO_STATUS_NORMAL) { + if (io_status != G_IO_STATUS_NORMAL) + { gmyth_debug ("Error on io_channel"); g_free (data_buffer); g_object_unref (strlist); @@ -702,100 +747,119 @@ } /* append new data to the increasing byte array */ - data = g_byte_array_append (data, (const guint8*)data_buffer, bytes_read); - gmyth_file_set_offset( GMYTH_FILE(transfer), - gmyth_file_get_offset( GMYTH_FILE(transfer) ) + bytes_read ); + data = + g_byte_array_append (data, (const guint8 *) data_buffer, + bytes_read); + gmyth_file_set_offset (GMYTH_FILE (transfer), + gmyth_file_get_offset (GMYTH_FILE (transfer)) + + bytes_read); - if ( !read_unlimited && ( gmyth_file_get_filesize( GMYTH_FILE(transfer) ) > 0 ) && - ( gmyth_file_get_offset( GMYTH_FILE(transfer) ) == gmyth_file_get_filesize( GMYTH_FILE(transfer) ) ) ) { + if (!read_unlimited + && (gmyth_file_get_filesize (GMYTH_FILE (transfer)) > 0) + && (gmyth_file_get_offset (GMYTH_FILE (transfer)) == + gmyth_file_get_filesize (GMYTH_FILE (transfer)))) + { retval = GMYTH_FILE_READ_EOF; goto error; } - + g_free (data_buffer); - } else { + } + else + { retval = GMYTH_FILE_READ_ERROR; } - if (strlist!=NULL) + if (strlist != NULL) { - g_object_unref (strlist); - strlist = NULL; + g_object_unref (strlist); + strlist = NULL; } - if (ret_strlist!=NULL) + if (ret_strlist != NULL) { - g_object_unref (ret_strlist); - ret_strlist = NULL; + g_object_unref (ret_strlist); + ret_strlist = NULL; } - if (read_unlimited && (bytes_sent == 0)) { - gmyth_debug( "Trying to move to the next program chain..." ); - if (priv->recorder != NULL && - priv->do_next_program_chain) - { - retval = GMYTH_FILE_READ_NEXT_PROG_CHAIN; - GMythProgramInfo *prog_info = gmyth_recorder_get_current_program_info (priv->recorder); - - if (prog_info != NULL && prog_info->pathname != NULL && strlen( prog_info->pathname->str ) > 0 && - g_ascii_strcasecmp( prog_info->pathname->str, - gmyth_file_get_file_name( GMYTH_FILE(transfer) ) ) != 0 ) - ret = gmyth_file_transfer_open (transfer, g_strrstr( prog_info->pathname->str, "/" ) ); - - if (prog_info != NULL ) - g_object_unref( prog_info ); - - if ( !ret ) - gmyth_debug( "Cannot change to the next program info!" ); - else - gmyth_debug( "OK!!! MOVED to the next program info [%s]!", - gmyth_file_get_file_name( GMYTH_FILE(transfer) ) ); - } + if (read_unlimited && (bytes_sent == 0)) + { + gmyth_debug ("Trying to move to the next program chain..."); + if (priv->recorder != NULL && priv->do_next_program_chain) + { + retval = GMYTH_FILE_READ_NEXT_PROG_CHAIN; + GMythProgramInfo *prog_info = + gmyth_recorder_get_current_program_info (priv->recorder); - } /* if */ + if (prog_info != NULL && prog_info->pathname != NULL + && strlen (prog_info->pathname->str) > 0 + && g_ascii_strcasecmp (prog_info->pathname->str, + gmyth_file_get_file_name (GMYTH_FILE + (transfer))) != + 0) + ret = + gmyth_file_transfer_open (transfer, + g_strrstr (prog_info->pathname-> + str, "/")); -error: - + if (prog_info != NULL) + g_object_unref (prog_info); + + if (!ret) + gmyth_debug ("Cannot change to the next program info!"); + else + gmyth_debug ("OK!!! MOVED to the next program info [%s]!", + gmyth_file_get_file_name (GMYTH_FILE (transfer))); + } + + } /* if */ + + error: + _control_release_context (transfer); g_string_free (query, TRUE); - if ( error != NULL ) { - gmyth_debug ("Cleaning-up ERROR: %s [msg = %s, code = %d]\n", __FUNCTION__, error->message, - error->code); + if (error != NULL) + { + gmyth_debug ("Cleaning-up ERROR: %s [msg = %s, code = %d]\n", + __FUNCTION__, error->message, error->code); g_error_free (error); } - - if ( total_read > 0 ) - gmyth_file_set_offset( GMYTH_FILE(transfer), - gmyth_file_get_offset( GMYTH_FILE(transfer) ) + total_read ); - + + if (total_read > 0) + gmyth_file_set_offset (GMYTH_FILE (transfer), + gmyth_file_get_offset (GMYTH_FILE (transfer)) + + total_read); + return retval; } -static void -_file_transfer_program_info_changed( GMythFileTransfer *transfer, - gint msg_code, gpointer livetv_recorder ) +static void +_file_transfer_program_info_changed (GMythFileTransfer * transfer, + gint msg_code, gpointer livetv_recorder) { - GMythRecorder *recorder; + GMythRecorder *recorder; GMythFileTransferPrivate *priv; g_return_if_fail (transfer != NULL); priv = GMYTH_FILE_TRANSFER_GET_PRIVATE (transfer); - recorder = GMYTH_RECORDER( livetv_recorder ); - gmyth_debug( "Program info changed! ( file transfer orig. = %p, ptr. = [%s] )", transfer, - livetv_recorder != NULL ? "[NOT NULL]" : "[NULL]"); - - if ( NULL != recorder ) - { - gmyth_debug( "YES, the requested program info movement on the LiveTV transfer is authentical!" ); - } - - priv = GMYTH_FILE_TRANSFER_GET_PRIVATE(transfer); - g_object_ref(recorder); - priv->recorder = recorder; - priv->do_next_program_chain = TRUE; + recorder = GMYTH_RECORDER (livetv_recorder); + gmyth_debug + ("Program info changed! ( file transfer orig. = %p, ptr. = [%s] )", + transfer, livetv_recorder != NULL ? "[NOT NULL]" : "[NULL]"); + + if (NULL != recorder) + { + gmyth_debug + ("YES, the requested program info movement on the LiveTV transfer is authentical!"); + } + + priv = GMYTH_FILE_TRANSFER_GET_PRIVATE (transfer); + g_object_ref (recorder); + priv->recorder = recorder; + priv->do_next_program_chain = TRUE; } /** @@ -807,42 +871,43 @@ * * @return true, if the acquire had been got. */ -gboolean -gmyth_file_transfer_settimeout( GMythFileTransfer *transfer, gboolean fast ) +gboolean +gmyth_file_transfer_settimeout (GMythFileTransfer * transfer, gboolean fast) { - GMythFileTransferPrivate *priv; - GMythStringList *strlist = NULL; + GMythFileTransferPrivate *priv; + GMythStringList *strlist = NULL; - g_return_val_if_fail (transfer != NULL, FALSE); + g_return_val_if_fail (transfer != NULL, FALSE); - priv = GMYTH_FILE_TRANSFER_GET_PRIVATE (transfer); + priv = GMYTH_FILE_TRANSFER_GET_PRIVATE (transfer); - g_return_val_if_fail (priv->sock != NULL, FALSE); - g_return_val_if_fail (priv->control_sock != NULL, FALSE); - - _control_acquire_context (transfer, TRUE ); + g_return_val_if_fail (priv->sock != NULL, FALSE); + g_return_val_if_fail (priv->control_sock != NULL, FALSE); - strlist = gmyth_string_list_new(); - 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 ); + _control_acquire_context (transfer, TRUE); - gint strlist_len = gmyth_socket_sendreceive_stringlist (priv->control_sock, - strlist ); - - if ( strlist_len > 0 ) - gmyth_debug( "Yes, timeout was changed: %s.", gmyth_string_list_get_char_array( strlist, 0 ) ); - else - gmyth_debug( "Timeout cannot be changed!" ); - - _control_release_context (transfer); + strlist = gmyth_string_list_new (); + 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_debug ( "%s setting timeout flag of this file transfer = %s\n", - strlist_len > 0 ? "Yes," : "NOT", fast ? "FAST" : "NOT FAST" ); + gint strlist_len = gmyth_socket_sendreceive_stringlist (priv->control_sock, + strlist); - g_object_unref (strlist); + if (strlist_len > 0) + gmyth_debug ("Yes, timeout was changed: %s.", + gmyth_string_list_get_char_array (strlist, 0)); + else + gmyth_debug ("Timeout cannot be changed!"); - return TRUE; + _control_release_context (transfer); + + gmyth_debug ("%s setting timeout flag of this file transfer = %s\n", + strlist_len > 0 ? "Yes," : "NOT", fast ? "FAST" : "NOT FAST"); + + g_object_unref (strlist); + + return TRUE; } /** @@ -853,13 +918,13 @@ * @return The actual file size in bytes. */ guint64 -gmyth_file_transfer_get_filesize (GMythFileTransfer *transfer) +gmyth_file_transfer_get_filesize (GMythFileTransfer * transfer) { guint64 filesize; - + g_return_val_if_fail (transfer != NULL, 0); - - g_object_get( GMYTH_FILE(transfer), "file-size", &filesize, NULL ); + + g_object_get (GMYTH_FILE (transfer), "file-size", &filesize, NULL); return filesize; } diff -r 76b9c97faada -r ad1457d65f74 gmyth/src/gmyth_file_transfer.h --- a/gmyth/src/gmyth_file_transfer.h Tue May 15 20:16:26 2007 +0100 +++ b/gmyth/src/gmyth_file_transfer.h Tue May 15 21:39:04 2007 +0100 @@ -9,23 +9,23 @@ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia. * @author Rosfran Lins Borges * - *//* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - + *//* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + #ifndef __GMYTH_FILE_TRANSFER_H__ #define __GMYTH_FILE_TRANSFER_H__ @@ -45,61 +45,58 @@ #include G_BEGIN_DECLS - #define GMYTH_FILE_TRANSFER_TYPE (gmyth_file_transfer_get_type ()) #define GMYTH_FILE_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransfer)) #define GMYTH_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferClass)) #define IS_GMYTH_FILE_TRANSFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_FILE_TRANSFER_TYPE)) #define IS_GMYTH_FILE_TRANSFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_FILE_TRANSFER_TYPE)) #define GMYTH_FILE_TRANSFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_FILE_TRANSFER_TYPE, GMythFileTransferClass)) - -typedef struct _GMythFileTransfer GMythFileTransfer; -typedef struct _GMythFileTransferClass GMythFileTransferClass; -typedef struct _GMythFileTransferPrivate GMythFileTransferPrivate; +typedef struct _GMythFileTransfer GMythFileTransfer; +typedef struct _GMythFileTransferClass GMythFileTransferClass; +typedef struct _GMythFileTransferPrivate GMythFileTransferPrivate; struct _GMythFileTransfer -{ - GMythFile parent; - GMythFileTransferPrivate *priv; -}; + { + GMythFile parent; + GMythFileTransferPrivate *priv; + }; struct _GMythFileTransferClass -{ - GMythFileClass parent_class; + { + GMythFileClass parent_class; - /* callbacks */ - guint program_info_changed_handler_signal_id; + /* callbacks */ + guint program_info_changed_handler_signal_id; - /* signal default handlers */ - void (*program_info_changed_handler) ( GMythFileTransfer *transfer, - gint msg_code, gpointer livetv_recorder ); -}; + /* signal default handlers */ + void (*program_info_changed_handler) (GMythFileTransfer * transfer, + gint msg_code, + gpointer livetv_recorder); + }; -GType gmyth_file_transfer_get_type (void); -GMythFileTransfer* gmyth_file_transfer_new (GMythBackendInfo *backend_info); -gchar* gmyth_file_transfer_get_file_name (GMythFileTransfer *transfer); -gboolean gmyth_file_transfer_open (GMythFileTransfer *transfer, - const gchar* filename); -void gmyth_file_transfer_close (GMythFileTransfer *transfer); -gboolean gmyth_file_transfer_is_open (GMythFileTransfer *transfer); +GType gmyth_file_transfer_get_type (void); +GMythFileTransfer *gmyth_file_transfer_new (GMythBackendInfo * backend_info); +gchar *gmyth_file_transfer_get_file_name (GMythFileTransfer * transfer); +gboolean gmyth_file_transfer_open (GMythFileTransfer * transfer, + const gchar * filename); +void gmyth_file_transfer_close (GMythFileTransfer * transfer); +gboolean gmyth_file_transfer_is_open (GMythFileTransfer * transfer); GMythFileReadResult - gmyth_file_transfer_read (GMythFileTransfer *transfer, - GByteArray *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); -guint64 gmyth_file_transfer_get_filesize (GMythFileTransfer *transfer); +gmyth_file_transfer_read (GMythFileTransfer * transfer, + GByteArray * 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); +guint64 gmyth_file_transfer_get_filesize (GMythFileTransfer * transfer); -void gmyth_file_transfer_emit_program_info_changed_signal ( - GMythFileTransfer *transfer, - gint msg_code, - gpointer live_tv_recorder ); +void gmyth_file_transfer_emit_program_info_changed_signal (GMythFileTransfer * + transfer, + gint msg_code, + gpointer + live_tv_recorder); G_END_DECLS - #endif /* __GMYTH_FILE_TRANSFER_H__ */ diff -r 76b9c97faada -r ad1457d65f74 gmyth/src/gmyth_livetv.c --- a/gmyth/src/gmyth_livetv.c Tue May 15 20:16:26 2007 +0100 +++ b/gmyth/src/gmyth_livetv.c Tue May 15 21:39:04 2007 +0100 @@ -8,28 +8,28 @@ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia. * @author Rosfran Lins Borges * - *//* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - + *//* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "gmyth_livetv.h" +#include "gmyth_livetv.h" #include "gmyth_remote_util.h" #include "gmyth_tvchain.h" #include "gmyth_socket.h" @@ -44,122 +44,131 @@ #include "gmyth_common.h" #include "gmyth_util.h" -static void gmyth_livetv_class_init (GMythLiveTVClass *klass); -static void gmyth_livetv_init (GMythLiveTV *object); +static void gmyth_livetv_class_init (GMythLiveTVClass * klass); +static void gmyth_livetv_init (GMythLiveTV * object); -static void gmyth_livetv_dispose (GObject *object); -static void gmyth_livetv_finalize (GObject *object); +static void gmyth_livetv_dispose (GObject * object); +static void gmyth_livetv_finalize (GObject * object); -static gint tvchain_curr_index = -1; +static gint tvchain_curr_index = -1; /*static GStaticMutex lock = G_STATIC_MUTEX_INIT;*/ #define GMYTHTV_TRANSFER_MAX_WAITS 100 -G_DEFINE_TYPE(GMythLiveTV, gmyth_livetv, G_TYPE_OBJECT) +G_DEFINE_TYPE (GMythLiveTV, gmyth_livetv, G_TYPE_OBJECT) + static void gmyth_livetv_class_init (GMythLiveTVClass * klass) +{ + GObjectClass *gobject_class; -static void -gmyth_livetv_class_init (GMythLiveTVClass *klass) -{ - GObjectClass *gobject_class; + gobject_class = (GObjectClass *) klass; - gobject_class = (GObjectClass *) klass; - - gobject_class->dispose = gmyth_livetv_dispose; - gobject_class->finalize = gmyth_livetv_finalize; + gobject_class->dispose = gmyth_livetv_dispose; + gobject_class->finalize = gmyth_livetv_finalize; } static void -gmyth_livetv_init (GMythLiveTV *livetv) +gmyth_livetv_init (GMythLiveTV * livetv) { livetv->monitor = NULL; - livetv->backend_info = NULL; - livetv->local_hostname = NULL; - livetv->file = NULL; - livetv->setup_done = FALSE; - - livetv->socket = NULL; - livetv->recorder = NULL; - livetv->tvchain = NULL; - livetv->proginfo = NULL; - livetv->uri = NULL; - - livetv->mutex = g_mutex_new(); + livetv->backend_info = NULL; + livetv->local_hostname = NULL; + livetv->file = NULL; + livetv->setup_done = FALSE; + + livetv->socket = NULL; + livetv->recorder = NULL; + livetv->tvchain = NULL; + livetv->proginfo = NULL; + livetv->uri = NULL; + + livetv->mutex = g_mutex_new (); } static void -gmyth_livetv_dispose (GObject *object) -{ - GMythLiveTV *livetv = GMYTH_LIVETV (object); +gmyth_livetv_dispose (GObject * object) +{ + GMythLiveTV *livetv = GMYTH_LIVETV (object); - if (livetv->disposed) { + if (livetv->disposed) + { /* If dispose did already run, return. */ return; } - + /* Make sure dispose does not run twice. */ livetv->disposed = TRUE; - if ( livetv->monitor != NULL ) { - g_object_unref (livetv->monitor); - livetv->monitor = NULL; - } - - if ( livetv->file != NULL ) { + if (livetv->monitor != NULL) + { + g_object_unref (livetv->monitor); + livetv->monitor = NULL; + } + + if (livetv->file != NULL) + { g_object_unref (livetv->file); livetv->file = NULL; } - - if ( livetv->recorder != NULL ) { + + if (livetv->recorder != NULL) + { //gmyth_recorder_close(livetv->recorder); - g_object_unref (livetv->recorder); - livetv->recorder = NULL; - } + g_object_unref (livetv->recorder); + livetv->recorder = NULL; + } - if ( livetv->socket != NULL ) { - g_object_unref (livetv->socket); - livetv->socket = NULL; - } - - if ( livetv->tvchain != NULL ) { - g_object_unref (livetv->tvchain); - livetv->tvchain = NULL; - } + if (livetv->socket != NULL) + { + g_object_unref (livetv->socket); + livetv->socket = NULL; + } - if ( livetv->proginfo != NULL ) { - g_object_unref (livetv->proginfo); - livetv->proginfo = NULL; - } - - if ( livetv->backend_info != NULL ) { - g_object_unref (livetv->backend_info); - livetv->backend_info = NULL; - } - - if ( livetv->uri != NULL ) { - g_object_unref (livetv->uri); - livetv->uri = NULL; - } - - if ( livetv->mutex != NULL ) { - g_mutex_free (livetv->mutex); - livetv->mutex = NULL; - } - - if ( livetv->local_hostname != NULL ) { + if (livetv->tvchain != NULL) + { + g_object_unref (livetv->tvchain); + livetv->tvchain = NULL; + } + + if (livetv->proginfo != NULL) + { + g_object_unref (livetv->proginfo); + livetv->proginfo = NULL; + } + + if (livetv->backend_info != NULL) + { + g_object_unref (livetv->backend_info); + livetv->backend_info = NULL; + } + + if (livetv->uri != NULL) + { + g_object_unref (livetv->uri); + livetv->uri = NULL; + } + + if (livetv->mutex != NULL) + { + g_mutex_free (livetv->mutex); + livetv->mutex = NULL; + } + + if (livetv->local_hostname != NULL) + { g_string_free (livetv->local_hostname, TRUE); livetv->local_hostname = NULL; } - G_OBJECT_CLASS (gmyth_livetv_parent_class)->dispose (object); + G_OBJECT_CLASS (gmyth_livetv_parent_class)->dispose (object); } static void -gmyth_livetv_finalize (GObject *object) +gmyth_livetv_finalize (GObject * object) { - g_signal_handlers_destroy (object); + g_signal_handlers_destroy (object); - G_OBJECT_CLASS ( gmyth_livetv_parent_class )->finalize ( object ); + G_OBJECT_CLASS (gmyth_livetv_parent_class)->finalize (object); } /** @@ -167,15 +176,15 @@ * * @return a newly allocated GMythLiveTV instance */ -GMythLiveTV* -gmyth_livetv_new (GMythBackendInfo *backend_info) +GMythLiveTV * +gmyth_livetv_new (GMythBackendInfo * backend_info) { - GMythLiveTV *livetv = GMYTH_LIVETV ( g_object_new( GMYTH_LIVETV_TYPE, NULL ) ); - - livetv->backend_info = backend_info; + GMythLiveTV *livetv = GMYTH_LIVETV (g_object_new (GMYTH_LIVETV_TYPE, NULL)); + + livetv->backend_info = backend_info; g_object_ref (livetv->backend_info); - return livetv; + return livetv; } /** @@ -189,83 +198,107 @@ * @param user_data pointer to the GMythLiveTV instance */ static void -gmyth_livetv_monitor_signal_handler( GMythMonitorHandler *monitor, gint msg_code, - gchar* message, gpointer user_data ) +gmyth_livetv_monitor_signal_handler (GMythMonitorHandler * monitor, + gint msg_code, gchar * message, + gpointer user_data) { - GMythLiveTV *live_tv = GMYTH_LIVETV ( user_data ); - - gmyth_debug( "LIVETV Signal handler ( msg = %s, code = %d, live_tv param = %s, user_data = %s )\n", message, msg_code, live_tv != NULL ? "" : - "NULL", user_data != NULL ? "" : "NULL" ); - - if ( NULL == live_tv || !IS_GMYTH_FILE_TRANSFER( live_tv->file ) ) - { - gmyth_debug( "LiveTV_obj is equals to NULL!!!" ); - return; - } - - switch ( msg_code ) - { - - case GMYTH_BACKEND_PROGRAM_INFO_CHANGED: - { - gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\ - "TV Chain ID is the same as the old one...\n", message ); - if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) { - gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!", - (gmyth_tvchain_get_id( live_tv->tvchain ))->str ); - /* advertises the FileTransfer about the program info changed */ - if ( live_tv->file != NULL ) - { - gmyth_debug( "Emitting signal to the FileTransfer... [ \"program-info-changed \" ]" ); - - gmyth_file_transfer_emit_program_info_changed_signal( GMYTH_FILE_TRANSFER(live_tv->file), - msg_code, (gpointer)(live_tv->recorder) ); - - /* gmyth_livetv_monitor_handler_stop( live_tv ); */ - } else - gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n"); - } - break; - } - case GMYTH_BACKEND_DONE_RECORDING: - { - gmyth_debug( "LIVETV Program Changed request received [ msg = %s ]. Watching if the new "\ - "TV Chain ID is the same as the old one...\n", message ); - if ( g_ascii_strcasecmp ( message, (gmyth_tvchain_get_id( live_tv->tvchain ))->str ) != 0 ) { - gmyth_debug( "OK!!! MOVED to the next program chain [actual == %s]!", - (gmyth_tvchain_get_id( live_tv->tvchain ))->str ); - /* advertises the FileTransfer about the program info changed */ - if ( live_tv->file != NULL ) - { - gmyth_debug( "Emitting signal to the FileTransfer... [ \"backend-done-recording\" ]" ); - - gmyth_file_transfer_emit_program_info_changed_signal( GMYTH_FILE_TRANSFER(live_tv->file), - msg_code, (gpointer)(live_tv->recorder) ); - - } else - gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n"); - } - break; - } - case GMYTH_BACKEND_STOP_LIVETV: - { - gmyth_debug( "LIVETV Stop LiveTV request received [ msg = %s ]. Going out the "\ - "LiveTV...\n", message ); - /* stops the LiveTV */ - if ( live_tv != NULL ) - { - gmyth_debug( "Going out the LiveTV... [ \"quit-livetv\" ]" ); - - g_object_unref( live_tv ); - } else - gmyth_debug( "LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n"); - - break; - } - default: - break; - } /* switch (Monitor Handler messages) */ - + GMythLiveTV *live_tv = GMYTH_LIVETV (user_data); + + gmyth_debug + ("LIVETV Signal handler ( msg = %s, code = %d, live_tv param = %s, user_data = %s )\n", + message, msg_code, live_tv != NULL ? "" : "NULL", + user_data != NULL ? "" : "NULL"); + + if (NULL == live_tv || !IS_GMYTH_FILE_TRANSFER (live_tv->file)) + { + gmyth_debug ("LiveTV_obj is equals to NULL!!!"); + return; + } + + switch (msg_code) + { + + case GMYTH_BACKEND_PROGRAM_INFO_CHANGED: + { + gmyth_debug + ("LIVETV Program Changed request received [ msg = %s ]. Watching if the new " + "TV Chain ID is the same as the old one...\n", message); + if (g_ascii_strcasecmp + (message, + (gmyth_tvchain_get_id (live_tv->tvchain))->str) != 0) + { + gmyth_debug + ("OK!!! MOVED to the next program chain [actual == %s]!", + (gmyth_tvchain_get_id (live_tv->tvchain))->str); + /* advertises the FileTransfer about the program info changed */ + if (live_tv->file != NULL) + { + gmyth_debug + ("Emitting signal to the FileTransfer... [ \"program-info-changed \" ]"); + + gmyth_file_transfer_emit_program_info_changed_signal + (GMYTH_FILE_TRANSFER (live_tv->file), msg_code, + (gpointer) (live_tv->recorder)); + + /* gmyth_livetv_monitor_handler_stop( live_tv ); */ + } + else + gmyth_debug + ("LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n"); + } + break; + } + case GMYTH_BACKEND_DONE_RECORDING: + { + gmyth_debug + ("LIVETV Program Changed request received [ msg = %s ]. Watching if the new " + "TV Chain ID is the same as the old one...\n", message); + if (g_ascii_strcasecmp + (message, + (gmyth_tvchain_get_id (live_tv->tvchain))->str) != 0) + { + gmyth_debug + ("OK!!! MOVED to the next program chain [actual == %s]!", + (gmyth_tvchain_get_id (live_tv->tvchain))->str); + /* advertises the FileTransfer about the program info changed */ + if (live_tv->file != NULL) + { + gmyth_debug + ("Emitting signal to the FileTransfer... [ \"backend-done-recording\" ]"); + + gmyth_file_transfer_emit_program_info_changed_signal + (GMYTH_FILE_TRANSFER (live_tv->file), msg_code, + (gpointer) (live_tv->recorder)); + + } + else + gmyth_debug + ("LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n"); + } + break; + } + case GMYTH_BACKEND_STOP_LIVETV: + { + gmyth_debug + ("LIVETV Stop LiveTV request received [ msg = %s ]. Going out the " + "LiveTV...\n", message); + /* stops the LiveTV */ + if (live_tv != NULL) + { + gmyth_debug ("Going out the LiveTV... [ \"quit-livetv\" ]"); + + g_object_unref (live_tv); + } + else + gmyth_debug + ("LIVETV file_transfer is NULL!!! Cannot move to the next program chain event received.\n"); + + break; + } + default: + break; + } /* switch (Monitor Handler messages) */ + } /** @@ -278,44 +311,50 @@ * had been concluded succcesfully */ gboolean -gmyth_livetv_monitor_handler_start( GMythLiveTV *livetv ) +gmyth_livetv_monitor_handler_start (GMythLiveTV * livetv) { - gboolean res = TRUE; - - if ( livetv->monitor != NULL ) - { - g_object_unref( livetv->monitor ); - livetv->monitor = NULL; - } - - livetv->monitor = gmyth_monitor_handler_new ( ); - - res = gmyth_monitor_handler_open (livetv->monitor, livetv->backend_info->hostname, - livetv->backend_info->port ); - - if ( res == TRUE ) - { - gmyth_debug("Connect MythTV Monitor event socket! Trying to start the message handler..."); - - res = gmyth_monitor_handler_start ( livetv->monitor ); - - if (res) - { - gmyth_debug("MythTV Monitor event socket connected and listening!"); - g_signal_connect ( G_OBJECT (livetv->monitor), "backend-events-handler", - (GCallback)gmyth_livetv_monitor_signal_handler, - livetv ); - } - else - { - gmyth_debug("Problems when trying to start MythTV Monitor event socket!"); - goto error; - } - } - -error: - return res; - + gboolean res = TRUE; + + if (livetv->monitor != NULL) + { + g_object_unref (livetv->monitor); + livetv->monitor = NULL; + } + + livetv->monitor = gmyth_monitor_handler_new (); + + res = + gmyth_monitor_handler_open (livetv->monitor, + livetv->backend_info->hostname, + livetv->backend_info->port); + + if (res == TRUE) + { + gmyth_debug + ("Connect MythTV Monitor event socket! Trying to start the message handler..."); + + res = gmyth_monitor_handler_start (livetv->monitor); + + if (res) + { + gmyth_debug + ("MythTV Monitor event socket connected and listening!"); + g_signal_connect (G_OBJECT (livetv->monitor), + "backend-events-handler", + (GCallback) gmyth_livetv_monitor_signal_handler, + livetv); + } + else + { + gmyth_debug + ("Problems when trying to start MythTV Monitor event socket!"); + goto error; + } + } + + error: + return res; + } /** @@ -328,27 +367,25 @@ * had been concluded succcesfully */ void -gmyth_livetv_monitor_handler_stop( GMythLiveTV *livetv ) +gmyth_livetv_monitor_handler_stop (GMythLiveTV * livetv) { - - if ( livetv->monitor != NULL ) - { - g_object_unref( livetv->monitor ); - livetv->monitor = NULL; - } - + + if (livetv->monitor != NULL) + { + g_object_unref (livetv->monitor); + livetv->monitor = NULL; + } + } #if 0 -static gchar* -gmyth_livetv_create_remote_url( GMythLiveTV *livetv ) +static gchar * +gmyth_livetv_create_remote_url (GMythLiveTV * livetv) { - gchar *uri = g_strdup(""); - gmyth_backend_info_get_remote_h - - //gmyth_backend(livetv->backend_info) - - return uri; + gchar *uri = g_strdup (""); + gmyth_backend_info_get_remote_h + //gmyth_backend(livetv->backend_info) + return uri; } #endif @@ -365,238 +402,280 @@ * had been concluded succcesfully */ static gboolean -gmyth_livetv_setup_recorder_channel_name (GMythLiveTV *livetv, gchar* channel) +gmyth_livetv_setup_recorder_channel_name (GMythLiveTV * livetv, gchar * channel) { - gboolean res = TRUE; - + gboolean res = TRUE; + g_return_val_if_fail (livetv != NULL, FALSE); - - if ( NULL == livetv->socket ) { - livetv->socket = gmyth_socket_new (); - - /* FIME: Implement this at gmyth_socket */ - res = gmyth_socket_connect_to_backend (livetv->socket, livetv->backend_info->hostname, - livetv->backend_info->port, TRUE); - if (!res) { - gmyth_debug ("[%s] LiveTV can not connect to backend", __FUNCTION__); - res = FALSE; - goto error; - } - } - - g_mutex_lock( livetv->mutex ); - - livetv->is_livetv = TRUE; - - livetv->local_hostname = gmyth_socket_get_local_hostname (); - if ( livetv->local_hostname == NULL ) { - res = FALSE; - goto error; - } - - if ( livetv->recorder != NULL ) - { - g_object_unref( livetv->recorder ); - livetv->recorder= NULL; - } - - if ( gmyth_remote_util_get_free_recorder_count (livetv->socket) <= 0 ) { - gmyth_debug ("No free remote encoder available."); - res = FALSE; - goto error; - } + if (NULL == livetv->socket) + { + livetv->socket = gmyth_socket_new (); - /* Gets the recorder num */ - livetv->recorder = remote_request_next_free_recorder (livetv->socket, -1); - gmyth_socket_close_connection (livetv->socket); + /* FIME: Implement this at gmyth_socket */ + res = + gmyth_socket_connect_to_backend (livetv->socket, + livetv->backend_info->hostname, + livetv->backend_info->port, TRUE); + if (!res) + { + gmyth_debug ("[%s] LiveTV can not connect to backend", + __FUNCTION__); + res = FALSE; + goto error; + } + } - if ( NULL == livetv->recorder ) { - gmyth_debug ("[%s] None remote encoder available", __FUNCTION__); - res = FALSE; - goto error; - } - - /* Init remote encoder. Opens its control socket. */ - res = gmyth_recorder_setup(livetv->recorder); - if ( !res ) { - gmyth_debug ("[%s] Fail while setting remote encoder\n", __FUNCTION__); - res = FALSE; - goto error; - } - - /* Creates livetv chain handler */ - livetv->tvchain = gmyth_tvchain_new(); - gmyth_tvchain_initialize ( livetv->tvchain, livetv->backend_info ); + g_mutex_lock (livetv->mutex); - if ( livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL ) { - res = FALSE; - goto error; - } - - // Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly) - res = gmyth_recorder_spawntv ( livetv->recorder, - gmyth_tvchain_get_id(livetv->tvchain) ); - if (!res) { - gmyth_debug ("[%s] Fail while spawn tv\n", __FUNCTION__); - res = FALSE; - goto error; - } - - if ( res == TRUE ) { - /* loop finished, set the max tries variable to zero again... */ - gint wait_to_transfer = 0; + livetv->is_livetv = TRUE; - while (wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS && - (gmyth_recorder_is_recording (livetv->recorder) == FALSE)) - g_usleep (300); + livetv->local_hostname = gmyth_socket_get_local_hostname (); - if ( channel != NULL ) - { - /* Pauses remote encoder. */ - res = gmyth_recorder_pause_recording(livetv->recorder); - if ( !res ) { - gmyth_debug ("[%s] Fail while pausing remote encoder\n", __FUNCTION__); - res = FALSE; - goto error; - } - - if ( gmyth_recorder_check_channel_name( livetv->recorder, channel ) ) - { - if ( gmyth_recorder_set_channel_name( livetv->recorder, channel ) ) - { - gmyth_debug( "Channel changed!!! [%s].\n", channel ); - } - } - - } /* if - changes the channel number */ - /* sleep (5); */ /* FIXME: this is evil (tpm) */ - } - - /* DEBUG message */ - GMythProgramInfo* prog_info = gmyth_recorder_get_current_program_info( livetv->recorder ); - - if ( NULL == prog_info ) - { - gmyth_debug( "ProgramInfo is equals to NULL!!!" ); - + if (livetv->local_hostname == NULL) + { + res = FALSE; + goto error; + } + + if (livetv->recorder != NULL) + { + g_object_unref (livetv->recorder); + livetv->recorder = NULL; + } + + if (gmyth_remote_util_get_free_recorder_count (livetv->socket) <= 0) + { + gmyth_debug ("No free remote encoder available."); + res = FALSE; + goto error; + } + + /* Gets the recorder num */ + livetv->recorder = remote_request_next_free_recorder (livetv->socket, -1); + gmyth_socket_close_connection (livetv->socket); + + if (NULL == livetv->recorder) + { + gmyth_debug ("[%s] None remote encoder available", __FUNCTION__); + res = FALSE; + goto error; + } + + /* Init remote encoder. Opens its control socket. */ + res = gmyth_recorder_setup (livetv->recorder); + if (!res) + { + gmyth_debug ("[%s] Fail while setting remote encoder\n", __FUNCTION__); + res = FALSE; + goto error; + } + + /* Creates livetv chain handler */ + livetv->tvchain = gmyth_tvchain_new (); + gmyth_tvchain_initialize (livetv->tvchain, livetv->backend_info); + + if (livetv->tvchain == NULL || livetv->tvchain->tvchain_id == NULL) + { + res = FALSE; + goto error; + } + + // Spawn live tv. Uses the socket to send mythprotocol data to start livetv in the backend (remotelly) + res = gmyth_recorder_spawntv (livetv->recorder, + gmyth_tvchain_get_id (livetv->tvchain)); + if (!res) + { + gmyth_debug ("[%s] Fail while spawn tv\n", __FUNCTION__); + res = FALSE; + goto error; + } + + if (res == TRUE) + { + /* loop finished, set the max tries variable to zero again... */ + gint wait_to_transfer = 0; + + while (wait_to_transfer++ < GMYTHTV_TRANSFER_MAX_WAITS && + (gmyth_recorder_is_recording (livetv->recorder) == FALSE)) + g_usleep (300); + + if (channel != NULL) + { + /* Pauses remote encoder. */ + res = gmyth_recorder_pause_recording (livetv->recorder); + if (!res) + { + gmyth_debug ("[%s] Fail while pausing remote encoder\n", + __FUNCTION__); + res = FALSE; + goto error; + } + + if (gmyth_recorder_check_channel_name (livetv->recorder, channel)) + { + if (gmyth_recorder_set_channel_name (livetv->recorder, channel)) + { + gmyth_debug ("Channel changed!!! [%s].\n", channel); + } + } + + } /* if - changes the channel number */ + /* sleep (5); *//* FIXME: this is evil (tpm) */ + } + + /* DEBUG message */ + GMythProgramInfo *prog_info = + gmyth_recorder_get_current_program_info (livetv->recorder); + + if (NULL == prog_info) + { + gmyth_debug ("ProgramInfo is equals to NULL!!!"); + gint i; gchar *channame = NULL; - - gmyth_debug( "Problem getting current proginfo!\n" ); - + + gmyth_debug ("Problem getting current proginfo!\n"); + /* * mythbackend must not be tuned in to a channel, so keep * changing channels until we find a valid one, or until * we decide to give up. */ - for (i=1; i<1000; i++) { - if ( channame != NULL ) - g_free(channame); - channame = g_strdup_printf( "%d", i ); - if (gmyth_recorder_set_channel_name(livetv->recorder, channame) < 0) { + for (i = 1; i < 1000; i++) + { + if (channame != NULL) + g_free (channame); + channame = g_strdup_printf ("%d", i); + if (gmyth_recorder_set_channel_name (livetv->recorder, channame) < + 0) + { continue; } - prog_info = gmyth_recorder_get_next_program_info(livetv->recorder, BROWSE_DIRECTION_UP); - gmyth_program_info_print( prog_info ); + prog_info = + gmyth_recorder_get_next_program_info (livetv->recorder, + BROWSE_DIRECTION_UP); + gmyth_program_info_print (prog_info); if (prog_info != NULL) break; } - } /* if - Program Info */ - - /* prints program info data text */ - gmyth_debug( "New ProgramInfo...\n" ); - gmyth_program_info_print( prog_info ); + } /* if - Program Info */ - /* check if the program chain could be obtained from the MythTV protocol message */ - if ( prog_info != NULL ) - { - gmyth_backend_info_set_username( livetv->tvchain->backend_info, "mythtv" ); - gmyth_backend_info_set_password( livetv->tvchain->backend_info, "mythtv" ); - gmyth_backend_info_set_db_name( livetv->tvchain->backend_info, "mythconverg" ); - GList* prog_list = gmyth_tvchain_get_program_info_from_channel( livetv->tvchain, channel ); + /* prints program info data text */ + gmyth_debug ("New ProgramInfo...\n"); + gmyth_program_info_print (prog_info); + + /* check if the program chain could be obtained from the MythTV protocol message */ + if (prog_info != NULL) + { + gmyth_backend_info_set_username (livetv->tvchain->backend_info, + "mythtv"); + gmyth_backend_info_set_password (livetv->tvchain->backend_info, + "mythtv"); + gmyth_backend_info_set_db_name (livetv->tvchain->backend_info, + "mythconverg"); + GList *prog_list = + gmyth_tvchain_get_program_info_from_channel (livetv->tvchain, + channel); GMythProgramInfo *ch_prog = NULL; - if ( prog_list != NULL && g_list_length(prog_list) > 0 ) - { - ch_prog = (GMythProgramInfo*)g_list_nth_data( prog_list, 0 ); - gmyth_debug( "Channel program info (from a list with size = %d)!", g_list_length(prog_list) ); - gmyth_program_info_print( ch_prog ); - } - - gmyth_debug( "Program Info: %s\n", gmyth_program_info_to_string( prog_info ) ); - livetv->proginfo = prog_info; - /* testing change channel */ - //gmyth_recorder_spawntv_no_tvchain( livetv->recorder ); - } else { - - /* check for the program info in the TV program chain could be obtained - from the MythTV MySQL database */ + if (prog_list != NULL && g_list_length (prog_list) > 0) + { + ch_prog = (GMythProgramInfo *) g_list_nth_data (prog_list, 0); + gmyth_debug ("Channel program info (from a list with size = %d)!", + g_list_length (prog_list)); + gmyth_program_info_print (ch_prog); + } - /* Reload all TV chain from Mysql database. */ - gmyth_tvchain_reload_all (livetv->tvchain); - - if ( livetv->tvchain == NULL ) { - res = FALSE; - goto error; - } - - /* Get program info from database using chanid and starttime */ - livetv->proginfo = gmyth_tvchain_get_program_at (livetv->tvchain, tvchain_curr_index++ ); - if ( livetv->proginfo == NULL ) { - gmyth_debug ("LiveTV not successfully started.\n"); - res = FALSE; - goto error; - } else { - res = TRUE; - gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK. [%s]\n", livetv->proginfo->pathname->str ); - } - - } - - livetv->uri = (GMythURI*)gmyth_backend_info_get_uri( livetv->backend_info ); - - g_mutex_unlock( livetv->mutex ); + gmyth_debug ("Program Info: %s\n", + gmyth_program_info_to_string (prog_info)); + livetv->proginfo = prog_info; + /* testing change channel */ + //gmyth_recorder_spawntv_no_tvchain( livetv->recorder ); + } + else + { - if ( !gmyth_livetv_monitor_handler_start( livetv ) ) - { - res = FALSE; - gmyth_debug( "LiveTV MONITOR handler error on setup!" ); - goto error; - } - - livetv->setup_done = TRUE; - - return res; + /* check for the program info in the TV program chain could be obtained + from the MythTV MySQL database */ -error: - gmyth_debug( "[%s] ERROR running LiveTV setup.\n", __FUNCTION__ ); + /* Reload all TV chain from Mysql database. */ + gmyth_tvchain_reload_all (livetv->tvchain); + + if (livetv->tvchain == NULL) + { + res = FALSE; + goto error; + } + + /* Get program info from database using chanid and starttime */ + livetv->proginfo = + gmyth_tvchain_get_program_at (livetv->tvchain, + tvchain_curr_index++); + if (livetv->proginfo == NULL) + { + gmyth_debug ("LiveTV not successfully started.\n"); + res = FALSE; + goto error; + } + else + { + res = TRUE; + gmyth_debug + ("GMythLiveTV: All requests to backend to start TV were OK. [%s]\n", + livetv->proginfo->pathname->str); + } + + } + + livetv->uri = + (GMythURI *) gmyth_backend_info_get_uri (livetv->backend_info); + + g_mutex_unlock (livetv->mutex); + + if (!gmyth_livetv_monitor_handler_start (livetv)) + { + res = FALSE; + gmyth_debug ("LiveTV MONITOR handler error on setup!"); + goto error; + } + + livetv->setup_done = TRUE; + + return res; + + error: + gmyth_debug ("[%s] ERROR running LiveTV setup.\n", __FUNCTION__); res = FALSE; - g_string_free( livetv->local_hostname, TRUE ); + g_string_free (livetv->local_hostname, TRUE); - if ( livetv->recorder != NULL ) { - g_object_unref (livetv->recorder); - livetv->recorder = NULL; - } + if (livetv->recorder != NULL) + { + g_object_unref (livetv->recorder); + livetv->recorder = NULL; + } - if ( livetv->tvchain != NULL ) { - g_object_unref (livetv->tvchain); - livetv->tvchain = NULL; - } + if (livetv->tvchain != NULL) + { + g_object_unref (livetv->tvchain); + livetv->tvchain = NULL; + } - if ( livetv->proginfo != NULL ) { - g_object_unref (livetv->proginfo); - livetv->proginfo = NULL; - } + if (livetv->proginfo != NULL) + { + g_object_unref (livetv->proginfo); + livetv->proginfo = NULL; + } - if ( livetv->monitor != NULL ) { - g_object_unref (livetv->monitor); - livetv->monitor = NULL; - } + if (livetv->monitor != NULL) + { + g_object_unref (livetv->monitor); + livetv->monitor = NULL; + } - return res; + return res; } @@ -613,10 +692,12 @@ * had been concluded succcesfully */ static gboolean -gmyth_livetv_setup_recorder ( GMythLiveTV *livetv, gint channel) +gmyth_livetv_setup_recorder (GMythLiveTV * livetv, gint channel) { - return gmyth_livetv_setup_recorder_channel_name ( livetv, ( channel != -1 ) ? - g_strdup_printf( "%d", channel ) : NULL ); + return gmyth_livetv_setup_recorder_channel_name (livetv, (channel != -1) ? + g_strdup_printf ("%d", + channel) : + NULL); } /** @@ -632,9 +713,9 @@ * had been concluded succcesfully */ gboolean -gmyth_livetv_channel_setup ( GMythLiveTV *livetv, gint channel ) +gmyth_livetv_channel_setup (GMythLiveTV * livetv, gint channel) { - return gmyth_livetv_setup_recorder ( livetv, channel ); + return gmyth_livetv_setup_recorder (livetv, channel); } /** @@ -650,9 +731,9 @@ * had been concluded succcesfully */ gboolean -gmyth_livetv_channel_name_setup ( GMythLiveTV *livetv, gchar* channel ) +gmyth_livetv_channel_name_setup (GMythLiveTV * livetv, gchar * channel) { - return gmyth_livetv_setup_recorder_channel_name ( livetv, channel ); + return gmyth_livetv_setup_recorder_channel_name (livetv, channel); } /** @@ -667,9 +748,9 @@ * had been concluded succcesfully */ gboolean -gmyth_livetv_setup ( GMythLiveTV *livetv ) +gmyth_livetv_setup (GMythLiveTV * livetv) { - return gmyth_livetv_setup_recorder ( livetv, -1 ); + return gmyth_livetv_setup_recorder (livetv, -1); } /** @@ -680,67 +761,81 @@ * @return true if the next program info could be got */ gboolean -gmyth_livetv_next_program_chain ( GMythLiveTV *livetv ) +gmyth_livetv_next_program_chain (GMythLiveTV * livetv) { - gboolean res = TRUE; - GMythProgramInfo *prog_info = NULL; - - if ( !livetv->setup_done ) - { - gmyth_debug ( "Call the setup function first!" ); - goto error; - } - - gmyth_debug( "Current ProgramInfo...\n" ); - prog_info = gmyth_recorder_get_current_program_info( livetv->recorder ); - - if ( prog_info != NULL ) - { - livetv->proginfo = prog_info; - } else { - gmyth_debug( "ProgramInfo equals to NULL!!! Getting the next program info..." ); - prog_info = gmyth_recorder_get_next_program_info( livetv->recorder, BROWSE_DIRECTION_RIGHT ); - livetv->proginfo = prog_info; - } - /* prints program info data text */ - gmyth_program_info_print( prog_info ); + gboolean res = TRUE; + GMythProgramInfo *prog_info = NULL; - if ( prog_info != NULL ) { - res = TRUE; - livetv->proginfo = prog_info; - gmyth_debug ("GMythLiveTV: All requests to backend to start TV were OK, program info changed."); - } else { - gmyth_debug ("[%s] LiveTV not successfully started on the next program chain.\n", __FUNCTION__ ); - goto error; - } - - livetv->setup_done = TRUE; + if (!livetv->setup_done) + { + gmyth_debug ("Call the setup function first!"); + goto error; + } - return res; + gmyth_debug ("Current ProgramInfo...\n"); + prog_info = gmyth_recorder_get_current_program_info (livetv->recorder); -error: - gmyth_debug( "ERROR running LiveTV setup.\n" ); + if (prog_info != NULL) + { + livetv->proginfo = prog_info; + } + else + { + gmyth_debug + ("ProgramInfo equals to NULL!!! Getting the next program info..."); + prog_info = + gmyth_recorder_get_next_program_info (livetv->recorder, + BROWSE_DIRECTION_RIGHT); + livetv->proginfo = prog_info; + } + /* prints program info data text */ + gmyth_program_info_print (prog_info); + + if (prog_info != NULL) + { + res = TRUE; + livetv->proginfo = prog_info; + gmyth_debug + ("GMythLiveTV: All requests to backend to start TV were OK, program info changed."); + } + else + { + gmyth_debug + ("[%s] LiveTV not successfully started on the next program chain.\n", + __FUNCTION__); + goto error; + } + + livetv->setup_done = TRUE; + + return res; + + error: + gmyth_debug ("ERROR running LiveTV setup.\n"); res = FALSE; - - g_string_free( livetv->local_hostname, TRUE ); - if ( livetv->recorder != NULL ) { - g_object_unref (livetv->recorder); - livetv->recorder = NULL; - } + g_string_free (livetv->local_hostname, TRUE); - if ( livetv->tvchain != NULL ) { - g_object_unref (livetv->tvchain); - livetv->tvchain = NULL; - } + if (livetv->recorder != NULL) + { + g_object_unref (livetv->recorder); + livetv->recorder = NULL; + } - if ( livetv->proginfo != NULL ) { - g_object_unref (livetv->proginfo); - livetv->proginfo = NULL; - } + if (livetv->tvchain != NULL) + { + g_object_unref (livetv->tvchain); + livetv->tvchain = NULL; + } - return res; + if (livetv->proginfo != NULL) + { + g_object_unref (livetv->proginfo); + livetv->proginfo = NULL; + } + + return res; } /** @@ -753,78 +848,91 @@ * data got from the actual program info. */ GMythFile * -gmyth_livetv_create_file_transfer( GMythLiveTV *livetv ) +gmyth_livetv_create_file_transfer (GMythLiveTV * livetv) { - //GMythURI* uri = NULL; - - if ( NULL == livetv ) - goto done; - - if ( !livetv->setup_done ) - { - gmyth_debug( "Error: You must do the LiveTV setup, just before generating the FileTransfer from LiveTV source!" ); - goto done; - } - - if ( livetv->proginfo != NULL ) - gmyth_debug( "URI path (from program info) = %s.\n", livetv->proginfo->pathname->str ); - else - gmyth_debug( "URI path (from URI) = %s.\n", livetv->uri->uri->str ); - - g_mutex_lock( livetv->mutex ); - - if ( livetv->file != NULL ) + //GMythURI* uri = NULL; + + if (NULL == livetv) + goto done; + + if (!livetv->setup_done) { - /*gmyth_file_transfer_close( livetv->file );*/ - g_object_unref( livetv->file ); + gmyth_debug + ("Error: You must do the LiveTV setup, just before generating the FileTransfer from LiveTV source!"); + goto done; + } + + if (livetv->proginfo != NULL) + gmyth_debug ("URI path (from program info) = %s.\n", + livetv->proginfo->pathname->str); + else + gmyth_debug ("URI path (from URI) = %s.\n", livetv->uri->uri->str); + + g_mutex_lock (livetv->mutex); + + if (livetv->file != NULL) + { + /*gmyth_file_transfer_close( livetv->file ); */ + g_object_unref (livetv->file); livetv->file = NULL; - } + } - if ( livetv->uri != NULL ) + if (livetv->uri != NULL) { - gmyth_debug( "URI is not NULL, creating from the ProgramInfo pathname... (%s)", livetv->proginfo->pathname->str ); - livetv->uri->path = g_string_erase(livetv->uri->path, 0, -1); - livetv->uri->path = g_string_new( g_strrstr( livetv->proginfo->pathname->str, "/" ) ); - } else { - gmyth_debug( "URI is NULL, creating from the ProgramInfo pathname... (%s)", livetv->proginfo->pathname->str ); - livetv->uri = gmyth_uri_new_with_value( livetv->proginfo->pathname->str ); + gmyth_debug + ("URI is not NULL, creating from the ProgramInfo pathname... (%s)", + livetv->proginfo->pathname->str); + livetv->uri->path = g_string_erase (livetv->uri->path, 0, -1); + livetv->uri->path = + g_string_new (g_strrstr (livetv->proginfo->pathname->str, "/")); } - - if ( NULL == livetv->uri ) - { - gmyth_debug( "Couldn't parse the URI to start LiveTV! [ uri = %s ]", livetv->proginfo->pathname->str ); - goto done; - } - - if ( gmyth_uri_is_local_file( livetv->uri ) ) - livetv->file = GMYTH_FILE( gmyth_file_local_new( livetv->backend_info ) ); else { - livetv->file = GMYTH_FILE( gmyth_file_transfer_new( livetv->backend_info ) ); + gmyth_debug + ("URI is NULL, creating from the ProgramInfo pathname... (%s)", + livetv->proginfo->pathname->str); + livetv->uri = + gmyth_uri_new_with_value (livetv->proginfo->pathname->str); + } + + if (NULL == livetv->uri) + { + gmyth_debug ("Couldn't parse the URI to start LiveTV! [ uri = %s ]", + livetv->proginfo->pathname->str); + goto done; + } + + if (gmyth_uri_is_local_file (livetv->uri)) + livetv->file = GMYTH_FILE (gmyth_file_local_new (livetv->backend_info)); + else + { + livetv->file = + GMYTH_FILE (gmyth_file_transfer_new (livetv->backend_info)); //gmyth_file_transfer_settimeout( GMYTH_FILE_TRANSFER(livetv->file), TRUE ); } - if ( NULL == livetv->file ) + if (NULL == livetv->file) { - gmyth_debug( "Error: couldn't create the FileTransfer from LiveTV source!" ); + gmyth_debug + ("Error: couldn't create the FileTransfer from LiveTV source!"); goto done; } - - g_object_ref( livetv->file ); - g_mutex_unlock( livetv->mutex ); + g_object_ref (livetv->file); -done: - /* - if ( uri != NULL ) - { - g_object_unref( uri ); - uri = NULL; - } - */ - - return livetv->file; - + g_mutex_unlock (livetv->mutex); + + done: + /* + if ( uri != NULL ) + { + g_object_unref( uri ); + uri = NULL; + } + */ + + return livetv->file; + } /** @@ -833,31 +941,37 @@ * @param live_tv the GMythLiveTV instance */ void -gmyth_livetv_stop_playing (GMythLiveTV *livetv) +gmyth_livetv_stop_playing (GMythLiveTV * livetv) { gmyth_debug ("Stopping the LiveTV...\n"); - if (livetv->is_livetv) { - if ( !gmyth_recorder_stop_livetv (livetv->recorder) ) { - gmyth_debug ("[%s] Error while stoping remote encoder", __FUNCTION__); - } - - if ( !gmyth_recorder_finish_recording(livetv->recorder) ) { - gmyth_debug ("[%s] Error while finishing recording on remote encoder", __FUNCTION__); - } - } + if (livetv->is_livetv) + { + if (!gmyth_recorder_stop_livetv (livetv->recorder)) + { + gmyth_debug ("[%s] Error while stoping remote encoder", + __FUNCTION__); + } + + if (!gmyth_recorder_finish_recording (livetv->recorder)) + { + gmyth_debug + ("[%s] Error while finishing recording on remote encoder", + __FUNCTION__); + } + } } gboolean -gmyth_livetv_is_playing (GMythLiveTV *livetv) +gmyth_livetv_is_playing (GMythLiveTV * livetv) { - return TRUE; + return TRUE; } void -gmyth_livetv_start_playing (GMythLiveTV *livetv) +gmyth_livetv_start_playing (GMythLiveTV * livetv) { - // TODO + // TODO } diff -r 76b9c97faada -r ad1457d65f74 gmyth/src/gmyth_livetv.h --- a/gmyth/src/gmyth_livetv.h Tue May 15 20:16:26 2007 +0100 +++ b/gmyth/src/gmyth_livetv.h Tue May 15 21:39:04 2007 +0100 @@ -8,22 +8,22 @@ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia. * @author Rosfran Lins Borges * - *//* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + *//* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ #ifndef GMYTH_LIVETV_H_ #define GMYTH_LIVETV_H_ @@ -39,67 +39,65 @@ #include "gmyth_backendinfo.h" G_BEGIN_DECLS - #define GMYTH_LIVETV_TYPE (gmyth_livetv_get_type ()) #define GMYTH_LIVETV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_LIVETV_TYPE, GMythLiveTV)) #define GMYTH_LIVETV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_LIVETV_TYPE, GMythLiveTVClass)) #define IS_GMYTH_LIVETV(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_LIVETV_TYPE)) #define IS_GMYTH_LIVETV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_LIVETV_TYPE)) #define GMYTH_LIVETV_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_LIVETV_TYPE, GMythLiveTVClass)) - -typedef struct _GMythLiveTV GMythLiveTV; -typedef struct _GMythLiveTVClass GMythLiveTVClass; +typedef struct _GMythLiveTV GMythLiveTV; +typedef struct _GMythLiveTVClass GMythLiveTVClass; struct _GMythLiveTVClass -{ - GObjectClass parent_class; + { + GObjectClass parent_class; - /* callbacks */ -}; + /* callbacks */ + }; struct _GMythLiveTV -{ - GObject parent; - - GMythSocket *socket; - - GString *local_hostname; - - GMythBackendInfo *backend_info; + { + GObject parent; - GMythRecorder *recorder; - GMythTVChain *tvchain; - GMythProgramInfo *proginfo; - - GMythFile *file; - - GMythMonitorHandler *monitor; - GMythURI *uri; + GMythSocket *socket; - gboolean is_livetv; - gboolean setup_done; - - GMutex *mutex; - gboolean disposed; -}; + GString *local_hostname; -GType gmyth_livetv_get_type (void); + GMythBackendInfo *backend_info; -GMythLiveTV* gmyth_livetv_new (GMythBackendInfo *backend_info); + GMythRecorder *recorder; + GMythTVChain *tvchain; + GMythProgramInfo *proginfo; -void gmyth_livetv_start_playing (GMythLiveTV *livetv); -void gmyth_livetv_stop_playing (GMythLiveTV *livetv); + GMythFile *file; -gboolean gmyth_livetv_setup (GMythLiveTV *livetv); -gboolean gmyth_livetv_channel_setup ( GMythLiveTV *livetv, gint channel); -gboolean gmyth_livetv_channel_name_setup ( GMythLiveTV *livetv, gchar* channel); -gboolean gmyth_livetv_next_program_chain ( GMythLiveTV *livetv ); + GMythMonitorHandler *monitor; + GMythURI *uri; -GMythFile* gmyth_livetv_create_file_transfer( GMythLiveTV *livetv ); + gboolean is_livetv; + gboolean setup_done; -gboolean gmyth_livetv_monitor_handler_start( GMythLiveTV *livetv ); -void gmyth_livetv_monitor_handler_stop( GMythLiveTV *livetv ); + GMutex *mutex; + gboolean disposed; + }; + +GType gmyth_livetv_get_type (void); + +GMythLiveTV *gmyth_livetv_new (GMythBackendInfo * backend_info); + +void gmyth_livetv_start_playing (GMythLiveTV * livetv); +void gmyth_livetv_stop_playing (GMythLiveTV * livetv); + +gboolean gmyth_livetv_setup (GMythLiveTV * livetv); +gboolean gmyth_livetv_channel_setup (GMythLiveTV * livetv, gint channel); +gboolean gmyth_livetv_channel_name_setup (GMythLiveTV * livetv, + gchar * channel); +gboolean gmyth_livetv_next_program_chain (GMythLiveTV * livetv); + +GMythFile *gmyth_livetv_create_file_transfer (GMythLiveTV * livetv); + +gboolean gmyth_livetv_monitor_handler_start (GMythLiveTV * livetv); +void gmyth_livetv_monitor_handler_stop (GMythLiveTV * livetv); G_END_DECLS - -#endif /*GMYTH_LIVETV_H_*/ +#endif /*GMYTH_LIVETV_H_ */ diff -r 76b9c97faada -r ad1457d65f74 gmyth/src/gmyth_monitor_handler.c --- a/gmyth/src/gmyth_monitor_handler.c Tue May 15 20:16:26 2007 +0100 +++ b/gmyth/src/gmyth_monitor_handler.c Tue May 15 21:39:04 2007 +0100 @@ -9,27 +9,27 @@ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia. * @author Rosfran Lins Borges * - *//* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * GStreamer MythTV plug-in properties: - * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv] - * - path (qurl - remote file to be opened) - * - port number * - */ + *//* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * GStreamer MythTV plug-in properties: + * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv] + * - path (qurl - remote file to be opened) + * - port number * + */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -49,7 +49,7 @@ #include "gmyth_monitor_handler.h" #include "gmyth_debug.h" - + #define GMYTHTV_QUERY_HEADER "QUERY_FILETRANSFER " #define GMYTHTV_VERSION 30 @@ -69,133 +69,135 @@ #define GMYTHTV_ENABLE_DEBUG 1 #endif -gboolean gmyth_monitor_handler_listener( GIOChannel *io_channel, - GIOCondition io_cond, gpointer data ); +gpointer gmyth_monitor_handler_listener (gpointer data); -static void gmyth_monitor_handler_default_listener( GMythMonitorHandler *monitor, gint msg_code, gchar* message ); +static void gmyth_monitor_handler_default_listener (GMythMonitorHandler * + monitor, gint msg_code, + gchar * message); -static void gmyth_monitor_handler_class_init (GMythMonitorHandlerClass *klass); -static void gmyth_monitor_handler_init (GMythMonitorHandler *object); +static void gmyth_monitor_handler_class_init (GMythMonitorHandlerClass * klass); +static void gmyth_monitor_handler_init (GMythMonitorHandler * object); -static void gmyth_monitor_handler_dispose (GObject *object); -static void gmyth_monitor_handler_finalize (GObject *object); +static void gmyth_monitor_handler_dispose (GObject * object); +static void gmyth_monitor_handler_finalize (GObject * object); -static gboolean gmyth_connect_to_backend_monitor (GMythMonitorHandler *monitor); +static gboolean gmyth_connect_to_backend_monitor (GMythMonitorHandler * + monitor); -static gboolean gmyth_monitor_handler_setup( GMythMonitorHandler *monitor, - GIOChannel *channel ); +static gboolean gmyth_monitor_handler_setup (GMythMonitorHandler * monitor, + GIOChannel * channel); -void gmyth_monitor_handler_close( GMythMonitorHandler *monitor ); +void gmyth_monitor_handler_close (GMythMonitorHandler * monitor); -G_DEFINE_TYPE(GMythMonitorHandler, gmyth_monitor_handler, G_TYPE_OBJECT) +G_DEFINE_TYPE (GMythMonitorHandler, gmyth_monitor_handler, G_TYPE_OBJECT) + static void + gmyth_monitor_handler_class_init (GMythMonitorHandlerClass * klass) +{ + GObjectClass *gobject_class; + GMythMonitorHandlerClass *gmonitor_class; -static void -gmyth_monitor_handler_class_init (GMythMonitorHandlerClass *klass) -{ - GObjectClass *gobject_class; - GMythMonitorHandlerClass *gmonitor_class; + gobject_class = (GObjectClass *) klass; + gmonitor_class = (GMythMonitorHandlerClass *) gobject_class; - gobject_class = (GObjectClass *) klass; - gmonitor_class = (GMythMonitorHandlerClass *) gobject_class; + gobject_class->dispose = gmyth_monitor_handler_dispose; + gobject_class->finalize = gmyth_monitor_handler_finalize; - gobject_class->dispose = gmyth_monitor_handler_dispose; - gobject_class->finalize = gmyth_monitor_handler_finalize; - - gmonitor_class->backend_events_handler_signal_id = - g_signal_new ("backend-events-handler", - G_TYPE_FROM_CLASS (gmonitor_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, - NULL, - NULL, - gmyth_marshal_VOID__INT_STRING, - G_TYPE_NONE, - 2, - G_TYPE_INT, - G_TYPE_STRING); - - gmonitor_class->backend_events_handler = gmyth_monitor_handler_default_listener; + gmonitor_class->backend_events_handler_signal_id = + g_signal_new ("backend-events-handler", + G_TYPE_FROM_CLASS (gmonitor_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | + G_SIGNAL_NO_HOOKS, 0, NULL, NULL, + gmyth_marshal_VOID__INT_STRING, G_TYPE_NONE, 2, + G_TYPE_INT, G_TYPE_STRING); + + gmonitor_class->backend_events_handler = + gmyth_monitor_handler_default_listener; } static void -gmyth_monitor_handler_init (GMythMonitorHandler *monitor) -{ - g_return_if_fail( monitor != NULL ); +gmyth_monitor_handler_init (GMythMonitorHandler * monitor) +{ + g_return_if_fail (monitor != NULL); - monitor->event_sock = NULL; - monitor->hostname = NULL; - monitor->port = 0; - monitor->actual_index = 0; - - monitor->allow_msgs_listener = FALSE; - - /* monitor->backend_msgs = g_hash_table_new( g_int_hash, g_int_equal ); */ - - /* it is used for signalizing the event socket consumer thread */ - monitor->mutex = g_mutex_new(); - - monitor->sid_io_watch = -1; - - monitor->gmyth_monitor_handler_listener = gmyth_monitor_handler_listener; + monitor->event_sock = NULL; + monitor->hostname = NULL; + monitor->port = 0; + monitor->actual_index = 0; + + monitor->allow_msgs_listener = FALSE; + + /* monitor->backend_msgs = g_hash_table_new( g_int_hash, g_int_equal ); */ + + /* it is used for signalizing the event socket consumer thread */ + monitor->mutex = g_mutex_new (); + + monitor->th = NULL; + + monitor->gmyth_monitor_handler_listener = gmyth_monitor_handler_listener; } static void -gmyth_monitor_handler_dispose (GObject *object) +gmyth_monitor_handler_dispose (GObject * object) { - GMythMonitorHandler *monitor = GMYTH_MONITOR_HANDLER (object); - gmyth_monitor_handler_close(monitor); + GMythMonitorHandler *monitor = GMYTH_MONITOR_HANDLER (object); + gmyth_monitor_handler_close (monitor); - monitor->allow_msgs_listener = FALSE; + monitor->allow_msgs_listener = FALSE; - if (monitor->sid_io_watch != -1) - { - g_source_remove (monitor->sid_io_watch); - } + if (monitor->th != NULL) + { + gboolean *ret = (gboolean*)g_thread_join( monitor->th ); + if ( *ret == FALSE ) + gmyth_debug ( "Error closing GThread listener socket!" ); + else + gmyth_debug ( "Closed GThread listener socket." ); + //g_object_unref( monitor->th ); + } /* mutex to control access to the event socket consumer thread */ - if ( monitor->mutex != NULL ) + if (monitor->mutex != NULL) { //g_mutex_unlock( monitor->mutex ); - g_mutex_free( monitor->mutex ); + g_mutex_free (monitor->mutex); monitor->mutex = NULL; } - - if ( monitor->event_sock != NULL ) + + if (monitor->event_sock != NULL) { - g_object_unref( monitor->event_sock ); - monitor->event_sock = NULL; + g_object_unref (monitor->event_sock); + monitor->event_sock = NULL; } - if ( monitor->hostname != NULL ) + if (monitor->hostname != NULL) { - g_free( monitor->hostname ); - monitor->hostname = NULL; + g_free (monitor->hostname); + monitor->hostname = NULL; } - if ( monitor->backend_msgs != NULL ) + if (monitor->backend_msgs != NULL) { - g_hash_table_destroy ( monitor->backend_msgs ); - monitor->backend_msgs = NULL; + g_hash_table_destroy (monitor->backend_msgs); + monitor->backend_msgs = NULL; } - + /* - if ( io_watcher_cond != NULL ) - { - g_cond_free( io_watcher_cond ); - io_watcher_cond = NULL; - } - */ - + if ( io_watcher_cond != NULL ) + { + g_cond_free( io_watcher_cond ); + io_watcher_cond = NULL; + } + */ + G_OBJECT_CLASS (gmyth_monitor_handler_parent_class)->dispose (object); } static void -gmyth_monitor_handler_finalize (GObject *object) +gmyth_monitor_handler_finalize (GObject * object) { - g_signal_handlers_destroy (object); + g_signal_handlers_destroy (object); - G_OBJECT_CLASS (gmyth_monitor_handler_parent_class)->finalize (object); + G_OBJECT_CLASS (gmyth_monitor_handler_parent_class)->finalize (object); } /** @@ -203,13 +205,14 @@ * * @return a new instance of the Monitor Handler. */ -GMythMonitorHandler* -gmyth_monitor_handler_new ( void ) +GMythMonitorHandler * +gmyth_monitor_handler_new (void) { - GMythMonitorHandler *monitor = GMYTH_MONITOR_HANDLER ( - g_object_new ( GMYTH_MONITOR_HANDLER_TYPE, FALSE ) ); + GMythMonitorHandler *monitor = + GMYTH_MONITOR_HANDLER (g_object_new + (GMYTH_MONITOR_HANDLER_TYPE, FALSE)); - return monitor; + return monitor; } /** @@ -220,16 +223,16 @@ * * @return true, if the access to IO Watcher was acquired. */ -static gboolean -myth_control_acquire_context( GMythMonitorHandler *monitor, gboolean do_wait ) +static gboolean +myth_control_acquire_context (GMythMonitorHandler * monitor, gboolean do_wait) { - - gboolean ret = TRUE; - - g_mutex_lock( monitor->mutex ); - + + gboolean ret = TRUE; + + g_mutex_lock (monitor->mutex); + return ret; - + } /** @@ -239,36 +242,36 @@ * * @return true, if the access to IO Watcher was released. */ -static gboolean -myth_control_release_context( GMythMonitorHandler *monitor ) +static gboolean +myth_control_release_context (GMythMonitorHandler * monitor) { - - gboolean ret = TRUE; - - g_mutex_unlock( monitor->mutex ); - + + gboolean ret = TRUE; + + g_mutex_unlock (monitor->mutex); + return ret; } void -gmyth_monitor_handler_close (GMythMonitorHandler *monitor) +gmyth_monitor_handler_close (GMythMonitorHandler * monitor) { - monitor->allow_msgs_listener = FALSE; + monitor->allow_msgs_listener = FALSE; -#if 0 - if ( monitor->monitor_th != NULL ) - { - g_thread_pool_free( monitor->monitor_th, TRUE, FALSE ); - //g_thread_exit( monitor->monitor_th ); - /*if ( monitor->monitor_th != NULL ) - g_object_unref( monitor->monitor_th );*/ - monitor->monitor_th = NULL; - } - - if ( monitor->event_sock != NULL ) - { - gmyth_socket_close_connection( monitor->event_sock ); - } +#if 0 + if (monitor->monitor_th != NULL) + { + g_thread_pool_free (monitor->monitor_th, TRUE, FALSE); + //g_thread_exit( monitor->monitor_th ); + /*if ( monitor->monitor_th != NULL ) + g_object_unref( monitor->monitor_th ); */ + monitor->monitor_th = NULL; + } + + if (monitor->event_sock != NULL) + { + gmyth_socket_close_connection (monitor->event_sock); + } #endif } @@ -284,34 +287,50 @@ * @return true, if the connection was successfully opened. */ gboolean -gmyth_monitor_handler_open (GMythMonitorHandler *monitor, const gchar *hostname, gint port) +gmyth_monitor_handler_open (GMythMonitorHandler * monitor, + const gchar * hostname, gint port) { - gboolean ret = TRUE; - - g_return_val_if_fail( hostname != NULL, FALSE ); + gboolean ret = TRUE; - if (monitor->hostname != NULL) { - g_free (monitor->hostname); - monitor->hostname = NULL; - } + g_return_val_if_fail (hostname != NULL, FALSE); - monitor->hostname = g_strdup (hostname); - monitor->port = port; + if (monitor->hostname != NULL) + { + g_free (monitor->hostname); + monitor->hostname = NULL; + } - gmyth_debug ("Monitor event socket --- hostname: %s, port %d\n", monitor->hostname, monitor->port); - - /* configure the event socket */ - if ( NULL == monitor->event_sock) { - if (!gmyth_connect_to_backend_monitor (monitor)) { - gmyth_debug( "Connection to backend failed (Event Socket)." ); - ret = FALSE; - } - else { - gmyth_debug("Remote monitor event socket already created.\n"); - } - } + monitor->hostname = g_strdup (hostname); + monitor->port = port; - return ret; + gmyth_debug ("Monitor event socket --- hostname: %s, port %d\n", + monitor->hostname, monitor->port); + + if ( NULL != monitor->event_sock) + { + g_object_unref( monitor->event_sock ); + monitor->event_sock = NULL; + } + + /* configure the event socket */ + if (NULL == monitor->event_sock) + { + if (!gmyth_connect_to_backend_monitor (monitor)) + { + gmyth_debug ("Connection to backend failed (Event Socket)!"); + ret = FALSE; + } + else + { + gmyth_debug ( "Remote monitor event socket had been succesfully created. (io_fd == %d)\n", + g_io_channel_unix_get_fd( monitor->event_sock->sd_io_ch ) ); + } + } else + { + gmyth_debug ("ASSERT ERROR: Remote monitor event socket is not NULL at the setup...\n"); + } + + return ret; } @@ -326,178 +345,213 @@ * @return The backend status message code ID. */ static gint -gmyth_monitor_handler_is_backend_message( GMythMonitorHandler *monitor, - GMythStringList* strlist, gchar **back_msg_action ) +gmyth_monitor_handler_is_backend_message (GMythMonitorHandler * monitor, + GMythStringList * strlist, + gchar ** back_msg_action) { - gint msg_type = GMYTH_BACKEND_NO_MESSAGE; - GString *back_msg = NULL; - - if ( gmyth_string_list_length(strlist) > 0 ) - { - - back_msg = gmyth_string_list_get_string( strlist, 0 ); - if ( back_msg != NULL && back_msg->str != NULL && - strstr( back_msg->str, "BACKEND" ) != NULL ) - { - gmyth_debug( "MONITOR HANDLER - Received backend message = %s", back_msg->str ); - *back_msg_action = gmyth_string_list_get_char_array( strlist, 1 ); - - if ( back_msg_action != NULL ) - { - - if ( g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "LIVETV_CHAIN" ) || - g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "RECORDING_LIST_CHANGE" ) || - g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "SCHEDULE_CHANGE" ) || - g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "LIVETV_WATCH" ) ) - { - gmyth_debug( "MONITOR: message type == GMYTH_BACKEND_PROGRAM_INFO_CHANGED, msg = %s", *back_msg_action ); - msg_type = GMYTH_BACKEND_PROGRAM_INFO_CHANGED; - } else if ( g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "DONE_RECORDING" ) ) { - gmyth_debug( "MONITOR: message type == GMYTH_BACKEND_DONE_RECORDING, msg = %s", *back_msg_action ); - msg_type = GMYTH_BACKEND_DONE_RECORDING; - } else if ( g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "QUIT" ) ) { - gmyth_debug( "MONITOR: message type == GMYTH_BACKEND_STOP_LIVETV, msg = %s", *back_msg_action ); - msg_type = GMYTH_BACKEND_STOP_LIVETV; - } - - /* g_hash_table_insert ( monitor->backend_msgs, - &(monitor->actual_index), *back_msg_action ); */ - - } /* if */ - - } /* if */ - - if ( back_msg != NULL ) - { - g_string_free( back_msg, TRUE ); - back_msg = NULL; - } - - } /* if - Does Monitor got any message from backend? */ - else { - *back_msg_action = g_strdup(""); - } - - return msg_type; + gint msg_type = GMYTH_BACKEND_NO_MESSAGE; + GString *back_msg = NULL; + + if (gmyth_string_list_length (strlist) > 0) + { + + back_msg = gmyth_string_list_get_string (strlist, 0); + if (back_msg != NULL && back_msg->str != NULL && + strstr (back_msg->str, "BACKEND") != NULL) + { + gmyth_debug ("MONITOR HANDLER - Received backend message = %s", + back_msg->str); + *back_msg_action = gmyth_string_list_get_char_array (strlist, 1); + + if (back_msg_action != NULL) + { + + if (g_strstr_len + (*back_msg_action, strlen (*back_msg_action), + "LIVETV_CHAIN") + || g_strstr_len (*back_msg_action, + strlen (*back_msg_action), + "RECORDING_LIST_CHANGE") + || g_strstr_len (*back_msg_action, + strlen (*back_msg_action), + "SCHEDULE_CHANGE") + || g_strstr_len (*back_msg_action, + strlen (*back_msg_action), "LIVETV_WATCH")) + { + gmyth_debug + ("MONITOR: message type == GMYTH_BACKEND_PROGRAM_INFO_CHANGED, msg = %s", + *back_msg_action); + msg_type = GMYTH_BACKEND_PROGRAM_INFO_CHANGED; + } + else if (g_strstr_len + (*back_msg_action, strlen (*back_msg_action), + "DONE_RECORDING")) + { + gmyth_debug + ("MONITOR: message type == GMYTH_BACKEND_DONE_RECORDING, msg = %s", + *back_msg_action); + msg_type = GMYTH_BACKEND_DONE_RECORDING; + } + else if (g_strstr_len + (*back_msg_action, strlen (*back_msg_action), "QUIT")) + { + gmyth_debug + ("MONITOR: message type == GMYTH_BACKEND_STOP_LIVETV, msg = %s", + *back_msg_action); + msg_type = GMYTH_BACKEND_STOP_LIVETV; + } + + /* g_hash_table_insert ( monitor->backend_msgs, + &(monitor->actual_index), *back_msg_action ); */ + + } /* if */ + + } /* if */ + + if (back_msg != NULL) + { + g_string_free (back_msg, TRUE); + back_msg = NULL; + } + + } /* if - Does Monitor got any message from backend? */ + else + { + *back_msg_action = g_strdup (""); + } + + return msg_type; } static void -gmyth_monitor_handler_default_listener( GMythMonitorHandler *monitor, gint msg_code, gchar* message ) +gmyth_monitor_handler_default_listener (GMythMonitorHandler * monitor, + gint msg_code, gchar * message) { - //assert( message!= NULL ); - gmyth_debug( "DEFAULT Signal handler ( msg = %s, code = %d )\n", - message, msg_code ); + //assert( message!= NULL ); + gmyth_debug ("DEFAULT Signal handler ( msg = %s, code = %d )\n", + message, msg_code); } static void -gmyth_monitor_handler_print( GString *str, gpointer ptr ) +gmyth_monitor_handler_print (GString * str, gpointer ptr) { - gmyth_debug( "Backend message event: %s --- ", str->str ); + gmyth_debug ("Backend message event: %s --- ", str->str); } /** * Opens connection the the Monitor socket on MythTV backend server, * where all status messages are notified to the client. * - * @param io_channel The GIOChannel instance to the Monitor connection. - * @param io_cond The GIOCondition describing the actual status of the IO Channel. * @param data Pointer to the GMythMonitorHandler. * - * @return true, if the data was successfully read. + * @return Pointer to a gboolean true value, if the data was + * successfully read. */ -gboolean -gmyth_monitor_handler_listener( GIOChannel *io_channel, GIOCondition io_cond, gpointer data ) +gpointer +gmyth_monitor_handler_listener (gpointer data) { - GMythMonitorHandler *monitor = (GMythMonitorHandler*)data; - guint recv = 0; - gboolean ret = TRUE; - gsize len = 0; - - static guint count = 0; + GMythMonitorHandler *monitor = (GMythMonitorHandler *) data; + guint recv = 0; + gboolean *ret = g_new0( gboolean, 1 ); + gsize len = 0; + GIOChannel *io_channel = monitor->event_sock->sd_io_ch; + GIOCondition io_cond = g_io_channel_get_buffer_condition( io_channel ); + static guint count = 0; - myth_control_acquire_context ( monitor, TRUE ); - - if ( ( io_cond & G_IO_HUP ) != 0 ) { - ret = FALSE; - goto clean_up; - } - - //GIOChannel *io_channel = monitor->event_sock->sd_io_ch; - //GIOCondition condition = g_io_channel_get_buffer_condition( io_channel ); - - GMythStringList *strlist = NULL; - - if ( NULL == io_channel ) { - gmyth_debug ("Monitor socket is NULL! (GIOChannel)"); - ret = FALSE; - goto clean_up; - } - - if (monitor->allow_msgs_listener) { - ++count; - - gmyth_debug ("%d - Listening on Monitor socket...!\n", count); - - do + *ret = TRUE; + + gmyth_debug ( "Entering MONITOR handler listener..." ); + + myth_control_acquire_context (monitor, TRUE); + + if ((io_cond & G_IO_HUP) != 0) { - - gint bytes_sent = 0; - - strlist = gmyth_string_list_new(); - - if ( monitor->event_sock != NULL ) - { - - len = gmyth_socket_read_stringlist( monitor->event_sock, strlist ); - - if ( ( len > 0 ) && strlist != NULL && gmyth_string_list_length( strlist ) > 0 ) - { - bytes_sent = gmyth_string_list_get_int( strlist, 0 ); // -1 on backend error - - gmyth_debug ( "[%s] MONITOR: received data buffer from IO event channel... %d strings gone!\n", - __FUNCTION__, len ); - - recv += len; - - /* debug purpose: prints out all the string list elements */ - g_list_foreach( strlist->glist, (GFunc)gmyth_monitor_handler_print, NULL ); - - gchar *back_msg_action = g_new0( gchar, 1 ); - gint msg_type = gmyth_monitor_handler_is_backend_message( monitor, strlist, - &back_msg_action ); - - if (monitor!=NULL) - g_signal_emit ( monitor, - GMYTH_MONITOR_HANDLER_GET_CLASS (monitor)->backend_events_handler_signal_id, - 0, /* details */ - msg_type, back_msg_action ); - - if (back_msg_action!= NULL) - g_free( back_msg_action ); - - } - - } - - if (strlist!=NULL) - { - g_object_unref( strlist ); - strlist = NULL; - } + *ret = FALSE; + goto clean_up; + } - io_cond = g_io_channel_get_buffer_condition (io_channel); + GMythStringList *strlist = NULL; - } while ( recv <= 0 && ( ( io_cond & G_IO_HUP ) == 0 ) ); - - gmyth_debug ("\tMONITOR EVENT: Read %d bytes\n", recv ); + if (NULL == io_channel) + { + gmyth_debug ("Monitor socket is NULL! (GIOChannel)"); + *ret = FALSE; + goto clean_up; + } - } /* main GThread while */ - -clean_up: - myth_control_release_context (monitor); - - return ret; + while (monitor->allow_msgs_listener) + { + ++count; + + gmyth_debug ("%d - Listening on Monitor socket...!\n", count); + + do + { + + gint bytes_sent = 0; + + strlist = gmyth_string_list_new (); + + if (monitor->event_sock != NULL) + { + + len = + gmyth_socket_read_stringlist (monitor->event_sock, strlist); + + if ((len > 0) && strlist != NULL + && gmyth_string_list_length (strlist) > 0) + { + bytes_sent = gmyth_string_list_get_int (strlist, 0); // -1 on backend error + + gmyth_debug + ("[%s] MONITOR: received data buffer from IO event channel... %d strings gone!\n", + __FUNCTION__, len); + + recv += len; + + /* debug purpose: prints out all the string list elements */ + g_list_foreach (strlist->glist, + (GFunc) gmyth_monitor_handler_print, NULL); + + gchar *back_msg_action = g_new0 (gchar, 1); + gint msg_type = + gmyth_monitor_handler_is_backend_message (monitor, + strlist, + &back_msg_action); + + if (monitor != NULL) + g_signal_emit (monitor, GMYTH_MONITOR_HANDLER_GET_CLASS (monitor)->backend_events_handler_signal_id, 0, /* details */ + msg_type, back_msg_action); + + if (back_msg_action != NULL) + g_free (back_msg_action); + + } + + } + + if (strlist != NULL) + { + g_object_unref (strlist); + strlist = NULL; + } + + io_cond = g_io_channel_get_buffer_condition (io_channel); + + } + while (recv <= 0 && ((io_cond & G_IO_HUP) == 0)); + + gmyth_debug ("\tMONITOR EVENT: Read %d bytes\n", recv); + + } /* main GThread while */ + + clean_up: + myth_control_release_context (monitor); + + g_thread_exit( ret ); + + return (gpointer)ret; } @@ -510,23 +564,24 @@ * @return true, if the socket was successfully opened. */ static gboolean -gmyth_connect_to_backend_monitor (GMythMonitorHandler *monitor) +gmyth_connect_to_backend_monitor (GMythMonitorHandler * monitor) { - gboolean ret = TRUE; + gboolean ret = TRUE; - monitor->event_sock = gmyth_socket_new(); + monitor->event_sock = gmyth_socket_new (); - /* Connects the socket, send Mythtv ANN Monitor and verify Mythtv protocol version */ - if (!gmyth_socket_connect_to_backend_events ( monitor->event_sock, - monitor->hostname, monitor->port, FALSE ) ) - { - g_object_unref (monitor->event_sock); - monitor->event_sock = NULL; - ret = FALSE; - } - - return ret; -} + /* Connects the socket, send Mythtv ANN Monitor and verify Mythtv protocol version */ + if (!gmyth_socket_connect_to_backend_events (monitor->event_sock, + monitor->hostname, + monitor->port, FALSE)) + { + g_object_unref (monitor->event_sock); + monitor->event_sock = NULL; + ret = FALSE; + } + + return ret; +} /** * Opens connection the the Monitor socket on MythTV backend server, @@ -539,33 +594,37 @@ * GMythMonitorHandler could be configured. */ static gboolean -gmyth_monitor_handler_setup( GMythMonitorHandler *monitor, GIOChannel *channel ) +gmyth_monitor_handler_setup (GMythMonitorHandler * monitor, + GIOChannel * channel) { - gboolean ret = TRUE; - - if ( channel != NULL ) { - - monitor->allow_msgs_listener = TRUE; - - monitor->sid_io_watch = -1; - - monitor->sid_io_watch = g_io_add_watch (channel, G_IO_IN | G_IO_HUP, - (GIOFunc)gmyth_monitor_handler_listener, monitor ); - } else { - ret = FALSE; - goto cleanup; - } + gboolean ret = TRUE; - if (monitor->sid_io_watch < 0){ - gmyth_debug( "[%s] Error adding watch listener function to the IO control channel!\n", __FUNCTION__ ); - ret = FALSE; - goto cleanup; - } - -cleanup: - - return ret; - + if (channel != NULL) + { + monitor->allow_msgs_listener = TRUE; + + monitor->th = g_thread_create ( (GThreadFunc)gmyth_monitor_handler_listener, + monitor, TRUE, NULL ); + gmyth_debug( "MONITOR GThread created!" ); + } + else + { + ret = FALSE; + goto cleanup; + } + + if (NULL == monitor->th) + { + gmyth_debug + ("[%s] Error adding GThread listener function to the IO control channel!\n", + __FUNCTION__); + ret = FALSE; + goto cleanup; + } + + cleanup: + + return ret; } /** @@ -575,24 +634,35 @@ * * @return true, if the MonitorHandler was started. */ -gboolean -gmyth_monitor_handler_start (GMythMonitorHandler *monitor) +gboolean +gmyth_monitor_handler_start (GMythMonitorHandler * monitor) { gboolean ret = TRUE; - - ret = gmyth_monitor_handler_setup( monitor, monitor->event_sock->sd_io_ch ); - if ( ret ) { - gmyth_debug ( "\n[%s]\tOK! Starting listener on the MONITOR event socket...[thread location = %p]\n", - __FUNCTION__, g_thread_self( ) ); - ret = TRUE; - } else { - gmyth_debug ( "\n[%s]\tERROR! Coudn't start listener on the MONITOR event socket...[thread location = %p]\n", - __FUNCTION__, g_thread_self( ) ); - ret = FALSE; + + if ( !( ret = g_thread_supported ()) ) + { + gmyth_debug( "Thread system wasn't initialized, starting NOW!!!" ); + g_thread_init (NULL); } - gmyth_debug( "[%s] Watch listener function over the IO control channel? %s!!!\n", - __FUNCTION__, ( ret == TRUE ? "YES" : "NO" ) ); - + ret = gmyth_monitor_handler_setup (monitor, monitor->event_sock->sd_io_ch); + if (ret) + { + gmyth_debug + ("\n[%s]\tOK! Starting listener on the MONITOR event socket...[thread location = %p]\n", + __FUNCTION__, g_thread_self ()); + } + else + { + gmyth_debug + ("\n[%s]\tERROR! Coudn't start listener on the MONITOR event socket...[thread location = %p]\n", + __FUNCTION__, g_thread_self ()); + ret = FALSE; + } + + gmyth_debug + ("[%s] Watch listener function over the IO control channel? %s!!!\n", + __FUNCTION__, (ret == TRUE ? "YES" : "NO")); + return ret; } diff -r 76b9c97faada -r ad1457d65f74 gmyth/src/gmyth_monitor_handler.h --- a/gmyth/src/gmyth_monitor_handler.h Tue May 15 20:16:26 2007 +0100 +++ b/gmyth/src/gmyth_monitor_handler.h Tue May 15 21:39:04 2007 +0100 @@ -10,23 +10,23 @@ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia. * @author Rosfran Lins Borges * - *//* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - + *//* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + #ifndef __GMYTH_MONITOR_HANDLER_H__ #define __GMYTH_MONITOR_HANDLER_H__ @@ -44,76 +44,74 @@ #include "gmyth_uri.h" G_BEGIN_DECLS - #define GMYTH_MONITOR_HANDLER_TYPE (gmyth_monitor_handler_get_type ()) #define GMYTH_MONITOR_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandler)) #define GMYTH_MONITOR_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandlerClass)) #define IS_GMYTH_MONITOR_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_MONITOR_HANDLER_TYPE)) #define IS_GMYTH_MONITOR_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_MONITOR_HANDLER_TYPE)) #define GMYTH_MONITOR_HANDLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_MONITOR_HANDLER_TYPE, GMythMonitorHandlerClass)) +#define GMYTHTV_MONITOR_HANDLER_READ_ERROR -314 + enum + { + GMYTH_BACKEND_NO_MESSAGE = 0, + GMYTH_BACKEND_PROGRAM_INFO_CHANGED, + GMYTH_BACKEND_DONE_RECORDING, + GMYTH_BACKEND_STOP_LIVETV + }; -#define GMYTHTV_MONITOR_HANDLER_READ_ERROR -314 - -enum { - GMYTH_BACKEND_NO_MESSAGE = 0, - GMYTH_BACKEND_PROGRAM_INFO_CHANGED, - GMYTH_BACKEND_DONE_RECORDING, - GMYTH_BACKEND_STOP_LIVETV -}; - -typedef struct _GMythMonitorHandler GMythMonitorHandler; -typedef struct _GMythMonitorHandlerClass GMythMonitorHandlerClass; +typedef struct _GMythMonitorHandler GMythMonitorHandler; +typedef struct _GMythMonitorHandlerClass GMythMonitorHandlerClass; struct _GMythMonitorHandlerClass -{ - GObjectClass parent_class; + { + GObjectClass parent_class; - /* callbacks */ - guint backend_events_handler_signal_id; + /* callbacks */ + guint backend_events_handler_signal_id; - /* signal default handlers */ - void (*backend_events_handler) (GMythMonitorHandler *monitor, gint msg_code, gchar* message ); -}; + /* signal default handlers */ + void (*backend_events_handler) (GMythMonitorHandler * monitor, + gint msg_code, gchar * message); + }; struct _GMythMonitorHandler -{ - GObject parent; + { + GObject parent; - /* MythTV version number */ - gint mythtv_version; + /* MythTV version number */ + gint mythtv_version; - /* socket descriptors */ - GMythSocket *event_sock; + /* socket descriptors */ + GMythSocket *event_sock; + + gpointer (*gmyth_monitor_handler_listener) (gpointer data); + + gchar *hostname; + gint port; + + gint64 actual_index; + + gboolean allow_msgs_listener; + + /* stores the messages coming from the backend */ + GHashTable *backend_msgs; + + GMutex *mutex; - gboolean (*gmyth_monitor_handler_listener) ( GIOChannel *io_channel, - GIOCondition io_cond, gpointer data ); - - gchar *hostname; - gint port; - - gint64 actual_index; - - gboolean allow_msgs_listener; - - /* stores the messages coming from the backend */ - GHashTable *backend_msgs; - - GMutex *mutex; - - guint sid_io_watch; + GThread *th; -}; + }; -GType gmyth_monitor_handler_get_type (void); +GType gmyth_monitor_handler_get_type (void); -GMythMonitorHandler* gmyth_monitor_handler_new ( void ); +GMythMonitorHandler *gmyth_monitor_handler_new (void); -gboolean gmyth_monitor_handler_open (GMythMonitorHandler *monitor, const gchar *hostname, gint port); +gboolean gmyth_monitor_handler_open (GMythMonitorHandler * monitor, + const gchar * hostname, gint port); -gboolean gmyth_monitor_handler_start (GMythMonitorHandler *monitor); +gboolean gmyth_monitor_handler_start (GMythMonitorHandler * monitor); -void gmyth_monitor_handler_close (GMythMonitorHandler *monitor); +void gmyth_monitor_handler_close (GMythMonitorHandler * monitor); G_END_DECLS - #endif /* __GMYTH_MONITOR_HANDLER_H__ */