gmyth/src/gmyth_monitor_handler.c
author rosfran
Tue Dec 19 23:28:32 2006 +0000 (2006-12-19)
branchtrunk
changeset 232 00b55a87f1ba
parent 230 1c6948679ddf
child 233 1cf29cf20fb3
permissions -rw-r--r--
[svn r233] Improved GObject' signals emition, following some tips from Kapeta.
rosfran@175
     1
/**
rosfran@175
     2
 * GMyth Library
rosfran@175
     3
 *
rosfran@175
     4
 * @file gmyth/gmyth_monitor_handler.c
rosfran@175
     5
 * 
rosfran@175
     6
 * @brief <p> GMythMonitorHandler deals with the streaming media events remote/local
rosfran@175
     7
 * that are sent to the MythTV frontend.
rosfran@175
     8
 *
rosfran@175
     9
 * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
rosfran@175
    10
 * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
rosfran@175
    11
 *
rosfran@175
    12
 *//*
rosfran@175
    13
 * 
rosfran@175
    14
 * This program is free software; you can redistribute it and/or modify
rosfran@175
    15
 * it under the terms of the GNU Lesser General Public License as published by
rosfran@175
    16
 * the Free Software Foundation; either version 2 of the License, or
rosfran@175
    17
 * (at your option) any later version.
rosfran@175
    18
 *
rosfran@175
    19
 * This program is distributed in the hope that it will be useful,
rosfran@175
    20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
rosfran@175
    21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
rosfran@175
    22
 * GNU General Public License for more details.
rosfran@175
    23
 *
rosfran@175
    24
 * You should have received a copy of the GNU Lesser General Public License
rosfran@175
    25
 * along with this program; if not, write to the Free Software
rosfran@175
    26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
rosfran@175
    27
 *
rosfran@175
    28
 * GStreamer MythTV plug-in properties:
rosfran@175
    29
 * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
rosfran@175
    30
 * - path (qurl - remote file to be opened)
rosfran@175
    31
 * - port number *   
rosfran@175
    32
 */
rosfran@175
    33
rosfran@212
    34
#ifdef HAVE_CONFIG_H
rosfran@212
    35
#include "config.h"
rosfran@212
    36
#endif
rosfran@212
    37
rosfran@175
    38
#include <unistd.h>
rosfran@175
    39
#include <glib.h>
rosfran@175
    40
#include <arpa/inet.h>
rosfran@175
    41
#include <sys/types.h>
rosfran@175
    42
#include <sys/socket.h>
rosfran@175
    43
#include <netdb.h>
rosfran@175
    44
#include <errno.h>
rosfran@175
    45
#include <stdlib.h>
rosfran@175
    46
#include <assert.h>
rosfran@175
    47
leo_sobral@213
    48
#include "gmyth_marshal.h"
rosfran@216
    49
leo_sobral@213
    50
#include "gmyth_monitor_handler.h"
rosfran@216
    51
rosfran@216
    52
#include "gmyth.h"
leo_sobral@213
    53
 
rosfran@175
    54
#define GMYTHTV_QUERY_HEADER		"QUERY_FILETRANSFER "
rosfran@175
    55
rosfran@175
    56
#define GMYTHTV_VERSION							30
rosfran@175
    57
rosfran@175
    58
#define GMYTHTV_TRANSFER_MAX_WAITS	700
rosfran@175
    59
rosfran@175
    60
#define GMYTHTV_BUFFER_SIZE					8*1024
rosfran@175
    61
rosfran@175
    62
#ifdef GMYTHTV_ENABLE_DEBUG
rosfran@175
    63
#define GMYTHTV_ENABLE_DEBUG				1
rosfran@175
    64
#else
rosfran@175
    65
#undef GMYTHTV_ENABLE_DEBUG
rosfran@175
    66
#endif
rosfran@175
    67
rosfran@175
    68
/* this NDEBUG is to maintain compatibility with GMyth library */
rosfran@175
    69
#ifndef NDEBUG
rosfran@175
    70
#define GMYTHTV_ENABLE_DEBUG				1
rosfran@175
    71
#endif
rosfran@175
    72
rosfran@229
    73
//GMainContext *io_watcher_context = NULL;
rosfran@192
    74
rosfran@220
    75
//GThread *monitor_th = NULL;
rosfran@175
    76
