1/* ----------------------------------------------------------------------- 2 * Copyright (c) 2003-2004 Waldemar Kornewald, Waldemar.Kornewald@web.de 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 * ----------------------------------------------------------------------- */ 22 23#include "DialUpView.h" 24#include "DialUpAddon.h" 25 26#include <cstring> 27#include "InterfaceUtils.h" 28#include "MessageDriverSettingsUtils.h" 29#include "TextRequestDialog.h" 30 31// built-in add-ons 32#include "ConnectionOptionsAddon.h" 33#include "GeneralAddon.h" 34#include "IPCPAddon.h" 35#include "PPPoEAddon.h" 36 37#include <PPPInterface.h> 38#include <settings_tools.h> 39#include <TemplateList.h> 40 41#include <Application.h> 42 43#include <Alert.h> 44#include <Button.h> 45#include <MenuField.h> 46#include <MenuItem.h> 47#include <Messenger.h> 48#include <PopUpMenu.h> 49#include <StringView.h> 50#include <TabView.h> 51 52#include <Directory.h> 53#include <Entry.h> 54#include <File.h> 55#include <Path.h> 56 57 58// message constants 59static const uint32 kMsgCreateNew = 'NEWI'; 60static const uint32 kMsgFinishCreateNew = 'FNEW'; 61static const uint32 kMsgDeleteCurrent = 'DELI'; 62static const uint32 kMsgSelectInterface = 'SELI'; 63static const uint32 kMsgConnectButton = 'CONI'; 64 65// labels 66#ifdef LANG_GERMAN 67static const char *kLabelInterface = "Verbindung: "; 68static const char *kLabelInterfaceName = "Verbindungs-Name: "; 69static const char *kLabelCreateNewInterface = "Neue Verbindung Erstellen"; 70static const char *kLabelCreateNew = "Neu..."; 71static const char *kLabelDeleteCurrent = "Auswahl L��schen"; 72static const char *kLabelConnect = "Verbinden"; 73static const char *kLabelDisconnect = "Trennen"; 74static const char *kLabelOK = "OK"; 75#else 76static const char *kLabelInterface = "Interface: "; 77static const char *kLabelInterfaceName = "Interface Name: "; 78static const char *kLabelCreateNewInterface = "Create New Interface"; 79static const char *kLabelCreateNew = "Create New..."; 80static const char *kLabelDeleteCurrent = "Delete Current"; 81static const char *kLabelConnect = "Connect"; 82static const char *kLabelDisconnect = "Disconnect"; 83static const char *kLabelOK = "OK"; 84#endif 85 86// connection status strings 87#ifdef LANG_GERMAN 88static const char *kTextConnecting = "Verbinde..."; 89static const char *kTextConnectionEstablished = "Verbindung hergestellt."; 90static const char *kTextNotConnected = "Nicht verbunden."; 91static const char *kTextDeviceUpFailed = "Konnte Verbindung nicht aufbauen."; 92static const char *kTextAuthenticating = "Authentifizierung..."; 93static const char *kTextAuthenticationFailed = "Authentifizierung fehlgeschlagen!"; 94static const char *kTextConnectionLost = "Verbindung verloren!"; 95static const char *kTextCreationError = "Fehler beim Initialisieren!"; 96static const char *kTextNoInterfacesFound = "Bitte erstellen Sie eine neue " 97 "Verbindung."; 98static const char *kTextChooseInterfaceName = "Bitte denken Sie sich einen neuen " 99 "Namen f��r diese Verbindung aus."; 100#else 101static const char *kTextConnecting = "Connecting..."; 102static const char *kTextConnectionEstablished = "Connection established."; 103static const char *kTextNotConnected = "Not connected."; 104static const char *kTextDeviceUpFailed = "Failed to connect."; 105static const char *kTextAuthenticating = "Authenticating..."; 106static const char *kTextAuthenticationFailed = "Authentication failed!"; 107static const char *kTextConnectionLost = "Connection lost!"; 108static const char *kTextCreationError = "Error creating interface!"; 109static const char *kTextNoInterfacesFound = "Please create a new interface..."; 110static const char *kTextChooseInterfaceName = "Please choose a new name for this " 111 "interface."; 112#endif 113 114// error strings for alerts 115#ifdef LANG_GERMAN 116static const char *kErrorTitle = "Fehler"; 117static const char *kErrorNoPPPStack = "Fehler: Kein Zugriff auf den PPP Stack!"; 118static const char *kErrorInterfaceExists = "Fehler: Eine Verbindung mit diesem Namen " 119 "existiert bereits!"; 120static const char *kErrorLoadingFailed = "Fehler: Konfiguration ist fehlerhaft! Die " 121 "Einstellungen werden zur��ckgesetzt."; 122static const char *kErrorSavingFailed = "Fehler: Speichern der Einstellungen ist " 123 "fehlgeschlagen!"; 124#else 125static const char *kErrorTitle = "Error"; 126static const char *kErrorNoPPPStack = "Error: Could not access the PPP stack!"; 127static const char *kErrorInterfaceExists = "Error: An interface with this name " 128 "already exists!"; 129static const char *kErrorLoadingFailed = "Error: Failed loading interface! The " 130 "current settings will be deleted."; 131static const char *kErrorSavingFailed = "Error: Failed saving interface settings!"; 132#endif 133 134 135static 136status_t 137up_down_thread(void *data) 138{ 139 static_cast<DialUpView*>(data)->UpDownThread(); 140 return B_OK; 141} 142 143 144DialUpView::DialUpView(BRect frame) 145 : BView(frame, "DialUpView", B_FOLLOW_ALL, 0), 146 fListener(this), 147 fUpDownThread(-1), 148 fDriverSettings(NULL), 149 fCurrentItem(NULL), 150 fWatching(PPP_UNDEFINED_INTERFACE_ID), 151 fKeepLabel(false) 152{ 153 BRect bounds = Bounds(); 154 // for caching 155 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 156 157 // add messenger to us so add-ons can contact us 158 BMessenger messenger(this); 159 fAddons.AddMessenger(DUN_MESSENGER, messenger); 160 161 // create pop-up with all interfaces and "New..."/"Delete current" items 162 fInterfaceMenu = new BPopUpMenu(kLabelCreateNew); 163 BRect rect = bounds; 164 rect.InsetBy(5, 5); 165 rect.bottom = rect.top + 20; 166 fMenuField = new BMenuField(rect, "Interfaces", kLabelInterface, fInterfaceMenu); 167 fMenuField->SetDivider(StringWidth(fMenuField->Label()) + 5); 168 169 rect.top = rect.bottom + 10; 170 rect.bottom = bounds.bottom 171 - 20 // height of bottom controls 172 - 20; // space for bottom controls 173 fTabView = new BTabView(rect, "TabView", B_WIDTH_FROM_LABEL); 174 BRect tabViewRect(fTabView->Bounds()); 175 tabViewRect.bottom -= fTabView->TabHeight(); 176 fAddons.AddRect(DUN_TAB_VIEW_RECT, tabViewRect); 177 178 BRect tmpRect(rect); 179 tmpRect.top += (tmpRect.Height() - 15) / 2; 180 tmpRect.bottom = tmpRect.top + 15; 181 fStringView = new BStringView(tmpRect, "NoInterfacesFound", 182 kTextNoInterfacesFound); 183 fStringView->SetAlignment(B_ALIGN_CENTER); 184 fStringView->Hide(); 185 tmpRect.top = tmpRect.bottom + 10; 186 tmpRect.bottom = tmpRect.top + 25; 187 fCreateNewButton = new BButton(tmpRect, "CreateNewButton", 188 kLabelCreateNewInterface, new BMessage(kMsgCreateNew)); 189 fCreateNewButton->ResizeToPreferred(); 190 tmpRect.left = (rect.Width() - fCreateNewButton->Bounds().Width()) / 2 + rect.left; 191 fCreateNewButton->MoveTo(tmpRect.left, tmpRect.top); 192 fCreateNewButton->Hide(); 193 194 rect.top = rect.bottom + 15; 195 rect.bottom = rect.top + 15; 196 rect.right = rect.left + 200; 197 fStatusView = new BStringView(rect, "StatusView", kTextNotConnected, B_FOLLOW_BOTTOM); 198 199 rect.InsetBy(0, -5); 200 rect.left = rect.right + 5; 201 rect.right = bounds.right - 5; 202 fConnectButton = new BButton(rect, "ConnectButton", kLabelConnect, 203 new BMessage(kMsgConnectButton), B_FOLLOW_BOTTOM); 204 205 AddChild(fMenuField); 206 AddChild(fTabView); 207 AddChild(fStringView); 208 AddChild(fCreateNewButton); 209 AddChild(fStatusView); 210 AddChild(fConnectButton); 211 212 // initialize 213 LoadInterfaces(); 214 LoadAddons(); 215 CreateTabs(); 216 fCurrentItem = NULL; 217 // reset, otherwise SelectInterface will not load the settings 218 SelectInterface(0); 219 UpdateControls(); 220} 221 222 223DialUpView::~DialUpView() 224{ 225 SaveSettingsToFile(); 226 227 int32 tmp; 228 wait_for_thread(fUpDownThread, &tmp); 229 230 // free known add-on types (these should free their known add-on types, etc.) 231 DialUpAddon *addon; 232 for(int32 index = 0; 233 fAddons.FindPointer(DUN_DELETE_ON_QUIT, index, 234 reinterpret_cast<void**>(&addon)) == B_OK; 235 index++) 236 delete addon; 237} 238 239 240void 241DialUpView::AttachedToWindow() 242{ 243 fInterfaceMenu->SetTargetForItems(this); 244 fCreateNewButton->SetTarget(this); 245 fConnectButton->SetTarget(this); 246 247 if(fListener.InitCheck() != B_OK) { 248 (new BAlert(kErrorTitle, kErrorNoPPPStack, kLabelOK, 249 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(NULL); 250 fConnectButton->Hide(); 251 } 252} 253 254 255void 256DialUpView::MessageReceived(BMessage *message) 257{ 258 switch(message->what) { 259 case PPP_REPORT_MESSAGE: 260 HandleReportMessage(message); 261 break; 262 263 // ------------------------------------------------- 264 case kMsgCreateNew: { 265 (new TextRequestDialog(kLabelCreateNewInterface, kTextChooseInterfaceName, 266 kLabelInterfaceName))->Go( 267 new BInvoker(new BMessage(kMsgFinishCreateNew), this)); 268 } break; 269 270 case kMsgFinishCreateNew: { 271 int32 which; 272 message->FindInt32("which", &which); 273 const char *name = message->FindString("text"); 274 if(which == 1 && name && strlen(name) > 0) 275 AddInterface(name, true); 276 277 if(fCurrentItem) 278 fCurrentItem->SetMarked(true); 279 } break; 280 // ------------------------------------------------- 281 282 case kMsgDeleteCurrent: { 283 if(!fCurrentItem) 284 return; 285 286 fInterfaceMenu->RemoveItem(fCurrentItem); 287 BDirectory settings, profile; 288 GetPPPDirectories(&settings, &profile); 289 BEntry entry; 290 settings.FindEntry(fCurrentItem->Label(), &entry); 291 entry.Remove(); 292 profile.FindEntry(fCurrentItem->Label(), &entry); 293 entry.Remove(); 294 delete fCurrentItem; 295 fCurrentItem = NULL; 296 297 BMenuItem *marked = fInterfaceMenu->FindMarked(); 298 if(marked) 299 marked->SetMarked(false); 300 301 UpdateControls(); 302 SelectInterface(0); 303 // this stops watching the deleted interface 304 } break; 305 306 case kMsgSelectInterface: { 307 int32 index; 308 message->FindInt32("index", &index); 309 SelectInterface(index); 310 } break; 311 312 case kMsgConnectButton: { 313 if(!fCurrentItem || fUpDownThread != -1) 314 return; 315 316 fUpDownThread = spawn_thread(up_down_thread, "up_down_thread", 317 B_NORMAL_PRIORITY, this); 318 resume_thread(fUpDownThread); 319 } break; 320 321 default: 322 BView::MessageReceived(message); 323 } 324} 325 326 327bool 328DialUpView::SelectInterfaceNamed(const char *name) 329{ 330 BMenuItem *item = fInterfaceMenu->FindItem(name); 331 332 int32 index = fInterfaceMenu->IndexOf(item); 333 if(!item || index >= CountInterfaces()) 334 return false; 335 336 SelectInterface(index); 337 338 return true; 339} 340 341 342bool 343DialUpView::NeedsRequest() const 344{ 345 return fGeneralAddon ? fGeneralAddon->NeedsAuthenticationRequest() : false; 346} 347 348 349BView* 350DialUpView::AuthenticationView() const 351{ 352 return fGeneralAddon ? fGeneralAddon->AuthenticationView() : NULL; 353} 354 355 356BView* 357DialUpView::StatusView() const 358{ 359 return fStatusView; 360} 361 362 363BView* 364DialUpView::ConnectButton() const 365{ 366 return fConnectButton; 367} 368 369 370bool 371DialUpView::LoadSettings(bool isNew) 372{ 373 fSettings.MakeEmpty(); 374 fProfile.MakeEmpty(); 375 BMessage *settingsPointer = fCurrentItem ? &fSettings : NULL, 376 *profilePointer = fCurrentItem ? &fProfile : NULL; 377 378 if(fCurrentItem && !isNew) { 379 BString name("pppidf/"); 380 name << fCurrentItem->Label(); 381 if(!ReadMessageDriverSettings(name.String(), &fSettings)) 382 return false; 383 name = "pppidf/profile/"; 384 name << fCurrentItem->Label(); 385 if(!ReadMessageDriverSettings(name.String(), &fProfile)) 386 profilePointer = settingsPointer; 387 } 388 389 DialUpAddon *addon; 390 for(int32 index = 0; fAddons.FindPointer(DUN_TAB_ADDON_TYPE, index, 391 reinterpret_cast<void**>(&addon)) == B_OK; index++) { 392 if(!addon) 393 continue; 394 395 if(!addon->LoadSettings(settingsPointer, profilePointer, isNew)) 396 return false; 397 } 398 399 // TODO: check if settings are valid 400 401 return true; 402} 403 404 405void 406DialUpView::IsModified(bool *settings, bool *profile) 407{ 408 *settings = *profile = false; 409 bool addonSettingsChanged, addonProfileChanged; 410 // for current addon 411 412 DialUpAddon *addon; 413 for(int32 index = 0; fAddons.FindPointer(DUN_TAB_ADDON_TYPE, index, 414 reinterpret_cast<void**>(&addon)) == B_OK; index++) { 415 if(!addon) 416 continue; 417 418 addon->IsModified(&addonSettingsChanged, &addonProfileChanged); 419 if(addonSettingsChanged) 420 *settings = true; 421 if(addonProfileChanged) 422 *profile = true; 423 } 424} 425 426 427bool 428DialUpView::SaveSettings(BMessage *settings, BMessage *profile, bool saveTemporary) 429{ 430 if(!fCurrentItem || !settings || !profile) 431 return false; 432 433 DialUpAddon *addon; 434 TemplateList<DialUpAddon*> addons; 435 for(int32 index = 0; 436 fAddons.FindPointer(DUN_TAB_ADDON_TYPE, index, 437 reinterpret_cast<void**>(&addon)) == B_OK; index++) { 438 if(!addon) 439 continue; 440 441 int32 insertIndex = 0; 442 for(; insertIndex < addons.CountItems(); insertIndex++) 443 if(addons.ItemAt(insertIndex)->Priority() <= addon->Priority()) 444 break; 445 446 addons.AddItem(addon, insertIndex); 447 } 448 449 settings->AddInt32("Interface", static_cast<int32>(fWatching)); 450 if(fCurrentItem) 451 settings->AddString("InterfaceName", fCurrentItem->Label()); 452 453 for(int32 index = 0; index < addons.CountItems(); index++) 454 if(!addons.ItemAt(index)->SaveSettings(settings, profile, saveTemporary)) 455 return false; 456 457 return true; 458} 459 460 461bool 462DialUpView::SaveSettingsToFile() 463{ 464 bool settingsChanged, profileChanged; 465 IsModified(&settingsChanged, &profileChanged); 466 if(!settingsChanged && !profileChanged) 467 return true; 468 469 BMessage settings, profile; 470 if(!SaveSettings(&settings, &profile, false)) 471 return false; 472 473 BDirectory settingsDirectory; 474 BDirectory profileDirectory; 475 GetPPPDirectories(&settingsDirectory, &profileDirectory); 476 if(settingsDirectory.InitCheck() != B_OK || profileDirectory.InitCheck() != B_OK) 477 return false; 478 479 BFile file; 480 if(settingsChanged) { 481 settingsDirectory.CreateFile(fCurrentItem->Label(), &file); 482 WriteMessageDriverSettings(file, settings); 483 } 484 485 if(profileChanged) { 486 profileDirectory.CreateFile(fCurrentItem->Label(), &file); 487 WriteMessageDriverSettings(file, profile); 488 } 489 490 return true; 491} 492 493 494void 495DialUpView::UpDownThread() 496{ 497 SaveSettingsToFile(); 498 BMessage settings, profile; 499 SaveSettings(&settings, &profile, true); 500 // save temporary profile 501 driver_settings *temporaryProfile = MessageToDriverSettings(profile); 502 503 PPPInterface interface; 504 if(fWatching == PPP_UNDEFINED_INTERFACE_ID) { 505 interface = fListener.Manager().InterfaceWithName(fCurrentItem->Label()); 506 if(interface.InitCheck() != B_OK) 507 interface = fListener.Manager().CreateInterfaceWithName( 508 fCurrentItem->Label(), temporaryProfile); 509 } else { 510 interface = fWatching; 511 interface.SetProfile(temporaryProfile); 512 } 513 514 free_driver_settings(temporaryProfile); 515 516 if(interface.InitCheck() != B_OK) { 517 Window()->Lock(); 518 fStatusView->SetText(kTextCreationError); 519 Window()->Unlock(); 520 return; 521 } 522 523 ppp_interface_info_t info; 524 interface.GetInterfaceInfo(&info); 525 if(info.info.phase == PPP_DOWN_PHASE) 526 interface.Up(); 527 else 528 interface.Down(); 529 530 fUpDownThread = -1; 531} 532 533 534void 535DialUpView::GetPPPDirectories(BDirectory *settingsDirectory, 536 BDirectory *profileDirectory) const 537{ 538 if(settingsDirectory) { 539 BDirectory settings(PPP_INTERFACE_SETTINGS_PATH); 540 if(settings.InitCheck() != B_OK) { 541 create_directory(PPP_INTERFACE_SETTINGS_PATH, 0750); 542 settings.SetTo(PPP_INTERFACE_SETTINGS_PATH); 543 } 544 545 *settingsDirectory = settings; 546 } 547 548 if(profileDirectory) { 549 BDirectory profile(PPP_INTERFACE_SETTINGS_PATH "/profile"); 550 if(profile.InitCheck() != B_OK) { 551 create_directory(PPP_INTERFACE_SETTINGS_PATH "/profile", 0750); 552 profile.SetTo(PPP_INTERFACE_SETTINGS_PATH "/profile"); 553 } 554 555 *profileDirectory = profile; 556 } 557} 558 559 560void 561DialUpView::HandleReportMessage(BMessage *message) 562{ 563 thread_id sender; 564 message->FindInt32("sender", &sender); 565 566 send_data(sender, B_OK, NULL, 0); 567 568 if(!fCurrentItem) 569 return; 570 571 ppp_interface_id id; 572 if(message->FindInt32("interface", reinterpret_cast<int32*>(&id)) != B_OK 573 || (fWatching != PPP_UNDEFINED_INTERFACE_ID && id != fWatching)) 574 return; 575 576 int32 type, code; 577 message->FindInt32("type", &type); 578 message->FindInt32("code", &code); 579 580 if(type == PPP_MANAGER_REPORT && code == PPP_REPORT_INTERFACE_CREATED) { 581 PPPInterface interface(id); 582 if(interface.InitCheck() != B_OK) 583 return; 584 585 ppp_interface_info_t info; 586 interface.GetInterfaceInfo(&info); 587 if(strcasecmp(info.info.name, fCurrentItem->Label())) 588 return; 589 590 WatchInterface(id); 591 } else if(type == PPP_CONNECTION_REPORT) { 592 if(fWatching == PPP_UNDEFINED_INTERFACE_ID) 593 return; 594 595 UpdateStatus(code); 596 } else if(type == PPP_DESTRUCTION_REPORT) { 597 if(fWatching == PPP_UNDEFINED_INTERFACE_ID) 598 return; 599 600 WatchInterface(fListener.Manager().InterfaceWithName(fCurrentItem->Label())); 601 } 602} 603 604 605void 606DialUpView::CreateTabs() 607{ 608 // create tabs for all registered and valid tab add-ons 609 DialUpAddon *addon; 610 BView *target; 611 float width, height; 612 TemplateList<DialUpAddon*> addons; 613 614 for(int32 index = 0; 615 fAddons.FindPointer(DUN_TAB_ADDON_TYPE, index, 616 reinterpret_cast<void**>(&addon)) == B_OK; 617 index++) { 618 if(!addon || addon->Position() < 0) 619 continue; 620 621 int32 insertIndex = 0; 622 for(; insertIndex < addons.CountItems(); insertIndex++) 623 if(addons.ItemAt(insertIndex)->Position() > addon->Position()) 624 break; 625 626 addons.AddItem(addon, insertIndex); 627 } 628 629 for(int32 index = 0; index < addons.CountItems(); index++) { 630 addon = addons.ItemAt(index); 631 632 if(!addon->GetPreferredSize(&width, &height)) 633 continue; 634 635 target = addon->CreateView(BPoint(0, 0)); 636 if(!target) 637 continue; 638 639 fTabView->AddTab(target, NULL); 640 } 641} 642 643 644void 645DialUpView::UpdateStatus(int32 code) 646{ 647 switch(code) { 648 case PPP_REPORT_UP_ABORTED: 649 case PPP_REPORT_DEVICE_UP_FAILED: 650 case PPP_REPORT_LOCAL_AUTHENTICATION_FAILED: 651 case PPP_REPORT_PEER_AUTHENTICATION_FAILED: 652 case PPP_REPORT_DOWN_SUCCESSFUL: 653 case PPP_REPORT_CONNECTION_LOST: { 654 fConnectButton->SetLabel(kLabelConnect); 655 } break; 656 657 default: 658 fConnectButton->SetLabel(kLabelDisconnect); 659 } 660 661 // maybe the status string must not be changed (codes that set fKeepLabel to false 662 // should still be handled) 663 if(fKeepLabel && code != PPP_REPORT_GOING_UP && code != PPP_REPORT_UP_SUCCESSFUL) 664 return; 665 666 if(fListener.InitCheck() != B_OK) { 667 fStatusView->SetText(kErrorNoPPPStack); 668 return; 669 } 670 671 // only errors should set fKeepLabel to true 672 switch(code) { 673 case PPP_REPORT_GOING_UP: 674 fKeepLabel = false; 675 fStatusView->SetText(kTextConnecting); 676 break; 677 678 case PPP_REPORT_UP_SUCCESSFUL: 679 fKeepLabel = false; 680 fStatusView->SetText(kTextConnectionEstablished); 681 break; 682 683 case PPP_REPORT_UP_ABORTED: 684 case PPP_REPORT_DOWN_SUCCESSFUL: 685 fStatusView->SetText(kTextNotConnected); 686 break; 687 688 case PPP_REPORT_DEVICE_UP_FAILED: 689 fKeepLabel = true; 690 fStatusView->SetText(kTextDeviceUpFailed); 691 break; 692 693 case PPP_REPORT_LOCAL_AUTHENTICATION_REQUESTED: 694 case PPP_REPORT_PEER_AUTHENTICATION_REQUESTED: 695 fStatusView->SetText(kTextAuthenticating); 696 break; 697 698 case PPP_REPORT_LOCAL_AUTHENTICATION_FAILED: 699 case PPP_REPORT_PEER_AUTHENTICATION_FAILED: 700 fKeepLabel = true; 701 fStatusView->SetText(kTextAuthenticationFailed); 702 break; 703 704 case PPP_REPORT_CONNECTION_LOST: 705 fKeepLabel = true; 706 fStatusView->SetText(kTextConnectionLost); 707 break; 708 } 709} 710 711 712void 713DialUpView::WatchInterface(ppp_interface_id ID) 714{ 715 // This method can be used to update the interface's connection status. 716 717 if(fWatching != ID) { 718 fListener.StopWatchingInterfaces(); 719 720 if(ID == PPP_UNDEFINED_INTERFACE_ID || fListener.WatchInterface(ID)) 721 fWatching = ID; 722 } 723 724 // update status 725 PPPInterface interface(fWatching); 726 if(interface.InitCheck() != B_OK) { 727 UpdateStatus(PPP_REPORT_DOWN_SUCCESSFUL); 728 return; 729 } 730 731 ppp_interface_info_t info; 732 interface.GetInterfaceInfo(&info); 733 734 // transform phase into status 735 switch(info.info.phase) { 736 case PPP_DOWN_PHASE: 737 UpdateStatus(PPP_REPORT_DOWN_SUCCESSFUL); 738 break; 739 740 case PPP_TERMINATION_PHASE: 741 break; 742 743 case PPP_ESTABLISHED_PHASE: 744 UpdateStatus(PPP_REPORT_UP_SUCCESSFUL); 745 break; 746 747 default: 748 UpdateStatus(PPP_REPORT_GOING_UP); 749 } 750} 751 752 753void 754DialUpView::LoadInterfaces() 755{ 756 fInterfaceMenu->AddSeparatorItem(); 757 fInterfaceMenu->AddItem(new BMenuItem(kLabelCreateNewInterface, 758 new BMessage(kMsgCreateNew))); 759 fDeleterItem = new BMenuItem(kLabelDeleteCurrent, 760 new BMessage(kMsgDeleteCurrent)); 761 fInterfaceMenu->AddItem(fDeleterItem); 762 763 BDirectory settingsDirectory; 764 BEntry entry; 765 BPath path; 766 GetPPPDirectories(&settingsDirectory, NULL); 767 while(settingsDirectory.GetNextEntry(&entry) == B_OK) { 768 if(entry.IsFile()) { 769 entry.GetPath(&path); 770 AddInterface(path.Leaf(), true); 771 } 772 } 773} 774 775 776void 777DialUpView::LoadAddons() 778{ 779 // Load integrated add-ons: 780 // "Connection Options" tab 781 ConnectionOptionsAddon *connectionOptionsAddon = 782 new ConnectionOptionsAddon(&fAddons); 783 fAddons.AddPointer(DUN_TAB_ADDON_TYPE, connectionOptionsAddon); 784 fAddons.AddPointer(DUN_DELETE_ON_QUIT, connectionOptionsAddon); 785 // "General" tab 786 GeneralAddon *fGeneralAddon = new GeneralAddon(&fAddons); 787 fAddons.AddPointer(DUN_TAB_ADDON_TYPE, fGeneralAddon); 788 fAddons.AddPointer(DUN_DELETE_ON_QUIT, fGeneralAddon); 789/* 790 // "IPCP" protocol 791 IPCPAddon *ipcpAddon = new IPCPAddon(&fAddons); 792 fAddons.AddPointer(DUN_TAB_ADDON_TYPE, ipcpAddon); 793 fAddons.AddPointer(DUN_DELETE_ON_QUIT, ipcpAddon); 794 // "PPPoE" device 795 PPPoEAddon *pppoeAddon = new PPPoEAddon(&fAddons); 796 fAddons.AddPointer(DUN_DEVICE_ADDON_TYPE, pppoeAddon); 797 fAddons.AddPointer(DUN_DELETE_ON_QUIT, pppoeAddon); 798*/ 799 // "PAP" authenticator 800 BMessage addon; 801#ifdef LANG_GERMAN 802 addon.AddString("FriendlyName", "Unverschl��sselt"); 803#else 804 addon.AddString("FriendlyName", "Plain-text Authentication"); 805#endif 806 addon.AddString("TechnicalName", "PAP"); 807 addon.AddString("KernelModuleName", "pap"); 808 fAddons.AddMessage(DUN_AUTHENTICATOR_ADDON_TYPE, &addon); 809 // addon.MakeEmpty(); // for next authenticator 810 811 // TODO: 812 // load all add-ons from the add-ons folder 813} 814 815 816void 817DialUpView::AddInterface(const char *name, bool isNew) 818{ 819 if(fInterfaceMenu->FindItem(name)) { 820 (new BAlert(kErrorTitle, kErrorInterfaceExists, kLabelOK, 821 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(NULL); 822 return; 823 } 824 825 BMenuItem *item = new BMenuItem(name, new BMessage(kMsgSelectInterface)); 826 item->SetTarget(this); 827 int32 index = FindNextMenuInsertionIndex(fInterfaceMenu, name); 828 if(index > CountInterfaces()) 829 index = CountInterfaces(); 830 fInterfaceMenu->AddItem(item, index); 831 UpdateControls(); 832 833 item->SetMarked(true); 834 SelectInterface(index, isNew); 835} 836 837 838void 839DialUpView::SelectInterface(int32 index, bool isNew) 840{ 841 BMenuItem *item = fInterfaceMenu->FindMarked(); 842 if(fCurrentItem && item == fCurrentItem) 843 return; 844 845 if(fCurrentItem && !SaveSettingsToFile()) 846 (new BAlert(kErrorTitle, kErrorSavingFailed, kLabelOK, 847 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(NULL); 848 849 if(index >= CountInterfaces() || index < 0) { 850 if(CountInterfaces() > 0) 851 SelectInterface(0); 852 else { 853 fCurrentItem = NULL; 854 WatchInterface(PPP_UNDEFINED_INTERFACE_ID); 855 } 856 } else { 857 fCurrentItem = fInterfaceMenu->ItemAt(index); 858 if(!fCurrentItem) { 859 SelectInterface(0); 860 return; 861 } 862 863 fCurrentItem->SetMarked(true); 864 fDeleterItem->SetEnabled(true); 865 WatchInterface(fListener.Manager().InterfaceWithName(fCurrentItem->Label())); 866 } 867 868 if(!fCurrentItem) 869 LoadSettings(false); 870 // tell modules to unload all settings 871 else if(!isNew && !LoadSettings(false)) { 872 (new BAlert(kErrorTitle, kErrorLoadingFailed, kLabelOK, 873 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(NULL); 874 LoadSettings(true); 875 } else if(isNew && !LoadSettings(true)) 876 (new BAlert(kErrorTitle, kErrorLoadingFailed, kLabelOK, 877 NULL, NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(NULL); 878} 879 880 881int32 882DialUpView::CountInterfaces() const 883{ 884 return fInterfaceMenu->CountItems() - 3; 885} 886 887 888void 889DialUpView::UpdateControls() 890{ 891 if(fTabView->IsHidden() && CountInterfaces() > 0) { 892 fInterfaceMenu->SetLabelFromMarked(true); 893 fStringView->Hide(); 894 fCreateNewButton->Hide(); 895 fTabView->Show(); 896 fConnectButton->SetEnabled(true); 897 } else if(!fTabView->IsHidden() && CountInterfaces() == 0) { 898 fDeleterItem->SetEnabled(false); 899 fInterfaceMenu->SetRadioMode(false); 900 fInterfaceMenu->Superitem()->SetLabel(kLabelCreateNew); 901 fTabView->Hide(); 902 fStringView->Show(); 903 fCreateNewButton->Show(); 904 fConnectButton->SetEnabled(false); 905 } 906} 907