def _setmodemodem(self):
     self.log("_setmodemodem")
     req=p_brew.memoryconfigrequest()
     respc=p_brew.memoryconfigresponse
     try:
         self.comm.sendatcommand("Z")
         self.comm.sendatcommand('E0V1')
         return True
     except:
         pass
     for baud in 0, 38400,115200:
         if baud:
             if not self.comm.setbaudrate(baud):
                 continue
         try:
             self.sendbrewcommand(req, respc, callsetmode=False)
             self.log('In BREW mode, trying to switch to Modem mode')
             if self._setmodebrewtomodem():
                 break
             return False
         except com_brew.modeignoreerrortypes:
             pass
     for baud in (0, 115200, 19200, 230400):
         self.log("Baud="+`baud`)
         if baud:
             if not self.comm.setbaudrate(baud):
                 continue
         try:
             self.comm.sendatcommand("Z")
             self.comm.sendatcommand('E0V1')
             return True
         except:
             pass
     return False
 def is_mode_brew(self):
     req=p_brew.memoryconfigrequest()
     respc=p_brew.memoryconfigresponse
     for baud in 0, 38400, 115200:
         if baud:
             if not self.comm.setbaudrate(baud):
                 continue
         try:
             self.sendbrewcommand(req, respc, callsetmode=False)
             return True
         except com_phone.modeignoreerrortypes:
             pass
     return False
示例#3
0
 def is_mode_brew(self):
     req=p_brew.memoryconfigrequest()
     respc=p_brew.memoryconfigresponse
     
     for baud in 0, 38400, 115200:
         if baud:
             if not self.comm.setbaudrate(baud):
                 continue
         try:
             self.sendbrewcommand(req, respc, callsetmode=False)
             return True
         except com_phone.modeignoreerrortypes:
             pass
     return False
 def _setmodebrew(self):
     req=p_brew.memoryconfigrequest()
     respc=p_brew.memoryconfigresponse
     for baud in 0, 38400,115200:
         if baud:
             if not self.comm.setbaudrate(baud):
                 continue
         try:
             self.sendbrewcommand(req, respc, callsetmode=False)
             return True
         except modeignoreerrortypes:
             pass
     for baud in (0, 115200, 19200, 230400):
         if baud:
             if not self.comm.setbaudrate(baud):
                 continue
         print "Baud="+`baud`
         try:
             for line in self.comm.sendatcommand("+GMM"):
                 if line.find("SPH-A700")>0:
                     raise BrewNotSupported("This phone is not supported by BitPim", self.desc)
         except modeignoreerrortypes:
             self.log("No response to AT+GMM")
         except:
             print "GMM Exception"
             self.mode=self.MODENONE
             self.comm.shouldloop=True
             raise
         try:
             self.comm.write("AT$QCDMG\r\n")
         except:
             self.mode=self.MODENONE
             self.comm.shouldloop=True
             raise
         try:
             if self.comm.readsome().find("OK")>=0:
                 break
         except modeignoreerrortypes:
             self.log("No response to setting QCDMG mode")
     for baud in 0,38400,115200:
         if baud:
             if not self.comm.setbaudrate(baud):
                 continue
         try:
             self.sendbrewcommand(req, respc, callsetmode=False)
             return True
         except modeignoreerrortypes:
             pass
     return False