rosfran@192
    77
//static gboolean* myth_control_sock_listener( GIOChannel *io_channel );
rosfran@220
    78
//static gboolean gmyth_monitor_handler_listener( GIOChannel *io_channel, 
rosfran@220
    79
//						GIOCondition condition, gpointer data );
rosfran@198
    80
rosfran@232
    81
//gboolean* gmyth_monitor_handler_listener( GMythMonitorHandler *monitor );
rosfran@220
    82
rosfran@232
    83
void gmyth_monitor_handler_listener( GMythMonitorHandler *monitor, gpointer user_data );
rosfran@232
    84
rosfran@232
    85
static void gmyth_monitor_handler_default_listener( GMythMonitorHandler *monitor, gint msg_code, gchar* message );
rosfran@175
    86
rosfran@175
    87
static GMutex*				mutex 					 = NULL;
rosfran@175
    88
rosfran@229
    89
//static GCond*					io_watcher_cond  = NULL;
rosfran@175
    90
rosfran@175
    91
static void gmyth_monitor_handler_class_init          (GMythMonitorHandlerClass *klass);
rosfran@175
    92
static void gmyth_monitor_handler_init                (GMythMonitorHandler *object);
rosfran@175
    93
rosfran@175
    94
static void gmyth_monitor_handler_dispose  (GObject *object);
rosfran@175
    95
static void gmyth_monitor_handler_finalize (GObject *object);
rosfran@175
    96
rosfran@175
    97
static gboolean gmyth_connect_to_backend_monitor (GMythMonitorHandler *monitor);
rosfran@175
    98
rosfran@175
    99
void gmyth_monitor_handler_close( GMythMonitorHandler *monitor );
rosfran@175
   100
rosfran@175
   101
G_DEFINE_TYPE(GMythMonitorHandler, gmyth_monitor_handler, G_TYPE_OBJECT)
rosfran@175
   102
rosfran@175
   103
static void
rosfran@175
   104
gmyth_monitor_handler_class_init (GMythMonitorHandlerClass *klass)
rosfran@175
   105
{
rosfran@175
   106
  GObjectClass *gobject_class;
rosfran@203
   107
  GMythMonitorHandlerClass *gmonitor_class;
rosfran@175
   108
rosfran@175
   109
  gobject_class = (GObjectClass *) klass;
rosfran@203
   110
  gmonitor_class = (GMythMonitorHandlerClass *) gobject_class;
rosfran@175
   111
rosfran@175
   112
  gobject_class->dispose  = gmyth_monitor_handler_dispose;
rosfran@175
   113
  gobject_class->finalize = gmyth_monitor_handler_finalize;
rosfran@203
   114
  
rosfran@203
   115
	gmonitor_class->backend_events_handler_signal_id = 
rosfran@212
   116
		  g_signal_new ("backend-events-handler",
rosfran@212
   117
		                 G_TYPE_FROM_CLASS (gmonitor_class),
rosfran@212
   118
		                 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
rosfran@212
   119
		                 0,
rosfran@216
   120
										 NULL,
rosfran@216
   121
										 NULL,
rosfran@232
   122
										 gmyth_marshal_VOID__INT_STRING,
rosfran@216
   123
										 G_TYPE_NONE,
rosfran@232
   124
										 2,
rosfran@216
   125
										 G_TYPE_INT,
rosfran@232
   126
										 G_TYPE_STRING);
rosfran@216
   127
										 
rosfran@216
   128
	gmonitor_class->backend_events_handler = gmyth_monitor_handler_default_listener;
rosfran@203
   129
rosfran@175
   130
}
rosfran@175
   131
rosfran@175
   132
static void
rosfran@175
   133
