1#!/usr/bin/env python2.7 2 3import ctypes 4import collections 5 6from ctypes import CDLL, CFUNCTYPE, POINTER, cast, py_object 7from ctypes import c_char_p, c_void_p, c_int, pointer 8 9_qrtr = CDLL("./libqrtr.so") 10 11class qrtr: 12 Result = collections.namedtuple('Result', ['service', 'instance', 'addr']) 13 _cbtype = CFUNCTYPE(None, c_void_p, c_int, c_int, c_int, c_int) 14 def __init__(self, port=0): 15 self.sock = _qrtr.qrtr_open(port) 16 if self.sock < 0: 17 raise RuntimeError("unable to open qrtr socket") 18 self.service = None 19 self._qrtr = _qrtr 20 21 def __del__(self): 22 self._qrtr.qrtr_close(self.sock) 23 24 def _lookup_list_add(self, ptr, srv, instance, node, port): 25 res = qrtr.Result(srv, instance, (node, port)) 26 cast(ptr, POINTER(py_object)).contents.value.append(res) 27 28 def lookup(self, srv, instance=0, ifilter=0): 29 results = [] 30 err = _qrtr.qrtr_lookup(self.sock, srv, instance, ifilter, 31 qrtr._cbtype(self._lookup_list_add), cast(pointer(py_object(results)), c_void_p)) 32 if err: 33 raise RuntimeError("query failed") 34 return results 35 36 def publish(self, service, version, instance): 37 err = _qrtr.qrtr_publish(self.sock, service, version, instance) 38 if err: 39 raise RuntimeError("publish failed") 40 self.service = (service, version, instance) 41 42 def new_server(self, service, version, instance): 43 err = _qrtr.qrtr_new_server(self.sock, service, version, instance) 44 if err: 45 raise RuntimeError("new_server failed") 46 self.service = (service, version, instance) 47 48 return self.service 49 50 def remove_server(self, service): 51 err = _qrtr.qrtr_remove_server(self.sock, *service) 52 if err: 53 raise RuntimeError("remove_server failed") 54 self.service = None 55 56 def new_lookup(self, service, version, instance): 57 err = _qrtr.qrtr_new_lookup(self.sock, service, version, instance) 58 if err: 59 raise RuntimeError("new_lookup failed") 60 return (service, version, instance) 61 62 def remove_lookup(self, lookup): 63 err = _qrtr.qrtr_remove_lookup(self.sock, *lookup) 64 if err: 65 raise RuntimeError("remove_lookup failed") 66 67 def send(self, addr, data): 68 node, port = addr 69 n = _qrtr.qrtr_sendto(self.sock, node, port, c_char_p(data), len(data)) 70 if n: 71 raise RuntimeError("sendto failed") 72 73 def recv(self, sz=65536): 74 buf = ctypes.create_string_buffer(sz) 75 n = _qrtr.qrtr_recv(self.sock, c_char_p(ctypes.addressof(buf)), sz) 76 if n <= 0: 77 raise RuntimeError("recv failed") 78 return buf[0:n] 79 80 def recvfrom(self, sz=65536): 81 node = ctypes.c_int() 82 port = ctypes.c_int() 83 buf = ctypes.create_string_buffer(sz) 84 n = _qrtr.qrtr_recvfrom(self.sock, c_char_p(ctypes.addressof(buf)), 85 ctypes.byref(node), ctypes.byref(port)) 86 if n <= 0: 87 raise RuntimeError("recvfrom failed") 88 return (buf[0:n], (node.value, port.value)) 89 90 def poll(self, tout=0): 91 return _qrtr.qrtr_poll(self.sock, tout) 92 93if __name__ == "__main__": 94 svcs = qrtr().lookup(15) # 15 is the test service 95 print " service instance addr" 96 for svc in svcs: 97 print "% 8d % 8d %s" % (svc.service, svc.instance, svc.addr) 98