示例#5
0
    def _setmodemodem(self):
        self.log("_setmodemodem")
        req=p_brew.memoryconfigrequest()
        respc=p_brew.memoryconfigresponse
        
        # Just try waking phone up first
        try:
            self.comm.sendatcommand("Z")
            self.comm.sendatcommand('E0V1')
            return True
        except:
            pass

        # Now check to see if in diagnostic mode
        for baud in 0, 38400,115200:
            if baud:
                if not self.comm.setbaudrate(baud):
                    continue
            try:
                self.sendbrewcommand(req, respc, callsetmode=False)
                self.log('In BREW mode, trying to switch to Modem mode')
                # Infinite loop
                if self._setmodebrewtomodem():
                    break
                return False
            except com_brew.modeignoreerrortypes:
                pass
        
        # Should be in modem mode.  Wake up the interface
        for baud in (0, 115200, 19200, 230400):
            self.log("Baud="+`baud`)
            if baud:
                if not self.comm.setbaudrate(baud):
                    continue

            try:
                self.comm.sendatcommand("Z")
                self.comm.sendatcommand('E0V1')
                return True
            except:
                pass

        return False
    def _setmodemodem(self):
        self.log("_setmodemodem")
        req=p_brew.memoryconfigrequest()
        respc=p_brew.memoryconfigresponse
        
        # Just try waking phone up first
        try:
            self.comm.sendatcommand("Z")
            self.comm.sendatcommand('E0V1')
            return True
        except:
            pass

        # Now check to see if in diagnostic mode
        for baud in 0, 38400,115200:
            if baud:
                if not self.comm.setbaudrate(baud):
                    continue
            try:
                self.sendbrewcommand(req, respc, callsetmode=False)
                self.log('In BREW mode, trying to switch to Modem mode')
                # Infinite loop
                if self._setmodebrewtomodem():
                    break
                return False
            except com_brew.modeignoreerrortypes:
                pass
        
        # Should be in modem mode.  Wake up the interface
        for baud in (0, 115200, 19200, 230400):
            self.log("Baud="+`baud`)
            if baud:
                if not self.comm.setbaudrate(baud):
                    continue

            try:
                self.comm.sendatcommand("Z")
                self.comm.sendatcommand('E0V1')
                return True
            except:
                pass

        return False
	def writefile(self, name, contents):

        start=time.time()

        self.log("Writing file '"+name+"' bytes "+`len(contents)`)

        desc="Writing "+name

        req=p_brew.writefilerequest()

        req.filesize=len(contents)

        req.data=contents[:0x100]

        req.filename=name

        self.sendbrewcommand(req, p_brew.writefileresponse)

        numblocks=len(contents)/0x100

        count=0

        for offset in range(0x100, len(contents), 0x100):

            req=p_brew.writefileblockrequest()

            count+=1

            if count>=0x100: count=1

            if count % 5==0:

                self.progress(offset>>8,numblocks,desc)

            req.blockcounter=count

            req.thereismore=offset+0x100<len(contents)

            block=contents[offset:]

            l=min(len(block), 0x100)

            block=block[:l]

            req.data=block

            self.sendbrewcommand(req, p_brew.writefileblockresponse)

        end=time.time()

        if end-start>3:

            self.log("Wrote "+`len(contents)`+" bytes at "+`int(len(contents)/(end-start))`+" bytes/second")

	def getfilecontents(self, file, use_cache=False):

        if use_cache:

            node=self.statfile(file)

            if node and file_cache.hit(file, node['date'][0], node['size']):

                self.log('Reading from cache: '+file)

                _data=file_cache.data(file)

                if _data:

                    return _data

                self.log('Cache file corrupted and discarded')

        start=time.time()

        self.log("Getting file contents '"+file+"'")

        desc="Reading "+file

        data=cStringIO.StringIO()

        req=p_brew.readfilerequest()

        req.filename=file

        res=self.sendbrewcommand(req, p_brew.readfileresponse)

        filesize=res.filesize

        data.write(res.data)

        counter=0

        while res.thereismore:

            counter+=1

            if counter>0xff:

                counter=0x01

            if counter%5==0:

                self.progress(data.tell(), filesize, desc)

            req=p_brew.readfileblockrequest()

            req.blockcounter=counter

            res=self.sendbrewcommand(req, p_brew.readfileblockresponse)

            data.write(res.data)

        self.progress(1,1,desc)

        data=data.getvalue()

        end=time.time()

        if end-start>3:

            self.log("Read "+`filesize`+" bytes at "+`int(filesize/(end-start))`+" bytes/second")

        if filesize!=len(data):

            self.log("expected size "+`filesize`+"  actual "+`len(data)`)

            self.raisecommsexception("Brew file read is incorrect size", common.CommsDataCorruption)

        if use_cache and node:

            file_cache.add(file, node.get('date', [0])[0], data)

        return data

	DirCache=_DirCache
	    def _setmodebrew(self):

        req=p_brew.memoryconfigrequest()

        respc=p_brew.memoryconfigresponse

        for baud in 0, 38400,115200:

            if baud:

                if not self.comm.setbaudrate(baud):

                    continue

            try:

                self.sendbrewcommand(req, respc, callsetmode=False)

                return True

            except modeignoreerrortypes:

                pass

        for baud in (0, 115200, 19200, 230400):

            if baud:

                if not self.comm.setbaudrate(baud):

                    continue

            print "Baud="+`baud`

            try:

                for line in self.comm.sendatcommand("+GMM"):

                    if line.find("SPH-A700")>0:

                        raise BrewNotSupported("This phone is not supported by BitPim", self.desc)

            except modeignoreerrortypes:

                self.log("No response to AT+GMM")

            except:

                print "GMM Exception"

                self.mode=self.MODENONE

                self.comm.shouldloop=True

                raise

            try:

                self.comm.write("AT$QCDMG\r\n")

            except:

                self.mode=self.MODENONE

                self.comm.shouldloop=True

                raise

            try:

                if self.comm.readsome().find("OK")>=0:

                    break

            except modeignoreerrortypes:

                self.log("No response to setting QCDMG mode")

        for baud in 0,38400,115200:

            if baud:

                if not self.comm.setbaudrate(baud):

                    continue

            try:

                self.sendbrewcommand(req, respc, callsetmode=False)

                return True

            except modeignoreerrortypes:

                pass

        return False

	def sendbrewcommand(self, request, responseclass, callsetmode=True):

        if callsetmode:

            self.setmode(self.MODEBREW)

        buffer=prototypes.buffer()

        request.writetobuffer(buffer)

        data=buffer.getvalue()

        self.logdata("brew request", data, request)

        data=common.pppescape(data+common.crcs(data))+common.pppterminator

        firsttwo=data[:2]

        try:

            data=self.comm.writethenreaduntil(data, False, common.pppterminator, logreaduntilsuccess=False) 

        except modeignoreerrortypes:

            self.mode=self.MODENONE

            self.raisecommsdnaexception("manipulating the filesystem")

        self.comm.success=True

        origdata=data

        d=data.rfind(common.pppterminator,0,-1)

        if d>=0:

            self.log("Multiple packets in data - taking last one starting at "+`d+1`)

            self.logdata("Original data", origdata, None)

            data=data[d+1:]

        data=common.pppunescape(data)

        d=data.find(firsttwo)

        if d>0:

            self.log("Junk at begining of packet, data at "+`d`)

            self.logdata("Original data", origdata, None)

            self.logdata("Working on data", data, None)

            data=data[d:]

        crc=data[-3:-1]

        data=data[:-3]

        calccrc=common.crcs(data)

        if calccrc!=crc:

            self.logdata("Original data", origdata, None)

            self.logdata("Working on data", data, None)

            raise common.CommsDataCorruption("Brew packet failed CRC check", self.desc)

        self.logdata("brew response", data, responseclass)

        if firsttwo=="Y\x0c" and data==firsttwo:

            raise common.CommsWrongPort("The port you are using is echoing data back, and is not valid for Brew data.  Most likely you have selected the modem interface when you should be using the diagnostic interface.", self.desc)

        if data[0]=="Y" and data[2]!="\x00":  

                err=ord(data[2])

                if err==0x1c:

                    raise BrewNoMoreEntriesException()

                if err==0x08:

                    raise BrewNoSuchDirectoryException()

                if err==0x06:

                    raise BrewNoSuchFileException()

                if err==0x1a:

                    raise BrewBadPathnameException()

                if err==0x0b:

                    raise BrewFileLockedException()

                if err==0x0d:

                    raise BrewNameTooLongException()

                if err==0x07:

                    raise BrewDirectoryExistsException()

                raise BrewCommandException(err)

        buffer=prototypes.buffer(data)

        res=responseclass()

        try:

            res.readfrombuffer(buffer)

        except:

            self.log(formatpacketerrorlog("Error decoding response", origdata, data, responseclass))

            raise

        return res

	"Talk to a phone using the 'brew' protocol"