gmyth_monitor_handler_init (GMythMonitorHandler *monitor)
rosfran@175
   134
{ 
rosfran@175
   135
  g_return_if_fail( monitor != NULL );
rosfran@175
   136
rosfran@175
   137
  monitor->event_sock = NULL;
rosfran@175
   138
  monitor->hostname = NULL;
rosfran@175
   139
  monitor->port = 0;
rosfran@175
   140
  monitor->actual_index = 0;
rosfran@175
   141
  
rosfran@229
   142
  //monitor->backend_msgs = g_hash_table_new( g_int_hash, g_int_equal );
rosfran@175
   143
    
rosfran@175
   144
  /* it is used for signalizing the event socket consumer thread */
rosfran@229
   145
  //io_watcher_cond = g_cond_new();
rosfran@175
   146
  
rosfran@175
   147
  /* mutex to control access to the event socket consumer thread */
rosfran@229
   148
  //mutex = g_mutex_new();
rosfran@220
   149
  
rosfran@220
   150
  monitor->monitor_th = NULL;
rosfran@220
   151
  
rosfran@220
   152
  monitor->gmyth_monitor_handler_listener = gmyth_monitor_handler_listener;
rosfran@175
   153
}
rosfran@175
   154
rosfran@175
   155
static void
rosfran@175
   156
gmyth_monitor_handler_dispose  (GObject *object)
rosfran@175
   157
{
rosfran@192
   158
	
rosfran@192
   159
	GMythMonitorHandler *monitor = GMYTH_MONITOR_HANDLER (object);
rosfran@192
   160
	
rosfran@220
   161
	if ( monitor->monitor_th != NULL )  
rosfran@220
   162
  {
rosfran@232
   163
  	g_thread_pool_free( monitor->monitor_th, TRUE, FALSE );
rosfran@232
   164
  	/*
rosfran@220
   165
  	g_thread_exit( monitor->monitor_th );
rosfran@228
   166
  	if ( monitor->monitor_th != NULL )
rosfran@228
   167
  		g_object_unref( monitor->monitor_th );
rosfran@232
   168
  	*/
rosfran@220
   169
  	monitor->monitor_th = NULL;
rosfran@220
   170
  }
rosfran@220
   171
	
rosfran@192
   172
  if ( monitor->event_sock != NULL )  
rosfran@192
   173
  {
rosfran@192
   174
  	g_object_unref( monitor->event_sock );
rosfran@192
   175
  	monitor->event_sock = NULL;
rosfran@192
   176
  }
rosfran@192
   177
  
rosfran@192
   178
  if ( monitor->hostname != NULL )  
rosfran@192
   179
  {
rosfran@192
   180
  	g_free( monitor->hostname );
rosfran@192
   181
  	monitor->hostname = NULL;
rosfran@192
   182
  }
rosfran@192
   183
rosfran@232
   184
  if ( monitor->backend_msgs != NULL )
rosfran@192
   185
  {
renatofilho@202
   186
  	g_hash_table_destroy ( monitor->backend_msgs );
rosfran@192
   187
  	monitor->backend_msgs = NULL;
rosfran@192
   188
  }
rosfran@192
   189
  
rosfran@192
   190
  if ( mutex != NULL )  
rosfran@192
   191
  {
rosfran@192
   192
  	g_mutex_free( mutex );
rosfran@192
   193
  	mutex = NULL;
rosfran@192
   194
  }
rosfran@192
   195
  
rosfran@229
   196
  /*
rosfran@192
   197
  if ( io_watcher_cond != NULL )  
rosfran@192
   198
  {
rosfran@192
   199
  	g_cond_free( io_watcher_cond );
rosfran@192
   200
  	io_watcher_cond = NULL;
rosfran@192
   201
  }
rosfran@229
   202
  */
rosfran@192
   203
  
rosfran@175
   204
  G_OBJECT_CLASS (gmyth_monitor_handler_parent_class)->dispose (object);
rosfran@175
   205
}
rosfran@175
   206
rosfran@175
   207
static void
rosfran@175
   208
gmyth_monitor_handler_finalize (GObject *object)
rosfran@175
   209
{
rosfran@175
   210
  g_signal_handlers_destroy (object);
rosfran@175
   211
rosfran@175
   212
  G_OBJECT_CLASS (gmyth_monitor_handler_parent_class)->finalize (object);
rosfran@175
   213
}
rosfran@175
   214
rosfran@175
   215
// fixme: do we need the card_id????
rosfran@175
   216
GMythMonitorHandler*
rosfran@216
   217
gmyth_monitor_handler_new ( void )
rosfran@175
   218
{
rosfran@216
   219
  GMythMonitorHandler *monitor = GMYTH_MONITOR_HANDLER ( g_object_new ( GMYTH_MONITOR_HANDLER_TYPE, 
rosfran@216
   220
  					FALSE ) );
rosfran@216
   221
				
rosfran@175
   222
  return monitor;
rosfran@175
   223
}
rosfran@175
   224
