forked from mirrors/linphone-iphone
Merge branch 'master' of git.linphone.org:linphone-private
This commit is contained in:
commit
2667f001eb
118 changed files with 11547 additions and 6585 deletions
455
.cproject
455
.cproject
|
|
@ -2,231 +2,232 @@
|
|||
<?fileVersion 4.0.0?>
|
||||
|
||||
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="0.2079208171">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.2079208171" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="linphone" buildProperties="" description="" id="0.2079208171" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
|
||||
<folderInfo id="0.2079208171." name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.2084203071" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||
<targetPlatform binaryParser="org.eclipse.cdt.core.MachO64;org.eclipse.cdt.core.ELF" id="org.eclipse.cdt.build.core.prefbase.toolchain.2084203071.81924294" name=""/>
|
||||
<builder id="org.eclipse.cdt.build.core.settings.default.builder.731584538" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1252970003" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1371414073" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.306286573" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.391709798" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1702094818" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.754828354" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.585510934" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<scannerConfigBuildInfo instanceId="0.2079208171">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
|
||||
<buildTargets>
|
||||
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="install" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>install</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="linphone.null.1149313048" name="linphone"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="0.2079208171">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.2079208171" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="linphone" buildProperties="" description="" id="0.2079208171" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
|
||||
<folderInfo id="0.2079208171." name="/" resourcePath="">
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.2084203071" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||
<targetPlatform binaryParser="org.eclipse.cdt.core.MachO64;org.eclipse.cdt.core.ELF" id="org.eclipse.cdt.build.core.prefbase.toolchain.2084203071.81924294" name=""/>
|
||||
<builder id="org.eclipse.cdt.build.core.settings.default.builder.731584538" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1252970003" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1371414073" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.306286573" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.391709798" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1702094818" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.754828354" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.585510934" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<scannerConfigBuildInfo instanceId="0.2079208171">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
|
||||
<buildTargets>
|
||||
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="install" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildTarget>install</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="linphone.null.1149313048" name="linphone"/>
|
||||
</storageModule>
|
||||
</cproject>
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -39,7 +39,6 @@ INSTALL
|
|||
Specfile
|
||||
.anjuta/
|
||||
.anjuta_sym_db.db
|
||||
coreapi/help/doxygen.dox
|
||||
gtk-glade/version_date.h
|
||||
share/linphone.desktop
|
||||
|
||||
|
|
|
|||
25
Makefile.am
25
Makefile.am
|
|
@ -3,14 +3,21 @@
|
|||
# let make re-run automake upon need
|
||||
ACLOCAL_AMFLAGS = -I m4 $(ACLOCAL_MACOS_FLAGS)
|
||||
|
||||
if EXTERNAL_ORTP
|
||||
ORTP_DIR =
|
||||
if EXTERNAL_MEDIASTREAMER
|
||||
MS2_DIR=
|
||||
else
|
||||
ORTP_DIR = oRTP
|
||||
MS2_DIR=mediastreamer2
|
||||
endif
|
||||
|
||||
SUBDIRS = m4 pixmaps po $(ORTP_DIR) mediastreamer2\
|
||||
coreapi console gtk-glade share scripts
|
||||
if EXTERNAL_ORTP
|
||||
ORTP_DIR=
|
||||
else
|
||||
ORTP_DIR=oRTP
|
||||
endif
|
||||
|
||||
|
||||
SUBDIRS = m4 pixmaps po $(ORTP_DIR) $(MS2_DIR) \
|
||||
coreapi console gtk share scripts
|
||||
|
||||
|
||||
|
||||
|
|
@ -42,6 +49,7 @@ SDK_EXCLUDED= \
|
|||
|
||||
|
||||
GTK_PREFIX=/usr
|
||||
GTK_THEME=Outcrop
|
||||
GTK_FILELIST=gtk+-2.18.5.filelist
|
||||
GTK_FILELIST_PATH=$(shell cd $(top_srcdir) && pwd)/$(GTK_FILELIST)
|
||||
LINPHONEDEPS_FILELIST=linphone-deps.filelist
|
||||
|
|
@ -113,7 +121,8 @@ gtk-cherrypick:
|
|||
cp $$file $(INSTALLDIR_WITH_PREFIX)/$$file ;\
|
||||
fi \
|
||||
done && \
|
||||
cp -rf share/themes $(INSTALLDIR_WITH_PREFIX)/share/.
|
||||
mkdir -p $(INSTALLDIR_WITH_PREFIX)/share/themes && \
|
||||
cp -rf share/themes/$(GTK_THEME) $(INSTALLDIR_WITH_PREFIX)/share/themes/.
|
||||
|
||||
zip:
|
||||
rm -f $(ZIPFILE)
|
||||
|
|
@ -125,7 +134,7 @@ zip:
|
|||
#add gtk dlls and files
|
||||
make gtk-cherrypick
|
||||
make other-cherrypick
|
||||
cp -f $(top_srcdir)/gtk-glade/gtkrc $(INSTALLDIR_WITH_PREFIX)/.
|
||||
cp -f $(top_srcdir)/gtk/gtkrc $(INSTALLDIR_WITH_PREFIX)/.
|
||||
cp -f $(top_srcdir)/README $(INSTALLDIR_WITH_PREFIX)/.
|
||||
cp -f $(top_srcdir)/COPYING $(INSTALLDIR_WITH_PREFIX)/.
|
||||
cd $(INSTALLDIR_WITH_PREFIX) && zip -r $(ZIPFILE) *
|
||||
|
|
@ -162,7 +171,7 @@ setup.exe: filelist
|
|||
rm -f $(INSTALLDIR_WITH_PREFIX)/$(ISS_SCRIPT)
|
||||
|
||||
newdate:
|
||||
cd gtk-glade && $(MAKE) newdate
|
||||
cd gtk && $(MAKE) newdate
|
||||
|
||||
|
||||
Portfile: $(top_srcdir)/scripts/Portfile.tmpl dist
|
||||
|
|
|
|||
10
TODO
10
TODO
|
|
@ -3,20 +3,12 @@ hot stuff:
|
|||
|
||||
* ice support
|
||||
* run a user given command upon incoming calls
|
||||
* linphonec on win32
|
||||
* RTP inactivity timeout to close lost calls.
|
||||
|
||||
* SIP/TLS and SRTP
|
||||
|
||||
low priority:
|
||||
-------------
|
||||
|
||||
* random RTP ports (to enable direct mapping NAT)
|
||||
* zeroconf support for advertising services (cool stuff!)
|
||||
* have the possibility to define several profiles (config files) and switch between them
|
||||
* display call duration
|
||||
* help tips for the registration box
|
||||
* The length (or duration) of the call could be displayed (see icons2.png)
|
||||
* 2. There could be a sound effect for "busy" - a short "beep-beep-beep" would be sufficient (try http://www.google.com/search?q=busy.wav)
|
||||
* The call history could be a bit more clear (see history.png). And it
|
||||
should be saved somewhere, so you can track your calls if you need to...
|
||||
* move resampling stuff to use speex instead of libresample.
|
||||
|
|
@ -30,14 +30,12 @@ LOCAL_SRC_FILES = \
|
|||
linphonecore.c \
|
||||
misc.c \
|
||||
enum.c \
|
||||
enum.h \
|
||||
presence.c \
|
||||
proxy.c \
|
||||
friend.c \
|
||||
authentication.c \
|
||||
lpconfig.c \
|
||||
chat.c \
|
||||
general_state.c \
|
||||
sipsetup.c \
|
||||
siplogin.c \
|
||||
address.c \
|
||||
|
|
@ -47,7 +45,8 @@ LOCAL_SRC_FILES = \
|
|||
sal_eXosip2_presence.c \
|
||||
sal_eXosip2_sdp.c \
|
||||
offeranswer.c \
|
||||
callbacks.c
|
||||
callbacks.c \
|
||||
linphonecall.c
|
||||
|
||||
LOCAL_CFLAGS += \
|
||||
-D_BYTE_ORDER=_LITTLE_ENDIAN \
|
||||
|
|
@ -58,7 +57,10 @@ LOCAL_CFLAGS += \
|
|||
-DLOG_DOMAIN=\"Linphone\"
|
||||
|
||||
LOCAL_CFLAGS += -DIN_LINPHONE
|
||||
#LOCAL_CFLAGS += -DVIDEO_ENABLED -DIN_LINPHONE
|
||||
|
||||
ifeq ($(LINPHONE_VIDEO),1)
|
||||
LOCAL_CFLAGS += -DVIDEO_ENABLED
|
||||
endif
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LOCAL_PATH) \
|
||||
|
|
@ -68,7 +70,7 @@ LOCAL_C_INCLUDES += \
|
|||
$(LOCAL_PATH)/../../externals/exosip/include \
|
||||
$(LOCAL_PATH)/../../externals/osip/include
|
||||
|
||||
LOCAL_LDLIBS += -llog
|
||||
LOCAL_LDLIBS += -llog -ldl
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libmediastreamer2 \
|
||||
|
|
@ -77,6 +79,15 @@ LOCAL_STATIC_LIBRARIES := \
|
|||
libeXosip2 \
|
||||
libosip2 \
|
||||
libgsm
|
||||
|
||||
ifeq ($(LINPHONE_VIDEO),1)
|
||||
LOCAL_STATIC_LIBRARIES += \
|
||||
libavcodec \
|
||||
libswscale \
|
||||
libavcore \
|
||||
libavutil
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
LOCAL_CFLAGS += -DHAVE_ILBC=1
|
||||
LOCAL_STATIC_LIBRARIES += libmsilbc
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([linphone],[3.3.2],[linphone-developers@nongnu.org])
|
||||
AC_INIT([linphone],[3.3.99.10],[linphone-developers@nongnu.org])
|
||||
AC_CANONICAL_SYSTEM
|
||||
AC_CONFIG_SRCDIR([coreapi/linphonecore.c])
|
||||
|
||||
dnl Source packaging numbers
|
||||
|
||||
|
|
@ -15,7 +16,12 @@ LINPHONE_VERSION=$LINPHONE_MAJOR_VERSION.$LINPHONE_MINOR_VERSION.${LINPHONE_MICR
|
|||
if test "$LINPHONE_EXTRA_VERSION" != "" ;then
|
||||
LINPHONE_VERSION=$LINPHONE_VERSION.${LINPHONE_EXTRA_VERSION}
|
||||
fi
|
||||
LIBLINPHONE_SO_VERSION=`expr $LINPHONE_MINOR_VERSION + $LINPHONE_MAJOR_VERSION`:$LINPHONE_MICRO_VERSION:$LINPHONE_MINOR_VERSION
|
||||
|
||||
LIBLINPHONE_SO_CURRENT=4 dnl increment this number when you add/change/remove an interface
|
||||
LIBLINPHONE_SO_REVISION=0 dnl increment this number when you change source code, without changing interfaces; set to 0 when incrementing CURRENT
|
||||
LIBLINPHONE_SO_AGE=0 dnl increment this number when you add an interface, set to 0 if you remove an interface
|
||||
|
||||
LIBLINPHONE_SO_VERSION=$LIBLINPHONE_SO_CURRENT:$LIBLINPHONE_SO_REVISION:$LIBLINPHONE_SO_AGE
|
||||
|
||||
AC_SUBST(LIBLINPHONE_SO_VERSION, $LIBLINPHONE_SO_VERSION)
|
||||
AC_SUBST(LINPHONE_VERSION)
|
||||
|
|
@ -23,7 +29,8 @@ AC_SUBST(LINPHONE_VERSION)
|
|||
AC_MSG_NOTICE([$PACKAGE_NAME-$PACKAGE_VERSION A full featured audio/video sip phone.])
|
||||
AC_MSG_NOTICE([licensed under the terms of the General Public License (GPL)])
|
||||
|
||||
AM_INIT_AUTOMAKE([tar-ustar])
|
||||
AM_INIT_AUTOMAKE
|
||||
AC_SUBST([LIBTOOL_DEPS])
|
||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
|
@ -62,7 +69,8 @@ AC_SUBST(CONSOLE_FLAGS)
|
|||
AC_SUBST(GUI_FLAGS)
|
||||
|
||||
dnl localization tools
|
||||
ifdef([IT_PROG_INTLTOOL],[IT_PROG_INTLTOOL],[AC_PROG_INTLTOOL])
|
||||
IT_PROG_INTLTOOL([0.40], [no-xml])
|
||||
|
||||
dnl Initialize libtool
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
AC_PROG_LIBTOOL
|
||||
|
|
@ -130,11 +138,8 @@ AC_ARG_ENABLE(gtk_ui,
|
|||
|
||||
if test "$gtk_ui" = "true" ; then
|
||||
PKG_CHECK_MODULES(LIBGTK, gtk+-2.0 >= 2.4.0 gthread-2.0)
|
||||
PKG_CHECK_MODULES(LIBGLADE, libglade-2.0 >= 2.4.0)
|
||||
AC_SUBST(LIBGTK_CFLAGS)
|
||||
AC_SUBST(LIBGTK_LIBS)
|
||||
AC_SUBST(LIBGLADE_CFLAGS)
|
||||
AC_SUBST(LIBGLADE_LIBS)
|
||||
else
|
||||
echo "GTK interface compilation is disabled."
|
||||
fi
|
||||
|
|
@ -288,11 +293,19 @@ AC_ARG_WITH( ffmpeg,
|
|||
[ --with-ffmpeg Sets the installation prefix of ffmpeg, needed for video support. [default=/usr] ],
|
||||
[ ffmpegdir=${withval}],[ ffmpegdir=/usr ])
|
||||
|
||||
AC_ARG_WITH( sdl,
|
||||
[ --with-sdl Sets the installation prefix of libSDL, needed for video support. [default=/usr] ],
|
||||
[ libsdldir=${withval}],[ libsdldir=/usr ])
|
||||
AC_ARG_ENABLE(x11,
|
||||
[ --disable-x11 Disable X11 support],
|
||||
[case "${enableval}" in
|
||||
yes) enable_x11=true ;;
|
||||
no) enable_x11=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --disable-x11) ;;
|
||||
esac],[enable_x11=true])
|
||||
|
||||
if test "$video" = "true"; then
|
||||
|
||||
if test "$enable_x11" = "true"; then
|
||||
AC_CHECK_HEADERS(X11/Xlib.h)
|
||||
fi
|
||||
AC_DEFINE(VIDEO_ENABLED,1,[defined if video support is available])
|
||||
fi
|
||||
|
||||
|
|
@ -324,8 +337,8 @@ dnl build console if required
|
|||
AM_CONDITIONAL(BUILD_CONSOLE, test x$console_ui = xtrue)
|
||||
dnl special things for arm-linux cross compilation toolchain
|
||||
AM_CONDITIONAL(ARMBUILD, test x$use_arm_toolchain = xyes)
|
||||
dnl compilation of gtk-glade user interface
|
||||
AM_CONDITIONAL(BUILD_GLADE_UI, [test x$gtk_ui = xtrue ] )
|
||||
dnl compilation of gtk user interface
|
||||
AM_CONDITIONAL(BUILD_GTK_UI, [test x$gtk_ui = xtrue ] )
|
||||
AM_CONDITIONAL(BUILD_WIN32, test x$mingw_found = xyes )
|
||||
|
||||
dnl check getenv
|
||||
|
|
@ -360,15 +373,40 @@ fi
|
|||
|
||||
AC_SUBST(STRICT_OPTIONS)
|
||||
|
||||
AC_CONFIG_SUBDIRS( mediastreamer2 )
|
||||
top_srcdir=`dirname $0`
|
||||
|
||||
AC_ARG_ENABLE([external-mediastreamer],
|
||||
[AS_HELP_STRING([--enable-external-mediastreamer],[Use external mediastreamer library])],,
|
||||
[enable_external_mediastreamer=no])
|
||||
|
||||
AS_CASE($enable_external_mediastreamer,
|
||||
[yes],[
|
||||
PKG_CHECK_MODULES([MEDIASTREAMER], [mediastreamer])
|
||||
MS2_VERSION=`$PKG_CONFIG --modversion mediastreamer`
|
||||
AM_CONDITIONAL(EXTERNAL_MEDIASTREAMER, [true])],
|
||||
[no],[
|
||||
AC_CONFIG_SUBDIRS( mediastreamer2 )
|
||||
MEDIASTREAMER_DIR=${top_srcdir}/mediastreamer2
|
||||
MEDIASTREAMER_CFLAGS="-I\$(top_srcdir)/mediastreamer2/include"
|
||||
MEDIASTREAMER_LIBS="\$(top_builddir)/mediastreamer2/src/libmediastreamer.la"
|
||||
dnl need to temporary change quotes to allow square brackets
|
||||
changequote(<<, >>)
|
||||
MS2_VERSION=`grep -e '^.C_INIT(' $MEDIASTREAMER_DIR/configure.ac | sed -e 's:\([^(]\+\)(\[mediastreamer\],\[\(.*\)\]):\2:g'`
|
||||
changequote([, ])
|
||||
AM_CONDITIONAL(EXTERNAL_MEDIASTREAMER, [false])],
|
||||
[AC_MSG_ERROR([bad value '${enable_external_mediastreamer}' for --enable-external-mediastreamer])])
|
||||
|
||||
AC_SUBST(MEDIASTREAMER_CFLAGS)
|
||||
AC_SUBST(MEDIASTREAMER_LIBS)
|
||||
AC_SUBST([MS2_VERSION])
|
||||
|
||||
dnl check for db2html (docbook) to generate html user manual
|
||||
AC_CHECK_PROG(have_sgmltools,sgmltools, yes, no)
|
||||
AM_CONDITIONAL(ENABLE_MANUAL, test x$have_sgmltools$build_manual = xyesyes )
|
||||
|
||||
dnl for external use of linphone libs
|
||||
LINPHONE_CFLAGS="-I${includedir} -I${includedir}/linphone "
|
||||
LINPHONE_LIBS="-L${libdir} -llinphone"
|
||||
LINPHONE_CFLAGS="-I${includedir} -I${includedir}/linphone"
|
||||
LINPHONE_LIBS="-L${libdir} -llinphone"
|
||||
|
||||
if test x$mingw_found = xyes ; then
|
||||
LINPHONE_LIBS="$LINPHONE_LIBS $OSIP_LIBS"
|
||||
|
|
@ -376,7 +414,6 @@ fi
|
|||
AC_SUBST(LINPHONE_CFLAGS)
|
||||
AC_SUBST(LINPHONE_LIBS)
|
||||
|
||||
|
||||
AC_DEFINE_UNQUOTED(LINPHONE_VERSION,"$PACKAGE_VERSION",[Linphone's version number])
|
||||
|
||||
AC_DEFINE_UNQUOTED(LINPHONE_PLUGINS_DIR, "${package_prefix}/lib/liblinphone/plugins" ,[path of liblinphone plugins, not mediastreamer2 plugins])
|
||||
|
|
@ -392,7 +429,8 @@ AC_ARG_ENABLE(external-ortp,
|
|||
esac],[external_ortp=false])
|
||||
|
||||
if test "$external_ortp" = 'true'; then
|
||||
LP_CHECK_ORTP
|
||||
PKG_CHECK_MODULES([ORTP], [ortp])
|
||||
ORTP_VERSION=`$PKG_CONFIG --modversion ortp`
|
||||
else
|
||||
AC_CONFIG_SUBDIRS( oRTP )
|
||||
ORTP_CFLAGS="-I\$(top_srcdir)/oRTP/include"
|
||||
|
|
@ -400,22 +438,16 @@ else
|
|||
if test x$ac_cv_c_bigendian = xyes ; then
|
||||
ORTP_CFLAGS="$ORTP_CFLAGS -DORTP_BIGENDIAN"
|
||||
fi
|
||||
changequote(<<, >>)
|
||||
ORTP_VERSION=`grep -E ^[AC]+_INIT ${top_srcdir}/oRTP/configure.ac | sed -e 's:^.*_INIT(.*,\[\(.*\)\]):\1:g'`
|
||||
changequote([, ])
|
||||
fi
|
||||
AC_SUBST(ORTP_CFLAGS)
|
||||
AC_SUBST(ORTP_LIBS)
|
||||
AC_SUBST([ORTP_VERSION])
|
||||
|
||||
AM_CONDITIONAL(EXTERNAL_ORTP, [test "$external_ortp" = 'true'])
|
||||
|
||||
dnl Packaging: Pick oRTP version from ${top_srcdir}/oRTP/configure.ac
|
||||
dnl Feel free to propose an alternative & cleaner version...
|
||||
top_srcdir=`dirname $0`
|
||||
changequote(, )dnl
|
||||
ORTP_VERSION=`grep -E ^[AC]+_INIT ${top_srcdir}/oRTP/configure.ac | sed -e 's:^.*_INIT(.*,\[\(.*\)\]):\1:g'`
|
||||
MS2_VERSION=`grep -E ^[AC]+_INIT ${top_srcdir}/mediastreamer2/configure.ac | sed -e 's:^.*_INIT(.*,\[\(.*\)\]):\1:g'`
|
||||
changequote([, ])dnl
|
||||
AC_SUBST([ORTP_VERSION])
|
||||
AC_SUBST([MS2_VERSION])
|
||||
|
||||
dnl ##################################################
|
||||
dnl # Check for doxygen
|
||||
dnl ##################################################
|
||||
|
|
@ -427,13 +459,12 @@ AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN != false)
|
|||
AC_OUTPUT([
|
||||
Makefile
|
||||
m4/Makefile
|
||||
po/Makefile.in
|
||||
po/Makefile.in
|
||||
pixmaps/Makefile
|
||||
coreapi/Makefile
|
||||
coreapi/help/Makefile
|
||||
coreapi/help/Doxyfile
|
||||
coreapi/help/doxygen.dox
|
||||
gtk-glade/Makefile
|
||||
gtk/Makefile
|
||||
console/Makefile
|
||||
share/Makefile
|
||||
share/C/Makefile
|
||||
|
|
@ -9,9 +9,7 @@ INCLUDES = \
|
|||
-I$(top_srcdir)/coreapi\
|
||||
$(ORTP_CFLAGS) \
|
||||
-I$(top_srcdir)/exosip \
|
||||
-I$(top_srcdir)/mediastreamer2/include
|
||||
|
||||
|
||||
$(MEDIASTREAMER_CFLAGS)
|
||||
|
||||
bin_PROGRAMS = linphonec linphonecsh
|
||||
|
||||
|
|
@ -22,7 +20,7 @@ endif
|
|||
linphonec_SOURCES = linphonec.c linphonec.h commands.c
|
||||
linphonec_CFLAGS=$(COMMON_CFLAGS) $(CONSOLE_FLAGS)
|
||||
linphonec_LDADD = $(top_builddir)/coreapi/liblinphone.la $(READLINE_LIBS) \
|
||||
$(top_builddir)/mediastreamer2/src/libmediastreamer.la \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS) \
|
||||
$(SPEEX_LIBS) \
|
||||
$(OSIP_LIBS)
|
||||
|
|
@ -41,7 +39,7 @@ sipomatic_CFLAGS= $(COMMON_CFLAGS) $(CONSOLE_FLAGS)
|
|||
|
||||
sipomatic_LDADD= $(INTLLIBS) \
|
||||
$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(top_builddir)/mediastreamer2/src/libmediastreamer.la \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS) \
|
||||
$(SPEEX_LIBS) \
|
||||
$(OSIP_LIBS)
|
||||
|
|
@ -53,6 +51,3 @@ linphonecsh_LDADD = $(ORTP_LIBS)
|
|||
endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -77,6 +77,11 @@
|
|||
#define PACKAGE_DIR ""
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_X11_XLIB_H
|
||||
#include <X11/Xlib.h>
|
||||
#include <SDL/SDL_syswm.h>
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Types
|
||||
|
|
@ -112,25 +117,24 @@ static char **linephonec_readline_completion(const char *text,
|
|||
#endif
|
||||
|
||||
/* These are callback for linphone core */
|
||||
static void linphonec_call_received(LinphoneCore *lc, const char *from);
|
||||
static void linphonec_prompt_for_auth(LinphoneCore *lc, const char *realm,
|
||||
const char *username);
|
||||
static void linphonec_display_refer (LinphoneCore * lc,const char *refer_to);
|
||||
static void linphonec_display_refer (LinphoneCore * lc, const char *refer_to);
|
||||
static void linphonec_display_something (LinphoneCore * lc, const char *something);
|
||||
static void linphonec_display_url (LinphoneCore * lc, const char *something, const char *url);
|
||||
static void linphonec_display_warning (LinphoneCore * lc, const char *something);
|
||||
static void stub () {}
|
||||
static void linphonec_notify_received(LinphoneCore *lc,const char *from,const char *msg);
|
||||
static void linphonec_notify_received(LinphoneCore *lc, LinphoneCall *call, const char *from,const char *event);
|
||||
|
||||
static void linphonec_notify_presence_received(LinphoneCore *lc,LinphoneFriend *fid);
|
||||
static void linphonec_new_unknown_subscriber(LinphoneCore *lc,
|
||||
LinphoneFriend *lf, const char *url);
|
||||
static void linphonec_bye_received(LinphoneCore *lc, const char *from);
|
||||
|
||||
static void linphonec_text_received(LinphoneCore *lc, LinphoneChatRoom *cr,
|
||||
const char *from, const char *msg);
|
||||
const LinphoneAddress *from, const char *msg);
|
||||
static void linphonec_display_status (LinphoneCore * lc, const char *something);
|
||||
static void linphonec_general_state (LinphoneCore * lc, LinphoneGeneralState *gstate);
|
||||
static void linphonec_dtmf_received(LinphoneCore *lc, int dtmf);
|
||||
static void linphonec_dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf);
|
||||
static void print_prompt(LinphoneCore *opm);
|
||||
void linphonec_out(const char *fmt,...);
|
||||
/***************************************************************************
|
||||
*
|
||||
* Global variables
|
||||
|
|
@ -156,6 +160,7 @@ LPC_AUTH_STACK auth_stack;
|
|||
static int trace_level = 0;
|
||||
static char *logfile_name = NULL;
|
||||
static char configfile_name[PATH_MAX];
|
||||
static const char *factory_configfile_name=NULL;
|
||||
static char *sipAddr = NULL; /* for autocall */
|
||||
#if !defined(_WIN32_WCE)
|
||||
static ortp_pipe_t client_sock=ORTP_PIPE_INVALID;
|
||||
|
|
@ -169,35 +174,27 @@ static bool_t pipe_reader_run=FALSE;
|
|||
static ortp_pipe_t server_sock;
|
||||
#endif /*_WIN32_WCE*/
|
||||
|
||||
bool_t linphonec_camera_enabled=TRUE;
|
||||
|
||||
LinphoneCoreVTable linphonec_vtable
|
||||
#if !defined (_MSC_VER)
|
||||
= {
|
||||
.show =(ShowInterfaceCb) stub,
|
||||
.inv_recv = linphonec_call_received,
|
||||
.bye_recv = linphonec_bye_received,
|
||||
.notify_recv = linphonec_notify_received,
|
||||
.notify_presence_recv = linphonec_notify_presence_received,
|
||||
.new_unknown_subscriber = linphonec_new_unknown_subscriber,
|
||||
.auth_info_requested = linphonec_prompt_for_auth,
|
||||
.display_status = linphonec_display_status,
|
||||
.display_message=linphonec_display_something,
|
||||
#ifdef VINCENT_MAURY_RSVP
|
||||
/* the yes/no dialog box */
|
||||
.display_yes_no= (DisplayMessageCb) stub,
|
||||
#endif
|
||||
.display_warning=linphonec_display_warning,
|
||||
.display_url=linphonec_display_url,
|
||||
.display_question=(DisplayQuestionCb)stub,
|
||||
.text_received=linphonec_text_received,
|
||||
.general_state=linphonec_general_state,
|
||||
.dtmf_received=linphonec_dtmf_received,
|
||||
.refer_received=linphonec_display_refer
|
||||
|
||||
|
||||
void linphonec_call_identify(LinphoneCall* call){
|
||||
static long callid=1;
|
||||
linphone_call_set_user_pointer (call,(void*)callid);
|
||||
callid++;
|
||||
}
|
||||
#endif /*_WIN32_WCE*/
|
||||
;
|
||||
|
||||
|
||||
LinphoneCall *linphonec_get_call(long id){
|
||||
const MSList *elem=linphone_core_get_calls(linphonec);
|
||||
for (;elem!=NULL;elem=elem->next){
|
||||
LinphoneCall *call=(LinphoneCall*)elem->data;
|
||||
if (linphone_call_get_user_pointer (call)==(void*)id){
|
||||
return call;
|
||||
}
|
||||
}
|
||||
linphonec_out("Sorry, no call with id %i exists at this time.\n",id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
|
|
@ -209,10 +206,9 @@ LinphoneCoreVTable linphonec_vtable
|
|||
* Linphone core callback
|
||||
*/
|
||||
static void
|
||||
linphonec_display_refer (LinphoneCore * lc,const char *refer_to)
|
||||
linphonec_display_refer (LinphoneCore * lc, const char *refer_to)
|
||||
{
|
||||
fprintf (stdout, "The distant end point asked to transfer the call to %s,don't forget to terminate the call if not\n%s", refer_to,prompt);
|
||||
fflush(stdout);
|
||||
linphonec_out("Receiving out of call refer to %s\n", refer_to);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -254,19 +250,6 @@ linphonec_display_url (LinphoneCore * lc, const char *something, const char *url
|
|||
fprintf (stdout, "%s : %s\n", something, url);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Linphone core callback
|
||||
*/
|
||||
static void
|
||||
linphonec_call_received(LinphoneCore *lc, const char *from)
|
||||
{
|
||||
linphonec_set_caller(from);
|
||||
if ( auto_answer) {
|
||||
answer_call=TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Linphone core callback
|
||||
*/
|
||||
|
|
@ -296,16 +279,16 @@ linphonec_prompt_for_auth(LinphoneCore *lc, const char *realm, const char *usern
|
|||
* Linphone core callback
|
||||
*/
|
||||
static void
|
||||
linphonec_notify_received(LinphoneCore *lc,const char *from,const char *msg)
|
||||
linphonec_notify_received(LinphoneCore *lc, LinphoneCall *call, const char *from,const char *event)
|
||||
{
|
||||
printf("Notify type %s from %s\n", msg, from);
|
||||
if(!strcmp(msg,"refer"))
|
||||
if(!strcmp(event,"refer"))
|
||||
{
|
||||
printf("The distant SIP end point get the refer we can close the call\n");
|
||||
linphonec_parse_command_line(linphonec, "terminate");
|
||||
linphonec_out("The distand endpoint %s of call %li has been transfered, you can safely close the call.\n",
|
||||
from,(long)linphone_call_get_user_pointer (call));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Linphone core callback
|
||||
*/
|
||||
|
|
@ -332,17 +315,73 @@ linphonec_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf,
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
* Linphone core callback
|
||||
*/
|
||||
static void
|
||||
linphonec_bye_received(LinphoneCore *lc, const char *from)
|
||||
{
|
||||
// Should change prompt back to original maybe
|
||||
static void linphonec_call_updated(LinphoneCall *call){
|
||||
const LinphoneCallParams *cp=linphone_call_get_current_params(call);
|
||||
if (!linphone_call_camera_enabled (call) && linphone_call_params_video_enabled (cp)){
|
||||
linphonec_out("Far end requests to share video.\nType 'camera on' if you agree.\n");
|
||||
}
|
||||
}
|
||||
|
||||
// printing this is unneeded as we'd get a "Communication ended"
|
||||
// message trough display_status callback anyway
|
||||
//printf("Bye received from %s\n", from);
|
||||
static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState st, const char *msg){
|
||||
char *from=linphone_call_get_remote_address_as_string(call);
|
||||
long id=(long)linphone_call_get_user_pointer (call);
|
||||
switch(st){
|
||||
case LinphoneCallEnd:
|
||||
linphonec_out("Call %i with %s ended.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallResuming:
|
||||
linphonec_out("Resuming call %i with %s.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallStreamsRunning:
|
||||
linphonec_out("Media streams established with %s for call %i.\n", from,id);
|
||||
break;
|
||||
case LinphoneCallPausing:
|
||||
linphonec_out("Pausing call %i with %s.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallPaused:
|
||||
linphonec_out("Call %i with %s is now paused.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallPausedByRemote:
|
||||
linphonec_out("Call %i has been paused by %s.\n",id,from);
|
||||
break;
|
||||
case LinphoneCallIncomingReceived:
|
||||
linphonec_call_identify(call);
|
||||
linphone_call_enable_camera (call,linphonec_camera_enabled);
|
||||
id=(long)linphone_call_get_user_pointer (call);
|
||||
linphonec_set_caller(from);
|
||||
if ( auto_answer) {
|
||||
answer_call=TRUE;
|
||||
}
|
||||
linphonec_out("Receiving new incoming call from %s, assigned id %i\n", from,id);
|
||||
break;
|
||||
case LinphoneCallOutgoingInit:
|
||||
linphonec_call_identify(call);
|
||||
id=(long)linphone_call_get_user_pointer (call);
|
||||
from=linphone_call_get_remote_address_as_string(call);
|
||||
linphonec_out("Establishing call id to %s, assigned id %i\n", from,id);
|
||||
break;
|
||||
case LinphoneCallUpdatedByRemote:
|
||||
linphonec_call_updated(call);
|
||||
break;
|
||||
case LinphoneCallOutgoingProgress:
|
||||
linphonec_out("Call %i to %s in progress.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallOutgoingRinging:
|
||||
linphonec_out("Call %i to %s ringing.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallConnected:
|
||||
linphonec_out("Call %i with %s connected.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallOutgoingEarlyMedia:
|
||||
linphonec_out("Call %i with %s early media.\n", id, from);
|
||||
break;
|
||||
case LinphoneCallError:
|
||||
linphonec_out("Call %i with %s error.\n", id, from);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ms_free(from);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -350,71 +389,18 @@ linphonec_bye_received(LinphoneCore *lc, const char *from)
|
|||
*/
|
||||
static void
|
||||
linphonec_text_received(LinphoneCore *lc, LinphoneChatRoom *cr,
|
||||
const char *from, const char *msg)
|
||||
const LinphoneAddress *from, const char *msg)
|
||||
{
|
||||
printf("%s: %s\n", from, msg);
|
||||
printf("%s: %s\n", linphone_address_as_string(from), msg);
|
||||
// TODO: provide mechanism for answering.. ('say' command?)
|
||||
}
|
||||
|
||||
|
||||
static void linphonec_dtmf_received(LinphoneCore *lc, int dtmf){
|
||||
fprintf(stdout,"Receiving tone %c\n",dtmf);
|
||||
static void linphonec_dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf){
|
||||
char *from=linphone_call_get_remote_address_as_string(call);
|
||||
fprintf(stdout,"Receiving tone %c from %s\n",dtmf,from);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
linphonec_general_state (LinphoneCore * lc, LinphoneGeneralState *gstate)
|
||||
{
|
||||
if (show_general_state) {
|
||||
switch(gstate->new_state) {
|
||||
case GSTATE_POWER_OFF:
|
||||
printf("GSTATE_POWER_OFF");
|
||||
break;
|
||||
case GSTATE_POWER_STARTUP:
|
||||
printf("GSTATE_POWER_STARTUP");
|
||||
break;
|
||||
case GSTATE_POWER_ON:
|
||||
printf("GSTATE_POWER_ON");
|
||||
break;
|
||||
case GSTATE_POWER_SHUTDOWN:
|
||||
printf("GSTATE_POWER_SHUTDOWN");
|
||||
break;
|
||||
case GSTATE_REG_NONE:
|
||||
printf("GSTATE_REG_NONE");
|
||||
break;
|
||||
case GSTATE_REG_OK:
|
||||
printf("GSTATE_REG_OK");
|
||||
break;
|
||||
case GSTATE_REG_FAILED:
|
||||
printf("GSTATE_REG_FAILED");
|
||||
break;
|
||||
case GSTATE_CALL_IDLE:
|
||||
printf("GSTATE_CALL_IDLE");
|
||||
break;
|
||||
case GSTATE_CALL_OUT_INVITE:
|
||||
printf("GSTATE_CALL_OUT_INVITE");
|
||||
break;
|
||||
case GSTATE_CALL_OUT_CONNECTED:
|
||||
printf("GSTATE_CALL_OUT_CONNECTED");
|
||||
break;
|
||||
case GSTATE_CALL_IN_INVITE:
|
||||
printf("GSTATE_CALL_IN_INVITE");
|
||||
break;
|
||||
case GSTATE_CALL_IN_CONNECTED:
|
||||
printf("GSTATE_CALL_IN_CONNECTED");
|
||||
break;
|
||||
case GSTATE_CALL_END:
|
||||
printf("GSTATE_CALL_END");
|
||||
break;
|
||||
case GSTATE_CALL_ERROR:
|
||||
printf("GSTATE_CALL_ERROR");
|
||||
break;
|
||||
default:
|
||||
printf("GSTATE_UNKNOWN_%d",gstate->new_state);
|
||||
}
|
||||
if (gstate->message) printf(" %s", gstate->message);
|
||||
printf("\n");
|
||||
}
|
||||
ms_free(from);
|
||||
}
|
||||
|
||||
static char received_prompt[PROMPT_MAX_LEN];
|
||||
|
|
@ -596,6 +582,8 @@ bool_t linphonec_get_autoanswer(){
|
|||
return auto_answer;
|
||||
}
|
||||
|
||||
LinphoneCoreVTable linphonec_vtable={0};
|
||||
|
||||
/***************************************************************************/
|
||||
/*
|
||||
* Main
|
||||
|
|
@ -621,31 +609,24 @@ char **convert_args_to_ascii(int argc, _TCHAR **wargv){
|
|||
int _tmain(int argc, _TCHAR* wargv[]) {
|
||||
char **argv=convert_args_to_ascii(argc,wargv);
|
||||
trace_level=6;
|
||||
linphonec_vtable.show =(ShowInterfaceCb) stub;
|
||||
linphonec_vtable.inv_recv = linphonec_call_received;
|
||||
linphonec_vtable.bye_recv = linphonec_bye_received;
|
||||
linphonec_vtable.notify_presence_recv = linphonec_notify_received;
|
||||
linphonec_vtable.new_unknown_subscriber = linphonec_new_unknown_subscriber;
|
||||
linphonec_vtable.auth_info_requested = linphonec_prompt_for_auth;
|
||||
linphonec_vtable.display_status = linphonec_display_status;
|
||||
linphonec_vtable.display_message=linphonec_display_something;
|
||||
#ifdef VINCENT_MAURY_RSVP
|
||||
/* the yes/no dialog box */
|
||||
linphonec_vtable.display_yes_no= (DisplayMessageCb) stub;
|
||||
#endif
|
||||
linphonec_vtable.display_warning=linphonec_display_warning;
|
||||
linphonec_vtable.display_url=linphonec_display_url;
|
||||
linphonec_vtable.display_question=(DisplayQuestionCb)stub;
|
||||
linphonec_vtable.text_received=linphonec_text_received;
|
||||
linphonec_vtable.general_state=linphonec_general_state;
|
||||
linphonec_vtable.dtmf_received=linphonec_dtmf_received;
|
||||
|
||||
#else
|
||||
int
|
||||
main (int argc, char *argv[]) {
|
||||
#endif
|
||||
|
||||
|
||||
linphonec_vtable.call_state_changed=linphonec_call_state_changed;
|
||||
linphonec_vtable.notify_presence_recv = linphonec_notify_presence_received;
|
||||
linphonec_vtable.new_subscription_request = linphonec_new_unknown_subscriber;
|
||||
linphonec_vtable.auth_info_requested = linphonec_prompt_for_auth;
|
||||
linphonec_vtable.display_status = linphonec_display_status;
|
||||
linphonec_vtable.display_message=linphonec_display_something;
|
||||
linphonec_vtable.display_warning=linphonec_display_warning;
|
||||
linphonec_vtable.display_url=linphonec_display_url;
|
||||
linphonec_vtable.text_received=linphonec_text_received;
|
||||
linphonec_vtable.dtmf_received=linphonec_dtmf_received;
|
||||
linphonec_vtable.refer_received=linphonec_display_refer;
|
||||
linphonec_vtable.notify_recv=linphonec_notify_received;
|
||||
|
||||
if (! linphonec_init(argc, argv) ) exit(EXIT_FAILURE);
|
||||
|
||||
linphonec_main_loop (linphonec, sipAddr);
|
||||
|
|
@ -733,8 +714,7 @@ linphonec_init(int argc, char **argv)
|
|||
/*
|
||||
* Initialize linphone core
|
||||
*/
|
||||
linphonec=linphone_core_new (&linphonec_vtable, configfile_name, NULL,
|
||||
NULL);
|
||||
linphonec=linphone_core_new (&linphonec_vtable, configfile_name, factory_configfile_name, NULL);
|
||||
linphone_core_enable_video(linphonec,vcap_enabled,display_enabled);
|
||||
linphone_core_enable_video_preview(linphonec,preview_enabled);
|
||||
if (!(vcap_enabled || display_enabled)) printf("Warning: video is disabled in linphonec, use -V or -C or -D to enable.\n");
|
||||
|
|
@ -766,11 +746,14 @@ void linphonec_main_loop_exit(void){
|
|||
void
|
||||
linphonec_finish(int exit_status)
|
||||
{
|
||||
printf("Terminating...\n");
|
||||
// Do not allow concurrent destroying to prevent glibc errors
|
||||
static bool_t terminating=FALSE;
|
||||
if (terminating) return;
|
||||
terminating=TRUE;
|
||||
linphonec_out("Terminating...\n");
|
||||
|
||||
/* Terminate any pending call */
|
||||
linphonec_parse_command_line(linphonec, "terminate");
|
||||
linphonec_command_finished();
|
||||
linphone_core_terminate_all_calls(linphonec);
|
||||
#ifdef HAVE_READLINE
|
||||
linphonec_finish_readline();
|
||||
#endif
|
||||
|
|
@ -785,7 +768,7 @@ linphonec_finish(int exit_status)
|
|||
{
|
||||
fclose (mylogfile);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
exit(exit_status);
|
||||
|
||||
}
|
||||
|
|
@ -885,6 +868,7 @@ print_usage (int exit_status)
|
|||
usage: linphonec [-c file] [-s sipaddr] [-a] [-V] [-d level ] [-l logfile]\n\
|
||||
linphonec -v\n\
|
||||
\n\
|
||||
-b file specify path of readonly factory configuration file.\n\
|
||||
-c file specify path of configuration file.\n\
|
||||
-d level be verbose. 0 is no output. 6 is all output\n\
|
||||
-l logfile specify the log file for your SIP phone\n\
|
||||
|
|
@ -899,6 +883,75 @@ usage: linphonec [-c file] [-s sipaddr] [-a] [-V] [-d level ] [-l logfile]\n\
|
|||
exit(exit_status);
|
||||
}
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
|
||||
#ifdef HAVE_X11_XLIB_H
|
||||
static void x11_apply_video_params(VideoParams *params, Window window){
|
||||
XWindowChanges wc;
|
||||
unsigned int flags=0;
|
||||
static Display *display = NULL;
|
||||
const char *dname=getenv("DISPLAY");
|
||||
|
||||
if (display==NULL && dname!=NULL){
|
||||
display=XOpenDisplay(dname);
|
||||
}
|
||||
|
||||
if (display==NULL){
|
||||
ms_error("Could not open display %s",dname);
|
||||
return;
|
||||
}
|
||||
memset(&wc,0,sizeof(wc));
|
||||
wc.x=params->x;
|
||||
wc.y=params->y;
|
||||
wc.width=params->w;
|
||||
wc.height=params->h;
|
||||
if (params->x!=-1 ){
|
||||
flags|=CWX|CWY;
|
||||
}
|
||||
if (params->w!=-1){
|
||||
flags|=CWWidth|CWHeight;
|
||||
}
|
||||
/*printf("XConfigureWindow x=%i,y=%i,w=%i,h=%i\n",
|
||||
wc.x, wc.y ,wc.width, wc.height);*/
|
||||
XConfigureWindow(display,window,flags,&wc);
|
||||
if (params->show)
|
||||
XMapWindow(display,window);
|
||||
else
|
||||
XUnmapWindow(display,window);
|
||||
XSync(display,FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void lpc_apply_video_params(){
|
||||
static unsigned long old_wid=0,old_pwid=0;
|
||||
unsigned long wid=linphone_core_get_native_video_window_id (linphonec);
|
||||
unsigned long pwid=linphone_core_get_native_preview_window_id (linphonec);
|
||||
|
||||
if (wid!=0 && (lpc_video_params.refresh || old_wid!=wid)){
|
||||
lpc_video_params.refresh=FALSE;
|
||||
#ifdef HAVE_X11_XLIB_H
|
||||
if (lpc_video_params.wid==0){ // do not manage window if embedded
|
||||
x11_apply_video_params(&lpc_video_params,wid);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
old_wid=wid;
|
||||
if (pwid!=0 && (lpc_preview_params.refresh || old_pwid!=pwid)){
|
||||
lpc_preview_params.refresh=FALSE;
|
||||
#ifdef HAVE_X11_XLIB_H
|
||||
/*printf("wid=%lu pwid=%lu\n",wid,pwid);*/
|
||||
if (lpc_preview_params.wid==0){ // do not manage window if embedded
|
||||
printf("Refreshing\n");
|
||||
x11_apply_video_params(&lpc_preview_params,pwid);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
old_pwid=pwid;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
|
|
@ -940,6 +993,10 @@ linphonec_idle_call ()
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
lpc_apply_video_params();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1112,6 +1169,20 @@ linphonec_parse_cmdline(int argc, char **argv)
|
|||
#endif /*_WIN32_WCE*/
|
||||
snprintf(configfile_name, PATH_MAX, "%s", argv[arg_num]);
|
||||
}
|
||||
else if (strncmp ("-b", argv[arg_num], 2) == 0)
|
||||
{
|
||||
if ( ++arg_num >= argc ) print_usage(EXIT_FAILURE);
|
||||
#if !defined(_WIN32_WCE)
|
||||
if (access(argv[arg_num],F_OK)!=0 )
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Cannot open config file %s.\n",
|
||||
argv[arg_num]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif /*_WIN32_WCE*/
|
||||
factory_configfile_name = argv[arg_num];
|
||||
}
|
||||
else if (strncmp ("-s", argv[arg_num], 2) == 0)
|
||||
{
|
||||
arg_num++;
|
||||
|
|
|
|||
|
|
@ -97,6 +97,17 @@ typedef struct {
|
|||
char *doc; /* Long description. */
|
||||
} LPC_COMMAND;
|
||||
|
||||
typedef struct {
|
||||
int x,y,w,h;
|
||||
unsigned long wid;
|
||||
bool_t show;
|
||||
bool_t refresh;
|
||||
} VideoParams;
|
||||
|
||||
|
||||
extern VideoParams lpc_video_params;
|
||||
extern VideoParams lpc_preview_params;
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Forward declarations
|
||||
|
|
@ -112,6 +123,10 @@ void linphonec_set_autoanswer(bool_t enabled);
|
|||
bool_t linphonec_get_autoanswer();
|
||||
void linphonec_command_finished(void);
|
||||
void linphonec_set_caller(const char *caller);
|
||||
LinphoneCall *linphonec_get_call(long id);
|
||||
void linphonec_call_identify(LinphoneCall* call);
|
||||
|
||||
extern bool_t linphonec_camera_enabled;
|
||||
|
||||
#endif /* def LINPHONEC_H */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
|
||||
SUBDIRS=help
|
||||
SUBDIRS=. help
|
||||
|
||||
EXTRA_DIST=linphonecore_jni.cc
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
linphone_includedir=$(includedir)/linphone
|
||||
|
||||
linphone_include_HEADERS=linphonecore.h ../config.h lpconfig.h sipsetup.h
|
||||
linphone_include_HEADERS=linphonecore.h linphonefriend.h linphonecore_utils.h ../config.h lpconfig.h sipsetup.h
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)\
|
||||
-I$(top_srcdir)/mediastreamer2/include
|
||||
$(MEDIASTREAMER_CFLAGS)
|
||||
|
||||
|
||||
lib_LTLIBRARIES=liblinphone.la
|
||||
|
|
@ -32,26 +32,35 @@ liblinphone_la_SOURCES=\
|
|||
authentication.c \
|
||||
lpconfig.c lpconfig.h \
|
||||
chat.c \
|
||||
general_state.c \
|
||||
linphonecall.c \
|
||||
sipsetup.c sipsetup.h \
|
||||
siplogin.c
|
||||
siplogin.c \
|
||||
lsd.c linphonecore_utils.h
|
||||
|
||||
|
||||
liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined
|
||||
|
||||
liblinphone_la_LIBADD= \
|
||||
$(EXOSIP_LIBS) \
|
||||
$(top_builddir)/mediastreamer2/src/libmediastreamer.la \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS)
|
||||
|
||||
if BUILD_WIN32
|
||||
liblinphone_la_LIBADD+=$(top_builddir)/oRTP/src/libortp.la
|
||||
endif
|
||||
|
||||
noinst_PROGRAMS=test_lsd
|
||||
|
||||
test_lsd_SOURCES=test_lsd.c
|
||||
|
||||
test_lsd_LDADD=liblinphone.la \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS)
|
||||
|
||||
AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE \
|
||||
$(ORTP_CFLAGS) \
|
||||
$(OSIP_CFLAGS) \
|
||||
$(MEDIASTREAMER_CFLAGS) \
|
||||
$(EXOSIP_CFLAGS) \
|
||||
-DENABLE_TRACE \
|
||||
-DLOG_DOMAIN=\"LinphoneCore\" \
|
||||
|
|
|
|||
|
|
@ -129,6 +129,29 @@ char *linphone_address_as_string_uri_only(const LinphoneAddress *u){
|
|||
return sal_address_as_string_uri_only(u);
|
||||
}
|
||||
|
||||
static bool_t strings_equals(const char *s1, const char *s2){
|
||||
if (s1==NULL && s2==NULL) return TRUE;
|
||||
if (s1!=NULL && s2!=NULL && strcmp(s1,s2)==0) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two LinphoneAddress ignoring tags and headers, basically just domain, username, and port.
|
||||
* Returns TRUE if they are equal.
|
||||
**/
|
||||
bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddress *a2){
|
||||
const char *u1,*u2;
|
||||
const char *h1,*h2;
|
||||
int p1,p2;
|
||||
u1=linphone_address_get_username(a1);
|
||||
u2=linphone_address_get_username(a2);
|
||||
p1=linphone_address_get_port_int(a1);
|
||||
p2=linphone_address_get_port_int(a2);
|
||||
h1=linphone_address_get_domain(a1);
|
||||
h2=linphone_address_get_domain(a2);
|
||||
return strings_equals(u1,u2) && strings_equals(h1,h2) && p1==p2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a LinphoneAddress object.
|
||||
**/
|
||||
|
|
@ -139,6 +162,7 @@ void linphone_address_destroy(LinphoneAddress *u){
|
|||
int linphone_address_get_port_int(const LinphoneAddress *u) {
|
||||
return sal_address_get_port_int(u);
|
||||
}
|
||||
|
||||
const char* linphone_address_get_port(const LinphoneAddress *u) {
|
||||
return sal_address_get_port(u);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,19 +23,85 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "linphonecore.h"
|
||||
#include "private.h"
|
||||
#include "mediastreamer2/mediastream.h"
|
||||
#include "lpconfig.h"
|
||||
|
||||
static void register_failure(SalOp *op, SalError error, SalReason reason, const char *details);
|
||||
|
||||
static void linphone_connect_incoming(LinphoneCore *lc, LinphoneCall *call){
|
||||
if (lc->vtable.show)
|
||||
lc->vtable.show(lc);
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Connected."));
|
||||
call->state=LCStateAVRunning;
|
||||
static bool_t media_parameters_changed(LinphoneCall *call, SalMediaDescription *oldmd, SalMediaDescription *newmd){
|
||||
return !sal_media_description_equals(oldmd,newmd) || call->up_bw!=linphone_core_get_upload_bandwidth(call->core);
|
||||
}
|
||||
|
||||
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){
|
||||
SalMediaDescription *oldmd=call->resultdesc;
|
||||
|
||||
if (lc->ringstream!=NULL){
|
||||
ring_stop(lc->ringstream);
|
||||
lc->ringstream=NULL;
|
||||
}
|
||||
linphone_core_start_media_streams(lc,call);
|
||||
if (new_md!=NULL){
|
||||
sal_media_description_ref(new_md);
|
||||
call->media_pending=FALSE;
|
||||
}else{
|
||||
call->media_pending=TRUE;
|
||||
}
|
||||
call->resultdesc=new_md;
|
||||
if (call->audiostream && call->audiostream->ticker){
|
||||
/* we already started media: check if we really need to restart it*/
|
||||
if (oldmd){
|
||||
if (!media_parameters_changed(call,oldmd,new_md) && !call->playing_ringbacktone){
|
||||
sal_media_description_unref(oldmd);
|
||||
if (call->all_muted){
|
||||
ms_message("Early media finished, unmuting inputs...");
|
||||
/*we were in early media, now we want to enable real media */
|
||||
linphone_call_enable_camera (call,linphone_call_camera_enabled (call));
|
||||
if (call->audiostream)
|
||||
linphone_core_mute_mic (lc, linphone_core_is_mic_muted(lc));
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->videostream && call->camera_active)
|
||||
video_stream_change_camera(call->videostream,lc->video_conf.device );
|
||||
#endif
|
||||
}
|
||||
ms_message("No need to restart streams, SDP is unchanged.");
|
||||
return;
|
||||
}else{
|
||||
ms_message("Media descriptions are different, need to restart the streams.");
|
||||
}
|
||||
}
|
||||
linphone_call_stop_media_streams (call);
|
||||
linphone_call_init_media_streams (call);
|
||||
}
|
||||
if (oldmd)
|
||||
sal_media_description_unref(oldmd);
|
||||
|
||||
if (new_md) {
|
||||
bool_t all_muted=FALSE;
|
||||
bool_t send_ringbacktone=FALSE;
|
||||
|
||||
if (call->audiostream==NULL){
|
||||
/*this happens after pausing the call locally. The streams is destroyed and then we wait the 200Ok to recreate it*/
|
||||
linphone_call_init_media_streams (call);
|
||||
}
|
||||
if (call->state==LinphoneCallIncomingEarlyMedia && linphone_core_get_remote_ringback_tone (lc)!=NULL){
|
||||
send_ringbacktone=TRUE;
|
||||
}
|
||||
if (call->state==LinphoneCallIncomingEarlyMedia ||
|
||||
(call->state==LinphoneCallOutgoingEarlyMedia && !call->params.real_early_media)){
|
||||
all_muted=TRUE;
|
||||
}
|
||||
linphone_call_start_media_streams(call,all_muted,send_ringbacktone);
|
||||
}
|
||||
}
|
||||
|
||||
static bool_t is_duplicate_call(LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to){
|
||||
MSList *elem;
|
||||
for(elem=lc->calls;elem!=NULL;elem=elem->next){
|
||||
LinphoneCall *call=(LinphoneCall*)elem->data;
|
||||
if (linphone_address_weak_equal(call->log->from,from) &&
|
||||
linphone_address_weak_equal(call->log->to, to)){
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void call_received(SalOp *h){
|
||||
|
|
@ -45,228 +111,310 @@ static void call_received(SalOp *h){
|
|||
const char *from,*to;
|
||||
char *tmp;
|
||||
LinphoneAddress *from_parsed;
|
||||
|
||||
LinphoneAddress *from_addr, *to_addr;
|
||||
SalMediaDescription *md;
|
||||
bool_t propose_early_media=lp_config_get_int(lc->config,"sip","incoming_calls_early_media",FALSE);
|
||||
const char *ringback_tone=linphone_core_get_remote_ringback_tone (lc);
|
||||
|
||||
/* first check if we can answer successfully to this invite */
|
||||
if (lc->presence_mode!=LINPHONE_STATUS_ONLINE){
|
||||
ms_message("Not present !! presence mode : %d\n",lc->presence_mode);
|
||||
if (lc->presence_mode==LINPHONE_STATUS_BUSY)
|
||||
if (lc->presence_mode==LinphoneStatusBusy ||
|
||||
lc->presence_mode==LinphoneStatusOffline ||
|
||||
lc->presence_mode==LinphoneStatusDoNotDisturb ||
|
||||
lc->presence_mode==LinphoneStatusMoved){
|
||||
if (lc->presence_mode==LinphoneStatusBusy )
|
||||
sal_call_decline(h,SalReasonBusy,NULL);
|
||||
else if (lc->presence_mode==LINPHONE_STATUS_AWAY
|
||||
||lc->presence_mode==LINPHONE_STATUS_BERIGHTBACK
|
||||
||lc->presence_mode==LINPHONE_STATUS_ONTHEPHONE
|
||||
||lc->presence_mode==LINPHONE_STATUS_OUTTOLUNCH
|
||||
||lc->presence_mode==LINPHONE_STATUS_OFFLINE)
|
||||
else if (lc->presence_mode==LinphoneStatusOffline)
|
||||
sal_call_decline(h,SalReasonTemporarilyUnavailable,NULL);
|
||||
else if (lc->presence_mode==LINPHONE_STATUS_NOT_DISTURB)
|
||||
else if (lc->presence_mode==LinphoneStatusDoNotDisturb)
|
||||
sal_call_decline(h,SalReasonTemporarilyUnavailable,NULL);
|
||||
else if (lc->alt_contact!=NULL && lc->presence_mode==LINPHONE_STATUS_MOVED)
|
||||
else if (lc->alt_contact!=NULL && lc->presence_mode==LinphoneStatusMoved)
|
||||
sal_call_decline(h,SalReasonRedirect,lc->alt_contact);
|
||||
else
|
||||
sal_call_decline(h,SalReasonBusy,NULL);
|
||||
sal_op_release(h);
|
||||
return;
|
||||
}
|
||||
if (lc->call!=NULL){/*busy*/
|
||||
if (!linphone_core_can_we_add_call(lc)){/*busy*/
|
||||
sal_call_decline(h,SalReasonBusy,NULL);
|
||||
sal_op_release(h);
|
||||
return;
|
||||
}
|
||||
from=sal_op_get_from(h);
|
||||
to=sal_op_get_to(h);
|
||||
|
||||
call=linphone_call_new_incoming(lc,linphone_address_new(from),linphone_address_new(to),h);
|
||||
lc->call=call;
|
||||
sal_call_set_local_media_description(h,call->localdesc);
|
||||
call->resultdesc=sal_call_get_final_media_description(h);
|
||||
if (call->resultdesc)
|
||||
sal_media_description_ref(call->resultdesc);
|
||||
if (call->resultdesc && sal_media_description_empty(call->resultdesc)){
|
||||
sal_call_decline(h,SalReasonMedia,NULL);
|
||||
linphone_call_destroy(call);
|
||||
lc->call=NULL;
|
||||
from_addr=linphone_address_new(from);
|
||||
to_addr=linphone_address_new(to);
|
||||
|
||||
if (is_duplicate_call(lc,from_addr,to_addr)){
|
||||
ms_warning("Receiving duplicated call, refusing this one.");
|
||||
sal_call_decline(h,SalReasonBusy,NULL);
|
||||
linphone_address_destroy(from_addr);
|
||||
linphone_address_destroy(to_addr);
|
||||
return;
|
||||
}
|
||||
|
||||
call=linphone_call_new_incoming(lc,from_addr,to_addr,h);
|
||||
sal_call_set_local_media_description(h,call->localdesc);
|
||||
md=sal_call_get_final_media_description(h);
|
||||
|
||||
if (md && sal_media_description_empty(md)){
|
||||
sal_call_decline(h,SalReasonMedia,NULL);
|
||||
linphone_call_unref(call);
|
||||
return;
|
||||
}
|
||||
|
||||
/* the call is acceptable so we can now add it to our list */
|
||||
linphone_core_add_call(lc,call);
|
||||
|
||||
from_parsed=linphone_address_new(sal_op_get_from(h));
|
||||
linphone_address_clean(from_parsed);
|
||||
tmp=linphone_address_as_string(from_parsed);
|
||||
linphone_address_destroy(from_parsed);
|
||||
gstate_new_state(lc, GSTATE_CALL_IN_INVITE, tmp);
|
||||
barmesg=ortp_strdup_printf("%s %s%s",tmp,_("is contacting you"),
|
||||
(sal_call_autoanswer_asked(h)) ?_(" and asked autoanswer."):_("."));
|
||||
if (lc->vtable.show) lc->vtable.show(lc);
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,barmesg);
|
||||
|
||||
/* play the ring */
|
||||
if (lc->sound_conf.ring_sndcard!=NULL){
|
||||
ms_message("Starting local ring...");
|
||||
lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,lc->sound_conf.ring_sndcard);
|
||||
/* play the ring if this is the only call*/
|
||||
if (lc->sound_conf.ring_sndcard!=NULL && ms_list_size(lc->calls)==1){
|
||||
lc->current_call=call;
|
||||
if (lc->ringstream && lc->dmfs_playing_start_time!=0){
|
||||
ring_stop(lc->ringstream);
|
||||
lc->ringstream=NULL;
|
||||
lc->dmfs_playing_start_time=0;
|
||||
}
|
||||
if(lc->ringstream==NULL && lc->sound_conf.local_ring){
|
||||
MSSndCard *ringcard=lc->sound_conf.lsd_card ?lc->sound_conf.lsd_card : lc->sound_conf.ring_sndcard;
|
||||
ms_message("Starting local ring...");
|
||||
lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,ringcard);
|
||||
}
|
||||
else
|
||||
{
|
||||
ms_message("the local ring is already started");
|
||||
}
|
||||
}else{
|
||||
/*TODO : play a tone within the context of the current call */
|
||||
}
|
||||
linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call");
|
||||
|
||||
sal_call_notify_ringing(h,propose_early_media || ringback_tone!=NULL);
|
||||
|
||||
if (propose_early_media || ringback_tone!=NULL){
|
||||
linphone_call_set_state(call,LinphoneCallIncomingEarlyMedia,"Incoming call early media");
|
||||
linphone_core_update_streams(lc,call,md);
|
||||
}
|
||||
linphone_call_set_state(call,LCStateRinging);
|
||||
sal_call_notify_ringing(h);
|
||||
#if !(__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000)
|
||||
linphone_core_init_media_streams(lc,lc->call);
|
||||
#endif
|
||||
if (lc->vtable.inv_recv) lc->vtable.inv_recv(lc,tmp);
|
||||
ms_free(barmesg);
|
||||
ms_free(tmp);
|
||||
|
||||
|
||||
if (sal_call_get_replaces(call->op)!=NULL && lp_config_get_int(lc->config,"sip","auto_answer_replacing_calls",1)){
|
||||
linphone_core_accept_call(lc,call);
|
||||
}
|
||||
}
|
||||
|
||||
static void call_ringing(SalOp *h){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h));
|
||||
LinphoneCall *call=lc->call;
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(h);
|
||||
SalMediaDescription *md;
|
||||
|
||||
if (call==NULL) return;
|
||||
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Remote ringing."));
|
||||
|
||||
md=sal_call_get_final_media_description(h);
|
||||
if (md==NULL){
|
||||
if (lc->ringstream && lc->dmfs_playing_start_time!=0){
|
||||
ring_stop(lc->ringstream);
|
||||
lc->ringstream=NULL;
|
||||
lc->dmfs_playing_start_time=0;
|
||||
}
|
||||
if (lc->ringstream!=NULL) return; /*already ringing !*/
|
||||
if (lc->sound_conf.play_sndcard!=NULL){
|
||||
MSSndCard *ringcard=lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
|
||||
ms_message("Remote ringing...");
|
||||
lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,lc->sound_conf.play_sndcard);
|
||||
gstate_new_state(lc, GSTATE_CALL_OUT_RINGING, NULL);
|
||||
lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,ringcard);
|
||||
linphone_call_set_state(call,LinphoneCallOutgoingRinging,"Remote ringing");
|
||||
}
|
||||
}else{
|
||||
/*accept early media */
|
||||
if (lc->audiostream && lc->audiostream->ticker!=NULL){
|
||||
if (call->audiostream && call->audiostream->ticker!=NULL){
|
||||
/*streams already started */
|
||||
ms_message("Early media already started.");
|
||||
return;
|
||||
}
|
||||
sal_media_description_ref(md);
|
||||
call->resultdesc=md;
|
||||
if (lc->vtable.show) lc->vtable.show(lc);
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Early media."));
|
||||
gstate_new_state(lc, GSTATE_CALL_OUT_RINGING, NULL);
|
||||
linphone_call_set_state(call,LinphoneCallOutgoingEarlyMedia,"Early media");
|
||||
if (lc->ringstream!=NULL){
|
||||
ring_stop(lc->ringstream);
|
||||
lc->ringstream=NULL;
|
||||
}
|
||||
ms_message("Doing early media...");
|
||||
linphone_core_start_media_streams(lc,call);
|
||||
call->media_pending=TRUE;
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
}
|
||||
call->state=LCStateRinging;
|
||||
}
|
||||
|
||||
/*
|
||||
* could be reach :
|
||||
* - when the call is accepted
|
||||
* - when a request is accepted (pause, resume)
|
||||
*/
|
||||
static void call_accepted(SalOp *op){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
LinphoneCall *call=lc->call;
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
SalMediaDescription *md;
|
||||
|
||||
if (call==NULL){
|
||||
ms_warning("No call to accept.");
|
||||
return ;
|
||||
}
|
||||
if (sal_op_get_user_pointer(op)!=lc->call){
|
||||
ms_warning("call_accepted: ignoring.");
|
||||
return;
|
||||
|
||||
md=sal_call_get_final_media_description(op);
|
||||
|
||||
if (call->state==LinphoneCallOutgoingProgress ||
|
||||
call->state==LinphoneCallOutgoingRinging ||
|
||||
call->state==LinphoneCallOutgoingEarlyMedia){
|
||||
linphone_call_set_state(call,LinphoneCallConnected,"Connected");
|
||||
}
|
||||
if (call->state==LCStateAVRunning){
|
||||
return ; /*already accepted*/
|
||||
}
|
||||
if (lc->audiostream->ticker!=NULL){
|
||||
/*case where we accepted early media */
|
||||
linphone_core_stop_media_streams(lc,call);
|
||||
linphone_core_init_media_streams(lc,call);
|
||||
}
|
||||
if (call->resultdesc)
|
||||
sal_media_description_unref(call->resultdesc);
|
||||
call->resultdesc=sal_call_get_final_media_description(op);
|
||||
if (call->resultdesc){
|
||||
sal_media_description_ref(call->resultdesc);
|
||||
call->media_pending=FALSE;
|
||||
}
|
||||
if (call->resultdesc && !sal_media_description_empty(call->resultdesc)){
|
||||
gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, NULL);
|
||||
linphone_connect_incoming(lc,call);
|
||||
if (md && !sal_media_description_empty(md)){
|
||||
if (sal_media_description_has_dir(md,SalStreamSendOnly) ||
|
||||
sal_media_description_has_dir(md,SalStreamInactive)){
|
||||
if (lc->vtable.display_status){
|
||||
char *tmp=linphone_call_get_remote_address_as_string (call);
|
||||
char *msg=ms_strdup_printf(_("Call with %s is paused."),tmp);
|
||||
lc->vtable.display_status(lc,msg);
|
||||
ms_free(tmp);
|
||||
ms_free(msg);
|
||||
}
|
||||
linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
|
||||
}else if (sal_media_description_has_dir(md,SalStreamRecvOnly)){
|
||||
/*we are put on hold when the call is initially accepted */
|
||||
if (lc->vtable.display_status){
|
||||
char *tmp=linphone_call_get_remote_address_as_string (call);
|
||||
char *msg=ms_strdup_printf(_("Call answered by %s - on hold."),tmp);
|
||||
lc->vtable.display_status(lc,msg);
|
||||
ms_free(tmp);
|
||||
ms_free(msg);
|
||||
}
|
||||
linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
|
||||
}else{
|
||||
if (lc->vtable.display_status){
|
||||
lc->vtable.display_status(lc,_("Call answered - connected."));
|
||||
}
|
||||
if (call->state==LinphoneCallStreamsRunning){
|
||||
/*media was running before, the remote as acceted a call modification (that is
|
||||
a reinvite made by us. We must notify the application this reinvite was accepted*/
|
||||
linphone_call_set_state(call, LinphoneCallUpdated, "Call updated");
|
||||
}
|
||||
linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
}
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
}else{
|
||||
/*send a bye*/
|
||||
ms_error("Incompatible SDP offer received in 200Ok, need to abort the call");
|
||||
linphone_core_terminate_call(lc,NULL);
|
||||
linphone_core_abort_call(lc,call,"No codec intersection");
|
||||
}
|
||||
}
|
||||
|
||||
static void call_ack(SalOp *op){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
LinphoneCall *call=lc->call;
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
if (call==NULL){
|
||||
ms_warning("No call to be ACK'd");
|
||||
return ;
|
||||
}
|
||||
if (sal_op_get_user_pointer(op)!=lc->call){
|
||||
ms_warning("call_ack: ignoring.");
|
||||
return;
|
||||
}
|
||||
if (call->media_pending){
|
||||
if (lc->audiostream->ticker!=NULL){
|
||||
/*case where we accepted early media */
|
||||
linphone_core_stop_media_streams(lc,call);
|
||||
linphone_core_init_media_streams(lc,call);
|
||||
}
|
||||
if (call->resultdesc)
|
||||
sal_media_description_unref(call->resultdesc);
|
||||
call->resultdesc=sal_call_get_final_media_description(op);
|
||||
if (call->resultdesc)
|
||||
sal_media_description_ref(call->resultdesc);
|
||||
if (call->resultdesc && !sal_media_description_empty(call->resultdesc)){
|
||||
gstate_new_state(lc, GSTATE_CALL_IN_CONNECTED, NULL);
|
||||
linphone_connect_incoming(lc,call);
|
||||
SalMediaDescription *md=sal_call_get_final_media_description(op);
|
||||
if (md && !sal_media_description_empty(md)){
|
||||
if (call->state==LinphoneCallStreamsRunning){
|
||||
/*media was running before, the remote as acceted a call modification (that is
|
||||
a reinvite made by us. We must notify the application this reinvite was accepted*/
|
||||
linphone_call_set_state(call, LinphoneCallUpdated, "Call updated");
|
||||
}
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
}else{
|
||||
/*send a bye*/
|
||||
ms_error("Incompatible SDP response received in ACK, need to abort the call");
|
||||
linphone_core_terminate_call(lc,NULL);
|
||||
linphone_core_abort_call(lc,call,"No codec intersection");
|
||||
return;
|
||||
}
|
||||
call->media_pending=FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void call_updated(SalOp *op){
|
||||
/* this callback is called when an incoming re-INVITE modifies the session*/
|
||||
static void call_updating(SalOp *op){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
linphone_core_stop_media_streams(lc,call);
|
||||
linphone_core_init_media_streams(lc,call);
|
||||
if (call->resultdesc)
|
||||
sal_media_description_unref(call->resultdesc);
|
||||
call->resultdesc=sal_call_get_final_media_description(op);
|
||||
if (call->resultdesc){
|
||||
sal_media_description_ref(call->resultdesc);
|
||||
if (!sal_media_description_empty(call->resultdesc)){
|
||||
linphone_connect_incoming(lc,call);
|
||||
LinphoneCallState prevstate=LinphoneCallIdle;
|
||||
SalMediaDescription *md;
|
||||
|
||||
md=sal_call_get_final_media_description(op);
|
||||
|
||||
if (md && !sal_media_description_empty(md))
|
||||
{
|
||||
if ((call->state==LinphoneCallPausedByRemote || call->state==LinphoneCallPaused) &&
|
||||
sal_media_description_has_dir(md,SalStreamSendRecv) && strcmp(md->addr,"0.0.0.0")!=0){
|
||||
/*make sure we can be resumed */
|
||||
if (lc->current_call!=NULL && lc->current_call!=call){
|
||||
ms_warning("Attempt to be resumed but already in call with somebody else!");
|
||||
/*we are actively running another call, reject with a busy*/
|
||||
sal_call_decline (op,SalReasonBusy,NULL);
|
||||
return;
|
||||
}
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We have been resumed..."));
|
||||
linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
}
|
||||
else if(call->state==LinphoneCallStreamsRunning &&
|
||||
( sal_media_description_has_dir(md,SalStreamRecvOnly)
|
||||
|| sal_media_description_has_dir(md,SalStreamInactive)
|
||||
|| strcmp(md->addr,"0.0.0.0")==0)){
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We are being paused..."));
|
||||
linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
if (lc->current_call!=call){
|
||||
ms_error("Inconsitency detected: current call is %p but call %p is being paused !",lc->current_call,call);
|
||||
}
|
||||
}else{
|
||||
prevstate=call->state;
|
||||
linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote");
|
||||
}
|
||||
/*accept the modification (sends a 200Ok)*/
|
||||
sal_call_accept(op);
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
if (prevstate!=LinphoneCallIdle){
|
||||
linphone_call_set_state (call,prevstate,"Connected (streams running)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void call_terminated(SalOp *op, const char *from){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
if (sal_op_get_user_pointer(op)!=lc->call){
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
|
||||
if (call==NULL) return;
|
||||
|
||||
if (linphone_call_get_state(call)==LinphoneCallEnd || linphone_call_get_state(call)==LinphoneCallError){
|
||||
ms_warning("call_terminated: ignoring.");
|
||||
return;
|
||||
}
|
||||
ms_message("Current call terminated...");
|
||||
if (lc->ringstream!=NULL) {
|
||||
//we stop the call only if we have this current call or if we are in call
|
||||
if (lc->ringstream!=NULL && ( (ms_list_size(lc->calls) == 1) || linphone_core_in_call(lc) )) {
|
||||
ring_stop(lc->ringstream);
|
||||
lc->ringstream=NULL;
|
||||
}
|
||||
linphone_core_stop_media_streams(lc,lc->call);
|
||||
lc->vtable.show(lc);
|
||||
lc->vtable.display_status(lc,_("Call terminated."));
|
||||
gstate_new_state(lc, GSTATE_CALL_END, NULL);
|
||||
if (lc->vtable.bye_recv!=NULL){
|
||||
LinphoneAddress *addr=linphone_address_new(from);
|
||||
char *tmp;
|
||||
linphone_address_clean(addr);
|
||||
tmp=linphone_address_as_string(addr);
|
||||
lc->vtable.bye_recv(lc,tmp);
|
||||
ms_free(tmp);
|
||||
linphone_address_destroy(addr);
|
||||
}
|
||||
linphone_call_destroy(lc->call);
|
||||
lc->call=NULL;
|
||||
linphone_call_stop_media_streams(call);
|
||||
if (lc->vtable.show!=NULL)
|
||||
lc->vtable.show(lc);
|
||||
if (lc->vtable.display_status!=NULL)
|
||||
lc->vtable.display_status(lc,_("Call terminated."));
|
||||
|
||||
linphone_call_set_state(call, LinphoneCallEnd,"Call ended");
|
||||
}
|
||||
|
||||
static void call_failure(SalOp *op, SalError error, SalReason sr, const char *details){
|
||||
static void call_failure(SalOp *op, SalError error, SalReason sr, const char *details, int code){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
char *msg486=_("User is busy.");
|
||||
char *msg480=_("User is temporarily unavailable.");
|
||||
|
|
@ -274,12 +422,13 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
|
|||
char *msg600=_("User does not want to be disturbed.");
|
||||
char *msg603=_("Call declined.");
|
||||
const char *msg=details;
|
||||
LinphoneCall *call=lc->call;
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
|
||||
if (sal_op_get_user_pointer(op)!=lc->call){
|
||||
ms_warning("call_failure: ignoring.");
|
||||
return;
|
||||
if (call==NULL){
|
||||
ms_warning("Call faillure reported on already cleaned call ?");
|
||||
return ;
|
||||
}
|
||||
|
||||
if (lc->vtable.show) lc->vtable.show(lc);
|
||||
|
||||
if (error==SalErrorNoResponse){
|
||||
|
|
@ -332,16 +481,16 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
|
|||
lc->vtable.display_status(lc,_("Call failed."));
|
||||
}
|
||||
}
|
||||
|
||||
if (lc->ringstream!=NULL) {
|
||||
ring_stop(lc->ringstream);
|
||||
lc->ringstream=NULL;
|
||||
}
|
||||
linphone_core_stop_media_streams(lc,call);
|
||||
if (call!=NULL) {
|
||||
linphone_call_destroy(call);
|
||||
if (sr!=SalReasonDeclined) gstate_new_state(lc, GSTATE_CALL_ERROR, msg);
|
||||
else gstate_new_state(lc, GSTATE_CALL_END, msg);
|
||||
lc->call=NULL;
|
||||
linphone_call_stop_media_streams (call);
|
||||
if (sr!=SalReasonDeclined) linphone_call_set_state(call,LinphoneCallError,msg);
|
||||
else{
|
||||
call->reason=LinphoneReasonDeclined;
|
||||
linphone_call_set_state(call,LinphoneCallEnd,"Call declined.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -359,6 +508,9 @@ static void auth_requested(SalOp *h, const char *realm, const char *username){
|
|||
sal_op_authenticate(h,&sai);
|
||||
ai->usecount++;
|
||||
}else{
|
||||
if (ai && ai->works==FALSE) {
|
||||
register_failure(h, SalErrorFailure, SalReasonForbidden, _("Authentication failure"));
|
||||
}
|
||||
if (lc->vtable.auth_info_requested)
|
||||
lc->vtable.auth_info_requested(lc,realm,username);
|
||||
}
|
||||
|
|
@ -377,42 +529,87 @@ static void register_success(SalOp *op, bool_t registered){
|
|||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)sal_op_get_user_pointer(op);
|
||||
char *msg;
|
||||
|
||||
cfg->registered=registered;
|
||||
gstate_new_state(lc, GSTATE_REG_OK, NULL);
|
||||
if (cfg->registered) msg=ms_strdup_printf(_("Registration on %s successful."),sal_op_get_proxy(op));
|
||||
else msg=ms_strdup_printf(_("Unregistration on %s done."),sal_op_get_proxy(op));
|
||||
if (lc->vtable.display_status)
|
||||
linphone_proxy_config_set_error(cfg,LinphoneReasonNone);
|
||||
linphone_proxy_config_set_state(cfg, registered ? LinphoneRegistrationOk : LinphoneRegistrationCleared ,
|
||||
registered ? "Registration sucessful" : "Unregistration done");
|
||||
if (lc->vtable.display_status){
|
||||
if (cfg->registered) msg=ms_strdup_printf(_("Registration on %s successful."),sal_op_get_proxy(op));
|
||||
else msg=ms_strdup_printf(_("Unregistration on %s done."),sal_op_get_proxy(op));
|
||||
lc->vtable.display_status(lc,msg);
|
||||
ms_free(msg);
|
||||
ms_free(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void register_failure(SalOp *op, SalError error, SalReason reason, const char *details){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
char *msg=ortp_strdup_printf(_("Registration on %s failed: %s"),sal_op_get_proxy(op),(details!=NULL) ? details : _("no response timeout"));
|
||||
if (lc->vtable.display_status) lc->vtable.display_status(lc,msg);
|
||||
gstate_new_state(lc, GSTATE_REG_FAILED, msg);
|
||||
ms_free(msg);
|
||||
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)sal_op_get_user_pointer(op);
|
||||
|
||||
if (cfg==NULL){
|
||||
ms_warning("Registration failed for unknown proxy config.");
|
||||
return ;
|
||||
}
|
||||
if (details==NULL)
|
||||
details=_("no response timeout");
|
||||
|
||||
if (lc->vtable.display_status) {
|
||||
char *msg=ortp_strdup_printf(_("Registration on %s failed: %s"),sal_op_get_proxy(op),details );
|
||||
lc->vtable.display_status(lc,msg);
|
||||
ms_free(msg);
|
||||
}
|
||||
if (error== SalErrorFailure && reason == SalReasonForbidden) {
|
||||
linphone_proxy_config_set_error(cfg, LinphoneReasonBadCredentials);
|
||||
} else if (error == SalErrorNoResponse) {
|
||||
linphone_proxy_config_set_error(cfg, LinphoneReasonNoResponse);
|
||||
}
|
||||
linphone_proxy_config_set_state(cfg,LinphoneRegistrationFailed,details);
|
||||
}
|
||||
|
||||
static void vfu_request(SalOp *op){
|
||||
#ifdef VIDEO_ENABLED
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
if (lc->videostream)
|
||||
video_stream_send_vfu(lc->videostream);
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer (op);
|
||||
if (call==NULL){
|
||||
ms_warning("VFU request but no call !");
|
||||
return ;
|
||||
}
|
||||
if (call->videostream)
|
||||
video_stream_send_vfu(call->videostream);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void dtmf_received(SalOp *op, char dtmf){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
if (lc->vtable.dtmf_received != NULL)
|
||||
lc->vtable.dtmf_received(lc, dtmf);
|
||||
lc->vtable.dtmf_received(lc, call, dtmf);
|
||||
}
|
||||
|
||||
static void refer_received(Sal *sal, SalOp *op, const char *referto){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal);
|
||||
if (lc->vtable.refer_received){
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
if (call){
|
||||
if (call->refer_to!=NULL){
|
||||
ms_free(call->refer_to);
|
||||
}
|
||||
call->refer_to=ms_strdup(referto);
|
||||
call->refer_pending=TRUE;
|
||||
linphone_call_set_state(call,LinphoneCallRefered,"Refered");
|
||||
if (lc->vtable.display_status){
|
||||
char *msg=ms_strdup_printf(_("We are transferred to %s"),referto);
|
||||
lc->vtable.display_status(lc,msg);
|
||||
ms_free(msg);
|
||||
}
|
||||
if (call->state!=LinphoneCallPaused){
|
||||
ms_message("Automatically pausing current call to accept transfer.");
|
||||
linphone_core_pause_call(lc,call);
|
||||
}
|
||||
linphone_core_start_refered_call(lc,call);
|
||||
sal_call_accept_refer(op);
|
||||
}else if (lc->vtable.refer_received){
|
||||
lc->vtable.refer_received(lc,referto);
|
||||
if (op) sal_refer_accept(op);
|
||||
sal_call_accept_refer(op);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -423,10 +620,10 @@ static void text_received(Sal *sal, const char *from, const char *msg){
|
|||
|
||||
static void notify(SalOp *op, const char *from, const char *msg){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer (op);
|
||||
ms_message("get a %s notify from %s",msg,from);
|
||||
if(lc->vtable.notify_recv)
|
||||
lc->vtable.notify_recv(lc,from,msg);
|
||||
lc->vtable.notify_recv(lc,call,from,msg);
|
||||
}
|
||||
|
||||
static void notify_presence(SalOp *op, SalSubscribeState ss, SalPresenceStatus status, const char *msg){
|
||||
|
|
@ -454,10 +651,14 @@ static void ping_reply(SalOp *op){
|
|||
LinphoneCall *call=(LinphoneCall*) sal_op_get_user_pointer(op);
|
||||
ms_message("ping reply !");
|
||||
if (call){
|
||||
if (call->state==LCStatePreEstablishing){
|
||||
if (call->state==LinphoneCallOutgoingInit){
|
||||
linphone_core_start_invite(call->core,call,NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ms_warning("ping reply without call attached...");
|
||||
}
|
||||
}
|
||||
|
||||
SalCallbacks linphone_sal_callbacks={
|
||||
|
|
@ -465,7 +666,7 @@ SalCallbacks linphone_sal_callbacks={
|
|||
call_ringing,
|
||||
call_accepted,
|
||||
call_ack,
|
||||
call_updated,
|
||||
call_updating,
|
||||
call_terminated,
|
||||
call_failure,
|
||||
auth_requested,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
cr->lc=lc;
|
||||
cr->peer=linphone_address_as_string(parsed_url);
|
||||
cr->peer_url=parsed_url;
|
||||
cr->route=ms_strdup(linphone_core_get_route(lc));
|
||||
lc->chatrooms=ms_list_append(lc->chatrooms,(void *)cr);
|
||||
return cr;
|
||||
}
|
||||
|
|
@ -46,21 +45,29 @@
|
|||
lc->chatrooms=ms_list_remove(lc->chatrooms,(void *) cr);
|
||||
linphone_address_destroy(cr->peer_url);
|
||||
ms_free(cr->peer);
|
||||
ms_free(cr->route);
|
||||
if (cr->op)
|
||||
sal_op_release(cr->op);
|
||||
}
|
||||
|
||||
void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg){
|
||||
const char *identity=linphone_core_get_identity(cr->lc);
|
||||
const char *route=NULL;
|
||||
const char *identity=linphone_core_find_best_identity(cr->lc,cr->peer_url,&route);
|
||||
SalOp *op;
|
||||
if(linphone_core_is_in_communication_with(cr->lc,cr->peer))
|
||||
LinphoneCall *call;
|
||||
if((call = linphone_core_get_call_by_remote_address(cr->lc,cr->peer))!=NULL)
|
||||
{
|
||||
ms_message("send SIP message into the call\n");
|
||||
op = cr->lc->call->op;
|
||||
op = call->op;
|
||||
}
|
||||
else
|
||||
{
|
||||
op = sal_op_new(cr->lc->sal);
|
||||
sal_op_set_route(op,cr->route);
|
||||
sal_op_set_route(op,route);
|
||||
if (cr->op!=NULL){
|
||||
sal_op_release (cr->op);
|
||||
cr->op=NULL;
|
||||
}
|
||||
cr->op=op;
|
||||
}
|
||||
sal_text_send(op,identity,cr->peer,msg);
|
||||
}
|
||||
|
|
@ -71,7 +78,7 @@ bool_t linphone_chat_room_matches(LinphoneChatRoom *cr, const LinphoneAddress *f
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void linphone_chat_room_text_received(LinphoneChatRoom *cr, LinphoneCore *lc, const char *from, const char *msg){
|
||||
void linphone_chat_room_text_received(LinphoneChatRoom *cr, LinphoneCore *lc, const LinphoneAddress *from, const char *msg){
|
||||
if (lc->vtable.text_received!=NULL) lc->vtable.text_received(lc, cr, from, msg);
|
||||
}
|
||||
|
||||
|
|
@ -95,8 +102,9 @@ void linphone_core_text_received(LinphoneCore *lc, const char *from, const char
|
|||
/* create a new chat room */
|
||||
cr=linphone_core_create_chat_room(lc,cleanfrom);
|
||||
}
|
||||
|
||||
linphone_address_destroy(addr);
|
||||
linphone_chat_room_text_received(cr,lc,cleanfrom,msg);
|
||||
linphone_chat_room_text_received(cr,lc,cr->peer_url,msg);
|
||||
ms_free(cleanfrom);
|
||||
}
|
||||
|
||||
|
|
@ -107,3 +115,6 @@ void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud){
|
|||
void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr){
|
||||
return cr->user_data;
|
||||
}
|
||||
const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr) {
|
||||
return cr->peer_url;
|
||||
}
|
||||
|
|
|
|||
1189
coreapi/exevents.c
1189
coreapi/exevents.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef EXEVENTS_H
|
||||
#define EXEVENTS_H
|
||||
#include <eXosip2/eXosip.h>
|
||||
#include "sdphandler.h"
|
||||
|
||||
|
||||
void linphone_core_process_event(LinphoneCore *lc, eXosip_event_t *ev);
|
||||
|
||||
/* these are the SdpHandler callbacks: we are called in to be aware of the content
|
||||
of the SDP messages exchanged */
|
||||
|
||||
int linphone_set_audio_offer(sdp_context_t *ctx);
|
||||
int linphone_set_video_offer(sdp_context_t *ctx);
|
||||
int linphone_accept_audio_offer(sdp_context_t *ctx,sdp_payload_t *payload);
|
||||
int linphone_accept_video_offer(sdp_context_t *ctx,sdp_payload_t *payload);
|
||||
int linphone_read_audio_answer(sdp_context_t *ctx,sdp_payload_t *payload);
|
||||
int linphone_read_video_answer(sdp_context_t *ctx,sdp_payload_t *payload);
|
||||
|
||||
void linphone_core_text_received(LinphoneCore *lc, eXosip_event_t *ev);
|
||||
|
||||
#endif
|
||||
114
coreapi/friend.c
114
coreapi/friend.c
|
|
@ -29,37 +29,37 @@
|
|||
const char *linphone_online_status_to_string(LinphoneOnlineStatus ss){
|
||||
const char *str=NULL;
|
||||
switch(ss){
|
||||
case LINPHONE_STATUS_ONLINE:
|
||||
case LinphoneStatusOnline:
|
||||
str=_("Online");
|
||||
break;
|
||||
case LINPHONE_STATUS_BUSY:
|
||||
case LinphoneStatusBusy:
|
||||
str=_("Busy");
|
||||
break;
|
||||
case LINPHONE_STATUS_BERIGHTBACK:
|
||||
case LinphoneStatusBeRightBack:
|
||||
str=_("Be right back");
|
||||
break;
|
||||
case LINPHONE_STATUS_AWAY:
|
||||
case LinphoneStatusAway:
|
||||
str=_("Away");
|
||||
break;
|
||||
case LINPHONE_STATUS_ONTHEPHONE:
|
||||
case LinphoneStatusOnThePhone:
|
||||
str=_("On the phone");
|
||||
break;
|
||||
case LINPHONE_STATUS_OUTTOLUNCH:
|
||||
case LinphoneStatusOutToLunch:
|
||||
str=_("Out to lunch");
|
||||
break;
|
||||
case LINPHONE_STATUS_NOT_DISTURB:
|
||||
case LinphoneStatusDoNotDisturb:
|
||||
str=_("Do not disturb");
|
||||
break;
|
||||
case LINPHONE_STATUS_MOVED:
|
||||
case LinphoneStatusMoved:
|
||||
str=_("Moved");
|
||||
break;
|
||||
case LINPHONE_STATUS_ALT_SERVICE:
|
||||
case LinphoneStatusAltService:
|
||||
str=_("Using another messaging service");
|
||||
break;
|
||||
case LINPHONE_STATUS_OFFLINE:
|
||||
case LinphoneStatusOffline:
|
||||
str=_("Offline");
|
||||
break;
|
||||
case LINPHONE_STATUS_PENDING:
|
||||
case LinphoneStatusPending:
|
||||
str=_("Pending");
|
||||
break;
|
||||
default:
|
||||
|
|
@ -68,31 +68,11 @@ const char *linphone_online_status_to_string(LinphoneOnlineStatus ss){
|
|||
return str;
|
||||
}
|
||||
|
||||
static int friend_data_compare(const void * a, const void * b, void * data){
|
||||
static int friend_compare(const void * a, const void * b){
|
||||
LinphoneAddress *fa=((LinphoneFriend*)a)->uri;
|
||||
LinphoneAddress *fb=((LinphoneFriend*)b)->uri;
|
||||
const char *ua,*ub;
|
||||
ua=linphone_address_get_username(fa);
|
||||
ub=linphone_address_get_username(fb);
|
||||
if (ua!=NULL && ub!=NULL) {
|
||||
//printf("Comparing usernames %s,%s\n",ua,ub);
|
||||
return strcasecmp(ua,ub);
|
||||
}
|
||||
else {
|
||||
/* compare hosts*/
|
||||
ua=linphone_address_get_domain(fa);
|
||||
ub=linphone_address_get_domain(fb);
|
||||
if (ua!=NULL && ub!=NULL){
|
||||
int ret=strcasecmp(ua,ub);
|
||||
//printf("Comparing hostnames %s,%s,res=%i\n",ua,ub,ret);
|
||||
return ret;
|
||||
}
|
||||
else return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int friend_compare(const void * a, const void * b){
|
||||
return friend_data_compare(a,b,NULL);
|
||||
if (linphone_address_weak_equal (fa,fb)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -128,6 +108,7 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
|
|||
char *friend=NULL;
|
||||
const char *route=NULL;
|
||||
const char *from=NULL;
|
||||
const char *fixed_contact=NULL;
|
||||
LinphoneProxyConfig *cfg;
|
||||
|
||||
friend=linphone_address_as_string(fr->uri);
|
||||
|
|
@ -135,10 +116,16 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
|
|||
if (cfg!=NULL){
|
||||
route=linphone_proxy_config_get_route(cfg);
|
||||
from=linphone_proxy_config_get_identity(cfg);
|
||||
if (cfg->op){
|
||||
fixed_contact=sal_op_get_contact(cfg->op);
|
||||
if (fixed_contact) {
|
||||
ms_message("Contact for subscribe has been fixed using proxy to %s",fixed_contact);
|
||||
}
|
||||
}
|
||||
}else from=linphone_core_get_primary_contact(fr->lc);
|
||||
if (fr->outsub==NULL){
|
||||
/* people for which we don't have yet an answer should appear as offline */
|
||||
fr->status=LINPHONE_STATUS_OFFLINE;
|
||||
fr->status=LinphoneStatusOffline;
|
||||
/*
|
||||
if (fr->lc->vtable.notify_recv)
|
||||
fr->lc->vtable.notify_recv(fr->lc,(LinphoneFriend*)fr);
|
||||
|
|
@ -149,6 +136,7 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
|
|||
}
|
||||
fr->outsub=sal_op_new(fr->lc->sal);
|
||||
sal_op_set_route(fr->outsub,route);
|
||||
sal_op_set_contact(fr->outsub,fixed_contact);
|
||||
sal_subscribe_presence(fr->outsub,from,friend);
|
||||
fr->subscribe_active=TRUE;
|
||||
ms_free(friend);
|
||||
|
|
@ -157,14 +145,19 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
|
|||
LinphoneFriend * linphone_friend_new(){
|
||||
LinphoneFriend *obj=ms_new0(LinphoneFriend,1);
|
||||
obj->pol=LinphoneSPAccept;
|
||||
obj->status=LINPHONE_STATUS_OFFLINE;
|
||||
obj->status=LinphoneStatusOffline;
|
||||
obj->subscribe=TRUE;
|
||||
return obj;
|
||||
}
|
||||
|
||||
LinphoneFriend *linphone_friend_new_with_addr(const char *addr){
|
||||
LinphoneAddress* linphone_address = linphone_address_new(addr);
|
||||
if (linphone_address == NULL) {
|
||||
ms_error("Cannot create friend for address [%s]",addr?addr:"null");
|
||||
return NULL;
|
||||
}
|
||||
LinphoneFriend *fr=linphone_friend_new();
|
||||
if (linphone_friend_set_sip_addr(fr,addr)<0){
|
||||
if (linphone_friend_set_addr(fr,linphone_address)<0){
|
||||
linphone_friend_destroy(fr);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -208,8 +201,8 @@ void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char
|
|||
linphone_address_destroy(fr);
|
||||
}
|
||||
|
||||
int linphone_friend_set_sip_addr(LinphoneFriend *lf, const char *addr){
|
||||
LinphoneAddress *fr=linphone_address_new(addr);
|
||||
int linphone_friend_set_addr(LinphoneFriend *lf, const LinphoneAddress *addr){
|
||||
LinphoneAddress *fr=linphone_address_clone(addr);
|
||||
if (fr==NULL) {
|
||||
ms_warning("Invalid friend sip uri: %s",addr);
|
||||
return -1;
|
||||
|
|
@ -230,7 +223,7 @@ int linphone_friend_set_name(LinphoneFriend *lf, const char *name){
|
|||
return 0;
|
||||
}
|
||||
|
||||
int linphone_friend_send_subscribe(LinphoneFriend *fr, bool_t val){
|
||||
int linphone_friend_enable_subscribes(LinphoneFriend *fr, bool_t val){
|
||||
fr->subscribe=val;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -243,37 +236,37 @@ int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscri
|
|||
|
||||
SalPresenceStatus linphone_online_status_to_sal(LinphoneOnlineStatus os){
|
||||
switch(os){
|
||||
case LINPHONE_STATUS_OFFLINE:
|
||||
case LinphoneStatusOffline:
|
||||
return SalPresenceOffline;
|
||||
break;
|
||||
case LINPHONE_STATUS_ONLINE:
|
||||
case LinphoneStatusOnline:
|
||||
return SalPresenceOnline;
|
||||
break;
|
||||
case LINPHONE_STATUS_BUSY:
|
||||
case LinphoneStatusBusy:
|
||||
return SalPresenceBusy;
|
||||
break;
|
||||
case LINPHONE_STATUS_BERIGHTBACK:
|
||||
case LinphoneStatusBeRightBack:
|
||||
return SalPresenceBerightback;
|
||||
break;
|
||||
case LINPHONE_STATUS_AWAY:
|
||||
case LinphoneStatusAway:
|
||||
return SalPresenceAway;
|
||||
break;
|
||||
case LINPHONE_STATUS_ONTHEPHONE:
|
||||
case LinphoneStatusOnThePhone:
|
||||
return SalPresenceOnthephone;
|
||||
break;
|
||||
case LINPHONE_STATUS_OUTTOLUNCH:
|
||||
case LinphoneStatusOutToLunch:
|
||||
return SalPresenceOuttolunch;
|
||||
break;
|
||||
case LINPHONE_STATUS_NOT_DISTURB:
|
||||
case LinphoneStatusDoNotDisturb:
|
||||
return SalPresenceDonotdisturb;
|
||||
break;
|
||||
case LINPHONE_STATUS_MOVED:
|
||||
case LinphoneStatusMoved:
|
||||
return SalPresenceMoved;
|
||||
break;
|
||||
case LINPHONE_STATUS_ALT_SERVICE:
|
||||
case LinphoneStatusAltService:
|
||||
return SalPresenceAltService;
|
||||
break;
|
||||
case LINPHONE_STATUS_PENDING:
|
||||
case LinphoneStatusPending:
|
||||
return SalPresenceOffline;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -347,7 +340,7 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
|
|||
if (fr->inc_subscribe_pending){
|
||||
switch(fr->pol){
|
||||
case LinphoneSPWait:
|
||||
linphone_friend_notify(fr,LINPHONE_STATUS_PENDING);
|
||||
linphone_friend_notify(fr,LinphoneStatusPending);
|
||||
break;
|
||||
case LinphoneSPAccept:
|
||||
if (fr->lc!=NULL)
|
||||
|
|
@ -356,7 +349,7 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
|
|||
}
|
||||
break;
|
||||
case LinphoneSPDeny:
|
||||
linphone_friend_notify(fr,LINPHONE_STATUS_OFFLINE);
|
||||
linphone_friend_notify(fr,LinphoneStatusOffline);
|
||||
break;
|
||||
}
|
||||
fr->inc_subscribe_pending=FALSE;
|
||||
|
|
@ -367,6 +360,7 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
|
|||
}
|
||||
ms_message("linphone_friend_apply() done.");
|
||||
lc->bl_refresh=TRUE;
|
||||
fr->commit=FALSE;
|
||||
}
|
||||
|
||||
void linphone_friend_edit(LinphoneFriend *fr){
|
||||
|
|
@ -391,7 +385,8 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf)
|
|||
return ;
|
||||
}
|
||||
lc->friends=ms_list_append(lc->friends,lf);
|
||||
linphone_friend_apply(lf,lc);
|
||||
if ( linphone_core_ready(lc)) linphone_friend_apply(lf,lc);
|
||||
else lf->commit=TRUE;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
|
@ -404,6 +399,15 @@ void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){
|
|||
}
|
||||
}
|
||||
|
||||
void linphone_core_send_initial_subscribes(LinphoneCore *lc){
|
||||
const MSList *elem;
|
||||
for(elem=lc->friends;elem!=NULL;elem=elem->next){
|
||||
LinphoneFriend *f=(LinphoneFriend*)elem->data;
|
||||
if (f->commit)
|
||||
linphone_friend_apply(f,lc);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_friend_set_ref_key(LinphoneFriend *lf, const char *key){
|
||||
if (lf->refkey!=NULL){
|
||||
ms_free(lf->refkey);
|
||||
|
|
@ -562,7 +566,7 @@ void linphone_core_write_friends_config(LinphoneCore* lc)
|
|||
{
|
||||
MSList *elem;
|
||||
int i;
|
||||
if (!lc->ready) return; /*dont write config when reading it !*/
|
||||
if (! linphone_core_ready(lc)) return; /*dont write config when reading it !*/
|
||||
for (elem=lc->friends,i=0; elem!=NULL; elem=ms_list_next(elem),i++){
|
||||
linphone_friend_write_to_config_file(lc->config,(LinphoneFriend*)elem->data,i);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,117 +0,0 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* File: general_state.c
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Thomas Reitmayr <treitmayr@yahoo.com>
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "private.h"
|
||||
#if 0
|
||||
static const char *_gstates_text[] = {
|
||||
"GSTATE_POWER_OFF", /* 0 */
|
||||
"GSTATE_POWER_STARTUP", /* 1 */
|
||||
"GSTATE_POWER_ON", /* 2 */
|
||||
"GSTATE_POWER_SHUTDOWN", /* 3 */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
"GSTATE_REG_NONE", /* 10 */
|
||||
"GSTATE_REG_OK", /* 11 */
|
||||
"GSTATE_REG_FAILED", /* 12 */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
"GSTATE_CALL_IDLE", /* 20 */
|
||||
"GSTATE_CALL_OUT_INVITE", /* 21 */
|
||||
"GSTATE_CALL_OUT_CONNECTED", /* 22 */
|
||||
"GSTATE_CALL_IN_INVITE", /* 23 */
|
||||
"GSTATE_CALL_IN_CONNECTED", /* 24 */
|
||||
"GSTATE_CALL_END", /* 25 */
|
||||
"GSTATE_CALL_ERROR" /* 26 */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* set the initial states */
|
||||
void gstate_initialize(LinphoneCore *lc) {
|
||||
lc->gstate_power = GSTATE_POWER_OFF;
|
||||
lc->gstate_reg = GSTATE_REG_NONE;
|
||||
lc->gstate_call = GSTATE_CALL_IDLE;
|
||||
}
|
||||
|
||||
gstate_t linphone_core_get_state(const LinphoneCore *lc, gstate_group_t group){
|
||||
switch(group){
|
||||
case GSTATE_GROUP_POWER:
|
||||
return lc->gstate_power;
|
||||
case GSTATE_GROUP_REG:
|
||||
return lc->gstate_reg;
|
||||
case GSTATE_GROUP_CALL:
|
||||
return lc->gstate_call;
|
||||
}
|
||||
return GSTATE_INVALID;
|
||||
}
|
||||
|
||||
static void linphone_core_set_state(LinphoneCore *lc, gstate_group_t group, gstate_t new_state){
|
||||
switch(group){
|
||||
case GSTATE_GROUP_POWER:
|
||||
lc->gstate_power=new_state;
|
||||
break;
|
||||
case GSTATE_GROUP_REG:
|
||||
lc->gstate_reg=new_state;
|
||||
break;
|
||||
case GSTATE_GROUP_CALL:
|
||||
lc->gstate_call=new_state;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void gstate_new_state(struct _LinphoneCore *lc,
|
||||
gstate_t new_state,
|
||||
const char *message) {
|
||||
LinphoneGeneralState states_arg;
|
||||
|
||||
/* determine the affected group */
|
||||
if (new_state < GSTATE_REG_NONE)
|
||||
states_arg.group = GSTATE_GROUP_POWER;
|
||||
else if (new_state < GSTATE_CALL_IDLE)
|
||||
states_arg.group = GSTATE_GROUP_REG;
|
||||
else
|
||||
states_arg.group = GSTATE_GROUP_CALL;
|
||||
|
||||
/* store the new state while remembering the old one */
|
||||
states_arg.new_state = new_state;
|
||||
states_arg.old_state = linphone_core_get_state(lc,states_arg.group);
|
||||
linphone_core_set_state(lc, states_arg.group,new_state);
|
||||
states_arg.message = message;
|
||||
|
||||
/*printf("gstate_new_state: %s\t-> %s\t(%s)\n",
|
||||
_gstates_text[states_arg.old_state],
|
||||
_gstates_text[states_arg.new_state],
|
||||
message);*/
|
||||
|
||||
/* call the virtual method */
|
||||
if (lc->vtable.general_state)
|
||||
lc->vtable.general_state(lc, &states_arg);
|
||||
|
||||
/* immediately proceed to idle state */
|
||||
if (new_state == GSTATE_CALL_END ||
|
||||
new_state == GSTATE_CALL_ERROR)
|
||||
gstate_new_state(lc, GSTATE_CALL_IDLE, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ RECURSIVE = NO
|
|||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH = ../
|
||||
EXAMPLE_PATH = ../../ .
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
EXTRA_DIST = Doxyfile.in doxygen.dox.in
|
||||
EXTRA_DIST = Doxyfile.in doxygen.dox
|
||||
|
||||
SOURCES=$(top_srcdir)/coreapi/*.h $(top_srcdir)/coreapi/*.c
|
||||
SOURCES= doxygen.dox $(top_srcdir)/coreapi/help/*.c $(top_srcdir)/coreapi/*.c $(top_srcdir)/coreapi/*.h
|
||||
|
||||
|
||||
#html doc
|
||||
|
|
@ -31,3 +31,40 @@ endif
|
|||
|
||||
clean-local:
|
||||
rm -rf doc
|
||||
|
||||
noinst_PROGRAMS=helloworld registration buddy_status chatroom
|
||||
|
||||
helloworld_SOURCES=helloworld.c
|
||||
|
||||
helloworld_LDADD=$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS)
|
||||
|
||||
registration_SOURCES=registration.c
|
||||
|
||||
registration_LDADD=$(helloworld_LDADD)
|
||||
|
||||
buddy_status_SOURCES=buddy_status.c
|
||||
|
||||
buddy_status_LDADD=$(helloworld_LDADD)
|
||||
|
||||
chatroom_SOURCES=chatroom.c
|
||||
|
||||
chatroom_LDADD=$(helloworld_LDADD)
|
||||
|
||||
|
||||
|
||||
INCLUDES=-I$(top_srcdir)/coreapi \
|
||||
$(MEDIASTREAMER_CFLAGS)
|
||||
|
||||
AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE \
|
||||
$(ORTP_CFLAGS) \
|
||||
$(OSIP_CFLAGS) \
|
||||
$(MEDIASTREAMER_CFLAGS) \
|
||||
$(EXOSIP_CFLAGS) \
|
||||
-DENABLE_TRACE \
|
||||
-DLOG_DOMAIN=\"LinphoneCore\" \
|
||||
$(IPV6_CFLAGS) \
|
||||
-DORTP_INET6 \
|
||||
$(VIDEO_CFLAGS)
|
||||
|
||||
|
|
|
|||
137
coreapi/help/buddy_status.c
Normal file
137
coreapi/help/buddy_status.c
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
|
||||
/*
|
||||
buddy_status
|
||||
Copyright (C) 2010 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup buddy_tutorials Basic buddy status notification
|
||||
* @ingroup tutorials
|
||||
*This program is a _very_ simple usage example of liblinphone,
|
||||
*demonstrating how to initiate SIP subscriptions and receive notifications from a sip uri identity passed from the command line.
|
||||
*<br>Argument must be like sip:jehan@sip.linphone.org .
|
||||
*<br>
|
||||
*ex budy_list sip:jehan@sip.linphone.org
|
||||
*<br>Subscription is cleared on SIGINT
|
||||
*<br>
|
||||
*@include buddy_status.c
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef IN_LINPHONE
|
||||
#include "linphonecore.h"
|
||||
#else
|
||||
#include "linphone/linphonecore.h"
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
static bool_t running=TRUE;
|
||||
|
||||
static void stop(int signum){
|
||||
running=FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* presence state change notification callback
|
||||
*/
|
||||
static void notify_presence_recv_updated (LinphoneCore *lc, LinphoneFriend *friend) {
|
||||
const LinphoneAddress* friend_address = linphone_friend_get_address(friend);
|
||||
printf("New state state [%s] for user id [%s] \n"
|
||||
,linphone_online_status_to_string(linphone_friend_get_status(friend))
|
||||
,linphone_address_as_string (friend_address));
|
||||
}
|
||||
static void new_subscription_request (LinphoneCore *lc, LinphoneFriend *friend, const char* url) {
|
||||
const LinphoneAddress* friend_address = linphone_friend_get_address(friend);
|
||||
printf(" [%s] wants to see your status, accepting\n"
|
||||
,linphone_address_as_string (friend_address));
|
||||
linphone_friend_edit(friend); /* start editing friend */
|
||||
linphone_friend_set_inc_subscribe_policy(friend,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
|
||||
linphone_friend_done(friend); /*commit change*/
|
||||
linphone_core_add_friend(lc,friend); /* add this new friend to the buddy list*/
|
||||
|
||||
}
|
||||
|
||||
LinphoneCore *lc;
|
||||
int main(int argc, char *argv[]){
|
||||
LinphoneCoreVTable vtable={0};
|
||||
|
||||
char* dest_friend=NULL;
|
||||
|
||||
|
||||
/* takes sip uri identity from the command line arguments */
|
||||
if (argc>1){
|
||||
dest_friend=argv[1];
|
||||
}
|
||||
|
||||
signal(SIGINT,stop);
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
|
||||
#endif
|
||||
/*
|
||||
Fill the LinphoneCoreVTable with application callbacks.
|
||||
All are optional. Here we only use the both notify_presence_recv and new_subscription_request callbacks
|
||||
in order to get notifications about friend status.
|
||||
*/
|
||||
vtable.notify_presence_recv=notify_presence_recv_updated;
|
||||
vtable.new_subscription_request=new_subscription_request;
|
||||
|
||||
/*
|
||||
Instantiate a LinphoneCore object given the LinphoneCoreVTable
|
||||
*/
|
||||
lc=linphone_core_new(&vtable,NULL,NULL,NULL);
|
||||
LinphoneFriend* my_friend=NULL;
|
||||
|
||||
if (dest_friend) {
|
||||
my_friend = linphone_friend_new_with_addr(dest_friend); /*creates friend object from dest*/
|
||||
if (my_friend == NULL) {
|
||||
printf("bad destination uri for friend [%s]\n",dest_friend);
|
||||
goto end;
|
||||
}
|
||||
|
||||
linphone_friend_enable_subscribes(my_friend,TRUE); /*configure this friend to emit SUBSCRIBE message after being added to LinphoneCore*/
|
||||
linphone_friend_set_inc_subscribe_policy(my_friend,LinphoneSPAccept); /* Accept incoming subscription request for this friend*/
|
||||
linphone_core_add_friend(lc,my_friend); /* add my friend to the buddy list, initiate SUBSCRIBE message*/
|
||||
|
||||
}
|
||||
|
||||
linphone_core_set_presence_info(lc,0,NULL,LinphoneStatusOnline); /*set my status to online*/
|
||||
|
||||
/* main loop for receiving notifications and doing background linphone core work: */
|
||||
while(running){
|
||||
linphone_core_iterate(lc); /* first iterate initiates subscription */
|
||||
ms_usleep(50000);
|
||||
}
|
||||
|
||||
linphone_core_set_presence_info(lc,0,NULL,LinphoneStatusOffline); /* change my presence status to offline*/
|
||||
linphone_core_iterate(lc); /* just to make sure new status is initiate message is issued */
|
||||
|
||||
linphone_friend_edit(my_friend); /* start editing friend */
|
||||
linphone_friend_enable_subscribes(my_friend,FALSE); /*disable subscription for this friend*/
|
||||
linphone_friend_done(my_friend); /*commit changes triggering an UNSUBSCRIBE message*/
|
||||
|
||||
linphone_core_iterate(lc); /* just to make sure unsubscribe message is issued */
|
||||
|
||||
end:
|
||||
printf("Shutting down...\n");
|
||||
linphone_core_destroy(lc);
|
||||
printf("Exited\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
100
coreapi/help/chatroom.c
Normal file
100
coreapi/help/chatroom.c
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
|
||||
/*
|
||||
linphone
|
||||
Copyright (C) 2010 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup chatroom_tuto Chat room and messaging
|
||||
* @ingroup tutorials
|
||||
*This program is a _very_ simple usage example of liblinphone,
|
||||
*desmonstrating how to send/receive SIP MESSAGE from a sip uri identity passed from the command line.
|
||||
*<br>Argument must be like sip:jehan@sip.linphone.org .
|
||||
*<br>
|
||||
*ex chatroom sip:jehan@sip.linphone.org
|
||||
*<br>
|
||||
*@include chatroom.c
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef IN_LINPHONE
|
||||
#include "linphonecore.h"
|
||||
#else
|
||||
#include "linphone/linphonecore.h"
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
static bool_t running=TRUE;
|
||||
|
||||
static void stop(int signum){
|
||||
running=FALSE;
|
||||
}
|
||||
void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message) {
|
||||
printf(" Message [%s] received from [%s] \n",message,linphone_address_as_string (from));
|
||||
}
|
||||
|
||||
|
||||
LinphoneCore *lc;
|
||||
int main(int argc, char *argv[]){
|
||||
LinphoneCoreVTable vtable={0};
|
||||
|
||||
char* dest_friend=NULL;
|
||||
|
||||
|
||||
/* takes sip uri identity from the command line arguments */
|
||||
if (argc>1){
|
||||
dest_friend=argv[1];
|
||||
}
|
||||
|
||||
signal(SIGINT,stop);
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
|
||||
#endif
|
||||
/*
|
||||
Fill the LinphoneCoreVTable with application callbacks.
|
||||
All are optional. Here we only use the text_received callback
|
||||
in order to get notifications about incoming message.
|
||||
*/
|
||||
vtable.text_received=text_received;
|
||||
|
||||
/*
|
||||
Instantiate a LinphoneCore object given the LinphoneCoreVTable
|
||||
*/
|
||||
lc=linphone_core_new(&vtable,NULL,NULL,NULL);
|
||||
|
||||
|
||||
/*Next step is to create a chat root*/
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(lc,dest_friend);
|
||||
|
||||
linphone_chat_room_send_message(chat_room,"Hello world"); /*sending message*/
|
||||
|
||||
/* main loop for receiving incoming messages and doing background linphone core work: */
|
||||
while(running){
|
||||
linphone_core_iterate(lc);
|
||||
ms_usleep(50000);
|
||||
}
|
||||
|
||||
printf("Shutting down...\n");
|
||||
linphone_chat_room_destroy(chat_room);
|
||||
linphone_core_destroy(lc);
|
||||
printf("Exited\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
193
coreapi/help/doxygen.dox
Normal file
193
coreapi/help/doxygen.dox
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/**
|
||||
* @mainpage
|
||||
*
|
||||
* @see http://www.linphone.org
|
||||
*
|
||||
* @section what_is_it What is liblinphone
|
||||
*
|
||||
* Liblinphone is a high level library for bringing SIP video call functionnality
|
||||
* into an application. It aims at making easy the integration of the SIP
|
||||
* video calls into any applications. All variants of linphone are directly based
|
||||
* on it:
|
||||
* - linphone (gtk interface)
|
||||
*
|
||||
* - linphonec (console interface)
|
||||
*
|
||||
* Liblinphone is GPL (see COPYING file). Please understand the licencing details
|
||||
* before using it!
|
||||
*
|
||||
* For any use of this library beyond the rights granted to you by the
|
||||
* GPL license, please contact Belledonne Communications
|
||||
* (contact@belledonne-communications.com)
|
||||
*
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
* @page liblinphone_license COPYING
|
||||
* @verbinclude COPYING
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup initializing Initializing liblinphone
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup call_control Placing and receiving calls
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup media_parameters Controlling media parameters
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup proxies Managing proxies
|
||||
*User registration is controled by #LinphoneProxyConfig settings.<br> Each #LinphoneProxyConfig object can be configured with registration informations
|
||||
*like \link linphone_proxy_config_set_server_addr() proxy address \endlink , \link linphone_proxy_config_set_identity() user id \endlink, \link linphone_proxy_config_expires() refresh period \endlink, and so on.
|
||||
*<br> A created proxy config using linphone_proxy_config_new(), once configured, must be added to #LinphoneCore using function linphone_core_add_proxy_config().
|
||||
*<br> It is recommended to set a default \link #LinphoneProxyConfig proxy config \endlink using function linphone_core_set_default_proxy(). Once done, if \link #LinphoneProxyConfig a proxy config \endlink has been configured with attribute \link linphone_proxy_config_enable_register() enable register \endlink , next call to linphone_core_iterate() triggers a SIP register.
|
||||
*<br> Registration status is reported by #LinphoneRegistrationStateCb.
|
||||
*<br>
|
||||
*<br> This pseudo code demonstrates basic registration operations:
|
||||
*<br> \code
|
||||
*
|
||||
* LinphoneProxyConfig* proxy_cfg;
|
||||
* /*create proxy config*/
|
||||
* proxy_cfg = linphone_proxy_config_new();
|
||||
* /*parse identity*/
|
||||
* LinphoneAddress *from = linphone_address_new("sip:toto@sip.titi.com");
|
||||
* LinphoneAuthInfo *info;
|
||||
* if (password!=NULL){
|
||||
* info=linphone_auth_info_new(linphone_address_get_username(from),NULL,"secret",NULL,NULL); /*create authentication structure from identity*/
|
||||
* linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
|
||||
* }
|
||||
* // configure proxy entries
|
||||
* linphone_proxy_config_set_identity(proxy_cfg,identity); /*set identity with user name and domain*/
|
||||
* const char* server_addr = linphone_address_get_domain(from); /*extract domain address from identity*/
|
||||
* linphone_proxy_config_set_server_addr(proxy_cfg,server_addr); /* we assume domain = proxy server address*/
|
||||
* linphone_proxy_config_enable_register(proxy_cfg,TRUE); /*activate registration for this proxy config*/
|
||||
* linphone_address_destroy(from); /*release resource*/
|
||||
*
|
||||
* linphone_core_add_proxy_config(lc,proxy_cfg); /*add proxy config to linphone core*/
|
||||
* linphone_core_set_default_proxy(lc,proxy_cfg); /*set to default proxy*/ \endcode
|
||||
*<br>
|
||||
* Registration sate call back:
|
||||
\code
|
||||
static void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){
|
||||
printf("New registration state %s for user id [%s] at proxy [%s]\n"
|
||||
,linphone_registration_state_to_string(cstate)
|
||||
,linphone_proxy_config_get_identity(cfg)
|
||||
,linphone_proxy_config_get_addr(cfg));
|
||||
}
|
||||
\endcode
|
||||
*<br><b>Authentication:</b>
|
||||
*<br>Most of the time, registration requires \ref authentication "authentication" to succed. #LinphoneAuthInfo info must be either added to #LinphoneCore using function linphone_core_add_auth_info() before #LinphoneProxyConfig is added to Linphone core, or on demand from call back #AuthInfoRequested .
|
||||
*<br>
|
||||
*<br><b>Unregistration:</b>
|
||||
*<br> Unregistration or any changes to #LinphoneProxyConfig must be first started by a call to function linphone_proxy_config_edit() and validated by function linphone_proxy_config_done()
|
||||
*<br> This pseudo code shows how to unregister a user associated to a #LinphoneProxyConfig
|
||||
*\code
|
||||
LinphoneProxyConfig* proxy_cfg;
|
||||
linphone_core_get_default_proxy(lc,&proxy_cfg); /* get default proxy config*/
|
||||
linphone_proxy_config_edit(proxy_cfg); /*start editing proxy configuration*/
|
||||
linphone_proxy_config_enable_register(proxy_cfg,FALSE); /*de-activate registration for this proxy config*/
|
||||
linphone_proxy_config_done(proxy_cfg); /*initiate REGISTER with expire = 0*/
|
||||
\endcode
|
||||
<br>
|
||||
A complete tutorial can be found at : \ref registration_tutorials "Registration tutorial"
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup network_parameters Controlling network parameters (ports, mtu...)
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup authentication Managing authentication: userid and passwords
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup buddy_list Managing Buddies and buddy list and presence
|
||||
<b>Buddies and buddy list</b>
|
||||
<br>Each buddy is represented by a #LinphoneFriend object created by function linphone_friend_new().
|
||||
Buddy configuration parameters like \link linphone_friend_set_addr() sip uri \endlink or \link linphone_friend_set_inc_subscribe_policy() status publication \endlink policy for this \link #LinphoneFriend friend \endlink are configurable for each buddy.
|
||||
<br>Here under a typical buddy creation:
|
||||
<br>
|
||||
\code
|
||||
LinphoneFriend* my_friend=linphone_friend_new_with_addr("sip:joe@sip.linphone.org"); /*creates friend object for buddy joe*/
|
||||
linphone_friend_enable_subscribes(my_friend,TRUE); /*configure this friend to emit SUBSCRIBE message after being added to LinphoneCore*/
|
||||
linphone_friend_set_inc_subscribe_policy(my_friend,LinphoneSPAccept); /* accept Incoming subscription request for this friend*/
|
||||
\endcode
|
||||
\link #LinphoneFriend friends \endlink status changes are reported by callback LinphoneCoreVTable.notify_presence_recv
|
||||
\code
|
||||
static void notify_presence_recv_updated (struct _LinphoneCore *lc, LinphoneFriend *friend) {
|
||||
const LinphoneAddress* friend_address = linphone_friend_get_address(friend);
|
||||
printf("New state state [%s] for user id [%s] \n"
|
||||
,linphone_online_status_to_string(linphone_friend_get_status(friend))
|
||||
,linphone_address_as_string (friend_address));
|
||||
}
|
||||
\endcode
|
||||
<br>Once created a buddy can be added to the buddy list using function linphone_core_add_friend() . Added friends will be notified about \link linphone_core_set_presence_info() local status changes \endlink
|
||||
<br>
|
||||
Any subsequente modifications to #LinphoneFriend must be first started by a call to function linphone_friend_edit() and validated by function linphone_friend_done()
|
||||
\code
|
||||
linphone_friend_edit(my_friend); /* start editing friend */
|
||||
linphone_friend_enable_subscribes(my_friend,FALSE); /*disable subscription for this friend*/
|
||||
linphone_friend_done(my_friend); /*commit changes triggering an UNSUBSCRIBE message*/
|
||||
\endcode
|
||||
|
||||
|
||||
<b> Publishing presence status </b>
|
||||
<br>Local presence status can be changed using function linphone_core_set_presence_info() .New status is propagated to all friends \link linphone_core_add_friend() previously added \endlink to #LinphoneCore.
|
||||
|
||||
<b>Handling incoming subscription request</b>
|
||||
<br> New incoming subscription requests are process according to \link linphone_friend_set_inc_subscribe_policy() the incoming subscription policy state \endlink for subscription initiated by \link linphone_core_add_friend() members of the buddy list. \endlink
|
||||
<br> For incoming request comming from an unknown buddy, the call back LinphoneCoreVTable.new_subscription_request is invoked.
|
||||
|
||||
<br> A complete tutorial can be found at : \ref buddy_tutorials "Registration tutorial"
|
||||
|
||||
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup chatroom Chat room and Messaging
|
||||
<b> Exchanging text messages</b>
|
||||
<br> Messages are sent using #LinphoneChatRoom object. First step is to create a \link linphone_core_create_chat_room() chat room \endlink
|
||||
from a peer sip uri.
|
||||
\code
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(lc,"sip:joe@sip.linphone.org");
|
||||
\endcode
|
||||
|
||||
<br>Once created, messages are sent using function linphone_chat_room_send_message() .
|
||||
\code
|
||||
linphone_chat_room_send_message(chat_room,"Hello world"); /*sending message*/
|
||||
\endcode
|
||||
<br>Incoming message are received from call back LinphoneCoreVTable.text_received
|
||||
\code
|
||||
void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message) {
|
||||
printf(" Message [%s] received from [%s] \n",message,linphone_address_as_string (from));
|
||||
}
|
||||
\endcode
|
||||
<br> A complete tutorial can be found at : \ref chatroom_tuto "Chat room tutorial"
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup call_logs Managing call logs
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup linphone_address SIP address parser API.
|
||||
* This api is useful for manipulating SIP addresses ('from' or 'to' headers).
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup misc Miscenalleous: logs, version strings, config storage
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup tutorials Tutorials:
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
/**
|
||||
* @mainpage
|
||||
*
|
||||
* @see http://www.linphone.org
|
||||
*
|
||||
* @section what_is_it What is liblinphone
|
||||
*
|
||||
* Liblinphone is a high level library for bringing SIP video call functionnality
|
||||
* into an application. It aims at making easy the integration of the SIP
|
||||
* video calls into any applications. All variants of linphone are directly based
|
||||
* on it:
|
||||
* - linphone (gtk interface)
|
||||
*
|
||||
* - linphonec (console interface)
|
||||
*
|
||||
* Liblinphone is GPL (see COPYING file). Please understand the licencing details
|
||||
* before using it!
|
||||
*
|
||||
* For any use of this library beyond the rights granted to you by the
|
||||
* GPL license, please contact Belledonne Communications
|
||||
* (contact@belledonne-communications.com)
|
||||
*
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
* @page liblinphone_license COPYING
|
||||
* @verbinclude COPYING
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tutorial_liblinphone Tutorial: Placing and receiving calls with liblinphone
|
||||
*
|
||||
|
||||
<H1>Initialize liblinphone</H1>
|
||||
|
||||
The first thing to do is to initialize the library passing it a set of callbacks functions to receive
|
||||
various notifications: incoming calls, progress of calls etc...
|
||||
These callbacks are all grouped in the LinphoneCoreVTable structure.
|
||||
All are optionnals (use NULL if you don't need them).
|
||||
The following code shows how initialize liblinphone:
|
||||
|
||||
<PRE>
|
||||
##include <linphonecore.h>
|
||||
|
||||
//callback function for notification of incoming calls
|
||||
static void on_invite_recv(LinphoneCore *lc, const char *from){
|
||||
printf("Receiving a call from %s\n",from);
|
||||
}
|
||||
|
||||
//callback function for notification end of calls (by remote)
|
||||
static void on_bye_recv(LinphoneCore *lc, const char *from){
|
||||
printf("Remote end hangup\n");
|
||||
}
|
||||
|
||||
/
|
||||
static void on_display_status(LinphoneCore *lc, const char *msg){
|
||||
printf("%s",msg);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
LinphoneCoreVTable vtable;
|
||||
|
||||
memset(&vtable,0,sizeof(vtable));
|
||||
vtable.inv_recv=&on_invite_recv;
|
||||
vtable.bye_recv=&on_bye_recv;
|
||||
vtable.display_status=&on_display_status;
|
||||
|
||||
}
|
||||
|
||||
</PRE>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup initializing Initialization and destruction
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup call_control Call control
|
||||
*
|
||||
* The application can initiate outgoing calls with linphone_core_invite().
|
||||
* It is notified of incoming call thanks to the inv_recv callback of the LinphoneCoreVTable
|
||||
* structure that is passed at creation of the LinphoneCore object.
|
||||
* It can then answer calls with linphone_core_accept_call().
|
||||
* Calls can be terminated or declined with linphone_core_terminate_call().
|
||||
* The application is notified when the remote party hangups thanks to
|
||||
* bye_recv callback of the #LinphoneCoreVTable.
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup media_parameters Controlling media parameters
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup proxies Managing proxies
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup network_parameters Controlling network parameters (ports, mtu...)
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup authentication Managing authentication: userid and passwords
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup call_logs Managing call logs
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup linphone_address SIP address parser API.
|
||||
* This api is useful for manipulating SIP addresses ('from' or 'to' headers).
|
||||
**/
|
||||
|
||||
/**
|
||||
* @defgroup misc Miscenalleous: logs, version strings, config storage
|
||||
**/
|
||||
130
coreapi/help/helloworld.c
Normal file
130
coreapi/help/helloworld.c
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
|
||||
/*
|
||||
linphone
|
||||
Copyright (C) 2010 Belledonne Communications SARL
|
||||
(simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup basic_call_tutorials Basic call
|
||||
* @ingroup tutorials
|
||||
This program is a _very_ simple usage example of liblinphone.
|
||||
It just takes a sip-uri as first argument and attempts to call it
|
||||
|
||||
@include helloworld.c
|
||||
*/
|
||||
#ifdef IN_LINPHONE
|
||||
#include "linphonecore.h"
|
||||
#else
|
||||
#include "linphone/linphonecore.h"
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
static bool_t running=TRUE;
|
||||
|
||||
static void stop(int signum){
|
||||
running=FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call state notification callback
|
||||
*/
|
||||
static void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){
|
||||
switch(cstate){
|
||||
case LinphoneCallOutgoingRinging:
|
||||
printf("It is now ringing remotely !\n");
|
||||
break;
|
||||
case LinphoneCallOutgoingEarlyMedia:
|
||||
printf("Receiving some early media\n");
|
||||
break;
|
||||
case LinphoneCallConnected:
|
||||
printf("We are connected !\n");
|
||||
break;
|
||||
case LinphoneCallStreamsRunning:
|
||||
printf("Media streams established !\n");
|
||||
break;
|
||||
case LinphoneCallEnd:
|
||||
printf("Call is terminated.\n");
|
||||
break;
|
||||
case LinphoneCallError:
|
||||
printf("Call failure !");
|
||||
break;
|
||||
default:
|
||||
printf("Unhandled notification %i\n",cstate);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
LinphoneCoreVTable vtable={0};
|
||||
LinphoneCore *lc;
|
||||
LinphoneCall *call=NULL;
|
||||
const char *dest=NULL;
|
||||
|
||||
/* take the destination sip uri from the command line arguments */
|
||||
if (argc>1){
|
||||
dest=argv[1];
|
||||
}
|
||||
|
||||
signal(SIGINT,stop);
|
||||
|
||||
#ifdef DEBUG
|
||||
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
|
||||
#endif
|
||||
/*
|
||||
Fill the LinphoneCoreVTable with application callbacks.
|
||||
All are optional. Here we only use the call_state_changed callbacks
|
||||
in order to get notifications about the progress of the call.
|
||||
*/
|
||||
vtable.call_state_changed=call_state_changed;
|
||||
|
||||
/*
|
||||
Instanciate a LinphoneCore object given the LinphoneCoreVTable
|
||||
*/
|
||||
lc=linphone_core_new(&vtable,NULL,NULL,NULL);
|
||||
|
||||
if (dest){
|
||||
/*
|
||||
Place an outgoing call
|
||||
*/
|
||||
call=linphone_core_invite(lc,dest);
|
||||
if (call==NULL){
|
||||
printf("Could not place call to %s\n",dest);
|
||||
goto end;
|
||||
}else printf("Call to %s is in progress...",dest);
|
||||
linphone_call_ref(call);
|
||||
}
|
||||
/* main loop for receiving notifications and doing background linphonecore work: */
|
||||
while(running){
|
||||
linphone_core_iterate(lc);
|
||||
ms_usleep(50000);
|
||||
}
|
||||
if (call && linphone_call_get_state(call)!=LinphoneCallEnd){
|
||||
/* terminate the call */
|
||||
printf("Terminating the call...\n");
|
||||
linphone_core_terminate_call(lc,call);
|
||||
/*at this stage we don't need the call object */
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
|
||||
end:
|
||||
printf("Shutting down...\n");
|
||||
linphone_core_destroy(lc);
|
||||
printf("Exited\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
TutorialBuddyStatus
|
||||
Copyright (C) 2010 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core.tutorials;
|
||||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.core.OnlineStatus;
|
||||
import org.linphone.core.LinphoneCall.State;
|
||||
import org.linphone.core.LinphoneCore.GlobalState;
|
||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||
import org.linphone.core.LinphoneFriend.SubscribePolicy;
|
||||
|
||||
/**
|
||||
*
|
||||
* This program is a _very_ simple usage example of liblinphone,
|
||||
* demonstrating how to initiate SIP subscriptions and receive notifications
|
||||
* from a sip uri identity passed from the command line.
|
||||
* <br>Argument must be like sip:jehan@sip.linphone.org .
|
||||
* ex budy_list sip:jehan@sip.linphone.org
|
||||
* <br>Subscription is cleared on SIGINT
|
||||
*
|
||||
* Ported from buddy_status.c
|
||||
*
|
||||
* @author Guillaume Beraudo
|
||||
*
|
||||
*/
|
||||
public class TutorialBuddyStatus implements LinphoneCoreListener {
|
||||
|
||||
private boolean running;
|
||||
private TutorialNotifier TutorialNotifier;
|
||||
|
||||
|
||||
public TutorialBuddyStatus(TutorialNotifier TutorialNotifier) {
|
||||
this.TutorialNotifier = TutorialNotifier;
|
||||
}
|
||||
|
||||
public TutorialBuddyStatus() {
|
||||
this.TutorialNotifier = new TutorialNotifier();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,String url) {
|
||||
write("["+lf.getAddress().getUserName()+"] wants to see your status, accepting");
|
||||
lf.edit(); // start editing friend
|
||||
lf.setIncSubscribePolicy(SubscribePolicy.SPAccept); // accept incoming subscription request for this friend
|
||||
lf.done(); // commit change
|
||||
try {
|
||||
// add this new friend to the buddy list
|
||||
lc.addFriend(lf);
|
||||
} catch (LinphoneCoreException e) {
|
||||
write("Error while adding friend [" + lf.getAddress().getUserName() + "] to linphone in the callback");
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {
|
||||
write("New state [" + lf.getStatus() +"] for user id ["+lf.getAddress().getUserName()+"]");
|
||||
}
|
||||
|
||||
|
||||
public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg,RegistrationState cstate, String smessage) {}
|
||||
public void show(LinphoneCore lc) {}
|
||||
public void byeReceived(LinphoneCore lc, String from) {}
|
||||
public void authInfoRequested(LinphoneCore lc, String realm, String username) {}
|
||||
public void displayStatus(LinphoneCore lc, String message) {}
|
||||
public void displayMessage(LinphoneCore lc, String message) {}
|
||||
public void displayWarning(LinphoneCore lc, String message) {}
|
||||
public void globalState(LinphoneCore lc, GlobalState state, String message) {}
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Check tutorial was called with the right number of arguments
|
||||
if (args.length != 1) {
|
||||
throw new IllegalArgumentException("Bad number of arguments");
|
||||
}
|
||||
|
||||
// Create tutorial object
|
||||
TutorialBuddyStatus tutorial = new TutorialBuddyStatus();
|
||||
try {
|
||||
// takes sip uri identity from the command line arguments
|
||||
String userSipAddress = args[1];
|
||||
tutorial.launchTutorial(userSipAddress);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void launchTutorial(String sipAddress) throws LinphoneCoreException {
|
||||
final LinphoneCoreFactory lcFactory = LinphoneCoreFactory.instance();
|
||||
|
||||
// First instantiate the core Linphone object given only a listener.
|
||||
// The listener will react to events in Linphone core.
|
||||
LinphoneCore lc = lcFactory.createLinphoneCore(this);
|
||||
|
||||
|
||||
try {
|
||||
|
||||
// Create friend object from string address
|
||||
LinphoneFriend lf = lcFactory.createLinphoneFriend(sipAddress);
|
||||
if (lf == null) {
|
||||
write("Could not create friend; weird SIP address?");
|
||||
return;
|
||||
}
|
||||
|
||||
// configure this friend to emit SUBSCRIBE message after being added to LinphoneCore
|
||||
lf.enableSubscribes(true);
|
||||
|
||||
// accept incoming subscription request for this friend
|
||||
lf.setIncSubscribePolicy(SubscribePolicy.SPAccept);
|
||||
try {
|
||||
// add my friend to the buddy list, initiate SUBSCRIBE message
|
||||
lc.addFriend(lf);
|
||||
} catch (LinphoneCoreException e) {
|
||||
write("Error while adding friend " + lf.getAddress().getUserName() + " to linphone");
|
||||
return;
|
||||
}
|
||||
|
||||
// set my status to online
|
||||
lc.setPresenceInfo(0, null, OnlineStatus.Online);
|
||||
|
||||
|
||||
// main loop for receiving notifications and doing background linphonecore work
|
||||
running = true;
|
||||
while (running) {
|
||||
lc.iterate(); // first iterate initiates subscription
|
||||
try{
|
||||
Thread.sleep(50);
|
||||
} catch(InterruptedException ie) {
|
||||
write("Interrupted!\nAborting");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// change my presence status to offline
|
||||
lc.setPresenceInfo(0, null, OnlineStatus.Offline);
|
||||
// just to make sure new status is initiate message is issued
|
||||
lc.iterate();
|
||||
|
||||
|
||||
lf.edit(); // start editing friend
|
||||
lf.enableSubscribes(false); // disable subscription for this friend
|
||||
lf.done(); // commit changes triggering an UNSUBSCRIBE message
|
||||
lc.iterate(); // just to make sure unsubscribe message is issued
|
||||
|
||||
|
||||
} finally {
|
||||
write("Shutting down...");
|
||||
// You need to destroy the LinphoneCore object when no longer used
|
||||
lc.destroy();
|
||||
write("Exited");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stopMainLoop() {
|
||||
running=false;
|
||||
}
|
||||
|
||||
|
||||
private void write(String s) {
|
||||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
TutorialChatRoom.java
|
||||
Copyright (C) 2010 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core.tutorials;
|
||||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.core.LinphoneCall.State;
|
||||
import org.linphone.core.LinphoneCore.GlobalState;
|
||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||
|
||||
|
||||
/**
|
||||
* This program is a _very_ simple usage example of liblinphone.
|
||||
* It demonstrates how to send/receive SIP MESSAGE from a sip uri identity
|
||||
* passed from the command line.
|
||||
*
|
||||
* Argument must be like sip:jehan@sip.linphone.org .
|
||||
*
|
||||
* ex chatroom sip:jehan@sip.linphone.org
|
||||
* just takes a sip-uri as first argument and attempts to call it.
|
||||
*
|
||||
* Ported from chatroom.c
|
||||
*
|
||||
* @author Guillaume Beraudo
|
||||
*
|
||||
*/
|
||||
public class TutorialChatRoom implements LinphoneCoreListener {
|
||||
private boolean running;
|
||||
private TutorialNotifier TutorialNotifier;
|
||||
|
||||
|
||||
public TutorialChatRoom(TutorialNotifier TutorialNotifier) {
|
||||
this.TutorialNotifier = TutorialNotifier;
|
||||
}
|
||||
|
||||
public TutorialChatRoom() {
|
||||
this.TutorialNotifier = new TutorialNotifier();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void show(LinphoneCore lc) {}
|
||||
public void byeReceived(LinphoneCore lc, String from) {}
|
||||
public void authInfoRequested(LinphoneCore lc, String realm, String username) {}
|
||||
public void displayStatus(LinphoneCore lc, String message) {}
|
||||
public void displayMessage(LinphoneCore lc, String message) {}
|
||||
public void displayWarning(LinphoneCore lc, String message) {}
|
||||
public void globalState(LinphoneCore lc, GlobalState state, String message) {}
|
||||
public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg,RegistrationState cstate, String smessage) {}
|
||||
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,String url) {}
|
||||
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg){}
|
||||
|
||||
|
||||
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {
|
||||
write("Message ["+message+"] received from ["+from.asString()+"]");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Check tutorial was called with the right number of arguments
|
||||
// Takes the sip uri identity from the command line arguments
|
||||
if (args.length != 1) {
|
||||
throw new IllegalArgumentException("Bad number of arguments");
|
||||
}
|
||||
|
||||
// Create tutorial object
|
||||
TutorialChatRoom tutorial = new TutorialChatRoom();
|
||||
try {
|
||||
String destinationSipAddress = args[1];
|
||||
tutorial.launchTutorial(destinationSipAddress);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void launchTutorial(String destinationSipAddress) throws LinphoneCoreException {
|
||||
|
||||
// First instantiate the core Linphone object given only a listener.
|
||||
// The listener will react to events in Linphone core.
|
||||
LinphoneCore lc = LinphoneCoreFactory.instance().createLinphoneCore(this);
|
||||
|
||||
try {
|
||||
// Next step is to create a chat room
|
||||
LinphoneChatRoom chatRoom = lc.createChatRoom(destinationSipAddress);
|
||||
|
||||
// Send message
|
||||
chatRoom.sendMessage("Hello world");
|
||||
|
||||
// main loop for receiving notifications and doing background linphonecore work
|
||||
running = true;
|
||||
while (running) {
|
||||
lc.iterate();
|
||||
try{
|
||||
Thread.sleep(50);
|
||||
} catch(InterruptedException ie) {
|
||||
write("Interrupted!\nAborting");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
write("Shutting down...");
|
||||
// You need to destroy the LinphoneCore object when no longer used
|
||||
lc.destroy();
|
||||
write("Exited");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stopMainLoop() {
|
||||
running=false;
|
||||
}
|
||||
|
||||
|
||||
private void write(String s) {
|
||||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
TutorialHelloWorld.java
|
||||
Copyright (C) 2010 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core.tutorials;
|
||||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.core.LinphoneCall.State;
|
||||
import org.linphone.core.LinphoneCore.GlobalState;
|
||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||
|
||||
|
||||
/**
|
||||
* This program is a _very_ simple usage example of liblinphone.
|
||||
* It just takes a sip-uri as first argument and attempts to call it.
|
||||
*
|
||||
* Ported from helloworld.c
|
||||
*
|
||||
* @author Guillaume Beraudo
|
||||
*
|
||||
*/
|
||||
public class TutorialHelloWorld implements LinphoneCoreListener {
|
||||
private boolean running;
|
||||
private TutorialNotifier TutorialNotifier;
|
||||
|
||||
|
||||
public TutorialHelloWorld(TutorialNotifier TutorialNotifier) {
|
||||
this.TutorialNotifier = TutorialNotifier;
|
||||
}
|
||||
|
||||
public TutorialHelloWorld() {
|
||||
this.TutorialNotifier = new TutorialNotifier();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void show(LinphoneCore lc) {}
|
||||
public void byeReceived(LinphoneCore lc, String from) {}
|
||||
public void authInfoRequested(LinphoneCore lc, String realm, String username) {}
|
||||
public void displayStatus(LinphoneCore lc, String message) {}
|
||||
public void displayMessage(LinphoneCore lc, String message) {}
|
||||
public void displayWarning(LinphoneCore lc, String message) {}
|
||||
public void globalState(LinphoneCore lc, GlobalState state, String message) {}
|
||||
public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg,RegistrationState cstate, String smessage) {}
|
||||
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,String url) {}
|
||||
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
|
||||
|
||||
/*
|
||||
* Call state notification listener
|
||||
*/
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg){
|
||||
write("State: " + msg);
|
||||
|
||||
if (State.CallEnd.equals(cstate))
|
||||
running = false;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Check tutorial was called with the right number of arguments
|
||||
if (args.length != 1) {
|
||||
throw new IllegalArgumentException("Bad number of arguments");
|
||||
}
|
||||
|
||||
// Create tutorial object
|
||||
TutorialHelloWorld helloWorld = new TutorialHelloWorld();
|
||||
try {
|
||||
String destinationSipAddress = args[1];
|
||||
helloWorld.launchTutorial(destinationSipAddress);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void launchTutorial(String destinationSipAddress) throws LinphoneCoreException {
|
||||
|
||||
// First instantiate the core Linphone object given only a listener.
|
||||
// The listener will react to events in Linphone core.
|
||||
LinphoneCore lc = LinphoneCoreFactory.instance().createLinphoneCore(this);
|
||||
|
||||
|
||||
|
||||
try {
|
||||
// Send the INVITE message to destination SIP address
|
||||
LinphoneCall call = lc.invite(destinationSipAddress);
|
||||
if (call == null) {
|
||||
write("Could not place call to " + destinationSipAddress);
|
||||
write("Aborting");
|
||||
return;
|
||||
}
|
||||
write("Call to " + destinationSipAddress + " is in progress...");
|
||||
|
||||
|
||||
|
||||
// main loop for receiving notifications and doing background linphonecore work
|
||||
running = true;
|
||||
while (running) {
|
||||
lc.iterate();
|
||||
try{
|
||||
Thread.sleep(50);
|
||||
} catch(InterruptedException ie) {
|
||||
write("Interrupted!\nAborting");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!State.CallEnd.equals(call.getState())) {
|
||||
write("Terminating the call");
|
||||
lc.terminateCall(call);
|
||||
}
|
||||
} finally {
|
||||
write("Shutting down...");
|
||||
// You need to destroy the LinphoneCore object when no longer used
|
||||
lc.destroy();
|
||||
write("Exited");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stopMainLoop() {
|
||||
running=false;
|
||||
}
|
||||
|
||||
|
||||
private void write(String s) {
|
||||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
TutorialNotifier.java
|
||||
Copyright (C) 2010 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core.tutorials;
|
||||
|
||||
/**
|
||||
* Notify to the standard output.
|
||||
* Subclass to define another text output.
|
||||
*
|
||||
* @author Guillaume Beraudo
|
||||
*
|
||||
*/
|
||||
public class TutorialNotifier {
|
||||
|
||||
public void notify(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
TutorialRegistration.java
|
||||
Copyright (C) 2010 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core.tutorials;
|
||||
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.core.LinphoneCall.State;
|
||||
import org.linphone.core.LinphoneCore.GlobalState;
|
||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||
|
||||
|
||||
/**
|
||||
* This program is a _very_ simple usage example of liblinphone.
|
||||
* Demonstrating how to initiate a SIP registration from a sip uri identity
|
||||
* passed from the command line.
|
||||
*
|
||||
* First argument must be like sip:jehan@sip.linphone.org, second must be password.
|
||||
* <br>
|
||||
* ex registration sip:jehan@sip.linphone.org secret
|
||||
*
|
||||
* Ported from registration.c
|
||||
*
|
||||
* @author Guillaume Beraudo
|
||||
*
|
||||
*/
|
||||
public class TutorialRegistration implements LinphoneCoreListener {
|
||||
private boolean running;
|
||||
private TutorialNotifier TutorialNotifier;
|
||||
|
||||
|
||||
public TutorialRegistration(TutorialNotifier TutorialNotifier) {
|
||||
this.TutorialNotifier = TutorialNotifier;
|
||||
}
|
||||
|
||||
public TutorialRegistration() {
|
||||
this.TutorialNotifier = new TutorialNotifier();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Registration state notification listener
|
||||
*/
|
||||
public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg,RegistrationState cstate, String smessage) {
|
||||
write(cfg.getIdentity() + " : "+smessage+"\n");
|
||||
|
||||
if (RegistrationState.RegistrationOk.equals(cstate))
|
||||
running = false;
|
||||
}
|
||||
|
||||
public void show(LinphoneCore lc) {}
|
||||
public void byeReceived(LinphoneCore lc, String from) {}
|
||||
public void authInfoRequested(LinphoneCore lc, String realm, String username) {}
|
||||
public void displayStatus(LinphoneCore lc, String message) {}
|
||||
public void displayMessage(LinphoneCore lc, String message) {}
|
||||
public void displayWarning(LinphoneCore lc, String message) {}
|
||||
public void globalState(LinphoneCore lc, GlobalState state, String message) {}
|
||||
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,String url) {}
|
||||
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Check tutorial was called with the right number of arguments
|
||||
if (args.length != 2) {
|
||||
throw new IllegalArgumentException("Bad number of arguments");
|
||||
}
|
||||
|
||||
// Create tutorial object
|
||||
TutorialRegistration tutorial = new TutorialRegistration();
|
||||
try {
|
||||
// takes sip uri identity from the command line arguments
|
||||
String userSipAddress = args[1];
|
||||
// takes password from the command line arguments
|
||||
String userSipPassword = args[2];
|
||||
tutorial.launchTutorial(userSipAddress, userSipPassword);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void launchTutorial(String sipAddress, String password) throws LinphoneCoreException {
|
||||
final LinphoneCoreFactory lcFactory = LinphoneCoreFactory.instance();
|
||||
|
||||
// First instantiate the core Linphone object given only a listener.
|
||||
// The listener will react to events in Linphone core.
|
||||
LinphoneCore lc = lcFactory.createLinphoneCore(this);
|
||||
|
||||
|
||||
try {
|
||||
|
||||
// Parse identity
|
||||
LinphoneAddress address = lcFactory.createLinphoneAddress(sipAddress);
|
||||
String username = address.getUserName();
|
||||
String domain = address.getDomain();
|
||||
|
||||
|
||||
if (password != null) {
|
||||
// create authentication structure from identity and add to linphone
|
||||
lc.addAuthInfo(lcFactory.createAuthInfo(username, password, null));
|
||||
}
|
||||
|
||||
// create proxy config
|
||||
LinphoneProxyConfig proxyCfg = lcFactory.createProxyConfig(sipAddress, domain, null, true);
|
||||
lc.addProxyConfig(proxyCfg); // add it to linphone
|
||||
lc.setDefaultProxyConfig(proxyCfg);
|
||||
|
||||
|
||||
|
||||
|
||||
// main loop for receiving notifications and doing background linphonecore work
|
||||
running = true;
|
||||
while (running) {
|
||||
lc.iterate(); // first iterate initiates registration
|
||||
try{
|
||||
Thread.sleep(50);
|
||||
} catch(InterruptedException ie) {
|
||||
write("Interrupted!\nAborting");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Automatic unregistration on exit
|
||||
|
||||
|
||||
} finally {
|
||||
write("Shutting down...");
|
||||
// You need to destroy the LinphoneCore object when no longer used
|
||||
lc.destroy();
|
||||
write("Exited");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stopMainLoop() {
|
||||
running=false;
|
||||
}
|
||||
|
||||
|
||||
private void write(String s) {
|
||||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
}
|
||||
142
coreapi/help/registration.c
Normal file
142
coreapi/help/registration.c
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
|
||||
/*
|
||||
linphone
|
||||
Copyright (C) 2010 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup registration_tutorials Basic registration
|
||||
* @ingroup tutorials
|
||||
*This program is a _very_ simple usage example of liblinphone.
|
||||
*Desmonstrating how to initiate a SIP registration from a sip uri identity passed from the command line.
|
||||
*first argument must be like sip:jehan@sip.linphone.org , second must be password .
|
||||
*<br>
|
||||
*ex registration sip:jehan@sip.linphone.org secret
|
||||
*<br>Registration is cleared on SIGINT
|
||||
*<br>
|
||||
*@include registration.c
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef IN_LINPHONE
|
||||
#include "linphonecore.h"
|
||||
#else
|
||||
#include "linphone/linphonecore.h"
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
static bool_t running=TRUE;
|
||||
|
||||
static void stop(int signum){
|
||||
running=FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registration state notification callback
|
||||
*/
|
||||
static void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){
|
||||
printf("New registration state %s for user id [%s] at proxy [%s]\n"
|
||||
,linphone_registration_state_to_string(cstate)
|
||||
,linphone_proxy_config_get_identity(cfg)
|
||||
,linphone_proxy_config_get_addr(cfg));
|
||||
}
|
||||
|
||||
LinphoneCore *lc;
|
||||
int main(int argc, char *argv[]){
|
||||
LinphoneCoreVTable vtable={0};
|
||||
|
||||
char* identity=NULL;
|
||||
char* password=NULL;
|
||||
|
||||
/* takes sip uri identity from the command line arguments */
|
||||
if (argc>1){
|
||||
identity=argv[1];
|
||||
}
|
||||
|
||||
/* takes password from the command line arguments */
|
||||
if (argc>2){
|
||||
password=argv[2];
|
||||
}
|
||||
|
||||
signal(SIGINT,stop);
|
||||
|
||||
#ifdef DEBUG
|
||||
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
|
||||
#endif
|
||||
/*
|
||||
Fill the LinphoneCoreVTable with application callbacks.
|
||||
All are optional. Here we only use the registration_state_changed callbacks
|
||||
in order to get notifications about the progress of the registration.
|
||||
*/
|
||||
vtable.registration_state_changed=registration_state_changed;
|
||||
|
||||
/*
|
||||
Instanciate a LinphoneCore object given the LinphoneCoreVTable
|
||||
*/
|
||||
lc=linphone_core_new(&vtable,NULL,NULL,NULL);
|
||||
|
||||
LinphoneProxyConfig* proxy_cfg;
|
||||
/*create proxy config*/
|
||||
proxy_cfg = linphone_proxy_config_new();
|
||||
/*parse identity*/
|
||||
LinphoneAddress *from = linphone_address_new(identity);
|
||||
if (from==NULL){
|
||||
printf("%s not a valid sip uri, must be like sip:toto@sip.linphone.org \n",identity);
|
||||
goto end;
|
||||
}
|
||||
LinphoneAuthInfo *info;
|
||||
if (password!=NULL){
|
||||
info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL); /*create authentication structure from identity*/
|
||||
linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
|
||||
}
|
||||
|
||||
// configure proxy entries
|
||||
linphone_proxy_config_set_identity(proxy_cfg,identity); /*set identity with user name and domain*/
|
||||
const char* server_addr = linphone_address_get_domain(from); /*extract domain address from identity*/
|
||||
linphone_proxy_config_set_server_addr(proxy_cfg,server_addr); /* we assume domain = proxy server address*/
|
||||
linphone_proxy_config_enable_register(proxy_cfg,TRUE); /*activate registration for this proxy config*/
|
||||
linphone_address_destroy(from); /*release resource*/
|
||||
|
||||
linphone_core_add_proxy_config(lc,proxy_cfg); /*add proxy config to linphone core*/
|
||||
linphone_core_set_default_proxy(lc,proxy_cfg); /*set to default proxy*/
|
||||
|
||||
|
||||
/* main loop for receiving notifications and doing background linphonecore work: */
|
||||
while(running){
|
||||
linphone_core_iterate(lc); /* first iterate initiates registration */
|
||||
ms_usleep(50000);
|
||||
}
|
||||
|
||||
linphone_core_get_default_proxy(lc,&proxy_cfg); /* get default proxy config*/
|
||||
linphone_proxy_config_edit(proxy_cfg); /*start editing proxy configuration*/
|
||||
linphone_proxy_config_enable_register(proxy_cfg,FALSE); /*de-activate registration for this proxy config*/
|
||||
linphone_proxy_config_done(proxy_cfg); /*initiate REGISTER with expire = 0*/
|
||||
|
||||
while(linphone_proxy_config_get_state(proxy_cfg) != LinphoneRegistrationCleared){
|
||||
linphone_core_iterate(lc); /*to make sure we receive call backs before shutting down*/
|
||||
ms_usleep(50000);
|
||||
}
|
||||
|
||||
end:
|
||||
printf("Shutting down...\n");
|
||||
linphone_core_destroy(lc);
|
||||
printf("Exited\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
955
coreapi/linphonecall.c
Normal file
955
coreapi/linphonecall.c
Normal file
|
|
@ -0,0 +1,955 @@
|
|||
|
||||
/*
|
||||
linphone
|
||||
Copyright (C) 2010 Belledonne Communications SARL
|
||||
(simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifdef WIN32
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include "linphonecore.h"
|
||||
#include "sipsetup.h"
|
||||
#include "lpconfig.h"
|
||||
#include "private.h"
|
||||
|
||||
|
||||
#include "mediastreamer2/mediastream.h"
|
||||
#include "mediastreamer2/msvolume.h"
|
||||
#include "mediastreamer2/msequalizer.h"
|
||||
#include "mediastreamer2/msfileplayer.h"
|
||||
#include "mediastreamer2/msjpegwriter.h"
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
static MSWebCam *get_nowebcam_device(){
|
||||
return ms_web_cam_manager_get_cam(ms_web_cam_manager_get(),"StaticImage: Static picture");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit){
|
||||
MSList *l=NULL;
|
||||
const MSList *it;
|
||||
for(it=codecs;it!=NULL;it=it->next){
|
||||
PayloadType *pt=(PayloadType*)it->data;
|
||||
if (pt->flags & PAYLOAD_TYPE_ENABLED){
|
||||
if (bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,bandwidth_limit)){
|
||||
ms_message("Codec %s/%i eliminated because of audio bandwidth constraint.",pt->mime_type,pt->clock_rate);
|
||||
continue;
|
||||
}
|
||||
if (linphone_core_check_payload_type_usability(lc,pt)){
|
||||
l=ms_list_append(l,payload_type_clone(pt));
|
||||
}
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call){
|
||||
MSList *l;
|
||||
PayloadType *pt;
|
||||
const char *me=linphone_core_get_identity(lc);
|
||||
LinphoneAddress *addr=linphone_address_new(me);
|
||||
const char *username=linphone_address_get_username (addr);
|
||||
SalMediaDescription *md=sal_media_description_new();
|
||||
|
||||
md->nstreams=1;
|
||||
strncpy(md->addr,call->localip,sizeof(md->addr));
|
||||
strncpy(md->username,username,sizeof(md->username));
|
||||
md->bandwidth=linphone_core_get_download_bandwidth(lc);
|
||||
/*set audio capabilities */
|
||||
strncpy(md->streams[0].addr,call->localip,sizeof(md->streams[0].addr));
|
||||
md->streams[0].port=call->audio_port;
|
||||
md->streams[0].proto=SalProtoRtpAvp;
|
||||
md->streams[0].type=SalAudio;
|
||||
md->streams[0].ptime=lc->net_conf.down_ptime;
|
||||
l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params.audio_bw);
|
||||
pt=payload_type_clone(rtp_profile_get_payload_from_mime(&av_profile,"telephone-event"));
|
||||
l=ms_list_append(l,pt);
|
||||
md->streams[0].payloads=l;
|
||||
|
||||
if (lc->dw_audio_bw>0)
|
||||
md->streams[0].bandwidth=lc->dw_audio_bw;
|
||||
|
||||
if (call->params.has_video){
|
||||
md->nstreams++;
|
||||
md->streams[1].port=call->video_port;
|
||||
md->streams[1].proto=SalProtoRtpAvp;
|
||||
md->streams[1].type=SalVideo;
|
||||
l=make_codec_list(lc,lc->codecs_conf.video_codecs,0);
|
||||
md->streams[1].payloads=l;
|
||||
if (lc->dw_video_bw)
|
||||
md->streams[1].bandwidth=lc->dw_video_bw;
|
||||
}
|
||||
linphone_address_destroy(addr);
|
||||
return md;
|
||||
}
|
||||
|
||||
static int find_port_offset(LinphoneCore *lc){
|
||||
int offset;
|
||||
MSList *elem;
|
||||
int audio_port;
|
||||
bool_t already_used=FALSE;
|
||||
for(offset=0;offset<100;offset+=2){
|
||||
audio_port=linphone_core_get_audio_port (lc)+offset;
|
||||
already_used=FALSE;
|
||||
for(elem=lc->calls;elem!=NULL;elem=elem->next){
|
||||
LinphoneCall *call=(LinphoneCall*)elem->data;
|
||||
if (call->audio_port==audio_port) {
|
||||
already_used=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!already_used) break;
|
||||
}
|
||||
if (offset==100){
|
||||
ms_error("Could not find any free port !");
|
||||
return -1;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){
|
||||
int port_offset;
|
||||
call->refcnt=1;
|
||||
call->state=LinphoneCallIdle;
|
||||
call->start_time=time(NULL);
|
||||
call->media_start_time=0;
|
||||
call->log=linphone_call_log_new(call, from, to);
|
||||
linphone_core_notify_all_friends(call->core,LinphoneStatusOnThePhone);
|
||||
port_offset=find_port_offset (call->core);
|
||||
if (port_offset==-1) return;
|
||||
call->audio_port=linphone_core_get_audio_port(call->core)+port_offset;
|
||||
call->video_port=linphone_core_get_video_port(call->core)+port_offset;
|
||||
|
||||
}
|
||||
|
||||
static void discover_mtu(LinphoneCore *lc, const char *remote){
|
||||
int mtu;
|
||||
if (lc->net_conf.mtu==0 ){
|
||||
/*attempt to discover mtu*/
|
||||
mtu=ms_discover_mtu(remote);
|
||||
if (mtu>0){
|
||||
ms_set_mtu(mtu);
|
||||
ms_message("Discovered mtu is %i, RTP payload max size is %i",
|
||||
mtu, ms_get_payload_max_size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params)
|
||||
{
|
||||
LinphoneCall *call=ms_new0(LinphoneCall,1);
|
||||
call->dir=LinphoneCallOutgoing;
|
||||
call->op=sal_op_new(lc->sal);
|
||||
sal_op_set_user_pointer(call->op,call);
|
||||
call->core=lc;
|
||||
linphone_core_get_local_ip(lc,linphone_address_get_domain(to),call->localip);
|
||||
linphone_call_init_common(call,from,to);
|
||||
call->params=*params;
|
||||
call->localdesc=create_local_media_description (lc,call);
|
||||
call->camera_active=params->has_video;
|
||||
if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun)
|
||||
linphone_core_run_stun_tests(call->core,call);
|
||||
discover_mtu(lc,linphone_address_get_domain (to));
|
||||
if (params->referer){
|
||||
sal_call_set_referer (call->op,params->referer->op);
|
||||
}
|
||||
return call;
|
||||
}
|
||||
|
||||
LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){
|
||||
LinphoneCall *call=ms_new0(LinphoneCall,1);
|
||||
char *to_str;
|
||||
char *from_str;
|
||||
|
||||
call->dir=LinphoneCallIncoming;
|
||||
sal_op_set_user_pointer(op,call);
|
||||
call->op=op;
|
||||
call->core=lc;
|
||||
|
||||
if (lc->sip_conf.ping_with_options){
|
||||
/*the following sends an option request back to the caller so that
|
||||
we get a chance to discover our nat'd address before answering.*/
|
||||
call->ping_op=sal_op_new(lc->sal);
|
||||
to_str=linphone_address_as_string(to);
|
||||
from_str=linphone_address_as_string(from);
|
||||
sal_op_set_route(call->ping_op,sal_op_get_network_origin(call->op));
|
||||
sal_op_set_user_pointer(call->ping_op,call);
|
||||
sal_ping(call->ping_op,to_str,from_str);
|
||||
ms_free(to_str);
|
||||
ms_free(from_str);
|
||||
}
|
||||
|
||||
linphone_address_clean(from);
|
||||
linphone_core_get_local_ip(lc,linphone_address_get_domain(from),call->localip);
|
||||
linphone_call_init_common(call, from, to);
|
||||
call->params.has_video=linphone_core_video_enabled(lc);
|
||||
call->localdesc=create_local_media_description (lc,call);
|
||||
call->camera_active=call->params.has_video;
|
||||
if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun)
|
||||
linphone_core_run_stun_tests(call->core,call);
|
||||
discover_mtu(lc,linphone_address_get_domain(from));
|
||||
return call;
|
||||
}
|
||||
|
||||
/* this function is called internally to get rid of a call.
|
||||
It performs the following tasks:
|
||||
- remove the call from the internal list of calls
|
||||
- unref the LinphoneCall object
|
||||
- update the call logs accordingly
|
||||
*/
|
||||
|
||||
static void linphone_call_set_terminated(LinphoneCall *call){
|
||||
LinphoneCallStatus status=LinphoneCallAborted;
|
||||
LinphoneCore *lc=call->core;
|
||||
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
if (call->state==LinphoneCallEnd){
|
||||
if (call->reason==LinphoneReasonDeclined){
|
||||
status=LinphoneCallDeclined;
|
||||
}
|
||||
else status=LinphoneCallSuccess;
|
||||
|
||||
}
|
||||
linphone_call_log_completed(call->log,call, status);
|
||||
|
||||
if (call == lc->current_call){
|
||||
ms_message("Resetting the current call");
|
||||
lc->current_call=NULL;
|
||||
}
|
||||
|
||||
if (linphone_core_del_call(lc,call) != 0){
|
||||
ms_error("Could not remove the call from the list !!!");
|
||||
}
|
||||
|
||||
if (ms_list_size(lc->calls)==0)
|
||||
linphone_core_notify_all_friends(lc,lc->presence_mode);
|
||||
|
||||
if (call->op!=NULL) {
|
||||
/* so that we cannot have anymore upcalls for SAL
|
||||
concerning this call*/
|
||||
sal_op_release(call->op);
|
||||
call->op=NULL;
|
||||
}
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
|
||||
const char *linphone_call_state_to_string(LinphoneCallState cs){
|
||||
switch (cs){
|
||||
case LinphoneCallIdle:
|
||||
return "LinphoneCallIdle";
|
||||
case LinphoneCallIncomingReceived:
|
||||
return "LinphoneCallIncomingReceived";
|
||||
case LinphoneCallOutgoingInit:
|
||||
return "LinphoneCallOutgoingInit";
|
||||
case LinphoneCallOutgoingProgress:
|
||||
return "LinphoneCallOutgoingProgress";
|
||||
case LinphoneCallOutgoingRinging:
|
||||
return "LinphoneCallOutgoingRinging";
|
||||
case LinphoneCallOutgoingEarlyMedia:
|
||||
return "LinphoneCallOutgoingEarlyMedia";
|
||||
case LinphoneCallConnected:
|
||||
return "LinphoneCallConnected";
|
||||
case LinphoneCallStreamsRunning:
|
||||
return "LinphoneCallStreamsRunning";
|
||||
case LinphoneCallPausing:
|
||||
return "LinphoneCallPausing";
|
||||
case LinphoneCallPaused:
|
||||
return "LinphoneCallPaused";
|
||||
case LinphoneCallResuming:
|
||||
return "LinphoneCallResuming";
|
||||
case LinphoneCallRefered:
|
||||
return "LinphoneCallRefered";
|
||||
case LinphoneCallError:
|
||||
return "LinphoneCallError";
|
||||
case LinphoneCallEnd:
|
||||
return "LinphoneCallEnd";
|
||||
case LinphoneCallPausedByRemote:
|
||||
return "LinphoneCallPausedByRemote";
|
||||
case LinphoneCallUpdatedByRemote:
|
||||
return "LinphoneCallUpdatedByRemote";
|
||||
case LinphoneCallIncomingEarlyMedia:
|
||||
return "LinphoneCallIncomingEarlyMedia";
|
||||
case LinphoneCallUpdated:
|
||||
return "LinphoneCallUpdated";
|
||||
}
|
||||
return "undefined state";
|
||||
}
|
||||
|
||||
void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message){
|
||||
LinphoneCore *lc=call->core;
|
||||
bool_t finalize_call=FALSE;
|
||||
if (call->state!=cstate){
|
||||
ms_message("Call %p: moving from state %s to %s",call,linphone_call_state_to_string(call->state),
|
||||
linphone_call_state_to_string(cstate));
|
||||
if (cstate!=LinphoneCallRefered){
|
||||
/*LinphoneCallRefered is rather an event, not a state.
|
||||
Indeed it does not change the state of the call (still paused or running)*/
|
||||
call->state=cstate;
|
||||
}
|
||||
if (cstate==LinphoneCallEnd || cstate==LinphoneCallError){
|
||||
finalize_call=TRUE;
|
||||
linphone_call_ref(call);
|
||||
linphone_call_set_terminated (call);
|
||||
}
|
||||
if (lc->vtable.call_state_changed)
|
||||
lc->vtable.call_state_changed(lc,call,cstate,message);
|
||||
if (finalize_call)
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_call_destroy(LinphoneCall *obj)
|
||||
{
|
||||
if (obj->op!=NULL) {
|
||||
sal_op_release(obj->op);
|
||||
obj->op=NULL;
|
||||
}
|
||||
if (obj->resultdesc!=NULL) {
|
||||
sal_media_description_unref(obj->resultdesc);
|
||||
obj->resultdesc=NULL;
|
||||
}
|
||||
if (obj->localdesc!=NULL) {
|
||||
sal_media_description_unref(obj->localdesc);
|
||||
obj->localdesc=NULL;
|
||||
}
|
||||
if (obj->ping_op) {
|
||||
sal_op_release(obj->ping_op);
|
||||
}
|
||||
if (obj->refer_to){
|
||||
ms_free(obj->refer_to);
|
||||
}
|
||||
ms_free(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup call_control
|
||||
* @{
|
||||
**/
|
||||
|
||||
/**
|
||||
* Increments the call 's reference count.
|
||||
* An application that wishes to retain a pointer to call object
|
||||
* must use this function to unsure the pointer remains
|
||||
* valid. Once the application no more needs this pointer,
|
||||
* it must call linphone_call_unref().
|
||||
**/
|
||||
void linphone_call_ref(LinphoneCall *obj){
|
||||
obj->refcnt++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements the call object reference count.
|
||||
* See linphone_call_ref().
|
||||
**/
|
||||
void linphone_call_unref(LinphoneCall *obj){
|
||||
obj->refcnt--;
|
||||
if (obj->refcnt==0){
|
||||
linphone_call_destroy(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current parameters associated to the call.
|
||||
**/
|
||||
const LinphoneCallParams * linphone_call_get_current_params(const LinphoneCall *call){
|
||||
return &call->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remote address associated to this call
|
||||
*
|
||||
**/
|
||||
const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call){
|
||||
return call->dir==LinphoneCallIncoming ? call->log->from : call->log->to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remote address associated to this call as a string.
|
||||
*
|
||||
* The result string must be freed by user using ms_free().
|
||||
**/
|
||||
char *linphone_call_get_remote_address_as_string(const LinphoneCall *call){
|
||||
return linphone_address_as_string(linphone_call_get_remote_address(call));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the call's current state.
|
||||
**/
|
||||
LinphoneCallState linphone_call_get_state(const LinphoneCall *call){
|
||||
return call->state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reason for a call termination (either error or normal termination)
|
||||
**/
|
||||
LinphoneReason linphone_call_get_reason(const LinphoneCall *call){
|
||||
return call->reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user_pointer in the LinphoneCall
|
||||
*
|
||||
* @ingroup call_control
|
||||
*
|
||||
* return user_pointer an opaque user pointer that can be retrieved at any time
|
||||
**/
|
||||
void *linphone_call_get_user_pointer(LinphoneCall *call)
|
||||
{
|
||||
return call->user_pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user_pointer in the LinphoneCall
|
||||
*
|
||||
* @ingroup call_control
|
||||
*
|
||||
* the user_pointer is an opaque user pointer that can be retrieved at any time in the LinphoneCall
|
||||
**/
|
||||
void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer)
|
||||
{
|
||||
call->user_pointer = user_pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the call log associated to this call.
|
||||
**/
|
||||
LinphoneCallLog *linphone_call_get_call_log(const LinphoneCall *call){
|
||||
return call->log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the refer-to uri (if the call was transfered).
|
||||
**/
|
||||
const char *linphone_call_get_refer_to(const LinphoneCall *call){
|
||||
return call->refer_to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns direction of the call (incoming or outgoing).
|
||||
**/
|
||||
LinphoneCallDir linphone_call_get_dir(const LinphoneCall *call){
|
||||
return call->log->dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the far end's user agent description string, if available.
|
||||
**/
|
||||
const char *linphone_call_get_remote_user_agent(LinphoneCall *call){
|
||||
if (call->op){
|
||||
return sal_op_get_remote_ua (call->op);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this calls has received a transfer that has not been
|
||||
* executed yet.
|
||||
* Pending transfers are executed when this call is being paused or closed,
|
||||
* locally or by remote endpoint.
|
||||
* If the call is already paused while receiving the transfer request, the
|
||||
* transfer immediately occurs.
|
||||
**/
|
||||
bool_t linphone_call_has_transfer_pending(const LinphoneCall *call){
|
||||
return call->refer_pending;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns call's duration in seconds.
|
||||
**/
|
||||
int linphone_call_get_duration(const LinphoneCall *call){
|
||||
if (call->media_start_time==0) return 0;
|
||||
return time(NULL)-call->media_start_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether camera input should be sent to remote end.
|
||||
**/
|
||||
void linphone_call_enable_camera (LinphoneCall *call, bool_t enable){
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->videostream!=NULL && call->videostream->ticker!=NULL){
|
||||
LinphoneCore *lc=call->core;
|
||||
MSWebCam *nowebcam=get_nowebcam_device();
|
||||
if (call->camera_active!=enable && lc->video_conf.device!=nowebcam){
|
||||
video_stream_change_camera(call->videostream,
|
||||
enable ? lc->video_conf.device : nowebcam);
|
||||
}
|
||||
}
|
||||
call->camera_active=enable;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a photo of currently received video and write it into a jpeg file.
|
||||
**/
|
||||
int linphone_call_take_video_snapshot(LinphoneCall *call, const char *file){
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->videostream!=NULL && call->videostream->jpegwriter!=NULL){
|
||||
return ms_filter_call_method(call->videostream->jpegwriter,MS_JPEG_WRITER_TAKE_SNAPSHOT,(void*)file);
|
||||
}
|
||||
ms_warning("Cannot take snapshot: no currently running video stream on this call.");
|
||||
return -1;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
**/
|
||||
bool_t linphone_call_camera_enabled (const LinphoneCall *call){
|
||||
return call->camera_active;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
**/
|
||||
void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled){
|
||||
cp->has_video=enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
**/
|
||||
bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp){
|
||||
return cp->has_video;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable sending of real early media (during outgoing calls).
|
||||
**/
|
||||
void linphone_call_params_enable_early_media_sending(LinphoneCallParams *cp, bool_t enabled){
|
||||
cp->real_early_media=enabled;
|
||||
}
|
||||
|
||||
bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *cp){
|
||||
return cp->real_early_media;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refine bandwidth settings for this call by setting a bandwidth limit for audio streams.
|
||||
* As a consequence, codecs whose bitrates are not compatible with this limit won't be used.
|
||||
**/
|
||||
void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bandwidth){
|
||||
cp->audio_bw=bandwidth;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
**/
|
||||
LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp){
|
||||
LinphoneCallParams *ncp=ms_new0(LinphoneCallParams,1);
|
||||
memcpy(ncp,cp,sizeof(LinphoneCallParams));
|
||||
return ncp;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
**/
|
||||
void linphone_call_params_destroy(LinphoneCallParams *p){
|
||||
ms_free(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
**/
|
||||
|
||||
|
||||
#ifdef TEST_EXT_RENDERER
|
||||
static void rendercb(void *data, const MSPicture *local, const MSPicture *remote){
|
||||
ms_message("rendercb, local buffer=%p, remote buffer=%p",
|
||||
local ? local->planes[0] : NULL, remote? remote->planes[0] : NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
void linphone_call_init_media_streams(LinphoneCall *call){
|
||||
LinphoneCore *lc=call->core;
|
||||
SalMediaDescription *md=call->localdesc;
|
||||
AudioStream *audiostream;
|
||||
|
||||
call->audiostream=audiostream=audio_stream_new(md->streams[0].port,linphone_core_ipv6_enabled(lc));
|
||||
if (linphone_core_echo_limiter_enabled(lc)){
|
||||
const char *type=lp_config_get_string(lc->config,"sound","el_type","mic");
|
||||
if (strcasecmp(type,"mic")==0)
|
||||
audio_stream_enable_echo_limiter(audiostream,ELControlMic);
|
||||
else if (strcasecmp(type,"full")==0)
|
||||
audio_stream_enable_echo_limiter(audiostream,ELControlFull);
|
||||
}
|
||||
audio_stream_enable_gain_control(audiostream,TRUE);
|
||||
if (linphone_core_echo_cancellation_enabled(lc)){
|
||||
int len,delay,framesize;
|
||||
len=lp_config_get_int(lc->config,"sound","ec_tail_len",0);
|
||||
delay=lp_config_get_int(lc->config,"sound","ec_delay",0);
|
||||
framesize=lp_config_get_int(lc->config,"sound","ec_framesize",0);
|
||||
audio_stream_set_echo_canceller_params(audiostream,len,delay,framesize);
|
||||
}
|
||||
audio_stream_enable_automatic_gain_control(audiostream,linphone_core_agc_enabled(lc));
|
||||
{
|
||||
int enabled=lp_config_get_int(lc->config,"sound","noisegate",0);
|
||||
audio_stream_enable_noise_gate(audiostream,enabled);
|
||||
}
|
||||
if (lc->a_rtp)
|
||||
rtp_session_set_transports(audiostream->session,lc->a_rtp,lc->a_rtcp);
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
if ((lc->video_conf.display || lc->video_conf.capture) && md->streams[1].port>0){
|
||||
call->videostream=video_stream_new(md->streams[1].port,linphone_core_ipv6_enabled(lc));
|
||||
if( lc->video_conf.displaytype != NULL)
|
||||
video_stream_set_display_filter_name(call->videostream,lc->video_conf.displaytype);
|
||||
#ifdef TEST_EXT_RENDERER
|
||||
video_stream_set_render_callback(call->videostream,rendercb,NULL);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
call->videostream=NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static int dtmf_tab[16]={'0','1','2','3','4','5','6','7','8','9','*','#','A','B','C','D'};
|
||||
|
||||
static void linphone_core_dtmf_received(RtpSession* s, int dtmf, void* user_data){
|
||||
LinphoneCore* lc = (LinphoneCore*)user_data;
|
||||
if (dtmf<0 || dtmf>15){
|
||||
ms_warning("Bad dtmf value %i",dtmf);
|
||||
return;
|
||||
}
|
||||
if (lc->vtable.dtmf_received != NULL)
|
||||
lc->vtable.dtmf_received(lc, linphone_core_get_current_call(lc), dtmf_tab[dtmf]);
|
||||
}
|
||||
|
||||
static void parametrize_equalizer(LinphoneCore *lc, AudioStream *st){
|
||||
if (st->equalizer){
|
||||
MSFilter *f=st->equalizer;
|
||||
int enabled=lp_config_get_int(lc->config,"sound","eq_active",0);
|
||||
const char *gains=lp_config_get_string(lc->config,"sound","eq_gains",NULL);
|
||||
ms_filter_call_method(f,MS_EQUALIZER_SET_ACTIVE,&enabled);
|
||||
if (enabled){
|
||||
if (gains){
|
||||
do{
|
||||
int bytes;
|
||||
MSEqualizerGain g;
|
||||
if (sscanf(gains,"%f:%f:%f %n",&g.frequency,&g.gain,&g.width,&bytes)==3){
|
||||
ms_message("Read equalizer gains: %f(~%f) --> %f",g.frequency,g.width,g.gain);
|
||||
ms_filter_call_method(f,MS_EQUALIZER_SET_GAIN,&g);
|
||||
gains+=bytes;
|
||||
}else break;
|
||||
}while(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void post_configure_audio_streams(LinphoneCall*call){
|
||||
AudioStream *st=call->audiostream;
|
||||
LinphoneCore *lc=call->core;
|
||||
float mic_gain=lp_config_get_float(lc->config,"sound","mic_gain",1);
|
||||
float thres = 0;
|
||||
float recv_gain;
|
||||
float ng_thres=lp_config_get_float(lc->config,"sound","ng_thres",0.05);
|
||||
float ng_floorgain=lp_config_get_float(lc->config,"sound","ng_floorgain",0);
|
||||
int dc_removal=lp_config_get_int(lc->config,"sound","dc_removal",0);
|
||||
|
||||
if (!call->audio_muted)
|
||||
audio_stream_set_mic_gain(st,mic_gain);
|
||||
else
|
||||
audio_stream_set_mic_gain(st,0);
|
||||
|
||||
recv_gain = lc->sound_conf.soft_play_lev;
|
||||
if (recv_gain != 0) {
|
||||
linphone_core_set_playback_gain_db (lc,recv_gain);
|
||||
}
|
||||
if (st->volsend){
|
||||
ms_filter_call_method(st->volsend,MS_VOLUME_REMOVE_DC,&dc_removal);
|
||||
}
|
||||
if (linphone_core_echo_limiter_enabled(lc)){
|
||||
float speed=lp_config_get_float(lc->config,"sound","el_speed",-1);
|
||||
thres=lp_config_get_float(lc->config,"sound","el_thres",-1);
|
||||
float force=lp_config_get_float(lc->config,"sound","el_force",-1);
|
||||
int sustain=lp_config_get_int(lc->config,"sound","el_sustain",-1);
|
||||
MSFilter *f=NULL;
|
||||
if (st->el_type!=ELInactive){
|
||||
f=st->volsend;
|
||||
if (speed==-1) speed=0.03;
|
||||
if (force==-1) force=25;
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_SPEED,&speed);
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_FORCE,&force);
|
||||
if (thres!=-1)
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_THRESHOLD,&thres);
|
||||
if (sustain!=-1)
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_SUSTAIN,&sustain);
|
||||
}
|
||||
}
|
||||
|
||||
if (st->volsend){
|
||||
ms_filter_call_method(st->volsend,MS_VOLUME_SET_NOISE_GATE_THRESHOLD,&ng_thres);
|
||||
ms_filter_call_method(st->volsend,MS_VOLUME_SET_NOISE_GATE_FLOORGAIN,&ng_floorgain);
|
||||
}
|
||||
if (st->volrecv){
|
||||
/* parameters for a limited noise-gate effect, using echo limiter threshold */
|
||||
float floorgain = 1/mic_gain;
|
||||
ms_filter_call_method(st->volrecv,MS_VOLUME_SET_NOISE_GATE_THRESHOLD,&thres);
|
||||
ms_filter_call_method(st->volrecv,MS_VOLUME_SET_NOISE_GATE_FLOORGAIN,&floorgain);
|
||||
}
|
||||
parametrize_equalizer(lc,st);
|
||||
if (lc->vtable.dtmf_received!=NULL){
|
||||
/* replace by our default action*/
|
||||
audio_stream_play_received_dtmfs(call->audiostream,FALSE);
|
||||
rtp_session_signal_connect(call->audiostream->session,"telephone-event",(RtpCallback)linphone_core_dtmf_received,(unsigned long)lc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static RtpProfile *make_profile(LinphoneCore *lc, const SalMediaDescription *md, const SalStreamDescription *desc, int *used_pt){
|
||||
int bw;
|
||||
const MSList *elem;
|
||||
RtpProfile *prof=rtp_profile_new("Call profile");
|
||||
bool_t first=TRUE;
|
||||
int remote_bw=0;
|
||||
*used_pt=-1;
|
||||
|
||||
for(elem=desc->payloads;elem!=NULL;elem=elem->next){
|
||||
PayloadType *pt=(PayloadType*)elem->data;
|
||||
int number;
|
||||
|
||||
if (first) {
|
||||
if (desc->type==SalAudio){
|
||||
linphone_core_update_allocated_audio_bandwidth_in_call(lc,pt);
|
||||
}
|
||||
*used_pt=payload_type_get_number(pt);
|
||||
first=FALSE;
|
||||
}
|
||||
if (desc->bandwidth>0) remote_bw=desc->bandwidth;
|
||||
else if (md->bandwidth>0) {
|
||||
/*case where b=AS is given globally, not per stream*/
|
||||
remote_bw=md->bandwidth;
|
||||
if (desc->type==SalVideo){
|
||||
remote_bw-=lc->audio_bw;
|
||||
}
|
||||
}
|
||||
|
||||
if (desc->type==SalAudio){
|
||||
bw=get_min_bandwidth(lc->up_audio_bw,remote_bw);
|
||||
}else bw=get_min_bandwidth(lc->up_video_bw,remote_bw);
|
||||
if (bw>0) pt->normal_bitrate=bw*1000;
|
||||
else if (desc->type==SalAudio){
|
||||
pt->normal_bitrate=-1;
|
||||
}
|
||||
if (desc->ptime>0){
|
||||
char tmp[40];
|
||||
snprintf(tmp,sizeof(tmp),"ptime=%i",desc->ptime);
|
||||
payload_type_append_send_fmtp(pt,tmp);
|
||||
}
|
||||
number=payload_type_get_number(pt);
|
||||
if (rtp_profile_get_payload(prof,number)!=NULL){
|
||||
ms_warning("A payload type with number %i already exists in profile !",number);
|
||||
}else
|
||||
rtp_profile_set_payload(prof,number,pt);
|
||||
}
|
||||
return prof;
|
||||
}
|
||||
|
||||
|
||||
static void setup_ring_player(LinphoneCore *lc, LinphoneCall *call){
|
||||
int pause_time=3000;
|
||||
audio_stream_play(call->audiostream,lc->sound_conf.ringback_tone);
|
||||
ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time);
|
||||
}
|
||||
|
||||
|
||||
void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone){
|
||||
LinphoneCore *lc=call->core;
|
||||
LinphoneAddress *me=linphone_core_get_primary_contact_parsed(lc);
|
||||
const char *tool="linphone-" LINPHONE_VERSION;
|
||||
char *cname;
|
||||
int used_pt=-1;
|
||||
|
||||
if(call->audiostream == NULL)
|
||||
{
|
||||
ms_fatal("start_media_stream() called without prior init !");
|
||||
return;
|
||||
}
|
||||
/* adjust rtp jitter compensation. It must be at least the latency of the sound card */
|
||||
int jitt_comp=MAX(lc->sound_conf.latency,lc->rtp_conf.audio_jitt_comp);
|
||||
|
||||
if (call->media_start_time==0) call->media_start_time=time(NULL);
|
||||
|
||||
cname=linphone_address_as_string_uri_only(me);
|
||||
{
|
||||
const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
|
||||
SalProtoRtpAvp,SalAudio);
|
||||
if (stream && stream->dir!=SalStreamInactive){
|
||||
MSSndCard *playcard=lc->sound_conf.lsd_card ?
|
||||
lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
|
||||
MSSndCard *captcard=lc->sound_conf.capt_sndcard;
|
||||
const char *playfile=lc->play_file;
|
||||
const char *recfile=lc->rec_file;
|
||||
call->audio_profile=make_profile(lc,call->resultdesc,stream,&used_pt);
|
||||
if (used_pt!=-1){
|
||||
if (playcard==NULL) {
|
||||
ms_warning("No card defined for playback !");
|
||||
}
|
||||
if (captcard==NULL) {
|
||||
ms_warning("No card defined for capture !");
|
||||
}
|
||||
/*Replace soundcard filters by inactive file players or recorders
|
||||
when placed in recvonly or sendonly mode*/
|
||||
if (stream->port==0 || stream->dir==SalStreamRecvOnly){
|
||||
captcard=NULL;
|
||||
playfile=NULL;
|
||||
}else if (stream->dir==SalStreamSendOnly){
|
||||
playcard=NULL;
|
||||
captcard=NULL;
|
||||
recfile=NULL;
|
||||
playfile=NULL;
|
||||
}
|
||||
if (send_ringbacktone){
|
||||
captcard=NULL;
|
||||
playfile=NULL;/* it is setup later*/
|
||||
}
|
||||
/*if playfile are supplied don't use soundcards*/
|
||||
if (lc->use_files) {
|
||||
captcard=NULL;
|
||||
playcard=NULL;
|
||||
}
|
||||
audio_stream_start_full(
|
||||
call->audiostream,
|
||||
call->audio_profile,
|
||||
stream->addr[0]!='\0' ? stream->addr : call->resultdesc->addr,
|
||||
stream->port,
|
||||
stream->port+1,
|
||||
used_pt,
|
||||
jitt_comp,
|
||||
playfile,
|
||||
recfile,
|
||||
playcard,
|
||||
captcard,
|
||||
captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc));
|
||||
post_configure_audio_streams(call);
|
||||
if (all_inputs_muted && !send_ringbacktone){
|
||||
audio_stream_set_mic_gain(call->audiostream,0);
|
||||
}
|
||||
if (send_ringbacktone){
|
||||
setup_ring_player(lc,call);
|
||||
}
|
||||
audio_stream_set_rtcp_information(call->audiostream, cname, tool);
|
||||
}else ms_warning("No audio stream accepted ?");
|
||||
}
|
||||
}
|
||||
#ifdef VIDEO_ENABLED
|
||||
{
|
||||
const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
|
||||
SalProtoRtpAvp,SalVideo);
|
||||
used_pt=-1;
|
||||
/* shutdown preview */
|
||||
if (lc->previewstream!=NULL) {
|
||||
video_preview_stop(lc->previewstream);
|
||||
lc->previewstream=NULL;
|
||||
}
|
||||
if (stream && stream->dir!=SalStreamInactive) {
|
||||
const char *addr=stream->addr[0]!='\0' ? stream->addr : call->resultdesc->addr;
|
||||
call->video_profile=make_profile(lc,call->resultdesc,stream,&used_pt);
|
||||
if (used_pt!=-1){
|
||||
VideoStreamDir dir=VideoStreamSendRecv;
|
||||
MSWebCam *cam=lc->video_conf.device;
|
||||
bool_t is_inactive=FALSE;
|
||||
|
||||
call->params.has_video=TRUE;
|
||||
|
||||
video_stream_set_sent_video_size(call->videostream,linphone_core_get_preferred_video_size(lc));
|
||||
video_stream_enable_self_view(call->videostream,lc->video_conf.selfview);
|
||||
if (lc->video_window_id!=0)
|
||||
video_stream_set_native_window_id(call->videostream,lc->video_window_id);
|
||||
if (lc->preview_window_id!=0)
|
||||
video_stream_set_native_preview_window_id (call->videostream,lc->preview_window_id);
|
||||
video_stream_use_preview_video_window (call->videostream,lc->use_preview_window);
|
||||
|
||||
if (stream->dir==SalStreamSendOnly && lc->video_conf.capture ){
|
||||
cam=get_nowebcam_device();
|
||||
dir=VideoStreamSendOnly;
|
||||
}else if (stream->dir==SalStreamRecvOnly && lc->video_conf.display ){
|
||||
dir=VideoStreamRecvOnly;
|
||||
}else if (stream->dir==SalStreamSendRecv){
|
||||
if (lc->video_conf.display && lc->video_conf.capture)
|
||||
dir=VideoStreamSendRecv;
|
||||
else if (lc->video_conf.display)
|
||||
dir=VideoStreamRecvOnly;
|
||||
else
|
||||
dir=VideoStreamSendOnly;
|
||||
}else{
|
||||
ms_warning("video stream is inactive.");
|
||||
/*either inactive or incompatible with local capabilities*/
|
||||
is_inactive=TRUE;
|
||||
}
|
||||
if (call->camera_active==FALSE || all_inputs_muted){
|
||||
cam=get_nowebcam_device();
|
||||
}
|
||||
if (!is_inactive){
|
||||
video_stream_set_direction (call->videostream, dir);
|
||||
video_stream_start(call->videostream,
|
||||
call->video_profile, addr, stream->port,
|
||||
stream->port+1,
|
||||
used_pt, jitt_comp, cam);
|
||||
video_stream_set_rtcp_information(call->videostream, cname,tool);
|
||||
}
|
||||
}else ms_warning("No video stream accepted.");
|
||||
}else{
|
||||
ms_warning("No valid video stream defined.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
call->all_muted=all_inputs_muted;
|
||||
call->playing_ringbacktone=send_ringbacktone;
|
||||
call->up_bw=linphone_core_get_upload_bandwidth(lc);
|
||||
|
||||
goto end;
|
||||
end:
|
||||
ms_free(cname);
|
||||
linphone_address_destroy(me);
|
||||
}
|
||||
|
||||
static void linphone_call_log_fill_stats(LinphoneCallLog *log, AudioStream *st){
|
||||
audio_stream_get_local_rtp_stats (st,&log->local_stats);
|
||||
}
|
||||
|
||||
void linphone_call_stop_media_streams(LinphoneCall *call){
|
||||
if (call->audiostream!=NULL) {
|
||||
linphone_call_log_fill_stats (call->log,call->audiostream);
|
||||
audio_stream_stop(call->audiostream);
|
||||
call->audiostream=NULL;
|
||||
}
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->videostream!=NULL){
|
||||
video_stream_stop(call->videostream);
|
||||
call->videostream=NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (call->audio_profile){
|
||||
rtp_profile_clear_all(call->audio_profile);
|
||||
rtp_profile_destroy(call->audio_profile);
|
||||
call->audio_profile=NULL;
|
||||
}
|
||||
if (call->video_profile){
|
||||
rtp_profile_clear_all(call->video_profile);
|
||||
rtp_profile_destroy(call->video_profile);
|
||||
call->video_profile=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -39,6 +39,11 @@ extern "C" {
|
|||
|
||||
struct _MSSndCard;
|
||||
struct _LinphoneCore;
|
||||
/**
|
||||
* Linphone core main object created by function linphone_core_new() .
|
||||
* @ingroup initializing
|
||||
*/
|
||||
typedef struct _LinphoneCore LinphoneCore;
|
||||
struct SalOp;
|
||||
|
||||
struct _LpConfig;
|
||||
|
|
@ -68,6 +73,11 @@ typedef struct _LCSipTransports LCSipTransports;
|
|||
* @var LinphoneAddress
|
||||
*/
|
||||
typedef struct SalAddress LinphoneAddress;
|
||||
#ifdef IN_LINPHONE
|
||||
#include "linphonefriend.h"
|
||||
#else
|
||||
#include "linphone/linphonefriend.h"
|
||||
#endif
|
||||
|
||||
LinphoneAddress * linphone_address_new(const char *uri);
|
||||
LinphoneAddress * linphone_address_clone(const LinphoneAddress *uri);
|
||||
|
|
@ -93,18 +103,12 @@ void linphone_address_set_port_int(LinphoneAddress *uri, int port);
|
|||
void linphone_address_clean(LinphoneAddress *uri);
|
||||
char *linphone_address_as_string(const LinphoneAddress *u);
|
||||
char *linphone_address_as_string_uri_only(const LinphoneAddress *u);
|
||||
bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddress *a2);
|
||||
void linphone_address_destroy(LinphoneAddress *u);
|
||||
|
||||
struct _SipSetupContext;
|
||||
|
||||
/**
|
||||
* The LinphoneCall object represents a call issued or received by the LinphoneCore
|
||||
**/
|
||||
struct _LinphoneCall;
|
||||
typedef struct _LinphoneCall LinphoneCall;
|
||||
|
||||
bool_t linphone_call_asked_to_autoanswer(struct _LinphoneCall *call);
|
||||
|
||||
/**
|
||||
* Enum representing the direction of a call.
|
||||
* @ingroup call_logs
|
||||
|
|
@ -127,7 +131,8 @@ typedef enum _LinphoneCallDir LinphoneCallDir;
|
|||
typedef enum _LinphoneCallStatus {
|
||||
LinphoneCallSuccess, /**< The call was sucessful*/
|
||||
LinphoneCallAborted, /**< The call was aborted */
|
||||
LinphoneCallMissed /**< The call was missed (unanswered)*/
|
||||
LinphoneCallMissed, /**< The call was missed (unanswered)*/
|
||||
LinphoneCallDeclined /**< The call was declined, either locally or by remote end*/
|
||||
} LinphoneCallStatus;
|
||||
|
||||
/**
|
||||
|
|
@ -161,52 +166,87 @@ const rtp_stats_t *linphone_call_log_get_local_stats(const LinphoneCallLog *cl);
|
|||
const rtp_stats_t *linphone_call_log_get_remote_stats(const LinphoneCallLog *cl);
|
||||
char * linphone_call_log_to_str(LinphoneCallLog *cl);
|
||||
|
||||
typedef enum{
|
||||
LinphoneSPWait,
|
||||
LinphoneSPDeny,
|
||||
LinphoneSPAccept
|
||||
}LinphoneSubscribePolicy;
|
||||
|
||||
typedef enum _LinphoneOnlineStatus{
|
||||
LINPHONE_STATUS_OFFLINE,
|
||||
LINPHONE_STATUS_ONLINE,
|
||||
LINPHONE_STATUS_BUSY,
|
||||
LINPHONE_STATUS_BERIGHTBACK,
|
||||
LINPHONE_STATUS_AWAY,
|
||||
LINPHONE_STATUS_ONTHEPHONE,
|
||||
LINPHONE_STATUS_OUTTOLUNCH,
|
||||
LINPHONE_STATUS_NOT_DISTURB,
|
||||
LINPHONE_STATUS_MOVED,
|
||||
LINPHONE_STATUS_ALT_SERVICE,
|
||||
LINPHONE_STATUS_PENDING,
|
||||
LINPHONE_STATUS_END
|
||||
}LinphoneOnlineStatus;
|
||||
/**
|
||||
* The LinphoneCallParams is an object containing various call related parameters.
|
||||
* It can be used to retrieve parameters from a currently running call or modify the call's characteristics
|
||||
* dynamically.
|
||||
**/
|
||||
struct _LinphoneCallParams;
|
||||
typedef struct _LinphoneCallParams LinphoneCallParams;
|
||||
|
||||
const char *linphone_online_status_to_string(LinphoneOnlineStatus ss);
|
||||
LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp);
|
||||
void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled);
|
||||
bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp);
|
||||
void linphone_call_params_enable_early_media_sending(LinphoneCallParams *cp, bool_t enabled);
|
||||
bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *cp);
|
||||
void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bw);
|
||||
void linphone_call_params_destroy(LinphoneCallParams *cp);
|
||||
|
||||
struct _LinphoneFriend;
|
||||
/**
|
||||
* Enum describing failure reasons.
|
||||
**/
|
||||
enum _LinphoneReason{
|
||||
LinphoneReasonNone,
|
||||
LinphoneReasonNoResponse, /**<No response received from remote*/
|
||||
LinphoneReasonBadCredentials, /**<Authentication failed due to bad or missing credentials*/
|
||||
LinphoneReasonDeclined, /**<The call has been declined*/
|
||||
};
|
||||
|
||||
typedef struct _LinphoneFriend LinphoneFriend;
|
||||
typedef enum _LinphoneReason LinphoneReason;
|
||||
|
||||
LinphoneFriend * linphone_friend_new();
|
||||
LinphoneFriend *linphone_friend_new_with_addr(const char *addr);
|
||||
int linphone_friend_set_sip_addr(LinphoneFriend *fr, const char *uri);
|
||||
int linphone_friend_set_name(LinphoneFriend *fr, const char *name);
|
||||
int linphone_friend_send_subscribe(LinphoneFriend *fr, bool_t val);
|
||||
int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscribePolicy pol);
|
||||
void linphone_friend_edit(LinphoneFriend *fr);
|
||||
void linphone_friend_done(LinphoneFriend *fr);
|
||||
void linphone_friend_destroy(LinphoneFriend *lf);
|
||||
const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf);
|
||||
bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf);
|
||||
LinphoneSubscribePolicy linphone_friend_get_inc_subscribe_policy(const LinphoneFriend *lf);
|
||||
LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf);
|
||||
BuddyInfo * linphone_friend_get_info(const LinphoneFriend *lf);
|
||||
void linphone_friend_set_ref_key(LinphoneFriend *lf, const char *key);
|
||||
const char *linphone_friend_get_ref_key(const LinphoneFriend *lf);
|
||||
bool_t linphone_friend_in_list(const LinphoneFriend *lf);
|
||||
const char *linphone_reason_to_string(LinphoneReason err);
|
||||
|
||||
#define linphone_friend_url(lf) ((lf)->url)
|
||||
/**
|
||||
* The LinphoneCall object represents a call issued or received by the LinphoneCore
|
||||
**/
|
||||
struct _LinphoneCall;
|
||||
typedef struct _LinphoneCall LinphoneCall;
|
||||
|
||||
typedef enum _LinphoneCallState{
|
||||
LinphoneCallIdle,
|
||||
LinphoneCallIncomingReceived, /**<This is a new incoming call */
|
||||
LinphoneCallOutgoingInit, /**<An outgoing call is started */
|
||||
LinphoneCallOutgoingProgress, /**<An outgoing call is in progress */
|
||||
LinphoneCallOutgoingRinging, /**<An outgoing call is ringing at remote end */
|
||||
LinphoneCallOutgoingEarlyMedia, /**<An outgoing call is proposed early media */
|
||||
LinphoneCallConnected, /**<Connected, the call is answered */
|
||||
LinphoneCallStreamsRunning, /**<The media streams are established and running*/
|
||||
LinphoneCallPausing, /**<The call is pausing at the initiative of local end */
|
||||
LinphoneCallPaused, /**< The call is paused, remote end has accepted the pause */
|
||||
LinphoneCallResuming, /**<The call is being resumed by local end*/
|
||||
LinphoneCallRefered, /**<The call is being transfered to another party, resulting in a new outgoing call to follow immediately*/
|
||||
LinphoneCallError, /**<The call encountered an error*/
|
||||
LinphoneCallEnd, /**<The call ended normally*/
|
||||
LinphoneCallPausedByRemote, /**<The call is paused by remote end*/
|
||||
LinphoneCallUpdatedByRemote, /**<The call's parameters are updated, used for example when video is asked by remote */
|
||||
LinphoneCallIncomingEarlyMedia, /**<We are proposing early media to an incoming call */
|
||||
LinphoneCallUpdated /**<The remote accepted the call update initiated by us */
|
||||
} LinphoneCallState;
|
||||
|
||||
const char *linphone_call_state_to_string(LinphoneCallState cs);
|
||||
|
||||
|
||||
LinphoneCallState linphone_call_get_state(const LinphoneCall *call);
|
||||
bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call);
|
||||
const LinphoneAddress * linphone_core_get_current_call_remote_address(struct _LinphoneCore *lc);
|
||||
const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call);
|
||||
char *linphone_call_get_remote_address_as_string(const LinphoneCall *call);
|
||||
LinphoneCallDir linphone_call_get_dir(const LinphoneCall *call);
|
||||
void linphone_call_ref(LinphoneCall *call);
|
||||
void linphone_call_unref(LinphoneCall *call);
|
||||
LinphoneCallLog *linphone_call_get_call_log(const LinphoneCall *call);
|
||||
const char *linphone_call_get_refer_to(const LinphoneCall *call);
|
||||
bool_t linphone_call_has_transfer_pending(const LinphoneCall *call);
|
||||
int linphone_call_get_duration(const LinphoneCall *call);
|
||||
const LinphoneCallParams * linphone_call_get_current_params(const LinphoneCall *call);
|
||||
void linphone_call_enable_camera(LinphoneCall *lc, bool_t enabled);
|
||||
bool_t linphone_call_camera_enabled(const LinphoneCall *lc);
|
||||
int linphone_call_take_video_snapshot(LinphoneCall *call, const char *file);
|
||||
LinphoneReason linphone_call_get_reason(const LinphoneCall *call);
|
||||
const char *linphone_call_get_remote_user_agent(LinphoneCall *call);
|
||||
void *linphone_call_get_user_pointer(LinphoneCall *call);
|
||||
void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -231,11 +271,34 @@ bool_t linphone_friend_in_list(const LinphoneFriend *lf);
|
|||
**/
|
||||
typedef struct _LinphoneProxyConfig LinphoneProxyConfig;
|
||||
|
||||
/**
|
||||
* LinphoneRegistrationState describes proxy registration states.
|
||||
**/
|
||||
typedef enum _LinphoneRegistrationState{
|
||||
LinphoneRegistrationNone,
|
||||
LinphoneRegistrationProgress,
|
||||
LinphoneRegistrationOk,
|
||||
LinphoneRegistrationCleared,
|
||||
LinphoneRegistrationFailed
|
||||
}LinphoneRegistrationState;
|
||||
|
||||
/**
|
||||
* Human readable version of the #LinphoneRegistrationState
|
||||
* @param cs sate
|
||||
*/
|
||||
const char *linphone_registration_state_to_string(LinphoneRegistrationState cs);
|
||||
|
||||
LinphoneProxyConfig *linphone_proxy_config_new(void);
|
||||
int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr);
|
||||
int linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity);
|
||||
int linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route);
|
||||
void linphone_proxy_config_expires(LinphoneProxyConfig *obj, int expires);
|
||||
/**
|
||||
* Indicates either or not, REGISTRATION must be issued for this #LinphoneProxyConfig .
|
||||
* <br> In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the linphone_proxy_config_edit() rule.
|
||||
* @param obj object pointer
|
||||
* @param val if true, registration will be engaged
|
||||
*/
|
||||
void linphone_proxy_config_enable_register(LinphoneProxyConfig *obj, bool_t val);
|
||||
#define linphone_proxy_config_enableregister linphone_proxy_config_enable_register
|
||||
void linphone_proxy_config_edit(LinphoneProxyConfig *obj);
|
||||
|
|
@ -244,6 +307,7 @@ void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val);
|
|||
void linphone_proxy_config_set_dial_escape_plus(LinphoneProxyConfig *cfg, bool_t val);
|
||||
void linphone_proxy_config_set_dial_prefix(LinphoneProxyConfig *cfg, const char *prefix);
|
||||
|
||||
LinphoneRegistrationState linphone_proxy_config_get_state(const LinphoneProxyConfig *obj);
|
||||
bool_t linphone_proxy_config_is_registered(const LinphoneProxyConfig *obj);
|
||||
const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg);
|
||||
|
||||
|
|
@ -258,6 +322,8 @@ struct _LinphoneCore * linphone_proxy_config_get_core(const LinphoneProxyConfig
|
|||
bool_t linphone_proxy_config_get_dial_escape_plus(const LinphoneProxyConfig *cfg);
|
||||
const char * linphone_proxy_config_get_dial_prefix(const LinphoneProxyConfig *cfg);
|
||||
|
||||
LinphoneReason linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg);
|
||||
|
||||
/* destruction is called automatically when removing the proxy config */
|
||||
void linphone_proxy_config_destroy(LinphoneProxyConfig *cfg);
|
||||
void linphone_proxy_config_set_sip_setup(LinphoneProxyConfig *cfg, const char *type);
|
||||
|
|
@ -341,95 +407,115 @@ const char *linphone_auth_info_get_userid(const LinphoneAuthInfo *i);
|
|||
void linphone_auth_info_destroy(LinphoneAuthInfo *info);
|
||||
LinphoneAuthInfo * linphone_auth_info_new_from_config_file(struct _LpConfig *config, int pos);
|
||||
|
||||
struct _LinphoneChatRoom;
|
||||
typedef struct _LinphoneChatRoom LinphoneChatRoom;
|
||||
|
||||
LinphoneChatRoom * linphone_core_create_chat_room(struct _LinphoneCore *lc, const char *to);
|
||||
void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg);
|
||||
struct _LinphoneChatRoom;
|
||||
/**
|
||||
* @addtogroup chatroom
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* A chat room is the place where text messages are exchanged.
|
||||
* <br> Can be created by linphone_core_create_chat_room().
|
||||
*/
|
||||
typedef struct _LinphoneChatRoom LinphoneChatRoom;
|
||||
/**
|
||||
* Create a new chat room for messaging from a sip uri like sip:joe@sip.linphone.org
|
||||
* @param lc #LinphoneCore object
|
||||
* @param to destination address for messages
|
||||
* @return #LinphoneChatRoom where messaging can take place.
|
||||
*/
|
||||
LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to);
|
||||
/**
|
||||
* Destructor
|
||||
* @param cr #LinphoneChatRoom object
|
||||
*/
|
||||
void linphone_chat_room_destroy(LinphoneChatRoom *cr);
|
||||
|
||||
|
||||
/**
|
||||
* get peer address \link linphone_core_create_chat_room() associated to \endlink this #LinphoneChatRoom
|
||||
* @param cr #LinphoneChatRoom object
|
||||
* @return #LinphoneAddress peer address
|
||||
*/
|
||||
const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr);
|
||||
/**
|
||||
* send a message to peer member of this chat room.
|
||||
* @param cr #LinphoneChatRoom object
|
||||
* @param msg message to be sent
|
||||
*/
|
||||
void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg);
|
||||
|
||||
void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud);
|
||||
void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr);
|
||||
|
||||
/* describes the different groups of states */
|
||||
typedef enum _gstate_group {
|
||||
GSTATE_GROUP_POWER,
|
||||
GSTATE_GROUP_REG,
|
||||
GSTATE_GROUP_CALL
|
||||
} gstate_group_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
typedef enum _LinphoneGlobalState{
|
||||
LinphoneGlobalOff,
|
||||
LinphoneGlobalStartup,
|
||||
LinphoneGlobalOn,
|
||||
LinphoneGlobalShutdown
|
||||
}LinphoneGlobalState;
|
||||
|
||||
typedef enum _gstate {
|
||||
/* states for GSTATE_GROUP_POWER */
|
||||
GSTATE_POWER_OFF = 0, /* initial state */
|
||||
GSTATE_POWER_STARTUP,
|
||||
GSTATE_POWER_ON,
|
||||
GSTATE_POWER_SHUTDOWN,
|
||||
/* states for GSTATE_GROUP_REG */
|
||||
GSTATE_REG_NONE = 10, /* initial state */
|
||||
GSTATE_REG_OK,
|
||||
GSTATE_REG_FAILED,
|
||||
GSTATE_REG_PENDING, /* a registration request is ongoing*/
|
||||
/* states for GSTATE_GROUP_CALL */
|
||||
GSTATE_CALL_IDLE = 20, /* initial state */
|
||||
GSTATE_CALL_OUT_INVITE,
|
||||
GSTATE_CALL_OUT_CONNECTED,
|
||||
GSTATE_CALL_IN_INVITE,
|
||||
GSTATE_CALL_IN_CONNECTED,
|
||||
GSTATE_CALL_END,
|
||||
GSTATE_CALL_ERROR,
|
||||
GSTATE_INVALID,
|
||||
GSTATE_CALL_OUT_RINGING /*remote ringing*/
|
||||
} gstate_t;
|
||||
|
||||
struct _LinphoneGeneralState {
|
||||
gstate_t old_state;
|
||||
gstate_t new_state;
|
||||
gstate_group_t group;
|
||||
const char *message;
|
||||
};
|
||||
typedef struct _LinphoneGeneralState LinphoneGeneralState;
|
||||
|
||||
/* private: set a new state */
|
||||
void gstate_new_state(struct _LinphoneCore *lc, gstate_t new_state, const char *message);
|
||||
/*private*/
|
||||
void gstate_initialize(struct _LinphoneCore *lc) ;
|
||||
const char *linphone_global_state_to_string(LinphoneGlobalState gs);
|
||||
|
||||
/**
|
||||
* @addtogroup initializing
|
||||
* @{
|
||||
**/
|
||||
|
||||
|
||||
/**Call state notification callback prototype*/
|
||||
typedef void (*LinphoneGlobalStateCb)(struct _LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
|
||||
/**Call state notification callback prototype*/
|
||||
typedef void (*LinphoneCallStateCb)(struct _LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message);
|
||||
/** @ingroup Proxies
|
||||
* Registration state notification callback prototype
|
||||
* */
|
||||
typedef void (*LinphoneRegistrationStateCb)(struct _LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message);
|
||||
/** Callback prototype */
|
||||
typedef void (*ShowInterfaceCb)(struct _LinphoneCore *lc);
|
||||
/** Callback prototype */
|
||||
typedef void (*InviteReceivedCb)(struct _LinphoneCore *lc, const char *from);
|
||||
/** Callback prototype */
|
||||
typedef void (*ByeReceivedCb)(struct _LinphoneCore *lc, const char *from);
|
||||
/** Callback prototype */
|
||||
typedef void (*DisplayStatusCb)(struct _LinphoneCore *lc, const char *message);
|
||||
/** Callback prototype */
|
||||
typedef void (*DisplayMessageCb)(struct _LinphoneCore *lc, const char *message);
|
||||
/** Callback prototype */
|
||||
typedef void (*DisplayUrlCb)(struct _LinphoneCore *lc, const char *message, const char *url);
|
||||
/** Callback prototype */
|
||||
typedef void (*DisplayQuestionCb)(struct _LinphoneCore *lc, const char *message);
|
||||
/** Callback prototype */
|
||||
typedef void (*LinphoneCoreCbFunc)(struct _LinphoneCore *lc,void * user_data);
|
||||
/** Callback prototype */
|
||||
typedef void (*NotifyReceivedCb)(struct _LinphoneCore *lc, const char *from, const char *msg);
|
||||
/** Callback prototype */
|
||||
typedef void (*NotifyPresenceReceivedCb)(struct _LinphoneCore *lc, LinphoneFriend * fid);
|
||||
/** Callback prototype */
|
||||
typedef void (*NewUnknownSubscriberCb)(struct _LinphoneCore *lc, LinphoneFriend *lf, const char *url);
|
||||
typedef void (*NotifyReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call, const char *from, const char *event);
|
||||
/**
|
||||
* Report status change for a friend previously \link linphone_core_add_friend() added \endlink to #LinphoneCore.
|
||||
* @param lc #LinphoneCore object .
|
||||
* @param lf Updated #LinphoneFriend .
|
||||
*/
|
||||
typedef void (*NotifyPresenceReceivedCb)(struct _LinphoneCore *lc, LinphoneFriend * lf);
|
||||
/**
|
||||
* Reports that a new subscription request has been received and wait for a decision.
|
||||
* <br> Status on this subscription request is notified by \link linphone_friend_set_inc_subscribe_policy() changing policy \endlink for this friend
|
||||
* @param lc #LinphoneCore object
|
||||
* @param lf #LinphoneFriend corresponding to the subscriber
|
||||
* @param url of the subscriber
|
||||
* Callback prototype
|
||||
* */
|
||||
typedef void (*NewSubscribtionRequestCb)(struct _LinphoneCore *lc, LinphoneFriend *lf, const char *url);
|
||||
/** Callback prototype */
|
||||
typedef void (*AuthInfoRequested)(struct _LinphoneCore *lc, const char *realm, const char *username);
|
||||
/** Callback prototype */
|
||||
typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog *newcl);
|
||||
/**
|
||||
* Callback prototype
|
||||
*
|
||||
* @param lc #LinphoneCore object
|
||||
* @param room #LinphoneChatRoom involved in this conversation. Can be be created by the framework in case \link #LinphoneAddress the from \endlink is not present in any chat room.
|
||||
* @param from #LinphoneAddress from
|
||||
* @param message incoming message
|
||||
* */
|
||||
typedef void (*TextMessageReceived)(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message);
|
||||
/** Callback prototype */
|
||||
typedef void (*TextMessageReceived)(struct _LinphoneCore *lc, LinphoneChatRoom *room, const char *from, const char *message);
|
||||
/** Callback prototype */
|
||||
typedef void (*GeneralStateChange)(struct _LinphoneCore *lc, LinphoneGeneralState *gstate);
|
||||
/** Callback prototype */
|
||||
typedef void (*DtmfReceived)(struct _LinphoneCore* lc, int dtmf);
|
||||
typedef void (*DtmfReceived)(struct _LinphoneCore* lc, LinphoneCall *call, int dtmf);
|
||||
/** Callback prototype */
|
||||
typedef void (*ReferReceived)(struct _LinphoneCore *lc, const char *refer_to);
|
||||
/** Callback prototype */
|
||||
|
|
@ -437,28 +523,26 @@ typedef void (*BuddyInfoUpdated)(struct _LinphoneCore *lc, LinphoneFriend *lf);
|
|||
|
||||
/**
|
||||
* This structure holds all callbacks that the application should implement.
|
||||
*
|
||||
* None is mandatory.
|
||||
**/
|
||||
typedef struct _LinphoneVTable
|
||||
{
|
||||
ShowInterfaceCb show; /**< Notifies the application that it should show up*/
|
||||
InviteReceivedCb inv_recv; /**< Notifies incoming calls */
|
||||
ByeReceivedCb bye_recv; /**< Notify calls terminated by far end*/
|
||||
typedef struct _LinphoneVTable{
|
||||
LinphoneGlobalStateCb global_state_changed; /**<Notifies globlal state changes*/
|
||||
LinphoneRegistrationStateCb registration_state_changed;/**<Notifies registration state changes*/
|
||||
LinphoneCallStateCb call_state_changed;/**<Notifies call state changes*/
|
||||
NotifyPresenceReceivedCb notify_presence_recv; /**< Notify received presence events*/
|
||||
NewUnknownSubscriberCb new_unknown_subscriber; /**< Notify about unknown subscriber */
|
||||
NewSubscribtionRequestCb new_subscription_request; /**< Notify about pending subscription request */
|
||||
AuthInfoRequested auth_info_requested; /**< Ask the application some authentication information */
|
||||
CallLogUpdated call_log_updated; /**< Notifies that call log list has been updated */
|
||||
TextMessageReceived text_received; /**< A text message has been received */
|
||||
DtmfReceived dtmf_received; /**< A dtmf has been received received */
|
||||
ReferReceived refer_received; /**< An out of call refer was received */
|
||||
BuddyInfoUpdated buddy_info_updated; /**< a LinphoneFriend's BuddyInfo has changed*/
|
||||
NotifyReceivedCb notify_recv; /**< Other notifications*/
|
||||
DisplayStatusCb display_status; /**< Callback that notifies various events with human readable text.*/
|
||||
DisplayMessageCb display_message;/**< Callback to display a message to the user */
|
||||
DisplayMessageCb display_warning;/** Callback to display a warning to the user */
|
||||
DisplayUrlCb display_url;
|
||||
DisplayQuestionCb display_question;
|
||||
CallLogUpdated call_log_updated; /**< Notifies that call log list has been updated */
|
||||
TextMessageReceived text_received; /**< A text message has been received */
|
||||
GeneralStateChange general_state; /**< State notification callback */
|
||||
DtmfReceived dtmf_received; /**< A dtmf has been received received */
|
||||
ReferReceived refer_received; /**< A refer was received */
|
||||
BuddyInfoUpdated buddy_info_updated; /**< a LinphoneFriend's BuddyInfo has changed*/
|
||||
NotifyReceivedCb notify_recv; /**< Other notifications*/
|
||||
ShowInterfaceCb show; /**< Notifies the application that it should show up*/
|
||||
} LinphoneCoreVTable;
|
||||
|
||||
/**
|
||||
|
|
@ -474,9 +558,9 @@ typedef struct _LCCallbackObj
|
|||
|
||||
|
||||
typedef enum _LinphoneFirewallPolicy{
|
||||
LINPHONE_POLICY_NO_FIREWALL,
|
||||
LINPHONE_POLICY_USE_NAT_ADDRESS,
|
||||
LINPHONE_POLICY_USE_STUN
|
||||
LinphonePolicyNoFirewall,
|
||||
LinphonePolicyUseNatAddress,
|
||||
LinphonePolicyUseStun
|
||||
} LinphoneFirewallPolicy;
|
||||
|
||||
typedef enum _LinphoneWaitingState{
|
||||
|
|
@ -486,7 +570,6 @@ typedef enum _LinphoneWaitingState{
|
|||
} LinphoneWaitingState;
|
||||
typedef void * (*LinphoneWaitingCallback)(struct _LinphoneCore *lc, void *context, LinphoneWaitingState ws, const char *purpose, float progress);
|
||||
|
||||
typedef struct _LinphoneCore LinphoneCore;
|
||||
|
||||
/* THE main API */
|
||||
|
||||
|
|
@ -505,21 +588,41 @@ void linphone_core_iterate(LinphoneCore *lc);
|
|||
|
||||
LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url);
|
||||
|
||||
int linphone_core_invite(LinphoneCore *lc, const char *url);
|
||||
LinphoneCall * linphone_core_invite(LinphoneCore *lc, const char *url);
|
||||
|
||||
int linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *addr);
|
||||
LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *addr);
|
||||
|
||||
int linphone_core_refer(LinphoneCore *lc, const char *url);
|
||||
LinphoneCall * linphone_core_invite_with_params(LinphoneCore *lc, const char *url, const LinphoneCallParams *params);
|
||||
|
||||
LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const LinphoneAddress *addr, const LinphoneCallParams *params);
|
||||
|
||||
int linphone_core_transfer_call(LinphoneCore *lc, LinphoneCall *call, const char *refer_to);
|
||||
|
||||
int linphone_core_transfer_call_to_another(LinphoneCore *lc, LinphoneCall *call, LinphoneCall *dest);
|
||||
|
||||
bool_t linphone_core_inc_invite_pending(LinphoneCore*lc);
|
||||
|
||||
bool_t linphone_core_in_call(const LinphoneCore *lc);
|
||||
|
||||
LinphoneCall *linphone_core_get_current_call(LinphoneCore *lc);
|
||||
LinphoneCall *linphone_core_get_current_call(const LinphoneCore *lc);
|
||||
|
||||
int linphone_core_accept_call(LinphoneCore *lc, const char *url);
|
||||
int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call);
|
||||
|
||||
int linphone_core_terminate_call(LinphoneCore *lc, const char *url);
|
||||
int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *call);
|
||||
|
||||
int linphone_core_terminate_all_calls(LinphoneCore *lc);
|
||||
|
||||
int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call);
|
||||
|
||||
int linphone_core_pause_all_calls(LinphoneCore *lc);
|
||||
|
||||
int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call);
|
||||
|
||||
int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, LinphoneCallParams *params);
|
||||
|
||||
LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc);
|
||||
|
||||
LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const char *remote_address);
|
||||
|
||||
void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf);
|
||||
|
||||
|
|
@ -527,6 +630,8 @@ int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact);
|
|||
|
||||
const char *linphone_core_get_primary_contact(LinphoneCore *lc);
|
||||
|
||||
const char * linphone_core_get_identity(LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_guess_hostname(LinphoneCore *lc, bool_t val);
|
||||
bool_t linphone_core_get_guess_hostname(LinphoneCore *lc);
|
||||
|
||||
|
|
@ -534,7 +639,7 @@ bool_t linphone_core_ipv6_enabled(LinphoneCore *lc);
|
|||
void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val);
|
||||
|
||||
LinphoneAddress *linphone_core_get_primary_contact_parsed(LinphoneCore *lc);
|
||||
|
||||
const char * linphone_core_get_identity(LinphoneCore *lc);
|
||||
/*0= no bandwidth limit*/
|
||||
void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw);
|
||||
void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw);
|
||||
|
|
@ -553,13 +658,6 @@ void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime);
|
|||
*/
|
||||
int linphone_core_get_download_ptime(LinphoneCore *lc);
|
||||
|
||||
#ifdef VINCENT_MAURY_RSVP
|
||||
/* QoS functions */
|
||||
int linphone_core_set_rpc_mode(LinphoneCore *lc, int on); /* on = 1 (RPC_ENABLE = 1) */
|
||||
int linphone_core_set_rsvp_mode(LinphoneCore *lc, int on); /* on = 1 (RSVP_ENABLE = 1) */
|
||||
int linphone_core_change_qos(LinphoneCore *lc, int answer); /* answer = 1 for yes, 0 for no */
|
||||
#endif
|
||||
|
||||
/* returns a MSList of PayloadType */
|
||||
const MSList *linphone_core_get_audio_codecs(const LinphoneCore *lc);
|
||||
|
||||
|
|
@ -573,12 +671,6 @@ bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, PayloadType *pt);
|
|||
|
||||
int linphone_core_enable_payload_type(LinphoneCore *lc, PayloadType *pt, bool_t enable);
|
||||
|
||||
/*
|
||||
* get payload type from mime type an clock rate
|
||||
* @ingroup media_parameters
|
||||
* iterates both audio an video
|
||||
* return NULL if not found
|
||||
*/
|
||||
PayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate) ;
|
||||
|
||||
const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt);
|
||||
|
|
@ -692,6 +784,10 @@ void linphone_core_set_ring(LinphoneCore *lc, const char *path);
|
|||
const char *linphone_core_get_ring(const LinphoneCore *lc);
|
||||
void linphone_core_set_ringback(LinphoneCore *lc, const char *path);
|
||||
const char * linphone_core_get_ringback(const LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_remote_ringback_tone(LinphoneCore *lc,const char *);
|
||||
const char *linphone_core_get_remote_ringback_tone(const LinphoneCore *lc);
|
||||
|
||||
int linphone_core_preview_ring(LinphoneCore *lc, const char *ring,LinphoneCoreCbFunc func,void * userdata);
|
||||
void linphone_core_enable_echo_cancellation(LinphoneCore *lc, bool_t val);
|
||||
bool_t linphone_core_echo_cancellation_enabled(LinphoneCore *lc);
|
||||
|
|
@ -716,20 +812,6 @@ bool_t linphone_core_is_rtp_muted(LinphoneCore *lc);
|
|||
bool_t linphone_core_get_rtp_no_xmit_on_audio_mute(const LinphoneCore *lc);
|
||||
void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, bool_t val);
|
||||
|
||||
void linphone_core_set_presence_info(LinphoneCore *lc,int minutes_away,const char *contact,LinphoneOnlineStatus os);
|
||||
|
||||
LinphoneOnlineStatus linphone_core_get_presence_info(const LinphoneCore *lc);
|
||||
|
||||
void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char **result);
|
||||
void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *fr);
|
||||
void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *fr);
|
||||
void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf);
|
||||
/* a list of LinphoneFriend */
|
||||
const MSList * linphone_core_get_friend_list(const LinphoneCore *lc);
|
||||
/* notify all friends that have subscribed */
|
||||
void linphone_core_notify_all_friends(LinphoneCore *lc, LinphoneOnlineStatus os);
|
||||
LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, const char *addr);
|
||||
LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key);
|
||||
|
||||
/* returns a list of LinphoneCallLog */
|
||||
const MSList * linphone_core_get_call_logs(LinphoneCore *lc);
|
||||
|
|
@ -764,18 +846,29 @@ const char *linphone_core_get_video_device(const LinphoneCore *lc);
|
|||
/* Set static picture to be used when "Static picture" is the video device */
|
||||
int linphone_core_set_static_picture(LinphoneCore *lc, const char *path);
|
||||
|
||||
/* Set and get frame rate for static picture */
|
||||
int linphone_core_set_static_picture_fps(LinphoneCore *lc, float fps);
|
||||
float linphone_core_get_static_picture_fps(LinphoneCore *lc);
|
||||
|
||||
/*function to be used for eventually setting window decorations (icons, title...)*/
|
||||
unsigned long linphone_core_get_native_video_window_id(const LinphoneCore *lc);
|
||||
void linphone_core_set_native_video_window_id(LinphoneCore *lc, unsigned long id);
|
||||
|
||||
unsigned long linphone_core_get_native_preview_window_id(const LinphoneCore *lc);
|
||||
void linphone_core_set_native_preview_window_id(LinphoneCore *lc, unsigned long id);
|
||||
|
||||
void linphone_core_use_preview_window(LinphoneCore *lc, bool_t yesno);
|
||||
|
||||
/*play/record support: use files instead of soundcard*/
|
||||
void linphone_core_use_files(LinphoneCore *lc, bool_t yesno);
|
||||
void linphone_core_set_play_file(LinphoneCore *lc, const char *file);
|
||||
void linphone_core_set_record_file(LinphoneCore *lc, const char *file);
|
||||
|
||||
gstate_t linphone_core_get_state(const LinphoneCore *lc, gstate_group_t group);
|
||||
void linphone_core_play_dtmf(LinphoneCore *lc, char dtmf, int duration_ms);
|
||||
void linphone_core_stop_dtmf(LinphoneCore *lc);
|
||||
|
||||
int linphone_core_get_current_call_duration(const LinphoneCore *lc);
|
||||
const LinphoneAddress *linphone_core_get_remote_uri(LinphoneCore *lc);
|
||||
|
||||
|
||||
int linphone_core_get_mtu(const LinphoneCore *lc);
|
||||
void linphone_core_set_mtu(LinphoneCore *lc, int mtu);
|
||||
|
|
@ -821,8 +914,14 @@ void linphone_core_set_audio_transports(LinphoneCore *lc, RtpTransport *rtp, Rtp
|
|||
|
||||
int linphone_core_get_current_call_stats(LinphoneCore *lc, rtp_stats_t *local, rtp_stats_t *remote);
|
||||
|
||||
const MSList *linphone_core_get_calls(LinphoneCore *lc);
|
||||
|
||||
LinphoneGlobalState linphone_core_get_global_state(const LinphoneCore *lc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ extern "C" void libmsilbc_init();
|
|||
#endif /*ANDROID*/
|
||||
|
||||
extern "C" void ms_andsnd_set_jvm(JavaVM *jvm) ;
|
||||
extern "C" void ms_andvid_set_jvm(JavaVM *jvm) ;
|
||||
|
||||
static JavaVM *jvm=0;
|
||||
|
||||
#ifdef ANDROID
|
||||
|
|
@ -45,6 +47,9 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *ajvm, void *reserved)
|
|||
{
|
||||
#ifdef ANDROID
|
||||
ms_andsnd_set_jvm(ajvm);
|
||||
#ifdef VIDEO_ENABLED
|
||||
ms_andvid_set_jvm(ajvm);
|
||||
#endif /*VIDEO_ENABLED*/
|
||||
#endif /*ANDROID*/
|
||||
jvm=ajvm;
|
||||
return JNI_VERSION_1_2;
|
||||
|
|
@ -72,21 +77,57 @@ public:
|
|||
userdata = auserdata?env->NewGlobalRef(auserdata):0;
|
||||
memset(&vTable,0,sizeof(vTable));
|
||||
vTable.show = showInterfaceCb;
|
||||
vTable.inv_recv = inviteReceivedCb;
|
||||
vTable.auth_info_requested = authInfoRequested;
|
||||
vTable.display_status = displayStatusCb;
|
||||
vTable.display_message = displayMessageCb;
|
||||
vTable.display_warning = displayMessageCb;
|
||||
vTable.general_state = generalStateChange;
|
||||
vTable.global_state_changed = globalStateChange;
|
||||
vTable.registration_state_changed = registrationStateChange;
|
||||
vTable.call_state_changed = callStateChange;
|
||||
vTable.text_received = text_received;
|
||||
vTable.new_subscription_request = new_subscription_request;
|
||||
vTable.notify_presence_recv = notify_presence_recv;
|
||||
|
||||
listernerClass = (jclass)env->NewGlobalRef(env->GetObjectClass( alistener));
|
||||
/*displayStatus(LinphoneCore lc,String message);*/
|
||||
displayStatusId = env->GetMethodID(listernerClass,"displayStatus","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;)V");
|
||||
/*void generalState(LinphoneCore lc,int state); */
|
||||
generalStateId = env->GetMethodID(listernerClass,"generalState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$GeneralState;Ljava/lang/String;)V");
|
||||
globalStateId = env->GetMethodID(listernerClass,"globalState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$GlobalState;Ljava/lang/String;)V");
|
||||
globalStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$GlobalState"));
|
||||
globalStateFromIntId = env->GetStaticMethodID(globalStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$GlobalState;");
|
||||
/*registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage);*/
|
||||
registrationStateId = env->GetMethodID(listernerClass,"registrationState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneProxyConfig;Lorg/linphone/core/LinphoneCore$RegistrationState;Ljava/lang/String;)V");
|
||||
registrationStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$RegistrationState"));
|
||||
registrationStateFromIntId = env->GetStaticMethodID(registrationStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$RegistrationState;");
|
||||
/*callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message);*/
|
||||
callStateId = env->GetMethodID(listernerClass,"callState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;Ljava/lang/String;)V");
|
||||
callStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCall$State"));
|
||||
callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;");
|
||||
|
||||
/*void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url)*/
|
||||
newSubscriptionRequestId = env->GetMethodID(listernerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V");
|
||||
|
||||
/*void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf);*/
|
||||
notifyPresenceReceivedId = env->GetMethodID(listernerClass,"notifyPresenceReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;)V");
|
||||
|
||||
/*void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message);*/
|
||||
textReceivedId = env->GetMethodID(listernerClass,"textReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Ljava/lang/String;)V");
|
||||
|
||||
proxyClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl"));
|
||||
proxyCtrId = env->GetMethodID(proxyClass,"<init>", "(J)V");
|
||||
|
||||
callClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCallImpl"));
|
||||
callCtrId = env->GetMethodID(callClass,"<init>", "(J)V");
|
||||
|
||||
chatRoomClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatRoomImpl"));
|
||||
chatRoomCtrId = env->GetMethodID(chatRoomClass,"<init>", "(J)V");
|
||||
|
||||
friendClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendImpl"));;
|
||||
friendCtrId =env->GetMethodID(friendClass,"<init>", "(J)V");
|
||||
|
||||
addressClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAddressImpl"));
|
||||
addressCtrId =env->GetMethodID(addressClass,"<init>", "(J)V");
|
||||
|
||||
generalStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$GeneralState"));
|
||||
generalStateFromIntId = env->GetStaticMethodID(generalStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$GeneralState;");
|
||||
}
|
||||
|
||||
~LinphoneCoreData() {
|
||||
|
|
@ -96,24 +137,56 @@ public:
|
|||
env->DeleteGlobalRef(listener);
|
||||
if (userdata) env->DeleteGlobalRef(userdata);
|
||||
env->DeleteGlobalRef(listernerClass);
|
||||
env->DeleteGlobalRef(generalStateClass);
|
||||
env->DeleteGlobalRef(globalStateClass);
|
||||
env->DeleteGlobalRef(registrationStateClass);
|
||||
env->DeleteGlobalRef(callStateClass);
|
||||
env->DeleteGlobalRef(proxyClass);
|
||||
env->DeleteGlobalRef(callClass);
|
||||
env->DeleteGlobalRef(chatRoomClass);
|
||||
env->DeleteGlobalRef(friendClass);
|
||||
|
||||
}
|
||||
jobject core;
|
||||
jobject listener;
|
||||
jobject userdata;
|
||||
|
||||
jclass listernerClass;
|
||||
jclass generalStateClass;
|
||||
jmethodID displayStatusId;
|
||||
jmethodID generalStateId;
|
||||
jmethodID generalStateFromIntId;
|
||||
jmethodID newSubscriptionRequestId;
|
||||
jmethodID notifyPresenceReceivedId;
|
||||
jmethodID textReceivedId;
|
||||
|
||||
jclass globalStateClass;
|
||||
jmethodID globalStateId;
|
||||
jmethodID globalStateFromIntId;
|
||||
|
||||
jclass registrationStateClass;
|
||||
jmethodID registrationStateId;
|
||||
jmethodID registrationStateFromIntId;
|
||||
|
||||
jclass callStateClass;
|
||||
jmethodID callStateId;
|
||||
jmethodID callStateFromIntId;
|
||||
|
||||
jclass proxyClass;
|
||||
jmethodID proxyCtrId;
|
||||
|
||||
jclass callClass;
|
||||
jmethodID callCtrId;
|
||||
|
||||
jclass chatRoomClass;
|
||||
jmethodID chatRoomCtrId;
|
||||
|
||||
jclass friendClass;
|
||||
jmethodID friendCtrId;
|
||||
|
||||
jclass addressClass;
|
||||
jmethodID addressCtrId;
|
||||
|
||||
LinphoneCoreVTable vTable;
|
||||
|
||||
static void showInterfaceCb(LinphoneCore *lc) {
|
||||
|
||||
}
|
||||
static void inviteReceivedCb(LinphoneCore *lc, const char *from) {
|
||||
|
||||
}
|
||||
static void byeReceivedCb(LinphoneCore *lc, const char *from) {
|
||||
|
||||
|
|
@ -134,7 +207,7 @@ public:
|
|||
static void authInfoRequested(LinphoneCore *lc, const char *realm, const char *username) {
|
||||
|
||||
}
|
||||
static void generalStateChange(LinphoneCore *lc, LinphoneGeneralState *gstate) {
|
||||
static void globalStateChange(LinphoneCore *lc, LinphoneGlobalState gstate,const char* message) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
|
|
@ -143,11 +216,84 @@ public:
|
|||
}
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
|
||||
env->CallVoidMethod(lcData->listener
|
||||
,lcData->generalStateId
|
||||
,lcData->globalStateId
|
||||
,lcData->core
|
||||
,env->CallStaticObjectMethod(lcData->generalStateClass,lcData->generalStateFromIntId,gstate->new_state),
|
||||
gstate->message ? env->NewStringUTF(gstate->message) : NULL);
|
||||
,env->CallStaticObjectMethod(lcData->globalStateClass,lcData->globalStateFromIntId,(jint)gstate),
|
||||
message ? env->NewStringUTF(message) : NULL);
|
||||
}
|
||||
static void registrationStateChange(LinphoneCore *lc, LinphoneProxyConfig* proxy,LinphoneRegistrationState state,const char* message) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM\n");
|
||||
return;
|
||||
}
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
|
||||
env->CallVoidMethod(lcData->listener
|
||||
,lcData->registrationStateId
|
||||
,lcData->core
|
||||
,env->NewObject(lcData->proxyClass,lcData->proxyCtrId,(jlong)proxy)
|
||||
,env->CallStaticObjectMethod(lcData->registrationStateClass,lcData->registrationStateFromIntId,(jint)state),
|
||||
message ? env->NewStringUTF(message) : NULL);
|
||||
}
|
||||
static void callStateChange(LinphoneCore *lc, LinphoneCall* call,LinphoneCallState state,const char* message) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM\n");
|
||||
return;
|
||||
}
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
|
||||
env->CallVoidMethod(lcData->listener
|
||||
,lcData->callStateId
|
||||
,lcData->core
|
||||
,env->NewObject(lcData->callClass,lcData->callCtrId,(jlong)call)
|
||||
,env->CallStaticObjectMethod(lcData->callStateClass,lcData->callStateFromIntId,(jint)state),
|
||||
message ? env->NewStringUTF(message) : NULL);
|
||||
}
|
||||
static void notify_presence_recv (LinphoneCore *lc, LinphoneFriend *my_friend) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM\n");
|
||||
return;
|
||||
}
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
|
||||
env->CallVoidMethod(lcData->listener
|
||||
,lcData->notifyPresenceReceivedId
|
||||
,lcData->core
|
||||
,env->NewObject(lcData->friendClass,lcData->friendCtrId,(jlong)my_friend));
|
||||
}
|
||||
static void new_subscription_request (LinphoneCore *lc, LinphoneFriend *my_friend, const char* url) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM\n");
|
||||
return;
|
||||
}
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
|
||||
env->CallVoidMethod(lcData->listener
|
||||
,lcData->newSubscriptionRequestId
|
||||
,lcData->core
|
||||
,env->NewObject(lcData->friendClass,lcData->friendCtrId,(jlong)my_friend)
|
||||
,url ? env->NewStringUTF(url) : NULL);
|
||||
}
|
||||
static void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM\n");
|
||||
return;
|
||||
}
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
|
||||
env->CallVoidMethod(lcData->listener
|
||||
,lcData->textReceivedId
|
||||
,lcData->core
|
||||
,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room)
|
||||
,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)from)
|
||||
,message ? env->NewStringUTF(message) : NULL);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* env
|
||||
|
|
@ -157,8 +303,8 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv*
|
|||
,jstring jfactoryConfig
|
||||
,jobject juserdata){
|
||||
|
||||
const char* userConfig = env->GetStringUTFChars(juserConfig, NULL);
|
||||
const char* factoryConfig = env->GetStringUTFChars(jfactoryConfig, NULL);
|
||||
const char* userConfig = juserConfig?env->GetStringUTFChars(juserConfig, NULL):NULL;
|
||||
const char* factoryConfig = jfactoryConfig?env->GetStringUTFChars(jfactoryConfig, NULL):NULL;
|
||||
LinphoneCoreData* ldata = new LinphoneCoreData(env,thiz,jlistener,juserdata);
|
||||
#ifdef ANDROID
|
||||
ms_andsnd_set_jvm(jvm);
|
||||
|
|
@ -176,8 +322,8 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv*
|
|||
//clear existing proxy config
|
||||
linphone_core_clear_proxy_config((LinphoneCore*) nativePtr);
|
||||
|
||||
env->ReleaseStringUTFChars(juserConfig, userConfig);
|
||||
env->ReleaseStringUTFChars(jfactoryConfig, factoryConfig);
|
||||
if (userConfig) env->ReleaseStringUTFChars(juserConfig, userConfig);
|
||||
if (factoryConfig) env->ReleaseStringUTFChars(jfactoryConfig, factoryConfig);
|
||||
return nativePtr;
|
||||
}
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_delete(JNIEnv* env
|
||||
|
|
@ -232,31 +378,33 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_iterate( JNIEnv* env
|
|||
,jlong lc) {
|
||||
linphone_core_iterate((LinphoneCore*)lc);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_invite( JNIEnv* env
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_invite( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jstring juri) {
|
||||
const char* uri = env->GetStringUTFChars(juri, NULL);
|
||||
linphone_core_invite((LinphoneCore*)lc,uri);
|
||||
LinphoneCall* lCall = linphone_core_invite((LinphoneCore*)lc,uri);
|
||||
env->ReleaseStringUTFChars(juri, uri);
|
||||
return (jlong)lCall;
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_inviteAddress( JNIEnv* env
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_inviteAddress( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jlong to) {
|
||||
linphone_core_invite_address((LinphoneCore*)lc,(LinphoneAddress*)to);
|
||||
return (jlong) linphone_core_invite_address((LinphoneCore*)lc,(LinphoneAddress*)to);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_terminateCall( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc) {
|
||||
linphone_core_terminate_call((LinphoneCore*)lc,NULL);
|
||||
,jlong lc
|
||||
,jlong call) {
|
||||
linphone_core_terminate_call((LinphoneCore*)lc,(LinphoneCall*)call);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getRemoteAddress( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc) {
|
||||
return (jlong)linphone_core_get_remote_uri((LinphoneCore*)lc);
|
||||
return (jlong)linphone_core_get_current_call_remote_address((LinphoneCore*)lc);
|
||||
}
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_isInCall( JNIEnv* env
|
||||
,jobject thiz
|
||||
|
|
@ -272,9 +420,10 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_isInComingInvitePend
|
|||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_acceptCall( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc) {
|
||||
,jlong lc
|
||||
,jlong call) {
|
||||
|
||||
linphone_core_accept_call((LinphoneCore*)lc,NULL);
|
||||
linphone_core_accept_call((LinphoneCore*)lc,(LinphoneCall*)call);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getCallLog( JNIEnv* env
|
||||
|
|
@ -330,6 +479,19 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_sendDtmf( JNIEnv* env
|
|||
,jchar dtmf) {
|
||||
linphone_core_send_dtmf((LinphoneCore*)lc,dtmf);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_playDtmf( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jchar dtmf
|
||||
,jint duration) {
|
||||
linphone_core_play_dtmf((LinphoneCore*)lc,dtmf,duration);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_stopDtmf( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc) {
|
||||
linphone_core_stop_dtmf((LinphoneCore*)lc);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_clearCallLogs(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc) {
|
||||
|
|
@ -370,6 +532,74 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_isEchoCancellationEn
|
|||
return linphone_core_echo_cancellation_enabled((LinphoneCore*)lc);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getCurrentCall(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
) {
|
||||
return (jlong)linphone_core_get_current_call((LinphoneCore*)lc);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addFriend(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jlong aFriend
|
||||
) {
|
||||
linphone_core_add_friend((LinphoneCore*)lc,(LinphoneFriend*)aFriend);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPresenceInfo(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jint minute_away
|
||||
,jstring jalternative_contact
|
||||
,jint status) {
|
||||
const char* alternative_contact = jalternative_contact?env->GetStringUTFChars(jalternative_contact, NULL):NULL;
|
||||
linphone_core_set_presence_info((LinphoneCore*)lc,minute_away,alternative_contact,(LinphoneOnlineStatus)status);
|
||||
if (alternative_contact) env->ReleaseStringUTFChars(jalternative_contact, alternative_contact);
|
||||
}
|
||||
|
||||
extern "C" long Java_org_linphone_core_LinphoneCoreImpl_createChatRoom(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jstring jto) {
|
||||
|
||||
const char* to = env->GetStringUTFChars(jto, NULL);
|
||||
LinphoneChatRoom* lResult = linphone_core_create_chat_room((LinphoneCore*)lc,to);
|
||||
env->ReleaseStringUTFChars(jto, to);
|
||||
return (long)lResult;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_enableVideo(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jboolean vcap_enabled
|
||||
,jboolean display_enabled) {
|
||||
linphone_core_enable_video((LinphoneCore*)lc, vcap_enabled,display_enabled);
|
||||
|
||||
}
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_isVideoEnabled(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc) {
|
||||
return linphone_core_video_enabled((LinphoneCore*)lc);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setRing(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jstring jpath) {
|
||||
const char* path = jpath?env->GetStringUTFChars(jpath, NULL):NULL;
|
||||
linphone_core_set_ring((LinphoneCore*)lc,path);
|
||||
if (path) env->ReleaseStringUTFChars(jpath, path);
|
||||
}
|
||||
extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getRing(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
) {
|
||||
const char* path = linphone_core_get_ring((LinphoneCore*)lc);
|
||||
if (path) {
|
||||
return env->NewStringUTF(path);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//ProxyConfig
|
||||
|
||||
|
|
@ -409,10 +639,14 @@ extern "C" jstring Java_org_linphone_core_LinphoneProxyConfigImpl_getProxy(JNIEn
|
|||
}
|
||||
}
|
||||
extern "C" int Java_org_linphone_core_LinphoneProxyConfigImpl_setRoute(JNIEnv* env,jobject thiz,jlong proxyCfg,jstring jroute) {
|
||||
const char* route = env->GetStringUTFChars(jroute, NULL);
|
||||
int err=linphone_proxy_config_set_route((LinphoneProxyConfig*)proxyCfg,route);
|
||||
env->ReleaseStringUTFChars(jroute, route);
|
||||
return err;
|
||||
if (jroute != NULL) {
|
||||
const char* route = env->GetStringUTFChars(jroute, NULL);
|
||||
int err=linphone_proxy_config_set_route((LinphoneProxyConfig*)proxyCfg,route);
|
||||
env->ReleaseStringUTFChars(jroute, route);
|
||||
return err;
|
||||
} else {
|
||||
return linphone_proxy_config_set_route((LinphoneProxyConfig*)proxyCfg,NULL);
|
||||
}
|
||||
}
|
||||
extern "C" jstring Java_org_linphone_core_LinphoneProxyConfigImpl_getRoute(JNIEnv* env,jobject thiz,jlong proxyCfg) {
|
||||
const char* route = linphone_proxy_config_get_route((LinphoneProxyConfig*)proxyCfg);
|
||||
|
|
@ -477,6 +711,7 @@ extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_setDialPrefix(JNI
|
|||
env->ReleaseStringUTFChars(jprefix, prefix);
|
||||
}
|
||||
|
||||
|
||||
//Auth Info
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneAuthInfoImpl_newLinphoneAuthInfo(JNIEnv* env
|
||||
|
|
@ -612,3 +847,203 @@ extern "C" jstring Java_org_linphone_core_PayloadTypeImpl_toString(JNIEnv* env
|
|||
ms_free(value);
|
||||
return jvalue;
|
||||
}
|
||||
//LinphoneCall
|
||||
extern "C" void Java_org_linphone_core_LinphoneCallImpl_ref(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
linphone_call_ref((LinphoneCall*)ptr);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCallImpl_unref(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
linphone_call_unref((LinphoneCall*)ptr);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCallLog( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return (jlong)linphone_call_get_call_log((LinphoneCall*)ptr);
|
||||
}
|
||||
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_isIncoming( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return linphone_call_get_dir((LinphoneCall*)ptr)==LinphoneCallIncoming?JNI_TRUE:JNI_FALSE;
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getRemoteAddress( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return (jlong)linphone_call_get_remote_address((LinphoneCall*)ptr);
|
||||
}
|
||||
|
||||
extern "C" jint Java_org_linphone_core_LinphoneCallImpl_getState( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return (jint)linphone_call_get_state((LinphoneCall*)ptr);
|
||||
}
|
||||
|
||||
//LinphoneFriend
|
||||
extern "C" long Java_org_linphone_core_LinphoneFriendImpl_newLinphoneFriend(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jstring jFriendUri) {
|
||||
LinphoneFriend* lResult;
|
||||
|
||||
if (jFriendUri) {
|
||||
const char* friendUri = env->GetStringUTFChars(jFriendUri, NULL);
|
||||
lResult= linphone_friend_new_with_addr(friendUri);
|
||||
env->ReleaseStringUTFChars(jFriendUri, friendUri);
|
||||
} else {
|
||||
lResult = linphone_friend_new();
|
||||
}
|
||||
return (long)lResult;
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setAddress(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr
|
||||
,jlong linphoneAddress) {
|
||||
linphone_friend_set_addr((LinphoneFriend*)ptr,(LinphoneAddress*)linphoneAddress);
|
||||
}
|
||||
extern "C" long Java_org_linphone_core_LinphoneFriendImpl_getAddress(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return (long)linphone_friend_get_address((LinphoneFriend*)ptr);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setIncSubscribePolicy(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr
|
||||
,jint policy) {
|
||||
linphone_friend_set_inc_subscribe_policy((LinphoneFriend*)ptr,(LinphoneSubscribePolicy)policy);
|
||||
}
|
||||
extern "C" jint Java_org_linphone_core_LinphoneFriendImpl_getIncSubscribePolicy(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return linphone_friend_get_inc_subscribe_policy((LinphoneFriend*)ptr);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendImpl_enableSubscribes(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr
|
||||
,jboolean value) {
|
||||
linphone_friend_enable_subscribes((LinphoneFriend*)ptr,value);
|
||||
}
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneFriendImpl_isSubscribesEnabled(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return linphone_friend_subscribes_enabled((LinphoneFriend*)ptr);
|
||||
}
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneFriendImpl_getStatus(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return linphone_friend_get_status((LinphoneFriend*)ptr);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendImpl_edit(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return linphone_friend_edit((LinphoneFriend*)ptr);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendImpl_done(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
linphone_friend_done((LinphoneFriend*)ptr);
|
||||
}
|
||||
//LinphoneChatRoom
|
||||
extern "C" long Java_org_linphone_core_LinphoneChatRoomImpl_getPeerAddress(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return (long) linphone_chat_room_get_peer_address((LinphoneChatRoom*)ptr);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr
|
||||
,jstring jmessage) {
|
||||
const char* message = env->GetStringUTFChars(jmessage, NULL);
|
||||
linphone_chat_room_send_message((LinphoneChatRoom*)ptr,message);
|
||||
env->ReleaseStringUTFChars(jmessage, message);
|
||||
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jobject obj) {
|
||||
linphone_core_set_native_video_window_id((LinphoneCore*)lc,(unsigned long)obj);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setFirewallPolicy(JNIEnv *env, jobject thiz, jlong lc, int enum_value){
|
||||
linphone_core_set_firewall_policy((LinphoneCore*)lc,(LinphoneFirewallPolicy)enum_value);
|
||||
}
|
||||
|
||||
extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getFirewallPolicy(JNIEnv *env, jobject thiz, jlong lc){
|
||||
return linphone_core_get_firewall_policy((LinphoneCore*)lc);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setStunServer(JNIEnv *env, jobject thiz, jlong lc, jstring jserver){
|
||||
const char* server = NULL;
|
||||
if (jserver) server=env->GetStringUTFChars(jserver, NULL);
|
||||
linphone_core_set_stun_server((LinphoneCore*)lc,server);
|
||||
if (server) env->ReleaseStringUTFChars(jserver,server);
|
||||
}
|
||||
|
||||
extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getStunServer(JNIEnv *env, jobject thiz, jlong lc){
|
||||
const char *ret= linphone_core_get_stun_server((LinphoneCore*)lc);
|
||||
if (ret==NULL) return NULL;
|
||||
jstring jvalue =env->NewStringUTF(ret);
|
||||
return jvalue;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_enableVideo(JNIEnv *env, jobject thiz, jlong lcp, jboolean b){
|
||||
linphone_call_params_enable_video((LinphoneCallParams*)lcp, b);
|
||||
}
|
||||
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_getVideoEnabled(JNIEnv *env, jobject thiz, jlong lcp){
|
||||
return linphone_call_params_video_enabled((LinphoneCallParams*)lcp);
|
||||
}
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallParamsImpl_copy(JNIEnv *env, jobject thiz, jlong lcp){
|
||||
return (jlong) linphone_call_params_copy((LinphoneCallParams*)lcp);
|
||||
}
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createDefaultCallParams(JNIEnv *env, jobject thiz, jlong lc){
|
||||
return (jlong) linphone_core_create_default_call_parameters((LinphoneCore*)lc);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCurrentParams(JNIEnv *env, jobject thiz, jlong lc){
|
||||
return (jlong) linphone_call_get_current_params((LinphoneCall*)lc);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_inviteAddressWithParams(JNIEnv *env, jobject thiz, jlong lc, jlong addr, jlong params){
|
||||
return (jlong) linphone_core_invite_address_with_params((LinphoneCore *)lc, (const LinphoneAddress *)addr, (const LinphoneCallParams *)params);
|
||||
}
|
||||
|
||||
extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_updateAddressWithParams(JNIEnv *env, jobject thiz, jlong lc, jlong call, jlong params){
|
||||
return (jint) linphone_core_update_call((LinphoneCore *)lc, (LinphoneCall *)call, (LinphoneCallParams *)params);
|
||||
}
|
||||
|
||||
extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_updateCall(JNIEnv *env, jobject thiz, jlong lc, jlong call, jlong params){
|
||||
return (jint) linphone_core_update_call((LinphoneCore *)lc, (LinphoneCall *)call, (LinphoneCallParams *)params);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPreferredVideoSize(JNIEnv *env, jobject thiz, jlong lc, jint width, jint height){
|
||||
MSVideoSize vsize;
|
||||
vsize.width = (int)width;
|
||||
vsize.height = (int)height;
|
||||
linphone_core_set_preferred_video_size((LinphoneCore *)lc, vsize);
|
||||
}
|
||||
|
||||
extern "C" jintArray Java_org_linphone_core_LinphoneCoreImpl_getPreferredVideoSize(JNIEnv *env, jobject thiz, jlong lc){
|
||||
MSVideoSize vsize = linphone_core_get_preferred_video_size((LinphoneCore *)lc);
|
||||
jintArray arr = env->NewIntArray(2);
|
||||
int tVsize [2]= {vsize.width,vsize.height};
|
||||
env->SetIntArrayRegion(arr, 0, 2, tVsize);
|
||||
return arr;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDownloadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){
|
||||
linphone_core_set_download_bandwidth((LinphoneCore *)lc, (int) bw);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setUploadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){
|
||||
linphone_core_set_upload_bandwidth((LinphoneCore *)lc, (int) bw);
|
||||
}
|
||||
|
||||
|
|
|
|||
52
coreapi/linphonecore_utils.h
Normal file
52
coreapi/linphonecore_utils.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2010 Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef LINPHONECORE_UTILS_H
|
||||
#define LINPHONECORE_UTILS_H
|
||||
|
||||
#ifdef IN_LINPHONE
|
||||
#include "linphonecore.h"
|
||||
#else
|
||||
#include "linphone/linphonecore.h"
|
||||
#endif
|
||||
|
||||
typedef struct _LsdPlayer LsdPlayer;
|
||||
typedef struct _LinphoneSoundDaemon LinphoneSoundDaemon;
|
||||
|
||||
typedef void (*LsdEndOfPlayCallback)(LsdPlayer *p);
|
||||
|
||||
void lsd_player_set_callback(LsdPlayer *p, LsdEndOfPlayCallback cb);
|
||||
void lsd_player_set_user_pointer(LsdPlayer *p, void *up);
|
||||
void *lsd_player_get_user_pointer(const LsdPlayer *p);
|
||||
int lsd_player_play(LsdPlayer *p, const char *filename);
|
||||
int lsd_player_stop(LsdPlayer *p);
|
||||
void lsd_player_enable_loop(LsdPlayer *p, bool_t loopmode);
|
||||
bool_t lsd_player_loop_enabled(const LsdPlayer *p);
|
||||
void lsd_player_set_gain(LsdPlayer *p, float gain);
|
||||
LinphoneSoundDaemon *lsd_player_get_daemon(const LsdPlayer *p);
|
||||
|
||||
LinphoneSoundDaemon * linphone_sound_daemon_new(const char *cardname, int rate, int nchannels);
|
||||
LsdPlayer * linphone_sound_daemon_get_player(LinphoneSoundDaemon *lsd);
|
||||
void linphone_sound_daemon_release_player(LinphoneSoundDaemon *lsd, LsdPlayer *lsdplayer);
|
||||
void linphone_sound_daemon_stop_all_players(LinphoneSoundDaemon *obj);
|
||||
void linphone_sound_daemon_release_all_players(LinphoneSoundDaemon *obj);
|
||||
void linphone_core_use_sound_daemon(LinphoneCore *lc, LinphoneSoundDaemon *lsd);
|
||||
void linphone_sound_daemon_destroy(LinphoneSoundDaemon *obj);
|
||||
|
||||
#endif
|
||||
267
coreapi/linphonefriend.h
Normal file
267
coreapi/linphonefriend.h
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
linphonefriend.h
|
||||
Copyright (C) 2010 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef LINPHONEFRIEND_H_
|
||||
#define LINPHONEFRIEND_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/**
|
||||
* @addtogroup buddy_list
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @ingroup buddy_list
|
||||
* Enum controlling behavior for incoming subscription request.
|
||||
* <br> Use by linphone_friend_set_inc_subscribe_policy()
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* Does not automatically accept an incoming subscription request.
|
||||
* This policy implies that a decision has to be taken for each incoming subscription request notified by callback LinphoneCoreVTable.new_subscription_request
|
||||
*
|
||||
*/
|
||||
LinphoneSPWait,
|
||||
/**
|
||||
* Rejects incoming subscription request.
|
||||
*/
|
||||
LinphoneSPDeny,
|
||||
/**
|
||||
* Automatically accepts a subscription request.
|
||||
*/
|
||||
LinphoneSPAccept
|
||||
}LinphoneSubscribePolicy;
|
||||
|
||||
/**
|
||||
* Enum describing remote friend status
|
||||
*/
|
||||
typedef enum _LinphoneOnlineStatus{
|
||||
/**
|
||||
* Offline
|
||||
*/
|
||||
LinphoneStatusOffline,
|
||||
/**
|
||||
* Online
|
||||
*/
|
||||
LinphoneStatusOnline,
|
||||
/**
|
||||
* Busy
|
||||
*/
|
||||
LinphoneStatusBusy,
|
||||
/**
|
||||
* Be right back
|
||||
*/
|
||||
LinphoneStatusBeRightBack,
|
||||
/**
|
||||
* Away
|
||||
*/
|
||||
LinphoneStatusAway,
|
||||
/**
|
||||
* On the phone
|
||||
*/
|
||||
LinphoneStatusOnThePhone,
|
||||
/**
|
||||
* Out to lunch
|
||||
*/
|
||||
LinphoneStatusOutToLunch,
|
||||
/**
|
||||
* Do not disturb
|
||||
*/
|
||||
LinphoneStatusDoNotDisturb,
|
||||
/**
|
||||
* Moved in this sate, call can be redirected if an alternate contact address has been set using function linphone_core_set_presence_info()
|
||||
*/
|
||||
LinphoneStatusMoved,
|
||||
/**
|
||||
* Using another messaging service
|
||||
*/
|
||||
LinphoneStatusAltService,
|
||||
/**
|
||||
* Pending
|
||||
*/
|
||||
LinphoneStatusPending,
|
||||
|
||||
LinphoneStatusEnd
|
||||
}LinphoneOnlineStatus;
|
||||
|
||||
|
||||
struct _LinphoneFriend;
|
||||
/**
|
||||
* Represents a buddy, all presence actions like subscription and status change notification are performed on this object
|
||||
*/
|
||||
typedef struct _LinphoneFriend LinphoneFriend;
|
||||
|
||||
/**
|
||||
* Contructor
|
||||
* @return a new empty #LinphoneFriend
|
||||
*/
|
||||
LinphoneFriend * linphone_friend_new();
|
||||
/**
|
||||
* Contructor same as linphone_friend_new() + linphone_friend_set_addr()
|
||||
* @param addr a buddy address, must be a sip uri like sip:joe@sip.linphone.org
|
||||
* @return a new #LinphoneFriend with \link linphone_friend_get_address() address initialized \endlink
|
||||
*/
|
||||
LinphoneFriend *linphone_friend_new_with_addr(const char *addr);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
* @param lf #LinphoneFriend object
|
||||
*/
|
||||
void linphone_friend_destroy(LinphoneFriend *lf);
|
||||
|
||||
/**
|
||||
* set #LinphoneAddress for this friend
|
||||
* @param fr #LinphoneFriend object
|
||||
* @param address #LinphoneAddress
|
||||
*/
|
||||
int linphone_friend_set_addr(LinphoneFriend *fr, const LinphoneAddress* address);
|
||||
|
||||
/**
|
||||
* get address of this friend
|
||||
* @param lf #LinphoneFriend object
|
||||
* @return #LinphoneAddress
|
||||
*/
|
||||
const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf);
|
||||
/**
|
||||
* get subscription flag value
|
||||
* @param lf #LinphoneFriend object
|
||||
* @return returns true is subscription is activated for this friend
|
||||
*
|
||||
*/
|
||||
bool_t linphone_friend_subscribes_enabled(const LinphoneFriend *lf);
|
||||
#define linphone_friend_get_send_subscribe linphone_friend_subscribes_enabled
|
||||
|
||||
/**
|
||||
* Configure #LinphoneFriend to subscribe to presence information
|
||||
* @param fr #LinphoneFriend object
|
||||
* @param val if TRUE this friend will receive subscription message
|
||||
*/
|
||||
|
||||
int linphone_friend_enable_subscribes(LinphoneFriend *fr, bool_t val);
|
||||
|
||||
#define linphone_friend_send_subscribe linphone_friend_enable_subscribes
|
||||
/**
|
||||
* Configure incoming subscription policy for this friend.
|
||||
* @param fr #LinphoneFriend object
|
||||
* @param pol #LinphoneSubscribePolicy policy to apply.
|
||||
*/
|
||||
int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscribePolicy pol);
|
||||
/**
|
||||
* get current subscription policy for this #LinphoneFriend
|
||||
* @param lf #LinphoneFriend object
|
||||
* @return #LinphoneSubscribePolicy
|
||||
*
|
||||
*/
|
||||
LinphoneSubscribePolicy linphone_friend_get_inc_subscribe_policy(const LinphoneFriend *lf);
|
||||
|
||||
/**
|
||||
* Starts editing a friend configuration.
|
||||
*
|
||||
* Because friend configuration must be consistent, applications MUST
|
||||
* call linphone_friend_edit() before doing any attempts to modify
|
||||
* friend configuration (such as \link linphone_friend_set_addr() address \endlink or \link linphone_friend_set_inc_subscribe_policy() subscription policy\endlink and so on).
|
||||
* Once the modifications are done, then the application must call
|
||||
* linphone_friend_done() to commit the changes.
|
||||
**/
|
||||
void linphone_friend_edit(LinphoneFriend *fr);
|
||||
/**
|
||||
* Commits modification made to the friend configuration.
|
||||
* @param fr #LinphoneFriend object
|
||||
**/
|
||||
void linphone_friend_done(LinphoneFriend *fr);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* get friend status
|
||||
* @return #LinphoneOnlineStatus
|
||||
*/
|
||||
LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf);
|
||||
BuddyInfo * linphone_friend_get_info(const LinphoneFriend *lf);
|
||||
void linphone_friend_set_ref_key(LinphoneFriend *lf, const char *key);
|
||||
const char *linphone_friend_get_ref_key(const LinphoneFriend *lf);
|
||||
bool_t linphone_friend_in_list(const LinphoneFriend *lf);
|
||||
|
||||
#define linphone_friend_url(lf) ((lf)->url)
|
||||
|
||||
/**
|
||||
* return humain readable presence status
|
||||
* @param ss
|
||||
*/
|
||||
const char *linphone_online_status_to_string(LinphoneOnlineStatus ss);
|
||||
|
||||
|
||||
/**
|
||||
* Set my presence status
|
||||
* @param lc #LinphoneCore object
|
||||
* @param minutes_away how long in away
|
||||
* @param alternative_contact sip uri used to redirect call in state #LinphoneStatusMoved
|
||||
* @param os #LinphoneOnlineStatus
|
||||
*/
|
||||
void linphone_core_set_presence_info(LinphoneCore *lc,int minutes_away,const char *alternative_contact,LinphoneOnlineStatus os);
|
||||
/**
|
||||
* get my presence status
|
||||
* @param lc #LinphoneCore object
|
||||
* @return #LinphoneOnlineStatus
|
||||
*/
|
||||
LinphoneOnlineStatus linphone_core_get_presence_info(const LinphoneCore *lc);
|
||||
|
||||
void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char **result);
|
||||
/**
|
||||
* Add a friend to the current buddy list, if \link linphone_friend_enable_subscribes() subscription attribute \endlink is set, a SIP SUBSCRIBE message is sent.
|
||||
* @param lc #LinphoneCore object
|
||||
* @param fr #LinphoneFriend to add
|
||||
*/
|
||||
void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *fr);
|
||||
/**
|
||||
* remove a friend from the buddy list
|
||||
* @param lc #LinphoneCore object
|
||||
* @param fr #LinphoneFriend to add
|
||||
*/
|
||||
void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *fr);
|
||||
/**
|
||||
* Black list a friend. same as linphone_friend_set_inc_subscribe_policy() with #LinphoneSPDeny policy;
|
||||
* @param lc #LinphoneCore object
|
||||
* @param lf #LinphoneFriend to add
|
||||
*/
|
||||
void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf);
|
||||
/**
|
||||
* get Buddy list of LinphoneFriend
|
||||
* @param lc #LinphoneCore object
|
||||
* */
|
||||
const MSList * linphone_core_get_friend_list(const LinphoneCore *lc);
|
||||
/**
|
||||
* notify all friends that have subscribed
|
||||
* @param lc #LinphoneCore object
|
||||
* @param os #LinphoneOnlineStatus to notify
|
||||
* */
|
||||
void linphone_core_notify_all_friends(LinphoneCore *lc, LinphoneOnlineStatus os);
|
||||
LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, const char *addr);
|
||||
LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LINPHONEFRIEND_H_ */
|
||||
308
coreapi/lsd.c
Normal file
308
coreapi/lsd.c
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2010 Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Linphone Sound Daemon: is a lightweight utility to play sounds to speaker during a conversation.
|
||||
This is useful for embedded platforms, where sound apis are not performant enough to allow
|
||||
simultaneous sound access.
|
||||
*/
|
||||
|
||||
#include "linphonecore_utils.h"
|
||||
#include "private.h"
|
||||
#include "mediastreamer2/msticker.h"
|
||||
#include "mediastreamer2/mssndcard.h"
|
||||
#include "mediastreamer2/msaudiomixer.h"
|
||||
#include "mediastreamer2/mschanadapter.h"
|
||||
#include "mediastreamer2/msfileplayer.h"
|
||||
#include "mediastreamer2/msitc.h"
|
||||
|
||||
|
||||
static struct _MSSndCard *linphone_sound_daemon_get_proxy_card(LinphoneSoundDaemon *obj);
|
||||
|
||||
#define MAX_BRANCHES 10
|
||||
|
||||
|
||||
struct _LsdPlayer{
|
||||
struct _LinphoneSoundDaemon *lsd;
|
||||
MSFilter *player;
|
||||
MSFilter *rateconv;
|
||||
MSFilter *chanadapter;
|
||||
LsdEndOfPlayCallback eop_cb;
|
||||
int mixer_pin;
|
||||
void *user_data;
|
||||
bool_t loop;
|
||||
bool_t pad[3];
|
||||
};
|
||||
|
||||
struct _LinphoneSoundDaemon {
|
||||
int out_rate;
|
||||
int out_nchans;
|
||||
MSFilter *mixer;
|
||||
MSFilter *soundout;
|
||||
MSTicker *ticker;
|
||||
MSSndCard *proxycard;
|
||||
LsdPlayer branches[MAX_BRANCHES];
|
||||
};
|
||||
|
||||
static MSFilter *create_writer(MSSndCard *c){
|
||||
LinphoneSoundDaemon *lsd=(LinphoneSoundDaemon*)c->data;
|
||||
MSFilter *itcsink=ms_filter_new(MS_ITC_SINK_ID);
|
||||
ms_filter_call_method(itcsink,MS_ITC_SINK_CONNECT,lsd->branches[0].player);
|
||||
return itcsink;
|
||||
}
|
||||
|
||||
static MSSndCardDesc proxycard={
|
||||
"Linphone Sound Daemon",
|
||||
/*detect*/ NULL,
|
||||
/*init*/ NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
/*create_reader*/ NULL,
|
||||
create_writer,
|
||||
/*uninit,*/
|
||||
};
|
||||
|
||||
LsdPlayer *linphone_sound_daemon_get_player(LinphoneSoundDaemon *obj){
|
||||
int i;
|
||||
for(i=1;i<MAX_BRANCHES;++i){
|
||||
LsdPlayer *b=&obj->branches[i];
|
||||
MSFilter *p=b->player;
|
||||
int state;
|
||||
ms_filter_call_method(p,MS_PLAYER_GET_STATE,&state);
|
||||
if (state==MSPlayerClosed){
|
||||
lsd_player_set_gain(b,1);
|
||||
lsd_player_enable_loop (b,FALSE);
|
||||
return b;
|
||||
}
|
||||
}
|
||||
ms_warning("No more free players !");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_sound_daemon_release_player(LinphoneSoundDaemon *obj, LsdPlayer * player){
|
||||
int state;
|
||||
ms_filter_call_method(player->player,MS_PLAYER_GET_STATE,&state);
|
||||
if (state!=MSPlayerClosed){
|
||||
ms_filter_call_method(player->player,MS_PLAYER_CLOSE,&state);
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneSoundDaemon *lsd_player_get_daemon(const LsdPlayer *p){
|
||||
return p->lsd;
|
||||
}
|
||||
|
||||
int lsd_player_stop(LsdPlayer *p){
|
||||
ms_filter_call_method_noarg(p->player,MS_PLAYER_PAUSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lsd_player_init(LsdPlayer *p, MSConnectionPoint mixer, MSFilterId playerid, LinphoneSoundDaemon *lsd){
|
||||
MSConnectionHelper h;
|
||||
p->player=ms_filter_new(playerid);
|
||||
p->rateconv=ms_filter_new(MS_RESAMPLE_ID);
|
||||
p->chanadapter=ms_filter_new(MS_CHANNEL_ADAPTER_ID);
|
||||
|
||||
ms_connection_helper_start(&h);
|
||||
ms_connection_helper_link(&h,p->player,-1,0);
|
||||
ms_connection_helper_link(&h,p->rateconv,0,0);
|
||||
ms_connection_helper_link(&h,p->chanadapter,0,0);
|
||||
ms_connection_helper_link(&h,mixer.filter,mixer.pin,-1);
|
||||
p->mixer_pin=mixer.pin;
|
||||
p->loop=FALSE;
|
||||
p->lsd=lsd;
|
||||
}
|
||||
|
||||
static void lsd_player_uninit(LsdPlayer *p, MSConnectionPoint mixer){
|
||||
MSConnectionHelper h;
|
||||
|
||||
ms_connection_helper_start(&h);
|
||||
ms_connection_helper_unlink (&h,p->player,-1,0);
|
||||
ms_connection_helper_unlink(&h,p->rateconv,0,0);
|
||||
ms_connection_helper_unlink(&h,p->chanadapter,0,0);
|
||||
ms_connection_helper_unlink(&h,mixer.filter,mixer.pin,-1);
|
||||
|
||||
ms_filter_destroy(p->player);
|
||||
ms_filter_destroy(p->rateconv);
|
||||
ms_filter_destroy(p->chanadapter);
|
||||
}
|
||||
|
||||
void lsd_player_set_callback(LsdPlayer *p, LsdEndOfPlayCallback cb){
|
||||
p->eop_cb=cb;
|
||||
}
|
||||
|
||||
void lsd_player_set_user_pointer(LsdPlayer *p, void *up){
|
||||
p->user_data=up;
|
||||
}
|
||||
|
||||
void *lsd_player_get_user_pointer(const LsdPlayer *p){
|
||||
return p->user_data;
|
||||
}
|
||||
|
||||
static void lsd_player_on_eop(void * userdata, unsigned int id, void *arg){
|
||||
LsdPlayer *p=(LsdPlayer *)userdata;
|
||||
if (p->eop_cb!=NULL)
|
||||
p->eop_cb(p);
|
||||
}
|
||||
|
||||
static void lsd_player_configure(LsdPlayer *b){
|
||||
int rate,chans;
|
||||
LinphoneSoundDaemon *lsd=b->lsd;
|
||||
|
||||
if (ms_filter_get_id(b->player)==MS_ITC_SOURCE_ID)
|
||||
ms_message("Configuring branch coming from audio call...");
|
||||
|
||||
ms_filter_call_method(b->player,MS_FILTER_GET_SAMPLE_RATE,&rate);
|
||||
ms_filter_call_method(b->player,MS_FILTER_GET_NCHANNELS,&chans);
|
||||
|
||||
|
||||
ms_filter_call_method(b->rateconv,MS_FILTER_SET_SAMPLE_RATE,&rate);
|
||||
ms_filter_call_method(b->rateconv,MS_FILTER_SET_NCHANNELS,&chans);
|
||||
ms_filter_call_method(b->rateconv,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&lsd->out_rate);
|
||||
|
||||
ms_filter_call_method(b->chanadapter,MS_FILTER_SET_NCHANNELS,&chans);
|
||||
ms_filter_call_method(b->chanadapter,MS_CHANNEL_ADAPTER_SET_OUTPUT_NCHANNELS,&lsd->out_nchans);
|
||||
ms_message("player configured for rate=%i, channels=%i",rate,chans);
|
||||
}
|
||||
|
||||
int lsd_player_play(LsdPlayer *b, const char *filename ){
|
||||
int state;
|
||||
|
||||
ms_filter_call_method(b->player,MS_PLAYER_GET_STATE,&state);
|
||||
if (state!=MSPlayerClosed){
|
||||
ms_filter_call_method_noarg(b->player,MS_PLAYER_CLOSE);
|
||||
}
|
||||
|
||||
if (ms_filter_call_method(b->player,MS_PLAYER_OPEN,(void*)filename)!=0){
|
||||
ms_warning("Could not play %s",filename);
|
||||
return -1;
|
||||
}
|
||||
ms_filter_set_notify_callback (b->player,lsd_player_on_eop,b);
|
||||
lsd_player_configure(b);
|
||||
ms_filter_call_method_noarg (b->player,MS_PLAYER_START);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lsd_player_enable_loop(LsdPlayer *p, bool_t loopmode){
|
||||
if (ms_filter_get_id(p->player)==MS_FILE_PLAYER_ID){
|
||||
int arg=loopmode ? 0 : -1;
|
||||
ms_filter_call_method(p->player,MS_FILE_PLAYER_LOOP,&arg);
|
||||
p->loop=loopmode;
|
||||
}
|
||||
}
|
||||
|
||||
bool_t lsd_player_loop_enabled(const LsdPlayer *p){
|
||||
return p->loop;
|
||||
}
|
||||
|
||||
void lsd_player_set_gain(LsdPlayer *p, float gain){
|
||||
MSAudioMixerCtl gainctl;
|
||||
gainctl.pin=p->mixer_pin;
|
||||
gainctl.gain=gain;
|
||||
ms_filter_call_method(p->lsd->mixer,MS_AUDIO_MIXER_SET_INPUT_GAIN,&gainctl);
|
||||
}
|
||||
|
||||
LinphoneSoundDaemon * linphone_sound_daemon_new(const char *cardname, int rate, int nchannels){
|
||||
int i;
|
||||
MSConnectionPoint mp;
|
||||
LinphoneSoundDaemon *lsd;
|
||||
MSSndCard *card=ms_snd_card_manager_get_card(
|
||||
ms_snd_card_manager_get(),
|
||||
cardname);
|
||||
if (card==NULL){
|
||||
card=ms_snd_card_manager_get_default_playback_card (
|
||||
ms_snd_card_manager_get());
|
||||
if (card==NULL){
|
||||
ms_error("linphone_sound_daemon_new(): No playback soundcard available");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lsd=ms_new0(LinphoneSoundDaemon,1);
|
||||
lsd->soundout=ms_snd_card_create_writer(card);
|
||||
lsd->mixer=ms_filter_new(MS_AUDIO_MIXER_ID);
|
||||
lsd->out_rate=rate;
|
||||
lsd->out_nchans=nchannels;
|
||||
ms_filter_call_method(lsd->soundout,MS_FILTER_SET_SAMPLE_RATE,&lsd->out_rate);
|
||||
ms_filter_call_method(lsd->soundout,MS_FILTER_SET_NCHANNELS,&lsd->out_nchans);
|
||||
ms_filter_call_method(lsd->mixer,MS_FILTER_SET_SAMPLE_RATE,&lsd->out_rate);
|
||||
ms_filter_call_method(lsd->mixer,MS_FILTER_SET_NCHANNELS,&lsd->out_nchans);
|
||||
|
||||
mp.filter=lsd->mixer;
|
||||
mp.pin=0;
|
||||
|
||||
lsd_player_init(&lsd->branches[0],mp,MS_ITC_SOURCE_ID,lsd);
|
||||
ms_filter_set_notify_callback(lsd->branches[0].player,(MSFilterNotifyFunc)lsd_player_configure,&lsd->branches[0]);
|
||||
ms_filter_enable_synchronous_notifcations (lsd->branches[0].player,TRUE);
|
||||
for(i=1;i<MAX_BRANCHES;++i){
|
||||
mp.pin=i;
|
||||
lsd_player_init(&lsd->branches[i],mp,MS_FILE_PLAYER_ID,lsd);
|
||||
}
|
||||
ms_filter_link(lsd->mixer,0,lsd->soundout,0);
|
||||
lsd->ticker=ms_ticker_new();
|
||||
ms_ticker_attach(lsd->ticker,lsd->soundout);
|
||||
|
||||
lsd->proxycard=ms_snd_card_new(&proxycard);
|
||||
lsd->proxycard->data=lsd;
|
||||
ms_message("LinphoneSoundDaemon started with rate=%i, nchannels=%i",rate,nchannels);
|
||||
return lsd;
|
||||
}
|
||||
|
||||
void linphone_sound_daemon_stop_all_players(LinphoneSoundDaemon *obj){
|
||||
int i;
|
||||
for(i=1;i<MAX_BRANCHES;++i){
|
||||
lsd_player_stop(&obj->branches[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_sound_daemon_release_all_players(LinphoneSoundDaemon *obj){
|
||||
int i;
|
||||
for(i=1;i<MAX_BRANCHES;++i){
|
||||
linphone_sound_daemon_release_player(obj,&obj->branches[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_sound_daemon_destroy(LinphoneSoundDaemon *obj){
|
||||
int i;
|
||||
MSConnectionPoint mp;
|
||||
ms_ticker_detach(obj->ticker,obj->soundout);
|
||||
mp.filter=obj->mixer;
|
||||
for(i=0;i<MAX_BRANCHES;++i){
|
||||
mp.pin=i;
|
||||
if (i!=0) linphone_sound_daemon_release_player(obj,&obj->branches[i]);
|
||||
lsd_player_uninit (&obj->branches[i],mp);
|
||||
}
|
||||
ms_filter_unlink(obj->mixer,0,obj->soundout,0);
|
||||
ms_ticker_destroy(obj->ticker);
|
||||
ms_filter_destroy(obj->soundout);
|
||||
ms_filter_destroy(obj->mixer);
|
||||
}
|
||||
|
||||
MSSndCard *linphone_sound_daemon_get_proxy_card(LinphoneSoundDaemon *lsd){
|
||||
return lsd->proxycard;
|
||||
}
|
||||
|
||||
void linphone_core_use_sound_daemon(LinphoneCore *lc, LinphoneSoundDaemon *lsd){
|
||||
if (lsd!=NULL){
|
||||
lc->sound_conf.lsd_card=linphone_sound_daemon_get_proxy_card (lsd);
|
||||
}else {
|
||||
lc->sound_conf.lsd_card=NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -258,6 +258,39 @@ void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc){
|
|||
}
|
||||
}
|
||||
|
||||
bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, PayloadType *pt, int bandwidth_limit)
|
||||
{
|
||||
double codec_band;
|
||||
bool_t ret=FALSE;
|
||||
|
||||
switch (pt->type){
|
||||
case PAYLOAD_AUDIO_CONTINUOUS:
|
||||
case PAYLOAD_AUDIO_PACKETIZED:
|
||||
codec_band=get_audio_payload_bandwidth(lc,pt);
|
||||
ret=bandwidth_is_greater(bandwidth_limit*1000,codec_band);
|
||||
/*hack to avoid using uwb codecs when having low bitrate and video*/
|
||||
if (bandwidth_is_greater(199,bandwidth_limit)){
|
||||
if (linphone_core_video_enabled(lc) && pt->clock_rate>16000){
|
||||
ret=FALSE;
|
||||
}
|
||||
}
|
||||
//ms_message("Payload %s: %g",pt->mime_type,codec_band);
|
||||
break;
|
||||
case PAYLOAD_VIDEO:
|
||||
if (bandwidth_limit!=0) {/* infinite (-1) or strictly positive*/
|
||||
/*let the video use all the bandwidth minus the maximum bandwidth used by audio */
|
||||
if (bandwidth_limit>0)
|
||||
pt->normal_bitrate=bandwidth_limit*1000;
|
||||
else
|
||||
pt->normal_bitrate=1500000; /*around 1.5 Mbit/s*/
|
||||
ret=TRUE;
|
||||
}
|
||||
else ret=FALSE;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* return TRUE if codec can be used with bandwidth, FALSE else*/
|
||||
bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType *pt)
|
||||
{
|
||||
|
|
@ -462,8 +495,13 @@ static int recvStunResponse(ortp_socket_t sock, char *ipaddr, int *port, int *id
|
|||
struct in_addr ia;
|
||||
stunParseMessage(buf,len, &resp );
|
||||
*id=resp.msgHdr.tr_id.octet[0];
|
||||
*port = resp.mappedAddress.ipv4.port;
|
||||
ia.s_addr=htonl(resp.mappedAddress.ipv4.addr);
|
||||
if (resp.hasXorMappedAddress){
|
||||
*port = resp.xorMappedAddress.ipv4.port;
|
||||
ia.s_addr=htonl(resp.xorMappedAddress.ipv4.addr);
|
||||
}else if (resp.hasMappedAddress){
|
||||
*port = resp.mappedAddress.ipv4.port;
|
||||
ia.s_addr=htonl(resp.mappedAddress.ipv4.addr);
|
||||
}else return -1;
|
||||
strncpy(ipaddr,inet_ntoa(ia),LINPHONE_IPADDR_SIZE);
|
||||
}
|
||||
return len;
|
||||
|
|
@ -497,10 +535,10 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
|
|||
lc->vtable.display_status(lc,_("Stun lookup in progress..."));
|
||||
|
||||
/*create the two audio and video RTP sockets, and send STUN message to our stun server */
|
||||
sock1=create_socket(linphone_core_get_audio_port(lc));
|
||||
sock1=create_socket(call->audio_port);
|
||||
if (sock1<0) return;
|
||||
if (video_enabled){
|
||||
sock2=create_socket(linphone_core_get_video_port(lc));
|
||||
sock2=create_socket(call->video_port);
|
||||
if (sock2<0) return ;
|
||||
}
|
||||
sendStunRequest(sock1,(struct sockaddr*)&ss,ss_len,11,TRUE);
|
||||
|
|
@ -754,14 +792,10 @@ static int get_local_ip_for_with_connect(int type, const char *dest, char *resul
|
|||
}
|
||||
|
||||
int linphone_core_get_local_ip_for(int type, const char *dest, char *result){
|
||||
if (dest==NULL) {
|
||||
if (type==AF_INET)
|
||||
dest="87.98.157.38"; /*a public IP address*/
|
||||
else dest="2a00:1450:8002::68";
|
||||
}
|
||||
strcpy(result,type==AF_INET ? "127.0.0.1" : "::1");
|
||||
#ifdef HAVE_GETIFADDRS
|
||||
{
|
||||
if (dest==NULL) {
|
||||
/*we use getifaddrs for lookup of default interface */
|
||||
int found_ifs;
|
||||
|
||||
found_ifs=get_local_ip_with_getifaddrs(type,result,LINPHONE_IPADDR_SIZE);
|
||||
|
|
@ -774,5 +808,33 @@ int linphone_core_get_local_ip_for(int type, const char *dest, char *result){
|
|||
}
|
||||
#endif
|
||||
/*else use connect to find the best local ip address */
|
||||
if (type==AF_INET)
|
||||
dest="87.98.157.38"; /*a public IP address*/
|
||||
else dest="2a00:1450:8002::68";
|
||||
return get_local_ip_for_with_connect(type,dest,result);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#include <resolv.h>
|
||||
|
||||
|
||||
|
||||
|
||||
void _linphone_core_configure_resolver(){
|
||||
/*bionic declares _res but does not define nor export it !!*/
|
||||
#ifdef ANDROID
|
||||
/*timeout and attempts are the same as retrans and retry, but are android specific names.*/
|
||||
setenv("RES_OPTIONS","timeout:1 attempts:2 retrans:1 retry:2",1);
|
||||
#else
|
||||
res_init();
|
||||
_res.retrans=1; /*retransmit every second*/
|
||||
_res.retry=2; /*only two times per DNS server*/
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void _linphone_core_configure_resolver(){
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,6 +20,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "sal.h"
|
||||
#include "offeranswer.h"
|
||||
|
||||
static bool_t only_telephone_event(const MSList *l){
|
||||
PayloadType *p=(PayloadType*)l->data;
|
||||
if (strcasecmp(p->mime_type,"telephone-event")!=0){
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static PayloadType * find_payload_type_best_match(const MSList *l, const PayloadType *refpt){
|
||||
PayloadType *pt;
|
||||
|
|
@ -29,7 +36,10 @@ static PayloadType * find_payload_type_best_match(const MSList *l, const Payload
|
|||
|
||||
for (elem=l;elem!=NULL;elem=elem->next){
|
||||
pt=(PayloadType*)elem->data;
|
||||
if (strcasecmp(pt->mime_type,refpt->mime_type)==0 && pt->clock_rate==refpt->clock_rate){
|
||||
/* the compare between G729 and G729A is for some stupid uncompliant phone*/
|
||||
if ( (strcasecmp(pt->mime_type,refpt->mime_type)==0 ||
|
||||
(strcasecmp(pt->mime_type, "G729") == 0 && strcasecmp(refpt->mime_type, "G729A") == 0 ))
|
||||
&& pt->clock_rate==refpt->clock_rate){
|
||||
candidate=pt;
|
||||
/*good candidate, check fmtp for H264 */
|
||||
if (strcasecmp(pt->mime_type,"H264")==0){
|
||||
|
|
@ -50,19 +60,46 @@ static PayloadType * find_payload_type_best_match(const MSList *l, const Payload
|
|||
return candidate;
|
||||
}
|
||||
|
||||
static MSList *match_payloads(const MSList *local, const MSList *remote){
|
||||
static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t reading_response, bool_t one_matching_codec){
|
||||
const MSList *e2;
|
||||
MSList *res=NULL;
|
||||
PayloadType *matched;
|
||||
bool_t found_codec=FALSE;
|
||||
|
||||
for(e2=remote;e2!=NULL;e2=e2->next){
|
||||
PayloadType *p2=(PayloadType*)e2->data;
|
||||
matched=find_payload_type_best_match(local,p2);
|
||||
if (matched){
|
||||
matched=payload_type_clone(matched);
|
||||
PayloadType *newp;
|
||||
int local_number=payload_type_get_number(matched);
|
||||
int remote_number=payload_type_get_number(p2);
|
||||
|
||||
if (one_matching_codec){
|
||||
if (strcasecmp(matched->mime_type,"telephone-event")!=0){
|
||||
if (found_codec){/* we have found a real codec already*/
|
||||
continue; /*this codec won't be added*/
|
||||
}else found_codec=TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
newp=payload_type_clone(matched);
|
||||
if (p2->send_fmtp)
|
||||
payload_type_set_send_fmtp(matched,p2->send_fmtp);
|
||||
res=ms_list_append(res,matched);
|
||||
payload_type_set_number(matched,payload_type_get_number(p2));
|
||||
payload_type_set_send_fmtp(newp,p2->send_fmtp);
|
||||
res=ms_list_append(res,newp);
|
||||
/* we should use the remote numbering even when parsing a response */
|
||||
payload_type_set_number(newp,remote_number);
|
||||
if (reading_response && remote_number!=local_number){
|
||||
ms_warning("For payload type %s, proposed number was %i but the remote phone answered %i",
|
||||
newp->mime_type, local_number, remote_number);
|
||||
/*
|
||||
We must add this payload type with our local numbering in order to be able to receive it.
|
||||
Indeed despite we must sent with the remote numbering, we must be able to receive with
|
||||
our local one.
|
||||
*/
|
||||
newp=payload_type_clone(matched);
|
||||
payload_type_set_number(newp,local_number);
|
||||
res=ms_list_append(res,newp);
|
||||
}
|
||||
}else{
|
||||
ms_message("No match for %s/%i",p2->mime_type,p2->clock_rate);
|
||||
}
|
||||
|
|
@ -70,21 +107,32 @@ static MSList *match_payloads(const MSList *local, const MSList *remote){
|
|||
return res;
|
||||
}
|
||||
|
||||
static bool_t only_telephone_event(const MSList *l){
|
||||
PayloadType *p=(PayloadType*)l->data;
|
||||
if (strcasecmp(p->mime_type,"telephone-event")!=0){
|
||||
return FALSE;
|
||||
|
||||
|
||||
static SalStreamDir compute_dir(SalStreamDir local, SalStreamDir answered){
|
||||
SalStreamDir res=local;
|
||||
if (local==SalStreamSendRecv){
|
||||
if (answered==SalStreamRecvOnly){
|
||||
res=SalStreamSendOnly;
|
||||
}else if (answered==SalStreamSendOnly){
|
||||
res=SalStreamRecvOnly;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
if (answered==SalStreamInactive){
|
||||
res=SalStreamInactive;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void initiate_outgoing(const SalStreamDescription *local_offer,
|
||||
const SalStreamDescription *remote_answer,
|
||||
SalStreamDescription *result){
|
||||
if (remote_answer->port!=0)
|
||||
result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads);
|
||||
result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
|
||||
result->proto=local_offer->proto;
|
||||
result->type=local_offer->type;
|
||||
result->dir=compute_dir(local_offer->dir,remote_answer->dir);
|
||||
|
||||
if (result->payloads && !only_telephone_event(result->payloads)){
|
||||
strcpy(result->addr,remote_answer->addr);
|
||||
result->port=remote_answer->port;
|
||||
|
|
@ -98,10 +146,17 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
|
|||
|
||||
static void initiate_incoming(const SalStreamDescription *local_cap,
|
||||
const SalStreamDescription *remote_offer,
|
||||
SalStreamDescription *result){
|
||||
result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads);
|
||||
SalStreamDescription *result, bool_t one_matching_codec){
|
||||
result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
|
||||
result->proto=local_cap->proto;
|
||||
result->type=local_cap->type;
|
||||
if (remote_offer->dir==SalStreamSendOnly)
|
||||
result->dir=SalStreamRecvOnly;
|
||||
else if (remote_offer->dir==SalStreamRecvOnly){
|
||||
result->dir=SalStreamSendOnly;
|
||||
}else if (remote_offer->dir==SalStreamInactive){
|
||||
result->dir=SalStreamInactive;
|
||||
}else result->dir=SalStreamSendRecv;
|
||||
if (result->payloads && !only_telephone_event(result->payloads)){
|
||||
strcpy(result->addr,local_cap->addr);
|
||||
result->port=local_cap->port;
|
||||
|
|
@ -124,7 +179,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
for(i=0,j=0;i<local_offer->nstreams;++i){
|
||||
ms_message("Processing for stream %i",i);
|
||||
ls=&local_offer->streams[i];
|
||||
rs=sal_media_description_find_stream(remote_answer,ls->proto,ls->type);
|
||||
rs=sal_media_description_find_stream((SalMediaDescription*)remote_answer,ls->proto,ls->type);
|
||||
if (rs) {
|
||||
initiate_outgoing(ls,rs,&result->streams[j]);
|
||||
++j;
|
||||
|
|
@ -143,16 +198,16 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
**/
|
||||
int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
|
||||
const SalMediaDescription *remote_offer,
|
||||
SalMediaDescription *result){
|
||||
SalMediaDescription *result, bool_t one_matching_codec){
|
||||
int i,j;
|
||||
const SalStreamDescription *ls,*rs;
|
||||
|
||||
for(i=0,j=0;i<remote_offer->nstreams;++i){
|
||||
rs=&remote_offer->streams[i];
|
||||
ms_message("Processing for stream %i",i);
|
||||
ls=sal_media_description_find_stream(local_capabilities,rs->proto,rs->type);
|
||||
ls=sal_media_description_find_stream((SalMediaDescription*)local_capabilities,rs->proto,rs->type);
|
||||
if (ls){
|
||||
initiate_incoming(ls,rs,&result->streams[j]);
|
||||
initiate_incoming(ls,rs,&result->streams[j],one_matching_codec);
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
**/
|
||||
int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
|
||||
const SalMediaDescription *remote_offer,
|
||||
SalMediaDescription *result);
|
||||
SalMediaDescription *result, bool_t one_matching_codec);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ void linphone_core_add_subscriber(LinphoneCore *lc, const char *subscriber, SalO
|
|||
linphone_friend_set_inc_subscribe_policy(fl,LinphoneSPAccept);
|
||||
fl->inc_subscribe_pending=TRUE;
|
||||
lc->subscribers=ms_list_append(lc->subscribers,(void *)fl);
|
||||
if (lc->vtable.new_unknown_subscriber!=NULL) {
|
||||
if (lc->vtable.new_subscription_request!=NULL) {
|
||||
char *tmp=linphone_address_as_string(fl->uri);
|
||||
lc->vtable.new_unknown_subscriber(lc,fl,tmp);
|
||||
lc->vtable.new_subscription_request(lc,fl,tmp);
|
||||
ms_free(tmp);
|
||||
}
|
||||
}
|
||||
|
|
@ -57,11 +57,24 @@ void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){
|
|||
LinphoneFriend *lf=NULL;
|
||||
char *tmp;
|
||||
LinphoneAddress *uri;
|
||||
LinphoneProxyConfig *cfg;
|
||||
const char *fixed_contact;
|
||||
|
||||
uri=linphone_address_new(from);
|
||||
linphone_address_clean(uri);
|
||||
tmp=linphone_address_as_string(uri);
|
||||
ms_message("Receiving new subscription from %s.",from);
|
||||
|
||||
cfg=linphone_core_lookup_known_proxy(lc,uri);
|
||||
if (cfg!=NULL){
|
||||
if (cfg->op){
|
||||
fixed_contact=sal_op_get_contact(cfg->op);
|
||||
if (fixed_contact) {
|
||||
sal_op_set_contact (op,fixed_contact);
|
||||
ms_message("Contact for next subscribe answer has been fixed using proxy to %s",fixed_contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* check if we answer to this subscription */
|
||||
if (linphone_find_friend(lc->friends,uri,&lf)!=NULL){
|
||||
lf->insub=op;
|
||||
|
|
@ -92,36 +105,36 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeState ss, Sal
|
|||
char *tmp;
|
||||
LinphoneFriend *lf;
|
||||
LinphoneAddress *friend=NULL;
|
||||
LinphoneOnlineStatus estatus=LINPHONE_STATUS_OFFLINE;
|
||||
LinphoneOnlineStatus estatus=LinphoneStatusOffline;
|
||||
|
||||
switch(sal_status){
|
||||
case SalPresenceOffline:
|
||||
estatus=LINPHONE_STATUS_OFFLINE;
|
||||
estatus=LinphoneStatusOffline;
|
||||
break;
|
||||
case SalPresenceOnline:
|
||||
estatus=LINPHONE_STATUS_ONLINE;
|
||||
estatus=LinphoneStatusOnline;
|
||||
break;
|
||||
case SalPresenceBusy:
|
||||
estatus=LINPHONE_STATUS_BUSY;
|
||||
estatus=LinphoneStatusBusy;
|
||||
break;
|
||||
case SalPresenceBerightback:
|
||||
estatus=LINPHONE_STATUS_AWAY;
|
||||
estatus=LinphoneStatusBeRightBack;
|
||||
break;
|
||||
case SalPresenceAway:
|
||||
estatus=LINPHONE_STATUS_AWAY;
|
||||
estatus=LinphoneStatusAway;
|
||||
break;
|
||||
case SalPresenceOnthephone:
|
||||
estatus=LINPHONE_STATUS_ONTHEPHONE;
|
||||
estatus=LinphoneStatusOnThePhone;
|
||||
break;
|
||||
case SalPresenceOuttolunch:
|
||||
estatus=LINPHONE_STATUS_OUTTOLUNCH;
|
||||
estatus=LinphoneStatusOutToLunch;
|
||||
break;
|
||||
case SalPresenceDonotdisturb:
|
||||
estatus=LINPHONE_STATUS_BUSY;
|
||||
estatus=LinphoneStatusDoNotDisturb;
|
||||
break;
|
||||
case SalPresenceMoved:
|
||||
case SalPresenceAltService:
|
||||
estatus=LINPHONE_STATUS_AWAY;
|
||||
estatus=LinphoneStatusMoved;
|
||||
break;
|
||||
}
|
||||
lf=linphone_find_friend_by_out_subscribe(lc->friends,op);
|
||||
|
|
@ -130,7 +143,8 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeState ss, Sal
|
|||
tmp=linphone_address_as_string(friend);
|
||||
lf->status=estatus;
|
||||
lf->subscribe_active=TRUE;
|
||||
lc->vtable.notify_presence_recv(lc,(LinphoneFriend*)lf);
|
||||
if (lc->vtable.notify_presence_recv)
|
||||
lc->vtable.notify_presence_recv(lc,(LinphoneFriend*)lf);
|
||||
ms_free(tmp);
|
||||
}else{
|
||||
ms_message("But this person is not part of our friend list, so we don't care.");
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "mediastreamer2/mediastream.h"
|
||||
|
||||
#ifndef LIBLINPHONE_VERSION
|
||||
#define LIBLINPHONE_VERSION LINPHONE_VERSION
|
||||
|
|
@ -54,13 +55,14 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
typedef enum _LCState{
|
||||
LCStateInit,
|
||||
LCStatePreEstablishing,
|
||||
LCStateRinging,
|
||||
LCStateAVRunning
|
||||
}LCState;
|
||||
|
||||
struct _LinphoneCallParams{
|
||||
LinphoneCall *referer; /*in case this call creation is consecutive to an incoming transfer, this points to the original call */
|
||||
int audio_bw; /* bandwidth limit for audio stream */
|
||||
bool_t has_video;
|
||||
bool_t real_early_media; /*send real media even during early media (for outgoing calls)*/
|
||||
bool_t pad[2];
|
||||
};
|
||||
|
||||
struct _LinphoneCall
|
||||
{
|
||||
|
|
@ -76,29 +78,43 @@ struct _LinphoneCall
|
|||
char localip[LINPHONE_IPADDR_SIZE]; /* our best guess for local ipaddress for this call */
|
||||
time_t start_time; /*time at which the call was initiated*/
|
||||
time_t media_start_time; /*time at which it was accepted, media streams established*/
|
||||
LCState state;
|
||||
LinphoneCallState state;
|
||||
LinphoneReason reason;
|
||||
int refcnt;
|
||||
void * user_pointer;
|
||||
int audio_port;
|
||||
int video_port;
|
||||
struct _AudioStream *audiostream; /**/
|
||||
struct _VideoStream *videostream;
|
||||
char *refer_to;
|
||||
LinphoneCallParams params;
|
||||
int up_bw; /*upload bandwidth setting at the time the call is started. Used to detect if it changes during a call */
|
||||
bool_t refer_pending;
|
||||
bool_t media_pending;
|
||||
bool_t audio_muted;
|
||||
bool_t camera_active;
|
||||
bool_t all_muted; /*this flag is set during early medias*/
|
||||
bool_t playing_ringbacktone;
|
||||
};
|
||||
|
||||
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to);
|
||||
|
||||
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params);
|
||||
LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op);
|
||||
#define linphone_call_set_state(lcall,st) (lcall)->state=(st)
|
||||
void linphone_call_destroy(struct _LinphoneCall *obj);
|
||||
void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message);
|
||||
|
||||
/* private: */
|
||||
LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, LinphoneAddress *local, LinphoneAddress * remote);
|
||||
void linphone_call_log_completed(LinphoneCallLog *calllog, LinphoneCall *call);
|
||||
void linphone_call_log_completed(LinphoneCallLog *calllog, LinphoneCall *call, LinphoneCallStatus status);
|
||||
void linphone_call_log_destroy(LinphoneCallLog *cl);
|
||||
|
||||
|
||||
void linphone_core_init_media_streams(LinphoneCore *lc, LinphoneCall *call);
|
||||
|
||||
void linphone_auth_info_write_config(struct _LpConfig *config, LinphoneAuthInfo *obj, int pos);
|
||||
|
||||
void linphone_core_update_proxy_register(LinphoneCore *lc);
|
||||
void linphone_core_refresh_subscribes(LinphoneCore *lc);
|
||||
int linphone_core_abort_call(LinphoneCore *lc, LinphoneCall *call, const char *error);
|
||||
|
||||
int linphone_proxy_config_send_publish(LinphoneProxyConfig *cfg, LinphoneOnlineStatus os);
|
||||
void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrationState rstate, const char *message);
|
||||
|
||||
int linphone_online_status_to_eXosip(LinphoneOnlineStatus os);
|
||||
void linphone_friend_close_subscriptions(LinphoneFriend *lf);
|
||||
|
|
@ -157,6 +173,7 @@ void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc);
|
|||
void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCore *lc, const PayloadType *pt);
|
||||
void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call);
|
||||
|
||||
void linphone_core_send_initial_subscribes(LinphoneCore *lc);
|
||||
void linphone_core_write_friends_config(LinphoneCore* lc);
|
||||
void linphone_friend_write_to_config_file(struct _LpConfig *config, LinphoneFriend *lf, int index);
|
||||
LinphoneFriend * linphone_friend_new_from_config_file(struct _LinphoneCore *lc, int index);
|
||||
|
|
@ -164,6 +181,7 @@ LinphoneFriend * linphone_friend_new_from_config_file(struct _LinphoneCore *lc,
|
|||
void linphone_proxy_config_update(LinphoneProxyConfig *cfg);
|
||||
void linphone_proxy_config_get_contact(LinphoneProxyConfig *cfg, const char **ip, int *port);
|
||||
LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri);
|
||||
const char *linphone_core_find_best_identity(LinphoneCore *lc, const LinphoneAddress *to, const char **route);
|
||||
int linphone_core_get_local_ip_for(int type, const char *dest, char *result);
|
||||
|
||||
LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(struct _LpConfig *config, int index);
|
||||
|
|
@ -173,19 +191,20 @@ int linphone_proxy_config_normalize_number(LinphoneProxyConfig *cfg, const char
|
|||
|
||||
void linphone_core_text_received(LinphoneCore *lc, const char *from, const char *msg);
|
||||
|
||||
void linphone_core_start_media_streams(LinphoneCore *lc, struct _LinphoneCall *call);
|
||||
void linphone_core_stop_media_streams(LinphoneCore *lc, struct _LinphoneCall *call);
|
||||
void linphone_call_init_media_streams(LinphoneCall *call);
|
||||
void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone);
|
||||
void linphone_call_stop_media_streams(LinphoneCall *call);
|
||||
|
||||
const char * linphone_core_get_identity(LinphoneCore *lc);
|
||||
const char * linphone_core_get_route(LinphoneCore *lc);
|
||||
bool_t linphone_core_is_in_communication_with(LinphoneCore *lc, const char *to);
|
||||
void linphone_core_start_waiting(LinphoneCore *lc, const char *purpose);
|
||||
void linphone_core_update_progress(LinphoneCore *lc, const char *purpose, float progresses);
|
||||
void linphone_core_stop_waiting(LinphoneCore *lc);
|
||||
|
||||
int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphoneProxyConfig *dest_proxy);
|
||||
|
||||
void linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call);
|
||||
extern SalCallbacks linphone_sal_callbacks;
|
||||
|
||||
void linphone_proxy_config_set_error(LinphoneProxyConfig *cfg, LinphoneReason error);
|
||||
|
||||
struct _LinphoneProxyConfig
|
||||
{
|
||||
|
|
@ -201,6 +220,8 @@ struct _LinphoneProxyConfig
|
|||
struct _SipSetupContext *ssctx;
|
||||
int auth_failures;
|
||||
char *dial_prefix;
|
||||
LinphoneRegistrationState state;
|
||||
SalOp *publish_op;
|
||||
bool_t commit;
|
||||
bool_t reg_sendregister;
|
||||
bool_t registered;
|
||||
|
|
@ -208,6 +229,7 @@ struct _LinphoneProxyConfig
|
|||
bool_t dial_escape_plus;
|
||||
void* user_data;
|
||||
time_t deletion_date;
|
||||
LinphoneReason error;
|
||||
};
|
||||
|
||||
struct _LinphoneAuthInfo
|
||||
|
|
@ -224,8 +246,8 @@ struct _LinphoneAuthInfo
|
|||
struct _LinphoneChatRoom{
|
||||
struct _LinphoneCore *lc;
|
||||
char *peer;
|
||||
char *route;
|
||||
LinphoneAddress *peer_url;
|
||||
SalOp *op;
|
||||
void * user_data;
|
||||
};
|
||||
|
||||
|
|
@ -241,6 +263,7 @@ struct _LinphoneFriend{
|
|||
bool_t subscribe;
|
||||
bool_t subscribe_active;
|
||||
bool_t inc_subscribe_pending;
|
||||
bool_t commit;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -259,7 +282,6 @@ typedef struct sip_config
|
|||
bool_t loopback_only;
|
||||
bool_t ipv6_enabled;
|
||||
bool_t sdp_200_ack;
|
||||
bool_t only_one_codec; /*in SDP answers*/
|
||||
bool_t register_only_when_network_is_up;
|
||||
bool_t ping_with_options;
|
||||
bool_t auto_net_state_mon;
|
||||
|
|
@ -297,6 +319,7 @@ typedef struct sound_config
|
|||
struct _MSSndCard * ring_sndcard; /* the playback sndcard currently used */
|
||||
struct _MSSndCard * play_sndcard; /* the playback sndcard currently used */
|
||||
struct _MSSndCard * capt_sndcard; /* the capture sndcard currently used */
|
||||
struct _MSSndCard * lsd_card; /* dummy playback card for Linphone Sound Daemon extension */
|
||||
const char **cards;
|
||||
int latency; /* latency in samples of the current used sound device */
|
||||
char rec_lev;
|
||||
|
|
@ -306,6 +329,7 @@ typedef struct sound_config
|
|||
char source;
|
||||
char *local_ring;
|
||||
char *remote_ring;
|
||||
char *ringback_tone;
|
||||
bool_t ec;
|
||||
bool_t ea;
|
||||
bool_t agc;
|
||||
|
|
@ -325,6 +349,7 @@ typedef struct video_config{
|
|||
bool_t show_local;
|
||||
bool_t display;
|
||||
bool_t selfview; /*during calls*/
|
||||
const char *displaytype;
|
||||
}video_config_t;
|
||||
|
||||
typedef struct ui_config
|
||||
|
|
@ -351,6 +376,7 @@ struct _LinphoneCore
|
|||
{
|
||||
LinphoneCoreVTable vtable;
|
||||
Sal *sal;
|
||||
LinphoneGlobalState state;
|
||||
struct _LpConfig *config;
|
||||
net_config_t net_conf;
|
||||
sip_config_t sip_conf;
|
||||
|
|
@ -364,22 +390,22 @@ struct _LinphoneCore
|
|||
MSList *friends;
|
||||
MSList *auth_info;
|
||||
struct _RingStream *ringstream;
|
||||
time_t dmfs_playing_start_time;
|
||||
LCCallbackObj preview_finished_cb;
|
||||
struct _LinphoneCall *call; /* the current call, in the future it will be a list of calls (conferencing)*/
|
||||
LinphoneCall *current_call; /* the current call */
|
||||
MSList *calls; /* all the processed calls */
|
||||
MSList *queued_calls; /* used by the autoreplier */
|
||||
MSList *call_logs;
|
||||
MSList *chatrooms;
|
||||
int max_call_logs;
|
||||
int missed_calls;
|
||||
struct _AudioStream *audiostream; /**/
|
||||
struct _VideoStream *videostream;
|
||||
struct _VideoStream *previewstream;
|
||||
VideoPreview *previewstream;
|
||||
struct _MSEventQueue *msevq;
|
||||
RtpTransport *a_rtp,*a_rtcp;
|
||||
MSList *bl_reqs;
|
||||
MSList *subscribers; /* unknown subscribers */
|
||||
int minutes_away;
|
||||
LinphoneOnlineStatus presence_mode;
|
||||
LinphoneOnlineStatus prev_mode;
|
||||
char *alt_contact;
|
||||
void *data;
|
||||
char *play_file;
|
||||
|
|
@ -390,19 +416,43 @@ struct _LinphoneCore
|
|||
int dw_video_bw;
|
||||
int up_video_bw;
|
||||
int audio_bw;
|
||||
gstate_t gstate_power;
|
||||
gstate_t gstate_reg;
|
||||
gstate_t gstate_call;
|
||||
LinphoneWaitingCallback wait_cb;
|
||||
void *wait_ctx;
|
||||
unsigned long video_window_id;
|
||||
unsigned long preview_window_id;
|
||||
time_t netup_time; /*time when network went reachable */
|
||||
bool_t use_files;
|
||||
bool_t apply_nat_settings;
|
||||
bool_t ready;
|
||||
bool_t initial_subscribes_sent;
|
||||
bool_t bl_refresh;
|
||||
bool_t preview_finished;
|
||||
bool_t auto_net_state_mon;
|
||||
bool_t network_reachable;
|
||||
bool_t audio_muted;
|
||||
bool_t use_preview_window;
|
||||
};
|
||||
|
||||
bool_t linphone_core_can_we_add_call(LinphoneCore *lc);
|
||||
int linphone_core_add_call( LinphoneCore *lc, LinphoneCall *call);
|
||||
int linphone_core_del_call( LinphoneCore *lc, LinphoneCall *call);
|
||||
int linphone_core_set_as_current_call(LinphoneCore *lc, LinphoneCall *call);
|
||||
int linphone_core_get_calls_nb(const LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
|
||||
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call);
|
||||
|
||||
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md);
|
||||
|
||||
bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, PayloadType *pt, int bandwidth_limit);
|
||||
|
||||
#define linphone_core_ready(lc) ((lc)->state!=LinphoneGlobalStartup)
|
||||
void _linphone_core_configure_resolver();
|
||||
|
||||
#define HOLD_OFF (0)
|
||||
#define HOLD_ON (1)
|
||||
|
||||
#ifndef NB_MAX_CALLS
|
||||
#define NB_MAX_CALLS (10)
|
||||
#endif
|
||||
|
||||
#endif /* _PRIVATE_H */
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){
|
|||
if (obj->type!=NULL) ms_free(obj->type);
|
||||
if (obj->dial_prefix!=NULL) ms_free(obj->dial_prefix);
|
||||
if (obj->op) sal_op_release(obj->op);
|
||||
if (obj->publish_op) sal_op_release(obj->publish_op);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -166,10 +167,16 @@ int linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route)
|
|||
obj->reg_route=NULL;
|
||||
}
|
||||
if (route!=NULL){
|
||||
LinphoneAddress *addr;
|
||||
/*try to prepend 'sip:' */
|
||||
if (strstr(route,"sip:")==NULL){
|
||||
obj->reg_route=ms_strdup_printf("sip:%s",route);
|
||||
}else obj->reg_route=ms_strdup(route);
|
||||
addr=linphone_address_new(obj->reg_route);
|
||||
if (addr==NULL){
|
||||
ms_free(obj->reg_route);
|
||||
obj->reg_route=NULL;
|
||||
}else linphone_address_destroy(addr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -263,6 +270,7 @@ static char *guess_contact_for_register(LinphoneProxyConfig *obj){
|
|||
|
||||
static void linphone_proxy_config_register(LinphoneProxyConfig *obj){
|
||||
const char *id_str;
|
||||
|
||||
if (obj->reg_identity!=NULL) id_str=obj->reg_identity;
|
||||
else id_str=linphone_core_get_primary_contact(obj->lc);
|
||||
if (obj->reg_sendregister){
|
||||
|
|
@ -274,10 +282,10 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *obj){
|
|||
sal_op_set_contact(obj->op,contact);
|
||||
ms_free(contact);
|
||||
sal_op_set_user_pointer(obj->op,obj);
|
||||
if (!sal_register(obj->op,obj->reg_proxy,obj->reg_identity,obj->expires)) {
|
||||
gstate_new_state(obj->lc,GSTATE_REG_PENDING,NULL);
|
||||
if (sal_register(obj->op,obj->reg_proxy,obj->reg_identity,obj->expires)==0) {
|
||||
linphone_proxy_config_set_state(obj,LinphoneRegistrationProgress,"Registration in progress");
|
||||
} else {
|
||||
gstate_new_state(obj->lc,GSTATE_REG_FAILED,NULL);
|
||||
linphone_proxy_config_set_state(obj,LinphoneRegistrationFailed,"Registration failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -432,7 +440,9 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy,
|
|||
SalOp *op=sal_op_new(proxy->lc->sal);
|
||||
err=sal_publish(op,linphone_proxy_config_get_identity(proxy),
|
||||
linphone_proxy_config_get_identity(proxy),linphone_online_status_to_sal(presence_mode));
|
||||
sal_op_release(op);
|
||||
if (proxy->publish_op!=NULL)
|
||||
sal_op_release(proxy->publish_op);
|
||||
proxy->publish_op=op;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -690,8 +700,11 @@ void linphone_proxy_config_update(LinphoneProxyConfig *cfg){
|
|||
if (cfg->type && cfg->ssctx==NULL){
|
||||
linphone_proxy_config_activate_sip_setup(cfg);
|
||||
}
|
||||
if (lc->sip_conf.register_only_when_network_is_up || lc->network_reachable)
|
||||
if (!lc->sip_conf.register_only_when_network_is_up || lc->network_reachable)
|
||||
linphone_proxy_config_register(cfg);
|
||||
if (cfg->publish && cfg->publish_op==NULL){
|
||||
linphone_proxy_config_send_publish(cfg,lc->presence_mode);
|
||||
}
|
||||
cfg->commit=FALSE;
|
||||
}
|
||||
}
|
||||
|
|
@ -796,6 +809,45 @@ void * linphone_proxy_config_get_user_data(LinphoneProxyConfig *cr) {
|
|||
return cr->user_data;
|
||||
}
|
||||
|
||||
|
||||
void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const char *message){
|
||||
LinphoneCore *lc=cfg->lc;
|
||||
cfg->state=state;
|
||||
if (lc && lc->vtable.registration_state_changed){
|
||||
lc->vtable.registration_state_changed(lc,cfg,state,message);
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneRegistrationState linphone_proxy_config_get_state(const LinphoneProxyConfig *cfg){
|
||||
return cfg->state;
|
||||
}
|
||||
|
||||
const char *linphone_registration_state_to_string(LinphoneRegistrationState cs){
|
||||
switch(cs){
|
||||
case LinphoneRegistrationCleared:
|
||||
return "LinphoneRegistrationCleared";
|
||||
break;
|
||||
case LinphoneRegistrationNone:
|
||||
return "LinphoneRegistrationNone";
|
||||
break;
|
||||
case LinphoneRegistrationProgress:
|
||||
return "LinphoneRegistrationProgress";
|
||||
break;
|
||||
case LinphoneRegistrationOk:
|
||||
return "LinphoneRegistrationOk";
|
||||
break;
|
||||
case LinphoneRegistrationFailed:
|
||||
return "LinphoneRegistrationFailed";
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LinphoneReason linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg) {
|
||||
return cfg->error;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_error(LinphoneProxyConfig *cfg,LinphoneReason error) {
|
||||
cfg->error = error;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
105
coreapi/sal.c
105
coreapi/sal.c
|
|
@ -52,21 +52,110 @@ void sal_media_description_unref(SalMediaDescription *md){
|
|||
}
|
||||
}
|
||||
|
||||
const SalStreamDescription *sal_media_description_find_stream(const SalMediaDescription *md,
|
||||
SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
|
||||
SalMediaProto proto, SalStreamType type){
|
||||
int i;
|
||||
for(i=0;i<md->nstreams;++i){
|
||||
const SalStreamDescription *ss=&md->streams[i];
|
||||
SalStreamDescription *ss=&md->streams[i];
|
||||
if (ss->proto==proto && ss->type==type) return ss;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool_t sal_media_description_empty(SalMediaDescription *md){
|
||||
bool_t sal_media_description_empty(const SalMediaDescription *md){
|
||||
int i;
|
||||
for(i=0;i<md->nstreams;++i){
|
||||
const SalStreamDescription *ss=&md->streams[i];
|
||||
if (ss->port!=0) return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir){
|
||||
int i;
|
||||
for(i=0;i<md->nstreams;++i){
|
||||
SalStreamDescription *ss=&md->streams[i];
|
||||
if (ss->port!=0) return FALSE;
|
||||
ss->dir=stream_dir;
|
||||
}
|
||||
}
|
||||
|
||||
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
|
||||
int i;
|
||||
bool_t found=FALSE;
|
||||
|
||||
/* we are looking for at least one stream with requested direction, inactive streams are ignored*/
|
||||
for(i=0;i<md->nstreams;++i){
|
||||
const SalStreamDescription *ss=&md->streams[i];
|
||||
if (ss->dir==stream_dir) found=TRUE;
|
||||
else{
|
||||
if (ss->dir!=SalStreamInactive) return FALSE;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
static bool_t fmtp_equals(const char *p1, const char *p2){
|
||||
if (p1 && p2 && strcmp(p1,p2)==0) return TRUE;
|
||||
if (p1==NULL && p2==NULL) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
*/
|
||||
|
||||
static bool_t payload_type_equals(const PayloadType *p1, const PayloadType *p2){
|
||||
if (p1->type!=p2->type) return FALSE;
|
||||
if (strcmp(p1->mime_type,p2->mime_type)!=0) return FALSE;
|
||||
if (p1->clock_rate!=p2->clock_rate) return FALSE;
|
||||
if (p1->channels!=p2->channels) return FALSE;
|
||||
/*
|
||||
Do not compare fmtp right now: they are modified internally when the call is started
|
||||
*/
|
||||
/*
|
||||
if (!fmtp_equals(p1->recv_fmtp,p2->recv_fmtp) ||
|
||||
!fmtp_equals(p1->send_fmtp,p2->send_fmtp))
|
||||
return FALSE;
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool_t payload_list_equals(const MSList *l1, const MSList *l2){
|
||||
const MSList *e1,*e2;
|
||||
for(e1=l1,e2=l2;e1!=NULL && e2!=NULL; e1=e1->next,e2=e2->next){
|
||||
PayloadType *p1=(PayloadType*)e1->data;
|
||||
PayloadType *p2=(PayloadType*)e2->data;
|
||||
if (!payload_type_equals(p1,p2))
|
||||
return FALSE;
|
||||
}
|
||||
if (e1!=NULL || e2!=NULL){
|
||||
/*means one list is longer than the other*/
|
||||
abort();
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t sal_stream_description_equals(const SalStreamDescription *sd1, const SalStreamDescription *sd2){
|
||||
if (sd1->proto!=sd2->proto) return FALSE;
|
||||
if (sd1->type!=sd2->type) return FALSE;
|
||||
if (strcmp(sd1->addr,sd2->addr)!=0) return FALSE;
|
||||
if (sd1->port!=sd2->port) return FALSE;
|
||||
if (!payload_list_equals(sd1->payloads,sd2->payloads)) return FALSE;
|
||||
if (sd1->bandwidth!=sd2->bandwidth) return FALSE;
|
||||
if (sd1->ptime!=sd2->ptime) return FALSE;
|
||||
/* compare candidates: TODO */
|
||||
if (sd1->dir!=sd2->dir) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2){
|
||||
int i;
|
||||
|
||||
if (strcmp(md1->addr,md2->addr)!=0) return FALSE;
|
||||
if (md1->nstreams!=md2->nstreams) return FALSE;
|
||||
if (md1->bandwidth!=md2->bandwidth) return FALSE;
|
||||
for(i=0;i<md1->nstreams;++i){
|
||||
if (!sal_stream_description_equals(&md1->streams[i],&md2->streams[i]))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -120,6 +209,10 @@ const char *sal_op_get_route(const SalOp *op){
|
|||
return ((SalOpBase*)op)->route;
|
||||
}
|
||||
|
||||
const char *sal_op_get_remote_ua(const SalOp *op){
|
||||
return ((SalOpBase*)op)->remote_ua;
|
||||
}
|
||||
|
||||
void *sal_op_get_user_pointer(const SalOp *op){
|
||||
return ((SalOpBase*)op)->user_pointer;
|
||||
}
|
||||
|
|
@ -164,6 +257,10 @@ void __sal_op_free(SalOp *op){
|
|||
ms_free(b->origin);
|
||||
b->origin=NULL;
|
||||
}
|
||||
if (b->remote_ua){
|
||||
ms_free(b->remote_ua);
|
||||
b->remote_ua=NULL;
|
||||
}
|
||||
if (b->local_media)
|
||||
sal_media_description_unref(b->local_media);
|
||||
if (b->remote_media)
|
||||
|
|
|
|||
|
|
@ -86,6 +86,13 @@ typedef enum{
|
|||
SalProtoRtpSavp
|
||||
}SalMediaProto;
|
||||
|
||||
typedef enum{
|
||||
SalStreamSendRecv,
|
||||
SalStreamSendOnly,
|
||||
SalStreamRecvOnly,
|
||||
SalStreamInactive
|
||||
}SalStreamDir;
|
||||
|
||||
typedef struct SalEndpointCandidate{
|
||||
char addr[64];
|
||||
int port;
|
||||
|
|
@ -102,6 +109,7 @@ typedef struct SalStreamDescription{
|
|||
int bandwidth;
|
||||
int ptime;
|
||||
SalEndpointCandidate candidates[SAL_ENDPOINT_CANDIDATE_MAX];
|
||||
SalStreamDir dir;
|
||||
} SalStreamDescription;
|
||||
|
||||
#define SAL_MEDIA_DESCRIPTION_MAX_STREAMS 4
|
||||
|
|
@ -118,9 +126,12 @@ typedef struct SalMediaDescription{
|
|||
SalMediaDescription *sal_media_description_new();
|
||||
void sal_media_description_ref(SalMediaDescription *md);
|
||||
void sal_media_description_unref(SalMediaDescription *md);
|
||||
bool_t sal_media_description_empty(SalMediaDescription *md);
|
||||
const SalStreamDescription *sal_media_description_find_stream(const SalMediaDescription *md,
|
||||
bool_t sal_media_description_empty(const SalMediaDescription *md);
|
||||
bool_t sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2);
|
||||
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir dir);
|
||||
SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
|
||||
SalMediaProto proto, SalStreamType type);
|
||||
void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir);
|
||||
|
||||
/*this structure must be at the first byte of the SalOp structure defined by implementors*/
|
||||
typedef struct SalOpBase{
|
||||
|
|
@ -130,6 +141,7 @@ typedef struct SalOpBase{
|
|||
char *from;
|
||||
char *to;
|
||||
char *origin;
|
||||
char *remote_ua;
|
||||
SalMediaDescription *local_media;
|
||||
SalMediaDescription *remote_media;
|
||||
void *user_pointer;
|
||||
|
|
@ -177,9 +189,9 @@ typedef void (*SalOnCallReceived)(SalOp *op);
|
|||
typedef void (*SalOnCallRinging)(SalOp *op);
|
||||
typedef void (*SalOnCallAccepted)(SalOp *op);
|
||||
typedef void (*SalOnCallAck)(SalOp *op);
|
||||
typedef void (*SalOnCallUpdated)(SalOp *op);
|
||||
typedef void (*SalOnCallUpdating)(SalOp *op);/*< Called when a reINVITE is received*/
|
||||
typedef void (*SalOnCallTerminated)(SalOp *op, const char *from);
|
||||
typedef void (*SalOnCallFailure)(SalOp *op, SalError error, SalReason reason, const char *details);
|
||||
typedef void (*SalOnCallFailure)(SalOp *op, SalError error, SalReason reason, const char *details, int code);
|
||||
typedef void (*SalOnAuthRequested)(SalOp *op, const char *realm, const char *username);
|
||||
typedef void (*SalOnAuthSuccess)(SalOp *op, const char *realm, const char *username);
|
||||
typedef void (*SalOnRegisterSuccess)(SalOp *op, bool_t registered);
|
||||
|
|
@ -200,7 +212,7 @@ typedef struct SalCallbacks{
|
|||
SalOnCallRinging call_ringing;
|
||||
SalOnCallAccepted call_accepted;
|
||||
SalOnCallAck call_ack;
|
||||
SalOnCallUpdated call_updated;
|
||||
SalOnCallUpdating call_updating;
|
||||
SalOnCallTerminated call_terminated;
|
||||
SalOnCallFailure call_failure;
|
||||
SalOnAuthRequested auth_requested;
|
||||
|
|
@ -234,6 +246,7 @@ void sal_set_user_agent(Sal *ctx, const char *user_agent);
|
|||
/*keepalive period in ms*/
|
||||
void sal_set_keepalive_period(Sal *ctx,unsigned int value);
|
||||
void sal_use_session_timers(Sal *ctx, int expires);
|
||||
void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec);
|
||||
int sal_iterate(Sal *sal);
|
||||
MSList * sal_get_pending_auths(Sal *sal);
|
||||
|
||||
|
|
@ -257,17 +270,27 @@ const char *sal_op_get_route(const SalOp *op);
|
|||
const char *sal_op_get_proxy(const SalOp *op);
|
||||
/*for incoming requests, returns the origin of the packet as a sip uri*/
|
||||
const char *sal_op_get_network_origin(const SalOp *op);
|
||||
/*returns far-end "User-Agent" string */
|
||||
const char *sal_op_get_remote_ua(const SalOp *op);
|
||||
void *sal_op_get_user_pointer(const SalOp *op);
|
||||
|
||||
/*Call API*/
|
||||
int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc);
|
||||
int sal_call(SalOp *h, const char *from, const char *to);
|
||||
int sal_call_notify_ringing(SalOp *h);
|
||||
int sal_call_notify_ringing(SalOp *h, bool_t early_media);
|
||||
/*accept an incoming call or, during a call accept a reINVITE*/
|
||||
int sal_call_accept(SalOp*h);
|
||||
int sal_call_decline(SalOp *h, SalReason reason, const char *redirection /*optional*/);
|
||||
int sal_call_hold(SalOp *h, bool_t holdon);
|
||||
int sal_call_update(SalOp *h);
|
||||
SalMediaDescription * sal_call_get_final_media_description(SalOp *h);
|
||||
int sal_refer(SalOp *h, const char *refer_to);
|
||||
int sal_refer_accept(SalOp *h);
|
||||
int sal_call_refer(SalOp *h, const char *refer_to);
|
||||
int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h);
|
||||
int sal_call_accept_refer(SalOp *h);
|
||||
/*informs this call is consecutive to an incoming refer */
|
||||
int sal_call_set_referer(SalOp *h, SalOp *refered_call);
|
||||
/* returns the SalOp of a call that should be replaced by h, if any */
|
||||
SalOp *sal_call_get_replaces(SalOp *h);
|
||||
int sal_call_send_dtmf(SalOp *h, char dtmf);
|
||||
int sal_call_terminate(SalOp *h);
|
||||
bool_t sal_call_autoanswer_asked(SalOp *op);
|
||||
|
|
@ -306,5 +329,4 @@ void __sal_op_init(SalOp *b, Sal *sal);
|
|||
void __sal_op_set_network_origin(SalOp *op, const char *origin /*a sip uri*/);
|
||||
void __sal_op_free(SalOp *b);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
static void text_received(Sal *sal, eXosip_event_t *ev);
|
||||
|
||||
static void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
|
||||
void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
|
||||
void *data;
|
||||
while((data=osip_list_get(l,0))!=NULL){
|
||||
osip_list_remove(l,0);
|
||||
|
|
@ -102,7 +102,7 @@ static SalOp * sal_find_other(Sal *sal, osip_message_t *response){
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
|
||||
void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
|
||||
osip_call_id_t *callid=osip_message_get_call_id(request);
|
||||
if (callid==NULL) {
|
||||
ms_error("There is no call id in the request !");
|
||||
|
|
@ -161,6 +161,8 @@ SalOp * sal_op_new(Sal *sal){
|
|||
op->sdp_answer=NULL;
|
||||
op->reinvite=FALSE;
|
||||
op->call_id=NULL;
|
||||
op->replaces=NULL;
|
||||
op->referred_by=NULL;
|
||||
op->masquerade_via=FALSE;
|
||||
op->auto_answer_asked=FALSE;
|
||||
return op;
|
||||
|
|
@ -201,6 +203,12 @@ void sal_op_release(SalOp *op){
|
|||
sal_remove_other(op->base.root,op);
|
||||
osip_call_id_free(op->call_id);
|
||||
}
|
||||
if (op->replaces){
|
||||
ms_free(op->replaces);
|
||||
}
|
||||
if (op->referred_by){
|
||||
ms_free(op->referred_by);
|
||||
}
|
||||
__sal_op_free(op);
|
||||
}
|
||||
|
||||
|
|
@ -284,8 +292,8 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
|
|||
ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
|
||||
if (ctx->callbacks.call_terminated==NULL)
|
||||
ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
|
||||
if (ctx->callbacks.call_updated==NULL)
|
||||
ctx->callbacks.call_updated=(SalOnCallUpdated)unimplemented_stub;
|
||||
if (ctx->callbacks.call_updating==NULL)
|
||||
ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
|
||||
if (ctx->callbacks.auth_requested==NULL)
|
||||
ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
|
||||
if (ctx->callbacks.auth_success==NULL)
|
||||
|
|
@ -371,6 +379,10 @@ void sal_use_session_timers(Sal *ctx, int expires){
|
|||
ctx->session_expires=expires;
|
||||
}
|
||||
|
||||
void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
|
||||
ctx->one_matching_codec=one_matching_codec;
|
||||
}
|
||||
|
||||
MSList *sal_get_pending_auths(Sal *sal){
|
||||
return ms_list_copy(sal->pending_auths);
|
||||
}
|
||||
|
|
@ -441,7 +453,7 @@ static void sdp_process(SalOp *h){
|
|||
offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
|
||||
}else{
|
||||
int i;
|
||||
offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result);
|
||||
offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
|
||||
h->sdp_answer=media_description_to_sdp(h->result);
|
||||
strcpy(h->result->addr,h->base.remote_media->addr);
|
||||
h->result->bandwidth=h->base.remote_media->bandwidth;
|
||||
|
|
@ -490,6 +502,12 @@ int sal_call(SalOp *h, const char *from, const char *to){
|
|||
h->sdp_offering=TRUE;
|
||||
set_sdp_from_desc(invite,h->base.local_media);
|
||||
}else h->sdp_offering=FALSE;
|
||||
if (h->replaces){
|
||||
osip_message_set_header(invite,"Replaces",h->replaces);
|
||||
if (h->referred_by)
|
||||
osip_message_set_header(invite,"Referred-By",h->referred_by);
|
||||
}
|
||||
|
||||
eXosip_lock();
|
||||
err=eXosip_call_send_initial_invite(invite);
|
||||
eXosip_unlock();
|
||||
|
|
@ -503,10 +521,31 @@ int sal_call(SalOp *h, const char *from, const char *to){
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sal_call_notify_ringing(SalOp *h){
|
||||
eXosip_lock();
|
||||
eXosip_call_send_answer(h->tid,180,NULL);
|
||||
eXosip_unlock();
|
||||
int sal_call_notify_ringing(SalOp *h, bool_t early_media){
|
||||
osip_message_t *msg;
|
||||
int err;
|
||||
|
||||
/*if early media send also 180 and 183 */
|
||||
if (early_media && h->sdp_answer){
|
||||
msg=NULL;
|
||||
eXosip_lock();
|
||||
err=eXosip_call_build_answer(h->tid,180,&msg);
|
||||
if (msg){
|
||||
set_sdp(msg,h->sdp_answer);
|
||||
eXosip_call_send_answer(h->tid,180,msg);
|
||||
}
|
||||
msg=NULL;
|
||||
err=eXosip_call_build_answer(h->tid,183,&msg);
|
||||
if (msg){
|
||||
set_sdp(msg,h->sdp_answer);
|
||||
eXosip_call_send_answer(h->tid,183,msg);
|
||||
}
|
||||
eXosip_unlock();
|
||||
}else{
|
||||
eXosip_lock();
|
||||
eXosip_call_send_answer(h->tid,180,NULL);
|
||||
eXosip_unlock();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -585,6 +624,14 @@ SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
|
|||
return h->result;
|
||||
}
|
||||
|
||||
int sal_call_set_referer(SalOp *h, SalOp *refered_call){
|
||||
if (refered_call->replaces)
|
||||
h->replaces=ms_strdup(refered_call->replaces);
|
||||
if (refered_call->referred_by)
|
||||
h->referred_by=ms_strdup(refered_call->referred_by);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sal_ping(SalOp *op, const char *from, const char *to){
|
||||
osip_message_t *options=NULL;
|
||||
|
||||
|
|
@ -603,7 +650,7 @@ int sal_ping(SalOp *op, const char *from, const char *to){
|
|||
return -1;
|
||||
}
|
||||
|
||||
int sal_refer_accept(SalOp *op){
|
||||
int sal_call_accept_refer(SalOp *op){
|
||||
osip_message_t *msg=NULL;
|
||||
int err=0;
|
||||
eXosip_lock();
|
||||
|
|
@ -623,7 +670,7 @@ int sal_refer_accept(SalOp *op){
|
|||
return err;
|
||||
}
|
||||
|
||||
int sal_refer(SalOp *h, const char *refer_to){
|
||||
int sal_call_refer(SalOp *h, const char *refer_to){
|
||||
osip_message_t *msg=NULL;
|
||||
int err=0;
|
||||
eXosip_lock();
|
||||
|
|
@ -634,6 +681,38 @@ int sal_refer(SalOp *h, const char *refer_to){
|
|||
return err;
|
||||
}
|
||||
|
||||
int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
|
||||
osip_message_t *msg=NULL;
|
||||
char referto[256]={0};
|
||||
int err=0;
|
||||
eXosip_lock();
|
||||
if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
|
||||
ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
|
||||
eXosip_unlock();
|
||||
return -1;
|
||||
}
|
||||
eXosip_call_build_refer(h->did,referto, &msg);
|
||||
osip_message_set_header(msg,"Referred-By",h->base.from);
|
||||
if (msg) err=eXosip_call_send_request(h->did, msg);
|
||||
else err=-1;
|
||||
eXosip_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
SalOp *sal_call_get_replaces(SalOp *h){
|
||||
if (h->replaces!=NULL){
|
||||
int cid;
|
||||
eXosip_lock();
|
||||
cid=eXosip_call_find_by_replaces(h->replaces);
|
||||
eXosip_unlock();
|
||||
if (cid>0){
|
||||
SalOp *ret=sal_find_call(h->base.root,cid);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int sal_call_send_dtmf(SalOp *h, char dtmf){
|
||||
osip_message_t *msg=NULL;
|
||||
char dtmf_body[128];
|
||||
|
|
@ -654,9 +733,13 @@ int sal_call_send_dtmf(SalOp *h, char dtmf){
|
|||
}
|
||||
|
||||
int sal_call_terminate(SalOp *h){
|
||||
int err;
|
||||
eXosip_lock();
|
||||
eXosip_call_terminate(h->cid,h->did);
|
||||
err=eXosip_call_terminate(h->cid,h->did);
|
||||
eXosip_unlock();
|
||||
if (err!=0){
|
||||
ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
|
||||
}
|
||||
sal_remove_call(h->base.root,h);
|
||||
h->cid=-1;
|
||||
return 0;
|
||||
|
|
@ -697,6 +780,31 @@ static void set_network_origin(SalOp *op, osip_message_t *req){
|
|||
__sal_op_set_network_origin(op,origin);
|
||||
}
|
||||
|
||||
static void set_remote_ua(SalOp* op, osip_message_t *req){
|
||||
if (op->base.remote_ua==NULL){
|
||||
osip_header_t *h=NULL;
|
||||
osip_message_get_user_agent(req,0,&h);
|
||||
if (h){
|
||||
op->base.remote_ua=ms_strdup(h->hvalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_replaces(SalOp *op, osip_message_t *req){
|
||||
osip_header_t *h=NULL;
|
||||
|
||||
if (op->replaces){
|
||||
ms_free(op->replaces);
|
||||
op->replaces=NULL;
|
||||
}
|
||||
osip_message_header_get_byname(req,"replaces",0,&h);
|
||||
if (h){
|
||||
if (h->hvalue && h->hvalue[0]!='\0'){
|
||||
op->replaces=ms_strdup(h->hvalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
|
||||
if (ev->cid>0){
|
||||
return sal_find_call(sal,ev->cid);
|
||||
|
|
@ -704,6 +812,9 @@ static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
|
|||
if (ev->rid>0){
|
||||
return sal_find_register(sal,ev->rid);
|
||||
}
|
||||
if (ev->sid>0){
|
||||
return sal_find_out_subscribe(sal,ev->sid);
|
||||
}
|
||||
if (ev->response) return sal_find_other(sal,ev->response);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -716,6 +827,8 @@ static void inc_new_call(Sal *sal, eXosip_event_t *ev){
|
|||
sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
|
||||
|
||||
set_network_origin(op,ev->request);
|
||||
set_remote_ua(op,ev->request);
|
||||
set_replaces(op,ev->request);
|
||||
|
||||
if (sdp){
|
||||
op->sdp_offering=FALSE;
|
||||
|
|
@ -769,35 +882,27 @@ static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
|
|||
sal_media_description_unref(op->base.remote_media);
|
||||
op->base.remote_media=NULL;
|
||||
}
|
||||
eXosip_lock();
|
||||
eXosip_call_build_answer(ev->tid,200,&msg);
|
||||
eXosip_unlock();
|
||||
if (msg==NULL) return;
|
||||
if (op->base.root->session_expires!=0){
|
||||
if (op->supports_session_timers) osip_message_set_supported(msg, "timer");
|
||||
}
|
||||
if (op->base.contact){
|
||||
_osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
|
||||
osip_message_set_contact(msg,op->base.contact);
|
||||
if (op->result){
|
||||
sal_media_description_unref(op->result);
|
||||
op->result=NULL;
|
||||
}
|
||||
if (sdp){
|
||||
op->sdp_offering=FALSE;
|
||||
op->base.remote_media=sal_media_description_new();
|
||||
sdp_to_media_description(sdp,op->base.remote_media);
|
||||
sdp_message_free(sdp);
|
||||
sdp_process(op);
|
||||
if (op->sdp_answer!=NULL){
|
||||
set_sdp(msg,op->sdp_answer);
|
||||
sdp_message_free(op->sdp_answer);
|
||||
op->sdp_answer=NULL;
|
||||
}
|
||||
sal->callbacks.call_updating(op);
|
||||
}else {
|
||||
op->sdp_offering=TRUE;
|
||||
set_sdp_from_desc(msg,op->base.local_media);
|
||||
eXosip_lock();
|
||||
eXosip_call_build_answer(ev->tid,200,&msg);
|
||||
if (msg!=NULL){
|
||||
set_sdp_from_desc(msg,op->base.local_media);
|
||||
eXosip_call_send_answer(ev->tid,200,msg);
|
||||
}
|
||||
eXosip_unlock();
|
||||
}
|
||||
eXosip_lock();
|
||||
eXosip_call_send_answer(ev->tid,200,msg);
|
||||
eXosip_unlock();
|
||||
|
||||
}
|
||||
|
||||
static void handle_ack(Sal *sal, eXosip_event_t *ev){
|
||||
|
|
@ -816,7 +921,7 @@ static void handle_ack(Sal *sal, eXosip_event_t *ev){
|
|||
sdp_message_free(sdp);
|
||||
}
|
||||
if (op->reinvite){
|
||||
sal->callbacks.call_updated(op);
|
||||
if (sdp) sal->callbacks.call_updating(op);
|
||||
op->reinvite=FALSE;
|
||||
}else{
|
||||
sal->callbacks.call_ack(op);
|
||||
|
|
@ -840,6 +945,7 @@ static void update_contact_from_response(SalOp *op, osip_message_t *response){
|
|||
tmp=sal_address_as_string(addr);
|
||||
ms_message("Contact address updated to %s for this dialog",tmp);
|
||||
sal_op_set_contact(op,tmp);
|
||||
sal_address_destroy(addr);
|
||||
ms_free(tmp);
|
||||
}
|
||||
}
|
||||
|
|
@ -855,7 +961,8 @@ static int call_proceeding(Sal *sal, eXosip_event_t *ev){
|
|||
eXosip_unlock();
|
||||
return -1;
|
||||
}
|
||||
op->did=ev->did;
|
||||
if (ev->did>0)
|
||||
op->did=ev->did;
|
||||
op->tid=ev->tid;
|
||||
|
||||
/* update contact if received and rport are set by the server
|
||||
|
|
@ -868,7 +975,8 @@ static void call_ringing(Sal *sal, eXosip_event_t *ev){
|
|||
sdp_message_t *sdp;
|
||||
SalOp *op=find_op(sal,ev);
|
||||
if (call_proceeding(sal, ev)==-1) return;
|
||||
|
||||
|
||||
set_remote_ua(op,ev->response);
|
||||
sdp=eXosip_get_sdp_info(ev->response);
|
||||
if (sdp){
|
||||
op->base.remote_media=sal_media_description_new();
|
||||
|
|
@ -891,7 +999,8 @@ static void call_accepted(Sal *sal, eXosip_event_t *ev){
|
|||
}
|
||||
|
||||
op->did=ev->did;
|
||||
|
||||
set_remote_ua(op,ev->response);
|
||||
|
||||
sdp=eXosip_get_sdp_info(ev->response);
|
||||
if (sdp){
|
||||
op->base.remote_media=sal_media_description_new();
|
||||
|
|
@ -938,7 +1047,7 @@ static void call_released(Sal *sal, eXosip_event_t *ev){
|
|||
}
|
||||
op->cid=-1;
|
||||
if (op->did==-1)
|
||||
sal->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,NULL);
|
||||
sal->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,NULL, 487);
|
||||
}
|
||||
|
||||
static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
|
||||
|
|
@ -1100,7 +1209,7 @@ static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
|
|||
sr=SalReasonUnknown;
|
||||
}else error=SalErrorNoResponse;
|
||||
}
|
||||
sal->callbacks.call_failure(op,error,sr,reason);
|
||||
sal->callbacks.call_failure(op,error,sr,reason,code);
|
||||
if (computedReason != NULL){
|
||||
ms_free(computedReason);
|
||||
}
|
||||
|
|
@ -1127,8 +1236,18 @@ static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
|
|||
eXosip_call_build_answer(ev->tid,200,&ans);
|
||||
if (ans)
|
||||
eXosip_call_send_answer(ev->tid,200,ans);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*in all other cases we must say it is not implemented.*/
|
||||
{
|
||||
osip_message_t *ans=NULL;
|
||||
eXosip_lock();
|
||||
eXosip_call_build_answer(ev->tid,501,&ans);
|
||||
if (ans)
|
||||
eXosip_call_send_answer(ev->tid,501,ans);
|
||||
eXosip_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
|
||||
|
|
@ -1162,6 +1281,59 @@ static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
|
|||
}
|
||||
}
|
||||
|
||||
static void fill_options_answer(osip_message_t *options){
|
||||
osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
|
||||
osip_message_set_accept(options,"application/sdp");
|
||||
}
|
||||
|
||||
static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
|
||||
osip_header_t *h=NULL;
|
||||
osip_message_t *ans=NULL;
|
||||
ms_message("Receiving REFER request !");
|
||||
osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
|
||||
|
||||
if (h){
|
||||
osip_from_t *from=NULL;
|
||||
char *tmp;
|
||||
osip_from_init(&from);
|
||||
|
||||
if (osip_from_parse(from,h->hvalue)==0){
|
||||
if (op ){
|
||||
osip_uri_header_t *uh=NULL;
|
||||
osip_header_t *referred_by=NULL;
|
||||
osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
|
||||
if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
|
||||
ms_message("Found replaces in Refer-To");
|
||||
if (op->replaces){
|
||||
ms_free(op->replaces);
|
||||
}
|
||||
op->replaces=ms_strdup(uh->gvalue);
|
||||
}
|
||||
osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
|
||||
if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
|
||||
if (op->referred_by)
|
||||
ms_free(op->referred_by);
|
||||
op->referred_by=ms_strdup(referred_by->hvalue);
|
||||
}
|
||||
}
|
||||
osip_uri_header_freelist(&from->url->url_headers);
|
||||
osip_from_to_str(from,&tmp);
|
||||
sal->callbacks.refer_received(sal,op,tmp);
|
||||
osip_free(tmp);
|
||||
osip_from_free(from);
|
||||
}
|
||||
eXosip_lock();
|
||||
eXosip_call_build_answer(ev->tid,202,&ans);
|
||||
if (ans)
|
||||
eXosip_call_send_answer(ev->tid,202,ans);
|
||||
eXosip_unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
ms_warning("cannot do anything with the refer without destination\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void call_message_new(Sal *sal, eXosip_event_t *ev){
|
||||
osip_message_t *ans=NULL;
|
||||
if (ev->request){
|
||||
|
|
@ -1190,8 +1362,7 @@ static void call_message_new(Sal *sal, eXosip_event_t *ev){
|
|||
eXosip_call_send_answer(ev->tid,200,ans);
|
||||
eXosip_unlock();
|
||||
}
|
||||
}
|
||||
if(MSG_IS_MESSAGE(ev->request)){
|
||||
}else if(MSG_IS_MESSAGE(ev->request)){
|
||||
/* SIP messages could be received into call */
|
||||
text_received(sal, ev);
|
||||
eXosip_lock();
|
||||
|
|
@ -1199,27 +1370,12 @@ static void call_message_new(Sal *sal, eXosip_event_t *ev){
|
|||
if (ans)
|
||||
eXosip_call_send_answer(ev->tid,200,ans);
|
||||
eXosip_unlock();
|
||||
}
|
||||
if(MSG_IS_REFER(ev->request)){
|
||||
osip_header_t *h=NULL;
|
||||
}else if(MSG_IS_REFER(ev->request)){
|
||||
SalOp *op=find_op(sal,ev);
|
||||
|
||||
ms_message("Receiving REFER request !");
|
||||
osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
|
||||
eXosip_lock();
|
||||
eXosip_call_build_answer(ev->tid,202,&ans);
|
||||
if (ans)
|
||||
eXosip_call_send_answer(ev->tid,202,ans);
|
||||
eXosip_unlock();
|
||||
if (h){
|
||||
sal->callbacks.refer_received(sal,op,h->hvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
ms_warning("cannot do anything with the refer without destination\n");
|
||||
}
|
||||
}
|
||||
if(MSG_IS_NOTIFY(ev->request)){
|
||||
process_refer(sal,op,ev);
|
||||
}else if(MSG_IS_NOTIFY(ev->request)){
|
||||
osip_header_t *h=NULL;
|
||||
char *from=NULL;
|
||||
SalOp *op=find_op(sal,ev);
|
||||
|
|
@ -1236,6 +1392,14 @@ static void call_message_new(Sal *sal, eXosip_event_t *ev){
|
|||
eXosip_call_send_answer(ev->tid,200,ans);
|
||||
eXosip_unlock();
|
||||
osip_free(from);
|
||||
}else if (MSG_IS_OPTIONS(ev->request)){
|
||||
eXosip_lock();
|
||||
eXosip_call_build_answer(ev->tid,200,&ans);
|
||||
if (ans){
|
||||
fill_options_answer(ans);
|
||||
eXosip_call_send_answer(ev->tid,200,ans);
|
||||
}
|
||||
eXosip_unlock();
|
||||
}
|
||||
}else ms_warning("call_message_new: No request ?");
|
||||
}
|
||||
|
|
@ -1284,6 +1448,8 @@ static void text_received(Sal *sal, eXosip_event_t *ev){
|
|||
osip_free(from);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void other_request(Sal *sal, eXosip_event_t *ev){
|
||||
ms_message("in other_request");
|
||||
if (ev->request==NULL) return;
|
||||
|
|
@ -1293,8 +1459,7 @@ static void other_request(Sal *sal, eXosip_event_t *ev){
|
|||
}else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
|
||||
osip_message_t *options=NULL;
|
||||
eXosip_options_build_answer(ev->tid,200,&options);
|
||||
osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
|
||||
osip_message_set_accept(options,"application/sdp");
|
||||
fill_options_answer(options);
|
||||
eXosip_options_send_answer(ev->tid,200,options);
|
||||
}else if (strcmp(ev->request->sip_method,"WAKEUP")==0
|
||||
&& comes_from_local_if(ev->request)) {
|
||||
|
|
@ -1304,12 +1469,7 @@ static void other_request(Sal *sal, eXosip_event_t *ev){
|
|||
}else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
|
||||
ms_message("Receiving REFER request !");
|
||||
if (comes_from_local_if(ev->request)) {
|
||||
osip_header_t *h=NULL;
|
||||
osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
|
||||
eXosip_message_send_answer(ev->tid,200,NULL);
|
||||
if (h){
|
||||
sal->callbacks.refer_received(sal,NULL,h->hvalue);
|
||||
}
|
||||
process_refer(sal,NULL,ev);
|
||||
}else ms_warning("Ignored REFER not coming from this local loopback interface.");
|
||||
}else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
|
||||
inc_update(sal,ev);
|
||||
|
|
@ -1405,7 +1565,9 @@ static void registration_success(Sal *sal, eXosip_event_t *ev){
|
|||
if (!register_again_with_updated_contact(op,ev->request,ev->response)){
|
||||
sal->callbacks.register_success(op,registered);
|
||||
}
|
||||
}else registered=FALSE;
|
||||
}else {
|
||||
sal->callbacks.register_success(op,FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
|
||||
|
|
@ -1574,8 +1736,16 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){
|
|||
other_request_reply(sal,ev);
|
||||
break;
|
||||
case EXOSIP_MESSAGE_REQUESTFAILURE:
|
||||
if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
|
||||
return process_authentication(sal,ev);
|
||||
if (ev->response) {
|
||||
switch (ev->response->status_code) {
|
||||
case 407:
|
||||
case 401:
|
||||
return process_authentication(sal,ev);
|
||||
case 412: {
|
||||
eXosip_automatic_action ();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
other_request_reply(sal,ev);
|
||||
break;
|
||||
|
|
@ -1764,10 +1934,12 @@ void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
|
|||
ctx->keepalive_period=value;
|
||||
eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
|
||||
}
|
||||
|
||||
const char * sal_address_get_port(const SalAddress *addr) {
|
||||
const osip_from_t *u=(const osip_from_t*)addr;
|
||||
return null_if_empty(u->url->port);
|
||||
}
|
||||
|
||||
int sal_address_get_port_int(const SalAddress *uri) {
|
||||
const char* port = sal_address_get_port(uri);
|
||||
if (port != NULL) {
|
||||
|
|
@ -1777,3 +1949,58 @@ int sal_address_get_port_int(const SalAddress *uri) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a re-Invite used to hold the current call
|
||||
*/
|
||||
int sal_call_hold(SalOp *h, bool_t holdon)
|
||||
{
|
||||
int err=0;
|
||||
|
||||
osip_message_t *reinvite=NULL;
|
||||
if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != OSIP_SUCCESS || reinvite==NULL)
|
||||
return -1;
|
||||
osip_message_set_subject(reinvite,holdon ? "Phone call hold" : "Phone call resume" );
|
||||
osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
|
||||
if (h->base.root->session_expires!=0){
|
||||
osip_message_set_header(reinvite, "Session-expires", "200");
|
||||
osip_message_set_supported(reinvite, "timer");
|
||||
}
|
||||
//add something to say that the distant sip phone will be in sendonly/sendrecv mode
|
||||
if (h->base.local_media){
|
||||
h->sdp_offering=TRUE;
|
||||
sal_media_description_set_dir(h->base.local_media, holdon ? SalStreamSendOnly : SalStreamSendRecv);
|
||||
set_sdp_from_desc(reinvite,h->base.local_media);
|
||||
}else h->sdp_offering=FALSE;
|
||||
eXosip_lock();
|
||||
err = eXosip_call_send_request(h->did, reinvite);
|
||||
eXosip_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* sends a reinvite. Local media description may have changed by application since call establishment*/
|
||||
int sal_call_update(SalOp *h){
|
||||
int err=0;
|
||||
osip_message_t *reinvite=NULL;
|
||||
|
||||
eXosip_lock();
|
||||
if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != OSIP_SUCCESS || reinvite==NULL){
|
||||
eXosip_unlock();
|
||||
return -1;
|
||||
}
|
||||
eXosip_unlock();
|
||||
osip_message_set_subject(reinvite,osip_strdup("Phone call parameters updated"));
|
||||
osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
|
||||
if (h->base.root->session_expires!=0){
|
||||
osip_message_set_header(reinvite, "Session-expires", "200");
|
||||
osip_message_set_supported(reinvite, "timer");
|
||||
}
|
||||
if (h->base.local_media){
|
||||
h->sdp_offering=TRUE;
|
||||
set_sdp_from_desc(reinvite,h->base.local_media);
|
||||
}else h->sdp_offering=FALSE;
|
||||
eXosip_lock();
|
||||
err = eXosip_call_send_request(h->did, reinvite);
|
||||
eXosip_unlock();
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ struct Sal{
|
|||
int session_expires;
|
||||
int keepalive_period;
|
||||
void *up;
|
||||
bool_t one_matching_codec;
|
||||
};
|
||||
|
||||
struct SalOp{
|
||||
|
|
@ -56,6 +57,8 @@ struct SalOp{
|
|||
eXosip_event_t *pending_auth;
|
||||
osip_call_id_t *call_id; /*used for out of calls transaction in order
|
||||
to retrieve the operation when receiving a response*/
|
||||
char *replaces;
|
||||
char *referred_by;
|
||||
bool_t supports_session_timers;
|
||||
bool_t sdp_offering;
|
||||
bool_t reinvite;
|
||||
|
|
@ -65,6 +68,7 @@ struct SalOp{
|
|||
|
||||
void sal_remove_out_subscribe(Sal *sal, SalOp *op);
|
||||
void sal_remove_in_subscribe(Sal *sal, SalOp *op);
|
||||
void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request);
|
||||
|
||||
void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev);
|
||||
void sal_exosip_subscription_answered(Sal *sal,eXosip_event_t *ev);
|
||||
|
|
@ -72,8 +76,9 @@ void sal_exosip_notify_recv(Sal *sal,eXosip_event_t *ev);
|
|||
void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev);
|
||||
|
||||
void sal_exosip_in_subscription_closed(Sal *sal, eXosip_event_t *ev);
|
||||
|
||||
SalOp * sal_find_out_subscribe(Sal *sal, int sid);
|
||||
void sal_exosip_fix_route(SalOp *op);
|
||||
|
||||
void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*));
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,8 +20,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "sal_eXosip2.h"
|
||||
|
||||
typedef enum {
|
||||
PIDF = 0,
|
||||
RFCxxxx = 1,
|
||||
MSOLDPRES = 2
|
||||
} presence_type_t;
|
||||
|
||||
static SalOp * sal_find_out_subscribe(Sal *sal, int sid){
|
||||
/*
|
||||
* REVISIT: this static variable forces every dialog to use the same presence description type depending
|
||||
* on what is received on a single dialog...
|
||||
*/
|
||||
static presence_type_t presence_style = PIDF;
|
||||
|
||||
SalOp * sal_find_out_subscribe(Sal *sal, int sid){
|
||||
const MSList *elem;
|
||||
SalOp *op;
|
||||
for(elem=sal->out_subscribes;elem!=NULL;elem=elem->next){
|
||||
|
|
@ -83,9 +94,14 @@ int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){
|
|||
eXosip_lock();
|
||||
eXosip_message_build_request(&sip,"MESSAGE",sal_op_get_to(op),
|
||||
sal_op_get_from(op),sal_op_get_route(op));
|
||||
osip_message_set_content_type(sip,"text/plain");
|
||||
osip_message_set_body(sip,msg,strlen(msg));
|
||||
eXosip_message_send_request(sip);
|
||||
if (sip!=NULL){
|
||||
osip_message_set_content_type(sip,"text/plain");
|
||||
osip_message_set_body(sip,msg,strlen(msg));
|
||||
sal_add_other(op->base.root,op,sip);
|
||||
eXosip_message_send_request(sip);
|
||||
}else{
|
||||
ms_error("Could not build MESSAGE request !");
|
||||
}
|
||||
eXosip_unlock();
|
||||
}
|
||||
else
|
||||
|
|
@ -93,22 +109,16 @@ int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){
|
|||
/* we are currently in communication with the destination */
|
||||
eXosip_lock();
|
||||
//First we generate an INFO message to get the current call_id and a good cseq
|
||||
eXosip_call_build_info(op->did,&sip);
|
||||
eXosip_call_build_request(op->did,"MESSAGE",&sip);
|
||||
if(sip == NULL)
|
||||
{
|
||||
ms_warning("could not get a build info to send MESSAGE, maybe no previous call established ?");
|
||||
osip_message_free(sip);
|
||||
eXosip_unlock();
|
||||
return -1;
|
||||
}
|
||||
//change the sip_message to be a MESSAGE ...
|
||||
osip_free(osip_message_get_method(sip));
|
||||
osip_message_set_method(sip,osip_strdup("MESSAGE"));
|
||||
osip_free(osip_cseq_get_method(osip_message_get_cseq(sip)));
|
||||
osip_cseq_set_method(osip_message_get_cseq(sip),osip_strdup("MESSAGE"));
|
||||
osip_message_set_content_type(sip,"text/plain");
|
||||
osip_message_set_body(sip,msg,strlen(msg));
|
||||
eXosip_message_send_request(sip);
|
||||
eXosip_call_send_request(op->did,sip);
|
||||
eXosip_unlock();
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -125,6 +135,10 @@ int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
|
|||
eXosip_lock();
|
||||
eXosip_subscribe_build_initial_request(&msg,sal_op_get_to(op),sal_op_get_from(op),
|
||||
sal_op_get_route(op),"presence",600);
|
||||
if (op->base.contact){
|
||||
_osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
|
||||
osip_message_set_contact(msg,op->base.contact);
|
||||
}
|
||||
op->sid=eXosip_subscribe_send_initial_request(msg);
|
||||
eXosip_unlock();
|
||||
if (op->sid==-1){
|
||||
|
|
@ -156,6 +170,10 @@ int sal_subscribe_accept(SalOp *op){
|
|||
osip_message_t *msg;
|
||||
eXosip_lock();
|
||||
eXosip_insubscription_build_answer(op->tid,202,&msg);
|
||||
if (op->base.contact){
|
||||
_osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
|
||||
osip_message_set_contact(msg,op->base.contact);
|
||||
}
|
||||
eXosip_insubscription_send_answer(op->tid,202,msg);
|
||||
eXosip_unlock();
|
||||
return 0;
|
||||
|
|
@ -168,268 +186,372 @@ int sal_subscribe_decline(SalOp *op){
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void add_presence_body(osip_message_t *notify, SalPresenceStatus online_status)
|
||||
{
|
||||
char buf[1000];
|
||||
#ifdef SUPPORT_MSN
|
||||
int atom_id = 1000;
|
||||
#endif
|
||||
char *contact_info;
|
||||
static void mk_presence_body (const SalPresenceStatus online_status, const char *contact_info,
|
||||
char *buf, size_t buflen, presence_type_t ptype) {
|
||||
switch (ptype) {
|
||||
case RFCxxxx: {
|
||||
/* definition from http://msdn.microsoft.com/en-us/library/cc246202%28PROT.10%29.aspx */
|
||||
int atom_id = 1000;
|
||||
|
||||
osip_from_t *from=NULL;
|
||||
from=osip_message_get_from(notify);
|
||||
osip_uri_to_str(from->url,&contact_info);
|
||||
|
||||
#ifdef SUPPORT_MSN
|
||||
|
||||
if (online_status==SalPresenceOnline)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
if (online_status==SalPresenceOnline)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
|
||||
<address uri=\"%s\" priority=\"0.800000\">\n\
|
||||
<status status=\"open\" />\n\
|
||||
<msnsubstatus substatus=\"online\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==SalPresenceBusy)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
}
|
||||
else if (online_status == SalPresenceBusy ||
|
||||
online_status == SalPresenceDonotdisturb)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
|
||||
<address uri=\"%s\" priority=\"0.800000\">\n\
|
||||
<status status=\"inuse\" />\n\
|
||||
<msnsubstatus substatus=\"busy\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
</atom>\n</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==SalPresenceBerightback)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
}
|
||||
else if (online_status==SalPresenceBerightback)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
|
||||
<status status=\"inactive\" />\n\
|
||||
<address uri=\"%s\" priority=\"0.800000\">\n\
|
||||
<status status=\"open\" />\n\
|
||||
<msnsubstatus substatus=\"berightback\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==SalPresenceAway)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
}
|
||||
else if (online_status == SalPresenceAway ||
|
||||
online_status == SalPresenceMoved)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
|
||||
<status status=\"inactive\" />\n\
|
||||
<address uri=\"%s\" priority=\"0.800000\">\n\
|
||||
<status status=\"open\" />\n\
|
||||
<msnsubstatus substatus=\"away\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==SalPresenceOnthephone)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
}
|
||||
else if (online_status==SalPresenceOnthephone)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
|
||||
<address uri=\"%s\" priority=\"0.800000\">\n\
|
||||
<status status=\"inuse\" />\n\
|
||||
<msnsubstatus substatus=\"onthephone\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==SalPresenceOuttolunch)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
}
|
||||
else if (online_status==SalPresenceOuttolunch)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
|
||||
<address uri=\"%s\" priority=\"0.800000\">\n\
|
||||
<status status=\"open\" />\n\
|
||||
<msnsubstatus substatus=\"outtolunch\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s\" priority=\"0.800000\">\n\
|
||||
<status status=\"closed\" />\n\
|
||||
<msnsubstatus substatus=\"away\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSOLDPRES: {
|
||||
/* Couldn't find schema http://schemas.microsoft.com/2002/09/sip/presence
|
||||
* so messages format has been taken from Communigate that can send notify
|
||||
* requests with this schema
|
||||
*/
|
||||
int atom_id = 1000;
|
||||
|
||||
if (online_status==SalPresenceOnline)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s\">\n\
|
||||
<status status=\"open\" />\n\
|
||||
<msnsubstatus substatus=\"online\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status == SalPresenceBusy ||
|
||||
online_status == SalPresenceDonotdisturb)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s\">\n\
|
||||
<status status=\"inuse\" />\n\
|
||||
<msnsubstatus substatus=\"busy\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==SalPresenceBerightback)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s\">\n\
|
||||
<status status=\"inactive\" />\n\
|
||||
<msnsubstatus substatus=\"berightback\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status == SalPresenceAway ||
|
||||
online_status == SalPresenceMoved)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s\">\n\
|
||||
<status status=\"inactive\" />\n\
|
||||
<msnsubstatus substatus=\"idle\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==SalPresenceOnthephone)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s\">\n\
|
||||
<status status=\"inuse\" />\n\
|
||||
<msnsubstatus substatus=\"onthephone\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==SalPresenceOuttolunch)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s\">\n\
|
||||
<status status=\"inactive\" />\n\
|
||||
<msnsubstatus substatus=\"outtolunch\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
|
||||
<presence>\n\
|
||||
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
|
||||
<atom id=\"%i\">\n\
|
||||
<address uri=\"%s;user=ip\" priority=\"0.800000\">\n\
|
||||
<status status=\"inactive\" />\n\
|
||||
<msnsubstatus substatus=\"away\" />\n\
|
||||
<address uri=\"%s\">\n\
|
||||
<status status=\"closed\" />\n\
|
||||
<msnsubstatus substatus=\"offline\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: { /* use pidf+xml as default format, rfc4479, rfc4480, rfc3863 */
|
||||
|
||||
osip_message_set_body(notify, buf, strlen(buf));
|
||||
osip_message_set_content_type(notify, "application/xpidf+xml");
|
||||
#else
|
||||
if (online_status==SalPresenceOnline)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
|
||||
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
|
||||
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status><basic>open</basic></status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else if (online_status == SalPresenceBusy ||
|
||||
online_status == SalPresenceDonotdisturb)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
|
||||
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
|
||||
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status><basic>open</basic></status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
</tuple>\n\
|
||||
<dm:person id=\"sg89aep\">\n\
|
||||
<rpid:activities><rpid:busy/></rpid:activities>\n\
|
||||
</dm:person>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else if (online_status==SalPresenceBerightback)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
|
||||
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
|
||||
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status><basic>open</basic></status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
</tuple>\n\
|
||||
<dm:person id=\"sg89aep\">\n\
|
||||
<rpid:activities><rpid:in-transit/></rpid:activities>\n\
|
||||
</dm:person>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else if (online_status == SalPresenceAway ||
|
||||
online_status == SalPresenceMoved)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
|
||||
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
|
||||
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status><basic>open</basic></status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
</tuple>\n\
|
||||
<dm:person id=\"sg89aep\">\n\
|
||||
<rpid:activities><rpid:away/></rpid:activities>\n\
|
||||
</dm:person>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else if (online_status==SalPresenceOnthephone)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
|
||||
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
|
||||
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status><basic>open</basic></status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
</tuple>\n\
|
||||
<dm:person id=\"sg89aep\">\n\
|
||||
<rpid:activities><rpid:on-the-phone/></rpid:activities>\n\
|
||||
</dm:person>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else if (online_status==SalPresenceOuttolunch)
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
|
||||
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
|
||||
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"7777\">\n\
|
||||
<status><basic>open</basic></status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
</tuple>\n\
|
||||
<dm:person id=\"78787878\">\n\
|
||||
<rpid:activities><rpid:meal/></rpid:activities>\n\
|
||||
<rpid:note>Out to lunch</rpid:note> \n\
|
||||
</dm:person>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
|
||||
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
|
||||
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status><basic>closed</basic></status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
</tuple>\n\
|
||||
</presence>\n", contact_info, contact_info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
|
||||
if (online_status==SalPresenceOnline)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>online</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else if (online_status==SalPresenceBusy)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>busy</es:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>busy</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else if (online_status==SalPresenceBerightback)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>in-transit</es:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>be right back</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else if (online_status==SalPresenceAway)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>away</es:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>away</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else if (online_status==SalPresenceOnthephone)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>on-the-phone</es:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>on the phone</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else if (online_status==SalPresenceOuttolunch)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>meal</es:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>out to lunch</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
contact_info, contact_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* */
|
||||
sprintf(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n%s",
|
||||
contact_info,
|
||||
"<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>closed</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>permanent-absence</es:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
</tuple>\n\
|
||||
\n</presence>\n");
|
||||
}
|
||||
osip_message_set_body(notify, buf, strlen(buf));
|
||||
osip_message_set_content_type(notify, "application/pidf+xml");
|
||||
}
|
||||
|
||||
static void add_presence_body(osip_message_t *notify, SalPresenceStatus online_status)
|
||||
{
|
||||
char buf[1000];
|
||||
char *contact_info;
|
||||
|
||||
osip_from_t *from=NULL;
|
||||
from=osip_message_get_from(notify);
|
||||
osip_uri_to_str(from->url,&contact_info);
|
||||
|
||||
mk_presence_body (online_status, contact_info, buf, sizeof (buf), presence_style);
|
||||
|
||||
osip_message_set_body(notify, buf, strlen(buf));
|
||||
osip_message_set_content_type(notify,
|
||||
presence_style ? "application/xpidf+xml" : "application/pidf+xml");
|
||||
|
||||
#endif
|
||||
osip_free(contact_info);
|
||||
}
|
||||
|
||||
|
|
@ -476,137 +598,10 @@ int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus p
|
|||
int i;
|
||||
char buf[1024];
|
||||
|
||||
if (presence_mode==SalPresenceOnline)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>online</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
from, from);
|
||||
}
|
||||
else if (presence_mode==SalPresenceBusy
|
||||
||presence_mode==SalPresenceDonotdisturb)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>busy</es:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>busy</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
from, from);
|
||||
}
|
||||
else if (presence_mode==SalPresenceBerightback)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>in-transit</es:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>be right back</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
from,from);
|
||||
}
|
||||
else if (presence_mode==SalPresenceAway
|
||||
||presence_mode==SalPresenceMoved)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>away</es:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>away</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
from, from);
|
||||
}
|
||||
else if (presence_mode==SalPresenceOnthephone)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>on-the-phone</es:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>on the phone</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
from, from);
|
||||
}
|
||||
else if (presence_mode==SalPresenceOuttolunch)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n\
|
||||
<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>open</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>meal</es:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
<contact priority=\"0.8\">%s</contact>\n\
|
||||
<note>out to lunch</note>\n\
|
||||
</tuple>\n\
|
||||
</presence>",
|
||||
from, from);
|
||||
}
|
||||
else{
|
||||
/* offline */
|
||||
snprintf(buf, sizeof(buf), "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
|
||||
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n\
|
||||
xmlns:es=\"urn:ietf:params:xml:ns:pidf:status:rpid-status\"\n\
|
||||
entity=\"%s\">\n%s",
|
||||
from,
|
||||
"<tuple id=\"sg89ae\">\n\
|
||||
<status>\n\
|
||||
<basic>closed</basic>\n\
|
||||
<es:activities>\n\
|
||||
<es:activity>permanent-absence</e:activity>\n\
|
||||
</es:activities>\n\
|
||||
</status>\n\
|
||||
</tuple>\n\
|
||||
\n</presence>\n");
|
||||
}
|
||||
mk_presence_body (presence_mode, from, buf, sizeof (buf), presence_style);
|
||||
|
||||
i = eXosip_build_publish(&pub,from, to, NULL, "presence", "1800", "application/pidf+xml", buf);
|
||||
i = eXosip_build_publish(&pub,from, to, NULL, "presence", "300",
|
||||
presence_style ? "application/xpidf+xml" : "application/pidf+xml", buf);
|
||||
if (i<0){
|
||||
ms_warning("Failed to build publish request.");
|
||||
return -1;
|
||||
|
|
@ -620,6 +615,7 @@ int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus p
|
|||
ms_message("Failed to send publish request.");
|
||||
return -1;
|
||||
}
|
||||
sal_add_other(sal_op_get_sal(op),op,pub);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -691,7 +687,8 @@ void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){
|
|||
}else if (strstr(body->body,"berightback")!=NULL
|
||||
|| strstr(body->body,"in-transit")!=NULL ){
|
||||
estatus=SalPresenceBerightback;
|
||||
}else if (strstr(body->body,"away")!=NULL){
|
||||
}else if (strstr(body->body,"away")!=NULL
|
||||
|| strstr(body->body,"idle")){
|
||||
estatus=SalPresenceAway;
|
||||
}else if (strstr(body->body,"onthephone")!=NULL
|
||||
|| strstr(body->body,"on-the-phone")!=NULL){
|
||||
|
|
@ -714,6 +711,15 @@ void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){
|
|||
ms_message("And outgoing subscription terminated by remote.");
|
||||
}
|
||||
sal->callbacks.notify_presence(op,op->sid!=-1 ? SalSubscribeActive : SalSubscribeTerminated, estatus,NULL);
|
||||
|
||||
/* try to detect presence message style used by server,
|
||||
* and switch our presence messages to servers style */
|
||||
if (strstr (body->body, "//IETF//DTD RFCxxxx XPIDF 1.0//EN") != NULL) {
|
||||
presence_style = RFCxxxx;
|
||||
} else if (strstr(body->body,"http://schemas.microsoft.com/2002/09/sip/presence")!=NULL) {
|
||||
presence_style = MSOLDPRES;
|
||||
}
|
||||
|
||||
osip_free(tmp);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,23 @@ static int _sdp_message_get_a_ptime(sdp_message_t *sdp, int mline){
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int _sdp_message_get_mline_dir(sdp_message_t *sdp, int mline){
|
||||
int i;
|
||||
sdp_attribute_t *attr;
|
||||
for (i=0;(attr=sdp_message_attribute_get(sdp,mline,i))!=NULL;i++){
|
||||
if (keywordcmp("sendrecv",attr->a_att_field)==0){
|
||||
return SalStreamSendRecv;
|
||||
}else if (keywordcmp("sendonly",attr->a_att_field)==0){
|
||||
return SalStreamSendOnly;
|
||||
}else if (keywordcmp("recvonly",attr->a_att_field)==0){
|
||||
return SalStreamSendOnly;
|
||||
}else if (keywordcmp("inactive",attr->a_att_field)==0){
|
||||
return SalStreamInactive;
|
||||
}
|
||||
}
|
||||
return SalStreamSendRecv;
|
||||
}
|
||||
|
||||
static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc)
|
||||
{
|
||||
sdp_message_t *local;
|
||||
|
|
@ -121,12 +138,21 @@ static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc)
|
|||
osip_strdup ("IN"), inet6 ? osip_strdup("IP6") : osip_strdup ("IP4"),
|
||||
osip_strdup (desc->addr));
|
||||
sdp_message_s_name_set (local, osip_strdup ("A conversation"));
|
||||
sdp_message_c_connection_add (local, -1,
|
||||
osip_strdup ("IN"), inet6 ? osip_strdup ("IP6") : osip_strdup ("IP4"),
|
||||
osip_strdup (desc->addr), NULL, NULL);
|
||||
if(!sal_media_description_has_dir (desc,SalStreamSendOnly))
|
||||
{
|
||||
sdp_message_c_connection_add (local, -1,
|
||||
osip_strdup ("IN"), inet6 ? osip_strdup ("IP6") : osip_strdup ("IP4"),
|
||||
osip_strdup (desc->addr), NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
sdp_message_c_connection_add (local, -1,
|
||||
osip_strdup ("IN"), inet6 ? osip_strdup ("IP6") : osip_strdup ("IP4"),
|
||||
inet6 ? osip_strdup ("::0") : osip_strdup ("0.0.0.0"), NULL, NULL);
|
||||
}
|
||||
sdp_message_t_time_descr_add (local, osip_strdup ("0"), osip_strdup ("0"));
|
||||
if (desc->bandwidth>0) sdp_message_b_bandwidth_add (local, -1, osip_strdup ("AS"),
|
||||
int_2char(desc->bandwidth));
|
||||
int_2char(desc->bandwidth));
|
||||
return local;
|
||||
}
|
||||
|
||||
|
|
@ -158,6 +184,7 @@ static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription
|
|||
const char *mt=desc->type==SalAudio ? "audio" : "video";
|
||||
const MSList *elem;
|
||||
const char *addr;
|
||||
const char *dir="sendrecv";
|
||||
int port;
|
||||
if (desc->candidates[0].addr[0]!='\0'){
|
||||
addr=desc->candidates[0].addr;
|
||||
|
|
@ -186,6 +213,21 @@ static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription
|
|||
for(elem=desc->payloads;elem!=NULL;elem=elem->next){
|
||||
add_payload(msg, lineno, (PayloadType*)elem->data);
|
||||
}
|
||||
switch(desc->dir){
|
||||
case SalStreamSendRecv:
|
||||
dir="sendrecv";
|
||||
break;
|
||||
case SalStreamRecvOnly:
|
||||
dir="recvonly";
|
||||
break;
|
||||
case SalStreamSendOnly:
|
||||
dir="sendonly";
|
||||
break;
|
||||
case SalStreamInactive:
|
||||
dir="inactive";
|
||||
break;
|
||||
}
|
||||
sdp_message_a_attribute_add (msg, lineno, osip_strdup (dir),NULL);
|
||||
}
|
||||
|
||||
sdp_message_t *media_description_to_sdp(const SalMediaDescription *desc){
|
||||
|
|
@ -272,6 +314,7 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
|
|||
for(j=0;(sbw=sdp_message_bandwidth_get(msg,i,j))!=NULL;++j){
|
||||
if (strcasecmp(sbw->b_bwtype,"AS")==0) stream->bandwidth=atoi(sbw->b_bandwidth);
|
||||
}
|
||||
stream->dir=_sdp_message_get_mline_dir(msg,i);
|
||||
/* for each payload type */
|
||||
for (j=0;((number=sdp_message_m_payload_get (msg, i,j)) != NULL); j++){
|
||||
const char *rtpmap,*fmtp;
|
||||
|
|
@ -280,13 +323,14 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
|
|||
payload_type_set_number(pt,ptn);
|
||||
/* get the rtpmap associated to this codec, if any */
|
||||
rtpmap=sdp_message_a_attr_value_get_with_pt(msg, i,ptn,"rtpmap");
|
||||
payload_type_fill_from_rtpmap(pt,rtpmap);
|
||||
/* get the fmtp, if any */
|
||||
fmtp=sdp_message_a_attr_value_get_with_pt(msg, i, ptn,"fmtp");
|
||||
payload_type_set_send_fmtp(pt,fmtp);
|
||||
stream->payloads=ms_list_append(stream->payloads,pt);
|
||||
ms_message("Found payload %s/%i fmtp=%s",pt->mime_type,pt->clock_rate,
|
||||
pt->send_fmtp ? pt->send_fmtp : "");
|
||||
if (payload_type_fill_from_rtpmap(pt,rtpmap)==0){
|
||||
/* get the fmtp, if any */
|
||||
fmtp=sdp_message_a_attr_value_get_with_pt(msg, i, ptn,"fmtp");
|
||||
payload_type_set_send_fmtp(pt,fmtp);
|
||||
stream->payloads=ms_list_append(stream->payloads,pt);
|
||||
ms_message("Found payload %s/%i fmtp=%s",pt->mime_type,pt->clock_rate,
|
||||
pt->send_fmtp ? pt->send_fmtp : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
desc->nstreams=i;
|
||||
|
|
|
|||
|
|
@ -1,694 +0,0 @@
|
|||
/*
|
||||
* Linphone is sip (RFC3261) compatible internet phone.
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "sdphandler.h"
|
||||
#include <osipparser2/osip_port.h>
|
||||
#include <osipparser2/sdp_message.h>
|
||||
#include <eXosip2/eXosip.h>
|
||||
#include "linphonecore.h"
|
||||
#include "ortp/b64.h"
|
||||
|
||||
#define keywordcmp(key,str) strncmp(key,str,strlen(key))
|
||||
|
||||
|
||||
#define sstrdup_sprintf ms_strdup_printf
|
||||
|
||||
#define eXosip_trace(loglevel,args) do \
|
||||
{ \
|
||||
char *__strmsg; \
|
||||
__strmsg=ms_strdup_printf args ; \
|
||||
OSIP_TRACE(osip_trace(__FILE__,__LINE__,(loglevel),NULL,"%s\n",__strmsg)); \
|
||||
osip_free (__strmsg); \
|
||||
}while (0);
|
||||
|
||||
|
||||
static char *make_relay_session_id(const char *username, const char *relay){
|
||||
/*ideally this should be a hash of the parameters with a random part*/
|
||||
char tmp[128];
|
||||
int s1=(int)random();
|
||||
int s2=(int)random();
|
||||
long long int res=((long long int)s1)<<32 | (long long int) s2;
|
||||
void *src=&res;
|
||||
b64_encode(src, sizeof(long long int), tmp, sizeof(tmp));
|
||||
return osip_strdup(tmp);
|
||||
}
|
||||
|
||||
char * int_2char(int a){
|
||||
char *p=osip_malloc(16);
|
||||
snprintf(p,16,"%i",a);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* return the value of attr "field" for payload pt at line pos (field=rtpmap,fmtp...)*/
|
||||
char *sdp_message_a_attr_value_get_with_pt(sdp_message_t *sdp,int pos,int pt,const char *field)
|
||||
{
|
||||
int i,tmppt=0,scanned=0;
|
||||
char *tmp;
|
||||
sdp_attribute_t *attr;
|
||||
for (i=0;(attr=sdp_message_attribute_get(sdp,pos,i))!=NULL;i++){
|
||||
if (keywordcmp(field,attr->a_att_field)==0 && attr->a_att_value!=NULL){
|
||||
int nb = sscanf(attr->a_att_value,"%i %n",&tmppt,&scanned);
|
||||
/* the return value may depend on how %n is interpreted by the libc: see manpage*/
|
||||
if (nb == 1 || nb==2 ){
|
||||
if (pt==tmppt){
|
||||
tmp=attr->a_att_value+scanned;
|
||||
if (strlen(tmp)>0)
|
||||
return tmp;
|
||||
}
|
||||
}else eXosip_trace(OSIP_WARNING,("sdp has a strange a= line (%s) nb=%i",attr->a_att_value,nb));
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* return the value of attr "field" */
|
||||
char *sdp_message_a_attr_value_get(sdp_message_t *sdp,int pos,const char *field)
|
||||
{
|
||||
int i;
|
||||
sdp_attribute_t *attr;
|
||||
for (i=0;(attr=sdp_message_attribute_get(sdp,pos,i))!=NULL;i++){
|
||||
if (keywordcmp(field,attr->a_att_field)==0 && attr->a_att_value!=NULL){
|
||||
return attr->a_att_value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _sdp_message_get_a_ptime(sdp_message_t *sdp, int mline){
|
||||
int i,ret;
|
||||
sdp_attribute_t *attr;
|
||||
for (i=0;(attr=sdp_message_attribute_get(sdp,mline,i))!=NULL;i++){
|
||||
if (keywordcmp("ptime",attr->a_att_field)==0){
|
||||
int nb = sscanf(attr->a_att_value,"%i",&ret);
|
||||
/* the return value may depend on how %n is interpreted by the libc: see manpage*/
|
||||
if (nb == 1){
|
||||
return ret;
|
||||
}else eXosip_trace(OSIP_WARNING,("sdp has a strange a=ptime line (%s) ",attr->a_att_value));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sdp_payload_init (sdp_payload_t * payload)
|
||||
{
|
||||
memset (payload, 0, sizeof (sdp_payload_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdp_context_t *sdp_handler_create_context(sdp_handler_t *handler, const char *localip, const char *username, const char *relay){
|
||||
sdp_context_t *ctx=osip_malloc(sizeof(sdp_context_t));
|
||||
memset(ctx,0,sizeof(sdp_context_t));
|
||||
if (localip!=NULL) ctx->localip=osip_strdup(localip);
|
||||
ctx->username=osip_strdup(username);
|
||||
ctx->handler=handler;
|
||||
if (relay){
|
||||
ctx->relay=osip_strdup(relay);
|
||||
ctx->relay_session_id=make_relay_session_id(username,relay);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void sdp_context_set_user_pointer(sdp_context_t * ctx, void* up){
|
||||
ctx->reference=up;
|
||||
}
|
||||
|
||||
void *sdp_context_get_user_pointer(sdp_context_t * ctx){
|
||||
return ctx->reference;
|
||||
}
|
||||
|
||||
int sdp_context_get_status(sdp_context_t* ctx){
|
||||
return ctx->negoc_status;
|
||||
}
|
||||
|
||||
/* generate a template sdp */
|
||||
sdp_message_t *
|
||||
sdp_context_generate_template (sdp_context_t * ctx)
|
||||
{
|
||||
sdp_message_t *local;
|
||||
int inet6;
|
||||
|
||||
sdp_message_init (&local);
|
||||
if (strchr(ctx->localip,':')!=NULL){
|
||||
inet6=1;
|
||||
}else inet6=0;
|
||||
if (!inet6){
|
||||
sdp_message_v_version_set (local, osip_strdup ("0"));
|
||||
sdp_message_o_origin_set (local, osip_strdup (ctx->username),
|
||||
osip_strdup ("123456"), osip_strdup ("654321"),
|
||||
osip_strdup ("IN"), osip_strdup ("IP4"),
|
||||
osip_strdup (ctx->localip));
|
||||
sdp_message_s_name_set (local, osip_strdup ("A conversation"));
|
||||
sdp_message_c_connection_add (local, -1,
|
||||
osip_strdup ("IN"), osip_strdup ("IP4"),
|
||||
osip_strdup (ctx->localip), NULL, NULL);
|
||||
sdp_message_t_time_descr_add (local, osip_strdup ("0"), osip_strdup ("0"));
|
||||
}else{
|
||||
sdp_message_v_version_set (local, osip_strdup ("0"));
|
||||
sdp_message_o_origin_set (local, osip_strdup (ctx->username),
|
||||
osip_strdup ("123456"), osip_strdup ("654321"),
|
||||
osip_strdup ("IN"), osip_strdup ("IP6"),
|
||||
osip_strdup (ctx->localip));
|
||||
sdp_message_s_name_set (local, osip_strdup ("A conversation"));
|
||||
sdp_message_c_connection_add (local, -1,
|
||||
osip_strdup ("IN"), osip_strdup ("IP6"),
|
||||
osip_strdup (ctx->localip), NULL, NULL);
|
||||
sdp_message_t_time_descr_add (local, osip_strdup ("0"), osip_strdup ("0"));
|
||||
}
|
||||
return local;
|
||||
}
|
||||
|
||||
static void add_relay_info(sdp_message_t *sdp, int mline, const char *relay, const char *relay_session_id){
|
||||
|
||||
if (relay) sdp_message_a_attribute_add(sdp, mline,
|
||||
osip_strdup ("relay-addr"),osip_strdup(relay));
|
||||
if (relay_session_id) sdp_message_a_attribute_add(sdp, mline,
|
||||
osip_strdup ("relay-session-id"), osip_strdup(relay_session_id));
|
||||
}
|
||||
|
||||
/* to add payloads to the offer, must be called inside the write_offer callback */
|
||||
void
|
||||
sdp_context_add_payload (sdp_context_t * ctx, sdp_payload_t * payload, char *media)
|
||||
{
|
||||
sdp_message_t *offer = ctx->offer;
|
||||
char *attr_field;
|
||||
if (!ctx->incb)
|
||||
{
|
||||
eXosip_trace (OSIP_ERROR,
|
||||
("You must not call sdp_context_add_*_payload outside the write_offer callback\n"));
|
||||
#if !defined(_WIN32_WCE)
|
||||
abort();
|
||||
#else
|
||||
exit(-1);
|
||||
#endif /*_WIN32_WCE*/
|
||||
|
||||
}
|
||||
if (payload->proto == NULL)
|
||||
payload->proto = "RTP/AVP";
|
||||
/*printf("payload->line=%i payload->pt=%i\n",payload->line, payload->pt);*/
|
||||
if (sdp_message_m_media_get (offer, payload->line) == NULL)
|
||||
{
|
||||
/*printf("Adding new mline %s \n",media);*/
|
||||
/* need a new line */
|
||||
sdp_message_m_media_add (offer, osip_strdup (media),
|
||||
int_2char (payload->localport), NULL,
|
||||
osip_strdup (payload->proto));
|
||||
if (ctx->relay){
|
||||
add_relay_info(offer,payload->line,ctx->relay,ctx->relay_session_id);
|
||||
}
|
||||
}
|
||||
sdp_message_m_payload_add (offer, payload->line, int_2char (payload->pt));
|
||||
if (payload->a_rtpmap != NULL)
|
||||
{
|
||||
attr_field =
|
||||
sstrdup_sprintf ("%i %s", payload->pt,
|
||||
payload->a_rtpmap);
|
||||
sdp_message_a_attribute_add (offer, payload->line,
|
||||
osip_strdup ("rtpmap"), attr_field);
|
||||
}
|
||||
if (payload->a_fmtp != NULL)
|
||||
{
|
||||
attr_field =
|
||||
sstrdup_sprintf ("%i %s", payload->pt,
|
||||
payload->a_fmtp);
|
||||
sdp_message_a_attribute_add (offer, payload->line, osip_strdup ("fmtp"),
|
||||
attr_field);
|
||||
}
|
||||
if (payload->b_as_bandwidth != 0)
|
||||
{
|
||||
if (sdp_message_bandwidth_get(offer,payload->line,0)==NULL){
|
||||
attr_field =
|
||||
sstrdup_sprintf ("%i", payload->b_as_bandwidth);
|
||||
sdp_message_b_bandwidth_add (offer, payload->line, osip_strdup ("AS"),
|
||||
attr_field);
|
||||
}
|
||||
}
|
||||
if (payload->a_ptime !=0) {
|
||||
attr_field = sstrdup_sprintf ("%i", payload->a_ptime);
|
||||
sdp_message_a_attribute_add(offer, payload->line,osip_strdup ("ptime"),attr_field);
|
||||
ms_message("adding ptime [%s]",attr_field);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sdp_context_add_audio_payload (sdp_context_t * ctx, sdp_payload_t * payload)
|
||||
{
|
||||
sdp_context_add_payload (ctx, payload, "audio");
|
||||
}
|
||||
|
||||
void
|
||||
sdp_context_add_video_payload (sdp_context_t * ctx, sdp_payload_t * payload)
|
||||
{
|
||||
sdp_context_add_payload (ctx, payload, "video");
|
||||
}
|
||||
|
||||
char *
|
||||
sdp_context_get_offer ( sdp_context_t * ctx)
|
||||
{
|
||||
sdp_message_t *offer;
|
||||
sdp_handler_t *sdph=ctx->handler;
|
||||
char *tmp;
|
||||
|
||||
offer = sdp_context_generate_template (ctx);
|
||||
/* add audio codecs */
|
||||
ctx->offer = offer;
|
||||
ctx->incb = 1;
|
||||
if (sdph->set_audio_codecs != NULL)
|
||||
sdph->set_audio_codecs (ctx);
|
||||
if (sdph->set_video_codecs != NULL)
|
||||
sdph->set_video_codecs (ctx);
|
||||
ctx->incb = 0;
|
||||
sdp_message_to_str(offer,&tmp);
|
||||
ctx->offerstr=tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/* refuse the line */
|
||||
static void refuse_mline(sdp_message_t *answer,char *mtype,char *proto, int mline)
|
||||
{
|
||||
sdp_message_m_media_add (answer,
|
||||
osip_strdup (mtype),
|
||||
int_2char (0), NULL,
|
||||
osip_strdup (proto));
|
||||
/* add a payload just to comply with sdp RFC.*/
|
||||
sdp_message_m_payload_add(answer,mline,int_2char(0));
|
||||
}
|
||||
|
||||
static char * parse_relay_addr(char *addr, int *port)
|
||||
{
|
||||
char *semicolon=NULL;
|
||||
char *p;
|
||||
|
||||
*port=56789;
|
||||
semicolon=strchr(addr,':');
|
||||
for (p=addr+strlen(addr)-1;p>addr;p--){
|
||||
if (*p==':') {
|
||||
semicolon=p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (semicolon){
|
||||
*port=atoi(semicolon+1);
|
||||
*semicolon='\0';
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
sdp_context_get_answer ( sdp_context_t *ctx,sdp_message_t *remote)
|
||||
{
|
||||
sdp_message_t *answer=NULL;
|
||||
char *mtype=NULL, *tmp=NULL;
|
||||
char *proto=NULL, *port=NULL, *pt=NULL;
|
||||
int i, j, ncodec, m_lines_accepted = 0;
|
||||
int err;
|
||||
sdp_payload_t payload;
|
||||
sdp_payload_t init_payload;
|
||||
sdp_handler_t *sdph=ctx->handler;
|
||||
sdp_bandwidth_t *sbw=NULL;
|
||||
char *relay;
|
||||
|
||||
tmp = sdp_message_c_addr_get (remote, 0, 0);
|
||||
if (tmp == NULL)
|
||||
tmp = sdp_message_c_addr_get (remote, -1, 0);
|
||||
if (ctx->localip==NULL) {
|
||||
/* NULL means guess, otherwise we use the address given as localip */
|
||||
ctx->localip=osip_malloc(128);
|
||||
eXosip_guess_localip(strchr(tmp,':') ? AF_INET6 : AF_INET,ctx->localip,128);
|
||||
}
|
||||
else eXosip_trace(OSIP_INFO1,("Using firewall address in sdp."));
|
||||
|
||||
answer = sdp_context_generate_template (ctx);
|
||||
|
||||
/* for each m= line */
|
||||
for (i = 0; !sdp_message_endof_media (remote, i); i++){
|
||||
sdp_payload_init(&init_payload);
|
||||
mtype = sdp_message_m_media_get (remote, i);
|
||||
proto = sdp_message_m_proto_get (remote, i);
|
||||
port = sdp_message_m_port_get (remote, i);
|
||||
init_payload.remoteport = osip_atoi (port);
|
||||
init_payload.proto = proto;
|
||||
init_payload.line = i;
|
||||
init_payload.c_addr = sdp_message_c_addr_get (remote, i, 0);
|
||||
if (init_payload.c_addr == NULL)
|
||||
init_payload.c_addr = sdp_message_c_addr_get (remote, -1, 0);
|
||||
/*parse relay address if given*/
|
||||
relay=sdp_message_a_attr_value_get(remote,i,"relay-addr");
|
||||
if (relay){
|
||||
init_payload.relay_host=parse_relay_addr(relay,&init_payload.relay_port);
|
||||
}
|
||||
init_payload.relay_session_id=sdp_message_a_attr_value_get(remote,i,"relay-session-id");
|
||||
/* get application specific bandwidth, if any */
|
||||
for(j=0;(sbw=sdp_message_bandwidth_get(remote,i,j))!=NULL;j++){
|
||||
if (strcasecmp(sbw->b_bwtype,"AS")==0) init_payload.b_as_bandwidth=atoi(sbw->b_bandwidth);
|
||||
}
|
||||
init_payload.a_ptime=_sdp_message_get_a_ptime(remote,i);
|
||||
if (keywordcmp ("audio", mtype) == 0)
|
||||
{
|
||||
if (sdph->accept_audio_codecs != NULL)
|
||||
{
|
||||
ncodec = 0;
|
||||
/* for each payload type */
|
||||
for (j = 0;
|
||||
((pt =
|
||||
sdp_message_m_payload_get (remote, i,
|
||||
j)) != NULL); j++)
|
||||
{
|
||||
memcpy(&payload,&init_payload,sizeof(payload));
|
||||
payload.pt = osip_atoi (pt);
|
||||
/* get the rtpmap associated to this codec, if any */
|
||||
payload.a_rtpmap =
|
||||
sdp_message_a_attr_value_get_with_pt
|
||||
(remote, i, payload.pt,
|
||||
"rtpmap");
|
||||
/* get the fmtp, if any */
|
||||
payload.a_fmtp =
|
||||
sdp_message_a_attr_value_get_with_pt
|
||||
(remote, i, payload.pt,
|
||||
"fmtp");
|
||||
|
||||
/* ask the application if this codec is supported */
|
||||
err = sdph->accept_audio_codecs (ctx,
|
||||
&payload);
|
||||
if (err == 0)
|
||||
{
|
||||
ncodec++;
|
||||
/* codec accepted */
|
||||
if (ncodec == 1)
|
||||
{
|
||||
/* first codec accepted, setup the line */
|
||||
sdp_message_m_media_add
|
||||
(answer,
|
||||
osip_strdup
|
||||
(mtype),
|
||||
int_2char
|
||||
(payload.
|
||||
localport),
|
||||
NULL,
|
||||
osip_strdup
|
||||
(proto));
|
||||
/* and accept the remote relay addr if we planned to use our own */
|
||||
if (ctx->relay!=NULL && relay){
|
||||
add_relay_info(answer,i,relay,payload.relay_session_id);
|
||||
}
|
||||
}
|
||||
/* add the payload, rtpmap, fmtp */
|
||||
sdp_message_m_payload_add (answer, i,
|
||||
int_2char
|
||||
(payload.
|
||||
pt));
|
||||
if (payload.a_rtpmap != NULL)
|
||||
{
|
||||
sdp_message_a_attribute_add
|
||||
(answer, i,
|
||||
osip_strdup
|
||||
("rtpmap"),
|
||||
sstrdup_sprintf
|
||||
("%i %s",
|
||||
payload.pt,
|
||||
payload.
|
||||
a_rtpmap));
|
||||
}
|
||||
if (payload.a_fmtp != NULL)
|
||||
{
|
||||
sdp_message_a_attribute_add
|
||||
(answer, i,
|
||||
osip_strdup
|
||||
("fmtp"),
|
||||
sstrdup_sprintf
|
||||
("%i %s",
|
||||
payload.pt,
|
||||
payload.
|
||||
a_fmtp));
|
||||
}
|
||||
if (payload.b_as_bandwidth !=
|
||||
0)
|
||||
{
|
||||
if (sdp_message_bandwidth_get(answer,i,0)==NULL)
|
||||
sdp_message_b_bandwidth_add
|
||||
(answer, i,
|
||||
osip_strdup
|
||||
("AS"),
|
||||
sstrdup_sprintf
|
||||
("%i",
|
||||
payload.
|
||||
b_as_bandwidth));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ncodec == 0)
|
||||
{
|
||||
/* refuse the line */
|
||||
refuse_mline(answer,mtype,proto,i);
|
||||
|
||||
}
|
||||
else
|
||||
m_lines_accepted++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* refuse this line (leave port to 0) */
|
||||
refuse_mline(answer,mtype,proto,i);
|
||||
}
|
||||
|
||||
}
|
||||
else if (keywordcmp ("video", mtype) == 0)
|
||||
{
|
||||
if (sdph->accept_video_codecs != NULL)
|
||||
{
|
||||
ncodec = 0;
|
||||
/* for each payload type */
|
||||
for (j = 0;
|
||||
((pt =
|
||||
sdp_message_m_payload_get (remote, i,
|
||||
j)) != NULL); j++)
|
||||
{
|
||||
memcpy(&payload,&init_payload,sizeof(payload));
|
||||
payload.pt = osip_atoi (pt);
|
||||
/* get the rtpmap associated to this codec, if any */
|
||||
payload.a_rtpmap =
|
||||
sdp_message_a_attr_value_get_with_pt
|
||||
(remote, i, payload.pt,
|
||||
"rtpmap");
|
||||
/* get the fmtp, if any */
|
||||
payload.a_fmtp =
|
||||
sdp_message_a_attr_value_get_with_pt
|
||||
(remote, i, payload.pt,
|
||||
"fmtp");
|
||||
/* ask the application if this codec is supported */
|
||||
err = sdph->accept_video_codecs (ctx,
|
||||
&payload);
|
||||
if (err == 0 )
|
||||
{
|
||||
ncodec++;
|
||||
/* codec accepted */
|
||||
if (ncodec == 1)
|
||||
{
|
||||
/* first codec accepted, setup the line */
|
||||
sdp_message_m_media_add
|
||||
(answer,
|
||||
osip_strdup
|
||||
(mtype),
|
||||
int_2char
|
||||
(payload.localport), NULL,
|
||||
osip_strdup
|
||||
(proto));
|
||||
/* and accept the remote relay addr if we planned to use our own */
|
||||
if (ctx->relay!=NULL && relay){
|
||||
add_relay_info(answer,i,relay,payload.relay_session_id);
|
||||
}
|
||||
}
|
||||
/* add the payload, rtpmap, fmtp */
|
||||
sdp_message_m_payload_add (answer, i,
|
||||
int_2char
|
||||
(payload.
|
||||
pt));
|
||||
if (payload.a_rtpmap != NULL)
|
||||
{
|
||||
sdp_message_a_attribute_add
|
||||
(answer, i,
|
||||
osip_strdup
|
||||
("rtpmap"),
|
||||
sstrdup_sprintf
|
||||
("%i %s",
|
||||
payload.pt,
|
||||
payload.
|
||||
a_rtpmap));
|
||||
}
|
||||
if (payload.a_fmtp != NULL)
|
||||
{
|
||||
sdp_message_a_attribute_add
|
||||
(answer, i,
|
||||
osip_strdup
|
||||
("fmtp"),
|
||||
sstrdup_sprintf
|
||||
("%i %s",
|
||||
payload.pt,
|
||||
payload.
|
||||
a_fmtp));
|
||||
}
|
||||
if (payload.b_as_bandwidth !=0)
|
||||
{
|
||||
if (sdp_message_bandwidth_get(answer,i,0)==NULL)
|
||||
sdp_message_b_bandwidth_add
|
||||
(answer, i,
|
||||
osip_strdup
|
||||
("AS"),
|
||||
sstrdup_sprintf
|
||||
("%i",
|
||||
payload.
|
||||
b_as_bandwidth));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ncodec == 0)
|
||||
{
|
||||
/* refuse the line */
|
||||
refuse_mline(answer,mtype,proto,i);
|
||||
}
|
||||
else
|
||||
m_lines_accepted++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* refuse the line */
|
||||
refuse_mline(answer,mtype,proto,i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ctx->answer!=NULL)
|
||||
sdp_message_free(ctx->answer);
|
||||
ctx->answer = answer;
|
||||
if (m_lines_accepted > 0){
|
||||
ctx->negoc_status = 200;
|
||||
sdp_message_to_str(answer,&tmp);
|
||||
if (ctx->answerstr!=NULL)
|
||||
osip_free(ctx->answerstr);
|
||||
ctx->answerstr=tmp;
|
||||
return tmp;
|
||||
}else{
|
||||
ctx->negoc_status = 415;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sdp_context_read_answer (sdp_context_t *ctx, sdp_message_t *remote)
|
||||
{
|
||||
char *mtype;
|
||||
char *proto, *port, *pt;
|
||||
int i, j,err;
|
||||
char *relay;
|
||||
sdp_payload_t payload,arg_payload;
|
||||
sdp_handler_t *sdph=ctx->handler;
|
||||
sdp_bandwidth_t *sbw=NULL;
|
||||
/* for each m= line */
|
||||
for (i = 0; !sdp_message_endof_media (remote, i); i++)
|
||||
{
|
||||
sdp_payload_init(&payload);
|
||||
mtype = sdp_message_m_media_get (remote, i);
|
||||
proto = sdp_message_m_proto_get (remote, i);
|
||||
port = sdp_message_m_port_get (remote, i);
|
||||
payload.remoteport = osip_atoi (port);
|
||||
payload.localport = osip_atoi (sdp_message_m_port_get (ctx->offer, i));
|
||||
payload.proto = proto;
|
||||
payload.line = i;
|
||||
payload.c_addr = sdp_message_c_addr_get (remote, i, 0);
|
||||
if (payload.c_addr == NULL)
|
||||
payload.c_addr = sdp_message_c_addr_get (remote, -1, 0);
|
||||
/*parse relay address if given*/
|
||||
relay=sdp_message_a_attr_value_get(remote,i,"relay-addr");
|
||||
if (relay){
|
||||
payload.relay_host=parse_relay_addr(relay,&payload.relay_port);
|
||||
}
|
||||
payload.relay_session_id=sdp_message_a_attr_value_get(remote,i,"relay-session-id");
|
||||
for(j=0;(sbw=sdp_message_bandwidth_get(remote,i,j))!=NULL;++j){
|
||||
if (strcasecmp(sbw->b_bwtype,"AS")==0) payload.b_as_bandwidth=atoi(sbw->b_bandwidth);
|
||||
}
|
||||
payload.a_ptime=_sdp_message_get_a_ptime(remote,i);
|
||||
if (keywordcmp ("audio", mtype) == 0)
|
||||
{
|
||||
if (sdph->get_audio_codecs != NULL)
|
||||
{
|
||||
/* for each payload type */
|
||||
for (j = 0;
|
||||
((pt =
|
||||
sdp_message_m_payload_get (remote, i,
|
||||
j)) != NULL); j++)
|
||||
{
|
||||
payload.pt = osip_atoi (pt);
|
||||
/* get the rtpmap associated to this codec, if any */
|
||||
payload.a_rtpmap =
|
||||
sdp_message_a_attr_value_get_with_pt
|
||||
(remote, i, payload.pt,
|
||||
"rtpmap");
|
||||
/* get the fmtp, if any */
|
||||
payload.a_fmtp =
|
||||
sdp_message_a_attr_value_get_with_pt
|
||||
(remote, i, payload.pt,
|
||||
"fmtp");
|
||||
/* ask the application if this codec is supported */
|
||||
memcpy(&arg_payload,&payload,sizeof(payload));
|
||||
err = sdph->get_audio_codecs (ctx,
|
||||
&arg_payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (keywordcmp ("video", mtype) == 0)
|
||||
{
|
||||
if (sdph->get_video_codecs != NULL)
|
||||
{
|
||||
/* for each payload type */
|
||||
for (j = 0;
|
||||
((pt =
|
||||
sdp_message_m_payload_get (remote, i,
|
||||
j)) != NULL); j++)
|
||||
{
|
||||
payload.pt = osip_atoi (pt);
|
||||
/* get the rtpmap associated to this codec, if any */
|
||||
payload.a_rtpmap =
|
||||
sdp_message_a_attr_value_get_with_pt
|
||||
(remote, i, payload.pt,
|
||||
"rtpmap");
|
||||
/* get the fmtp, if any */
|
||||
payload.a_fmtp =
|
||||
sdp_message_a_attr_value_get_with_pt
|
||||
(remote, i, payload.pt,
|
||||
"fmtp");
|
||||
/* ask the application if this codec is supported */
|
||||
memcpy(&arg_payload,&payload,sizeof(payload));
|
||||
err = sdph->get_video_codecs (ctx,
|
||||
&arg_payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void sdp_context_free(sdp_context_t *ctx){
|
||||
osip_free(ctx->localip);
|
||||
osip_free(ctx->username);
|
||||
if (ctx->offer!=NULL) sdp_message_free(ctx->offer);
|
||||
if (ctx->answer!=NULL) sdp_message_free(ctx->answer);
|
||||
if (ctx->offerstr!=NULL) osip_free(ctx->offerstr);
|
||||
if (ctx->answerstr!=NULL) osip_free(ctx->answerstr);
|
||||
if (ctx->relay!=NULL) osip_free(ctx->relay);
|
||||
if (ctx->relay_session_id!=NULL) osip_free(ctx->relay_session_id);
|
||||
osip_free(ctx);
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* Linphone is sip (RFC3261) compatible internet phone.
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef SDP_HANDLER_H
|
||||
#define SDP_HANDLER_H
|
||||
|
||||
#include <osipparser2/sdp_message.h>
|
||||
#include "linphonecore.h"
|
||||
|
||||
typedef struct _sdp_payload
|
||||
{
|
||||
int line; /* the index of the m= line */
|
||||
int pt; /*payload type */
|
||||
int localport;
|
||||
int remoteport;
|
||||
int b_as_bandwidth; /* application specific bandwidth */
|
||||
char *proto;
|
||||
char *c_nettype;
|
||||
char *c_addrtype;
|
||||
char *c_addr;
|
||||
char *c_addr_multicast_ttl;
|
||||
char *c_addr_multicast_int;
|
||||
char *a_rtpmap;
|
||||
char *a_fmtp;
|
||||
char *relay_host;
|
||||
int relay_port;
|
||||
char *relay_session_id;
|
||||
int a_ptime;
|
||||
} sdp_payload_t;
|
||||
|
||||
typedef struct _sdp_context sdp_context_t;
|
||||
|
||||
typedef int (*sdp_handler_read_codec_func_t) (struct _sdp_context *,
|
||||
sdp_payload_t *);
|
||||
typedef int (*sdp_handler_write_codec_func_t) (struct _sdp_context *);
|
||||
|
||||
typedef struct _sdp_handler
|
||||
{
|
||||
sdp_handler_read_codec_func_t accept_audio_codecs; /*from remote sdp */
|
||||
sdp_handler_read_codec_func_t accept_video_codecs; /*from remote sdp */
|
||||
sdp_handler_write_codec_func_t set_audio_codecs; /*to local sdp */
|
||||
sdp_handler_write_codec_func_t set_video_codecs; /*to local sdp */
|
||||
sdp_handler_read_codec_func_t get_audio_codecs; /*from incoming answer */
|
||||
sdp_handler_read_codec_func_t get_video_codecs; /*from incoming answer */
|
||||
} sdp_handler_t;
|
||||
|
||||
|
||||
typedef enum _sdp_context_state
|
||||
{
|
||||
SDP_CONTEXT_STATE_INIT,
|
||||
SDP_CONTEXT_STATE_NEGOCIATION_OPENED,
|
||||
SDP_CONTEXT_STATE_NEGOCIATION_CLOSED
|
||||
} sdp_context_state_t;
|
||||
|
||||
struct _sdp_context
|
||||
{
|
||||
sdp_handler_t *handler;
|
||||
char *localip;
|
||||
char *username;
|
||||
void *reference;
|
||||
sdp_message_t *offer; /* the local sdp to be used for outgoing request */
|
||||
char *offerstr;
|
||||
sdp_message_t *answer; /* the local sdp generated from an inc request */
|
||||
char *answerstr;
|
||||
char *relay;
|
||||
char *relay_session_id;
|
||||
int negoc_status; /* in sip code */
|
||||
int incb;
|
||||
sdp_context_state_t state;
|
||||
};
|
||||
|
||||
/* create a context for a sdp negociation: localip is the ip address to be used in the sdp message, can
|
||||
be a firewall address.
|
||||
It can be null when negociating for an incoming offer; In that case it will be guessed. */
|
||||
sdp_context_t *sdp_handler_create_context(sdp_handler_t *handler, const char *localip, const char *username, const char *relay);
|
||||
void sdp_context_set_user_pointer(sdp_context_t * ctx, void* up);
|
||||
void *sdp_context_get_user_pointer(sdp_context_t * ctx);
|
||||
void sdp_context_add_audio_payload( sdp_context_t * ctx, sdp_payload_t * payload);
|
||||
void sdp_context_add_video_payload( sdp_context_t * ctx, sdp_payload_t * payload);
|
||||
char * sdp_context_get_offer(sdp_context_t *ctx);
|
||||
char * sdp_context_get_answer(sdp_context_t* ctx, sdp_message_t *remote_offer);
|
||||
int sdp_context_get_status(sdp_context_t* ctx);
|
||||
void sdp_context_read_answer(sdp_context_t *ctx, sdp_message_t *remote_answer);
|
||||
void sdp_context_free(sdp_context_t *ctx);
|
||||
|
||||
int sdp_payload_init (sdp_payload_t * payload);
|
||||
#endif
|
||||
104
coreapi/test_lsd.c
Normal file
104
coreapi/test_lsd.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2010 Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Linphone Sound Daemon: is a lightweight utility to play sounds to speaker during a conversation.
|
||||
This is useful for embedded platforms, where sound apis are not performant enough to allow
|
||||
simultaneous sound access.
|
||||
|
||||
This file is a test program that plays several sound files and places a call simultatenously.
|
||||
*/
|
||||
|
||||
#include "linphonecore_utils.h"
|
||||
|
||||
|
||||
static void play_finished(LsdPlayer *p){
|
||||
const char *filename=(const char *)lsd_player_get_user_pointer (p);
|
||||
ms_message("Playing of %s is finished.",filename);
|
||||
if (!lsd_player_loop_enabled (p)){
|
||||
linphone_sound_daemon_release_player (lsd_player_get_daemon(p),p);
|
||||
}
|
||||
}
|
||||
|
||||
static void wait_a_bit(LinphoneCore *lc, int seconds){
|
||||
time_t orig=ms_time(NULL);
|
||||
while(ms_time(NULL)-orig<seconds){
|
||||
/* we need to call iterate to receive notifications */
|
||||
linphone_core_iterate(lc);
|
||||
ms_usleep (50000);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
LinphoneCore *lc;
|
||||
LinphoneCoreVTable vtable={0};
|
||||
LinphoneSoundDaemon *lsd;
|
||||
LsdPlayer *p;
|
||||
|
||||
linphone_core_enable_logs(stdout);
|
||||
lc=linphone_core_new(&vtable,NULL,NULL,NULL);
|
||||
lsd=linphone_sound_daemon_new (NULL,44100,1);
|
||||
|
||||
linphone_core_use_sound_daemon(lc,lsd);
|
||||
|
||||
/* start a play */
|
||||
p=linphone_sound_daemon_get_player(lsd);
|
||||
lsd_player_set_callback (p,play_finished);
|
||||
lsd_player_set_user_pointer (p,"share/hello8000.wav");
|
||||
lsd_player_play (p,"share/hello8000.wav");
|
||||
wait_a_bit (lc,2);
|
||||
|
||||
/*start another one */
|
||||
p=linphone_sound_daemon_get_player(lsd);
|
||||
lsd_player_set_callback (p,play_finished);
|
||||
lsd_player_set_user_pointer (p,"share/hello16000.wav");
|
||||
lsd_player_enable_loop (p,TRUE);
|
||||
lsd_player_play (p,"share/hello16000.wav");
|
||||
|
||||
/* after a few seconds decrease the volume */
|
||||
wait_a_bit (lc,3);
|
||||
lsd_player_set_gain (p,0.3);
|
||||
wait_a_bit(lc,5);
|
||||
|
||||
/*now play some stereo music*/
|
||||
p=linphone_sound_daemon_get_player(lsd);
|
||||
lsd_player_set_callback (p,play_finished);
|
||||
lsd_player_set_user_pointer (p,"share/rings/rock.wav");
|
||||
lsd_player_play(p,"share/rings/rock.wav");
|
||||
wait_a_bit(lc,2);
|
||||
|
||||
/*now play some stereo music at 22khz in order to test
|
||||
stereo resampling */
|
||||
p=linphone_sound_daemon_get_player(lsd);
|
||||
lsd_player_set_callback (p,play_finished);
|
||||
lsd_player_set_user_pointer (p,"share/rings/bigben.wav");
|
||||
lsd_player_play(p,"share/rings/bigben.wav");
|
||||
wait_a_bit(lc,6);
|
||||
|
||||
/* now place an outgoing call if sip address argument is given */
|
||||
if (argc>1){
|
||||
linphone_core_invite(lc,argv[1]);
|
||||
wait_a_bit(lc,10);
|
||||
linphone_core_terminate_call(lc,NULL);
|
||||
}
|
||||
linphone_core_use_sound_daemon(lc,NULL);
|
||||
linphone_sound_daemon_destroy(lsd);
|
||||
linphone_core_destroy(lc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--Generated with glade3 3.4.5 on Wed Jul 30 17:55:28 2008 -->
|
||||
<glade-interface>
|
||||
<widget class="GtkDialog" id="call_logs">
|
||||
<property name="width_request">500</property>
|
||||
<property name="height_request">370</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Call history</property>
|
||||
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
|
||||
<property name="icon">linphone2.png</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<child>
|
||||
<widget class="GtkTextView" id="logtextview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="wrap_mode">GTK_WRAP_WORD</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="label" translatable="yes">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
linphone, gtk-glade interface.
|
||||
Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "linphone.h"
|
||||
|
||||
|
||||
void linphone_gtk_call_log_update(GtkWidget *w){
|
||||
GtkTextView *v=GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"logtextview"));
|
||||
GtkTextBuffer *b=gtk_text_view_get_buffer(v);
|
||||
GtkTextIter iter,begin;
|
||||
int off;
|
||||
char *logmsg;
|
||||
const MSList *logs;
|
||||
for (logs=linphone_core_get_call_logs(linphone_gtk_get_core());logs!=NULL;logs=logs->next){
|
||||
LinphoneCallLog *cl=(LinphoneCallLog*)logs->data;
|
||||
logmsg=linphone_call_log_to_str(cl);
|
||||
gtk_text_buffer_get_end_iter(b,&iter);
|
||||
off=gtk_text_iter_get_offset(&iter);
|
||||
gtk_text_buffer_insert(b,&iter,logmsg,-1);
|
||||
gtk_text_buffer_get_end_iter(b,&iter);
|
||||
gtk_text_buffer_insert(b,&iter,"\n",-1);
|
||||
gtk_text_buffer_get_end_iter(b,&iter);
|
||||
gtk_text_buffer_get_iter_at_offset(b,&begin,off);
|
||||
gtk_text_buffer_apply_tag_by_name(b,cl->dir==LinphoneCallOutgoing ? "green" : "blue" ,&begin,&iter);
|
||||
ms_free(logmsg);
|
||||
}
|
||||
gtk_text_buffer_get_end_iter(b,&iter);
|
||||
gtk_text_view_scroll_to_iter(v,&iter,0,FALSE,0,0);
|
||||
}
|
||||
|
||||
void linphone_gtk_call_log_response(GtkWidget *w){
|
||||
GtkWidget *mw=linphone_gtk_get_main_window();
|
||||
g_object_set_data(G_OBJECT(mw),"call_logs",NULL);
|
||||
gtk_widget_destroy(w);
|
||||
}
|
||||
|
||||
GtkWidget * linphone_gtk_show_call_logs(void){
|
||||
GtkWidget *mw=linphone_gtk_get_main_window();
|
||||
GtkTextBuffer *b;
|
||||
GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"call_logs");
|
||||
if (w==NULL){
|
||||
w=linphone_gtk_create_window("call_logs");
|
||||
g_object_set_data(G_OBJECT(mw),"call_logs",w);
|
||||
g_signal_connect(G_OBJECT(w),"response",(GCallback)linphone_gtk_call_log_response,NULL);
|
||||
gtk_widget_show(w);
|
||||
b=gtk_text_view_get_buffer(GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"logtextview")));
|
||||
gtk_text_buffer_create_tag(b,"blue","foreground","blue",NULL);
|
||||
gtk_text_buffer_create_tag(b,"green","foreground","green",NULL);
|
||||
linphone_gtk_call_log_update(w);
|
||||
}else gtk_window_present(GTK_WINDOW(w));
|
||||
return w;
|
||||
}
|
||||
|
||||
|
|
@ -1,208 +0,0 @@
|
|||
/*
|
||||
linphone, gtk-glade interface.
|
||||
Copyright (C) 2009 Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* C Implementation: incall_frame
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
*
|
||||
* Author: Simon Morlat <simon.morlat@linphone.org>, (C) 2009
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "linphone.h"
|
||||
|
||||
|
||||
gboolean linphone_gtk_use_in_call_view(){
|
||||
static int val=-1;
|
||||
if (val==-1) val=linphone_gtk_get_ui_config_int("use_incall_view",1);
|
||||
return val;
|
||||
}
|
||||
|
||||
void linphone_gtk_show_in_call_view(void){
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window();
|
||||
GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch");
|
||||
GtkWidget *in_call_frame=linphone_gtk_get_widget(main_window,"in_call_frame");
|
||||
gint idx;
|
||||
|
||||
/* Make the in call frame visible and arrange for the notebook to
|
||||
show that page */
|
||||
gtk_widget_show(in_call_frame);
|
||||
idx = gtk_notebook_page_num(notebook, in_call_frame);
|
||||
if (idx >= 0) {
|
||||
gtk_notebook_set_current_page(notebook, idx);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_show_idle_view(void){
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window();
|
||||
GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch");
|
||||
GtkWidget *idle_frame=linphone_gtk_get_widget(main_window,"idle_frame");
|
||||
GtkWidget *in_call_frame=linphone_gtk_get_widget(main_window,"in_call_frame");
|
||||
gint idx;
|
||||
|
||||
/* Switch back to the idle frame page, maybe we should have
|
||||
remembered where we were in gtk_show_in_call_view() to switch
|
||||
back to that page of the notebook, but this should do in most
|
||||
cases. */
|
||||
gtk_widget_show(idle_frame); /* Make sure it is visible... */
|
||||
idx = gtk_notebook_page_num(notebook, idle_frame);
|
||||
if (idx >= 0) {
|
||||
gtk_notebook_set_current_page(notebook, idx);
|
||||
gtk_widget_hide(in_call_frame);
|
||||
}
|
||||
}
|
||||
|
||||
void display_peer_name_in_label(GtkWidget *label, const char *uri){
|
||||
LinphoneAddress *from;
|
||||
const char *displayname=NULL;
|
||||
char *id=NULL;
|
||||
char *uri_label;
|
||||
|
||||
if (uri==NULL) {
|
||||
ms_error("Strange: in call with nobody ?");
|
||||
return;
|
||||
}
|
||||
|
||||
from=linphone_address_new(uri);
|
||||
if (from!=NULL){
|
||||
displayname=linphone_address_get_display_name(from);
|
||||
id=linphone_address_as_string_uri_only(from);
|
||||
}else id=ms_strdup(uri);
|
||||
|
||||
if (displayname!=NULL){
|
||||
uri_label=g_markup_printf_escaped("<span size=\"large\">%s</span>\n<i>%s</i>",
|
||||
displayname,id);
|
||||
}else
|
||||
uri_label=g_markup_printf_escaped("<span size=\"large\"><i>%s</i></span>\n",id);
|
||||
gtk_label_set_markup(GTK_LABEL(label),uri_label);
|
||||
ms_free(id);
|
||||
g_free(uri_label);
|
||||
if (from!=NULL) linphone_address_destroy(from);
|
||||
}
|
||||
|
||||
void linphone_gtk_in_call_view_set_calling(const char *uri){
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window();
|
||||
GtkWidget *status=linphone_gtk_get_widget(main_window,"in_call_status");
|
||||
GtkWidget *callee=linphone_gtk_get_widget(main_window,"in_call_uri");
|
||||
GtkWidget *duration=linphone_gtk_get_widget(main_window,"in_call_duration");
|
||||
GtkWidget *animation=linphone_gtk_get_widget(main_window,"in_call_animation");
|
||||
GdkPixbufAnimation *pbuf=create_pixbuf_animation("calling_anim.gif");
|
||||
|
||||
gtk_label_set_markup(GTK_LABEL(status),_("<b>Calling...</b>"));
|
||||
display_peer_name_in_label(callee,uri);
|
||||
|
||||
gtk_label_set_text(GTK_LABEL(duration),_("00::00::00"));
|
||||
if (pbuf!=NULL){
|
||||
gtk_image_set_from_animation(GTK_IMAGE(animation),pbuf);
|
||||
g_object_unref(G_OBJECT(pbuf));
|
||||
}else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_INFO,GTK_ICON_SIZE_DIALOG);
|
||||
}
|
||||
|
||||
void linphone_gtk_in_call_view_set_in_call(){
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window();
|
||||
GtkWidget *status=linphone_gtk_get_widget(main_window,"in_call_status");
|
||||
GtkWidget *callee=linphone_gtk_get_widget(main_window,"in_call_uri");
|
||||
GtkWidget *duration=linphone_gtk_get_widget(main_window,"in_call_duration");
|
||||
GtkWidget *animation=linphone_gtk_get_widget(main_window,"in_call_animation");
|
||||
GdkPixbufAnimation *pbuf=create_pixbuf_animation("incall_anim.gif");
|
||||
const LinphoneAddress *uri=linphone_core_get_remote_uri(lc);
|
||||
char *tmp=linphone_address_as_string(uri);
|
||||
display_peer_name_in_label(callee,tmp);
|
||||
ms_free(tmp);
|
||||
|
||||
gtk_label_set_markup(GTK_LABEL(status),_("<b>In call with</b>"));
|
||||
|
||||
gtk_label_set_text(GTK_LABEL(duration),_("00::00::00"));
|
||||
if (pbuf!=NULL){
|
||||
gtk_image_set_from_animation(GTK_IMAGE(animation),pbuf);
|
||||
g_object_unref(G_OBJECT(pbuf));
|
||||
}else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_INFO,GTK_ICON_SIZE_DIALOG);
|
||||
linphone_gtk_enable_mute_button(
|
||||
GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(main_window,"incall_mute")),TRUE);
|
||||
}
|
||||
|
||||
void linphone_gtk_in_call_view_update_duration(int duration){
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window();
|
||||
GtkWidget *duration_label=linphone_gtk_get_widget(main_window,"in_call_duration");
|
||||
char tmp[256]={0};
|
||||
int seconds=duration%60;
|
||||
int minutes=(duration/60)%60;
|
||||
int hours=duration/3600;
|
||||
snprintf(tmp,sizeof(tmp)-1,_("%02i::%02i::%02i"),hours,minutes,seconds);
|
||||
gtk_label_set_text(GTK_LABEL(duration_label),tmp);
|
||||
}
|
||||
|
||||
static gboolean in_call_view_terminated(){
|
||||
linphone_gtk_show_idle_view();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void linphone_gtk_in_call_view_terminate(const char *error_msg){
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window();
|
||||
GtkWidget *status=linphone_gtk_get_widget(main_window,"in_call_status");
|
||||
GtkWidget *animation=linphone_gtk_get_widget(main_window,"in_call_animation");
|
||||
GdkPixbuf *pbuf=create_pixbuf(linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png"));
|
||||
|
||||
if (error_msg==NULL)
|
||||
gtk_label_set_markup(GTK_LABEL(status),_("<b>Call ended.</b>"));
|
||||
else{
|
||||
char *msg=g_markup_printf_escaped("<span color=\"red\"><b>%s</b></span>",error_msg);
|
||||
gtk_label_set_markup(GTK_LABEL(status),msg);
|
||||
g_free(msg);
|
||||
}
|
||||
if (pbuf!=NULL){
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(animation),pbuf);
|
||||
g_object_unref(G_OBJECT(pbuf));
|
||||
}
|
||||
linphone_gtk_enable_mute_button(
|
||||
GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(main_window,"incall_mute")),FALSE);
|
||||
g_timeout_add_seconds(2,(GSourceFunc)in_call_view_terminated,NULL);
|
||||
}
|
||||
|
||||
void linphone_gtk_draw_mute_button(GtkToggleButton *button, gboolean active){
|
||||
if (active){
|
||||
GtkWidget *image=create_pixmap("mic_muted.png");
|
||||
gtk_button_set_label(GTK_BUTTON(button),_("Unmute"));
|
||||
if (image!=NULL) {
|
||||
gtk_button_set_image(GTK_BUTTON(button),image);
|
||||
gtk_widget_show(image);
|
||||
}
|
||||
}else{
|
||||
GtkWidget *image=create_pixmap("mic_active.png");
|
||||
gtk_button_set_label(GTK_BUTTON(button),_("Mute"));
|
||||
if (image!=NULL) {
|
||||
gtk_button_set_image(GTK_BUTTON(button),image);
|
||||
gtk_widget_show(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_mute_toggled(GtkToggleButton *button){
|
||||
gboolean active=gtk_toggle_button_get_active(button);
|
||||
linphone_core_mute_mic(linphone_gtk_get_core(),active);
|
||||
linphone_gtk_draw_mute_button(button,active);
|
||||
}
|
||||
|
||||
void linphone_gtk_enable_mute_button(GtkToggleButton *button, gboolean sensitive){
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(button),sensitive);
|
||||
linphone_gtk_draw_mute_button(button,FALSE);
|
||||
}
|
||||
0
gtk-glade/.gitignore → gtk/.gitignore
vendored
0
gtk-glade/.gitignore → gtk/.gitignore
vendored
|
|
@ -1,15 +1,14 @@
|
|||
GLADE_FILES= about.glade \
|
||||
main.glade \
|
||||
password.glade \
|
||||
contact.glade \
|
||||
incoming_call.glade \
|
||||
parameters.glade \
|
||||
sip_account.glade \
|
||||
chatroom.glade \
|
||||
call_logs.glade \
|
||||
log.glade \
|
||||
buddylookup.glade \
|
||||
waiting.glade
|
||||
UI_FILES= about.ui \
|
||||
main.ui \
|
||||
password.ui \
|
||||
contact.ui \
|
||||
parameters.ui \
|
||||
sip_account.ui \
|
||||
chatroom.ui \
|
||||
call_logs.ui \
|
||||
log.ui \
|
||||
buddylookup.ui \
|
||||
waiting.ui
|
||||
|
||||
PIXMAPS= \
|
||||
stock_people.png
|
||||
|
|
@ -18,13 +17,13 @@ LINPHONE_ICO_RC_FILE=linphone.rc
|
|||
LINPHONE_ICO_FILE=linphone.ico
|
||||
|
||||
EXTRA_DIST= $(PIXMAPS) \
|
||||
$(GLADE_FILES) \
|
||||
$(UI_FILES) \
|
||||
linphone.iss \
|
||||
$(LINPHONE_ICO_RC_FILE) \
|
||||
$(LINPHONE_ICO_FILE)
|
||||
|
||||
|
||||
if BUILD_GLADE_UI
|
||||
if BUILD_GTK_UI
|
||||
|
||||
BUILT_SOURCES=version_date.h
|
||||
|
||||
|
|
@ -46,11 +45,10 @@ linphone_3_SOURCES= \
|
|||
loginframe.c \
|
||||
linphone.h
|
||||
|
||||
linphone_3_LDADD=$(top_builddir)/oRTP/src/libortp.la \
|
||||
$(top_builddir)/mediastreamer2/src/libmediastreamer.la \
|
||||
linphone_3_LDADD=$(ORTP_LIBS) \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(LIBGTK_LIBS) $(INTLLIBS) \
|
||||
$(LIBGLADE_LIBS)
|
||||
$(LIBGTK_LIBS) $(INTLLIBS)
|
||||
|
||||
|
||||
if BUILD_WIN32
|
||||
|
|
@ -64,25 +62,20 @@ else
|
|||
linphone_3_LDFLAGS=-export-dynamic
|
||||
endif
|
||||
|
||||
gladedir=$(datadir)/linphone
|
||||
glade_DATA=$(GLADE_FILES) $(PIXMAPS) $(top_srcdir)/COPYING
|
||||
|
||||
#all-local: gtk-linphone.ui
|
||||
|
||||
#gtk-linphone.ui: gtk-linphone.glade
|
||||
# gtk-builder-convert gtk-linphone.glade $@
|
||||
uidir=$(datadir)/linphone
|
||||
ui_DATA=$(UI_FILES) $(PIXMAPS) $(top_srcdir)/COPYING
|
||||
|
||||
endif
|
||||
|
||||
|
||||
AM_CFLAGS= -DIN_LINPHONE -I$(top_srcdir)/coreapi/ \
|
||||
-I$(top_srcdir)/mediastreamer2/include/ \
|
||||
$(MEDIASTREAMER_CFLAGS) \
|
||||
$(ORTP_CFLAGS) \
|
||||
$(LIBGLADE_CFLAGS) $(STRICT_OPTIONS) $(LIBGTK_CFLAGS) $(IPV6_CFLAGS) \
|
||||
$(STRICT_OPTIONS) $(LIBGTK_CFLAGS) $(IPV6_CFLAGS) \
|
||||
$(OSIP_CFLAGS)
|
||||
|
||||
|
||||
version_date.h: $(top_srcdir)/configure.in
|
||||
version_date.h: $(top_srcdir)/configure.ac
|
||||
echo "#define LINPHONE_VERSION_DATE \"$(VERSION)-`date +%y%m%d`\"" > $@
|
||||
|
||||
newdate:
|
||||
|
|
@ -1,19 +1,18 @@
|
|||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 2.12 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkAboutDialog" id="about">
|
||||
<object class="GtkAboutDialog" id="about">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">About linphone</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="icon">linphone2.png</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<property name="program_name">Linphone</property>
|
||||
<property name="version">undef</property>
|
||||
<property name="copyright" translatable="yes">Created by Simon Morlat
|
||||
<property name="copyright" translatable="yes">(C) Belledonne Communications,2010
|
||||
</property>
|
||||
<property name="comments" translatable="yes">An internet video phone using the standard SIP (rfc3261) protocol.</property>
|
||||
<property name="website">http://www.linphone.org</property>
|
||||
|
|
@ -35,7 +34,7 @@ hu: anonymous
|
|||
<property name="artists">Icons by kerosine.fr</property>
|
||||
<signal name="response" handler="linphone_gtk_about_response"/>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox8">
|
||||
<object class="GtkVBox" id="dialog-vbox8">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
|
|
@ -44,18 +43,18 @@ hu: anonymous
|
|||
<placeholder/>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area7">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area7">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="layout_style">end</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -1,94 +1,94 @@
|
|||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 2.16 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkDialog" id="buddylookup">
|
||||
<object class="GtkDialog" id="buddylookup">
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Search contacts in directory</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="icon">linphone2.png</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<signal name="response" handler="gtk_widget_destroy"/>
|
||||
<signal handler="gtk_widget_destroy" name="response"/>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox1">
|
||||
<object class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame1">
|
||||
<object class="GtkFrame" id="frame1">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment1">
|
||||
<object class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox2">
|
||||
<object class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="keyword">
|
||||
<object class="GtkEntry" id="keyword">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<signal name="changed" handler="linphone_gtk_keyword_changed"/>
|
||||
</widget>
|
||||
<signal handler="linphone_gtk_keyword_changed" name="changed"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">automatic</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">etched-in</property>
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="search_results">
|
||||
<object class="GtkTreeView" id="search_results">
|
||||
<property name="width_request">512</property>
|
||||
<property name="height_request">140</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="row_activated" handler="linphone_gtk_buddy_lookup_contact_activated"/>
|
||||
</widget>
|
||||
<signal handler="linphone_gtk_buddy_lookup_contact_activated" name="row_activated"/>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkProgressBar" id="progressbar">
|
||||
<object class="GtkProgressBar" id="progressbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="activity_mode">True</property>
|
||||
<property name="show_text">True</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox1">
|
||||
<object class="GtkHButtonBox" id="hbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="add_buddy">
|
||||
<object class="GtkButton" id="add_buddy">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="linphone_gtk_add_buddy_from_database"/>
|
||||
<signal handler="linphone_gtk_add_buddy_from_database" name="clicked"/>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<object class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1">
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
|
|
@ -96,17 +96,17 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label2">
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Add to my list</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
|
|
@ -114,34 +114,31 @@
|
|||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Search somebody</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
|
|
@ -150,14 +147,14 @@
|
|||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
</object>
|
||||
</interface>
|
||||
109
gtk/call_logs.ui
Normal file
109
gtk/call_logs.ui
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.16"/>
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkListStore" id="call_logs_store">
|
||||
<columns>
|
||||
<!-- column-name icon -->
|
||||
<column type="gchar"/>
|
||||
<!-- column-name sipaddress -->
|
||||
<column type="gchar"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkDialog" id="call_logs">
|
||||
<property name="width_request">500</property>
|
||||
<property name="height_request">370</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Call history</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="logs_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<signal name="row_activated" handler="linphone_gtk_history_row_activated"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label" translatable="yes">Clear all</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">image1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="call_back_button">
|
||||
<property name="label" translatable="yes">Call back</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="call_logs_close">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="2">button1</action-widget>
|
||||
<action-widget response="1">call_back_button</action-widget>
|
||||
<action-widget response="0">call_logs_close</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-clear</property>
|
||||
</object>
|
||||
</interface>
|
||||
131
gtk/calllogs.c
Normal file
131
gtk/calllogs.c
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
linphone, gtk-glade interface.
|
||||
Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "linphone.h"
|
||||
|
||||
|
||||
void linphone_gtk_call_log_update(GtkWidget *w){
|
||||
GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(w,"logs_view"));
|
||||
GtkListStore *store;
|
||||
const MSList *logs;
|
||||
|
||||
store=(GtkListStore*)gtk_tree_view_get_model(v);
|
||||
if (store==NULL){
|
||||
store=gtk_list_store_new(3,G_TYPE_STRING,G_TYPE_STRING, G_TYPE_POINTER);
|
||||
gtk_tree_view_set_model(v,GTK_TREE_MODEL(store));
|
||||
g_object_unref(G_OBJECT(store));
|
||||
}
|
||||
gtk_list_store_clear (store);
|
||||
|
||||
for (logs=linphone_core_get_call_logs(linphone_gtk_get_core());logs!=NULL;logs=logs->next){
|
||||
LinphoneCallLog *cl=(LinphoneCallLog*)logs->data;
|
||||
GtkTreeIter iter;
|
||||
LinphoneAddress *la=cl->dir==LinphoneCallIncoming ? cl->from : cl->to;
|
||||
char *addr= linphone_address_as_string_uri_only (la);
|
||||
const char *display;
|
||||
gchar *logtxt;
|
||||
display=linphone_address_get_display_name (la);
|
||||
if (display==NULL){
|
||||
display=linphone_address_get_username (la);
|
||||
if (display==NULL)
|
||||
display=linphone_address_get_domain (la);
|
||||
}
|
||||
logtxt=g_markup_printf_escaped("<big><b>%s</b></big>\t<small><i>%s</i></small>\n"
|
||||
"%s\t%i minutes %i seconds",display, addr, cl->start_date,
|
||||
cl->duration/60,cl->duration%60);
|
||||
gtk_list_store_append (store,&iter);
|
||||
gtk_list_store_set (store,&iter,
|
||||
0, cl->dir==LinphoneCallOutgoing ? GTK_STOCK_GO_UP : GTK_STOCK_GO_DOWN,
|
||||
1, logtxt,2,la,-1);
|
||||
ms_free(addr);
|
||||
g_free(logtxt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static bool_t put_selection_to_uribar(GtkWidget *treeview){
|
||||
GtkTreeSelection *sel;
|
||||
|
||||
sel=gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
|
||||
if (sel!=NULL){
|
||||
GtkTreeModel *model=NULL;
|
||||
GtkTreeIter iter;
|
||||
if (gtk_tree_selection_get_selected (sel,&model,&iter)){
|
||||
gpointer pla;
|
||||
LinphoneAddress *la;
|
||||
char *tmp;
|
||||
gtk_tree_model_get(model,&iter,2,&pla,-1);
|
||||
la=(LinphoneAddress*)pla;
|
||||
tmp=linphone_address_as_string (la);
|
||||
gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")),tmp);
|
||||
ms_free(tmp);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void linphone_gtk_history_row_activated(GtkWidget *treeview){
|
||||
put_selection_to_uribar(treeview);
|
||||
}
|
||||
|
||||
void linphone_gtk_call_log_response(GtkWidget *w, guint response_id){
|
||||
GtkWidget *mw=linphone_gtk_get_main_window();
|
||||
if (response_id==1){
|
||||
if (put_selection_to_uribar(linphone_gtk_get_widget(w,"logs_view")))
|
||||
linphone_gtk_start_call(linphone_gtk_get_widget(mw,"start_call"));
|
||||
}else if (response_id==2){
|
||||
linphone_core_clear_call_logs (linphone_gtk_get_core());
|
||||
linphone_gtk_call_log_update(w);
|
||||
return;
|
||||
}
|
||||
g_object_set_data(G_OBJECT(mw),"call_logs",NULL);
|
||||
gtk_widget_destroy(w);
|
||||
}
|
||||
|
||||
|
||||
static void fill_renderers(GtkTreeView *v){
|
||||
GtkTreeViewColumn *c;
|
||||
GtkCellRenderer *r=gtk_cell_renderer_pixbuf_new ();
|
||||
|
||||
g_object_set(r,"stock-size",GTK_ICON_SIZE_BUTTON,NULL);
|
||||
c=gtk_tree_view_column_new_with_attributes("icon",r,"stock-id",0,NULL);
|
||||
gtk_tree_view_append_column (v,c);
|
||||
|
||||
r=gtk_cell_renderer_text_new ();
|
||||
c=gtk_tree_view_column_new_with_attributes("sipaddress",r,"markup",1,NULL);
|
||||
gtk_tree_view_append_column (v,c);
|
||||
}
|
||||
|
||||
GtkWidget * linphone_gtk_show_call_logs(void){
|
||||
GtkWidget *mw=linphone_gtk_get_main_window();
|
||||
GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"call_logs");
|
||||
if (w==NULL){
|
||||
w=linphone_gtk_create_window("call_logs");
|
||||
gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"call_back_button")),
|
||||
create_pixmap (linphone_gtk_get_ui_config("callback_button","status-green.png")));
|
||||
fill_renderers(GTK_TREE_VIEW(linphone_gtk_get_widget(w,"logs_view")));
|
||||
g_object_set_data(G_OBJECT(mw),"call_logs",w);
|
||||
g_signal_connect(G_OBJECT(w),"response",(GCallback)linphone_gtk_call_log_response,NULL);
|
||||
gtk_widget_show(w);
|
||||
linphone_gtk_call_log_update(w);
|
||||
}else gtk_window_present(GTK_WINDOW(w));
|
||||
return w;
|
||||
}
|
||||
|
||||
|
|
@ -94,13 +94,13 @@ void linphone_gtk_send_text(GtkWidget *button){
|
|||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const char *from, const char *message){
|
||||
void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message){
|
||||
GtkWidget *w=(GtkWidget*)linphone_chat_room_get_user_data(room);
|
||||
if (w==NULL){
|
||||
w=linphone_gtk_init_chatroom(room,from);
|
||||
w=linphone_gtk_init_chatroom(room,linphone_address_as_string_uri_only(from));
|
||||
}
|
||||
linphone_gtk_push_text(GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"textlog")),
|
||||
from,
|
||||
linphone_address_as_string_uri_only(from),
|
||||
message,FALSE);
|
||||
gtk_window_present(GTK_WINDOW(w));
|
||||
/*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/
|
||||
|
|
@ -1,69 +1,67 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<?xml version="1.0"?>
|
||||
<!--Generated with glade3 3.4.5 on Wed Jul 30 15:51:13 2008 -->
|
||||
<glade-interface>
|
||||
<widget class="GtkWindow" id="chatroom">
|
||||
<signal name="destroy" handler="linphone_gtk_chat_destroyed"/>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="chatroom">
|
||||
<signal handler="linphone_gtk_chat_destroyed" name="destroy"/>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox1">
|
||||
<object class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkTextView" id="textlog">
|
||||
<object class="GtkTextView" id="textlog">
|
||||
<property name="width_request">200</property>
|
||||
<property name="height_request">200</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="wrap_mode">GTK_WRAP_WORD</property>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<object class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="text_entry">
|
||||
<object class="GtkEntry" id="text_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<signal name="activate" handler="linphone_gtk_send_text"/>
|
||||
</widget>
|
||||
<signal handler="linphone_gtk_send_text" name="activate"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="send">
|
||||
<object class="GtkButton" id="send">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="linphone_gtk_send_text"/>
|
||||
<signal handler="linphone_gtk_send_text" name="clicked"/>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox2">
|
||||
<object class="GtkHBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1">
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-ok</property>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Send</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">7</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
|
|
@ -71,30 +69,29 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox1">
|
||||
<object class="GtkHButtonBox" id="hbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button1">
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="label" translatable="yes">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="linphone_gtk_chat_close"/>
|
||||
</widget>
|
||||
<signal handler="linphone_gtk_chat_close" name="clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 2.16 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkDialog" id="contact">
|
||||
<object class="GtkDialog" id="contact">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
|
|
@ -10,46 +10,46 @@
|
|||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox7">
|
||||
<object class="GtkVBox" id="dialog-vbox7">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame17">
|
||||
<object class="GtkFrame" id="frame17">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment17">
|
||||
<object class="GtkAlignment" id="alignment17">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox13">
|
||||
<object class="GtkVBox" id="vbox13">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table7">
|
||||
<object class="GtkTable" id="table7">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="n_rows">2</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label45">
|
||||
<object class="GtkLabel" id="label45">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Name</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label46">
|
||||
<object class="GtkLabel" id="label46">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">SIP Address</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
|
|
@ -57,11 +57,11 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="name">
|
||||
<object class="GtkEntry" id="name">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
|
|
@ -69,11 +69,11 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="sip_address">
|
||||
<object class="GtkEntry" id="sip_address">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
|
|
@ -82,14 +82,14 @@
|
|||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="show_presence">
|
||||
<object class="GtkCheckButton" id="show_presence">
|
||||
<property name="label" translatable="yes">Show this contact presence status</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
|
|
@ -97,13 +97,13 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="allow_presence">
|
||||
<object class="GtkCheckButton" id="allow_presence">
|
||||
<property name="label" translatable="yes">Allow this contact to see my presence status</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
|
|
@ -111,46 +111,43 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label47">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label47">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes"><b>Contact information</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area7">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area7">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancel_button">
|
||||
<object class="GtkButton" id="cancel_button">
|
||||
<property name="label" translatable="yes">gtk-cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="linphone_gtk_contact_cancel"/>
|
||||
</widget>
|
||||
<signal handler="linphone_gtk_contact_cancel" name="clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
|
|
@ -158,29 +155,29 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="ok_button">
|
||||
<object class="GtkButton" id="ok_button">
|
||||
<property name="label" translatable="yes">gtk-ok</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="linphone_gtk_contact_ok"/>
|
||||
</widget>
|
||||
<signal handler="linphone_gtk_contact_ok" name="clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -39,18 +39,18 @@ typedef struct _status_picture_tab_t{
|
|||
} status_picture_tab_t;
|
||||
|
||||
status_picture_tab_t status_picture_tab[]={
|
||||
{ LINPHONE_STATUS_ONLINE, "status-green.png" },
|
||||
{ LINPHONE_STATUS_BUSY, "status-orange.png" },
|
||||
{ LINPHONE_STATUS_BERIGHTBACK, "status-orange.png" },
|
||||
{ LINPHONE_STATUS_AWAY, "status-orange.png" },
|
||||
{ LINPHONE_STATUS_ONTHEPHONE, "status-orange.png" },
|
||||
{ LINPHONE_STATUS_OUTTOLUNCH, "status-orange.png" },
|
||||
{ LINPHONE_STATUS_NOT_DISTURB, "status-red.png" },
|
||||
{ LINPHONE_STATUS_MOVED, "status-orange.png" },
|
||||
{ LINPHONE_STATUS_ALT_SERVICE, "status-orange.png" },
|
||||
{ LINPHONE_STATUS_OFFLINE, "status-offline.png" },
|
||||
{ LINPHONE_STATUS_PENDING, "status-offline.png" },
|
||||
{ LINPHONE_STATUS_END, NULL },
|
||||
{ LinphoneStatusOnline, "status-green.png" },
|
||||
{ LinphoneStatusBusy, "status-orange.png" },
|
||||
{ LinphoneStatusBeRightBack, "status-orange.png" },
|
||||
{ LinphoneStatusAway, "status-orange.png" },
|
||||
{ LinphoneStatusOnThePhone, "status-orange.png" },
|
||||
{ LinphoneStatusOutToLunch, "status-orange.png" },
|
||||
{ LinphoneStatusDoNotDisturb, "status-red.png" },
|
||||
{ LinphoneStatusMoved, "status-orange.png" },
|
||||
{ LinphoneStatusAltService, "status-orange.png" },
|
||||
{ LinphoneStatusOffline, "status-offline.png" },
|
||||
{ LinphoneStatusPending, "status-offline.png" },
|
||||
{ LinphoneStatusEnd, NULL },
|
||||
};
|
||||
|
||||
static GdkPixbuf *create_status_picture(LinphoneOnlineStatus ss){
|
||||
|
|
@ -132,7 +132,7 @@ static GtkWidget * create_presence_menu(){
|
|||
GdkPixbuf *pbuf;
|
||||
status_picture_tab_t *t;
|
||||
for(t=status_picture_tab;t->img!=NULL;++t){
|
||||
if (t->status==LINPHONE_STATUS_PENDING){
|
||||
if (t->status==LinphoneStatusPending){
|
||||
continue;
|
||||
}
|
||||
menu_item=gtk_image_menu_item_new_with_label(linphone_online_status_to_string(t->status));
|
||||
|
|
@ -317,7 +317,7 @@ void linphone_gtk_show_friends(void){
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if (!online_only || (linphone_friend_get_status(lf)!=LINPHONE_STATUS_OFFLINE)){
|
||||
if (!online_only || (linphone_friend_get_status(lf)!=LinphoneStatusOffline)){
|
||||
BuddyInfo *bi;
|
||||
if (name==NULL || name[0]=='\0') display=uri;
|
||||
gtk_list_store_append(store,&iter);
|
||||
|
|
@ -450,9 +450,12 @@ void linphone_gtk_contact_ok(GtkWidget *button){
|
|||
linphone_gtk_display_something(GTK_MESSAGE_WARNING,_("Invalid sip contact !"));
|
||||
return ;
|
||||
}
|
||||
linphone_friend_set_sip_addr(lf,fixed_uri);
|
||||
LinphoneAddress* friend_address = linphone_address_new(fixed_uri);
|
||||
linphone_address_set_display_name(friend_address,name);
|
||||
linphone_friend_set_addr(lf,friend_address);
|
||||
ms_free(fixed_uri);
|
||||
linphone_friend_set_name(lf,name);
|
||||
linphone_address_destroy(friend_address);
|
||||
|
||||
linphone_friend_send_subscribe(lf,show_presence);
|
||||
linphone_friend_set_inc_subscribe_policy(lf,allow_presence==TRUE ? LinphoneSPAccept : LinphoneSPDeny);
|
||||
if (linphone_friend_in_list(lf)) {
|
||||
315
gtk/incall_view.c
Normal file
315
gtk/incall_view.c
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
linphone, gtk-glade interface.
|
||||
Copyright (C) 2009 Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/*
|
||||
* C Implementation: incall_frame
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
*
|
||||
* Author: Simon Morlat <simon.morlat@linphone.org>, (C) 2009
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "linphone.h"
|
||||
|
||||
|
||||
gboolean linphone_gtk_use_in_call_view(){
|
||||
static int val=-1;
|
||||
if (val==-1) val=linphone_gtk_get_ui_config_int("use_incall_view",1);
|
||||
return val;
|
||||
}
|
||||
|
||||
LinphoneCall *linphone_gtk_get_currently_displayed_call(){
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window ();
|
||||
GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch");
|
||||
const MSList *calls=linphone_core_get_calls(lc);
|
||||
if (!linphone_gtk_use_in_call_view() || ms_list_size(calls)==1){
|
||||
if (calls) return (LinphoneCall*)calls->data;
|
||||
}else{
|
||||
int idx=gtk_notebook_get_current_page (notebook);
|
||||
GtkWidget *page=gtk_notebook_get_nth_page(notebook,idx);
|
||||
if (page!=NULL){
|
||||
LinphoneCall *call=(LinphoneCall*)g_object_get_data(G_OBJECT(page),"call");
|
||||
return call;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GtkWidget *make_tab_header(int number){
|
||||
GtkWidget *w=gtk_hbox_new (FALSE,0);
|
||||
GtkWidget *i=create_pixmap ("status-green.png");
|
||||
GtkWidget *l;
|
||||
gchar *text=g_strdup_printf("Call %i",number);
|
||||
l=gtk_label_new (text);
|
||||
gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0);
|
||||
gtk_box_pack_end(GTK_BOX(w),l,TRUE,TRUE,0);
|
||||
gtk_widget_show_all(w);
|
||||
return w;
|
||||
}
|
||||
|
||||
void linphone_gtk_create_in_call_view(LinphoneCall *call){
|
||||
GtkWidget *call_view=linphone_gtk_create_widget("main","in_call_frame");
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window ();
|
||||
GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch");
|
||||
static int call_index=1;
|
||||
int idx;
|
||||
|
||||
if (ms_list_size(linphone_core_get_calls(linphone_gtk_get_core()))==1){
|
||||
/*this is the only call at this time */
|
||||
call_index=1;
|
||||
}
|
||||
g_object_set_data(G_OBJECT(call_view),"call",call);
|
||||
linphone_call_set_user_pointer (call,call_view);
|
||||
linphone_call_ref(call);
|
||||
gtk_notebook_append_page (notebook,call_view,make_tab_header(call_index));
|
||||
gtk_widget_show(call_view);
|
||||
idx = gtk_notebook_page_num(notebook, call_view);
|
||||
gtk_notebook_set_current_page(notebook, idx);
|
||||
call_index++;
|
||||
linphone_gtk_enable_hold_button (call,FALSE,TRUE);
|
||||
linphone_gtk_enable_mute_button(
|
||||
GTK_BUTTON(linphone_gtk_get_widget(call_view,"incall_mute")),FALSE);
|
||||
}
|
||||
|
||||
void linphone_gtk_remove_in_call_view(LinphoneCall *call){
|
||||
GtkWidget *w=(GtkWidget*)linphone_call_get_user_pointer (call);
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window ();
|
||||
GtkWidget *nb=linphone_gtk_get_widget(main_window,"viewswitch");
|
||||
int idx;
|
||||
g_return_if_fail(w!=NULL);
|
||||
idx=gtk_notebook_page_num(GTK_NOTEBOOK(nb),w);
|
||||
gtk_notebook_remove_page (GTK_NOTEBOOK(nb),idx);
|
||||
gtk_widget_destroy(w);
|
||||
linphone_call_set_user_pointer (call,NULL);
|
||||
linphone_call_unref(call);
|
||||
gtk_notebook_set_current_page(GTK_NOTEBOOK(nb), 0);
|
||||
}
|
||||
|
||||
static void display_peer_name_in_label(GtkWidget *label, const LinphoneAddress *from){
|
||||
const char *displayname=NULL;
|
||||
const char *id;
|
||||
char *uri_label;
|
||||
displayname=linphone_address_get_display_name(from);
|
||||
id=linphone_address_as_string_uri_only(from);
|
||||
|
||||
if (displayname!=NULL){
|
||||
uri_label=g_markup_printf_escaped("<span size=\"large\">%s</span>\n<i>%s</i>",
|
||||
displayname,id);
|
||||
}else
|
||||
uri_label=g_markup_printf_escaped("<span size=\"large\"><i>%s</i></span>\n",id);
|
||||
gtk_label_set_markup(GTK_LABEL(label),uri_label);
|
||||
g_free(uri_label);
|
||||
}
|
||||
|
||||
void linphone_gtk_in_call_view_set_calling(LinphoneCall *call){
|
||||
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
|
||||
GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status");
|
||||
GtkWidget *callee=linphone_gtk_get_widget(callview,"in_call_uri");
|
||||
GtkWidget *duration=linphone_gtk_get_widget(callview,"in_call_duration");
|
||||
GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation");
|
||||
GdkPixbufAnimation *pbuf=create_pixbuf_animation("calling_anim.gif");
|
||||
|
||||
gtk_label_set_markup(GTK_LABEL(status),_("<b>Calling...</b>"));
|
||||
display_peer_name_in_label(callee,linphone_call_get_remote_address (call));
|
||||
|
||||
gtk_label_set_text(GTK_LABEL(duration),_("00::00::00"));
|
||||
if (pbuf!=NULL){
|
||||
gtk_image_set_from_animation(GTK_IMAGE(animation),pbuf);
|
||||
g_object_unref(G_OBJECT(pbuf));
|
||||
}else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_FIND,GTK_ICON_SIZE_DIALOG);
|
||||
}
|
||||
|
||||
void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_pause){
|
||||
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
|
||||
GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status");
|
||||
GtkWidget *callee=linphone_gtk_get_widget(callview,"in_call_uri");
|
||||
GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation");
|
||||
GdkPixbufAnimation *pbuf=create_pixbuf_animation("calling_anim.gif");
|
||||
GtkWidget *answer_button;
|
||||
|
||||
gtk_label_set_markup(GTK_LABEL(status),_("<b>Incoming call</b>"));
|
||||
gtk_widget_show_all(linphone_gtk_get_widget(callview,"answer_decline_panel"));
|
||||
gtk_widget_hide(linphone_gtk_get_widget(callview,"duration_frame"));
|
||||
gtk_widget_hide(linphone_gtk_get_widget(callview,"mute_pause_buttons"));
|
||||
display_peer_name_in_label(callee,linphone_call_get_remote_address (call));
|
||||
|
||||
answer_button=linphone_gtk_get_widget(callview,"accept_call");
|
||||
gtk_button_set_image(GTK_BUTTON(answer_button),
|
||||
create_pixmap (linphone_gtk_get_ui_config("start_call_icon","startcall-green.png")));
|
||||
if (with_pause){
|
||||
gtk_button_set_label(GTK_BUTTON(answer_button),
|
||||
_("Pause all calls\nand answer"));
|
||||
}else gtk_button_set_label(GTK_BUTTON(answer_button),_("Answer"));
|
||||
gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(callview,"decline_call")),
|
||||
create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png")));
|
||||
|
||||
if (pbuf!=NULL){
|
||||
gtk_image_set_from_animation(GTK_IMAGE(animation),pbuf);
|
||||
g_object_unref(G_OBJECT(pbuf));
|
||||
}else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_EXECUTE,GTK_ICON_SIZE_DIALOG);
|
||||
}
|
||||
|
||||
void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){
|
||||
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
|
||||
GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status");
|
||||
GtkWidget *callee=linphone_gtk_get_widget(callview,"in_call_uri");
|
||||
GtkWidget *duration=linphone_gtk_get_widget(callview,"in_call_duration");
|
||||
GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation");
|
||||
GdkPixbufAnimation *pbuf=create_pixbuf_animation("incall_anim.gif");
|
||||
|
||||
display_peer_name_in_label(callee,linphone_call_get_remote_address (call));
|
||||
|
||||
gtk_widget_show(linphone_gtk_get_widget(callview,"duration_frame"));
|
||||
gtk_widget_show(linphone_gtk_get_widget(callview,"mute_pause_buttons"));
|
||||
gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel"));
|
||||
gtk_label_set_markup(GTK_LABEL(status),_("<b>In call</b>"));
|
||||
|
||||
gtk_label_set_text(GTK_LABEL(duration),_("00::00::00"));
|
||||
if (pbuf!=NULL){
|
||||
gtk_image_set_from_animation(GTK_IMAGE(animation),pbuf);
|
||||
g_object_unref(G_OBJECT(pbuf));
|
||||
}else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_EXECUTE,GTK_ICON_SIZE_DIALOG);
|
||||
linphone_gtk_enable_mute_button(
|
||||
GTK_BUTTON(linphone_gtk_get_widget(callview,"incall_mute")),TRUE);
|
||||
}
|
||||
|
||||
void linphone_gtk_in_call_view_set_paused(LinphoneCall *call){
|
||||
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
|
||||
GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status");
|
||||
GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation");
|
||||
gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel"));
|
||||
gtk_label_set_markup(GTK_LABEL(status),_("<b>Paused call</b>"));
|
||||
gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_MEDIA_PAUSE,GTK_ICON_SIZE_DIALOG);
|
||||
}
|
||||
|
||||
void linphone_gtk_in_call_view_update_duration(LinphoneCall *call){
|
||||
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
|
||||
GtkWidget *duration_label=linphone_gtk_get_widget(callview,"in_call_duration");
|
||||
int duration=linphone_call_get_duration(call);
|
||||
char tmp[256]={0};
|
||||
int seconds=duration%60;
|
||||
int minutes=(duration/60)%60;
|
||||
int hours=duration/3600;
|
||||
snprintf(tmp,sizeof(tmp)-1,_("%02i::%02i::%02i"),hours,minutes,seconds);
|
||||
gtk_label_set_text(GTK_LABEL(duration_label),tmp);
|
||||
}
|
||||
|
||||
static gboolean in_call_view_terminated(LinphoneCall *call){
|
||||
linphone_gtk_remove_in_call_view(call);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_msg){
|
||||
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
|
||||
GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status");
|
||||
GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation");
|
||||
GdkPixbuf *pbuf=create_pixbuf(linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png"));
|
||||
|
||||
if (error_msg==NULL)
|
||||
gtk_label_set_markup(GTK_LABEL(status),_("<b>Call ended.</b>"));
|
||||
else{
|
||||
char *msg=g_markup_printf_escaped("<span color=\"red\"><b>%s</b></span>",error_msg);
|
||||
gtk_label_set_markup(GTK_LABEL(status),msg);
|
||||
g_free(msg);
|
||||
}
|
||||
if (pbuf!=NULL){
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(animation),pbuf);
|
||||
g_object_unref(G_OBJECT(pbuf));
|
||||
}
|
||||
gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel"));
|
||||
linphone_gtk_enable_mute_button(
|
||||
GTK_BUTTON(linphone_gtk_get_widget(callview,"incall_mute")),FALSE);
|
||||
linphone_gtk_enable_hold_button(call,FALSE,TRUE);
|
||||
g_timeout_add_seconds(2,(GSourceFunc)in_call_view_terminated,call);
|
||||
}
|
||||
|
||||
void linphone_gtk_draw_mute_button(GtkButton *button, gboolean active){
|
||||
g_object_set_data(G_OBJECT(button),"active",GINT_TO_POINTER(active));
|
||||
if (active){
|
||||
GtkWidget *image=create_pixmap("mic_muted.png");
|
||||
gtk_button_set_label(GTK_BUTTON(button),_("Unmute"));
|
||||
if (image!=NULL) {
|
||||
gtk_button_set_image(GTK_BUTTON(button),image);
|
||||
gtk_widget_show(image);
|
||||
}
|
||||
}else{
|
||||
GtkWidget *image=create_pixmap("mic_active.png");
|
||||
gtk_button_set_label(GTK_BUTTON(button),_("Mute"));
|
||||
if (image!=NULL) {
|
||||
gtk_button_set_image(GTK_BUTTON(button),image);
|
||||
gtk_widget_show(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_mute_clicked(GtkButton *button){
|
||||
int active=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button),"active"));
|
||||
linphone_core_mute_mic(linphone_gtk_get_core(),!active);
|
||||
linphone_gtk_draw_mute_button(button,!active);
|
||||
}
|
||||
|
||||
void linphone_gtk_enable_mute_button(GtkButton *button, gboolean sensitive)
|
||||
{
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(button),sensitive);
|
||||
linphone_gtk_draw_mute_button(button,FALSE);
|
||||
}
|
||||
|
||||
void linphone_gtk_draw_hold_button(GtkButton *button, gboolean active){
|
||||
g_object_set_data(G_OBJECT(button),"active",GINT_TO_POINTER(active));
|
||||
if (active){
|
||||
GtkWidget *image=create_pixmap("hold_off.png");
|
||||
gtk_button_set_label(GTK_BUTTON(button),_("Resume"));
|
||||
if (image!=NULL) {
|
||||
gtk_button_set_image(GTK_BUTTON(button),image);
|
||||
gtk_widget_show(image);
|
||||
}
|
||||
}else{
|
||||
GtkWidget *image=create_pixmap("hold_on.png");
|
||||
gtk_button_set_label(GTK_BUTTON(button),_("Pause"));
|
||||
if (image!=NULL) {
|
||||
gtk_button_set_image(GTK_BUTTON(button),image);
|
||||
gtk_widget_show(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_hold_clicked(GtkButton *button){
|
||||
int active=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button),"active"));
|
||||
LinphoneCall *call=linphone_gtk_get_currently_displayed_call ();
|
||||
if(!active)
|
||||
{
|
||||
linphone_core_pause_call(linphone_gtk_get_core(),call);
|
||||
}
|
||||
else
|
||||
{
|
||||
linphone_core_resume_call(linphone_gtk_get_core(),call);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_enable_hold_button(LinphoneCall *call, gboolean sensitive, gboolean holdon){
|
||||
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer (call);
|
||||
GtkWidget *button;
|
||||
g_return_if_fail(callview!=NULL);
|
||||
button=linphone_gtk_get_widget(callview,"hold_call");
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(button),sensitive);
|
||||
linphone_gtk_draw_hold_button(GTK_BUTTON(button),!holdon);
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 2.16 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkDialog" id="incoming_call">
|
||||
<object class="GtkDialog" id="incoming_call">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="type">popup</property>
|
||||
|
|
@ -13,84 +13,81 @@
|
|||
<property name="urgency_hint">True</property>
|
||||
<property name="deletable">False</property>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox8">
|
||||
<object class="GtkVBox" id="dialog-vbox8">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame16">
|
||||
<object class="GtkFrame" id="frame16">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment16">
|
||||
<object class="GtkAlignment" id="alignment16">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="message">
|
||||
<object class="GtkLabel" id="message">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Incoming call from</property>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label43">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label43">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Incoming call</property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area7">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area7">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="layout_style">spread</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="accept_call">
|
||||
<object class="GtkButton" id="accept_call">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="linphone_gtk_accept_call"/>
|
||||
<signal handler="linphone_gtk_accept_call" name="clicked"/>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox17">
|
||||
<object class="GtkHBox" id="hbox17">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image12">
|
||||
<object class="GtkImage" id="image12">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-yes</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label44">
|
||||
<object class="GtkLabel" id="label44">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Accept</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
|
|
@ -98,53 +95,53 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="decline_cal">
|
||||
<object class="GtkButton" id="decline_cal">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal name="clicked" handler="linphone_gtk_decline_call"/>
|
||||
<signal handler="linphone_gtk_decline_call" name="clicked"/>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox20">
|
||||
<object class="GtkHBox" id="hbox20">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image13">
|
||||
<object class="GtkImage" id="image13">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-no</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="decline_call">
|
||||
<object class="GtkLabel" id="decline_call">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Decline</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -48,6 +48,8 @@ GdkPixbuf *_gdk_pixbuf_new_from_memory_at_scale(const void *data, gint len, gint
|
|||
|
||||
GtkWidget *linphone_gtk_create_window(const char *window_name);
|
||||
GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name);
|
||||
GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_name);
|
||||
|
||||
LinphoneCore *linphone_gtk_get_core(void);
|
||||
GtkWidget *linphone_gtk_get_main_window();
|
||||
void linphone_gtk_display_something(GtkMessageType type,const gchar *message);
|
||||
|
|
@ -59,7 +61,7 @@ void linphone_gtk_set_my_presence(LinphoneOnlineStatus ss);
|
|||
void linphone_gtk_show_parameters(void);
|
||||
void linphone_gtk_load_identities(void);
|
||||
void linphone_gtk_create_chatroom(const char *with);
|
||||
void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const char *from, const char *message);
|
||||
void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message);
|
||||
void linphone_gtk_call_log_update(GtkWidget *w);
|
||||
void linphone_gtk_create_log_window(void);
|
||||
void linphone_gtk_log_show(void);
|
||||
|
|
@ -85,13 +87,17 @@ void linphone_gtk_show_directory_search(void);
|
|||
|
||||
/*functions controlling the different views*/
|
||||
gboolean linphone_gtk_use_in_call_view();
|
||||
void linphone_gtk_show_in_call_view(void);
|
||||
void linphone_gtk_show_idle_view(void);
|
||||
void linphone_gtk_in_call_view_set_calling(const char *uri);
|
||||
void linphone_gtk_in_call_view_set_in_call(void);
|
||||
void linphone_gtk_in_call_view_update_duration(int duration);
|
||||
void linphone_gtk_in_call_view_terminate(const char *error_msg);
|
||||
void linphone_gtk_enable_mute_button(GtkToggleButton *button, gboolean sensitive);
|
||||
LinphoneCall *linphone_gtk_get_currently_displayed_call();
|
||||
void linphone_gtk_create_in_call_view(LinphoneCall *call);
|
||||
void linphone_gtk_in_call_view_set_calling(LinphoneCall *call);
|
||||
void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call);
|
||||
void linphone_gtk_in_call_view_update_duration(LinphoneCall *call);
|
||||
void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_msg);
|
||||
void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_pause);
|
||||
void linphone_gtk_in_call_view_set_paused(LinphoneCall *call);
|
||||
void linphone_gtk_enable_mute_button(GtkButton *button, gboolean sensitive);
|
||||
void linphone_gtk_enable_hold_button(LinphoneCall *call, gboolean sensitive, gboolean holdon);
|
||||
|
||||
void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg);
|
||||
|
||||
void linphone_gtk_exit_login_frame(void);
|
||||
void linphone_gtk_set_ui_config(const char *key, const char *value);
|
||||
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
|
@ -1,24 +1,24 @@
|
|||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<!-- interface-requires gtk+ 2.16 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.16"/>
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkDialog" id="log">
|
||||
<object class="GtkDialog" id="log">
|
||||
<property name="width_request">540</property>
|
||||
<property name="height_request">290</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Linphone debug window</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="icon">linphone2.png</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="type_hint">normal</property>
|
||||
<property name="deletable">False</property>
|
||||
<property name="has_separator">False</property>
|
||||
<signal name="response" handler="gtk_widget_hide"/>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox1">
|
||||
<object class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
|
|
@ -27,48 +27,51 @@
|
|||
<property name="window_placement_set">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<widget class="GtkTextView" id="textview">
|
||||
<object class="GtkTextView" id="textview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="wrap_mode">word</property>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button1">
|
||||
<property name="label" translatable="yes">gtk-close</property>
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="linphone_gtk_log_hide"/>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
<action-widgets>
|
||||
<action-widget response="0">button1</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -213,14 +213,6 @@ static void linphone_gtk_log_file(OrtpLogLevel lev, const char *msg)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gboolean delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
|
||||
{
|
||||
gtk_widget_hide (widget);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void linphone_gtk_log_hide(){
|
||||
if (log_window)
|
||||
gtk_widget_hide(log_window);
|
||||
|
|
@ -234,7 +226,7 @@ void linphone_gtk_create_log_window(void){
|
|||
gtk_text_buffer_create_tag(b,"orange","foreground","orange",NULL);
|
||||
/*prevent the log window from being destroyed*/
|
||||
g_signal_connect (G_OBJECT (log_window), "delete-event",
|
||||
G_CALLBACK (delete_event_cb), NULL);
|
||||
G_CALLBACK (gtk_widget_hide_on_delete), log_window);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -27,28 +27,28 @@ enum {
|
|||
NetworkKindOpticalFiber
|
||||
};
|
||||
|
||||
static gboolean check_login_ok(LinphoneProxyConfig *cfg){
|
||||
if (linphone_proxy_config_is_registered(cfg)){
|
||||
linphone_gtk_exit_login_frame();
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void do_login(SipSetupContext *ssctx, const char *identity, const char * passwd){
|
||||
GtkWidget *mw=linphone_gtk_get_main_window();
|
||||
if (sip_setup_context_login_account(ssctx,identity,passwd)==0){
|
||||
guint t=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(mw),"login_tout"));
|
||||
if (t!=0) g_source_remove(t);
|
||||
t=g_timeout_add(50,(GSourceFunc)check_login_ok,sip_setup_context_get_proxy_config(ssctx));
|
||||
g_object_set_data(G_OBJECT(mw),"login_tout",GINT_TO_POINTER(t));
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean do_login_noprompt(LinphoneProxyConfig *cfg){
|
||||
SipSetupContext *ssctx=linphone_proxy_config_get_sip_setup_context(cfg);
|
||||
LinphoneAddress *addr;
|
||||
const char *username;
|
||||
char *tmp;
|
||||
if (ssctx==NULL) return TRUE;/*not ready ?*/
|
||||
do_login(ssctx,linphone_proxy_config_get_identity(cfg),NULL);
|
||||
username=linphone_gtk_get_ui_config ("login_username",NULL);
|
||||
if (username==NULL) {
|
||||
linphone_gtk_set_ui_config_int("automatic_login",0);
|
||||
linphone_gtk_show_login_frame(cfg);
|
||||
return FALSE;
|
||||
}
|
||||
addr=linphone_address_new(linphone_proxy_config_get_identity(cfg));
|
||||
linphone_address_set_username(addr,username);
|
||||
tmp=linphone_address_as_string (addr);
|
||||
do_login(ssctx,tmp,NULL);
|
||||
linphone_address_destroy(addr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -75,17 +75,32 @@ void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg){
|
|||
return;
|
||||
}
|
||||
|
||||
gtk_widget_hide(linphone_gtk_get_widget(mw,"logout"));
|
||||
gtk_widget_hide(linphone_gtk_get_widget(mw,"idle_frame"));
|
||||
{
|
||||
const char *login_image=linphone_gtk_get_ui_config("login_image",NULL);
|
||||
if (login_image){
|
||||
GdkPixbuf *pbuf=create_pixbuf (login_image);
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE(linphone_gtk_get_widget(mw,"login_image")),
|
||||
pbuf);
|
||||
g_object_unref(G_OBJECT(pbuf));
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_hide(linphone_gtk_get_widget(mw,"disconnect_item"));
|
||||
gtk_widget_hide(linphone_gtk_get_widget(mw,"main_frame"));
|
||||
gtk_widget_show(linphone_gtk_get_widget(mw,"login_frame"));
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"main_menu"),FALSE);
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"modes"),FALSE);
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"options_menu"),FALSE);
|
||||
str=g_strdup_printf(_("Please enter login information for %s"),linphone_proxy_config_get_domain(cfg));
|
||||
gtk_label_set_text(GTK_LABEL(label),str);
|
||||
g_object_set_data(G_OBJECT(mw),"login_proxy_config",cfg);
|
||||
g_free(str);
|
||||
|
||||
from=linphone_address_new(linphone_proxy_config_get_identity(cfg));
|
||||
if (linphone_address_get_username(from)[0]=='?'){
|
||||
const char *username=linphone_gtk_get_ui_config ("login_username",NULL);
|
||||
if (username)
|
||||
linphone_address_set_username(from,username);
|
||||
}
|
||||
|
||||
ai=linphone_core_find_auth_info(lc,linphone_proxy_config_get_domain(cfg),linphone_address_get_username(from));
|
||||
/*display the last entered username, if not '?????'*/
|
||||
|
|
@ -101,11 +116,11 @@ void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg){
|
|||
|
||||
void linphone_gtk_exit_login_frame(void){
|
||||
GtkWidget *mw=linphone_gtk_get_main_window();
|
||||
gtk_widget_show(linphone_gtk_get_widget(mw,"idle_frame"));
|
||||
gtk_widget_show(linphone_gtk_get_widget(mw,"main_frame"));
|
||||
gtk_widget_hide(linphone_gtk_get_widget(mw,"login_frame"));
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"main_menu"),TRUE);
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"modes"),TRUE);
|
||||
gtk_widget_show(linphone_gtk_get_widget(mw,"logout"));
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"options_menu"),TRUE);
|
||||
gtk_widget_show(linphone_gtk_get_widget(mw,"disconnect_item"));
|
||||
}
|
||||
|
||||
void linphone_gtk_logout_clicked(){
|
||||
|
|
@ -142,6 +157,7 @@ void linphone_gtk_login_frame_connect_clicked(GtkWidget *button){
|
|||
|
||||
autologin=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(mw,"automatic_login")));
|
||||
linphone_gtk_set_ui_config_int("automatic_login",autologin);
|
||||
linphone_gtk_set_ui_config("login_username",username);
|
||||
|
||||
from=linphone_address_new(linphone_proxy_config_get_identity(cfg));
|
||||
linphone_address_set_username(from,username);
|
||||
|
|
@ -17,7 +17,7 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#define USE_LIBGLADE 1
|
||||
//#define USE_LIBGLADE 1
|
||||
|
||||
#define VIDEOSELFVIEW_DEFAULT 1
|
||||
|
||||
|
|
@ -41,9 +41,8 @@ const char *this_program_ident_string="linphone_ident_string=" LINPHONE_VERSION;
|
|||
static LinphoneCore *the_core=NULL;
|
||||
static GtkWidget *the_ui=NULL;
|
||||
|
||||
static void linphone_gtk_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState rs, const char *msg);
|
||||
static void linphone_gtk_show(LinphoneCore *lc);
|
||||
static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from);
|
||||
static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from);
|
||||
static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid);
|
||||
static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url);
|
||||
static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username);
|
||||
|
|
@ -51,30 +50,11 @@ static void linphone_gtk_display_status(LinphoneCore *lc, const char *status);
|
|||
static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg);
|
||||
static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning);
|
||||
static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url);
|
||||
static void linphone_gtk_display_question(LinphoneCore *lc, const char *question);
|
||||
static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl);
|
||||
static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate);
|
||||
static void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to);
|
||||
static gboolean linphone_gtk_auto_answer(GtkWidget *incall_window);
|
||||
static void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to);
|
||||
static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg);
|
||||
static gboolean linphone_gtk_auto_answer(LinphoneCall *call);
|
||||
|
||||
static LinphoneCoreVTable vtable={
|
||||
.show=linphone_gtk_show,
|
||||
.inv_recv=linphone_gtk_inv_recv,
|
||||
.bye_recv=linphone_gtk_bye_recv,
|
||||
.notify_presence_recv=linphone_gtk_notify_recv,
|
||||
.new_unknown_subscriber=linphone_gtk_new_unknown_subscriber,
|
||||
.auth_info_requested=linphone_gtk_auth_info_requested,
|
||||
.display_status=linphone_gtk_display_status,
|
||||
.display_message=linphone_gtk_display_message,
|
||||
.display_warning=linphone_gtk_display_warning,
|
||||
.display_url=linphone_gtk_display_url,
|
||||
.display_question=linphone_gtk_display_question,
|
||||
.call_log_updated=linphone_gtk_call_log_updated,
|
||||
.text_received=linphone_gtk_text_received,
|
||||
.general_state=linphone_gtk_general_state,
|
||||
.refer_received=linphone_gtk_refer_received,
|
||||
.buddy_info_updated=linphone_gtk_buddy_info_updated
|
||||
};
|
||||
|
||||
static gboolean verbose=0;
|
||||
static gboolean auto_answer = 0;
|
||||
|
|
@ -115,7 +95,7 @@ static GOptionEntry linphone_options[]={
|
|||
.description = N_("if set automatically answer incoming calls")
|
||||
},
|
||||
#ifdef WIN32
|
||||
{ /* zsd addition */
|
||||
{
|
||||
.long_name = "workdir",
|
||||
.short_name = '\0',
|
||||
.arg = G_OPTION_ARG_STRING,
|
||||
|
|
@ -127,7 +107,7 @@ static GOptionEntry linphone_options[]={
|
|||
};
|
||||
|
||||
#define INSTALLED_XML_DIR PACKAGE_DATA_DIR "/linphone"
|
||||
#define BUILD_TREE_XML_DIR "gtk-glade"
|
||||
#define BUILD_TREE_XML_DIR "gtk"
|
||||
|
||||
#ifndef WIN32
|
||||
#define CONFIG_FILE ".linphonerc"
|
||||
|
|
@ -211,6 +191,23 @@ static const char *linphone_gtk_get_factory_config_file(){
|
|||
|
||||
static void linphone_gtk_init_liblinphone(const char *config_file,
|
||||
const char *factory_config_file) {
|
||||
LinphoneCoreVTable vtable={0};
|
||||
|
||||
vtable.call_state_changed=linphone_gtk_call_state_changed;
|
||||
vtable.registration_state_changed=linphone_gtk_registration_state_changed;
|
||||
vtable.show=linphone_gtk_show;
|
||||
vtable.notify_presence_recv=linphone_gtk_notify_recv;
|
||||
vtable.new_subscription_request=linphone_gtk_new_unknown_subscriber;
|
||||
vtable.auth_info_requested=linphone_gtk_auth_info_requested;
|
||||
vtable.display_status=linphone_gtk_display_status;
|
||||
vtable.display_message=linphone_gtk_display_message;
|
||||
vtable.display_warning=linphone_gtk_display_warning;
|
||||
vtable.display_url=linphone_gtk_display_url;
|
||||
vtable.call_log_updated=linphone_gtk_call_log_updated;
|
||||
vtable.text_received=linphone_gtk_text_received;
|
||||
vtable.refer_received=linphone_gtk_refer_received;
|
||||
vtable.buddy_info_updated=linphone_gtk_buddy_info_updated;
|
||||
|
||||
linphone_core_set_user_agent("Linphone", LINPHONE_VERSION);
|
||||
the_core=linphone_core_new(&vtable,config_file,factory_config_file,NULL);
|
||||
linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL);
|
||||
|
|
@ -283,12 +280,78 @@ GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){
|
|||
|
||||
#else
|
||||
|
||||
static int get_ui_file(const char *name, char *path, int pathsize){
|
||||
snprintf(path,pathsize,"%s/%s.ui",BUILD_TREE_XML_DIR,name);
|
||||
if (access(path,F_OK)!=0){
|
||||
snprintf(path,pathsize,"%s/%s.ui",INSTALLED_XML_DIR,name);
|
||||
if (access(path,F_OK)!=0){
|
||||
g_error("Could not locate neither %s/%s.ui and %s/%s.ui .",BUILD_TREE_XML_DIR,name,
|
||||
INSTALLED_XML_DIR,name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
GtkWidget *linphone_gtk_create_window(const char *window_name){
|
||||
GError* error = NULL;
|
||||
GtkBuilder* builder = gtk_builder_new ();
|
||||
char path[512];
|
||||
GtkWidget *w;
|
||||
|
||||
if (get_ui_file(window_name,path,sizeof(path))==-1) return NULL;
|
||||
|
||||
if (!gtk_builder_add_from_file (builder, path, &error)){
|
||||
g_error("Couldn't load builder file: %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
w=GTK_WIDGET(gtk_builder_get_object (builder,window_name));
|
||||
if (w==NULL){
|
||||
g_error("Could not retrieve '%s' window from xml file",window_name);
|
||||
return NULL;
|
||||
}
|
||||
g_object_set_data(G_OBJECT(w),"builder",builder);
|
||||
gtk_builder_connect_signals(builder,w);
|
||||
linphone_gtk_configure_window(w,window_name);
|
||||
return w;
|
||||
}
|
||||
|
||||
GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_name){
|
||||
char path[2048];
|
||||
GtkWidget *w;
|
||||
GtkBuilder* builder = gtk_builder_new ();
|
||||
GError *error=NULL;
|
||||
gchar *object_ids[2];
|
||||
object_ids[0]=g_strdup(widget_name);
|
||||
object_ids[1]=NULL;
|
||||
|
||||
if (get_ui_file(filename,path,sizeof(path))==-1) return NULL;
|
||||
if (!gtk_builder_add_objects_from_file(builder,path,object_ids,&error)){
|
||||
g_error("Couldn't load %s from builder file %s: %s", widget_name,path,error->message);
|
||||
g_error_free (error);
|
||||
g_free(object_ids[0]);
|
||||
return NULL;
|
||||
}
|
||||
g_free(object_ids[0]);
|
||||
w=GTK_WIDGET(gtk_builder_get_object (builder,widget_name));
|
||||
if (w==NULL){
|
||||
g_error("Could not retrieve '%s' window from xml file",widget_name);
|
||||
return NULL;
|
||||
}
|
||||
g_object_set_data(G_OBJECT(w),"builder",builder);
|
||||
gtk_builder_connect_signals(builder,w);
|
||||
return w;
|
||||
}
|
||||
|
||||
GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){
|
||||
GObject *w=gtk_builder_get_object(the_ui,name);
|
||||
GtkBuilder *builder=(GtkBuilder*)g_object_get_data(G_OBJECT(window),"builder");
|
||||
GObject *w;
|
||||
if (builder==NULL){
|
||||
g_error("Fail to retrieve builder from window !");
|
||||
return NULL;
|
||||
}
|
||||
w=gtk_builder_get_object(builder,name);
|
||||
if (w==NULL){
|
||||
g_error("No widget named %s found in xml interface.",name);
|
||||
}
|
||||
|
|
@ -352,8 +415,10 @@ void linphone_gtk_show_about(){
|
|||
struct stat filestat;
|
||||
const char *license_file=PACKAGE_DATA_DIR "/linphone/COPYING";
|
||||
GtkWidget *about;
|
||||
const char *tmp;
|
||||
GdkPixbuf *logo=create_pixbuf(
|
||||
linphone_gtk_get_ui_config("logo","linphone-banner.png"));
|
||||
static const char *defcfg="defcfg";
|
||||
|
||||
about=linphone_gtk_create_window("about");
|
||||
gtk_about_dialog_set_url_hook(about_url_clicked,NULL,NULL);
|
||||
|
|
@ -375,7 +440,19 @@ void linphone_gtk_show_about(){
|
|||
gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about),linphone_gtk_get_ui_config("title","Linphone"));
|
||||
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),linphone_gtk_get_ui_config("home","http://www.linphone.org"));
|
||||
if (logo) gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about),logo);
|
||||
|
||||
tmp=linphone_gtk_get_ui_config("artists",defcfg);
|
||||
if (tmp!=defcfg){
|
||||
const char *tmp2[2];
|
||||
tmp2[0]=tmp;
|
||||
tmp2[1]=NULL;
|
||||
gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(about),tmp2);
|
||||
}
|
||||
tmp=linphone_gtk_get_ui_config("translators",defcfg);
|
||||
if (tmp!=defcfg)
|
||||
gtk_about_dialog_set_translator_credits (GTK_ABOUT_DIALOG(about),tmp);
|
||||
tmp=linphone_gtk_get_ui_config("comments",defcfg);
|
||||
if (tmp!=defcfg)
|
||||
gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about),tmp);
|
||||
gtk_widget_show(about);
|
||||
}
|
||||
|
||||
|
|
@ -390,7 +467,7 @@ static void set_video_window_decorations(GdkWindow *w){
|
|||
gdk_window_set_keep_above(w, FALSE);
|
||||
}else{
|
||||
LinphoneAddress *uri =
|
||||
linphone_address_clone(linphone_core_get_remote_uri(linphone_gtk_get_core()));
|
||||
linphone_address_clone(linphone_core_get_current_call_remote_address(linphone_gtk_get_core()));
|
||||
char *display_name;
|
||||
|
||||
linphone_address_clean(uri);
|
||||
|
|
@ -435,6 +512,7 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){
|
|||
static gboolean first_time=TRUE;
|
||||
unsigned long id;
|
||||
static unsigned long previd=0;
|
||||
static unsigned long preview_previd=0;
|
||||
static gboolean in_iterate=FALSE;
|
||||
|
||||
/*avoid reentrancy*/
|
||||
|
|
@ -457,6 +535,25 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){
|
|||
w=gdk_window_foreign_new(id);
|
||||
#else
|
||||
w=gdk_window_foreign_new((HANDLE)id);
|
||||
#endif
|
||||
if (w) {
|
||||
set_video_window_decorations(w);
|
||||
g_object_unref(G_OBJECT(w));
|
||||
}
|
||||
else ms_error("gdk_window_foreign_new() failed");
|
||||
if (video_needs_update) video_needs_update=FALSE;
|
||||
}
|
||||
}
|
||||
id=linphone_core_get_native_preview_window_id (lc);
|
||||
if (id!=preview_previd ){
|
||||
GdkWindow *w;
|
||||
preview_previd=id;
|
||||
if (id!=0){
|
||||
ms_message("Updating window decorations for preview");
|
||||
#ifndef WIN32
|
||||
w=gdk_window_foreign_new(id);
|
||||
#else
|
||||
w=gdk_window_foreign_new((HANDLE)id);
|
||||
#endif
|
||||
if (w) {
|
||||
set_video_window_decorations(w);
|
||||
|
|
@ -553,88 +650,119 @@ static void completion_add_text(GtkEntry *entry, const char *text){
|
|||
save_uri_history();
|
||||
}
|
||||
|
||||
void linphone_gtk_call_terminated(const char *error){
|
||||
void linphone_gtk_call_terminated(LinphoneCall *call, const char *error){
|
||||
GtkWidget *mw=linphone_gtk_get_main_window();
|
||||
GtkWidget *icw;
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),FALSE);
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),TRUE);
|
||||
linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(mw,"main_mute")),FALSE);
|
||||
if (linphone_gtk_use_in_call_view())
|
||||
linphone_gtk_in_call_view_terminate(error);
|
||||
|
||||
if (linphone_gtk_use_in_call_view() && call)
|
||||
linphone_gtk_in_call_view_terminate(call,error);
|
||||
update_video_title();
|
||||
icw=GTK_WIDGET(g_object_get_data(G_OBJECT(mw),"incoming_call"));
|
||||
if (icw!=NULL){
|
||||
g_object_set_data(G_OBJECT(mw),"incoming_call",NULL);
|
||||
gtk_widget_destroy(icw);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean in_call_timer(){
|
||||
if (linphone_core_in_call(linphone_gtk_get_core())){
|
||||
linphone_gtk_in_call_view_update_duration(
|
||||
linphone_core_get_current_call_duration(linphone_gtk_get_core()));
|
||||
LinphoneCall *call=linphone_core_get_current_call(linphone_gtk_get_core());
|
||||
if (call){
|
||||
linphone_gtk_in_call_view_update_duration(call);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void linphone_gtk_call_started(GtkWidget *mw){
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),FALSE);
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),TRUE);
|
||||
static bool_t all_other_calls_paused(LinphoneCall *refcall, const MSList *calls){
|
||||
for(;calls!=NULL;calls=calls->next){
|
||||
LinphoneCall *call=(LinphoneCall*)calls->data;
|
||||
LinphoneCallState cs=linphone_call_get_state(call);
|
||||
if (refcall!=call){
|
||||
if (cs!=LinphoneCallPaused && cs!=LinphoneCallPausing)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void linphone_gtk_update_call_buttons(LinphoneCall *call){
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
GtkWidget *mw=linphone_gtk_get_main_window();
|
||||
const MSList *calls=linphone_core_get_calls(lc);
|
||||
GtkWidget *button;
|
||||
bool_t start_active=TRUE;
|
||||
bool_t stop_active=FALSE;
|
||||
bool_t add_call=FALSE;
|
||||
|
||||
if (calls==NULL){
|
||||
start_active=TRUE;
|
||||
stop_active=FALSE;
|
||||
}else{
|
||||
stop_active=TRUE;
|
||||
if (all_other_calls_paused(NULL,calls)){
|
||||
start_active=TRUE;
|
||||
add_call=TRUE;
|
||||
}else if (call!=NULL && linphone_call_get_state(call)==LinphoneCallIncomingReceived && all_other_calls_paused(call,calls)){
|
||||
if (ms_list_size(calls)>1){
|
||||
start_active=TRUE;
|
||||
add_call=TRUE;
|
||||
}else{
|
||||
start_active=TRUE;
|
||||
add_call=FALSE;
|
||||
}
|
||||
}else{
|
||||
start_active=FALSE;
|
||||
}
|
||||
}
|
||||
button=linphone_gtk_get_widget(mw,"start_call");
|
||||
gtk_widget_set_sensitive(button,start_active);
|
||||
gtk_widget_set_visible(button,!add_call);
|
||||
|
||||
button=linphone_gtk_get_widget(mw,"add_call");
|
||||
gtk_widget_set_sensitive(button,start_active);
|
||||
gtk_widget_set_visible(button,add_call);
|
||||
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),stop_active);
|
||||
if (linphone_core_get_calls(lc)==NULL){
|
||||
linphone_gtk_enable_mute_button(
|
||||
GTK_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")),
|
||||
FALSE);
|
||||
}
|
||||
update_video_title();
|
||||
if (linphone_gtk_use_in_call_view())
|
||||
g_timeout_add(250,(GSourceFunc)in_call_timer,NULL);
|
||||
}
|
||||
|
||||
static gboolean linphone_gtk_start_call_do(GtkWidget *uri_bar){
|
||||
const char *entered=gtk_entry_get_text(GTK_ENTRY(uri_bar));
|
||||
if (linphone_core_invite(linphone_gtk_get_core(),entered)==0) {
|
||||
if (linphone_core_invite(linphone_gtk_get_core(),entered)!=NULL) {
|
||||
completion_add_text(GTK_ENTRY(uri_bar),entered);
|
||||
}else{
|
||||
linphone_gtk_call_terminated(NULL);
|
||||
linphone_gtk_call_terminated(NULL,NULL);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void _linphone_gtk_accept_call(){
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
GtkWidget *mw=linphone_gtk_get_main_window();
|
||||
GtkWidget *icw=GTK_WIDGET(g_object_get_data(G_OBJECT(mw),"incoming_call"));
|
||||
if (icw!=NULL){
|
||||
g_object_set_data(G_OBJECT(mw),"incoming_call",NULL);
|
||||
gtk_widget_destroy(icw);
|
||||
static gboolean linphone_gtk_auto_answer(LinphoneCall *call){
|
||||
if (linphone_call_get_state(call)==LinphoneCallIncomingReceived){
|
||||
linphone_core_accept_call (linphone_gtk_get_core(),call);
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
|
||||
linphone_core_accept_call(lc,NULL);
|
||||
linphone_gtk_call_started(linphone_gtk_get_main_window());
|
||||
if (linphone_gtk_use_in_call_view()){
|
||||
linphone_gtk_in_call_view_set_in_call();
|
||||
linphone_gtk_show_in_call_view();
|
||||
}
|
||||
linphone_gtk_enable_mute_button(
|
||||
GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute"))
|
||||
,TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void linphone_gtk_start_call(GtkWidget *w){
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
if (linphone_core_inc_invite_pending(lc)){
|
||||
/*accept the call*/
|
||||
_linphone_gtk_accept_call();
|
||||
}else if (linphone_core_in_call(lc)) {
|
||||
/*already in call */
|
||||
LinphoneCall *call;
|
||||
/*change into in-call mode, then do the work later as it might block a bit */
|
||||
GtkWidget *mw=gtk_widget_get_toplevel(w);
|
||||
GtkWidget *uri_bar=linphone_gtk_get_widget(mw,"uribar");
|
||||
|
||||
call=linphone_gtk_get_currently_displayed_call ();
|
||||
if (call!=NULL && linphone_call_get_state(call)==LinphoneCallIncomingReceived){
|
||||
linphone_core_accept_call(lc,call);
|
||||
}else{
|
||||
/*change into in-call mode, then do the work later as it might block a bit */
|
||||
GtkWidget *mw=gtk_widget_get_toplevel(w);
|
||||
GtkWidget *uri_bar=linphone_gtk_get_widget(mw,"uribar");
|
||||
const char *entered=gtk_entry_get_text(GTK_ENTRY(uri_bar));
|
||||
linphone_gtk_call_started(mw);
|
||||
if (linphone_gtk_use_in_call_view()){
|
||||
linphone_gtk_in_call_view_set_calling(entered);
|
||||
linphone_gtk_show_in_call_view();
|
||||
}
|
||||
/*immediately disable the button and delay a bit the execution the linphone_core_invite()
|
||||
so that we don't freeze the button. linphone_core_invite() might block for some hundreds of milliseconds*/
|
||||
gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),FALSE);
|
||||
g_timeout_add(100,(GSourceFunc)linphone_gtk_start_call_do,uri_bar);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void linphone_gtk_uri_bar_activate(GtkWidget *w){
|
||||
|
|
@ -643,21 +771,23 @@ void linphone_gtk_uri_bar_activate(GtkWidget *w){
|
|||
|
||||
|
||||
void linphone_gtk_terminate_call(GtkWidget *button){
|
||||
linphone_core_terminate_call(linphone_gtk_get_core(),NULL);
|
||||
LinphoneCall *call=linphone_gtk_get_currently_displayed_call ();
|
||||
if (call)
|
||||
linphone_core_terminate_call(linphone_gtk_get_core(),call);
|
||||
}
|
||||
|
||||
void linphone_gtk_decline_call(GtkWidget *button){
|
||||
linphone_core_terminate_call(linphone_gtk_get_core(),NULL);
|
||||
gtk_widget_destroy(gtk_widget_get_toplevel(button));
|
||||
void linphone_gtk_decline_clicked(GtkWidget *button){
|
||||
LinphoneCall *call=linphone_gtk_get_currently_displayed_call ();
|
||||
if (call)
|
||||
linphone_core_terminate_call(linphone_gtk_get_core(),call);
|
||||
}
|
||||
|
||||
void linphone_gtk_accept_call(GtkWidget *button){
|
||||
_linphone_gtk_accept_call();
|
||||
}
|
||||
|
||||
static gboolean linphone_gtk_auto_answer(GtkWidget *incall_window){
|
||||
linphone_gtk_accept_call(linphone_gtk_get_widget(incall_window,"accept_call"));
|
||||
return FALSE;
|
||||
void linphone_gtk_answer_clicked(GtkWidget *button){
|
||||
LinphoneCall *call=linphone_gtk_get_currently_displayed_call ();
|
||||
if (call){
|
||||
linphone_core_pause_all_calls(linphone_gtk_get_core());
|
||||
linphone_core_accept_call(linphone_gtk_get_core(),call);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_set_audio_video(){
|
||||
|
|
@ -704,35 +834,6 @@ static void linphone_gtk_show(LinphoneCore *lc){
|
|||
linphone_gtk_show_main_window();
|
||||
}
|
||||
|
||||
static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from){
|
||||
GtkWidget *w=linphone_gtk_create_window("incoming_call");
|
||||
GtkWidget *label;
|
||||
gchar *msg;
|
||||
|
||||
if (auto_answer){
|
||||
g_timeout_add(2000,(GSourceFunc)linphone_gtk_auto_answer,w);
|
||||
}
|
||||
|
||||
gtk_window_set_transient_for(GTK_WINDOW(w),GTK_WINDOW(linphone_gtk_get_main_window()));
|
||||
gtk_window_set_position(GTK_WINDOW(w),GTK_WIN_POS_CENTER_ON_PARENT);
|
||||
|
||||
label=linphone_gtk_get_widget(w,"message");
|
||||
msg=g_strdup_printf(_("Incoming call from %s"),from);
|
||||
gtk_label_set_text(GTK_LABEL(label),msg);
|
||||
gtk_window_set_title(GTK_WINDOW(w),msg);
|
||||
gtk_widget_show(w);
|
||||
gtk_window_present(GTK_WINDOW(w));
|
||||
/*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/
|
||||
g_free(msg);
|
||||
g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call",w);
|
||||
gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")),
|
||||
from);
|
||||
}
|
||||
|
||||
static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from){
|
||||
|
||||
}
|
||||
|
||||
static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid){
|
||||
linphone_gtk_show_friends();
|
||||
}
|
||||
|
|
@ -868,36 +969,75 @@ static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const ch
|
|||
linphone_gtk_display_something(GTK_MESSAGE_INFO,richtext);
|
||||
}
|
||||
|
||||
static void linphone_gtk_display_question(LinphoneCore *lc, const char *question){
|
||||
linphone_gtk_display_something(GTK_MESSAGE_QUESTION,question);
|
||||
}
|
||||
|
||||
static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl){
|
||||
GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"call_logs");
|
||||
if (w) linphone_gtk_call_log_update(w);
|
||||
}
|
||||
|
||||
static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate){
|
||||
switch(gstate->new_state){
|
||||
case GSTATE_CALL_OUT_CONNECTED:
|
||||
case GSTATE_CALL_IN_CONNECTED:
|
||||
if (linphone_gtk_use_in_call_view())
|
||||
linphone_gtk_in_call_view_set_in_call();
|
||||
static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg){
|
||||
switch(cs){
|
||||
case LinphoneCallOutgoingInit:
|
||||
linphone_gtk_create_in_call_view (call);
|
||||
break;
|
||||
case LinphoneCallOutgoingProgress:
|
||||
linphone_gtk_in_call_view_set_calling (call);
|
||||
break;
|
||||
case LinphoneCallStreamsRunning:
|
||||
linphone_gtk_in_call_view_set_in_call(call);
|
||||
linphone_gtk_enable_mute_button(
|
||||
GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")),
|
||||
GTK_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")),
|
||||
TRUE);
|
||||
g_timeout_add(250,(GSourceFunc)in_call_timer,NULL);
|
||||
break;
|
||||
case GSTATE_CALL_ERROR:
|
||||
linphone_gtk_call_terminated(gstate->message);
|
||||
case LinphoneCallError:
|
||||
linphone_gtk_in_call_view_terminate (call,msg);
|
||||
break;
|
||||
case GSTATE_CALL_END:
|
||||
linphone_gtk_call_terminated(NULL);
|
||||
case LinphoneCallEnd:
|
||||
linphone_gtk_in_call_view_terminate(call,NULL);
|
||||
break;
|
||||
case LinphoneCallIncomingReceived:
|
||||
linphone_gtk_create_in_call_view (call);
|
||||
linphone_gtk_in_call_view_set_incoming(call,!all_other_calls_paused (call,linphone_core_get_calls(lc)));
|
||||
if (auto_answer) {
|
||||
linphone_call_ref(call);
|
||||
g_timeout_add(2000,(GSourceFunc)linphone_gtk_auto_answer ,call);
|
||||
}
|
||||
break;
|
||||
case LinphoneCallResuming:
|
||||
linphone_gtk_enable_hold_button(call,TRUE,TRUE);
|
||||
linphone_gtk_in_call_view_set_in_call (call);
|
||||
break;
|
||||
case LinphoneCallPausing:
|
||||
linphone_gtk_enable_hold_button(call,TRUE,FALSE);
|
||||
case LinphoneCallPausedByRemote:
|
||||
linphone_gtk_in_call_view_set_paused(call);
|
||||
break;
|
||||
case LinphoneCallConnected:
|
||||
linphone_gtk_enable_hold_button (call,TRUE,TRUE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
linphone_gtk_update_call_buttons (call);
|
||||
}
|
||||
|
||||
static void linphone_gtk_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg,
|
||||
LinphoneRegistrationState rs, const char *msg){
|
||||
switch (rs){
|
||||
case LinphoneRegistrationOk:
|
||||
if (cfg){
|
||||
SipSetup *ss=linphone_proxy_config_get_sip_setup(cfg);
|
||||
if (ss && (sip_setup_get_capabilities(ss) & SIP_SETUP_CAP_LOGIN)){
|
||||
linphone_gtk_exit_login_frame();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void icon_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data){
|
||||
GtkWidget *menu=(GtkWidget*)g_object_get_data(G_OBJECT(status_icon),"menu");
|
||||
gtk_menu_popup(GTK_MENU(menu),NULL,NULL,gtk_status_icon_position_menu,status_icon,button,activate_time);
|
||||
|
|
@ -1001,24 +1141,29 @@ void linphone_gtk_load_identities(void){
|
|||
gtk_combo_box_set_active(box,def_index);
|
||||
}
|
||||
|
||||
static void linphone_gtk_dtmf_clicked(GtkButton *button){
|
||||
static void linphone_gtk_dtmf_pressed(GtkButton *button){
|
||||
const char *label=gtk_button_get_label(button);
|
||||
GtkWidget *uri_bar=linphone_gtk_get_widget(gtk_widget_get_toplevel(GTK_WIDGET(button)),"uribar");
|
||||
int pos=-1;
|
||||
gtk_editable_insert_text(GTK_EDITABLE(uri_bar),label,1,&pos);
|
||||
linphone_core_play_dtmf (linphone_gtk_get_core(),label[0],-1);
|
||||
if (linphone_core_in_call(linphone_gtk_get_core())){
|
||||
linphone_core_send_dtmf(linphone_gtk_get_core(),label[0]);
|
||||
}else{
|
||||
GtkWidget *uri_bar=linphone_gtk_get_widget(gtk_widget_get_toplevel(GTK_WIDGET(button)),"uribar");
|
||||
int pos=-1;
|
||||
gtk_editable_insert_text(GTK_EDITABLE(uri_bar),label,1,&pos);
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_gtk_dtmf_released(GtkButton *button){
|
||||
linphone_core_stop_dtmf (linphone_gtk_get_core());
|
||||
}
|
||||
|
||||
static void linphone_gtk_connect_digits(void){
|
||||
GtkContainer *cont=GTK_CONTAINER(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"dtmf_table"));
|
||||
GList *children=gtk_container_get_children(cont);
|
||||
GList *elem;
|
||||
for(elem=children;elem!=NULL;elem=elem->next){
|
||||
GtkButton *button=GTK_BUTTON(elem->data);
|
||||
g_signal_connect(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_dtmf_clicked,NULL);
|
||||
g_signal_connect(G_OBJECT(button),"pressed",(GCallback)linphone_gtk_dtmf_pressed,NULL);
|
||||
g_signal_connect(G_OBJECT(button),"released",(GCallback)linphone_gtk_dtmf_released,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1049,19 +1194,23 @@ static void linphone_gtk_configure_main_window(){
|
|||
static const char *title;
|
||||
static const char *home;
|
||||
static const char *start_call_icon;
|
||||
static const char *add_call_icon;
|
||||
static const char *stop_call_icon;
|
||||
static const char *search_icon;
|
||||
static gboolean update_check_menu;
|
||||
static gboolean buttons_have_borders;
|
||||
static gboolean show_abcd;
|
||||
GtkWidget *w=linphone_gtk_get_main_window();
|
||||
if (!config_loaded){
|
||||
title=linphone_gtk_get_ui_config("title","Linphone");
|
||||
home=linphone_gtk_get_ui_config("home","http://www.linphone.org");
|
||||
start_call_icon=linphone_gtk_get_ui_config("start_call_icon","startcall-green.png");
|
||||
add_call_icon=linphone_gtk_get_ui_config("add_call_icon","addcall-green.png");
|
||||
stop_call_icon=linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png");
|
||||
search_icon=linphone_gtk_get_ui_config("directory_search_icon",NULL);
|
||||
update_check_menu=linphone_gtk_get_ui_config_int("update_check_menu",0);
|
||||
buttons_have_borders=linphone_gtk_get_ui_config_int("buttons_border",1);
|
||||
show_abcd=linphone_gtk_get_ui_config_int("show_abcd",1);
|
||||
config_loaded=TRUE;
|
||||
}
|
||||
linphone_gtk_configure_window(w,"main_window");
|
||||
|
|
@ -1072,18 +1221,22 @@ static void linphone_gtk_configure_main_window(){
|
|||
#endif
|
||||
}
|
||||
if (start_call_icon){
|
||||
GdkPixbuf *pbuf=create_pixbuf(start_call_icon);
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(linphone_gtk_get_widget(w,"start_call_icon")),pbuf);
|
||||
if (buttons_have_borders)
|
||||
gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"start_call")),GTK_RELIEF_NORMAL);
|
||||
g_object_unref(G_OBJECT(pbuf));
|
||||
gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"start_call")),
|
||||
create_pixmap (start_call_icon));
|
||||
if (!buttons_have_borders)
|
||||
gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"start_call")),GTK_RELIEF_NONE);
|
||||
}
|
||||
if (add_call_icon){
|
||||
gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"add_call")),
|
||||
create_pixmap (add_call_icon));
|
||||
if (!buttons_have_borders)
|
||||
gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"add_call")),GTK_RELIEF_NONE);
|
||||
}
|
||||
if (stop_call_icon){
|
||||
GdkPixbuf *pbuf=create_pixbuf(stop_call_icon);
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(linphone_gtk_get_widget(w,"terminate_call_icon")),pbuf);
|
||||
if (buttons_have_borders)
|
||||
gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"terminate_call")),GTK_RELIEF_NORMAL);
|
||||
g_object_unref(G_OBJECT(pbuf));
|
||||
gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"terminate_call")),
|
||||
create_pixmap (stop_call_icon));
|
||||
if (!buttons_have_borders)
|
||||
gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"terminate_call")),GTK_RELIEF_NONE);
|
||||
}
|
||||
if (search_icon){
|
||||
GdkPixbuf *pbuf=create_pixbuf(search_icon);
|
||||
|
|
@ -1110,10 +1263,17 @@ static void linphone_gtk_configure_main_window(){
|
|||
g_object_unref(G_OBJECT(pbuf));
|
||||
}
|
||||
}
|
||||
if (!linphone_gtk_can_manage_accounts())
|
||||
gtk_widget_hide(linphone_gtk_get_widget(w,"run_assistant"));
|
||||
if (linphone_gtk_can_manage_accounts())
|
||||
gtk_widget_show(linphone_gtk_get_widget(w,"assistant_item"));
|
||||
if (update_check_menu){
|
||||
gtk_widget_show(linphone_gtk_get_widget(w,"versioncheck"));
|
||||
gtk_widget_show(linphone_gtk_get_widget(w,"versioncheck_item"));
|
||||
}
|
||||
if (!show_abcd){
|
||||
gtk_widget_hide(linphone_gtk_get_widget(w,"dtmf_A"));
|
||||
gtk_widget_hide(linphone_gtk_get_widget(w,"dtmf_B"));
|
||||
gtk_widget_hide(linphone_gtk_get_widget(w,"dtmf_C"));
|
||||
gtk_widget_hide(linphone_gtk_get_widget(w,"dtmf_D"));
|
||||
gtk_table_resize(GTK_TABLE(linphone_gtk_get_widget(w,"dtmf_table")),4,3);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1129,6 +1289,18 @@ void linphone_gtk_manage_login(void){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
gboolean linphone_gtk_close(GtkWidget *mw){
|
||||
/*shutdown calls if any*/
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
if (linphone_core_in_call(lc)){
|
||||
linphone_core_terminate_all_calls(lc);
|
||||
}
|
||||
linphone_core_enable_video_preview(lc,FALSE);
|
||||
gtk_widget_hide(mw);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void linphone_gtk_init_main_window(){
|
||||
GtkWidget *main_window;
|
||||
|
||||
|
|
@ -1141,36 +1313,23 @@ static void linphone_gtk_init_main_window(){
|
|||
linphone_gtk_connect_digits();
|
||||
linphone_gtk_check_menu_items();
|
||||
main_window=linphone_gtk_get_main_window();
|
||||
linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(main_window,
|
||||
linphone_gtk_enable_mute_button(GTK_BUTTON(linphone_gtk_get_widget(main_window,
|
||||
"main_mute")),FALSE);
|
||||
linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(main_window,
|
||||
"incall_mute")),FALSE);
|
||||
if (!linphone_gtk_use_in_call_view()) {
|
||||
gtk_widget_show(linphone_gtk_get_widget(main_window, "main_mute"));
|
||||
}
|
||||
if (linphone_core_in_call(linphone_gtk_get_core())) linphone_gtk_call_started(
|
||||
linphone_gtk_get_main_window());/*hide the call button, show terminate button*/
|
||||
linphone_gtk_update_call_buttons (NULL);
|
||||
/*prevent the main window from being destroyed by a user click on WM controls, instead we hide it*/
|
||||
g_signal_connect (G_OBJECT (main_window), "delete-event",
|
||||
G_CALLBACK (linphone_gtk_close), main_window);
|
||||
}
|
||||
|
||||
void linphone_gtk_close(){
|
||||
/* couldn't find a way to prevent closing to destroy the main window*/
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
the_ui=NULL;
|
||||
the_ui=linphone_gtk_create_window("main");
|
||||
linphone_gtk_init_main_window();
|
||||
/*shutdown call if any*/
|
||||
if (linphone_core_in_call(lc)){
|
||||
linphone_core_terminate_call(lc,NULL);
|
||||
linphone_gtk_call_terminated(NULL);
|
||||
}
|
||||
linphone_core_enable_video_preview(lc,FALSE);
|
||||
}
|
||||
|
||||
void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){
|
||||
if (verbose){
|
||||
const char *lname="undef";
|
||||
char *msg;
|
||||
#ifdef __linux
|
||||
#if defined(__linux) || defined(__APPLE__)
|
||||
va_list cap;/*copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)*/
|
||||
#endif
|
||||
switch(lev){
|
||||
|
|
@ -1192,7 +1351,7 @@ void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){
|
|||
default:
|
||||
g_error("Bad level !");
|
||||
}
|
||||
#ifdef __linux
|
||||
#if defined(__linux) || defined(__APPLE__)
|
||||
va_copy(cap,args);
|
||||
msg=g_strdup_vprintf(fmt,cap);
|
||||
va_end(cap);
|
||||
|
|
@ -1284,6 +1443,7 @@ int main(int argc, char *argv[]){
|
|||
}
|
||||
|
||||
settings=gtk_settings_get_default();
|
||||
g_type_class_unref (g_type_class_ref (GTK_TYPE_IMAGE_MENU_ITEM));
|
||||
g_object_set(settings, "gtk-menu-images", TRUE, NULL);
|
||||
g_object_set(settings, "gtk-button-images", TRUE, NULL);
|
||||
#ifdef WIN32
|
||||
|
|
@ -1308,9 +1468,7 @@ int main(int argc, char *argv[]){
|
|||
add_pixmap_directory(PACKAGE_DATA_DIR "/pixmaps/linphone");
|
||||
|
||||
|
||||
g_set_application_name("Linphone");
|
||||
pbuf=create_pixbuf(linphone_gtk_get_ui_config("icon",LINPHONE_ICON));
|
||||
if (pbuf!=NULL) gtk_window_set_default_icon(pbuf);
|
||||
|
||||
|
||||
the_ui=linphone_gtk_create_window("main");
|
||||
|
||||
|
|
@ -1318,6 +1476,11 @@ int main(int argc, char *argv[]){
|
|||
linphone_core_enable_logs_with_cb(linphone_gtk_log_handler);
|
||||
|
||||
linphone_gtk_init_liblinphone(config_file, factory_config_file);
|
||||
|
||||
g_set_application_name(linphone_gtk_get_ui_config("title","Linphone"));
|
||||
pbuf=create_pixbuf(linphone_gtk_get_ui_config("icon",LINPHONE_ICON));
|
||||
if (pbuf!=NULL) gtk_window_set_default_icon(pbuf);
|
||||
|
||||
/* do not lower timeouts under 30 ms because it exhibits a bug on gtk+/win32, with cpu running 20% all the time...*/
|
||||
gtk_timeout_add(30,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core());
|
||||
gtk_timeout_add(30,(GtkFunction)linphone_gtk_check_logs,(gpointer)NULL);
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,13 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<?xml version="1.0"?>
|
||||
<!--Generated with glade3 3.4.5 on Sun Mar 29 21:17:24 2009 -->
|
||||
<glade-interface>
|
||||
<widget class="GtkAssistant" id="p2pwizard">
|
||||
<interface>
|
||||
<object class="GtkAssistant" id="p2pwizard">
|
||||
<property name="title" translatable="yes">Creating a FONICS account</property>
|
||||
<signal name="apply" handler="linphone_gtk_fonis_wizard_apply"/>
|
||||
<signal name="prepare" handler="linphone_gtk_fonis_wizard_prepare"/>
|
||||
<signal handler="linphone_gtk_fonis_wizard_apply" name="apply"/>
|
||||
<signal handler="linphone_gtk_fonis_wizard_prepare" name="prepare"/>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Welcome !
|
||||
This wizard will help you to setup a SIP account.
|
||||
|
|
@ -16,119 +15,115 @@ This wizard will help you to setup a SIP account.
|
|||
<property name="justify">GTK_JUSTIFY_CENTER</property>
|
||||
<property name="wrap">True</property>
|
||||
<property name="selectable">True</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="page_type">GTK_ASSISTANT_PAGE_INTRO</property>
|
||||
<property name="title">Introduction</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox1">
|
||||
<object class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label2">
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Please choose a username:</property>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame1">
|
||||
<object class="GtkFrame" id="frame1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment1">
|
||||
<object class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox2">
|
||||
<object class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<object class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="username">
|
||||
<object class="GtkEntry" id="username">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button1">
|
||||
<object class="GtkButton" id="button1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="linphone_gtk_fonis_wizard_check_username_clicked"/>
|
||||
<signal handler="linphone_gtk_fonis_wizard_check_username_clicked" name="clicked"/>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox2">
|
||||
<object class="GtkHBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1">
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-apply</property>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label5">
|
||||
<object class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Check availability</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="check_result">
|
||||
<object class="GtkLabel" id="check_result">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label4">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="title">Create your account !</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label3">
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Done ! Your account is now created and ready to use.</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="page_type">GTK_ASSISTANT_PAGE_CONFIRM</property>
|
||||
<property name="title">Finished !</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
</object>
|
||||
</interface>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 2.16 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkDialog" id="password">
|
||||
<object class="GtkDialog" id="password">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Linphone - Authentication required</property>
|
||||
|
|
@ -12,68 +12,68 @@
|
|||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox9">
|
||||
<object class="GtkVBox" id="dialog-vbox9">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox12">
|
||||
<object class="GtkVBox" id="vbox12">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="message">
|
||||
<object class="GtkLabel" id="message">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Please enter the domain password</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="wrap">True</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table1">
|
||||
<object class="GtkTable" id="table1">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">2</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="userid_label">
|
||||
<object class="GtkLabel" id="userid_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">UserID</property>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="userid_entry">
|
||||
<object class="GtkEntry" id="userid_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Password:</property>
|
||||
<property name="justify">right</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="password_entry">
|
||||
<object class="GtkEntry" id="password_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<signal name="activate" handler="linphone_gtk_password_ok"/>
|
||||
</widget>
|
||||
<signal handler="linphone_gtk_password_ok" name="activate"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
|
|
@ -81,31 +81,31 @@
|
|||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area8">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area8">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button8">
|
||||
<object class="GtkButton" id="button8">
|
||||
<property name="label" translatable="yes">gtk-ok</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="linphone_gtk_password_ok"/>
|
||||
</widget>
|
||||
<signal handler="linphone_gtk_password_ok" name="clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
|
|
@ -113,29 +113,29 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button9">
|
||||
<object class="GtkButton" id="button9">
|
||||
<property name="label" translatable="yes">gtk-cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="linphone_gtk_password_cancel"/>
|
||||
</widget>
|
||||
<signal handler="linphone_gtk_password_cancel" name="clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -102,9 +102,22 @@ void linphone_gtk_ipv6_toggled(GtkWidget *w){
|
|||
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)));
|
||||
}
|
||||
|
||||
void linphone_gtk_sip_port_changed(GtkWidget *w){
|
||||
linphone_core_set_sip_port(linphone_gtk_get_core(),
|
||||
(gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)));
|
||||
void linphone_gtk_udp_sip_port_changed(GtkWidget *w){
|
||||
LCSipTransports tr;
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
|
||||
linphone_core_get_sip_transports(lc,&tr);
|
||||
tr.udp_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
|
||||
linphone_core_set_sip_transports(lc,&tr);
|
||||
}
|
||||
|
||||
void linphone_gtk_tcp_sip_port_changed(GtkWidget *w){
|
||||
LCSipTransports tr;
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
|
||||
linphone_core_get_sip_transports(lc,&tr);
|
||||
tr.tcp_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w));
|
||||
linphone_core_set_sip_transports(lc,&tr);
|
||||
}
|
||||
|
||||
void linphone_gtk_audio_port_changed(GtkWidget *w){
|
||||
|
|
@ -119,17 +132,17 @@ void linphone_gtk_video_port_changed(GtkWidget *w){
|
|||
|
||||
void linphone_gtk_no_firewall_toggled(GtkWidget *w){
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
|
||||
linphone_core_set_firewall_policy(linphone_gtk_get_core(),LINPHONE_POLICY_NO_FIREWALL);
|
||||
linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyNoFirewall);
|
||||
}
|
||||
|
||||
void linphone_gtk_use_nat_address_toggled(GtkWidget *w){
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
|
||||
linphone_core_set_firewall_policy(linphone_gtk_get_core(),LINPHONE_POLICY_USE_NAT_ADDRESS);
|
||||
linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyUseNatAddress);
|
||||
}
|
||||
|
||||
void linphone_gtk_use_stun_toggled(GtkWidget *w){
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
|
||||
linphone_core_set_firewall_policy(linphone_gtk_get_core(),LINPHONE_POLICY_USE_STUN);
|
||||
linphone_core_set_firewall_policy(linphone_gtk_get_core(),LinphonePolicyUseStun);
|
||||
}
|
||||
|
||||
void linphone_gtk_mtu_changed(GtkWidget *w){
|
||||
|
|
@ -746,12 +759,16 @@ void linphone_gtk_show_parameters(void){
|
|||
GtkWidget *codec_list=linphone_gtk_get_widget(pb,"codec_list");
|
||||
int mtu;
|
||||
int ui_advanced;
|
||||
LCSipTransports tr;
|
||||
|
||||
/* NETWORK CONFIG */
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ipv6_enabled")),
|
||||
linphone_core_ipv6_enabled(lc));
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"sip_port")),
|
||||
linphone_core_get_sip_port(lc));
|
||||
linphone_core_get_sip_transports(lc,&tr);
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"udp_sip_port")),
|
||||
tr.udp_port);
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"tcp_sip_port")),
|
||||
tr.tcp_port);
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"audio_rtp_port")),
|
||||
linphone_core_get_audio_port(lc));
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"video_rtp_port")),
|
||||
|
|
@ -762,13 +779,13 @@ void linphone_gtk_show_parameters(void){
|
|||
if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"stun_server")),tmp);
|
||||
pol=linphone_core_get_firewall_policy(lc);
|
||||
switch(pol){
|
||||
case LINPHONE_POLICY_NO_FIREWALL:
|
||||
case LinphonePolicyNoFirewall:
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"no_nat")),TRUE);
|
||||
break;
|
||||
case LINPHONE_POLICY_USE_NAT_ADDRESS:
|
||||
case LinphonePolicyUseNatAddress:
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_nat_address")),TRUE);
|
||||
break;
|
||||
case LINPHONE_POLICY_USE_STUN:
|
||||
case LinphonePolicyUseStun:
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"use_stun")),TRUE);
|
||||
break;
|
||||
}
|
||||
|
|
@ -813,11 +830,13 @@ void linphone_gtk_show_parameters(void){
|
|||
linphone_gtk_show_sip_accounts(pb);
|
||||
/* CODECS CONFIG */
|
||||
linphone_gtk_init_codec_list(GTK_TREE_VIEW(codec_list));
|
||||
linphone_gtk_draw_codec_list(GTK_TREE_VIEW(codec_list),0);
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"codec_view")),0);
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"download_bw")),
|
||||
linphone_core_get_download_bandwidth(lc));
|
||||
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"upload_bw")),
|
||||
linphone_core_get_upload_bandwidth(lc));
|
||||
|
||||
|
||||
/* UI CONFIG */
|
||||
linphone_gtk_fill_langs(pb);
|
||||
|
|
@ -1,8 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<interface>
|
||||
<object class="GtkAdjustment" id="adjustment1">
|
||||
<property name="upper">100000</property>
|
||||
<property name="lower">0</property>
|
||||
<property name="page_increment">10</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_size">10</property>
|
||||
<property name="value">3600</property>
|
||||
</object>
|
||||
<!-- interface-requires gtk+ 2.6 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkDialog" id="sip_account">
|
||||
<object class="GtkDialog" id="sip_account">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Linphone - Configure a SIP account</property>
|
||||
|
|
@ -11,74 +19,74 @@
|
|||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox2">
|
||||
<object class="GtkVBox" id="dialog-vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame15">
|
||||
<object class="GtkFrame" id="frame15">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment15">
|
||||
<object class="GtkAlignment" id="alignment15">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox11">
|
||||
<object class="GtkVBox" id="vbox11">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table6">
|
||||
<object class="GtkTable" id="table6">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="n_rows">4</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label38">
|
||||
<object class="GtkLabel" id="label38">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Your SIP identity:</property>
|
||||
<property name="justify">right</property>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="identity">
|
||||
<object class="GtkEntry" id="identity">
|
||||
<property name="width_request">275</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Looks like sip:<username>@<domain></property>
|
||||
<property name="tooltip-text" translatable="yes">Looks like sip:<username>@<domain></property>
|
||||
<property name="text" translatable="yes">sip:</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label39">
|
||||
<object class="GtkLabel" id="label39">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">SIP Proxy address:</property>
|
||||
<property name="justify">right</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="proxy">
|
||||
<object class="GtkEntry" id="proxy">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Looks like sip:<proxy hostname></property>
|
||||
<property name="tooltip-text" translatable="yes">Looks like sip:<proxy hostname></property>
|
||||
<property name="text" translatable="yes">sip:</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
|
|
@ -87,23 +95,23 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label40">
|
||||
<object class="GtkLabel" id="label40">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Route (optional):</property>
|
||||
<property name="justify">right</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="route">
|
||||
<object class="GtkEntry" id="route">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
|
|
@ -112,24 +120,24 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label41">
|
||||
<object class="GtkLabel" id="label41">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Registration duration (sec):</property>
|
||||
<property name="justify">right</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="regperiod">
|
||||
<object class="GtkSpinButton" id="regperiod">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="adjustment">3600 0 100000 1 10 10</property>
|
||||
</widget>
|
||||
<property name="adjustment">adjustment1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
|
|
@ -137,73 +145,70 @@
|
|||
<property name="bottom_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="register">
|
||||
<object class="GtkCheckButton" id="register">
|
||||
<property name="label" translatable="yes">Register at startup</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="publish">
|
||||
<object class="GtkCheckButton" id="publish">
|
||||
<property name="label" translatable="yes">Publish presence information</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label42">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label42">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Configure a SIP account</property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area2">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button6">
|
||||
<object class="GtkButton" id="button6">
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="linphone_gtk_proxy_ok"/>
|
||||
</widget>
|
||||
<signal handler="linphone_gtk_proxy_ok" name="clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
|
|
@ -211,29 +216,29 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button7">
|
||||
<object class="GtkButton" id="button7">
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="linphone_gtk_proxy_cancel"/>
|
||||
</widget>
|
||||
<signal handler="linphone_gtk_proxy_cancel" name="clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
</object>
|
||||
</interface>
|
||||
|
Before Width: | Height: | Size: 764 B After Width: | Height: | Size: 764 B |
|
|
@ -177,7 +177,7 @@ const gchar *linphone_gtk_get_ui_config(const char *key, const char *def){
|
|||
LpConfig *cfg=linphone_core_get_config(linphone_gtk_get_core());
|
||||
return lp_config_get_string(cfg,"GtkUi",key,def);
|
||||
}else{
|
||||
ms_warning ("Cannot read config, no core created yet.");
|
||||
g_error ("Cannot read config, no core created yet.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -192,6 +192,10 @@ void linphone_gtk_set_ui_config_int(const char *key , int val){
|
|||
lp_config_set_int(cfg,"GtkUi",key,val);
|
||||
}
|
||||
|
||||
void linphone_gtk_set_ui_config(const char *key , const char * val){
|
||||
LpConfig *cfg=linphone_core_get_config(linphone_gtk_get_core());
|
||||
lp_config_set_string(cfg,"GtkUi",key,val);
|
||||
}
|
||||
|
||||
static void parse_item(const char *item, const char *window_name, GtkWidget *w, gboolean show){
|
||||
char tmp[64];
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<?xml version="1.0"?>
|
||||
<!--Generated with glade3 3.4.5 on Sun Mar 29 15:33:09 2009 -->
|
||||
<glade-interface>
|
||||
<widget class="GtkWindow" id="waiting">
|
||||
<interface>
|
||||
<object class="GtkWindow" id="waiting">
|
||||
<property name="title" translatable="yes">Linphone</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
|
|
@ -10,52 +9,49 @@
|
|||
<property name="icon">linphone2.png</property>
|
||||
<property name="deletable">False</property>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame1">
|
||||
<object class="GtkFrame" id="frame1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment1">
|
||||
<object class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<object class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1">
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-dialog-info</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkProgressBar" id="progressbar">
|
||||
<object class="GtkProgressBar" id="progressbar">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Please wait</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">GTK_JUSTIFY_CENTER</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</object>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -17,7 +17,16 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core;
|
||||
|
||||
/**
|
||||
* Object that represents a SIP address.
|
||||
* The LinphoneAddress is an opaque object to represents SIP addresses, ie the content of SIP's 'from' and 'to' headers.
|
||||
* A SIP address is made of display name, username, domain name, port, and various uri headers (such as tags).
|
||||
* It looks like 'Alice <sip:alice@example.net>'. The LinphoneAddress has methods to extract and manipulate all parts of the address.
|
||||
* When some part of the address (for example the username) is empty, the accessor methods return null.
|
||||
* <br> Can be instanciated using both {@link LinphoneCoreFactory#createLinphoneAddress(String, String, String)} or {@link LinphoneCoreFactory#createLinphoneAddress(String)}
|
||||
* @author jehanmonnier
|
||||
*
|
||||
*/
|
||||
public interface LinphoneAddress {
|
||||
/**
|
||||
* Human display name
|
||||
|
|
@ -58,6 +67,9 @@ public interface LinphoneAddress {
|
|||
*/
|
||||
public String asStringUriOnly();
|
||||
|
||||
/*must return the same thing as asString()*/
|
||||
/**
|
||||
* same as {@link #asString()}
|
||||
*
|
||||
* */
|
||||
public String toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,13 +17,51 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core;
|
||||
|
||||
/**
|
||||
* Object holding authentication information.
|
||||
* In most case, authentication information consists of a username and password. Sometimes, a userid is required by proxy, and realm can be useful to discriminate different SIP domains.
|
||||
*<br>This object is instanciated using {@link LinphoneCoreFactory#createAuthInfo(String, String, String)}.
|
||||
*<br>
|
||||
*Once created and filled, a LinphoneAuthInfo must be added to the LinphoneCore in order to become known and used automatically when needed.
|
||||
*Use {@link LinphoneCore#addAuthInfo(LinphoneAuthInfo)} for that purpose.
|
||||
*<br>
|
||||
*The LinphoneCore object can take the initiative to request authentication information when needed to the application
|
||||
*through the {@link LinphoneCoreListener#authInfoRequested(LinphoneCore, String, String)} listener.
|
||||
*<br>
|
||||
*The application can respond to this information request later using {@link LinphoneCore#addAuthInfo(LinphoneAuthInfo)}.
|
||||
*This will unblock all pending authentication transactions and retry them with authentication headers.
|
||||
*
|
||||
*/
|
||||
public interface LinphoneAuthInfo {
|
||||
/**
|
||||
* get user name
|
||||
* @return username
|
||||
*/
|
||||
String getUsername();
|
||||
String getPassword();
|
||||
String getRealm();
|
||||
/**
|
||||
* Sets the username.
|
||||
* @param username
|
||||
*/
|
||||
void setUsername(String username);
|
||||
/**
|
||||
* get password
|
||||
* @return password
|
||||
*/
|
||||
String getPassword();
|
||||
/**
|
||||
* sets password
|
||||
* @param password
|
||||
*/
|
||||
void setPassword(String password);
|
||||
/**
|
||||
* get realm
|
||||
* @return
|
||||
*/
|
||||
String getRealm();
|
||||
/**
|
||||
* set realm
|
||||
* @param realm
|
||||
*/
|
||||
void setRealm(String realm);
|
||||
}
|
||||
|
||||
|
|
|
|||
158
java/common/org/linphone/core/LinphoneCall.java
Normal file
158
java/common/org/linphone/core/LinphoneCall.java
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
LinphoneCall.java
|
||||
Copyright (C) 2010 Belledonne Communications, Grenoble, France
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Object representing a Call. calls are created using {@link LinphoneCore#invite(LinphoneAddress)} or paased to the application by listener {@link LinphoneCoreListener#callState(LinphoneCore, LinphoneCall, State, String)}
|
||||
*
|
||||
*/
|
||||
public interface LinphoneCall {
|
||||
/**
|
||||
* Linphone call states
|
||||
*
|
||||
*/
|
||||
static class State {
|
||||
static private Vector values = new Vector();
|
||||
private final int mValue;
|
||||
private final String mStringValue;
|
||||
/**
|
||||
* Idle
|
||||
*/
|
||||
public final static State Idle = new State(0,"Idle");
|
||||
/**
|
||||
* Incoming call received.
|
||||
*/
|
||||
public final static State IncomingReceived = new State(1,"IncomingReceived");
|
||||
/**
|
||||
* Outgoing call initialiazed.
|
||||
*/
|
||||
public final static State OutgoingInit = new State(2,"OutgoingInit");
|
||||
/**
|
||||
* Outgoing call in progress.
|
||||
*/
|
||||
public final static State OutgoingProgress = new State(3,"OutgoingProgress");
|
||||
/**
|
||||
* Outgoing call ringing.
|
||||
*/
|
||||
public final static State OutgoingRinging = new State(4,"OutgoingRinging");
|
||||
/**
|
||||
* Outgoing call early media
|
||||
*/
|
||||
public final static State OutgoingEarlyMedia = new State(5,"OutgoingEarlyMedia");
|
||||
/**
|
||||
* Connected
|
||||
*/
|
||||
public final static State Connected = new State(6,"Connected");
|
||||
/**
|
||||
* Streams running
|
||||
*/
|
||||
public final static State StreamsRunning = new State(7,"StreamsRunning");
|
||||
/**
|
||||
* Paussing
|
||||
*/
|
||||
public final static State Pausing = new State(8,"Pausing");
|
||||
/**
|
||||
* Paused
|
||||
*/
|
||||
public final static State Paused = new State(9,"Paused");
|
||||
/**
|
||||
* Resuming
|
||||
*/
|
||||
public final static State Resuming = new State(10,"Resuming");
|
||||
/**
|
||||
* Refered
|
||||
*/
|
||||
public final static State Refered = new State(11,"Refered");
|
||||
/**
|
||||
* Error
|
||||
*/
|
||||
public final static State Error = new State(12,"Error");
|
||||
/**
|
||||
* Call end
|
||||
*/
|
||||
public final static State CallEnd = new State(13,"CallEnd");
|
||||
|
||||
/**
|
||||
* Paused by remote
|
||||
*/
|
||||
public final static State PausedByRemote = new State(14,"PausedByRemote");
|
||||
|
||||
/**
|
||||
* The call's parameters are updated, used for example when video is asked by remote
|
||||
*/
|
||||
public static final State CallUpdatedByRemote = new State(15, "CallUpdatedByRemote");
|
||||
|
||||
/**
|
||||
* We are proposing early media to an incoming call
|
||||
*/
|
||||
public static final State CallIncomingEarlyMedia = new State(16,"CallIncomingEarlyMedia");
|
||||
|
||||
/**
|
||||
* The remote accepted the call update initiated by us
|
||||
*/
|
||||
public static final State CallUpdated = new State(17, "CallUpdated");
|
||||
|
||||
|
||||
private State(int value,String stringValue) {
|
||||
mValue = value;
|
||||
values.addElement(this);
|
||||
mStringValue=stringValue;
|
||||
}
|
||||
public static State fromInt(int value) {
|
||||
|
||||
for (int i=0; i<values.size();i++) {
|
||||
State state = (State) values.elementAt(i);
|
||||
if (state.mValue == value) return state;
|
||||
}
|
||||
throw new RuntimeException("state not found ["+value+"]");
|
||||
}
|
||||
public String toString() {
|
||||
return mStringValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the call's current state.
|
||||
**/
|
||||
public State getState();
|
||||
|
||||
/**
|
||||
* Returns the remote address associated to this call
|
||||
*
|
||||
**/
|
||||
public LinphoneAddress getRemoteAddress();
|
||||
/**
|
||||
* get direction of the call (incoming or outgoing).
|
||||
* @return CallDirection
|
||||
*/
|
||||
public CallDirection getDirection();
|
||||
/**
|
||||
* get the call log associated to this call.
|
||||
* @Return LinphoneCallLog
|
||||
**/
|
||||
public LinphoneCallLog getCallLog();
|
||||
|
||||
/**
|
||||
* @return parameters for this call; read only, call copy() to get a read/write version.
|
||||
*/
|
||||
public LinphoneCallParams getCurrentParamsReadOnly();
|
||||
|
||||
}
|
||||
|
|
@ -17,13 +17,78 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core;
|
||||
/**
|
||||
* Call data records object
|
||||
*
|
||||
*/
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
|
||||
public interface LinphoneCallLog {
|
||||
/**
|
||||
* Represents call status
|
||||
*
|
||||
*/
|
||||
static class CallStatus {
|
||||
static private Vector values = new Vector();
|
||||
private final int mValue;
|
||||
private final String mStringValue;
|
||||
/**
|
||||
* Call success.
|
||||
*/
|
||||
public final static CallStatus Sucess = new CallStatus(0,"Sucess");
|
||||
/**
|
||||
* Call aborted.
|
||||
*/
|
||||
public final static CallStatus Aborted = new CallStatus(1,"Aborted");
|
||||
/**
|
||||
* missed incoming call.
|
||||
*/
|
||||
public final static CallStatus Missed = new CallStatus(2,"Missed");
|
||||
/**
|
||||
* remote call declined.
|
||||
*/
|
||||
public final static CallStatus Declined = new CallStatus(3,"Declined");
|
||||
private CallStatus(int value,String stringValue) {
|
||||
mValue = value;
|
||||
values.addElement(this);
|
||||
mStringValue=stringValue;
|
||||
}
|
||||
public static CallStatus fromInt(int value) {
|
||||
|
||||
for (int i=0; i<values.size();i++) {
|
||||
CallStatus state = (CallStatus) values.elementAt(i);
|
||||
if (state.mValue == value) return state;
|
||||
}
|
||||
throw new RuntimeException("CallStatus not found ["+value+"]");
|
||||
}
|
||||
public String toString() {
|
||||
return mStringValue;
|
||||
}
|
||||
public int toInt() {
|
||||
return mValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Originator of the call as a LinphoneAddress object.
|
||||
* @return LinphoneAddress
|
||||
*/
|
||||
public LinphoneAddress getFrom();
|
||||
|
||||
/**
|
||||
* Destination of the call as a LinphoneAddress object.
|
||||
* @return
|
||||
*/
|
||||
public LinphoneAddress getTo ();
|
||||
|
||||
/**
|
||||
* The direction of the call
|
||||
* @return CallDirection
|
||||
*/
|
||||
public CallDirection getDirection();
|
||||
/**
|
||||
* get status of this call
|
||||
* @return
|
||||
*/
|
||||
public CallStatus getStatus();
|
||||
}
|
||||
|
|
|
|||
32
java/common/org/linphone/core/LinphoneCallParams.java
Normal file
32
java/common/org/linphone/core/LinphoneCallParams.java
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
LinphoneCallParameters.java
|
||||
Copyright (C) 2010 Belledonne Communications, Grenoble, France
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core;
|
||||
|
||||
/**
|
||||
* The LinphoneCallParams is an object containing various call related parameters.
|
||||
* It can be used to retrieve parameters from a currently running call or modify the call's characteristics
|
||||
* dynamically.
|
||||
* @author Guillaume Beraudo
|
||||
*
|
||||
*/
|
||||
public interface LinphoneCallParams {
|
||||
void setVideoEnabled(boolean b);
|
||||
boolean getVideoEnabled();
|
||||
LinphoneCallParams copy();
|
||||
}
|
||||
39
java/common/org/linphone/core/LinphoneChatRoom.java
Normal file
39
java/common/org/linphone/core/LinphoneChatRoom.java
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
LinphoneChatRoom.java
|
||||
Copyright (C) 2010 Belledonne Communications, Grenoble, France
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package org.linphone.core;
|
||||
/**
|
||||
*
|
||||
* A chat room is the place where text messages are exchanged.
|
||||
Can be created by linphone_core_create_chat_room().
|
||||
*
|
||||
*/
|
||||
public interface LinphoneChatRoom {
|
||||
/**
|
||||
* get peer address associated to this LinphoneChatRoom
|
||||
*
|
||||
* @return LinphoneAddress peer address
|
||||
*/
|
||||
LinphoneAddress getPeerAddress();
|
||||
/**
|
||||
* send a message to peer member of this chat room.
|
||||
* @param message to be sent
|
||||
*/
|
||||
void sendMessage(String message);
|
||||
|
||||
}
|
||||
|
|
@ -21,48 +21,45 @@ package org.linphone.core;
|
|||
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Linphone core main object created by method {@link LinphoneCoreFactory#createLinphoneCore(LinphoneCoreListener, String, String, Object)}.
|
||||
*
|
||||
*/
|
||||
public interface LinphoneCore {
|
||||
/*
|
||||
/**
|
||||
* linphone core states
|
||||
*/
|
||||
static public class GeneralState {
|
||||
static public class GlobalState {
|
||||
static private Vector values = new Vector();
|
||||
/* states for GSTATE_GROUP_POWER */
|
||||
static public GeneralState GSTATE_POWER_OFF = new GeneralState(0,"GSTATE_POWER_OFF"); /* initial state */
|
||||
static public GeneralState GSTATE_POWER_STARTUP = new GeneralState(1,"GSTATE_POWER_STARTUP");
|
||||
static public GeneralState GSTATE_POWER_ON = new GeneralState(2,"GSTATE_POWER_ON");
|
||||
static public GeneralState GSTATE_POWER_SHUTDOWN = new GeneralState(3,"GSTATE_POWER_SHUTDOWN");
|
||||
/* states for GSTATE_GROUP_REG */
|
||||
static public GeneralState GSTATE_REG_NONE = new GeneralState(10,"GSTATE_REG_NONE"); /* initial state */
|
||||
static public GeneralState GSTATE_REG_OK = new GeneralState(11,"GSTATE_REG_OK");
|
||||
static public GeneralState GSTATE_REG_FAILED = new GeneralState(12,"GSTATE_REG_FAILED");
|
||||
static public GeneralState GSTATE_REG_PENDING = new GeneralState(13,"GSTATE_REG_PENDING");
|
||||
/* states for GSTATE_GROUP_CALL */
|
||||
static public GeneralState GSTATE_CALL_IDLE = new GeneralState(20,"GSTATE_CALL_IDLE"); /* initial state */
|
||||
static public GeneralState GSTATE_CALL_OUT_INVITE = new GeneralState(21,"GSTATE_CALL_OUT_INVITE");
|
||||
static public GeneralState GSTATE_CALL_OUT_CONNECTED = new GeneralState(22,"GSTATE_CALL_OUT_CONNECTED");
|
||||
static public GeneralState GSTATE_CALL_IN_INVITE = new GeneralState(23,"GSTATE_CALL_IN_INVITE");
|
||||
static public GeneralState GSTATE_CALL_IN_CONNECTED = new GeneralState(24,"GSTATE_CALL_IN_CONNECTED");
|
||||
static public GeneralState GSTATE_CALL_END = new GeneralState(25,"GSTATE_CALL_END");
|
||||
static public GeneralState GSTATE_CALL_ERROR = new GeneralState(26,"GSTATE_CALL_ERROR");
|
||||
static public GeneralState GSTATE_INVALID = new GeneralState(27,"GSTATE_INVALID");
|
||||
static public GeneralState GSTATE_CALL_OUT_RINGING = new GeneralState(28,"GSTATE_CALL_OUT_RINGING");
|
||||
/**
|
||||
* Off
|
||||
*/
|
||||
static public GlobalState GlobalOff = new GlobalState(0,"GlobalOff");
|
||||
/**
|
||||
* Startup
|
||||
*/
|
||||
static public GlobalState GlobalStartup = new GlobalState(1,"GlobalStartup");
|
||||
/**
|
||||
* On
|
||||
*/
|
||||
static public GlobalState GlobalOn = new GlobalState(2,"GlobalOn");
|
||||
/**
|
||||
* Shutdown
|
||||
*/
|
||||
static public GlobalState GlobalShutdown = new GlobalState(3,"GlobalShutdown");
|
||||
|
||||
private final int mValue;
|
||||
private final String mStringValue;
|
||||
|
||||
private GeneralState(int value,String stringValue) {
|
||||
private GlobalState(int value,String stringValue) {
|
||||
mValue = value;
|
||||
values.addElement(this);
|
||||
mStringValue=stringValue;
|
||||
}
|
||||
public static GeneralState fromInt(int value) {
|
||||
public static GlobalState fromInt(int value) {
|
||||
|
||||
for (int i=0; i<values.size();i++) {
|
||||
GeneralState state = (GeneralState) values.elementAt(i);
|
||||
GlobalState state = (GlobalState) values.elementAt(i);
|
||||
if (state.mValue == value) return state;
|
||||
}
|
||||
throw new RuntimeException("state not found ["+value+"]");
|
||||
|
|
@ -71,9 +68,106 @@ public interface LinphoneCore {
|
|||
return mStringValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Describes proxy registration states.
|
||||
*
|
||||
*/
|
||||
static public class RegistrationState {
|
||||
static private Vector values = new Vector();
|
||||
/**
|
||||
* None
|
||||
*/
|
||||
static public RegistrationState RegistrationNone = new RegistrationState(0,"RegistrationNone");
|
||||
/**
|
||||
* In Progress
|
||||
*/
|
||||
static public RegistrationState RegistrationProgress = new RegistrationState(1,"RegistrationProgress");
|
||||
/**
|
||||
* Ok
|
||||
*/
|
||||
static public RegistrationState RegistrationOk = new RegistrationState(2,"RegistrationOk");
|
||||
/**
|
||||
* Cleared
|
||||
*/
|
||||
static public RegistrationState RegistrationCleared = new RegistrationState(3,"RegistrationCleared");
|
||||
/**
|
||||
* Failed
|
||||
*/
|
||||
static public RegistrationState RegistrationFailed = new RegistrationState(4,"RegistrationFailed");
|
||||
private final int mValue;
|
||||
private final String mStringValue;
|
||||
|
||||
private RegistrationState(int value,String stringValue) {
|
||||
mValue = value;
|
||||
values.addElement(this);
|
||||
mStringValue=stringValue;
|
||||
}
|
||||
public static RegistrationState fromInt(int value) {
|
||||
|
||||
for (int i=0; i<values.size();i++) {
|
||||
RegistrationState state = (RegistrationState) values.elementAt(i);
|
||||
if (state.mValue == value) return state;
|
||||
}
|
||||
throw new RuntimeException("state not found ["+value+"]");
|
||||
}
|
||||
public String toString() {
|
||||
return mStringValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Describes firewall policy.
|
||||
*
|
||||
*/
|
||||
static public class FirewallPolicy {
|
||||
static private Vector values = new Vector();
|
||||
/**
|
||||
* No firewall is assumed.
|
||||
*/
|
||||
static public FirewallPolicy NoFirewall = new FirewallPolicy(0,"NoFirewall");
|
||||
/**
|
||||
* Use NAT address (discouraged)
|
||||
*/
|
||||
static public FirewallPolicy UseNatAddress = new FirewallPolicy(1,"UseNatAddress");
|
||||
/**
|
||||
* Use stun server to discover RTP addresses and ports.
|
||||
*/
|
||||
static public FirewallPolicy UseStun = new FirewallPolicy(2,"UseStun");
|
||||
|
||||
private final int mValue;
|
||||
private final String mStringValue;
|
||||
|
||||
private FirewallPolicy(int value,String stringValue) {
|
||||
mValue = value;
|
||||
values.addElement(this);
|
||||
mStringValue=stringValue;
|
||||
}
|
||||
public static FirewallPolicy fromInt(int value) {
|
||||
|
||||
for (int i=0; i<values.size();i++) {
|
||||
FirewallPolicy state = (FirewallPolicy) values.elementAt(i);
|
||||
if (state.mValue == value) return state;
|
||||
}
|
||||
throw new RuntimeException("state not found ["+value+"]");
|
||||
}
|
||||
public String toString() {
|
||||
return mStringValue;
|
||||
}
|
||||
public int value(){
|
||||
return mValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Signaling transports
|
||||
*
|
||||
*/
|
||||
static public class Transport {
|
||||
/**
|
||||
* UDP transport
|
||||
*/
|
||||
public final static Transport udp =new Transport("udp");
|
||||
/**
|
||||
* TCP transport
|
||||
*/
|
||||
public final static Transport tcp =new Transport("tcp");
|
||||
private final String mStringValue;
|
||||
|
||||
|
|
@ -85,15 +179,26 @@ public interface LinphoneCore {
|
|||
}
|
||||
}
|
||||
/**
|
||||
* clear all added proxy config
|
||||
* clear all added proxy configs
|
||||
*/
|
||||
public void clearProxyConfigs();
|
||||
|
||||
/**
|
||||
* Add a proxy configuration. This will start registration on the proxy, if registration is enabled.
|
||||
* @param proxyCfg
|
||||
* @throws LinphoneCoreException
|
||||
*/
|
||||
public void addProxyConfig(LinphoneProxyConfig proxyCfg) throws LinphoneCoreException;
|
||||
|
||||
/**
|
||||
* Sets the default proxy.
|
||||
*<br>
|
||||
* This default proxy must be part of the list of already entered {@link LinphoneProxyConfig}.
|
||||
* Toggling it as default will make LinphoneCore use the identity associated with the proxy configuration in all incoming and outgoing calls.
|
||||
* @param proxyCfg
|
||||
*/
|
||||
public void setDefaultProxyConfig(LinphoneProxyConfig proxyCfg);
|
||||
|
||||
/**
|
||||
* get he default proxy configuration, that is the one used to determine the current identity.
|
||||
* @return null if no default proxy config
|
||||
*/
|
||||
public LinphoneProxyConfig getDefaultProxyConfig() ;
|
||||
|
|
@ -102,7 +207,11 @@ public interface LinphoneCore {
|
|||
* clear all the added auth info
|
||||
*/
|
||||
void clearAuthInfos();
|
||||
|
||||
/**
|
||||
* Adds authentication information to the LinphoneCore.
|
||||
* <br>This information will be used during all SIP transacations that require authentication.
|
||||
* @param info
|
||||
*/
|
||||
void addAuthInfo(LinphoneAuthInfo info);
|
||||
|
||||
/**
|
||||
|
|
@ -114,16 +223,31 @@ public interface LinphoneCore {
|
|||
public LinphoneAddress interpretUrl(String destination) throws LinphoneCoreException;
|
||||
|
||||
/**
|
||||
* Starts a call given a destination. Internally calls interpretUrl() then invite(LinphoneAddress).
|
||||
* Starts a call given a destination. Internally calls {@link #interpretUrl(String)} then {@link #invite(LinphoneAddress)}.
|
||||
* @param uri
|
||||
*/
|
||||
public void invite(String destination)throws LinphoneCoreException;
|
||||
|
||||
public void invite(LinphoneAddress to)throws LinphoneCoreException;
|
||||
|
||||
public void terminateCall();
|
||||
public LinphoneCall invite(String destination)throws LinphoneCoreException;
|
||||
/**
|
||||
* get the remote address in case of in/out call
|
||||
* Initiates an outgoing call given a destination LinphoneAddress
|
||||
*<br>The LinphoneAddress can be constructed directly using linphone_address_new(), or created by linphone_core_interpret_url(). The application doesn't own a reference to the returned LinphoneCall object. Use linphone_call_ref() to safely keep the LinphoneCall pointer valid within your application.
|
||||
* @param to the destination of the call (sip address).
|
||||
* @return LinphoneCall
|
||||
* @throws LinphoneCoreException
|
||||
*/
|
||||
public LinphoneCall invite(LinphoneAddress to)throws LinphoneCoreException;
|
||||
/**
|
||||
* Terminates a call.
|
||||
* @param aCall to be terminated
|
||||
*/
|
||||
public void terminateCall(LinphoneCall aCall);
|
||||
/**
|
||||
* Returns The LinphoneCall the current call if one is in call
|
||||
*
|
||||
**/
|
||||
public LinphoneCall getCurrentCall();
|
||||
|
||||
/**
|
||||
* get current call remote address in case of in/out call
|
||||
* @return null if no call engaged yet
|
||||
*/
|
||||
public LinphoneAddress getRemoteAddress();
|
||||
|
|
@ -137,6 +261,17 @@ public interface LinphoneCore {
|
|||
* @return Returns true if in incoming call is pending, ie waiting for being answered or declined.
|
||||
*/
|
||||
public boolean isInComingInvitePending();
|
||||
/**
|
||||
* Main loop function. It is crucial that your application call it periodically.
|
||||
*
|
||||
* #iterate() performs various backgrounds tasks:
|
||||
* <li>receiving of SIP messages
|
||||
* <li> handles timers and timeout
|
||||
* <li> performs registration to proxies
|
||||
* <li> authentication retries The application MUST call this function from periodically, in its main loop.
|
||||
* <br> Be careful that this function must be call from the same thread as other liblinphone methods. In not the case make sure all liblinphone calls are serialized with a mutex.
|
||||
|
||||
*/
|
||||
public void iterate();
|
||||
/**
|
||||
* Accept an incoming call.
|
||||
|
|
@ -147,7 +282,7 @@ public interface LinphoneCore {
|
|||
* this method.
|
||||
* @throws LinphoneCoreException
|
||||
*/
|
||||
public void acceptCall() throws LinphoneCoreException;
|
||||
public void acceptCall(LinphoneCall aCall) throws LinphoneCoreException;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -211,24 +346,143 @@ public interface LinphoneCore {
|
|||
*/
|
||||
public void sendDtmf(char number);
|
||||
/**
|
||||
*
|
||||
* Initiate a dtmf signal to the speqker if not in call
|
||||
* @param number
|
||||
* @param duration in ms , -1 for unlimited
|
||||
*/
|
||||
public void playDtmf(char number,int duration);
|
||||
/**
|
||||
* stop current dtmf
|
||||
*/
|
||||
public void stopDtmf();
|
||||
|
||||
/**
|
||||
* remove all call logs
|
||||
*/
|
||||
public void clearCallLogs();
|
||||
|
||||
|
||||
/***
|
||||
* get payload type from mime type an clock rate
|
||||
*
|
||||
* return null if not found
|
||||
*/
|
||||
public PayloadType findPayloadType(String mime,int clockRate);
|
||||
|
||||
/**
|
||||
* not implemented yet
|
||||
* @param pt
|
||||
* @param enable
|
||||
* @throws LinphoneCoreException
|
||||
*/
|
||||
public void enablePayloadType(PayloadType pt, boolean enable) throws LinphoneCoreException;
|
||||
|
||||
/**
|
||||
* Enables or disable echo cancellation.
|
||||
* @param enable
|
||||
*/
|
||||
public void enableEchoCancellation(boolean enable);
|
||||
|
||||
/**
|
||||
* get EC status
|
||||
* @return true if echo cancellation is enabled.
|
||||
*/
|
||||
public boolean isEchoCancellationEnabled();
|
||||
|
||||
/**
|
||||
* not implemented yet
|
||||
* @param aTransport
|
||||
*/
|
||||
public void setSignalingTransport(Transport aTransport);
|
||||
/**
|
||||
* not implemented
|
||||
* @param value
|
||||
*/
|
||||
public void enableSpeaker(boolean value);
|
||||
/**
|
||||
* not implemented
|
||||
* @return
|
||||
*/
|
||||
public boolean isSpeakerEnabled();
|
||||
/**
|
||||
* add a friend to the current buddy list, if subscription attribute is set, a SIP SUBSCRIBE message is sent.
|
||||
* @param lf LinphoenFriend to add
|
||||
* @throws LinphoneCoreException
|
||||
*/
|
||||
void addFriend(LinphoneFriend lf) throws LinphoneCoreException;
|
||||
|
||||
/**
|
||||
* Set my presence status
|
||||
* @param minute_away how long in away
|
||||
* @param status sip uri used to redirect call in state LinphoneStatusMoved
|
||||
*/
|
||||
void setPresenceInfo(int minute_away,String alternative_contact, OnlineStatus status);
|
||||
/**
|
||||
* Create a new chat room for messaging from a sip uri like sip:joe@sip.linphone.org
|
||||
* @param to destination address for messages
|
||||
*
|
||||
* @return {@link LinphoneChatRoom} where messaging can take place.
|
||||
*/
|
||||
LinphoneChatRoom createChatRoom(String to);
|
||||
|
||||
public void setVideoWindow(Object w);
|
||||
public void setPreviewWindow(Object w);
|
||||
/**
|
||||
* Enables video globally.
|
||||
*
|
||||
*
|
||||
* This function does not have any effect during calls. It just indicates #LinphoneCore to
|
||||
* initiate future calls with video or not. The two boolean parameters indicate in which
|
||||
* direction video is enabled. Setting both to false disables video entirely.
|
||||
*
|
||||
* @param vcap_enabled indicates whether video capture is enabled
|
||||
* @param display_enabled indicates whether video display should be shown
|
||||
*
|
||||
**/
|
||||
void enableVideo(boolean vcap_enabled, boolean display_enabled);
|
||||
/**
|
||||
* Returns TRUE if video is enabled, FALSE otherwise.
|
||||
*
|
||||
***/
|
||||
boolean isVideoEnabled();
|
||||
|
||||
/**
|
||||
* Specify a STUN server to help firewall traversal.
|
||||
* @param stun_server Stun server address and port, such as stun.linphone.org or stun.linphone.org:3478
|
||||
*/
|
||||
public void setStunServer(String stun_server);
|
||||
/**
|
||||
* @return stun server address if previously set.
|
||||
*/
|
||||
public String getStunServer();
|
||||
|
||||
/**
|
||||
* Sets policy regarding workarounding NATs
|
||||
* @param pol one of the FirewallPolicy members.
|
||||
**/
|
||||
public void setFirewallPolicy(FirewallPolicy pol);
|
||||
/**
|
||||
* @return previously set firewall policy.
|
||||
*/
|
||||
public FirewallPolicy getFirewallPolicy();
|
||||
|
||||
public LinphoneCall inviteAddressWithParams(LinphoneAddress destination, LinphoneCallParams params) throws LinphoneCoreException ;
|
||||
|
||||
public int updateCall(LinphoneCall call, LinphoneCallParams params);
|
||||
|
||||
public LinphoneCallParams createDefaultCallParameters();
|
||||
|
||||
/**
|
||||
* Sets the path to a wav file used for ringing.
|
||||
*
|
||||
* @param path The file must be a wav 16bit linear. Local ring is disabled if null
|
||||
*/
|
||||
public void setRing(String path);
|
||||
/**
|
||||
* gets the path to a wav file used for ringing.
|
||||
*
|
||||
* @param null if not set
|
||||
*/
|
||||
public String getRing();
|
||||
public void setUploadBandwidth(int bw);
|
||||
|
||||
public void setDownloadBandwidth(int bw);
|
||||
|
||||
public void setPreferredVideoSize(VideoSize vSize);
|
||||
|
||||
public VideoSize getPreferredVideoSize();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package org.linphone.core;
|
|||
|
||||
|
||||
|
||||
|
||||
abstract public class LinphoneCoreFactory {
|
||||
|
||||
private static String factoryName = "org.linphone.core.LinphoneCoreFactoryImpl";
|
||||
|
|
@ -49,9 +50,21 @@ abstract public class LinphoneCoreFactory {
|
|||
abstract public LinphoneAuthInfo createAuthInfo(String username,String password, String realm);
|
||||
|
||||
abstract public LinphoneCore createLinphoneCore(LinphoneCoreListener listener, String userConfig,String factoryConfig,Object userdata) throws LinphoneCoreException;
|
||||
|
||||
abstract public LinphoneCore createLinphoneCore(LinphoneCoreListener listener) throws LinphoneCoreException;
|
||||
|
||||
/**
|
||||
* Constructs a LinphoneAddress object
|
||||
* @param username
|
||||
* @param domain
|
||||
* @param displayName
|
||||
* @return
|
||||
*/
|
||||
abstract public LinphoneAddress createLinphoneAddress(String username,String domain,String displayName);
|
||||
|
||||
/**
|
||||
* Constructs a LinphoneAddress object by parsing the user supplied address, given as a string.
|
||||
* @param address should be like sip:joe@sip.linphone.org
|
||||
* @return
|
||||
*/
|
||||
abstract public LinphoneAddress createLinphoneAddress(String address);
|
||||
|
||||
abstract public LinphoneProxyConfig createProxyConfig(String identity, String proxy,String route,boolean enableRegister) throws LinphoneCoreException;
|
||||
|
|
@ -62,4 +75,17 @@ abstract public class LinphoneCoreFactory {
|
|||
abstract public void setDebugMode(boolean enable);
|
||||
|
||||
abstract public void setLogHandler(LinphoneLogHandler handler);
|
||||
/**
|
||||
* Create a LinphoneFriend, similar to {@link #createLinphoneFriend()} + {@link LinphoneFriend#setAddress(LinphoneAddress)}
|
||||
* @param friendUri a buddy address, must be a sip uri like sip:joe@sip.linphone.org
|
||||
* @return a new LinphoneFriend with address initialized
|
||||
*/
|
||||
abstract public LinphoneFriend createLinphoneFriend(String friendUri);
|
||||
/**
|
||||
* Create a new LinphoneFriend
|
||||
* @return
|
||||
*/
|
||||
abstract public LinphoneFriend createLinphoneFriend();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,18 +19,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
package org.linphone.core;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*This interface holds all callbacks that the application should implement. None is mandatory.
|
||||
*/
|
||||
public interface LinphoneCoreListener {
|
||||
|
||||
/**< Notifies the application that it should show up
|
||||
* @return */
|
||||
public void show(LinphoneCore lc);
|
||||
/**< Notifies incoming calls
|
||||
* @return */
|
||||
public void inviteReceived(LinphoneCore lc,String from);
|
||||
/**< Notify calls terminated by far end
|
||||
* @return */
|
||||
public void byeReceived(LinphoneCore lc,String from);
|
||||
/**< Ask the application some authentication information
|
||||
* @return */
|
||||
public void authInfoRequested(LinphoneCore lc,String realm,String username);
|
||||
|
|
@ -43,10 +40,43 @@ public interface LinphoneCoreListener {
|
|||
/** Callback to display a warning to the user
|
||||
* @return */
|
||||
public void displayWarning(LinphoneCore lc,String message);
|
||||
/** State notification callback
|
||||
* @param state LinphoneCore.GeneralState
|
||||
/** General State notification
|
||||
* @param state LinphoneCore.State
|
||||
* @return
|
||||
* */
|
||||
public void generalState(LinphoneCore lc,LinphoneCore.GeneralState state, String message);
|
||||
public void globalState(LinphoneCore lc,LinphoneCore.GlobalState state, String message);
|
||||
/** Call State notification
|
||||
* @param state LinphoneCall.State
|
||||
* @return
|
||||
* */
|
||||
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message);
|
||||
/**
|
||||
* Registration state notification
|
||||
* */
|
||||
public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage);
|
||||
/**
|
||||
* Reports that a new subscription request has been received and wait for a decision.
|
||||
*Status on this subscription request is notified by changing policy for this friend
|
||||
*@param lc LinphoneCore
|
||||
*@param lf LinphoneFriend corresponding to the subscriber
|
||||
*@param url of the subscriber
|
||||
*
|
||||
*/
|
||||
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url);
|
||||
/**
|
||||
* Report status change for a friend previously added to LinphoneCore.
|
||||
* @param lc LinphoneCore
|
||||
* @param lf updated LinphoneFriend
|
||||
*/
|
||||
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf);
|
||||
/**
|
||||
* invoked when a new text message is received
|
||||
* @param lc LinphoneCore
|
||||
* @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room.
|
||||
* @param from LinphoneAddress from
|
||||
* @param message incoming message
|
||||
*/
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message);
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue