blob: 89cbb1c067f977c84c4b5af1acc954022d72a072 [file] [log] [blame]
Benny Prijono55040452008-07-21 18:20:57 +00001# $Id$
Benny Prijono9c461142008-07-10 22:41:20 +00002#
3# SIP call sample.
4#
5# Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6#
Benny Prijonoec72b6e2008-07-24 09:01:33 +00007# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20#
Benny Prijono9c461142008-07-10 22:41:20 +000021import sys
22import pjsua as pj
23
24LOG_LEVEL=3
25current_call = None
26
27# Logging callback
28def log_cb(level, str, len):
29 print str,
30
31
32# Callback to receive events from account
33class MyAccountCallback(pj.AccountCallback):
34
Benny Prijono55040452008-07-21 18:20:57 +000035 def __init__(self, account=None):
Benny Prijono9c461142008-07-10 22:41:20 +000036 pj.AccountCallback.__init__(self, account)
37
38 # Notification on incoming call
39 def on_incoming_call(self, call):
40 global current_call
Benny Prijono9c461142008-07-10 22:41:20 +000041 if current_call:
42 call.answer(486, "Busy")
43 return
44
45 print "Incoming call from ", call.info().remote_uri
46 print "Press 'a' to answer"
47
48 current_call = call
49
50 call_cb = MyCallCallback(current_call)
51 current_call.set_callback(call_cb)
52
53 current_call.answer(180)
54
55
56# Callback to receive events from Call
57class MyCallCallback(pj.CallCallback):
58
Benny Prijono55040452008-07-21 18:20:57 +000059 def __init__(self, call=None):
Benny Prijono9c461142008-07-10 22:41:20 +000060 pj.CallCallback.__init__(self, call)
61
62 # Notification when call state has changed
63 def on_state(self):
64 global current_call
Benny Prijono9c461142008-07-10 22:41:20 +000065 print "Call with", self.call.info().remote_uri,
66 print "is", self.call.info().state_text,
67 print "last code =", self.call.info().last_code,
68 print "(" + self.call.info().last_reason + ")"
69
70 if self.call.info().state == pj.CallState.DISCONNECTED:
71 current_call = None
Benny Prijono55040452008-07-21 18:20:57 +000072 print 'Current call is', current_call
Benny Prijono9c461142008-07-10 22:41:20 +000073
74 # Notification when call's media state has changed.
75 def on_media_state(self):
76 if self.call.info().media_state == pj.MediaState.ACTIVE:
77 # Connect the call to sound device
78 call_slot = self.call.info().conf_slot
79 pj.Lib.instance().conf_connect(call_slot, 0)
80 pj.Lib.instance().conf_connect(0, call_slot)
81 print "Media is now active"
82 else:
83 print "Media is inactive"
84
85# Function to make call
86def make_call(uri):
87 try:
88 print "Making call to", uri
Benny Prijono55040452008-07-21 18:20:57 +000089 return acc.make_call(uri, cb=MyCallCallback())
Benny Prijono9c461142008-07-10 22:41:20 +000090 except pj.Error, e:
Benny Prijono55040452008-07-21 18:20:57 +000091 print "Exception: " + str(e)
Benny Prijono9c461142008-07-10 22:41:20 +000092 return None
93
94
95# Create library instance
96lib = pj.Lib()
97
98try:
99 # Init library with default config and some customized
100 # logging config.
101 lib.init(log_cfg = pj.LogConfig(level=LOG_LEVEL, callback=log_cb))
102
103 # Create UDP transport which listens to any available port
104 transport = lib.create_transport(pj.TransportType.UDP,
105 pj.TransportConfig(0))
106 print "\nListening on", transport.info().host,
107 print "port", transport.info().port, "\n"
108
109 # Start the library
110 lib.start()
111
112 # Create local account
Benny Prijono55040452008-07-21 18:20:57 +0000113 acc = lib.create_account_for_transport(transport, cb=MyAccountCallback())
Benny Prijono9c461142008-07-10 22:41:20 +0000114
115 # If argument is specified then make call to the URI
116 if len(sys.argv) > 1:
Benny Prijono55040452008-07-21 18:20:57 +0000117 lck = lib.auto_lock()
Benny Prijono9c461142008-07-10 22:41:20 +0000118 current_call = make_call(sys.argv[1])
Benny Prijono55040452008-07-21 18:20:57 +0000119 print 'Current call is', current_call
120 del lck
Benny Prijono9c461142008-07-10 22:41:20 +0000121
122 my_sip_uri = "sip:" + transport.info().host + \
123 ":" + str(transport.info().port)
124
125 # Menu loop
126 while True:
127 print "My SIP URI is", my_sip_uri
128 print "Menu: m=make call, h=hangup call, a=answer call, q=quit"
129
130 input = sys.stdin.readline().rstrip("\r\n")
131 if input == "m":
132 if current_call:
133 print "Already have another call"
134 continue
135 print "Enter destination URI to call: ",
136 input = sys.stdin.readline().rstrip("\r\n")
137 if input == "":
138 continue
Benny Prijono55040452008-07-21 18:20:57 +0000139 lck = lib.auto_lock()
Benny Prijono9c461142008-07-10 22:41:20 +0000140 current_call = make_call(input)
Benny Prijono55040452008-07-21 18:20:57 +0000141 del lck
Benny Prijono9c461142008-07-10 22:41:20 +0000142
143 elif input == "h":
144 if not current_call:
145 print "There is no call"
146 continue
147 current_call.hangup()
148
149 elif input == "a":
150 if not current_call:
151 print "There is no call"
152 continue
153 current_call.answer(200)
154
155 elif input == "q":
156 break
157
158 # Shutdown the library
Benny Prijono55040452008-07-21 18:20:57 +0000159 transport = None
160 acc.delete()
161 acc = None
Benny Prijono9c461142008-07-10 22:41:20 +0000162 lib.destroy()
163 lib = None
164
165except pj.Error, e:
166 print "Exception: " + str(e)
167 lib.destroy()
168 lib = None
169