I am trying to get Bluetooth printer to work on a WinCE handheld.
When I run it in PythonCE by execfile('.../bt_ce.py')
, it give no feedback, like I haven't typed in anything. No handle or index is printed back. After I tried it again, it always result in Error 110
or 2102
.
I am very new to C++ and WinCE API. I can't see where the problem is.
My device is a WinCE 5.0 Barcode scanner. My code is as follows adapted from https://msdn.microsoft.com/en-us/library/ms881004.aspx
# -*- coding: utf-8 -*-
import ctypes
from ctypes import POINTER, Structure, c_ulonglong, c_int, pointer, c_ulong, c_wchar
from comtypes import GUID
from ctypes.wintypes import DWORD,WORD,BYTE,UINT, HANDLE, WCHAR, ULONG
INT = c_int
ULONGLONG = c_ulonglong
# typedef ULONGLONG bt_addr, *pbt_addr, BT_ADDR, *PBT_ADDR;
bt_addr = ULONGLONG
BT_ADDR = POINTER(bt_addr)
"""
execfile('\\program files\\ppygui_client\\bluetooth_ce.py')
"""
RFCOMM_PORT_FLAGS_REMOTE_DCB = 0x00000001
RFCOMM_PORT_FLAGS_KEEP_DCD = 0x00000002
RFCOMM_PORT_FLAGS_AUTHENTICATE = 0x00000004
RFCOMM_PORT_FLAGS_ENCRYPT = 0x00000008
RegisterDevice = ctypes.windll.coredll.RegisterDevice
DeregisterDevice = ctypes.windll.coredll.DeregisterDevice
GetLastError = ctypes.windll.coredll.GetLastError
SetLastError = ctypes.windll.coredll.SetLastError
class PORTEMUPortParams(Structure):
_fields_=[
( 'channel' , INT),
( 'flocal', INT ),
( 'device', BT_ADDR),
( 'imtu', INT ),
( 'iminmtu', INT ),
( 'imaxmtu', INT ),
( 'isendquota', INT ),
( 'irecvquota', INT ),
( 'uuidService', GUID ),
( 'uiportflags', UINT)
]
def __init__( self, device_str=None,
flocal=False,
channel = None,
uuidService=None,
uiportflags=None ):
if device_str is None and not flocal:
raise Exception( 'device address missing in client mode.' )
# memset (&pp, 0, sizeof(pp));
ctypes.memset( ctypes.addressof(self), 0, ctypes.sizeof(self) )
self.flocal = INT( flocal )
if not flocal:
bta = c_ulonglong( long(device_str, 16) )
print(bta)
bta_p = BT_ADDR( bta )
self.deivce = bta_p
# I don't have the channel address
# pp.channel # channel & 0xff;
if uuidService:
self.uuidService = uuidService
else:
# https://stackoverflow.com/questions/27302060/how-to-check-if-an-paired-bluetooth-device-is-a-printer-or-a-scanner-android
self.uuidService = GUID("{00001101-0000-1000-8000-00805F9B34FB}")
if channel:
self.channel = channel & 0xff
if uiportflags:
self.uiportflags = uiportflags
print( "try uuidService" )
pp = PORTEMUPortParams('dc1d30428b19')
pp.uiportflags = RFCOMM_PORT_FLAGS_AUTHENTICATE
# pp.uiportflags = RFCOMM_PORT_FLAGS_REMOTE_DCB
# pp.uiportflags = RFCOMM_PORT_FLAGS_REMOTE_DCB | RFCOMM_PORT_FLAGS_AUTHENTICATE
index = 6
SetLastError( DWORD(0) )
#HANDLE h = RegisterDevice ("COM", index, "btd.dll", (DWORD)&pp );
h = RegisterDevice(u"COM", index, u"btd.dll", DWORD( ctypes.addressof(pp) ) )
if h :
print( 'handle=', h )
print( "COM", index )
DeregisterDevice( h )
else:
print('failed', GetLastError())
The port number is incorrect, for somereason, port 1,2,5,6 is always occupied on my device. Changing the port fixes this problem.
The Winsock way is indeed easier to get it working. Accroding to documentation of the .net InTheHand
bluetooth library. There are two ways to setup bt virtual COM port on WinCE, one is RegisterDevice call, the other is via registery controlled service which requires reboot. The former is instable, seems to have no effect on many devices. I guess mine are included, what a waste of time...