/* AP Radar * June 2002 * donald.g.park@iname.com * * Released under the MIT Open Source Licence * http://www.opensource.org/licenses/mit-license.php */ #include #include //#include // some day #include // for sprintf #include #include #include #include "Window.h" #include "Parent.h" #include "Main.h" #include "AccessPointList.h" #include "NetworkInterface.h" #include "Ipv4Address.h" using SigC::slot; using SigC::bind; using namespace std; using namespace Gtk::Menu_Helpers; Window::Window() //: Gtk::Window(GTK_WINDOW_TOPLEVEL) { } void Window::init() { // The idle call is in Window because I could only register a method // of a class that inherits from GTK. Only this class has the mojo, // register_data(), that makes the slot call work. // Connect idle function - 5000 milisecond delay Glib::signal_timeout().connect(SigC::slot(*this, &Window::goIdle), 5000); char title[128]; sprintf(title, "AP Radar %s", PACKAGE_VERSION); set_title (title); set_border_width (0); main_vbox = new Gtk::VBox(false, 0) ; add(*main_vbox); logo_hbox = new Gtk::HBox(false, 0) ; Gtk::Image* wrench; string wrenchpath = (*(conf->getDirname()))+"/wrench.png"; wrench = new Gtk::Image (wrenchpath); Gtk::Button* configbutton = new Gtk::Button(); configbutton->set_relief(Gtk::RELIEF_NONE); configbutton->add(*wrench); configbutton->signal_clicked().connect(bind(slot(*this, &Window::wrench_button_clicked), 1)); logo_hbox->pack_start(*configbutton,Gtk::PACK_SHRINK,9); Gtk::Image* logo; string logopath = (*(conf->getDirname()))+"/logo.png"; logo = new Gtk::Image (logopath); logo_hbox->pack_start(*logo); main_vbox->add(*logo_hbox); aplist_frame = new Gtk::Frame ("Access Point List"); main_vbox->pack_start (*aplist_frame); eth_frame = new Gtk::Frame ("eth?"); main_vbox->pack_start (*eth_frame); aplist_vbox = new Gtk::VBox(false, 0); aplist_frame->add(*aplist_vbox); eth_vbox = new Gtk::VBox(false, 0); eth_frame->add(*eth_vbox); // how do i change the font? //Glib::RefPtr style = eth_vbox->get_modifier_style(); //Pango::FontDescription* font = new Pango::FontDescription("Sans Regular 18"); //style->set_font(*font); //eth_vbox->modify_style(style); string iconpath = (*(conf->getDirname()))+"/icon.xpm"; set_default_icon_from_file(iconpath); show_all (); // build config frame config_frame_flag = false; config_frame = new Gtk::Frame("config"); Gtk::VBox* config_vbox = new Gtk::VBox(false,0); // config option: ping default gateway Gtk::CheckButton* cb = new Gtk::CheckButton("ping default gateway"); cb->set_active(conf->getPingGateway()); // default true cb->signal_toggled().connect( bind(slot(*this, &Window::ping_config_clicked), cb)); config_vbox->pack_start(*cb); Gtk::CheckButton* cb2 = new Gtk::CheckButton("run "+ *(conf->getDhcpCommand())+" on associate"); cb2->set_active(conf->getRunDhcp()); // default true cb2->signal_toggled().connect( bind(slot(*this, &Window::dhclient_config_clicked), cb2)); config_vbox->pack_start(*cb2); // setup the preferred essid list (broken) Gtk::TreeModelColumn* essid = new Gtk::TreeModelColumn(); Gtk::TreeModelColumnRecord elist; elist.add(*essid); Glib::RefPtr essidlist = Gtk::ListStore::create(elist); Gtk::TreeModel::iterator iter = essidlist->append(); Gtk::TreeModel::Row row = *iter; row[*essid] = "www.personaltelco.net"; Gtk::TreeView* tv = new Gtk::TreeView(essidlist); config_vbox->pack_start(*tv); // add the vbox to the frame config_frame->add(*config_vbox); } Window::~Window() {} void Window::DHCPon() { dhcp_vbox = new Gtk::VBox(false, 0); Gtk::Label* label = new Gtk::Label(); label->set_label("dhcpcd started"); dhcp_vbox->pack_start(*label,true,true,0); //eth_horz->add(*dhcp_vbox); show_all(); } void Window::DHCPoff() { } bool Window::goIdle() { cout << endl; cout << " == Timer started AP Scan == " << endl; if(conf->getInterface() == NULL) { cout << "No wireless interface was found (try -i ethX). skipping AP scan" << endl; return 1; } conf->syncAPList(conf->getMain()->ScanAPs()); setInterface(conf->getInterface()); if(conf->getPingGateway()) { // ping the gateway Ipv4Address* gateway = conf->getInterface()->getIpv4Gateway(); if(gateway) { conf->getInterface()->ping(gateway); if(conf->getInterface()->getGatewayPingTime() > 0) { time_t wait = time(NULL) - conf->getInterface()->getGatewayPingTime(); ostringstream o; if(wait == 0 ) { o << "<1 sec"; } else { o << wait; if (wait > 1) { o << " secs"; } else { o << " sec"; } } default_delay_button->set_label(o.str()); } } } return 1; } gint Window::delete_event_impl (GdkEventAny*) { Gtk::Main::quit(); return 0; } AccessPointList* ScanAPs(); void Window::on_button_clicked(char *data) { //cout << "button push - data:" << "\"" << data << "\"" << endl; conf->syncAPList(conf->getMain()->ScanAPs()); } void Window::dhclient_config_clicked(Gtk::CheckButton* b) { if(b->get_active()) { conf->setRunDhcp(true); } else { conf->setRunDhcp(false); } conf->saveConfigOptions(); } void Window::ping_config_clicked(Gtk::CheckButton* b) { if(b->get_active()) { conf->setPingGateway(true); } else { conf->setPingGateway(false); } conf->saveConfigOptions(); } void Window::wrench_button_clicked(int a) { // Test for the presence of aplist_frame before removing // cant get this to work // Glib::ListHandle widgetlist = main_vbox->get_children(); // Glib::ListHandle::const_iterator temp = widgetlist.begin(); // while(temp) { // if(*temp == *aplist_frame) { // cout << "saw aplist_frame!" << endl; // main_vbox->remove(*aplist_frame); // } // temp = temp++; // } if(config_frame_flag) { main_vbox->remove(*config_frame); resize(width, height); config_frame_flag = false; } else { // remember the window size before the config // frame is added get_size(width, height); main_vbox->pack_end(*config_frame); config_frame_flag = true; } show_all(); // Use a separate config window // Gtk::Window* w = new Gtk::Window(); // w->set_title(*(new Glib::ustring("AP Radar Config"))); // w->add(*config_frame); // w->show_all(); } void Window::AP_button_clicked(AccessPoint *data) { cout << "an AP button was pushed - " << data->getEssid() << endl; // build a menu - this should be on a right click. not sure how todo that. menu = manage(new Gtk::Menu()); menu->items().push_back(MenuElem("Associate", AccelKey("a"))); menu->items().push_back(MenuElem("Monitor", AccelKey("m"))); //add popup stuff later //menu->popup(0,0); if(conf->getInterface() != NULL) { conf->getInterface()->associate(data); DHCPon(); } // make the window refresh setInterface(conf->getInterface()); } void Window::add_AP(AccessPoint* ap) { Gtk::Button *button; button = manage ( new Gtk::Button (ap->getEssid()->c_str())); button->set_relief(Gtk::RELIEF_NONE); button->signal_clicked().connect(bind(slot(*this, &Window::AP_button_clicked), ap)); Gtk::Box *hbox; hbox = manage( new Gtk::HBox(false, 0) ); ap->setUiRow(hbox); aplist_vbox->pack_start (*hbox, true, true, 0); hbox->pack_start(*button, true, true, 0); string* modebuttonname; if(ap->getModeString() != NULL) { modebuttonname = ap->getModeString(); } else { modebuttonname = new string("Unknown mode"); } button = manage ( new Gtk::Button (modebuttonname->c_str())); button->set_relief(Gtk::RELIEF_NONE); hbox->pack_start(*button, true, true, 0); Gtk::Image* logo; string* wepbuttonname; string* weptip; if(ap->getWEP() == -1) { wepbuttonname = new string("WEP unknown"); } if(ap->getWEP() == 0) { wepbuttonname = new string("wep off"); string iconpath = (*(conf->getDirname()))+"/wepoff.png"; logo = manage( new Gtk::Image (iconpath )); weptip = new string("WEP encryption off"); } if(ap->getWEP() == 1) { wepbuttonname = new string("wep on"); string iconpath = (*(conf->getDirname()))+"/wepon.png"; logo = manage( new Gtk::Image (iconpath )); weptip = new string("WEP key: XX"); } button = manage ( new Gtk::Button ()); button->add(*logo); button->set_relief(Gtk::RELIEF_NONE); hbox->pack_start(*button, true, true, 0); tooltips.set_tip(*button,*weptip); string* frequencyname; char buf[15]; //sprintf(buf,"%1.3fGHz", ap->getFrequency() / 1000 / 1000 / 1000); sprintf(buf,"Ch %d", ap->getChannel()); frequencyname = new string(buf); button = manage ( new Gtk::Button (frequencyname->c_str())); button->set_relief(Gtk::RELIEF_NONE); hbox->pack_start(*button, true, true, 0); tooltips.set_tip(*button,"channel"); string* signalstrengthname; //sprintf(buf,"%1.3fGHz", ap->getFrequency() / 1000 / 1000 / 1000); sprintf(buf,"%d dBm", ap->getSignalStrength()); signalstrengthname = new string(buf); button = manage ( new Gtk::Button (signalstrengthname->c_str())); ap->signalStrengthButton = button; button->set_relief(Gtk::RELIEF_NONE); hbox->pack_start(*button, true, true, 0); tooltips.set_tip(*button,"signal strength"); show_all(); } void Window::refresh_AP(AccessPoint* ap) { // update signal strength char buf[15]; sprintf(buf,"%d dBm", ap->getSignalStrength()); ap->getUiRow()->remove(*(ap->signalStrengthButton)); Gtk::Button* button; button = new Gtk::Button(buf); ap->signalStrengthButton=button; ap->getUiRow()->pack_start(*button, true, true, 0); } void Window::remove_AP(AccessPoint* ap) { cout << "Removing AP " << *(ap->getEssid()) << endl; aplist_vbox->remove(*(ap->getUiRow())); } void Window::setConfig(Config* c) { conf = c; } void Window::setInterface(NetworkInterface* n) { if (n == NULL) return; if(eth_vbox->children().size() > 0 ) { eth_vbox->children().clear(); } const Glib::ustring* str2; string part1 = *(n->getName()); string part2 = *(n->getDriverName()); string together = part1.append('(' + part2 + ')'); str2 = new Glib::ustring(together); eth_frame->set_label(*str2); Gtk::HBox* interface_hbox1 = new Gtk::HBox(); eth_vbox->pack_start (*interface_hbox1, Gtk::PACK_SHRINK, 0); Gtk::Button* button; // test for nulls in each field const char* essid_str = n->getEssid()->c_str(); if(essid_str == NULL) essid_str="______"; button = new Gtk::Button (essid_str); button->set_relief(Gtk::RELIEF_NONE); interface_hbox1->pack_start(*button); button = new Gtk::Button (n->getModeString()->c_str()); button->set_relief(Gtk::RELIEF_NONE); interface_hbox1->pack_start(*button); string* ipaddr = new string; Ipv4Address* ipaddy = n->getIpv4Address(); if(ipaddy != NULL) { ipaddr = ipaddy->toString(); } else { ipaddr = new string("__.__.__.__"); } button = new Gtk::Button (ipaddr->c_str()); button->set_relief(Gtk::RELIEF_NONE); interface_hbox1->pack_start(*button); // line 2 Gtk::HBox* interface_hbox2 = new Gtk::HBox(); Gtk::Label* defroute = new Gtk::Label("default gateway:"); interface_hbox2->pack_start(*defroute, Gtk::PACK_SHRINK, 6); ipaddr = new string; ipaddy = n->getIpv4Gateway(); if(ipaddy != NULL) { ipaddr = ipaddy->toString(); } else { ipaddr = new string("__.__.__.__"); } button = new Gtk::Button (ipaddr->c_str()); button->set_relief(Gtk::RELIEF_NONE); interface_hbox2->pack_start(*button,Gtk::PACK_SHRINK,0); default_delay_button = new Gtk::Button(); default_delay_button->set_relief(Gtk::RELIEF_NONE); interface_hbox2->pack_start(*default_delay_button,Gtk::PACK_SHRINK,0); tooltips.set_tip(*default_delay_button,"default gateway ping time"); eth_vbox->pack_start (*interface_hbox2, Gtk::PACK_SHRINK, 0); show_all(); } /* * Copyright (c) 2002 Donald G. Park * The MIT License * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */