RPi Locator and Display Services
gtkDS.c File Reference
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <libgssdp/gssdp.h>
#include <gio/gio.h>
#include <glib-unix.h>
#include <gio/gnetworking.h>
#include <ifaddrs.h>
+ Include dependency graph for gtkDS.c:

Go to the source code of this file.

Data Structures

struct  _ipBroadcastArray
 
struct  _messageData
 
struct  _signalData
 
struct  _registryData
 
struct  _gssdpRegistryData
 
struct  _controlData
 
struct  MessageQueueSource
 

Macros

#define PACKAGE_VERSION   "0.9.0"
 
#define PACKAGE_NAME   "gtkDS"
 
#define PACKAGE_DESCRIPTION   "Display Messages from other Raspberry Pi's on the network."
 
#define G_OPTION_FLAG_NONE   0
 
#define SZ_TIMESTAMP_BUFF   32
 
#define SZ_PARAMS_BUFF   64
 
#define SZ_RMTADDR_BUFF   256
 
#define SZ_MESSAGE_BUFF   512
 
#define SZ_RESPONSE_BUFF   256
 
#define UDP_COMM_PORT   48029
 
#define UDP_BROADCAST_PORT   48028
 
#define UDP_REGULAR_PORT   48027
 
#define MS_TEN_MINUTES   600000
 
#define SKN_SMALL_DISPLAY_MODE_ON   1
 
#define SKN_SMALL_DISPLAY_MODE_OFF   0
 
#define MAX_MESSAGES_VIEWABLE   64
 
#define SZ_CHAR_LABEL   48
 
#define SZ_INFO_BUFF   256
 
#define SZ_CHAR_BUFF   128
 
#define SZ_LINE_BUFF   512
 
#define SZ_COMM_BUFF   256
 
#define SKN_UDP_ANY_PORT   0
 
#define ARY_MAX_INTF   8
 
#define PLATFORM_ERROR   -1
 

Typedefs

typedef struct _ipBroadcastArray IPBroadcastArray
 
typedef struct _ipBroadcastArrayPIPBroadcastArray
 
typedef struct _messageData MsgData
 
typedef struct _messageDataPMsgData
 
typedef struct _signalData USignalData
 
typedef struct _signalDataPUSignalData
 
typedef struct _registryData RegData
 
typedef struct _registryDataPRegData
 
typedef struct _registryData ** PPRegData
 
typedef struct _gssdpRegistryData GSSDPRegData
 
typedef struct _gssdpRegistryDataPGSSDPRegData
 
typedef struct _controlData ControlData
 
typedef struct _controlDataPControlData
 
typedef gboolean(* MessageQueueSourceFunc) (gpointer message, gpointer user_data)
 

Enumerations

enum  _messages { MSGS_COLUMN_TIMESTAMP, COLUMN_NODE, COLUMN_MESSAGES, MSG_NUM_COLUMNS }
 
enum  _registry {
  UDP_COLUMN_TIMESTAMP, COLUMN_FROM, COLUMN_NAME, COLUMN_IP,
  COLUMN_PORT, REG_NUM_COLUMNS
}
 
enum  _gssdp_registry {
  GSSDP_COLUMN_TIMESTAMP, COLUMN_URN, COLUMN_LOCATION, COLUMN_STATUS,
  GSSDP_NUM_COLUMNS
}
 

Functions

gchar * skn_get_timestamp ()
 
gchar * skn_gio_condition_to_string (GIOCondition condition)
 
gchar * skn_strip (gchar *alpha)
 
PIPBroadcastArray skn_get_default_interface_name_and_ipv4_address (char *intf, char *ipv4)
 
gint skn_get_broadcast_ip_array (PIPBroadcastArray paB)
 
gint skn_get_default_interface_name (char *pchDefaultInterfaceName)
 
gboolean skn_udp_network_broadcast_all_interfaces (GSocket *gSock, PIPBroadcastArray pab)
 
static gboolean cb_unix_signal_handler (PUSignalData psig)
 
static gboolean cb_registry_refresh (PControlData pctrl)
 
static gboolean cb_registry_request_handler (PRegData msg, PControlData pctrl)
 
static gboolean cb_message_request_handler (PMsgData msg, PControlData pctrl)
 
static gboolean cb_udp_comm_request_handler (GSocket *socket, GIOCondition condition, PControlData pctrl)
 
static gboolean cb_udp_broadcast_response_handler (GSocket *gSock, GIOCondition condition, PControlData pctrl)
 
PPRegData udp_registry_response_parser (PRegData msg, gchar *response)
 
GtkWidget * ui_page_layout (GtkWidget *parent, PControlData pctrl)
 
GtkWidget * ui_message_page_new (GtkWidget *parent, guint gSmall)
 
GtkWidget * ui_registry_page_new (GtkWidget *parent, guint gSmall)
 
GtkWidget * ui_gssdp_registry_page_new (GtkWidget *parent, guint gSmall)
 
gboolean ui_add_message_entry (GtkWidget *treeview, PMsgData msg, gboolean limiter)
 
gboolean ui_add_registry_entry (GtkWidget *treeview, PRegData msg, gboolean limiter)
 
gboolean ui_add_gssdp_registry_entry (GtkWidget *treeview, PGSSDPRegData msg, gboolean limiter)
 
guint ui_update_status_bar (PControlData pctrl)
 
gboolean gssdp_publish (PControlData pctrl, guint udp_port)
 
gboolean gssdp_browse (PControlData pctrl)
 
static void cb_gssdp_resource_available (GSSDPResourceBrowser *resource_browser, const char *usn, GList *locations, PControlData pctrl)
 
static void cb_gssdp_resource_unavailable (GSSDPResourceBrowser *resource_browser, const char *usn, PControlData pctrl)
 
static gboolean message_queue_source_prepare (GSource *source, gint *timeout_)
 
static gboolean message_queue_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
 
static void message_queue_source_finalize (GSource *source)
 
static gboolean message_queue_source_closure_callback (gpointer message, gpointer user_data)
 
GSource * message_queue_source_new (GAsyncQueue *queue, GDestroyNotify destroy_message, GCancellable *cancellable)
 
PIPBroadcastArray skn_get_default_interface_name_and_ipv4_address (gchar *intf, gchar *ipv4)
 
static gboolean cb_gssdp_registry_request_handler (PGSSDPRegData msg, PControlData pctrl)
 
static void cb_gtk_shutdown (GtkWidget *object, gpointer data)
 
int main (int argc, char **argv)
 

Variables

enum _messages EMessages
 
enum _registry EUDPRegistry
 
enum _gssdp_registry EGSSDPRegistry
 
static GSourceFuncs message_queue_source_funcs
 

Macro Definition Documentation

#define ARY_MAX_INTF   8

Definition at line 72 of file gtkDS.c.

Referenced by skn_get_broadcast_ip_array().

#define G_OPTION_FLAG_NONE   0

Definition at line 45 of file gtkDS.c.

Referenced by main().

#define MAX_MESSAGES_VIEWABLE   64
#define MS_TEN_MINUTES   600000

Definition at line 58 of file gtkDS.c.

Referenced by main().

#define PACKAGE_DESCRIPTION   "Display Messages from other Raspberry Pi's on the network."

Definition at line 32 of file gtkDS.c.

#define PACKAGE_NAME   "gtkDS"

Definition at line 29 of file gtkDS.c.

#define PACKAGE_VERSION   "0.9.0"

gtkDS.c IOT/RaspberryPi message display service gcc pkg-config --cflags --libs gtk+-3.0 gssdp-1.0 -O3 -Wall -o gtkDS gtkDS.c

Program Flow:

  1. Initialize -> parse_options
  2. upd_socket -> loop -> receive_message_and_push_queue
  1. upd_broad -> loop -> receive_broadcast_message_and_push_queue
  1. gssdp_rgroup -> loop -> receive_gssdp_notification_and_response_directly
  1. gssdp_rbrowse -> loop -> receive_gssdp_message_and_push_queue
  2. udp_timeout -> loop -> trigger_refresh_on_gssdp_and_registry
  1. AsyncQueue -> loop -> update_Message_GtkTreeView_head -> if max_count then delete_GtkTreeView_tail
  1. AsyncQueue -> loop -> update_Registry_GtkTreeView_head -> if max_count then delete_GtkTreeView_tail
  1. AsyncQueue -> loop -> update_GSSDP_GtkTreeView_head -> if max_count then delete_GtkTreeView_tail
  2. unix_signal -> loop -> close_loop
  1. GtkStack -> loop -> service_message_registry_and_gssdp_scrolling_pages
  1. GtkWindow -> loop -> destroy_signal_callback -> close_loop
  2. Cleanup -> exit

Definition at line 26 of file gtkDS.c.

#define PLATFORM_ERROR   -1
#define SKN_SMALL_DISPLAY_MODE_OFF   0
#define SKN_SMALL_DISPLAY_MODE_ON   1

Definition at line 60 of file gtkDS.c.

#define SKN_UDP_ANY_PORT   0

Definition at line 71 of file gtkDS.c.

#define SZ_CHAR_BUFF   128
#define SZ_CHAR_LABEL   48

Definition at line 65 of file gtkDS.c.

#define SZ_COMM_BUFF   256

Definition at line 69 of file gtkDS.c.

#define SZ_INFO_BUFF   256

Definition at line 66 of file gtkDS.c.

Referenced by skn_get_default_interface_name().

#define SZ_LINE_BUFF   512

Definition at line 68 of file gtkDS.c.

#define SZ_MESSAGE_BUFF   512

Definition at line 52 of file gtkDS.c.

Referenced by gssdp_publish(), and ui_update_status_bar().

#define SZ_PARAMS_BUFF   64

Definition at line 50 of file gtkDS.c.

#define SZ_RESPONSE_BUFF   256

Definition at line 53 of file gtkDS.c.

Referenced by cb_udp_broadcast_response_handler(), and cb_udp_comm_request_handler().

#define SZ_RMTADDR_BUFF   256

Definition at line 51 of file gtkDS.c.

Referenced by udp_registry_response_parser().

#define SZ_TIMESTAMP_BUFF   32

Definition at line 49 of file gtkDS.c.

#define UDP_BROADCAST_PORT   48028

Definition at line 56 of file gtkDS.c.

Referenced by main(), and skn_udp_network_broadcast_all_interfaces().

#define UDP_COMM_PORT   48029

Definition at line 55 of file gtkDS.c.

Referenced by main().

#define UDP_REGULAR_PORT   48027

Definition at line 57 of file gtkDS.c.

Typedef Documentation

typedef struct _controlData ControlData
typedef gboolean(* MessageQueueSourceFunc) (gpointer message, gpointer user_data)

MessageQueueSourceFunc: : (transfer full) (nullable): message pulled off the queue : user data provided to g_source_set_callback()

Callback function type for MessageQueueSource.

Definition at line 234 of file gtkDS.c.

typedef struct _messageData MsgData
typedef struct _controlData * PControlData
typedef struct _messageData * PMsgData
typedef struct _registryData ** PPRegData
typedef struct _registryData * PRegData
typedef struct _signalData * PUSignalData
typedef struct _registryData RegData
typedef struct _signalData USignalData

Enumeration Type Documentation

Enumerator
GSSDP_COLUMN_TIMESTAMP 
COLUMN_URN 
COLUMN_LOCATION 
COLUMN_STATUS 
GSSDP_NUM_COLUMNS 

Definition at line 162 of file gtkDS.c.

enum _messages
Enumerator
MSGS_COLUMN_TIMESTAMP 
COLUMN_NODE 
COLUMN_MESSAGES 
MSG_NUM_COLUMNS 

Definition at line 146 of file gtkDS.c.

146  {
148  COLUMN_NODE,
151 } EMessages;
enum _messages EMessages
enum _registry
Enumerator
UDP_COLUMN_TIMESTAMP 
COLUMN_FROM 
COLUMN_NAME 
COLUMN_IP 
COLUMN_PORT 
REG_NUM_COLUMNS 

Definition at line 153 of file gtkDS.c.

153  {
155  COLUMN_FROM,
156  COLUMN_NAME,
157  COLUMN_IP,
158  COLUMN_PORT,
160 } EUDPRegistry;
enum _registry EUDPRegistry

Function Documentation

static gboolean cb_gssdp_registry_request_handler ( PGSSDPRegData  msg,
PControlData  pctrl 
)
static

Definition at line 786 of file gtkDS.c.

References _controlData::gGSSDPRegCount, MAX_MESSAGES_VIEWABLE, _controlData::pg3Target, ui_add_gssdp_registry_entry(), and ui_update_status_bar().

Referenced by main().

