Skip to content
Maciej Wasilak edited this page Jan 14, 2014 · 2 revisions

This page is meant for collecting some important bits of knowledge, that do not fit anywhere else.

Twisted

Twisted UDP IPv6 Support

Twisted UDP currently doesn't support IPv6 for UDP communications. There is a ticket for that, and most probably Twisted 14.0 will have official support. But for now a hack is needed:

Inside file twisted/Twisted-13.x.x/twisted/internet/udp.py :

    def __init__(self, port, proto, interface='', maxPacketSize=8192, reactor=None):
        """
        Initialize with a numeric port to listen on.
        """
        base.BasePort.__init__(self, reactor)
        self.port = port
        self.protocol = proto
        self.maxPacketSize = maxPacketSize
        self.interface = interface
        self.setLogStr()
        self._connectedAddr = None
+       if interface and abstract.isIPv6Address(interface): ###
+          self.addressFamily = socket.AF_INET6 ###

and

    def doRead(self):
        """
        Called when my socket is ready for reading.
        """
        read = 0
        while read < self.maxThroughput:
            try:
                data, addr = self.socket.recvfrom(self.maxPacketSize)
            except socket.error as se:
                no = se.args[0]
                if no in _sockErrReadIgnore:
                    return
                if no in _sockErrReadRefuse:
                    if self._connectedAddr:
                        self.protocol.connectionRefused()
                    return
                raise
            else:
                read += len(data)
                try:
+                 addr = (addr[0], addr[1]) ###
                    self.protocol.datagramReceived(data, addr)
                except:
                    log.err()

This allows for simple unicast UDP communication. Works on Windows, Linux and Android.

Kivy and python-for-android

Installing python-for-android

Official installation guide is well-written - I had no problems with the process. Android NDK doesn't seem to contain all Android versions - for example there is no version for Android 4.1.2. I used the nearest lower version.

Updating Twisted version inside python-for-android

It is possible to update Twisted version to current one (for example 13.2) inside file /python-for-android/recipes/twisted/recipe.sh Python-for-android will download new Twisted version into python-for-android/build/twisted. However it won't start using it inside distro builds. Last time I manually replaced old Twisted with the new one in directory /python-for-android/build/python-install/lib/python2.7/site-packages/twisted.

Adding IPv6 support to python-for-android

You need to modify files in directory /python-for-android/build/python/Python-2.x.x/:

/configure /congfigure.in

Details are in the link and link.

diff -wuprN Python-2.7.2/configure Python-2.7.2-new/configure
--- Python-2.7.2/configure        2011-06-11 17:46:28.000000000 +0200
+++ Python-2.7.2-new/configure        2012-08-13 00:28:43.083150979 +0200
@@ -10881,20 +10881,8 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_buggy_getaddrinfo" >&5
 $as_echo "$ac_cv_buggy_getaddrinfo" >&6; }
 
-if test $have_getaddrinfo = no -o "$ac_cv_buggy_getaddrinfo" = yes
-then
-        if test $ipv6 = yes
-        then
-                echo 'Fatal: You must get working getaddrinfo() function.'
-                echo ' or you can specify "--disable-ipv6"'.
-                exit 1
-        fi
-else
-
 $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
 
-fi
-
 for ac_func in getnameinfo
 do :
   ac_fn_c_check_func "$LINENO" "getnameinfo" "ac_cv_func_getnameinfo"
diff -wuprN Python-2.7.2/configure.in Python-2.7.2-new/configure.in
--- Python-2.7.2/configure.in        2011-06-11 17:46:28.000000000 +0200
+++ Python-2.7.2-new/configure.in        2012-08-13 00:27:38.479150981 +0200
@@ -3125,17 +3125,17 @@ fi
 
 AC_MSG_RESULT($ac_cv_buggy_getaddrinfo)
 
