c - Get a FILE* from a bluetooth COM port on Windows -
a c library use requires file* opened com port work it, have set port (connection speed, etc) before passing library. on windows, done using setcommstate(handle, dcb*).
transformation between handle , file* solved problem (how make file* handle in winapi? , how file handle fopen file structure?), but, surprisingly, fails in different ways when applied com ports obtained via bluetooth (rfcomm/spp).
if first open handle , set com port parameters, _open_osfhandle fails me:
handle qc9200_handle = createfile(t("\\\\.\\com9"), generic_read | generic_write, 0, null, open_existing, file_attribute_normal, null); /* returns valid value 0x30 */ setcommstate(qc9200_handle, &qc9200_dcb); /* succeeds */ int qc9200_fd = _open_osfhandle((intptr_t)qc9200_handle, _o_rdwr|_o_binary); /* returns -1 , sets errno=einval (22) */
i tried setting various combinations of flags _o_append (the 1 both mentioned in the docs , makes sense application) _o_rdwr|_o_binary (which thought should have worked), errno einval.
if try start file* or int file_descriptor produce handle later, both _topen(path, _o_rdwr|_o_binary)
, _tfopen(path, "r+b")
fail right away , set errno=eacces (13) no matter access mode request, when launch application administrator rights. don't fail immediately, though, takes second, , can see light flashing on usb dongle before failure. trying open(comport, "+<", "\\\\.\\com9")
port perl fails "access denied".
fishing events processmonitor, surprisingly, gives bunch of regqueryvalue hklm\system\currentcontrolset\enum\bthenum_localmfg\device parameters\{port name, authenticated, encrypted} , 1 irp_mj_read %windir%\system32\ucrtbased.dll while fopen on stack.
the com port in question obtained using ordinary windows 7 bluetooth settings, , every terminal program capable of working com ports access it, too, if not run administrator. when same things virtual com port (com0com), works expected; errors persist when i'm using bluetooth com port.
upd: getfiletype(handle) reveals, handle bluetooth com port not file-handle, nor getfiletype knows about. that's why c runtime library refuses return file descriptor handle , that's why fopen refuses open port. i'll have implement fprintf-like function accepts handles instead , #ifdef , use on windows.
thanks russian language forum, able solve this.
after opening handle
virtual com port, called getfiletype()
on it,
printf("handle=%d\ngetfiletype=%lu\n", handle, getfiletype(handle));
which resulted in
handle=36 getfiletype=0
with getlasterror
returning 0.
getfiletype(handle) == 0x0000
means file_type_unknown
.
it seems crt doesn't know how produce file*
unknown-type handles
, way run vfprintf
-like function write serial port implement such function handle
s myself.
given it's bad idea use file*
serial ports because standard library issue seek()
calls between reads , writes, , serial ports unseekable, had drop file*
, use plain int
file descriptors on posix , handle
s on windows.
Comments
Post a Comment