Search code examples
bluetoothwindows-cectypespython-2.5pythonce

WinCE bluetooth virtual com port RegisterDevice always result in Error 110 or 2404


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())

Solution

  • 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...