blob: aa8bef8f785973138de9dea9031339ee7b07fa8e [file] [log] [blame]
# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Server to support long-polling for values of I/O ports.
Current it only supports Linux GPIO interface.
"""
import logging
import optparse
import os
import SimpleXMLRPCServer
import socket
import SocketServer
import sys
import poll_common
from poll_server import Polld, PolldError
class ThreadedXMLRPCServer(SocketServer.ThreadingMixIn,
SimpleXMLRPCServer.SimpleXMLRPCServer):
"""Threaded SimpleXMLRPCServer."""
daemon_threads = True
allow_reuse_address = True
def parse_args():
"""Parses commandline arguments.
Returns:
tuple (options, args) from optparse.parse_args().
"""
description = (
'%prog is a server to minitor I/O ports. '
'This server communicates with the client via xmlrpc.'
)
examples = (
'\nExamples:\n'
' > %prog -p 8888\n\tLaunch server listening on port 8888\n'
)
parser = optparse.OptionParser()
parser.description = description
parser.add_option('-d', '--debug', action='store_true', default=False,
help='enable debug messages')
parser.add_option('', '--host', default=poll_common.DEFAULT_HOST, type=str,
help='hostname to start server on')
parser.add_option('', '--port', default=poll_common.DEFAULT_PORT, type=int,
help='port for server to listen on')
parser.set_usage(parser.get_usage() + examples)
return parser.parse_args()
def real_main():
(options, args) = parse_args()
loglevel = logging.INFO
format='%(asctime)s - %(name)s - %(levelname)s'
if options.debug:
loglevel = logging.DEBUG
format += ' - %(filename)s:%(lineno)d:%(funcName)s'
format += ' - %(message)s'
logging.basicConfig(level=loglevel, format=format)
logger = logging.getLogger(os.path.basename(sys.argv[0]))
logger.info('Start')
try:
server = ThreadedXMLRPCServer((options.host, options.port),
logRequests=options.debug,
allow_none=True)
except socket.error as e:
error = "Problem opening Server's socket: %s" % e
logger.fatal(error)
raise PolldError(error)
polld = Polld()
server.register_introspection_functions()
server.register_multicall_functions()
server.register_instance(polld)
logger.info('Listening on %s port %s' % (options.host, options.port))
server.serve_forever()
def main():
"""Main function wrapper to catch exceptions properly."""
try:
real_main()
except KeyboardInterrupt:
sys.exit(0)
except PolldError as e:
sys.stderr.write('Error: ' + e.message)
sys.exit(1)
if __name__ == '__main__':
main()