Archived:How to access Symbian resources in WRT or Flash Lite, using PySymbian
Article Metadata
Code Example
Article
Contents |
Introduction
New programming languages for mobile application development, such Flash Lite and WRT, can't access device native resources such as GPS, Accelerometer, etc. This problem happens because they usually run in a sandbox. An approach that fixes this problem is the development of an access layer which must be between device and mobile application (Flash Lite or WRT). This access layer can be developed in any programming language that has native access to the device.
The figure below shows how this layer works.
Solution
We propose the development of a mobile web server written in Python language which the main goal is to allow the retrieval of available native services in a Web Service REST-based approach. The web server was developed in an extensible manner that allows an easy addition of new services, decoupling the parameters handling of the service implementation. Due to that, it's possible to write a service with just the business logic itself.
Figure 2 depicts our architecture solution. There are three main entities associated with the architecture: client, HTTP server and the services.
- Client: the application written in whatever technology, such as WRT or FlashLite, which requires internal resources. This application is completely independent from ServerPython, because this use only HTTP request to communicate with it.
- HTTP Server: Manages all requests from Clients and invokes the right service.
- Services: A set of services implemented by the developer. This is the hotspot of the ServerPython framework.
Figure 2. Architecture of the Mobile Web Server
Figure 3 shows the class diagram of the ServerPython. The Services class is the hotspot of the framework. The developer has to create methods and call the addCallBack method of the MyServer class added in the instance of Services.
Figure 3. Class diagram
The Source-Code
In this section, we present some of the main features of our solution.
The code below presents the HTTPServer class which handles the HTTP requests.
class HTTPServer:
def __init__(self, host, port):
"""This class is responsible for parsing the HTTP request and calling the correct method"""
self.host = host;
self.port = port;
self.callbacks={}
def doGet(self, request, response):
"""This method is called when a GET request is sent to the web server. It MUST be overwritten in subclasses and it's called through template method design pattern"""
pass
def doPost(self, request, response):
"""This method is called when a POST request is sent to the web server. It MUST be overwritten in subclasses and it's called through the template method design pattern"""
pass
def __handlerAttributes(self, rawAttributes):
"""This method is called to handler the attributes of the HTTP request"""
rawAttributes=rawAttributes[:-2]
map={}
for i in rawAttributes:
map[i[:i.find(':')]]=i[i.find(':')+2:-1]
return map
def __handlerRequest(self, connection, rawRequest):
"""This method is called to handler the request. It splits the tokens, call the '__handlerAttributes' method and finaly call the correct request, i.e. GET or POST method"""
self._rawRequest = rawRequest
tokenizedLine=self._rawRequest.split('\n')
requestLine=tokenizedLine[0]
attributes = self.__handlerAttributes(tokenizedLine[1:])
tokenizedLine = requestLine.split()
attributes["request-method"]=tokenizedLine[0]
attributes["requisition"]=tokenizedLine[1]
attributes["http-version"]=tokenizedLine[2]
request_object = attributes["requisition"]
if request_object.startswith('/'):
request_object=request_object[1:]
objects=request_object.split('?')
attributes["object-requested"]=objects[0]
map={}
if len(objects)>1:
objects=objects[1].split('&')
for i in objects:
iObject = i.split('=')
map[iObject[0]]=iObject[1]
attributes["parameters"]=map
request = Request(self._rawRequest, attributes)
response = Response()
if attributes["request-method"]=='GET':
self.doGet(request, response)
elif attributes["request-method"]=='POST':
self.doPost(request, response)
rsp = response.getResponse()
connection.send(rsp)
class MyServer(HTTPServer):
"""This is a subclass of HTTPServer. The implementation of the GET HTTP method is provided. In our case, we call the correct service"""
def __init__(self,host, port):
HTTPServer.__init__(self, host, port)
def doGet(self, request, response):
"""Implementation of the GET method"""
functionName=request.getProperty("object-requested")
attributes=request.getProperty("parameters")
response.println(str(self.callbacks[functionName](attributes))) # Call the service requested and return the result as a string
This is a service example. In this function we retrieve the position of device through GPS
def get_position(attributes):
positioning.select_module(positioning.default_module())
pos=positioning.position()['position']
ret='latitude=' + str(pos['latitude']) + '&longitude=' + str(pos['longitude'])
return ret
This is a piece of code that shows how to start the server and to add a service.
server = MyServer('127.0.0.1',5004)
server.addCallBack("get_position", get_position)
server.startServer()
Step-by-step guide to install and use the ServerPython
- Download and install spython.sis into your device.
- Start the spython application.
- Start the application which uses the intended resource (Flash Lite or WRT)
The developer can easily include new methods into the S60ServerPython, which requires minor knowledges about Python language. Below is described the required steps to make this task.
Implement a method 'method_x' in the Services class. It imposed just one restriction to the new method structure. The method MUST receive a map representing the passed parameters of the URL.
Execute the method 'server.addCallBack('url_to_x', method_x)', where server is an attribute of the type MyServer inside the Services class.
Download
Here you can download the source code and the SIS file of the ServerPython. Note that if you want to use GPS, you have to install the SIS file. Click here to get the zip file with the source and SIS.
An example application in Flash Lite
As discussed previously, a client (Flash Lite) application has access to S60 internal resources through HTTP requests. In ActionScript 2.0 (which is used in Flash Lite 2.x and 3.x) a HTTP request can be executed using the LoadVars class. The basic use of this class is shown below:
var lv:LoadVars = new LoadVars();
lv.onLoad = function(success:Boolean){
//Actions when data is loaded.
}
lv.sendAndLoad("http://www.iana.org/domains/example/",lv,"GET");
The http://www.iana.org/domains/example/ URL has to be changed to http://127.0.0.1:5004/get_position
if you want to get the GPS position from the device using the ServerPython.
A complete example on getting GPS position and showing a Google static map can be found here: File:Gps-serverpython.zip example project. More details about this example code are available here: Accessing system resources with PySymbian on S60 3rd Edition devices.
Created by
- Ivo Calado (ivocalado [at] embedded [dot] ufcg [dot] edu [dot] br)
- Marcos Fábio Pereira (marcos [at] embedded [dot] ufcg [dot] edu [dot] br)