class  RealBrewProtocol2 :
	"""Talk to a phone using the 'brew' protocol
    This class uses the new filesystem commands which are supported
    by newer qualcomm chipsets used in phones like the LG vx8100
    """
	    def exists(self, name):

        try:

            self.statfile(name)

        except BrewNoSuchFileException:

            return False

        return True

	def reconfig_directory(self):

        req=p_brew.new_reconfigfilesystemrequest()

        self.sendbrewcommand(req, p_brew.new_reconfigfilesystemresponse)

	def rmfile(self,name):

        self.log("Deleting file '"+name+"'")

        if self.exists(name):

            req=p_brew.new_rmfilerequest()

            req.filename=name

            self.sendbrewcommand(req, p_brew.new_rmfileresponse)

        file_cache.clear(name)

	def rmdir(self,name):

        self.log("Deleting directory '"+name+"'")

        if self.exists(name):

            req=p_brew.new_rmdirrequest()

            req.dirname=name

            self.sendbrewcommand(req, p_brew.new_rmdirresponse)

            self.reconfig_directory()

	def mkdir(self, name):

        self.log("Making directory '"+name+"'")

        if self.exists(name):

            raise BrewDirectoryExistsException

        req=p_brew.new_mkdirrequest()

        req.dirname=name

        self.sendbrewcommand(req, p_brew.new_mkdirresponse)

        self.reconfig_directory()

	def openfile(self, name, mode, flags=p_brew.new_fileopen_flag_existing):

        self.log("Open file '"+name+"'")

        req=p_brew.new_openfilerequest()

        req.filename=name

        req.mode=mode

        req.flags=flags

        res=self.sendbrewcommand(req, p_brew.new_openfileresponse)

        return res.handle

	def closefile(self, handle):

        self.log("Close file")

        req=p_brew.new_closefilerequest()

        req.handle=handle

        self.sendbrewcommand(req, p_brew.new_closefileresponse)

	def writefile(self, name, contents):

        start=time.time()

        self.log("Writing file '"+name+"' bytes "+`len(contents)`)

        desc="Writing "+name

        size=len(contents)       

        exists=self.exists(name)

        if exists:

            info=self.statfile(name)

            current_size=info['size']

        else:

            current_size=0

        if exists and size<current_size:

            self.rmfile(name)

            exists=False

        if exists:

            handle=self.openfile(name, p_brew.new_fileopen_mode_write, p_brew.new_fileopen_flag_existing)

        else:

            handle=self.openfile(name, p_brew.new_fileopen_mode_write, p_brew.new_fileopen_flag_create)

        if not handle:

            raise BrewNoSuchFileException

        try:

            remain=size

            pos=0

            count=0

            while remain:

                req=p_brew.new_writefilerequest()

                req.handle=handle

                if remain>243:

                    req.bytes=243

                else:

                    req.bytes=remain

                req.position=size-remain

                req.data=contents[req.position:(req.position+req.bytes)]

                count=(count&0xff)+1

                if count % 5==0:

                    self.progress(req.position,size,desc)

                res=self.sendbrewcommand(req, p_brew.new_writefileresponse)

                if res.bytes!=req.bytes:

                    self.raisecommsexception("Brew file write error", common.CommsDataCorruption)

                remain-=req.bytes

        except Exception, e: 

            self.closefile(handle)

            raise Exception, e 

        self.closefile(handle)

        self.progress(1,1,desc)

        end=time.time()

        if end-start>3:

            self.log("Wrote "+`len(contents)`+" bytes at "+`int(len(contents)/(end-start))`+" bytes/second")

	def getfilecontents(self, file, use_cache=False):

        node=self.statfile(file)

        if use_cache:

            if node and file_cache.hit(file, node['date'][0], node['size']):

                self.log('Reading from cache: '+file)

                _data=file_cache.data(file)

                if _data:

                    return _data

                self.log('Cache file corrupted and discarded')

        start=time.time()

        self.log("Getting file contents '"+file+"'")

        desc="Reading "+file

        data=cStringIO.StringIO()

        handle=self.openfile(file, p_brew.new_fileopen_mode_read)

        if not handle:

            raise BrewNoSuchFileException

        try:

            filesize=node['size']

            read=0

            counter=0

            while True:

                counter=(counter&0xff)+1

                if counter%5==0:

                    self.progress(data.tell(), filesize, desc)

                req=p_brew.new_readfilerequest()

                req.handle=handle

                req.bytes=0xEB

                req.position=read

                res=self.sendbrewcommand(req, p_brew.new_readfileresponse)

                if res.bytes:

                    data.write(res.data)

                    read+=res.bytes

                else:

                    break

                if read==filesize:

                    break

        except Exception, e: 

            self.closefile(handle)

            raise Exception, e 

        self.closefile(handle)

        self.progress(1,1,desc)

        data=data.getvalue()

        end=time.time()

        if end-start>3:

            self.log("Read "+`filesize`+" bytes at "+`int(filesize/(end-start))`+" bytes/second")

        if filesize!=len(data):

            self.log("expected size "+`filesize`+"  actual "+`len(data)`)

            self.raisecommsexception("Brew file read is incorrect size", common.CommsDataCorruption)

        if use_cache and node:

            file_cache.add(file, node.get('date', [0])[0], data)

        return data

	def listfiles(self, dir=''):

        self.log("Listing files in dir: '"+dir+"'")

        return self.getfilesystem(dir, recurse=0, directories=0)

	def getfilesystem(self, dir="", recurse=0, directories=1, files=1):

        results={}

        self.log("Listing dir '"+dir+"'")

        req=p_brew.new_opendirectoryrequest()

        if dir=="":

            req.dirname="/"

        else:

            req.dirname=dir

        res=self.sendbrewcommand(req, p_brew.new_opendirectoryresponse)

        handle=res.handle

        if handle==0: 

            raise BrewNoSuchDirectoryException

        dirs={}

        count=0

        try:

            for i in xrange(1, 10000):

                req=p_brew.new_listentryrequest()

                req.entrynumber=i

                req.handle=handle

                res=self.sendbrewcommand(req, p_brew.new_listentryresponse)

                if len(res.entryname) == 0: 

                    break

                if len(dir):

                    direntry=dir+"/"+res.entryname

                else:

                    direntry=res.entryname

                if files and res.type==0: 

                    results[direntry]={ 'name': direntry, 'type': 'file',
                                    'size': res.size }

                    if res.date==0:

                        results[direntry]['date']=(0, "")

                    else:

                        results[direntry]['date']=(res.date, time.strftime("%x %X", time.localtime(res.date)))

                elif directories and res.type: 

                    results[direntry]={ 'name': direntry, 'type': 'directory' }

                    if recurse>0:

                        dirs[count]=direntry

                        count+=1

        except Exception, e: 

            req=p_brew.new_closedirectoryrequest()

            req.handle=handle

            res=self.sendbrewcommand(req, p_brew.new_closedirectoryresponse)

            raise Exception, e

        req=p_brew.new_closedirectoryrequest()

        req.handle=handle

        res=self.sendbrewcommand(req, p_brew.new_closedirectoryresponse)

        for i in range(count):

            results.update(self.getfilesystem(dirs[i], recurse-1))

        return results

	def statfile(self, name):

        self.log('stat file '+name)

        req=p_brew.new_statfilerequest()

        req.filename=name

        res=self.sendbrewcommand(req, p_brew.new_statfileresponse)

        if res.flags==2:

            raise BrewNoSuchFileException

        if res.type==1:

            results={ 'name': name, 'type': 'file', 'size': res.size }

            if res.created_date==0:

                results['date']=(0, '')

            else:

                results['date']=(res.created_date, time.strftime("%x %X", time.localtime(res.created_date)))

        else:

            results={ 'name': name, 'type': 'directory' }

        return results

	"""Talk to a phone using the 'brew' protocol
    This class uses the new filesystem commands which are supported
    by newer qualcomm chipsets used in phones like the LG vx8100
    """

