# written by Ralf Ackermann # this code is described at # http://www.ubiqkom.org/blog/?cat=9 # your tasks # - use the address of your BT keyboard (the code has the address of mine) # - pair the keyboard typing 0000 during the connection establishment # you need # - the RBT-001 BT module manual - http://www.tigal.com/product.asp?pid=1124 # to understand / modify it # - the kbdd source code - http://fanoush.webpark.cz/maemo/ # to understand / interpret the output it generates when you press / release keys import serial import time import sys # ================================================ def calculate_crc(data, size): # print "calculate_crc()" crc=0 crc=data[1]+data[2]+data[3]+data[4] crc=crc & 0xff # we need the lower byte of the sum # print "crc (hex): 0x%02x" % crc return(crc) # ================================================ def dump_hex_and_ascii(data, size): chars_per_line=0 for i in range(0, size): sys.stdout.write("%02x " % ord(data[i])) chars_per_line=chars_per_line+1 if (chars_per_line == 8): print "" chars_per_line=0 if (chars_per_line != 0): print "" chars_per_line=0 for i in range(0, size): char_2_print=ord(data[i]) if ((char_2_print < 32) | (char_2_print > 126)): char_2_print='.' sys.stdout.write(" %c " % char_2_print) chars_per_line=chars_per_line+1 if (chars_per_line == 8): print "" chars_per_line=0 if (chars_per_line != 0): print "" # ================================================ def rbt_receive_response(): available_bytes=0 available_bytes=ser.inWaiting() if (available_bytes > 0): print "available_bytes: ", available_bytes read_data=ser.read(available_bytes) dump_hex_and_ascii(read_data, available_bytes) # print "read_data: ", read_data # ================================================ def rbt_send_cmd_receive_response(data, size): print "rbt_send_cmd_receive_response(%02x)" % data[2] crc=calculate_crc(data, size) data[5]=crc for i in range(0, size): # print "Writing: %x" % data[i] ser.write(chr(data[i])) # time.sleep(0.1) # time.sleep(1.0) time.sleep(3.0) rbt_receive_response() # ================================================ # 1 byte start delimiter # === start of CRC area === # 1 byte packet type identification # 0x52 ('R") - request # 0x43 ('C') - confirm # 0x69 ('i') - indication # 0x72 ('r') - response # 1 byte opcode # 2 byte data length # === end of CRC area === # 1 byte checksum # length bytes data # 1 byte end delimiter # ------ # remote device name # take care to observe the byte order # N95 BT address - 00 18 42 e9 f8 ba # cmd_02=[0x02, 0x52, 0x02, 0x06, 0x00, 0x00, 0xba, 0xf8, 0xe9, 0x42, 0x18, 0x00, 0x03] # N95 # BT keyboard BT address - 00 0b 0d 8a 36 3a cmd_02=[0x02, 0x52, 0x02, 0x06, 0x00, 0x00, 0x3a, 0x36, 0x8a, 0x0d, 0x0b, 0x00, 0x03] # BT keyboard - CRC still to be determined cmd_02_length=len(cmd_02) # ------ # read local name cmd_03=[0x02, 0x52, 0x03, 0x00, 0x00, 0x00, 0x03] cmd_03_length=len(cmd_03) # ------ # write local name cmd_04=[0x02, 0x52, 0x04, 0x05, 0x00, 0x00, 0x04, 0x52, 0x42, 0x54, 0x00, 0x03] cmd_04_length=len(cmd_04) # ------ # read local name cmd_05=[0x02, 0x52, 0x05, 0x00, 0x00, 0x00, 0x03] cmd_05_length=len(cmd_05) # ------ # get fixed PIN cmd_16=[0x02, 0x52, 0x16, 0x00, 0x00, 0x00, 0x03] cmd_16_length=len(cmd_16) # ------ # get security mode cmd_18=[0x02, 0x52, 0x18, 0x00, 0x00, 0x00, 0x03] cmd_18_length=len(cmd_18) # ------ # list paired devices cmd_1c=[0x02, 0x52, 0x1c, 0x00, 0x00, 0x00, 0x03] cmd_1c_length=len(cmd_1c) # ------ # establish link cmd_0a=[0x02, 0x52, 0x0a, 0x08, 0x00, 0x00, 0x01, 0x3a, 0x36, 0x8a, 0x0d, 0x0b, 0x00, 0x01, 0x03] # BT keyboard - CRC still to be determined cmd_0a_length=len(cmd_0a) # ------ # reset cmd_26=[0x02, 0x52, 0x26, 0x00, 0x00, 0x78, 0x03] cmd_26_length=len(cmd_26) # ------ # main program starts here # ------ ser = serial.Serial("/dev/tty.SLAB_USBtoUART") print "Using serial port: ", ser.portstr # rbt_send_cmd_receive_response(cmd_26, cmd_26_length) # reset rbt_send_cmd_receive_response(cmd_04, cmd_04_length) # write local name rbt_send_cmd_receive_response(cmd_03, cmd_03_length) # read local name rbt_send_cmd_receive_response(cmd_05, cmd_05_length) # read local bluetooth address rbt_send_cmd_receive_response(cmd_16, cmd_16_length) # get fixed PIN rbt_send_cmd_receive_response(cmd_18, cmd_18_length) # get security mode rbt_send_cmd_receive_response(cmd_1c, cmd_1c_length) # list paired devices rbt_send_cmd_receive_response(cmd_02, cmd_02_length) # remote device name rbt_send_cmd_receive_response(cmd_0a, cmd_0a_length) # establish link print "=======================" print "Entering receive loop !" print "=======================" # we expect SPP_INCOMING_DATA indicator packets for pressed / released keys now # this is just for test - so press CTRL-C to stop while (1 == 1): rbt_receive_response() time.sleep(2.0) ser.close()