2014-02-04 11:00:32 +01:00
/ *
* This file is part of the Doodle3D project ( http : //doodle3d.com).
*
* Copyright ( c ) 2013 , Doodle3D
* This software is licensed under the terms of the GNU GPL v2 or later .
* See file LICENSE . txt or visit http : //www.gnu.org/licenses/gpl.html for full license details.
* /
// prototype inheritance
// http://robertnyman.com/2008/10/06/javascript-inheritance-how-and-why/
NetworkPanel . prototype = new FormPanel ( ) ;
function NetworkPanel ( ) {
2014-02-04 15:26:43 +01:00
var NOT _CONNECTED = "not connected" ; // used as first item in networks list
2014-02-04 11:00:32 +01:00
// network mode
2014-02-07 12:35:15 +01:00
NetworkPanel . NETWORK _MODE = {
2014-02-04 11:00:32 +01:00
NEITHER : "neither" ,
CLIENT : "clientMode" ,
ACCESS _POINT : "accessPointMode"
} ;
2014-02-07 12:35:15 +01:00
var _networkMode = NetworkPanel . NETWORK _MODE . NEITHER ;
var _networkModeChangedHandler ;
2014-02-04 11:00:32 +01:00
var _api = new NetworkAPI ( ) ;
var _networks = { } ;
var _currentNetwork ; // the ssid of the network the box is on
var _selectedNetwork ; // the ssid of the selected network in the client mode settings
var _currentLocalIP = "" ;
var _currentAP ;
2014-02-04 15:26:43 +01:00
var _currentNetworkStatus ;
2014-02-04 11:00:32 +01:00
var _retryRetrieveStatusDelayTime = 1000 ;
var _retryRetrieveStatusDelay ;
// after switching wifi network or creating a access point we delay the status retrieval
// because the webserver needs time to switch
var _retrieveNetworkStatusDelayTime = 1000 ;
var _retrieveNetworkStatusDelay ;
// ui elements
var _element ;
var _networkSelector ;
var _apFieldSet ;
var _clientFieldSet ;
var _apRadioButton ;
var _clientRadioButton ;
var _btnRefresh
var _btnConnect ;
var _btnCreate ;
var _passwordField ;
var _passwordLabel ;
var _clientStateDisplay ;
2014-02-04 14:18:50 +01:00
var _apModeStateDisplay ;
2014-02-04 11:00:32 +01:00
var _self = this ;
this . init = function ( wifiboxURL , wifiboxCGIBinURL , panelElement ) {
2014-02-04 22:56:58 +01:00
//console.log("NetworkPanel:init");
2014-02-04 11:00:32 +01:00
// super call:
_self . constructor . prototype . init . call ( _self , wifiboxURL , wifiboxCGIBinURL , panelElement ) ;
2014-02-04 14:18:50 +01:00
_api . init ( wifiboxURL , wifiboxCGIBinURL ) ;
2014-02-04 11:00:32 +01:00
_element = panelElement ;
_apRadioButton = _element . find ( "#ap" ) ;
_clientRadioButton = _element . find ( "#client" ) ;
_btnRefresh = _element . find ( "#refreshNetworks" ) ;
_btnConnect = _element . find ( "#connectToNetwork" ) ;
_btnCreate = _element . find ( "#createAP" ) ;
_networkSelector = _element . find ( "#network" ) ;
_apFieldSet = _element . find ( "#apSettings" ) ;
_clientFieldSet = _element . find ( "#clientSettings" ) ;
_passwordField = _element . find ( "#password" ) ;
_passwordLabel = _element . find ( "#passwordLabel" ) ;
_clientStateDisplay = _element . find ( "#clientModeState" ) ;
_apModeStateDisplay = _element . find ( "#apModeState" ) ;
_apRadioButton . parent ( ) . on ( 'touchstart mousedown' , showAPSettings ) ;
_clientRadioButton . parent ( ) . on ( 'touchstart mousedown' , showClientSettings ) ;
_btnRefresh . on ( 'touchstart mousedown' , onRefreshClick ) ;
_btnConnect . on ( 'touchstart mousedown' , _self . connectToNetwork ) ;
_btnCreate . on ( 'touchstart mousedown' , _self . createAP ) ;
2014-02-04 14:18:50 +01:00
_networkSelector . change ( networkSelectorChanged ) ;
2014-02-04 11:00:32 +01:00
}
/ *
* Handlers
* /
function showAPSettings ( ) {
_apFieldSet . show ( ) ;
_clientFieldSet . hide ( ) ;
} ;
function showClientSettings ( ) {
_clientFieldSet . show ( ) ;
_apFieldSet . hide ( ) ;
} ;
function onRefreshClick ( ) {
_btnRefresh . attr ( "disabled" , true ) ;
_self . refreshNetworks ( function ( ) {
_btnRefresh . removeAttr ( "disabled" ) ;
} )
}
function networkSelectorChanged ( e ) {
var selectedOption = $ ( this ) . find ( "option:selected" ) ;
_self . selectNetwork ( selectedOption . val ( ) ) ;
} ;
this . update = function ( ) {
console . log ( "NetworkPanel:update" ) ;
_self . refreshNetworks ( ) ;
2014-02-04 14:18:50 +01:00
_self . retrieveNetworkStatus ( false ) ;
2014-02-04 11:00:32 +01:00
}
this . refreshNetworks = function ( completeHandler ) {
2014-02-04 22:56:58 +01:00
//console.log("NetworkPanel:refreshNetworks");
2014-02-04 11:00:32 +01:00
_api . scan ( function ( data ) {
//console.log("NetworkPanel:scanned");
_networks = { } ;
var foundCurrentNetwork = false ;
// fill network selector
_networkSelector . empty ( ) ;
_networkSelector . append (
2014-02-04 15:26:43 +01:00
$ ( "<option></option>" ) . val ( NOT _CONNECTED ) . html ( NOT _CONNECTED )
2014-02-04 11:00:32 +01:00
) ;
$ . each ( data . networks , function ( index , element ) {
if ( element . ssid == _currentNetwork ) {
foundCurrentNetwork = true ;
}
_networkSelector . append (
$ ( "<option></option>" ) . val ( element . ssid ) . html ( element . ssid )
) ;
_networks [ element . ssid ] = element ;
} ) ;
if ( foundCurrentNetwork ) {
_networkSelector . val ( _currentNetwork ) ;
_self . selectNetwork ( _currentNetwork ) ;
}
if ( completeHandler ) completeHandler ( ) ;
} ) ;
} ;
2014-02-04 14:18:50 +01:00
this . retrieveNetworkStatus = function ( connecting ) {
//console.log("NetworkPanel:retrieveNetworkStatus");
2014-02-04 11:00:32 +01:00
_api . status ( function ( data ) {
if ( typeof data . status === 'string' ) {
data . status = parseInt ( data . status ) ;
}
console . log ( "NetworkPanel:retrievedStatus status: " , data . status , data . statusMessage ) ;
2014-02-04 15:52:37 +01:00
// if status changed
if ( data . status != _currentNetworkStatus ) {
// Determine which network mode ui to show
switch ( data . status ) {
case NetworkAPI . STATUS . NOT _CONNECTED :
2014-02-07 12:35:15 +01:00
setNetworkMode ( NetworkPanel . NETWORK _MODE . NEITHER ) ;
2014-02-04 15:52:37 +01:00
break ;
case NetworkAPI . STATUS . CONNECTING _FAILED :
case NetworkAPI . STATUS . CONNECTING :
case NetworkAPI . STATUS . CONNECTED :
2014-02-07 12:35:15 +01:00
setNetworkMode ( NetworkPanel . NETWORK _MODE . CLIENT ) ;
2014-02-04 15:52:37 +01:00
break ;
case NetworkAPI . STATUS . CREATING :
case NetworkAPI . STATUS . CREATED :
2014-02-07 12:35:15 +01:00
setNetworkMode ( NetworkPanel . NETWORK _MODE . ACCESS _POINT ) ;
2014-02-04 15:52:37 +01:00
break ;
}
// update info
switch ( data . status ) {
case NetworkAPI . STATUS . CONNECTED :
2014-02-04 11:00:32 +01:00
_currentNetwork = data . ssid ;
_currentLocalIP = data . localip ;
_self . selectNetwork ( data . ssid ) ;
2014-02-04 15:52:37 +01:00
break ;
case NetworkAPI . STATUS . CONNECTING _FAILED :
case NetworkAPI . STATUS . CONNECTING :
2014-02-04 11:00:32 +01:00
_currentLocalIP = "" ;
2014-02-04 15:52:37 +01:00
break ;
case NetworkAPI . STATUS . CREATING :
case NetworkAPI . STATUS . CREATED :
_currentNetwork = undefined ;
_self . selectNetwork ( NOT _CONNECTED ) ;
if ( data . ssid && data . status == NetworkAPI . STATUS . CREATED ) {
_currentAP = data . ssid ;
}
break ;
}
// update ui
2014-02-04 15:26:43 +01:00
updateClientModeUI ( data . status , data . statusMessage ) ;
updateAPModeUI ( data . status , "" ) ;
}
2014-02-04 11:00:32 +01:00
// Keep checking for updates?
if ( connecting ) {
switch ( data . status ) {
case NetworkAPI . STATUS . CONNECTING :
case NetworkAPI . STATUS . CREATING :
clearTimeout ( _retryRetrieveStatusDelay ) ;
2014-02-04 14:18:50 +01:00
_retryRetrieveStatusDelay = setTimeout ( function ( ) { _self . retrieveNetworkStatus ( connecting ) ; } , _retryRetrieveStatusDelayTime ) ; // retry after delay
2014-02-04 11:00:32 +01:00
break ;
}
}
2014-02-04 15:26:43 +01:00
_currentNetworkStatus = data . status ;
2014-02-04 11:00:32 +01:00
} , function ( ) {
console . log ( "NetworkPanel:retrieveStatus failed" ) ;
clearTimeout ( _retryRetrieveStatusDelay ) ;
2014-02-04 14:18:50 +01:00
_retryRetrieveStatusDelay = setTimeout ( function ( ) { _self . retrieveNetworkStatus ( connecting ) ; } , _retryRetrieveStatusDelayTime ) ; // retry after delay
2014-02-04 11:00:32 +01:00
} ) ;
} ;
function setNetworkMode ( mode ) {
2014-02-04 22:56:58 +01:00
//console.log("NetworkPanel:setNetworkMode: ",_networkMode,">",mode);
2014-02-04 11:00:32 +01:00
if ( mode == _networkMode ) return ;
switch ( mode ) {
2014-02-07 12:35:15 +01:00
case NetworkPanel . NETWORK _MODE . NEITHER :
2014-02-04 11:00:32 +01:00
_apFieldSet . show ( ) ;
_clientFieldSet . show ( ) ;
break ;
2014-02-07 12:35:15 +01:00
case NetworkPanel . NETWORK _MODE . CLIENT :
2014-02-04 11:00:32 +01:00
_clientRadioButton . prop ( 'checked' , true ) ;
_apFieldSet . hide ( ) ;
_clientFieldSet . show ( ) ;
break ;
2014-02-07 12:35:15 +01:00
case NetworkPanel . NETWORK _MODE . ACCESS _POINT :
2014-02-04 11:00:32 +01:00
_apRadioButton . prop ( 'checked' , true ) ;
_apFieldSet . show ( ) ;
_clientFieldSet . hide ( ) ;
break ;
}
_networkMode = mode ;
2014-02-07 12:35:15 +01:00
if ( _networkModeChangedHandler ) _networkModeChangedHandler ( _networkMode ) ;
2014-02-04 11:00:32 +01:00
}
this . selectNetwork = function ( ssid ) {
2014-02-04 22:56:58 +01:00
//console.log("NetworkPanel:selectNetwork: ",ssid);
2014-02-04 11:00:32 +01:00
if ( ssid == "" ) return ;
_selectedNetwork = ssid ;
2014-02-04 15:26:43 +01:00
var network = _networks [ ssid ] ;
if ( network === undefined || network . encryption == "none" ) {
_passwordLabel . hide ( ) ;
_passwordField . hide ( ) ;
2014-02-04 11:00:32 +01:00
} else {
2014-02-04 15:26:43 +01:00
_passwordLabel . show ( ) ;
_passwordField . show ( ) ;
2014-02-04 11:00:32 +01:00
}
2014-02-04 15:26:43 +01:00
_passwordField . val ( "" ) ;
2014-02-04 11:00:32 +01:00
} ;
2014-02-04 15:26:43 +01:00
function updateClientModeUI ( state , statusMessage ) {
//console.log("NetworkPanel:updateClientModeUI ",state,statusMessage);
2014-02-04 11:00:32 +01:00
var msg = "" ;
switch ( state ) {
2014-02-04 15:26:43 +01:00
case NetworkAPI . STATUS . NOT _CONNECTED :
case NetworkAPI . STATUS . CREATING :
case NetworkAPI . STATUS . CREATED :
2014-02-04 14:18:50 +01:00
_btnConnect . removeAttr ( "disabled" ) ;
msg = "Not connected" ;
2014-02-04 15:52:37 +01:00
_networkSelector . val ( NOT _CONNECTED ) ;
2014-02-04 14:18:50 +01:00
break ;
2014-02-04 15:26:43 +01:00
case NetworkAPI . STATUS . CONNECTED :
2014-02-04 14:18:50 +01:00
_btnConnect . removeAttr ( "disabled" ) ;
msg = "Connected to: <b>" + _currentNetwork + "</b>." ;
if ( _currentLocalIP != undefined && _currentLocalIP != "" ) {
var a = "<a href='http://" + _currentLocalIP + "' target='_black'>" + _currentLocalIP + "</a>" ;
msg += " (IP: " + a + ")" ;
}
2014-02-04 15:52:37 +01:00
_networkSelector . val ( _currentNetwork ) ;
2014-02-04 14:18:50 +01:00
break ;
2014-02-04 15:26:43 +01:00
case NetworkAPI . STATUS . CONNECTING :
2014-02-04 14:18:50 +01:00
_btnConnect . attr ( "disabled" , true ) ;
msg = "Connecting... Reconnect by connecting your device to <b>" + _selectedNetwork + "</b> and going to <a href='http://connect.doodle3d.com'>connect.doodle3d.com</a>" ;
break ;
2014-02-04 15:26:43 +01:00
case NetworkAPI . STATUS . CONNECTING _FAILED :
2014-02-04 14:18:50 +01:00
_btnConnect . removeAttr ( "disabled" ) ;
msg = statusMessage ;
break ;
2014-02-04 11:00:32 +01:00
}
2014-02-04 22:56:58 +01:00
//console.log(" client display msg: ",msg);
2014-02-04 11:00:32 +01:00
_clientStateDisplay . html ( msg ) ;
} ;
2014-02-04 15:26:43 +01:00
function updateAPModeUI ( state , statusMessage ) {
2014-02-04 11:00:32 +01:00
var msg = "" ;
switch ( state ) {
2014-02-04 15:26:43 +01:00
case NetworkAPI . STATUS . CONNECTING _FAILED :
case NetworkAPI . STATUS . NOT _CONNECTED :
case NetworkAPI . STATUS . CONNECTING :
case NetworkAPI . STATUS . CONNECTED :
_btnCreate . removeAttr ( "disabled" ) ;
msg = "Not currently a access point" ;
break ;
case NetworkAPI . STATUS . CREATED :
_btnCreate . removeAttr ( "disabled" ) ;
msg = "Is access point: <b>" + _currentAP + "</b>" ;
break ;
case NetworkAPI . STATUS . CREATING :
_btnCreate . attr ( "disabled" , true ) ;
msg = "Creating access point... Reconnect by connecting your device to <b>" + settings . substituted _ssid + "</b> and going to <a href='http://draw.doodle3d.com'>draw.doodle3d.com</a>" ;
break ;
2014-02-04 11:00:32 +01:00
}
2014-02-04 22:56:58 +01:00
//console.log(" ap display msg: ",msg);
2014-02-04 11:00:32 +01:00
_apModeStateDisplay . html ( msg ) ;
} ;
this . connectToNetwork = function ( ) {
2014-02-04 22:56:58 +01:00
//console.log("NetworkPanel:connectToNetwork");
2014-02-04 11:00:32 +01:00
if ( _selectedNetwork == undefined ) return ;
// save network related settings and on complete, connect to network
_self . saveSettings ( _self . readForm ( ) , function ( validated ) {
if ( ! validated ) return ;
2014-02-04 15:26:43 +01:00
updateClientModeUI ( NetworkAPI . STATUS . CONNECTING , "" ) ;
2014-02-04 11:00:32 +01:00
_api . associate ( _selectedNetwork , _passwordField . val ( ) , true ) ;
2014-02-04 14:36:10 +01:00
// after switching wifi network or creating a access point we delay the status retrieval
// because the webserver needs time to switch it's status
clearTimeout ( _retrieveNetworkStatusDelay ) ;
_retrieveNetworkStatusDelay = setTimeout ( function ( ) { _self . retrieveNetworkStatus ( true ) ; } , _retrieveNetworkStatusDelayTime ) ;
2014-02-04 11:00:32 +01:00
} ) ;
} ;
this . createAP = function ( ) {
2014-02-04 22:56:58 +01:00
//console.log("createAP");
2014-02-04 14:34:03 +01:00
// save network related settings and on complete, create access point
_self . saveSettings ( _self . readForm ( ) , function ( success ) {
if ( ! success ) return ;
2014-02-04 15:26:43 +01:00
updateAPModeUI ( NetworkAPI . STATUS . CREATING , "" ) ;
2014-02-04 14:34:03 +01:00
_api . openAP ( ) ;
2014-02-04 11:00:32 +01:00
2014-02-04 14:34:03 +01:00
// after switching wifi network or creating a access point we delay the status retrieval
// because the webserver needs time to switch it's status
clearTimeout ( _retrieveNetworkStatusDelay ) ;
_retrieveNetworkStatusDelay = setTimeout ( function ( ) { _self . retrieveNetworkStatus ( true ) ; } , _retrieveNetworkStatusDelayTime ) ;
} ) ;
} ;
2014-02-07 12:35:15 +01:00
this . setNetworkModeChangedHandler = function ( handler ) {
_networkModeChangedHandler = handler ;
}
2014-02-04 11:00:32 +01:00
}