class  BrewProtocol (RealBrewProtocol) :
	"""This is just a wrapper class that allows the manipulation between
    RealBrewProtocol and DebugBrewProtocol classes.
    """
	    def __init__(self):

        phone_path=os.environ.get('PHONE_FS', None)

        if __debug__ and phone_path:

            print 'Debug Phone File System:',phone_path

            DebugBrewProtocol._fs_path=os.path.normpath(phone_path)

            self._update_base_class(self.__class__)

        elif __debug__ and getattr(self, "protocolclass", 0) and \
                getattr(self.protocolclass, "BREW_FILE_SYSTEM", 0) == 2:

            print '_set_new_brew', self.protocolclass

	def _update_base_class(self, klass):

        _bases=[]

        found=False

        for e in klass.__bases__:

            if e==RealBrewProtocol:

                _bases.append(DebugBrewProtocol)

                found=True

            else:

                _bases.append(e)

        if found:

            klass.__bases__=tuple(_bases)

        else:

            for e in _bases:

                self._update_base_class(e)

	def _set_new_brew(self, klass):

        _bases=[]

        found=False

        for e in klass.__bases__:

            if e==RealBrewProtocol:

                _bases.append(RealBrewProtocol2)

                found=True

            _bases.append(e)

        if found:

            klass.__bases__=tuple(_bases)

        else:

            for e in _bases:

                self._set_new_brew(e)

	"""This is just a wrapper class that allows the manipulation between
    RealBrewProtocol and DebugBrewProtocol classes.
    """

def formatpacketerrorlog(str, origdata, data, klass):

    hd=""

    if data is not None:

        hd="Data - "+`len(data)`+" bytes\n"

        if klass is not None:

            try:

                hd+="<#! %s.%s !#>\n" % (klass.__module__, klass.__name__)

            except:

                klass=klass.__class__

                hd+="<#! %s.%s !#>\n" % (klass.__module__, klass.__name__)

        hd+=common.datatohexstring(data)

    if origdata is not None:

        hd+="\nOriginal Data - "+`len(data)`+" bytes\n"+common.datatohexstring(origdata)

    return str+" "+hd

def brewbasename(str):

    "returns basename of str"

    if str.rfind("/")>0:

        return str[str.rfind("/")+1:]

    return str

def brewdirname(str):

    "returns dirname of str"

    if str.rfind("/")>0:

        return str[:str.rfind("/")]

    return str

class  SPURIOUSZERO (prototypes.BaseProtogenClass) :
	"""This is a special class used to consume the spurious zero in some p_brew.listfileresponse
    The three bytes are formatted as follows:
       - An optional 'null' byte (this class)
       - A byte specifying how long the directory name portion is, including trailing slash
       - A byte specifying the length of the whole name
       - The bytes of the filename (which includes the full directory name)
    Fun and games ensue because files in the root directory have a zero length directory
    name, so we have some heuristics to try and distinguish if the first byte is the
    spurious zero or not
    Also allow for zero length filenames.
    """
	    def __init__(self, *args, **kwargs):

        super(SPURIOUSZERO,self).__init__(*args, **kwargs)

        self._value=None

        if self._ismostderived(SPURIOUSZERO):

            self._update(args, kwargs)

	def _update(self, args, kwargs):

        super(SPURIOUSZERO, self)._update(args, kwargs)

        self._complainaboutunusedargs(SPURIOUSZERO, kwargs)

        if len(args):

            raise TypeError("Unexpected arguments "+`args`)

	def readfrombuffer(self, buf):

         self._bufferstartoffset=buf.getcurrentoffset()

         while True:  

             if buf.peeknextbyte()!=0:

                 self._value=-1

                 break

             if buf.peeknextbyte(1)==0:

                 if buf.howmuchmore()==2:

                     break

                 self._value=buf.getnextbyte() 

                 break

             all=buf.peeknextbytes(min(max(2+buf.peeknextbyte(1), 3+buf.peeknextbyte(2)), buf.howmuchmore()))

             ddirlen=ord(all[1])

             dfulllen=ord(all[2])

             if ddirlen<dfulllen and ddirlen<len(all)-3 and all[3+ddirlen-1]=='/':

                 self._value=buf.getnextbyte() 

                 break

             self._value=-2

             break

         self._bufferendoffset=buf.getcurrentoffset()

	def writetobuffer(self, buf):

        raise NotImplementedError()

	def packetsize(self):

         raise NotImplementedError()

	def getvalue(self):

        "Returns the string we are"

        if self._value is None:

            raise prototypes.ValueNotSetException()

        return self._value

	"""This is a special class used to consume the spurious zero in some p_brew.listfileresponse
    The three bytes are formatted as follows:
       - An optional 'null' byte (this class)
       - A byte specifying how long the directory name portion is, including trailing slash
       - A byte specifying the length of the whole name
       - The bytes of the filename (which includes the full directory name)
    Fun and games ensue because files in the root directory have a zero length directory
    name, so we have some heuristics to try and distinguish if the first byte is the
    spurious zero or not
    Also allow for zero length filenames.
    """
file_cache=None
class  EmptyFileCache (object) :
	def __init__(self, bitpim_path):

        self._path=None

        self._cache_file_name=None

        self._data={ 'file_index': 0 }

        self.esn=None

	def hit(self, file_name, datetime, data_len):

        return False

	def data(self, file_name):

        return None

	def add(self, file_name, datetime, data):

        pass

	def clear(self, file_name):

        pass

	def set_path(self, bitpim_path):

        try:

            print 'setting path to',`bitpim_path`

            if not bitpim_path:

                raise ValueError

            self.__class__=FileCache

            self._path=os.path.join(bitpim_path, 'cache')

            self._cache_file_name=os.path.join(self._path,
                                               self._cache_index_file_name)

            self._check_path()

            self._read_index()

            self._write_index()

        except:

            self.__class__=EmptyFileCache