786  {
787 
788  g_return_val_if_fail((NULL != msg) && (NULL != pctrl), G_SOURCE_CONTINUE);
789 
790  pctrl->gGSSDPRegCount += 1;
791 
793 
794  ui_update_status_bar(pctrl);
795 
796  g_free(msg);
797 
798  return(G_SOURCE_CONTINUE);
799 }
guint ui_update_status_bar(PControlData pctrl)
Definition: gtkDS.c:522
guint gGSSDPRegCount
Definition: gtkDS.c:120
gboolean ui_add_gssdp_registry_entry(GtkWidget *treeview, PGSSDPRegData msg, gboolean limiter)
Definition: gtkDS.c:1220
#define MAX_MESSAGES_VIEWABLE
Definition: gtkDS.c:63
GtkWidget * pg3Target
Definition: gtkDS.c:137

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void cb_gssdp_resource_available ( GSSDPResourceBrowser *  resource_browser,
const char *  usn,
GList *  locations,
PControlData  pctrl 
)
static

Definition at line 1303 of file gtkDS.c.

References _gssdpRegistryData::ch_location, _gssdpRegistryData::ch_status, _gssdpRegistryData::ch_timestamp, _gssdpRegistryData::ch_urn, _controlData::queueGSSDPRegistry, and skn_get_timestamp().

Referenced by gssdp_browse().

