Parent Directory
|
Revision Log
Pass/store rtp information in RtpIpInfo objects. These include the media direction in addition to the ip address and port number.
1 /* 2 * This file is part of Project DiaStar Server. 3 * 4 * More information about this project can be found at: 5 * http://www.projectdiastar.org. 6 * 7 * Copyright (C) 2009,2010 Dialogic Corp. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation; either version 2 12 * of the License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 22 * 02110-1301, USA. 23 * Alternatively see <http://www.gnu.org/licenses/>. 24 * Or see the LICENSE file included within the source tree. 25 * 26 */ 27 28 /*! 29 * \file appdiastar.cxx 30 * \brief Project DiaStar server. Manages all interactions between the Woomera 31 * protocol layer and the Dialogic channel driver. 32 * \author John Tarlton <john.tarlton@dialogic.com> 33 * \author Antony Martin <antony.martin@dialogic.com> 34 * \version 0.1 35 */ 36 37 /*------------------------------ Dependencies --------------------------------*/ 38 39 #include <climits> 40 41 #include <woomera.h> 42 43 #include "logger.h" 44 #include "getoption.h" 45 #include "string-util.h" 46 #include "net-util.h" 47 48 #include <srllib.h> 49 #include <gclib.h> 50 #include <ipmlib.h> 51 52 #include "dialogicchannelmanager.h" 53 #include "appevent.h" 54 #include "appdiastar.h" 55 56 /*----------------------------------------------------------------------------*/ 57 58 /*! 59 * Woomera callback for protocol messages (isdn,sip etc). 60 * Forward message to its dedicated handler function. 61 */ 62 woomera_server_response* protocol_message_handler( woomera_callctlr_command* msg, 63 void* prot_user_data ) 64 { 65 if ( (!msg) || (!prot_user_data) ) 66 { 67 LOGERROR("protocol_message_handler() bad params"); 68 return 0; 69 } 70 71 AppDiaStar* app_woomera = static_cast<AppDiaStar*>(prot_user_data); 72 73 switch ( msg->e ) 74 { 75 case WOOMERA_CALLCTL_COMMAND_MAKE_CALL: 76 return app_woomera->makeCall(msg); 77 78 case WOOMERA_CALLCTL_COMMAND_HANGUP_CALL: 79 return app_woomera->hangupCall(msg); 80 81 case WOOMERA_CALLCTL_COMMAND_ACCEPT_CALL: 82 return app_woomera->acceptCall(msg); 83 84 case WOOMERA_CALLCTL_COMMAND_ANSWER_CALL: 85 return app_woomera->answerCall(msg); 86 87 case WOOMERA_CALLCTL_COMMAND_SEIZE_CALL: 88 /* Not used here */ 89 break; 90 91 case WOOMERA_CALLCTL_COMMAND_DTMF: 92 return app_woomera->sendDtmf(msg); 93 94 case WOOMERA_CALLCTL_COMMAND_PLAY: 95 return app_woomera->play(msg); 96 97 case WOOMERA_CALLCTL_COMMAND_RECORD: 98 return app_woomera->record(msg); 99 100 case WOOMERA_CALLCTL_COMMAND_STOP: 101 return app_woomera->stop(msg); 102 103 case WOOMERA_CALLCTL_COMMAND_UPDATE: 104 return app_woomera->update(msg); 105 106 default: 107 LOGERROR("protocol_message_handler() Got unsupported cmd"); 108 break; 109 } 110 return 0; 111 } 112 113 114 /*! 115 * Protocol definition for Woomera. 116 */ 117 static woomera_protocol_def protocol_def = { 118 0, 119 protocol_message_handler 120 }; 121 122 123 /*! 124 * Callback for Dialogic events. 125 */ 126 void dialogic_event_callback( woomera_server_attr* attr ) 127 { 128 if ( (!attr) || (!attr->user_data) ) 129 { 130 LOGERROR("dialogic_event_callback() bad attr"); 131 return; 132 } 133 134 if ( sr_waitevt(0) < 0 ) 135 { 136 return; 137 } 138 METAEVENT metaevent; 139 if ( gc_GetMetaEvent(&metaevent) != GC_SUCCESS ) 140 { 141 /* serious problem - should never fail. 142 */ 143 LOGERROR("dialogic_event_callback() gc_GetMetaEvent() failed"); 144 } 145 else 146 { 147 DialogicChannelManager* channelMgr; 148 channelMgr = static_cast<DialogicChannelManager*>(attr->user_data); 149 channelMgr->dispatchEvent(metaevent); 150 } 151 } 152 153 154 /* 155 * Callback for ImageMaker events. 156 * Forward the event to its target device (ipm) via the srl event api. 157 */ 158 void imagemaker_event_callback( const ImageMakerThreadResponse* response ) 159 { 160 /* merge response data with the request (event) data */ 161 ImageMakerEvent* imageMakerEvent = static_cast<ImageMakerEvent*>(response->userdata); 162 163 imageMakerEvent->top = response->top; 164 imageMakerEvent->left = response->left; 165 imageMakerEvent->height = response->height; 166 imageMakerEvent->width = response->width; 167 strcpy(imageMakerEvent->filename, response->filename.c_str()); 168 169 if ( response->ok ) 170 { 171 _sr_putevt(imageMakerEvent->dev_handle, 172 APP_IMAGEMAKER_OK, 173 sizeof(ImageMakerEvent), 174 imageMakerEvent, 175 0); 176 } 177 else 178 { 179 _sr_putevt(imageMakerEvent->dev_handle, 180 APP_IMAGEMAKER_FAIL, 181 sizeof(ImageMakerEvent), 182 imageMakerEvent, 183 0); 184 } 185 /* _sr_putevt() has made a copy of the data so the original can be deleted. 186 */ 187 delete imageMakerEvent; 188 } 189 190 191 /* 192 * Callback for RtspConnector events. 193 * Forward the event to its target device (ipm) via the srl event api. 194 */ 195 void rtspconnector_event_callback( RtspEvent* event ) 196 { 197 int device_handle = reinterpret_cast<int>(event->userdata); 198 199 _sr_putevt(device_handle, 200 APP_RTSP_EVENT, 201 sizeof(RtspEvent), 202 event, 203 0); 204 } 205 206 ///////////////////////////////////////////////////////////////////////////// 207 208 /* 209 * This is the application's top level function, it has two modes of operation 210 * which are selected by the 'probe' command line option. When this option is 211 * specified the application performs hardware detection and outputs the results 212 * in an 'ini' file format that may be used for subsequent sessions. If probing 213 * has not been requested the application runs the woomera server. 214 */ 215 bool AppDiaStar::run( const GetOptions& opts, int stop_fd, void(*stop_event_callback)(int) ) 216 { 217 /* 218 * Probe only. 219 */ 220 if ( opts.isFound("probe") ) 221 { 222 DialogicChannelManager* channelMgr = new DialogicChannelManager(*this, config_); 223 if ( !channelMgr->init() ) 224 { 225 delete channelMgr; 226 return false; 227 } 228 229 bool isdn = false; 230 bool ss7 = false; 231 bool h324 = false; 232 233 if ( opts.isFound("isdn") ) 234 { 235 /* dti config will be set for isdn */ 236 isdn = true; 237 ss7 = false; 238 } 239 240 if ( opts.isFound("ss7") ) 241 { 242 /* dti config will be set for ss7 */ 243 isdn = false; 244 ss7 = true; 245 LOGNOTICE("AppDiaStar::run() dk:" << opts.getValue("ss7")); 246 } 247 248 if ( opts.isFound("h324") ) 249 { 250 if ( isdn || ss7 ) 251 { 252 h324 = true; 253 } 254 else 255 { 256 LOGERROR("AppDiaStar::run() option --h324 requires either option --isdn or option --ss7"); 257 } 258 } 259 260 bool res = config_.probe(opts.getValue("conf"), 261 isdn, 262 ss7, 263 opts.getValue("ss7"), 264 h324); 265 delete channelMgr; 266 return res; 267 } 268 269 /* 270 * Normal operation. 271 */ 272 LOGNOTICE("AppDiaStar::run() initialising..."); 273 274 std::string opt_conf = opts.getValue("conf"); 275 276 std::string opt_sdp_address = opts.getValue("sdp-address"); 277 if ( !opt_sdp_address.empty() ) 278 { 279 config_.setSdpContactAddress(opt_sdp_address); 280 } 281 282 /* 283 * Woomera address and port. 284 */ 285 std::string opt_woomera_address = opts.getValue("woomera-address"); 286 if ( opt_woomera_address.empty() ) 287 { 288 if ( !getInterfaceIpv4Addr("eth0", opt_woomera_address) ) 289 { 290 opt_woomera_address = "127.0.0.1"; 291 } 292 } 293 294 std::string opt_woomera_port = opts.getValue("woomera-port"); 295 if ( opt_woomera_port.empty() ) 296 { 297 opt_woomera_port = "42420"; 298 } 299 int port = atoi(opt_woomera_port.c_str()); 300 if ( (port <= 0) || (port > 65535) ) 301 { 302 port = 42420; 303 } 304 305 IpInfo woomera_ipinfo(opt_woomera_address, port); 306 307 /* initialise woomera subsystem. 308 */ 309 woomera_init(); 310 woomeraServer_ = woomera_server_new(); 311 woomeraCallCtlr_ = woomera_callctlr_new(woomera_server_send_event, woomeraServer_); 312 313 woomera_server_set_contact_address(woomeraServer_, woomera_ipinfo.getAddressAndPort().c_str()); 314 315 /* setup exit hander 316 */ 317 woomera_server_set_event(woomeraServer_, stop_fd, stop_event_callback); 318 319 /* Initialise Dialogic and attach to Woomera's event mechanism. 320 * When Woomera detects events on these fdS it will call the function 321 * specified by the callback member of the attr struct that is passed to 322 * woomera_server_run(). 323 */ 324 int nfds = sr_getfdcnt(); 325 int* fdarray = (int*) malloc(sizeof(int) * nfds); 326 sr_getfdinfo(fdarray); 327 for ( int i = 0; i < nfds; i++ ) 328 { 329 woomera_server_set_event(woomeraServer_, fdarray[i], 0); 330 } 331 free(fdarray); 332 333 channelMgr_ = new DialogicChannelManager(*this, config_); 334 if ( !channelMgr_->start(opt_conf) ) 335 { 336 LOGCRIT("AppDiaStar::run() failed to start DialogicChannelManager. Exiting..."); 337 delete channelMgr_; 338 return false; 339 } 340 341 /* 342 * Tell Woomera any extra commands that are available. 343 */ 344 if ( config_.haveMm() ) 345 { 346 woomera_callctlr_allow(woomeraCallCtlr_, WOOMERA_SERVER_PLAY); 347 woomera_callctlr_allow(woomeraCallCtlr_, WOOMERA_SERVER_RECORD); 348 woomera_callctlr_allow(woomeraCallCtlr_, WOOMERA_SERVER_STOP); 349 } 350 351 /* 352 * Tell Woomera which protocols have been configured. 353 */ 354 if ( config_.haveIsdn() ) 355 { 356 woomera_callctlr_add_protocol(woomeraCallCtlr_, &protocol_def, "isdn", this); 357 } 358 if ( config_.haveSs7() ) 359 { 360 woomera_callctlr_add_protocol(woomeraCallCtlr_, &protocol_def, "ss7", this); 361 } 362 if ( config_.haveSip() ) 363 { 364 woomera_callctlr_add_protocol(woomeraCallCtlr_, &protocol_def, "sip", this); 365 } 366 if ( config_.haveConf() ) 367 { 368 woomera_callctlr_add_protocol(woomeraCallCtlr_, &protocol_def, "conf", this); 369 } 370 if ( config_.haveH324() ) 371 { 372 woomera_callctlr_add_protocol(woomeraCallCtlr_, &protocol_def, "h324", this); 373 } 374 375 /* 376 * Set Woomera rtp media format. 377 */ 378 std::string client_audio = config_.getClientAudioFormat(); 379 if ( client_audio == "pcma" ) 380 { 381 woomera_callctlr_set_audio_format(woomeraCallCtlr_, woomera_key_pcma); 382 } 383 else if ( client_audio == "g722" ) 384 { 385 woomera_callctlr_set_audio_format(woomeraCallCtlr_, woomera_key_g722); 386 } 387 else if ( client_audio == "g729" ) 388 { 389 woomera_callctlr_set_audio_format(woomeraCallCtlr_, woomera_key_g729); 390 } 391 else /* pcmu */ 392 { 393 woomera_callctlr_set_audio_format(woomeraCallCtlr_, woomera_key_pcmu); 394 } 395 396 std::string client_video = config_.getClientVideoFormat(); 397 if ( client_video == "h263-1998" ) 398 { 399 woomera_callctlr_set_video_format(woomeraCallCtlr_, woomera_key_h263_1998); 400 } 401 else if ( client_video == "mpv4-es" ) 402 { 403 woomera_callctlr_set_video_format(woomeraCallCtlr_, woomera_key_mp4ves); 404 } 405 else if ( client_video == "h264" ) 406 { 407 woomera_callctlr_set_video_format(woomeraCallCtlr_, woomera_key_h264); 408 } 409 else /* h.263 */ 410 { 411 woomera_callctlr_set_video_format(woomeraCallCtlr_, woomera_key_h263); 412 } 413 414 /* 415 * run the woomera server. 416 */ 417 attr_ = woomera_server_attr_new(); 418 attr_->server = woomeraServer_; 419 attr_->callctlr = woomeraCallCtlr_; 420 attr_->port = woomera_ipinfo.getPort(); 421 attr_->timeout = 1000; 422 attr_->broadcast_port = 0; 423 attr_->community[0] = '\0'; 424 attr_->callback = &dialogic_event_callback; 425 attr_->user_data = channelMgr_; /* used by dialogic_event_callback */ 426 427 /* pass control to the woomera event loop, this will return following 428 * a call to woomera_server_stop(). 429 */ 430 LOGNOTICE("AppDiaStar::run() starting Woomera server"); 431 woomera_server_run(attr_); 432 433 /* exit 434 */ 435 woomera_server_delete(woomeraServer_); 436 woomera_callctlr_delete(woomeraCallCtlr_); 437 delete channelMgr_; 438 return true; 439 } 440 441 442 /* 443 * forward to woomera, this will cause woomera_server_run() to return. 444 */ 445 void AppDiaStar::stop() 446 { 447 woomera_server_stop(attr_); 448 } 449 450 451 /* 452 * Parse a dial string into number and attribute parts. 453 * Format: NUMBER / NAME = VALUE : NAME = VALUE 454 * E.g. 1234567890/group=span1:cpa=yes 455 */ 456 void AppDiaStar::parseDialString( const std::string& s, 457 std::string& number, 458 std::map<std::string, std::string>& attrs ) 459 { 460 std::string::size_type seperator = s.find('/'); 461 if ( seperator == std::string::npos ) 462 { 463 number = s; 464 } 465 else 466 { 467 number = s.substr(0, seperator); 468 std::string attributes = s.substr(seperator + 1); 469 470 std::vector<std::string> attr; 471 tokenise(attributes, attr, ':'); 472 std::vector<std::string>::const_iterator i; 473 for ( i = attr.begin(); i != attr.end(); ++i ) 474 { 475 std::vector<std::string> kv; 476 tokenise(*i, kv, '='); 477 if ( kv.size() == 2 ) 478 { 479 attrs.insert(std::map<std::string, std::string>::value_type(kv[0], kv[1])); 480 } 481 kv.clear(); 482 } 483 } 484 } 485 486 487 /* 488 * Create a channel to manage the call. 489 */ 490 woomera_server_response* AppDiaStar::makeCall( woomera_callctlr_command* msg ) 491 { 492 LOGINFO("AppDiaStar::makeCall() callid: " << msg->call_id); 493 494 woomera_callctlr_command_make_call* callParms = &msg->m.make_call; 495 496 woomera_server_response* response = woomera_server_response_new(msg->connection_id); 497 response->mime = woomera_mime_new(); 498 499 const char* rtp_audio = woomera_mime_get_string(msg->incoming_mime, 500 woomera_key_rtp_audio); 501 if ( !rtp_audio ) 502 { 503 LOGERROR("AppDiaStar::makeCall() missing header: " << woomera_key_rtp_audio); 504 response->response = 400; 505 strcpy(response->args, "Missing RTP-Audio header"); 506 return response; 507 } 508 RtpIpInfo remote_rtp_audio(rtp_audio, RtpIpInfo::SENDRECV); 509 510 const char* rtp_video = woomera_mime_get_string(msg->incoming_mime, 511 woomera_key_rtp_video); 512 RtpIpInfo remote_rtp_video(rtp_video, RtpIpInfo::SENDRECV); 513 514 /* local caller id */ 515 std::string local_number = callParms->calling_number; 516 517 std::string local_name; 518 const char* woomera_local_name = woomera_mime_get_string(msg->incoming_mime, 519 woomera_key_local_name); 520 if ( woomera_local_name ) 521 { 522 /* woomera passes this value as "name!number" */ 523 local_name = woomera_local_name; 524 std::string::size_type pos = local_name.find('!'); 525 if ( pos != std::string::npos ) 526 { 527 local_name = local_name.substr(0, pos); 528 } 529 } 530 if ( local_name.empty() ) 531 { 532 local_name = local_number; 533 } 534 535 /* dial string */ 536 std::string remote_url; 537 if ( woomera_mime_includes(msg->common_mime, woomera_key_remote_url) != 0 ) 538 { 539 remote_url = woomera_mime_get_string(msg->common_mime, 540 woomera_key_remote_url); 541 } 542 else 543 { 544 remote_url = callParms->called_number; 545 } 546 547 std::string remote_number; 548 std::map<std::string, std::string> attrs; 549 parseDialString(remote_url, remote_number, attrs); 550 551 std::map<std::string, std::string>::const_iterator i; /* attribs */ 552 553 std::string group = "default"; 554 i = attrs.find("group"); 555 if ( i != attrs.end() ) 556 { 557 group = (*i).second; 558 } 559 560 LOGDEBUG("AppDiaStar::makeCall() protocol: " << woomera_protocol_get_name(msg->protocol)); 561 562 DialogicChannel* channel = 0; 563 if ( strcmp(woomera_protocol_get_name(msg->protocol), "isdn") == 0 ) 564 { 565 channel = channelMgr_->createIsdnChannel(group, PROTOCOL_ISDN); 566 } 567 else if ( strcmp(woomera_protocol_get_name(msg->protocol), "ss7") == 0 ) 568 { 569 channel = channelMgr_->createIsdnChannel(group, PROTOCOL_SS7); 570 } 571 else if ( strcmp(woomera_protocol_get_name(msg->protocol), "sip") == 0 ) 572 { 573 channel = channelMgr_->createSipChannel(group); 574 } 575 else if ( strcmp(woomera_protocol_get_name(msg->protocol), "h324") == 0 ) 576 { 577 channel = channelMgr_->createIsdnChannel(group, PROTOCOL_H324); 578 } 579 else if ( strcmp(woomera_protocol_get_name(msg->protocol), "conf") == 0 ) 580 { 581 channel = channelMgr_->createConfChannel(remote_number); 582 } 583 else 584 { 585 ; /* unreachable */ 586 } 587 588 if ( !channel ) 589 { 590 LOGWARN("AppDiaStar::makeCall() No channel available"); 591 response->response = 503; 592 strcpy(response->args, "No channel available"); 593 return response; 594 } 595 596 /* save client's media info. 597 */ 598 channel->setRemoteRtpAudioInfo(remote_rtp_audio); 599 channel->setRemoteRtpVideoInfo(remote_rtp_video); 600 601 if ( channel->getProtocol() == PROTOCOL_CONF ) 602 { 603 ConfPartyDevice* confParty = channel->getConfPartyDevice(); 604 confParty->setCaption(local_name); 605 606 ConfPartyDevice::Role role = ConfPartyDevice::PRESENTER; 607 i = attrs.find("role"); 608 if ( i != attrs.end() ) 609 { 610 if ( (*i).second == "controller" ) 611 { 612 role = ConfPartyDevice::CONTROLLER; 613 } 614 else if ( (*i).second == "presenter" ) 615 { 616 role = ConfPartyDevice::PRESENTER; 617 } 618 else if ( (*i).second == "attendee" ) 619 { 620 role = ConfPartyDevice::ATTENDEE; 621 } 622 else 623 { 624 channelMgr_->destroyChannel(channel); 625 response->response = 400; 626 strcpy(response->args, "invalid role"); 627 return response; 628 } 629 } 630 confParty->setRole(role); 631 632 i = attrs.find("position"); 633 if ( i != attrs.end() ) 634 { 635 if ( (*i).second == "none" ) 636 { 637 confParty->setVisible(false);; 638 } 639 else 640 { 641 unsigned int position = atoi((*i).second.c_str()); 642 confParty->setPosition(position); 643 } 644 } 645 646 ConfDevice* confDevice = channel->getConfDevice(); 647 if ( !confDevice->addParty(confParty) ) 648 { 649 channelMgr_->destroyChannel(channel); 650 response->response = 500; 651 strcpy(response->args, "Call failed"); 652 return response; 653 } 654 655 i = attrs.find("tiles"); 656 if ( i != attrs.end() ) 657 { 658 confDevice->setLayout((*i).second); 659 } 660 } 661 else /* isdn, ss7, sip, h324 */ 662 { 663 bool cpa = false; 664 i = attrs.find("cpa"); 665 if ( i != attrs.end() ) 666 { 667 cpa = (*i).second == "yes"; 668 } 669 670 if ( !channel->makeCall(local_number, local_name, remote_number, cpa) ) 671 { 672 channelMgr_->destroyChannel(channel); 673 response->response = 500; 674 strcpy(response->args, "Call failed"); 675 return response; 676 } 677 } 678 679 addCall(msg->call_id, channel); 680 681 response->response = 200; 682 strcpy(response->args, "Call started"); 683 return response; 684 } 685 686 687 /* 688 * Forward the command to the channel object. 689 */ 690 woomera_server_response* AppDiaStar::hangupCall( woomera_callctlr_command* msg ) 691 { 692 LOGINFO("AppDiaStar::hangupCall() callid: " << msg->call_id); 693 694 woomera_server_response* response = woomera_server_response_new(msg->connection_id); 695 696 Call* call = findCall(msg->call_id); 697 if ( call && call->getChannel() ) 698 { 699 int cause = GC_NORMAL_CLEARING; 700 const char* reason = woomera_mime_get_string(msg->incoming_mime, 701 woomera_key_reason); 702 if ( reason ) 703 { 704 cause = atoi(reason); 705 } 706 707 Channel* channel = call->getChannel(); 708 709 if ( channel->getProtocol() == PROTOCOL_CONF ) 710 { 711 removeCall(msg->call_id); 712 channelMgr_->destroyChannel((DialogicChannel*)channel); 713 response->response = 200; 714 strcpy(response->args, "Call cleared"); 715 } 716 else /* isdn, ss7, h324, sip */ 717 { 718 if ( channel->hangup(cause) ) 719 { 720 removeCall(msg->call_id); 721 response->response = 200; 722 strcpy(response->args, "Call cleared"); 723 } 724 else 725 { 726 response->response = 500; 727 strcpy(response->args, "Unable to hangup call"); 728 } 729 } 730 return response; 731 } 732 733 response->response = 481; 734 strcpy(response->args, "Call not found"); 735 return response; 736 } 737 738 739 /* 740 * Forward the command to the channel object. 741 */ 742 woomera_server_response* AppDiaStar::acceptCall( woomera_callctlr_command* msg ) 743 { 744 LOGINFO("AppDiaStar::acceptCall() callid: " << msg->call_id); 745 746 woomera_server_response* response = woomera_server_response_new(msg->connection_id); 747 748 Call* call = findCall(msg->call_id); 749 if ( call && call->getChannel() ) 750 { 751 Channel* channel = call->getChannel(); 752 if ( channel->accept() ) 753 { 754 /* save remote rtp ip-address and port. (video is optional) 755 */ 756 const char* rtp_audio = woomera_mime_get_string(msg->incoming_mime, 757 woomera_key_rtp_audio); 758 if ( !rtp_audio ) 759 { 760 LOGERROR("AppDiaStar::acceptCall() missing header: " << woomera_key_rtp_audio); 761 return 0; 762 } 763 RtpIpInfo remote_rtp_audio(rtp_audio, RtpIpInfo::SENDRECV); 764 765 const char* rtp_video = woomera_mime_get_string(msg->incoming_mime, 766 woomera_key_rtp_video); 767 RtpIpInfo* remote_rtp_video = 0; 768 if ( rtp_video ) 769 { 770 remote_rtp_video = new RtpIpInfo(rtp_video, RtpIpInfo::SENDRECV); 771 } 772 773 channel->setRemoteRtpAudioInfo(remote_rtp_audio); 774 775 if ( remote_rtp_video ) 776 { 777 channel->setRemoteRtpVideoInfo(*remote_rtp_video); 778 delete remote_rtp_video; 779 } 780 781 /* save so that onAccept() can send the final response. 782 */ 783 call->setConnectionId(msg->connection_id); 784 785 response->response = 100; 786 strcpy(response->args, "Call accepting"); 787 } 788 else 789 { 790 response->response = 500; 791 strcpy(response->args, "Unable to accept call"); 792 } 793 } 794 else 795 { 796 response->response = 481; 797 strcpy(response->args, "Call not found"); 798 } 799 return response; 800 } 801 802 803 /* 804 * Forward the command to the channel object. 805 */ 806 woomera_server_response* AppDiaStar::answerCall( woomera_callctlr_command* msg ) 807 { 808 LOGINFO("AppDiaStar::answerCall() callid: " << msg->call_id); 809 810 woomera_server_response* response = woomera_server_response_new(msg->connection_id); 811 812 Call* call = findCall(msg->call_id); 813 if ( call && call->getChannel() ) 814 { 815 /* save so that onAnswer() can send the final response. 816 */ 817 call->setConnectionId(msg->connection_id); 818 819 Channel* channel = call->getChannel(); 820 if ( channel->answer() ) 821 { 822 response->response = 100; 823 strcpy(response->args, "Call answering"); 824 } 825 else 826 { 827 response->response = 500; 828 strcpy(response->args, "Unable to answer call"); 829 } 830 } 831 else 832 { 833 response->response = 481; 834 strcpy(response->args, "Call not found"); 835 } 836 return response; 837 } 838 839 840 /* 841 * Forward the command to the channel object. 842 */ 843 woomera_server_response* AppDiaStar::sendDtmf( woomera_callctlr_command* msg ) 844 { 845 LOGINFO("AppDiaStar::sendDtmf() callid: " << msg->call_id); 846 847 woomera_server_response* response = woomera_server_response_new(msg->connection_id); 848 849 Call* call = findCall(msg->call_id); 850 if ( call && call->getChannel() ) 851 { 852 Channel* channel = call->getChannel(); 853 if ( channel->sendDtmf(msg->m.dtmf.digits) ) 854 { 855 /* save so that onSendDtmfCompleted() can send the final response. 856 */ 857 call->setConnectionId(msg->connection_id); 858 859 response->response = 100; 860 strcpy(response->args, "Sending dtmf"); 861 } 862 else 863 { 864 response->response = 500; 865 strcpy(response->args, "Unable to send dtmf"); 866 } 867 } 868 else 869 { 870 response->response = 481; 871 strcpy(response->args, "Call not found"); 872 } 873 return response; 874 } 875 876 877 /* 878 * Handle a PLAY request. 879 */ 880 woomera_server_response* AppDiaStar::play( woomera_callctlr_command* msg ) 881 { 882 LOGINFO("AppDiaStar::play() callid: " << msg->call_id); 883 884 woomera_server_response* response = woomera_server_response_new(msg->connection_id); 885 886 Call* call = findCall(msg->call_id); 887 if ( call && call->getChannel() ) 888 { 889 const char* woomera_audio_uri = woomera_mime_get_string(msg->incoming_mime, 890 woomera_key_audio_uri); 891 892 const char* woomera_video_uri = woomera_mime_get_string(msg->incoming_mime, 893 woomera_key_video_uri); 894 895 const char* woomera_overlay = woomera_mime_get_string(msg->incoming_mime, 896 woomera_key_overlay); 897 898 if ( !woomera_audio_uri && !woomera_video_uri && !woomera_overlay) 899 { 900 LOGERROR("AppDiaStar::play() no media specified"); 901 response->response = 400; 902 strcpy(response->args, "No media"); 903 return response; 904 } 905 906 const char* woomera_stop_digits = woomera_mime_get_string(msg->incoming_mime, 907 woomera_key_stop_digits); 908 909 const char* woomera_language = woomera_mime_get_string(msg->incoming_mime, 910 woomera_key_language); 911 912 const char* woomera_repeat = woomera_mime_get_string(msg->incoming_mime, 913 woomera_key_repeat); 914 915 std::string audio_uri, video_uri, overlay, stop_digits, lang; 916 917 if ( woomera_audio_uri ) 918 { 919 audio_uri = woomera_audio_uri; 920 } 921 if ( woomera_video_uri ) 922 { 923 video_uri = woomera_video_uri; 924 } 925 if ( woomera_overlay ) 926 { 927 overlay = woomera_overlay; 928 } 929 if ( woomera_stop_digits ) 930 { 931 stop_digits = woomera_stop_digits; 932 } 933 if ( woomera_language ) 934 { 935 lang = woomera_language; 936 } 937 938 int repeat = 1; 939 if ( woomera_repeat ) 940 { 941 if (strcmp("infinite", woomera_repeat) == 0 ) 942 { 943 repeat = INT_MAX; 944 } 945 else 946 { 947 repeat = atoi(woomera_repeat);; 948 } 949 } 950 951 Channel* channel = call->getChannel(); 952 953 if ( (channel->getProtocol() != PROTOCOL_SIP) && 954 (channel->getProtocol() != PROTOCOL_H324) && 955 (channel->getProtocol() != PROTOCOL_CONF) ) 956 { 957 response->response = 503; 958 strcpy(response->args, "Play not supported by call protocol"); 959 } 960 else 961 { 962 if ( audio_uri.empty() && video_uri.empty() && overlay.empty() ) 963 { 964 response->response = 400; 965 strcpy(response->args, "No files specified"); 966 } 967 else 968 { 969 if ( channel->play(audio_uri, video_uri, overlay, stop_digits, lang, repeat) ) 970 { 971 call->setConnectionId(msg->connection_id); 972 973 if ( !audio_uri.empty() || !video_uri.empty() ) 974 { 975 response->response = 100; 976 strcpy(response->args, "Starting play"); 977 } 978 else /* overlay only */ 979 { 980 response->response = 200; 981 strcpy(response->args, "Play started"); 982 } 983 } 984 else 985 { 986 response->response = 500; 987 strcpy(response->args, "Play request failed"); 988 } 989 } 990 } 991 } 992 else 993 { 994 response->response = 481; 995 strcpy(response->args, "Call not found"); 996 } 997 return response; 998 } 999 1000 1001 /* 1002 * Handle a RECORD request. 1003 */ 1004 woomera_server_response* AppDiaStar::record( woomera_callctlr_command* msg ) 1005 { 1006 LOGINFO("AppDiaStar::record() callid: " << msg->call_id); 1007 1008 woomera_server_response* response = woomera_server_response_new(msg->connection_id); 1009 1010 Call* call = findCall(msg->call_id); 1011 if ( call && call->getChannel() ) 1012 { 1013 const char* woomera_audio_uri = woomera_mime_get_string(msg->incoming_mime, 1014 woomera_key_audio_uri); 1015 1016 const char* woomera_video_uri = woomera_mime_get_string(msg->incoming_mime, 1017 woomera_key_video_uri); 1018 1019 if ( !woomera_audio_uri && !woomera_video_uri ) 1020 { 1021 LOGERROR("AppDiaStar::record() no media specified"); 1022 response->response = 400; 1023 strcpy(response->args, "No media"); 1024 return response; 1025 } 1026 1027 const char* woomera_stop_digits = woomera_mime_get_string(msg->incoming_mime, 1028 woomera_key_stop_digits); 1029 1030 const char* woomera_language = woomera_mime_get_string(msg->incoming_mime, 1031 woomera_key_language); 1032 1033 const char* woomera_beep = woomera_mime_get_string(msg->incoming_mime, 1034 woomera_key_beep); 1035 1036 const char* woomera_max_time = woomera_mime_get_string(msg->incoming_mime, 1037 woomera_key_max_time); 1038 1039 std::string audio_uri, video_uri, stop_digits, lang; 1040 bool beep = true; 1041 unsigned int max_time = 0; /* default to unlimited */ 1042 1043 if ( woomera_audio_uri ) 1044 { 1045 audio_uri = woomera_audio_uri; 1046 } 1047 if ( woomera_video_uri ) 1048 { 1049 video_uri = woomera_video_uri; 1050 } 1051 if ( woomera_stop_digits ) 1052 { 1053 stop_digits = woomera_stop_digits; 1054 } 1055 if ( woomera_language ) 1056 { 1057 lang = woomera_language; 1058 } 1059 if ( woomera_beep ) 1060 { 1061 beep = (strcmp(woomera_beep, "yes") == 0); 1062 } 1063 if ( woomera_max_time ) 1064 { 1065 max_time = (unsigned int) atoi(woomera_max_time); 1066 max_time *= 1000; /* scale to ms */ 1067 } 1068 Channel* channel = call->getChannel(); 1069 1070 if ( (channel->getProtocol() != PROTOCOL_SIP) && 1071 (channel->getProtocol() != PROTOCOL_H324) && 1072 (channel->getProtocol() != PROTOCOL_CONF) ) 1073 { 1074 response->response = 503; 1075 strcpy(response->args, "Record not supported by call protocol"); 1076 } 1077 else 1078 { 1079 if ( audio_uri.empty() && video_uri.empty() ) 1080 { 1081 response->response = 400; 1082 strcpy(response->args, "No files specified"); 1083 } 1084 else 1085 { 1086 if ( channel->record(audio_uri, video_uri, stop_digits, lang, beep, max_time) ) 1087 { 1088 call->setConnectionId(msg->connection_id); 1089 1090 response->response = 100; 1091 strcpy(response->args, "Starting record"); 1092 } 1093 else 1094 { 1095 response->response = 500; 1096 strcpy(response->args, "Record request failed"); 1097 } 1098 } 1099 } 1100 } 1101 else 1102 { 1103 response->response = 481; 1104 strcpy(response->args, "Call not found"); 1105 } 1106 return response; 1107 } 1108 1109 1110 /* 1111 * Handle a STOP (play/record) request. 1112 */ 1113 woomera_server_response* AppDiaStar::stop( woomera_callctlr_command* msg ) 1114 { 1115 LOGINFO("AppDiaStar::stop() callid: " << msg->call_id); 1116 1117 woomera_server_response* response = woomera_server_response_new(msg->connection_id); 1118 1119 Call* call = findCall(msg->call_id); 1120 if ( call && call->getChannel() ) 1121 { 1122 Channel* channel = call->getChannel(); 1123 1124 if ( (channel->getProtocol() != PROTOCOL_SIP) && 1125 (channel->getProtocol() != PROTOCOL_CONF) ) 1126 { 1127 response->response = 503; 1128 strcpy(response->args, "Stop not supported by call protocol"); 1129 } 1130 else 1131 { 1132 if ( channel->stop() ) 1133 { 1134 response->response = 200; 1135 strcpy(response->args, "Stopping"); 1136 } 1137 else 1138 { 1139 response->response = 500; 1140 strcpy(response->args, "Stop failed"); 1141 } 1142 } 1143 } 1144 else 1145 { 1146 response->response = 481; 1147 strcpy(response->args, "Call not found"); 1148 } 1149 return response; 1150 } 1151 1152 1153 /* 1154 * Handle an UPDATE request. 1155 * 1156 * For media updates: 1157 * If the new rtp parameters refer to a another channel, the connection is 1158 * done internally to avoid extra trancoding steps. Otherwise, streaming is 1159 * restarted using the new rtp values. 1160 * When MEDIA requests are used to optimise bridging between channels, each 1161 * channel will receive its own request so the connections referred to here 1162 * are half-duplex. 1163 */ 1164 woomera_server_response* AppDiaStar::update( woomera_callctlr_command* msg ) 1165 { 1166 LOGINFO("AppDiaStar::update() callid: " << msg->call_id); 1167 1168 woomera_server_response* response = woomera_server_response_new(msg->connection_id); 1169 1170 Call* call = findCall(msg->call_id); 1171 if ( call && call->getChannel() ) 1172 { 1173 Channel* channel = call->getChannel(); 1174 1175 /* Media */ 1176 1177 const char* rtp_audio = woomera_mime_get_string(msg->incoming_mime, 1178 woomera_key_rtp_audio); 1179 1180 const char* rtp_video = woomera_mime_get_string(msg->incoming_mime, 1181 woomera_key_rtp_video); 1182 1183 if ( rtp_audio || rtp_video) 1184 { 1185 call->setConnectionId(msg->connection_id); /* Async completion. */ 1186 1187 RtpIpInfo remote_rtp_audio(rtp_audio, RtpIpInfo::SENDRECV); 1188 RtpIpInfo remote_rtp_video(rtp_video, RtpIpInfo::SENDRECV); 1189 1190 /* If the new rtp values are local to this server, try to optimise 1191 * the connection(s) internally. 1192 */ 1193 Channel* other_channel = channelMgr_->findChannel(remote_rtp_audio, remote_rtp_video); 1194 if ( other_channel && channel->isBridged() ) 1195 { 1196 /* Already bridged internally. */ 1197 response->response = 409; 1198 strcpy(response->args, "Conflict"); 1199 } 1200 else 1201 { 1202 channel->stopMedia(); 1203 1204 if ( config_.isBridgeInternal() && other_channel && channel->bridge(other_channel) ) 1205 { 1206 LOGDEBUG("AppDiaStar::update() optimised connection to channel: " << std::hex << other_channel); 1207 response->response = 100; 1208 strcpy(response->args, "Updating rtp"); 1209 } 1210 else /* External. */ 1211 { 1212 LOGDEBUG("AppDiaStar::update() remote rtp: a=" << remote_rtp_audio << ", v=" << remote_rtp_video); 1213 1214 if ( rtp_audio ) 1215 { 1216 channel->setRemoteRtpAudioInfo(remote_rtp_audio); 1217 } 1218 if ( rtp_video ) 1219 { 1220 channel->setRemoteRtpVideoInfo(remote_rtp_video); 1221 } 1222 1223 if ( channel->startMedia() ) 1224 { 1225 if ( channel->unbridge() ) 1226 { 1227 response->response = 100; 1228 strcpy(response->args, "Updating rtp"); 1229 } 1230 else 1231 { 1232 response->response = 200; 1233 strcpy(response->args, "Updated rtp"); 1234 } 1235 } 1236 else 1237 { 1238 response->response = 500; 1239 strcpy(response->args, "Update request failed"); 1240 } 1241 } 1242 } 1243 } 1244 1245 /* Event notifications */ 1246 1247 const char* tone_events = woomera_mime_get_string(msg->incoming_mime, 1248 woomera_key_tone_events); 1249 if ( tone_events ) 1250 { 1251 if ( strcmp(tone_events, "enable") == 0 ) 1252 { 1253 LOGDEBUG("AppDiaStar::update() enable tone events"); 1254 channel->enableToneEvents(); 1255 } 1256 else 1257 { 1258 LOGDEBUG("AppDiaStar::update() disable tone events"); 1259 channel->disableToneEvents(); 1260 } 1261 response->response = 200; 1262 strcpy(response->args, "OK"); 1263 } 1264 1265 const char* info_events = woomera_mime_get_string(msg->incoming_mime, 1266 woomera_key_info_events); 1267 if ( info_events ) 1268 { 1269 if ( strcmp(info_events, "enable") == 0 ) 1270 { 1271 LOGDEBUG("AppDiaStar::update() enable info events"); 1272 channel->enableInfoEvents(); 1273 } 1274 else 1275 { 1276 LOGDEBUG("AppDiaStar::update() disable info events"); 1277 channel->disableInfoEvents(); 1278 } 1279 response->response = 200; 1280 strcpy(response->args, "OK"); 1281 } 1282 } 1283 else 1284 { 1285 response->response = 481; 1286 strcpy(response->args, "Call not found"); 1287 } 1288 return response; 1289 } 1290 1291 1292 /* 1293 * Forward the event to Woomera. 1294 */ 1295 void AppDiaStar::onIncoming( Channel* channel, 1296 const std::string& local_number, 1297 const std::string& local_uri, 1298 const std::string& remote_number, 1299 const std::string& remote_name ) 1300 { 1301 LOGDEBUG("AppDiaStar::onIncoming() " << std::hex << channel); 1302 1303 woomera_callctlr_incoming_call_info* info = woomera_callctlr_incoming_call_info_new(); 1304 1305 if ( !info->common_mime ) 1306 { 1307 info->common_mime = woomera_mime_new(); 1308 } 1309 1310 copy_string_to_c_array(local_number, info->local_number, sizeof(info->local_number)); 1311 copy_string_to_c_array(local_uri, info->local_url, sizeof(info->local_url)); /* Woomera uses URL */ 1312 copy_string_to_c_array(remote_number, info->remote_number, sizeof(info->remote_number)); 1313 copy_string_to_c_array(remote_name, info->remote_name, sizeof(info->remote_name)); 1314 1315 if ( channel->getProtocol() == PROTOCOL_ISDN ) 1316 { 1317 strcpy(info->scheme, "isdn"); 1318 } 1319 else if ( channel->getProtocol() == PROTOCOL_SS7 ) 1320 { 1321 strcpy(info->scheme, "ss7"); 1322 } 1323 else if ( channel->getProtocol() == PROTOCOL_H324 ) 1324 { 1325 strcpy(info->scheme, "h324"); 1326 } 1327 else /* PROTOCOL_SIP */ 1328 { 1329 strcpy(info->scheme, "sip"); 1330 } 1331 1332 /* Tell Woomera, it will take ownership of 'info' and fill in the callid. 1333 */ 1334 if ( woomera_callctlr_on_incoming_call(woomeraCallCtlr_, info) == 0 ) 1335 { 1336 addCall(info->call_id, channel); 1337 LOGINFO("AppDiaStar::onIncoming() callid: " << info->call_id); 1338 } 1339 else 1340 { 1341 LOGERROR("AppDiaStar::onIncoming() woomera_callctlr_on_incoming_call() failed"); 1342 channel->hangup(27); /* O.O.O.*/ 1343 } 1344 } 1345 1346 1347 /* 1348 * Accept completion, forward the event to Woomera. 1349 */ 1350 void AppDiaStar::onAccepted( Channel* channel ) 1351 { 1352 LOGDEBUG("AppDiaStar::onAccepted() " << std::hex << channel); 1353 1354 Call* call = findCall(channel); 1355 if ( call ) 1356 { 1357 LOGINFO("AppDiaStar::onAccepted() callid: " << call->getId()); 1358 1359 woomera_server_response* response = woomera_server_response_new(call->getConnectionId()); 1360 1361 response->mime = woomera_mime_new(); 1362 1363 /* include the local media details in the response. 1364 */ 1365 RtpIpInfo local_rtp_audio; 1366 channel->getLocalRtpAudioInfo(local_rtp_audio); 1367 woomera_mime_set_string(response->mime, 1368 woomera_key_rtp_audio, 1369 local_rtp_audio.getAddressAndPort().c_str()); 1370 1371 if ( channel->isVideo() ) 1372 { 1373 RtpIpInfo local_rtp_video; 1374 channel->getLocalRtpVideoInfo(local_rtp_video); 1375 woomera_mime_set_string(response->mime, 1376 woomera_key_rtp_video, 1377 local_rtp_video.getAddressAndPort().c_str()); 1378 } 1379 1380 woomera_mime_set_string(response->mime, woomera_key_dtmf, "OutofBand"); 1381 1382 response->response = 200; 1383 strcpy(response->args, "Call accepted"); 1384 1385 woomera_server_send_response(woomeraServer_, response); 1386 } 1387 } 1388 1389 1390 /* 1391 * Answer completion, forward the event to Woomera. 1392 */ 1393 void AppDiaStar::onAnswered( Channel* channel ) 1394 { 1395 LOGDEBUG("AppDiaStar::onAnswered() " << std::hex << channel); 1396 1397 Call* call = findCall(channel); 1398 if ( call ) 1399 { 1400 LOGINFO("AppDiaStar::onAnswered() callid: " << call->getId()); 1401 1402 woomera_server_response* response = woomera_server_response_new(call->getConnectionId()); 1403 1404 response->mime = woomera_mime_new(); 1405 1406 /* include the local media details in the response. 1407 */ 1408 RtpIpInfo local_rtp_audio; 1409 channel->getLocalRtpAudioInfo(local_rtp_audio); 1410 woomera_mime_set_string(response->mime, 1411 woomera_key_rtp_audio, 1412 local_rtp_audio.getAddressAndPort().c_str()); 1413 1414 if ( channel->isVideo() ) 1415 { 1416 RtpIpInfo local_rtp_video; 1417 channel->getLocalRtpVideoInfo(local_rtp_video); 1418 woomera_mime_set_string(response->mime, 1419 woomera_key_rtp_video, 1420 local_rtp_video.getAddressAndPort().c_str()); 1421 } 1422 1423 woomera_mime_set_string(response->mime, woomera_key_dtmf, "OutofBand"); 1424 1425 response->response = 200; 1426 strcpy(response->args, "Call answered"); 1427 1428 woomera_server_send_response(woomeraServer_, response); 1429 } 1430 } 1431 1432 1433 /* 1434 * Forward to Woomera as proceeding and media events. 1435 */ 1436 void AppDiaStar::onProceeding( Channel* channel ) 1437 { 1438 LOGDEBUG("AppDiaStar::onProceeding() " << std::hex << channel); 1439 1440 Call* call = findCall(channel); 1441 if ( call ) 1442 { 1443 LOGINFO("AppDiaStar::onProceeding() callid: " << call->getId()); 1444 1445 woomera_callctlr_on_proceeding(woomeraCallCtlr_, 1446 call->getId().c_str()); 1447 1448 if ( !call->sentMediaEvent() ) 1449 { 1450 onMedia(channel); 1451 call->setSentMediaEvent(); 1452 } 1453 } 1454 } 1455 1456 1457 /* 1458 * Forward the event to Woomera. 1459 */ 1460 void AppDiaStar::onRinging( Channel* channel ) 1461 { 1462 LOGDEBUG("AppDiaStar::onRinging() " << std::hex << channel); 1463 1464 Call* call = findCall(channel); 1465 if ( call ) 1466 { 1467 LOGINFO("AppDiaStar::onRinging() callid: " << call->getId()); 1468 1469 woomera_callctlr_on_ringing(woomeraCallCtlr_, 1470 call->getId().c_str(), 1471 false); 1472 1473 if ( !call->sentMediaEvent() ) 1474 { 1475 onMedia(channel); 1476 call->setSentMediaEvent(); 1477 } 1478 } 1479 } 1480 1481 1482 /* 1483 * Forward the event to Woomera. 1484 */ 1485 void AppDiaStar::onHangup( Channel* channel, 1486 int cause, 1487 const std::string& cause_text, 1488 const std::string& conn_type ) 1489 { 1490 LOGDEBUG("AppDiaStar::onHangup() " << std::hex << channel); 1491 1492 Call* call = findCall(channel); 1493 if ( call ) 1494 { 1495 LOGINFO("AppDiaStar::onHangup() callid: " << call->getId() << 1496 ", cause: " << cause << " \"" << cause_text << "\""); 1497 1498 woomera_callctlr_on_clear(woomeraCallCtlr_, 1499 call->getId().c_str(), 1500 cause, 1501 cause_text.c_str(), 1502 conn_type.empty() ? 0 : conn_type.c_str()); 1503 removeCall(call->getId()); 1504 } 1505 } 1506 1507 1508 /* 1509 * Forward the event to Woomera. 1510 */ 1511 void AppDiaStar::onConnect( Channel* channel, const std::string& conn_type ) 1512 { 1513 LOGDEBUG("AppDiaStar::onConnect() " << std::hex << channel); 1514 1515 Call* call = findCall(channel); 1516 if ( call ) 1517 { 1518 LOGINFO("AppDiaStar::onConnect() callid: " << call->getId()); 1519 1520 woomera_callctlr_on_connect(woomeraCallCtlr_, 1521 call->getId().c_str(), 1522 false, 1523 conn_type.c_str()); 1524 1525 if ( !call->sentMediaEvent() ) 1526 { 1527 onMedia(channel); 1528 call->setSentMediaEvent(); 1529 } 1530 } 1531 } 1532 1533 1534 /* 1535 * Forward to Woomera. 1536 */ 1537 void AppDiaStar::onMedia( Channel* channel ) 1538 { 1539 LOGDEBUG("AppDiaStar::onMedia() " << std::hex << channel); 1540 1541 Call* call = findCall(channel); 1542 if ( call ) 1543 { 1544 LOGINFO("AppDiaStar::onMedia() callid: " << call->getId()); 1545 1546 RtpIpInfo local_rtp_audio; 1547 channel->getLocalRtpAudioInfo(local_rtp_audio); 1548 1549 RtpIpInfo local_rtp_video; 1550 channel->getLocalRtpVideoInfo(local_rtp_video); 1551 1552 woomera_callctlr_on_media(woomeraCallCtlr_, 1553 call->getId().c_str(), 1554 local_rtp_audio.getAddressAndPort().c_str(), 1555 /* XXX 1556 channel->isVideo() ? local_rtp_video.getAddressAndPort().c_str() : NULL, 1557 */ 1558 local_rtp_video.getAddressAndPort().c_str(), 1559 config_.isOutOfBandDtmf()); 1560 } 1561 } 1562 1563 1564 /* 1565 * Forward the event to Woomera. 1566 */ 1567 void AppDiaStar::onDtmf( Channel* channel, const std::string& digits ) 1568 { 1569 Call* call = findCall(channel); 1570 if ( call && !digits.empty() ) 1571 { 1572 LOGINFO("AppDiaStar::onDtmf() callid: " << call->getId() << 1573 " digits: \"" << digits << "\""); 1574 1575 woomera_callctlr_on_dtmf(woomeraCallCtlr_, 1576 call->getId().c_str(), 1577 digits.c_str()); 1578 } 1579 } 1580 1581 1582 /* 1583 * Forward the event to Woomera. 1584 */ 1585 void AppDiaStar::onTone( Channel* channel, const std::string& name ) 1586 { 1587 Call* call = findCall(channel); 1588 if ( call ) 1589 { 1590 LOGINFO("AppDiaStar::onTone() callid: " << call->getId() << 1591 " tone: \"" << name << "\""); 1592 1593 woomera_callctlr_on_tone(woomeraCallCtlr_, 1594 call->getId().c_str(), 1595 name.c_str()); 1596 } 1597 } 1598 1599 1600 /* 1601 * Forward the event to Woomera. 1602 */ 1603 void AppDiaStar::onInfo( Channel* channel, 1604 const std::string& mimetype, 1605 const std::string& content ) 1606 { 1607 Call* call = findCall(channel); 1608 if ( call ) 1609 { 1610 LOGINFO("AppDiaStar::onInfo() callid: " << call->getId() << 1611 " mimetype: \"" << mimetype << "\""); 1612 1613 woomera_callctlr_on_info(woomeraCallCtlr_, 1614 call->getId().c_str(), 1615 mimetype.c_str(), 1616 content.c_str()); 1617 } 1618 } 1619 1620 1621 /* 1622 * Forward the event to Woomera. 1623 */ 1624 void AppDiaStar::onSendDtmfCompleted( Channel* channel ) 1625 { 1626 LOGINFO("AppDiaStar::onSendDtmfCompleted() " << std::hex << channel); 1627 1628 Call* call = findCall(channel); 1629 if ( call ) 1630 { 1631 woomera_server_response* response = woomera_server_response_new(call->getConnectionId()); 1632 1633 response->mime = woomera_mime_new(); 1634 1635 response->response = 200; 1636 strcpy(response->args, "SendDtmf completed"); 1637 1638 woomera_server_send_response(woomeraServer_, response); 1639 } 1640 } 1641 1642 1643 /* 1644 * Play started, forward the event to Woomera. 1645 */ 1646 void AppDiaStar::onPlayOk( Channel* channel ) 1647 { 1648 LOGDEBUG("AppDiaStar::onPlayOk() " << std::hex << channel); 1649 1650 Call* call = findCall(channel); 1651 if ( call ) 1652 { 1653 LOGINFO("AppDiaStar::onPlayOk() callid: " << call->getId()); 1654 1655 woomera_server_response* response = woomera_server_response_new(call->getConnectionId()); 1656 1657 response->response = 200; 1658 strcpy(response->args, "Play started"); 1659 1660 woomera_server_send_response(woomeraServer_, response); 1661 } 1662 } 1663 1664 1665 /* 1666 * Play request failed, forward the event to Woomera. 1667 */ 1668 void AppDiaStar::onPlayFail( Channel* channel ) 1669 { 1670 LOGDEBUG("AppDiaStar::onPlayFail() " << std::hex << channel); 1671 1672 Call* call = findCall(channel); 1673 if ( call ) 1674 { 1675 LOGINFO("AppDiaStar::onPlayFail() callid: " << call->getId()); 1676 1677 woomera_server_response* response = woomera_server_response_new(call->getConnectionId()); 1678 1679 response->response = 400; 1680 strcpy(response->args, "Play failed"); 1681 1682 woomera_server_send_response(woomeraServer_, response); 1683 } 1684 } 1685 1686 1687 /* 1688 * Forward the event to Woomera. 1689 */ 1690 void AppDiaStar::onPlayCompleted( Channel* channel, 1691 const std::string& reason, 1692 unsigned int duration ) 1693 { 1694 LOGINFO("AppDiaStar::onPlayCompleted() " << std::hex << channel); 1695 1696 Call* call = findCall(channel); 1697 if ( call ) 1698 { 1699 std::stringstream ss; 1700 ss << duration; 1701 woomera_callctlr_on_play_completed(woomeraCallCtlr_, 1702 call->getId().c_str(), 1703 reason.c_str(), 1704 ss.str().c_str()); 1705 } 1706 } 1707 1708 1709 /* 1710 * Record started, forward the event to Woomera. 1711 */ 1712 void AppDiaStar::onRecordOk( Channel* channel ) 1713 { 1714 LOGDEBUG("AppDiaStar::onRecordOk() " << std::hex << channel); 1715 1716 Call* call = findCall(channel); 1717 if ( call ) 1718 { 1719 LOGINFO("AppDiaStar::onRecordOk() callid: " << call->getId()); 1720 1721 woomera_server_response* response = woomera_server_response_new(call->getConnectionId()); 1722 1723 response->response = 200; 1724 strcpy(response->args, "Record started"); 1725 1726 woomera_server_send_response(woomeraServer_, response); 1727 } 1728 } 1729 1730 1731 /* 1732 * Record request failed, forward the event to Woomera. 1733 */ 1734 void AppDiaStar::onRecordFail( Channel* channel ) 1735 { 1736 LOGDEBUG("AppDiaStar::onRecordFail() " << std::hex << channel); 1737 1738 Call* call = findCall(channel); 1739 if ( call ) 1740 { 1741 LOGINFO("AppDiaStar::onRecordFail() callid: " << call->getId()); 1742 1743 woomera_server_response* response = woomera_server_response_new(call->getConnectionId()); 1744 1745 response->response = 400; 1746 strcpy(response->args, "Record failed"); 1747 1748 woomera_server_send_response(woomeraServer_, response); 1749 } 1750 } 1751 1752 1753 /* 1754 * Forward the event to Woomera. 1755 */ 1756 void AppDiaStar::onRecordCompleted( Channel* channel, 1757 const std::string& reason, 1758 unsigned int duration ) 1759 { 1760 LOGINFO("AppDiaStar::onRecordCompleted() " << std::hex << channel); 1761 1762 Call* call = findCall(channel); 1763 if ( call ) 1764 { 1765 std::stringstream ss; 1766 ss << duration; 1767 woomera_callctlr_on_record_completed(woomeraCallCtlr_, 1768 call->getId().c_str(), 1769 reason.c_str(), 1770 ss.str().c_str()); 1771 } 1772 } 1773 1774 /* 1775 * Forward the event to Woomera. 1776 */ 1777 void AppDiaStar::onBridgeCompleted( Channel* channel ) 1778 { 1779 LOGDEBUG("AppDiaStar::onBridgedCompleted() " << std::hex << channel); 1780 1781 Call* call = findCall(channel); 1782 if ( call ) 1783 { 1784 LOGINFO("AppDiaStar::onBridgedCompleted() callid: " << call->getId()); 1785 1786 woomera_server_response* response = woomera_server_response_new(call->getConnectionId()); 1787 1788 response->response = 200; 1789 strcpy(response->args, "Update rtp completed"); 1790 1791 woomera_server_send_response(woomeraServer_, response); 1792 } 1793 } 1794 1795 /* vim:ts=4:set nu: 1796 * EOF 1797 */
| No admin address has been configured | ViewVC Help |
| Powered by ViewVC 1.0.8 |