class  FileCache (object) :
	_cache_index_file_name='index.idx'
	    current_version=1
	    def __init__(self, bitpim_path):

        self._path=os.path.join(bitpim_path, 'cache')

        self._cache_file_name=os.path.join(self._path,
                                           self._cache_index_file_name)

        self._data={ 'file_index': 0 }

        self.esn=None

        try:

            if not bitpim_path:

                raise ValueError

            self._check_path()

            self._read_index()

            self._write_index()

        except:

            self.__class__=EmptyFileCache

	def _check_path(self):

        try:

            os.makedirs(self._path)

        except:

            pass

        if not os.path.isdir(self._path):

            raise Exception("Bad cache directory: '"+self._path+"'")

	def _read_index(self):

        self._check_path()

        d={ 'result': {} }

        try:

            common.readversionedindexfile(self._cache_file_name, d, None,
                                          self.current_version)

            self._data.update(d['result'])

        except:

            print 'failed to read cache index file'

	def _write_index(self):

        self._check_path()

        common.writeversionindexfile(self._cache_file_name, self._data,
                                     self.current_version)

	def _entry(self, file_name):

        k=self._data.get(self.esn, None)

        if k:

            return k.get(file_name, None)

	def hit(self, file_name, datetime, data_len):

        try:

            e=self._entry(file_name)

            if e:

                return e['datetime'] and e['datetime']==datetime and \
                       e['size']==data_len

            return False

        except:

            if __debug__:

                raise

            return False

	def data(self, file_name):

        try:

            e=self._entry(file_name)

            if e:

                _data=file(os.path.join(self._path, e['cache']), 'rb').read()

                if len(_data)==e['size']:

                    return _data

        except IOError:

            return None

        except:

            if __debug__:

                raise

            return None

	def add(self, file_name, datetime, data):

        try:

            if self.esn:

                e=self._entry(file_name)

                if not e:

                    self._data.setdefault(self.esn, {})[file_name]={}

                    e=self._data[self.esn][file_name]

                    e['cache']='F%05d'%self._data['file_index']

                    self._data['file_index']+=1

                e['datetime']=datetime

                e['size']=len(data)

                _cache_file_name=os.path.join(self._path, e['cache'])

                try:

                    file(_cache_file_name, 'wb').write(data)

                    self._write_index()

                except IOError:

                    self._read_index()

        except:

            if __debug__:

                raise

	def clear(self, file_name):

        try:

            e=self._entry(file_name)

            if e:

                try:

                    os.remove(os.path.join(self._path, e['cache']))

                except:

                    pass

                del self._data[self.esn][file_name]

                self._write_index()

        except:

            if __debug__:

                raise

	def set_path(self, bitpim_path):

        try:

            print 'setting path to',`bitpim_path`

            if not bitpim_path:

                raise ValueError

            self.__class__=FileCache

            self._path=os.path.join(bitpim_path, 'cache')

            self._cache_file_name=os.path.join(self._path,
                                               self._cache_index_file_name)

            self._check_path()

            self._read_index()

            self._write_index()

        except:

            raise

            self.__class__=EmptyFileCache
	def _setmodemodem(self):

        self.log("_setmodemodem")

        req=p_brew.memoryconfigrequest()

        respc=p_brew.memoryconfigresponse

        try:

            self.comm.sendatcommand("Z")

            self.comm.sendatcommand('E0V1')

            return True

        except:

            pass

        for baud in 0, 38400,115200:

            if baud:

                if not self.comm.setbaudrate(baud):

                    continue

            try:

                self.sendbrewcommand(req, respc, callsetmode=False)

                self.log('In BREW mode, trying to switch to Modem mode')

                if self._setmodebrewtomodem():

                    break

                return False

            except com_brew.modeignoreerrortypes:

                pass

        for baud in (0, 115200, 19200, 230400):

            self.log("Baud="+`baud`)

            if baud:

                if not self.comm.setbaudrate(baud):

                    continue

            try:

                self.comm.sendatcommand("Z")

                self.comm.sendatcommand('E0V1')

                return True

            except:

                pass

        return False

	def _setmodephonebook(self):

        self.log("_setmodephonebook")

        self.setmode(self.MODEMODEM)

        self.setmode(self.MODEPHONEBOOK)

        return True

	def _setmodephonebooktomodem(self):

        self.log("_setmodephonebooktomodem")

        self.log('Switching from phonebook to modem')

        response=self.comm.sendatcommand("#PMODE=0")

        return True

	def sendpbcommand(self, request, responseclass, ignoreerror=False, fixup=None):

        """Similar to the sendpbcommand in com_sanyo and com_lg, except that
        a list of responses is returned, one per line of information returned
        from the phone"""

        buffer=prototypes.buffer()

        request.writetobuffer(buffer)

        data=buffer.getvalue()

        self.logdata("Samsung phonebook request", data, request)

        try:

            response_lines=self.comm.sendatcommand(data, ignoreerror=ignoreerror)

        except commport.ATError:

            self.comm.success=False

            self.mode=self.MODENONE

            self.raisecommsdnaexception("manipulating the phonebook")

        self.comm.success=True

        reslist=[]

        for line in response_lines:

            if fixup:

                line=fixup(line)

            self.logdata("Samsung phonebook response", line, responseclass)

            res=responseclass()

            buffer=prototypes.buffer(line)

            res.readfrombuffer(buffer)

            reslist.append(res)

        return reslist

	def get_esn(self):

        req=self.protocolclass.esnrequest()

        res=self.sendpbcommand(req, self.protocolclass.esnresponse)

        try:

            print res[0].esn

            return res[0].esn

        except:

            pass

        return ''

	def read_groups(self):

        g={}

        try:

            self.setmode(self.MODEPHONEBOOK)

        except:

            return g

        req=self.protocolclass.groupnamerequest()

	for i in range(self.protocolclass.NUMGROUPS+1):

            req.gid=i

            try:

                res=self.sendpbcommand(req, self.protocolclass.groupnameresponse)

            except:

                return g

            g[i]={'name': res[0].entry.groupname}

	return g

	def savegroups(self, data):

        """Write the groups, sending only those groups that have had
        a name change.  (So that ringers don't get messed up)"""

        groups=data['groups']

        groups_onphone=self.read_groups() 

        if not groups_onphone:

            return

        keys=groups.keys()

        keys.sort()

        for k in keys:

            if groups[k]['name']!=groups_onphone[k]['name']:

                if groups[k]['name']!="Unassigned":

                    req=self.protocolclass.groupnamesetrequest()

                    req.gid=k

                    req.groupname=groups[k]['name']

                    self.sendpbcommand(req, self.protocolclass.unparsedresponse, ignoreerror=True)

	def pblinerepair(self, line):

        "Repair a line from a phone with broken firmware"

        return line

	def getphonebook(self, result):

        """Read the phonebook data."""

        pbook={}

        self.setmode(self.MODEPHONEBOOK)

        count=0

        req=self.protocolclass.phonebookslotrequest()

        lastname=""

        for slot in range(1,self.protocolclass.NUMPHONEBOOKENTRIES+1):

            req.slot=slot

            res=self.sendpbcommand(req, self.protocolclass.phonebookslotresponse, fixup=self.pblinerepair)

            if len(res) > 0:

                lastname=res[0].entry.name

                self.log(`slot`+": "+lastname)

                entry=self.extractphonebookentry(res[0].entry, result)

                pbook[count]=entry

                count+=1

            self.progress(slot, self.protocolclass.NUMPHONEBOOKENTRIES, lastname)

        result['phonebook']=pbook

        cats=[]

        for i in result['groups']:

            if result['groups'][i]['name']!='Unassigned':

                cats.append(result['groups'][i]['name'])

        result['categories']=cats

        print "returning keys",result.keys()

        return pbook

	def extractphonebookentry(self, entry, fundamentals):

        res={}

        res['serials']=[ {'sourcetype': self.serialsname,
                          'slot': entry.slot,
                          'sourceuniqueid': fundamentals['uniqueserial']} ]

        res['names']=[ {'full': entry.name} ]

        cat=fundamentals['groups'].get(entry.group, {'name': "Unassigned"})['name']

        if cat!="Unassigned":

            res['categories']=[ {'category': cat} ]

        if len(entry.email):

            res['emails']=[ {'email': entry.email} ]

        if len(entry.url):

            res['urls']=[ {'url': entry.url} ]

        res['numbers']=[]

        secret=0

        speeddialtype=entry.speeddial

        numberindex=0

        for type in self.numbertypetab:

            if len(entry.numbers[numberindex].number):

                numhash={'number': entry.numbers[numberindex].number, 'type': type }

                if entry.numbers[numberindex].secret==1:

                    secret=1

                if speeddialtype==numberindex:

                    numhash['speeddial']=entry.uslot

                res['numbers'].append(numhash)

            numberindex+=1

        res['flags']=[ {'secret': secret} ]

        if entry.ringtone != self.protocolclass.DEFAULT_RINGTONE:

            tone=self.serialsname+"Index_"+`entry.ringtone`

            res['ringtones']=[{'ringtone': tone, 'use': 'call'}]

        try:

            if entry.wallpaper != self.protocolclass.DEFAULT_WALLPAPER:

                tone=self.serialsname+"Index_"+`entry.wallpaper`

                res['wallpapers']=[{'wallpaper': tone, 'use': 'call'}]

        except:

            pass

        return res

	def savephonebook(self, data):

        "Saves out the phonebook"

        pb=data['phonebook']

        keys=pb.keys()

        keys.sort()

        keys=keys[:self.protocolclass.NUMPHONEBOOKENTRIES]

        uslots={}

        names={}

        birthdays={}

        req=self.protocolclass.phonebookslotrequest()

        self.log('Erasing '+self.desc+' phonebook')

        progressmax=self.protocolclass.NUMPHONEBOOKENTRIES+len(keys)

        for slot in range(1,self.protocolclass.NUMPHONEBOOKENTRIES+1):

            req.slot=slot

            self.progress(slot,progressmax,"Erasing  "+`slot`)

            try:

                res=self.sendpbcommand(req,self.protocolclass.phonebookslotresponse, fixup=self.pblinerepair)

                if len(res) > 0:

                    names[slot]=res[0].entry.name

                    birthdays[slot]=res[0].entry.birthday

                    if len(res[0].entry.url)>0:

                        reqhack=self.protocolclass.phonebookslotupdaterequest()

                        reqhack.entry=res[0].entry

                        reqhack.entry.url=""

                        reqhack.entry.ringtone=self.protocolclass.DEFAULT_RINGTONE

                        reqhack.entry.wallpaper=self.protocolclass.DEFAULT_WALLPAPER

                        reqhack.entry.timestamp=[1900,1,1,0,0,0]

                        self.sendpbcommand(reqhack, self.protocolclass.phonebookslotupdateresponse)

                else:

                    names[slot]=""

            except:

                names[slot]=""

                self.log("Slot "+`slot`+" read failed")

            reqerase=self.protocolclass.phonebooksloterase()

            reqerase.slot=slot

            self.sendpbcommand(reqerase, self.protocolclass.phonebookslotupdateresponse)

        self.savegroups(data)

        for i in range(len(keys)):

            slot=keys[i]

            req=self.protocolclass.phonebookslotupdaterequest()

            req.entry=self.makeentry(pb[slot],data)

            req.entry.ringtone=self.protocolclass.DEFAULT_RINGTONE

            req.entry.wallpaper=self.protocolclass.DEFAULT_WALLPAPER

            if names[slot]==req.entry.name:

                req.entry.birthday=birthdays[slot]

            self.log('Writing entry '+`slot`+" - "+req.entry.name)

            self.progress(i+self.protocolclass.NUMPHONEBOOKENTRIES,progressmax,"Writing "+req.entry.name)

            self.sendpbcommand(req, self.protocolclass.phonebookslotupdateresponse)

        self.progress(progressmax+1,progressmax+1, "Phone book write completed")

        return data

	def makeentry(self, entry, data):

        e=self.protocolclass.pbentry()

        for k in entry:

            if k=='numbertypes' or k=='secrets':

                continue

            if k=='ringtone':

                continue

            elif k=='wallpaper':

                continue

            elif k=='numbers':

                for numberindex in range(self.protocolclass.NUMPHONENUMBERS):

                    enpn=self.protocolclass.phonenumber()

                    e.numbers.append(enpn)

                for i in range(len(entry[k])):

                    numberindex=entry['numbertypes'][i]

                    e.numbers[numberindex].number=entry[k][i]

                    e.numbers[numberindex].secret=entry['secrets'][i]

                continue

            setattr(e, k, entry[k])

        return e

	def getcalendar(self, result):

        entries = {}

        self.log("Getting calendar entries")

        self.setmode(self.MODEPHONEBOOK)

        req=self.protocolclass.eventrequest()

        cal_cnt=0

        for slot in range(self.protocolclass.NUMCALENDAREVENTS):

            req.slot=slot

            res=self.sendpbcommand(req,self.protocolclass.eventresponse)

            if len(res) > 0:

                self.progress(slot+1, self.protocolclass.NUMCALENDAREVENTS,
                              res[0].eventname)

                entry=bpcalendar.CalendarEntry()

                entry.start=res[0].start[0:5]

                if res[0].end:

                    entry.end=res[0].end[0:5]

                else:

                    entry.end=entry.start

                entry.description=res[0].eventname

                try:

                    alarm=self.__cal_alarm_values[res[0].alarm]

                except:

                    alarm=None

                entry.alarm=alarm

                entries[entry.id]=entry

                cal_cnt += 1

        result['calendar']=entries

        self.setmode(self.MODEMODEM)

        return result

	def _set_unused_calendar_fields(self, entry):

            entry['repeat']=None

            entry['changeserial']=1

            entry['snoozedelay']=0

            entry['daybitmap']=0

            entry['ringtone']=0

	def process_calendar(self, dict):

        """ Optimize and expand calendar data suitable for phone download
        """

        r={}

        rp=[]

        today=datetime.date.today()

        last_date=today

        if __debug__:

            print 'original calendar:'

        for k,e in dict.items():

            if __debug__:

                print e.description,':',e.start

            sd=datetime.date(*e.start[:3])

            ed=datetime.date(*e.end[:3])

            if ed>last_date:

                last_date=ed

            if e.repeat is None:

                if sd>=today:

                    r.setdefault(e.start[:3], []).append(Samsung_Calendar(e))

            else:

                if ed>=today:

                    rp.append(e)

        delta_1=datetime.timedelta(1)

        for n in rp:

            current_date=today

            end_date=datetime.date(*n.end[:3])

            cnt=0

            while current_date<=end_date:

                if n.is_active(current_date.year, current_date.month,
                               current_date.day):

                    cd_l=(current_date.year, current_date.month,
                          current_date.day)

                    r.setdefault(cd_l, []).append(\
                                      Samsung_Calendar(n, cd_l))

                    cnt+=1

                    if cnt>self.protocolclass.NUMCALENDAREVENTS:

                        break

                current_date+=delta_1

        res=[]

        keys=r.keys()

        keys.sort()

        for k in keys:

            r[k].sort()

            if len(r[k])>self._cal_max_events_per_day:

                res+=r[k][:self._cal_max_events_per_day]

            else:

                res+=r[k]

        if len(res)>self.protocolclass.NUMCALENDAREVENTS:

            res=res[:self.protocolclass.NUMCALENDAREVENTS]

        return res

	def savecalendar(self, dict, merge):

        self.log("Sending calendar entries")

        cal=self.process_calendar(dict['calendar'])

        if __debug__:

            print 'processed calendar: ', len(cal), ' items'

            for c in cal:

                print c.description,':', c.start

        self.setmode(self.MODEPHONEBOOK)

        self.log("Saving calendar entries")

        cal_cnt=0

        req=self.protocolclass.eventupdaterequest()

        l = self.protocolclass.NUMCALENDAREVENTS

        for c in cal:

            req.slot=cal_cnt

            req.start=list(c.start)+[0]

            if self.__cal_end_datetime_value is None:

                req.end=list(c.end)+[0]

            else:

                req.end=req.start

            req.timestamp=list(time.localtime(time.time())[0:6])

            req.alarm=c.alarm

            name=c.description

            if len(name)>self.__cal_max_name_len:

                name=name[:self.__cal_max_name_len]

            req.eventname=name

            self.progress(cal_cnt+1, l, "Updating "+name)

            self.sendpbcommand(req,self.protocolclass.eventupdateresponse)

            cal_cnt += 1

        self.log('Deleting unused entries')

        for k in range(cal_cnt, l):

            self.progress(k, l, "Deleting entry %d" % k)

            reqerase=self.protocolclass.eventsloterase()

            reqerase.slot=k

            self.sendpbcommand(reqerase, self.protocolclass.eventupdateresponse)

        self.setmode(self.MODEMODEM)

        return dict

	def gettodo(self, result):

        todos = {}

        self.log("Getting todo entries")

        self.setmode(self.MODEPHONEBOOK)

        req=self.protocolclass.todorequest()

        for slot in range(self.protocolclass.NUMTODOENTRIES):

            req.slot=slot

            res=self.sendpbcommand(req,self.protocolclass.todoresponse)

            if len(res) > 0:

                entry = todo.TodoEntry()

                entry.summary=res[0].subject

                entry.due_date='%4.4d%2.2d%2.2d'%(res[0].duedate[0],res[0].duedate[1],res[0].duedate[2])

                if res[0].priority:

                    entry.priority=1

                else:

                    entry.priority=10

                self.log("Todo "+`slot`+" "+entry.summary+" "+entry.due_date)

                todos[entry.id]=entry

        result['todo']=todos

        return result

	def savetodo(self, dict, merge):

        self.setmode(self.MODEPHONEBOOK)

        todos=dict.get('todo', {})

        todos_len=len(todos)

        l=self.protocolclass.NUMTODOENTRIES

        if todos_len > l:

            self.log("The number of Todo entries (%d) exceeded the mamximum (%d)" % (cal_len, l))

        self.setmode(self.MODEPHONEBOOK)

        self.log("Saving todo entries")

        todo_cnt=0

        req=self.protocolclass.todoupdaterequest()

        for k in todos:

            todo=todos[k]

            print todo.__doc__

            if todo_cnt >= l:

                break

            req.slot=todo_cnt

            if todo.priority is not None and todo.priority<5:

                req.priority=0

            else:

                req.priority=1

            dd=todo.due_date

            req.duedate=(int(dd[0:3]),int(dd[4:5]),int(dd[6:7]),0,0,0)

            req.timestamp=list(time.localtime(time.time())[0:6])

            req.subject=todo.summary

            self.sendpbcommand(req,self.protocolclass.todoupdateresponse)

            todo_cnt += 1

        req=self.protocolclass.todoerase()

        for slot in range(todo_cnt, self.protocolclass.NUMTODOENTRIES):

            req.slot=slot

            self.sendpbcommand(req,self.protocolclass.todoupdateresponse)

	def getmemo(self, result):

        memos = {}

        self.log("Getting memo entries")

        self.setmode(self.MODEPHONEBOOK)

        req=self.protocolclass.memorequest()

        for slot in range(self.protocolclass.NUMMEMOENTRIES):

            req.slot=slot

            res=self.sendpbcommand(req,self.protocolclass.memoresponse)

            if len(res) > 0:

                entry=memo.MemoEntry()

                entry.text=res[0].text

                entry.set_date_isostr='%4.4d%2.2d%2.2dT%2.2d%2.2d%2.2d'%(res[0].timestamp[0],res[0].timestamp[1],res[0].timestamp[2],res[0].timestamp[3],res[0].timestamp[4],res[0].timestamp[5])

                memos[entry.id]=entry

        result['memo']=memos

        return result

	def savememo(self, dict, merge):

        self.setmode(self.MODEPHONEBOOK)

        memos=dict.get('memo', {})

        memos_len=len(memos)

        l=self.protocolclass.NUMMEMOENTRIES

        if memos_len > l:

            self.log("The number of Memo entries (%d) exceeded the mamximum (%d)" % (cal_len, l))

        self.setmode(self.MODEPHONEBOOK)

        self.log("Saving memo entries")

        memo_cnt=0

        req=self.protocolclass.memoupdaterequest()

        for k in memos:

            memo=memos[k]

            if memo_cnt >= l:

                break

            dd=memo.set_date_isostr

            req.timestamp=list(time.localtime(time.time())[0:6])

            req.text=memo.text

            self.sendpbcommand(req,self.protocolclass.memoupdateresponse)

            memo_cnt += 1

        req=self.protocolclass.memoerase()

        for slot in range(memo_cnt, self.protocolclass.NUMMEMOENTRIES):

            req.slot=slot

            self.sendpbcommand(req,self.protocolclass.memoupdateresponse)

	getcallhistory=None
	"Talk to a Samsung phone using AT commands"

