Wiley.Mobile.Python.Rapid.prototyping.of.applications.on.the.mobile.platform.Dec.2007 (779889), страница 27
Текст из файла (страница 27)
This example can easily beused as a basis for any other type of communication: For instance, onceyou have learnt about JSON in Chapter 8, you can modify this client totransfer more complex data structures, such as lists and dictionaries, overthe Bluetooth link. Also, your programs can use this method to transferany files between the PC and the phone.On the PC side, you can use any terminal emulator software, such asHyperTerminal or Screen, to communicate with the client.
Appendix BPHONE-TO-PC COMMUNICATION143explains how to use one. If you have already used the PyS60 interpreter’sBluetooth console, you are already familiar with this setting.Example 59: Bluetooth clientimport appuifw, socket, e32ECHO = Truedef choose_service(services):names = []channels = []for name, channel in services.items():names.append(name)channels.append(channel)index = appuifw.popup_menu(names, u"Choose service")return channels[index]def read_and_echo(fd):buf = r = ""while r != "\n" and r != "\r":r = fd.read(1)if ECHO: fd.write(r)buf += rif ECHO: fd.write("\n")return bufaddress, services = socket.bt_discover()channel = choose_service(services)conn = socket.socket(socket.AF_BT, socket.SOCK_STREAM)conn.connect((address, channel))to_peer = conn.makefile("rw", 0)while True:msg = appuifw.query(u"Send a message", "text")if msg:print >> to_peer, msg + "\r"print "Sending: " + msgprint "Waiting for reply..."reply = read_and_echo(to_peer).strip()appuifw.note(unicode(reply), "info")if reply.find("bye!") != -1:breakelse:breakto_peer.close()conn.close()print "bye!"The program starts by discovering nearby Bluetooth devices.
Youshould choose your PC from the presented list. Then, the functionchoose service() is used to show a popup menu that lists theservices that are available on the chosen device. In this list, you shouldsee an entry such as ‘Serial Port’ or ‘PyBook’, if everything is set upcorrectly on the PC side. The function returns a channel number thatcorresponds to the chosen service.144BLUETOOTH AND TELEPHONE FUNCTIONALITYThe Bluetooth address of your computer and the channel corresponding to its RFCOMM port are then known and we can establish aconnection to the PC. We convert the connected socket to a convenientfile object with the makefile() function. Now we have an activeBluetooth link to the PC.As in the chat example, we handle communication in an infinite loop.The client is the first to send a message – if you choose to cancel the‘Send a message’ dialog, the program exits.
Otherwise, we send the lineyou typed to PC with the following expression:print >> to_peerNote that we add an additional character, "\r" or carriage return, atthe end of the line. This is needed by the terminal emulator software onthe PC side to start a new line properly.In the chat example we used the file object’s standard readline()function to receive a line. That would be a working option here as well,if we ran a program of our own on the PC side, but in this case we arecommunicating with a terminal emulator and that needs some specialtreatment.The function read and echo() is a custom implementation of thestandard readline() function.
Compared to the standard function,there are two differences: the line may end in either a carriage returncharacter, "\r", or a new line character, "\n"; and the function mayecho each character back to the sender, if the constant ECHO is set True.One character is read at a time, using the fd.read(1) expression. Aterminal emulator expects that the other end is responsible for showingthe characters typed, thus, unless we echo the characters back to the PC,you can send messages to the phone but you cannot see the characterswhile you type.The received line is shown in a popup dialog. If the line contains thestring ‘‘bye!’’, the connection is shut down.
Thus, you may close theconnection by typing ‘‘bye!’’ on the terminal emulator software.You can now try this example: follow the instructions in Section B.2on how to start a terminal emulator software PC with an RFCOMM serialport. Instead of using the standard Bluetooth console on the phone side,use the example above.
If everything works correctly, the first messagethat you typed on the phone should appear on the terminal emulator. Youcan continue sending messages back and forth until you press cancel onthe phone or send ‘‘bye!’’ from the PC side.7.4.2 Creating Bluetooth Servers with PySerialSection 7.4.1 showed how to make a phone client that communicateswith the PC. However, we used a standard terminal emulator on the PCPHONE-TO-PC COMMUNICATION145side, so the messages that were sent to the phone were typed in manually.The most flexible approach, however, is to make servers of your own.This way you can access all resources on your PC, process information,send results to the phone and receive commands from it over a Bluetoothlink without any manual attendance. This section shows you how.You can access the serial port on the PC side most easily with acustom Python module, PySerial, which is available at http://pyserial.sourceforge.net.
Install the module as instructed on the Web page.Naturally you need a Python interpreter installed on your PC as well. Youcan find the newest one at www.python.org.Example 60 creates a simple server program for your PC, using PySerial,that receives messages from the phone and responds to them automatically. The functionality is demonstrated by a simple ’Guess my number’game: the server picks a random number between 1 and 10 and thephone user has to guess it.Example 60: PySerial script running on PCimport serial, sys, randomif sys.platform.find("win") != -1:PORT = 0elif sys.platform.find("linux") != -1:PORT = "/dev/rfcomm0"elif sys.platform.find("darwin") != -1:PORT = "/dev/tty.pybook"num = random.randint(1, 10)serial = serial.Serial(PORT)print "Waiting for message..."while True:msg = serial.readline().strip()guess = int(msg)print "Guess: %d" % guessif guess > num:print >> serial, "My number is smaller"elif guess < num:print >> serial, "My number is larger"else:print >> serial, "Correct! bye!"breakYou can use the client program in Example 59 to play the game.However, one minor modification is needed: this program is not interestedin receiving back the characters it sent, so we can disable echoing in theclient.
Replace the line ECHO = True with ECHO = False in the clientcode.In the beginning, we choose the port for communication based on theplatform where the server is running. If you are using Windows, the linePORT = 0 corresponds to the COM port that you set up for Bluetooth146BLUETOOTH AND TELEPHONE FUNCTIONALITYcommunication in Section B.1. Note that indexing starts from zero, soPORT = 0 corresponds to COM1 and so on. For Linux and Mac, the filename should be correct unless you modified the default name used inthe instructions, in which case you should change the file name hereaccordingly.The server is a straightforward one: once the serial port is opened andassigned to the variable serial, we can start communicating with thephone through it.
The Serial object works like a standard file object,so we can use the familiar readline() function to read a line at timefrom the client. Each line should contain one number, which is thencompared to the correct one, num, after which an appropriate hint is sentback to the phone. When extending the example, note that the PySerialmodule contains many useful options, such as timeout values, which canbe used to tune the server. See the PySerial documentation for a full listof features.To use this program, follow the instructions in Section B.2 but nowinstead of opening a terminal emulator, such as Screen or HyperTerminal,you need to execute Example 60 on the PC side. On the PC, a Pythonscript is executed by typing the command python btserver.py intothe command shell.
The file btserver.py should contain the code forExample 60.Even though the ’Guess my number’ game might not seem fascinatingin itself, you should notice how easily one can build software on the PCside that communicates with the phone. There are thousands of custommodules freely available for Python, which let you control and accessvarious devices and applications on the PC. With this method, you cancontrol any of those modules with your mobile phone over Bluetooth.For example, you could turn your PC into a multiplayer gameconsole which uses mobile phones as controllers – have a look atwww.pygame.org to get started with making games in Python.
If youare an artist, you can make stunning interactive installations usingwww.nodebox.net, controlled by a mobile phone.Section 7.4.3 shows how to control any application on your Mac OS Xwith your mobile phone. Even if you use Windows or Linux, you mightwant to have a look at the next section, since the basic idea can beapplied with other operating systems as well.7.4.3Controlling Applications with AppleScriptThe Mac OS X operating system includes a programming language calledAppleScript. Its main purpose is to provide a simple mechanism toautomate usage of any application. You can find more information aboutit at www.apple.com/applescript.Similar mechanisms also exist for other environments.
For example, inLinux you can easily use Example 61 to execute any command or shellPHONE-TO-PC COMMUNICATION147script on the command line. Major desktop environments for Linux, KDEand Gnome, also support some AppleScript-like mechanisms to controlapplications programmatically.Example 61 lets you, or possibly someone else, use your computerremotely. You should understand that doing this is potentially dangerous,especially if the program is executed in a public space. You should neverrun a server that lets the phone freely choose a command to execute.Instead, have a predefined list of commands that the phone is allowedto use and make sure that these commands cannot do any harm to yourcomputer.We need a special Python server program that runs on the Mac andexecutes an AppleScript file, as requested by the phone. Basically, theserver is similar to Example 60 but, because of its specific purpose, thisone contains even fewer lines of code.Example 61: AppleScript interface running on Macimport serial, osALLOWED_SCRIPTS = ["edit"]ser = serial.Serial('/dev/tty.pybook')print "Waiting for message..."while True:msg = serial.readline().strip()if msg == "exit":print >> serial, "bye!"breakelif msg in ALLOWED_SCRIPTS:print "Running script: " + msgos.system("osascript %s.script" % msg)print >> serial, "Script ok!"The idea is that the phone client is used to choose one of the scripts toexecute on the PC side.
Once again, we can use Example 59 as the phoneclient. Again, echoing should be disabled by setting ECHO = False inthe client.In Python, the os.system() function is used to execute an externalcommand. In this case, we execute the command osascript that isused to interpret AppleScripts on Mac OS X. However, the script namemust exist on the ALLOWED SCRIPTS list before it can be executed.This makes sure that a malicious user cannot connect to the server andexecute any command she likes, for instance to format the hard disk. Ifthe phone sends the line exit, the connection is shut down.