Re: Phone Detection Scheme

"Roger Binns" <[email protected]>
Newsgroups gmane.comp.mobile.bitpim.devel
Message-ID <00bd01c53a65$678e8af0$3501a8c0@rogersqyvr14d3>
> Based on Roger's suggestion, I'm looking for a good way of auto 
> detecting phones.  To do this properly and reliably, I think that each 
> phone model would have to implement its own detection routine.  

I would suggest a different approach.

Gather information from the system such as what USB devices and
com ports are connected, and send various Brew and AT command
sequences to the ports (do the latter part in parallel so it doesn't
take all day).

Each phone module should then be able to rule itself out completely
or be able to make a better determination based on the ports it
sees available as well as AT command/Brew command responses.

Since you like a challenge, here is some code for you to integrate
as well that will auto-detect new ports being plugged in or removed. 
I have excerpted from the code I use to hibernate my machine when it
has finished writing a DVD (the dvd software ejects the disc and
that shows up as a device removal).

First of all you need to change the window procedure for a window.
I'd suggest the main one.

        # save the old window proc
        self.oldwndproc = win32gui.SetWindowLong(self.GetHandle(),
                                                 win32con.GWL_WNDPROC,
                                                 self.MyWndProc)

Then define a new window procedure.

    def MyWndProc(self, hwnd, msg, wparam, lparam):

        if msg==win32con.WM_DEVICECHANGE:
            type,params=DeviceChanged(wparam, lparam).GetEventInfo()
            self.OnDeviceChanged(type, **params)
            return True
        
        # Restore the old WndProc.  Notice the use of win32api
        # instead of win32gui here.  This is to avoid an error due to
        # not passing a callable object.
        if msg == win32con.WM_DESTROY:
            win32api.SetWindowLong(self.GetHandle(),
                                   win32con.GWL_WNDPROC,
                                   self.oldwndproc)

        # Pass all messages (in this case, yours may be different) on
        # to the original WndProc
        return win32gui.CallWindowProc(self.oldwndproc,
                                       hwnd, msg, wparam, lparam)

Make a self.OnDeviceChanged function that will be called with the relevant
information.

   def OnDeviceChanged(self, type, name="", drives=[], flag=None):
        self.Log("%s: name %s, drives %s, flag %s\n" % (type, name,`drives`,flag))

This is the code that decodes the device change parameters into something
useful.

class DeviceChanged:

    DBT_DEVICEARRIVAL = 0x8000
    DBT_DEVICEQUERYREMOVE = 0x8001
    DBT_DEVICEQUERYREMOVEFAILED = 0x8002
    DBT_DEVICEREMOVEPENDING =  0x8003
    DBT_DEVICEREMOVECOMPLETE = 0x8004
    DBT_DEVICETYPESPECIFIC = 0x8005    
    DBT_DEVNODES_CHANGED = 7
    DBT_CONFIGCHANGED = 0x18

    DBT_DEVTYP_OEM = 0
    DBT_DEVTYP_DEVNODE = 1
    DBT_DEVTYP_VOLUME = 2
    DBT_DEVTYP_PORT = 3
    DBT_DEVTYP_NET = 4

    DBTF_MEDIA   =   0x0001
    DBTF_NET    =    0x0002

    def __init__(self, wparam, lparam):
        self._info=None
        for name in dir(self):
            if name.startswith("DBT") and not name.startswith("DBT_DEVTYP") and getattr(self,name)==wparam:
                self._info=(name, dict(self._decode_struct(lparam)))

    def GetEventInfo(self):
        return self._info
        
    def _decode_struct(self, lparam):
        if lparam==0: return ()
        format = "iii"
        buf = win32gui.PyMakeBuffer(struct.calcsize(format), lparam)
        dbch_size, dbch_devicetype, dbch_reserved = struct.unpack(format, buf)

        buf = win32gui.PyMakeBuffer(dbch_size, lparam) # we know true size now

        if dbch_devicetype==self.DBT_DEVTYP_PORT:
            name=""
            for b in buf[struct.calcsize(format):]:
                if b!="\x00":
                    name+=b
                    continue
                break
            return ("name", name),

        if dbch_devicetype==self.DBT_DEVTYP_VOLUME:
            # yes, the last item is a WORD, not a DWORD like the hungarian would lead you to think
            format="iiiih0i"
            dbcv_size, dbcv_devicetype, dbcv_reserved, dbcv_unitmask, dbcv_flags = struct.unpack(format, buf)
            units=[chr(ord('A')+x) for x in range(26) if dbcv_unitmask&(2**x)]
            flag=""
            for name in dir(self):
                if name.startswith("DBTF_") and getattr(self, name)==dbcv_flags:
                    flag=name
                    break

            return ("drives", units), ("flag", flag)

        print "unhandled devicetype struct", dbch_devicetype
        return ()

Roger


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.