rosfran@220
   225
static gboolean 
rosfran@220
   226
myth_control_acquire_context( gboolean do_wait ) 
rosfran@220
   227
{
rosfran@220
   228
	
rosfran@220
   229
	gboolean ret = TRUE;	
rosfran@220
   230
	//guint max_iter = 50;
rosfran@220
   231
	
rosfran@220
   232
	//g_mutex_lock( mutex );
rosfran@220
   233
	
rosfran@220
   234
  //while ( !has_io_access ) 
rosfran@220
   235
  //	g_cond_wait( io_watcher_cond, mutex );
rosfran@220
   236
  	
rosfran@220
   237
  //has_io_access = FALSE;
rosfran@220
   238
  /*
rosfran@220
   239
  if ( do_wait ) {
rosfran@220
   240
  	while ( --max_iter > 0 && !g_main_context_wait( io_watcher_context, io_watcher_cond, mutex ) )
rosfran@220
   241
  		ret = FALSE;
rosfran@220
   242
  } else if ( !g_main_context_acquire( io_watcher_context ) )
rosfran@220
   243
  	ret = FALSE;
rosfran@220
   244
  */
rosfran@220
   245
  	
rosfran@220
   246
  //g_static_mutex_lock( &st_mutex );
rosfran@220
   247
  
rosfran@220
   248
  return ret;
rosfran@220
   249
  
rosfran@220
   250
}
rosfran@220
   251
rosfran@220
   252
static gboolean 
rosfran@220
   253
myth_control_release_context( ) 
rosfran@220
   254
{
rosfran@220
   255
	
rosfran@220
   256
	gboolean ret = TRUE;
rosfran@220
   257
    
rosfran@220
   258
  //g_static_mutex_unlock( &st_mutex );
rosfran@220
   259
  
rosfran@220
   260
	//g_main_context_release( io_watcher_context );
rosfran@220
   261
  
rosfran@220
   262
  //g_main_context_wakeup( io_watcher_context );
rosfran@220
   263
  
rosfran@220
   264
  //has_io_access = TRUE;
rosfran@220
   265
rosfran@220
   266
  //g_cond_broadcast( io_watcher_cond );
rosfran@220
   267
  
rosfran@220
   268
  //g_mutex_unlock( mutex );  
rosfran@220
   269
 
rosfran@220
   270
  return ret;
rosfran@220
   271
  
rosfran@220
   272
}
rosfran@220
   273
rosfran@175
   274
gboolean
rosfran@229
   275
gmyth_monitor_handler_open (GMythMonitorHandler *monitor, const gchar *hostname, gint port)
rosfran@175
   276
{
rosfran@175
   277
  gboolean ret = TRUE;
rosfran@229
   278
  
rosfran@229
   279
  g_return_val_if_fail( hostname != NULL, FALSE );
rosfran@175
   280
rosfran@175
   281
  if (monitor->hostname != NULL) {
rosfran@175
   282
    g_free (monitor->hostname);
rosfran@175
   283
    monitor->hostname = NULL;
rosfran@175
   284
  }
rosfran@175
   285
rosfran@175
   286
  monitor->hostname = g_strdup( hostname );
rosfran@175
   287
  monitor->port = port;
rosfran@175
   288
rosfran@175
   289
  gmyth_debug ("Monitor event socket --- hostname: %s, port %d\n", monitor->hostname, monitor->port);
rosfran@175
   290
  
rosfran@175
   291
  /* configure the event socket */
rosfran@225
   292
  if ( NULL == monitor->event_sock ) { 
rosfran@175
   293
    if (!gmyth_connect_to_backend_monitor (monitor)) {
rosfran@175
   294
      g_printerr( "Connection to backend failed (Event Socket).\n" );
rosfran@175
   295
      ret = FALSE;
rosfran@175
   296
    }
rosfran@175
   297
  } else {
rosfran@175
   298
    g_warning("Remote monitor event socket already created.\n");
rosfran@175
   299
  }
rosfran@175
   300
rosfran@175
   301
  return ret;
rosfran@175
   302
rosfran@175
   303
}
rosfran@175
   304
rosfran@212
   305
static gint
rosfran@212
   306
