| # $Id$ |
| # |
| # Sample and simple Python script to make and receive calls, and do |
| # presence and instant messaging/IM using PJSUA-API binding for Python. |
| # |
| # Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org> |
| # |
| import py_pjsua |
| import sys |
| import thread |
| |
| # |
| # Configurations |
| # |
| THIS_FILE = "pjsua_app.py" |
| C_QUIT = 0 |
| C_LOG_LEVEL = 4 |
| |
| # STUN config. |
| # Set C_STUN_HOST to the address:port of the STUN server to enable STUN |
| # |
| C_STUN_HOST = "" |
| #C_STUN_HOST = "192.168.0.2" |
| #C_STUN_HOST = "stun.iptel.org:3478" |
| |
| # SIP port |
| C_SIP_PORT = 5060 |
| |
| |
| # Globals |
| # |
| g_ua_cfg = None |
| g_acc_id = py_pjsua.PJSUA_INVALID_ID |
| g_current_call = py_pjsua.PJSUA_INVALID_ID |
| g_wav_files = [] |
| g_wav_id = 0 |
| g_wav_port = 0 |
| g_rec_file = "" |
| g_rec_id = 0 |
| g_rec_port = 0 |
| |
| # Utility: display PJ error and exit |
| # |
| def err_exit(title, rc): |
| py_pjsua.perror(THIS_FILE, title, rc) |
| py_pjsua.destroy() |
| exit(1) |
| |
| |
| # Logging function (also callback, called by pjsua-lib) |
| # |
| def log_cb(level, str, len): |
| if level <= C_LOG_LEVEL: |
| print str, |
| |
| def write_log(level, str): |
| log_cb(level, str + "\n", 0) |
| |
| |
| # Utility to get call info |
| # |
| def call_name(call_id): |
| ci = py_pjsua.call_get_info(call_id) |
| return "[Call " + `call_id` + " " + ci.remote_info + "]" |
| |
| # Callback when call state has changed. |
| # |
| def on_call_state(call_id, e): |
| global g_current_call |
| ci = py_pjsua.call_get_info(call_id) |
| write_log(3, call_name(call_id) + " state = " + `ci.state_text`) |
| if ci.state == py_pjsua.PJSIP_INV_STATE_DISCONNECTED: |
| g_current_call = py_pjsua.PJSUA_INVALID_ID |
| |
| # Callback for incoming call |
| # |
| def on_incoming_call(acc_id, call_id, rdata): |
| global g_current_call |
| |
| if g_current_call != py_pjsua.PJSUA_INVALID_ID: |
| # There's call in progress - answer Busy |
| py_pjsua.call_answer(call_id, 486, None, None) |
| return |
| |
| g_current_call = call_id |
| ci = py_pjsua.call_get_info(call_id) |
| write_log(3, "*** Incoming call: " + call_name(call_id) + "***") |
| write_log(3, "*** Press a to answer or h to hangup ***") |
| |
| |
| |
| # Callback when media state has changed (e.g. established or terminated) |
| # |
| def on_call_media_state(call_id): |
| ci = py_pjsua.call_get_info(call_id) |
| if ci.media_status == py_pjsua.PJSUA_CALL_MEDIA_ACTIVE: |
| py_pjsua.conf_connect(ci.conf_slot, 0) |
| py_pjsua.conf_connect(0, ci.conf_slot) |
| write_log(3, call_name(call_id) + ": media is active") |
| else: |
| write_log(3, call_name(call_id) + ": media is inactive") |
| |
| |
| # Callback when account registration state has changed |
| # |
| def on_reg_state(acc_id): |
| acc_info = py_pjsua.acc_get_info(acc_id) |
| if acc_info.has_registration != 0: |
| cmd = "registration" |
| else: |
| cmd = "unregistration" |
| if acc_info.status != 0 and acc_info.status != 200: |
| write_log(3, "Account " + cmd + " failed: rc=" + `acc_info.status` + " " + acc_info.status_text) |
| else: |
| write_log(3, "Account " + cmd + " success") |
| |
| |
| # Callback when buddy's presence state has changed |
| # |
| def on_buddy_state(buddy_id): |
| write_log(3, "On Buddy state called") |
| buddy_info = py_pjsua.buddy_get_info(buddy_id) |
| if buddy_info.status != 0 and buddy_info.status != 200: |
| write_log(3, "Status of " + `buddy_info.uri` + " is " + `buddy_info.status_text`) |
| else: |
| write_log(3, "Status : " + `buddy_info.status`) |
| |
| # Callback on incoming pager (MESSAGE) |
| # |
| def on_pager(call_id, strfrom, strto, contact, mime_type, text): |
| write_log(3, "MESSAGE from " + `strfrom` + " : " + `text`) |
| |
| |
| # Callback on the delivery status of outgoing pager (MESSAGE) |
| # |
| def on_pager_status(call_id, strto, body, user_data, status, reason): |
| write_log(3, "MESSAGE to " + `strto` + " status " + `status` + " reason " + `reason`) |
| |
| |
| # Received typing indication |
| # |
| def on_typing(call_id, strfrom, to, contact, is_typing): |
| str_t = "" |
| if is_typing: |
| str_t = "is typing.." |
| else: |
| str_t = "has stopped typing" |
| write_log(3, "IM indication: " + strfrom + " " + str_t) |
| |
| # Received the status of previous call transfer request |
| # |
| def on_call_transfer_status(call_id,status_code,status_text,final,p_cont): |
| strfinal = "" |
| if final == 1: |
| strfinal = "[final]" |
| |
| write_log(3, "Call " + `call_id` + ": transfer status= " + `status_code` + " " + status_text+ " " + strfinal) |
| |
| if status_code/100 == 2: |
| write_log(3, "Call " + `call_id` + " : call transfered successfully, disconnecting call") |
| status = py_pjsua.call_hangup(call_id, 410, None, None) |
| p_cont = 0 |
| |
| # Callback on incoming call transfer request |
| # |
| def on_call_transfer_request(call_id, dst, code): |
| write_log(3, "Call transfer request from " + `call_id` + " to " + dst + " with code " + `code`) |
| |
| # |
| # Initialize pjsua. |
| # |
| def app_init(): |
| global g_acc_id, g_ua_cfg |
| |
| # Create pjsua before anything else |
| status = py_pjsua.create() |
| if status != 0: |
| err_exit("pjsua create() error", status) |
| |
| # Create and initialize logging config |
| log_cfg = py_pjsua.logging_config_default() |
| log_cfg.level = C_LOG_LEVEL |
| log_cfg.cb = log_cb |
| |
| # Create and initialize pjsua config |
| # Note: for this Python module, thread_cnt must be 0 since Python |
| # doesn't like to be called from alien thread (pjsua's thread |
| # in this case) |
| ua_cfg = py_pjsua.config_default() |
| ua_cfg.thread_cnt = 0 |
| ua_cfg.user_agent = "PJSUA/Python 0.1" |
| ua_cfg.cb.on_incoming_call = on_incoming_call |
| ua_cfg.cb.on_call_media_state = on_call_media_state |
| ua_cfg.cb.on_reg_state = on_reg_state |
| ua_cfg.cb.on_call_state = on_call_state |
| ua_cfg.cb.on_buddy_state = on_buddy_state |
| ua_cfg.cb.on_pager = on_pager |
| ua_cfg.cb.on_pager_status = on_pager_status |
| ua_cfg.cb.on_typing = on_typing |
| ua_cfg.cb.on_call_transfer_status = on_call_transfer_status |
| ua_cfg.cb.on_call_transfer_request = on_call_transfer_request |
| |
| # Configure STUN setting |
| if C_STUN_HOST != "": |
| ua_cfg.stun_host = C_STUN_HOST; |
| |
| # Create and initialize media config |
| med_cfg = py_pjsua.media_config_default() |
| med_cfg.ec_tail_len = 0 |
| |
| # |
| # Initialize pjsua!! |
| # |
| status = py_pjsua.init(ua_cfg, log_cfg, med_cfg) |
| if status != 0: |
| err_exit("pjsua init() error", status) |
| |
| # Configure UDP transport config |
| transport_cfg = py_pjsua.transport_config_default() |
| transport_cfg.port = C_SIP_PORT |
| |
| # Create UDP transport |
| status, transport_id = \ |
| py_pjsua.transport_create(py_pjsua.PJSIP_TRANSPORT_UDP, transport_cfg) |
| if status != 0: |
| err_exit("Error creating UDP transport", status) |
| |
| |
| # Create initial default account |
| status, acc_id = py_pjsua.acc_add_local(transport_id, 1) |
| if status != 0: |
| err_exit("Error creating account", status) |
| |
| g_acc_id = acc_id |
| g_ua_cfg = ua_cfg |
| |
| # Add SIP account interractively |
| # |
| def add_account(): |
| global g_acc_id |
| |
| acc_domain = "" |
| acc_username = "" |
| acc_passwd ="" |
| confirm = "" |
| |
| # Input account configs |
| print "Your SIP domain (e.g. myprovider.com): ", |
| acc_domain = sys.stdin.readline() |
| if acc_domain == "\n": |
| return |
| acc_domain = acc_domain.replace("\n", "") |
| |
| print "Your username (e.g. alice): ", |
| acc_username = sys.stdin.readline() |
| if acc_username == "\n": |
| return |
| acc_username = acc_username.replace("\n", "") |
| |
| print "Your password (e.g. secret): ", |
| acc_passwd = sys.stdin.readline() |
| if acc_passwd == "\n": |
| return |
| acc_passwd = acc_passwd.replace("\n", "") |
| |
| # Configure account configuration |
| acc_cfg = py_pjsua.acc_config_default() |
| acc_cfg.id = "sip:" + acc_username + "@" + acc_domain |
| acc_cfg.reg_uri = "sip:" + acc_domain |
| |
| cred_info = py_pjsua.Pjsip_Cred_Info() |
| cred_info.realm = "*" |
| cred_info.scheme = "digest" |
| cred_info.username = acc_username |
| cred_info.data_type = 0 |
| cred_info.data = acc_passwd |
| |
| acc_cfg.cred_info.append(1) |
| acc_cfg.cred_info[0] = cred_info |
| |
| # Add new SIP account |
| status, acc_id = py_pjsua.acc_add(acc_cfg, 1) |
| if status != 0: |
| py_pjsua.perror(THIS_FILE, "Error adding SIP account", status) |
| else: |
| g_acc_id = acc_id |
| write_log(3, "Account " + acc_cfg.id + " added") |
| |
| def add_player(): |
| global g_wav_files |
| global g_wav_id |
| global g_wav_port |
| |
| file_name = "" |
| status = -1 |
| wav_id = 0 |
| |
| print "Enter the path of the file player(e.g. /tmp/audio.wav): ", |
| file_name = sys.stdin.readline() |
| if file_name == "\n": |
| return |
| file_name = file_name.replace("\n", "") |
| status, wav_id = py_pjsua.player_create(file_name, 0) |
| if status != 0: |
| py_pjsua.perror(THIS_FILE, "Error adding file player ", status) |
| else: |
| g_wav_files.append(file_name) |
| if g_wav_id == 0: |
| g_wav_id = wav_id |
| g_wav_port = py_pjsua.player_get_conf_port(wav_id) |
| write_log(3, "File player " + file_name + " added") |
| |
| def add_recorder(): |
| global g_rec_file |
| global g_rec_id |
| global g_rec_port |
| |
| file_name = "" |
| status = -1 |
| rec_id = 0 |
| |
| print "Enter the path of the file recorder(e.g. /tmp/audio.wav): ", |
| file_name = sys.stdin.readline() |
| if file_name == "\n": |
| return |
| file_name = file_name.replace("\n", "") |
| status, rec_id = py_pjsua.recorder_create(file_name, 0, None, 0, 0) |
| if status != 0: |
| py_pjsua.perror(THIS_FILE, "Error adding file recorder ", status) |
| else: |
| g_rec_file = file_name |
| g_rec_id = rec_id |
| g_rec_port = py_pjsua.recorder_get_conf_port(rec_id) |
| write_log(3, "File recorder " + file_name + " added") |
| |
| def conf_list(): |
| ports = None |
| print "Conference ports : " |
| ports = py_pjsua.enum_conf_ports() |
| |
| for port in ports: |
| info = None |
| info = py_pjsua.conf_get_port_info(port) |
| txlist = "" |
| for listener in info.listeners: |
| txlist = txlist + "#" + `listener` + " " |
| |
| print "Port #" + `info.slot_id` + "[" + `(info.clock_rate/1000)` + "KHz/" + `(info.samples_per_frame * 1000 / info.clock_rate)` + "ms] " + info.name + " transmitting to: " + txlist |
| |
| def connect_port(): |
| src_port = 0 |
| dst_port = 0 |
| |
| print "Connect src port # (empty to cancel): " |
| src_port = sys.stdin.readline() |
| if src_port == "\n": |
| return |
| src_port = src_port.replace("\n", "") |
| src_port = int(src_port) |
| print "To dst port # (empty to cancel): " |
| dst_port = sys.stdin.readline() |
| if dst_port == "\n": |
| return |
| dst_port = dst_port.replace("\n", "") |
| dst_port = int(dst_port) |
| status = py_pjsua.conf_connect(src_port, dst_port) |
| if status != 0: |
| py_pjsua.perror(THIS_FILE, "Error connecting port ", status) |
| else: |
| write_log(3, "Port connected from " + `src_port` + " to " + `dst_port`) |
| |
| def disconnect_port(): |
| src_port = 0 |
| dst_port = 0 |
| |
| print "Disconnect src port # (empty to cancel): " |
| src_port = sys.stdin.readline() |
| if src_port == "\n": |
| return |
| src_port = src_port.replace("\n", "") |
| src_port = int(src_port) |
| print "From dst port # (empty to cancel): " |
| dst_port = sys.stdin.readline() |
| if dst_port == "\n": |
| return |
| dst_port = dst_port.replace("\n", "") |
| dst_port = int(dst_port) |
| status = py_pjsua.conf_disconnect(src_port, dst_port) |
| if status != 0: |
| py_pjsua.perror(THIS_FILE, "Error disconnecting port ", status) |
| else: |
| write_log(3, "Port disconnected " + `src_port` + " from " + `dst_port`) |
| |
| def dump_call_quality(): |
| global g_current_call |
| |
| buf = "" |
| if g_current_call != -1: |
| buf = py_pjsua.call_dump(g_current_call, 1, 1024, " ") |
| write_log(3, "\n" + buf) |
| else: |
| write_log(3, "No current call") |
| |
| def xfer_call(): |
| global g_current_call |
| |
| if g_current_call == -1: |
| |
| write_log(3, "No current call") |
| |
| else: |
| call = g_current_call |
| ci = py_pjsua.call_get_info(g_current_call) |
| print "Transfering current call ["+ `g_current_call` + "] " + ci.remote_info |
| print "Enter sip url : " |
| url = sys.stdin.readline() |
| if url == "\n": |
| return |
| url = url.replace("\n", "") |
| if call != g_current_call: |
| print "Call has been disconnected" |
| return |
| msg_data = py_pjsua.msg_data_init() |
| status = py_pjsua.call_xfer(g_current_call, url, msg_data); |
| if status != 0: |
| py_pjsua.perror(THIS_FILE, "Error transfering call ", status) |
| else: |
| write_log(3, "Call transfered to " + url) |
| |
| def xfer_call_replaces(): |
| if g_current_call == -1: |
| write_log(3, "No current call") |
| else: |
| call = g_current_call |
| |
| ids = py_pjsua.enum_calls() |
| if len(ids) <= 1: |
| print "There are no other calls" |
| return |
| |
| ci = py_pjsua.call_get_info(g_current_call) |
| print "Transfer call [" + `g_current_call` + "] " + ci.remote_info + " to one of the following:" |
| for i in range(0, len(ids)): |
| if ids[i] == call: |
| continue |
| call_info = py_pjsua.call_get_info(ids[i]) |
| print `ids[i]` + " " + call_info.remote_info + " [" + call_info.state_text + "]" |
| |
| print "Enter call number to be replaced : " |
| buf = sys.stdin.readline() |
| buf = buf.replace("\n","") |
| if buf == "": |
| return |
| dst_call = int(buf) |
| |
| if call != g_current_call: |
| print "Call has been disconnected" |
| return |
| |
| if dst_call == call: |
| print "Destination call number must not be the same as the call being transfered" |
| return |
| |
| if dst_call >= py_pjsua.PJSUA_MAX_CALLS: |
| print "Invalid destination call number" |
| return |
| |
| if py_pjsua.call_is_active(dst_call) == 0: |
| print "Invalid destination call number" |
| return |
| |
| py_pjsua.call_xfer_replaces(call, dst_call, 0, None) |
| |
| # |
| # Worker thread function. |
| # Python doesn't like it when it's called from an alien thread |
| # (pjsua's worker thread, in this case), so for Python we must |
| # disable worker thread in pjsua and poll pjsua from Python instead. |
| # |
| def worker_thread_main(arg): |
| global C_QUIT |
| thread_desc = 0; |
| status = py_pjsua.thread_register("python worker", thread_desc) |
| if status != 0: |
| py_pjsua.perror(THIS_FILE, "Error registering thread", status) |
| else: |
| while C_QUIT == 0: |
| py_pjsua.handle_events(50) |
| print "Worker thread quitting.." |
| C_QUIT = 2 |
| |
| |
| # Start pjsua |
| # |
| def app_start(): |
| # Done with initialization, start pjsua!! |
| # |
| status = py_pjsua.start() |
| if status != 0: |
| err_exit("Error starting pjsua!", status) |
| |
| # Start worker thread |
| thr = thread.start_new(worker_thread_main, (0,)) |
| |
| print "PJSUA Started!!" |
| |
| |
| # Print account and buddy list |
| def print_acc_buddy_list(): |
| global g_acc_id |
| |
| acc_ids = py_pjsua.enum_accs() |
| print "Account list:" |
| for acc_id in acc_ids: |
| acc_info = py_pjsua.acc_get_info(acc_id) |
| if acc_info.has_registration == 0: |
| acc_status = acc_info.status_text |
| else: |
| acc_status = `acc_info.status` + "/" + acc_info.status_text + " (expires=" + `acc_info.expires` + ")" |
| |
| if acc_id == g_acc_id: |
| print " *", |
| else: |
| print " ", |
| |
| print "[" + `acc_id` + "] " + acc_info.acc_uri + ": " + acc_status |
| print " Presence status: ", |
| if acc_info.online_status != 0: |
| print "Online" |
| else: |
| print "Invisible" |
| |
| if py_pjsua.get_buddy_count() > 0: |
| print "" |
| print "Buddy list:" |
| buddy_ids = py_pjsua.enum_buddies() |
| for buddy_id in buddy_ids: |
| bi = py_pjsua.buddy_get_info(buddy_id) |
| print " [" + `buddy_id` + "] " + bi.status_text + " " + bi.uri |
| |
| |
| # Print application menu |
| # |
| def print_menu(): |
| print "" |
| print ">>>" |
| print_acc_buddy_list() |
| print """ |
| +============================================================================+ |
| | Call Commands : | Buddy, IM & Presence: | Account: | |
| | | | | |
| | m Make call | +b Add buddy | +a Add account | |
| | a Answer current call | -b Delete buddy | -a Delete accnt | |
| | h Hangup current call | | | |
| | H Hold call | i Send instant message | rr register | |
| | v re-inVite (release Hold) | s Subscribe presence | ru Unregister | |
| | # Send DTMF string | u Unsubscribe presence | | |
| | dq Dump curr. call quality | t ToGgle Online status | | |
| | +--------------------------+------------------+ |
| | x Xfer call | Media Commands: | Status: | |
| | X Xfer with Replaces | | | |
| | | cl List ports | d Dump status | |
| | | cc Connect port | dd Dump detail | |
| | | cd Disconnect port | | |
| | | +p Add file player | | |
| |------------------------------+ +r Add file recorder | | |
| | q Quit application | | | |
| +============================================================================+""" |
| print "You have " + `py_pjsua.call_get_count()` + " active call(s)" |
| print ">>>", |
| |
| # Menu |
| # |
| def app_menu(): |
| global g_acc_id |
| global g_current_call |
| |
| quit = 0 |
| while quit == 0: |
| print_menu() |
| choice = sys.stdin.readline() |
| |
| if choice[0] == "q": |
| quit = 1 |
| |
| elif choice[0] == "i": |
| # Sending IM |
| print "Send IM to SIP URL: ", |
| url = sys.stdin.readline() |
| if url == "\n": |
| continue |
| |
| # Send typing indication |
| py_pjsua.im_typing(g_acc_id, url, 1, None) |
| |
| print "The content: ", |
| message = sys.stdin.readline() |
| if message == "\n": |
| py_pjsua.im_typing(g_acc_id, url, 0, None) |
| continue |
| |
| # Send the IM! |
| py_pjsua.im_send(g_acc_id, url, None, message, None, 0) |
| |
| elif choice[0] == "m": |
| # Make call |
| print "Using account ", g_acc_id |
| print "Make call to SIP URL: ", |
| url = sys.stdin.readline() |
| url = url.replace("\n", "") |
| if url == "": |
| continue |
| |
| # Initiate the call! |
| status, call_id = py_pjsua.call_make_call(g_acc_id, url, 0, 0, None) |
| |
| if status != 0: |
| py_pjsua.perror(THIS_FILE, "Error making call", status) |
| else: |
| g_current_call = call_id |
| |
| elif choice[0] == "+" and choice[1] == "b": |
| # Add new buddy |
| bc = py_pjsua.Buddy_Config() |
| print "Buddy URL: ", |
| bc.uri = sys.stdin.readline() |
| if bc.uri == "\n": |
| continue |
| |
| bc.uri = bc.uri.replace("\n", "") |
| bc.subscribe = 1 |
| status, buddy_id = py_pjsua.buddy_add(bc) |
| if status != 0: |
| py_pjsua.perror(THIS_FILE, "Error adding buddy", status) |
| elif choice[0] == "-" and choice[1] == "b": |
| print "Enter buddy ID to delete : " |
| buf = sys.stdin.readline() |
| buf = buf.replace("\n","") |
| if buf == "": |
| continue |
| i = int(buf) |
| if py_pjsua.buddy_is_valid(i) == 0: |
| print "Invalid buddy id " + `i` |
| else: |
| py_pjsua.buddy_del(i) |
| print "Buddy " + `i` + " deleted" |
| elif choice[0] == "+" and choice[1] == "a": |
| # Add account |
| add_account() |
| elif choice[0] == "-" and choice[1] == "a": |
| print "Enter account ID to delete : " |
| buf = sys.stdin.readline() |
| buf = buf.replace("\n","") |
| if buf == "": |
| continue |
| i = int(buf) |
| |
| if py_pjsua.acc_is_valid(i) == 0: |
| print "Invalid account id " + `i` |
| else: |
| py_pjsua.acc_del(i) |
| print "Account " + `i` + " deleted" |
| |
| elif choice[0] == "+" and choice[1] == "p": |
| add_player() |
| elif choice[0] == "+" and choice[1] == "r": |
| add_recorder() |
| elif choice[0] == "c" and choice[1] == "l": |
| conf_list() |
| elif choice[0] == "c" and choice[1] == "c": |
| connect_port() |
| elif choice[0] == "c" and choice[1] == "d": |
| disconnect_port() |
| elif choice[0] == "d" and choice[1] == "q": |
| dump_call_quality() |
| elif choice[0] == "x": |
| xfer_call() |
| elif choice[0] == "X": |
| xfer_call_replaces() |
| elif choice[0] == "h": |
| if g_current_call != py_pjsua.PJSUA_INVALID_ID: |
| py_pjsua.call_hangup(g_current_call, 603, None, None) |
| else: |
| print "No current call" |
| elif choice[0] == "H": |
| if g_current_call != py_pjsua.PJSUA_INVALID_ID: |
| py_pjsua.call_set_hold(g_current_call, None) |
| |
| else: |
| print "No current call" |
| elif choice[0] == "v": |
| if g_current_call != py_pjsua.PJSUA_INVALID_ID: |
| |
| py_pjsua.call_reinvite(g_current_call, 1, None); |
| |
| else: |
| print "No current call" |
| elif choice[0] == "#": |
| if g_current_call == py_pjsua.PJSUA_INVALID_ID: |
| print "No current call" |
| elif py_pjsua.call_has_media(g_current_call) == 0: |
| print "Media is not established yet!" |
| else: |
| call = g_current_call |
| print "DTMF strings to send (0-9*#A-B)" |
| buf = sys.stdin.readline() |
| buf = buf.replace("\n", "") |
| if buf == "": |
| continue |
| if call != g_current_call: |
| print "Call has been disconnected" |
| continue |
| status = py_pjsua.call_dial_dtmf(g_current_call, buf) |
| if status != 0: |
| py_pjsua.perror(THIS_FILE, "Unable to send DTMF", status); |
| else: |
| print "DTMF digits enqueued for transmission" |
| elif choice[0] == "s": |
| print "Subscribe presence of (buddy id) : " |
| buf = sys.stdin.readline() |
| buf = buf.replace("\n","") |
| if buf == "": |
| continue |
| i = int(buf) |
| py_pjsua.buddy_subscribe_pres(i, 1) |
| elif choice[0] == "u": |
| print "Unsubscribe presence of (buddy id) : " |
| buf = sys.stdin.readline() |
| buf = buf.replace("\n","") |
| if buf == "": |
| continue |
| i = int(buf) |
| py_pjsua.buddy_subscribe_pres(i, 0) |
| elif choice[0] == "t": |
| acc_info = py_pjsua.acc_get_info(g_acc_id) |
| if acc_info.online_status == 0: |
| acc_info.online_status = 1 |
| else: |
| acc_info.online_status = 0 |
| py_pjsua.acc_set_online_status(g_acc_id, acc_info.online_status) |
| st = "" |
| if acc_info.online_status == 0: |
| st = "offline" |
| else: |
| st = "online" |
| print "Setting " + acc_info.acc_uri + " online status to " + st |
| elif choice[0] == "r": |
| if choice[1] == "r": |
| py_pjsua.acc_set_registration(g_acc_id, 1) |
| elif choice[1] == "u": |
| py_pjsua.acc_set_registration(g_acc_id, 0) |
| elif choice[0] == "d": |
| py_pjsua.dump(choice[1] == "d") |
| elif choice[0] == "a": |
| if g_current_call != py_pjsua.PJSUA_INVALID_ID: |
| |
| py_pjsua.call_answer(g_current_call, 200, None, None) |
| else: |
| print "No current call" |
| |
| |
| # |
| # main |
| # |
| app_init() |
| app_start() |
| app_menu() |
| |
| # |
| # Done, quitting.. |
| # |
| print "PJSUA shutting down.." |
| C_QUIT = 1 |
| # Give the worker thread chance to quit itself |
| while C_QUIT != 2: |
| py_pjsua.handle_events(50) |
| |
| print "PJSUA destroying.." |
| py_pjsua.destroy() |
| |