class  Profile (com_phone.Profile) :
	BP_Calendar_Version=3
	    usbids=( ( 0x04e8, 0x6601, 1),  
        )
	    deviceclasses=("modem","serial")
	    WALLPAPER_WIDTH=128
	    WALLPAPER_HEIGHT=118
	    OVERSIZE_PERCENTAGE=100
	    MAX_WALLPAPER_BASENAME_LENGTH=19
	    WALLPAPER_FILENAME_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .`~!@#$%^&()-_=+[{]};\'"
	    WALLPAPER_CONVERT_FORMAT="png"
	    MAX_RINGTONE_BASENAME_LENGTH=19
	    RINGTONE_FILENAME_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .`~!@#$%^&()-_=+[{]};\'"
	    _supportedsyncs=()
	    def __init__(self):

        com_phone.Profile.__init__(self)

	def _getgroup(self, name, groups):

        for key in groups:

            if groups[key]['name']==name:

                return key,groups[key]

        return None,None

	def normalisegroups(self, helper, data):

        "Assigns groups based on category data"

        pad=[]

        keys=data['groups'].keys()

        keys.sort()

        for k in keys:

            if k==self.protocolclass.NUMGROUPS: 

                name=data['groups'][k]['name']

                pad.append(name)

        groups=helper.getmostpopularcategories(self.protocolclass.NUMGROUPS, data['phonebook'], ["Unassigned"], 12, pad)

        groups.sort()

        newgroups={}

        newgroups[self.protocolclass.NUMGROUPS]={'name': 'Unassigned'}

        for name in groups:

            if name=="Unassigned": continue

            key,value=self._getgroup(name, data['groups'])

            if key is not None:

                newgroups[key]=value

        for name in groups:

            key,value=self._getgroup(name, newgroups)

            if key is None:

                for key in range(self.protocolclass.NUMGROUPS):

                    if key not in newgroups:

                        newgroups[key]={'name': name, 'icon': 1}

                        break

        if data['groups']!=newgroups:

            data['groups']=newgroups

	def convertphonebooktophone(self, helper, data):

        """Converts the data to what will be used by the phone
        @param data: contains the dict returned by getfundamentals
                     as well as where the results go"""

        self.normalisegroups(helper, data)

        results={}

        pb=data['phonebook']

        slots=[ (helper.getserial(pb[pbentry].get("serials", []), self.serialsname, data['uniqueserial'], "slot", None), pbentry)
                for pbentry in pb]

        slots.sort() 

        newones=[(pbentry,slot) for slot,pbentry in slots if slot is None]

        existing=[(pbentry,slot) for slot,pbentry in slots if slot is not None]

        uslotsused={}

        tempslot=0 

        for pbentry,slot in existing+newones:

            if len(results)==self.protocolclass.NUMPHONEBOOKENTRIES:

                break

            try:

                e={} 

                entry=data['phonebook'][pbentry]

                secret=helper.getflag(entry.get('flags', []), 'secret', False)

                if secret:

                    secret=1

                else:

                    secret=0

                e['name']=helper.getfullname(entry.get('names', []),1,1,20)[0]

                cat=helper.makeone(helper.getcategory(entry.get('categories',[]),0,1,12), None)

                if cat is None:

                    e['group']=self.protocolclass.NUMGROUPS 

                else:

                    key,value=self._getgroup(cat, data['groups'])

                    if key is not None:

                        e['group']=key

                    else:

                        e['group']=self.protocolclass.NUMGROUPS 

                e['email']=helper.makeone(helper.getemails(entry.get('emails', []), 0,1,32), "")

                e['url']=helper.makeone(helper.geturls(entry.get('urls', []), 0,1,32), "")

                minnumbers=1

                numbers=helper.getnumbers(entry.get('numbers', []),minnumbers,self.protocolclass.NUMPHONENUMBERS)

                e['numbertypes']=[]

                e['numbers']=[]

                e['secrets']=[]

                unusednumbers=[] 

                typesused={}

                defaulttypenum=0

                for num in numbers:

                    typename=num['type']

                    if typesused.has_key(typename):

                        unusednumbers.append(num)

                        continue

                    typesused[typename]=1

                    for typenum,tnsearch in enumerate(self.numbertypetab):

                        if typename==tnsearch:

                            if defaulttypenum==0:

                                defaulttypenum=typenum

                            number=self.phonize(num['number'])

                            if len(number)>self.protocolclass.MAXNUMBERLEN:

                                number=number[:self.protocolclass.MAXNUMBERLEN]

                            e['numbers'].append(number)

                            if(num.has_key('speeddial')):

                                e['speeddial']=typenum

                                tryuslot = num['speeddial']

                            e['numbertypes'].append(typenum)

                            e['secrets'].append(secret)

                            break

                if e.has_key('speeddial'):

                    if tryuslot>=1 and tryuslot<=self.protocolclass.NUMPHONEBOOKENTRIES and not uslotsused.has_key(tryuslot):

                        uslotsused[tryuslot]=1

                        e['uslot']=tryuslot

                else:

                    e['speeddial']=defaulttypenum

                e['ringtone']=helper.getringtone(entry.get('ringtones', []), 'call', None)

                e['wallpaper']=helper.getwallpaper(entry.get('wallpapers', []), 'call', None)

                if slot is None or slot<1 or slot>self.protocolclass.NUMPHONEBOOKENTRIES or slot in results:

                    for i in range(1,100000):

                        if i not in results:

                            slot=i

                            break

                e['slot']=slot

                e['timestamp']=list(time.localtime(time.time())[0:6])

                results[slot]=e

            except helper.ConversionFailed:

                continue

        tryuslot=1

        for slot in results.keys():

            e=results[slot]

            if not e.has_key('uslot'):

                while tryuslot<self.protocolclass.NUMPHONEBOOKENTRIES and uslotsused.has_key(tryuslot):

                    tryuslot += 1

                uslotsused[tryuslot]=1

                e['uslot'] = tryuslot

                results[slot] = e

        data['phonebook']=results

        return data

	def phonize(self,str):

        """Convert the phone number into something the phone understands
        All digits, P, T, * and # are kept, everything else is removed"""

        return re.sub("[^0-9PT#*]", "", str)[:self.protocolclass.MAXNUMBERLEN]


