summaryrefslogblamecommitdiffstats
path: root/Src/PyCatcher/src/driverConnector.py
blob: 97acf0ae311dbcab73e2f85f668125c844e2610e (plain) (tree)
1
2
3
4
5
6



                                                 
                                          
           






                           









                                                

                                 










                                                                                                               




                                                                        











                                          

                                    






















                                                                                                                               














                                                                                                                       
                            







                                                               
                                                             
                                                                  


                                                                 
                                                             
                                                                  


                                                                  
                                                             
                                                                

                                                                    
                                    
                                                             

                                                                  
                                                                   
                                
                                                             



                                                                  

                                                                   
                                 
                                                              
                                  

                                                                 
                                 
                                                                    


















                                                                                                
                                
                                                             
                                                             

                                                                                   
                                   
                                                             
                                                                

                                                                                      

                                                             
                                                                

                                                                                      
                                
                                                      

                                                                       
                                    








                                                          
                            

































                                                                                                          
                                  







                                                         






                                                                 







                                                       

                                             










                                                    
 






                                                       
                                                                     










                                                               
from pyCatcherModel import BaseStationInformation
import subprocess
import threading 
import re
from settings import Commands, PCH_retries
import time
import gtk
import datetime
import thread
from threading import Timer
import os
import signal
import select

class DriverConnector:        
    def __init__ (self):
        self._scan_thread_break = False
        self._firmware_thread_break = False
        self._firmware_waiting_callback = None
        self._firmware_loaded_callback = None
        self._base_station_found_callback = None
        self._firmware_thread = None
        self._scan_thread = None
        self._pch_thread = None
        self._pch_callback = None
        
    def start_scanning (self, base_station_found_callback):
        self._base_station_found_callback = base_station_found_callback
        self._scan_thread = ScanThread(self._base_station_found_callback)
        self._scan_thread.start()

    def start_firmware(self, firmware_waiting_callback, firmware_loaded_callback):
        self._firmware_waiting_callback = firmware_waiting_callback
        self._firmware_loaded_callback = firmware_loaded_callback      
        self._firmware_thread = FirmwareThread(self._firmware_waiting_callback, self._firmware_loaded_callback)
        self._firmware_thread.start()

    def start_pch_scan(self, arfcn, timeout, scan_finished_callback):
        self._pch_callback = scan_finished_callback
        self._pch_thread = PCHThread(arfcn, timeout, self._pch_callback)
        self._pch_thread.start()
        
    def stop_scanning (self):
        self._scan_thread.terminate()
        
    def stop_firmware(self):
        self._firmware_thread_break = True
        
    def shutdown(self):
        if self._firmware_thread:
            self._firmware_thread.join(3)
        if self._scan_thread:
            self._scan_thread.join(3)
        if self._pch_thread:
            self._pch_thread.join(3)
        
