[Vbrowser] imported.
[vuplus_dvbapp] / lib / python / Plugins / Extensions / Vbrowser / 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                         fbClass.getInstance().unlock()
50                         eRCInput.getInstance().unlock()
51                         return False
52                 finally:
53                         if cmd_fd is not None:
54                                 os.close(cmd_fd)
55                 return True
56
57 class VBServerThread(threading.Thread):
58         def __init__(self):
59                 threading.Thread.__init__(self)
60                 self.mSock = None
61                 self.mFlag = False
62                 self.mTimeout = 5
63
64         def open(self, timeout = 5):
65                 addr = vbcfg.SOCKETFILE
66                 self.mTimeout = timeout
67
68                 try:
69                         os.unlink(addr)
70                 except:
71                         if os.path.exists(addr):
72                                 return False
73                 try:
74                         self.mSock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
75                         self.mSock.settimeout(self.mTimeout)
76                         self.mSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
77                         self.mSock.bind(addr)
78                 except: return False
79                 return True
80
81         def parse(self, data):
82                 hlen = struct.calcsize('ibi')
83                 packet = ""
84                 opcode, result, length = struct.unpack('ibi', data[:hlen])
85                 #vbcfg.DEBUG("%s %s %d" % (opcode, result, length))
86                 if length > 0:
87                         packet = data[hlen:hlen+length]
88                 return [opcode, result, packet]
89
90         def assamble(self, opcode, result, packet):
91                 if packet is None:
92                         packet = ""
93                 header = struct.pack('ibi', opcode, (result and 1 or 0), len(packet))
94                 return header + packet
95
96         def process(self, conn, addr):
97                 read_data = conn.recv(_BUFSIZE)
98                 request = self.parse(read_data)
99                 opcode, result, read_packet = request[0], request[1], request[2]
100                 result, send_packet = False,None
101                 try:
102                         result, send_packet = GetHandler(opcode)(result, read_packet)
103                 except Exception, ErrMsg:
104                         vbcfg.ERR(ErrMsg)
105                 send_data = self.assamble(opcode, result, send_packet)
106                 conn.sendall(send_data)
107
108         def run(self):
109                 if self.mSock is None:
110                         raise
111
112                 self.mFlag = True
113                 self.mSock.listen(1)
114                 while self.mFlag:
115                         readable, writable, errored = select.select([self.mSock], [], [], self.mTimeout)
116                         for s in readable:
117                                 if s is self.mSock:
118                                         conn, addr = None, None
119                                         try:
120                                                 conn, addr = self.mSock.accept()
121                                                 self.process(conn, addr)
122                                         except Exception, err:
123                                                 vbcfg.ERR("VBSServerThread: %s" % err)
124                                         finally:
125                                                 if conn is not None:
126                                                         conn.close()
127
128         def kill(self):
129                 self.mFlag = False
130
131 class VBHandlers:
132         def __init__(self, opcode_list, szcbh):
133                 opcode = 0
134                 for opcode_str in opcode_list:
135                         if opcode_str is None and len(opcode_str) == 0:
136                                 continue
137                         _OPCODE[opcode_str] = [opcode, None]
138                         opcode = opcode + 1
139
140                 registreted_idx = 0
141                 for fname in dir(self):
142                         try:
143                                 if not fname.startswith(szcbh):
144                                         continue
145                                 fref = getattr(self, fname)
146                                 if fref is None:
147                                         continue
148                                 opcodestr = fname[len(szcbh):]
149                                 vbcfg.DEBUG("registrated at %s" % opcodestr)
150                                 SetHandler(opcodestr, fref)
151                                 registreted_idx += 1
152                         except: pass
153                 vbcfg.DEBUG("%d registreated" % registreted_idx)