gmyth_monitor_handler_is_backend_message( GMythMonitorHandler *monitor,
rosfran@212
   307
                        GMythStringList* strlist, gchar **back_msg_action )
rosfran@212
   308
{
rosfran@216
   309
	gint msg_type = GMYTH_BACKEND_NO_MESSAGE;
rosfran@216
   310
	GString *back_msg = NULL;
rosfran@216
   311
	
rosfran@216
   312
	back_msg = gmyth_string_list_get_string( strlist, 0 );
rosfran@216
   313
	if ( back_msg != NULL && back_msg->str != NULL &&
rosfran@216
   314
	                                strstr( back_msg->str, "BACKEND" ) != NULL )
rosfran@216
   315
	{
rosfran@216
   316
	  if ( monitor->backend_msgs != NULL )
rosfran@216
   317
	  {
rosfran@216
   318
	  	*back_msg_action = gmyth_string_list_get_char_array( strlist, 1 );	        	
rosfran@216
   319
	  	
rosfran@216
   320
	  	if ( back_msg_action != NULL )
rosfran@216
   321
	  	{	        	
rosfran@216
   322
	  	
rosfran@216
   323
	    	if ( g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "LIVETV_CHAIN" ) ||
rosfran@216
   324
	    			g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "RECORDING_LIST_CHANGE" ) ||
rosfran@216
   325
	    			g_strstr_len( *back_msg_action, strlen( *back_msg_action ), "LIVETV_WATCH" ) )
rosfran@232
   326
	    	{
rosfran@232
   327
	    		gmyth_debug( "MONITOR: message type == GMYTH_BACKEND_PROGRAM_INFO_CHANGED, msg = %s", *back_msg_action );
rosfran@216
   328
	    		msg_type = GMYTH_BACKEND_PROGRAM_INFO_CHANGED;
rosfran@216
   329
	    	}  	
rosfran@216
   330
	
rosfran@216
   331
	      //g_hash_table_insert ( monitor->backend_msgs,
rosfran@216
   332
	      //                       &(monitor->actual_index), *back_msg_action );
rosfran@216
   333
	                              
rosfran@216
   334
	  	} // if
rosfran@216
   335
	    
rosfran@216
   336
	  } // if
rosfran@216
   337
	}
rosfran@216
   338
	
rosfran@216
   339
	if ( back_msg != NULL )
rosfran@216
   340
	{
rosfran@216
   341
		g_string_free( back_msg, TRUE );
rosfran@216
   342
		back_msg = NULL;        	
rosfran@216
   343
	}
rosfran@216
   344
	
rosfran@216
   345
	return msg_type;
rosfran@212
   346
rosfran@212
   347
}
rosfran@212
   348
rosfran@212
   349
static void
rosfran@232
   350
gmyth_monitor_handler_default_listener( GMythMonitorHandler *monitor, gint msg_code, gchar* message )
rosfran@212
   351
{
rosfran@212
   352
	//assert( message!= NULL );  
rosfran@232
   353
	gmyth_debug( "DEFAULT Signal handler ( msg = %s, code = %d )\n", 
rosfran@232
   354
				message, msg_code );
rosfran@212
   355
}
rosfran@212
   356
rosfran@198
   357
static void
rosfran@199
   358
gmyth_monitor_handler_print( GString *str, gpointer ptr )
rosfran@199
   359
{
rosfran@212
   360
	gmyth_debug( "Backend message event: %s --- ", str->str );
rosfran@199
   361
}
rosfran@199
   362
rosfran@220
   363
//static void
rosfran@220
   364
//gmyth_monitor_handler_listener (GMythMonitorHandler *monitor, gpointer user_data)
rosfran@220
   365
//static gboolean
rosfran@220
   366
//gmyth_monitor_handler_listener( GIOChannel *io_channel, GIOCondition condition, gpointer data )
rosfran@232
   367
//gboolean* gmyth_monitor_handler_listener( GMythMonitorHandler *monitor )
rosfran@232
   368
void
rosfran@232
   369
