def f():
            if self.positioner:
                self.positioner.close()
                self.positioner = None
            try:
                from pytwink import Positioner

                modlist = positioning.modules()
                module_id = None
                for entry in modlist:
                    if entry["name"] == u"Network based" and \
                       entry["available"]:
                        module_id = entry["id"]
                        break
                if not module_id:
                    raise "no network positioning module"

                updatetimeout = 15000000
                maxupdateage =  30000000
                self.positioner = Positioner(module_id, updatetimeout, maxupdateage)
                self.positioner.ask_position(self._positioner_done)
                return
            except:
                self._send_card()

            self.active = True
module_id = None
for entry in modlist:
    if entry["name"] == u"Network based" and \
       entry["available"]:
        module_id = entry["id"]
        break

if not module_id:
    print "no suitable module"
else:
    from pytwink import Positioner

    updatetimeout = 15000000
    maxupdateage =  30000000
    positioner = Positioner(module_id, updatetimeout, maxupdateage)

    myLock = e32.Ao_lock()

    def cb(errCode):
        print repr(errCode)
        if not errCode:
            print repr(positioner.get_position())
        myLock.signal()

    try:
        print "asking position"
        positioner.ask_position(cb)
        positioner.cancel()
        positioner.ask_position(cb)
        myLock.wait()
class ScannerSender:
    """
    The task of an object of this type is to add context data and send
    it, reporting on success or failure with a callback.
    """
    def __init__(self, config):
        """
        apid: Initial access point ID to use.
        """
        self.config = config
        self.gsm_scanner = GsmScanner()
        self.btprox_scanner = None
        self.positioner = None
        self.uploader = Uploader(config)
        self.immediate = AoImmediate()
        self.immediate.open()
        self.btprox_scan_error_shown = False
        self.active = False

    def cancel(self):
        """
        Cancels any operation(s) in progress, whether finished or not.
        """
        self.immediate.cancel()
        self.gsm_scanner.cancel()
        if self.btprox_scanner:
            self.btprox_scanner.cancel()
        if self.positioner:
            self.positioner.cancel()
        self.uploader.cancel()
        self.active = False

    def close(self):
        """
        Does cleanup.
        """
        self.immediate.close()
        self.gsm_scanner.close()
        if self.btprox_scanner:
            self.btprox_scanner.close()
        if self.positioner:
            self.positioner.close()
        self.uploader.close()

    def scan_and_send(self, card, cb):
        """
        The caller of this method should check the "active" flag to
        ensure that no send is already in progress.
        
        card:: Card to which to add context data and to send.
        cb:: Status reporting callback.
        """
        if self.active: raise "assertion failure"

        self.card = card
        self.cb = cb

        self._clear_context()
        if self.config.get_noscan():
            self._send_card()
        else:
            self._scan_gsm()

    def _clear_context(self):
        """
        Note that it is important to set values to None when scanning
        fails so that we never end up sending a card with an old
        value.
        """
        self.card.set_gsm(None)
        self.card.set_btprox(None)

    def _scan_gsm(self):
        ut.report("_scan_gsm")
        def f():
            self.gsm_scanner.scan(self._gsm_done)
            self.active = True
        self.cb("progress", u"Scanning context")
        self._via_immediate(f)

    def _gsm_done(self, gsm):
        """
        Note that it is important to set values to None when scanning
        fails so that we never end up sending a card with an old
        value.
        """
        ut.report("_gsm_done")
        self.active = False
        self.card.set_gsm(gsm)
        self._scan_btprox()

    def init_btprox_scanner(self):
        try:
            self.btprox_scanner = BtproxScanner()
        except:
            self.btprox_scanner = None

    def _scan_btprox(self):
        ut.report("_scan_btprox")
        try:
            if not self.config.get_btprox_scan():
                self._btprox_done(None)
                return
            if not self.btprox_scanner:
                self.init_btprox_scanner()
            if not self.btprox_scanner:
                if not self.btprox_scan_error_shown:
                    self.btprox_scan_error_shown = True
                    appuifw.note(u"Could not scan proximity: Is Bluetooth enabled?", "error")
                self._btprox_done(None)
                return
            self.btprox_scanner.scan(self._btprox_done)
            self.active = True
        except:
            ut.print_exception()
            self._btprox_done(None)

    def _btprox_done(self, btdata):
        """
        btdata:: Has value None if there was a scanning error.
        """
        ut.report("_btprox_done")
        self.active = False
        if btdata is None:
            self.btprox_scanner = None
        self.card.set_btprox(btdata)
        if self.card.gps is None:
            # Our positioning hack no longer appears to work, so disabling for now.
            #self._scan_position()
            self._send_card()
        else:
            self._send_card()

    def _scan_position(self):
        ut.report("_scan_position")

        def f():
            if self.positioner:
                self.positioner.close()
                self.positioner = None
            try:
                from pytwink import Positioner

                modlist = positioning.modules()
                module_id = None
                for entry in modlist:
                    if entry["name"] == u"Network based" and \
                       entry["available"]:
                        module_id = entry["id"]
                        break
                if not module_id:
                    raise "no network positioning module"

                updatetimeout = 15000000
                maxupdateage =  30000000
                self.positioner = Positioner(module_id, updatetimeout, maxupdateage)
                self.positioner.ask_position(self._positioner_done)
                return
            except:
                self._send_card()

            self.active = True

        self.cb("progress", u"Querying position")
        self._via_immediate(f)

    def _positioner_done(self, code):
        ut.report("_positioner_done (%d)" % code)
        self.active = False
        if not code:
            self.card.gps = {"position": self.positioner.get_position()}
        self._send_card()

    def _send_card(self):
        if self.config.get_store_on():
            self.cb("progress", u"Storing card")
            def f():
                try:
                    self.card.prepare_for_sending()
                    data = serialize_card(self.card)
                    save_unsent_card(data)
                    self.cb("ok", u"Card stored")
                except:
                    ut.print_exception()
                    self.cb("fail", u"Storing failed")
        else:
            self.cb("progress", u"Sending card")
            def f():
                try:
                    self.card.prepare_for_sending()
                    self.uploader.send(serialize_card(self.card), self._send_done)
                    self.active = True
                except:
                    self.config.set_apid(None)
                    ut.print_exception()
                    #appuifw.note(u"Sending failed", "error")
                    self.cb("fail", u"Sending failed")
        self._via_immediate(f)

    def _send_done(self, serr, equ):
        self.active = False
        if serr:
            ut.report("send error (Symbian %d)" % serr)
            self.cb("fail", u"Sending failed")
        elif equ == "refused":
            self.cb("fail", u"Server did not accept card")
        elif equ == "accepted":
            self.cb("ok", u"Card sent")
        else:
            self.cb("fail", u"Unexpected response from server")

    def _via_immediate(self, cb):
        def this_cb(code, dummy):
            self.active = False
            cb()
        self.immediate.complete(this_cb, None)
        self.active = True