1303  {
1304  PGSSDPRegData msg = NULL;
1305  gchar *stamp = skn_get_timestamp();
1306  gchar *converted = NULL;
1307 
1308  g_warn_if_fail(NULL != pctrl);
1309 
1310  msg = g_new0(GSSDPRegData, 1);
1311 
1312  g_utf8_strncpy(msg->ch_timestamp, stamp, sizeof(msg->ch_timestamp));
1313  g_free(stamp);
1314 
1315  /* Convert to UTF8 */
1316  converted = g_convert (usn, g_utf8_strlen(usn, -1), "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
1317  if (NULL != converted) {
1318  g_utf8_strncpy(msg->ch_urn, converted, sizeof(msg->ch_urn));
1319  g_free(converted);
1320  } else {
1321  g_utf8_strncpy(msg->ch_urn, usn, sizeof(msg->ch_urn));
1322  }
1323 
1324  converted = g_convert (locations->data, g_utf8_strlen(locations->data, -1), "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
1325  if (NULL != converted) {
1326  g_utf8_strncpy(msg->ch_location, converted, sizeof(msg->ch_location));
1327  g_free(converted);
1328  } else {
1329  g_utf8_strncpy(msg->ch_location, locations->data, sizeof(msg->ch_location));
1330  }
1331 
1332  g_utf8_strncpy(msg->ch_status, "Available", sizeof(msg->ch_status));
1333 
1334  g_async_queue_push(pctrl->queueGSSDPRegistry, msg);
1335 
1336 }
GAsyncQueue * queueGSSDPRegistry
Definition: gtkDS.c:133
gchar ch_timestamp[SZ_TIMESTAMP_BUFF]
Definition: gssdpDC.c:92
gchar ch_status[SZ_PARAMS_BUFF]
Definition: gssdpDC.c:95
gchar ch_urn[SZ_RMTADDR_BUFF]
Definition: gssdpDC.c:93
gchar ch_location[SZ_RMTADDR_BUFF]
Definition: gssdpDC.c:94
gchar * skn_get_timestamp()
Definition: gtkDS.c:515

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void cb_gssdp_resource_unavailable ( GSSDPResourceBrowser *  resource_browser,
const char *  usn,
PControlData  pctrl 
)
static

Definition at line 1337 of file gtkDS.c.

References _gssdpRegistryData::ch_location, _gssdpRegistryData::ch_status, _gssdpRegistryData::ch_timestamp, _gssdpRegistryData::ch_urn, _controlData::queueGSSDPRegistry, and skn_get_timestamp().

Referenced by gssdp_browse().

1337  {
1338  PGSSDPRegData msg = NULL;
1339  gchar *stamp = skn_get_timestamp();
1340  gchar *converted = NULL;
1341 
1342  g_warn_if_fail(NULL != pctrl);
1343 
1344  msg = g_new0(GSSDPRegData, 1);
1345 
1346  g_utf8_strncpy(msg->ch_timestamp, stamp, sizeof(msg->ch_timestamp));
1347  g_free(stamp);
1348 
1349  /* Convert to UTF8 */
1350  converted = g_convert (usn, g_utf8_strlen(usn, -1), "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
1351  if (NULL != converted) {
1352  g_utf8_strncpy(msg->ch_urn, converted, sizeof(msg->ch_urn));
1353  g_free(converted);
1354  } else {
1355  g_utf8_strncpy(msg->ch_urn, usn, sizeof(msg->ch_urn));
1356  }
1357 
1358  g_utf8_strncpy(msg->ch_location, "N/A", sizeof(msg->ch_location));
1359  g_utf8_strncpy(msg->ch_status, "Unavailable", sizeof(msg->ch_status));
1360 
1361  g_async_queue_push(pctrl->queueGSSDPRegistry, msg);
1362 }
GAsyncQueue * queueGSSDPRegistry
Definition: gtkDS.c:133
gchar ch_timestamp[SZ_TIMESTAMP_BUFF]
Definition: gssdpDC.c:92
gchar ch_status[SZ_PARAMS_BUFF]
Definition: gssdpDC.c:95
gchar ch_urn[SZ_RMTADDR_BUFF]
Definition: gssdpDC.c:93
gchar ch_location[SZ_RMTADDR_BUFF]
Definition: gssdpDC.c:94
gchar * skn_get_timestamp()
Definition: gtkDS.c:515

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void cb_gtk_shutdown ( GtkWidget *  object,
gpointer  data 
)
static

Definition at line 1296 of file gtkDS.c.

References _signalData::loop, and _signalData::signalName.

Referenced by main().

1296  {
1297  PUSignalData psig = (PUSignalData)data;
1298  g_message("gtkDS::cb_gtk_shutdown() %s Destroy Signal Received => Shutdown Initiated!\n", psig->signalName);
1299  g_main_loop_quit(psig->loop);
1300 }
gchar * signalName
Definition: cmdDC.c:78
struct _signalData * PUSignalData
GMainLoop * loop
Definition: cmdDC.c:77

+ Here is the caller graph for this function:

static gboolean cb_message_request_handler ( PMsgData  msg,
PControlData  pctrl 
)
static

Definition at line 754 of file gtkDS.c.

References _controlData::gMsgCount, MAX_MESSAGES_VIEWABLE, _controlData::pg1Target, ui_add_message_entry(), and ui_update_status_bar().

Referenced by main().

754  {
755 
756  g_return_val_if_fail((NULL != msg) && (NULL != pctrl), G_SOURCE_CONTINUE);
757 
758  pctrl->gMsgCount += 1;
759 
761 
762  ui_update_status_bar(pctrl);
763 
764  g_free(msg);
765 
766  return(G_SOURCE_CONTINUE);
767 }
gboolean ui_add_message_entry(GtkWidget *treeview, PMsgData msg, gboolean limiter)
Definition: gtkDS.c:1172
guint gMsgCount
Definition: gtkDS.c:119
guint ui_update_status_bar(PControlData pctrl)
Definition: gtkDS.c:522
GtkWidget * pg1Target
Definition: gtkDS.c:135
#define MAX_MESSAGES_VIEWABLE
Definition: gtkDS.c:63

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static gboolean cb_registry_refresh ( PControlData  pctrl)
static

Definition at line 541 of file gtkDS.c.

References _controlData::gbSock, _controlData::paB, _controlData::resource_browser, skn_udp_network_broadcast_all_interfaces(), and TRUE.

Referenced by main().

541  {
542  g_return_val_if_fail((NULL != pctrl), G_SOURCE_CONTINUE);
543 
545 // gssdp_resource_browser_rescan(pctrl->resource_browser); require 2.4+
546  gssdp_resource_browser_set_active(pctrl->resource_browser, TRUE);
547  return ( G_SOURCE_CONTINUE );
548 }
GSSDPResourceBrowser * resource_browser
Definition: gssdpDC.c:108
#define TRUE
GSocket * gbSock
Definition: cmdDS.c:95
PIPBroadcastArray paB
Definition: cmdDC.c:102
gboolean skn_udp_network_broadcast_all_interfaces(GSocket *gSock, PIPBroadcastArray pab)
Definition: gtkDS.c:489

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static gboolean cb_registry_request_handler ( PRegData  msg,
PControlData  pctrl 
)
static

Definition at line 770 of file gtkDS.c.

References _controlData::gRegCount, MAX_MESSAGES_VIEWABLE, _controlData::pg2Target, ui_add_registry_entry(), and ui_update_status_bar().

Referenced by main().

770  {
771 
772  g_return_val_if_fail((NULL != msg) && (NULL != pctrl), G_SOURCE_CONTINUE);
773 
774  pctrl->gRegCount += 1;
775 
776  ui_add_registry_entry( pctrl->pg2Target, msg, (pctrl->gRegCount >= (MAX_MESSAGES_VIEWABLE * 2)));
777 
778  ui_update_status_bar(pctrl);
779 
780  g_free(msg);
781 
782  return(G_SOURCE_CONTINUE);
783 }
guint gRegCount
Definition: cmdDC.c:104
gboolean ui_add_registry_entry(GtkWidget *treeview, PRegData msg, gboolean limiter)
Definition: gtkDS.c:1195
GtkWidget * pg2Target
Definition: gtkDS.c:136
guint ui_update_status_bar(PControlData pctrl)
Definition: gtkDS.c:522
#define MAX_MESSAGES_VIEWABLE
Definition: gtkDS.c:63

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static gboolean cb_udp_broadcast_response_handler ( GSocket *  gSock,
GIOCondition  condition,
PControlData  pctrl 
)
static

Definition at line 550 of file gtkDS.c.

References _registryData::ch_from, _registryData::ch_message, _controlData::ch_this_ip, _registryData::ch_timestamp, _controlData::gUDPPort, _controlData::loop, _controlData::pch_service_name, _controlData::queueRegistry, _controlData::resolver, skn_get_timestamp(), skn_gio_condition_to_string(), SZ_RESPONSE_BUFF, and udp_registry_response_parser().

Referenced by main().

550  {
551  GError *error = NULL;
552  GSocketAddress *gsRmtAddr = NULL;
553  GInetAddress *gsAddr = NULL;
554  PRegData message = NULL;
555  PRegData msg = NULL;
556  PRegData *msgs;
557  gchar * rmtHost = NULL;
558  gssize gss_receive = 0;
559  gchar *stamp = skn_get_timestamp();
560  gchar response[SZ_RESPONSE_BUFF];
561  gint h_index = 0;
562  gchar *converted = NULL;
563 
564  if ((condition & G_IO_HUP) || (condition & G_IO_ERR) || (condition & G_IO_NVAL)) { /* SHUTDOWN THE MAIN LOOP */
565  g_message("gtkDS::cb_udp_broadcast_response_handler(error) Operational Error / Shutdown Signaled => %s\n", skn_gio_condition_to_string(condition));
566  g_main_loop_quit(pctrl->loop);
567  return ( G_SOURCE_REMOVE );
568  }
569  if (condition != G_IO_IN) {
570  g_message("gtkDS::cb_udp_broadcast_response_handler(error) NOT G_IO_IN => %s\n", skn_gio_condition_to_string(condition));
571  return (G_SOURCE_CONTINUE);
572  }
573 
574  /*
575  * Allocate a new queue message and read incoming request directly into it */
576  message = g_new0(RegData,1);
577 
578  /*
579  * If socket times out before reading data any operation will error with 'G_IO_ERROR_TIMED_OUT'.
580  * Read Request Message and get Requestor IP Address or Name
581  */
582  gss_receive = g_socket_receive_from (gSock, &gsRmtAddr, message->ch_message, sizeof(message->ch_message), NULL, &error);
583  if (error != NULL) { // gss_receive = Number of bytes read, or 0 if the connection was closed by the peer, or -1 on error
584  g_error("g_socket_receive_from() => %s", error->message);
585  g_clear_error(&error);
586  g_free(message);
587  g_free(stamp);
588  return (G_SOURCE_CONTINUE);
589  }
590  if (gss_receive > 0 ) {
591  if (G_IS_INET_SOCKET_ADDRESS(gsRmtAddr) ) {
592  gsAddr = g_inet_socket_address_get_address( G_INET_SOCKET_ADDRESS(gsRmtAddr) );
593  if ( G_IS_INET_ADDRESS(gsAddr) ) {
594  g_object_ref(gsAddr);
595  rmtHost = g_resolver_lookup_by_address (pctrl->resolver, gsAddr, NULL, NULL);
596  if (NULL == rmtHost) {
597  rmtHost = g_inet_address_to_string ( gsAddr);
598  }
599  }
600  }
601 
602  /*
603  * Convert to UTF8
604  */
605  converted = g_convert (message->ch_message, gss_receive, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
606  if (NULL != converted) {
607  g_utf8_strncpy(message->ch_message, converted, sizeof(message->ch_message));
608  g_free(converted);
609  }
610 
611  g_utf8_strncpy(message->ch_timestamp, stamp, sizeof(message->ch_timestamp));
612  g_utf8_strncpy(message->ch_from, rmtHost, sizeof(message->ch_from));
613  if ( (msgs = udp_registry_response_parser(message, message->ch_message)) != NULL ) {
614  /*
615  * Send it to be processed by a message handler */
616  g_free(message);
617  h_index = 0;
618  msg = (PRegData)msgs[h_index];
619  while ( msg != NULL ) {
620  g_async_queue_push (pctrl->queueRegistry, msg);
621  msg = (PRegData)msgs[++h_index];
622  }
623  g_free(msgs);
624  } else {
625  g_free(message);
626 
627  /* Format: name=rpi_locator_service,ip=10.100.1.19,port=48028|
628  * name=gtk_display_service,ip=10.100.1.19,port=48029|
629  */
630 
631  g_snprintf(response, sizeof(response),
632  "name=rpi_locator_service,ip=%s,port=48028|name=%s,ip=%s,port=%d|",
633  pctrl->ch_this_ip, pctrl->pch_service_name, pctrl->ch_this_ip, pctrl->gUDPPort);
634  /*
635  * Send Registry Response to caller */
636 
637  g_print("[REGISTRY] Responding to Query: %s\n", response);
638 
639  g_socket_send_to (gSock, gsRmtAddr, response, strlen(response), NULL, &error);
640  if (error != NULL) { // gss_send = Number of bytes written (which may be less than size ), or -1 on error
641  g_error("g_socket_send_to() => %s", error->message);
642  g_free(message);
643  g_clear_error(&error);
644  }
645  }
646  }
647  g_free(stamp);
648  g_free(rmtHost);
649 
650  if ( G_IS_INET_ADDRESS(gsAddr) )
651  g_object_unref(gsAddr);
652 
653  if ( G_IS_INET_SOCKET_ADDRESS(gsRmtAddr) )
654  g_object_unref(gsRmtAddr);
655 
656  return (G_SOURCE_CONTINUE);
657 }
gchar * pch_service_name
Definition: cmdDS.c:101
#define SZ_RESPONSE_BUFF
Definition: gtkDS.c:53
gchar ch_message[SZ_MESSAGE_BUFF]
Definition: cmdDS.c:80
gchar * skn_gio_condition_to_string(GIOCondition condition)
Definition: gtkDS.c:801
GMainLoop * loop
Definition: cmdDC.c:91
guint gUDPPort
Definition: cmdDS.c:102
PPRegData udp_registry_response_parser(PRegData msg, gchar *response)
Definition: gtkDS.c:870
gchar ch_this_ip[SZ_RMTADDR_BUFF]
Definition: cmdDC.c:109
GAsyncQueue * queueRegistry
Definition: gtkDS.c:132
gchar ch_from[SZ_RMTADDR_BUFF]
Definition: cmdDC.c:83
struct _registryData * PRegData
gchar ch_timestamp[SZ_TIMESTAMP_BUFF]
Definition: cmdDC.c:82
GResolver * resolver
Definition: cmdDC.c:100
gchar * skn_get_timestamp()
Definition: gtkDS.c:515

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static gboolean cb_udp_comm_request_handler ( GSocket *  socket,
GIOCondition  condition,
PControlData  pctrl 
)
static

Definition at line 659 of file gtkDS.c.

References _messageData::ch_message, _messageData::ch_remoteAddress, _messageData::ch_timestamp, _controlData::loop, _controlData::queueMessage, _controlData::resolver, skn_get_timestamp(), skn_gio_condition_to_string(), and SZ_RESPONSE_BUFF.

Referenced by main().

659  {
660  GError *error = NULL;
661  GSocketAddress *gsRmtAddr = NULL;
662  GInetAddress *gsAddr = NULL;
663  PMsgData message = NULL;
664  gchar * rmtHost = NULL;
665  gssize gss_receive = 0;
666  gchar *stamp = skn_get_timestamp();
667  gchar response[SZ_RESPONSE_BUFF];
668 
669  if ((condition & G_IO_HUP) || (condition & G_IO_ERR) || (condition & G_IO_NVAL)) { /* SHUTDOWN THE MAIN LOOP */
670  g_message("gtkDS::cb_udp_comm_request_handler(error) Operational Error / Shutdown Signaled => %s\n", skn_gio_condition_to_string(condition));
671  g_main_loop_quit(pctrl->loop);
672  return ( G_SOURCE_REMOVE );
673  }
674  if (condition != G_IO_IN) {
675  g_message("gtkDS::cb_udp_comm_request_handler(error) NOT G_IO_IN => %s\n", skn_gio_condition_to_string(condition));
676  return (G_SOURCE_CONTINUE);
677  }
678 
679  /*
680  * Allocate a new queue message and read incoming request directly into it */
681  message = g_new0(MsgData,1);
682  g_utf8_strncpy(message->ch_timestamp, stamp, sizeof(message->ch_timestamp));
683  g_free(stamp);
684 
685  /*
686  * If socket times out before reading data any operation will error with 'G_IO_ERROR_TIMED_OUT'.
687  * Read Request Message and get Requestor IP Address or Name
688  */
689  gss_receive = g_socket_receive_from (gSock, &gsRmtAddr, message->ch_message, sizeof(message->ch_message), NULL, &error);
690  if (error != NULL) { // gss_receive = Number of bytes read, or 0 if the connection was closed by the peer, or -1 on error
691  g_error("g_socket_receive_from() => %s", error->message);
692  g_clear_error(&error);
693  g_free(message);
694  return (G_SOURCE_CONTINUE);
695  }
696  if (gss_receive > 0 ) {
697  if (G_IS_INET_SOCKET_ADDRESS(gsRmtAddr) ) {
698  gsAddr = g_inet_socket_address_get_address( G_INET_SOCKET_ADDRESS(gsRmtAddr) );
699  if ( G_IS_INET_ADDRESS(gsAddr) ) {
700  g_object_ref(gsAddr);
701  rmtHost = g_resolver_lookup_by_address (pctrl->resolver, gsAddr, NULL, NULL);
702  if (NULL == rmtHost) {
703  rmtHost = g_inet_address_to_string ( gsAddr);
704  }
705  }
706  }
707  g_snprintf(message->ch_remoteAddress, sizeof(message->ch_remoteAddress), "%s", rmtHost);
708  g_free(rmtHost);
709  g_snprintf(response, sizeof(response), "%d %s", 202, "Accepted");
710  } else {
711  g_snprintf(message->ch_message, sizeof(message->ch_message), "%s", "Error: Input not Usable");
712  g_snprintf(response, sizeof(response), "%d %s", 406, "Not Acceptable");
713  }
714 
715  /*
716  * Send Response to caller */
717  g_socket_send_to (gSock, gsRmtAddr, response, strlen(response), NULL, &error);
718  if (error != NULL) { // gss_send = Number of bytes written (which may be less than size ), or -1 on error
719  g_error("g_socket_send_to() => %s", error->message);
720  g_free(message);
721  g_clear_error(&error);
722 
723  if ( G_IS_INET_ADDRESS(gsAddr) )
724  g_object_unref(gsAddr);
725 
726  if ( G_IS_INET_SOCKET_ADDRESS(gsRmtAddr) )
727  g_object_unref(gsRmtAddr);
728 
729  return (G_SOURCE_CONTINUE);
730  }
731 
732  /*
733  * Send it to be processed by a message handler */
734  stamp = g_convert (message->ch_message, gss_receive, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
735  if (NULL != stamp) {
736  g_utf8_strncpy(message->ch_message, stamp, sizeof(message->ch_message));
737  g_free(stamp);
738  } else {
739  g_error("g_convert(udp_comm_request) => %s", error->message);
740  g_clear_error(&error);
741  }
742  g_async_queue_push (pctrl->queueMessage, message);
743 
744  if ( G_IS_INET_ADDRESS(gsAddr) )
745  g_object_unref(gsAddr);
746 
747  if ( G_IS_INET_SOCKET_ADDRESS(gsRmtAddr) )
748  g_object_unref(gsRmtAddr);
749 
750  return (G_SOURCE_CONTINUE);
751 }
gchar ch_timestamp[SZ_TIMESTAMP_BUFF]
Definition: gtkDS.c:87
GAsyncQueue * queueMessage
Definition: gtkDS.c:131
#define SZ_RESPONSE_BUFF
Definition: gtkDS.c:53
gchar * skn_gio_condition_to_string(GIOCondition condition)
Definition: gtkDS.c:801
gchar ch_remoteAddress[SZ_RMTADDR_BUFF]
Definition: gtkDS.c:88
GMainLoop * loop
Definition: cmdDC.c:91
gchar ch_message[SZ_MESSAGE_BUFF]
Definition: gtkDS.c:89
GResolver * resolver
Definition: cmdDC.c:100
gchar * skn_get_timestamp()
Definition: gtkDS.c:515

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static gboolean cb_unix_signal_handler ( PUSignalData  psig)
static

Definition at line 535 of file gtkDS.c.

References _signalData::loop, and _signalData::signalName.

Referenced by main().

535  {
536  g_message("gtkDS::cb_unix_signal_handler() %s Unix Signal Received => Shutdown Initiated!\n", psig->signalName);
537  g_main_loop_quit(psig->loop);
538  return ( G_SOURCE_REMOVE );
539 }
gchar * signalName
Definition: cmdDC.c:78
GMainLoop * loop
Definition: cmdDC.c:77

+ Here is the caller graph for this function:

gboolean gssdp_browse ( PControlData  pctrl)

Setup a monitor for the registry page

Definition at line 1401 of file gtkDS.c.

References cb_gssdp_resource_available(), cb_gssdp_resource_unavailable(), _controlData::gssdp_rgroup_client, _controlData::pch_search, _controlData::resource_browser, and TRUE.

Referenced by main().

1401  {
1402 
1403  pctrl->resource_browser = gssdp_resource_browser_new (pctrl->gssdp_rgroup_client, pctrl->pch_search); // GSSDP_ALL_RESOURCES);
1404  g_signal_connect (pctrl->resource_browser, "resource-available", G_CALLBACK (cb_gssdp_resource_available), pctrl);
1405  g_signal_connect (pctrl->resource_browser, "resource-unavailable", G_CALLBACK (cb_gssdp_resource_unavailable), pctrl);
1406 
1407  gssdp_resource_browser_set_active(pctrl->resource_browser, TRUE);
1408 
1409  return (TRUE);
1410 }
GSSDPResourceBrowser * resource_browser
Definition: gssdpDC.c:108
#define TRUE
static void cb_gssdp_resource_unavailable(GSSDPResourceBrowser *resource_browser, const char *usn, PControlData pctrl)
Definition: gtkDS.c:1337
static void cb_gssdp_resource_available(GSSDPResourceBrowser *resource_browser, const char *usn, GList *locations, PControlData pctrl)
Definition: gtkDS.c:1303
gchar * pch_search
Definition: gssdpDC.c:118
GSSDPClient * gssdp_rgroup_client
Definition: gssdpDC.c:107

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

gboolean gssdp_publish ( PControlData  pctrl,
guint  udp_port 
)

Definition at line 1364 of file gtkDS.c.

References _controlData::ch_this_ip, FALSE, _controlData::gssdp_rgroup_client, _controlData::resource_group, SZ_MESSAGE_BUFF, and TRUE.

Referenced by main().

1364  {
1365  GError *error = NULL;
1366  gchar ch_buffer[SZ_MESSAGE_BUFF];
1367 
1368 
1369  pctrl->gssdp_rgroup_client = gssdp_client_new(NULL, NULL, &error);
1370  if (error) {
1371  g_printerr ("Error creating the GSSDP gssdp_client for resource_group: %s\n", error->message);
1372  g_error_free (error);
1373  return(FALSE);
1374  }
1375 
1376  pctrl->resource_group = gssdp_resource_group_new(pctrl->gssdp_rgroup_client);
1377 
1378  g_snprintf(ch_buffer, sizeof(ch_buffer), "http://%s/", pctrl->ch_this_ip );
1379  gssdp_resource_group_add_resource_simple
1380  (pctrl->resource_group,
1381  "urn:rpilocator",
1382  "uuid:80e6e2b7-fa4a-4d06-820a-406d5ecbbe51::upnp:rootdevice",
1383  ch_buffer);
1384 
1385  g_snprintf(ch_buffer, sizeof(ch_buffer), "udp://%s:%d", pctrl->ch_this_ip, udp_port );
1386  gssdp_resource_group_add_resource_simple
1387  (pctrl->resource_group,
1388  "urn:rpilocator",
1389  "uuid:21798cdc-d875-42b9-bb52-8043e6396301::urn:schemas-upnp-org:service:GtkDisplayService:1",
1390  ch_buffer);
1391 
1392  gssdp_resource_group_set_available(pctrl->resource_group, TRUE);
1393 
1394 
1395  return(TRUE);
1396 }
#define FALSE
#define TRUE
gchar ch_this_ip[SZ_RMTADDR_BUFF]
Definition: cmdDC.c:109
#define SZ_MESSAGE_BUFF
Definition: gtkDS.c:52
GSSDPResourceGroup * resource_group
Definition: gtkDS.c:127
GSSDPClient * gssdp_rgroup_client
Definition: gssdpDC.c:107

+ Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 1412 of file gtkDS.c.

References cb_gssdp_registry_request_handler(), cb_gtk_shutdown(), cb_message_request_handler(), cb_registry_refresh(), cb_registry_request_handler(), cb_udp_broadcast_response_handler(), cb_udp_comm_request_handler(), cb_unix_signal_handler(), _controlData::ch_intfName, _controlData::ch_this_ip, FALSE, G_OPTION_FLAG_NONE, _controlData::gBroadSourceId, _controlData::gbSock, _controlData::gCommSourceId, _controlData::gGSSDPRegCount, _controlData::gGSSDPRegSourceId, _controlData::gMsgCount, _controlData::gMsgSourceId, _controlData::gRegCount, _controlData::gRegSourceId, _controlData::gSmall, gssdp_browse(), gssdp_publish(), _controlData::gssdp_rgroup_client, _controlData::gUDPPort, _signalData::loop, _controlData::loop, message_queue_source_new(), MS_TEN_MINUTES, _controlData::paB, _controlData::pch_search, _controlData::pch_service_name, _controlData::queueGSSDPRegistry, _controlData::queueMessage, _controlData::queueRegistry, _controlData::resolver, _controlData::resource_browser, _controlData::resource_group, _signalData::signalName, skn_get_default_interface_name_and_ipv4_address(), SKN_SMALL_DISPLAY_MODE_OFF, skn_udp_network_broadcast_all_interfaces(), TRUE, UDP_BROADCAST_PORT, UDP_COMM_PORT, and ui_page_layout().

1412  {
1413 
1414  GError *error = NULL;
1415  GMainLoop *loop = NULL;
1416  GSocket *gSock = NULL;
1417  GSocketAddress *gsAddr = NULL;
1418  GSource * gCommSource = NULL;
1419  GSocketAddress *gbAddr = NULL;
1420  GSource * gBroadSource = NULL;
1421  GSource * gMsgSource = NULL;
1422  GSource * gRegSource = NULL;
1423  GSource * gGSSDPRegSource = NULL;
1424  ControlData cData;
1425  PIPBroadcastArray paB = NULL;
1426  GInetAddress *anyAddr = NULL;
1427  USignalData sigTerm;
1428  USignalData sigInt;
1429  USignalData sigHup;
1430  USignalData winDestroy;
1431  GtkWidget *window = NULL;
1432  guint gUDPPort = 0;
1433  GOptionContext *gOptions = NULL;
1434  GOptionEntry pgmOptions[] = {
1435  {"service-name", 'a', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &cData.pch_service_name, "Alternate Service Name", "gtk_display_service"},
1436  {"udp_port_number", 'p', G_OPTION_FLAG_NONE, G_OPTION_ARG_INT, &gUDPPort, "UDP Port Number to listen on. default=48029", "48029"},
1437  {"small", 's', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &cData.gSmall, "Small Screen mode, reduced status and titles.", NULL},
1438  {"search-key", 'f', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &cData.pch_search, "GSSDP Search Key.", "[urn:rpilocator | ssdp:all]"},
1439  {NULL}
1440  };
1442  cData.pch_search = NULL;
1443  cData.pch_service_name = NULL;
1444 
1445  gOptions = g_option_context_new ("UDP message display service for IOT.");
1446  g_option_context_add_group (gOptions, (GOptionGroup *) gtk_get_option_group(TRUE) );
1447  g_option_context_add_main_entries (gOptions, pgmOptions, NULL);
1448 
1449  g_option_context_parse (gOptions, &argc, &argv, &error);
1450  if (error != NULL) {
1451  g_error("g_option_context_parse() => %s", error->message);
1452  g_clear_error(&error);
1453  exit(EXIT_FAILURE);
1454  }
1455  g_option_context_free(gOptions);
1456 
1457  if (gUDPPort == 0) {
1458  gUDPPort = cData.gUDPPort = UDP_COMM_PORT;
1459  } else {
1460  cData.gUDPPort = gUDPPort;
1461  }
1462  if (NULL == cData.pch_search) {
1463  cData.pch_search = "urn:rpilocator";
1464  }
1465  if (NULL == cData.pch_service_name) {
1466  cData.pch_service_name = "gtk_display_service";
1467  }
1468 
1469  cData.paB = paB = skn_get_default_interface_name_and_ipv4_address((char *)&cData.ch_intfName, (char *)&cData.ch_this_ip);
1470  if (NULL == paB) {
1471  g_error("skn_skn_get_default_interface_name_and_ipv4_address() => Unable to discover network interface or non-available.");
1472  exit(EXIT_FAILURE);
1473  }
1474 
1475  winDestroy.loop = sigTerm.loop = sigInt.loop = sigHup.loop = cData.loop = loop = g_main_loop_new(NULL, FALSE);
1476  sigTerm.signalName = "SIGTERM";
1477  sigInt.signalName = "SIGINT";
1478  sigHup.signalName = "SIGHUP";
1479  winDestroy.signalName = "gtkDestroyWindow";
1480  cData.resolver = g_resolver_get_default();
1481  cData.queueMessage = g_async_queue_new();
1482  cData.queueRegistry = g_async_queue_new();
1483  cData.queueGSSDPRegistry = g_async_queue_new();
1484  cData.gMsgCount = 0;
1485  cData.gRegCount = 0;
1486  cData.gGSSDPRegCount = 0;
1487 
1488 
1489  /*
1490  * Create and Add MessageQueue to main loop for service (i.e. incoming messages) */
1491  gMsgSource = message_queue_source_new (cData.queueMessage, (GDestroyNotify) g_free, NULL);
1492  g_source_ref(gMsgSource);
1493  g_source_set_callback (gMsgSource, (GSourceFunc)cb_message_request_handler, &cData, NULL);
1494  cData.gMsgSourceId = g_source_attach (gMsgSource, NULL);
1495 
1496  gRegSource = message_queue_source_new(cData.queueRegistry, (GDestroyNotify) g_free, NULL);
1497  g_source_ref(gRegSource);
1498  g_source_set_callback (gRegSource, (GSourceFunc)cb_registry_request_handler, &cData, NULL);
1499  cData.gRegSourceId = g_source_attach (gRegSource, NULL);
1500 
1501  gGSSDPRegSource = message_queue_source_new(cData.queueGSSDPRegistry, (GDestroyNotify) g_free, NULL);
1502  g_source_ref(gGSSDPRegSource);
1503  g_source_set_callback (gGSSDPRegSource, (GSourceFunc)cb_gssdp_registry_request_handler, &cData, NULL);
1504  cData.gGSSDPRegSourceId = g_source_attach (gGSSDPRegSource, NULL);
1505 
1506  /*
1507  * Create regular UDP Socket for receiving messages */
1508  gSock = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &error);
1509  if (error != NULL) {
1510  g_error("g_socket_new() => %s", error->message);
1511  g_clear_error(&error);
1512  exit(EXIT_FAILURE);
1513  }
1514 
1515  anyAddr = g_inet_address_new_any(G_SOCKET_FAMILY_IPV4);
1516  gsAddr = g_inet_socket_address_new(anyAddr, gUDPPort);
1517 
1518  g_socket_bind(gSock, gsAddr, TRUE, &error);
1519  if (error != NULL) {
1520  g_error("g_socket_bind() => %s", error->message);
1521  g_clear_error(&error);
1522  exit(EXIT_FAILURE);
1523  }
1524 
1525  gCommSource = g_socket_create_source (gSock, G_IO_IN, NULL);
1526  g_source_ref(gCommSource);
1527  g_source_set_callback (gCommSource, (GSourceFunc) cb_udp_comm_request_handler, &cData, NULL); // its really a GSocketSourceFunc
1528  cData.gCommSourceId = g_source_attach (gCommSource, NULL);
1529 
1530  /*
1531  * Create broadcast UDP Socket for receiving messages */
1532  cData.gbSock = g_socket_new(G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &error);
1533  if (error != NULL) {
1534  g_error("g_socket_new(broadcast) => %s", error->message);
1535  g_clear_error(&error);
1536  exit(EXIT_FAILURE);
1537  }
1538  g_socket_set_broadcast(cData.gbSock, TRUE);
1539 
1540  gbAddr = g_inet_socket_address_new(anyAddr, UDP_BROADCAST_PORT);
1541  g_object_unref(anyAddr);
1542 
1543  g_socket_bind(cData.gbSock, gbAddr, TRUE, &error);
1544  if (error != NULL) {
1545  g_error("g_socket_bind() => %s", error->message);
1546  g_clear_error(&error);
1547  exit(EXIT_FAILURE);
1548  }
1549 
1550  gBroadSource = g_socket_create_source(cData.gbSock, G_IO_IN, NULL);
1551  g_source_ref(gBroadSource);
1552  g_source_set_callback (gBroadSource, (GSourceFunc) cb_udp_broadcast_response_handler, &cData, NULL); // its really a GSocketSourceFunc
1553  cData.gBroadSourceId = g_source_attach (gBroadSource, NULL);
1554 
1555  g_timeout_add(MS_TEN_MINUTES, (GSourceFunc)cb_registry_refresh, &cData);
1556 
1557  /*
1558  * Handle ctrl-break and kill signals cleanly */
1559  g_unix_signal_add (SIGINT, (GSourceFunc) cb_unix_signal_handler, &sigInt); // SIGINT signal (Ctrl+C)
1560  g_unix_signal_add (SIGTERM,(GSourceFunc) cb_unix_signal_handler, &sigTerm);
1561  g_unix_signal_add (SIGHUP, (GSourceFunc) cb_unix_signal_handler, &sigHup);
1562 
1563  /*
1564  * Create a GTK+3 Page to show messages */
1565  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1566  gtk_window_set_title (GTK_WINDOW (window), "Gtk Display Service");
1567  gtk_container_set_border_width(GTK_CONTAINER(window), 10);
1568  gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
1569  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(cb_gtk_shutdown), &winDestroy);
1570 
1571  /*
1572  * Create body of main page */
1573  ui_page_layout(GTK_WIDGET(window), &cData);
1574 
1575  gtk_widget_show_all(GTK_WIDGET(window));
1576 
1577 
1578  /*
1579  * Broadcast Registry Request: 10.100.1.255 */
1580  if ( gssdp_publish(&cData, gUDPPort) && gssdp_browse(&cData) && skn_udp_network_broadcast_all_interfaces(cData.gbSock, paB) ) {
1581  g_message("gtkDS: Ready to do Good, on %s:%s:%d...\n", cData.ch_intfName, cData.ch_this_ip, gUDPPort);
1582 
1583  g_main_loop_run(loop);
1584  }
1585 
1586  gssdp_resource_browser_set_active(cData.resource_browser, FALSE);
1587  gssdp_resource_group_set_available (cData.resource_group, FALSE);
1588 
1589  g_source_unref(gCommSource);
1590  g_source_unref(gBroadSource);
1591  g_source_unref(gRegSource);
1592  g_source_unref(gMsgSource);
1593  g_source_unref(gGSSDPRegSource);
1594  g_object_unref(gSock);
1595  g_object_unref(cData.gbSock);
1596  g_object_unref(gsAddr);
1597  g_object_unref(gbAddr);
1598  g_object_unref(cData.resolver);
1599  g_async_queue_unref(cData.queueRegistry);
1600  g_async_queue_unref(cData.queueMessage);
1601  g_async_queue_unref(cData.queueGSSDPRegistry);
1602  g_object_unref (cData.resource_browser);
1603  g_object_unref (cData.resource_group);
1604  g_object_unref (cData.gssdp_rgroup_client);
1605 
1606  g_main_loop_unref(loop);
1607 
1608  g_message("gtkDS: shutdown...");
1609 
1610  exit(EXIT_SUCCESS);
1611 }
GSSDPResourceBrowser * resource_browser
Definition: gssdpDC.c:108
#define MS_TEN_MINUTES
Definition: gtkDS.c:58
#define UDP_BROADCAST_PORT
Definition: gtkDS.c:56
guint gMsgCount
Definition: gtkDS.c:119
#define UDP_COMM_PORT
Definition: gtkDS.c:55
gchar * pch_service_name
Definition: cmdDS.c:101
guint gCommSourceId
Definition: gtkDS.c:116
GAsyncQueue * queueMessage
Definition: gtkDS.c:131
GAsyncQueue * queueGSSDPRegistry
Definition: gtkDS.c:133
guint gRegCount
Definition: cmdDC.c:104
#define FALSE
static gboolean cb_message_request_handler(PMsgData msg, PControlData pctrl)
Definition: gtkDS.c:754
static gboolean cb_udp_broadcast_response_handler(GSocket *gSock, GIOCondition condition, PControlData pctrl)
Definition: gtkDS.c:550
static gboolean cb_unix_signal_handler(PUSignalData psig)
Definition: gtkDS.c:535
#define TRUE
gboolean gssdp_browse(PControlData pctrl)
Definition: gtkDS.c:1401
gboolean gssdp_publish(PControlData pctrl, guint udp_port)
Definition: gtkDS.c:1364
GMainLoop * loop
Definition: cmdDC.c:91
static void cb_gtk_shutdown(GtkWidget *object, gpointer data)
Definition: gtkDS.c:1296
#define G_OPTION_FLAG_NONE
Definition: gtkDS.c:45
gchar * signalName
Definition: cmdDC.c:78
GSocket * gbSock
Definition: cmdDS.c:95
guint gUDPPort
Definition: cmdDS.c:102
PIPBroadcastArray skn_get_default_interface_name_and_ipv4_address(char *intf, char *ipv4)
guint gMsgSourceId
Definition: gtkDS.c:114
gchar ch_this_ip[SZ_RMTADDR_BUFF]
Definition: cmdDC.c:109
static gboolean cb_registry_refresh(PControlData pctrl)
Definition: gtkDS.c:541
static gboolean cb_gssdp_registry_request_handler(PGSSDPRegData msg, PControlData pctrl)
Definition: gtkDS.c:786
#define SKN_SMALL_DISPLAY_MODE_OFF
Definition: gtkDS.c:61
guint gGSSDPRegCount
Definition: gtkDS.c:120
guint gSmall
Definition: gtkDS.c:124
PIPBroadcastArray paB
Definition: cmdDC.c:102
GAsyncQueue * queueRegistry
Definition: gtkDS.c:132
GtkWidget * ui_page_layout(GtkWidget *parent, PControlData pctrl)
Definition: gtkDS.c:1244
GSource * message_queue_source_new(GAsyncQueue *queue, GDestroyNotify destroy_message, GCancellable *cancellable)
Definition: gtkDS.c:326
guint gBroadSourceId
Definition: cmdDS.c:91
GMainLoop * loop
Definition: cmdDC.c:77
guint gGSSDPRegSourceId
Definition: gtkDS.c:118
static gboolean cb_udp_comm_request_handler(GSocket *socket, GIOCondition condition, PControlData pctrl)
Definition: gtkDS.c:659
guint gRegSourceId
Definition: gtkDS.c:115
GSSDPResourceGroup * resource_group
Definition: gtkDS.c:127
GResolver * resolver
Definition: cmdDC.c:100
gchar * pch_search
Definition: gssdpDC.c:118
gboolean skn_udp_network_broadcast_all_interfaces(GSocket *gSock, PIPBroadcastArray pab)
Definition: gtkDS.c:489
GSSDPClient * gssdp_rgroup_client
Definition: gssdpDC.c:107
gchar ch_intfName[SZ_RMTADDR_BUFF]
Definition: cmdDC.c:108
static gboolean cb_registry_request_handler(PRegData msg, PControlData pctrl)
Definition: gtkDS.c:770

+ Here is the call graph for this function:

static gboolean message_queue_source_closure_callback ( gpointer  message,
gpointer  user_data 
)
static

Definition at line 277 of file gtkDS.c.

277  {
278  GClosure *closure = user_data;
279  GValue param_value = G_VALUE_INIT;
280  GValue result_value = G_VALUE_INIT;
281  gboolean retval;
282 
283  g_warn_if_reached();
284 
285  /* The invoked function is responsible for freeing @message. */
286  g_value_init (&result_value, G_TYPE_BOOLEAN);
287  g_value_init (&param_value, G_TYPE_POINTER);
288  g_value_set_pointer (&param_value, message);
289 
290  g_closure_invoke (closure, &result_value, 1, &param_value, NULL);
291  retval = g_value_get_boolean (&result_value);
292 
293  g_value_unset (&param_value);
294  g_value_unset (&result_value);
295 
296  return (retval);
297 }
static gboolean message_queue_source_dispatch ( GSource *  source,
GSourceFunc  callback,
gpointer  user_data 
)
static

Definition at line 241 of file gtkDS.c.

References MessageQueueSource::destroy_message, MessageQueueSource::queue, and TRUE.

241  {
242  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;
243  gpointer message;
245 
246  /* Pop a message off the queue. */
247  message = g_async_queue_try_pop (message_queue_source->queue);
248 
249  /* If there was no message, bail. */
250  if (message == NULL)
251  {
252  /* Keep the source around to handle the next message. */
253  return TRUE;
254  }
255 
256  /* @func may be %NULL if no callback was specified.
257  * If so, drop the message. */
258  if (func == NULL)
259  {
260  if (message_queue_source->destroy_message != NULL)
261  {
262  message_queue_source->destroy_message (message);
263  }
264 
265  /* Keep the source around to consume the next message. */
266  return TRUE;
267  }
268 
269  return (func(message, user_data));
270 }
GDestroyNotify destroy_message
Definition: gtkDS.c:224
gboolean(* MessageQueueSourceFunc)(gpointer message, gpointer user_data)
Definition: gtkDS.c:234
#define TRUE
GAsyncQueue * queue
Definition: gtkDS.c:223
static void message_queue_source_finalize ( GSource *  source)
static

Definition at line 272 of file gtkDS.c.

References MessageQueueSource::queue.

272  {
273  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;
274  g_async_queue_unref (message_queue_source->queue);
275 }
GAsyncQueue * queue
Definition: gtkDS.c:223
GSource* message_queue_source_new ( GAsyncQueue *  queue,
GDestroyNotify  destroy_message,
GCancellable *  cancellable 
)

message_queue_source_new: : the queue to check : (nullable): function to free a message, or NULL : (nullable): a #GCancellable, or NULL

Create a new MessageQueueSource, a type of #GSource which dispatches for each message queued to it.

If a callback function of type MessageQueueSourceFunc is connected to the returned #GSource using g_source_set_callback(), it will be invoked for each message, with the message passed as its first argument. It is responsible for freeing the message. If no callback is set, messages are automatically freed as they are queued.

Returns: (transfer full): a new MessageQueueSource

Definition at line 326 of file gtkDS.c.

References MessageQueueSource::destroy_message, message_queue_source_funcs, and MessageQueueSource::queue.

Referenced by main().

326  {
327  GSource *source; /* alias of @message_queue_source */
328  MessageQueueSource *message_queue_source; /* alias of @source */
329 
330  g_return_val_if_fail (queue != NULL, NULL);
331  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
332 
333  source = g_source_new (&message_queue_source_funcs, sizeof (MessageQueueSource));
334  message_queue_source = (MessageQueueSource *) source;
335 
336  /* The caller can overwrite this name with something more useful later. */
337  g_source_set_name (source, "MessageQueueSource");
338 
339  message_queue_source->queue = g_async_queue_ref (queue);
340  message_queue_source->destroy_message = destroy_message;
341 
342  /* Add a cancellable source. */
343  if (cancellable != NULL)
344  {
345  GSource *cancellable_source;
346 
347  cancellable_source = g_cancellable_source_new (cancellable);
348  g_source_set_dummy_callback (cancellable_source);
349  g_source_add_child_source (source, cancellable_source);
350  g_source_unref (cancellable_source);
351  }
352 
353  return (source);
354 }
GDestroyNotify destroy_message
Definition: gtkDS.c:224
static GSourceFuncs message_queue_source_funcs
Definition: gtkDS.c:299
GAsyncQueue * queue
Definition: gtkDS.c:223

+ Here is the caller graph for this function:

static gboolean message_queue_source_prepare ( GSource *  source,
gint *  timeout_ 
)
static

Definition at line 236 of file gtkDS.c.

References MessageQueueSource::queue.

236  {
237  MessageQueueSource *message_queue_source = (MessageQueueSource *) source;
238  return (g_async_queue_length (message_queue_source->queue) > 0);
239 }
GAsyncQueue * queue
Definition: gtkDS.c:223
gint skn_get_broadcast_ip_array ( PIPBroadcastArray  paB)

Collect IP and Broadcast Addresses for this machine

  • Affects the PIPBroadcastArray
  • Return -1 on error, or count of interfaces
  • contains this ipAddress in paB->ipAddrStr[paB->defaultIndex]

Definition at line 377 of file gtkDS.c.

References ARY_MAX_INTF, _ipBroadcastArray::broadAddrStr, _ipBroadcastArray::cbName, _ipBroadcastArray::chDefaultIntfName, _ipBroadcastArray::count, _ipBroadcastArray::defaultIndex, _ipBroadcastArray::ifNameStr, _ipBroadcastArray::ipAddrStr, _ipBroadcastArray::maskAddrStr, PLATFORM_ERROR, skn_get_default_interface_name(), and SZ_CHAR_BUFF.

Referenced by skn_get_default_interface_name_and_ipv4_address().

377  {
378  struct ifaddrs * ifap;
379  struct ifaddrs * p;
380  gint rc = 0;
381 
382  memset(paB, 0, sizeof(IPBroadcastArray));
383  paB->count = 0;
384  paB->defaultIndex = 0;
385  strcpy(paB->cbName, "IPBroadcastArray");
386 
388  if (rc == EXIT_FAILURE) { // Alternate method for Mac: 'route -n -A inet'
389  g_warning("[REGISTRY] No Default Network Interfaces Found!.");
390  paB->chDefaultIntfName[0] = 0;
391  }
392  rc = getifaddrs(&ifap);
393  if (rc != 0) {
394  g_warning("[REGISTRY] No Network Interfaces Found at All ! %d:%d:%s", rc, errno, strerror(errno) );
395  return (PLATFORM_ERROR);
396  }
397  p = ifap;
398 
399  while (p && (paB->count < ARY_MAX_INTF)) {
400  if (p->ifa_addr != NULL && p->ifa_addr->sa_family == AF_INET && ((p->ifa_flags & IFF_BROADCAST) > 0)) {
401 
402  inet_ntop(p->ifa_addr->sa_family, &((struct sockaddr_in *) p->ifa_addr)->sin_addr, paB->ipAddrStr[paB->count], (SZ_CHAR_BUFF - 1));
403  inet_ntop(p->ifa_addr->sa_family, &((struct sockaddr_in *) p->ifa_netmask)->sin_addr, paB->maskAddrStr[paB->count], (SZ_CHAR_BUFF - 1));
404  inet_ntop(p->ifa_addr->sa_family, &((struct sockaddr_in *) p->ifa_broadaddr)->sin_addr, paB->broadAddrStr[paB->count], (SZ_CHAR_BUFF - 1));
405 
406  strncpy(paB->ifNameStr[paB->count], p->ifa_name, (SZ_CHAR_BUFF -1));
407 
408  /* Take match as the default */
409  if (strcmp(paB->chDefaultIntfName, p->ifa_name) == 0) {
410  paB->defaultIndex = paB->count;
411  }
412 
413  paB->count++;
414  }
415  p = p->ifa_next;
416  } // end while
417  freeifaddrs(ifap);
418 
419  return (paB->count);
420 }
char ifNameStr[ARY_MAX_INTF][SZ_CHAR_BUFF]
Definition: cmdDC.c:68
gint skn_get_default_interface_name(char *pchDefaultInterfaceName)
Definition: gtkDS.c:438
char ipAddrStr[ARY_MAX_INTF][SZ_CHAR_BUFF]
Definition: cmdDC.c:69
#define ARY_MAX_INTF
Definition: gtkDS.c:72
#define PLATFORM_ERROR
Definition: gtkDS.c:73
char maskAddrStr[ARY_MAX_INTF][SZ_CHAR_BUFF]
Definition: cmdDC.c:70
#define SZ_CHAR_BUFF
Definition: gtkDS.c:67
char cbName[SZ_CHAR_BUFF]
Definition: cmdDC.c:66
int defaultIndex
Definition: cmdDC.c:72
char chDefaultIntfName[SZ_CHAR_BUFF]
Definition: cmdDC.c:67
char broadAddrStr[ARY_MAX_INTF][SZ_CHAR_BUFF]
Definition: cmdDC.c:71

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

gint skn_get_default_interface_name ( char *  pchDefaultInterfaceName)

Retrieves default internet interface name into param

  • absolute best way to do this, but not supported on Darwin(i.e OSX) return EXIT_SUCCESS or EXIT_FAILURE

[jscott OSX]$ route -n get 0.0.0.0 route to: default destination: default mask: default gateway: 10.21.1.254 interface: en3 flags: <UP,GATEWAY,DONE,STATIC,PRCLONING> recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire 0 0 0 0 0 0 1500 0

Definition at line 438 of file gtkDS.c.

References skn_strip(), and SZ_INFO_BUFF.

Referenced by skn_get_broadcast_ip_array().

438  {
439  FILE *f_route;
440  char line[SZ_INFO_BUFF], *dRoute = NULL, *iName = NULL;
441 
442  f_route = fopen("/proc/net/route", "r");
443  if (f_route != NULL) {
444  while (fgets(line, SZ_INFO_BUFF - 1, f_route)) {
445  iName = strtok(line, "\t");
446  dRoute = strtok(NULL, "\t");
447 
448  if (iName != NULL && dRoute != NULL) {
449  if (strcmp(dRoute, "00000000") == 0) {
450  strncpy(pchDefaultInterfaceName, iName, (SZ_INFO_BUFF - 1));
451  break;
452  }
453  }
454  }
455  fclose(f_route);
456 
457  return (EXIT_SUCCESS);
458  }
459  g_warning("[REGISTRY] Opening ProcFs for RouteInfo Failed: %d:%s, Alternate method will be attempted.", errno, strerror(errno));
460 
461  f_route = popen("route -n get 0.0.0.0", "r"); // for linux 'route -n -A inet', with interface at line_word[7]
462  if (f_route != NULL) {
463  while (fgets(line, SZ_INFO_BUFF - 1, f_route)) {
464  dRoute = strtok(line, ":");
465  iName = strtok(NULL, "\n");
466  if (strcmp(skn_strip(dRoute), "interface") == 0) {
467  strncpy(pchDefaultInterfaceName, skn_strip(iName), (SZ_INFO_BUFF - 1));
468  break;
469  }
470  }
471  fclose(f_route);
472 
473  return (EXIT_SUCCESS);
474  } else {
475  g_warning("[REGISTRY] Alternate method to get RouteInfo Failed: %d:%s", errno, strerror(errno));
476  return (EXIT_FAILURE);
477  }
478 
479 }
gchar * skn_strip(gchar *alpha)
Definition: gtkDS.c:834
#define SZ_INFO_BUFF
Definition: gtkDS.c:66

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

PIPBroadcastArray skn_get_default_interface_name_and_ipv4_address ( char *  intf,
char *  ipv4 
)

Referenced by main().

+ Here is the caller graph for this function:

PIPBroadcastArray skn_get_default_interface_name_and_ipv4_address ( gchar *  intf,
gchar *  ipv4 
)

Definition at line 357 of file gtkDS.c.

References _ipBroadcastArray::chDefaultIntfName, _ipBroadcastArray::defaultIndex, _ipBroadcastArray::ipAddrStr, PLATFORM_ERROR, skn_get_broadcast_ip_array(), and SZ_CHAR_BUFF.

357  {
358  PIPBroadcastArray paB = g_new0(IPBroadcastArray, 1);
359 
361  g_utf8_strncpy(intf, paB->chDefaultIntfName, SZ_CHAR_BUFF);
362  g_utf8_strncpy(ipv4, paB->ipAddrStr[paB->defaultIndex], SZ_CHAR_BUFF);
363  } else {
364  g_warning("[REGISTRY] InterfaceName and Address: unable to access information.");
365  return(NULL);
366  }
367  return (paB);
368 }
char ipAddrStr[ARY_MAX_INTF][SZ_CHAR_BUFF]
Definition: cmdDC.c:69
#define PLATFORM_ERROR
Definition: gtkDS.c:73
#define SZ_CHAR_BUFF
Definition: gtkDS.c:67
int defaultIndex
Definition: cmdDC.c:72
char chDefaultIntfName[SZ_CHAR_BUFF]
Definition: cmdDC.c:67
gint skn_get_broadcast_ip_array(PIPBroadcastArray paB)
Definition: gtkDS.c:377

+ Here is the call graph for this function:

gchar* skn_get_timestamp ( )

Definition at line 515 of file gtkDS.c.

Referenced by cb_gssdp_resource_available(), cb_gssdp_resource_unavailable(), cb_udp_broadcast_response_handler(), and cb_udp_comm_request_handler().

515  {
516  GDateTime *stamp = g_date_time_new_now_local();
517  gchar *response = g_date_time_format(stamp,"%F.%T");
518 
519  return(response);
520 }

+ Here is the caller graph for this function:

gchar* skn_gio_condition_to_string ( GIOCondition  condition)

Definition at line 801 of file gtkDS.c.

Referenced by cb_udp_broadcast_response_handler(), and cb_udp_comm_request_handler().

801  {
802  gchar *value = NULL;
803 
804  switch(condition) {
805  case G_IO_IN:
806  value = "There is data to read.";
807  break;
808  case G_IO_OUT:
809  value = "Data can be written (without blocking).";
810  break;
811  case G_IO_PRI:
812  value = "There is urgent data to read.";
813  break;
814  case G_IO_ERR:
815  value = "Error condition.";
816  break;
817  case G_IO_HUP:
818  value = "Hung up (the connection has been broken, usually for pipes and sockets).";
819  break;
820  case G_IO_NVAL:
821  value = "Invalid request. The file descriptor is not open.";
822  break;
823  default:
824  value = "Unknown GIOCondition!";
825  }
826 
827  return (value);
828 }

+ Here is the caller graph for this function:

gchar* skn_strip ( gchar *  alpha)

Remove Trailing and Leading Blanks

  • caution: pointers from argv are readonly and segfault on 'alpha[end] = 0'

Definition at line 834 of file gtkDS.c.

Referenced by skn_get_default_interface_name().

834  {
835  if (alpha == NULL || strlen(alpha) < 1)
836  return(alpha);
837 
838  int len = strlen(alpha);
839  int end = len - 1;
840  int start = 0;
841 
842  // use isgraph() or !isspace() vs isalnum() to allow ['|' ';' '%']
843  while ( !g_unichar_isgraph(alpha[end]) && end > 0 ) { // remove trailing non-alphanumeric chars
844  alpha[end--] = 0;
845  }
846 
847  len = strlen(alpha);
848  while ( !g_unichar_isalnum(alpha[start]) && start < len ) { // find first non-alpha stricter
849  start++;
850  }
851  if (start < len && start > 0) { // move in place
852  end = len - start;
853  memmove(&alpha[0], &alpha[start], end);
854  alpha[end] = 0;
855  }
856 
857  return(alpha);
858 }

+ Here is the caller graph for this function:

gboolean skn_udp_network_broadcast_all_interfaces ( GSocket *  gSock,
PIPBroadcastArray  paB 
)

Send a registry request on the broadcast ip of all interfaces

Parameters
gSockIN GLib active/bound socket with broadcast enabled
ch_requestIN Greetings message, anytext
ch_intfNameOUT Default Ethernet Interface Name
ch_ipAddressOUT Default Ethernet IP Address
Returns
true on success,

Definition at line 489 of file gtkDS.c.

References _ipBroadcastArray::broadAddrStr, _ipBroadcastArray::count, _ipBroadcastArray::defaultIndex, _ipBroadcastArray::ifNameStr, _ipBroadcastArray::ipAddrStr, TRUE, and UDP_BROADCAST_PORT.

Referenced by cb_registry_refresh(), and main().

489  {
490  struct sockaddr_in remaddr; /* remote address */
491  socklen_t addrlen = sizeof(remaddr); /* length of addresses */
492  gchar *request = "urn:rpilocator - Rpi Where Are You?";
493  gint vIndex = 0;
494  gint i_socket = g_socket_get_fd(gSock);
495 
496  g_print("[REGISTRY] Socket Bound to %s\n", paB->ipAddrStr[paB->defaultIndex]);
497 
498  for (vIndex = 0; vIndex < paB->count; vIndex++) {
499  memset(&remaddr, 0, sizeof(remaddr));
500  remaddr.sin_family = AF_INET;
501  remaddr.sin_addr.s_addr = inet_addr(paB->broadAddrStr[vIndex]);
502  remaddr.sin_port = htons(UDP_BROADCAST_PORT);
503 
504  if (sendto(i_socket, request, strlen(request), 0, (struct sockaddr *) &remaddr, addrlen) < 0) {
505  g_warning("SendTo() Timed out; Failure code=%d, etext=%s", errno, strerror(errno));
506  break;
507  }
508  g_print("[REGISTRY] Query Broadcasted on %s:%s:%d\n", paB->ifNameStr[vIndex], paB->broadAddrStr[vIndex], UDP_BROADCAST_PORT);
509  }
510 
511  return(TRUE);
512 }
char ifNameStr[ARY_MAX_INTF][SZ_CHAR_BUFF]
Definition: cmdDC.c:68
#define UDP_BROADCAST_PORT
Definition: gtkDS.c:56
char ipAddrStr[ARY_MAX_INTF][SZ_CHAR_BUFF]
Definition: cmdDC.c:69
#define TRUE
int defaultIndex
Definition: cmdDC.c:72
char broadAddrStr[ARY_MAX_INTF][SZ_CHAR_BUFF]
Definition: cmdDC.c:71

+ Here is the caller graph for this function:

PPRegData udp_registry_response_parser ( PRegData  msg,
gchar *  response 
)

Parse this response message

Format: name=rpi_locator_service,ip=10.100.1.19,port=48028| name=lcd_display_service,ip=10.100.1.19,port=48029|

the vertical bar char '|' is the line separator, % and ; are also supported

Definition at line 870 of file gtkDS.c.

References _registryData::ch_ip, _registryData::ch_name, _registryData::ch_port, FALSE, SZ_RMTADDR_BUFF, and TRUE.

Referenced by cb_udp_broadcast_response_handler().

870  {
871  gboolean rc = FALSE;
872  gboolean final_rc = FALSE;
873  gchar ** lines = NULL;
874  gchar *current_line = NULL;
875  gchar ** entries = NULL;
876  gchar *current_entry = NULL;
877  gchar ** key_value = NULL;
878  PRegData *msgs;
879  PRegData preg = NULL;
880  gint h_index = 0;
881  gint v_index = 0;
882  gint o_index = 0;
883  gint a_count = 0;
884  gint e_count = 0;
885 
886  if (g_utf8_strchr(response, -1, '|') == NULL) { // must be a registry entry
887  return (NULL);
888  }
889 
890  lines = g_strsplit_set(response, "|;%", -1); // get whole entries
891  if ((NULL == lines) || (g_strv_length(lines) < 1)) {
892  return(NULL);
893  }
894 
895  a_count = g_strv_length(lines);
896  msgs = g_new0(PRegData, a_count);
897  for(o_index = 0; o_index < a_count; o_index += 1) {
898  msgs[o_index] = g_new0(RegData, 1);
899  memmove(msgs[o_index], msg, sizeof(RegData));
900  }
901 
902  o_index = 0;
903  current_line = lines[h_index];
904  while ((NULL != current_line) && (h_index < a_count)) { // do each entry
905  if(g_utf8_strlen(current_line, -1) < 1) {
906  current_line = lines[++h_index];
907  continue;
908  }
909 
910  v_index = 0;
911  entries = g_strsplit_set(current_line, ",", -1);
912  current_entry = entries[v_index];
913  e_count = g_strv_length(entries);
914  preg = msgs[o_index];
915  rc = FALSE;
916 
917  while((NULL != current_entry) && (v_index < e_count)) {
918  if(g_utf8_strlen(current_entry, -1) < 1) {
919  current_entry = entries[++v_index];
920  continue;
921  }
922 
923  // get name, ip, port
924 
925  key_value = g_strsplit_set(current_entry, "=", -1);
926  if((key_value != NULL) && (g_strv_length(key_value) > 0)) {
927  if(g_strrstr(key_value[0], "a") != NULL) {
928  final_rc = rc = TRUE;
929  g_utf8_strncpy(preg->ch_name, key_value[1], SZ_RMTADDR_BUFF);
930  }
931  if(g_strrstr(key_value[0], "i") != NULL) {
932  final_rc = rc = TRUE;
933  g_utf8_strncpy(preg->ch_ip, key_value[1], SZ_RMTADDR_BUFF);
934  }
935  if(g_strrstr(key_value[0], "o") != NULL) {
936  final_rc = rc = TRUE;
937  g_utf8_strncpy(preg->ch_port, key_value[1], SZ_RMTADDR_BUFF);
938  }
939  }
940  g_strfreev(key_value);
941  current_entry = entries[++v_index];
942  } // end entries
943 
944  if (rc && (g_utf8_strlen(preg->ch_ip, -1) > 6)) { // only move if used and valid
945  o_index += 1;
946  }
947  g_strfreev(entries);
948 
949  h_index +=1;
950  current_line = lines[h_index];
951  } // end lines
952  g_strfreev(lines);
953 
954  if (final_rc) {
955  while(o_index < a_count) {
956  g_free(msgs[o_index]);
957  msgs[o_index++] = NULL;
958  }
959  return(msgs);
960  } else {
961  while(o_index < a_count) {
962  g_free(msgs[o_index]);
963  msgs[o_index++] = NULL;
964  }
965  g_free(msgs);
966  return(NULL);
967  }
968 }
gchar ch_ip[SZ_PARAMS_BUFF]
Definition: cmdDC.c:85
#define FALSE
gchar ch_port[SZ_PARAMS_BUFF]
Definition: cmdDC.c:86
#define TRUE
#define SZ_RMTADDR_BUFF
Definition: gtkDS.c:51
gchar ch_name[SZ_RMTADDR_BUFF]
Definition: cmdDC.c:84

+ Here is the caller graph for this function:

gboolean ui_add_gssdp_registry_entry ( GtkWidget *  treeview,
PGSSDPRegData  msg,
gboolean  limiter 
)

Definition at line 1220 of file gtkDS.c.

References _gssdpRegistryData::ch_location, _gssdpRegistryData::ch_status, _gssdpRegistryData::ch_timestamp, _gssdpRegistryData::ch_urn, COLUMN_LOCATION, COLUMN_STATUS, COLUMN_URN, GSSDP_COLUMN_TIMESTAMP, and TRUE.

Referenced by cb_gssdp_registry_request_handler().

1220  {
1221  gboolean result = TRUE;
1222  GtkListStore *store = GTK_LIST_STORE( gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)) );
1223  GtkTreeIter iter;
1224  gint num_rows = 0;
1225 
1226  // insert at head of list
1227  gtk_list_store_insert_with_values (store, NULL, 0, GSSDP_COLUMN_TIMESTAMP, msg->ch_timestamp,
1228  COLUMN_URN, msg->ch_urn,
1230  COLUMN_STATUS, msg->ch_status, -1);
1231 
1232  if (limiter) { // get last iter and remove it
1233  num_rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
1234 
1235  if ( (num_rows > 8) && (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, (num_rows -1))) ) { // last entry
1236  gtk_tree_model_unref_node(GTK_TREE_MODEL(store), &iter);
1237  gtk_list_store_remove(store, &iter);
1238  }
1239  }
1240 
1241  return (result);
1242 }
gchar ch_timestamp[SZ_TIMESTAMP_BUFF]
Definition: gssdpDC.c:92
#define TRUE
gchar ch_status[SZ_PARAMS_BUFF]
Definition: gssdpDC.c:95
gchar ch_urn[SZ_RMTADDR_BUFF]
Definition: gssdpDC.c:93
gchar ch_location[SZ_RMTADDR_BUFF]
Definition: gssdpDC.c:94