gmyth_monitor_handler_listener (GMythMonitorHandler *monitor, gpointer user_data)
rosfran@175
   370
{
rosfran@220
   371
	//GMythMonitorHandler *monitor = (GMythMonitorHandler*)data; 
rosfran@175
   372
  GIOStatus io_status;
rosfran@199
   373
  GIOCondition io_cond;  
rosfran@175
   374
  guint recv = 0;
rosfran@212
   375
  gboolean *ret = g_new0( gboolean, 1 );
rosfran@198
   376
  *ret = TRUE;
rosfran@198
   377
  //gboolean ret = TRUE;
rosfran@175
   378
  gsize len = 0;
rosfran@175
   379
  
rosfran@199
   380
  static guint count = 0;
rosfran@198
   381
  
rosfran@212
   382
  GIOChannel *io_channel = monitor->event_sock->sd_io_ch;
rosfran@203
   383
  //GIOCondition condition = g_io_channel_get_buffer_condition( io_channel );
rosfran@199
   384
  
rosfran@199
   385
  GMythStringList *strlist = NULL;
rosfran@198
   386
  
rosfran@175
   387
  //GMythMonitorHandler *monitor = (GMythMonitorHandler*)data;
rosfran@175
   388
  
rosfran@220
   389
  myth_control_acquire_context (TRUE);
rosfran@175
   390
  
rosfran@175
   391
  if ( io_channel == NULL ) {
rosfran@175
   392
  	g_debug ("Monitor socket is NULL!\n");
rosfran@198
   393
  	*ret = FALSE;
rosfran@175
   394
  	goto clean_up;
rosfran@175
   395
  }
rosfran@198
   396
    
rosfran@198
   397
  while (TRUE) {
rosfran@198
   398
  	++count;
rosfran@198
   399
  	
rosfran@198
   400
  	gmyth_debug ("%d - Listening on Monitor socket...!\n", count);
rosfran@175
   401
	
rosfran@199
   402
    do 
rosfran@199
   403
    {
rosfran@199
   404
    	
rosfran@199
   405
    	gint bytes_sent = 0;
rosfran@199
   406
    	
rosfran@199
   407
    	strlist = gmyth_string_list_new();
rosfran@220
   408
    	
rosfran@220
   409
    	if ( monitor->event_sock != NULL )
rosfran@220
   410
    	{
rosfran@220
   411
    		
rosfran@220
   412
	      len = gmyth_socket_read_stringlist( monitor->event_sock, strlist );
rosfran@199
   413
	      
rosfran@220
   414
		    if ( strlist != NULL && gmyth_string_list_length( strlist ) > 0 ) 
rosfran@220
   415
		    { 
rosfran@220
   416
			    bytes_sent = gmyth_string_list_get_int( strlist,  0 ); // -1 on backend error
rosfran@220
   417
	
rosfran@220
   418
		      gmyth_debug ( "[%s] MONITOR: received data buffer from IO event channel... %d strings gone!\n", 
rosfran@220
   419
		      		__FUNCTION__, len );
rosfran@220
   420
		      		
rosfran@220
   421
		      recv += len;
rosfran@220
   422
		      
rosfran@220
   423
		      /* debug purpose: prints out all the string list elements */
rosfran@220
   424
		      g_list_foreach( strlist->glist, (GFunc)gmyth_monitor_handler_print, NULL );
rosfran@220
   425
		      
rosfran@220
   426
		      gchar *back_msg_action = g_new0( gchar, 1 );
rosfran@220
   427
		      gint msg_type = gmyth_monitor_handler_is_backend_message( monitor, strlist, 
rosfran@220
   428
		      		&back_msg_action );
rosfran@220
   429
		      
rosfran@220
   430
	        g_signal_emit ( monitor,
rosfran@220
   431
	               GMYTH_MONITOR_HANDLER_GET_CLASS (monitor)->backend_events_handler_signal_id,
rosfran@220
   432
	               0, /* details */
rosfran@232
   433
	               msg_type, back_msg_action );
rosfran@220
   434
	               
rosfran@220
   435
	        if (back_msg_action!= NULL)
rosfran@220
   436
	        	g_free( back_msg_action );
rosfran@220
   437
		      
rosfran@220
   438
		    }
rosfran@220
   439
		    
rosfran@220
   440
    	}
rosfran@199
   441
	    
rosfran@199
   442
	    if (strlist!=NULL)
rosfran@199
   443
	    	g_object_unref( strlist );
rosfran@199
   444
      	
rosfran@199
   445
      io_cond = g_io_channel_get_buffer_condition( io_channel );
rosfran@199
   446
rosfran@220
   447
    } while ( recv <= 0 && ( io_cond & G_IO_IN ) != 0 );
rosfran@199
   448
    
rosfran@212
   449
    gmyth_debug ("[%s]\tMONITOR EVENT: Read %d bytes\n", __FUNCTION__, recv );
rosfran@203
   450
rosfran@175
   451
	  g_usleep( 300 );
rosfran@175
   452
	  
rosfran@203
   453
  } /* main GThread while */
rosfran@198
   454
  
rosfran@220
   455
  myth_control_release_context ();
rosfran@220
   456
  
rosfran@199
   457
  if ( io_status == G_IO_STATUS_ERROR ) {
rosfran@199
   458
    //gmyth_debug ("[%s] Error reading: %s\n", __FUNCTION__, error != NULL ? error->message : "" );
rosfran@199
   459
    gmyth_debug ("Error reading MONITOR event socket.\n");
rosfran@198
   460
   	*ret = FALSE;
rosfran@175
   461
   	goto clean_up;   	
rosfran@175
   462
  }
rosfran@175
   463
  
rosfran@175
   464
clean_up:
rosfran@198
   465
rosfran@199
   466
  if (strlist!=NULL)
rosfran@199
   467
  	g_object_unref( strlist );
rosfran@220
   468
  	
rosfran@232
   469
 	return;
rosfran@199
   470
rosfran@175
   471
}
rosfran@175
   472
