/* diversity-ap.c - DiversityAp * * Copyright 2007-2008 OpenMoko, Inc. * Authored by Chia-I Wu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Inspired by NMAccessPoint from libnm-glib. */ #include /* for strcmp and memset */ #include #include #include #include "diversity-marshal.h" enum { DUMMY, LAST_SIGNAL }; enum { PROP_0, PROP_IN_SERVICE, PROP_FLAGS, PROP_WPA_FLAGS, PROP_RSN_FLAGS, PROP_SSID, PROP_FREQUENCY, PROP_HW_ADDRESS, PROP_MODE, PROP_RATE, PROP_STRENGTH, }; #define DIVERSITY_AP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), DIVERSITY_TYPE_AP, DiversityApPrivate)) typedef struct _DiversityApPrivate DiversityApPrivate; struct _DiversityApPrivate { gboolean in_service; guint32 flags; guint32 wpa_flags; guint32 rsn_flags; gchar *ssid; guint32 frequency; gchar *hw_address; gint mode; guint32 rate; gint8 strength; /* TODO geometry_set should be overrided to update grid */ gint8 grid[DIVERSITY_AP_STRENGTH_GRID * DIVERSITY_AP_STRENGTH_GRID]; }; static guint ap_signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE(DiversityAp, diversity_ap, DIVERSITY_TYPE_OBJECT); static void diversity_ap_finalize(GObject *obj) { DiversityAp *ap = DIVERSITY_AP(obj); DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); g_free(priv->ssid); g_free(priv->hw_address); ((GObjectClass *) diversity_ap_parent_class)->finalize(obj); } static void diversity_ap_set_property(GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec) { DiversityAp *ap = DIVERSITY_AP(obj); switch (prop_id) { case PROP_IN_SERVICE: diversity_ap_set_in_service(ap, g_value_get_boolean(value)); break; case PROP_FLAGS: diversity_ap_set_flags(ap, g_value_get_uint(value)); break; case PROP_WPA_FLAGS: diversity_ap_set_wpa_flags(ap, g_value_get_uint(value)); break; case PROP_RSN_FLAGS: diversity_ap_set_rsn_flags(ap, g_value_get_uint(value)); break; case PROP_SSID: diversity_ap_set_ssid(ap, g_value_get_string(value)); break; case PROP_FREQUENCY: diversity_ap_set_frequency(ap, g_value_get_uint(value)); break; case PROP_HW_ADDRESS: diversity_ap_set_hw_address(ap, g_value_get_string(value)); break; case PROP_MODE: diversity_ap_set_mode(ap, g_value_get_int(value)); break; case PROP_RATE: diversity_ap_set_rate(ap, g_value_get_uint(value)); break; case PROP_STRENGTH: diversity_ap_set_strength(ap, g_value_get_char(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec); break; } } static void diversity_ap_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) { DiversityAp *ap = DIVERSITY_AP(obj); DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); switch (prop_id) { case PROP_IN_SERVICE: g_value_set_boolean(value, priv->in_service); break; case PROP_FLAGS: g_value_set_uint(value, priv->flags); break; case PROP_WPA_FLAGS: g_value_set_uint(value, priv->wpa_flags); break; case PROP_RSN_FLAGS: g_value_set_uint(value, priv->rsn_flags); break; case PROP_SSID: g_value_set_string(value, priv->ssid); break; case PROP_FREQUENCY: g_value_set_uint(value, priv->frequency); break; case PROP_HW_ADDRESS: g_value_set_string(value, priv->hw_address); break; case PROP_MODE: g_value_set_int(value, priv->mode); break; case PROP_RATE: g_value_set_uint(value, priv->rate); break; case PROP_STRENGTH: g_value_set_char(value, priv->strength); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec); break; } } static void diversity_ap_class_init(DiversityApClass *klass) { GObjectClass *o_class = (GObjectClass *) klass; o_class->finalize = diversity_ap_finalize; o_class->set_property = diversity_ap_set_property; o_class->get_property = diversity_ap_get_property; g_type_class_add_private(klass, sizeof(DiversityApPrivate)); g_object_class_install_property(o_class, PROP_IN_SERVICE, g_param_spec_boolean("in_service", "In service", "AP is in service", FALSE, G_PARAM_READWRITE)); g_object_class_install_property(o_class, PROP_FLAGS, g_param_spec_uint("flags", "Flags", "Flags", 0, G_MAXUINT32, 0, G_PARAM_READWRITE)); g_object_class_install_property(o_class, PROP_WPA_FLAGS, g_param_spec_uint("wpa_flags", "WPA Flags", "WPA Flags", 0, G_MAXUINT32, 0, G_PARAM_READWRITE)); g_object_class_install_property(o_class, PROP_RSN_FLAGS, g_param_spec_uint("rsn_flags", "RSN Flags", "RSN Flags", 0, G_MAXUINT32, 0, G_PARAM_READWRITE)); g_object_class_install_property(o_class, PROP_SSID, g_param_spec_string("ssid", "SSID", "SSID", "", G_PARAM_READWRITE)); g_object_class_install_property(o_class, PROP_FREQUENCY, g_param_spec_uint("frequency", "Frequency", "Frequency", 0, 10000, 0, G_PARAM_READWRITE)); g_object_class_install_property(o_class, PROP_HW_ADDRESS, g_param_spec_string("hw_address", "MAC Address", "Hardware MAC address", NULL, G_PARAM_READWRITE)); g_object_class_install_property(o_class, PROP_MODE, g_param_spec_int("mode", "Mode", "Mode", 0, 100, 0, G_PARAM_READWRITE)); g_object_class_install_property(o_class, PROP_RATE, g_param_spec_uint("rate", "Rate", "Rate", 0, G_MAXUINT32, 0, G_PARAM_READWRITE)); g_object_class_install_property(o_class, PROP_STRENGTH, g_param_spec_char("strength", "Strength", "Strength", G_MININT8, G_MAXINT8, 0, G_PARAM_READWRITE)); ap_signals[DUMMY] = g_signal_new("dummy", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(DiversityApClass, dummy), NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); } static void diversity_ap_init(DiversityAp *ap) { DiversityObject *obj = DIVERSITY_OBJECT(ap); DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); obj->type = DIVERSITY_OBJECT_TYPE_AP; memset(priv, 0, sizeof(*priv)); } DiversityAp *diversity_ap_new(void) { DiversityAp *ap; ap = g_object_new(DIVERSITY_TYPE_AP, NULL); return ap; } void diversity_ap_set_in_service(DiversityAp *ap, gboolean in_service) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); if (priv->in_service != in_service) { priv->in_service = in_service; g_object_notify(G_OBJECT(ap), "in_service"); } } gboolean diversity_ap_get_in_service(DiversityAp *ap) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); return priv->in_service; } void diversity_ap_set_flags(DiversityAp *ap, guint32 flags) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); priv->flags = flags; g_object_notify(G_OBJECT(ap), "flags"); } guint32 diversity_ap_get_flags(DiversityAp *ap) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); return priv->flags; } void diversity_ap_set_wpa_flags(DiversityAp *ap, guint32 wpa_flags) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); priv->wpa_flags = wpa_flags; g_object_notify(G_OBJECT(ap), "wpa_flags"); } guint32 diversity_ap_get_wpa_flags(DiversityAp *ap) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); return priv->wpa_flags; } void diversity_ap_set_rsn_flags(DiversityAp *ap, guint32 rsn_flags) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); priv->rsn_flags = rsn_flags; g_object_notify(G_OBJECT(ap), "rsn_flags"); } guint32 diversity_ap_get_rsn_flags(DiversityAp *ap) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); return priv->rsn_flags; } void diversity_ap_set_ssid(DiversityAp *ap, const gchar *ssid) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); if (priv->ssid) g_free(priv->ssid); priv->ssid = g_strdup(ssid); g_object_notify(G_OBJECT(ap), "ssid"); } const gchar *diversity_ap_get_ssid(DiversityAp *ap) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); return priv->ssid; } void diversity_ap_set_frequency(DiversityAp *ap, guint32 freq) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); priv->frequency = freq; g_object_notify(G_OBJECT(ap), "frequency"); } guint32 diversity_ap_get_frequency(DiversityAp *ap) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); return priv->frequency; } void diversity_ap_set_hw_address(DiversityAp *ap, const gchar *hw_address) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); if (priv->hw_address) g_free(priv->hw_address); priv->hw_address = g_strdup(hw_address); g_object_notify(G_OBJECT(ap), "hw_address"); } const gchar *diversity_ap_get_hw_address(DiversityAp *ap) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); return priv->hw_address; } void diversity_ap_set_mode(DiversityAp *ap, gint mode) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); priv->mode = mode; g_object_notify(G_OBJECT(ap), "mode"); } gint diversity_ap_get_mode(DiversityAp *ap) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); return priv->mode; } void diversity_ap_set_rate(DiversityAp *ap, guint32 rate) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); priv->rate = rate; g_object_notify(G_OBJECT(ap), "rate"); } guint32 diversity_ap_get_rate(DiversityAp *ap) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); return priv->rate; } void diversity_ap_set_strength(DiversityAp *ap, gint8 strength) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); priv->strength = strength; g_object_notify(G_OBJECT(ap), "strength"); } gint8 diversity_ap_get_strength(DiversityAp *ap) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); return priv->strength; } void diversity_ap_update_strength_grid(DiversityAp *ap, gdouble x, gdouble y, gint8 strength) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); DiversityRectangle rect; gint i, j; diversity_object_geometry_get(DIVERSITY_OBJECT(ap), &rect.x, &rect.y, &rect.width, &rect.height); /* TODO adjust geometry */ if (!DIVERSITY_RECTANGLE_HAVE(&rect, x, y)) return; i = (gint) (DIVERSITY_AP_STRENGTH_GRID * (x - rect.x) / rect.width); j = (gint) (DIVERSITY_AP_STRENGTH_GRID * (y - rect.y) / rect.height); priv->grid[i * DIVERSITY_AP_STRENGTH_GRID + j] = strength; diversity_ap_set_strength(ap, strength); } void diversity_ap_merge(DiversityAp *ap, DiversityAp *src) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); DiversityApPrivate *src_priv = DIVERSITY_AP_GET_PRIVATE(src); g_object_freeze_notify(G_OBJECT(ap)); if (priv->in_service != src_priv->in_service) diversity_ap_set_in_service(ap, src_priv->in_service); if (priv->flags != src_priv->flags) diversity_ap_set_flags(ap, src_priv->flags); if (priv->wpa_flags != src_priv->wpa_flags) diversity_ap_set_wpa_flags(ap, src_priv->wpa_flags); if (priv->rsn_flags != src_priv->rsn_flags) diversity_ap_set_rsn_flags(ap, src_priv->rsn_flags); if (priv->ssid && src_priv->ssid) { if (strcmp(priv->ssid, src_priv->ssid) != 0) diversity_ap_set_ssid(ap, src_priv->ssid); } else { diversity_ap_set_ssid(ap, src_priv->ssid); } if (priv->frequency != src_priv->frequency) diversity_ap_set_frequency(ap, src_priv->frequency); if (priv->hw_address && src_priv->hw_address) { if (strcmp(priv->hw_address, src_priv->hw_address) != 0) diversity_ap_set_hw_address(ap, src_priv->hw_address); } else { diversity_ap_set_hw_address(ap, src_priv->hw_address); } if (priv->mode != src_priv->mode) diversity_ap_set_mode(ap, src_priv->mode); if (priv->rate != src_priv->rate) diversity_ap_set_rate(ap, src_priv->rate); if (priv->strength != src_priv->strength) diversity_ap_set_strength(ap, src_priv->strength); g_object_thaw_notify(G_OBJECT(ap)); } const gint8 *diversity_ap_get_strength_grid(DiversityAp *ap) { DiversityApPrivate *priv = DIVERSITY_AP_GET_PRIVATE(ap); return priv->grid; }