+ Here is the caller graph for this function:

gboolean ui_add_message_entry ( GtkWidget *  treeview,
PMsgData  msg,
gboolean  limiter 
)

Definition at line 1172 of file gtkDS.c.

References _messageData::ch_message, _messageData::ch_remoteAddress, _messageData::ch_timestamp, COLUMN_MESSAGES, COLUMN_NODE, MSGS_COLUMN_TIMESTAMP, and TRUE.

Referenced by cb_message_request_handler().

1172  {
1173  gboolean result = TRUE;
1174  GtkListStore *store = GTK_LIST_STORE( gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)) );
1175  GtkTreeIter iter;
1176  gint num_rows = 0;
1177 
1178  // insert at head of list
1179  gtk_list_store_insert_with_values (store, NULL, 0, MSGS_COLUMN_TIMESTAMP, msg->ch_timestamp,
1181  COLUMN_MESSAGES, msg->ch_message, -1);
1182 
1183  if (limiter) { // get last iter and remove it
1184  num_rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
1185 
1186  if ( (num_rows > 8) && (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, (num_rows -1))) ) { // last entry
1187  gtk_tree_model_unref_node(GTK_TREE_MODEL(store), &iter);
1188  gtk_list_store_remove(store, &iter);
1189  }
1190  }
1191 
1192  return (result);
1193 }
gchar ch_timestamp[SZ_TIMESTAMP_BUFF]
Definition: gtkDS.c:87
gchar ch_remoteAddress[SZ_RMTADDR_BUFF]
Definition: gtkDS.c:88
#define TRUE
gchar ch_message[SZ_MESSAGE_BUFF]
Definition: gtkDS.c:89