rosfran@175
   473
static gboolean
rosfran@175
   474
gmyth_connect_to_backend_monitor (GMythMonitorHandler *monitor)
rosfran@175
   475
{
rosfran@175
   476
  gboolean ret = TRUE;
rosfran@175
   477
rosfran@175
   478
  monitor->event_sock = gmyth_socket_new();
rosfran@175
   479
rosfran@175
   480
  /* Connects the socket, send Mythtv ANN Monitor and verify Mythtv protocol version */ 
rosfran@175
   481
  if (!gmyth_socket_connect_to_backend_events ( monitor->event_sock,
rosfran@175
   482
          monitor->hostname, monitor->port, FALSE ) ) 
rosfran@175
   483
  {
rosfran@175
   484
    g_object_unref (monitor->event_sock);
rosfran@175
   485
    monitor->event_sock = NULL;
rosfran@175
   486
    ret = FALSE;
rosfran@175
   487
  }
rosfran@175
   488
  
rosfran@175
   489
  return ret;
rosfran@175
   490
}    
rosfran@175
   491
rosfran@192
   492
static gboolean*
rosfran@220
   493
gmyth_monitor_handler_setup( GMythMonitorHandler *monitor, GIOChannel *channel )
rosfran@192
   494
{
rosfran@192
   495
	gboolean *ret = g_new0( gboolean, 1 );
rosfran@220
   496
	guint src_id = 0;
rosfran@192
   497
	
rosfran@192
   498
	*ret = TRUE;
rosfran@192
   499
	
rosfran@220
   500
  //io_watcher_context = g_main_context_default();
rosfran@220
   501
  //GMainLoop *loop = g_main_loop_new( io_watcher_context, TRUE );
rosfran@192
   502
rosfran@220
   503
  //GSource *source;
rosfran@192
   504
rosfran@192
   505
  if ( channel != NULL ) {
rosfran@220
   506
    //source = g_io_create_watch( channel, G_IO_IN | G_IO_HUP );
rosfran@220
   507
    src_id = g_io_add_watch( channel, G_IO_IN, 
rosfran@220
   508
    					(GIOFunc)gmyth_monitor_handler_listener, monitor );
rosfran@192
   509
  } else {
rosfran@192
   510
  	*ret = FALSE;
rosfran@192
   511
  	goto cleanup;
rosfran@192
   512
  }
rosfran@192
   513
rosfran@220
   514
  //g_source_set_callback ( source, (GSourceFunc)gmyth_monitor_handler_listener, NULL, NULL );
rosfran@192
   515
rosfran@220
   516
  //g_source_attach( source, io_watcher_context );
rosfran@192
   517
  
rosfran@220
   518
  //if (NULL == source){
rosfran@220
   519
  if (src_id < 0){
rosfran@192
   520
    gmyth_debug( "[%s] Error adding watch listener function to the IO control channel!\n", __FUNCTION__ );
rosfran@192
   521
    *ret = FALSE;
rosfran@192
   522
    goto cleanup;
rosfran@192
   523
  }
rosfran@192
   524
  
rosfran@220
   525
  //g_main_loop_run( loop );
rosfran@192
   526
  
rosfran@192
   527
cleanup:
rosfran@220
   528
  //if ( source != NULL )
rosfran@220
   529
  //  g_source_unref( source );
rosfran@198
   530
    
rosfran@198
   531
  //if ( io_watcher_context != NULL )
rosfran@198
   532
  //  g_main_context_unref( io_watcher_context );
rosfran@198
   533
rosfran@198
   534
  //if ( loop != NULL )
rosfran@198
   535
  //  g_main_loop_unref( loop );
rosfran@198
   536
    
rosfran@192
   537
  return ret;
rosfran@192
   538
  
rosfran@192
   539
}
rosfran@192
   540
