msg50698 - (view) |
Author: Qiu Yingbo (qyb) |
Date: 2006-07-14 08:19 |
the patch implements IrDA socket's getsockaddrarg() support under Linux and Win32 platform. Now we can connect to IrDA device from a socket object and build more flexible wireless application. I have test it under Windows XP. Simple test: connect a irda device from socket import * from struct import * s = socket(AF_IRDA, SOCK_STREAM) info = s.getsockopt(SOL_IRLMP, IRLMP_ENUMDEVICES, 1024) list = info[4:] list addr = unpack('I', list[:4])[0] s.connect((addr, "IrDA:IrCOMM")) s.close() Complex test: Get mobile phone's deviceinfo by OBEX protocol from struct import * from socket import * def obex_genheader_byte_stream(opcode, byte_stream): length = htons(3 + len(byte_stream)) return chr(opcode) + pack('h', length) + byte_stream def obex_genheader_unicode(opcode, unistr): unistr = unistr + '\x00\x00' length = htons(3 + len(unistr)) return chr(opcode) + pack('h', length) + unistr def obex_connect(sockobj, target): if (len(target)): header = obex_genheader_byte_stream(0x46, target) else: header = '' length = htons(7 + len(header)) cmd = chr(0x80) + pack('h', length) + chr(0x10) + chr(0) + pack('h', htons(1024)) + header sockobj.sendall(cmd) return True def obex_get(sockobj, filename): header = obex_genheader_unicode(0x01, filename) length = htons(3 + len(header)) cmd = chr(0x83) + pack('h', length) + header sockobj.sendall(cmd) return True s = socket(AF_IRDA, SOCK_STREAM) info = s.getsockopt(SOL_IRLMP, IRLMP_ENUMDEVICES, 1024) list = info[4:] addr = unpack('I', list[:4])[0] s.connect((addr, "IrDA:OBEX")) obex_connect(s, '') response = s.recv(4096) obex_get(s, "telecom/devinfo.txt".encode('utf-16be')) response = s.recv(4096) print response[6:] s.close() |
|
|
msg109870 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2010-07-10 14:04 |
A new patch should be generated against 3.2 (the current one doesn't apply cleanly). Also, checking for linux/irda.h requires that sys/socket.h is included, hence needing the following snippet in configure.in: # On Linux, irda.h requires sys/socket.h AC_CHECK_HEADERS(linux/irda.h,,,[ #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif ]) |
|
|
msg109882 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2010-07-10 15:46 |
Here is a straight port of the patch to py3k, compiling under Linux and Windows. Several problems though: 1. the patch seems incomplete, in that manual decoding of return values is necessary (see posted example obex_test.py) 2. there seems to be no way to test it if you don't have an IRDA device (I don't have any) 3. the patch itself seems fragile: for example, it won't always put a terminating '\0' in sir_name; also, straight memcpy() of an int into a char[] buffer is wrong (endianness issues) |
|
|
msg159200 - (view) |
Author: Charles-François Natali (neologix) *  |
Date: 2012-04-24 20:00 |
Here's a cleanup up patch against default. However, I don't have any IrDA capable device neither, so I won't be able to help much. I'll ask on python-dev if someone can help. As for the manual decoding, AFAICT you'll have the same issue with CAN sockets. The real question is really "how high-level should the socket module be?". Because if we added let's say and IRDASocket type, then we could easily add helper functions to and methods to e.g. list available IrDA devices, decode fields, etc. Same thing holds for CAN sockets, and one could imagine we could also maybe add a MulticastSocket that would make joining/leaving a multicast group easy (because it is a pain), etc. |
|
|
msg159333 - (view) |
Author: Gregory P. Smith (gregory.p.smith) *  |
Date: 2012-04-25 19:34 |
Your updated patch looks fine to me. I don't see any reason not to commit it and mention it in the release notes. If it has bugs, they can be discovered and fixed later by people with actual relevant hardware an interest. |
|
|
msg159338 - (view) |
Author: Charles-François Natali (neologix) *  |
Date: 2012-04-25 20:57 |
Actually I think it suffers from the same problem as AF_UNIX: sockaddr_irda->sir_name, like sockaddr_un->sun_path, don't have to be NUL-terminated, and the kernel can return non NUL-terminated strings. Which means that such code: { /* regular NULL-terminated string */ return PyUnicode_DecodeFSDefault(a->sun_path); } or return Py_BuildValue("iO&", a->sir_addr, PyUnicode_DecodeFSDefault, a->sir_name); can overrung pas sun_path/sir_name, and potentially segfault. See http://bugs.python.org/issue8372. What's the simplest way to account for this? Is there a way to pass PyUnicode_DecodeFSDefault a max length (without having to make an intermediary copy or sir_name, appending a NUL at the end)? |
|
|
msg159670 - (view) |
Author: Charles-François Natali (neologix) *  |
Date: 2012-04-30 07:44 |
> Actually I think it suffers from the same problem as AF_UNIX: > sockaddr_irda->sir_name, like sockaddr_un->sun_path, don't have to be > NUL-terminated, and the kernel can return non NUL-terminated strings. Actually, I've had a look at the Linux and Windows documentation, and sir_name is NUL-terminated. I've also had a look at the kernel source, and it treats sir_name as NUL-terminated, so it should be safe. Here's a new patch, with a couple new constants, documentation update and some - really basic - tests. I guess Gregory is right, and we could push this as-is, and wait until some users is interested in improving the support and tests. |
|
|