+ Here is the caller graph for this function:

gboolean ui_add_registry_entry ( GtkWidget *  treeview,
PRegData  msg,
gboolean  limiter 
)

Definition at line 1195 of file gtkDS.c.

References _registryData::ch_from, _registryData::ch_ip, _registryData::ch_name, _registryData::ch_port, _registryData::ch_timestamp, COLUMN_FROM, COLUMN_IP, COLUMN_NAME, COLUMN_PORT, TRUE, and UDP_COLUMN_TIMESTAMP.

Referenced by cb_registry_request_handler().

1195  {
1196  gboolean result = TRUE;
1197  GtkListStore *store = GTK_LIST_STORE( gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)) );
1198  GtkTreeIter iter;
1199  gint num_rows = 0;
1200 
1201  // insert at head of list
1202  gtk_list_store_insert_with_values (store, NULL, 0, UDP_COLUMN_TIMESTAMP, msg->ch_timestamp ,
1203  COLUMN_FROM, msg->ch_from,
1204  COLUMN_NAME, msg->ch_name,
1205  COLUMN_IP, msg->ch_ip,
1206  COLUMN_PORT, msg->ch_port, -1);
1207 
1208  if (limiter) { // get last iter and remove it
1209  num_rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
1210 
1211  if ( (num_rows > 8) && (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, (num_rows -1))) ) { // last entry
1212  gtk_tree_model_unref_node(GTK_TREE_MODEL(store), &iter);
1213  gtk_list_store_remove(store, &iter);
1214  }
1215  }
1216 
1217  return (result);
1218 }
gchar ch_ip[SZ_PARAMS_BUFF]
Definition: cmdDC.c:85
gchar ch_port[SZ_PARAMS_BUFF]
Definition: cmdDC.c:86
#define TRUE
gchar ch_name[SZ_RMTADDR_BUFF]
Definition: cmdDC.c:84
gchar ch_from[SZ_RMTADDR_BUFF]
Definition: cmdDC.c:83
gchar ch_timestamp[SZ_TIMESTAMP_BUFF]
Definition: cmdDC.c:82

