[commit] r5057 - in freeswitch/trunk/src: include mod/applications/mod_esf mod/endpoints/mod_sofia
Author: anthm Date: Tue May 1 17:21:35 2007 New Revision: 5057 Added: freeswitch/trunk/src/mod/applications/mod_esf/ freeswitch/trunk/src/mod/applications/mod_esf/Makefile freeswitch/trunk/src/mod/applications/mod_esf/mod_esf.c freeswitch/trunk/src/mod/applications/mod_esf/mod_esf.vcproj Modified: freeswitch/trunk/src/include/switch_types.h freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Log: add mod_esf (extra sip functionality) Modified: freeswitch/trunk/src/include/switch_types.h ============================================================================== --- freeswitch/trunk/src/include/switch_types.h (original) +++ freeswitch/trunk/src/include/switch_types.h Tue May 1 17:21:35 2007 @@ -365,6 +365,7 @@ SWITCH_MESSAGE_INDICATE_UNHOLD - indicate unhold SWITCH_MESSAGE_INDICATE_REDIRECT - indicate redirect SWITCH_MESSAGE_INDICATE_REJECT - indicate reject + SWITCH_MESSAGE_INDICATE_BROADCAST - indicate media broadcast </pre> */ typedef enum { @@ -381,7 +382,8 @@ SWITCH_MESSAGE_INDICATE_HOLD, SWITCH_MESSAGE_INDICATE_UNHOLD, SWITCH_MESSAGE_INDICATE_REDIRECT, - SWITCH_MESSAGE_INDICATE_REJECT + SWITCH_MESSAGE_INDICATE_REJECT, + SWITCH_MESSAGE_INDICATE_BROADCAST } switch_core_session_message_types_t; Added: freeswitch/trunk/src/mod/applications/mod_esf/Makefile ============================================================================== --- (empty file) +++ freeswitch/trunk/src/mod/applications/mod_esf/Makefile Tue May 1 17:21:35 2007 @@ -0,0 +1,2 @@ +BASE=../../../.. +include /usr/src/freeswitch.trunk/build/modmake.rules Added: freeswitch/trunk/src/mod/applications/mod_esf/mod_esf.c ============================================================================== --- (empty file) +++ freeswitch/trunk/src/mod/applications/mod_esf/mod_esf.c Tue May 1 17:21:35 2007 @@ -0,0 +1,269 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com> + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II <anthmct@yahoo.com> + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II <anthmct@yahoo.com> + * + * + * mod_esf.c -- Extra SIP Functionality + * + */ +#include <switch.h> + +static const char modname[] = "mod_esf"; + +struct ls_control_packet { + uint32_t unique_id; + uint32_t command; + uint32_t ip; + uint32_t port; +}; +typedef struct ls_control_packet ls_control_packet_t; + +typedef enum { + LS_START_BCAST = 6, + LS_STOP_BCAST = 7 +} ls_command_t; + +typedef enum { + SEND_TYPE_UNKNOWN = 0, + SEND_TYPE_RTP = 1, + SEND_TYPE_RAW = 2, + SEND_TYPE_NOMEDIA = 3 +} ls_how_t; + +static void bcast_function(switch_core_session_t *session, char *data) +{ + switch_channel_t *channel; + switch_socket_t *socket; + switch_sockaddr_t *audio_addr, *control_packet_addr; + switch_frame_t *read_frame; + switch_status_t status; + switch_size_t bytes; + ls_control_packet_t control_packet; + switch_codec_t *read_codec; + uint32_t flags = 0; + const char *err; + switch_rtp_t *rtp_session; + uint32_t rtp_port; + char guess_ip[25]; + ls_how_t ready = SEND_TYPE_UNKNOWN; + int argc; + char *mydata, *argv[5]; + char *mcast_ip = "224.168.168.168"; + uint32_t mcast_port = 34567; + uint32_t mcast_control_port = 6061; + char *mcast_port_str = "34567"; + + + channel = switch_core_session_get_channel(session); + assert(channel != NULL); + + + if (!switch_strlen_zero((char *) data)) { + mydata = switch_core_session_strdup(session, data); + assert(mydata != NULL); + + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (!switch_strlen_zero(argv[0])) { + mcast_ip = argv[0]; + } + + if (!switch_strlen_zero(argv[1])) { + mcast_port_str = argv[1]; + mcast_port = atoi(mcast_port_str); + } + + if (!switch_strlen_zero(argv[2])) { + mcast_control_port = atoi(argv[2]); + } + } + + + if (switch_true(switch_channel_get_variable(channel, "no_media"))) { + switch_core_session_message_t msg = { 0 }; + + ready = SEND_TYPE_NOMEDIA; + + switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, mcast_ip); + switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, mcast_port_str); + + /* special answer with the mcast addr */ + msg.from = __FILE__; + msg.string_arg = data; + msg.message_id = SWITCH_MESSAGE_INDICATE_BROADCAST; + switch_core_session_receive_message(session, &msg); + } else { + switch_channel_answer(channel); + } + + read_codec = switch_core_session_get_read_codec(session); + + if (switch_socket_create(&socket, AF_INET, SOCK_DGRAM, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Error 1\n"); + goto fail; + } + + if (switch_sockaddr_info_get(&control_packet_addr, mcast_ip, SWITCH_UNSPEC, + mcast_control_port, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Error 3\n"); + goto fail; + } + + + while(!ready) { + status = switch_core_session_read_frame(session, &read_frame, -1, 0); + if (switch_test_flag(read_frame, SFF_CNG)) { + continue; + } + + if (!SWITCH_READ_ACCEPTABLE(status)) { + goto fail; + } + + if (read_frame->packet && read_frame->packetlen) { + ready = SEND_TYPE_RAW; + } else { + ready = SEND_TYPE_RTP; + } + + } + + if (ready == SEND_TYPE_RTP) { + rtp_port = switch_rtp_request_port(); + switch_find_local_ip(guess_ip, sizeof(guess_ip), AF_INET); + rtp_session = switch_rtp_new(guess_ip, + rtp_port, + mcast_ip, + mcast_port, + read_codec->implementation->ianacode, + read_codec->implementation->samples_per_frame, + read_codec->implementation->microseconds_per_frame, + (switch_rtp_flag_t) flags, + NULL, "soft", &err, switch_core_session_get_pool(session)); + + if (!switch_rtp_ready(rtp_session)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "RTP Error\n"); + goto fail; + } + } else if (ready == SEND_TYPE_NOMEDIA) { + switch_yield(10000); + } else if (ready == SEND_TYPE_RAW) { + if (switch_sockaddr_info_get(&audio_addr, mcast_ip, SWITCH_UNSPEC, mcast_port, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Error 2\n"); + goto fail; + } + } + + control_packet.unique_id = htonl(time(NULL)); + control_packet.command = htonl(LS_START_BCAST); + control_packet.ip = inet_addr(mcast_ip); + control_packet.port = htonl(mcast_port); + + bytes = 16; + switch_socket_sendto(socket, control_packet_addr, 0, (void *)&control_packet, &bytes); + bytes = 16; + switch_socket_sendto(socket, control_packet_addr, 0, (void *)&control_packet, &bytes); + + + for(;;) { + status = switch_core_session_read_frame(session, &read_frame, -1, 0); + if (!SWITCH_READ_ACCEPTABLE(status)) { + break; + } + if (switch_test_flag(read_frame, SFF_CNG)) { + continue; + } + if (ready == SEND_TYPE_RTP) { + switch_rtp_write_frame(rtp_session, read_frame, 0); + } else { + bytes = read_frame->packetlen; + switch_socket_sendto(socket, audio_addr, 0, read_frame->packet, &bytes); + } + } + + + + control_packet.unique_id = htonl(time(NULL)); + control_packet.command = htonl(LS_STOP_BCAST); + bytes = 8; + switch_socket_sendto(socket, control_packet_addr, 0, (void *)&control_packet, &bytes); + bytes = 8; + switch_socket_sendto(socket, control_packet_addr, 0, (void *)&control_packet, &bytes); + + fail: + + if (ready == SEND_TYPE_RTP && switch_rtp_ready(rtp_session)) { + switch_rtp_destroy(&rtp_session); + } + + if (socket) { + switch_socket_close(socket); + } + + return; +} + + +static const switch_application_interface_t bcast_application_interface = { + /*.interface_name */ "esf_ls_page_group", + /*.application_function */ bcast_function, + NULL, NULL, NULL, + /* flags */ SAF_NONE, + /*.next */ NULL +}; + +static const switch_loadable_module_interface_t mod_ivrtest_module_interface = { + /*.module_name = */ modname, + /*.endpoint_interface = */ NULL, + /*.timer_interface = */ NULL, + /*.dialplan_interface = */ NULL, + /*.codec_interface = */ NULL, + /*.application_interface */ &bcast_application_interface +}; + +SWITCH_MOD_DECLARE(switch_status_t) switch_module_load(const switch_loadable_module_interface_t **module_interface, char *filename) +{ + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = &mod_ivrtest_module_interface; + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + + +//switch_status_t switch_module_runtime(void) + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab: + */ Added: freeswitch/trunk/src/mod/applications/mod_esf/mod_esf.vcproj ============================================================================== --- (empty file) +++ freeswitch/trunk/src/mod/applications/mod_esf/mod_esf.vcproj Tue May 1 17:21:35 2007 @@ -0,0 +1,210 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="mod_esf" + ProjectGUID="{419AA391-5F3F-4BFE-A869-9D154D62A792}" + RootNamespace="mod_esf" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories=""$(InputDir)..\..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\..\libs\include"" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(SolutionDir)$(OutDir)/mod/$(InputName).dll" + LinkIncremental="1" + AdditionalLibraryDirectories="..\..\..\..\w32\vsnet\$(OutDir)" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)$(TargetName).pdb" + SubSystem="2" + ImportLibrary="$(OutDir)/mod_esf.lib" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories=""$(InputDir)..\..\..\include";"$(InputDir)include";"$(InputDir)..\..\..\..\libs\include"" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(SolutionDir)$(OutDir)/mod/$(InputName).dll" + LinkIncremental="1" + AdditionalLibraryDirectories="..\..\..\..\w32\vsnet\$(OutDir)" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(OutDir)$(TargetName).pdb" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + ImportLibrary="$(OutDir)/mod_esf.lib" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\mod_esf.c" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c ============================================================================== --- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original) +++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Tue May 1 17:21:35 2007 @@ -674,7 +674,20 @@ switch (msg->message_id) { - case SWITCH_MESSAGE_INDICATE_NOMEDIA:{ + case SWITCH_MESSAGE_INDICATE_BROADCAST: { + char *ip = NULL, *port = NULL; + ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE); + port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE); + if (ip && port) { + sofia_glue_set_local_sdp(tech_pvt, ip, atoi(port), NULL, 1); + } + nua_respond(tech_pvt->nh, SIP_200_OK, + SIPTAG_CONTACT_STR(tech_pvt->profile->url), + SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1), TAG_END()); + switch_channel_mark_answered(channel); + } + break; + case SWITCH_MESSAGE_INDICATE_NOMEDIA: { char *uuid; switch_core_session_t *other_session; switch_channel_t *other_channel; @@ -696,7 +709,7 @@ sofia_glue_tech_absorb_sdp(tech_pvt); } sofia_glue_do_invite(session); - } + } break; case SWITCH_MESSAGE_INDICATE_MEDIA:{ switch_clear_flag_locked(tech_pvt, TFLAG_NOMEDIA);
participants (1)
-
Freeswitch SVN