class FirmwareThread(threading.Thread):
    def __init__(self, firmware_waiting_callback, firmware_loaded_callback):
        gtk.gdk.threads_init()
        threading.Thread.__init__(self)
        self._firmware_waiting_callback = firmware_waiting_callback
        self._firmware_loaded_callback = firmware_loaded_callback
        self._thread_break = False

    def terminate(self):
        self._thread_break = True
       
    def run(self):
        loader_process_object = subprocess.Popen(Commands['osmocon_command'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        time.sleep(3)
        self._firmware_waiting_callback()
        while not self._thread_break:
            line = loader_process_object.stdout.readline()
            #if line:
            #    print line
            if line.strip() == 'Finishing download phase':
                self._firmware_loaded_callback()
            #time.sleep(0.5)
        loader_process_object.terminate()

class ScanThread(threading.Thread):
        def __init__(self, base_station_found_callback):
            gtk.gdk.threads_init()
            threading.Thread.__init__(self)
            self._base_station_found_callback = base_station_found_callback
            self._thread_break = False
            
        def terminate(self):
            self._thread_break = True
        
        def run(self): 
            scan_process = subprocess.Popen(Commands['scan_command'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            time.sleep(2)
            printall = False
            while not self._thread_break:
                line = scan_process.stdout.readline()
                if line:
                    #print line
                    #sys.stdout.flush()
                    if re.search('SysInfo', line):
                        base_station = BaseStationInformation()
                        #get country
                        line = scan_process.stdout.readline()
                        match = re.search(r'Country:\s(\w+)',line)
                        if match:
                            base_station.country = match.group(1)
                        #get provider
                        line = scan_process.stdout.readline()
                        match = re.search(r'Provider:\s(.+)',line)
                        if match:
                            base_station.provider = match.group(1)
                        #get arfcn
                        line = scan_process.stdout.readline()
                        match = re.search(r'ARFCN:\s(\d+)',line)
                        if match:
                            base_station.arfcn = int(match.group(1))
                        #get cell id
                        line = scan_process.stdout.readline()
                        match = re.search(r'Cell ID:\s(\d+)',line)
                        if match:
                            base_station.cell = int(match.group(1))
                        #get lac
                        line = scan_process.stdout.readline()
                        match = re.search(r'LAC:\s(\d+)',line)
                        if match:
                            base_station.lac = int(match.group(1))
                        #get bsic
                        line = scan_process.stdout.readline()
                        match = re.search(r'BSIC:\s(\d+,\d+)',line)
                        if match:
                            base_station.bsic = match.group(1)
                        #get rxlev
                        line = scan_process.stdout.readline()
                        match = re.search(r'rxlev:\s(.\d+)',line)
                        if match:
                            base_station.rxlev = int(match.group(1))
                        line = scan_process.stdout.readline()
                        match = re.search(r'\s((\d+)\s)*',line)
                        if match:
                            base_station.neighbours = map(int,match.group(0).strip().split(' '))
                        #get si1
                        line = scan_process.stdout.readline()
                        match = re.search(r'SI1:\s(.+)',line)
                        if match:
                            base_station.system_info_t1 = match.group(1).split(' ')
                        #get si3
                        line = scan_process.stdout.readline()
                        match = re.search(r'SI3:\s(.+)',line)
                        if match:
                            base_station.system_info_t3 = match.group(1).split(' ')
                        #get si4
                        line = scan_process.stdout.readline()
                        match = re.search(r'SI4:\s(.+)',line)
                        if match:
                            base_station.system_info_t4 = match.group(1).split(' ')
                        #get si2
                        line = scan_process.stdout.readline()
                        match = re.search(r'SI2:\s(.+)',line)
                        if match:
                            base_station.system_info_t2 = match.group(1).split(' ')
                        #get si2ter
                        line = scan_process.stdout.readline()
                        match = re.search(r'SI2ter:\s(.+)',line)
                        if match:
                            base_station.system_info_t2ter = match.group(1).split(' ')
                        #get si2bis
                        line = scan_process.stdout.readline()
                        match = re.search(r'SI2bis:\s(.+)',line)
                        if match:
                            base_station.system_info_t2bis = match.group(1).split(' ')
                        #endinfo
                        scan_process.stdout.readline()
                        
                        self._base_station_found_callback(base_station)
            scan_process.terminate()

class PCHThread(threading.Thread):
    def __init__(self, arfcn, timeout, finished_callback):
        gtk.gdk.threads_init()
        threading.Thread.__init__(self)
        self._arfcn = arfcn
        self._timeout = timeout
        self._thread_break = False
        self._scan_finished_callback = finished_callback
        self._tmsi_dict = {}

    def terminate(self):
        self._thread_break = True

    def run(self):
        pch_retries = PCH_retries
        max_scan_time = self._timeout
        arfcn = self._arfcn
        pages_found = 0
        ia_non_hop_found = 0
        ia_hop_fund = 0
        retry = False
        buffer = []

        command = Commands['pch_command'] + ['-a', str(arfcn)]
        scan_process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        time.sleep(2)
        poll_obj = select.poll()
        poll_obj.register(scan_process.stdout, select.POLLIN)

        start_time = datetime.datetime.now()
        scan_time = datetime.datetime.now() - start_time

        while(True and not self._thread_break):

            if(retry):
                scan_process.terminate()
                scan_process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
                poll_obj.register(scan_process.stdout, select.POLLIN)
                retry = False

            while(pch_retries > 0 and scan_time.seconds < max_scan_time and not self._thread_break):
                scan_time = datetime.datetime.now() - start_time
                poll_result = poll_obj.poll(0)
                pch_failed = False
                if poll_result:
                    line = scan_process.stdout.readline()
                else:
                    line = None

                if line:
                    if 'Paging' in line:
                        pages_found += 1
                        match = re.search(r'M\((.*)\)',line)
                        if match:
                            tmsi = match.group(1)
                            if not self._tmsi_dict.has_key(tmsi):
                                self._tmsi_dict[tmsi] = 1
                            else:
                                self._tmsi_dict[tmsi] += 1
                    if 'IMM' in line:
                        if 'HOP' in line:
                            ia_hop_fund += 1
                        else:
                            ia_non_hop_found += 1
                    if 'FBSB RESP: result=255' in line:
                        if(pch_retries > 0):
                            retry = True
                        else:
                            pch_failed = True
                        break

            if(retry):
                print 'SCAN: retry (%d)'%pch_retries
                pch_retries -= 1
            else:
                break

        if scan_process:
            scan_process.kill()


        result = {
            'Pagings': pages_found,
            'Assignments_hopping': ia_hop_fund,
            'Assignments_non_hopping': ia_non_hop_found
        }

        if not self._thread_break:
            self._scan_finished_callback((arfcn, result), pch_failed)

class BufferFillerThread(threading.Thread):
    def __init__(self, buffer, process):
        gtk.gdk.threads_init()
        threading.Thread.__init__(self)
        self._buffer = buffer
        self._process = process

    def run(self):
        while(True):
            self._buffer.append(self._process.stdout.readline())