Ejemplo n.º 1
0
class Application:
    """
    The Application main entry
    """
    def __init__(self, argv):
        logger = Logger().logger
        self.appConfig = AppConfig(logger)
        self.logger = logger
        self.quitting = False
        self.handling_events = False
        self.accounts = {}

        self.logger.debug("Creating the Endpoint")
        self.endpoint = Endpoint(self)

    def start(self):
        self.logger.debug("starting up")

        self.endpoint.libCreate()
        self.endpoint.libInit(self.appConfig.epConfig)

        self.logger.debug("lib initialized")

        self.endpoint.transportCreate(self.appConfig.udp.type,
                                      self.appConfig.udp.config)

        self.logger.debug("transport created")

        self.endpoint.libStart()

        self.logger.debug("lib started")

        for account in self.appConfig.accounts:
            if account.enabled:
                self._createAccount(account.config)

    def _createAccount(self, config):
        self.logger.debug("creating account '{}'".format(config.idUri))
        account = Account(self, config)
        account.create(account.config)
        self.accounts[config.idUri] = account
        self.logger.debug("created account '{}'".format(config.idUri))

    def onSelectAccount(self, param):
        """
        params is:
            SipRxData rdata    The incoming request.
            int accountIndex   Upon entry, this will be filled by the account index chosen by the library. Application may change it to another value to use another account.

        SipRxData is:
            string        info         A short info string describing the request, which normally contains the request method and its CSeq.
            string        wholeMsg     The whole message data as a string, containing both the header section and message body section.
            SocketAddress srcAddress   Source address of the message. (This is a string containing "host[:port]")
        """
        self.logger.debug("recieved msg {} for {}".format(
            param.rdata.info, param.accountIndex))
        return 0

    def make_call(self):
        while True and not self.quitting:
            self.logger.debug("handling events")
            self.handling_events = True
            self.endpoint.libHandleEvents(10)
            self.handling_events = False
            self.logger.debug("finished handling events")
            time.sleep(.50)
            self.logger.debug("pretending making call")

    def os_signal_handler(self, signal, frame):
        self.shutdown()

    def shutdown(self):
        self.quitting = True
        self.logger.debug("shutting down")
        self.endpoint.libDestroy()
