Ignore:
Timestamp:
Aug 2, 2017 9:45:09 AM (5 years ago)
Author:
riza
Message:

Close #2034: Add support to Python3 using PJSUA2 API.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip-apps/src/pygui/accountsetting.py

    r4704 r5638  
    2121import sys 
    2222if sys.version_info[0] >= 3: # Python 3 
    23         import tkinter as tk 
    24         from tkinter import ttk 
    25         from tkinter import messagebox as msgbox 
     23    import tkinter as tk 
     24    from tkinter import ttk 
     25    from tkinter import messagebox as msgbox 
    2626else: 
    27         import Tkinter as tk 
    28         import tkMessageBox as msgbox 
    29         import ttk 
     27    import Tkinter as tk 
     28    import tkMessageBox as msgbox 
     29    import ttk 
    3030 
    3131import pjsua2 as pj 
     
    3434 
    3535class Dialog(tk.Toplevel): 
    36         """ 
    37         This implements account settings dialog to manipulate account settings. 
    38         """ 
    39         def __init__(self, parent, cfg): 
    40                 tk.Toplevel.__init__(self, parent) 
    41                 self.transient(parent) 
    42                 self.parent = parent 
    43                 self.geometry("+100+100") 
    44                 self.title('Account settings') 
    45                  
    46                 self.frm = ttk.Frame(self) 
    47                 self.frm.pack(expand='yes', fill='both') 
    48                  
    49                 self.isOk = False 
    50                 self.cfg = cfg 
    51                  
    52                 self.createWidgets() 
    53          
    54         def doModal(self): 
    55                 if self.parent: 
    56                         self.parent.wait_window(self) 
    57                 else: 
    58                         self.wait_window(self) 
    59                 return self.isOk 
    60                  
    61         def createWidgets(self): 
    62                 # The notebook 
    63                 self.frm.rowconfigure(0, weight=1) 
    64                 self.frm.rowconfigure(1, weight=0) 
    65                 self.frm.columnconfigure(0, weight=1) 
    66                 self.frm.columnconfigure(1, weight=1) 
    67                 self.wTab = ttk.Notebook(self.frm) 
    68                 self.wTab.grid(column=0, row=0, columnspan=2, padx=10, pady=10, ipadx=20, ipady=20, sticky=tk.N+tk.S+tk.W+tk.E) 
    69                  
    70                 # Main buttons 
    71                 btnOk = ttk.Button(self.frm, text='Ok', command=self.onOk) 
    72                 btnOk.grid(column=0, row=1, sticky=tk.E, padx=20, pady=10) 
    73                 btnCancel = ttk.Button(self.frm, text='Cancel', command=self.onCancel) 
    74                 btnCancel.grid(column=1, row=1, sticky=tk.W, padx=20, pady=10) 
    75                  
    76                 # Tabs 
    77                 self.createBasicTab() 
    78                 self.createSipTab() 
    79                 self.createMediaTab() 
    80                 self.createMediaNatTab() 
    81                  
    82         def createBasicTab(self): 
    83                 # Prepare the variables to set/receive values from GUI 
    84                 self.cfgPriority = tk.IntVar(value=self.cfg.priority) 
    85                 self.cfgAccId = tk.StringVar(value=self.cfg.idUri) 
    86                 self.cfgRegistrar = tk.StringVar(value=self.cfg.regConfig.registrarUri) 
    87                 self.cfgRegisterOnAdd = tk.IntVar(value=self.cfg.regConfig.registerOnAdd) 
    88                 self.cfgUsername = tk.StringVar() 
    89                 self.cfgPassword = tk.StringVar() 
    90                 if len(self.cfg.sipConfig.authCreds): 
    91                         self.cfgUsername.set( self.cfg.sipConfig.authCreds[0].username ) 
    92                         self.cfgPassword.set( self.cfg.sipConfig.authCreds[0].data ) 
    93                 self.cfgProxy = tk.StringVar() 
    94                 if len(self.cfg.sipConfig.proxies): 
    95                         self.cfgProxy.set( self.cfg.sipConfig.proxies[0] ) 
    96                  
    97                 # Build the tab page 
    98                 frm = ttk.Frame(self.frm) 
    99                 frm.columnconfigure(0, weight=1) 
    100                 frm.columnconfigure(1, weight=2) 
    101                 row = 0 
    102                 ttk.Label(frm, text='Priority:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    103                 tk.Spinbox(frm, from_=0, to=9, textvariable=self.cfgPriority, width=2).grid(row=row, column=1, sticky=tk.W, padx=6) 
    104                 row += 1 
    105                 ttk.Label(frm, text='ID (URI):').grid(row=row, column=0, sticky=tk.E, pady=2) 
    106                 ttk.Entry(frm, textvariable=self.cfgAccId, width=32).grid(row=row, column=1, sticky=tk.W, padx=6) 
    107                 row += 1 
    108                 ttk.Label(frm, text='Registrar URI:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    109                 ttk.Entry(frm, textvariable=self.cfgRegistrar, width=32).grid(row=row, column=1, sticky=tk.W, padx=6) 
    110                 row += 1 
    111                 ttk.Checkbutton(frm, text='Register on add', variable=self.cfgRegisterOnAdd).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    112                 row += 1 
    113                 ttk.Label(frm, text='Optional proxy URI:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    114                 ttk.Entry(frm, textvariable=self.cfgProxy, width=32).grid(row=row, column=1, sticky=tk.W, padx=6) 
    115                 row += 1 
    116                 ttk.Label(frm, text='Auth username:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    117                 ttk.Entry(frm, textvariable=self.cfgUsername, width=16).grid(row=row, column=1, sticky=tk.W, padx=6) 
    118                 row += 1 
    119                 ttk.Label(frm, text='Password:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    120                 ttk.Entry(frm, textvariable=self.cfgPassword, show='*', width=16).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    121  
    122                 self.wTab.add(frm, text='Basic Settings') 
    123                  
    124  
    125         def createSipTab(self): 
    126                 # Prepare the variables to set/receive values from GUI 
    127                 self.cfgPrackUse        = tk.IntVar(value=self.cfg.callConfig.prackUse) 
    128                 self.cfgTimerUse        = tk.IntVar(value=self.cfg.callConfig.timerUse) 
    129                 self.cfgTimerExpires    = tk.IntVar(value=self.cfg.callConfig.timerSessExpiresSec) 
    130                 self.cfgPublish         = tk.BooleanVar(value=self.cfg.presConfig.publishEnabled) 
    131                 self.cfgMwiEnabled      = tk.BooleanVar(value=self.cfg.mwiConfig.enabled) 
    132                 self.cfgEnableContactRewrite = tk.BooleanVar(value=self.cfg.natConfig.contactRewriteUse != 0)  
    133                 self.cfgEnableViaRewrite = tk.BooleanVar(value=self.cfg.natConfig.viaRewriteUse != 0)  
    134                 self.cfgEnableSdpRewrite = tk.BooleanVar(value=self.cfg.natConfig.sdpNatRewriteUse != 0) 
    135                 self.cfgEnableSipOutbound = tk.BooleanVar(value=self.cfg.natConfig.sipOutboundUse != 0) 
    136                 self.cfgKaInterval      = tk.IntVar(value=self.cfg.natConfig.udpKaIntervalSec) 
    137                  
    138                 # Build the tab page 
    139                 frm = ttk.Frame(self.frm) 
    140                 frm.columnconfigure(0, weight=1) 
    141                 frm.columnconfigure(1, weight=2) 
    142                 row = 0 
    143                 ttk.Label(frm, text='100rel/PRACK:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    144                 ttk.Radiobutton(frm, text='Only offer PRACK', value=pj.PJSUA_100REL_NOT_USED, variable=self.cfgPrackUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
    145                 row += 1 
    146                 ttk.Radiobutton(frm, text='Offer and use if remote supports', value=pj.PJSUA_100REL_OPTIONAL, variable=self.cfgPrackUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
    147                 row += 1 
    148                 ttk.Radiobutton(frm, text='Required', value=pj.PJSUA_100REL_MANDATORY, variable=self.cfgPrackUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
    149                 row += 1 
    150                 ttk.Label(frm, text='Session Timer:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    151                 ttk.Radiobutton(frm, text='Not offered', value=pj.PJSUA_SIP_TIMER_INACTIVE, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
    152                 row += 1 
    153                 ttk.Radiobutton(frm, text='Optional', value=pj.PJSUA_SIP_TIMER_OPTIONAL, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
    154                 row += 1 
    155                 ttk.Radiobutton(frm, text='Required', value=pj.PJSUA_SIP_TIMER_REQUIRED, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
    156                 row += 1 
    157                 ttk.Radiobutton(frm, text="Always use", value=pj.PJSUA_SIP_TIMER_ALWAYS, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
    158                 row += 1 
    159                 ttk.Label(frm, text='Session Timer Expiration:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    160                 tk.Spinbox(frm, from_=90, to=7200, textvariable=self.cfgTimerExpires, width=5).grid(row=row, column=1, sticky=tk.W, padx=6) 
    161                 ttk.Label(frm, text='(seconds)').grid(row=row, column=1, sticky=tk.E) 
    162                 row += 1 
    163                 ttk.Label(frm, text='Presence:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    164                 ttk.Checkbutton(frm, text='Enable PUBLISH', variable=self.cfgPublish).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    165                 row += 1 
    166                 ttk.Label(frm, text='Message Waiting Indication:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    167                 ttk.Checkbutton(frm, text='Enable MWI', variable=self.cfgMwiEnabled).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    168                 row += 1 
    169                 ttk.Label(frm, text='NAT Traversal:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    170                 ttk.Checkbutton(frm, text='Enable Contact Rewrite', variable=self.cfgEnableContactRewrite).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    171                 row += 1 
    172                 ttk.Checkbutton(frm, text='Enable Via Rewrite', variable=self.cfgEnableViaRewrite).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    173                 row += 1 
    174                 ttk.Checkbutton(frm, text='Enable SDP IP Address Rewrite', variable=self.cfgEnableSdpRewrite).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    175                 row += 1 
    176                 ttk.Checkbutton(frm, text='Enable SIP Outbound Extension', variable=self.cfgEnableSipOutbound).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    177                 row += 1 
    178                 ttk.Label(frm, text='UDP Keep-Alive Interval:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    179                 tk.Spinbox(frm, from_=0, to=3600, textvariable=self.cfgKaInterval, width=5).grid(row=row, column=1, sticky=tk.W, padx=6) 
    180                 ttk.Label(frm, text='(seconds) Zero to disable.').grid(row=row, column=1, sticky=tk.E) 
    181  
    182  
    183                 self.wTab.add(frm, text='SIP Features') 
    184  
    185         def createMediaTab(self): 
    186                 # Prepare the variables to set/receive values from GUI 
    187                 self.cfgMedPort = tk.IntVar(value=self.cfg.mediaConfig.transportConfig.port) 
    188                 self.cfgMedPortRange = tk.IntVar(value=self.cfg.mediaConfig.transportConfig.portRange) 
    189                 self.cfgMedLockCodec = tk.BooleanVar(value=self.cfg.mediaConfig.lockCodecEnabled) 
    190                 self.cfgMedSrtp = tk.IntVar(value=self.cfg.mediaConfig.srtpUse) 
    191                 self.cfgMedSrtpSecure = tk.IntVar(value=self.cfg.mediaConfig.srtpSecureSignaling) 
    192                 self.cfgMedIpv6 = tk.BooleanVar(value=self.cfg.mediaConfig.ipv6Use==pj.PJSUA_IPV6_ENABLED) 
    193                  
    194                 # Build the tab page 
    195                 frm = ttk.Frame(self.frm) 
    196                 frm.columnconfigure(0, weight=1) 
    197                 frm.columnconfigure(1, weight=21) 
    198                 row = 0 
    199                 ttk.Label(frm, text='Secure RTP (SRTP):').grid(row=row, column=0, sticky=tk.E, pady=2) 
    200                 ttk.Radiobutton(frm, text='Disable', value=pj.PJMEDIA_SRTP_DISABLED, variable=self.cfgMedSrtp).grid(row=row, column=1, sticky=tk.W, padx=6) 
    201                 row += 1 
    202                 ttk.Radiobutton(frm, text='Mandatory', value=pj.PJMEDIA_SRTP_MANDATORY, variable=self.cfgMedSrtp).grid(row=row, column=1, sticky=tk.W, padx=6) 
    203                 row += 1 
    204                 ttk.Radiobutton(frm, text='Optional (non-standard)', value=pj.PJMEDIA_SRTP_OPTIONAL, variable=self.cfgMedSrtp).grid(row=row, column=1, sticky=tk.W, padx=6) 
    205                 row += 1 
    206                 ttk.Label(frm, text='SRTP signaling:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    207                 ttk.Radiobutton(frm, text='Does not require secure signaling', value=0, variable=self.cfgMedSrtpSecure).grid(row=row, column=1, sticky=tk.W, padx=6) 
    208                 row += 1 
    209                 ttk.Radiobutton(frm, text='Require secure next hop (TLS)', value=1, variable=self.cfgMedSrtpSecure).grid(row=row, column=1, sticky=tk.W, padx=6) 
    210                 row += 1 
    211                 ttk.Radiobutton(frm, text='Require secure end-to-end (SIPS)', value=2, variable=self.cfgMedSrtpSecure).grid(row=row, column=1, sticky=tk.W, padx=6) 
    212                 row += 1 
    213                 ttk.Label(frm, text='RTP transport start port:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    214                 tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgMedPort, width=5).grid(row=row, column=1, sticky=tk.W, padx=6) 
    215                 ttk.Label(frm, text='(0: any)').grid(row=row, column=1, sticky=tk.E, pady=2) 
    216                 row += 1 
    217                 ttk.Label(frm, text='Port range:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    218                 tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgMedPortRange, width=5).grid(row=row, column=1, sticky=tk.W, padx=6) 
    219                 ttk.Label(frm, text='(0: not limited)').grid(row=row, column=1, sticky=tk.E, pady=2) 
    220                 row += 1 
    221                 ttk.Label(frm, text='Lock codec:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    222                 ttk.Checkbutton(frm, text='Enable', variable=self.cfgMedLockCodec).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    223                 row += 1 
    224                 ttk.Label(frm, text='Use IPv6:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    225                 ttk.Checkbutton(frm, text='Yes', variable=self.cfgMedIpv6).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    226  
    227                 self.wTab.add(frm, text='Media settings') 
    228  
    229         def createMediaNatTab(self): 
    230                 # Prepare the variables to set/receive values from GUI 
    231                 self.cfgSipUseStun = tk.IntVar(value = self.cfg.natConfig.sipStunUse) 
    232                 self.cfgMediaUseStun = tk.IntVar(value = self.cfg.natConfig.mediaStunUse) 
    233                 self.cfgIceEnabled = tk.BooleanVar(value = self.cfg.natConfig.iceEnabled) 
    234                 self.cfgIceAggressive = tk.BooleanVar(value = self.cfg.natConfig.iceAggressiveNomination) 
    235                 self.cfgAlwaysUpdate = tk.BooleanVar(value = True if self.cfg.natConfig.iceAlwaysUpdate else False) 
    236                 self.cfgIceNoHostCands = tk.BooleanVar(value = True if self.cfg.natConfig.iceMaxHostCands == 0 else False) 
    237                 self.cfgTurnEnabled = tk.BooleanVar(value = self.cfg.natConfig.turnEnabled) 
    238                 self.cfgTurnServer = tk.StringVar(value = self.cfg.natConfig.turnServer) 
    239                 self.cfgTurnConnType = tk.IntVar(value = self.cfg.natConfig.turnConnType) 
    240                 self.cfgTurnUser = tk.StringVar(value = self.cfg.natConfig.turnUserName) 
    241                 self.cfgTurnPasswd = tk.StringVar(value = self.cfg.natConfig.turnPassword) 
    242                  
    243                 # Build the tab page 
    244                 frm = ttk.Frame(self.frm) 
    245                 frm.columnconfigure(0, weight=1) 
    246                 frm.columnconfigure(1, weight=2) 
    247                 row = 0 
    248                 ttk.Label(frm, text='SIP STUN Usage:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    249                 ttk.Radiobutton(frm, text='Default', value=pj.PJSUA_STUN_USE_DEFAULT, variable=self.cfgSipUseStun).grid(row=row, column=1, sticky=tk.W, padx=6) 
    250                 row += 1 
    251                 ttk.Radiobutton(frm, text='Disable', value=pj.PJSUA_STUN_USE_DISABLED, variable=self.cfgSipUseStun).grid(row=row, column=1, sticky=tk.W, padx=6) 
    252                 row += 1 
    253                 ttk.Label(frm, text='Media STUN Usage:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    254                 ttk.Radiobutton(frm, text='Default', value=pj.PJSUA_STUN_USE_DEFAULT, variable=self.cfgMediaUseStun).grid(row=row, column=1, sticky=tk.W, padx=6) 
    255                 row += 1 
    256                 ttk.Radiobutton(frm, text='Disable', value=pj.PJSUA_STUN_USE_DISABLED, variable=self.cfgMediaUseStun).grid(row=row, column=1, sticky=tk.W, padx=6) 
    257                 row += 1 
    258                 ttk.Label(frm, text='ICE:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    259                 ttk.Checkbutton(frm, text='Enable', variable=self.cfgIceEnabled).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    260                 row += 1 
    261                 ttk.Checkbutton(frm, text='Use aggresive nomination', variable=self.cfgIceAggressive).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    262                 row += 1 
    263                 ttk.Checkbutton(frm, text='Always re-INVITE after negotiation', variable=self.cfgAlwaysUpdate).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    264                 row += 1 
    265                 ttk.Checkbutton(frm, text='Disable host candidates', variable=self.cfgIceNoHostCands).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    266                 row += 1 
    267                 ttk.Label(frm, text='TURN:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    268                 ttk.Checkbutton(frm, text='Enable', variable=self.cfgTurnEnabled).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
    269                 row += 1 
    270                 ttk.Label(frm, text='TURN server:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    271                 ttk.Entry(frm, textvariable=self.cfgTurnServer, width=20).grid(row=row, column=1, sticky=tk.W, padx=6) 
    272                 ttk.Label(frm, text='host[:port]').grid(row=row, column=1, sticky=tk.E, pady=6) 
    273                 row += 1 
    274                 ttk.Label(frm, text='TURN connection:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    275                 ttk.Radiobutton(frm, text='UDP', value=pj.PJ_TURN_TP_UDP, variable=self.cfgTurnConnType).grid(row=row, column=1, sticky=tk.W, padx=6) 
    276                 row += 1 
    277                 ttk.Radiobutton(frm, text='TCP', value=pj.PJ_TURN_TP_TCP, variable=self.cfgTurnConnType).grid(row=row, column=1, sticky=tk.W, padx=6) 
    278                 row += 1 
    279                 ttk.Label(frm, text='TURN username:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    280                 ttk.Entry(frm, textvariable=self.cfgTurnUser, width=16).grid(row=row, column=1, sticky=tk.W, padx=6) 
    281                 row += 1 
    282                 ttk.Label(frm, text='TURN password:').grid(row=row, column=0, sticky=tk.E, pady=2) 
    283                 ttk.Entry(frm, textvariable=self.cfgTurnPasswd, show='*', width=16).grid(row=row, column=1, sticky=tk.W, padx=6) 
    284  
    285                 self.wTab.add(frm, text='NAT settings') 
    286                  
    287         def onOk(self): 
    288                 # Check basic settings 
    289                 errors = ""; 
    290                 if not self.cfgAccId.get(): 
    291                         errors += "Account ID is required\n" 
    292                 if self.cfgAccId.get(): 
    293                         if not endpoint.validateSipUri(self.cfgAccId.get()): 
    294                                 errors += "Invalid SIP ID URI: '%s'\n" % (self.cfgAccId.get()) 
    295                 if self.cfgRegistrar.get(): 
    296                         if not endpoint.validateSipUri(self.cfgRegistrar.get()): 
    297                                 errors += "Invalid SIP registrar URI: '%s'\n" % (self.cfgRegistrar.get()) 
    298                 if self.cfgProxy.get(): 
    299                         if not endpoint.validateSipUri(self.cfgProxy.get()): 
    300                                 errors += "Invalid SIP proxy URI: '%s'\n" % (self.cfgProxy.get()) 
    301                 if self.cfgTurnEnabled.get(): 
    302                         if not self.cfgTurnServer.get(): 
    303                                 errors += "TURN server is required\n" 
    304                 if errors: 
    305                         msgbox.showerror("Error detected:", errors) 
    306                         return 
    307                  
    308                 # Basic settings 
    309                 self.cfg.priority = self.cfgPriority.get() 
    310                 self.cfg.idUri = self.cfgAccId.get() 
    311                 self.cfg.regConfig.registrarUri = self.cfgRegistrar.get() 
    312                 self.cfg.regConfig.registerOnAdd = self.cfgRegisterOnAdd.get() 
    313                 while len(self.cfg.sipConfig.authCreds): 
    314                         self.cfg.sipConfig.authCreds.pop() 
    315                 if self.cfgUsername.get(): 
    316                         cred = pj.AuthCredInfo() 
    317                         cred.scheme = "digest" 
    318                         cred.realm = "*" 
    319                         cred.username = self.cfgUsername.get() 
    320                         cred.data = self.cfgPassword.get() 
    321                         self.cfg.sipConfig.authCreds.append(cred) 
    322                 while len(self.cfg.sipConfig.proxies): 
    323                         self.cfg.sipConfig.proxies.pop() 
    324                 if self.cfgProxy.get(): 
    325                         self.cfg.sipConfig.proxies.append(self.cfgProxy.get()) 
    326  
    327                 # SIP features 
    328                 self.cfg.callConfig.prackUse            = self.cfgPrackUse.get()  
    329                 self.cfg.callConfig.timerUse            = self.cfgTimerUse.get() 
    330                 self.cfg.callConfig.timerSessExpiresSec = self.cfgTimerExpires.get()  
    331                 self.cfg.presConfig.publishEnabled      = self.cfgPublish.get()  
    332                 self.cfg.mwiConfig.enabled              = self.cfgMwiEnabled.get()  
    333                 self.cfg.natConfig.contactRewriteUse    = 1 if self.cfgEnableContactRewrite.get() else 0 
    334                 self.cfg.natConfig.viaRewriteUse        = 1 if self.cfgEnableViaRewrite.get() else 0 
    335                 self.cfg.natConfig.sdpNatRewriteUse     = 1 if self.cfgEnableSdpRewrite.get() else 0 
    336                 self.cfg.natConfig.sipOutboundUse       = 1 if self.cfgEnableSipOutbound.get() else 0 
    337                 self.cfg.natConfig.udpKaIntervalSec     = self.cfgKaInterval.get() 
    338  
    339                 # Media 
    340                 self.cfg.mediaConfig.transportConfig.port       = self.cfgMedPort.get() 
    341                 self.cfg.mediaConfig.transportConfig.portRange  = self.cfgMedPortRange.get() 
    342                 self.cfg.mediaConfig.lockCodecEnabled           = self.cfgMedLockCodec.get() 
    343                 self.cfg.mediaConfig.srtpUse                    = self.cfgMedSrtp.get() 
    344                 self.cfg.mediaConfig.srtpSecureSignaling        = self.cfgMedSrtpSecure.get() 
    345                 self.cfg.mediaConfig.ipv6Use                    = pj.PJSUA_IPV6_ENABLED if self.cfgMedIpv6.get() else pj.PJSUA_IPV6_DISABLED 
    346                  
    347                 # NAT 
    348                 self.cfg.natConfig.sipStunUse           = self.cfgSipUseStun.get() 
    349                 self.cfg.natConfig.mediaStunUse         = self.cfgMediaUseStun.get() 
    350                 self.cfg.natConfig.iceEnabled           = self.cfgIceEnabled.get() 
    351                 self.cfg.natConfig.iceAggressiveNomination = self.cfgIceAggressive .get() 
    352                 self.cfg.natConfig.iceAlwaysUpdate      = self.cfgAlwaysUpdate.get() 
    353                 self.cfg.natConfig.iceMaxHostCands      = 0 if self.cfgIceNoHostCands.get() else -1  
    354                 self.cfg.natConfig.turnEnabled          = self.cfgTurnEnabled.get() 
    355                 self.cfg.natConfig.turnServer           = self.cfgTurnServer.get() 
    356                 self.cfg.natConfig.turnConnType         = self.cfgTurnConnType.get() 
    357                 self.cfg.natConfig.turnUserName         = self.cfgTurnUser.get() 
    358                 self.cfg.natConfig.turnPasswordType     = 0 
    359                 self.cfg.natConfig.turnPassword         = self.cfgTurnPasswd.get() 
    360                  
    361                 self.isOk = True 
    362                 self.destroy() 
    363                  
    364         def onCancel(self): 
    365                 self.destroy() 
     36    """ 
     37    This implements account settings dialog to manipulate account settings. 
     38    """ 
     39    def __init__(self, parent, cfg): 
     40        tk.Toplevel.__init__(self, parent) 
     41        self.transient(parent) 
     42        self.parent = parent 
     43        self.geometry("+100+100") 
     44        self.title('Account settings') 
     45 
     46        self.frm = ttk.Frame(self) 
     47        self.frm.pack(expand='yes', fill='both') 
     48 
     49        self.isOk = False 
     50        self.cfg = cfg 
     51 
     52        self.createWidgets() 
     53 
     54    def doModal(self): 
     55        if self.parent: 
     56            self.parent.wait_window(self) 
     57        else: 
     58            self.wait_window(self) 
     59        return self.isOk 
     60 
     61    def createWidgets(self): 
     62        # The notebook 
     63        self.frm.rowconfigure(0, weight=1) 
     64        self.frm.rowconfigure(1, weight=0) 
     65        self.frm.columnconfigure(0, weight=1) 
     66        self.frm.columnconfigure(1, weight=1) 
     67        self.wTab = ttk.Notebook(self.frm) 
     68        self.wTab.grid(column=0, row=0, columnspan=2, padx=10, pady=10, ipadx=20, ipady=20, sticky=tk.N+tk.S+tk.W+tk.E) 
     69 
     70        # Main buttons 
     71        btnOk = ttk.Button(self.frm, text='Ok', command=self.onOk) 
     72        btnOk.grid(column=0, row=1, sticky=tk.E, padx=20, pady=10) 
     73        btnCancel = ttk.Button(self.frm, text='Cancel', command=self.onCancel) 
     74        btnCancel.grid(column=1, row=1, sticky=tk.W, padx=20, pady=10) 
     75 
     76        # Tabs 
     77        self.createBasicTab() 
     78        self.createSipTab() 
     79        self.createMediaTab() 
     80        self.createMediaNatTab() 
     81 
     82    def createBasicTab(self): 
     83        # Prepare the variables to set/receive values from GUI 
     84        self.cfgPriority = tk.IntVar(value=self.cfg.priority) 
     85        self.cfgAccId = tk.StringVar(value=self.cfg.idUri) 
     86        self.cfgRegistrar = tk.StringVar(value=self.cfg.regConfig.registrarUri) 
     87        self.cfgRegisterOnAdd = tk.BooleanVar(value=self.cfg.regConfig.registerOnAdd) 
     88        self.cfgUsername = tk.StringVar() 
     89        self.cfgPassword = tk.StringVar() 
     90        if len(self.cfg.sipConfig.authCreds): 
     91            self.cfgUsername.set( self.cfg.sipConfig.authCreds[0].username ) 
     92            self.cfgPassword.set( self.cfg.sipConfig.authCreds[0].data ) 
     93        self.cfgProxy = tk.StringVar() 
     94        if len(self.cfg.sipConfig.proxies): 
     95            self.cfgProxy.set( self.cfg.sipConfig.proxies[0] ) 
     96 
     97        # Build the tab page 
     98        frm = ttk.Frame(self.frm) 
     99        frm.columnconfigure(0, weight=1) 
     100        frm.columnconfigure(1, weight=2) 
     101        row = 0 
     102        ttk.Label(frm, text='Priority:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     103        tk.Spinbox(frm, from_=0, to=9, textvariable=self.cfgPriority, width=2).grid(row=row, column=1, sticky=tk.W, padx=6) 
     104        row += 1 
     105        ttk.Label(frm, text='ID (URI):').grid(row=row, column=0, sticky=tk.E, pady=2) 
     106        ttk.Entry(frm, textvariable=self.cfgAccId, width=32).grid(row=row, column=1, sticky=tk.W, padx=6) 
     107        row += 1 
     108        ttk.Label(frm, text='Registrar URI:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     109        ttk.Entry(frm, textvariable=self.cfgRegistrar, width=32).grid(row=row, column=1, sticky=tk.W, padx=6) 
     110        row += 1 
     111        ttk.Checkbutton(frm, text='Register on add', variable=self.cfgRegisterOnAdd).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     112        row += 1 
     113        ttk.Label(frm, text='Optional proxy URI:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     114        ttk.Entry(frm, textvariable=self.cfgProxy, width=32).grid(row=row, column=1, sticky=tk.W, padx=6) 
     115        row += 1 
     116        ttk.Label(frm, text='Auth username:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     117        ttk.Entry(frm, textvariable=self.cfgUsername, width=16).grid(row=row, column=1, sticky=tk.W, padx=6) 
     118        row += 1 
     119        ttk.Label(frm, text='Password:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     120        ttk.Entry(frm, textvariable=self.cfgPassword, show='*', width=16).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     121 
     122        self.wTab.add(frm, text='Basic Settings') 
     123 
     124 
     125    def createSipTab(self): 
     126        # Prepare the variables to set/receive values from GUI 
     127        self.cfgPrackUse        = tk.IntVar(value=self.cfg.callConfig.prackUse) 
     128        self.cfgTimerUse        = tk.IntVar(value=self.cfg.callConfig.timerUse) 
     129        self.cfgTimerExpires    = tk.IntVar(value=self.cfg.callConfig.timerSessExpiresSec) 
     130        self.cfgPublish         = tk.BooleanVar(value=self.cfg.presConfig.publishEnabled) 
     131        self.cfgMwiEnabled      = tk.BooleanVar(value=self.cfg.mwiConfig.enabled) 
     132        self.cfgEnableContactRewrite = tk.BooleanVar(value=self.cfg.natConfig.contactRewriteUse != 0) 
     133        self.cfgEnableViaRewrite = tk.BooleanVar(value=self.cfg.natConfig.viaRewriteUse != 0) 
     134        self.cfgEnableSdpRewrite = tk.BooleanVar(value=self.cfg.natConfig.sdpNatRewriteUse != 0) 
     135        self.cfgEnableSipOutbound = tk.BooleanVar(value=self.cfg.natConfig.sipOutboundUse != 0) 
     136        self.cfgKaInterval      = tk.IntVar(value=self.cfg.natConfig.udpKaIntervalSec) 
     137 
     138        # Build the tab page 
     139        frm = ttk.Frame(self.frm) 
     140        frm.columnconfigure(0, weight=1) 
     141        frm.columnconfigure(1, weight=2) 
     142        row = 0 
     143        ttk.Label(frm, text='100rel/PRACK:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     144        ttk.Radiobutton(frm, text='Only offer PRACK', value=pj.PJSUA_100REL_NOT_USED, variable=self.cfgPrackUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
     145        row += 1 
     146        ttk.Radiobutton(frm, text='Offer and use if remote supports', value=pj.PJSUA_100REL_OPTIONAL, variable=self.cfgPrackUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
     147        row += 1 
     148        ttk.Radiobutton(frm, text='Required', value=pj.PJSUA_100REL_MANDATORY, variable=self.cfgPrackUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
     149        row += 1 
     150        ttk.Label(frm, text='Session Timer:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     151        ttk.Radiobutton(frm, text='Not offered', value=pj.PJSUA_SIP_TIMER_INACTIVE, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
     152        row += 1 
     153        ttk.Radiobutton(frm, text='Optional', value=pj.PJSUA_SIP_TIMER_OPTIONAL, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
     154        row += 1 
     155        ttk.Radiobutton(frm, text='Required', value=pj.PJSUA_SIP_TIMER_REQUIRED, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
     156        row += 1 
     157        ttk.Radiobutton(frm, text="Always use", value=pj.PJSUA_SIP_TIMER_ALWAYS, variable=self.cfgTimerUse).grid(row=row, column=1, sticky=tk.W, padx=6) 
     158        row += 1 
     159        ttk.Label(frm, text='Session Timer Expiration:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     160        tk.Spinbox(frm, from_=90, to=7200, textvariable=self.cfgTimerExpires, width=5).grid(row=row, column=1, sticky=tk.W, padx=6) 
     161        ttk.Label(frm, text='(seconds)').grid(row=row, column=1, sticky=tk.E) 
     162        row += 1 
     163        ttk.Label(frm, text='Presence:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     164        ttk.Checkbutton(frm, text='Enable PUBLISH', variable=self.cfgPublish).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     165        row += 1 
     166        ttk.Label(frm, text='Message Waiting Indication:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     167        ttk.Checkbutton(frm, text='Enable MWI', variable=self.cfgMwiEnabled).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     168        row += 1 
     169        ttk.Label(frm, text='NAT Traversal:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     170        ttk.Checkbutton(frm, text='Enable Contact Rewrite', variable=self.cfgEnableContactRewrite).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     171        row += 1 
     172        ttk.Checkbutton(frm, text='Enable Via Rewrite', variable=self.cfgEnableViaRewrite).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     173        row += 1 
     174        ttk.Checkbutton(frm, text='Enable SDP IP Address Rewrite', variable=self.cfgEnableSdpRewrite).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     175        row += 1 
     176        ttk.Checkbutton(frm, text='Enable SIP Outbound Extension', variable=self.cfgEnableSipOutbound).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     177        row += 1 
     178        ttk.Label(frm, text='UDP Keep-Alive Interval:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     179        tk.Spinbox(frm, from_=0, to=3600, textvariable=self.cfgKaInterval, width=5).grid(row=row, column=1, sticky=tk.W, padx=6) 
     180        ttk.Label(frm, text='(seconds) Zero to disable.').grid(row=row, column=1, sticky=tk.E) 
     181 
     182 
     183        self.wTab.add(frm, text='SIP Features') 
     184 
     185    def createMediaTab(self): 
     186        # Prepare the variables to set/receive values from GUI 
     187        self.cfgMedPort = tk.IntVar(value=self.cfg.mediaConfig.transportConfig.port) 
     188        self.cfgMedPortRange = tk.IntVar(value=self.cfg.mediaConfig.transportConfig.portRange) 
     189        self.cfgMedLockCodec = tk.BooleanVar(value=self.cfg.mediaConfig.lockCodecEnabled) 
     190        self.cfgMedSrtp = tk.IntVar(value=self.cfg.mediaConfig.srtpUse) 
     191        self.cfgMedSrtpSecure = tk.IntVar(value=self.cfg.mediaConfig.srtpSecureSignaling) 
     192        self.cfgMedIpv6 = tk.BooleanVar(value=self.cfg.mediaConfig.ipv6Use==pj.PJSUA_IPV6_ENABLED) 
     193 
     194        # Build the tab page 
     195        frm = ttk.Frame(self.frm) 
     196        frm.columnconfigure(0, weight=1) 
     197        frm.columnconfigure(1, weight=21) 
     198        row = 0 
     199        ttk.Label(frm, text='Secure RTP (SRTP):').grid(row=row, column=0, sticky=tk.E, pady=2) 
     200        ttk.Radiobutton(frm, text='Disable', value=pj.PJMEDIA_SRTP_DISABLED, variable=self.cfgMedSrtp).grid(row=row, column=1, sticky=tk.W, padx=6) 
     201        row += 1 
     202        ttk.Radiobutton(frm, text='Mandatory', value=pj.PJMEDIA_SRTP_MANDATORY, variable=self.cfgMedSrtp).grid(row=row, column=1, sticky=tk.W, padx=6) 
     203        row += 1 
     204        ttk.Radiobutton(frm, text='Optional (non-standard)', value=pj.PJMEDIA_SRTP_OPTIONAL, variable=self.cfgMedSrtp).grid(row=row, column=1, sticky=tk.W, padx=6) 
     205        row += 1 
     206        ttk.Label(frm, text='SRTP signaling:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     207        ttk.Radiobutton(frm, text='Does not require secure signaling', value=0, variable=self.cfgMedSrtpSecure).grid(row=row, column=1, sticky=tk.W, padx=6) 
     208        row += 1 
     209        ttk.Radiobutton(frm, text='Require secure next hop (TLS)', value=1, variable=self.cfgMedSrtpSecure).grid(row=row, column=1, sticky=tk.W, padx=6) 
     210        row += 1 
     211        ttk.Radiobutton(frm, text='Require secure end-to-end (SIPS)', value=2, variable=self.cfgMedSrtpSecure).grid(row=row, column=1, sticky=tk.W, padx=6) 
     212        row += 1 
     213        ttk.Label(frm, text='RTP transport start port:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     214        tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgMedPort, width=5).grid(row=row, column=1, sticky=tk.W, padx=6) 
     215        ttk.Label(frm, text='(0: any)').grid(row=row, column=1, sticky=tk.E, pady=2) 
     216        row += 1 
     217        ttk.Label(frm, text='Port range:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     218        tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgMedPortRange, width=5).grid(row=row, column=1, sticky=tk.W, padx=6) 
     219        ttk.Label(frm, text='(0: not limited)').grid(row=row, column=1, sticky=tk.E, pady=2) 
     220        row += 1 
     221        ttk.Label(frm, text='Lock codec:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     222        ttk.Checkbutton(frm, text='Enable', variable=self.cfgMedLockCodec).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     223        row += 1 
     224        ttk.Label(frm, text='Use IPv6:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     225        ttk.Checkbutton(frm, text='Yes', variable=self.cfgMedIpv6).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     226 
     227        self.wTab.add(frm, text='Media settings') 
     228 
     229    def createMediaNatTab(self): 
     230        # Prepare the variables to set/receive values from GUI 
     231        self.cfgSipUseStun = tk.IntVar(value = self.cfg.natConfig.sipStunUse) 
     232        self.cfgMediaUseStun = tk.IntVar(value = self.cfg.natConfig.mediaStunUse) 
     233        self.cfgIceEnabled = tk.BooleanVar(value = self.cfg.natConfig.iceEnabled) 
     234        self.cfgIceAggressive = tk.BooleanVar(value = self.cfg.natConfig.iceAggressiveNomination) 
     235        self.cfgAlwaysUpdate = tk.BooleanVar(value = True if self.cfg.natConfig.iceAlwaysUpdate else False) 
     236        self.cfgIceNoHostCands = tk.BooleanVar(value = True if self.cfg.natConfig.iceMaxHostCands == 0 else False) 
     237        self.cfgTurnEnabled = tk.BooleanVar(value = self.cfg.natConfig.turnEnabled) 
     238        self.cfgTurnServer = tk.StringVar(value = self.cfg.natConfig.turnServer) 
     239        self.cfgTurnConnType = tk.IntVar(value = self.cfg.natConfig.turnConnType) 
     240        self.cfgTurnUser = tk.StringVar(value = self.cfg.natConfig.turnUserName) 
     241        self.cfgTurnPasswd = tk.StringVar(value = self.cfg.natConfig.turnPassword) 
     242 
     243        # Build the tab page 
     244        frm = ttk.Frame(self.frm) 
     245        frm.columnconfigure(0, weight=1) 
     246        frm.columnconfigure(1, weight=2) 
     247        row = 0 
     248        ttk.Label(frm, text='SIP STUN Usage:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     249        ttk.Radiobutton(frm, text='Default', value=pj.PJSUA_STUN_USE_DEFAULT, variable=self.cfgSipUseStun).grid(row=row, column=1, sticky=tk.W, padx=6) 
     250        row += 1 
     251        ttk.Radiobutton(frm, text='Disable', value=pj.PJSUA_STUN_USE_DISABLED, variable=self.cfgSipUseStun).grid(row=row, column=1, sticky=tk.W, padx=6) 
     252        row += 1 
     253        ttk.Label(frm, text='Media STUN Usage:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     254        ttk.Radiobutton(frm, text='Default', value=pj.PJSUA_STUN_USE_DEFAULT, variable=self.cfgMediaUseStun).grid(row=row, column=1, sticky=tk.W, padx=6) 
     255        row += 1 
     256        ttk.Radiobutton(frm, text='Disable', value=pj.PJSUA_STUN_USE_DISABLED, variable=self.cfgMediaUseStun).grid(row=row, column=1, sticky=tk.W, padx=6) 
     257        row += 1 
     258        ttk.Label(frm, text='ICE:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     259        ttk.Checkbutton(frm, text='Enable', variable=self.cfgIceEnabled).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     260        row += 1 
     261        ttk.Checkbutton(frm, text='Use aggresive nomination', variable=self.cfgIceAggressive).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     262        row += 1 
     263        ttk.Checkbutton(frm, text='Always re-INVITE after negotiation', variable=self.cfgAlwaysUpdate).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     264        row += 1 
     265        ttk.Checkbutton(frm, text='Disable host candidates', variable=self.cfgIceNoHostCands).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     266        row += 1 
     267        ttk.Label(frm, text='TURN:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     268        ttk.Checkbutton(frm, text='Enable', variable=self.cfgTurnEnabled).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2) 
     269        row += 1 
     270        ttk.Label(frm, text='TURN server:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     271        ttk.Entry(frm, textvariable=self.cfgTurnServer, width=20).grid(row=row, column=1, sticky=tk.W, padx=6) 
     272        ttk.Label(frm, text='host[:port]').grid(row=row, column=1, sticky=tk.E, pady=6) 
     273        row += 1 
     274        ttk.Label(frm, text='TURN connection:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     275        ttk.Radiobutton(frm, text='UDP', value=pj.PJ_TURN_TP_UDP, variable=self.cfgTurnConnType).grid(row=row, column=1, sticky=tk.W, padx=6) 
     276        row += 1 
     277        ttk.Radiobutton(frm, text='TCP', value=pj.PJ_TURN_TP_TCP, variable=self.cfgTurnConnType).grid(row=row, column=1, sticky=tk.W, padx=6) 
     278        row += 1 
     279        ttk.Label(frm, text='TURN username:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     280        ttk.Entry(frm, textvariable=self.cfgTurnUser, width=16).grid(row=row, column=1, sticky=tk.W, padx=6) 
     281        row += 1 
     282        ttk.Label(frm, text='TURN password:').grid(row=row, column=0, sticky=tk.E, pady=2) 
     283        ttk.Entry(frm, textvariable=self.cfgTurnPasswd, show='*', width=16).grid(row=row, column=1, sticky=tk.W, padx=6) 
     284 
     285        self.wTab.add(frm, text='NAT settings') 
     286 
     287    def onOk(self): 
     288        # Check basic settings 
     289        errors = ""; 
     290        if not self.cfgAccId.get(): 
     291            errors += "Account ID is required\n" 
     292        if self.cfgAccId.get(): 
     293            if not endpoint.validateSipUri(self.cfgAccId.get()): 
     294                errors += "Invalid SIP ID URI: '%s'\n" % (self.cfgAccId.get()) 
     295        if self.cfgRegistrar.get(): 
     296            if not endpoint.validateSipUri(self.cfgRegistrar.get()): 
     297                errors += "Invalid SIP registrar URI: '%s'\n" % (self.cfgRegistrar.get()) 
     298        if self.cfgProxy.get(): 
     299            if not endpoint.validateSipUri(self.cfgProxy.get()): 
     300                errors += "Invalid SIP proxy URI: '%s'\n" % (self.cfgProxy.get()) 
     301        if self.cfgTurnEnabled.get(): 
     302            if not self.cfgTurnServer.get(): 
     303                errors += "TURN server is required\n" 
     304        if errors: 
     305            msgbox.showerror("Error detected:", errors) 
     306            return 
     307 
     308        # Basic settings 
     309        self.cfg.priority = self.cfgPriority.get() 
     310        self.cfg.idUri = self.cfgAccId.get() 
     311        self.cfg.regConfig.registrarUri = self.cfgRegistrar.get() 
     312        self.cfg.regConfig.registerOnAdd = self.cfgRegisterOnAdd.get() 
     313        while len(self.cfg.sipConfig.authCreds): 
     314            self.cfg.sipConfig.authCreds.pop() 
     315        if self.cfgUsername.get(): 
     316            cred = pj.AuthCredInfo() 
     317            cred.scheme = "digest" 
     318            cred.realm = "*" 
     319            cred.username = self.cfgUsername.get() 
     320            cred.data = self.cfgPassword.get() 
     321            self.cfg.sipConfig.authCreds.append(cred) 
     322        while len(self.cfg.sipConfig.proxies): 
     323            self.cfg.sipConfig.proxies.pop() 
     324        if self.cfgProxy.get(): 
     325            self.cfg.sipConfig.proxies.append(self.cfgProxy.get()) 
     326 
     327        # SIP features 
     328        self.cfg.callConfig.prackUse            = self.cfgPrackUse.get() 
     329        self.cfg.callConfig.timerUse            = self.cfgTimerUse.get() 
     330        self.cfg.callConfig.timerSessExpiresSec = self.cfgTimerExpires.get() 
     331        self.cfg.presConfig.publishEnabled      = self.cfgPublish.get() 
     332        self.cfg.mwiConfig.enabled              = self.cfgMwiEnabled.get() 
     333        self.cfg.natConfig.contactRewriteUse    = 1 if self.cfgEnableContactRewrite.get() else 0 
     334        self.cfg.natConfig.viaRewriteUse        = 1 if self.cfgEnableViaRewrite.get() else 0 
     335        self.cfg.natConfig.sdpNatRewriteUse     = 1 if self.cfgEnableSdpRewrite.get() else 0 
     336        self.cfg.natConfig.sipOutboundUse       = 1 if self.cfgEnableSipOutbound.get() else 0 
     337        self.cfg.natConfig.udpKaIntervalSec     = self.cfgKaInterval.get() 
     338 
     339        # Media 
     340        self.cfg.mediaConfig.transportConfig.port       = self.cfgMedPort.get() 
     341        self.cfg.mediaConfig.transportConfig.portRange  = self.cfgMedPortRange.get() 
     342        self.cfg.mediaConfig.lockCodecEnabled           = self.cfgMedLockCodec.get() 
     343        self.cfg.mediaConfig.srtpUse                    = self.cfgMedSrtp.get() 
     344        self.cfg.mediaConfig.srtpSecureSignaling        = self.cfgMedSrtpSecure.get() 
     345        self.cfg.mediaConfig.ipv6Use                    = pj.PJSUA_IPV6_ENABLED if self.cfgMedIpv6.get() else pj.PJSUA_IPV6_DISABLED 
     346 
     347        # NAT 
     348        self.cfg.natConfig.sipStunUse           = self.cfgSipUseStun.get() 
     349        self.cfg.natConfig.mediaStunUse         = self.cfgMediaUseStun.get() 
     350        self.cfg.natConfig.iceEnabled           = self.cfgIceEnabled.get() 
     351        self.cfg.natConfig.iceAggressiveNomination = self.cfgIceAggressive .get() 
     352        self.cfg.natConfig.iceAlwaysUpdate      = self.cfgAlwaysUpdate.get() 
     353        self.cfg.natConfig.iceMaxHostCands      = 0 if self.cfgIceNoHostCands.get() else -1 
     354        self.cfg.natConfig.turnEnabled          = self.cfgTurnEnabled.get() 
     355        self.cfg.natConfig.turnServer           = self.cfgTurnServer.get() 
     356        self.cfg.natConfig.turnConnType         = self.cfgTurnConnType.get() 
     357        self.cfg.natConfig.turnUserName         = self.cfgTurnUser.get() 
     358        self.cfg.natConfig.turnPasswordType     = 0 
     359        self.cfg.natConfig.turnPassword         = self.cfgTurnPasswd.get() 
     360 
     361        self.isOk = True 
     362        self.destroy() 
     363 
     364    def onCancel(self): 
     365        self.destroy() 
    366366 
    367367 
    368368if __name__ == '__main__': 
    369         application.main() 
     369    application.main() 
Note: See TracChangeset for help on using the changeset viewer.