rosfran@175
   541
gboolean 
rosfran@175
   542
gmyth_monitor_handler_start (GMythMonitorHandler *monitor)
rosfran@175
   543
{
rosfran@192
   544
	gboolean *ret = g_new0( gboolean, 1 ); 
rosfran@192
   545
	*ret = TRUE;	
rosfran@192
   546
	
rosfran@228
   547
	/*if (!g_thread_supported () ) 	g_thread_init (NULL);*/
rosfran@232
   548
	/*
rosfran@232
   549
  monitor->monitor_th = g_thread_pool_new( (GThreadFunc)gmyth_monitor_handler_listener, 
rosfran@220
   550
  					monitor, TRUE, NULL );
rosfran@232
   551
 */				
rosfran@232
   552
  monitor->monitor_th = g_thread_pool_new( (GFunc)gmyth_monitor_handler_listener, 
rosfran@232
   553
  					monitor, 3, TRUE, NULL );
rosfran@232
   554
  g_thread_pool_push( monitor->monitor_th, monitor, NULL ); 
rosfran@192
   555
  					
rosfran@198
   556
  //if ( ( ret = g_thread_join( monitor_th ) ) == FALSE )
rosfran@220
   557
  if ( monitor->monitor_th != NULL )
rosfran@220
   558
  //if ( gmyth_monitor_handler_setup( monitor, monitor->event_sock->sd_io_ch ) )
rosfran@192
   559
  {
rosfran@192
   560
  	gmyth_debug ( "\n[%s]\tOK! Starting listener on the MONITOR event socket...[thread location = %p]\n", 
rosfran@192
   561
  				__FUNCTION__, g_thread_self( ) );
rosfran@198
   562
  	*ret = TRUE;  	  	
rosfran@198
   563
  } else {
rosfran@198
   564
  	gmyth_debug ( "\n[%s]\tERROR! Coudn't start listener on the MONITOR event socket...[thread location = %p]\n", 
rosfran@198
   565
  				__FUNCTION__, g_thread_self( ) );
rosfran@198
   566
  	*ret = FALSE;
rosfran@192
   567
  }
rosfran@175
   568
rosfran@198
   569
//cleanup:
rosfran@192
   570
    
rosfran@192
   571
  gmyth_debug( "[%s] Watch listener function over the IO control channel? %s!!!\n", 
rosfran@192
   572
  			__FUNCTION__, ( *ret == TRUE ? "YES" : "NO" ) );
rosfran@175
   573
    
rosfran@198
   574
    return *ret;
rosfran@175
   575
}
rosfran@175
   576
rosfran@175
   577
void
rosfran@175
   578
gmyth_monitor_handler_close( GMythMonitorHandler *monitor )
rosfran@175
   579
{
rosfran@175
   580
	
rosfran@175
   581
  if (monitor->event_sock) {
rosfran@175
   582
    g_object_unref( monitor->event_sock );
rosfran@175
   583
    monitor->event_sock = NULL;
rosfran@175
   584
  }
rosfran@175
   585
rosfran@175
   586
  if (monitor->hostname) {
rosfran@175
   587
    g_free( monitor->hostname );
rosfran@175
   588
    monitor->hostname = NULL;
rosfran@175
   589
  }
rosfran@175
   590
  
rosfran@175
   591
}
rosfran@175
   592