#!/usr/bin/python

# bluetooth communication with lego mindstorms ev3

#based on
# file: rfcomm-client.py
# auth: Albert Huang <albert@csail.mit.edu>
# desc: simple demonstration of a client application that uses RFCOMM sockets
#       intended for use with rfcomm-server
#
# $Id: rfcomm-client.py 424 2006-08-24 03:35:54Z albert $

from bluetooth import *
import sys
import array
from os.path import getsize
import struct
import time
import argparse

if sys.version < '3':
    input = raw_input

# bluetooth address of ev3 brick; displayed by hcitool scan
#addr = "AA:BB:CC:DD:EE:FF"
addr = "00:16:53:43:A3:B5"

parser = argparse.ArgumentParser(description='Receive text messages by bluetooth from ev3 brick and optionally save them into file(s); with default address '+addr)
#parser.add_argument('filename')
parser.add_argument('filenames', metavar='F', nargs='*', help='file(s) to store messages')
parser.add_argument('-a', '--address', metavar='MAC', default=addr, help='bluetooth address of ev3 brick')
parser.add_argument('-c', '--count', type=int, metavar='N', default=0, help='receive N messages; if files are given then N = number of files')
parser.add_argument('-q','--quiet', action='count', help='do not print message(s); -qq: silent')

args = parser.parse_args()

#msgfile2 = args.filename
msgfiles2 = args.filenames
addr = args.address


# search service at given address
service_matches = find_service( address = addr )

if len(service_matches) == 0:
    print("couldn't find service at address %d" % addr)
    sys.exit(0)

first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]

if args.quiet < 2:
	print("Found %i services. Connecting to \"%s\" (channel %s) on %s" % (len(service_matches), name, port, host))

# Create the client socket
sock=BluetoothSocket( RFCOMM )
sock.connect((host, port))

n2 = 0
n = len(msgfiles2)
if args.quiet < 2:
	if n==0:
		if  args.count==0:
			print("Connected. Waiting for messages ... (press ctrl+c to quit.)")
		else:
			print("Connected. Waiting for %i message(s) ... (press ctrl+c to quit.)" % args.count)
	else:
		print("Connected. Waiting for %i message(s) ... (press ctrl+c to quit.)" % n)

def fetch_data():
	global data
	try:
		data=sock.recv(1024)
		n2=len(data)
		if args.quiet < 2:
			print("%i bytes received" % n2)
		if n2 >= 2:
			[msglen] = struct.unpack("<H", data[0:2])
		else:
			if args.quiet < 1:
				print("not enough data received; (only %i bytes)" % n2)
		
		if n2 < 2+msglen and args.quiet < 1:
			print("not enough data received; (only %i bytes; required %i bytes)" % (n2, 2+msglen))
		
		[textlen] = struct.unpack("<H", data[7+ord(data[6]):9+ord(data[6])])
		msgtitle=data[7:7+ord(data[6])]
		msgtext=data[9+ord(data[6]):9+ord(data[6])+textlen]
		if args.quiet < 1:
			print("%s\n%s\n" % (msgtitle, msgtext))
	except KeyboardInterrupt:
		sock.close()
		if args.quiet < 2:
			print "Interrupted by user"
		return 0
	except BluetoothError:
		sock.close()
		if args.quiet < 2:
			print "bluetooth disconnected"
		return 0
	return 1

if n==0:
	if  args.count==0:
		while fetch_data():
			continue
	else:
		for i in range(args.count):
			if not fetch_data():
			    break
else:
	for msgfile2 in msgfiles2:
		if fetch_data() and len(data)>0:
			msg2 = array.array('B')
			msg2.fromstring(data)
			try:
				f2=open(msgfile2,"wb")
			except IOError:
				print("error: could not write file '%s'." %msgfile2)
				continue
			try:
				msg2.tofile(f2)
			except IOError:
				print("error: could not write file '%s'." %msgfile2)
				continue
			try:
				f2.close()
			except IOError:
				print("error: could not write file '%s'." %msgfile2)
				continue
			del msg2

sock.close()
