summaryrefslogtreecommitdiff
path: root/PyFantom/pyfantom.py
blob: ba3eedd498374fecf24472f1a956629f3fe12d47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
from ctypes import *
import ctypes.util
import platform

# Check platform.
if platform.system() == 'Darwin':
    import sys
    if sys.maxsize > 2**32:
    raise RuntimeError("fantom drivers not available in 64 bit mode.\n"
        "You can run python in 32 bit mode using:\n"
        "arch -i386 python2.6\n")
    libpath = '/Library/Frameworks/Fantom.framework/Fantom'
    #libpath = ctypes.util.find_library('Fantom')
else:
    raise RuntimeError('unsupported platform')

# Load library.
dll = cdll.LoadLibrary(libpath)
dll.nFANTOM100_createNXTIterator.argtypes = [c_ushort, c_uint, POINTER(c_int)]
dll.nFANTOM100_createNXTIterator.restype = c_uint
dll.nFANTOM100_destroyNXTIterator.argtypes = [c_int, POINTER(c_int)]
dll.nFANTOM100_destroyNXTIterator.restype = None
dll.nFANTOM100_iNXTIterator_advance.argtypes = [c_uint, POINTER(c_int)]
dll.nFANTOM100_iNXTIterator_advance.restype = None
dll.nFANTOM100_iNXTIterator_getNXT.argtypes = [c_uint, POINTER(c_int)]
dll.nFANTOM100_iNXTIterator_getNXT.restype = c_uint
dll.nFANTOM100_iNXTIterator_getName.argtypes = [c_uint, c_char_p, POINTER(c_int)]
dll.nFANTOM100_iNXTIterator_getName.restype = None

# Status codes.
StatusOffset = -142000
StatusNoMoreItemsFound = StatusOffset - 17
StatusSuccess = 0

def check_status (status):
    """Check status, raise on error."""
    if status.value < StatusSuccess:
        raise FantomException('bad status')

class FantomException(RuntimeError):
    pass

class NXTIterator:
    """Interface to an iterator, to find connected NXT."""

    def __init__(self, search_bluetooth,
        bluetooth_search_timeout_in_seconds = 5):
        """Initialize iterator."""
        self.search_bluetooth = search_bluetooth
        self.bluetooth_search_timeout_in_seconds = \
                bluetooth_search_timeout_in_seconds
        self.handle = None
        self.stop = False

    def __iter__(self):
        """Return the iterator object itself."""
        return self

    def next(self):
        """Implement the iterator protocol."""
        if self.stop:
            raise StopIteration()
        # Find first, or find next.
    status = c_int(0)
        if self.handle is None:
            handle = dll.nFANTOM100_createNXTIterator(self.search_bluetooth,
                    self.bluetooth_search_timeout_in_seconds, byref(status))
        else:
            handle = self.handle
            dll.nFANTOM100_iNXTIterator_advance(handle, byref(status))
        # Check result.
        if status.value == StatusNoMoreItemsFound:
            self.stop = True
            raise StopIteration()
        check_status (status)
        self.handle = handle
        # Return itself (not part of the protocol, but it has get_nxt and
        # get_name).
        return self

    def get_nxt(self):
        """Get the NXT instance."""
        if self.handle is None or self.stop:
            raise FantomException('invalid iterator')
        status = c_int(0)
        nxt = dll.nFANTOM100_iNXTIterator_getNXT(self.handle, byref(status))
        check_status (status)
        # XXX
        return nxt.value

    def get_name(self):
        """Get the NXT resource name."""
        if self.handle is None or self.stop:
            raise FantomException('invalid iterator')
        status = c_int(0)
        name = create_string_buffer (256)
        dll.nFANTOM100_iNXTIterator_getName(self.handle, name, byref(status))
        check_status (status)
        return name.value

    def __del__(self):
        """Destroy iterator."""
        if self.handle is not None:
            status = c_int(0)
            dll.nFANTOM100_destroyNXTIterator(self.handle, byref(status))

if __name__ == '__main__':
    for i in NXTIterator(False):
        print i.get_name()