-if test $have_getaddrinfo = no -o "$ac_cv_buggy_getaddrinfo" = yes
-then
-        if test $ipv6 = yes
-        then
-                echo 'Fatal: You must get working getaddrinfo() function.'
-                echo ' or you can specify "--disable-ipv6"'.
-                exit 1
-        fi
-else
+#if test $have_getaddrinfo = no -o "$ac_cv_buggy_getaddrinfo" = yes
+#then
+#        if test $ipv6 = yes
+#        then
+#                echo 'Fatal: You must get working getaddrinfo() function.'
+#                echo ' or you can specify "--disable-ipv6"'.
+#                exit 1
+#        fi
+#else
         AC_DEFINE(HAVE_GETADDRINFO, 1, [Define if you have the getaddrinfo function.])
-fi
+#fi
 
 AC_CHECK_FUNCS(getnameinfo)

Buliding Kivy distribution

Commands:

cd ~/python-for-android/
./distribute.sh -m twisted kivy

This script builds new python-for-android distribution with Kivy and Twisted support.

Compiling Kivy browser

Type:

cd ~/python-for-android/dist/default/
./build.py --dir ~/my_txThings_app --package me.mydomain.coap.browser --name "CoAP Browser" --orientation "sensor" --version 0.0.1 --permission INTERNET debug

This script builds the application inside ~/my_txThings_app (main.py file has to be present). Options describe app name, version, Android permissions, and screen setting (use "sensor" for auto-rotate)

Downloading app to the phone

Connect the phone with USB cable, enable USB debugging and type:

cd ~/python-for-android/dist/default/bin
adb install -r CoAPBrowser-0.0.1-debug.apk

This downloads app to the phone. You can run your app.

Adjusting screen resolution

You can run kivy app in a window, so that it looks almost like on a phone:

On Windows you need a .BAT file:

@ECHO OFF
ECHO Settings metrics...
set KIVY_DPI=306
set KIVY_METRICS_DENSITY=2
set KIVY_METRICS_FONTSCALE=1
python main.py --size 1280x720

On Linux you can type all the args on the command line.

IPv6

Dual-stack on Windows

I've tried to configure txThings client on Windows, so that it can send both IPv6 and IPv4 datagrams from a single socket. In theory Windows supports dual stack and IPv6 sockets can send and receive IPv4 datagrams. This functionality is turned off by default. I've tried to turn it on inside file twisted/internet/udp.py:

    def _bindSocket(self):
        try:
            skt = self.createInternetSocket()
            skt.bind((self.interface, self.port))
        except socket.error as le:
            raise error.CannotListenError(self.interface, self.port, le)

        # Make sure that if we listened on port 0, we update that to
        # reflect what the OS actually assigned us.
        self._realPortNumber = skt.getsockname()[1]

        log.msg("%s starting on %s" % (
                self._getLogPrefix(self.protocol), self._realPortNumber))

        self.connected = 1
        self.socket = skt
+      if self.addressFamily == socket.AF_INET6:
+          self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY,0)
        self.fileno = self.socket.fileno

Unfortunately this causes error:AttributeError: 'module' object has no attribute 'IPPROTO_IPV6'

It seems that this is a bug in Python for Windows which won't be fixed for Python 2.x ever (source). That's bad because Twisted is not Python 3 compatible.

Currently it is not possible to use a single socket for IPv6 and IPv4 connectivity on Windows. You need two separate sockets

Dual-stack on Linux and Android

On Linux and Android dual stack UDP sockets work fine. You have to create standard IPv6 socket. After that you can send IPv4 datagrams with it, you just have to pass IPv4-Mapped IPv6 Address (RFC 4291):

ipv6_address = "::ffff:" + ipv4_address

IPv6 on Samsung Galaxy SIII (SGS3)

SGS3 has IPv6 support. However the phone won't accept Router Advertisements if the screen is off (source). Samsung seems to be proud with it (SRSLY!?!?!). Default interval for sending Router Advertisements is 10 minutes, so keep your screen on.