Ejemplo n.º 2
0
class Main(tk.Tk):
    def __init__(self):
        super().__init__()
        """
        Initialize PJSUA2
        """
        self.ep = Endpoint()
        self.ep.libCreate()

        self.ep_cfg = pj.EpConfig()
        # self.ep_cfg.uaConfig.threadCnt = 0
        # self.ep_cfg.uaConfig.mainThreadOnly = True
        self.ep_cfg.logConfig.level = 1

        self.ep.libInit(self.ep_cfg)

        self.ts_cfg = pj.TransportConfig()
        self.ep.transportCreate(pj.PJSIP_TRANSPORT_UDP, self.ts_cfg)
        self.ep.libStart()
        """
        Initialize Account
        """
        self.acc = None
        self.domain = DEFAULT_DOMAIN

        self.buddy_list = {}
        self.chat_list = {}
        """
        Initialize UI
        """
        self.title('SIP Client')
        self.resizable(width=False, height=False)
        self.geometry('+{}+{}'.format(int(self.winfo_screenwidth() / 2),
                                      int(self.winfo_screenheight() / 2)))

        self.buddy = tk.Entry(self, font=FONT_CONTENT, width=30)
        self.buddy.grid(row=0, column=0, columnspan=3, padx=10, pady=10)
        self.buddy.bind('<Return>', self._add_buddy)

        self.buddy_view = ttk.Treeview(self,
                                       column=['1', '2'],
                                       show='headings',
                                       selectmode='browse')
        self.buddy_view.column('1', width=80, anchor='center')
        self.buddy_view.column('2', width=200, anchor='center')
        self.buddy_view.heading('1', text='Buddies')
        self.buddy_view.heading('2', text='Status')
        self.buddy_view.grid(row=1, column=0, columnspan=3, padx=10, pady=10)
        self.buddy_view.bind('<Double-Button-1>', self._create_chat)
        self.buddy_view.bind('<BackSpace>', self._delete_buddy)

        tk.Button(self,
                  text='Logout',
                  font=FONT_CONTENT,
                  width=8,
                  command=self._login).grid(row=2, column=0, padx=10, pady=10)
        tk.Button(self,
                  text='Exit',
                  font=FONT_CONTENT,
                  width=8,
                  command=self._exit).grid(row=2, column=2, padx=10, pady=10)

        self._login()

        # self._on_timer()

        self.mainloop()

    def _add_buddy(self, event):
        iid = self.buddy.get()

        if iid not in self.buddy_list:
            # Initialize buddy
            bud = Buddy(self, iid)
            # Initialize configuration of buddy
            bud_cfg = pj.BuddyConfig()
            bud_cfg.uri = 'sip:' + iid + '@' + self.domain
            # Create buddy
            bud.cfg = bud_cfg
            bud.create(self.acc, bud.cfg)
            bud.subscribePresence(True)
            # Push into buddy_list
            self.buddy_list[iid] = bud
            self.update_buddy(bud)

        self.buddy.delete(0, 'end')

    def _delete_buddy(self, event):
        for key in self.buddy_view.selection():
            self.buddy_view.delete(key)
            self.buddy_list.pop(key)

    def update_buddy(self, bud):
        iid = bud.iid
        if iid in self.buddy_list:
            self.buddy_view.item(iid, value=(iid, bud.status()))
        else:
            self.buddy_view.insert('',
                                   'end',
                                   iid=iid,
                                   values=(iid, bud.status()))

    def update_account(self):
        # TODO()
        print(self.acc.status())

    def incoming_call(self, prm):
        call = Call(self.acc, call_id=prm.callId)
        call_prm = pj.CallOpParam()
        # Ringing State
        call_prm.statusCode = pj.PJSIP_SC_RINGING
        call.answer(call_prm)
        # Set uri
        call.uri = call.getInfo().remoteUri
        iid = call.uri.split(':')[1].split('@')[0]
        if msg.askquestion('Incoming Call',
                           'Accept call from ' + iid + ' ?',
                           default=msg.YES):
            # If not exist current buddy, then create
            if iid not in self.buddy_list:
                # Initialize buddy
                bud = Buddy(self, iid)
                # Initialize configuration of buddy
                bud_cfg = pj.BuddyConfig()
                bud_cfg.uri = 'sip:' + iid + '@' + self.domain
                # Create buddy
                bud.cfg = bud_cfg
                bud.create(self.acc, bud.cfg)
                bud.subscribePresence(True)
                # Push into buddy_list
                self.buddy_list[iid] = bud
                self.update_buddy(bud)
            # If not exist current chat dialog, then create
            if iid not in self.chat_list:
                self.chat_list[iid] = Chat(self.acc, self.buddy_list[iid],
                                           self)
            # Inform the corresponding chat
            self.chat_list[iid].receive_call(call)
        else:
            call.hangup(call_prm)

    def instant_message(self, uri, msg):
        iid = uri[1:-1].split(':')[1].split('@')[0]
        if iid in self.chat_list:
            self.chat_list[iid].receive_message(msg)
        else:
            pass

    def _create_chat(self, event):
        for iid in self.buddy_view.selection():
            self.chat_list[iid] = Chat(self.acc, self.buddy_list[iid], self)

    def delete_chat(self, iid):
        self.chat_list.pop(iid)

    def _login(self):
        # Initialize configuration of account
        acc_cfg = pj.AccountConfig()
        # Create LoginDialog
        dlg = Login(self, acc_cfg)
        # Wait for response
        if dlg.do_modal():
            # Initialize account
            self.acc = Account(self)
            # Set configuration
            self.acc.cfg = acc_cfg
            self.acc.create(self.acc.cfg)
            # Set online status
            ps = pj.PresenceStatus()
            ps.status = pj.PJSUA_BUDDY_STATUS_ONLINE
            self.acc.setOnlineStatus(ps)

            # Update title
            self.title(self.acc.cfg.idUri)
            # Get the uri of server
            self.domain = self.acc.cfg.regConfig.registrarUri.split(':')[1]
            # Reset all
            self.buddy_list = {}
            self.chat_list = {}
            for key in self.buddy_view.get_children():
                self.buddy_view.delete(key)
        # If never login
        if not self.acc:
            # Then exit
            self._exit()

    def _exit(self):
        self.ep.libDestroy()
        self.ep = None
        self.destroy()