Alexandre Lision | 0e14301 | 2014-01-22 11:02:46 -0500 | [diff] [blame] | 1 | /* $Id: pjsua2_demo.cpp 4708 2014-01-21 10:59:25Z nanang $ */ |
| 2 | /* |
| 3 | * Copyright (C) 2008-2013 Teluu Inc. (http://www.teluu.com) |
| 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation; either version 2 of the License, or |
| 8 | * (at your option) any later version. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software |
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 18 | */ |
| 19 | #include <pjsua2.hpp> |
| 20 | #include <iostream> |
| 21 | #include <memory> |
| 22 | #include <pj/file_access.h> |
| 23 | |
| 24 | using namespace pj; |
| 25 | |
| 26 | class MyAccount; |
| 27 | |
| 28 | class MyCall : public Call |
| 29 | { |
| 30 | private: |
| 31 | MyAccount *myAcc; |
| 32 | |
| 33 | public: |
| 34 | MyCall(Account &acc, int call_id = PJSUA_INVALID_ID) |
| 35 | : Call(acc, call_id) |
| 36 | { |
| 37 | myAcc = (MyAccount *)&acc; |
| 38 | } |
| 39 | |
| 40 | virtual void onCallState(OnCallStateParam &prm); |
| 41 | }; |
| 42 | |
| 43 | class MyAccount : public Account |
| 44 | { |
| 45 | public: |
| 46 | std::vector<Call *> calls; |
| 47 | |
| 48 | public: |
| 49 | MyAccount() |
| 50 | {} |
| 51 | |
| 52 | ~MyAccount() |
| 53 | { |
| 54 | std::cout << "*** Account is being deleted: No of calls=" |
| 55 | << calls.size() << std::endl; |
| 56 | } |
| 57 | |
| 58 | void removeCall(Call *call) |
| 59 | { |
| 60 | for (std::vector<Call *>::iterator it = calls.begin(); |
| 61 | it != calls.end(); ++it) |
| 62 | { |
| 63 | if (*it == call) { |
| 64 | calls.erase(it); |
| 65 | break; |
| 66 | } |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | virtual void onRegState(OnRegStateParam &prm) |
| 71 | { |
| 72 | AccountInfo ai = getInfo(); |
| 73 | std::cout << (ai.regIsActive? "*** Register: code=" : "*** Unregister: code=") |
| 74 | << prm.code << std::endl; |
| 75 | } |
| 76 | |
| 77 | virtual void onIncomingCall(OnIncomingCallParam &iprm) |
| 78 | { |
| 79 | Call *call = new MyCall(*this, iprm.callId); |
| 80 | CallInfo ci = call->getInfo(); |
| 81 | CallOpParam prm; |
| 82 | |
| 83 | std::cout << "*** Incoming Call: " << ci.remoteUri << " [" |
| 84 | << ci.stateText << "]" << std::endl; |
| 85 | |
| 86 | calls.push_back(call); |
| 87 | prm.statusCode = (pjsip_status_code)200; |
| 88 | call->answer(prm); |
| 89 | } |
| 90 | }; |
| 91 | |
| 92 | void MyCall::onCallState(OnCallStateParam &prm) |
| 93 | { |
| 94 | PJ_UNUSED_ARG(prm); |
| 95 | |
| 96 | CallInfo ci = getInfo(); |
| 97 | std::cout << "*** Call: " << ci.remoteUri << " [" << ci.stateText |
| 98 | << "]" << std::endl; |
| 99 | |
| 100 | if (ci.state == PJSIP_INV_STATE_DISCONNECTED) { |
| 101 | myAcc->removeCall(this); |
| 102 | /* Delete the call */ |
| 103 | delete this; |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | static void mainProg1() throw(Error) |
| 108 | { |
| 109 | Endpoint ep; |
| 110 | |
| 111 | // Create library |
| 112 | ep.libCreate(); |
| 113 | |
| 114 | // Init library |
| 115 | EpConfig ep_cfg; |
| 116 | ep_cfg.logConfig.level = 4; |
| 117 | ep.libInit( ep_cfg ); |
| 118 | |
| 119 | // Transport |
| 120 | TransportConfig tcfg; |
| 121 | tcfg.port = 5060; |
| 122 | ep.transportCreate(PJSIP_TRANSPORT_UDP, tcfg); |
| 123 | |
| 124 | // Start library |
| 125 | ep.libStart(); |
| 126 | std::cout << "*** PJSUA2 STARTED ***" << std::endl; |
| 127 | |
| 128 | // Add account |
| 129 | AccountConfig acc_cfg; |
| 130 | acc_cfg.idUri = "sip:test1@pjsip.org"; |
| 131 | acc_cfg.regConfig.registrarUri = "sip:pjsip.org"; |
| 132 | acc_cfg.sipConfig.authCreds.push_back( AuthCredInfo("digest", "*", |
| 133 | "test1", 0, "test1") ); |
| 134 | std::auto_ptr<MyAccount> acc(new MyAccount); |
| 135 | acc->create(acc_cfg); |
| 136 | |
| 137 | pj_thread_sleep(2000); |
| 138 | |
| 139 | // Make outgoing call |
| 140 | Call *call = new MyCall(*acc); |
| 141 | acc->calls.push_back(call); |
| 142 | CallOpParam prm(true); |
| 143 | prm.opt.audioCount = 1; |
| 144 | prm.opt.videoCount = 0; |
| 145 | call->makeCall("sip:test1@pjsip.org", prm); |
| 146 | |
| 147 | // Hangup all calls |
| 148 | pj_thread_sleep(8000); |
| 149 | ep.hangupAllCalls(); |
| 150 | pj_thread_sleep(4000); |
| 151 | |
| 152 | // Destroy library |
| 153 | std::cout << "*** PJSUA2 SHUTTING DOWN ***" << std::endl; |
| 154 | } |
| 155 | |
| 156 | void mainProg2() throw(Error) |
| 157 | { |
| 158 | Endpoint ep; |
| 159 | |
| 160 | // Create library |
| 161 | ep.libCreate(); |
| 162 | |
| 163 | string json_str; |
| 164 | |
| 165 | { |
| 166 | EpConfig epCfg; |
| 167 | JsonDocument jDoc; |
| 168 | |
| 169 | epCfg.uaConfig.maxCalls = 61; |
| 170 | epCfg.uaConfig.userAgent = "Just JSON Test"; |
| 171 | epCfg.uaConfig.stunServer.push_back("stun1.pjsip.org"); |
| 172 | epCfg.uaConfig.stunServer.push_back("stun2.pjsip.org"); |
| 173 | epCfg.logConfig.filename = "THE.LOG"; |
| 174 | |
| 175 | jDoc.writeObject(epCfg); |
| 176 | json_str = jDoc.saveString(); |
| 177 | std::cout << json_str << std::endl << std::endl; |
| 178 | } |
| 179 | |
| 180 | { |
| 181 | EpConfig epCfg; |
| 182 | JsonDocument rDoc; |
| 183 | string output; |
| 184 | |
| 185 | rDoc.loadString(json_str); |
| 186 | rDoc.readObject(epCfg); |
| 187 | |
| 188 | JsonDocument wDoc; |
| 189 | |
| 190 | wDoc.writeObject(epCfg); |
| 191 | json_str = wDoc.saveString(); |
| 192 | std::cout << json_str << std::endl << std::endl; |
| 193 | |
| 194 | wDoc.saveFile("jsontest.js"); |
| 195 | } |
| 196 | |
| 197 | { |
| 198 | EpConfig epCfg; |
| 199 | JsonDocument rDoc; |
| 200 | |
| 201 | rDoc.loadFile("jsontest.js"); |
| 202 | rDoc.readObject(epCfg); |
| 203 | pj_file_delete("jsontest.js"); |
| 204 | } |
| 205 | |
| 206 | ep.libDestroy(); |
| 207 | } |
| 208 | |
| 209 | |
| 210 | void mainProg3() throw(Error) |
| 211 | { |
| 212 | Endpoint ep; |
| 213 | |
| 214 | // Create library |
| 215 | ep.libCreate(); |
| 216 | |
| 217 | // Init library |
| 218 | EpConfig ep_cfg; |
| 219 | ep.libInit( ep_cfg ); |
| 220 | |
| 221 | // Start library |
| 222 | ep.libStart(); |
| 223 | std::cout << "*** PJSUA2 STARTED ***" << std::endl; |
| 224 | |
| 225 | // Create player and recorder |
| 226 | { |
| 227 | AudioMediaPlayer amp; |
| 228 | amp.createPlayer("../../tests/pjsua/wavs/input.16.wav"); |
| 229 | |
| 230 | AudioMediaRecorder amr; |
| 231 | amr.createRecorder("recorder_test_output.wav"); |
| 232 | |
| 233 | amp.startTransmit(ep.audDevManager().getPlaybackDevMedia()); |
| 234 | amp.startTransmit(amr); |
| 235 | |
| 236 | pj_thread_sleep(5000); |
| 237 | } |
| 238 | |
| 239 | ep.libDestroy(); |
| 240 | } |
| 241 | |
| 242 | |
| 243 | void mainProg() throw(Error) |
| 244 | { |
| 245 | Endpoint ep; |
| 246 | |
| 247 | // Create library |
| 248 | ep.libCreate(); |
| 249 | |
| 250 | string json_str; |
| 251 | |
| 252 | { |
| 253 | JsonDocument jdoc; |
| 254 | AccountConfig accCfg; |
| 255 | |
| 256 | accCfg.idUri = "\"Just Test\" <sip:test@pjsip.org>"; |
| 257 | accCfg.regConfig.registrarUri = "sip:pjsip.org"; |
| 258 | SipHeader h; |
| 259 | h.hName = "X-Header"; |
| 260 | h.hValue = "User header"; |
| 261 | accCfg.regConfig.headers.push_back(h); |
| 262 | |
| 263 | accCfg.sipConfig.proxies.push_back("<sip:sip.pjsip.org;transport=tcp>"); |
| 264 | accCfg.sipConfig.proxies.push_back("<sip:sip.pjsip.org;transport=tls>"); |
| 265 | |
| 266 | accCfg.mediaConfig.transportConfig.tlsConfig.ciphers.push_back(1); |
| 267 | accCfg.mediaConfig.transportConfig.tlsConfig.ciphers.push_back(2); |
| 268 | accCfg.mediaConfig.transportConfig.tlsConfig.ciphers.push_back(3); |
| 269 | |
| 270 | AuthCredInfo aci; |
| 271 | aci.scheme = "digest"; |
| 272 | aci.username = "test"; |
| 273 | aci.data = "passwd"; |
| 274 | aci.realm = "*"; |
| 275 | accCfg.sipConfig.authCreds.push_back(aci); |
| 276 | |
| 277 | jdoc.writeObject(accCfg); |
| 278 | json_str = jdoc.saveString(); |
| 279 | std::cout << "Original:" << std::endl; |
| 280 | std::cout << json_str << std::endl << std::endl; |
| 281 | } |
| 282 | |
| 283 | { |
| 284 | JsonDocument rdoc; |
| 285 | |
| 286 | rdoc.loadString(json_str); |
| 287 | AccountConfig accCfg; |
| 288 | rdoc.readObject(accCfg); |
| 289 | |
| 290 | JsonDocument wdoc; |
| 291 | wdoc.writeObject(accCfg); |
| 292 | json_str = wdoc.saveString(); |
| 293 | |
| 294 | std::cout << "Parsed:" << std::endl; |
| 295 | std::cout << json_str << std::endl << std::endl; |
| 296 | } |
| 297 | |
| 298 | ep.libDestroy(); |
| 299 | } |
| 300 | |
| 301 | int main() |
| 302 | { |
| 303 | int ret = 0; |
| 304 | |
| 305 | /* Test endpoint instantiation and destruction without libCreate(), |
| 306 | * libInit() etc. |
| 307 | */ |
| 308 | { |
| 309 | Endpoint ep; |
| 310 | } |
| 311 | |
| 312 | try { |
| 313 | mainProg3(); |
| 314 | std::cout << "Success" << std::endl; |
| 315 | } catch (Error & err) { |
| 316 | std::cout << "Exception: " << err.info() << std::endl; |
| 317 | ret = 1; |
| 318 | } |
| 319 | |
| 320 | return ret; |
| 321 | } |
| 322 | |
| 323 | |