+ Here is the caller graph for this function:

GtkWidget * ui_gssdp_registry_page_new ( GtkWidget *  parent,
guint  gSmall 
)

Definition at line 1104 of file gtkDS.c.

References COLUMN_LOCATION, COLUMN_STATUS, COLUMN_URN, FALSE, GSSDP_COLUMN_TIMESTAMP, GSSDP_NUM_COLUMNS, SKN_SMALL_DISPLAY_MODE_OFF, and TRUE.

Referenced by ui_page_layout().

1104  {
1105  GtkWidget *scrolled = NULL;
1106  GtkTreeView *treeview = NULL;
1107  GtkListStore *store = NULL;
1108  GtkCellRenderer *renderer = NULL;
1109  GtkTreeViewColumn *column = NULL;
1110 
1111  if (gSmall == SKN_SMALL_DISPLAY_MODE_OFF) {
1112  gtk_box_pack_start (GTK_BOX (parent), gtk_label_new ("GSSDP Network Services Registry.") , FALSE, FALSE, 6);
1113  }
1114 
1115  /*
1116  * main container is a GtkTreeView wrapped by a scrollable window */
1117  scrolled = gtk_scrolled_window_new (NULL, NULL);
1118  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1119  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled),GTK_SHADOW_ETCHED_OUT);
1120  gtk_box_pack_start (GTK_BOX (parent), scrolled, TRUE, TRUE, 0);
1121 
1122 
1123  /* create list store for tree view */
1124  store = gtk_list_store_new (GSSDP_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
1125 
1126  treeview = GTK_TREE_VIEW(gtk_tree_view_new_with_model (GTK_TREE_MODEL(store)));
1127  gtk_tree_view_set_grid_lines(treeview, GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
1128 
1129  /* column for timestamp */
1130  renderer = gtk_cell_renderer_text_new ();
1131  column = gtk_tree_view_column_new_with_attributes ("Timestamp", renderer, "text", GSSDP_COLUMN_TIMESTAMP, NULL);
1132  gtk_tree_view_column_set_resizable(column, TRUE);
1133  gtk_tree_view_column_set_sort_column_id (column, GSSDP_COLUMN_TIMESTAMP);
1134  gtk_tree_view_append_column(treeview, column);
1135 
1136  /* column for service name */
1137  renderer = gtk_cell_renderer_text_new ();
1138  column = gtk_tree_view_column_new_with_attributes ("GSSDP URN", renderer, "text", COLUMN_URN, NULL);
1139  gtk_tree_view_column_set_resizable(column, TRUE);
1140  gtk_tree_view_column_set_sort_column_id (column, COLUMN_URN);
1141  gtk_tree_view_append_column(treeview, column);
1142 
1143  /* column for IP Address */
1144  renderer = gtk_cell_renderer_text_new ();
1145  column = gtk_tree_view_column_new_with_attributes ("GSSDP Location", renderer, "text", COLUMN_LOCATION, NULL);
1146  gtk_tree_view_column_set_expand(column, TRUE);
1147  gtk_tree_view_column_set_resizable(column, TRUE);
1148  gtk_tree_view_column_set_sort_column_id (column, COLUMN_LOCATION);
1149  gtk_tree_view_append_column (treeview, column);
1150 
1151  /* column for port number */
1152  renderer = gtk_cell_renderer_text_new ();
1153  column = gtk_tree_view_column_new_with_attributes ("GSSDP Status", renderer, "text", COLUMN_STATUS, NULL);
1154  gtk_tree_view_column_set_resizable(column, TRUE);
1155  gtk_tree_view_column_set_sort_column_id (column, COLUMN_STATUS);
1156  gtk_tree_view_append_column (treeview, column);
1157 
1158  g_object_unref (store);
1159 
1160  gtk_tree_view_set_enable_search(treeview, TRUE);
1161  gtk_tree_view_set_search_column (treeview, COLUMN_URN);
1162 
1163  gtk_container_add (GTK_CONTAINER(scrolled), GTK_WIDGET(treeview));
1164 
1165  gtk_widget_show_all(parent);
1166 
1167  gtk_tree_view_columns_autosize(treeview);
1168 
1169  return (GTK_WIDGET(treeview));
1170 }
#define FALSE
#define TRUE
#define SKN_SMALL_DISPLAY_MODE_OFF
Definition: gtkDS.c:61

+ Here is the caller graph for this function:

GtkWidget * ui_message_page_new ( GtkWidget *  parent,
guint  gSmall 
)

Definition at line 970 of file gtkDS.c.

References COLUMN_MESSAGES, COLUMN_NODE, FALSE, MSG_NUM_COLUMNS, MSGS_COLUMN_TIMESTAMP, SKN_SMALL_DISPLAY_MODE_OFF, and TRUE.

Referenced by ui_page_layout().

970  {
971  GtkWidget *scrolled = NULL;
972  GtkTreeView *treeview = NULL;
973  GtkListStore *store = NULL;
974  GtkCellRenderer *renderer = NULL;
975  GtkTreeViewColumn *column = NULL;
976 
977  if (gSmall == SKN_SMALL_DISPLAY_MODE_OFF) {
978  gtk_box_pack_start (GTK_BOX (parent), gtk_label_new ("Device Messages from the local Internet of Things (IOT).") , FALSE, FALSE, 6);
979  }
980  /*
981  * main container is a GtkTreeView wrapped by a scrollable window */
982  scrolled = gtk_scrolled_window_new (NULL, NULL);
983  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
984  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled),GTK_SHADOW_ETCHED_OUT);
985  gtk_box_pack_start (GTK_BOX (parent), scrolled, TRUE, TRUE, 0);
986 
987 
988  /* create list store for tree view */
989  store = gtk_list_store_new (MSG_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
990 
991  treeview = GTK_TREE_VIEW(gtk_tree_view_new_with_model (GTK_TREE_MODEL(store)));
992  gtk_tree_view_set_grid_lines(treeview, GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
993 
994  /* column for timestamp */
995  renderer = gtk_cell_renderer_text_new ();
996  column = gtk_tree_view_column_new_with_attributes ("Timestamp", renderer, "text", MSGS_COLUMN_TIMESTAMP, NULL);
997  gtk_tree_view_column_set_sort_column_id (column, MSGS_COLUMN_TIMESTAMP);
998  gtk_tree_view_column_set_resizable(column, TRUE);
999  gtk_tree_view_append_column(treeview, column);
1000 
1001  /* column for service name */
1002  renderer = gtk_cell_renderer_text_new ();
1003  column = gtk_tree_view_column_new_with_attributes ("Sent By", renderer, "text", COLUMN_NODE, NULL);
1004  gtk_tree_view_column_set_sort_column_id (column, COLUMN_NODE);
1005  gtk_tree_view_column_set_resizable(column, TRUE);
1006  gtk_tree_view_append_column (treeview, column);
1007 
1008  /* column for IP Address */
1009  renderer = gtk_cell_renderer_text_new ();
1010  column = gtk_tree_view_column_new_with_attributes ("Message", renderer, "text", COLUMN_MESSAGES, NULL);
1011  gtk_tree_view_column_set_sort_column_id (column, COLUMN_MESSAGES);
1012  gtk_tree_view_column_set_resizable(column, TRUE);
1013  gtk_tree_view_column_set_expand(column, TRUE);
1014  gtk_tree_view_append_column (treeview, column);
1015 
1016  g_object_unref (store);
1017 
1018  gtk_tree_view_set_search_column(treeview, COLUMN_NODE);
1019  gtk_tree_view_set_enable_search(treeview, TRUE);
1020 
1021  gtk_container_add (GTK_CONTAINER(scrolled), GTK_WIDGET(treeview));
1022 
1023  gtk_widget_show_all(parent);
1024  gtk_tree_view_columns_autosize(treeview);
1025 
1026  return (GTK_WIDGET(treeview));
1027 }
#define FALSE
#define TRUE
#define SKN_SMALL_DISPLAY_MODE_OFF
Definition: gtkDS.c:61

+ Here is the caller graph for this function:

GtkWidget * ui_page_layout ( GtkWidget *  parent,
PControlData  pctrl 
)

Definition at line 1244 of file gtkDS.c.

References _controlData::gSmall, _controlData::gStatusContextId, _controlData::pg1Target, _controlData::pg2Target, _controlData::pg3Target, SKN_SMALL_DISPLAY_MODE_OFF, _controlData::statusBar, TRUE, ui_gssdp_registry_page_new(), ui_message_page_new(), and ui_registry_page_new().

Referenced by main().

1244  {
1245  GtkWidget *grid = NULL;
1246  GtkWidget *switcher = NULL;
1247  GtkWidget *stack = NULL;
1248  GtkWidget *pg1Box = NULL;
1249  GtkWidget *pg2Box = NULL;
1250  GtkWidget *pg3Box = NULL;
1251 
1252 
1253  grid = gtk_grid_new(); // left, top, width, hieght
1254 
1255  switcher = gtk_stack_switcher_new();
1256  gtk_widget_set_hexpand (switcher, TRUE);
1257  gtk_widget_set_halign (switcher, GTK_ALIGN_CENTER);
1258  gtk_grid_attach (GTK_GRID (grid), switcher, 0, 0, 1, 1);
1259 
1260  stack = gtk_stack_new();
1261  gtk_widget_set_hexpand (stack, TRUE);
1262  gtk_widget_set_vexpand(stack, TRUE);
1263  gtk_stack_set_homogeneous( GTK_STACK(stack), TRUE);
1264  gtk_stack_set_transition_type( GTK_STACK(stack), GTK_STACK_TRANSITION_TYPE_CROSSFADE);
1265  gtk_stack_set_transition_duration( GTK_STACK(stack), 400);
1266  gtk_grid_attach (GTK_GRID (grid), stack, 0, 1, 1, 1);
1267 
1268  pg1Box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1269  pctrl->pg1Target = ui_message_page_new(pg1Box, pctrl->gSmall);
1270  gtk_stack_add_titled ( GTK_STACK(stack), GTK_WIDGET(pg1Box), "messages", "Messages");
1271  pg2Box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1272  pctrl->pg2Target = ui_registry_page_new(pg2Box, pctrl->gSmall);
1273  gtk_stack_add_titled ( GTK_STACK(stack), GTK_WIDGET(pg2Box), "udp_registry", "Rpi Registry");
1274  pg3Box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1275  pctrl->pg3Target = ui_gssdp_registry_page_new(pg3Box, pctrl->gSmall);
1276  gtk_stack_add_titled ( GTK_STACK(stack), GTK_WIDGET(pg3Box), "gssdp_registry", "GSSDP Registry");
1277 
1278  gtk_stack_switcher_set_stack (GTK_STACK_SWITCHER(switcher), GTK_STACK(stack));
1279  gtk_stack_set_visible_child (GTK_STACK(stack), GTK_WIDGET(pg1Box));
1280 
1281  if (pctrl->gSmall == SKN_SMALL_DISPLAY_MODE_OFF) {
1282  pctrl->statusBar = gtk_statusbar_new();
1283  gtk_grid_attach (GTK_GRID (grid), pctrl->statusBar, 0, 3, 1, 1);
1284  pctrl->gStatusContextId = gtk_statusbar_get_context_id(GTK_STATUSBAR(pctrl->statusBar), "GtkDisplayService");
1285  gtk_statusbar_push(GTK_STATUSBAR(pctrl->statusBar), pctrl->gStatusContextId, "Online and Ready to do good work.");
1286  }
1287 
1288  gtk_container_add (GTK_CONTAINER(parent), grid);
1289 
1290  gtk_widget_show_all(grid);
1291 
1292  return (stack);
1293 }
gint gStatusContextId
Definition: gtkDS.c:122
GtkWidget * ui_registry_page_new(GtkWidget *parent, guint gSmall)
Definition: gtkDS.c:1029
GtkWidget * pg2Target
Definition: gtkDS.c:136
#define TRUE
GtkWidget * statusBar
Definition: gtkDS.c:134
#define SKN_SMALL_DISPLAY_MODE_OFF
Definition: gtkDS.c:61
guint gSmall
Definition: gtkDS.c:124
GtkWidget * ui_message_page_new(GtkWidget *parent, guint gSmall)
Definition: gtkDS.c:970
GtkWidget * ui_gssdp_registry_page_new(GtkWidget *parent, guint gSmall)
Definition: gtkDS.c:1104
GtkWidget * pg1Target
Definition: gtkDS.c:135
GtkWidget * pg3Target
Definition: gtkDS.c:137

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

GtkWidget * ui_registry_page_new ( GtkWidget *  parent,
guint  gSmall 
)

Definition at line 1029 of file gtkDS.c.

References COLUMN_FROM, COLUMN_IP, COLUMN_NAME, COLUMN_PORT, FALSE, REG_NUM_COLUMNS, SKN_SMALL_DISPLAY_MODE_OFF, TRUE, and UDP_COLUMN_TIMESTAMP.

Referenced by ui_page_layout().

1029  {
1030  GtkWidget *scrolled = NULL;
1031  GtkTreeView *treeview = NULL;
1032  GtkListStore *store = NULL;
1033  GtkCellRenderer *renderer = NULL;
1034  GtkTreeViewColumn *column = NULL;
1035 
1036 
1037  if (gSmall == SKN_SMALL_DISPLAY_MODE_OFF) {
1038  gtk_box_pack_start (GTK_BOX (parent), gtk_label_new ("Raspberry Pi Network Services Registry.") , FALSE, FALSE, 6);
1039  }
1040 
1041  /*
1042  * main container is a GtkTreeView wrapped by a scrollable window */
1043  scrolled = gtk_scrolled_window_new (NULL, NULL);
1044  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1045  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled),GTK_SHADOW_ETCHED_OUT);
1046  gtk_box_pack_start (GTK_BOX (parent), scrolled, TRUE, TRUE, 0);
1047 
1048 
1049  /* create list store for tree view */
1050  store = gtk_list_store_new (REG_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
1051 
1052  treeview = GTK_TREE_VIEW(gtk_tree_view_new_with_model (GTK_TREE_MODEL(store)));
1053  gtk_tree_view_set_grid_lines(treeview, GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
1054 
1055  /* column for timestamp */
1056  renderer = gtk_cell_renderer_text_new ();
1057  column = gtk_tree_view_column_new_with_attributes ("Timestamp", renderer, "text", UDP_COLUMN_TIMESTAMP, NULL);
1058  gtk_tree_view_column_set_resizable(column, TRUE);
1059  gtk_tree_view_column_set_sort_column_id (column, UDP_COLUMN_TIMESTAMP);
1060  gtk_tree_view_append_column(treeview, column);
1061 
1062  /* column for from node */
1063  renderer = gtk_cell_renderer_text_new ();
1064  column = gtk_tree_view_column_new_with_attributes ("Reported By", renderer, "text", COLUMN_FROM, NULL);
1065  gtk_tree_view_column_set_sort_column_id (column, COLUMN_FROM);
1066  gtk_tree_view_column_set_resizable(column, TRUE);
1067  gtk_tree_view_append_column(treeview, column);
1068 
1069  /* column for service name */
1070  renderer = gtk_cell_renderer_text_new ();
1071  column = gtk_tree_view_column_new_with_attributes ("Service Name", renderer, "text", COLUMN_NAME, NULL);
1072  gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
1073  gtk_tree_view_column_set_resizable(column, TRUE);
1074  gtk_tree_view_append_column(treeview, column);
1075 
1076  /* column for IP Address */
1077  renderer = gtk_cell_renderer_text_new ();
1078  column = gtk_tree_view_column_new_with_attributes ("IP Address", renderer, "text", COLUMN_IP, NULL);
1079  gtk_tree_view_column_set_sort_column_id (column, COLUMN_IP);
1080  gtk_tree_view_column_set_resizable(column, TRUE);
1081  gtk_tree_view_append_column (treeview, column);
1082 
1083  /* column for port number */
1084  renderer = gtk_cell_renderer_text_new ();
1085  column = gtk_tree_view_column_new_with_attributes ("UDP Port", renderer, "text", COLUMN_PORT, NULL);
1086  gtk_tree_view_column_set_sort_column_id (column, COLUMN_PORT);
1087  gtk_tree_view_column_set_resizable(column, TRUE);
1088  gtk_tree_view_append_column (treeview, column);
1089 
1090  g_object_unref (store);
1091 
1092  gtk_tree_view_set_enable_search(treeview, TRUE);
1093  gtk_tree_view_set_search_column (treeview, COLUMN_NAME);
1094 
1095  gtk_container_add (GTK_CONTAINER(scrolled), GTK_WIDGET(treeview));
1096 
1097  gtk_widget_show_all(parent);
1098 
1099  gtk_tree_view_columns_autosize(treeview);
1100 
1101  return (GTK_WIDGET(treeview));
1102 }
#define FALSE
#define TRUE
#define SKN_SMALL_DISPLAY_MODE_OFF
Definition: gtkDS.c:61

+ Here is the caller graph for this function:

guint ui_update_status_bar ( PControlData  pctrl)

Definition at line 522 of file gtkDS.c.

References _controlData::gGSSDPRegCount, _controlData::gMsgCount, _controlData::gRegCount, _controlData::gSmall, _controlData::gStatusContextId, SKN_SMALL_DISPLAY_MODE_OFF, _controlData::statusBar, and SZ_MESSAGE_BUFF.

Referenced by cb_gssdp_registry_request_handler(), cb_message_request_handler(), and cb_registry_request_handler().

522  {
523  gchar ch_status_message[SZ_MESSAGE_BUFF];
524 
525  if (pctrl->gSmall != SKN_SMALL_DISPLAY_MODE_OFF) {
526  return (0);
527  }
528 
529  g_snprintf(ch_status_message, sizeof(ch_status_message), "Messages=%d, GSSDP entries=%d, RpiLocator entries=%d", pctrl->gMsgCount, pctrl->gGSSDPRegCount, pctrl->gRegCount);
530  gtk_statusbar_pop(GTK_STATUSBAR(pctrl->statusBar), pctrl->gStatusContextId);
531 
532  return (gtk_statusbar_push(GTK_STATUSBAR(pctrl->statusBar), pctrl->gStatusContextId, ch_status_message));
533 }
guint gMsgCount
Definition: gtkDS.c:119
gint gStatusContextId
Definition: gtkDS.c:122
guint gRegCount
Definition: cmdDC.c:104
GtkWidget * statusBar
Definition: gtkDS.c:134
#define SKN_SMALL_DISPLAY_MODE_OFF
Definition: gtkDS.c:61
guint gGSSDPRegCount
Definition: gtkDS.c:120
guint gSmall
Definition: gtkDS.c:124
#define SZ_MESSAGE_BUFF
Definition: gtkDS.c:52

+ Here is the caller graph for this function:

Variable Documentation

enum _gssdp_registry EGSSDPRegistry
enum _messages EMessages
enum _registry EUDPRegistry
GSourceFuncs message_queue_source_funcs
static
Initial value:
=
{
NULL,
NULL,
}
static gboolean message_queue_source_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
Definition: gtkDS.c:241
static void message_queue_source_finalize(GSource *source)
Definition: gtkDS.c:272
static gboolean message_queue_source_prepare(GSource *source, gint *timeout_)
Definition: gtkDS.c:236
static gboolean message_queue_source_closure_callback(gpointer message, gpointer user_data)
Definition: gtkDS.c:277

Definition at line 299 of file gtkDS.c.

Referenced by message_queue_source_new().