Commit 2174b5ff authored by Jussi Kukkonen's avatar Jussi Kukkonen

"civic location changed"-signal implementation for plazes

parent a6237bf7
......@@ -42,17 +42,33 @@ G_DEFINE_TYPE(GeocluePosition, geoclue_position, G_TYPE_OBJECT)
enum {
CURRENT_POSITION_CHANGED,
CIVIC_LOCATION_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
/* Default handler */
/* Default handlers */
void geoclue_position_current_position_changed(GeocluePosition* obj, gdouble lat, gdouble lon)
{
g_print("Current Position Changed\n");
}
void geoclue_position_civic_location_changed(GeocluePosition* obj,
char* OUT_country,
char* OUT_region,
char* OUT_locality,
char* OUT_area,
char* OUT_postalcode,
char* OUT_street,
char* OUT_building,
char* OUT_floor,
char* OUT_room,
char* OUT_text)
{
g_print("Civic location Changed\n");
}
/*
......@@ -70,9 +86,32 @@ static gboolean get_webservice_xml (xmlChar **xml, gchar* url, GError** error);
static xmlXPathContextPtr get_xpath_context (gchar* url, GError** error);
static gboolean evaluate_xpath_string (gchar** OUT_string, xmlXPathContextPtr xpathCtx, gchar* expr);
static gboolean evaluate_xpath_number (gdouble* OUT_double, xmlXPathContextPtr xpathCtx, gchar* expr);
static gboolean query_position (gdouble* OUT_latitude, gdouble* OUT_longitude, GError **error);
static gboolean query_civic_location (char** OUT_country,
char** OUT_region,
char** OUT_locality,
char** OUT_area,
char** OUT_postalcode,
char** OUT_street,
char** OUT_building,
char** OUT_floor,
char** OUT_room,
char** OUT_text,
GError **error);
static void set_current_position (GeocluePosition *obj, gdouble lat, gdouble lon);
static void set_civic_location (GeocluePosition *obj,
char* OUT_country,
char* OUT_region,
char* OUT_locality,
char* OUT_area,
char* OUT_postalcode,
char* OUT_street,
char* OUT_building,
char* OUT_floor,
char* OUT_room,
char* OUT_text);
......@@ -92,6 +131,7 @@ static void net_connection_event_cb (ConIcConnection *connection,
gpointer user_data)
{
gdouble lat, lon;
gchar *country, *region, *locality, *area, *postalcode, *street, *building, *floor, *room, *text;
g_return_if_fail (IS_GEOCLUE_POSITION (user_data));
/* NOTE: this macro is broken in libconic 0.12
......@@ -108,9 +148,21 @@ static void net_connection_event_cb (ConIcConnection *connection,
if (query_position (&lat, &lon, NULL)) {
set_current_position (obj, lat, lon);
}
if (query_civic_location (&country, &region, &locality, &area,
&postalcode, &street, &building,
&floor, &room, &text,
NULL)) {
set_civic_location (obj,
country, region, locality, area,
postalcode, street, building,
floor, room, text);
}
break;
case CON_IC_STATUS_DISCONNECTED:
obj->is_current_valid = FALSE;
obj->is_civic_valid = FALSE;
break;
default:
break;
......@@ -337,6 +389,71 @@ static gboolean query_position (gdouble* OUT_latitude, gdouble* OUT_longitude, G
return TRUE;
}
static gboolean query_civic_location (char** OUT_country,
char** OUT_region,
char** OUT_locality,
char** OUT_area,
char** OUT_postalcode,
char** OUT_street,
char** OUT_building,
char** OUT_floor,
char** OUT_room,
char** OUT_text,
GError **error)
{
xmlXPathContextPtr xpathCtx;
gboolean valid = FALSE;
gchar* query_url;
gchar* mac_address;
*OUT_country = NULL;
*OUT_region = NULL;
*OUT_locality = NULL;
*OUT_area = NULL;
*OUT_postalcode = NULL;
*OUT_street = NULL;
*OUT_building = NULL;
*OUT_floor = NULL;
*OUT_room = NULL;
*OUT_text = NULL;
if (!get_mac_address (&mac_address)) {
g_set_error (error,
GEOCLUE_POSITION_ERROR,
GEOCLUE_POSITION_ERROR_FAILED,
"Could not find out MAC address of the router");
return FALSE;
}
query_url = g_strdup_printf("%s?mac_address=%s", WEBSERVICE_API, mac_address);
g_free (mac_address);
if (!(xpathCtx = get_xpath_context (query_url, error))) {
return FALSE;
}
valid = evaluate_xpath_string (OUT_country, xpathCtx, "//plaze/country") || valid;
valid = evaluate_xpath_string (OUT_locality, xpathCtx, "//plaze/city") || valid;
valid = evaluate_xpath_string (OUT_postalcode, xpathCtx, "//plaze/zip_code") || valid;
valid = evaluate_xpath_string (OUT_street, xpathCtx, "//plaze/address") || valid;
valid = evaluate_xpath_string (OUT_text, xpathCtx, "//plaze/name") || valid;
xmlXPathFreeContext(xpathCtx);
g_debug ("location: %s, %s, %s, %s, %s", *OUT_country, *OUT_locality, *OUT_postalcode, *OUT_street, *OUT_text);
if (!valid){
g_set_error (error,
GEOCLUE_POSITION_ERROR,
GEOCLUE_POSITION_ERROR_NODATA,
"%s does not have civic location for this router MAC address.", WEBSERVICE_API);
return FALSE;
}
return TRUE;
}
static void set_current_position (GeocluePosition *obj, gdouble lat, gdouble lon)
{
if ((lat != obj->current_lat) || (lat != obj->current_lat)) {
......@@ -349,6 +466,67 @@ static void set_current_position (GeocluePosition *obj, gdouble lat, gdouble lon
obj->is_current_valid = OBSERVING_NET_CONNECTIONS;
}
/* compare strings that are allowed to be null */
static gboolean is_same_string (char* a, char* b)
{
if ((a != NULL) && (b == NULL)) return FALSE;
if ((a == NULL) && (b != NULL)) return FALSE;
if ((a != NULL) && (b != NULL)) {
if (g_ascii_strcasecmp (a, b) != 0) {
return FALSE;
}
}
return TRUE;
}
static void set_civic_location (GeocluePosition *obj,
char* country,
char* region,
char* locality,
char* area,
char* postalcode,
char* street,
char* building,
char* floor,
char* room,
char* text)
{
if (!is_same_string (obj->civic_country, country) ||
!is_same_string (obj->civic_region, region) ||
!is_same_string (obj->civic_locality, locality) ||
!is_same_string (obj->civic_area, area) ||
!is_same_string (obj->civic_postalcode, postalcode) ||
!is_same_string (obj->civic_street, street) ||
!is_same_string (obj->civic_building, building) ||
!is_same_string (obj->civic_floor, floor) ||
!is_same_string (obj->civic_room, room) ||
!is_same_string (obj->civic_text, text)) {
obj->civic_country = g_strdup (country);
obj->civic_region = g_strdup (region);
obj->civic_locality = g_strdup (locality);
obj->civic_area = g_strdup (area);
obj->civic_postalcode = g_strdup (postalcode);
obj->civic_street = g_strdup (street);
obj->civic_building = g_strdup (building);
obj->civic_floor = g_strdup (floor);
obj->civic_room = g_strdup (room);
obj->civic_text = g_strdup (text);
geoclue_position_civic_location_changed (obj,
country, region, locality, area,
postalcode, street, building,
floor, room, text);
}
/* if net connection is monitored, the validity of location can be guaranteed */
obj->is_civic_valid = OBSERVING_NET_CONNECTIONS;
}
static void
geoclue_position_init (GeocluePosition *obj)
{
......@@ -388,7 +566,7 @@ geoclue_position_class_init (GeocluePositionClass *klass)
klass->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
signals[CURRENT_POSITION_CHANGED] =
signals[CURRENT_POSITION_CHANGED] =
g_signal_new ("current_position_changed",
TYPE_GEOCLUE_POSITION,
G_SIGNAL_RUN_LAST,
......@@ -397,8 +575,20 @@ geoclue_position_class_init (GeocluePositionClass *klass)
NULL,
_geoclue_position_VOID__DOUBLE_DOUBLE,
G_TYPE_NONE, 2 ,G_TYPE_DOUBLE, G_TYPE_DOUBLE);
klass->current_position_changed = geoclue_position_current_position_changed;
signals[CIVIC_LOCATION_CHANGED] =
g_signal_new ("civic_location_changed",
TYPE_GEOCLUE_POSITION,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GeocluePositionClass, civic_location_changed),
NULL,
NULL,
_geoclue_position_VOID__STRING_STRING_STRING_STRING_STRING_STRING_STRING_STRING_STRING_STRING,
G_TYPE_NONE, 10, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
klass->civic_location_changed = geoclue_position_civic_location_changed;
if (klass->connection == NULL)
{
......@@ -550,43 +740,34 @@ gboolean geoclue_position_civic_location (GeocluePosition* obj,
char** OUT_text,
GError** error)
{
xmlXPathContextPtr xpathCtx;
gboolean valid = FALSE; /* consider location valid if any data type is present */
gchar* query_url;
gchar* mac_address;
if (!get_mac_address (&mac_address)) {
g_set_error (error,
GEOCLUE_POSITION_ERROR,
GEOCLUE_POSITION_ERROR_FAILED,
"Could not find out MAC address of the router");
return FALSE;
}
query_url = g_strdup_printf("%s?mac_address=%s", WEBSERVICE_API, mac_address);
g_free (mac_address);
if (!(xpathCtx = get_xpath_context (query_url, error))) {
return FALSE;
}
valid = evaluate_xpath_string (OUT_country, xpathCtx, "//plaze/country") || valid;
valid = evaluate_xpath_string (OUT_locality, xpathCtx, "//plaze/city") || valid;
valid = evaluate_xpath_string (OUT_postalcode, xpathCtx, "//plaze/zip_code") || valid;
valid = evaluate_xpath_string (OUT_street, xpathCtx, "//plaze/address") || valid;
valid = evaluate_xpath_string (OUT_text, xpathCtx, "//plaze/name") || valid;
xmlXPathFreeContext(xpathCtx);
g_debug ("location: %s, %s, %s, %s, %s", *OUT_country, *OUT_locality, *OUT_postalcode, *OUT_street, *OUT_text);
if (!valid){
g_set_error (error,
GEOCLUE_POSITION_ERROR,
GEOCLUE_POSITION_ERROR_NODATA,
"%s does not have civic location for this router MAC address.", WEBSERVICE_API);
g_debug ("civic location");
if (obj->is_civic_valid) {
g_debug ("current civic is valid");
*OUT_country = g_strdup (obj->civic_country);
*OUT_region = g_strdup (obj->civic_region);
*OUT_locality = g_strdup (obj->civic_locality);
*OUT_area = g_strdup (obj->civic_area);
*OUT_postalcode = g_strdup (obj->civic_postalcode);
*OUT_street = g_strdup (obj->civic_street);
*OUT_building = g_strdup (obj->civic_building);
*OUT_floor = g_strdup (obj->civic_floor);
*OUT_room = g_strdup (obj->civic_room);
*OUT_text = g_strdup (obj->civic_text);
return TRUE;
} else if (query_civic_location (OUT_country, OUT_region, OUT_locality, OUT_area,
OUT_postalcode, OUT_street, OUT_building,
OUT_floor, OUT_room, OUT_text,
error)) {
g_debug ("civic queried");
set_civic_location (obj,
*OUT_country, *OUT_region, *OUT_locality, *OUT_area,
*OUT_postalcode, *OUT_street, *OUT_building,
*OUT_floor, *OUT_room, *OUT_text);
return TRUE;
} else {
g_debug ("civic query failed");
return FALSE;
}
return TRUE;
}
......@@ -670,6 +851,7 @@ int main(int argc, char **argv)
obj->loop = g_main_loop_new(NULL,TRUE);
g_debug ("Running main loop");
g_main_loop_run(obj->loop);
g_object_unref(obj);
......
......@@ -52,6 +52,19 @@ struct GeocluePosition
gdouble current_lat;
gdouble current_lon;
gboolean is_current_valid;
gchar* civic_country;
gchar* civic_region;
gchar* civic_locality;
gchar* civic_area;
gchar* civic_postalcode;
gchar* civic_street;
gchar* civic_building;
gchar* civic_floor;
gchar* civic_room;
gchar* civic_text;
gboolean is_civic_valid;
#ifdef HAVE_LIBCONIC
ConIcConnection* net_connection;
DBusConnection* dbus_connection;
......@@ -65,6 +78,7 @@ struct GeocluePositionClass
/* Signals */
void (*current_position_changed) (GeocluePosition*, gdouble, gdouble );
void (*civic_location_changed) (GeocluePosition*, gchar*, gchar*, gchar*, gchar*, gchar*, gchar*, gchar*, gchar*, gchar*, gchar*);
};
#define TYPE_GEOCLUE_POSITION (geoclue_position_get_type ())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment