Commit 16ee2632 authored by noamsml@chromium.org's avatar noamsml@chromium.org

Fixes for wifi side of GCD prototype

1.  Moved actual device indicator to config.json
2.  Wireless interface now part of config.json
3.  LED path now part of config.json
4.  udhcpd config now generated by script

This should make the script a fair bit more robust and allow it to work on any
machine.

In addition, updated the SSID to the new format.

BUG=
NOTRY=true

Review URL: https://codereview.chromium.org/405483004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284171 0039d316-1c4b-4281-b951-d872f2087c98
parent acc18a83
......@@ -20,6 +20,7 @@ import base64
import datetime
import json
import os
import random
import subprocess
import time
import traceback
......@@ -35,13 +36,13 @@ from tornado.ioloop import IOLoop
_OAUTH_SCOPE = 'https://www.googleapis.com/auth/clouddevices'
_API_CLIENT_FILE = 'config.json'
_CONFIG_FILE = 'config.json'
_API_DISCOVERY_FILE = 'discovery.json'
_DEVICE_STATE_FILE = 'device_state.json'
_DEVICE_SETUP_SSID = 'GCDPrototype.camera.privet'
_DEVICE_SETUP_SSID = 'GCD Prototype %02d..Bcamprv'
_DEVICE_NAME = 'GCD Prototype'
_DEVICE_TYPE = 'camera'
_DEVICE_TYPE = 'vendor'
_DEVICE_PORT = 8080
DEVICE_DRAFT = {
......@@ -64,12 +65,12 @@ DEVICE_DRAFT = {
}
}
wpa_supplicant_cmd = 'wpa_supplicant -Dwext -iwlan0 -cwpa_supplicant.conf'
ifconfig_cmd = 'ifconfig wlan0 192.168.0.3'
wpa_supplicant_cmd = 'wpa_supplicant -Dwext -i%s -cwpa_supplicant.conf'
ifconfig_cmd = 'ifconfig %s 192.168.0.3'
hostapd_cmd = 'hostapd hostapd-min.conf'
dhclient_release = 'dhclient -r wlan0'
dhclient_renew = 'dhclient wlan0'
dhcpd_cmd = 'udhcpd -f /etc/udhcpd.conf'
dhclient_release = 'dhclient -r %s'
dhclient_renew = 'dhclient %s'
dhcpd_cmd = 'udhcpd -f udhcpd.conf'
wpa_supplicant_conf = 'wpa_supplicant.conf'
......@@ -84,8 +85,22 @@ network={
psk="%s"
}"""
led_path = '/sys/class/leds/ath9k_htc-phy0/'
hostapd_conf = 'hostapd-min.conf'
hostapd_template = """
interface=%s
driver=nl80211
ssid=%s
channel=1
"""
udhcpd_conf = 'udhcpd.conf'
udhcpd_template = """
start 192.168.0.20
end 192.168.0.254
interface %s
"""
class DeviceUnregisteredError(Exception):
pass
......@@ -105,7 +120,7 @@ class CommandWrapperReal(object):
"""Command wrapper that executs shell commands."""
def __init__(self, cmd):
if type(cmd) == str:
if type(cmd) in [str, unicode]:
cmd = cmd.split()
self.cmd = cmd
self.cmd_str = ' '.join(cmd)
......@@ -160,8 +175,9 @@ class CloudCommandHandlerFake(object):
class CloudCommandHandlerReal(object):
"""Executes device commands."""
def __init__(self, ioloop):
def __init__(self, ioloop, led_path):
self.ioloop = ioloop
self.led_path = led_path
def handle_command(self, command_name, args):
if command_name == 'flashLED':
......@@ -180,7 +196,7 @@ class CloudCommandHandlerReal(object):
if not times:
return
file_trigger = open(os.path.join(led_path, 'brightness'), 'w')
file_trigger = open(os.path.join(self.led_path, 'brightness'), 'w')
if value:
file_trigger.write('1')
......@@ -202,10 +218,12 @@ class WifiHandler(object):
"""Token is optional, and all delegates should support it being None."""
raise Exception('Unhandled condition: WiFi connected')
def __init__(self, ioloop, state, delegate):
def __init__(self, ioloop, state, config, setup_ssid, delegate):
self.ioloop = ioloop
self.state = state
self.delegate = delegate
self.setup_ssid = setup_ssid
self.interface = config['wireless_interface']
def start(self):
raise Exception('Start not implemented!')
......@@ -221,13 +239,18 @@ class WifiHandlerReal(WifiHandler):
devices for testing the wifi-specific logic.
"""
def __init__(self, ioloop, state, delegate):
super(WifiHandlerReal, self).__init__(ioloop, state, delegate)
def __init__(self, ioloop, state, config, setup_ssid, delegate):
super(WifiHandlerReal, self).__init__(ioloop, state, config,
setup_ssid, delegate)
if config['simulate_commands']:
self.command_wrapper = CommandWrapperFake
else:
self.command_wrapper = CommandWrapperReal
self.hostapd = self.CommandWrapper(hostapd_cmd)
self.wpa_supplicant = self.CommandWrapper(wpa_supplicant_cmd)
self.dhcpd = self.CommandWrapper(dhcpd_cmd)
self.hostapd = self.command_wrapper(hostapd_cmd)
self.wpa_supplicant = self.command_wrapper(
wpa_supplicant_cmd % self.interface)
self.dhcpd = self.command_wrapper(dhcpd_cmd)
def start(self):
if self.state.has_wifi():
......@@ -236,21 +259,30 @@ class WifiHandlerReal(WifiHandler):
self.start_hostapd()
def start_hostapd(self):
hostapd_config = open(hostapd_conf, 'w')
hostapd_config.write(hostapd_template % (self.interface, self.setup_ssid))
hostapd_config.close()
self.hostapd.start()
time.sleep(3)
self.run_command(ifconfig_cmd)
self.run_command(ifconfig_cmd % self.interface)
self.dhcpd.start()
def switch_to_wifi(self, ssid, passwd, token):
try:
udhcpd_config = open(udhcpd_conf, 'w')
udhcpd_config.write(udhcpd_template % self.interface)
udhcpd_config.close()
wpa_config = open(wpa_supplicant_conf, 'w')
wpa_config.write(wpa_supplicant_template % (ssid, passwd))
wpa_config.close()
self.hostapd.end()
self.dhcpd.end()
self.wpa_supplicant.start()
self.run_command(dhclient_release)
self.run_command(dhclient_renew)
self.run_command(dhclient_release % self.interface)
self.run_command(dhclient_renew % self.interface)
self.state.set_wifi(ssid, passwd)
self.delegate.on_wifi_connected(token)
......@@ -276,8 +308,9 @@ class WifiHandlerReal(WifiHandler):
class WifiHandlerPassthrough(WifiHandler):
"""Passthrough wifi handler."""
def __init__(self, ioloop, state, delegate):
super(WifiHandlerPassthrough, self).__init__(ioloop, state, delegate)
def __init__(self, ioloop, state, config, setup_ssid, delegate):
super(WifiHandlerPassthrough, self).__init__(ioloop, state, config,
setup_ssid, delegate)
def start(self):
self.delegate.on_wifi_connected(None)
......@@ -373,6 +406,33 @@ class State(object):
return self.device_id_
class Config(object):
"""Configuration parameters (should not change)"""
def __init__(self):
if not os.path.isfile(_CONFIG_FILE):
config = {
'oauth_client_id': '',
'oauth_secret': '',
'api_key': '',
'wireless_interface': ''
}
config_f = open(_CONFIG_FILE + '.sample', 'w')
config_f.write(json.dumps(credentials, sort_keys=True,
indent=2, separators=(',', ': ')))
config_f.close()
raise Exception('Missing ' + _CONFIG_FILE)
config_f = open(_CONFIG_FILE)
config = json.load(config_f)
config_f.close()
self.config = config
def __getitem__(self, item):
if item in self.config:
return self.config[item]
return None
class MDnsWrapper(object):
"""Handles mDNS requests to device."""
......@@ -432,28 +492,13 @@ class CloudDevice(object):
def on_device_stopped(self):
raise Exception('Not implemented: Device stopped')
def __init__(self, ioloop, state, command_wrapper, delegate):
def __init__(self, ioloop, state, config, command_wrapper, delegate):
self.state = state
self.http = httplib2.Http()
if not os.path.isfile(_API_CLIENT_FILE):
credentials = {
'oauth_client_id': '',
'oauth_secret': '',
'api_key': ''
}
credentials_f = open(_API_CLIENT_FILE + '.samlpe', 'w')
credentials_f.write(json.dumps(credentials, sort_keys=True,
indent=2, separators=(',', ': ')))
credentials_f.close()
raise Exception('Missing ' + _API_CLIENT_FILE)
credentials_f = open(_API_CLIENT_FILE)
credentials = json.load(credentials_f)
credentials_f.close()
self.oauth_client_id = credentials['oauth_client_id']
self.oauth_secret = credentials['oauth_secret']
self.api_key = credentials['api_key']
self.oauth_client_id = config['oauth_client_id']
self.oauth_secret = config['oauth_secret']
self.api_key = config['api_key']
if not os.path.isfile(_API_DISCOVERY_FILE):
raise Exception('Download https://developers.google.com/'
......@@ -470,7 +515,7 @@ class CloudDevice(object):
self.device_id = None
self.credentials = None
self.delegate = delegate
self.command_handler = command_wrapper(ioloop)
self.command_handler = command_wrapper
def try_start(self, token):
"""Tries start or register device."""
......@@ -682,24 +727,35 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate):
return 'complete'
def __init__(self, ioloop, state):
if os.path.exists('on_real_device'):
self.config = Config()
if self.config['on_real_device']:
mdns_wrappers = CommandWrapperReal
cloud_wrapper = CloudCommandHandlerReal
wifi_handler = WifiHandlerReal
self.setup_real()
else:
mdns_wrappers = CommandWrapperReal
cloud_wrapper = CloudCommandHandlerFake
wifi_handler = WifiHandlerPassthrough
if self.config['led_path']:
cloud_wrapper = CloudCommandHandlerReal(ioloop,
self.config['led_path'])
self.setup_real(self.config['led_path'])
else:
cloud_wrapper = CloudCommandHandlerFake(ioloop)
self.setup_fake()
self.cloud_device = CloudDevice(ioloop, state, cloud_wrapper, self)
self.wifi_handler = wifi_handler(ioloop, state, self)
self.setup_ssid = _DEVICE_SETUP_SSID % random.randint(0,99)
self.cloud_device = CloudDevice(ioloop, state, self.config,
cloud_wrapper, self)
self.wifi_handler = wifi_handler(ioloop, state, self.config,
self.setup_ssid, self)
self.mdns_wrapper = MDnsWrapper(mdns_wrappers)
self.on_wifi = False
self.registered = False
self.in_session = False
self.ioloop = ioloop
self.handlers = {
'/internal/ping': self.do_ping,
'/privet/info': self.do_info,
......@@ -733,14 +789,14 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate):
print 'Skipping device setup'
@staticmethod
def setup_real():
def setup_real(led_path):
file_trigger = open(os.path.join(led_path, 'trigger'), 'w')
file_trigger.write('none')
file_trigger.close()
def start(self):
self.wifi_handler.start()
self.mdns_wrapper.set_setup_name(_DEVICE_SETUP_SSID)
self.mdns_wrapper.set_setup_name(self.setup_ssid)
self.mdns_wrapper.start()
@get_only
......
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