Support turbo2.
[vuplus_dvbapp] / lib / python / Plugins / Extensions / HbbTV / vbipc.py
1 from enigma import fbClass, eRCInput
2 import os, threading, time, socket, select, struct
3 import vbcfg
4
5 _OPCODE  = {}
6 _BUFSIZE = 4096
7
8 def SetHandler(opcode, handler):
9         try:
10                 _OPCODE[opcode][1] = handler
11         except:
12                 vbcfg.ERR("Fail to set handler (unknown opcode): %s" % opcode)
13                 return False
14         return True
15
16 def GetHandler(opcode):
17         for key, value in _OPCODE.items():
18                 if value[0] == opcode:
19                         vbcfg.DEBUG("recv socket: [%s]" % key)
20                         return value[1]
21         return None
22
23 def GetOpcode(opcode):
24         try:
25                 return _OPCODE[opcode][0]
26         except: return -1;
27
28 class VBController:
29         @staticmethod
30         def assamble(opcodestr, data):
31                 opcode = _OPCODE[opcodestr][0]
32                 header = struct.pack('i', opcode)
33                 return header + data
34
35         @staticmethod
36         def command(opcodestr, data = ""):
37                 cmd_fd = None
38                 vbcfg.DEBUG("send ipc: [%s]" % opcodestr)
39                 try:
40                         send_data = VBController.assamble(opcodestr, data)
41                         if not os.path.exists(vbcfg.CONTROLFILE):
42                                 raise Exception("no found controller file.")
43                         cmd_fd = os.open(vbcfg.CONTROLFILE, os.O_WRONLY)
44                         if cmd_fd is None:
45                                 raise Exception("fail to open controller file.")
46                         os.write(cmd_fd, send_data)
47                 except Exception, err:
48                         vbcfg.ERR("VBHController: %s" % err)
49                         vbcfg.setPosition(vbcfg.g_position)
50                         fbClass.getInstance().unlock()
51                         eRCInput.getInstance().unlock()
52                         return False
53                 finally:
54                         if cmd_fd is not None:
55                                 os.close(cmd_fd)
56                 return True
57
58 class VBServerThread(threading.Thread):
59         def __init__(self):
60                 threading.Thread.__init__(self)
61                 self.mSock = None
62                 self.mFlag = False
63                 self.mTimeout = 5
64
65         def open(self, timeout = 5):
66                 addr = vbcfg.SOCKETFILE
67                 self.mTimeout = timeout
68
69                 try:
70                         os.unlink(addr)
71                 except:
72                         if os.path.exists(addr):
73                                 return False
74                 try:
75                         self.mSock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
76                         self.mSock.settimeout(self.mTimeout)
77                         self.mSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
78                         self.mSock.bind(addr)
79                 except: return False
80                 return True
81
82         def parse(self, data):
83                 hlen = struct.calcsize('ibi')
84                 packet = ""
85                 opcode, result, length = struct.unpack('ibi', data[:hlen])
86                 #vbcfg.DEBUG("%s %s %d" % (opcode, result, length))
87                 if length > 0:
88                         packet = data[hlen:hlen+length]
89                 return [opcode, result, packet]
90
91         def assamble(self, opcode, result, packet):
92                 if packet is None:
93                         packet = ""
94                 header = struct.pack('ibi', opcode, (result and 1 or 0), len(packet))
95                 return header + packet
96
97         def process(self, conn, addr):
98                 read_data = conn.recv(_BUFSIZE)
99                 request = self.parse(read_data)
100                 opcode, result, read_packet = request[0], request[1], request[2]
101                 result, send_packet = False,None
102                 try:
103                         result, send_packet = GetHandler(opcode)(result, read_packet)
104                 except Exception, ErrMsg:
105                         vbcfg.ERR(ErrMsg)
106                 send_data = self.assamble(opcode, result, send_packet)
107                 conn.sendall(send_data)
108
109         def run(self):
110                 if self.mSock is None:
111                         raise
112
113                 self.mFlag = True
114                 self.mSock.listen(1)
115                 while self.mFlag:
116                         readable, writable, errored = select.select([self.mSock], [], [], self.mTimeout)
117                         for s in readable:
118                                 if s is self.mSock:
119                                         conn, addr = None, None
120                                         try:
121                                                 conn, addr = self.mSock.accept()
122                                                 self.process(conn, addr)
123                                         except Exception, err:
124                                                 vbcfg.ERR("VBSServerThread: %s" % err)
125                                         finally:
126                                                 if conn is not None:
127                                                         conn.close()
128                 self.mSock.close()
129
130         def kill(self):
131                 self.mFlag = False
132                 addr = vbcfg.SOCKETFILE
133                 try:
134                         os.unlink(addr)
135                 except:
136                         pass
137
138 class VBHandlers:
139         def __init__(self, opcode_list, szcbh):
140                 opcode = 0
141                 for opcode_str in opcode_list:
142                         if opcode_str is None and len(opcode_str) == 0:
143                                 continue
144                         _OPCODE[opcode_str] = [opcode, None]
145                         opcode = opcode + 1
146
147                 registreted_idx = 0
148                 for fname in dir(self):
149                         try:
150                                 if not fname.startswith(szcbh):
151                                         continue
152                                 fref = getattr(self, fname)
153                                 if fref is None:
154                                         continue
155                                 opcodestr = fname[len(szcbh):]
156                                 vbcfg.DEBUG("registrated at %s" % opcodestr)
157                                 SetHandler(opcodestr, fref)
158                                 registreted_idx += 1
159                         except: pass
160                 vbcfg.DEBUG("%d registreated" % registreted_idx)