class  Samsung_Calendar :
	_cal_alarm_values={
        10: 0, 30: 1, 60: 2, -1: 3, 0: 4 }
	    def __init__(self, calendar_entry, new_date=None):

        self._start=self._end=self._alarm=self._desc=None

        self._extract_cal_info(calendar_entry, new_date)

	def _extract_cal_info(self, cal_entry, new_date):

        s=cal_entry.start

        if new_date is not None:

            s=new_date[:3]+s[3:]

        self._start=s

        self._end=cal_entry.end

        self._desc=cal_entry.description

        self._alarm=0

        alarm=cal_entry.alarm

        _keys=self._cal_alarm_values.keys()

        _keys.sort()

        _keys.reverse()

        for k in _keys:

            if alarm>=k:

                self._alarm=self._cal_alarm_values[k]

                break

	def __lt__(self, rhs):

        return self.start<rhs.start

	def __le__(self, rhs):

        return self.start<=rhs.start

	def __eq__(self, rhs):

        return self.start==rhs.start

	def __ne__(self, rhs):

        return self.start!=rhs.start

	def __gt__(self, rhs):

        return self.start>rhs.start

	def __ge__(self, rhs):

        return self.start>=rhs.start

	def _get_start(self):

        return self._start

	start=property(fget=_get_start)
	    def _get_end(self):

        return self._end

	end=property(fget=_get_end)
	    def _get_desc(self):

        return self._desc

	description=property(fget=_get_desc)
	    def _get_alarm(self):

        return self._alarm

	alarm=property(fget=_get_alarm)