1
2
3
4 import os
5 import bluetooth
6 import logging
7 log = logging.getLogger("modules.Phone")
8
9 import conduit.dataproviders.DataProvider as DataProvider
10 import conduit.utils as Utils
11 import ScanThreads
12 import Data
13
14 try:
15 import gammu
16 log.info("Module Information: %s" % Utils.get_module_information(gammu, "__version__"))
17 GAMMU_SUPPORTED = True
18 except ImportError:
19 log.info("Gammu based phone support disabled")
20 GAMMU_SUPPORTED = False
21
23 """
24 Encapsulates the basic connection to a phone using gammu.
25 """
26 - def __init__(self, address, connection, model=''):
27 """
28 Attempts to connect to the phone at address and connection and
29 get all available phone informatin, like the model, manufacturer, etc.
30 """
31 self.address = address
32 self.connection = connection
33 self.model = model
34 self.isKnownToGammu = False
35 self.info = {}
36
37 self.sm = gammu.StateMachine()
38 self.sm.SetConfig(0, {
39 'StartInfo' : 'no',
40 'UseGlobalDebugFile' : 1,
41 'DebugFile' : '',
42 'SyncTime' : 'no',
43 'Connection' : connection,
44 'LockDevice' : 'no',
45 'DebugLevel' : 'nothing',
46 'Device' : address,
47 'Localize' : None,
48 'Model' : model}
49 )
50
51 self.sm.Init()
52
53 self.info['connection'] = connection
54
55
56
57 try:
58 self.info['manufacturer'] = self.sm.GetManufacturer()
59 except gammu.ERR_NOTSUPPORTED, gammu.ERR_NOTIMPLEMENTED:
60 self.info['manufacturer'] = "Unknown"
61
62 model = "Unknown"
63 try:
64 m = self.sm.GetModel()
65 if m[0] == '' or m[0] == 'unknown':
66 model = m[1]
67 else:
68 model = m[0]
69 self.isKnownToGammu = True
70 except gammu.ERR_NOTSUPPORTED, gammu.ERR_NOTIMPLEMENTED:
71 model = "Unknown"
72 self.info['model'] = model
73
74 try:
75 self.info['firmware'] = self.sm.GetFirmware()[0]
76 except gammu.ERR_NOTSUPPORTED, gammu.ERR_NOTIMPLEMENTED:
77 self.info['firmware'] = "Unknown"
78
89
107
109 while self.is_cancelled() == False:
110 log.info("Beginning Bluetooth Scan")
111 try:
112 self.discovery.find_devices()
113 self.discovery.process_inquiry()
114 for address,info in self._found.items():
115 if address in os.environ.get('PHONE_BLACKLIST',"").split(","):
116 log.info("Skipping %s, blacklisted" % address)
117 continue
118
119
120 if not info.has_key('connection'):
121
122 info.update(
123 self.lookup_model_information(address)
124 )
125
126
127 services = bluetooth.find_service(address=address)
128 log.info("Supported services: %s" % ", ".join([i['name'] for i in services]))
129 info['services'] = services
130
131 self.foundCallback(address,info['name'],"bluetooth",info)
132 except bluetooth.BluetoothError:
133 log.warn("Error discovering services")
134
135 self.pause_scanning()
136
140
148
150
151 _name_ = "Contacts"
152 _module_type_ = "source"
153 _in_type_ = "contact"
154 _out_type_ = "contact"
155
156
157 MAX_EMPTY_GUESS = 5
158 MAX_EMPTY_KNOWN = 5
159
160 - def __init__(self, address, connection):
161 DataProvider.DataSource.__init__(self)
162 self.address = address
163 self.connection = connection
164
165
166 self.model = "at"
167 self.phone = None
168
171
174
176 '''
177 Initiates get next sequence.
178
179 Should be implemented in subclases.
180 '''
181 raise NotImplementedError
182
183 - def _get_next_entry(self, location):
184 '''
185 Gets next entry.
186
187 Should be implemented in subclases.
188 '''
189 raise NotImplementedError
190
191 - def _get_entry(self, location):
192 '''
193 Gets entry.
194
195 Should be implemented in subclases.
196 '''
197 raise NotImplementedError
198
200 '''
201 Gets status of entries.
202
203 Should be implemented in subclases.
204 '''
205 raise NotImplementedError
206
207 - def _parse_entry(self):
208 '''
209 Parses entry.
210
211 Should be implemented in subclases.
212 '''
213 raise NotImplementedError
214
216 '''
217 Sends entries to parent.
218
219 Should be implemented in subclases.
220 '''
221 raise NotImplementedError
222
224 '''
225 UNFINISHED PORT OF WAMMU's SUBCLASSABLE APPROACH FOR GETTING DATA
226 '''
227 guess = False
228 try:
229 total = self._get_num_items()
230 except gammu.GSMError, val:
231 guess = True
232 total = self._guess_num_items()
233
234 remain = total
235
236 data = []
237
238 try:
239 start = True
240 while remain > 0:
241
242
243
244 try:
245 if start:
246 value = self._get_first_entry()
247 start = False
248 else:
249 try:
250 loc = value['Location']
251 except TypeError:
252 loc = value[0]['Location']
253 value = self._get_next_entry(loc)
254 except gammu.ERR_CORRUPTED:
255 log.warn('While reading, entry on location %d seems to be corrupted, ignoring it!' % loc)
256 continue
257 except gammu.ERR_EMPTY:
258 break
259
260 self._parse_entry(value)
261 if type(value) == list:
262 for i in range(len(value)):
263 value[i]['Synced'] = True
264 else:
265 value['Synced'] = True
266 data.append(value)
267 remain = remain - 1
268 except (gammu.ERR_NOTSUPPORTED, gammu.ERR_NOTIMPLEMENTED):
269 location = 1
270 empty = 0
271 while remain > 0:
272
273
274
275 try:
276 value = self._get_entry(location)
277 self._parse_entry(value)
278 if type(value) == list:
279 for i in range(len(value)):
280 value[i]['Synced'] = True
281 else:
282 value['Synced'] = True
283 data.append(value)
284 remain = remain - 1
285
286 if remain == 0 and guess:
287 remain = 20
288 total = total + 20
289 empty = 0
290 except gammu.ERR_EMPTY, val:
291 empty = empty + 1
292
293 if empty >= self.MAX_EMPTY_GUESS and guess:
294 break
295
296 if empty >= self.MAX_EMPTY_KNOWN and remain < 10:
297 self.ShowError(val[0])
298 remain = 0
299 except gammu.ERR_CORRUPTED:
300 log.warn('While reading, entry on location %d seems to be corrupted, ignoring it!' % location)
301 continue
302 except gammu.GSMError, val:
303 log.critical(val[0])
304 return
305 location = location + 1
306 except gammu.ERR_INVALIDLOCATION, val:
307
308 if not guess:
309 log.critical(val[0])
310 return
311 except gammu.GSMError, val:
312 log.critical(val[0])
313 return
314
315
316
318 if not self.phone:
319 self.phone = GammuPhone(self.address, self.connection, self.model)
320 log.debug("Connected to phone: %s" % (self.phone.info['model']))
321 self.get_all()
322
324
325 location = "ME"
326 contactList = []
327
328 status = self.phone.sm.GetMemoryStatus(Type=location)
329 remain = status['Used']
330 log.debug("%s contacts on phone" % remain)
331
332 start = True
333 while remain > 0:
334 if start:
335 entry = self.phone.sm.GetNextMemory(Start=True, Type=location)
336 start = False
337 else:
338 entry = self.phone.sm.GetNextMemory(Location=entry['Location'], Type=location)
339
340 remain = remain - 1
341
342 contact = Contact('', '')
343 for v in entry['Entries']:
344 if v['Type'] == 'Number_General':
345 contact.phoneNumber = v['Value']
346 elif v['Type'] == 'Text_Name':
347 contact.name = v['Value']
348
349 if len(contact.name) > 0 and len(contact.phoneNumber) > 0:
350 print "*"*20,contact
351
352
353 return contactList
354