fix bugs and add operation(add/remove apn).
[vuplus_dvbapp] / lib / python / Plugins / SystemPlugins / 3GModemManager / plugin.py
1 from Plugins.Plugin import PluginDescriptor
2
3 from Screens.Screen import Screen
4 from Screens.MessageBox import MessageBox
5 from Screens.DefaultWizard import DefaultWizard
6 from Screens.Standby import TryQuitMainloop
7 from Screens.VirtualKeyBoard import VirtualKeyBoard
8
9 from Components.Label import Label
10 from Components.Sources.StaticText import StaticText
11 from Components.ActionMap import NumberActionMap, ActionMap
12 from Components.Network import iNetwork
13 from Components.MenuList import MenuList
14 from Components.config import config, getConfigListEntry, ConfigInteger, ConfigSubsection, ConfigSelection, ConfigText, ConfigYesNo, NoSave, ConfigNothing
15 from Components.ConfigList import ConfigListScreen
16 from Components.Pixmap import Pixmap
17
18 from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_PLUGIN
19
20 from enigma import eTimer, eConsoleAppContainer, eSocketNotifier, getDesktop
21 from select import POLLIN, POLLPRI
22 from xml.sax import make_parser, handler
23 import os, socket, time
24
25 debug_mode_modem_mgr = False
26 def printDebugModemMgr(msg):
27         global debug_mode_modem_mgr
28         if debug_mode_modem_mgr:
29                 print "[ModemManager Plugin] Debug >>", msg
30
31 def printInfoModemMgr(msg):
32         print "[ModemManager Plugin] Info >>", msg
33
34 isEmpty = lambda x: x is None or len(x)==0
35
36 class DeviceEventListener:
37         notifyCallbackFunctionList = []
38         def __init__(self):
39                 self.sock = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, 15)
40                 try:            
41                         self.sock.bind((os.getpid(), 1))
42                         self.notifier = eSocketNotifier(self.sock.fileno(), POLLIN|POLLPRI)
43                         self.notifier.callback.append(self.cbEventHandler)
44                 except Exception, msg:
45                         print "[ModemManager Plugin] Error >>", msg
46                         self.sock.close()
47
48         def cbEventHandler(self, sockfd):
49                 recv = self.sock.recv(65536)
50                 #printDebugModemMgr(str(recv.splitlines()))
51                 if recv.startswith("add@/block") or recv.startswith("remove@/block"):
52                         for x in self.notifyCallbackFunctionList:
53                                 try:    x(recv)
54                                 except: self.notifyCallbackFunctionList.remove(x)
55
56         def addCallback(self, func):
57                 if func is not None:
58                         self.notifyCallbackFunctionList.append(func)
59
60         def delCallback(self, func):
61                 if func is not None:
62                         self.notifyCallbackFunctionList.remove(func)
63
64         def close(self):
65                 try:
66                         self.notifier.callback.remove(self.cbEventHandler)
67                         self.sock.close()
68                 except: pass
69
70 class TaskManager:
71         def __init__(self):
72                 self.taskIdx = 0
73                 self.taskList = []
74                 self.gTaskInstance = None
75                 self.occurError = False
76                 self.cbSetStatusCB = None
77
78         def append(self, command, cbDataFunc, cbCloseFunc):
79                 self.taskList.append([command+'\n', cbDataFunc, cbCloseFunc])
80
81         def dump(self):
82                 print "############### TASK ###############"
83                 print "Current Task Index :", self.taskIdx
84                 print "Current Task Instance :", self.gTaskInstance
85                 print "Occur Error :", self.occurError
86                 print "Task List:\n", self.taskList
87                 print "####################################"
88
89         def error(self):
90                 printInfoModemMgr("set task error!!")
91                 self.occurError = True
92
93         def reset(self):
94                 self.taskIdx = 0
95                 self.gTaskInstance = None
96                 self.occurError = False
97
98         def clean(self):
99                 self.reset()
100                 self.taskList = []
101                 self.cbSetStatusCB = None
102                 print "clear task!!"
103
104         def index(self):
105                 self.taskIdx
106
107         def setStatusCB(self, cbfunc):
108                 self.cbSetStatusCB = cbfunc
109                 
110         def next(self):
111                 if self.taskIdx >= len(self.taskList) or self.occurError:
112                         printInfoModemMgr("can't run task!!")
113                         return False
114                 command     = self.taskList[self.taskIdx][0]
115                 cbDataFunc  = self.taskList[self.taskIdx][1]
116                 cbCloseFunc = self.taskList[self.taskIdx][2]
117
118                 self.gTaskInstance = eConsoleAppContainer()
119                 if cbDataFunc is not None:
120                         self.gTaskInstance.dataAvail.append(cbDataFunc)
121                 if cbCloseFunc is not None:
122                         self.gTaskInstance.appClosed.append(cbCloseFunc)
123                 if self.cbSetStatusCB is not None:
124                         self.cbSetStatusCB(self.taskIdx)
125
126                 printInfoModemMgr("prepared command :%s"%(command))
127                 self.gTaskInstance.execute(command)
128                 self.taskIdx += 1
129                 return True
130
131 class ParserHandler(handler.ContentHandler):
132         nodeList = []
133         def __init__(self):
134                 self.nodeList = []
135         def startDocument(self):
136                 pass
137         def endDocument(self):  
138                 pass
139         def startElement(self, name, attrs):
140                 if name == 'apn':
141                         node = {}
142                         for attr in attrs.getNames():
143                                 node[attr] = str(attrs.getValue(attr))
144                         self.nodeList.append(node)
145         def endElement(self, name):
146                 pass
147         def characters(self, content):
148                 pass
149         def setDocumentLocator(self, locator):
150                 pass
151         def getNodeList(self):
152                 return self.nodeList
153
154 class EditModemManual(ConfigListScreen, Screen):
155         param = int(getDesktop(0).size().height()) >= 720 and (450,360) or (160,300)
156         skin =  """
157                 <screen position="center,center" size="600,360" title="3G Modem Manager Config Edit">
158                         <widget name="config" zPosition="2" position="0,0" size="600,300" scrollbarMode="showOnDemand" transparent="1" />
159
160                         <ePixmap pixmap="skin_default/buttons/red.png" position="5,320" size="140,40" alphatest="on" />
161                         <ePixmap pixmap="skin_default/buttons/green.png" position="155,320" size="140,40" alphatest="on" />
162                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,320" size="140,40" alphatest="on" />
163                         <ePixmap pixmap="skin_default/buttons/blue.png" position="455,320" size="140,40" alphatest="on" />
164
165                         <widget source="key_red" render="Label" position="5,320" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
166                         <widget source="key_green" render="Label" position="155,320" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
167                         <widget source="key_blue" render="Label" position="455,320" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#18188b"  foregroundColor="#ffffff" transparent="1" />
168
169                         <widget name="VKeyIcon" pixmap="skin_default/buttons/key_text.png" position="50,200" zPosition="10" size="35,25" transparent="1" alphatest="on" />
170                         <widget name="HelpWindow" pixmap="skin_default/vkey_icon.png" position="%d,%d" zPosition="1" size="1,1" transparent="1" alphatest="on" />
171                 </screen>
172                 """ % param
173
174         def __init__(self, session, cbFuncClose, uid=None, pwd=None, pin=None, apn=None, phone='*99#', isAdd=False):
175                 Screen.__init__(self, session)
176                 self.cbFuncClose, self.isAdd = cbFuncClose, isAdd
177
178                 if isAdd:
179                         self.uid,self.pwd,self.pin,self.apn,self.phone = "","","","",""
180                 else:
181                         self.uid,self.pwd,self.pin,self.apn,self.phone = uid,pwd,pin,apn,phone
182                         if self.uid is None: self.uid = ""
183                         if self.pwd is None: self.pwd = ""
184                         if self.pin is None: self.pin = ""
185                         if self.apn is None: self.apn = ""
186                         if self.phone is None: self.phone = ""
187
188                 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions",],
189                 {
190                         "ok":     self.keyOK,
191                         "cancel": self.keyExit,
192                         "red":    self.keyExit,
193                         "green":  self.keyOK,
194                         "blue":   self.keyRemove,
195                 }, -2)
196
197                 self["VirtualKB"] = ActionMap(["VirtualKeyboardActions" ],
198                 {
199                         "showVirtualKeyboard": self.KeyText,
200                 }, -1)
201
202                 self.configList = []
203                 ConfigListScreen.__init__(self, self.configList, session=session)
204                 self.createConfigList()
205
206                 self["key_red"]    = StaticText(_("Cancel"))
207                 self["key_green"]  = StaticText(_("Save"))
208                 self["key_blue"]   = StaticText(_(self.isAdd and " " or "Remove"))
209                 self["VKeyIcon"]   = Pixmap()
210                 self["HelpWindow"] = Pixmap()
211                 self["VirtualKB"].setEnabled(False)
212                 if self.isAdd:
213                         self.setTitle("3G Modem Manager Config Add")
214
215         def createConfigList(self):
216                 self.configName     = ConfigText(default="", visible_width=50, fixed_size=False)
217                 self.configUserName = ConfigText(default=str(self.uid), visible_width=50, fixed_size=False)
218                 self.configPassword = ConfigText(default=str(self.pwd), visible_width=50, fixed_size=False)
219                 self.configAPN      = ConfigText(default=str(self.apn), visible_width=50, fixed_size=False)
220                 self.configPIN      = ConfigText(default=str(self.pin), visible_width=50, fixed_size=False)
221                 self.configPhone    = ConfigText(default=str(self.phone), visible_width=50, fixed_size=False)
222
223                 self.configEntryName     = getConfigListEntry(_("Name :"),     self.configName)
224                 self.configEntryUserName = getConfigListEntry(_("User :"),     self.configUserName)
225                 self.configEntryPassword = getConfigListEntry(_("Password :"), self.configPassword)
226                 self.configEntryAPN      = getConfigListEntry(_("APN :"),      self.configAPN)
227                 self.configEntryPIN      = getConfigListEntry(_("PIN :"),      self.configPIN)
228                 self.configEntryPhone    = getConfigListEntry(_("Phone :"),    self.configPhone)
229
230                 if self.isAdd:
231                         self.configList.append(self.configEntryName)
232                 self.configList.append(self.configEntryUserName)
233                 self.configList.append(self.configEntryPassword)
234                 self.configList.append(self.configEntryAPN)
235                 self.configList.append(self.configEntryPIN)
236                 self.configList.append(self.configEntryPhone)
237
238                 self["config"].list = self.configList
239                 self["config"].l.setList(self.configList)
240
241         def getCurrentItem(self):
242                 currentPosition = self["config"].getCurrent()
243                 if currentPosition == self.configEntryName:
244                         return self.configName
245                 if currentPosition == self.configEntryUserName:
246                         return self.configUserName
247                 elif currentPosition == self.configEntryPassword:
248                         return self.configPassword
249                 elif currentPosition == self.configEntryAPN:
250                         return self.configAPN
251                 elif currentPosition == self.configEntryPIN:
252                         return self.configPIN
253                 elif currentPosition == self.configEntryPhone:
254                         return self.configPhone
255                 return None
256
257         def KeyText(self):
258                 currentItemValue = ""
259                 currentItem = self.getCurrentItem()
260                 if currentItem is not None:
261                         currentItemValue = currentItem.value
262                         if isEmpty(currentItemValue):
263                                 currentItemValue = ""
264                 self.session.openWithCallback(self.cbKeyText, VirtualKeyBoard, title=("Please input here"), text=currentItemValue)
265
266         def cbKeyText(self, data=None):
267                 if data is not None:
268                         currentItem = self.getCurrentItem()
269                         if currentItem is not None:
270                                 currentItem.setValue(data)
271
272         def keyExit(self):
273                 self.close()
274
275         def keyRemove(self):
276                 if self.isAdd:
277                         return
278                 if self.cbFuncClose is not None:
279                         self.cbFuncClose(isRemove = True)
280                 self.close()
281
282         def showKeyboard(self, ret=None):
283                 self["VKeyIcon"].show()
284                 current = self["config"].getCurrent()
285                 if hasattr(current[1], 'help_window'):
286                         if current[1].help_window.instance is not None:
287                                 current[1].help_window.instance.show()
288
289         def hideKeyboard(self):
290                 self["VKeyIcon"].hide()
291                 current = self["config"].getCurrent()
292                 if hasattr(current[1], 'help_window'):
293                         if current[1].help_window.instance is not None:
294                                 current[1].help_window.instance.hide()
295
296         def keyOK(self):
297                 message = '%s field is empty!!'
298                 if isEmpty(self.configName.value) and self.isAdd:
299                         self.hideKeyboard()
300                         self.session.openWithCallback(self.showKeyboard, MessageBox, message%('Name'), MessageBox.TYPE_INFO)
301                         return
302                 if isEmpty(self.configAPN.value):
303                         self.hideKeyboard()
304                         self.session.openWithCallback(self.showKeyboard, MessageBox, message%('APN'), MessageBox.TYPE_INFO)
305                         return
306
307                 if self.cbFuncClose is not None:
308                         self.uid   = self.configUserName.value
309                         self.pwd   = self.configPassword.value
310                         self.pin   = self.configPIN.value
311                         self.apn   = self.configAPN.value
312                         self.phone = self.configPhone.value
313                         self.name  = self.isAdd and self.configName.value or None
314                         self.cbFuncClose(self.uid,self.pwd,self.pin,self.apn,self.phone,self.name)
315                 self.close()
316
317 class ModemManual(Screen):
318         skin =  """
319                 <screen position="center,center" size="600,360" title="3G Modem Manager Config">
320                         <widget name="menulist" position="0,0" size="300,300" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
321                         <widget name="apnInfo" position="310,0" size="290,300" font="Regular;20" halign="left" backgroundColor="#a08500" transparent="1" />
322
323                         <ePixmap pixmap="skin_default/buttons/red.png" position="5,320" size="140,40" alphatest="on" />
324                         <ePixmap pixmap="skin_default/buttons/green.png" position="155,320" size="140,40" alphatest="on" />
325                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,320" size="140,40" alphatest="on" />
326                         <ePixmap pixmap="skin_default/buttons/blue.png" position="455,320" size="140,40" alphatest="on" />
327
328                         <widget source="key_red" render="Label" position="5,320" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
329                         <widget source="key_green" render="Label" position="155,320" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
330                         <widget source="key_yellow" render="Label" position="305,320" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#a08500"  foregroundColor="#ffffff" transparent="1" />
331                         <widget source="key_blue" render="Label" position="455,320" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#18188b"  foregroundColor="#ffffff" transparent="1" />
332                 </screen>
333                 """
334
335         def __init__(self, session, cbFuncClose, uid=None, pwd=None, pin=None, apn=None, phone='*99#'):
336                 Screen.__init__(self, session)
337                 self.cbFuncClose,self.uid,self.pwd,self.pin,self.apn,self.phone = cbFuncClose,uid,pwd,pin,apn,phone
338                 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions"],
339                 {
340                         "ok":     self.keyOK,
341                         "cancel": self.keyExit,
342                         "red":    self.keyExit,
343                         "green":  self.keyOK,
344                         "yellow": self.keyEdit,
345                         "blue":   self.keyAdd,
346                         "left":   self.keyLeft,
347                         "right":  self.keyRight,
348                         "up":     self.keyUp,
349                         "down":   self.keyDown,
350                 }, -2)
351
352                 self.apnItems = self.setListOnView()
353                 self["menulist"]   = MenuList(self.apnItems)
354                 self["key_red"]    = StaticText(_("Cancel"))
355                 self["key_green"]  = StaticText(_("OK"))
356                 self["key_yellow"] = StaticText(_("Edit"))
357                 self["key_blue"]   = StaticText(_("Add"))
358                 self["apnInfo"]    = Label(' ')
359
360                 self.keyUp()
361         
362         def keyAdd(self):
363                 self.session.open(EditModemManual, self.cb3GManualSetting, isAdd=True)
364
365         def keyEdit(self):
366                 self.session.open(EditModemManual, self.cb3GManualSetting, self.uid,self.pwd,self.pin,self.apn,self.phone)
367
368         def cb3GManualSetting(self, uid=None, pwd=None, pin=None, apn=None, phone='*99#', name=None, isRemove=False):
369                 if not isRemove:
370                         self.uid = isEmpty(uid) and "" or uid
371                         self.pwd = isEmpty(pwd) and "" or pwd
372                         self.pin = isEmpty(pin) and "" or pin
373                         self.apn = isEmpty(apn) and "" or apn
374                         self.phone = isEmpty(phone) and "" or phone
375                         
376                 if name is not None:
377                         self["menulist"].list.append((name, {'carrier':name, 'apn':self.apn, 'user':self.uid, 'password':self.pwd, 'pin':self.pin, 'phone':self.phone}))
378                         self["menulist"].setList(self["menulist"].list)
379                         self["menulist"].moveToIndex(len(self["menulist"].list)-1)
380                 if isRemove:
381                         index = 0
382                         newList = []
383                         selectedIndex = self["menulist"].getSelectionIndex()
384                         for x in self["menulist"].list:
385                                 if index == selectedIndex:
386                                         index += 1
387                                         continue
388                                 newList.append(x)
389                                 index += 1
390                         self["menulist"].setList(newList)
391                         self["menulist"].moveToIndex(0)
392                         self.setAPNInfo(True)
393                         name = ' '
394                 if not isRemove and isEmpty(name):
395                         self.updateAPNList()
396                 self.updateAPNInfo()
397                 self.saveAPNList(name)
398
399         def updateAPNList(self):
400                 selectedIndex = self["menulist"].getSelectionIndex()
401                 apnList = self["menulist"].list
402                 currentListItem = apnList[selectedIndex][1]
403
404                 currentListItem['user'] = self.uid
405                 currentListItem['apn'] = self.apn
406                 currentListItem['password'] = self.pwd
407                 currentListItem['pin'] = self.pin
408                 currentListItem['phone'] = self.phone
409
410                 self["menulist"].setList(apnList)
411
412         def saveAPNList(self, name=None):
413                 apnList = self["menulist"].list
414                 selectedIndex = self["menulist"].getSelectionIndex()
415
416                 def makeItem(carrier, apn, user, password, pin, phone):
417                         printDebugModemMgr("%s, %s, %s, %s, %s, %s"%(carrier, apn, user, password, pin, phone))
418                         tempStr  = '    <apn'
419                         tempStr += ' carrier="%s"'%(carrier)
420                         tempStr += ' apn="%s"'%(apn)
421                         if not isEmpty(user):     tempStr += ' user="%s"'%(user)
422                         if not isEmpty(password): tempStr += ' password="%s"'%(password)
423                         if not isEmpty(pin):      tempStr += ' pin="%s"'%(pin)
424                         if not isEmpty(phone) :   tempStr += ' phone="%s"'%(phone)
425                         tempStr += ' />\n'
426                         return tempStr
427
428                 tempIndex = 0
429                 apnString = '<apns version="1">\n'
430                 for x in apnList:
431                         try:
432                                 if selectedIndex == tempIndex and name is None:
433                                         apnString += makeItem(x[0], self.apn, self.uid, self.pwd, self.pin, self.phone)
434                                         continue
435                                 apnString += makeItem(x[1].get('carrier'), x[1].get('apn'), x[1].get('user'), x[1].get('password'), x[1].get('pin'), x[1].get('phone'))
436                         finally: tempIndex += 1
437                 apnString += '</apns>\n'
438                 printDebugModemMgr(apnString)
439                 apnListFile = file(resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/3GModemManager/apnlist.xml"), 'w')
440                 apnListFile.write(apnString)
441                 apnListFile.close()
442
443         def keyLeft(self):
444                 self['menulist'].pageUp()
445                 self.setAPNInfo()
446
447         def keyRight(self):
448                 self['menulist'].pageDown()
449                 self.setAPNInfo()
450
451         def keyUp(self):
452                 self['menulist'].up()
453                 self.setAPNInfo()
454
455         def keyDown(self):
456                 self['menulist'].down()
457                 self.setAPNInfo()
458
459         def keyOK(self):
460                 if self.cbFuncClose is not None:
461                         self.cbFuncClose(self.uid,self.pwd,self.pin,self.apn,self.phone)
462                 self.close()
463
464         def keyExit(self):
465                 self.close()
466
467         def setAPNInfo(self, noUpdate=False):
468                 try:
469                         x = self["menulist"].getCurrent()[1]
470                         self.apn, self.uid, self.pwd, self.pin, self.phone = x.get("apn"), x.get("user"), x.get("password"), x.get('pin'), x.get('phone')
471                 except Exception, err: pass
472                 if noUpdate: return
473                 self.updateAPNInfo()
474
475         def updateAPNInfo(self):
476                 apn,uid,pwd,pin,phone = self.apn,self.uid,self.pwd,self.pin,self.phone
477                 if apn is None:   apn = ""
478                 if uid is None:   uid = ""
479                 if pwd is None:   pwd = ""
480                 if pin is None:   pin = ""
481                 if phone is None: phone = ""
482                 info = 'APN : %s\nUSER : %s\nPASSWD : %s\nPIN : %s\nPHONE : %s\n' % (apn, uid, pwd, pin, phone)
483                 self["apnInfo"].setText(info)
484
485         def setListOnView(self):
486                 lvApnItems = []
487                 def uppercaseCompare(a,b):
488                         aa = a.get("carrier")
489                         bb = b.get("carrier")
490                         if isEmpty(aa): aa = ""
491                         if isEmpty(bb): bb = ""
492                         return cmp(aa.upper(),bb.upper())
493                 def isExistAPN(name):
494                         for x in lvApnItems:
495                                 if x[0] == name:
496                                         return True
497                         return False
498                 try:
499                         handle = ParserHandler()
500                         parser = make_parser()
501                         parser.setContentHandler(handle)
502                         parser.parse(resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/3GModemManager/apnlist.xml"))
503
504                         apnList = handle.getNodeList()
505                         apnList.sort(uppercaseCompare)
506                         for x in apnList:
507                                 name = str(x.get('carrier'))
508                                 if isEmpty(name):
509                                         continue
510                                 if isExistAPN(name):
511                                         continue
512                                 d = {}
513                                 d['carrier']  = name
514                                 d['apn']      = x.get('apn')
515                                 d['user']     = x.get('user')
516                                 d['password'] = x.get('password')
517                                 d['pin']      = x.get('pin')
518                                 d['phone']    = x.get('phone')
519                                 lvApnItems.append((name,d))
520                 except Exception, err: pass
521                 finally: del handle
522                 return lvApnItems
523
524 class ModemManager(Screen):
525         skin =  """
526                 <screen position="center,center" size="600,360" title="3G Modem Manager">
527                         <widget name="menulist" position="0,0" size="300,150" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />
528                         <widget name="usbinfo" position="310,0" size="290,150" font="Regular;18" halign="left" />
529
530                         <widget name="statusTitle" position="0,160" size="600,120" font="Regular;20" halign="center" backgroundColor="#a08500" transparent="1" />
531                         <widget name="statusInfo" position="0,185" size="600,120" font="Regular;20" halign="left" backgroundColor="#a08500" transparent="1" />
532
533                         <ePixmap pixmap="skin_default/buttons/red.png" position="5,320" size="140,40" alphatest="on" />
534                         <ePixmap pixmap="skin_default/buttons/green.png" position="155,320" size="140,40" alphatest="on" />
535                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="305,320" size="140,40" alphatest="on" />
536                         <ePixmap pixmap="skin_default/buttons/blue.png" position="455,320" size="140,40" alphatest="on" />
537
538                         <widget source="key_red" render="Label" position="5,320" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" foregroundColor="#ffffff" transparent="1" />
539                         <widget source="key_green" render="Label" position="155,320" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" foregroundColor="#ffffff" transparent="1" />
540                         <widget source="key_yellow" render="Label" position="305,320" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#a08500"  foregroundColor="#ffffff" transparent="1" />
541                         <widget source="key_blue" render="Label" position="455,320" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#18188b"  foregroundColor="#ffffff" transparent="1" />
542                 </screen>
543                 """
544         uid,pwd,pin,apn,phone = None,None,None,None,'*99#'
545         connectionStatus = 0
546         def __init__(self, session): 
547                 Screen.__init__(self, session)
548                 self.usb_lv_items = self.setListOnView()
549
550                 self["actions"] = ActionMap(["OkCancelActions", "ShortcutActions", "WizardActions", "ColorActions", "SetupActions", "NumberActions"],
551                 {
552                         "ok":     self.keyOK,
553                         "cancel": self.keyExit,
554                         "red":    self.keyExit,
555                         "green":  self.keyOK,
556                         "yellow": self.keyManual,
557                         "blue":   self.keyReset,
558                         "up":     self.keyUp,
559                         "down":   self.keyDown,
560                         "left":   self.keyLeft,
561                         "right":  self.keyRight,
562                         "0":      self.keyNumber,
563                 }, -2)
564                 self["menulist"] = MenuList(self.usb_lv_items)
565                 self['usbinfo'] = Label(' ')
566                 self['statusTitle'] = Label('[ Status ]')
567                 self['statusInfo'] = Label(' ')
568                 self["key_red"] = StaticText(_("Exit"))
569                 if self.isConnected():
570                         self["key_green"] = StaticText("Disconnect")
571                         self.setDisconnectStatus(0)
572                 else:
573                         self["key_green"] = StaticText("Connect")
574                         self.setConnectStatus(0)
575                 self["key_yellow"] = StaticText(_("Manual"))
576                 self["key_blue"] = StaticText(_("Reset"))
577
578                 self.updateUSBInfo()
579
580                 self.udevListener = DeviceEventListener()
581                 self.udevListener.addCallback(self.cbUdevListener)
582
583                 self.taskManager = TaskManager()
584
585                 self.refreshStatusTimer = eTimer()
586                 self.refreshStatusTimer.callback.append(self.cbRefreshStatus)
587
588                 #self.restartAppTimer = eTimer()
589                 #self.restartAppTimer.callback.append(self.cbRestartAppTimer)
590                 self.commandBin = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/3GModemManager/3gcommand")
591                 self.forceStop = False
592
593         def cbRestartAppTimer(self):
594                 self.restartAppTimer.stop()
595                 model = file('/proc/stb/info/vumodel').read().strip()
596                 if model is not None:
597                         if model == 'solo' or model == 'bm750':
598                                 self.session.open(TryQuitMainloop, 3)
599
600         def cbRefreshStatus(self):
601                 self.refreshStatusTimer.stop()
602                 if self["key_green"].getText() == 'Connect':
603                         self.setConnectStatus(0)
604                 elif self["key_green"].getText() == 'Disconnect': 
605                         self.setDisconnectStatus(0)
606
607         def cbUdevListener(self, data):
608                 printDebugModemMgr('Udev Listener Refresh!!')
609                 time.sleep(2)
610                 self["menulist"].setList(self.setListOnView())
611                 self.updateUSBInfo()
612
613         def isAttemptConnect(self):
614                 if self.connectionStatus == 0 or self.forceStop:
615                         return False
616                 maxIdx = 4
617                 if self["key_green"].getText() == 'Disconnect':
618                         maxIdx = 2
619                 if self.connectionStatus < maxIdx:
620                         printInfoModemMgr("can't excute a command during connecting...")
621                         return True
622                 return False
623
624         def keyManual(self):
625                 if self.isAttemptConnect():
626                         return
627                 self.session.open(ModemManual, self.cb3GManualSetting, self.uid,self.pwd,self.pin,self.apn,self.phone)
628                 #self.session.open(ModemManual, self.cb3GManualSetting)
629
630         def keyReset(self):
631                 if self.isAttemptConnect():
632                         return
633                 self.cb3GManualSetting()
634
635         def cb3GManualSetting(self, uid=None, pwd=None, pin=None, apn=None, phone='*99#'):
636                 self.uid,self.pwd,self.pin,self.apn,self.phone = uid,pwd,pin,apn,phone
637                 self.updateUSBInfo()
638
639         def keyNumber(self, num=None):
640                 global debug_mode_modem_mgr
641                 debug_mode_modem_mgr = not debug_mode_modem_mgr
642                 printInfoModemMgr('changed log mode, debug %s'%(debug_mode_modem_mgr and 'on' or 'off'))
643
644         def keyExit(self):
645                 if self.isAttemptConnect():
646                         message = "Can't disconnect doring connecting..\nDo you want to forcibly exit?"
647                         self.session.openWithCallback(self.cbForciblyExit, MessageBox, _(message), default = False)
648                         return
649                 self.udevListener.close()
650                 self.close()
651
652         def cbForciblyExit(self, result):
653                 if result:
654                         os.system('%s -s 6' % self.commandBin)
655                         self.udevListener.close()
656                         self.close()
657
658         def keyLeft(self):
659                 self["menulist"].pageUp()
660                 self.updateUSBInfo()
661
662         def keyRight(self):
663                 self["menulist"].pageDown()
664                 self.updateUSBInfo()
665
666         def keyUp(self):
667                 self["menulist"].up()
668                 self.updateUSBInfo()
669
670         def keyDown(self):
671                 self["menulist"].down()
672                 self.updateUSBInfo()
673
674         def keyOK(self):
675                 self.forceStop = False
676                 if self.isAttemptConnect():
677                         return
678
679                 def areadyExistAnotherAdapter():
680                         networkAdapters = iNetwork.getConfiguredAdapters()
681                         for x in networkAdapters:
682                                 if x[:3] != 'ppp':
683                                         return True
684                         return False
685
686                 if self["key_green"].getText() == 'Disconnect':
687                         message = "Do you want to disconnect?"
688                         self.session.openWithCallback(self.cbConfirmDone, MessageBox, _(message), default = False)
689                         return
690
691                 if areadyExistAnotherAdapter():
692                         message = "Another adapter connected has been found.\n\nA connection is attempted after disconnect all of other device. Do you want to?"
693                         self.session.openWithCallback(self.cbConfirmDone, MessageBox, _(message), default = True)
694                 else:   self.cbConfirmDone(True)
695
696         def cbConfirmDone(self, ret):
697                 if not ret: return
698                 if self["key_green"].getText() == 'Connect':
699                         networkAdapters = iNetwork.getConfiguredAdapters()
700                         for x in networkAdapters:
701                                 if x[:3] == 'ppp': continue
702                                 iNetwork.setAdapterAttribute(x, "up", False)
703                                 iNetwork.deactivateInterface(x)
704
705                 x = {}
706                 try: x = self["menulist"].getCurrent()[1]
707                 except:
708                         printInfoModemMgr('no selected device..')
709                         return
710
711                 devFile = '/usr/share/usb_modeswitch/%s:%s' % (x.get("Vendor"), x.get("ProdID"))
712                 if not os.path.exists(devFile) :
713                         message = "Can't found device file!! [%s]" % (devFile)
714                         printInfoModemMgr(message)
715                         self.session.open(MessageBox, _(message), MessageBox.TYPE_INFO)
716                         return
717
718                 if self["key_green"].getText() == 'Disconnect':
719                         cmd = "%s -s 0" % (self.commandBin)
720                         self.taskManager.append(cmd, self.cbPrintAvail, self.cbPrintClose)
721
722                         cmd = "%s -s 1" % (self.commandBin)
723                         self.taskManager.append(cmd, self.cbPrintAvail, self.cbUnloadClose)
724                         self.taskManager.setStatusCB(self.setDisconnectStatus)
725                 else:
726                         cmd = "%s -s 2 -e vendor=0x%s -e product=0x%s" % (self.commandBin, x.get("Vendor"), x.get("ProdID"))
727                         self.taskManager.append(cmd, self.cbStep1PrintAvail, self.cbPrintClose)
728
729                         cmd = "%s -s 3 -e %s:%s" % (self.commandBin, x.get("Vendor"), x.get("ProdID"))
730                         self.taskManager.append(cmd, self.cbPrintAvail, self.cbPrintClose)
731
732                         cmd = "%s -s 4" % (self.commandBin)
733                         self.taskManager.append(cmd, self.cbStep3PrintAvail, self.cbMakeWvDialClose)
734
735                         cmd = "%s -s 5" % (self.commandBin)
736                         self.taskManager.append(cmd, self.cbRunWvDialAvail, self.cbPrintClose)
737                         self.taskManager.setStatusCB(self.setConnectStatus)
738                 
739                 self.taskManager.next()
740
741         def printStatus(self, idx, STATUS):
742                 message = ''
743                 self.connectionStatus = idx
744                 for x in range(0,len(STATUS)):
745                         if idx == x:
746                                 message += '  > '
747                         else:   message += '      '
748                         message += STATUS[x]
749                         message += '\n'
750                 self['statusInfo'].setText(message)
751
752         def setConnectStatus(self, idx):
753                 STATUS = {
754                  0:'1. Load a Mobile Broadband Device'
755                 ,1:'2. Set up a Mobile Broadband Device'
756                 ,2:'3. Generate a WvDial profile'
757                 ,3:'4. Attempt to connect'
758                 ,4:'5. Done'
759                 }
760                 self.printStatus(idx, STATUS)
761
762         def setDisconnectStatus(self, idx):
763                 STATUS = {
764                  0:'1. Drop WvDial'
765                 ,1:'2. Unload a Mobile Broadband Device'
766                 ,2:'3. Done'
767                 }
768                 self.printStatus(idx, STATUS)
769
770         def cbStep1PrintAvail(self, data):
771                 print data
772                 if data.find('modules.dep') > -1:
773                         self.forceStop = True
774
775         def cbStep3PrintAvail(self, data):
776                 print data
777                 if data.find('no modem was detected') > -1:
778                         self.forceStop = True
779
780         def cbPrintAvail(self, data):
781                 print data
782
783         def cbPrintClose(self, ret):
784                 if self.forceStop:
785                         self.taskManager.clean()
786                         time.sleep(2)
787                         message = "Occur error during connection...\nPlease, Check your setting!!"
788                         self.session.open(MessageBox, _(message), MessageBox.TYPE_INFO)
789                         return
790                 self.taskManager.next()
791
792         def cbUnloadClose(self, ret):
793                 self.taskManager.clean()
794                 time.sleep(2)
795                 self["key_green"].setText('Connect')
796                 self.setDisconnectStatus(2)
797                 self.refreshStatusTimer.start(1000)
798
799         def cbRunWvDialAvail(self, data):
800                 print data
801                 if data.find('Bad init') > -1 or data.find('Invalid dial') > -1 or data.find('No Carrier') > -1:
802                         self.forceStop = True
803                         return
804                 if data.find('Pid of pppd:') > -1:
805                         self.taskManager.clean()
806                         time.sleep(2)
807                         self["key_green"].setText('Disconnect')
808                         self.setConnectStatus(4)
809                         self.refreshStatusTimer.start(1000)
810                         #self.restartAppTimer.start(3000)
811
812         def cbMakeWvDialClose(self, ret):
813                 if self.forceStop:
814                         self.taskManager.clean()
815                         time.sleep(2)
816                         message = "Occur error during connection...\nPlease, Check your setting!!"
817                         self.session.open(MessageBox, _(message), MessageBox.TYPE_INFO)
818                         return
819
820                 info = {}
821                 try:
822         
823                         datalist = file('/etc/wvdial.conf').read().splitlines()
824                         for x in datalist:
825                                 if x.startswith('Modem ='):
826                                         print x
827                                         info['Modem'] = x[7:].strip()
828                                 elif x.startswith('Init2 ='):
829                                         print x
830                                         info['Init'] = x[7:].strip()
831                                 elif x.startswith('Baud ='):
832                                         print x
833                                         info['Baud'] = x[6:].strip()
834                 except Exception, err: 
835                         printDebugModemMgr("getModemInfo Error : [%s]" % (str(err)))
836                         # TODO : occur error!!
837                         return
838
839                 if not isEmpty(self.apn):   info['apn']   = self.apn
840                 if not isEmpty(self.uid):   info['uid']   = self.uid
841                 if not isEmpty(self.pwd):   info['pwd']   = self.pwd
842                 if not isEmpty(self.pin):   info['pin']   = self.pin
843                 if not isEmpty(self.phone): info['phone'] = self.phone
844                 #info['phone'] = '*99#'
845                 self.makeWvDialConf(info)
846                 self.taskManager.next()
847
848         def writeConf(self, data, oper='>>'):
849                 confFile = '/etc/wvdial.conf'
850                 if oper == '>':
851                         os.system('mv %s %s.bak' % (confFile, confFile))
852                 cmd = "echo '%s' %s %s" % (data, oper, confFile)
853                 os.system(cmd)
854
855         def makeWvDialConf(self, params):
856                 baud  = params.get('Baud')
857                 init  = params.get('Init')
858                 modem = params.get('Modem')
859                 phone = params.get('phone')
860                 apn = params.get('apn')
861                 uid = params.get('uid')
862                 pwd = params.get('pwd')
863                 pin = params.get('pin')
864                 idxInit = 1
865
866                 if isEmpty(phone): phone = '*99#'
867                 if isEmpty(uid):   uid = 'USER'
868                 if isEmpty(pwd):   pwd = 'PASSWORD'
869
870                 self.writeConf('','>')
871
872                 self.writeConf('[Dialer Defaults]')
873                 if isEmpty(modem) or isEmpty(init) or isEmpty(baud):
874                         return False
875                 self.writeConf('Modem = %s' % (modem))
876                 self.writeConf('Baud = %s' % (baud))
877                 self.writeConf('Dial Command = ATDT')
878                 self.writeConf('Init%d = ATZ' % (idxInit))
879                 idxInit = idxInit + 1
880                 if not isEmpty(pin):
881                         self.writeConf('Init%d = AT+CPIN=%s' % (idxInit, pin))
882                         idxInit = idxInit + 1
883                 self.writeConf('Init%d = %s' % (idxInit, init))
884                 idxInit = idxInit + 1
885                 if isEmpty(apn) and isEmpty(uid) and isEmpty(pwd) and isEmpty(pin):
886                         self.writeConf('Init%d = AT&F' % (idxInit))
887                         idxInit = idxInit + 1
888                 if not isEmpty(apn):
889                         self.writeConf('Init%d = AT+CGDCONT=1,"IP","%s"' % (idxInit, apn))
890                         idxInit = idxInit + 1
891                 self.writeConf('Init%d = AT+CFUN = 1' % (idxInit))
892                 self.writeConf('Username = %s' % (uid))
893                 self.writeConf('Password = %s' % (pwd))
894                 self.writeConf('Phone = %s' % (phone)) #*99#
895                 self.writeConf('Modem Type = Analog Modem')
896                 self.writeConf('ISDN = 0')
897                 self.writeConf('Carrier Check = 0')
898                 self.writeConf('Abort on No Dialtone = 0')
899                 self.writeConf('Stupid Mode = 1')
900                 self.writeConf('Check DNS = 1')
901                 self.writeConf('Check Def Route = 1')
902                 self.writeConf('Auto DNS = 1')
903                 if debug_mode_modem_mgr:
904                         printDebugModemMgr(file('/etc/wvdial.conf').read())
905
906         def isConnected(self):
907                 return len(os.popen('ifconfig -a | grep ppp').read().strip()) > 0
908
909         def updateUSBInfo(self):
910                 info = ' '
911                 try:
912                         apn,uid,pwd,pin,phone = self.apn,self.uid,self.pwd,self.pin,self.phone
913                         if apn is None:   apn = ""
914                         if uid is None:   uid = ""
915                         if pwd is None:   pwd = ""
916                         if pin is None:   pin = ""
917                         if phone is None: phone = ""
918                         x = self["menulist"].getCurrent()[1]
919                         info = 'Vendor : %s/%s\nAPN : %s\nUser : %s\nPassword : %s\nPin : %s\nPhone : %s' % (
920                                         x.get("Vendor"), 
921                                         x.get("ProdID"), 
922                                         apn,
923                                         uid,
924                                         pwd,
925                                         pin,
926                                         phone
927                                 )
928                 except: pass
929                 self['usbinfo'].setText(info)
930
931         def setListOnView(self):
932                 lv_usb_items = []
933                 try:
934                         for x in self.getUSBList():
935                                 lv_usb_items.append((x.get("Product"),x))
936                 except: pass
937                 return lv_usb_items
938
939         def getUSBList(self):
940                 parsed_usb_list = []
941                 usb_devices = os.popen('cat /proc/bus/usb/devices').read()
942                 tmp_device = {}
943                 for x in usb_devices.splitlines():
944                         if x is None or len(x) == 0:
945                                 printDebugModemMgr("TMP DEVICE : [%s]" % (tmp_device))
946                                 if len(tmp_device):
947                                         parsed_usb_list.append(tmp_device)
948                                 tmp_device = {}
949                                 continue
950                         try:
951                                 if x[0] in ('P', 'S', 'I', 'T'):
952                                         tmp = x[2:].strip()
953                                         printDebugModemMgr("TMP : [%s]" % (tmp))
954                                         if tmp.startswith('Bus='):
955                                                 #printDebugModemMgr("TMP SPLIT for BUS : [%s]" % (str(tmp.split())))
956                                                 for xx in tmp.split():
957                                                         if xx.startswith('Bus='):
958                                                                 tmp_device['Bus'] = xx[4:]
959                                                                 break
960                                         if tmp.startswith('Manufacturer='):
961                                                 tmp_device['Manufacturer'] = tmp[13:]
962                                         if tmp.startswith('Product='):
963                                                 tmp_device['Product'] = tmp[8:]
964                                         elif tmp.startswith('SerialNumber='):
965                                                 tmp_device['SerialNumber'] = tmp[13:]
966                                         elif tmp.startswith('Vendor='):
967                                                 #printDebugModemMgr("TMP SPLIT for BUS : [%s]" % (str(tmp.split())))
968                                                 for xx in tmp.split():
969                                                         if xx.startswith('Vendor='):
970                                                                 tmp_device['Vendor'] = xx[7:]
971                                                         elif xx.startswith('ProdID='):
972                                                                 tmp_device['ProdID'] = xx[7:]
973                                                 #tmp_device['Vendor'] = tmp
974                                         elif tmp.find('Driver=') > 0:
975                                                 d = tmp[tmp.find('Driver=')+7:]
976                                                 if d != '(none)':
977                                                         tmp_device['Interface'] = d
978                         except Exception, errmsg:
979                                 print errmsg
980                 if len(tmp_device):
981                         parsed_usb_list.append(tmp_device)
982                 printDebugModemMgr("PARSED DEVICE LIST : " + str(parsed_usb_list))
983                 rt_usb_list = []
984                 for x in parsed_usb_list:
985                         printDebugModemMgr('Looking >> ' + str(x))
986                         try:
987                                 xx = x.get("Interface")
988                                 if xx.startswith('usb'):
989                                         rt_usb_list.append(x)
990                         except: pass
991                 printInfoModemMgr("USB DEVICE LIST : " + str(rt_usb_list))
992                 return rt_usb_list
993
994 def main(session, **kwargs):
995         session.open(ModemManager)
996                                                            
997 def Plugins(**kwargs):            
998         return PluginDescriptor(name=_("Modem Manager"), description="management 3g modem", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)
999