forked from mirrors/linphone-iphone
Initial import
git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@1 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
This commit is contained in:
commit
2b8200409c
1602 changed files with 411919 additions and 0 deletions
24
linphone/.cvsignore
Normal file
24
linphone/.cvsignore
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
intltool-extract
|
||||
intltool-merge
|
||||
intltool-update
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
mkinstalldirs
|
||||
speex
|
||||
stamp-h1
|
||||
linphone.spec
|
||||
1101
linphone/ABOUT-NLS
Normal file
1101
linphone/ABOUT-NLS
Normal file
File diff suppressed because it is too large
Load diff
57
linphone/AUTHORS
Normal file
57
linphone/AUTHORS
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
Simon MORLAT (simon dot morlat at linphone dot org) wrotes:
|
||||
- main graphical program (gnome)
|
||||
- RTP library (oRTP)
|
||||
- SIP user-agent library (osipua)
|
||||
- audio library (mediastreamer), for codec and i/o handling.
|
||||
- sipomatic, the automatic sip replier, which is often used for testing.
|
||||
|
||||
Florian Wintertein < f-win at gmx dot net > wrotes the console version of linphone (linphonec)
|
||||
in console/ directory.
|
||||
|
||||
Aymeric Moizard (jack at atosc dot org) wrotes:
|
||||
- the oSIP SIP transactionnal stack (not part of linphone)
|
||||
- some piece of code of the osip distribution have been reused in osipua
|
||||
- presence information support in osipua
|
||||
- and contributes to some parts of osipua (digest authentification)
|
||||
For more information about oSIP, see http://osip.atosc.org
|
||||
|
||||
Sharath Udupa is developing the media_api, a usefull library to manage audio and video streams
|
||||
for basic calls as well as conference.
|
||||
|
||||
Sandro Santilli < strk at keybit dot net > wrote enhancements in the
|
||||
console interface (readline, new commands) and some bug fixes for
|
||||
the core api.
|
||||
|
||||
Bryan Ogawa ( bko at cisco dot com ) sent a patch that made the linphone-0.7.1 release.
|
||||
This patch fixed several issues in the SIP part while working with proxies.
|
||||
|
||||
Koichi KUNITAKE < kunitake at linux-ipv6 dot org > has contributed a patch bringing
|
||||
full IPv6 support.
|
||||
|
||||
The Speex codec is a project from Jean Marc Valin. See http://speex.sourceforge.net for more
|
||||
information.
|
||||
|
||||
The GSM library was written by :
|
||||
Jutta Degener and Carsten Bormann,Technische Universitaet Berlin.
|
||||
|
||||
The LPC10-1.5 library was written by:
|
||||
Andy Fingerhut
|
||||
Applied Research Laboratory <-- this line is optional if
|
||||
Washington University, Campus Box 1045/Bryan 509 you have limited space
|
||||
One Brookings Drive
|
||||
Saint Louis, MO 63130-4899
|
||||
jaf@arl.wustl.edu
|
||||
http://www.arl.wustl.edu/~jaf/
|
||||
|
||||
See text files in gsmlib and lpc10-1.5 directories for further information.
|
||||
|
||||
G711 library has some code from the alsa-lib on http://www.alsa-project.org
|
||||
|
||||
Icons by Pablo Marcelo Moia.
|
||||
|
||||
Translations:
|
||||
fr: Simon Morlat
|
||||
en: Simon Morlat and Delphine Perreau
|
||||
it: Alberto Zanoni <alberto.zanoni@-NO-SPAM-PLEASE!-tiscalinet.it>
|
||||
de: Jean-Jacques Sarton <jj.sarton@-NO-SPAM-PLEASE-t-online.de>
|
||||
es: Jesús Benítez <gnelson at inMail dot sk>
|
||||
9
linphone/BUGS
Normal file
9
linphone/BUGS
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
linphone-1.0.0:
|
||||
It seems ipv6 support is "broken". Some help is welcome.
|
||||
|
||||
linphone-0.12.0
|
||||
When compiling with gcc-2.95.4 on debian, an assert fails and cause abort()
|
||||
in libasound (alsa-lib). When compiling with gcc-3.2, it does not happen.
|
||||
It seems that asoundlib and linphone must be compiled with the same compiler.
|
||||
|
||||
Simon MORLAT
|
||||
340
linphone/COPYING
Normal file
340
linphone/COPYING
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
513
linphone/ChangeLog
Normal file
513
linphone/ChangeLog
Normal file
|
|
@ -0,0 +1,513 @@
|
|||
2008-09-02 Francois-Xavier Kowalski <fix@hp.com>
|
||||
|
||||
* gtk/Makefile.am (INCLUDES): 1.6
|
||||
Deprecated automake directive INCLUDES does not work within a
|
||||
conditionnal.
|
||||
|
||||
2008-08-22 Francois-Xavier Kowalski <fix@hp.com>
|
||||
|
||||
* mediastreamer2/src/Makefile.am (libmediastreamer_la_SOURCES+): 1.27
|
||||
Deliver swscale.h in case ffmpeg does not come with libswscale
|
||||
(in which case the swscale feature is included into
|
||||
libavcodec). Also deliver ffmpeg-priv.h wrapper.
|
||||
|
||||
* mediastreamer2/src/videoout.c: 1.39
|
||||
* mediastreamer2/src/videodec.c: 1.24
|
||||
* mediastreamer2/src/sizeconv.c: 1.14
|
||||
* mediastreamer2/src/pixconv.c: 1.13
|
||||
* mediastreamer2/src/nowebcam.c: 1.15
|
||||
Use ffmpeg-priv,h
|
||||
|
||||
* mediastreamer2/mediastreamer-config.h.in: 1.13
|
||||
Remove from CVSm as it is generated by autoheader
|
||||
|
||||
* mediastreamer2/configure.ac: 1.47
|
||||
Use pkg-config to check for arts
|
||||
|
||||
* mediastreamer2/acinclude.m4: 1.12
|
||||
Remove -I/usr/include and -L/usr/lib(64) from CFLAGS and LIBS.
|
||||
Check for ffmpeg swscale feature into libavcodec or into
|
||||
libswscale
|
||||
|
||||
2007-09-26 Francois-Xavier Kowalski <fix@hp.com>
|
||||
|
||||
* m4/exosip.m4: 1.3
|
||||
make Linphone buildable with the eXosip/osip version that ships
|
||||
with Fedora.
|
||||
|
||||
* oRTP/include/ortp/stun_udp.h: 1.9
|
||||
* mediastreamer2/include/mediastreamer2/msvideo.h: 1.7
|
||||
* mediastreamer2/include/mediastreamer2/msticker.h: 1.6
|
||||
* mediastreamer2/include/mediastreamer2/msqueue.h: 1.3
|
||||
Clean ANSI/C vs. ANSI/C++ differences
|
||||
|
||||
2007-08-01 Sandro Santilli <strk@keybit.net>
|
||||
|
||||
* console/commands.c: Clean up commands 'nat', 'stun'
|
||||
and 'firewall' to be more intuitive.
|
||||
|
||||
2007-02-03 Francois-Xavier Kowalski <fix@hp.com>
|
||||
|
||||
* m4/osip.m4 (OSIP_CFLAGS): 1.2
|
||||
* gnome/Makefile.am (linphone_applet_LDADD): 1.33
|
||||
* coreapi/Makefile.am (liblinphone_la_CFLAGS): 1.38
|
||||
* console/Makefile.am (sipomatic_LDADD): 1.45
|
||||
Cope with osip2-2.2.2 delivered as legacy on FC6. New option
|
||||
"--with-osip-version"
|
||||
|
||||
2007-01-18 Francois-Xavier Kowalski <fix@hp.com>
|
||||
|
||||
* oRTP/Makefile.am: 1.24
|
||||
* mediastreamer2/Makefile.am: 1.30
|
||||
* Makefile.am: 1.45
|
||||
Fix RPM package generattion to cope with
|
||||
<https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=206841>
|
||||
|
||||
2007-01-17 gettextize <bug-gnu-gettext@gnu.org>
|
||||
|
||||
* m4/gettext.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/lib-link.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/lib-prefix.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/nls.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/po.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/codeset.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/intl.m4: New file, from gettext-0.16.1.
|
||||
* m4/intldir.m4: New file, from gettext-0.16.1.
|
||||
* m4/intmax.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/inttypes_h.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/inttypes-pri.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/lock.m4: New file, from gettext-0.16.1.
|
||||
* m4/longdouble.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/longlong.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/size_max.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/stdint_h.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/ulonglong.m4: Upgrade to gettext-0.16.1.
|
||||
* m4/visibility.m4: New file, from gettext-0.16.1.
|
||||
* m4/Makefile.am (EXTRA_DIST): Add the new files.
|
||||
|
||||
2006-10-18 Sandro Santilli <strk@keybit.net>
|
||||
|
||||
* console/Makefile.am: set osip includes last in the
|
||||
search path.
|
||||
|
||||
2006-09-19 Francois-Xavier Kowalski <fix@hp.com>
|
||||
|
||||
* linphone.spec.in (BuildRequires): 1.8
|
||||
Add RPM build-time dependency on gettext-devel to define
|
||||
AM_GNU_GETTEXT.
|
||||
|
||||
2006-07-26 Sandro Santilli <strk@keybit.net>
|
||||
|
||||
* .cvsignore, developer-docs/mediastreamer/.cvsignore,
|
||||
ipkg/.cvsignore, mediastreamer2/.cvsignore,
|
||||
mediastreamer2/build/.cvsignore,
|
||||
mediastreamer2/build/win32native/.cvsignore,
|
||||
mediastreamer2/include/.cvsignore,
|
||||
mediastreamer2/include/mediastreamer2/.cvsignore,
|
||||
mediastreamer2/plugins/.cvsignore,
|
||||
mediastreamer2/src/.cvsignore,
|
||||
mediastreamer2/tests/.cvsignore,
|
||||
oRTP/build/win32/.cvsignore,
|
||||
oRTP/build/win32native/.cvsignore,
|
||||
oRTP/src/tests/win_receiver/.cvsignore,
|
||||
oRTP/src/tests/win_sender/.cvsignore,
|
||||
po/.cvsignore, share/cs/.cvsignore:
|
||||
Added-fixed .cvsignore files
|
||||
|
||||
2006-07-20 gettextize <bug-gnu-gettext@gnu.org>
|
||||
|
||||
* m4/codeset.m4: New file, from gettext-0.14.6.
|
||||
* m4/gettext.m4: New file, from gettext-0.14.6.
|
||||
* m4/glibc2.m4: New file, from gettext-0.14.6.
|
||||
* m4/glibc21.m4: New file, from gettext-0.14.6.
|
||||
* m4/iconv.m4: New file, from gettext-0.14.6.
|
||||
* m4/intdiv0.m4: New file, from gettext-0.14.6.
|
||||
* m4/intmax.m4: New file, from gettext-0.14.6.
|
||||
* m4/inttypes.m4: New file, from gettext-0.14.6.
|
||||
* m4/inttypes_h.m4: New file, from gettext-0.14.6.
|
||||
* m4/inttypes-pri.m4: New file, from gettext-0.14.6.
|
||||
* m4/isc-posix.m4: New file, from gettext-0.14.6.
|
||||
* m4/lcmessage.m4: New file, from gettext-0.14.6.
|
||||
* m4/lib-ld.m4: New file, from gettext-0.14.6.
|
||||
* m4/lib-link.m4: New file, from gettext-0.14.6.
|
||||
* m4/lib-prefix.m4: New file, from gettext-0.14.6.
|
||||
* m4/longdouble.m4: New file, from gettext-0.14.6.
|
||||
* m4/longlong.m4: New file, from gettext-0.14.6.
|
||||
* m4/nls.m4: New file, from gettext-0.14.6.
|
||||
* m4/po.m4: New file, from gettext-0.14.6.
|
||||
* m4/printf-posix.m4: New file, from gettext-0.14.6.
|
||||
* m4/progtest.m4: New file, from gettext-0.14.6.
|
||||
* m4/signed.m4: New file, from gettext-0.14.6.
|
||||
* m4/size_max.m4: New file, from gettext-0.14.6.
|
||||
* m4/stdint_h.m4: New file, from gettext-0.14.6.
|
||||
* m4/uintmax_t.m4: New file, from gettext-0.14.6.
|
||||
* m4/ulonglong.m4: New file, from gettext-0.14.6.
|
||||
* m4/wchar_t.m4: New file, from gettext-0.14.6.
|
||||
* m4/wint_t.m4: New file, from gettext-0.14.6.
|
||||
* m4/xsize.m4: New file, from gettext-0.14.6.
|
||||
* m4/Makefile.am (EXTRA_DIST): Add the new files.
|
||||
* Makefile.am (EXTRA_DIST): Add config.rpath.
|
||||
|
||||
2006-07-07 Francois-Xavier Kowalski <fix@hp.com>
|
||||
|
||||
* linphone.spec.in (Version): 1.7
|
||||
Force build of gtk-doc, as the default choice that comes with
|
||||
GTK_DOC_CHECK m4 macro is "no".
|
||||
|
||||
2006-05-17 Francois-Xavier Kowalski <fix@hp.com>
|
||||
|
||||
* configure.in: 1.179
|
||||
* configure.in: 1.178
|
||||
Allow rpm users to use oRTP packages built from Linphone root.
|
||||
|
||||
May 8 2006 : Sandro Santilli <strk@keybit.net>
|
||||
|
||||
* configure.in: lowered libspeex requirement to 1.1.6
|
||||
|
||||
undefined yet: linphone-1.4.0
|
||||
- new audio/video streaming engine (mediastreamer2) that let the following improvements:
|
||||
+ split video frame to get them smaller than MTU
|
||||
+ less video latency
|
||||
+ video supported at CIF and QCIF resolution with variable framerate.
|
||||
+ arts sound input/output
|
||||
+ improved sound latency with alsa
|
||||
+ alsa support works with dmix/dsnoop
|
||||
+ old oss drivers that don't like select and non blocking mode should finally work
|
||||
- lpc10-15 support removed (speex does better at 8kbit/s)
|
||||
- jack support unported to mediastreamer2, sorry : volunteer needed
|
||||
- video resolution and framerate set according to bandwidth constraints.
|
||||
- linphonec new "soundcard" command to list and choose sound devices.
|
||||
- new download and upload bandwidth parameters.
|
||||
|
||||
March 31 2006: linphone-1.3.4
|
||||
- fix linphonec bug in auto-answer mode: was terminating call after a few seconds.
|
||||
|
||||
March 28 2006: linphone-1.3.3
|
||||
- various FedoraCore 4 compile problem solved
|
||||
- fix video bug ('could not mmap': happening on kernel>=2.6.15 with pwc driver)
|
||||
- SIP register were not using route field (submitted patch)
|
||||
|
||||
March 17 2006: linphone-1.3.2
|
||||
- fix early media call problem: ack for 200ok was never sent.
|
||||
|
||||
March 10 2006: linphone-1.3.1
|
||||
- fix compile errors with gcc-2.95 (thanks Wolfram Gloger)
|
||||
|
||||
March 8 2006 : linphone-1.3.0 (SUMMARY)
|
||||
- a lots of improvements in linphonec (see strk 's Changelogs below)
|
||||
- telephone event problem with sipomatic.
|
||||
- updated cz translation.
|
||||
- fix bugs around addressbook.
|
||||
- video support with H263-1998/RFC2429 nearly clean.
|
||||
- added timeout for incoming calls
|
||||
|
||||
February 20 2006 : Sandro Santilli <strk@keybit.net>
|
||||
|
||||
* console/commands.c: added filter support for
|
||||
command 'friend list'.
|
||||
|
||||
February 13 2006 : Sandro Santilli <strk@keybit.net>
|
||||
|
||||
* console/linphonec.c: fixed unused variable warning.
|
||||
|
||||
February 02 2006 : Sandro Santilli <strk@keybit.net>
|
||||
Console:
|
||||
- Padded vtable with missing callbacks
|
||||
(fixing a segfault on friends subscription)
|
||||
- Handled friends notify (bare version)
|
||||
- Handled text messages receive (bare version)
|
||||
- Printed message on subscription request (bare version)
|
||||
- Added 'friend list' and 'friend call' commands
|
||||
- Allowed for multiple DTMF send in a single line
|
||||
- Added status-specific callback (bare version)
|
||||
|
||||
|
||||
January 26 2006 : Sandro Santilli <strk@keybit.net>
|
||||
- Core: fixed bug in linphone_core_set_nat_address refusing
|
||||
to set address if use flag was off, added support
|
||||
for NULL addr parameter to only change use flag.
|
||||
- Support: added missing GFileTest enum values
|
||||
- Console: 'nat' commands, cleanups
|
||||
|
||||
January 25 2006 : Sandro Santilli <strk@keybit.net>
|
||||
- Core: added request uri in proxy registration failure message
|
||||
- Console: removed the -t switch
|
||||
(terminate on close is default behaviour)
|
||||
|
||||
January 20 2006 : Sandro Santilli <strk@keybit.net>
|
||||
- Console:
|
||||
linphonec_init() and linphonec_finish() functions. Handled
|
||||
SIGINT and SIGTERM to invoke linphonec_finish(). Handling of
|
||||
auto-termination (-t) moved to linphonec_finish(). Reworked main
|
||||
(input read) loop to not rely on 'terminate' and 'run' variable
|
||||
(dropped). configfile_name allocated on stack using PATH_MAX
|
||||
limit. Changed print_usage signature to allow for an exit_status
|
||||
specification.
|
||||
|
||||
January 18 2006 : Sandro Santilli <strk@keybit.net>
|
||||
- Console:
|
||||
Command completion inhibited
|
||||
in proxy addition and auth request prompts. Avoided use of
|
||||
readline's internal filename completion.
|
||||
|
||||
January 14 2006 : Sandro Santilli <strk@keybit.net>
|
||||
- Console:
|
||||
Reworked commands interface to use a table structure, used by
|
||||
command line parser and help function. Implemented first
|
||||
level of completion (commands). Added notification of
|
||||
invalid "answer" and "terminate" commands (no incoming call,
|
||||
no active call). Forbidden "call" intialization when a call is
|
||||
already active. Cleaned up all commands, adding more feedback
|
||||
and error checks.
|
||||
|
||||
January 13 2006 : Sandro Santilli <strk@keybit.net>
|
||||
- Console:
|
||||
Added linphonec.h. Code layout change (added comments, forward
|
||||
decl, globals on top, copyright notices and Logs). Handled
|
||||
out-of-memory condition on history management. Removed
|
||||
assumption on sizeof(char). Fixed bug in authentication
|
||||
prompt (introduced by readline). Added support for multiple
|
||||
authentication requests (up to MAX_PENDING_AUTH).
|
||||
|
||||
January 12 2006 : Sandro Santilli <strk@keybit.net>
|
||||
- Console:
|
||||
Changed default configuration file to ~/.linphonerc,
|
||||
automatically handling migration from old layout if not present
|
||||
(use ~/.linphonec or ~/.gnome2/linphone). Added compile-time
|
||||
define to show identity in prompt. Used EXIT_SUCCESS and
|
||||
EXIT_FAILURE macros.
|
||||
Made readline use ~/.linphonec_history file for
|
||||
reading/writing. Fixed auto-call handling code. Fixed
|
||||
OOB write of sscanf() in linphonec_parse_command_line().
|
||||
Simplified control flow in linphonec_main_loop().
|
||||
Put linphonec_{initialize,finish}_readline() calls out of
|
||||
main_loop(). Removed redundant exit(0) at end of main().
|
||||
Fixed small leaks.
|
||||
|
||||
December 14 2005 : linphone-1.2.0
|
||||
- various ipv6 bugfixes (again)
|
||||
- fix po.pl file (was utf-8 but declared as iso8902)
|
||||
- enum/automatic proxy conflict solved. use "sip:7887488478" for enums, just "382884824" to go through the default proxy.
|
||||
- experimental video support progresses, compliance improved.
|
||||
- remove ilbc from source tree: it is now available as a separete plugin.
|
||||
- updated to work with lastest ffmpeg cvs
|
||||
- fix bug when answering 'busy here'; active call was closed !
|
||||
- fix Ctrl+H bug in linphonec
|
||||
- added bresilian translation
|
||||
- added swedish translation
|
||||
- uri bar improvements
|
||||
- fix a DoS attack by setting a payload type number > 127
|
||||
|
||||
August 24 2005 : linphone-1.1.0
|
||||
- peer to peer text chat
|
||||
- automatic sip url completion when using a default proxy:
|
||||
when user types 'mymother' in the url bar, linphone calls sip:mymother@[default-proxy]
|
||||
- ilbc 20 and 30 miliseconds frames support
|
||||
- support for setting a soundcard for playback and another for record
|
||||
- ipv6 bugfixes: works with ipv6 local loopback with sipomatic at least ! Needs to be tested in a real network.
|
||||
- gtk interface bugfixes
|
||||
- increase max supported sound devices (was 5).
|
||||
- automatic incoming redirections
|
||||
- experimental video support (needs special compilation procedure, see mailing lists)
|
||||
|
||||
|
||||
March 27 2005 : linphone-1.0.1
|
||||
- patch for NAT traversal (SDP connection address in SDP answer)
|
||||
- patch for writing correct port information when NAT is enabled
|
||||
- patch for always using "rport" extension to traverse NAT with
|
||||
signalling.
|
||||
- patch for saving/restoring correct configuration of proxy:
|
||||
"reg_register" -> "reg_sendregister" and fix for saving "expires"
|
||||
|
||||
March 21 2005 : linphone-1.0.0
|
||||
- switch from osipua to eXosip/osip2 for improved sip functionnalities and compliance.
|
||||
- support for presence (busy, online...) for everyone in the address book (uses SUBSCRIBE/NOTIFY)
|
||||
- support for PUBLISH (presence information through sip servers)
|
||||
- support for configuring multiple proxies.
|
||||
- RTP adaptive jitter buffer ( provides lower latency )
|
||||
- RTCP coumpound messages sent periodically.
|
||||
- on demand digest authentication for INVITE and REGISTER
|
||||
- support for 183 with sdp answers.
|
||||
- add support for jackd (contributed)
|
||||
- call logging
|
||||
- arm build improved
|
||||
- cz and nl translations contributed.
|
||||
|
||||
|
||||
January 2004 : linphone-0.12.2
|
||||
- add enum support (see RFC3241 and RFC3026)
|
||||
Thanks to Rene Bartsch < ml at bartschnet dot de > for its usefull
|
||||
and precious help.
|
||||
- interactive presence box (no more need to click OK to confirm)
|
||||
- update spanish translation
|
||||
- alsa interface: the user can choose precisely the pcm device to be used
|
||||
by setting the sound/alsadev parameter of the config file.
|
||||
- use 1 RTP socket instead of 2: this makes linphone NAT-friendly.
|
||||
|
||||
Thursday October 2 2003 : linphone-0.12.1
|
||||
- add support for personalizing rings.
|
||||
- make glib dependency optionnal (but recommended).
|
||||
- add polish translation.
|
||||
- use of libartsc to suspend arts instead of killing him.
|
||||
|
||||
Tuesday August 19 2003 : linphone-0.12.0
|
||||
- add support for speex/16000
|
||||
- re-enable alsa support (0.9.x)
|
||||
- few improvements on gui.
|
||||
- added spanish translation by Jesús Benítez <gnelson at inMail dot sk>
|
||||
|
||||
Monday April 05 2003: linphone-0.11.0
|
||||
- merge ipv6 support patch, contributed by Koichi KUNITAKE
|
||||
< kunitake at linux-ipv6 dot org > (thanks !)
|
||||
- some improvements on graphical interface.
|
||||
|
||||
Friday Feb 28 2003 : linphone-0.10.1
|
||||
- add firewall friendly capability
|
||||
- compiles all well on arm-linux
|
||||
- bugfixes.
|
||||
|
||||
Friday Jan 24 2003 : linphone-0.10.0
|
||||
- Gnome interface ported to gnome-2
|
||||
- Unified core engine for both graphical and console interface.
|
||||
- Many bug fix and improvements in the SIP stack.
|
||||
- Japoneese translations and manual added, by Yamaguchi Yoshiya.
|
||||
- updated for speex-1.0rc1
|
||||
- ported to FreeBSD thanks to Georg Shwarz
|
||||
|
||||
Monday Oct 21 2002 : linphone-0.9.1
|
||||
- AMD: add support for the "received" and "rport" parameter in osipua.
|
||||
|
||||
Monday Oct 21 2002 : linphone-0.9.1
|
||||
- integration of the patch of Lenaic Huard that adds the ability for linphone to send
|
||||
dtmf tones through rtp (only reported to console interface).
|
||||
- following this patch, a nice keypad has been added to the graphical interface to bring
|
||||
the fonctionnality of the patch gui's users.
|
||||
- integration of the patch of Aymeric Moizard, concerning compliance with RFC3261 (new
|
||||
sip's RFC) using the new dialog_t api of libosip.
|
||||
- updated for use of speex-beta1 (speex codec)
|
||||
- osipua fix by jack@atosc.org
|
||||
1: reject calls with 603
|
||||
2: establishement of 1 early dialog for incoming calls.
|
||||
3: update to libosip CVS and its new OSIP_TRACE MACROs.
|
||||
4: fix presence handling.
|
||||
5: fix expires header in REGISTER.
|
||||
|
||||
|
||||
Monday Aug 26 2002: linphone-0.9.0
|
||||
- the sdp rtpmap string for alaw and mulaw codec was incorrect.
|
||||
|
||||
Sunday Aug 4 2002: linphone-0.9.0pre3
|
||||
Non visible changes:
|
||||
- Linphone's internal audio architecture is ported to the new mediastreamer architecture.
|
||||
The mediastreamer library is already present in linphone since October 29 2001 but
|
||||
was never used at this time by the core program. Now lots of work has be done inside the
|
||||
mediastreamer so that it is ready to be used by the core program. As a consequence, the
|
||||
old architecture defined by the audio/ directory and the codec.c io.c files is dropped.
|
||||
The mediastreamer architecture provides a modular framework for audio and video
|
||||
processing. It includes various audio and video codecs (or wrappers to third party
|
||||
audio and video codecs).
|
||||
Visible changes:
|
||||
- The Speex codec (http://speex.sourceforge.net) is now availlable to linphone, since it has
|
||||
its mediastreamer wrapper. This patent-free codec provides two bitrates, the lowest
|
||||
being able to work with 56k dialup connections. This is a very important step, because
|
||||
from now only the low quality LPC10 codec was availlable for such connections.
|
||||
- Thanks to Florian Winsterstein (f-win at gmx.de), a console version of linphone called
|
||||
"linphonec" is availlable. Linphonec can be compiled without gnome.
|
||||
|
||||
Wednesday May 8 2002: linphone-0.8.0
|
||||
Visible changes:
|
||||
- Updated to libosip-0.8.5, that reflects the lastest sip draft.
|
||||
- Uses the SDP parser the libosip, and uses also a modified version of its SDP negociator.
|
||||
The MediaDesc object is removed, now osipua users have to deal with BodyHandler's, as the
|
||||
SdpHandler that deals with sdp message generation and negociation.
|
||||
The SDP parser and negociator can use the a=rtpmap fields, so that compliance is improved.
|
||||
- LPC10-1.5 codec has been assigned payload type 115 instead of 4 previously. This breaks
|
||||
compatibility with older versions of linphone.
|
||||
- oRTP (the new RTP library) is used in place of the old lprtplib.
|
||||
- fix endianess problems in the audio part.
|
||||
Non visible changes (changes on libraries not currently used by linphone but used later):
|
||||
- mediastreamer has new working objects: webcam image capture, mpeg encoding and decoding
|
||||
thanks to the libavcodec (ffmpeg) library, rtp wrapper thanks to oRTP.
|
||||
|
||||
Tuesday April 15 2002: linphone-0.7.2
|
||||
- A crash in property box "apply" fixed.
|
||||
- bugfix in osipua.
|
||||
|
||||
Tuesday March 12 2002: linphone-0.7.1
|
||||
- Some bug fixes by Bryan Ogawa in osipua: route, record-route, tags.
|
||||
|
||||
Friday March 1 2002: linphone-0.7.0
|
||||
- Digest authentification support added by Aymeric.
|
||||
- Improvements in property box.
|
||||
- Translations in German and Italian by J.J. Sarton and A. Zanoni
|
||||
- Bugfix and improvements in the osipua stack.
|
||||
- Better handling of the registration parameters (the user can set its own address of record).
|
||||
|
||||
|
||||
Thu December 6 2001
|
||||
-osipua.c: Memory allocations.
|
||||
fi call of from_tag_add(...,sgetcopy(ua->fromtag));
|
||||
-utils.c: Memory allocations.
|
||||
-CallLegs are removed automatically by the osipua layer (eg: when a transaction timed out).
|
||||
|
||||
Tue November 27 2001
|
||||
-Bugfix in osipua for proxy support: record-route and route header support, request-uri bug fixed.
|
||||
-New choice "outbound proxy" in the property box.
|
||||
-Fix compilation issues.
|
||||
|
||||
|
||||
Mon October 29 2001
|
||||
-New unithreaded design of the osipua library, based on libosip-0.7.x series.
|
||||
-Asynchronous name resolution in osipua.
|
||||
-To and From tag support added.
|
||||
-Proxy support added. The user can choose between registering for a redirect server, or
|
||||
registering for a proxy server. When he choose proxy, then all requests are sent to the proxy.
|
||||
-New good looking graphical interface.
|
||||
-Mediastreamer is included, but still unused. It has a begin of gtkdoc dcocumentation.
|
||||
|
||||
Wed September 26 2001
|
||||
-Add registration and redirection ability in gui and osipua.
|
||||
-Critical bugs in osipua/osip fixed.
|
||||
-Display all sip error strings in appbar.
|
||||
-Documentation translated in French.
|
||||
|
||||
Tue August 21 2001
|
||||
- Add address book functionnality
|
||||
- Add ringback
|
||||
- Minor bugfixes in configure.in, src/callbacks.c
|
||||
- Work with libosip-0.6.1
|
||||
|
||||
Wed August 1 2001:
|
||||
- Integration with osip sip stack. lpsiplib is no more used and abandonned. osipua provides the session level
|
||||
on top of osip.
|
||||
- added G711 codecs.
|
||||
- configuration structures and api re-written for more clarity.
|
||||
- new codec selection box
|
||||
- new sytem for codec registration
|
||||
- automatic selection of codecs regarding to network connection type.
|
||||
- add resizing ability for icon applet.
|
||||
|
||||
|
||||
June 2001: linphone-0.3.0
|
||||
-Nearly all code in linphone is object oriented.
|
||||
-linphone can be run as a gnome applet, or as a silent dameon, or as a normal application.
|
||||
-bugfixes in sip/sdp messages.
|
||||
-addition of a test program called sipomatic that can automatically answers to call. (for test)
|
||||
-add io_disk implementation of the audio lib. this can be used to replace the sond card by io on file system.
|
||||
|
||||
|
||||
|
||||
Tue May 15 2001: linphone-0.2.1
|
||||
-Fix a stupid bug in the audio library.
|
||||
|
||||
Fri May 11 2001: linphone-0.2.0
|
||||
-add many missing features of version 0.1.0 (for the property box)
|
||||
-audio levels on the main window.
|
||||
-Sip library modified: now it uses one thread, and should be able to handle several calls in the future.
|
||||
-audio library is more performant. It is able to find itself the best blocksize (latency) by testing the driver.
|
||||
-interactive help on the property box and user manual.
|
||||
-add an icon.
|
||||
|
||||
linphone-0.1.0 :
|
||||
Released on april,19 2001
|
||||
Initial version.
|
||||
236
linphone/INSTALL
Normal file
236
linphone/INSTALL
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script). Here is a another example:
|
||||
|
||||
/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
|
||||
configuration-related scripts to be executed by `/bin/bash'.
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
42
linphone/Makefile.am
Normal file
42
linphone/Makefile.am
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
# let make re-run automake upon need
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
if EXTERNAL_ORTP
|
||||
ORTP_DIR =
|
||||
else
|
||||
ORTP_DIR = oRTP
|
||||
endif
|
||||
|
||||
SUBDIRS = m4 pixmaps po ipkg $(ORTP_DIR) mediastreamer2\
|
||||
media_api coreapi console gtk gtk-glade share
|
||||
|
||||
|
||||
EXTRA_DIST = config.rpath linphone2.glade BUGS linphone.kdevprj \
|
||||
intltool-extract.in \
|
||||
intltool-merge.in \
|
||||
intltool-update.in \
|
||||
README.arm \
|
||||
autogen.sh \
|
||||
linphone.spec.in linphone.spec
|
||||
ACLOCAL_FLAGS=-I$(top_srcdir)/m4
|
||||
|
||||
DISTCLEANFILES= intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
|
||||
|
||||
# `make rpm'
|
||||
|
||||
all-local: linphone.spec
|
||||
linphone.spec: linphone.spec.in
|
||||
|
||||
.phony: rpm
|
||||
rpm:
|
||||
$(MAKE) dist
|
||||
# Create "Specfile" at the same level as the tarball content
|
||||
-rm -f $(PACKAGE)-$(VERSION).tar
|
||||
gunzip $(PACKAGE)-$(VERSION).tar.gz
|
||||
cp $(PACKAGE).spec Specfile
|
||||
tar --append --file=$(PACKAGE)-$(VERSION).tar Specfile
|
||||
gzip $(PACKAGE)-$(VERSION).tar
|
||||
# <https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=2068410>
|
||||
TAR_OPTIONS=--wildcards rpmbuild -ta --clean --rmsource --rmspec $(PACKAGE)-$(VERSION).tar.gz
|
||||
75
linphone/NEWS
Normal file
75
linphone/NEWS
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
linphone-2.1.1 -- February 13, 2008
|
||||
* fix interroperability bug with Asterisk about a BYE not sent by linphone.
|
||||
* fix alsa support weakness (capture underruns not recovered)
|
||||
|
||||
linphone-2.1.0 -- January 25, 2008
|
||||
* 4CIF support
|
||||
* enable resizing of video output
|
||||
* hu translation added
|
||||
|
||||
linphone-2.0.1 -- November 30, 2007
|
||||
* fix interop issue with asterisk
|
||||
* answer OPTIONS and other SIP messages
|
||||
* allow usage of ALSA user pcm devices with the sound->alsadev config item.
|
||||
|
||||
linphone-2.0.0 -- November 15, 2007
|
||||
* port to libeXosip2-3.0.x with libosip2-3.0.x
|
||||
* implements early media
|
||||
* implements incoming re-INVITE
|
||||
* presence support improvements
|
||||
* ipv6 working on windows
|
||||
* implements SDP over 200ok/ACK
|
||||
* add experimental snow codec support
|
||||
* answers to VFU request in SIP-INFO by sending an I-frame.
|
||||
* ffmpeg rate control enabled, improved mpeg4 quality for low bandwidths
|
||||
* separate video grabbing and display in linphonec
|
||||
|
||||
linphone-1.7.1 -- April 16, 2007
|
||||
* cz translation
|
||||
* compilation bugfixes (when video support is disabled)
|
||||
* fix IM icons path bug
|
||||
|
||||
linphone-1.7.0 -- April 11, 2007
|
||||
* new splash screen when no webcam is detected
|
||||
* new friend commands for linphonec
|
||||
* gnome interface becomes gtk-only
|
||||
* fix issue with codec bitrate settings when no bandwidth limits are given
|
||||
* open rtp sockets before sending SDP offer or answer (so that we don't miss the
|
||||
first I-frame)
|
||||
|
||||
linphone-1.6.0 -- January 23, 2007
|
||||
* Video4Linux V2 support with mjpeg cameras
|
||||
* use MPEG4 config string provided in the SDP (if any)
|
||||
* fix bug when choosing an invalid ring sound file
|
||||
* fix bug when using quickcam driver with CIF size
|
||||
* reduce audio bandwidth usage for <128kbit/s connections with video
|
||||
|
||||
linphone-1.5.1 -- November 14, 2006
|
||||
* fix translations
|
||||
|
||||
linphone-1.5.0 -- October 11, 2006
|
||||
* compliant theora support (using Luca Barbato's draft)
|
||||
* mpeg4 support (compliant with RFC3016)
|
||||
* controls to display and modify video codec list (gnome interface)
|
||||
* banwidth usage improvements
|
||||
* splash screen when no webcam is detected
|
||||
|
||||
linphone-1.4.1 -- September 18, 2006
|
||||
* fixes crash when attempting to make two simultaneous calls
|
||||
* fixes crash when having no soundcard
|
||||
* require theora>=1.0.0-alpha7
|
||||
* do not allow resizing of the gnome interface
|
||||
* do not change mixer settings at startup
|
||||
|
||||
linphone-1.4.0 -- September 11, 2006
|
||||
* no more glib dependency at all
|
||||
* new mediastreamer2 framework for audio/video streaming
|
||||
* stable video support with H.263-1998
|
||||
* echo cancelation
|
||||
* experimental theora support
|
||||
* jack support unported to mediastreamer2, sorry : volunteer needed
|
||||
* video resolution and framerate set according to bandwidth constraints.
|
||||
* linphonec new "soundcard" command to list and choose sound devices.
|
||||
* new download and upload bandwidth parameters used to find suitable video/audio codec choice and parameters.
|
||||
* new 'play' and 'record' functions to linphonec to play and record wav files
|
||||
* arts sound backend
|
||||
53
linphone/README
Normal file
53
linphone/README
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
******************Building linphone ***********************************
|
||||
- you need at least:
|
||||
- libosip2>=3.0.3
|
||||
- libeXosip2>=3.0.3
|
||||
- speex>=1.1.6
|
||||
- libreadline
|
||||
+ gsm codec (gsm source package or libgsm-dev or gsm-devel) (optional)
|
||||
+ if you want to gtk interface:
|
||||
- gtk>=2.4.0
|
||||
+ if you want video support:
|
||||
- SDL>=1.2.10
|
||||
- libavcodec (ffmpeg) from a year 2007 or later cvs
|
||||
|
||||
with their corresponding -dev or -devel package if you don't use source packages.
|
||||
|
||||
|
||||
|
||||
************************************** user documentation *********************
|
||||
go to linphone's web site: http://www.linphone.org
|
||||
|
||||
|
||||
******************************** DEVELOPER documentation ********************
|
||||
|
||||
Here is a short description of the content of the source tree.
|
||||
|
||||
- oRTP/ is a poweful implementation of the RTP protocol. See the oRTP/README for more details.
|
||||
It is used by the mediastreamer to send and receive streams to the network.
|
||||
|
||||
- mediastreamer2/ is one of the important part of linphone. It is a framework library for audio
|
||||
and video processing. It contains several objects for grabing audio and video and outputing
|
||||
it (through rtp, to file).
|
||||
It contains also codec objects to compress audio and video streams.
|
||||
The mediastream.h files contain routines to easyly setup audio streams.
|
||||
|
||||
- mediastreamer/ is deprecated.
|
||||
|
||||
- media_api/ is going to be an easy to use library to handle audio and video session. It uses
|
||||
the mediastreamer at the backend to do the processing. It is going to be the only interface
|
||||
between the core application and the mediastreamer. At the moment this library is still in
|
||||
early stages of development and is unused by the core application.
|
||||
|
||||
- coreapi/ is the central point of linphone, which handles relationship between sip signalisation and media
|
||||
streaming. It contains an easy to use api to create a sip phone.
|
||||
|
||||
- gtk/ is the directory that contains the gui frontend of linphone. It uses all libraries descibed above.
|
||||
|
||||
- console/
|
||||
* linphonec.c is the main file for the console version of linphone.
|
||||
* sipomatic.c / sipomatic.h contains the code for sipomatic, the test program that auto-answer to linphone calls. If you want to understand
|
||||
how linphone runs, this is a good start example.
|
||||
|
||||
- share/ contains translation, documentation, rings and hello sound files.
|
||||
|
||||
12
linphone/README.CVS
Normal file
12
linphone/README.CVS
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
In order to compile from CVS, you have to first install:
|
||||
- pkg-config
|
||||
- intltool (intltool-devel if rpm)
|
||||
- install the mandatory and optional dependencies described in README file.
|
||||
|
||||
Then:
|
||||
./autogen.sh #to generate the configure script
|
||||
./configure # with desired options
|
||||
make
|
||||
|
||||
|
||||
Simon MORLAT < simon dot morlat at linphone dot org >
|
||||
93
linphone/README.M68k.txt
Normal file
93
linphone/README.M68k.txt
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
LINPHONE ON M68k-LINUX (by GIAN)
|
||||
********************************
|
||||
|
||||
The console version of linphone works on arm-linux, but also on m68k-linux? I’m trying to provide this:
|
||||
|
||||
* I used the same toolchain specified in the LTIB menu configuration, that is, on my system:
|
||||
/opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e
|
||||
|
||||
* I have created within my home directory a ColdFire-install-environment/ directory, copied into it the fresh tarballs of libogg-1.1.3, libosip2-2.2.2, speex-1.1.12, linphone-1.4.0 readline-5.1 and ncurses-5.5 (readline needs ncurses) Uncompressed all these
|
||||
tarballs.
|
||||
|
||||
Very important things common to all packages being cross compiled:
|
||||
******************************************************************
|
||||
* Copy the ipaq-config.site in the ipkg/ directory of linphone into some safe place, for example:
|
||||
cp /home/gianluca/ColdFire-install-environment/linphone-1.4.0-install/linphone-1.4.0/ipkg/ipag-config.site /home/gianluca/ColdFire-install-environment/linphone-1.4.0-install/
|
||||
Edit the ipaq-config.site file and replace all the arm-linux strings with m68k-linux one. Add also the –mcfv4e flag to the CFLAGS, CXXFLAGS, and CPPFLAGS labels.
|
||||
* You need a directory that we call M68K_INSTALL_TREE that will own files in the same way they will be installed on the target computer.
|
||||
|
||||
mkdir /ColdFire-linphonec-1.4.0-mcfv4e
|
||||
export M68K_INSTALL_TREE=/ColdFire-linphonec-1.4.0-mcfv4e
|
||||
export CONFIG_SITE=/home/gianluca/ColdFire-install-environment/linphone-1.4.0-install/ipaq-config.site
|
||||
export PATH=$PATH:/opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e/bin
|
||||
|
||||
|
||||
Cross compiling ncurses for M68k:
|
||||
********************************
|
||||
./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --with-shared
|
||||
make
|
||||
make install DESTDIR=$M68K_INSTALL_TREE
|
||||
|
||||
|
||||
Cross compiling readline for M68k:
|
||||
*********************************
|
||||
./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --disable-static
|
||||
make
|
||||
make install DESTDIR=$M68K_INSTALL_TREE
|
||||
|
||||
|
||||
|
||||
Cross compiling libosip for M68k:
|
||||
********************************
|
||||
./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --disable-static
|
||||
make
|
||||
make install DESTDIR=$M68K_INSTALL_TREE
|
||||
|
||||
|
||||
Cross compiling libogg for M68k:
|
||||
********************************
|
||||
./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --disable-static –enable-fixed-point
|
||||
make
|
||||
make install DESTDIR=$M68K_INSTALL_TREE
|
||||
|
||||
|
||||
Cross compiling speex for M68k:
|
||||
********************************
|
||||
./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --disable-static --enable-fixed-point --enable-m68k-asm --with-ogg=/ColdFire-linphonec-1.4.0-mcfv4e/usr --with-ogg-includes=/ColdFire-linphonec-1.4.0-mcfv4e/usr/include –with-ogg-libraries=/ColdFire-linphonec-1.4.0-mcfv4e/usr/lib --disable-oggtest
|
||||
make
|
||||
make install DESTDIR=$M68K_INSTALL_TREE
|
||||
|
||||
|
||||
cp /home/gianluca/ColdFire-iinstall-environment/linphone-1.4.0-install/linphone-1.4.0/mediastreamer2/src/.libs/libquickstream.so.0.0.0 /opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e/m68k-linux/lib
|
||||
cd /opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e/m68k-linux/lib
|
||||
ln -s libquickstream.so.0.0.0 libquickstream.so.0
|
||||
ln -s libquickstream.so.0.0.0 libquickstream.so
|
||||
|
||||
cp /home/gianluca/ColdFire-install-environment/linphone-1.4.0-install/linphone-1.4.0/mediastreamer2/src/.libs/libmediastreamer.so.0.0.0 /opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e/m68k-linux/lib
|
||||
cd /opt/mtwk/usr/local/m68k-linux/gcc-3.4.0-glibc-2.3.2-v4e/m68k-linux/lib
|
||||
ln -s libmediastreamer.so.0.0.0 libmediastreamer.so.0
|
||||
ln -s libmediastreamer.so.0.0.0 libmediastreamer.so
|
||||
|
||||
|
||||
Cross compiling linphone for M68k:
|
||||
********************************
|
||||
First you need to remove all .la files from the M68K_INSTALL_TREE because it confuses libtool and makes
|
||||
the linker use your build machine binaries instead of the m68k-crosscompiled ones.
|
||||
rm -f $M68K_INSTALL_TREE/usr/lib/*.la
|
||||
#for some reason pkg-config doesn't like cross-compiling...
|
||||
export PKG_CONFIG=/usr/bin/pkg-config
|
||||
./configure --prefix=/usr --host=m68k-linux --with-gnu-ld --disable-static --disable-strict --enable-gnome_ui=no --enable-alsa --disable-glib --disable-video --with-osip=$ARM_INSTALL_TREE/usr --with-osipparser=$ARM_INSTALL_TREE/usr --with-readline=$ARM_INSTALL_TREE/usr SPEEX_CFLAGS="-I$ARM_INSTALL_TREE/usr/include" SPEEX_LIBS="-L$ARM_INSTALL_TREE/usr/lib -lspeex"
|
||||
make
|
||||
make install DESTDIR=$M68K_INSTALL_TREE
|
||||
|
||||
|
||||
Binaries can also be stripped with m68k-linux-strip to save more space.
|
||||
|
||||
|
||||
Running linphone under the ColdFire board
|
||||
********************************************
|
||||
|
||||
You just have to start linphone from a terminal by typing 'linphonec'.
|
||||
|
||||
Gianluca Salvador
|
||||
|
||||
106
linphone/README.arm
Normal file
106
linphone/README.arm
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
LINPHONE ON ARM-LINUX (HANDHELD COMPUTERS)
|
||||
******************************************
|
||||
|
||||
The console version of linphone works on arm-linux and has been tested on ipaqs
|
||||
under the familiar linux distribution (http://www.handhelds.org).
|
||||
You can find .ipk binary packages on the linphone's download page.
|
||||
If you want to build your own arm-linux packages, here are some instructions to
|
||||
cross compile linphone and its dependencies: readline, speex and libosip.
|
||||
This is my own experience on cross compiling software. As there is no precise
|
||||
step by step documentation (as far as I know) on how to cross-compile on arm,
|
||||
there is no guaranty that the following instructions are the best way to do it.
|
||||
First, be aware that only the console version of linphone can compile on ARM.
|
||||
|
||||
|
||||
* You need the lastest arm toolchain from http://www.handhelds.org. Uncompress it in / .
|
||||
It contains all the cross-compilation tools. Be sure that the arm-linux-gcc binaries
|
||||
are in your PATH (export PATH=$PATH:/usr/local/arm/3.4.1/bin/ , for example)
|
||||
* create within your home directory a arm/ directory, copy into it the fresh
|
||||
tarballs of libosip2>=2.2.x, speex>=1.1.6, linphone>=1.2.1 readline>=5.1 and ncurses>=5.5 (readline needs ncurses)
|
||||
Uncompress all these
|
||||
tarballs.
|
||||
|
||||
|
||||
Very important things common to all packages being cross compiled:
|
||||
******************************************************************
|
||||
* copy the ipaq-config.site in the ipkg/ directory of linphone into some safe place,
|
||||
for example: ~/ipaq-config.site .
|
||||
* You need a directory that we call ARM_INSTALL_TREE that will own files in the same way they will be installed on the target computer.
|
||||
It is also used to build linphone over the arm binaries of its dependencies (speex,osip,ncurses,readline).
|
||||
|
||||
For example:
|
||||
|
||||
export CONFIG_SITE=~/ipaq-config.site
|
||||
export ARM_INSTALL_TREE=/armbuild
|
||||
|
||||
|
||||
Cross compiling ncurses for ARM:
|
||||
********************************
|
||||
./configure --prefix=/usr --host=arm-linux --with-gnu-ld --with-shared
|
||||
make
|
||||
make install DESTDIR=$ARM_INSTALL_TREE
|
||||
make install DESTDIR=`pwd`/armbuild
|
||||
|
||||
|
||||
Cross compiling readline for ARM:
|
||||
*********************************
|
||||
./configure --prefix=/usr --host=arm-linux --with-gnu-ld --disable-static
|
||||
make
|
||||
make install DESTDIR=$ARM_INSTALL_TREE
|
||||
make install DESTDIR=`pwd`/armbuild
|
||||
|
||||
|
||||
|
||||
Cross compiling libosip for ARM:
|
||||
********************************
|
||||
./configure --prefix=/usr --host=arm-linux --with-gnu-ld --disable-static
|
||||
make
|
||||
make install DESTDIR=$ARM_INSTALL_TREE
|
||||
make install DESTDIR=`pwd`/armbuild
|
||||
|
||||
Cross compiling speex for ARM:
|
||||
********************************
|
||||
First you need to remove ogg headers from your build system to avoid a dirty conflict between
|
||||
your build machine binaries and the arm binaries. They are usually in a libogg-dev package (rpm or deb).
|
||||
Then:
|
||||
./configure --prefix=/usr --host=arm-linux --with-gnu-ld --disable-static --enable-fixed-point --enable-arm-asm
|
||||
make
|
||||
make install DESTDIR=$ARM_INSTALL_TREE
|
||||
make install DESTDIR='pwd'/armbuild
|
||||
|
||||
|
||||
Cross compiling linphone for ARM
|
||||
********************************
|
||||
First you need to remove all .la files from the ARM_INSTALL_TREE because it confuses libtool and makes
|
||||
the linker use your build machine binaries instead of the arm-crosscompiled ones.
|
||||
rm -f $ARM_INSTALL_TREE/usr/lib/*.la
|
||||
#for some reason pkg-config doesn't like cross-compiling...
|
||||
export PKG_CONFIG=/usr/bin/pkg-config
|
||||
./configure --prefix=/usr --host=arm-linux --with-gnu-ld --disable-static \
|
||||
--disable-glib --with-osip=$ARM_INSTALL_TREE/usr \
|
||||
--with-readline=$ARM_INSTALL_TREE/usr \
|
||||
SPEEX_CFLAGS="-I$ARM_INSTALL_TREE/usr/include" \
|
||||
SPEEX_LIBS="-L$ARM_INSTALL_TREE/usr/lib -lspeex "
|
||||
make
|
||||
make install DESTDIR='pwd'/armbuild
|
||||
|
||||
You can use the install trees libosip2-x.x.x/armbuild speex-x.x.x/armbuild and
|
||||
linphone-0.x.x/armbuild/ to make binary packages of
|
||||
each software, as ipkgs for the familiar distribution (http://www.familiar.org).
|
||||
In the ipkg/ directory of linphone you can find .control files for ipkg-build.
|
||||
In order to make the osip ipkg, you have to do the following:
|
||||
- create a directory named CONTROL inside libosip2-2.2.x/armbuild
|
||||
- copy the libosip.control file into CONTROL/ and rename it into "control".
|
||||
- edit the "control" file to adjust version number accordingly.
|
||||
- remove the non essential parts of libosip inside libosip2-2.x.x/armbuild/usr/ : just
|
||||
leave the lib/ directory. This saves space on the destination computer.
|
||||
- then inside libosip2-2.x.x, run ipkg-build -o root -g root armbuild
|
||||
The same procedure applies to make linphone's ipkg.
|
||||
Binaries can also be stripped with arm-linux-strip to save more space.
|
||||
|
||||
Running linphone under the handheld computer
|
||||
********************************************
|
||||
|
||||
You just have to start linphone from a terminal by typing 'linphonec'.
|
||||
|
||||
Simon
|
||||
22
linphone/TODO
Normal file
22
linphone/TODO
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
hot stuff:
|
||||
---------
|
||||
|
||||
* ice support
|
||||
* run a user given command upon incoming calls
|
||||
* linphonec on win32
|
||||
* RTP inactivity timeout to close lost calls.
|
||||
|
||||
|
||||
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.
|
||||
26
linphone/autogen.sh
Executable file
26
linphone/autogen.sh
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
|
||||
AM_VERSION="1.9"
|
||||
if ! type aclocal-$AM_VERSION 1>/dev/null 2>&1; then
|
||||
# automake-1.9 (recommended) is not available on Fedora 8
|
||||
AUTOMAKE=automake
|
||||
ACLOCAL=aclocal
|
||||
else
|
||||
ACLOCAL=aclocal-${AM_VERSION}
|
||||
AUTOMAKE=automake-${AM_VERSION}
|
||||
fi
|
||||
|
||||
echo "Generating build scripts in linphone..."
|
||||
set -x
|
||||
libtoolize --copy --force
|
||||
autoheader
|
||||
$ACLOCAL -I m4
|
||||
$AUTOMAKE --force-missing --add-missing --copy
|
||||
autoconf
|
||||
rm -rf config.cache
|
||||
|
||||
echo "Generating build scripts in oRTP..."
|
||||
cd oRTP && ./autogen.sh && cd -
|
||||
|
||||
echo "Generating build scripts in mediastreamer2..."
|
||||
cd mediastreamer2 && ./autogen.sh && cd -
|
||||
140
linphone/build.mk
Executable file
140
linphone/build.mk
Executable file
|
|
@ -0,0 +1,140 @@
|
|||
#!/usr/bin/make -f
|
||||
# This script "automatically" builds some binary distribution of linphone :
|
||||
# debian packages (sid) and familiar (arm-linux/ipaq) packages.
|
||||
# generation of rpms can be added in the future.
|
||||
# it can be invoked in the following way:
|
||||
# ./build.mk debs LINPHONE=<path to linphone's tar.gz>
|
||||
# ./build.mk all LINPHONE=<path to linphone's tar.gz> GLIB=<path to glib>2.2's tar.gz>
|
||||
# LIBOSIP=<path to libosip's tar.gz>
|
||||
#
|
||||
|
||||
|
||||
ARMROOT=/armbuild
|
||||
ARMTOOLCHAIN=/usr/local/arm/3.2.3/bin
|
||||
|
||||
all: check debs ipks
|
||||
|
||||
|
||||
clean:
|
||||
rm -f *.stamp
|
||||
rm -rf build-debs
|
||||
rm -rf build-ipks
|
||||
|
||||
check:
|
||||
@if test -n "${LD_PRELOAD}" ; then echo "ERROR: LD_PRELOAD is set !!"; exit 1;fi
|
||||
|
||||
ipks: ipkg-tools.stamp libosip.ipk linphone.ipk clean
|
||||
|
||||
ipkg-tools.stamp:
|
||||
if which ipkg-build ; then echo "Found ipkg-build." ;\
|
||||
else echo "** ERROR ** Cannot find ipkg-build"; exit 1; fi
|
||||
if test -e $(ARMTOOLCHAIN)/arm-linux-gcc ; then \
|
||||
echo "arm toolchain seems ok.";\
|
||||
else echo "** ERROR ** Cannot find arm toolchain."; exit 1; fi
|
||||
touch ipkg-tools.stamp
|
||||
|
||||
glib.ipk : glib.stamp linphone-sources-ipk.stamp
|
||||
rm -rf build-ipks/glib*
|
||||
cp $(GLIB) build-ipks/.
|
||||
export CONFIG_SITE=`pwd`/build-ipks/ipaq-config.site && \
|
||||
cd build-ipks && tar -xvzf glib*.tar.gz && rm -f glib*.tar.gz && cd glib* && \
|
||||
./configure --prefix=$(ARMROOT)/usr --host=arm-linux --with-gnu-ld --disable-static \
|
||||
&& make AM_CFLAGS=-DSSIZE_MAX=0xffffffff && make install && \
|
||||
make install prefix=`pwd`$(ARMROOT)/usr
|
||||
echo "Building .ipk file..."
|
||||
cd build-ipks/glib*$(ARMROOT) && mkdir CONTROL && cd CONTROL && \
|
||||
cp ../../../linphone*/ipkg/glib.control control && \
|
||||
cd ../.. && rm -rf armbuild/usr/include
|
||||
cd build-ipks/glib* && ipkg-build -o root -g root armbuild/
|
||||
cp build-ipks/glib*/*.ipk .
|
||||
|
||||
libosip.ipk : libosip.stamp linphone-sources-ipk.stamp
|
||||
rm -rf build-ipks/libosip*
|
||||
cp $(LIBOSIP) build-ipks/
|
||||
export CONFIG_SITE=`pwd`/build-ipks/ipaq-config.site && \
|
||||
cd build-ipks && tar -xvzf libosip*.tar.gz && rm -f libosip*.tar.gz && cd libosip* && \
|
||||
./configure --prefix=$(ARMROOT)/usr --host=arm-linux --with-gnu-ld --disable-static \
|
||||
&& make && make install && make install prefix=`pwd`$(ARMROOT)/usr
|
||||
echo "Building .ipk file..."
|
||||
cd build-ipks/libosip*$(ARMROOT) && mkdir CONTROL && cd CONTROL && \
|
||||
cp ../../../linphone*/ipkg/libosip.control control &&\
|
||||
cd ../.. && rm -rf armbuild/usr/include
|
||||
cd build-ipks/libosip* && ipkg-build -o root -g root armbuild/
|
||||
cp build-ipks/libosip*/*.ipk .
|
||||
|
||||
|
||||
linphone.ipk : linphone.stamp linphone-sources-ipk.stamp
|
||||
export CONFIG_SITE=`pwd`/build-ipks/ipaq-config.site && \
|
||||
cd build-ipks/linphone* && export PKG_CONFIG_PATH=$(ARMROOT)/usr/lib/pkgconfig &&\
|
||||
./configure --prefix=$(ARMROOT)/usr --with-realprefix=/usr --host=arm-linux \
|
||||
--with-gnu-ld --disable-static --disable-gnome_ui --disable-glib --with-osip=$(ARMROOT)/usr \
|
||||
--disable-ogg --disable-rtcp && make && make install prefix=`pwd`$(ARMROOT)/usr
|
||||
echo "Building .ipk file..."
|
||||
cd build-ipks/linphone*$(ARMROOT) && mkdir -p CONTROL && cd CONTROL && \
|
||||
cp -f ../../ipkg/linphone.control control &&\
|
||||
cd ../.. && rm -rf armbuild/usr/include armbuild/usr/share/gtk-doc \
|
||||
&& cd armbuild/usr/share/sounds/linphone/rings && \
|
||||
rm -f rock.wav sweet.wav bigben.wav toy.wav tapping.wav synth.wav && cd - \
|
||||
cd build-ipks/linphone* && ipkg-build -o root -g root armbuild/
|
||||
cp -f build-ipks/linphone*/*.ipk .
|
||||
|
||||
build-ipks.stamp:
|
||||
-@touch $(ARMROOT)/dummy
|
||||
@if test -e $(ARMROOT)/dummy ; \
|
||||
then echo "armroot is fine: $(ARMROOT)"; \
|
||||
else \
|
||||
echo "** ERROR: you need to create a $(ARMROOT) directory readable and writeable by the user running this build script.";\
|
||||
exit 1;\
|
||||
fi
|
||||
rm -f $(ARMROOT)/dummy
|
||||
touch build-ipks.stamp
|
||||
mkdir build-ipks
|
||||
|
||||
|
||||
linphone-sources-ipk.stamp: linphone.stamp build-ipks.stamp
|
||||
cp $(LINPHONE) build-ipks/.
|
||||
cd build-ipks && tar -xvzf linphone*.tar.gz && cp linphone*/ipkg/ipaq-config.site . \
|
||||
&& rm -f linphone*.tar.gz
|
||||
touch linphone-sources-ipk.stamp
|
||||
|
||||
debs: linphone.stamp clean
|
||||
rm -f linphone.stamp
|
||||
rm -rf build-debs
|
||||
mkdir build-debs
|
||||
cp $(LINPHONE) build-debs/.
|
||||
cd build-debs && tar -xvzf *.tar.gz && cd linphone* && dpkg-buildpackage -rfakeroot
|
||||
cp build-debs/*.deb .
|
||||
|
||||
linphone.stamp:
|
||||
@if test -n "$(LINPHONE)" ; \
|
||||
then echo "linphone source is $(LINPHONE)" ; \
|
||||
touch linphone.stamp; \
|
||||
else \
|
||||
echo "No linphone source found." ; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
libosip.stamp:
|
||||
@if test -n "$(LIBOSIP)" ; \
|
||||
then echo "libosip source is $(LIBOSIP)" ; \
|
||||
touch libosip.stamp; \
|
||||
else \
|
||||
echo "No libosip source found." ; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
glib.stamp:
|
||||
@if test -n "$(GLIB)" ; \
|
||||
then echo "glib source is $(GLIB)" ; \
|
||||
else \
|
||||
echo "No glib source found." ; \
|
||||
exit -1; \
|
||||
fi
|
||||
@if which glib-genmarshal ; \
|
||||
then \
|
||||
echo "native glib-2.2 found on build host." ; \
|
||||
touch glib.stamp ;\
|
||||
else \
|
||||
echo "** ERROR ** You need a working glib>2.2 on the build machine to be able to crosscompile it for arm." ;\
|
||||
echo "** ERROR ** Please install a glib on this machine."; exit 1; \
|
||||
fi
|
||||
614
linphone/config.rpath
Executable file
614
linphone/config.rpath
Executable file
|
|
@ -0,0 +1,614 @@
|
|||
#! /bin/sh
|
||||
# Output a system dependent set of variables, describing how to set the
|
||||
# run time search path of shared libraries in an executable.
|
||||
#
|
||||
# Copyright 1996-2006 Free Software Foundation, Inc.
|
||||
# Taken from GNU libtool, 2001
|
||||
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# The first argument passed to this file is the canonical host specification,
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
|
||||
# or
|
||||
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
|
||||
# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
|
||||
# should be set by the caller.
|
||||
#
|
||||
# The set of defined variables is at the end of this script.
|
||||
|
||||
# Known limitations:
|
||||
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
|
||||
# than 256 bytes, otherwise the compiler driver will dump core. The only
|
||||
# known workaround is to choose shorter directory names for the build
|
||||
# directory and/or the installation directory.
|
||||
|
||||
# All known linkers require a `.a' archive for static linking (except MSVC,
|
||||
# which needs '.lib').
|
||||
libext=a
|
||||
shrext=.so
|
||||
|
||||
host="$1"
|
||||
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
|
||||
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
|
||||
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
|
||||
# Code taken from libtool.m4's _LT_CC_BASENAME.
|
||||
|
||||
for cc_temp in $CC""; do
|
||||
case $cc_temp in
|
||||
compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
|
||||
distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
|
||||
\-*) ;;
|
||||
*) break;;
|
||||
esac
|
||||
done
|
||||
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
|
||||
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
|
||||
|
||||
wl=
|
||||
if test "$GCC" = yes; then
|
||||
wl='-Wl,'
|
||||
else
|
||||
case "$host_os" in
|
||||
aix*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
darwin*)
|
||||
case $cc_basename in
|
||||
xlc*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
mingw* | pw32* | os2*)
|
||||
;;
|
||||
hpux9* | hpux10* | hpux11*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
irix5* | irix6* | nonstopux*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
newsos6)
|
||||
;;
|
||||
linux*)
|
||||
case $cc_basename in
|
||||
icc* | ecc*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
pgcc | pgf77 | pgf90)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
ccc*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
como)
|
||||
wl='-lopt='
|
||||
;;
|
||||
*)
|
||||
case `$CC -V 2>&1 | sed 5q` in
|
||||
*Sun\ C*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
osf3* | osf4* | osf5*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
sco3.2v5*)
|
||||
;;
|
||||
solaris*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
sunos4*)
|
||||
wl='-Qoption ld '
|
||||
;;
|
||||
sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
sysv4*MP*)
|
||||
;;
|
||||
unicos*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
uts4*)
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
|
||||
|
||||
hardcode_libdir_flag_spec=
|
||||
hardcode_libdir_separator=
|
||||
hardcode_direct=no
|
||||
hardcode_minus_L=no
|
||||
|
||||
case "$host_os" in
|
||||
cygwin* | mingw* | pw32*)
|
||||
# FIXME: the MSVC++ port hasn't been tested in a loooong time
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++.
|
||||
if test "$GCC" != yes; then
|
||||
with_gnu_ld=no
|
||||
fi
|
||||
;;
|
||||
interix*)
|
||||
# we just hope/assume this is gcc and not c89 (= MSVC++)
|
||||
with_gnu_ld=yes
|
||||
;;
|
||||
openbsd*)
|
||||
with_gnu_ld=no
|
||||
;;
|
||||
esac
|
||||
|
||||
ld_shlibs=yes
|
||||
if test "$with_gnu_ld" = yes; then
|
||||
# Set some defaults for GNU ld with shared library support. These
|
||||
# are reset later if shared libraries are not supported. Putting them
|
||||
# here allows them to be overridden if necessary.
|
||||
# Unlike libtool, we use -rpath here, not --rpath, since the documented
|
||||
# option of GNU ld is called -rpath, not --rpath.
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
case "$host_os" in
|
||||
aix3* | aix4* | aix5*)
|
||||
# On AIX/PPC, the GNU linker is very broken
|
||||
if test "$host_cpu" != ia64; then
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
amigaos*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_minus_L=yes
|
||||
# Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
|
||||
# that the semantics of dynamic libraries on AmigaOS, at least up
|
||||
# to version 4, is to share data among multiple programs linked
|
||||
# with the same dynamic library. Since this doesn't match the
|
||||
# behavior of shared libraries on other platforms, we cannot use
|
||||
# them.
|
||||
ld_shlibs=no
|
||||
;;
|
||||
beos*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
cygwin* | mingw* | pw32*)
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
# no search path for DLLs.
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
interix3*)
|
||||
hardcode_direct=no
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
;;
|
||||
linux*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
netbsd*)
|
||||
;;
|
||||
solaris*)
|
||||
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
|
||||
ld_shlibs=no
|
||||
elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
|
||||
case `$LD -v 2>&1` in
|
||||
*\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
|
||||
ld_shlibs=no
|
||||
;;
|
||||
*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
sunos4*)
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if test "$ld_shlibs" = no; then
|
||||
hardcode_libdir_flag_spec=
|
||||
fi
|
||||
else
|
||||
case "$host_os" in
|
||||
aix3*)
|
||||
# Note: this linker hardcodes the directories in LIBPATH if there
|
||||
# are no directories specified by -L.
|
||||
hardcode_minus_L=yes
|
||||
if test "$GCC" = yes; then
|
||||
# Neither direct hardcoding nor static linking is supported with a
|
||||
# broken collect2.
|
||||
hardcode_direct=unsupported
|
||||
fi
|
||||
;;
|
||||
aix4* | aix5*)
|
||||
if test "$host_cpu" = ia64; then
|
||||
# On IA64, the linker does run time linking by default, so we don't
|
||||
# have to do anything special.
|
||||
aix_use_runtimelinking=no
|
||||
else
|
||||
aix_use_runtimelinking=no
|
||||
# Test if we are trying to use run time linking or normal
|
||||
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
|
||||
# need to do runtime linking.
|
||||
case $host_os in aix4.[23]|aix4.[23].*|aix5*)
|
||||
for ld_flag in $LDFLAGS; do
|
||||
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
|
||||
aix_use_runtimelinking=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
hardcode_direct=yes
|
||||
hardcode_libdir_separator=':'
|
||||
if test "$GCC" = yes; then
|
||||
case $host_os in aix4.[012]|aix4.[012].*)
|
||||
collect2name=`${CC} -print-prog-name=collect2`
|
||||
if test -f "$collect2name" && \
|
||||
strings "$collect2name" | grep resolve_lib_name >/dev/null
|
||||
then
|
||||
# We have reworked collect2
|
||||
hardcode_direct=yes
|
||||
else
|
||||
# We have old collect2
|
||||
hardcode_direct=unsupported
|
||||
hardcode_minus_L=yes
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_libdir_separator=
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# Begin _LT_AC_SYS_LIBPATH_AIX.
|
||||
echo 'int main () { return 0; }' > conftest.c
|
||||
${CC} ${LDFLAGS} conftest.c -o conftest
|
||||
aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
|
||||
}'`
|
||||
if test -z "$aix_libpath"; then
|
||||
aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
|
||||
}'`
|
||||
fi
|
||||
if test -z "$aix_libpath"; then
|
||||
aix_libpath="/usr/lib:/lib"
|
||||
fi
|
||||
rm -f conftest.c conftest
|
||||
# End _LT_AC_SYS_LIBPATH_AIX.
|
||||
if test "$aix_use_runtimelinking" = yes; then
|
||||
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
|
||||
else
|
||||
if test "$host_cpu" = ia64; then
|
||||
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
|
||||
else
|
||||
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
amigaos*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_minus_L=yes
|
||||
# see comment about different semantics on the GNU ld section
|
||||
ld_shlibs=no
|
||||
;;
|
||||
bsdi[45]*)
|
||||
;;
|
||||
cygwin* | mingw* | pw32*)
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++.
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
# no search path for DLLs.
|
||||
hardcode_libdir_flag_spec=' '
|
||||
libext=lib
|
||||
;;
|
||||
darwin* | rhapsody*)
|
||||
hardcode_direct=no
|
||||
if test "$GCC" = yes ; then
|
||||
:
|
||||
else
|
||||
case $cc_basename in
|
||||
xlc*)
|
||||
;;
|
||||
*)
|
||||
ld_shlibs=no
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
dgux*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
;;
|
||||
freebsd1*)
|
||||
ld_shlibs=no
|
||||
;;
|
||||
freebsd2.2*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
freebsd2*)
|
||||
hardcode_direct=yes
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
freebsd* | kfreebsd*-gnu | dragonfly*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
hpux9*)
|
||||
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
hardcode_direct=yes
|
||||
# hardcode_minus_L: Not really in the search PATH,
|
||||
# but as the default location of the library.
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
hpux10*)
|
||||
if test "$with_gnu_ld" = no; then
|
||||
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
hardcode_direct=yes
|
||||
# hardcode_minus_L: Not really in the search PATH,
|
||||
# but as the default location of the library.
|
||||
hardcode_minus_L=yes
|
||||
fi
|
||||
;;
|
||||
hpux11*)
|
||||
if test "$with_gnu_ld" = no; then
|
||||
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
case $host_cpu in
|
||||
hppa*64*|ia64*)
|
||||
hardcode_direct=no
|
||||
;;
|
||||
*)
|
||||
hardcode_direct=yes
|
||||
# hardcode_minus_L: Not really in the search PATH,
|
||||
# but as the default location of the library.
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
irix5* | irix6* | nonstopux*)
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
netbsd*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
newsos6)
|
||||
hardcode_direct=yes
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
openbsd*)
|
||||
hardcode_direct=yes
|
||||
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
else
|
||||
case "$host_os" in
|
||||
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
;;
|
||||
*)
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
os2*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
osf3*)
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
osf4* | osf5*)
|
||||
if test "$GCC" = yes; then
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
else
|
||||
# Both cc and cxx compiler support -rpath directly
|
||||
hardcode_libdir_flag_spec='-rpath $libdir'
|
||||
fi
|
||||
hardcode_libdir_separator=:
|
||||
;;
|
||||
solaris*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
;;
|
||||
sunos4*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
hardcode_direct=yes
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
sysv4)
|
||||
case $host_vendor in
|
||||
sni)
|
||||
hardcode_direct=yes # is this really true???
|
||||
;;
|
||||
siemens)
|
||||
hardcode_direct=no
|
||||
;;
|
||||
motorola)
|
||||
hardcode_direct=no #Motorola manual says yes, but my tests say they lie
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
sysv4.3*)
|
||||
;;
|
||||
sysv4*MP*)
|
||||
if test -d /usr/nec; then
|
||||
ld_shlibs=yes
|
||||
fi
|
||||
;;
|
||||
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
|
||||
;;
|
||||
sysv5* | sco3.2v5* | sco5v6*)
|
||||
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
|
||||
hardcode_libdir_separator=':'
|
||||
;;
|
||||
uts4*)
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
;;
|
||||
*)
|
||||
ld_shlibs=no
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Check dynamic linker characteristics
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
|
||||
libname_spec='lib$name'
|
||||
case "$host_os" in
|
||||
aix3*)
|
||||
;;
|
||||
aix4* | aix5*)
|
||||
;;
|
||||
amigaos*)
|
||||
;;
|
||||
beos*)
|
||||
;;
|
||||
bsdi[45]*)
|
||||
;;
|
||||
cygwin* | mingw* | pw32*)
|
||||
shrext=.dll
|
||||
;;
|
||||
darwin* | rhapsody*)
|
||||
shrext=.dylib
|
||||
;;
|
||||
dgux*)
|
||||
;;
|
||||
freebsd1*)
|
||||
;;
|
||||
kfreebsd*-gnu)
|
||||
;;
|
||||
freebsd* | dragonfly*)
|
||||
;;
|
||||
gnu*)
|
||||
;;
|
||||
hpux9* | hpux10* | hpux11*)
|
||||
case $host_cpu in
|
||||
ia64*)
|
||||
shrext=.so
|
||||
;;
|
||||
hppa*64*)
|
||||
shrext=.sl
|
||||
;;
|
||||
*)
|
||||
shrext=.sl
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
interix3*)
|
||||
;;
|
||||
irix5* | irix6* | nonstopux*)
|
||||
case "$host_os" in
|
||||
irix5* | nonstopux*)
|
||||
libsuff= shlibsuff=
|
||||
;;
|
||||
*)
|
||||
case $LD in
|
||||
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
|
||||
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
|
||||
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
|
||||
*) libsuff= shlibsuff= ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
linux*oldld* | linux*aout* | linux*coff*)
|
||||
;;
|
||||
linux*)
|
||||
;;
|
||||
knetbsd*-gnu)
|
||||
;;
|
||||
netbsd*)
|
||||
;;
|
||||
newsos6)
|
||||
;;
|
||||
nto-qnx*)
|
||||
;;
|
||||
openbsd*)
|
||||
;;
|
||||
os2*)
|
||||
libname_spec='$name'
|
||||
shrext=.dll
|
||||
;;
|
||||
osf3* | osf4* | osf5*)
|
||||
;;
|
||||
solaris*)
|
||||
;;
|
||||
sunos4*)
|
||||
;;
|
||||
sysv4 | sysv4.3*)
|
||||
;;
|
||||
sysv4*MP*)
|
||||
;;
|
||||
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
|
||||
;;
|
||||
uts4*)
|
||||
;;
|
||||
esac
|
||||
|
||||
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
|
||||
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
|
||||
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
|
||||
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
|
||||
|
||||
# How to pass a linker flag through the compiler.
|
||||
wl="$escaped_wl"
|
||||
|
||||
# Static library suffix (normally "a").
|
||||
libext="$libext"
|
||||
|
||||
# Shared library suffix (normally "so").
|
||||
shlibext="$shlibext"
|
||||
|
||||
# Flag to hardcode \$libdir into a binary during linking.
|
||||
# This must work even if \$libdir does not exist.
|
||||
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
|
||||
|
||||
# Whether we need a single -rpath flag with a separated argument.
|
||||
hardcode_libdir_separator="$hardcode_libdir_separator"
|
||||
|
||||
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
|
||||
# resulting binary.
|
||||
hardcode_direct="$hardcode_direct"
|
||||
|
||||
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
|
||||
# resulting binary.
|
||||
hardcode_minus_L="$hardcode_minus_L"
|
||||
|
||||
EOF
|
||||
378
linphone/configure.in
Normal file
378
linphone/configure.in
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([linphone],[2.99.4],[linphone-developers@nongnu.org])
|
||||
|
||||
dnl Source packaging numbers
|
||||
|
||||
LINPHONE_MAJOR_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f1)
|
||||
LINPHONE_MINOR_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f2)
|
||||
LINPHONE_MICRO_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f3)
|
||||
LINPHONE_EXTRA_VERSION=$(echo $PACKAGE_VERSION | cut -d. -f4)
|
||||
|
||||
dnl program extension
|
||||
LINPHONE_VERSION=$LINPHONE_MAJOR_VERSION.$LINPHONE_MINOR_VERSION.${LINPHONE_MICRO_VERSION}.${LINPHONE_EXTRA_VERSION}
|
||||
|
||||
LIBLINPHONE_SO_VERSION=`expr $LINPHONE_MINOR_VERSION + $LINPHONE_MAJOR_VERSION`:$LINPHONE_MICRO_VERSION:$LINPHONE_MINOR_VERSION
|
||||
|
||||
AC_SUBST(LIBLINPHONE_SO_VERSION, $LIBLINPHONE_SO_VERSION)
|
||||
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])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
AC_SUBST([mkdir_p])
|
||||
AC_ISC_POSIX
|
||||
AC_PROG_CC
|
||||
AC_C_INLINE
|
||||
AM_PROG_CC_STDC
|
||||
AC_HEADER_STDC
|
||||
dnl localization tools
|
||||
ifdef([IT_PROG_INTLTOOL],[IT_PROG_INTLTOOL],[AC_PROG_INTLTOOL])
|
||||
dnl Initialize libtool
|
||||
AC_PROG_LIBTOOL
|
||||
AM_PROG_LIBTOOL
|
||||
AC_ENABLE_SHARED(yes)
|
||||
AC_ENABLE_STATIC(no)
|
||||
dnl Add the languages which your application supports here.
|
||||
PKG_PROG_PKG_CONFIG
|
||||
ALL_LINGUAS="fr it de ja es pl cs nl sv pt_BR hu"
|
||||
GETTEXT_PACKAGE=linphone
|
||||
AM_GNU_GETTEXT([external])
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",[The name of the gettext package name])
|
||||
AC_CHECK_LIB(intl,libintl_gettext)
|
||||
|
||||
AC_CHECK_FUNCS([get_current_dir_name strndup stpcpy] )
|
||||
|
||||
dnl conditionnal build of console interface.
|
||||
AC_ARG_ENABLE(console_ui,
|
||||
[ --enable-console_ui=[yes/no] Turn on or off compilation of console interface [default=yes]],
|
||||
[case "${enableval}" in
|
||||
yes) console_ui=true ;;
|
||||
no) console_ui=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-console_ui) ;;
|
||||
esac],[console_ui=true])
|
||||
|
||||
dnl conditionnal build of gtk interface.
|
||||
AC_ARG_ENABLE(gtk_ui,
|
||||
[ --enable-gtk_ui=[yes/no] Turn on or off compilation of gtk interface [default=yes]],
|
||||
[case "${enableval}" in
|
||||
yes) gtk_ui=true ;;
|
||||
no) gtk_ui=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-gtk_ui) ;;
|
||||
esac],[gtk_ui=true])
|
||||
|
||||
dnl conditionnal build of old gtk interface.
|
||||
AC_ARG_ENABLE(old-gtk_ui,
|
||||
[ --enable-old-gtk_ui=[yes/no] Turn on or off compilation of old gtk interface [default=no]],
|
||||
[case "${enableval}" in
|
||||
yes) old_gtk_ui=true ;;
|
||||
no) old_gtk_ui=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-old-gtk_ui) ;;
|
||||
esac],[old_gtk_ui=false])
|
||||
|
||||
if test "$gtk_ui" = "true" ; then
|
||||
PKG_CHECK_MODULES(LIBGTK, gtk+-2.0 >= 2.4.0 gthread-2.0, ,gtk_ui=false)
|
||||
AC_SUBST(LIBGTK_CFLAGS)
|
||||
AC_SUBST(LIBGTK_LIBS)
|
||||
|
||||
if test "$gtk_ui" = "true" ; then
|
||||
AC_DEFINE(HAVE_GTK,1,[Defined if we can use the gtk api])
|
||||
else
|
||||
missing_gtk_libs=true
|
||||
fi
|
||||
else
|
||||
echo "GTK interface compilation is disabled."
|
||||
fi
|
||||
|
||||
|
||||
if test "$gtk_ui" = "true" ; then
|
||||
PKG_CHECK_MODULES(GNOME_APPLETS, libpanelapplet-2.0 >= 2.0.0 ,
|
||||
build_gnome_applet=true,build_gnome_applet=false)
|
||||
AC_SUBST(GNOME_APPLETS_CFLAGS)
|
||||
AC_SUBST(GNOME_APPLETS_LIBS)
|
||||
PKG_CHECK_MODULES(LIBGLADE, libglade-2.0 >= 2.4.0 , glade_ui=true, glade_ui=false)
|
||||
AC_SUBST(LIBGLADE_CFLAGS)
|
||||
AC_SUBST(LIBGLADE_LIBS)
|
||||
else
|
||||
build_gnome_applet=false
|
||||
fi
|
||||
|
||||
|
||||
dnl os-specific problems not handled by existing macros.
|
||||
case "$host_os" in
|
||||
*freebsd*)
|
||||
LDFLAGS="$LDFLAGS -pthread"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$host_cpu" in
|
||||
*arm*)
|
||||
AC_DEFINE(__ARM__,1,[Defined if we are compiling for arm processor])
|
||||
use_arm_toolchain=yes
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_WITH( realprefix,
|
||||
[ --with-realprefix Set the real installation prefix. This option has to be used for cross-compilation only. (ex:/usr or /usr/local)[default=none] ],
|
||||
[ realprefix=${withval}],[ realprefix="none" ])
|
||||
|
||||
|
||||
|
||||
AC_ARG_ENABLE(manual,
|
||||
[ --disable-manual Do not attempt to build html linphone's user documentation],
|
||||
[case "${enableval}" in
|
||||
yes) build_manual=yes ;;
|
||||
no) build_manual=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-manual) ;;
|
||||
esac],[build_manual=yes])
|
||||
|
||||
|
||||
dnl enable ipv6 support
|
||||
AC_ARG_ENABLE(ipv6,
|
||||
[ --enable-ipv6 Turn on ipv6 support],
|
||||
[case "${enableval}" in
|
||||
yes) ipv6=true;;
|
||||
no) ipv6=false;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-ipv6) ;;
|
||||
esac],[ipv6=true])
|
||||
IPV6_CFLAGS=
|
||||
if test x$ipv6 = xtrue ; then
|
||||
IPV6_CFLAGS=-DINET6
|
||||
fi
|
||||
AC_SUBST(IPV6_CFLAGS)
|
||||
|
||||
dnl enable truespeech codec support
|
||||
AC_ARG_ENABLE(truespeech,
|
||||
[ --enable-truespeech Turn on TrueSpeech support (x86 only)],
|
||||
[case "${enableval}" in
|
||||
yes) truespeech=true;;
|
||||
no) truespeech=false;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-truespeech) ;;
|
||||
esac],[truespeech=false])
|
||||
TRUESPEECH_CFLAGS=
|
||||
if test x$truespeech = xtrue ; then
|
||||
TRUESPEECH_CFLAGS=-DTRUESPEECH
|
||||
fi
|
||||
AC_SUBST(TRUESPEECH_CFLAGS)
|
||||
AM_CONDITIONAL([BUILD_TRUESPEECH], [test x$truespeech = xtrue])
|
||||
|
||||
|
||||
|
||||
|
||||
dnl support for RSVP (by Vincent Maury)
|
||||
AC_ARG_ENABLE(rsvp,
|
||||
[ --enable-rsvp enable support for QoS reservations.],
|
||||
AC_DEFINE(VINCENT_MAURY_RSVP,1,[Tell whether RSVP support
|
||||
should be compiled.]) )
|
||||
|
||||
if test "x${prefix}" = "xNONE"; then
|
||||
prefix=${ac_default_prefix}
|
||||
fi
|
||||
|
||||
dnl Set PACKAGE_LOCALE_DIR in config.h.
|
||||
DATADIRNAME=share
|
||||
AC_DEFINE_UNQUOTED(PACKAGE_LOCALE_DIR, "${prefix}/${DATADIRNAME}/locale",[Defines the place where locales can be found])
|
||||
|
||||
AC_DEFINE_UNQUOTED(PACKAGE_DATA_DIR, "${prefix}/${DATADIRNAME}",[Defines the place where data are found])
|
||||
|
||||
dnl Set PACKAGE_SOUND_DIR in config.h.
|
||||
AC_DEFINE_UNQUOTED(PACKAGE_SOUND_DIR, "${prefix}/${DATADIRNAME}/sounds/linphone",[Defines the place where linphone sounds are found])
|
||||
|
||||
|
||||
dnl check if we have the getifaddrs() sytem call
|
||||
AC_CHECK_FUNCS(getifaddrs)
|
||||
|
||||
dnl check for osip2
|
||||
LP_CHECK_OSIP2
|
||||
|
||||
dnl setup flags for exosip library
|
||||
LP_SETUP_EXOSIP
|
||||
|
||||
if test "$console_ui" = "true" ; then
|
||||
dnl check gnu readline
|
||||
LP_CHECK_READLINE
|
||||
else
|
||||
echo "Console interface compilation is disabled."
|
||||
fi
|
||||
|
||||
AC_WORDS_BIGENDIAN
|
||||
|
||||
dnl normaly this should only by done by mediastreamer2/configure.ac
|
||||
dnl but to workaround bugs when cross-compiling for arm-linux,
|
||||
dnl we need to have SPEEX_LIBS defined
|
||||
dnl Furthermore it is good to repeat here all mediastreamer2 toggles
|
||||
dnl since top-level configure --help will not print them.
|
||||
|
||||
PKG_CHECK_MODULES(SPEEX, speex >= 1.1.6, build_speex=yes)
|
||||
AC_SUBST(SPEEX_LIBS)
|
||||
|
||||
dnl conditionnal build of video support
|
||||
AC_ARG_ENABLE(video,
|
||||
[ --enable-video Turn on video support compiling],
|
||||
[case "${enableval}" in
|
||||
yes) video=true ;;
|
||||
no) video=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-video) ;;
|
||||
esac],[video=true])
|
||||
|
||||
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 ])
|
||||
|
||||
if test "$video" = "true"; then
|
||||
AC_DEFINE(VIDEO_ENABLED,1,[defined if video support is available])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(alsa,
|
||||
[ --enable-alsa Turn on alsa native support compiling],
|
||||
[case "${enableval}" in
|
||||
yes) alsa=true ;;
|
||||
no) alsa=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-alsa) ;;
|
||||
esac],[alsa=true])
|
||||
|
||||
AC_ARG_ENABLE(artsc,
|
||||
[ --enable-artsc Turn on artsc (kde) sound input/output (auto) ],
|
||||
[case "${enableval}" in
|
||||
yes) artsc=true ;;
|
||||
no) artsc=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-artsc) ;;
|
||||
esac],[artsc=false])
|
||||
|
||||
AC_ARG_ENABLE(portaudio,
|
||||
[ --enable-portaudio Turn on portaudio native support compiling],
|
||||
[case "${enableval}" in
|
||||
yes) portaudio=true ;;
|
||||
no) portaudio=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-portaudio) ;;
|
||||
esac],[portaudio=false])
|
||||
|
||||
dnl same thing for media_api
|
||||
AM_CONDITIONAL(BUILD_MEDIA_API, test x$media_api = xtrue)
|
||||
|
||||
|
||||
dnl build console if required
|
||||
AM_CONDITIONAL(BUILD_CONSOLE, test x$console_ui = xtrue)
|
||||
dnl build gtk if required
|
||||
AM_CONDITIONAL(BUILD_GTK, test x$old_gtk_ui = xtrue)
|
||||
dnl build gnome applet if possible
|
||||
AM_CONDITIONAL(BUILD_GNOME_APPLET, test x$build_gnome_applet = 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$glade_ui = xtrue ] )
|
||||
|
||||
##################################################
|
||||
# Stricter build options (after external packages)
|
||||
##################################################
|
||||
|
||||
|
||||
AC_ARG_ENABLE(strict,
|
||||
AC_HELP_STRING([--enable-strict],
|
||||
[Build with stricter options (gcc only) @<:@yes@:>@]),[
|
||||
strictness="${enableval}"],[strictness=yes]
|
||||
)
|
||||
|
||||
if test "$GCC$strictness" = "yesyes" ; then
|
||||
STRICT_OPTIONS="-Wall -Wp,-D_FORTIFY_SOURCE=2"
|
||||
STRICT_OPTIONS="$STRICT_OPTIONS -Werror"
|
||||
CFLAGS="$CFLAGS -fno-strict-aliasing"
|
||||
fi
|
||||
|
||||
AC_SUBST(STRICT_OPTIONS)
|
||||
|
||||
AC_CONFIG_SUBDIRS( mediastreamer2 )
|
||||
|
||||
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 -I${includedir}/ortp "
|
||||
LINPHONE_LIBS="-L${libdir} -llinphone"
|
||||
AC_SUBST(LINPHONE_CFLAGS)
|
||||
AC_SUBST(LINPHONE_LIBS)
|
||||
|
||||
|
||||
AC_DEFINE_UNQUOTED(LINPHONE_VERSION,"$PACKAGE_VERSION",[Linphone's version number])
|
||||
|
||||
|
||||
AC_ARG_ENABLE(external-ortp,
|
||||
[ --enable-external-ortp Use external oRTP library],
|
||||
[case "${enableval}" in
|
||||
yes) external_ortp=true ;;
|
||||
no) external_ortp=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-external-ortp) ;;
|
||||
esac],[external_ortp=false])
|
||||
|
||||
if test "$external_ortp" = 'true'; then
|
||||
LP_CHECK_ORTP
|
||||
else
|
||||
AC_CONFIG_SUBDIRS( oRTP )
|
||||
ORTP_CFLAGS="-I\$(top_srcdir)/oRTP/include"
|
||||
ORTP_LIBS="\$(top_builddir)/oRTP/src/libortp.la"
|
||||
if test x$ac_cv_c_bigendian = xyes ; then
|
||||
ORTP_CFLAGS="$ORTP_CFLAGS -DORTP_BIGENDIAN"
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(ORTP_CFLAGS)
|
||||
AC_SUBST(ORTP_LIBS)
|
||||
|
||||
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])
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
m4/Makefile
|
||||
po/Makefile.in
|
||||
pixmaps/Makefile
|
||||
ipkg/Makefile
|
||||
ipkg/linphone.control
|
||||
media_api/Makefile
|
||||
coreapi/Makefile
|
||||
gtk/Makefile
|
||||
gtk-glade/Makefile
|
||||
console/Makefile
|
||||
share/Makefile
|
||||
share/C/Makefile
|
||||
share/fr/Makefile
|
||||
share/it/Makefile
|
||||
share/ja/Makefile
|
||||
share/cs/Makefile
|
||||
share/linphone.pc
|
||||
linphone.spec
|
||||
])
|
||||
|
||||
echo "Linphone build configuration ended."
|
||||
|
||||
if test x$gtk_ui = xtrue ; then
|
||||
echo "* GTK interface will be compiled."
|
||||
fi
|
||||
if test x$gtk_ui = xtrue ; then
|
||||
echo "* Console interface will be compiled."
|
||||
fi
|
||||
if test x$glade_ui = xtrue ; then
|
||||
echo "* Gtk-glade still in early development interface will be compiled"
|
||||
fi
|
||||
if test "$have_db2html" = "no" ; then
|
||||
echo "* db2html not found; user documentation will not be generated."
|
||||
fi
|
||||
|
||||
echo "Now type 'make' to compile, and then 'make install' as root to install it."
|
||||
7
linphone/console/.cvsignore
Normal file
7
linphone/console/.cvsignore
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
linphonec
|
||||
sipomatic
|
||||
wav2raw
|
||||
37
linphone/console/Makefile.am
Normal file
37
linphone/console/Makefile.am
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
if BUILD_CONSOLE
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)\
|
||||
-I$(top_srcdir)/coreapi\
|
||||
$(ORTP_CFLAGS) \
|
||||
-I$(top_srcdir)/exosip \
|
||||
-I$(top_srcdir)/mediastreamer2/include
|
||||
|
||||
|
||||
|
||||
bin_PROGRAMS = linphonec sipomatic
|
||||
|
||||
linphonec_SOURCES = linphonec.c linphonec.h commands.c
|
||||
|
||||
linphonec_LDADD = $(top_builddir)/coreapi/liblinphone.la $(READLINE_LIBS) $(OSIP_LIBS)
|
||||
|
||||
sipomatic_SOURCES=\
|
||||
sipomatic.c sipomatic.h
|
||||
|
||||
sipomatic_LDADD= $(INTLLIBS) \
|
||||
$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(OSIP_LIBS)
|
||||
|
||||
endif
|
||||
|
||||
AM_CFLAGS=$(STRICT_OPTIONS) -DENABLE_TRACE -D_ORTP_SOURCE $(VIDEO_CFLAGS) $(READLINE_CFLAGS) $(OSIP_CFLAGS)
|
||||
|
||||
|
||||
|
||||
AM_LDFLAGS= $(top_builddir)/mediastreamer2/src/libmediastreamer.la \
|
||||
$(ORTP_LIBS) \
|
||||
$(SPEEX_LIBS) \
|
||||
$(OSIP_LIBS)
|
||||
|
||||
20
linphone/console/TODO
Normal file
20
linphone/console/TODO
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
In pseudo-order of priority:
|
||||
---------------------------
|
||||
|
||||
- Exctract presence info in friends list
|
||||
|
||||
- Allow friend call arg to be a pattern
|
||||
|
||||
- hide input during password insertions
|
||||
[ could use ncurses noecho() ]
|
||||
|
||||
- Allow for single-shot mode (call somebody and quit after the fact)
|
||||
maybe "linphonec [OPTS] <sip-uri>" would do..
|
||||
Unfortunately the -s switch would confuse people, I'd rather
|
||||
change its semantic to "source file" where file wold contain
|
||||
a list of commands, so ./linephone -s myfriend.sip would call
|
||||
yourfriend...
|
||||
|
||||
- implement "smart" command completion
|
||||
|
||||
1236
linphone/console/commands.c
Normal file
1236
linphone/console/commands.c
Normal file
File diff suppressed because it is too large
Load diff
51
linphone/console/example/linphonec
Normal file
51
linphone/console/example/linphonec
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# this file is used to store user config values for linphonec
|
||||
# please modify and copy it to ~/.linphonec
|
||||
#
|
||||
#
|
||||
|
||||
logfile=~/linphonec.log
|
||||
debuglevel=0
|
||||
|
||||
local_addr=192.168.1.10
|
||||
if_name=eth0
|
||||
# type of network connection 4 = ethernet
|
||||
con_type=4
|
||||
|
||||
|
||||
# rtp
|
||||
audio_rtp_port=7078
|
||||
jitt_comp=150
|
||||
|
||||
|
||||
# audio
|
||||
driver_mode=0
|
||||
rec_lev=100
|
||||
play_lev=100
|
||||
source=109
|
||||
autokill=0
|
||||
|
||||
|
||||
# sip
|
||||
sip_port=5060
|
||||
use_registrar=0
|
||||
username=1006
|
||||
hostname=192.168.1.1
|
||||
registrar=sip:192.168.1.1:5060
|
||||
reg_passwd=
|
||||
addr_of_rec=sip:1006@192.168.1.1
|
||||
reg_expires=900
|
||||
as_proxy=1
|
||||
as_redirect=0
|
||||
as_outbound=1
|
||||
|
||||
|
||||
# codecs
|
||||
audio_codecs=259 371 264 256
|
||||
|
||||
|
||||
# short dial
|
||||
s0=sip:1002@130.83.176.121
|
||||
s1=sip:1001@192.168.1.1
|
||||
s2=sip:1002@192.168.1.1
|
||||
s3=sip:1003@192.168.1.1
|
||||
s4=sip:1004@192.168.1.1
|
||||
1114
linphone/console/linphonec.c
Normal file
1114
linphone/console/linphonec.c
Normal file
File diff suppressed because it is too large
Load diff
134
linphone/console/linphonec.h
Normal file
134
linphone/console/linphonec.h
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* $Id: linphonec.h,v 1.3 2006/01/20 14:12:34 strk Exp $
|
||||
*
|
||||
* Copyright (C) 2005 Sandro Santilli <strk@keybit.net>
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef LINPHONEC_H
|
||||
#define LINPHONEC_H 1
|
||||
|
||||
#ifdef HAVE_READLINE_H
|
||||
#include <readline.h>
|
||||
#else
|
||||
#ifdef HAVE_READLINE_READLINE_H
|
||||
#include <readline/readline.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_HISTORY_H
|
||||
#include <history.h>
|
||||
#else
|
||||
#ifdef HAVE_READLINE_HISTORY_H
|
||||
#include <readline/history.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Compile-time defines
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#define HISTSIZE 500 /* how many lines of input history */
|
||||
#define PROMPT_MAX_LEN 256 /* max len of prompt string */
|
||||
#define LINE_MAX_LEN 256 /* really needed ? */
|
||||
|
||||
/*
|
||||
* Define this to have your primary contact
|
||||
* as the prompt string
|
||||
*/
|
||||
/* #define IDENTITY_AS_PROMPT 1 */
|
||||
|
||||
/*
|
||||
* Time between calls to linphonec_idle_call during main
|
||||
* input read loop in microseconds.
|
||||
*/
|
||||
#define LPC_READLINE_TIMEOUT 1000000
|
||||
|
||||
/*
|
||||
* Filename of linphonec history
|
||||
*/
|
||||
#define LPC_HIST_FILE "~/.linphonec_history"
|
||||
|
||||
/*
|
||||
* Maximum number of pending authentications
|
||||
*/
|
||||
#define MAX_PENDING_AUTH 8
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Types
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* A structure which contains information on the commands this program
|
||||
* can understand.
|
||||
*/
|
||||
typedef int (*lpc_cmd_handler)(LinphoneCore *, char *);
|
||||
typedef struct {
|
||||
char *name; /* User printable name of the function. */
|
||||
lpc_cmd_handler func; /* Function to call to do the job. */
|
||||
char *help; /* Short help for this function. */
|
||||
char *doc; /* Long description. */
|
||||
} LPC_COMMAND;
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Forward declarations
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
extern int linphonec_parse_command_line(LinphoneCore *lc, char *cl);
|
||||
extern char *linphonec_command_generator(const char *text, int state);
|
||||
extern void linphonec_finish(int exit_status);
|
||||
|
||||
#endif /* def LINPHONEC_H */
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* $Log: linphonec.h,v $
|
||||
* Revision 1.3 2006/01/20 14:12:34 strk
|
||||
* Added linphonec_init() and linphonec_finish() functions.
|
||||
* Handled SIGINT and SIGTERM to invoke linphonec_finish().
|
||||
* Handling of auto-termination (-t) moved to linphonec_finish().
|
||||
* Reworked main (input read) loop to not rely on 'terminate'
|
||||
* and 'run' variable (dropped). configfile_name allocated on stack
|
||||
* using PATH_MAX limit. Changed print_usage signature to allow
|
||||
* for an exit_status specification.
|
||||
*
|
||||
* Revision 1.2 2006/01/14 13:29:32 strk
|
||||
* Reworked commands interface to use a table structure,
|
||||
* used by command line parser and help function.
|
||||
* Implemented first level of completion (commands).
|
||||
* Added notification of invalid "answer" and "terminate"
|
||||
* commands (no incoming call, no active call).
|
||||
* Forbidden "call" intialization when a call is already active.
|
||||
* Cleaned up all commands, adding more feedback and error checks.
|
||||
*
|
||||
* Revision 1.1 2006/01/13 13:00:29 strk
|
||||
* Added linphonec.h. Code layout change (added comments, forward decl,
|
||||
* globals on top, copyright notices and Logs). Handled out-of-memory
|
||||
* condition on history management. Removed assumption on sizeof(char).
|
||||
* Fixed bug in authentication prompt (introduced by readline).
|
||||
* Added support for multiple authentication requests (up to MAX_PENDING_AUTH).
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
467
linphone/console/sipomatic.c
Normal file
467
linphone/console/sipomatic.c
Normal file
|
|
@ -0,0 +1,467 @@
|
|||
/***************************************************************************
|
||||
linphone - sipomatic.c
|
||||
This is a test program for linphone. It acts as a sip server and answers to linphone's
|
||||
call.
|
||||
-------------------
|
||||
begin : ven mar 30
|
||||
copyright : (C) 2001 by Simon MORLAT
|
||||
email : 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <signal.h>
|
||||
#include "sipomatic.h"
|
||||
#include <eXosip2/eXosip.h>
|
||||
|
||||
|
||||
int run_cond=1;
|
||||
|
||||
Sipomatic sipomatic;
|
||||
|
||||
int sipomatic_accept_audio_offer(sdp_context_t *ctx,sdp_payload_t *payload);
|
||||
int sipomatic_accept_video_offer(sdp_context_t *ctx,sdp_payload_t *payload);
|
||||
|
||||
|
||||
sdp_handler_t sipomatic_sdp_handler={
|
||||
sipomatic_accept_audio_offer, /*from remote sdp */
|
||||
sipomatic_accept_video_offer,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
void stop_handler(int signum)
|
||||
{
|
||||
run_cond=0;
|
||||
}
|
||||
|
||||
void sipomatic_process_event(Sipomatic *obj,eXosip_event_t *ev)
|
||||
{
|
||||
Call *call;
|
||||
switch(ev->type){
|
||||
case EXOSIP_CALL_INVITE:
|
||||
call_new(obj,ev);
|
||||
break;
|
||||
case EXOSIP_CALL_CLOSED:
|
||||
case EXOSIP_CALL_CANCELLED:
|
||||
call=sipomatic_find_call(obj,ev->did);
|
||||
if (call==NULL){
|
||||
ms_warning("Could not find call with did %i !",ev->did);
|
||||
}
|
||||
call_release(call);
|
||||
call_destroy(call);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
eXosip_event_free(ev);
|
||||
}
|
||||
|
||||
|
||||
void endoffile_cb(void *ud, unsigned int ev,void * arg){
|
||||
Call*call=(Call*)ud;
|
||||
call->eof=1;
|
||||
}
|
||||
|
||||
void call_accept(Call *call)
|
||||
{
|
||||
sdp_context_t *ctx;
|
||||
PayloadType *payload;
|
||||
char *hellofile;
|
||||
static int call_count=0;
|
||||
char record_file[250];
|
||||
osip_message_t *msg=NULL;
|
||||
sprintf(record_file,"/tmp/sipomatic%i.wav",call_count);
|
||||
|
||||
ctx=call->sdpc;
|
||||
payload=rtp_profile_get_payload(call->profile,call->audio.pt);
|
||||
if (strcmp(payload->mime_type,"telephone-event")==0){
|
||||
/* telephone-event is not enough to accept a call */
|
||||
ms_message("Cannot accept call with only telephone-event.\n");
|
||||
eXosip_call_send_answer(call->did,415,NULL);
|
||||
call->state=CALL_STATE_FINISHED;
|
||||
return;
|
||||
}
|
||||
if (payload->clock_rate==16000){
|
||||
hellofile=call->root->file_path16000hz;
|
||||
}else hellofile=call->root->file_path8000hz;
|
||||
eXosip_call_build_answer(call->tid,200,&msg);
|
||||
osip_message_set_content_type(msg,"application/sdp");
|
||||
osip_message_set_body(msg,call->sdpc->answerstr,strlen(call->sdpc->answerstr));
|
||||
eXosip_call_send_answer(call->tid,200,msg);
|
||||
call->audio_stream=audio_stream_new(call->audio.localport,call->root->ipv6);
|
||||
audio_stream_start_with_files(call->audio_stream, call->profile,
|
||||
call->audio.remaddr,call->audio.remoteport,call->audio.remoteport+1,
|
||||
call->audio.pt,20,hellofile,record_file);
|
||||
call_count++;
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->video.remoteport!=0){
|
||||
video_stream_send_only_start(call->video_stream,call->profile,
|
||||
call->video.remaddr,call->video.remoteport,call->video.remoteport+1,call->video.pt, 60,
|
||||
ms_web_cam_manager_get_default_cam(ms_web_cam_manager_get()));
|
||||
}
|
||||
#endif
|
||||
call->time=time(NULL);
|
||||
call->state=CALL_STATE_RUNNING;
|
||||
ms_filter_set_notify_callback(call->audio_stream->soundread,endoffile_cb,(void*)call);
|
||||
}
|
||||
|
||||
|
||||
PayloadType * sipomatic_payload_is_supported(sdp_payload_t *payload,RtpProfile *local_profile,RtpProfile *dialog_profile)
|
||||
{
|
||||
int localpt;
|
||||
if (payload->a_rtpmap!=NULL){
|
||||
localpt=rtp_profile_get_payload_number_from_rtpmap(local_profile,payload->a_rtpmap);
|
||||
}else{
|
||||
localpt=payload->pt;
|
||||
ms_warning("payload has no rtpmap.");
|
||||
}
|
||||
|
||||
if (localpt>=0){
|
||||
/* this payload is supported in our local rtp profile, so add it to the dialog rtp
|
||||
profile */
|
||||
PayloadType *rtppayload;
|
||||
rtppayload=rtp_profile_get_payload(local_profile,localpt);
|
||||
if (rtppayload==NULL) return NULL;
|
||||
/*check if we have the appropriate coder/decoder for this payload */
|
||||
if (strcmp(rtppayload->mime_type,"telephone-event")!=0) {
|
||||
if (!ms_filter_codec_supported(rtppayload->mime_type)) {
|
||||
ms_message("Codec %s is not supported.", rtppayload->mime_type);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
rtppayload=payload_type_clone(rtppayload);
|
||||
rtp_profile_set_payload(dialog_profile,payload->pt,rtppayload);
|
||||
/* add to the rtp payload type some other parameters (bandwidth) */
|
||||
if (payload->b_as_bandwidth!=0) rtppayload->normal_bitrate=payload->b_as_bandwidth*1000;
|
||||
if (payload->a_fmtp!=NULL)
|
||||
payload_type_set_send_fmtp(rtppayload,payload->a_fmtp);
|
||||
if (strcasecmp(rtppayload->mime_type,"iLBC")==0){
|
||||
/*default to 30 ms mode */
|
||||
payload->a_fmtp="ptime=30";
|
||||
payload_type_set_recv_fmtp(rtppayload,payload->a_fmtp);
|
||||
}
|
||||
return rtppayload;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int sipomatic_accept_audio_offer(sdp_context_t *ctx,sdp_payload_t *payload)
|
||||
{
|
||||
static int audioport=8000;
|
||||
Call *call=(Call*)sdp_context_get_user_pointer(ctx);
|
||||
PayloadType *supported;
|
||||
struct stream_params *params=&call->audio;
|
||||
|
||||
/* see if this codec is supported in our local rtp profile*/
|
||||
supported=sipomatic_payload_is_supported(payload,&av_profile,call->profile);
|
||||
if (supported==NULL) {
|
||||
ms_message("Refusing codec %i (%s)",payload->pt,payload->a_rtpmap);
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(supported->mime_type,"telephone-event")==0) return 0;
|
||||
if (params->ncodecs==0 ){
|
||||
/* this is the first codec we may accept*/
|
||||
params->localport=payload->localport=audioport;
|
||||
params->remoteport=payload->remoteport;
|
||||
params->line=payload->line;
|
||||
params->pt=payload->pt; /* remember the first payload accepted */
|
||||
params->remaddr=payload->c_addr;
|
||||
params->ncodecs++;
|
||||
audioport+=4;
|
||||
}else{
|
||||
/* refuse all other audio lines*/
|
||||
if(params->line!=payload->line) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sipomatic_accept_video_offer(sdp_context_t *ctx,sdp_payload_t *payload)
|
||||
{
|
||||
#ifdef VIDEO_ENABLED
|
||||
static int videoport=80000;
|
||||
Call *call=(Call*)sdp_context_get_user_pointer(ctx);
|
||||
PayloadType *supported;
|
||||
struct stream_params *params=&call->video;
|
||||
|
||||
/* see if this codec is supported in our local rtp profile*/
|
||||
supported=sipomatic_payload_is_supported(payload,&av_profile,call->profile);
|
||||
if (supported==NULL) {
|
||||
ms_message("Refusing video codec %i (%s)",payload->pt,payload->a_rtpmap);
|
||||
return -1;
|
||||
}
|
||||
if (params->ncodecs==0 ){
|
||||
/* this is the first codec we may accept*/
|
||||
params->localport=payload->localport=videoport;
|
||||
params->remoteport=payload->remoteport;
|
||||
params->line=payload->line;
|
||||
params->pt=payload->pt; /* remember the first payload accepted */
|
||||
params->remaddr=payload->c_addr;
|
||||
params->ncodecs++;
|
||||
videoport+=4;
|
||||
}else{
|
||||
/* refuse all other video lines*/
|
||||
if(params->line!=payload->line) return -1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sipomatic_init(Sipomatic *obj, char *url, bool_t ipv6)
|
||||
{
|
||||
osip_uri_t *uri=NULL;
|
||||
int port=5064;
|
||||
|
||||
obj->ipv6=ipv6;
|
||||
|
||||
if (url==NULL){
|
||||
url=getenv("SIPOMATIC_URL");
|
||||
if (url==NULL){
|
||||
if (ipv6) url="sip:robot@[::1]:5064";
|
||||
else url="sip:robot@127.0.0.1:5064";
|
||||
}
|
||||
}
|
||||
if (url!=NULL) {
|
||||
osip_uri_init(&uri);
|
||||
if (osip_uri_parse(uri,url)==0){
|
||||
if (uri->port!=NULL) port=atoi(uri->port);
|
||||
}else{
|
||||
ms_warning("Invalid identity uri:%s",url);
|
||||
}
|
||||
}
|
||||
ms_message("Starting using url %s",url);
|
||||
ms_mutex_init(&obj->lock,NULL);
|
||||
obj->calls=NULL;
|
||||
obj->acceptance_time=5;
|
||||
obj->max_call_time=300;
|
||||
obj->file_path8000hz=ms_strdup_printf("%s/%s",PACKAGE_SOUND_DIR,ANNOUCE_FILE8000HZ);
|
||||
obj->file_path16000hz=ms_strdup_printf("%s/%s",PACKAGE_SOUND_DIR,ANNOUCE_FILE16000HZ);
|
||||
osip_trace_initialize(OSIP_INFO1,stdout);
|
||||
osip_trace_initialize(OSIP_INFO2,stdout);
|
||||
osip_trace_initialize(OSIP_WARNING,stdout);
|
||||
osip_trace_initialize(OSIP_ERROR,stdout);
|
||||
osip_trace_initialize(OSIP_BUG,stdout);
|
||||
osip_trace_initialize(OSIP_FATAL,stdout);
|
||||
osip_trace_enable_level(OSIP_INFO1);
|
||||
osip_trace_enable_level(OSIP_INFO2);
|
||||
osip_trace_enable_level(OSIP_WARNING);
|
||||
osip_trace_enable_level(OSIP_ERROR);
|
||||
osip_trace_enable_level(OSIP_BUG);
|
||||
osip_trace_enable_level(OSIP_FATAL);
|
||||
eXosip_init();
|
||||
eXosip_set_user_agent("sipomatic-" LINPHONE_VERSION "/eXosip");
|
||||
eXosip_listen_addr(IPPROTO_UDP,NULL,port,ipv6 ? AF_INET6 : AF_INET,0);
|
||||
}
|
||||
|
||||
void sipomatic_uninit(Sipomatic *obj)
|
||||
{
|
||||
ms_mutex_destroy(&obj->lock);
|
||||
eXosip_quit();
|
||||
}
|
||||
|
||||
void sipomatic_iterate(Sipomatic *obj)
|
||||
{
|
||||
MSList *elem;
|
||||
MSList *to_be_destroyed=NULL;
|
||||
Call *call;
|
||||
double elapsed;
|
||||
eXosip_event_t *ev;
|
||||
|
||||
while((ev=eXosip_event_wait(0,0))!=NULL){
|
||||
sipomatic_process_event(obj,ev);
|
||||
}
|
||||
elem=obj->calls;
|
||||
while(elem!=NULL){
|
||||
call=(Call*)elem->data;
|
||||
elapsed=time(NULL)-call->time;
|
||||
switch(call->state){
|
||||
case CALL_STATE_INIT:
|
||||
if (elapsed>obj->acceptance_time){
|
||||
call_accept(call);
|
||||
}
|
||||
break;
|
||||
case CALL_STATE_RUNNING:
|
||||
if (elapsed>obj->max_call_time || call->eof){
|
||||
call_release(call);
|
||||
to_be_destroyed=ms_list_append(to_be_destroyed,call);
|
||||
}
|
||||
break;
|
||||
}
|
||||
elem=ms_list_next(elem);
|
||||
}
|
||||
for(;to_be_destroyed!=NULL; to_be_destroyed=ms_list_next(to_be_destroyed)){
|
||||
call_destroy((Call*)to_be_destroyed->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Call* sipomatic_find_call(Sipomatic *obj,int did)
|
||||
{
|
||||
MSList *it;
|
||||
Call *call=NULL;
|
||||
for (it=obj->calls;it!=NULL;it=ms_list_next(it)){
|
||||
call=(Call*)it->data;
|
||||
if ( call->did==did) return call;
|
||||
}
|
||||
return call;
|
||||
}
|
||||
|
||||
|
||||
Call * call_new(Sipomatic *root, eXosip_event_t *ev)
|
||||
{
|
||||
Call *obj;
|
||||
char *sdpans;
|
||||
int status;
|
||||
sdp_message_t *sdp;
|
||||
sdp_context_t *sdpc;
|
||||
|
||||
sdp=eXosip_get_sdp_info(ev->request);
|
||||
sdpc=sdp_handler_create_context(&sipomatic_sdp_handler,NULL,"sipomatic",NULL);
|
||||
obj=ms_new0(Call,1);
|
||||
obj->profile=rtp_profile_new("remote");
|
||||
eXosip_call_send_answer(ev->tid,100,NULL);
|
||||
sdp_context_set_user_pointer(sdpc,obj);
|
||||
sdpans=sdp_context_get_answer(sdpc,sdp);
|
||||
if (sdpans!=NULL){
|
||||
eXosip_call_send_answer(ev->tid,180,NULL);
|
||||
|
||||
}else{
|
||||
status=sdp_context_get_status(sdpc);
|
||||
eXosip_call_send_answer(ev->tid,status,NULL);
|
||||
sdp_context_free(sdpc);
|
||||
rtp_profile_destroy(obj->profile);
|
||||
ms_free(obj);
|
||||
return NULL;
|
||||
}
|
||||
obj->sdpc=sdpc;
|
||||
obj->did=ev->did;
|
||||
obj->tid=ev->tid;
|
||||
obj->time=time(NULL);
|
||||
obj->audio_stream=NULL;
|
||||
obj->state=CALL_STATE_INIT;
|
||||
obj->eof=0;
|
||||
obj->root=root;
|
||||
root->calls=ms_list_append(root->calls,obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void call_release(Call *call)
|
||||
{
|
||||
eXosip_call_terminate(0,call->did);
|
||||
if (call->audio_stream!=NULL) audio_stream_stop(call->audio_stream);
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->video_stream!=NULL) video_stream_send_only_stop(call->video_stream);
|
||||
#endif
|
||||
call->state=CALL_STATE_FINISHED;
|
||||
}
|
||||
|
||||
void call_destroy(Call *obj)
|
||||
{
|
||||
obj->root->calls=ms_list_remove(obj->root->calls,obj);
|
||||
rtp_profile_destroy(obj->profile);
|
||||
sdp_context_free(obj->sdpc);
|
||||
ms_free(obj);
|
||||
}
|
||||
|
||||
void sipomatic_set_annouce_file(Sipomatic *obj, char *file)
|
||||
{
|
||||
if (obj->file_path8000hz!=NULL){
|
||||
ms_free(obj->file_path8000hz);
|
||||
}
|
||||
obj->file_path8000hz=ms_strdup(file);
|
||||
}
|
||||
|
||||
|
||||
void display_help()
|
||||
{
|
||||
printf("sipomatic [-u sip-url] [-f annouce-file ] [-s port]\n"
|
||||
"sipomatic -h or --help: display this help.\n"
|
||||
"sipomatic -v or --version: display version information.\n"
|
||||
" -u sip-url : specify the sip url sipomatic listens and answers.\n"
|
||||
" -f annouce-file : set the annouce file (16 bit raw format,8000Hz)\n"
|
||||
" -6 enable ipv6 network usage\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
char *getarg(int argc, char*argv[], int i)
|
||||
{
|
||||
if (i<argc){
|
||||
return argv[i];
|
||||
}
|
||||
else display_help();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int sendport=5070;
|
||||
char *file=NULL;
|
||||
char *url=NULL;
|
||||
bool_t ipv6=FALSE;
|
||||
int i;
|
||||
|
||||
for(i=1;i<argc;i++){
|
||||
if ( (strcmp(argv[i],"-h")==0) || (strcmp(argv[i],"--help")==0) ){
|
||||
display_help();
|
||||
continue;
|
||||
}
|
||||
if ( (strcmp(argv[i],"-v")==0) || (strcmp(argv[i],"--version")==0) ){
|
||||
printf("version: " LINPHONE_VERSION "\n");
|
||||
exit(0);
|
||||
}
|
||||
if (strcmp(argv[i],"-u")==0){
|
||||
i++;
|
||||
url=getarg(argc,argv,i);
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i],"-s")==0){
|
||||
char *port;
|
||||
i++;
|
||||
port=getarg(argc,argv,i);
|
||||
sendport=atoi(port);
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i],"-f")==0){
|
||||
i++;
|
||||
file=getarg(argc,argv,i);
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i],"-6")==0){
|
||||
ipv6=TRUE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
signal(SIGINT,stop_handler);
|
||||
ortp_init();
|
||||
ms_init();
|
||||
ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
|
||||
rtp_profile_set_payload(&av_profile,115,&payload_type_lpc1015);
|
||||
rtp_profile_set_payload(&av_profile,110,&payload_type_speex_nb);
|
||||
rtp_profile_set_payload(&av_profile,111,&payload_type_speex_wb);
|
||||
rtp_profile_set_payload(&av_profile,112,&payload_type_ilbc);
|
||||
rtp_profile_set_payload(&av_profile,101,&payload_type_telephone_event);
|
||||
rtp_profile_set_payload(&av_profile,116,&payload_type_truespeech);
|
||||
rtp_profile_set_payload(&av_profile,98,&payload_type_h263_1998);
|
||||
|
||||
sipomatic_init(&sipomatic,url,ipv6);
|
||||
if (file!=NULL) sipomatic_set_annouce_file(&sipomatic,file);
|
||||
|
||||
while (run_cond){
|
||||
sipomatic_iterate(&sipomatic);
|
||||
usleep(20000);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
96
linphone/console/sipomatic.h
Normal file
96
linphone/console/sipomatic.h
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/***************************************************************************
|
||||
linphone - sipomatic.c
|
||||
This is a test program for linphone. It acts as a sip server and answers to linphone's
|
||||
call.
|
||||
-------------------
|
||||
begin : ven mar 30
|
||||
copyright : (C) 2001 by Simon MORLAT
|
||||
email : 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "../coreapi/linphonecore.h"
|
||||
#include "../coreapi/sdphandler.h"
|
||||
#include <eXosip2/eXosip.h>
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
#include "mediastreamer2/mediastream.h"
|
||||
|
||||
#include <ortp/ortp.h>
|
||||
#include <ortp/telephonyevents.h>
|
||||
|
||||
|
||||
#define ANNOUCE_FILE8000HZ "hello8000.wav"
|
||||
#define ANNOUCE_FILE16000HZ "hello16000.wav"
|
||||
|
||||
struct _Sipomatic
|
||||
{
|
||||
ms_mutex_t lock;
|
||||
MSList *calls;
|
||||
double acceptance_time;
|
||||
double max_call_time;
|
||||
char *file_path8000hz;
|
||||
char *file_path16000hz;
|
||||
bool_t ipv6;
|
||||
};
|
||||
|
||||
typedef struct _Sipomatic Sipomatic;
|
||||
|
||||
void sipomatic_init(Sipomatic *obj, char *url, bool_t ipv6);
|
||||
void sipomatic_uninit(Sipomatic *obj);
|
||||
void sipomatic_iterate(Sipomatic *obj);
|
||||
#define sipomatic_lock(obj) ms_mutex_lock(&(obj)->lock);
|
||||
#define sipomatic_unlock(obj) ms_mutex_unlock(&(obj)->lock);
|
||||
|
||||
void sipomatic_set_annouce_file(Sipomatic *obj, char *file);
|
||||
|
||||
struct stream_params{
|
||||
int ncodecs;
|
||||
int line;
|
||||
int localport;
|
||||
int remoteport;
|
||||
int pt;
|
||||
char *remaddr;
|
||||
};
|
||||
|
||||
struct _Call
|
||||
{
|
||||
Sipomatic *root;
|
||||
sdp_context_t *sdpc;
|
||||
int time;
|
||||
int did;
|
||||
int tid;
|
||||
AudioStream *audio_stream;
|
||||
#ifdef VIDEO_ENABLED
|
||||
VideoStream *video_stream;
|
||||
#endif
|
||||
int state;
|
||||
struct _CallParams *params;
|
||||
int eof;
|
||||
RtpProfile *profile;
|
||||
struct stream_params audio;
|
||||
struct stream_params video;
|
||||
};
|
||||
|
||||
#define CALL_STATE_INIT 0
|
||||
#define CALL_STATE_RUNNING 1
|
||||
#define CALL_STATE_FINISHED 2
|
||||
|
||||
typedef struct _Call Call;
|
||||
|
||||
|
||||
Call * call_new(Sipomatic *obj, eXosip_event_t *ev);
|
||||
void call_accept(Call *call);
|
||||
void call_release(Call *call);
|
||||
void call_destroy(Call *call);
|
||||
|
||||
Call* sipomatic_find_call(Sipomatic *obj,int cid);
|
||||
67
linphone/console/wav2raw.c
Normal file
67
linphone/console/wav2raw.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ifd,ofd;
|
||||
char *name,*p;
|
||||
char buf[200];
|
||||
int len;
|
||||
|
||||
if (argc<2) return -1;
|
||||
name=malloc(strlen(argv[1])+10);
|
||||
sprintf(name,"%s",argv[1]);
|
||||
p=strstr(name,".raw");
|
||||
if (p!=NULL){
|
||||
sprintf(p,"%s",".wav\0");
|
||||
}else{
|
||||
sprintf(name,"%s%s",argv[1],".raw");
|
||||
}
|
||||
|
||||
ifd=open(name,O_RDONLY);
|
||||
if (ifd<0) {
|
||||
perror("Could not open input file");
|
||||
return -1;
|
||||
}
|
||||
ofd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP);
|
||||
if (ofd<0) {
|
||||
perror("Could not open output file");
|
||||
return -1;
|
||||
}
|
||||
len=read(ifd,buf,20);
|
||||
printf("len=%i\n",len);
|
||||
/* erase the wav header */
|
||||
if (len>0){
|
||||
memset(buf,0,20);
|
||||
write(ofd,buf,20);
|
||||
}else{
|
||||
printf("Error while processing %s: %s\n",argv[1],strerror(errno));
|
||||
return -1;
|
||||
};
|
||||
|
||||
while ( (len=read(ifd,buf,200))>0){
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
for (i=0;i<len/2;i+=2){
|
||||
tmp=buf[i];
|
||||
buf[i]=buf[i+1];
|
||||
buf[i+1]=tmp;
|
||||
}
|
||||
#endif
|
||||
write(ofd,buf,len);
|
||||
}
|
||||
|
||||
close(ifd);
|
||||
close(ofd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
7
linphone/coreapi/.cvsignore
Normal file
7
linphone/coreapi/.cvsignore
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
*.lo
|
||||
*.la
|
||||
*.loT
|
||||
46
linphone/coreapi/Makefile.am
Normal file
46
linphone/coreapi/Makefile.am
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
linphone_includedir=$(includedir)/linphone
|
||||
|
||||
linphone_include_HEADERS=linphonecore.h ../config.h lpconfig.h
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)\
|
||||
-I$(top_srcdir)/mediastreamer2/include
|
||||
|
||||
|
||||
lib_LTLIBRARIES=liblinphone.la
|
||||
|
||||
liblinphone_la_SOURCES=\
|
||||
linphonecore.c linphonecore.h private.h\
|
||||
exevents.c exevents.h \
|
||||
misc.c \
|
||||
enum.c enum.h \
|
||||
sdphandler.c sdphandler.h \
|
||||
presence.c \
|
||||
proxy.c \
|
||||
friend.c \
|
||||
authentication.c \
|
||||
lpconfig.c lpconfig.h \
|
||||
chat.c \
|
||||
general_state.c
|
||||
|
||||
|
||||
liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION)
|
||||
|
||||
liblinphone_la_LIBADD= \
|
||||
$(EXOSIP_LIBS) \
|
||||
$(top_builddir)/mediastreamer2/src/libmediastreamer.la
|
||||
|
||||
|
||||
AM_CFLAGS=$(STRICT_OPTIONS) \
|
||||
$(OSIP_CFLAGS) \
|
||||
$(EXOSIP_CFLAGS) \
|
||||
$(ORTP_CFLAGS) \
|
||||
-DENABLE_TRACE \
|
||||
-DLOG_DOMAIN=\"LinphoneCore\" \
|
||||
$(IPV6_CFLAGS) \
|
||||
-DORTP_INET6 \
|
||||
$(VIDEO_CFLAGS)
|
||||
|
||||
273
linphone/coreapi/authentication.c
Normal file
273
linphone/coreapi/authentication.c
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
/***************************************************************************
|
||||
* authentication.c
|
||||
*
|
||||
* Fri Jul 16 12:08:34 2004
|
||||
* Copyright 2004 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "private.h"
|
||||
#include <eXosip2/eXosip.h>
|
||||
#include <osipparser2/osip_message.h>
|
||||
#include "lpconfig.h"
|
||||
|
||||
extern LinphoneProxyConfig *linphone_core_get_proxy_config_from_rid(LinphoneCore *lc, int rid);
|
||||
extern void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char *realm);
|
||||
extern void linphone_core_retry_proxy_register(LinphoneCore *lc, const char *realm);
|
||||
|
||||
LinphoneAuthInfo *linphone_auth_info_new(const char *username, const char *userid,
|
||||
const char *passwd, const char *ha1,const char *realm)
|
||||
{
|
||||
LinphoneAuthInfo *obj=ms_new0(LinphoneAuthInfo,1);
|
||||
if (username!=NULL && (strlen(username)>0) ) obj->username=ms_strdup(username);
|
||||
if (userid!=NULL && (strlen(userid)>0)) obj->userid=ms_strdup(userid);
|
||||
if (passwd!=NULL && (strlen(passwd)>0)) obj->passwd=ms_strdup(passwd);
|
||||
if (ha1!=NULL && (strlen(ha1)>0)) obj->ha1=ms_strdup(ha1);
|
||||
if (realm!=NULL && (strlen(realm)>0)) obj->realm=ms_strdup(realm);
|
||||
obj->works=FALSE;
|
||||
obj->first_time=TRUE;
|
||||
return obj;
|
||||
}
|
||||
|
||||
void linphone_auth_info_set_passwd(LinphoneAuthInfo *info, const char *passwd){
|
||||
if (info->passwd!=NULL) {
|
||||
ms_free(info->passwd);
|
||||
info->passwd=NULL;
|
||||
}
|
||||
if (passwd!=NULL && (strlen(passwd)>0)) info->passwd=ms_strdup(passwd);
|
||||
}
|
||||
|
||||
void linphone_auth_info_destroy(LinphoneAuthInfo *obj){
|
||||
if (obj->username!=NULL) ms_free(obj->username);
|
||||
if (obj->userid!=NULL) ms_free(obj->userid);
|
||||
if (obj->passwd!=NULL) ms_free(obj->passwd);
|
||||
if (obj->ha1!=NULL) ms_free(obj->ha1);
|
||||
if (obj->realm!=NULL) ms_free(obj->realm);
|
||||
ms_free(obj);
|
||||
}
|
||||
|
||||
void linphone_auth_info_write_config(LpConfig *config, LinphoneAuthInfo *obj, int pos)
|
||||
{
|
||||
char key[50];
|
||||
sprintf(key,"auth_info_%i",pos);
|
||||
lp_config_clean_section(config,key);
|
||||
|
||||
if (obj==NULL){
|
||||
return;
|
||||
}
|
||||
if (obj->username!=NULL){
|
||||
lp_config_set_string(config,key,"username",obj->username);
|
||||
}
|
||||
if (obj->userid!=NULL){
|
||||
lp_config_set_string(config,key,"userid",obj->userid);
|
||||
}
|
||||
if (obj->passwd!=NULL){
|
||||
lp_config_set_string(config,key,"passwd",obj->passwd);
|
||||
}
|
||||
if (obj->ha1!=NULL){
|
||||
lp_config_set_string(config,key,"ha1",obj->ha1);
|
||||
}
|
||||
if (obj->realm!=NULL){
|
||||
lp_config_set_string(config,key,"realm",obj->realm);
|
||||
}
|
||||
lp_config_sync(config);
|
||||
}
|
||||
|
||||
LinphoneAuthInfo *linphone_auth_info_new_from_config_file(LpConfig * config, int pos)
|
||||
{
|
||||
char key[50];
|
||||
const char *username,*userid,*passwd,*ha1,*realm;
|
||||
|
||||
sprintf(key,"auth_info_%i",pos);
|
||||
if (!lp_config_has_section(config,key)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
username=lp_config_get_string(config,key,"username",NULL);
|
||||
userid=lp_config_get_string(config,key,"userid",NULL);
|
||||
passwd=lp_config_get_string(config,key,"passwd",NULL);
|
||||
ha1=lp_config_get_string(config,key,"ha1",NULL);
|
||||
realm=lp_config_get_string(config,key,"realm",NULL);
|
||||
return linphone_auth_info_new(username,userid,passwd,ha1,realm);
|
||||
}
|
||||
|
||||
static bool_t key_match(const char *tmp1, const char *tmp2){
|
||||
if (tmp1==NULL && tmp2==NULL) return TRUE;
|
||||
if (tmp1!=NULL && tmp2!=NULL && strcmp(tmp1,tmp2)==0) return TRUE;
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
static int auth_info_compare(const void *pinfo,const void *pref){
|
||||
LinphoneAuthInfo *info=(LinphoneAuthInfo*)pinfo;
|
||||
LinphoneAuthInfo *ref=(LinphoneAuthInfo*)pref;
|
||||
if (key_match(info->realm,ref->realm) && key_match(info->username,ref->username)) return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
LinphoneAuthInfo *linphone_core_auth_info_find(LinphoneCore *lc, const char *realm, const char *username)
|
||||
{
|
||||
LinphoneAuthInfo ref;
|
||||
MSList *elem;
|
||||
ref.realm=(char*)realm;
|
||||
ref.username=(char*)username;
|
||||
elem=ms_list_find_custom(lc->auth_info,auth_info_compare,(void*)&ref);
|
||||
if (elem==NULL) return NULL;
|
||||
return (LinphoneAuthInfo*)elem->data;
|
||||
}
|
||||
|
||||
void linphone_core_add_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info)
|
||||
{
|
||||
int n;
|
||||
MSList *elem;
|
||||
char *userid;
|
||||
if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
|
||||
else userid=info->userid;
|
||||
eXosip_lock();
|
||||
eXosip_add_authentication_info(info->username,userid,
|
||||
info->passwd,info->ha1,info->realm);
|
||||
eXosip_unlock();
|
||||
/* if the user was prompted, re-allow automatic_action */
|
||||
if (lc->automatic_action>0) lc->automatic_action--;
|
||||
/* find if we are attempting to modify an existing auth info */
|
||||
elem=ms_list_find_custom(lc->auth_info,auth_info_compare,info);
|
||||
if (elem!=NULL){
|
||||
linphone_auth_info_destroy((LinphoneAuthInfo*)elem->data);
|
||||
elem->data=(void *)info;
|
||||
n=ms_list_position(lc->auth_info,elem);
|
||||
}else {
|
||||
lc->auth_info=ms_list_append(lc->auth_info,(void *)info);
|
||||
n=ms_list_size(lc->auth_info)-1;
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_abort_authentication(LinphoneCore *lc, LinphoneAuthInfo *info){
|
||||
if (lc->automatic_action>0) lc->automatic_action--;
|
||||
}
|
||||
|
||||
void linphone_core_remove_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info){
|
||||
int len=ms_list_size(lc->auth_info);
|
||||
int newlen;
|
||||
int i;
|
||||
MSList *elem;
|
||||
lc->auth_info=ms_list_remove(lc->auth_info,info);
|
||||
newlen=ms_list_size(lc->auth_info);
|
||||
/*printf("len=%i newlen=%i\n",len,newlen);*/
|
||||
linphone_auth_info_destroy(info);
|
||||
for (i=0;i<len;i++){
|
||||
linphone_auth_info_write_config(lc->config,NULL,i);
|
||||
}
|
||||
for (elem=lc->auth_info,i=0;elem!=NULL;elem=ms_list_next(elem),i++){
|
||||
linphone_auth_info_write_config(lc->config,(LinphoneAuthInfo*)elem->data,i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void linphone_core_clear_all_auth_info(LinphoneCore *lc){
|
||||
MSList *elem;
|
||||
int i;
|
||||
eXosip_lock();
|
||||
eXosip_clear_authentication_info();
|
||||
eXosip_unlock();
|
||||
for(i=0,elem=lc->auth_info;elem!=NULL;elem=ms_list_next(elem),i++){
|
||||
LinphoneAuthInfo *info=(LinphoneAuthInfo*)elem->data;
|
||||
linphone_auth_info_destroy(info);
|
||||
linphone_auth_info_write_config(lc->config,NULL,i);
|
||||
}
|
||||
ms_list_free(lc->auth_info);
|
||||
lc->auth_info=NULL;
|
||||
}
|
||||
|
||||
void linphone_authentication_ok(LinphoneCore *lc, eXosip_event_t *ev){
|
||||
char *prx_realm=NULL,*www_realm=NULL;
|
||||
osip_proxy_authorization_t *prx_auth;
|
||||
osip_authorization_t *www_auth;
|
||||
osip_message_t *msg=ev->request;
|
||||
char *username;
|
||||
LinphoneAuthInfo *as=NULL;
|
||||
|
||||
username=osip_uri_get_username(msg->from->url);
|
||||
osip_message_get_proxy_authorization(msg,0,&prx_auth);
|
||||
osip_message_get_authorization(msg,0,&www_auth);
|
||||
if (prx_auth!=NULL)
|
||||
prx_realm=osip_proxy_authorization_get_realm(prx_auth);
|
||||
if (www_auth!=NULL)
|
||||
www_realm=osip_authorization_get_realm(www_auth);
|
||||
|
||||
if (prx_realm==NULL && www_realm==NULL){
|
||||
ms_message("No authentication info in the request, ignoring");
|
||||
return;
|
||||
}
|
||||
/* see if we already have this auth information , not to ask it everytime to the user */
|
||||
if (prx_realm!=NULL)
|
||||
as=linphone_core_auth_info_find(lc,prx_realm,username);
|
||||
if (www_realm!=NULL)
|
||||
as=linphone_core_auth_info_find(lc,www_realm,username);
|
||||
if (as){
|
||||
ms_message("Authentication for user=%s realm=%s is working.",username,prx_realm ? prx_realm : www_realm);
|
||||
as->works=TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void linphone_core_find_or_ask_for_auth_info(LinphoneCore *lc,const char *username,const char* realm, int tid)
|
||||
{
|
||||
LinphoneAuthInfo *as;
|
||||
if ((as=linphone_core_auth_info_find(lc,realm,username))==NULL ||
|
||||
(as->works==FALSE && as->first_time==FALSE) ) {
|
||||
if (lc->vtable.auth_info_requested!=NULL) {
|
||||
lc->vtable.auth_info_requested(lc,realm,username);
|
||||
lc->automatic_action++;/*suspends eXosip_automatic_action until the user supplies a password */
|
||||
}
|
||||
if (as) as->first_time=FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_process_authentication(LinphoneCore *lc, eXosip_event_t *ev)
|
||||
{
|
||||
char *prx_realm=NULL,*www_realm=NULL;
|
||||
osip_proxy_authenticate_t *prx_auth;
|
||||
osip_www_authenticate_t *www_auth;
|
||||
osip_message_t *resp=ev->response;
|
||||
char *username;
|
||||
|
||||
if (strcmp(ev->request->sip_method,"REGISTER")==0) {
|
||||
gstate_new_state(lc, GSTATE_REG_FAILED, "Authentication required");
|
||||
}
|
||||
|
||||
username=osip_uri_get_username(resp->from->url);
|
||||
prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
|
||||
www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
|
||||
if (prx_auth!=NULL)
|
||||
prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
|
||||
if (www_auth!=NULL)
|
||||
www_realm=osip_www_authenticate_get_realm(www_auth);
|
||||
|
||||
if (prx_realm==NULL && www_realm==NULL){
|
||||
ms_warning("No realm in the server response.");
|
||||
return;
|
||||
}
|
||||
/* see if we already have this auth information , not to ask it everytime to the user */
|
||||
if (prx_realm!=NULL)
|
||||
linphone_core_find_or_ask_for_auth_info(lc,username,prx_realm,ev->tid);
|
||||
if (www_realm!=NULL)
|
||||
linphone_core_find_or_ask_for_auth_info(lc,username,www_realm,ev->tid);
|
||||
}
|
||||
|
||||
109
linphone/coreapi/chat.c
Normal file
109
linphone/coreapi/chat.c
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/***************************************************************************
|
||||
* chat.c
|
||||
*
|
||||
* Sun Jun 5 19:34:18 2005
|
||||
* Copyright 2005 Simon Morlat
|
||||
* Email simon dot morlat at linphone dot 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 "linphonecore.h"
|
||||
#include "private.h"
|
||||
#include <eXosip2/eXosip.h>
|
||||
|
||||
LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to){
|
||||
char *real_url=NULL;
|
||||
osip_from_t *parsed_url=NULL;
|
||||
char *route;
|
||||
if (linphone_core_interpret_url(lc,to,&real_url,&parsed_url,&route)){
|
||||
LinphoneChatRoom *cr=ms_new0(LinphoneChatRoom,1);
|
||||
cr->lc=lc;
|
||||
cr->peer=real_url;
|
||||
cr->peer_url=parsed_url;
|
||||
cr->route=route;
|
||||
lc->chatrooms=ms_list_append(lc->chatrooms,(void *)cr);
|
||||
return cr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void linphone_chat_room_destroy(LinphoneChatRoom *cr){
|
||||
LinphoneCore *lc=cr->lc;
|
||||
lc->chatrooms=ms_list_remove(lc->chatrooms,(void *) cr);
|
||||
osip_from_free(cr->peer_url);
|
||||
ms_free(cr->peer);
|
||||
ms_free(cr->route);
|
||||
}
|
||||
|
||||
void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg){
|
||||
const char *identity=linphone_core_get_identity(cr->lc);
|
||||
osip_message_t *sip=NULL;
|
||||
eXosip_message_build_request(&sip,"MESSAGE",cr->peer,identity,cr->route);
|
||||
osip_message_set_content_type(sip,"text/plain");
|
||||
osip_message_set_body(sip,msg,strlen(msg));
|
||||
eXosip_message_send_request(sip);
|
||||
}
|
||||
|
||||
bool_t linphone_chat_room_matches(LinphoneChatRoom *cr, osip_from_t *from){
|
||||
if (cr->peer_url->url->username && from->url->username &&
|
||||
strcmp(cr->peer_url->url->username,from->url->username)==0) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void linphone_chat_room_text_received(LinphoneChatRoom *cr, LinphoneCore *lc, const char *from, const char *msg){
|
||||
if (lc->vtable.text_received!=NULL) lc->vtable.text_received(lc, cr, from, msg);
|
||||
}
|
||||
|
||||
void linphone_core_text_received(LinphoneCore *lc, eXosip_event_t *ev){
|
||||
MSList *elem;
|
||||
const char *msg;
|
||||
LinphoneChatRoom *cr=NULL;
|
||||
char *cleanfrom;
|
||||
osip_from_t *from_url=ev->request->from;
|
||||
osip_body_t *body=NULL;
|
||||
|
||||
osip_message_get_body(ev->request,0,&body);
|
||||
if (body==NULL){
|
||||
ms_error("Could not get text message from SIP body");
|
||||
return;
|
||||
}
|
||||
msg=body->body;
|
||||
from_2char_without_params(from_url,&cleanfrom);
|
||||
for(elem=lc->chatrooms;elem!=NULL;elem=ms_list_next(elem)){
|
||||
cr=(LinphoneChatRoom*)elem->data;
|
||||
if (linphone_chat_room_matches(cr,from_url)){
|
||||
break;
|
||||
}
|
||||
cr=NULL;
|
||||
}
|
||||
if (cr==NULL){
|
||||
/* create a new chat room */
|
||||
cr=linphone_core_create_chat_room(lc,cleanfrom);
|
||||
}
|
||||
linphone_chat_room_text_received(cr,lc,cleanfrom,msg);
|
||||
osip_free(cleanfrom);
|
||||
}
|
||||
|
||||
|
||||
void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud){
|
||||
cr->user_data=ud;
|
||||
}
|
||||
void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr){
|
||||
return cr->user_data;
|
||||
}
|
||||
172
linphone/coreapi/enum.c
Normal file
172
linphone/coreapi/enum.c
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2000 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.
|
||||
*/
|
||||
|
||||
/* enum lookup code */
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "enum.h"
|
||||
|
||||
#define DNS_ANSWER_MAX_SIZE 2048
|
||||
|
||||
|
||||
char *create_enum_domain(const char *number){
|
||||
int len=strlen(number);
|
||||
char *domain=ms_malloc((len*2)+10);
|
||||
int i,j;
|
||||
|
||||
for (i=0,j=len-1;j>=0;j--){
|
||||
domain[i]=number[j];
|
||||
i++;
|
||||
domain[i]='.';
|
||||
i++;
|
||||
}
|
||||
strcpy(&domain[i],"e164.arpa");
|
||||
ms_message("enum domain for %s is %s",number,domain);
|
||||
return domain;
|
||||
}
|
||||
|
||||
|
||||
bool_t is_a_number(const char *str){
|
||||
char *p=(char *)str;
|
||||
bool_t res=FALSE;
|
||||
bool_t space_found=FALSE;
|
||||
for(;;p++){
|
||||
switch(p[0]){
|
||||
case '9':
|
||||
case '8':
|
||||
case '7':
|
||||
case '6':
|
||||
case '5':
|
||||
case '4':
|
||||
case '3':
|
||||
case '2':
|
||||
case '1':
|
||||
case '0':
|
||||
res=TRUE;
|
||||
if (space_found) return FALSE; /* avoid splited numbers */
|
||||
break;
|
||||
case '\0':
|
||||
return res;
|
||||
break;
|
||||
case ' ':
|
||||
space_found=TRUE;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
//4970072278724
|
||||
bool_t is_enum(const char *sipaddress, char **enum_domain){
|
||||
char *p;
|
||||
p=strstr(sipaddress,"sip:");
|
||||
if (p==NULL) return FALSE; /* enum should look like sip:4369959250*/
|
||||
else p+=4;
|
||||
if (is_a_number(p)){
|
||||
if (enum_domain!=NULL){
|
||||
*enum_domain=create_enum_domain(p);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int enum_lookup(const char *enum_domain, enum_lookup_res_t **res){
|
||||
int err;
|
||||
//char dns_answer[DNS_ANSWER_MAX_SIZE];
|
||||
char *begin,*end;
|
||||
char *host_result, *command;
|
||||
int i;
|
||||
bool_t forkok;
|
||||
/*
|
||||
ns_msg handle;
|
||||
int count;
|
||||
|
||||
memset(&handle,0,sizeof(handle));
|
||||
*res=NULL;
|
||||
ms_message("Resolving %s...",enum_domain);
|
||||
|
||||
err=res_search(enum_domain,ns_c_in,ns_t_naptr,dns_answer,DNS_ANSWER_MAX_SIZE);
|
||||
if (err<0){
|
||||
ms_warning("Error resolving enum:",herror(h_errno));
|
||||
return -1;
|
||||
}
|
||||
ns_initparse(dns_answer,DNS_ANSWER_MAX_SIZE,&handle);
|
||||
count=ns_msg_count(handle,ns_s_an);
|
||||
|
||||
for(i=0;i<count;i++){
|
||||
ns_rr rr;
|
||||
memset(&rr,0,sizeof(rr));
|
||||
ns_parserr(&handle,ns_s_an,i,&rr);
|
||||
ms_message("data=%s",ns_rr_rdata(rr));
|
||||
}
|
||||
*/
|
||||
command=ms_strdup_printf("host -t naptr %s",enum_domain);
|
||||
forkok=lp_spawn_command_line_sync(command,&host_result,&err);
|
||||
ms_free(command);
|
||||
if (forkok){
|
||||
if (err!=0){
|
||||
ms_warning("Host exited with %i error status.",err);
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
ms_warning("Could not spawn the \'host\' command.");
|
||||
return -1;
|
||||
}
|
||||
ms_message("Answer received from dns (err=%i): %s",err,host_result);
|
||||
|
||||
begin=strstr(host_result,"sip:");
|
||||
if (begin==0) {
|
||||
ms_warning("No sip address found in dns naptr answer.");
|
||||
return -1;
|
||||
}
|
||||
*res=ms_malloc0(sizeof(enum_lookup_res_t));
|
||||
err=0;
|
||||
for(i=0;i<MAX_ENUM_LOOKUP_RESULTS;i++){
|
||||
end=strstr(begin,"!");
|
||||
if (end==NULL) goto parse_error;
|
||||
end[0]='\0';
|
||||
(*res)->sip_address[i]=ms_strdup(begin);
|
||||
err++;
|
||||
begin=strstr(end+1,"sip:");
|
||||
if (begin==NULL) break;
|
||||
}
|
||||
ms_free(host_result);
|
||||
return err;
|
||||
|
||||
parse_error:
|
||||
ms_free(*res);
|
||||
ms_free(host_result);
|
||||
*res=NULL;
|
||||
ms_warning("Parse error in enum_lookup().");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void enum_lookup_res_free(enum_lookup_res_t *res){
|
||||
int i;
|
||||
for (i=0;i<MAX_ENUM_LOOKUP_RESULTS;i++){
|
||||
if (res->sip_address[i]!=NULL) ms_free(res->sip_address[i]);
|
||||
}
|
||||
ms_free(res);
|
||||
}
|
||||
35
linphone/coreapi/enum.h
Normal file
35
linphone/coreapi/enum.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
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 ENUM_LOOKUP_H
|
||||
#define ENUM_LOOKUP_H
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#define MAX_ENUM_LOOKUP_RESULTS 10
|
||||
|
||||
typedef struct enum_lookup_res{
|
||||
char *sip_address[MAX_ENUM_LOOKUP_RESULTS];
|
||||
}enum_lookup_res_t;
|
||||
|
||||
bool_t is_enum(const char *sipaddress, char **enum_domain);
|
||||
int enum_lookup(const char *enum_domain, enum_lookup_res_t **res);
|
||||
void enum_lookup_res_free(enum_lookup_res_t *res);
|
||||
|
||||
#endif
|
||||
1012
linphone/coreapi/exevents.c
Normal file
1012
linphone/coreapi/exevents.c
Normal file
File diff suppressed because it is too large
Load diff
40
linphone/coreapi/exevents.h
Normal file
40
linphone/coreapi/exevents.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
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
|
||||
736
linphone/coreapi/friend.c
Normal file
736
linphone/coreapi/friend.c
Normal file
|
|
@ -0,0 +1,736 @@
|
|||
/***************************************************************************
|
||||
* friend.c
|
||||
*
|
||||
* Sat May 15 15:25:16 2004
|
||||
* Copyright 2004 Simon Morlat
|
||||
* Email
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "private.h"
|
||||
#include <eXosip2/eXosip.h>
|
||||
#include <osipparser2/osip_message.h>
|
||||
#include "lpconfig.h"
|
||||
|
||||
const char *linphone_online_status_to_string(LinphoneOnlineStatus ss){
|
||||
const char *str=NULL;
|
||||
switch(ss){
|
||||
case LINPHONE_STATUS_UNKNOWN:
|
||||
str=_("Unknown");
|
||||
break;
|
||||
case LINPHONE_STATUS_ONLINE:
|
||||
str=_("Online");
|
||||
break;
|
||||
case LINPHONE_STATUS_BUSY:
|
||||
str=_("Busy");
|
||||
break;
|
||||
case LINPHONE_STATUS_BERIGHTBACK:
|
||||
str=_("Be right back");
|
||||
break;
|
||||
case LINPHONE_STATUS_AWAY:
|
||||
str=_("Away");
|
||||
break;
|
||||
case LINPHONE_STATUS_ONTHEPHONE:
|
||||
str=_("On the phone");
|
||||
break;
|
||||
case LINPHONE_STATUS_OUTTOLUNCH:
|
||||
str=_("Out to lunch");
|
||||
break;
|
||||
case LINPHONE_STATUS_NOT_DISTURB:
|
||||
str=_("Do not disturb");
|
||||
break;
|
||||
case LINPHONE_STATUS_MOVED:
|
||||
str=_("Moved");
|
||||
break;
|
||||
case LINPHONE_STATUS_ALT_SERVICE:
|
||||
str=_("Using another messaging service");
|
||||
break;
|
||||
case LINPHONE_STATUS_OFFLINE:
|
||||
str=_("Offline");
|
||||
break;
|
||||
case LINPHONE_STATUS_PENDING:
|
||||
str=_("Pending");
|
||||
break;
|
||||
case LINPHONE_STATUS_CLOSED:
|
||||
str=_("Closed");
|
||||
break;
|
||||
default:
|
||||
str=_("Unknown-bug");
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static int friend_data_compare(const void * a, const void * b, void * data){
|
||||
osip_from_t *fa=((LinphoneFriend*)a)->url;
|
||||
osip_from_t *fb=((LinphoneFriend*)b)->url;
|
||||
char *ua,*ub;
|
||||
ua=fa->url->username;
|
||||
ub=fb->url->username;
|
||||
if (ua!=NULL && ub!=NULL) {
|
||||
//printf("Comparing usernames %s,%s\n",ua,ub);
|
||||
return strcasecmp(ua,ub);
|
||||
}
|
||||
else {
|
||||
/* compare hosts*/
|
||||
ua=fa->url->host;
|
||||
ub=fb->url->host;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
MSList *find_friend(MSList *fl, const osip_from_t *friend, LinphoneFriend **lf){
|
||||
MSList *res=NULL;
|
||||
LinphoneFriend dummy;
|
||||
if (lf!=NULL) *lf=NULL;
|
||||
dummy.url=(osip_from_t*)friend;
|
||||
res=ms_list_find_custom(fl,friend_compare,&dummy);
|
||||
if (lf!=NULL && res!=NULL) *lf=(LinphoneFriend*)res->data;
|
||||
return res;
|
||||
}
|
||||
|
||||
LinphoneFriend *linphone_find_friend_by_nid(MSList *l, int nid){
|
||||
MSList *elem;
|
||||
for (elem=l;elem!=NULL;elem=elem->next){
|
||||
LinphoneFriend *lf=(LinphoneFriend*)elem->data;
|
||||
if (lf->nid==nid) return lf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LinphoneFriend *linphone_find_friend_by_sid(MSList *l, int sid){
|
||||
MSList *elem;
|
||||
for (elem=l;elem!=NULL;elem=elem->next){
|
||||
LinphoneFriend *lf=(LinphoneFriend*)elem->data;
|
||||
if (lf->sid==sid) return lf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void __linphone_friend_do_subscribe(LinphoneFriend *fr){
|
||||
char *friend=NULL;
|
||||
const char *route=NULL;
|
||||
const char *from=NULL;
|
||||
osip_message_t *msg=NULL;
|
||||
osip_from_to_str(fr->url,&friend);
|
||||
if (fr->proxy!=NULL){
|
||||
route=fr->proxy->reg_route;
|
||||
from=fr->proxy->reg_identity;
|
||||
}else from=linphone_core_get_primary_contact(fr->lc);
|
||||
if (fr->sid<0){
|
||||
/* people for which we don't have yet an answer should appear as offline */
|
||||
fr->lc->vtable.notify_recv(fr->lc,(LinphoneFriend*)fr,friend,_("Gone"),"sip-closed.png");
|
||||
}
|
||||
eXosip_lock();
|
||||
eXosip_subscribe_build_initial_request(&msg,friend,from,route,"presence",600);
|
||||
eXosip_subscribe_send_initial_request(msg);
|
||||
eXosip_unlock();
|
||||
osip_free(friend);
|
||||
}
|
||||
|
||||
|
||||
LinphoneFriend * linphone_friend_new(){
|
||||
LinphoneFriend *obj=ms_new0(LinphoneFriend,1);
|
||||
obj->out_did=-1;
|
||||
obj->in_did=-1;
|
||||
obj->nid=-1;
|
||||
obj->sid=-1;
|
||||
obj->pol=LinphoneSPAccept;
|
||||
obj->status=LINPHONE_STATUS_OFFLINE;
|
||||
obj->subscribe=TRUE;
|
||||
return obj;
|
||||
}
|
||||
|
||||
LinphoneFriend *linphone_friend_new_with_addr(const char *addr){
|
||||
LinphoneFriend *fr=linphone_friend_new();
|
||||
if (linphone_friend_set_sip_addr(fr,addr)<0){
|
||||
linphone_friend_destroy(fr);
|
||||
return NULL;
|
||||
}
|
||||
return fr;
|
||||
}
|
||||
|
||||
|
||||
int linphone_friend_set_sip_addr(LinphoneFriend *lf, const char *addr){
|
||||
int err;
|
||||
osip_from_t *fr=NULL;
|
||||
osip_from_init(&fr);
|
||||
err=osip_from_parse(fr,addr);
|
||||
if (err<0) {
|
||||
ms_warning("Invalid friend sip uri: %s",addr);
|
||||
osip_from_free(fr);
|
||||
return -1;
|
||||
}
|
||||
if (lf->url!=NULL) osip_from_free(lf->url);
|
||||
lf->url=fr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linphone_friend_set_name(LinphoneFriend *lf, const char *name){
|
||||
osip_from_t *fr=lf->url;
|
||||
if (fr==NULL){
|
||||
ms_error("linphone_friend_set_sip_addr() must be called before linphone_friend_set_name().");
|
||||
return -1;
|
||||
}
|
||||
if (fr->displayname!=NULL){
|
||||
osip_free(fr->displayname);
|
||||
fr->displayname=NULL;
|
||||
}
|
||||
if (name && name[0]!='\0'){
|
||||
fr->displayname=osip_strdup(name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linphone_friend_send_subscribe(LinphoneFriend *fr, bool_t val){
|
||||
fr->subscribe=val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscribePolicy pol)
|
||||
{
|
||||
fr->pol=pol;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linphone_friend_set_proxy(LinphoneFriend *fr, struct _LinphoneProxyConfig *cfg){
|
||||
fr->proxy=cfg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void linphone_friend_set_sid(LinphoneFriend *lf, int sid){
|
||||
lf->sid=sid;
|
||||
}
|
||||
void linphone_friend_set_nid(LinphoneFriend *lf, int nid){
|
||||
lf->nid=nid;
|
||||
lf->inc_subscribe_pending=TRUE;
|
||||
}
|
||||
|
||||
void add_presence_body(osip_message_t *notify, LinphoneOnlineStatus online_status)
|
||||
{
|
||||
char buf[1000];
|
||||
#ifdef SUPPORT_MSN
|
||||
int atom_id = 1000;
|
||||
#endif
|
||||
char *contact_info;
|
||||
|
||||
osip_contact_t *ct=NULL;
|
||||
osip_message_get_contact(notify,0,&ct);
|
||||
osip_contact_to_str(ct,&contact_info);
|
||||
|
||||
#ifdef SUPPORT_MSN
|
||||
|
||||
if (online_status==LINPHONE_STATUS_ONLINE)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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=\"open\" />\n\
|
||||
<msnsubstatus substatus=\"online\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==LINPHONE_STATUS_BUSY)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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=\"inuse\" />\n\
|
||||
<msnsubstatus substatus=\"busy\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==LINPHONE_STATUS_BERIGHTBACK)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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\
|
||||
<msnsubstatus substatus=\"berightback\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==LINPHONE_STATUS_AWAY)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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\
|
||||
<msnsubstatus substatus=\"away\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==LINPHONE_STATUS_ONTHEPHONE)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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=\"inuse\" />\n\
|
||||
<msnsubstatus substatus=\"onthephone\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
|
||||
}
|
||||
else if (online_status==LINPHONE_STATUS_OUTTOLUNCH)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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\
|
||||
<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\
|
||||
<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>\n\
|
||||
</atom>\n\
|
||||
</presence>", contact_info, atom_id, contact_info);
|
||||
}
|
||||
|
||||
osip_message_set_body(notify, buf, strlen(buf));
|
||||
osip_message_set_content_type(notify, "application/xpidf+xml");
|
||||
#else
|
||||
|
||||
if (online_status==LINPHONE_STATUS_ONLINE)
|
||||
{
|
||||
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==LINPHONE_STATUS_BUSY)
|
||||
{
|
||||
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==LINPHONE_STATUS_BERIGHTBACK)
|
||||
{
|
||||
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==LINPHONE_STATUS_AWAY)
|
||||
{
|
||||
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==LINPHONE_STATUS_ONTHEPHONE)
|
||||
{
|
||||
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==LINPHONE_STATUS_OUTTOLUNCH)
|
||||
{
|
||||
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</e: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");
|
||||
|
||||
#endif
|
||||
osip_free(contact_info);
|
||||
}
|
||||
|
||||
|
||||
void linphone_friend_notify(LinphoneFriend *lf, int ss, LinphoneOnlineStatus os){
|
||||
//printf("Wish to notify %p, lf->nid=%i\n",lf,lf->nid);
|
||||
if (lf->in_did!=-1){
|
||||
osip_message_t *msg=NULL;
|
||||
const char *identity;
|
||||
if (lf->proxy!=NULL) identity=lf->proxy->reg_identity;
|
||||
else identity=linphone_core_get_primary_contact(lf->lc);
|
||||
eXosip_lock();
|
||||
eXosip_insubscription_build_notify(lf->in_did,ss,0,&msg);
|
||||
if (msg!=NULL){
|
||||
osip_message_set_contact(msg,identity);
|
||||
add_presence_body(msg,os);
|
||||
eXosip_insubscription_send_request(lf->in_did,msg);
|
||||
}else ms_error("could not create notify for incoming subscription.");
|
||||
eXosip_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_friend_unsubscribe(LinphoneFriend *lf){
|
||||
if (lf->out_did!=-1) {
|
||||
osip_message_t *msg=NULL;
|
||||
eXosip_lock();
|
||||
eXosip_subscribe_build_refresh_request(lf->out_did,&msg);
|
||||
if (msg){
|
||||
osip_message_set_expires(msg,"0");
|
||||
eXosip_subscribe_send_refresh_request(lf->out_did,msg);
|
||||
}else ms_error("Could not build subscribe refresh request !");
|
||||
eXosip_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_friend_destroy(LinphoneFriend *lf){
|
||||
linphone_friend_notify(lf,EXOSIP_SUBCRSTATE_TERMINATED,LINPHONE_STATUS_CLOSED);
|
||||
linphone_friend_unsubscribe(lf);
|
||||
if (lf->url!=NULL) osip_from_free(lf->url);
|
||||
ms_free(lf);
|
||||
}
|
||||
|
||||
void linphone_friend_check_for_removed_proxy(LinphoneFriend *lf, LinphoneProxyConfig *cfg){
|
||||
if (lf->proxy==cfg){
|
||||
lf->proxy=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char *linphone_friend_get_addr(LinphoneFriend *lf){
|
||||
char *ret,*tmp;
|
||||
if (lf->url==NULL) return NULL;
|
||||
osip_uri_to_str(lf->url->url,&tmp);
|
||||
ret=ms_strdup(tmp);
|
||||
osip_free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *linphone_friend_get_name(LinphoneFriend *lf){
|
||||
if (lf->url==NULL) return NULL;
|
||||
if (lf->url->displayname==NULL) return NULL;
|
||||
return ms_strdup(lf->url->displayname);
|
||||
}
|
||||
|
||||
char * linphone_friend_get_url(LinphoneFriend *lf){
|
||||
char *tmp,*ret;
|
||||
if (lf->url==NULL) return NULL;
|
||||
osip_from_to_str(lf->url,&tmp);
|
||||
ret=ms_strdup(tmp);
|
||||
ms_free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf){
|
||||
return lf->subscribe;
|
||||
}
|
||||
|
||||
LinphoneSubscribePolicy linphone_friend_get_inc_subscribe_policy(const LinphoneFriend *lf){
|
||||
return lf->pol;
|
||||
}
|
||||
|
||||
LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf){
|
||||
return lf->status;
|
||||
}
|
||||
|
||||
|
||||
void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
|
||||
if (fr->url==NULL) {
|
||||
ms_warning("No sip url defined.");
|
||||
return;
|
||||
}
|
||||
fr->lc=lc;
|
||||
|
||||
if (fr->inc_subscribe_pending){
|
||||
switch(fr->pol){
|
||||
case LinphoneSPWait:
|
||||
linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_PENDING,LINPHONE_STATUS_PENDING);
|
||||
break;
|
||||
case LinphoneSPAccept:
|
||||
if (fr->lc!=NULL)
|
||||
{
|
||||
linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_ACTIVE,fr->lc->presence_mode);
|
||||
}
|
||||
break;
|
||||
case LinphoneSPDeny:
|
||||
linphone_friend_notify(fr,EXOSIP_SUBCRSTATE_TERMINATED,LINPHONE_STATUS_CLOSED);
|
||||
break;
|
||||
}
|
||||
fr->inc_subscribe_pending=FALSE;
|
||||
}
|
||||
if (fr->subscribe && fr->out_did==-1){
|
||||
|
||||
__linphone_friend_do_subscribe(fr);
|
||||
}
|
||||
ms_message("linphone_friend_apply() done.");
|
||||
}
|
||||
|
||||
void linphone_friend_edit(LinphoneFriend *fr){
|
||||
}
|
||||
|
||||
void linphone_friend_done(LinphoneFriend *fr){
|
||||
ms_return_if_fail(fr!=NULL);
|
||||
if (fr->lc==NULL) return;
|
||||
linphone_friend_apply(fr,fr->lc);
|
||||
}
|
||||
|
||||
void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf)
|
||||
{
|
||||
ms_return_if_fail(lf->lc==NULL);
|
||||
ms_return_if_fail(lf->url!=NULL);
|
||||
linphone_friend_apply(lf,lc);
|
||||
lc->friends=ms_list_append(lc->friends,lf);
|
||||
return ;
|
||||
}
|
||||
|
||||
void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){
|
||||
MSList *el=ms_list_find(lc->friends,(void *)fl);
|
||||
if (el!=NULL){
|
||||
lc->friends=ms_list_remove_link(lc->friends,el);
|
||||
linphone_friend_destroy((LinphoneFriend*)el->data);
|
||||
}
|
||||
}
|
||||
|
||||
#define key_compare(key, word) strncasecmp((key),(word),strlen(key))
|
||||
|
||||
LinphoneSubscribePolicy __policy_str_to_enum(const char* pol){
|
||||
if (key_compare("accept",pol)==0){
|
||||
return LinphoneSPAccept;
|
||||
}
|
||||
if (key_compare("deny",pol)==0){
|
||||
return LinphoneSPDeny;
|
||||
}
|
||||
if (key_compare("wait",pol)==0){
|
||||
return LinphoneSPWait;
|
||||
}
|
||||
ms_warning("Unrecognized subscribe policy: %s",pol);
|
||||
return LinphoneSPWait;
|
||||
}
|
||||
|
||||
LinphoneProxyConfig *__index_to_proxy(LinphoneCore *lc, int index){
|
||||
if (index>=0) return (LinphoneProxyConfig*)ms_list_nth_data(lc->sip_conf.proxies,index);
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
LinphoneFriend * linphone_friend_new_from_config_file(LinphoneCore *lc, int index){
|
||||
const char *tmp;
|
||||
char item[50];
|
||||
int a;
|
||||
LinphoneFriend *lf;
|
||||
LpConfig *config=lc->config;
|
||||
|
||||
sprintf(item,"friend_%i",index);
|
||||
|
||||
if (!lp_config_has_section(config,item)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp=lp_config_get_string(config,item,"url",NULL);
|
||||
if (tmp==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
lf=linphone_friend_new_with_addr(tmp);
|
||||
if (lf==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
tmp=lp_config_get_string(config,item,"pol",NULL);
|
||||
if (tmp==NULL) linphone_friend_set_inc_subscribe_policy(lf,LinphoneSPWait);
|
||||
else{
|
||||
linphone_friend_set_inc_subscribe_policy(lf,__policy_str_to_enum(tmp));
|
||||
}
|
||||
a=lp_config_get_int(config,item,"subscribe",0);
|
||||
linphone_friend_send_subscribe(lf,a);
|
||||
|
||||
a=lp_config_get_int(config,item,"proxy",-1);
|
||||
if (a!=-1) {
|
||||
linphone_friend_set_proxy(lf,__index_to_proxy(lc,a));
|
||||
}
|
||||
return lf;
|
||||
}
|
||||
|
||||
const char *__policy_enum_to_str(LinphoneSubscribePolicy pol){
|
||||
switch(pol){
|
||||
case LinphoneSPAccept:
|
||||
return "accept";
|
||||
break;
|
||||
case LinphoneSPDeny:
|
||||
return "deny";
|
||||
break;
|
||||
case LinphoneSPWait:
|
||||
return "wait";
|
||||
break;
|
||||
}
|
||||
ms_warning("Invalid policy enum value.");
|
||||
return "wait";
|
||||
}
|
||||
|
||||
void linphone_friend_write_to_config_file(LpConfig *config, LinphoneFriend *lf, int index){
|
||||
char key[50];
|
||||
char *tmp;
|
||||
int a;
|
||||
|
||||
sprintf(key,"friend_%i",index);
|
||||
|
||||
if (lf==NULL){
|
||||
lp_config_clean_section(config,key);
|
||||
return;
|
||||
}
|
||||
if (lf->url!=NULL){
|
||||
osip_from_to_str(lf->url,&tmp);
|
||||
if (tmp==NULL) {
|
||||
return;
|
||||
}
|
||||
lp_config_set_string(config,key,"url",tmp);
|
||||
osip_free(tmp);
|
||||
}
|
||||
lp_config_set_string(config,key,"pol",__policy_enum_to_str(lf->pol));
|
||||
lp_config_set_int(config,key,"subscribe",lf->subscribe);
|
||||
if (lf->proxy!=NULL){
|
||||
a=ms_list_index(lf->lc->sip_conf.proxies,lf->proxy);
|
||||
lp_config_set_int(config,key,"proxy",a);
|
||||
}else lp_config_set_int(config,key,"proxy",-1);
|
||||
}
|
||||
101
linphone/coreapi/general_state.c
Normal file
101
linphone/coreapi/general_state.c
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* 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"
|
||||
|
||||
|
||||
static gstate_t _gstates[GSTATE_GROUP_CALL+1];
|
||||
|
||||
#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(void) {
|
||||
_gstates[GSTATE_GROUP_POWER] = GSTATE_POWER_OFF;
|
||||
_gstates[GSTATE_GROUP_REG] = GSTATE_REG_NONE;
|
||||
_gstates[GSTATE_GROUP_CALL] = GSTATE_CALL_IDLE;
|
||||
}
|
||||
|
||||
|
||||
/* retrieve the current state of the specified state group */
|
||||
gstate_t gstate_get_state(gstate_group_t group) {
|
||||
return _gstates[group];
|
||||
}
|
||||
|
||||
|
||||
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 = _gstates[states_arg.group];
|
||||
_gstates[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);
|
||||
}
|
||||
|
||||
2261
linphone/coreapi/linphonecore.c
Normal file
2261
linphone/coreapi/linphonecore.c
Normal file
File diff suppressed because it is too large
Load diff
715
linphone/coreapi/linphonecore.h
Normal file
715
linphone/coreapi/linphonecore.h
Normal file
|
|
@ -0,0 +1,715 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2000 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_H
|
||||
#define LINPHONECORE_H
|
||||
|
||||
|
||||
#include <osipparser2/osip_message.h>
|
||||
#include "ortp/ortp.h"
|
||||
#include "ortp/payloadtype.h"
|
||||
#include "mediastreamer2/mscommon.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct _MSSndCard;
|
||||
struct _LinphoneCore;
|
||||
|
||||
bool_t payload_type_enabled(struct _PayloadType *pt);
|
||||
void payload_type_set_enable(struct _PayloadType *pt,int value);
|
||||
const char *payload_type_get_description(struct _PayloadType *pt);
|
||||
int payload_type_get_bitrate(PayloadType *pt);
|
||||
const char *payload_type_get_mime(PayloadType *pt);
|
||||
int payload_type_get_rate(PayloadType *pt);
|
||||
|
||||
|
||||
struct _LpConfig;
|
||||
|
||||
typedef struct sip_config
|
||||
{
|
||||
char *contact;
|
||||
char *guessed_contact;
|
||||
int sip_port;
|
||||
MSList *proxies;
|
||||
MSList *deleted_proxies;
|
||||
int inc_timeout; /*timeout after an un-answered incoming call is rejected*/
|
||||
bool_t use_info;
|
||||
bool_t guess_hostname;
|
||||
bool_t loopback_only;
|
||||
bool_t ipv6_enabled;
|
||||
bool_t sdp_200_ack;
|
||||
} sip_config_t;
|
||||
|
||||
typedef struct rtp_config
|
||||
{
|
||||
int audio_rtp_port;
|
||||
int video_rtp_port;
|
||||
int audio_jitt_comp; /*jitter compensation*/
|
||||
int video_jitt_comp; /*jitter compensation*/
|
||||
int nortp_timeout;
|
||||
}rtp_config_t;
|
||||
|
||||
|
||||
|
||||
typedef struct net_config
|
||||
{
|
||||
char *nat_address;
|
||||
char *stun_server;
|
||||
char *relay;
|
||||
int download_bw;
|
||||
int upload_bw;
|
||||
int firewall_policy;
|
||||
int mtu;
|
||||
bool_t nat_sdp_only;
|
||||
}net_config_t;
|
||||
|
||||
|
||||
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 */
|
||||
const char **cards;
|
||||
int latency; /* latency in samples of the current used sound device */
|
||||
char rec_lev;
|
||||
char play_lev;
|
||||
char ring_lev;
|
||||
char source;
|
||||
char pad;
|
||||
char *local_ring;
|
||||
char *remote_ring;
|
||||
bool_t ec;
|
||||
} sound_config_t;
|
||||
|
||||
typedef struct codecs_config
|
||||
{
|
||||
MSList *audio_codecs; /* list of audio codecs in order of preference*/
|
||||
MSList *video_codecs; /* for later use*/
|
||||
}codecs_config_t;
|
||||
|
||||
typedef struct video_config{
|
||||
struct _MSWebCam *device;
|
||||
const char **cams;
|
||||
bool_t capture;
|
||||
bool_t show_local;
|
||||
bool_t display;
|
||||
}video_config_t;
|
||||
|
||||
typedef struct ui_config
|
||||
{
|
||||
int is_daemon;
|
||||
int is_applet;
|
||||
unsigned int timer_id; /* the timer id for registration */
|
||||
}ui_config_t;
|
||||
|
||||
|
||||
|
||||
typedef struct autoreplier_config
|
||||
{
|
||||
int enabled;
|
||||
int after_seconds; /* accept the call after x seconds*/
|
||||
int max_users; /* maximum number of user that can call simultaneously */
|
||||
int max_rec_time; /* the max time of incoming voice recorded */
|
||||
int max_rec_msg; /* maximum number of recorded messages */
|
||||
const char *message; /* the path of the file to be played */
|
||||
}autoreplier_config_t;
|
||||
|
||||
|
||||
struct _LinphoneCore;
|
||||
struct _sdp_context;
|
||||
|
||||
typedef struct _StreamParams
|
||||
{
|
||||
int initialized;
|
||||
int line;
|
||||
int localport;
|
||||
int remoteport;
|
||||
int remotertcpport;
|
||||
char *remoteaddr;
|
||||
int pt;
|
||||
char *relay_session_id;
|
||||
} StreamParams;
|
||||
|
||||
typedef enum _LCState{
|
||||
LCStateInit,
|
||||
LCStateRinging,
|
||||
LCStateAVRunning
|
||||
}LCState;
|
||||
|
||||
typedef enum _LinphoneCallDir {LinphoneCallOutgoing, LinphoneCallIncoming} LinphoneCallDir;
|
||||
|
||||
|
||||
typedef struct _LinphoneCall
|
||||
{
|
||||
struct _LinphoneCore *core;
|
||||
StreamParams audio_params;
|
||||
StreamParams video_params;
|
||||
LinphoneCallDir dir;
|
||||
struct _RtpProfile *profile; /*points to the local_profile or to the remote "guessed" profile*/
|
||||
struct _LinphoneCallLog *log;
|
||||
int cid; /*call id */
|
||||
int did; /*dialog id */
|
||||
int tid; /*last transaction id*/
|
||||
struct _sdp_context *sdpctx;
|
||||
time_t start_time;
|
||||
LCState state;
|
||||
bool_t auth_pending;
|
||||
} LinphoneCall;
|
||||
|
||||
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, const osip_from_t *from, const osip_to_t *to);
|
||||
LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, const char *from, const char *to, int cid, int did , int tid);
|
||||
#define linphone_call_set_state(lcall,st) (lcall)->state=(st)
|
||||
void linphone_call_destroy(struct _LinphoneCall *obj);
|
||||
|
||||
|
||||
typedef enum _LinphoneCallStatus {
|
||||
LinphoneCallSuccess,
|
||||
LinphoneCallAborted,
|
||||
LinphoneCallMissed
|
||||
} LinphoneCallStatus;
|
||||
|
||||
typedef struct _LinphoneCallLog{
|
||||
LinphoneCallDir dir;
|
||||
LinphoneCallStatus status;
|
||||
char *from;
|
||||
char *to;
|
||||
char start_date[128];
|
||||
int duration;
|
||||
|
||||
} LinphoneCallLog;
|
||||
|
||||
/* private: */
|
||||
LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, char *local, char * remote);
|
||||
void linphone_call_log_completed(LinphoneCallLog *calllog, LinphoneCall *call);
|
||||
void linphone_call_log_destroy(LinphoneCallLog *cl);
|
||||
|
||||
/*public: */
|
||||
char * linphone_call_log_to_str(LinphoneCallLog *cl);
|
||||
|
||||
typedef enum{
|
||||
LinphoneSPWait,
|
||||
LinphoneSPDeny,
|
||||
LinphoneSPAccept
|
||||
}LinphoneSubscribePolicy;
|
||||
|
||||
typedef enum _LinphoneOnlineStatus{
|
||||
LINPHONE_STATUS_UNKNOWN,
|
||||
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_OFFLINE,
|
||||
LINPHONE_STATUS_PENDING,
|
||||
LINPHONE_STATUS_CLOSED,
|
||||
LINPHONE_STATUS_END
|
||||
}LinphoneOnlineStatus;
|
||||
|
||||
const char *linphone_online_status_to_string(LinphoneOnlineStatus ss);
|
||||
|
||||
typedef struct _LinphoneFriend{
|
||||
osip_from_t *url;
|
||||
int in_did;
|
||||
int out_did;
|
||||
int sid;
|
||||
int nid;
|
||||
LinphoneSubscribePolicy pol;
|
||||
LinphoneOnlineStatus status;
|
||||
struct _LinphoneProxyConfig *proxy;
|
||||
struct _LinphoneCore *lc;
|
||||
bool_t subscribe;
|
||||
bool_t inc_subscribe_pending;
|
||||
}LinphoneFriend;
|
||||
|
||||
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);
|
||||
int linphone_friend_set_proxy(LinphoneFriend *fr, struct _LinphoneProxyConfig *cfg);
|
||||
void linphone_friend_edit(LinphoneFriend *fr);
|
||||
void linphone_friend_done(LinphoneFriend *fr);
|
||||
void linphone_friend_destroy(LinphoneFriend *lf);
|
||||
/* memory returned by those 3 functions must be freed */
|
||||
char *linphone_friend_get_name(LinphoneFriend *lf);
|
||||
char *linphone_friend_get_addr(LinphoneFriend *lf);
|
||||
char *linphone_friend_get_url(LinphoneFriend *lf); /* name <sip address> */
|
||||
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);
|
||||
|
||||
#define linphone_friend_url(lf) ((lf)->url)
|
||||
|
||||
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);
|
||||
|
||||
typedef struct _LinphoneProxyConfig
|
||||
{
|
||||
struct _LinphoneCore *lc;
|
||||
char *reg_proxy;
|
||||
char *reg_identity;
|
||||
char *reg_route;
|
||||
char *realm;
|
||||
int expires;
|
||||
int reg_time;
|
||||
int rid;
|
||||
bool_t frozen;
|
||||
bool_t reg_sendregister;
|
||||
bool_t auth_pending;
|
||||
bool_t registered;
|
||||
bool_t publish;
|
||||
} LinphoneProxyConfig;
|
||||
|
||||
LinphoneProxyConfig *linphone_proxy_config_new(void);
|
||||
int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr);
|
||||
void linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity);
|
||||
void linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route);
|
||||
void linphone_proxy_config_expires(LinphoneProxyConfig *obj, const int expires);
|
||||
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);
|
||||
int linphone_proxy_config_done(LinphoneProxyConfig *obj);
|
||||
void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val);
|
||||
#define linphone_proxy_config_get_route(obj) ((obj)->reg_route)
|
||||
#define linphone_proxy_config_get_identity(obj) ((obj)->reg_identity)
|
||||
#define linphone_proxy_config_publish_enabled(obj) ((obj)->publish)
|
||||
#define linphone_proxy_config_get_addr(obj) ((obj)->reg_proxy)
|
||||
#define linphone_proxy_config_get_expires(obj) ((obj)->expires)
|
||||
#define linphone_proxy_config_register_enabled(obj) ((obj)->reg_sendregister)
|
||||
|
||||
/* destruction is called automatically when removing the proxy config */
|
||||
void linphone_proxy_config_destroy(LinphoneProxyConfig *cfg);
|
||||
LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(struct _LpConfig *config, int index);
|
||||
void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,LinphoneProxyConfig *obj, int index);
|
||||
|
||||
typedef struct _LinphoneAuthInfo
|
||||
{
|
||||
char *username;
|
||||
char *realm;
|
||||
char *userid;
|
||||
char *passwd;
|
||||
char *ha1;
|
||||
bool_t works;
|
||||
bool_t first_time;
|
||||
}LinphoneAuthInfo;
|
||||
|
||||
LinphoneAuthInfo *linphone_auth_info_new(const char *username, const char *userid,
|
||||
const char *passwd, const char *ha1,const char *realm);
|
||||
void linphone_auth_info_set_passwd(LinphoneAuthInfo *info, const char *passwd);
|
||||
/* you don't need those function*/
|
||||
void linphone_auth_info_destroy(LinphoneAuthInfo *info);
|
||||
LinphoneAuthInfo * linphone_auth_info_new_from_config_file(struct _LpConfig *config, int pos);
|
||||
|
||||
struct _LinphoneChatRoom{
|
||||
struct _LinphoneCore *lc;
|
||||
char *peer;
|
||||
char *route;
|
||||
osip_from_t *peer_url;
|
||||
void * user_data;
|
||||
};
|
||||
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);
|
||||
void linphone_chat_room_destroy(LinphoneChatRoom *cr);
|
||||
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 _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,
|
||||
/* 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_t;
|
||||
|
||||
struct _LinphoneGeneralState {
|
||||
gstate_t old_state;
|
||||
gstate_t new_state;
|
||||
gstate_group_t group;
|
||||
const char *message;
|
||||
};
|
||||
typedef struct _LinphoneGeneralState LinphoneGeneralState;
|
||||
|
||||
/* retrieve the current state of the specified state group */
|
||||
gstate_t gstate_get_state(gstate_group_t group);
|
||||
|
||||
/* private: set the initial states */
|
||||
void gstate_initialize(void);
|
||||
|
||||
/* private: set a new state */
|
||||
void gstate_new_state(struct _LinphoneCore *lc, gstate_t new_state, const char *message);
|
||||
|
||||
typedef void (*ShowInterfaceCb)(struct _LinphoneCore *lc);
|
||||
typedef void (*InviteReceivedCb)(struct _LinphoneCore *lc, const char *from);
|
||||
typedef void (*ByeReceivedCb)(struct _LinphoneCore *lc, const char *from);
|
||||
typedef void (*DisplayStatusCb)(struct _LinphoneCore *lc, const char *message);
|
||||
typedef void (*DisplayMessageCb)(struct _LinphoneCore *lc, const char *message);
|
||||
typedef void (*DisplayUrlCb)(struct _LinphoneCore *lc, const char *message, const char *url);
|
||||
typedef void (*DisplayQuestionCb)(struct _LinphoneCore *lc, const char *message);
|
||||
typedef void (*LinphoneCoreCbFunc)(struct _LinphoneCore *lc,void * user_data);
|
||||
typedef void (*NotifyReceivedCb)(struct _LinphoneCore *lc, LinphoneFriend * fid, const char *url, const char *status, const char *img);
|
||||
typedef void (*NewUnknownSubscriberCb)(struct _LinphoneCore *lc, LinphoneFriend *lf, const char *url);
|
||||
typedef void (*AuthInfoRequested)(struct _LinphoneCore *lc, const char *realm, const char *username);
|
||||
typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog *newcl);
|
||||
typedef void (*TextMessageReceived)(struct _LinphoneCore *lc, LinphoneChatRoom *room, const char *from, const char *message);
|
||||
typedef void (*GeneralStateChange)(struct _LinphoneCore *lc, LinphoneGeneralState *gstate);
|
||||
|
||||
typedef struct _LinphoneVTable
|
||||
{
|
||||
ShowInterfaceCb show;
|
||||
InviteReceivedCb inv_recv;
|
||||
ByeReceivedCb bye_recv;
|
||||
NotifyReceivedCb notify_recv;
|
||||
NewUnknownSubscriberCb new_unknown_subscriber;
|
||||
AuthInfoRequested auth_info_requested;
|
||||
DisplayStatusCb display_status;
|
||||
DisplayMessageCb display_message;
|
||||
#ifdef VINCENT_MAURY_RSVP
|
||||
/* the yes/no dialog box */
|
||||
DisplayMessageCb display_yes_no;
|
||||
#endif
|
||||
DisplayMessageCb display_warning;
|
||||
DisplayUrlCb display_url;
|
||||
DisplayQuestionCb display_question;
|
||||
CallLogUpdated call_log_updated;
|
||||
TextMessageReceived text_received;
|
||||
GeneralStateChange general_state;
|
||||
} LinphoneCoreVTable;
|
||||
|
||||
typedef struct _LCCallbackObj
|
||||
{
|
||||
LinphoneCoreCbFunc _func;
|
||||
void * _user_data;
|
||||
}LCCallbackObj;
|
||||
|
||||
|
||||
|
||||
typedef enum _LinphoneFirewallPolicy{
|
||||
LINPHONE_POLICY_NO_FIREWALL,
|
||||
LINPHONE_POLICY_USE_NAT_ADDRESS,
|
||||
LINPHONE_POLICY_USE_STUN
|
||||
} LinphoneFirewallPolicy;
|
||||
|
||||
typedef struct _LinphoneCore
|
||||
{
|
||||
LinphoneCoreVTable vtable;
|
||||
struct _LpConfig *config;
|
||||
net_config_t net_conf;
|
||||
sip_config_t sip_conf;
|
||||
rtp_config_t rtp_conf;
|
||||
sound_config_t sound_conf;
|
||||
video_config_t video_conf;
|
||||
codecs_config_t codecs_conf;
|
||||
ui_config_t ui_conf;
|
||||
autoreplier_config_t autoreplier_conf;
|
||||
LinphoneProxyConfig *default_proxy;
|
||||
MSList *friends;
|
||||
MSList *auth_info;
|
||||
struct _RingStream *ringstream;
|
||||
LCCallbackObj preview_finished_cb;
|
||||
bool_t preview_finished;
|
||||
LinphoneCall *call; /* the current call, in the future it will be a list of calls (conferencing)*/
|
||||
int rid; /*registration id*/
|
||||
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;
|
||||
struct _RtpProfile *local_profile;
|
||||
MSList *subscribers; /* unknown subscribers */
|
||||
int minutes_away;
|
||||
LinphoneOnlineStatus presence_mode;
|
||||
LinphoneOnlineStatus prev_mode;
|
||||
char *alt_contact;
|
||||
void *data;
|
||||
ms_mutex_t lock;
|
||||
char *play_file;
|
||||
char *rec_file;
|
||||
time_t prevtime;
|
||||
int dw_audio_bw;
|
||||
int up_audio_bw;
|
||||
int dw_video_bw;
|
||||
int up_video_bw;
|
||||
int audio_bw;
|
||||
int automatic_action;
|
||||
bool_t use_files;
|
||||
bool_t apply_nat_settings;
|
||||
#ifdef VINCENT_MAURY_RSVP
|
||||
/* QoS parameters*/
|
||||
int rsvp_enable;
|
||||
int rpc_enable;
|
||||
#endif
|
||||
} LinphoneCore;
|
||||
|
||||
#define LINPHONE_IPADDR_SIZE 64
|
||||
|
||||
/* THE main API */
|
||||
|
||||
void linphone_core_enable_logs(FILE *file);
|
||||
void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc);
|
||||
void linphone_core_disable_logs(void);
|
||||
|
||||
const char *linphone_core_get_version(void);
|
||||
|
||||
LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable,
|
||||
const char *config_path, void* userdata);
|
||||
|
||||
void linphone_core_init(LinphoneCore *lc, const LinphoneCoreVTable *vtable,
|
||||
const char *config_path, void * userdata);
|
||||
|
||||
/* function to be periodically called in a main loop */
|
||||
void linphone_core_iterate(LinphoneCore *lc);
|
||||
|
||||
int linphone_core_invite(LinphoneCore *lc, const char *url);
|
||||
|
||||
int linphone_core_refer(LinphoneCore *lc, const char *url);
|
||||
|
||||
bool_t linphone_core_inc_invite_pending(LinphoneCore*lc);
|
||||
|
||||
bool_t linphone_core_in_call(const LinphoneCore *lc);
|
||||
|
||||
int linphone_core_accept_call(LinphoneCore *lc, const char *url);
|
||||
|
||||
int linphone_core_terminate_call(LinphoneCore *lc, const char *url);
|
||||
|
||||
void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf);
|
||||
|
||||
int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact);
|
||||
|
||||
const char *linphone_core_get_primary_contact(LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_guess_hostname(LinphoneCore *lc, bool_t val);
|
||||
bool_t linphone_core_get_guess_hostname(LinphoneCore *lc);
|
||||
|
||||
bool_t linphone_core_ipv6_enabled(LinphoneCore *lc);
|
||||
void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val);
|
||||
|
||||
osip_from_t *linphone_core_get_primary_contact_parsed(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);
|
||||
|
||||
int linphone_core_get_download_bandwidth(const LinphoneCore *lc);
|
||||
int linphone_core_get_upload_bandwidth(const 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);
|
||||
|
||||
int linphone_core_set_audio_codecs(LinphoneCore *lc, MSList *codecs);
|
||||
/* returns a MSList of PayloadType */
|
||||
const MSList *linphone_core_get_video_codecs(const LinphoneCore *lc);
|
||||
|
||||
int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs);
|
||||
|
||||
bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType *pt);
|
||||
|
||||
int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config);
|
||||
|
||||
void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config);
|
||||
|
||||
const MSList *linphone_core_get_proxy_config_list(const LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_default_proxy(LinphoneCore *lc, LinphoneProxyConfig *config);
|
||||
|
||||
void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index);
|
||||
|
||||
int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **config);
|
||||
|
||||
void linphone_core_add_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info);
|
||||
|
||||
void linphone_core_remove_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info);
|
||||
|
||||
void linphone_core_abort_authentication(LinphoneCore *lc, LinphoneAuthInfo *info);
|
||||
|
||||
void linphone_core_clear_all_auth_info(LinphoneCore *lc);
|
||||
|
||||
int linphone_core_get_audio_jittcomp(LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_audio_jittcomp(LinphoneCore *lc, int value);
|
||||
|
||||
int linphone_core_get_audio_port(const LinphoneCore *lc);
|
||||
|
||||
int linphone_core_get_video_port(const LinphoneCore *lc);
|
||||
|
||||
int linphone_core_get_nortp_timeout(const LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_audio_port(LinphoneCore *lc, int port);
|
||||
|
||||
void linphone_core_set_video_port(LinphoneCore *lc, int port);
|
||||
|
||||
void linphone_core_set_nortp_timeout(LinphoneCore *lc, int port);
|
||||
|
||||
void linphone_core_set_use_info_for_dtmf(LinphoneCore *lc, bool_t use_info);
|
||||
|
||||
bool_t linphone_core_get_use_info_for_dtmf(LinphoneCore *lc);
|
||||
|
||||
int linphone_core_get_sip_port(LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_sip_port(LinphoneCore *lc,int port);
|
||||
|
||||
void linphone_core_set_inc_timeout(LinphoneCore *lc, int seconds);
|
||||
|
||||
int linphone_core_get_inc_timeout(LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_stun_server(LinphoneCore *lc, const char *server);
|
||||
|
||||
const char * linphone_core_get_stun_server(const LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_nat_address(LinphoneCore *lc, const char *addr);
|
||||
|
||||
const char *linphone_core_get_nat_address(const LinphoneCore *lc);
|
||||
|
||||
void linphone_core_set_firewall_policy(LinphoneCore *lc, LinphoneFirewallPolicy pol);
|
||||
|
||||
LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc);
|
||||
|
||||
const char * linphone_core_get_relay_addr(const LinphoneCore *lc);
|
||||
|
||||
int linphone_core_set_relay_addr(LinphoneCore *lc, const char *addr);
|
||||
|
||||
/* sound functions */
|
||||
/* returns a null terminated static array of string describing the sound devices */
|
||||
const char** linphone_core_get_sound_devices(LinphoneCore *lc);
|
||||
int linphone_core_get_ring_level(LinphoneCore *lc);
|
||||
int linphone_core_get_play_level(LinphoneCore *lc);
|
||||
int linphone_core_get_rec_level(LinphoneCore *lc);
|
||||
void linphone_core_set_ring_level(LinphoneCore *lc, int level);
|
||||
void linphone_core_set_play_level(LinphoneCore *lc, int level);
|
||||
void linphone_core_set_rec_level(LinphoneCore *lc, int level);
|
||||
const char * linphone_core_get_ringer_device(LinphoneCore *lc);
|
||||
const char * linphone_core_get_playback_device(LinphoneCore *lc);
|
||||
const char * linphone_core_get_capture_device(LinphoneCore *lc);
|
||||
int linphone_core_set_ringer_device(LinphoneCore *lc, const char * devid);
|
||||
int linphone_core_set_playback_device(LinphoneCore *lc, const char * devid);
|
||||
int linphone_core_set_capture_device(LinphoneCore *lc, const char * devid);
|
||||
char linphone_core_get_sound_source(LinphoneCore *lc);
|
||||
void linphone_core_set_sound_source(LinphoneCore *lc, char source);
|
||||
void linphone_core_set_ring(LinphoneCore *lc, const char *path);
|
||||
const char *linphone_core_get_ring(LinphoneCore *lc);
|
||||
int linphone_core_preview_ring(LinphoneCore *lc, const char *ring,LinphoneCoreCbFunc func,void * userdata);
|
||||
typedef enum {RINGBACK_TYPE_FR,RINGBACK_TYPE_US} RingBackType;
|
||||
void linphone_core_set_ringback(LinphoneCore *lc,RingBackType type);
|
||||
RingBackType linphone_core_get_ringback(LinphoneCore *lc);
|
||||
void linphone_core_enable_echo_cancelation(LinphoneCore *lc, bool_t val);
|
||||
bool_t linphone_core_echo_cancelation_enabled(LinphoneCore *lc);
|
||||
|
||||
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_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(LinphoneCore *lc);
|
||||
/* notify all friends that have subscribed */
|
||||
void linphone_core_notify_all_friends(LinphoneCore *lc, LinphoneOnlineStatus os);
|
||||
|
||||
/* returns a list of LinphoneCallLog */
|
||||
MSList * linphone_core_get_call_logs(LinphoneCore *lc);
|
||||
|
||||
/* video support */
|
||||
void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t display_enabled);
|
||||
bool_t linphone_core_video_enabled(LinphoneCore *lc);
|
||||
|
||||
/*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);
|
||||
|
||||
|
||||
|
||||
void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t val);
|
||||
bool_t linphone_core_video_preview_enabled(const LinphoneCore *lc);
|
||||
|
||||
|
||||
|
||||
/* returns a null terminated static array of string describing the webcams */
|
||||
const char** linphone_core_get_video_devices(const LinphoneCore *lc);
|
||||
int linphone_core_set_video_device(LinphoneCore *lc, const char *id);
|
||||
const char *linphone_core_get_video_device(const LinphoneCore *lc);
|
||||
|
||||
int linphone_core_get_mtu(const LinphoneCore *lc);
|
||||
void linphone_core_set_mtu(LinphoneCore *lc, int mtu);
|
||||
|
||||
bool_t linphone_core_is_in_main_thread(LinphoneCore *lc);
|
||||
|
||||
void *linphone_core_get_user_data(LinphoneCore *lc);
|
||||
|
||||
/* returns LpConfig object to read/write to the config file: usefull if you wish to extend
|
||||
the config file with your own sections */
|
||||
struct _LpConfig *linphone_core_get_config(LinphoneCore *lc);
|
||||
|
||||
void linphone_core_uninit(LinphoneCore *lc);
|
||||
void linphone_core_destroy(LinphoneCore *lc);
|
||||
|
||||
/* end of lecacy api */
|
||||
|
||||
/*internal use only */
|
||||
#define linphone_core_lock(lc) ms_mutex_lock(&(lc)->lock)
|
||||
#define linphone_core_unlock(lc) ms_mutex_unlock((&lc)->lock)
|
||||
void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call);
|
||||
void linphone_core_stop_media_streams(LinphoneCore *lc);
|
||||
const char * linphone_core_get_identity(LinphoneCore *lc);
|
||||
const char * linphone_core_get_route(LinphoneCore *lc);
|
||||
bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, char **real_url, osip_to_t **real_parsed_url, char **route);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
354
linphone/coreapi/lpconfig.c
Normal file
354
linphone/coreapi/lpconfig.c
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
/***************************************************************************
|
||||
* lpconfig.c
|
||||
*
|
||||
* Thu Mar 10 11:13:44 2005
|
||||
* Copyright 2005 Simon Morlat
|
||||
* Email 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#define MAX_LEN 1024
|
||||
|
||||
#include "linphonecore.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define lp_new0(type,n) (type*)calloc(sizeof(type),n)
|
||||
|
||||
#include "lpconfig.h"
|
||||
|
||||
#define LISTNODE(_struct_) \
|
||||
struct _struct_ *_prev;\
|
||||
struct _struct_ *_next;
|
||||
|
||||
typedef struct _ListNode{
|
||||
LISTNODE(_ListNode)
|
||||
} ListNode;
|
||||
|
||||
typedef void (*ListNodeForEachFunc)(ListNode *);
|
||||
|
||||
ListNode * list_node_append(ListNode *head,ListNode *elem){
|
||||
ListNode *e=head;
|
||||
while(e->_next!=NULL) e=e->_next;
|
||||
e->_next=elem;
|
||||
elem->_prev=e;
|
||||
return head;
|
||||
}
|
||||
|
||||
ListNode * list_node_remove(ListNode *head, ListNode *elem){
|
||||
ListNode *before,*after;
|
||||
before=elem->_prev;
|
||||
after=elem->_next;
|
||||
if (before!=NULL) before->_next=after;
|
||||
if (after!=NULL) after->_prev=before;
|
||||
elem->_prev=NULL;
|
||||
elem->_next=NULL;
|
||||
if (head==elem) return after;
|
||||
return head;
|
||||
}
|
||||
|
||||
void list_node_foreach(ListNode *head, ListNodeForEachFunc func){
|
||||
for (;head!=NULL;head=head->_next){
|
||||
func(head);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define LIST_PREPEND(e1,e2) ( (e2)->_prev=NULL,(e2)->_next=(e1),(e1)->_prev=(e2),(e2) )
|
||||
#define LIST_APPEND(head,elem) ((head)==0 ? (elem) : (list_node_append((ListNode*)(head),(ListNode*)(elem)), (head)) )
|
||||
#define LIST_REMOVE(head,elem)
|
||||
|
||||
/* returns void */
|
||||
#define LIST_FOREACH(head) list_node_foreach((ListNode*)head)
|
||||
|
||||
typedef struct _LpItem{
|
||||
char *key;
|
||||
char *value;
|
||||
} LpItem;
|
||||
|
||||
typedef struct _LpSection{
|
||||
char *name;
|
||||
MSList *items;
|
||||
} LpSection;
|
||||
|
||||
struct _LpConfig{
|
||||
FILE *file;
|
||||
char *filename;
|
||||
MSList *sections;
|
||||
};
|
||||
|
||||
LpItem * lp_item_new(const char *key, const char *value){
|
||||
LpItem *item=lp_new0(LpItem,1);
|
||||
item->key=strdup(key);
|
||||
item->value=strdup(value);
|
||||
return item;
|
||||
}
|
||||
|
||||
LpSection *lp_section_new(const char *name){
|
||||
LpSection *sec=lp_new0(LpSection,1);
|
||||
sec->name=strdup(name);
|
||||
return sec;
|
||||
}
|
||||
|
||||
void lp_item_destroy(void *pitem){
|
||||
LpItem *item=(LpItem*)pitem;
|
||||
free(item->key);
|
||||
free(item->value);
|
||||
free(item);
|
||||
}
|
||||
|
||||
void lp_section_destroy(LpSection *sec){
|
||||
free(sec->name);
|
||||
ms_list_for_each(sec->items,lp_item_destroy);
|
||||
ms_list_free(sec->items);
|
||||
free(sec);
|
||||
}
|
||||
|
||||
void lp_section_add_item(LpSection *sec,LpItem *item){
|
||||
sec->items=ms_list_append(sec->items,(void *)item);
|
||||
}
|
||||
|
||||
void lp_config_add_section(LpConfig *lpconfig, LpSection *section){
|
||||
lpconfig->sections=ms_list_append(lpconfig->sections,(void *)section);
|
||||
}
|
||||
|
||||
void lp_config_remove_section(LpConfig *lpconfig, LpSection *section){
|
||||
lpconfig->sections=ms_list_remove(lpconfig->sections,(void *)section);
|
||||
lp_section_destroy(section);
|
||||
}
|
||||
|
||||
static bool_t is_first_char(const char *start, const char *pos){
|
||||
const char *p;
|
||||
for(p=start;p<pos;p++){
|
||||
if (*p!=' ') return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void lp_config_parse(LpConfig *lpconfig){
|
||||
char tmp[MAX_LEN];
|
||||
LpSection *cur=NULL;
|
||||
|
||||
if (lpconfig->file==NULL) return;
|
||||
|
||||
while(fgets(tmp,MAX_LEN,lpconfig->file)!=NULL){
|
||||
char *pos1,*pos2;
|
||||
pos1=strchr(tmp,'[');
|
||||
if (pos1!=NULL && is_first_char(tmp,pos1) ){
|
||||
pos2=strchr(pos1,']');
|
||||
if (pos2!=NULL){
|
||||
int nbs;
|
||||
char secname[MAX_LEN];
|
||||
secname[0]='\0';
|
||||
/* found section */
|
||||
*pos2='\0';
|
||||
nbs = sscanf(pos1+1,"%s",secname);
|
||||
if (nbs == 1 ){
|
||||
if (strlen(secname)>0){
|
||||
cur=lp_section_new(secname);
|
||||
lp_config_add_section(lpconfig,cur);
|
||||
}
|
||||
}else{
|
||||
ms_warning("parse error!");
|
||||
}
|
||||
}
|
||||
}else {
|
||||
pos1=strchr(tmp,'=');
|
||||
if (pos1!=NULL){
|
||||
char key[MAX_LEN];
|
||||
key[0]='\0';
|
||||
|
||||
*pos1='\0';
|
||||
if (sscanf(tmp,"%s",key)>0){
|
||||
|
||||
pos1++;
|
||||
pos2=strchr(pos1,'\n');
|
||||
if (pos2==NULL) pos2=pos1+strlen(pos2);
|
||||
else {
|
||||
*pos2='\0'; /*replace the '\n' */
|
||||
pos2--;
|
||||
}
|
||||
/* remove ending white spaces */
|
||||
for (; pos2>pos1 && *pos2==' ';pos2--) *pos2='\0';
|
||||
if (pos2-pos1>=0){
|
||||
/* found a pair key,value */
|
||||
if (cur!=NULL){
|
||||
lp_section_add_item(cur,lp_item_new(key,pos1));
|
||||
/*printf("Found %s %s=%s\n",cur->name,key,pos1);*/
|
||||
}else{
|
||||
ms_warning("found key,item but no sections");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LpConfig * lp_config_new(const char *filename){
|
||||
LpConfig *lpconfig=lp_new0(LpConfig,1);
|
||||
if (filename!=NULL){
|
||||
lpconfig->filename=strdup(filename);
|
||||
lpconfig->file=fopen(filename,"rw");
|
||||
if (lpconfig->file!=NULL){
|
||||
lp_config_parse(lpconfig);
|
||||
fclose(lpconfig->file);
|
||||
/* make existing configuration files non-group/world-accessible */
|
||||
if (chmod(filename, S_IRUSR | S_IWUSR) == -1)
|
||||
ms_warning("unable to correct permissions on "
|
||||
"configuration file: %s",
|
||||
strerror(errno));
|
||||
lpconfig->file=NULL;
|
||||
}
|
||||
}
|
||||
return lpconfig;
|
||||
}
|
||||
|
||||
void lp_item_set_value(LpItem *item, const char *value){
|
||||
free(item->value);
|
||||
item->value=strdup(value);
|
||||
}
|
||||
|
||||
|
||||
void lp_config_destroy(LpConfig *lpconfig){
|
||||
if (lpconfig->filename!=NULL) free(lpconfig->filename);
|
||||
ms_list_for_each(lpconfig->sections,(void (*)(void*))lp_section_destroy);
|
||||
ms_list_free(lpconfig->sections);
|
||||
free(lpconfig);
|
||||
}
|
||||
|
||||
LpSection *lp_config_find_section(LpConfig *lpconfig, const char *name){
|
||||
LpSection *sec;
|
||||
MSList *elem;
|
||||
/*printf("Looking for section %s\n",name);*/
|
||||
for (elem=lpconfig->sections;elem!=NULL;elem=ms_list_next(elem)){
|
||||
sec=(LpSection*)elem->data;
|
||||
if (strcmp(sec->name,name)==0){
|
||||
/*printf("Section %s found\n",name);*/
|
||||
return sec;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LpItem *lp_section_find_item(LpSection *sec, const char *name){
|
||||
MSList *elem;
|
||||
LpItem *item;
|
||||
/*printf("Looking for item %s\n",name);*/
|
||||
for (elem=sec->items;elem!=NULL;elem=ms_list_next(elem)){
|
||||
item=(LpItem*)elem->data;
|
||||
if (strcmp(item->key,name)==0) {
|
||||
/*printf("Item %s found\n",name);*/
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void lp_section_remove_item(LpSection *sec, LpItem *item){
|
||||
sec->items=ms_list_remove(sec->items,(void *)item);
|
||||
lp_item_destroy(item);
|
||||
}
|
||||
|
||||
const char *lp_config_get_string(LpConfig *lpconfig, const char *section, const char *key, const char *default_string){
|
||||
LpSection *sec;
|
||||
LpItem *item;
|
||||
sec=lp_config_find_section(lpconfig,section);
|
||||
if (sec!=NULL){
|
||||
item=lp_section_find_item(sec,key);
|
||||
if (item!=NULL) return item->value;
|
||||
}
|
||||
return default_string;
|
||||
}
|
||||
|
||||
int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, int default_value){
|
||||
const char *str=lp_config_get_string(lpconfig,section,key,NULL);
|
||||
if (str!=NULL) return atoi(str);
|
||||
else return default_value;
|
||||
}
|
||||
|
||||
void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *key, const char *value){
|
||||
LpItem *item;
|
||||
LpSection *sec=lp_config_find_section(lpconfig,section);
|
||||
if (sec!=NULL){
|
||||
item=lp_section_find_item(sec,key);
|
||||
if (item!=NULL){
|
||||
if (value!=NULL)
|
||||
lp_item_set_value(item,value);
|
||||
else lp_section_remove_item(sec,item);
|
||||
}else{
|
||||
if (value!=NULL)
|
||||
lp_section_add_item(sec,lp_item_new(key,value));
|
||||
}
|
||||
}else if (value!=NULL){
|
||||
sec=lp_section_new(section);
|
||||
lp_config_add_section(lpconfig,sec);
|
||||
lp_section_add_item(sec,lp_item_new(key,value));
|
||||
}
|
||||
}
|
||||
|
||||
void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value){
|
||||
char tmp[30];
|
||||
snprintf(tmp,30,"%i",value);
|
||||
lp_config_set_string(lpconfig,section,key,tmp);
|
||||
}
|
||||
|
||||
void lp_item_write(LpItem *item, FILE *file){
|
||||
fprintf(file,"%s=%s\n",item->key,item->value);
|
||||
}
|
||||
|
||||
void lp_section_write(LpSection *sec, FILE *file){
|
||||
fprintf(file,"[%s]\n",sec->name);
|
||||
ms_list_for_each2(sec->items,(void (*)(void*, void*))lp_item_write,(void *)file);
|
||||
fprintf(file,"\n");
|
||||
}
|
||||
|
||||
int lp_config_sync(LpConfig *lpconfig){
|
||||
FILE *file;
|
||||
if (lpconfig->filename==NULL) return -1;
|
||||
#ifndef WIN32
|
||||
/* don't create group/world-accessible files */
|
||||
(void) umask(S_IRWXG | S_IRWXO);
|
||||
#endif
|
||||
file=fopen(lpconfig->filename,"w");
|
||||
if (file==NULL){
|
||||
ms_warning("Could not write %s !",lpconfig->filename);
|
||||
return -1;
|
||||
}
|
||||
ms_list_for_each2(lpconfig->sections,(void (*)(void *,void*))lp_section_write,(void *)file);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lp_config_has_section(LpConfig *lpconfig, const char *section){
|
||||
if (lp_config_find_section(lpconfig,section)!=NULL) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lp_config_clean_section(LpConfig *lpconfig, const char *section){
|
||||
LpSection *sec=lp_config_find_section(lpconfig,section);
|
||||
if (sec!=NULL){
|
||||
lp_config_remove_section(lpconfig,sec);
|
||||
}
|
||||
}
|
||||
48
linphone/coreapi/lpconfig.h
Normal file
48
linphone/coreapi/lpconfig.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/***************************************************************************
|
||||
* lpconfig.h
|
||||
*
|
||||
* Thu Mar 10 15:02:49 2005
|
||||
* Copyright 2005 Simon Morlat
|
||||
* Email 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef LPCONFIG_H
|
||||
#define LPCONFIG_H
|
||||
|
||||
typedef struct _LpConfig LpConfig;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
LpConfig * lp_config_new(const char *filename);
|
||||
const char *lp_config_get_string(LpConfig *lpconfig, const char *section, const char *key, const char *default_string);
|
||||
int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, int default_value);
|
||||
void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *key, const char *value);
|
||||
void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value);
|
||||
int lp_config_sync(LpConfig *lpconfig);
|
||||
int lp_config_has_section(LpConfig *lpconfig, const char *section);
|
||||
void lp_config_clean_section(LpConfig *lpconfig, const char *section);
|
||||
void lp_config_destroy(LpConfig *cfg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
450
linphone/coreapi/misc.c
Normal file
450
linphone/coreapi/misc.c
Normal file
|
|
@ -0,0 +1,450 @@
|
|||
|
||||
/*
|
||||
linphone
|
||||
Copyright (C) 2000 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 "private.h"
|
||||
#include "mediastreamer2/mediastream.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
static char lock_name[80];
|
||||
static char lock_set=0;
|
||||
/* put a lock file in /tmp. this is called when linphone runs as a daemon*/
|
||||
int set_lock_file()
|
||||
{
|
||||
FILE *lockfile;
|
||||
|
||||
snprintf(lock_name,80,"/tmp/linphone.%i",getuid());
|
||||
lockfile=fopen(lock_name,"w");
|
||||
if (lockfile==NULL)
|
||||
{
|
||||
printf("Failed to create lock file.\n");
|
||||
return(-1);
|
||||
}
|
||||
fprintf(lockfile,"%i",getpid());
|
||||
fclose(lockfile);
|
||||
lock_set=1;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* looks if there is a lock file. If presents return its content (the pid of the already running linphone), if not found, returns -1*/
|
||||
int get_lock_file()
|
||||
{
|
||||
int pid;
|
||||
FILE *lockfile;
|
||||
|
||||
snprintf(lock_name,80,"/tmp/linphone.%i",getuid());
|
||||
lockfile=fopen(lock_name,"r");
|
||||
if (lockfile==NULL)
|
||||
return(-1);
|
||||
if (fscanf(lockfile,"%i",&pid)!=1){
|
||||
ms_warning("Could not read pid in lock file.");
|
||||
fclose(lockfile);
|
||||
return -1;
|
||||
}
|
||||
fclose(lockfile);
|
||||
return pid;
|
||||
}
|
||||
|
||||
/* remove the lock file if it was set*/
|
||||
int remove_lock_file()
|
||||
{
|
||||
int err=0;
|
||||
if (lock_set)
|
||||
{
|
||||
err=unlink(lock_name);
|
||||
lock_set=0;
|
||||
}
|
||||
return(err);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char *int2str(int number)
|
||||
{
|
||||
char *numstr=ms_malloc(10);
|
||||
snprintf(numstr,10,"%i",number);
|
||||
return numstr;
|
||||
}
|
||||
|
||||
void check_sound_device(LinphoneCore *lc)
|
||||
{
|
||||
int fd,len;
|
||||
int a;
|
||||
char *file=NULL;
|
||||
char *i810_audio=NULL;
|
||||
char *snd_pcm_oss=NULL;
|
||||
char *snd_mixer_oss=NULL;
|
||||
char *snd_pcm=NULL;
|
||||
|
||||
fd=open("/proc/modules",O_RDONLY);
|
||||
if (fd>0){
|
||||
/* read the entire /proc/modules file and check if sound conf seems correct */
|
||||
/*a=fstat(fd,&statbuf);
|
||||
if (a<0) ms_warning("Can't stat /proc/modules:%s.",strerror(errno));
|
||||
len=statbuf.st_size;
|
||||
if (len==0) ms_warning("/proc/modules has zero size!");
|
||||
*/
|
||||
/***** fstat does not work on /proc/modules for unknown reason *****/
|
||||
len=6000;
|
||||
file=ms_malloc(len+1);
|
||||
a=read(fd,file,len);
|
||||
if (a<len) file=ms_realloc(file,a+1);
|
||||
file[a]='\0';
|
||||
i810_audio=strstr(file,"i810_audio");
|
||||
if (i810_audio!=NULL){
|
||||
/* I'm sorry i put this warning in comments because
|
||||
* i don't use yet the right driver !! */
|
||||
/* lc->vtable.display_warning(lc,_("You are currently using the i810_audio driver.\nThis driver is buggy and so does not work with Linphone.\nWe suggest that you replace it by its equivalent ALSA driver,\neither with packages from your distribution, or by downloading\nALSA drivers at http://www.alsa-project.org."));*/
|
||||
goto end;
|
||||
}
|
||||
snd_pcm=strstr(file,"snd-pcm");
|
||||
if (snd_pcm!=NULL){
|
||||
snd_pcm_oss=strstr(file,"snd-pcm-oss");
|
||||
snd_mixer_oss=strstr(file,"snd-mixer-oss");
|
||||
if (snd_pcm_oss==NULL){
|
||||
lc->vtable.display_warning(lc,_("Your computer appears to be using ALSA sound drivers.\nThis is the best choice. However the pcm oss emulation module\nis missing and linphone needs it. Please execute\n'modprobe snd-pcm-oss' as root to load it."));
|
||||
}
|
||||
if (snd_mixer_oss==NULL){
|
||||
lc->vtable.display_warning(lc,_("Your computer appears to be using ALSA sound drivers.\nThis is the best choice. However the mixer oss emulation module\nis missing and linphone needs it. Please execute\n 'modprobe snd-mixer-oss' as root to load it."));
|
||||
}
|
||||
}
|
||||
}else {
|
||||
#ifdef __linux
|
||||
ms_warning("Could not open /proc/modules.");
|
||||
#endif
|
||||
}
|
||||
/* now check general volume. Some user forget to rise it and then complain that linphone is
|
||||
not working */
|
||||
/* but some other users complain that linphone should not change levels...
|
||||
if (lc->sound_conf.sndcard!=NULL){
|
||||
a=snd_card_get_level(lc->sound_conf.sndcard,SND_CARD_LEVEL_GENERAL);
|
||||
if (a<50){
|
||||
ms_warning("General level is quite low (%i). Linphone rises it up for you.",a);
|
||||
snd_card_set_level(lc->sound_conf.sndcard,SND_CARD_LEVEL_GENERAL,80);
|
||||
}
|
||||
}
|
||||
*/
|
||||
end:
|
||||
if (file!=NULL) ms_free(file);
|
||||
if (fd>0) close(fd);
|
||||
}
|
||||
|
||||
#define UDP_HDR_SZ 8
|
||||
#define RTP_HDR_SZ 12
|
||||
#define IP4_HDR_SZ 20 /*20 is the minimum, but there may be some options*/
|
||||
|
||||
const char *payload_type_get_description(PayloadType *pt){
|
||||
return (const char *)pt->user_data;
|
||||
}
|
||||
|
||||
void payload_type_set_enable(PayloadType *pt,int value)
|
||||
{
|
||||
if ((value)!=0) payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED); \
|
||||
else payload_type_unset_flag(pt,PAYLOAD_TYPE_ENABLED);
|
||||
}
|
||||
|
||||
|
||||
bool_t payload_type_enabled(PayloadType *pt) {
|
||||
return (((pt)->flags & PAYLOAD_TYPE_ENABLED)!=0);
|
||||
}
|
||||
|
||||
int payload_type_get_bitrate(PayloadType *pt)
|
||||
{
|
||||
return pt->normal_bitrate;
|
||||
}
|
||||
const char *payload_type_get_mime(PayloadType *pt){
|
||||
return pt->mime_type;
|
||||
}
|
||||
|
||||
int payload_type_get_rate(PayloadType *pt){
|
||||
return pt->clock_rate;
|
||||
}
|
||||
|
||||
static double get_audio_payload_bandwidth(const PayloadType *pt){
|
||||
double npacket=50;
|
||||
double packet_size;
|
||||
int bitrate;
|
||||
bitrate=pt->normal_bitrate;
|
||||
packet_size=(double)(bitrate/(50*8))+UDP_HDR_SZ+RTP_HDR_SZ+IP4_HDR_SZ;
|
||||
return packet_size*8.0*npacket;
|
||||
}
|
||||
|
||||
void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc, const PayloadType *pt){
|
||||
lc->audio_bw=(int)(get_audio_payload_bandwidth(pt)/1000.0);
|
||||
/*update*/
|
||||
linphone_core_set_upload_bandwidth(lc,lc->net_conf.upload_bw);
|
||||
}
|
||||
|
||||
static void update_allocated_audio_bandwidth(LinphoneCore *lc){
|
||||
const MSList *elem;
|
||||
PayloadType *max=NULL;
|
||||
for(elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){
|
||||
PayloadType *pt=(PayloadType*)elem->data;
|
||||
if (payload_type_enabled(pt)){
|
||||
if (max==NULL) max=pt;
|
||||
else if (max->normal_bitrate<pt->normal_bitrate){
|
||||
max=pt;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (max) {
|
||||
linphone_core_update_allocated_audio_bandwidth(lc,max);
|
||||
}
|
||||
}
|
||||
|
||||
/* return TRUE if codec can be used with bandwidth, FALSE else*/
|
||||
bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType *pt)
|
||||
{
|
||||
double codec_band;
|
||||
int min_audio_bw;
|
||||
int min_video_bw;
|
||||
bool_t ret=FALSE;
|
||||
/*
|
||||
update allocated audio bandwidth to allocate the remaining to video.
|
||||
This must be done outside calls, because after sdp negociation
|
||||
the audio bandwidth is refined to the selected codec
|
||||
*/
|
||||
if (!linphone_core_in_call(lc)) update_allocated_audio_bandwidth(lc);
|
||||
min_audio_bw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc),
|
||||
linphone_core_get_upload_bandwidth(lc));
|
||||
if (min_audio_bw==0) min_audio_bw=-1;
|
||||
min_video_bw=get_min_bandwidth(lc->dw_video_bw,lc->up_video_bw);
|
||||
|
||||
switch (pt->type){
|
||||
case PAYLOAD_AUDIO_CONTINUOUS:
|
||||
case PAYLOAD_AUDIO_PACKETIZED:
|
||||
codec_band=get_audio_payload_bandwidth(pt);
|
||||
ret=bandwidth_is_greater(min_audio_bw*1000,codec_band);
|
||||
//ms_message("Payload %s: %g",pt->mime_type,codec_band);
|
||||
break;
|
||||
case PAYLOAD_VIDEO:
|
||||
if (min_video_bw!=0) {/* infinite (-1) or strictly positive*/
|
||||
/*let the video use all the bandwidth minus the maximum bandwidth used by audio */
|
||||
if (min_video_bw>0)
|
||||
pt->normal_bitrate=min_video_bw*1000;
|
||||
else
|
||||
pt->normal_bitrate=512000;
|
||||
ret=TRUE;
|
||||
}
|
||||
else ret=FALSE;
|
||||
break;
|
||||
}
|
||||
/*if (!ret) ms_warning("Payload %s is not usable with your internet connection.",pt->mime_type);*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PayloadType * find_payload(RtpProfile *prof, PayloadType *pt /*from config*/){
|
||||
PayloadType *candidate=NULL;
|
||||
int i;
|
||||
PayloadType *it;
|
||||
for(i=0;i<127;++i){
|
||||
it=rtp_profile_get_payload(prof,i);
|
||||
if (it!=NULL && strcasecmp(pt->mime_type,it->mime_type)==0
|
||||
&& (pt->clock_rate==it->clock_rate || pt->clock_rate<=0)
|
||||
&& payload_type_get_user_data(it)==NULL ){
|
||||
if ( (pt->recv_fmtp && it->recv_fmtp && strcasecmp(pt->recv_fmtp,it->recv_fmtp)==0) ||
|
||||
(pt->recv_fmtp==NULL && it->recv_fmtp==NULL) ){
|
||||
/*exact match*/
|
||||
return it;
|
||||
}else candidate=it;
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
static MSList *fix_codec_list(RtpProfile *prof, MSList *conflist)
|
||||
{
|
||||
MSList *elem;
|
||||
MSList *newlist=NULL;
|
||||
PayloadType *payload,*confpayload;
|
||||
|
||||
for (elem=conflist;elem!=NULL;elem=ms_list_next(elem))
|
||||
{
|
||||
confpayload=(PayloadType*)elem->data;
|
||||
payload=find_payload(prof,confpayload);
|
||||
if (payload!=NULL){
|
||||
if (ms_filter_codec_supported(confpayload->mime_type)){
|
||||
MSFilterDesc *desc=ms_filter_get_encoder(confpayload->mime_type);
|
||||
payload_type_set_user_data(payload,(void*)desc->text);
|
||||
payload_type_set_enable(payload,payload_type_enabled(confpayload));
|
||||
newlist=ms_list_append(newlist,payload);
|
||||
}
|
||||
}
|
||||
else{
|
||||
ms_warning("Cannot support %s/%i: does not exist.",confpayload->mime_type,
|
||||
confpayload->clock_rate);
|
||||
}
|
||||
}
|
||||
return newlist;
|
||||
}
|
||||
|
||||
|
||||
void linphone_core_setup_local_rtp_profile(LinphoneCore *lc)
|
||||
{
|
||||
int i;
|
||||
MSList *audiopt,*videopt;
|
||||
PayloadType *payload;
|
||||
bool_t prepend;
|
||||
lc->local_profile=rtp_profile_clone_full(&av_profile);
|
||||
|
||||
/* first look at the list given by configuration file to see if
|
||||
it is correct */
|
||||
audiopt=fix_codec_list(lc->local_profile,lc->codecs_conf.audio_codecs);
|
||||
videopt=fix_codec_list(lc->local_profile,lc->codecs_conf.video_codecs);
|
||||
|
||||
/* now find and add payloads that are not listed in the configuration
|
||||
codec list */
|
||||
for (i=0;i<127;i++)
|
||||
{
|
||||
payload=rtp_profile_get_payload(lc->local_profile,i);
|
||||
if (payload!=NULL){
|
||||
if (payload_type_get_user_data(payload)!=NULL) continue;
|
||||
/* find a mediastreamer codec for this payload type */
|
||||
if (ms_filter_codec_supported(payload->mime_type)){
|
||||
MSFilterDesc *desc=ms_filter_get_encoder(payload->mime_type);
|
||||
ms_message("Adding new codec %s/%i",payload->mime_type,payload->clock_rate);
|
||||
payload_type_set_enable(payload,1);
|
||||
payload_type_set_user_data(payload,(void *)desc->text);
|
||||
prepend=FALSE;
|
||||
/* by default, put speex, mpeg4, or h264 on top of list*/
|
||||
if (strcmp(payload->mime_type,"speex")==0)
|
||||
prepend=TRUE;
|
||||
if (strcmp(payload->mime_type,"MP4V-ES")==0)
|
||||
prepend=TRUE;
|
||||
if (strcmp(payload->mime_type,"H264")==0)
|
||||
prepend=TRUE;
|
||||
switch (payload->type){
|
||||
case PAYLOAD_AUDIO_CONTINUOUS:
|
||||
case PAYLOAD_AUDIO_PACKETIZED:
|
||||
if (prepend)
|
||||
audiopt=ms_list_prepend(audiopt,(void *)payload);
|
||||
else
|
||||
audiopt=ms_list_append(audiopt,(void *)payload);
|
||||
break;
|
||||
case PAYLOAD_VIDEO:
|
||||
if (prepend)
|
||||
videopt=ms_list_prepend(videopt,(void *)payload);
|
||||
else
|
||||
videopt=ms_list_append(videopt,(void *)payload);
|
||||
break;
|
||||
default:
|
||||
ms_error("Unsupported rtp media type.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ms_list_for_each(lc->codecs_conf.audio_codecs,(void (*)(void*))payload_type_destroy);
|
||||
ms_list_for_each(lc->codecs_conf.video_codecs,(void (*)(void *))payload_type_destroy);
|
||||
ms_list_free(lc->codecs_conf.audio_codecs);
|
||||
ms_list_free(lc->codecs_conf.video_codecs);
|
||||
/* set the fixed lists instead:*/
|
||||
lc->codecs_conf.audio_codecs=audiopt;
|
||||
lc->codecs_conf.video_codecs=videopt;
|
||||
}
|
||||
|
||||
int from_2char_without_params(osip_from_t *from,char **str)
|
||||
{
|
||||
osip_from_t *tmpfrom=NULL;
|
||||
osip_from_clone(from,&tmpfrom);
|
||||
if (tmpfrom!=NULL){
|
||||
while(!osip_list_eol(&tmpfrom->gen_params,0)){
|
||||
osip_generic_param_t *param=(osip_generic_param_t*)osip_list_get(&tmpfrom->gen_params,0);
|
||||
osip_generic_param_free(param);
|
||||
osip_list_remove(&tmpfrom->gen_params,0);
|
||||
}
|
||||
}else return -1;
|
||||
osip_from_to_str(tmpfrom,str);
|
||||
osip_from_free(tmpfrom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret){
|
||||
FILE *f=popen(command,"r");
|
||||
if (f!=NULL){
|
||||
int err;
|
||||
*result=ms_malloc(4096);
|
||||
err=fread(*result,1,4096-1,f);
|
||||
if (err<0){
|
||||
ms_warning("Error reading command output:%s",strerror(errno));
|
||||
ms_free(result);
|
||||
return FALSE;
|
||||
}
|
||||
(*result)[err]=0;
|
||||
err=pclose(f);
|
||||
if (command_ret!=NULL) *command_ret=err;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if defined(HAVE_GETIFADDRS) && defined(INET6)
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <ifaddrs.h>
|
||||
bool_t host_has_ipv6_network()
|
||||
{
|
||||
struct ifaddrs *ifp;
|
||||
struct ifaddrs *ifpstart;
|
||||
bool_t ipv6_present=FALSE;
|
||||
|
||||
if (getifaddrs (&ifpstart) < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (ifp=ifpstart; ifp != NULL; ifp = ifp->ifa_next)
|
||||
{
|
||||
if (!ifp->ifa_addr)
|
||||
continue;
|
||||
|
||||
switch (ifp->ifa_addr->sa_family) {
|
||||
case AF_INET:
|
||||
|
||||
break;
|
||||
case AF_INET6:
|
||||
ipv6_present=TRUE;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs (ifpstart);
|
||||
|
||||
return ipv6_present;
|
||||
}
|
||||
#else
|
||||
|
||||
bool_t host_has_ipv6_network()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
208
linphone/coreapi/presence.c
Normal file
208
linphone/coreapi/presence.c
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2000 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 "linphonecore.h"
|
||||
#include <eXosip2/eXosip.h>
|
||||
#include <osipparser2/osip_message.h>
|
||||
#include "private.h"
|
||||
|
||||
|
||||
extern const char *__policy_enum_to_str(LinphoneSubscribePolicy pol);
|
||||
|
||||
|
||||
void linphone_core_add_subscriber(LinphoneCore *lc, const char *subscriber, int did, int nid){
|
||||
LinphoneFriend *fl=linphone_friend_new_with_addr(subscriber);
|
||||
if (fl==NULL) return ;
|
||||
fl->in_did=did;
|
||||
linphone_friend_set_nid(fl,nid);
|
||||
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) {
|
||||
char *clean_subscriber; /* we need to remove tags...*/
|
||||
from_2char_without_params(fl->url,&clean_subscriber);
|
||||
lc->vtable.new_unknown_subscriber(lc,fl,clean_subscriber);
|
||||
ms_free(clean_subscriber);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf){
|
||||
linphone_friend_set_inc_subscribe_policy(lf,LinphoneSPDeny);
|
||||
}
|
||||
|
||||
static void __do_notify(void * data, void * user_data){
|
||||
int *tab=(int*)user_data;
|
||||
LinphoneFriend *lf=(LinphoneFriend*)data;
|
||||
linphone_friend_notify(lf,tab[0],tab[1]);
|
||||
}
|
||||
|
||||
void __linphone_core_notify_all_friends(LinphoneCore *lc, int ss, int os){
|
||||
int tab[2];
|
||||
tab[0]=ss;
|
||||
tab[1]=os;
|
||||
ms_list_for_each2(lc->friends,__do_notify,(void *)tab);
|
||||
}
|
||||
|
||||
void linphone_core_notify_all_friends(LinphoneCore *lc, LinphoneOnlineStatus os){
|
||||
ms_message("Notifying all friends that we are in status %i",os);
|
||||
__linphone_core_notify_all_friends(lc,EXOSIP_SUBCRSTATE_ACTIVE,os);
|
||||
}
|
||||
|
||||
/* check presence state before answering to call; returns TRUE if we can proceed, else answer the appropriate answer
|
||||
to close the dialog*/
|
||||
bool_t linphone_core_check_presence(LinphoneCore *lc){
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void linphone_subscription_new(LinphoneCore *lc, eXosip_event_t *ev){
|
||||
LinphoneFriend *lf=NULL;
|
||||
osip_from_t *from=ev->request->from;
|
||||
char *tmp;
|
||||
osip_message_t *msg=NULL;
|
||||
|
||||
osip_from_to_str(ev->request->from,&tmp);
|
||||
|
||||
ms_message("Receiving new subscription from %s.",tmp);
|
||||
/* check if we answer to this subscription */
|
||||
if (find_friend(lc->friends,from,&lf)!=NULL){
|
||||
lf->in_did=ev->did;
|
||||
linphone_friend_set_nid(lf,ev->nid);
|
||||
eXosip_insubscription_build_answer(ev->tid,202,&msg);
|
||||
eXosip_insubscription_send_answer(ev->tid,202,msg);
|
||||
__eXosip_wakeup_event();
|
||||
linphone_friend_done(lf); /*this will do all necessary actions */
|
||||
}else{
|
||||
/* check if this subscriber is in our black list */
|
||||
if (find_friend(lc->subscribers,from,&lf)){
|
||||
if (lf->pol==LinphoneSPDeny){
|
||||
ms_message("Rejecting %s because we already rejected it once.",from);
|
||||
eXosip_insubscription_send_answer(ev->tid,401,NULL);
|
||||
}
|
||||
else {
|
||||
/* else it is in wait for approval state, because otherwise it is in the friend list.*/
|
||||
ms_message("New subscriber found in friend list, in %s state.",__policy_enum_to_str(lf->pol));
|
||||
}
|
||||
}else {
|
||||
eXosip_insubscription_build_answer(ev->tid,202,&msg);
|
||||
eXosip_insubscription_send_answer(ev->tid,202,msg);
|
||||
linphone_core_add_subscriber(lc,tmp,ev->did,ev->nid);
|
||||
}
|
||||
}
|
||||
osip_free(tmp);
|
||||
}
|
||||
|
||||
void linphone_notify_recv(LinphoneCore *lc, eXosip_event_t *ev)
|
||||
{
|
||||
const char *status=_("Gone");
|
||||
const char *img="sip-closed.png";
|
||||
char *tmp;
|
||||
LinphoneFriend *lf;
|
||||
osip_from_t *friend=NULL;
|
||||
osip_from_t *from=NULL;
|
||||
osip_body_t *body=NULL;
|
||||
LinphoneOnlineStatus estatus=LINPHONE_STATUS_UNKNOWN;
|
||||
ms_message("Receiving notify with sid=%i,nid=%i",ev->sid,ev->nid);
|
||||
if (ev->request!=NULL){
|
||||
from=ev->request->from;
|
||||
osip_message_get_body(ev->request,0,&body);
|
||||
if (body==NULL){
|
||||
ms_error("No body in NOTIFY");
|
||||
return;
|
||||
}
|
||||
if (strstr(body->body,"pending")!=NULL){
|
||||
status=_("Waiting for Approval");
|
||||
img="sip-wfa.png";
|
||||
estatus=LINPHONE_STATUS_PENDING;
|
||||
}else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) {
|
||||
status=_("Online");
|
||||
img="sip-online.png";
|
||||
estatus=LINPHONE_STATUS_ONLINE;
|
||||
}else if (strstr(body->body,"busy")!=NULL){
|
||||
status=_("Busy");
|
||||
img="sip-busy.png";
|
||||
estatus=LINPHONE_STATUS_BUSY;
|
||||
}else if (strstr(body->body,"berightback")!=NULL
|
||||
|| strstr(body->body,"in-transit")!=NULL ){
|
||||
status=_("Be Right Back");
|
||||
img="sip-bifm.png";
|
||||
estatus=LINPHONE_STATUS_BERIGHTBACK;
|
||||
}else if (strstr(body->body,"away")!=NULL){
|
||||
status=_("Away");
|
||||
img="sip-away.png";
|
||||
estatus=LINPHONE_STATUS_AWAY;
|
||||
}else if (strstr(body->body,"onthephone")!=NULL
|
||||
|| strstr(body->body,"on-the-phone")!=NULL){
|
||||
status=_("On The Phone");
|
||||
img="sip-otp.png";
|
||||
estatus=LINPHONE_STATUS_ONTHEPHONE;
|
||||
}else if (strstr(body->body,"outtolunch")!=NULL
|
||||
|| strstr(body->body,"meal")!=NULL){
|
||||
status=_("Out To Lunch");
|
||||
img="sip-otl.png";
|
||||
estatus=LINPHONE_STATUS_OUTTOLUNCH;
|
||||
}else if (strstr(body->body,"closed")!=NULL){
|
||||
status=_("Closed");
|
||||
img="sip-away.png";
|
||||
estatus=LINPHONE_STATUS_CLOSED;
|
||||
}else{
|
||||
status=_("Gone");
|
||||
img="sip-closed.png";
|
||||
estatus=LINPHONE_STATUS_OFFLINE;
|
||||
}
|
||||
ms_message("We are notified that sip:%s@%s has online status %s",from->url->username,from->url->host,status);
|
||||
}
|
||||
lf=linphone_find_friend_by_sid(lc->friends,ev->sid);
|
||||
if (lf!=NULL){
|
||||
friend=lf->url;
|
||||
from_2char_without_params(friend,&tmp);
|
||||
lf->status=estatus;
|
||||
lc->vtable.notify_recv(lc,(LinphoneFriend*)lf,tmp,status,img);
|
||||
ms_free(tmp);
|
||||
if (ev->ss_status==EXOSIP_SUBCRSTATE_TERMINATED) {
|
||||
lf->sid=-1;
|
||||
lf->out_did=-1;
|
||||
ms_message("Outgoing subscription terminated by remote.");
|
||||
}
|
||||
}else{
|
||||
ms_message("But this person is not part of our friend list, so we don't care.");
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_subscription_answered(LinphoneCore *lc, eXosip_event_t *ev){
|
||||
LinphoneFriend *lf;
|
||||
osip_from_t *from=ev->response->to;
|
||||
find_friend(lc->friends,from,&lf);
|
||||
if (lf!=NULL){
|
||||
lf->out_did=ev->did;
|
||||
linphone_friend_set_sid(lf,ev->sid);
|
||||
}else{
|
||||
ms_warning("Receiving answer for unknown subscribe sip:%s@%s", from->url->username,from->url->host);
|
||||
}
|
||||
}
|
||||
void linphone_subscription_closed(LinphoneCore *lc,eXosip_event_t *ev){
|
||||
LinphoneFriend *lf;
|
||||
osip_from_t *from=ev->request->from;
|
||||
lf=linphone_find_friend_by_nid(lc->friends,ev->nid);
|
||||
if (lf!=NULL){
|
||||
lf->in_did=-1;
|
||||
linphone_friend_set_nid(lf,-1);
|
||||
}else{
|
||||
ms_warning("Receiving unsuscribe for unknown in-subscribtion from sip:%s@%s", from->url->username, from->url->host);
|
||||
}
|
||||
}
|
||||
121
linphone/coreapi/private.h
Normal file
121
linphone/coreapi/private.h
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/***************************************************************************
|
||||
* private.h
|
||||
*
|
||||
* Mon Jun 13 14:23:23 2005
|
||||
* Copyright 2005 Simon Morlat
|
||||
* Email simon dot morlat at linphone dot 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 _PRIVATE_H
|
||||
#define _PRIVATE_H
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include <eXosip2/eXosip.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef LINPHONE_VERSION
|
||||
#define LINPHONE_VERSION "2.99.4"
|
||||
#endif
|
||||
|
||||
#ifndef LIBLINPHONE_VERSION
|
||||
#define LIBLINPHONE_VERSION LINPHONE_VERSION
|
||||
#endif
|
||||
|
||||
#ifndef PACKAGE_SOUND_DIR
|
||||
#define PACKAGE_SOUND_DIR "."
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <io.h> /* for access() */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETTEXT
|
||||
#include <libintl.h>
|
||||
#ifndef _
|
||||
#define _(String) gettext(String)
|
||||
#endif
|
||||
#else
|
||||
#define _(something) (something)
|
||||
#endif
|
||||
|
||||
void linphone_core_init_media_streams(LinphoneCore *lc);
|
||||
|
||||
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_proxy_config_send_publish(LinphoneProxyConfig *cfg, LinphoneOnlineStatus os);
|
||||
|
||||
int linphone_online_status_to_eXosip(LinphoneOnlineStatus os);
|
||||
|
||||
void linphone_friend_set_sid(LinphoneFriend *lf, int sid);
|
||||
void linphone_friend_set_nid(LinphoneFriend *lf, int nid);
|
||||
void linphone_friend_notify(LinphoneFriend *lf, int ss, LinphoneOnlineStatus os);
|
||||
|
||||
int set_lock_file();
|
||||
int get_lock_file();
|
||||
int remove_lock_file();
|
||||
int do_registration(LinphoneCore *lc, bool_t doit);
|
||||
void check_for_registration(LinphoneCore *lc);
|
||||
char *int2str(int number);
|
||||
int from_2char_without_params(osip_from_t *from,char **str);
|
||||
void check_sound_device(LinphoneCore *lc);
|
||||
void linphone_core_setup_local_rtp_profile(LinphoneCore *lc);
|
||||
void linphone_core_get_local_ip(LinphoneCore *lc, const char *to, char *result);
|
||||
bool_t host_has_ipv6_network();
|
||||
bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret);
|
||||
|
||||
static inline int get_min_bandwidth(int dbw, int ubw){
|
||||
if (dbw<0) return ubw;
|
||||
if (ubw<0) return dbw;
|
||||
return MIN(dbw,ubw);
|
||||
}
|
||||
|
||||
static inline bool_t bandwidth_is_greater(int bw1, int bw2){
|
||||
if (bw1<0) return TRUE;
|
||||
else if (bw2<0) return FALSE;
|
||||
else return bw1>=bw2;
|
||||
}
|
||||
|
||||
#define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0
|
||||
|
||||
void linphone_process_authentication(LinphoneCore* lc, eXosip_event_t *ev);
|
||||
void linphone_authentication_ok(LinphoneCore *lc, eXosip_event_t *ev);
|
||||
void linphone_subscription_new(LinphoneCore *lc, eXosip_event_t *ev);
|
||||
void linphone_notify_recv(LinphoneCore *lc,eXosip_event_t *ev);
|
||||
LinphoneProxyConfig *linphone_core_get_proxy_config_from_rid(LinphoneCore *lc, int rid);
|
||||
|
||||
void linphone_subscription_answered(LinphoneCore *lc, eXosip_event_t *ev);
|
||||
void linphone_subscription_closed(LinphoneCore *lc, eXosip_event_t *ev);
|
||||
|
||||
void linphone_call_init_media_params(LinphoneCall *call);
|
||||
|
||||
void linphone_set_sdp(osip_message_t *sip, const char *sdp);
|
||||
|
||||
MSList *find_friend(MSList *fl, const osip_from_t *friend, LinphoneFriend **lf);
|
||||
LinphoneFriend *linphone_find_friend_by_nid(MSList *l, int nid);
|
||||
LinphoneFriend *linphone_find_friend_by_sid(MSList *l, int sid);
|
||||
|
||||
void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc, const PayloadType *pt);
|
||||
|
||||
#endif /* _PRIVATE_H */
|
||||
512
linphone/coreapi/proxy.c
Normal file
512
linphone/coreapi/proxy.c
Normal file
|
|
@ -0,0 +1,512 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2000 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include <eXosip2/eXosip.h>
|
||||
#include <osipparser2/osip_message.h>
|
||||
#include "lpconfig.h"
|
||||
#include "private.h"
|
||||
|
||||
|
||||
void linphone_proxy_config_init(LinphoneProxyConfig *obj){
|
||||
memset(obj,0,sizeof(LinphoneProxyConfig));
|
||||
obj->rid=-1;
|
||||
obj->expires=3600;
|
||||
}
|
||||
|
||||
LinphoneProxyConfig *linphone_proxy_config_new(){
|
||||
LinphoneProxyConfig *obj=NULL;
|
||||
obj=ms_new(LinphoneProxyConfig,1);
|
||||
linphone_proxy_config_init(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){
|
||||
if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy);
|
||||
if (obj->reg_identity!=NULL) ms_free(obj->reg_identity);
|
||||
if (obj->reg_route!=NULL) ms_free(obj->reg_route);
|
||||
}
|
||||
|
||||
static void linphone_proxy_config_register(LinphoneProxyConfig *obj){
|
||||
osip_message_t *msg;
|
||||
eXosip_lock();
|
||||
eXosip_register_build_register(obj->rid,obj->expires,&msg);
|
||||
eXosip_register_send_register(obj->rid,msg);
|
||||
eXosip_unlock();
|
||||
}
|
||||
|
||||
|
||||
int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr){
|
||||
int err;
|
||||
osip_from_t *url;
|
||||
if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy);
|
||||
obj->reg_proxy=NULL;
|
||||
if (server_addr!=NULL && strlen(server_addr)>0){
|
||||
osip_from_init(&url);
|
||||
err=osip_from_parse(url,server_addr);
|
||||
if (err==0 && url->url->host!=NULL){
|
||||
obj->reg_proxy=ms_strdup(server_addr);
|
||||
}else{
|
||||
ms_warning("Could not parse %s",server_addr);
|
||||
}
|
||||
osip_from_free(url);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity){
|
||||
int err=0;
|
||||
osip_from_t *url;
|
||||
if (identity!=NULL && strlen(identity)>0){
|
||||
osip_from_init(&url);
|
||||
err=osip_from_parse(url,identity);
|
||||
if (err<0 || url->url->host==NULL || url->url->username==NULL){
|
||||
ms_warning("Could not parse %s",identity);
|
||||
osip_from_free(url);
|
||||
return;
|
||||
}
|
||||
osip_from_free(url);
|
||||
} else err=-2;
|
||||
if (obj->reg_identity!=NULL) {
|
||||
ms_free(obj->reg_identity);
|
||||
obj->reg_identity=NULL;
|
||||
}
|
||||
if (err==-2) obj->reg_identity=NULL;
|
||||
else obj->reg_identity=ms_strdup(identity);
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route)
|
||||
{
|
||||
int err;
|
||||
osip_uri_param_t *lr_param=NULL;
|
||||
osip_route_t *rt=NULL;
|
||||
char *tmproute=NULL;
|
||||
if (route!=NULL && strlen(route)>0){
|
||||
osip_route_init(&rt);
|
||||
err=osip_route_parse(rt,route);
|
||||
if (err<0){
|
||||
ms_warning("Could not parse %s",route);
|
||||
osip_route_free(rt);
|
||||
return ;
|
||||
}
|
||||
if (obj->reg_route!=NULL) {
|
||||
ms_free(obj->reg_route);
|
||||
obj->reg_route=NULL;
|
||||
}
|
||||
|
||||
/* check if the lr parameter is set , if not add it */
|
||||
osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
|
||||
if (lr_param==NULL){
|
||||
osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
|
||||
osip_route_to_str(rt,&tmproute);
|
||||
obj->reg_route=ms_strdup(tmproute);
|
||||
osip_free(tmproute);
|
||||
}else obj->reg_route=ms_strdup(route);
|
||||
}else{
|
||||
if (obj->reg_route!=NULL) ms_free(obj->reg_route);
|
||||
obj->reg_route=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool_t linphone_proxy_config_check(LinphoneCore *lc, LinphoneProxyConfig *obj){
|
||||
if (obj->reg_proxy==NULL){
|
||||
if (lc->vtable.display_warning)
|
||||
lc->vtable.display_warning(lc,_("The sip proxy address you entered is invalid, it must start with \"sip:\""
|
||||
" followed by a hostname."));
|
||||
return FALSE;
|
||||
}
|
||||
if (obj->reg_identity==NULL){
|
||||
if (lc->vtable.display_warning)
|
||||
lc->vtable.display_warning(lc,_("The sip identity you entered is invalid.\nIt should look like "
|
||||
"sip:username@proxydomain, such as sip:alice@example.net"));
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_enableregister(LinphoneProxyConfig *obj, bool_t val){
|
||||
obj->reg_sendregister=val;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_expires(LinphoneProxyConfig *obj, int val){
|
||||
if (val<=0) val=600;
|
||||
obj->expires=val;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val){
|
||||
obj->publish=val;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_edit(LinphoneProxyConfig *obj){
|
||||
obj->frozen=TRUE;
|
||||
if (obj->reg_sendregister){
|
||||
/* unregister */
|
||||
if (obj->registered) {
|
||||
osip_message_t *msg;
|
||||
eXosip_lock();
|
||||
eXosip_register_build_register(obj->rid,0,&msg);
|
||||
eXosip_register_send_register(obj->rid,msg);
|
||||
eXosip_unlock();
|
||||
obj->registered=FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_proxy_config_apply(LinphoneProxyConfig *obj,LinphoneCore *lc)
|
||||
{
|
||||
obj->lc=lc;
|
||||
linphone_proxy_config_done(obj);
|
||||
}
|
||||
|
||||
int linphone_proxy_config_done(LinphoneProxyConfig *obj)
|
||||
{
|
||||
const char *id_str;
|
||||
if (!linphone_proxy_config_check(obj->lc,obj)) return -1;
|
||||
if (obj->reg_identity!=NULL) id_str=obj->reg_identity;
|
||||
else id_str=linphone_core_get_primary_contact(obj->lc);
|
||||
obj->frozen=FALSE;
|
||||
if (obj->reg_sendregister){
|
||||
char *ct=NULL;
|
||||
osip_message_t *msg=NULL;
|
||||
obj->rid=eXosip_register_build_initial_register(id_str,obj->reg_proxy,NULL,obj->expires,&msg);
|
||||
eXosip_register_send_register(obj->rid,msg);
|
||||
if (ct!=NULL) osip_free(ct);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char *realm)
|
||||
{
|
||||
if (cfg->realm!=NULL) {
|
||||
ms_free(cfg->realm);
|
||||
cfg->realm=NULL;
|
||||
}
|
||||
if (realm!=NULL) cfg->realm=ms_strdup(realm);
|
||||
}
|
||||
|
||||
int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy,
|
||||
LinphoneOnlineStatus presence_mode)
|
||||
{
|
||||
osip_message_t *pub;
|
||||
int i;
|
||||
const char *from=NULL;
|
||||
char buf[5000];
|
||||
|
||||
if (proxy->publish==FALSE) return 0;
|
||||
|
||||
if (proxy!=NULL) {
|
||||
from=linphone_proxy_config_get_identity(proxy);
|
||||
}
|
||||
if (from==NULL) from=linphone_core_get_primary_contact(proxy->lc);
|
||||
|
||||
if (presence_mode==LINPHONE_STATUS_ONLINE)
|
||||
{
|
||||
snprintf(buf, 5000, "<?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==LINPHONE_STATUS_BUSY
|
||||
||presence_mode==LINPHONE_STATUS_NOT_DISTURB)
|
||||
{
|
||||
snprintf(buf, 5000, "<?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==LINPHONE_STATUS_BERIGHTBACK)
|
||||
{
|
||||
snprintf(buf, 5000, "<?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==LINPHONE_STATUS_AWAY
|
||||
||presence_mode==LINPHONE_STATUS_MOVED
|
||||
||presence_mode==LINPHONE_STATUS_ALT_SERVICE)
|
||||
{
|
||||
snprintf(buf, 5000, "<?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==LINPHONE_STATUS_ONTHEPHONE)
|
||||
{
|
||||
snprintf(buf, 5000, "<?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==LINPHONE_STATUS_OUTTOLUNCH)
|
||||
{
|
||||
snprintf(buf, 5000, "<?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 if (presence_mode==LINPHONE_STATUS_OFFLINE)
|
||||
{
|
||||
/* */
|
||||
snprintf(buf, 5000, "<?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");
|
||||
}
|
||||
|
||||
i = eXosip_build_publish(&pub, (char *)from, (char *)from, NULL, "presence", "1800", "application/pidf+xml", buf);
|
||||
|
||||
if (i<0)
|
||||
{
|
||||
ms_message("Failed to build publish request.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
eXosip_lock();
|
||||
i = eXosip_publish(pub, from); /* should update the sip-if-match parameter
|
||||
from sip-etag from last 200ok of PUBLISH */
|
||||
eXosip_unlock();
|
||||
if (i<0)
|
||||
{
|
||||
ms_message("Failed to send publish request.");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){
|
||||
if (!linphone_proxy_config_check(lc,cfg)) return -1;
|
||||
lc->sip_conf.proxies=ms_list_append(lc->sip_conf.proxies,(void *)cfg);
|
||||
linphone_proxy_config_apply(cfg,lc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void linphone_friend_check_for_removed_proxy(LinphoneFriend *lf, LinphoneProxyConfig *cfg);
|
||||
|
||||
void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){
|
||||
MSList *elem;
|
||||
lc->sip_conf.proxies=ms_list_remove(lc->sip_conf.proxies,(void *)cfg);
|
||||
/* add to the list of destroyed proxies, so that the possible unREGISTER request can succeed authentication */
|
||||
lc->sip_conf.deleted_proxies=ms_list_append(lc->sip_conf.deleted_proxies,(void *)cfg);
|
||||
/* this will unREGISTER */
|
||||
linphone_proxy_config_edit(cfg);
|
||||
if (lc->default_proxy==cfg){
|
||||
lc->default_proxy=NULL;
|
||||
}
|
||||
/* invalidate all references to this proxy in our friend list */
|
||||
for (elem=lc->friends;elem!=NULL;elem=ms_list_next(elem)){
|
||||
linphone_friend_check_for_removed_proxy((LinphoneFriend*)elem->data,cfg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void linphone_core_set_default_proxy(LinphoneCore *lc, LinphoneProxyConfig *config){
|
||||
/* check if this proxy is in our list */
|
||||
if (config!=NULL){
|
||||
if (ms_list_find(lc->sip_conf.proxies,config)==NULL){
|
||||
ms_warning("Bad proxy address: it is not in the list !");
|
||||
lc->default_proxy=NULL;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
lc->default_proxy=config;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index){
|
||||
if (index<0) linphone_core_set_default_proxy(lc,NULL);
|
||||
else linphone_core_set_default_proxy(lc,ms_list_nth_data(lc->sip_conf.proxies,index));
|
||||
}
|
||||
|
||||
int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **config){
|
||||
int pos=-1;
|
||||
if (config!=NULL) *config=lc->default_proxy;
|
||||
if (lc->default_proxy!=NULL){
|
||||
pos=ms_list_position(lc->sip_conf.proxies,ms_list_find(lc->sip_conf.proxies,(void *)lc->default_proxy));
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
static int rid_compare(const void *pcfg,const void *prid){
|
||||
const LinphoneProxyConfig *cfg=(const LinphoneProxyConfig*)pcfg;
|
||||
const int *rid=(const int*)prid;
|
||||
ms_message("cfg= %s, cfg->rid=%i, rid=%i",cfg->reg_proxy, cfg->rid, *rid);
|
||||
return cfg->rid-(*rid);
|
||||
}
|
||||
|
||||
LinphoneProxyConfig *linphone_core_get_proxy_config_from_rid(LinphoneCore *lc, int rid){
|
||||
MSList *elem=ms_list_find_custom(lc->sip_conf.proxies,rid_compare, &rid);
|
||||
if (elem==NULL){
|
||||
ms_message("linphone_core_get_proxy_config_from_rid: searching in deleted proxies...");
|
||||
elem=ms_list_find_custom(lc->sip_conf.deleted_proxies,rid_compare, &rid);
|
||||
}
|
||||
if (elem==NULL) return NULL;
|
||||
else return (LinphoneProxyConfig*)elem->data;
|
||||
}
|
||||
|
||||
void linphone_core_retry_proxy_register(LinphoneCore *lc, const char *realm)
|
||||
{
|
||||
MSList *elem;
|
||||
for (elem=lc->sip_conf.proxies;elem!=NULL;elem=ms_list_next(elem)){
|
||||
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
|
||||
/*ms_message("linphone_core_retry_proxy_register: cfg->auth_pending=%i, cfg->realm=%s, realm=%s",
|
||||
cfg->auth_pending,cfg->realm,realm);*/
|
||||
if (cfg->auth_pending && cfg->realm!=NULL && strcmp(cfg->realm,realm)==0){
|
||||
ms_message("Restarting REGISTER request for %s.",cfg->reg_proxy);
|
||||
linphone_proxy_config_register(cfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const MSList *linphone_core_get_proxy_config_list(const LinphoneCore *lc){
|
||||
return lc->sip_conf.proxies;
|
||||
}
|
||||
|
||||
|
||||
void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyConfig *obj, int index)
|
||||
{
|
||||
char key[50];
|
||||
|
||||
sprintf(key,"proxy_%i",index);
|
||||
lp_config_clean_section(config,key);
|
||||
if (obj==NULL){
|
||||
return;
|
||||
}
|
||||
if (obj->reg_proxy!=NULL){
|
||||
lp_config_set_string(config,key,"reg_proxy",obj->reg_proxy);
|
||||
}
|
||||
if (obj->reg_route!=NULL){
|
||||
lp_config_set_string(config,key,"reg_route",obj->reg_route);
|
||||
}
|
||||
if (obj->reg_identity!=NULL){
|
||||
lp_config_set_string(config,key,"reg_identity",obj->reg_identity);
|
||||
}
|
||||
lp_config_set_int(config,key,"reg_expires",obj->expires);
|
||||
lp_config_set_int(config,key,"reg_sendregister",obj->reg_sendregister);
|
||||
lp_config_set_int(config,key,"publish",obj->publish);
|
||||
}
|
||||
|
||||
LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LpConfig *config, int index)
|
||||
{
|
||||
const char *tmp;
|
||||
LinphoneProxyConfig *cfg;
|
||||
char key[50];
|
||||
|
||||
sprintf(key,"proxy_%i",index);
|
||||
|
||||
if (!lp_config_has_section(config,key)){
|
||||
return NULL;
|
||||
}
|
||||
tmp=lp_config_get_string(config,key,"reg_proxy",NULL);
|
||||
if (tmp==NULL) return NULL;
|
||||
cfg=linphone_proxy_config_new();
|
||||
linphone_proxy_config_set_server_addr(cfg,tmp);
|
||||
|
||||
tmp=lp_config_get_string(config,key,"reg_route",NULL);
|
||||
if (tmp!=NULL) linphone_proxy_config_set_route(cfg,tmp);
|
||||
|
||||
tmp=lp_config_get_string(config,key,"reg_identity",NULL);
|
||||
if (tmp!=NULL) linphone_proxy_config_set_identity(cfg,tmp);
|
||||
|
||||
linphone_proxy_config_expires(cfg,lp_config_get_int(config,key,"reg_expires",600));
|
||||
linphone_proxy_config_enableregister(cfg,lp_config_get_int(config,key,"reg_sendregister",0));
|
||||
|
||||
linphone_proxy_config_enable_publish(cfg,lp_config_get_int(config,key,"publish",0));
|
||||
|
||||
return cfg;
|
||||
}
|
||||
682
linphone/coreapi/sdphandler.c
Normal file
682
linphone/coreapi/sdphandler.c
Normal file
|
|
@ -0,0 +1,682 @@
|
|||
/*
|
||||
* 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"));
|
||||
abort ();
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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_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(&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.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");
|
||||
/* 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) 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->accept_audio_codecs != NULL)
|
||||
{
|
||||
ncodec = 0;
|
||||
/* 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 */
|
||||
err = sdph->accept_audio_codecs (ctx,
|
||||
&payload);
|
||||
if (err == 0 && payload.localport > 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++)
|
||||
{
|
||||
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 && payload.localport > 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);
|
||||
}
|
||||
101
linphone/coreapi/sdphandler.h
Normal file
101
linphone/coreapi/sdphandler.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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
|
||||
2
linphone/debian/.cvsignore
Normal file
2
linphone/debian/.cvsignore
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
15
linphone/debian/Makefile.am
Normal file
15
linphone/debian/Makefile.am
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
EXTRA_DIST= copyright dirs manpage.sgml.ex rules \
|
||||
control docs manpage.1.ex menu watch.ex changelog
|
||||
|
||||
|
||||
changelog: changelog.stamp
|
||||
echo -n -e "linphone (">changelog
|
||||
echo -n -e $(VERSION)>>changelog
|
||||
echo -n -e "-1) unstable; urgency=low\n\n">>changelog
|
||||
echo -n -e " * New Release.\n\n">>changelog
|
||||
echo -n -e " -- Simon Morlat <simon.morlat@linphone.org> ">>changelog
|
||||
date -R >>changelog
|
||||
touch changelog.stamp
|
||||
|
||||
changelog.stamp:
|
||||
touch changelog.stamp
|
||||
14
linphone/debian/control
Normal file
14
linphone/debian/control
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
Source: linphone
|
||||
Section: sound
|
||||
Priority: optional
|
||||
Maintainer: Uwe Steinmann <uwe@steinmann.cx>
|
||||
Build-Depends: debhelper (>> 3.0.0), libosip0-dev (>= 0.9.6), libasound2-dev (>=0.9.4)
|
||||
Standards-Version: 3.5.2
|
||||
|
||||
Package: linphone
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, libosip0 (>= 0.9.6), libspeex1, libasound2 (>=0.9.4)
|
||||
Description: A sip phone
|
||||
Linphone is a web phone: it let you phone to your friends anywhere in the
|
||||
whole world, freely, simply by using the internet. It is compatible with the
|
||||
well known SIP protocol.
|
||||
10
linphone/debian/copyright
Normal file
10
linphone/debian/copyright
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
This package was debianized by Uwe Steinmann <uwe@steinmann.cx> on
|
||||
Thu, 28 Feb 2002 08:29:57 +0100.
|
||||
|
||||
It was downloaded from http://www.linphone.org
|
||||
|
||||
Upstream Author(s): Simon Morlat <simon.morlat@linphone.org>
|
||||
|
||||
Copyright:
|
||||
|
||||
GPL
|
||||
2
linphone/debian/dirs
Normal file
2
linphone/debian/dirs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
usr/bin
|
||||
usr/sbin
|
||||
3
linphone/debian/docs
Normal file
3
linphone/debian/docs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
BUGS
|
||||
NEWS
|
||||
README
|
||||
60
linphone/debian/manpage.1.ex
Normal file
60
linphone/debian/manpage.1.ex
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH LINPHONE SECTION "February 28, 2002"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
linphone \- program to do something
|
||||
.SH SYNOPSIS
|
||||
.B linphone
|
||||
.RI [ options ] " files" ...
|
||||
.br
|
||||
.B bar
|
||||
.RI [ options ] " files" ...
|
||||
.SH DESCRIPTION
|
||||
This manual page documents briefly the
|
||||
.B linphone
|
||||
and
|
||||
.B bar
|
||||
commands.
|
||||
This manual page was written for the Debian distribution
|
||||
because the original program does not have a manual page.
|
||||
Instead, it has documentation in the GNU Info format; see below.
|
||||
.PP
|
||||
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
||||
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
|
||||
.\" respectively.
|
||||
\fBlinphone\fP is a program that...
|
||||
.SH OPTIONS
|
||||
These programs follow the usual GNU command line syntax, with long
|
||||
options starting with two dashes (`-').
|
||||
A summary of options is included below.
|
||||
For a complete description, see the Info files.
|
||||
.TP
|
||||
.B \-h, \-\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
.B \-v, \-\-version
|
||||
Show version of program.
|
||||
.SH SEE ALSO
|
||||
.BR bar (1),
|
||||
.BR baz (1).
|
||||
.br
|
||||
The programs are documented fully by
|
||||
.IR "The Rise and Fall of a Fooish Bar" ,
|
||||
available via the Info system.
|
||||
.SH AUTHOR
|
||||
This manual page was written by Uwe Steinmann <uwe@steinmann.cx>,
|
||||
for the Debian GNU/Linux system (but may be used by others).
|
||||
152
linphone/debian/manpage.sgml.ex
Normal file
152
linphone/debian/manpage.sgml.ex
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
|
||||
|
||||
<!-- Process this file with docbook-to-man to generate an nroff manual
|
||||
page: `docbook-to-man manpage.sgml > manpage.1'. You may view
|
||||
the manual page with: `docbook-to-man manpage.sgml | nroff -man |
|
||||
less'. A typical entry in a Makefile or Makefile.am is:
|
||||
|
||||
manpage.1: manpage.sgml
|
||||
docbook-to-man $< > $@
|
||||
|
||||
|
||||
The docbook-to-man binary is found in the docbook-to-man package.
|
||||
Please remember that if you create the nroff version in one of the
|
||||
debian/rules file targets (such as build), you will need to include
|
||||
docbook-to-man in your Build-Depends control field.
|
||||
|
||||
-->
|
||||
|
||||
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
|
||||
<!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
|
||||
<!ENTITY dhsurname "<surname>SURNAME</surname>">
|
||||
<!-- Please adjust the date whenever revising the manpage. -->
|
||||
<!ENTITY dhdate "<date>February 28, 2002</date>">
|
||||
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
|
||||
allowed: see man(7), man(1). -->
|
||||
<!ENTITY dhsection "<manvolnum>SECTION</manvolnum>">
|
||||
<!ENTITY dhemail "<email>uwe@steinmann.cx</email>">
|
||||
<!ENTITY dhusername "Uwe Steinmann">
|
||||
<!ENTITY dhucpackage "<refentrytitle>LINPHONE</refentrytitle>">
|
||||
<!ENTITY dhpackage "linphone">
|
||||
|
||||
<!ENTITY debian "<productname>Debian</productname>">
|
||||
<!ENTITY gnu "<acronym>GNU</acronym>">
|
||||
]>
|
||||
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<address>
|
||||
&dhemail;
|
||||
</address>
|
||||
<author>
|
||||
&dhfirstname;
|
||||
&dhsurname;
|
||||
</author>
|
||||
<copyright>
|
||||
<year>2001</year>
|
||||
<holder>&dhusername;</holder>
|
||||
</copyright>
|
||||
&dhdate;
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
&dhucpackage;
|
||||
|
||||
&dhsection;
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname>&dhpackage;</refname>
|
||||
|
||||
<refpurpose>program to do something</refpurpose>
|
||||
</refnamediv>
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>&dhpackage;</command>
|
||||
|
||||
<arg><option>-e <replaceable>this</replaceable></option></arg>
|
||||
|
||||
<arg><option>--example <replaceable>that</replaceable></option></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
<refsect1>
|
||||
<title>DESCRIPTION</title>
|
||||
|
||||
<para>This manual page documents briefly the
|
||||
<command>&dhpackage;</command> and <command>bar</command>
|
||||
commands.</para>
|
||||
|
||||
<para>This manual page was written for the &debian; distribution
|
||||
because the original program does not have a manual page.
|
||||
Instead, it has documentation in the &gnu;
|
||||
<application>Info</application> format; see below.</para>
|
||||
|
||||
<para><command>&dhpackage;</command> is a program that...</para>
|
||||
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>OPTIONS</title>
|
||||
|
||||
<para>These programs follow the usual GNU command line syntax,
|
||||
with long options starting with two dashes (`-'). A summary of
|
||||
options is included below. For a complete description, see the
|
||||
<application>Info</application> files.</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>-h</option>
|
||||
<option>--help</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Show summary of options.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-v</option>
|
||||
<option>--version</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Show version of program.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>SEE ALSO</title>
|
||||
|
||||
<para>bar (1), baz (1).</para>
|
||||
|
||||
<para>The programs are documented fully by <citetitle>The Rise and
|
||||
Fall of a Fooish Bar</citetitle> available via the
|
||||
<application>Info</application> system.</para>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>AUTHOR</title>
|
||||
|
||||
<para>This manual page was written by &dhusername; &dhemail; for
|
||||
the &debian; system (but may be used by others). Permission is
|
||||
granted to copy, distribute and/or modify this document under
|
||||
the terms of the <acronym>GNU</acronym> Free Documentation
|
||||
License, Version 1.1 or any later version published by the Free
|
||||
Software Foundation; with no Invariant Sections, no Front-Cover
|
||||
Texts and no Back-Cover Texts.</para>
|
||||
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
||||
<!-- Keep this comment at the end of the file
|
||||
Local variables:
|
||||
mode: sgml
|
||||
sgml-omittag:t
|
||||
sgml-shorttag:t
|
||||
sgml-minimize-attributes:nil
|
||||
sgml-always-quote-attributes:t
|
||||
sgml-indent-step:2
|
||||
sgml-indent-data:t
|
||||
sgml-parent-document:nil
|
||||
sgml-default-dtd-file:nil
|
||||
sgml-exposed-tags:nil
|
||||
sgml-local-catalogs:nil
|
||||
sgml-local-ecat-files:nil
|
||||
End:
|
||||
-->
|
||||
|
||||
|
||||
3
linphone/debian/menu
Normal file
3
linphone/debian/menu
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
?package(linphone):needs=X11 section=Apps/Net \
|
||||
title="Linphone" command="/usr/bin/linphone" hints="Telephony"\
|
||||
icon="/usr/share/pixmaps/linphone/linphone2.xpm"
|
||||
107
linphone/debian/rules
Executable file
107
linphone/debian/rules
Executable file
|
|
@ -0,0 +1,107 @@
|
|||
#!/usr/bin/make -f
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# GNU copyright 1997 to 1999 by Joey Hess.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
# This is the debhelper compatibility version to use.
|
||||
export DH_COMPAT=3
|
||||
|
||||
# These are used for cross-compiling and for saving the configure script
|
||||
# from having to guess our platform (since we know it already)
|
||||
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
|
||||
|
||||
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
|
||||
CFLAGS += -g
|
||||
endif
|
||||
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
|
||||
INSTALL_PROGRAM += -s
|
||||
endif
|
||||
|
||||
configure: configure-stamp
|
||||
configure-stamp:
|
||||
dh_testdir
|
||||
# Add here commands to configure the package.
|
||||
./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --disable-static --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --sysconfdir=/etc
|
||||
|
||||
touch configure-stamp
|
||||
|
||||
build: build-stamp
|
||||
|
||||
build-stamp: configure-stamp
|
||||
dh_testdir
|
||||
|
||||
# Add here commands to compile the package.
|
||||
$(MAKE)
|
||||
#/usr/bin/docbook-to-man debian/linphone.sgml > linphone.1
|
||||
|
||||
touch build-stamp
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
rm -f build-stamp configure-stamp
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
-make clean
|
||||
-make distclean
|
||||
-test -r /usr/share/misc/config.sub && \
|
||||
-cp -f /usr/share/misc/config.sub config.sub
|
||||
-test -r /usr/share/misc/config.guess && \
|
||||
-cp -f /usr/share/misc/config.guess config.guess
|
||||
|
||||
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
|
||||
# Add here commands to install the package into debian/linphone.
|
||||
$(MAKE) install PIXDESTDIR=$(CURDIR)/debian/linphone prefix=$(CURDIR)/debian/linphone/usr sysconfdir=$(CURDIR)/debian/linphone/etc
|
||||
# remove speex libs, in order to not to conflict with speex debian package.
|
||||
rm -f $(CURDIR)/debian/linphone/usr/lib/libspeex* \
|
||||
$(CURDIR)/debian/linphone/usr/bin/speex* \
|
||||
$(CURDIR)/debian/linphone/usr/include/speex* \
|
||||
$(CURDIR)/debian/linphone/usr/share/man/man1/speex*
|
||||
|
||||
# Build architecture-independent files here.
|
||||
binary-indep: build install
|
||||
# We have nothing to do by default.
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
# dh_installdebconf
|
||||
dh_installdocs
|
||||
dh_installexamples
|
||||
dh_installmenu
|
||||
# dh_installlogrotate
|
||||
# dh_installemacsen
|
||||
# dh_installpam
|
||||
# dh_installmime
|
||||
# dh_installinit
|
||||
dh_installcron
|
||||
dh_installman
|
||||
dh_installinfo
|
||||
# dh_undocumented
|
||||
dh_installchangelogs ChangeLog
|
||||
dh_link
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
# dh_makeshlibs
|
||||
dh_installdeb
|
||||
# dh_perl
|
||||
dh_shlibdeps
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install configure
|
||||
5
linphone/debian/watch.ex
Normal file
5
linphone/debian/watch.ex
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Example watch control file for uscan
|
||||
# Rename this file to "watch" and then you can run the "uscan" command
|
||||
# to check for upstream updates and more.
|
||||
# Site Directory Pattern Version Script
|
||||
sunsite.unc.edu /pub/Linux/Incoming linphone-(.*)\.tar\.gz debian uupdate
|
||||
2
linphone/developer-docs/.cvsignore
Normal file
2
linphone/developer-docs/.cvsignore
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
2
linphone/developer-docs/mediastreamer/.cvsignore
Normal file
2
linphone/developer-docs/mediastreamer/.cvsignore
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Makefile.in
|
||||
Makefile
|
||||
6
linphone/exosip/.cvsignore
Normal file
6
linphone/exosip/.cvsignore
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
*.lo
|
||||
*.la
|
||||
16
linphone/exosip/Makefile.am
Normal file
16
linphone/exosip/Makefile.am
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
noinst_LTLIBRARIES = libeXosip.la
|
||||
|
||||
|
||||
AM_CFLAGS = $(EXOSIP_CFLAGS)
|
||||
|
||||
libeXosip_la_SOURCES = eXosip.c \
|
||||
jrequest.c jresponse.c jcallback.c jdialog.c udp.c \
|
||||
jcall.c jreg.c jfreinds.c jidentity.c eXutils.c \
|
||||
jnotify.c jsubscribers.c jsubscribe.c jevents.c \
|
||||
sdp_offans.c misc.c eXosip2.h \
|
||||
jpipe.c jpipe.h jauth.c jpublish.c \
|
||||
eXosip.h eXosip_cfg.h
|
||||
|
||||
libeXosip_la_LIBADD = $(EXOSIP_LIBS)
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
3192
linphone/exosip/eXosip.c
Normal file
3192
linphone/exosip/eXosip.c
Normal file
File diff suppressed because it is too large
Load diff
752
linphone/exosip/eXosip.h
Normal file
752
linphone/exosip/eXosip.h
Normal file
|
|
@ -0,0 +1,752 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#ifndef __EXOSIP_H__
|
||||
#define __EXOSIP_H__
|
||||
|
||||
#include <osipparser2/osip_parser.h>
|
||||
#include <osip2/osip_negotiation.h>
|
||||
#include <time.h>
|
||||
|
||||
/**
|
||||
* @file eXosip.h
|
||||
* @brief eXosip API
|
||||
*
|
||||
* eXosip is a high layer library for rfc3261: the SIP protocol.
|
||||
* It has limited API and functionnalities to make it easy to use.
|
||||
* If you need complexity in your SIP applications, you may prefer
|
||||
* to use directly osip.
|
||||
*
|
||||
* eXosip capabilities:
|
||||
* REGISTER to handle mobility.
|
||||
* INVITE/BYE/OPTIONS to start/stop VoIP sessions.
|
||||
* re-INVITE to modify VoIP sessions (On-hold/Off-hold)
|
||||
* MESSAGE to send Instant Message.
|
||||
* SUBSCRIBE/NOTIFY to handle presence capabilities.
|
||||
*
|
||||
* <P>
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup eXosip eXosip Management
|
||||
* @ingroup eXosip
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Use IPv6 instead of IPv4.
|
||||
*
|
||||
* @param ipv6_enable This paramter should be set to 1 to enable IPv6.
|
||||
*/
|
||||
void eXosip_enable_ipv6(int ipv6_enable);
|
||||
|
||||
/**
|
||||
* Initiate the eXtented oSIP library.
|
||||
*
|
||||
* @param input command input (RESERVED FOR FUTUR USE).
|
||||
* @param output resulting output (RESERVED FOR FUTUR USE).
|
||||
* @param port The SIP port to use. (5060 is the default)
|
||||
*/
|
||||
int eXosip_init(FILE *input, FILE *output, int port);
|
||||
|
||||
|
||||
/**
|
||||
* Force eXosip to use a specific local ip address in all its SIP message.
|
||||
*
|
||||
* @param localip the ip address.
|
||||
*
|
||||
* If set to NULL, then the local ip address will be guessed
|
||||
* automatically (returns to default mode).
|
||||
*/
|
||||
int eXosip_force_localip(const char *localip);
|
||||
|
||||
/**
|
||||
* Release ressource used by the eXtented oSIP library.
|
||||
*
|
||||
*/
|
||||
void eXosip_quit(void);
|
||||
|
||||
/**
|
||||
* Automatic refresh of subscription and register
|
||||
* send subscribe refresh when subscription is close to expiration.
|
||||
* send register refresh when registration is close to expiration.
|
||||
*
|
||||
*/
|
||||
void eXosip_automatic_refresh(void);
|
||||
|
||||
/**
|
||||
* Wake Up the eXosip_event_wait method.
|
||||
*
|
||||
*/
|
||||
void __eXosip_wakeup_event(void);
|
||||
|
||||
/**
|
||||
* This method is used to modify the sdp connection address
|
||||
* When you are behind a NAT. (EXPERIMENTAL)
|
||||
*
|
||||
*/
|
||||
void eXosip_set_firewallip(const char *firewall_address);
|
||||
|
||||
/**
|
||||
* This method is used to modify NAT firewall type
|
||||
* When you are behind a NAT. (EXPERIMENTAL)
|
||||
* @param nat type ("", "fcone", "rcone", "prcone", "sym")
|
||||
*/
|
||||
void eXosip_set_nattype(const char *nat_type);
|
||||
|
||||
/**
|
||||
* This method is used to force ALL SIP packets to go through given proxy
|
||||
* @param proxyurl - when empty disable forced proxy behaviour
|
||||
*/
|
||||
void eXosip_force_proxy(const char *proxyurl);
|
||||
|
||||
/**
|
||||
* This method is used to set contact header on answers which establishes dialogs
|
||||
* @param contacturl - the url to use for conatct SIP header,
|
||||
* when empty - the contact header will be generated from 'to'
|
||||
* header of the incoming request
|
||||
*/
|
||||
void eXosip_set_answer_contact(const char *contacturl);
|
||||
|
||||
/**
|
||||
* This method is used to build a contact header for SIP packets
|
||||
* @param url url from wich username part will be extracted
|
||||
* @param strbuf buffer where the result will be stored
|
||||
* @param bufsize size of the 'strbuf'
|
||||
* @param public_net when TRUE use firewall ip (if defined) as hostname part
|
||||
* else use local host ip
|
||||
*
|
||||
*/
|
||||
void eXosip_guess_contact_uri(const char *url, char *strbuf, int bufsize, int public_net);
|
||||
|
||||
/**
|
||||
* Find the current localip (interface with default route).
|
||||
* ****DEPRECATED**** Use eXosip_guess_localip
|
||||
*
|
||||
* @param ip a string containing the local IP address.
|
||||
*/
|
||||
void eXosip_get_localip(char *ip);
|
||||
|
||||
/**
|
||||
* Find the current localip (interface with default route).
|
||||
*
|
||||
* @param family AF_INET or AF_INET6
|
||||
* @param address a string containing the local IP address.
|
||||
* @param size The size of the string
|
||||
*/
|
||||
int eXosip_guess_localip(int family, char *address, int size);
|
||||
|
||||
/**
|
||||
* Find the interface to be used to reach the specified host.
|
||||
*
|
||||
* @param ip a string containing the local IP address.
|
||||
* @param localip the local ip address to be used to reach host.
|
||||
*
|
||||
* You usually don't need this function at all.
|
||||
*/
|
||||
void eXosip_get_localip_for(char *host, char **localip);
|
||||
|
||||
/**
|
||||
* Add authentication credentials. These are used when an outgoing
|
||||
* request comes back with an authorization required response.
|
||||
*
|
||||
* @param username username
|
||||
* @param userid not sure what this is for
|
||||
* @param passwd password
|
||||
* @param ha1 currently ignored
|
||||
* @param realm realm within which credentials apply, or NULL
|
||||
* to apply credentials to unrecognized realms
|
||||
*/
|
||||
int eXosip_add_authentication_info(const char *username, const char *userid,
|
||||
const char *passwd, const char *ha1,
|
||||
const char *realm);
|
||||
|
||||
/**
|
||||
* Clear all authentication credentials stored in eXosip.
|
||||
*
|
||||
*/
|
||||
int eXosip_clear_authentication_info(void);
|
||||
|
||||
/**
|
||||
* Remove an audio payload.
|
||||
*
|
||||
*/
|
||||
void eXosip_sdp_negotiation_remove_audio_payloads(void);
|
||||
|
||||
/**
|
||||
* Remove an audio payload.
|
||||
*
|
||||
* @param payload The payload
|
||||
* @param number_of_port The number of port
|
||||
* @param proto The protocol
|
||||
* @param c_nettype The connection type of network
|
||||
* @param c_addrtype The connection type of address
|
||||
* @param c_addr The connection address
|
||||
* @param c_addr_multicast_ttl The multicast TTL value
|
||||
* @param c_addr_multicast_int ?
|
||||
* @param a_rtpmap The rtpmap of element.
|
||||
*/
|
||||
void eXosip_sdp_negotiation_add_codec(char *payload, char *number_of_port,
|
||||
char *proto, char *c_nettype,
|
||||
char *c_addrtype, char *c_addr,
|
||||
char *c_addr_multicast_ttl,
|
||||
char *c_addr_multicast_int,
|
||||
char *a_rtpmap);
|
||||
|
||||
/**
|
||||
* Replace the internal SDP negociator facility.
|
||||
*
|
||||
* @param sn The new negociator context
|
||||
*/
|
||||
int eXosip_sdp_negotiation_replace(osip_negotiation_t *sn);
|
||||
|
||||
struct eXosip_call_t;
|
||||
|
||||
/**
|
||||
* Set the reference element to be used in callback for the negociator.
|
||||
* This must be done only if eXosip_sdp_negotiation_replace has been
|
||||
* used and must not be done if this method has not been used.
|
||||
*
|
||||
* @param jc The related call.
|
||||
* @param sn The new negociator context.
|
||||
*/
|
||||
void eXosip_sdp_negotiation_ctx_set_mycontext(struct eXosip_call_t *jc, void *arg);
|
||||
|
||||
#define DEFAULT_MODE 2
|
||||
#define CALLBACK_MODE 1
|
||||
#define EVENT_MODE 2
|
||||
/**
|
||||
* Set the functionnal mode of eXosip.
|
||||
* The default mode is the EVENT_MODE.
|
||||
*
|
||||
* @param mode mode to use.
|
||||
*/
|
||||
void eXosip_set_mode(int mode);
|
||||
|
||||
/**
|
||||
* Set the SIP User-Agent: header string.
|
||||
*/
|
||||
void eXosip_set_user_agent(const char *user_agent);
|
||||
|
||||
/**
|
||||
* Lock the eXtented oSIP library.
|
||||
*
|
||||
*/
|
||||
int eXosip_lock(void);
|
||||
|
||||
/**
|
||||
* UnLock the eXtented oSIP library.
|
||||
*
|
||||
*/
|
||||
int eXosip_unlock(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup eXosip_call eXosip Call Management
|
||||
* @ingroup eXosip
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Build a default INVITE message for a new call.
|
||||
*
|
||||
* @param invite Pointer for the SIP element to hold.
|
||||
* @param to SIP url for callee.
|
||||
* @param from SIP url for caller.
|
||||
* @param route Route header for INVITE. (optionnal)
|
||||
* @param subject Subject for the call.
|
||||
*/
|
||||
int eXosip_build_initial_invite(osip_message_t **invite, char *to,
|
||||
char *from, char *route, char *subject);
|
||||
/**
|
||||
* Initiate a call.
|
||||
*
|
||||
* @param invite SIP INVITE message to send.
|
||||
* @param reference Application context. (optionnal)
|
||||
* @param sdp_reference_context Sdp Application context. (optionnal)
|
||||
* @param local_sdp_port The port to be used for this call.
|
||||
*/
|
||||
int eXosip_initiate_call (osip_message_t *invite, void *reference,
|
||||
void *sdp_context_reference, char *local_sdp_port);
|
||||
|
||||
/**
|
||||
* Initiate a call with the specified body-type and body
|
||||
*
|
||||
* @param invite SIP INVITE message to send.
|
||||
* @param body_type body type (ex: "application/sdp")
|
||||
* @param body The body.
|
||||
*/
|
||||
int eXosip_initiate_call_with_body (osip_message_t *invite, const char *body_type, const char *body, void *reference);
|
||||
|
||||
|
||||
/**
|
||||
* When a call failed to initiate due to authorization reasons (407), retry the call using the authentication information
|
||||
* previously stored in eXosip using eXosip_add_authentication_info()
|
||||
*
|
||||
* @param cid The eXosip call id as returned by eXosip_initiate_call*()
|
||||
*/
|
||||
int eXosip_retry_call (int cid);
|
||||
|
||||
/**
|
||||
* Initiate a blind transfer outside of a call.
|
||||
* (probably not supported by many softphone...)
|
||||
*
|
||||
* @param refer_to SIP url for transfer.
|
||||
* @param from SIP url for caller.
|
||||
* @param to SIP url for callee.
|
||||
* @param route Route header for REFER. (optionnal)
|
||||
*/
|
||||
int eXosip_transfer_call_out_of_dialog(char *refer_to, char *from, char *to, char *route);
|
||||
|
||||
/**
|
||||
* Set redirection url before a call to eXosip_answer_call.
|
||||
*
|
||||
* @param jid dialog id of call.
|
||||
* @param contact contact address.
|
||||
*/
|
||||
int eXosip_set_redirection_address (int jid, char *contact);
|
||||
|
||||
/**
|
||||
* Answer call.
|
||||
*
|
||||
* @param jid dialog id of call.
|
||||
* @param status Status code to use.
|
||||
*/
|
||||
int eXosip_answer_call (int jid, int status, char *local_sdp_port);
|
||||
|
||||
/**
|
||||
* Answer call.
|
||||
*
|
||||
* @param jid dialog id of call.
|
||||
* @param status Status code to use.
|
||||
* @param answer The resulting sip answer to send.
|
||||
*/
|
||||
int eXosip2_answer (int jid, int status, osip_message_t **answer);
|
||||
|
||||
/**
|
||||
* Answer call.
|
||||
*
|
||||
* @param jid dialog id of call.
|
||||
* @param answer The sip answer to send.
|
||||
*/
|
||||
int eXosip2_answer_send(int jid, osip_message_t *answer);
|
||||
|
||||
/**
|
||||
* Answer call with the specified body.
|
||||
*
|
||||
* @param jid dialog id of call.
|
||||
* @param status Status code to use.
|
||||
* @param body_type body type (ex: "application/sdp")
|
||||
* @param body The body.
|
||||
*/
|
||||
int eXosip_answer_call_with_body (int jid, int status,const char *body_type, const char*body);
|
||||
|
||||
|
||||
/**
|
||||
* Retreive payload negotiated for this dialog
|
||||
*
|
||||
* @param jid dialog id of call.
|
||||
* @param payload will hold the negotited payload code
|
||||
* @param payload_name will hold negotioated payload mime string
|
||||
* @param pnsize size of the payload_name buffer
|
||||
*/
|
||||
int eXosip_retrieve_negotiated_payload(int jid, int *payload, char *payload_name, int pnsize);
|
||||
|
||||
/**
|
||||
* Set a new application context for an existing call
|
||||
*
|
||||
* @param jc Pointer to the call to modify
|
||||
* @param reference New application context.
|
||||
*/
|
||||
int eXosip_set_call_reference(int jid, void *reference);
|
||||
|
||||
/**
|
||||
* Put a call on hold.
|
||||
*
|
||||
* @param jid dialog id of call.
|
||||
*/
|
||||
int eXosip_on_hold_call (int jid);
|
||||
int eXosip_off_hold_call (int jid, char *rtp_ip, int port);
|
||||
|
||||
/**
|
||||
* Tranfer a call.
|
||||
*
|
||||
* @param jid dialog id of call.
|
||||
* @param refer_to SIP Url for transfer.
|
||||
*/
|
||||
int eXosip_transfer_call(int jid, char *refer_to);
|
||||
|
||||
/**
|
||||
* Tranfer a call.
|
||||
*
|
||||
* @param jid dialog id of call.
|
||||
* @param refer_to SIP Url for transfer.
|
||||
*/
|
||||
int eXosip_transfer_send_notify(int jid, int subscription_status, char *body);
|
||||
|
||||
/**
|
||||
* Terminate a call.
|
||||
*
|
||||
* @param cid call id of call.
|
||||
* @param jid dialog id of call.
|
||||
*/
|
||||
int eXosip_terminate_call(int cid, int jid);
|
||||
|
||||
/**
|
||||
* Send an OPTIONS message within a call.
|
||||
*
|
||||
* @param cid call id of call.
|
||||
* @param jid dialog id of call.
|
||||
*/
|
||||
int eXosip_options_call (int jid);
|
||||
|
||||
/**
|
||||
* Send an INFO message within a call.
|
||||
*
|
||||
* @param jid dialog id of call.
|
||||
* @param content_type content-type of body.
|
||||
* @param body body to attach.
|
||||
*/
|
||||
int eXosip_info_call(int jid, char *content_type, char *body);
|
||||
|
||||
/**
|
||||
* Answer an OPTIONS message.
|
||||
*
|
||||
* @param cid call id of call.
|
||||
* @param jid dialog id of call.
|
||||
*/
|
||||
int eXosip_answer_options(int cid, int jid, int status);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup eXosip_registration eXosip Registration Management
|
||||
* @ingroup eXosip
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Send initial registration to a server. (REGISTER request)
|
||||
*
|
||||
* @param from SIP url for caller.
|
||||
* @param proxy Proxy used for registration.
|
||||
* @param contact Contact address. (optionnal)
|
||||
* @param route Outbound proxy address. (optionnal)
|
||||
*/
|
||||
int eXosip_register_init (char *from, char *proxy, char *contact, char* route);
|
||||
|
||||
/**
|
||||
* Update the registration. (REGISTER request)
|
||||
*
|
||||
* @param rid .
|
||||
* @param expires The expires value for registration.
|
||||
*/
|
||||
int eXosip_register (int rid, int expires);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup eXosip_impp eXosip Instant Messaging and Presence Management
|
||||
* @ingroup eXosip
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Send an Instant Message (MESSAGE request).
|
||||
*
|
||||
* @param rid .
|
||||
*/
|
||||
int eXosip_message (char *to, char *from, char *route, char *buff);
|
||||
|
||||
/**
|
||||
* build publication for a user. (PUBLISH request)
|
||||
*
|
||||
* @param message returned published request.
|
||||
* @param to SIP url for callee.
|
||||
* @param from SIP url for caller.
|
||||
* @param route Route used for publication.
|
||||
* @param event SIP Event header.
|
||||
* @param expires SIP Expires header.
|
||||
* @param ctype Content-Type of body.
|
||||
* @param body body for publication.
|
||||
*/
|
||||
int eXosip_build_publish(osip_message_t **message,
|
||||
char *to,
|
||||
char *from,
|
||||
char *route,
|
||||
const char *event,
|
||||
const char *expires,
|
||||
const char *ctype,
|
||||
const char *body);
|
||||
|
||||
/**
|
||||
* Send an Publication Message (PUBLISH request).
|
||||
*
|
||||
* @param message is a ready to be sent publish message .
|
||||
* @param sip_if_match is the SIP-If-Match header. (NULL for initial publication)
|
||||
*/
|
||||
int eXosip_publish (osip_message_t *message, const char *sip_if_match);
|
||||
|
||||
/**
|
||||
* Send initial subscription to a user. (SUBSCRIBE request)
|
||||
*
|
||||
* @param to SIP url for callee.
|
||||
* @param from SIP url for caller.
|
||||
* @param route Route used for registration.
|
||||
*/
|
||||
int eXosip_subscribe(char *to, char *from, char *route);
|
||||
|
||||
/**
|
||||
* Update a subscription (SUBSCRIBE request).
|
||||
*
|
||||
* @param sid id of subscription.
|
||||
* @param expires Time between updates.
|
||||
*/
|
||||
int eXosip_subscribe_refresh(int sid, char *expires);
|
||||
|
||||
/**
|
||||
* Close a subscription (SUBSCRIBE request).
|
||||
*
|
||||
* @param sid id of subscription.
|
||||
*/
|
||||
int eXosip_subscribe_close(int sid);
|
||||
|
||||
typedef enum eXosip_ss {
|
||||
EXOSIP_SUBCRSTATE_UNKNOWN,
|
||||
EXOSIP_SUBCRSTATE_PENDING,
|
||||
EXOSIP_SUBCRSTATE_ACTIVE,
|
||||
EXOSIP_SUBCRSTATE_TERMINATED
|
||||
} eXosip_ss_t;
|
||||
|
||||
typedef enum eXosip_ss_reason {
|
||||
DEACTIVATED,
|
||||
PROBATION,
|
||||
REJECTED,
|
||||
TIMEOUT,
|
||||
GIVEUP,
|
||||
NORESOURCE
|
||||
} eXosip_ss_reason_t;
|
||||
|
||||
/* typo error */
|
||||
#define NORESSOURCE NORESOURCE
|
||||
|
||||
typedef enum eXosip_ss_status {
|
||||
EXOSIP_NOTIFY_UNKNOWN,
|
||||
EXOSIP_NOTIFY_PENDING, /* subscription not yet accepted */
|
||||
EXOSIP_NOTIFY_ONLINE,
|
||||
EXOSIP_NOTIFY_BUSY,
|
||||
EXOSIP_NOTIFY_BERIGHTBACK,
|
||||
EXOSIP_NOTIFY_AWAY,
|
||||
EXOSIP_NOTIFY_ONTHEPHONE,
|
||||
EXOSIP_NOTIFY_OUTTOLUNCH,
|
||||
EXOSIP_NOTIFY_CLOSED
|
||||
} eXosip_ss_status_t;
|
||||
|
||||
/**
|
||||
* Accept a subscription and notify state (NOTIFY request).
|
||||
*
|
||||
* @param nid call id of call.
|
||||
* @param code code for answer to subscribe.
|
||||
* @param subscription_status subscription status.
|
||||
* @param online_status online status to send.
|
||||
*/
|
||||
int eXosip_notify_accept_subscribe (int nid, int code, int subscription_status, int online_status);
|
||||
|
||||
/**
|
||||
* Update a subscription and notify state (NOTIFY request).
|
||||
*
|
||||
* @param nid call id of call.
|
||||
* @param subscription_status subscription status.
|
||||
* @param online_status online status to send.
|
||||
*/
|
||||
int eXosip_notify(int nid, int subscription_status, int online_status);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
int eXosip_send_ack(int did);
|
||||
|
||||
/**
|
||||
* @defgroup eXosip_event eXosip event Management
|
||||
* @ingroup eXosip
|
||||
* @{
|
||||
*/
|
||||
typedef enum eXosip_event_type_t {
|
||||
|
||||
/* Registration Info */
|
||||
EXOSIP_REGISTRATION_NEW, /* announce new registration. */
|
||||
EXOSIP_REGISTRATION_SUCCESS, /* user is successfully registred. */
|
||||
EXOSIP_REGISTRATION_FAILURE, /* user is not registred. */
|
||||
EXOSIP_REGISTRATION_REFRESHED, /* registration has been refreshed. */
|
||||
EXOSIP_REGISTRATION_TERMINATED, /* UA is not registred any more. */
|
||||
|
||||
/* for UAC events */
|
||||
EXOSIP_CALL_NOANSWER, /* announce no answer within the timeout */
|
||||
EXOSIP_CALL_PROCEEDING, /* announce processing by a remote app */
|
||||
EXOSIP_CALL_RINGING, /* announce ringback */
|
||||
EXOSIP_CALL_ANSWERED, /* announce start of call */
|
||||
EXOSIP_CALL_REDIRECTED, /* announce a redirection */
|
||||
EXOSIP_CALL_REQUESTFAILURE, /* announce a request failure */
|
||||
EXOSIP_CALL_SERVERFAILURE, /* announce a server failure */
|
||||
EXOSIP_CALL_GLOBALFAILURE, /* announce a global failure */
|
||||
|
||||
/* for UAS events */
|
||||
EXOSIP_CALL_NEW, /* announce a new call */
|
||||
EXOSIP_CALL_ACK, /* ACK received for 200ok to INVITE */
|
||||
EXOSIP_CALL_CANCELLED, /* announce that call has been cancelled */
|
||||
EXOSIP_CALL_TIMEOUT, /* announce that call has failed */
|
||||
EXOSIP_CALL_HOLD, /* audio must be stopped */
|
||||
EXOSIP_CALL_OFFHOLD, /* audio must be restarted */
|
||||
EXOSIP_CALL_CLOSED, /* a BYE was received for this call */
|
||||
|
||||
/* for both UAS & UAC events */
|
||||
EXOSIP_CALL_STARTAUDIO, /* audio must be established */
|
||||
EXOSIP_CALL_RELEASED, /* call context is cleared. */
|
||||
|
||||
/* for UAC events */
|
||||
EXOSIP_OPTIONS_NOANSWER, /* announce no answer within the timeout */
|
||||
EXOSIP_OPTIONS_PROCEEDING, /* announce processing by a remote app */
|
||||
EXOSIP_OPTIONS_ANSWERED, /* announce a 200ok */
|
||||
EXOSIP_OPTIONS_REDIRECTED, /* announce a redirection */
|
||||
EXOSIP_OPTIONS_REQUESTFAILURE, /* announce a request failure */
|
||||
EXOSIP_OPTIONS_SERVERFAILURE, /* announce a server failure */
|
||||
EXOSIP_OPTIONS_GLOBALFAILURE, /* announce a global failure */
|
||||
|
||||
EXOSIP_INFO_NOANSWER, /* announce no answer within the timeout */
|
||||
EXOSIP_INFO_PROCEEDING, /* announce processing by a remote app */
|
||||
EXOSIP_INFO_ANSWERED, /* announce a 200ok */
|
||||
EXOSIP_INFO_REDIRECTED, /* announce a redirection */
|
||||
EXOSIP_INFO_REQUESTFAILURE, /* announce a request failure */
|
||||
EXOSIP_INFO_SERVERFAILURE, /* announce a server failure */
|
||||
EXOSIP_INFO_GLOBALFAILURE, /* announce a global failure */
|
||||
|
||||
/* for UAS events */
|
||||
EXOSIP_OPTIONS_NEW, /* announce a new options method */
|
||||
EXOSIP_INFO_NEW, /* new info request received */
|
||||
|
||||
EXOSIP_MESSAGE_NEW, /* announce new incoming MESSAGE. */
|
||||
EXOSIP_MESSAGE_SUCCESS, /* announce a 200ok to a previous sent */
|
||||
EXOSIP_MESSAGE_FAILURE, /* announce a failure. */
|
||||
|
||||
/* Presence and Instant Messaging */
|
||||
EXOSIP_SUBSCRIPTION_NEW, /* announce new incoming SUBSCRIBE. */
|
||||
EXOSIP_SUBSCRIPTION_UPDATE, /* announce incoming SUBSCRIBE. */
|
||||
EXOSIP_SUBSCRIPTION_CLOSED, /* announce end of subscription. */
|
||||
|
||||
EXOSIP_SUBSCRIPTION_NOANSWER, /* announce no answer */
|
||||
EXOSIP_SUBSCRIPTION_PROCEEDING, /* announce a 1xx */
|
||||
EXOSIP_SUBSCRIPTION_ANSWERED, /* announce a 200ok */
|
||||
EXOSIP_SUBSCRIPTION_REDIRECTED, /* announce a redirection */
|
||||
EXOSIP_SUBSCRIPTION_REQUESTFAILURE, /* announce a request failure */
|
||||
EXOSIP_SUBSCRIPTION_SERVERFAILURE, /* announce a server failure */
|
||||
EXOSIP_SUBSCRIPTION_GLOBALFAILURE, /* announce a global failure */
|
||||
EXOSIP_SUBSCRIPTION_NOTIFY, /* announce new NOTIFY request */
|
||||
|
||||
EXOSIP_SUBSCRIPTION_RELEASED, /* call context is cleared. */
|
||||
|
||||
EXOSIP_IN_SUBSCRIPTION_NEW, /* announce new incoming SUBSCRIBE.*/
|
||||
EXOSIP_IN_SUBSCRIPTION_RELEASED, /* announce end of subscription. */
|
||||
|
||||
EXOSIP_CALL_REFERED, /* announce incoming REFER */
|
||||
EXOSIP_CALL_REFER_STATUS, /* announce incoming NOTIFY */
|
||||
|
||||
EXOSIP_CALLBACK_COUNT
|
||||
} eXosip_event_type_t;
|
||||
|
||||
typedef struct eXosip_event {
|
||||
eXosip_event_type_t type;
|
||||
void *external_reference;
|
||||
char reason_phrase[50];
|
||||
int status_code;
|
||||
|
||||
char textinfo[256];
|
||||
char req_uri[256];
|
||||
char local_uri[256];
|
||||
char remote_uri[256];
|
||||
char remote_contact[256];
|
||||
char refer_to[256];
|
||||
char subject[256];
|
||||
osip_content_type_t *i_ctt;
|
||||
osip_list_t *i_bodies;
|
||||
|
||||
char remote_sdp_audio_ip[50];
|
||||
int remote_sdp_audio_port;
|
||||
int local_sdp_audio_port;
|
||||
int payload;
|
||||
char payload_name[50];
|
||||
char sdp_body[1000]; /* The whole SDP body */
|
||||
int online_status;
|
||||
int ss_status;
|
||||
int ss_reason;
|
||||
|
||||
/* For a high level usage of the eXosip stack? (API is enough?) */
|
||||
int did;
|
||||
int cid;
|
||||
int rid;
|
||||
int sid;
|
||||
int nid;
|
||||
|
||||
/* For a low level usage of the eXosip stack */
|
||||
struct eXosip_dialog_t *jd;
|
||||
struct eXosip_call_t *jc;
|
||||
struct eXosip_reg_t *jr;
|
||||
struct eXosip_subscribe_t *js;
|
||||
struct eXosip_notify_t *jn;
|
||||
|
||||
} eXosip_event_t;
|
||||
|
||||
/**
|
||||
* Free ressource in an eXosip event.
|
||||
*
|
||||
* @param je event to work on.
|
||||
*/
|
||||
void eXosip_event_free(eXosip_event_t *je);
|
||||
|
||||
/**
|
||||
* Wait for an eXosip event. (FUTURE USE)
|
||||
*
|
||||
* @param tv_s timeout value (seconds).
|
||||
* @param tv_ms timeout value (mseconds).
|
||||
*/
|
||||
eXosip_event_t *eXosip_event_wait(int tv_s, int tv_ms);
|
||||
|
||||
|
||||
/**
|
||||
* Wait for next eXosip event.
|
||||
*
|
||||
*/
|
||||
eXosip_event_t *eXosip_event_get(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
510
linphone/exosip/eXosip2.h
Normal file
510
linphone/exosip/eXosip2.h
Normal file
|
|
@ -0,0 +1,510 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#ifndef __EXOSIP2_H__
|
||||
#define __EXOSIP2_H__
|
||||
|
||||
#ifdef WIN32
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#define snprintf _snprintf
|
||||
#define close(s) closesocket(s)
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <osip2/osip.h>
|
||||
#include <osip2/osip_dialog.h>
|
||||
#include <osip2/osip_negotiation.h>
|
||||
|
||||
#include <eXosip_cfg.h>
|
||||
#include <eXosip.h>
|
||||
|
||||
#include "jpipe.h"
|
||||
|
||||
#ifndef JD_EMPTY
|
||||
|
||||
#define JD_EMPTY 0
|
||||
#define JD_INITIALIZED 1
|
||||
#define JD_TRYING 2
|
||||
#define JD_QUEUED 3
|
||||
#define JD_RINGING 4
|
||||
#define JD_ESTABLISHED 5
|
||||
#define JD_REDIRECTED 6
|
||||
#define JD_AUTH_REQUIRED 7
|
||||
#define JD_CLIENTERROR 8
|
||||
#define JD_SERVERERROR 9
|
||||
#define JD_GLOBALFAILURE 10
|
||||
#define JD_TERMINATED 11
|
||||
|
||||
#define JD_MAX 11
|
||||
|
||||
#endif
|
||||
|
||||
#define EXOSIP_VERSION "0.1"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void eXosip_update(void);
|
||||
void __eXosip_wakeup(void);
|
||||
|
||||
typedef struct eXosip_dialog_t eXosip_dialog_t;
|
||||
|
||||
struct eXosip_dialog_t {
|
||||
|
||||
int d_id;
|
||||
int d_STATE;
|
||||
osip_dialog_t *d_dialog; /* active dialog */
|
||||
|
||||
int d_timer;
|
||||
osip_message_t *d_200Ok;
|
||||
osip_message_t *d_ack;
|
||||
osip_list_t *media_lines;
|
||||
|
||||
osip_list_t *d_inc_trs;
|
||||
osip_list_t *d_out_trs;
|
||||
|
||||
/* struct _BodyHandler *d_bh; */
|
||||
|
||||
eXosip_dialog_t *next;
|
||||
eXosip_dialog_t *parent;
|
||||
};
|
||||
|
||||
typedef struct eXosip_subscribe_t eXosip_subscribe_t;
|
||||
|
||||
struct eXosip_subscribe_t {
|
||||
|
||||
int s_id;
|
||||
char s_uri[255];
|
||||
int s_online_status;
|
||||
int s_ss_status;
|
||||
int s_ss_reason;
|
||||
int s_ss_expires;
|
||||
eXosip_dialog_t *s_dialogs;
|
||||
|
||||
osip_transaction_t *s_inc_tr;
|
||||
osip_transaction_t *s_out_tr;
|
||||
|
||||
eXosip_subscribe_t *next;
|
||||
eXosip_subscribe_t *parent;
|
||||
};
|
||||
|
||||
typedef struct eXosip_notify_t eXosip_notify_t;
|
||||
|
||||
struct eXosip_notify_t {
|
||||
|
||||
int n_id;
|
||||
char n_uri[255];
|
||||
int n_online_status;
|
||||
char *n_contact_info;
|
||||
|
||||
int n_ss_status;
|
||||
int n_ss_reason;
|
||||
int n_ss_expires;
|
||||
eXosip_dialog_t *n_dialogs;
|
||||
|
||||
osip_transaction_t *n_inc_tr;
|
||||
osip_transaction_t *n_out_tr;
|
||||
|
||||
eXosip_notify_t *next;
|
||||
eXosip_notify_t *parent;
|
||||
};
|
||||
|
||||
typedef struct eXosip_call_t eXosip_call_t;
|
||||
|
||||
struct eXosip_call_t {
|
||||
|
||||
int c_id;
|
||||
char c_subject[100];
|
||||
int c_ack_sdp; /* flag for alternative SDP offer-response model */
|
||||
eXosip_dialog_t *c_dialogs;
|
||||
osip_transaction_t *c_inc_tr;
|
||||
osip_transaction_t *c_out_tr;
|
||||
osip_transaction_t *c_inc_options_tr;
|
||||
osip_transaction_t *c_out_options_tr;
|
||||
void *external_reference;
|
||||
|
||||
osip_negotiation_ctx_t *c_ctx;
|
||||
char c_sdp_port[10];
|
||||
|
||||
char c_redirection[1024]; /* contact for 3xx answers */
|
||||
|
||||
eXosip_call_t *next;
|
||||
eXosip_call_t *parent;
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
typedef struct eXosip_realm_t eXosip_realm_t;
|
||||
|
||||
struct eXosip_realm_t {
|
||||
|
||||
int r_id;
|
||||
|
||||
char *r_realm;
|
||||
char *r_username;
|
||||
char *r_passwd;
|
||||
|
||||
eXosip_realm_t *next;
|
||||
eXosip_realm_t *parent;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct eXosip_reg_t eXosip_reg_t;
|
||||
|
||||
struct eXosip_reg_t {
|
||||
|
||||
int r_id;
|
||||
|
||||
int r_reg_period; /* delay between registration */
|
||||
char *r_aor; /* sip identity */
|
||||
char *r_registrar; /* registrar */
|
||||
char *r_route; /* outbound proxy */
|
||||
#if 0
|
||||
eXosip_realm_t *r_realms; /* list of realms */
|
||||
#endif
|
||||
char *r_contact; /* list of contacts string */
|
||||
|
||||
osip_transaction_t *r_last_tr;
|
||||
eXosip_reg_t *next;
|
||||
eXosip_reg_t *parent;
|
||||
};
|
||||
|
||||
|
||||
typedef struct eXosip_pub_t eXosip_pub_t;
|
||||
|
||||
struct eXosip_pub_t {
|
||||
int p_id;
|
||||
|
||||
time_t p_expires; /* expiration date (started+period) */
|
||||
int p_period; /* delay between registration */
|
||||
char p_aor[256]; /* sip identity */
|
||||
char p_sip_etag[64]; /* sip_etag from 200ok */
|
||||
|
||||
osip_transaction_t *p_last_tr;
|
||||
eXosip_pub_t *next;
|
||||
eXosip_pub_t *parent;
|
||||
};
|
||||
|
||||
int _eXosip_pub_update(eXosip_pub_t **pub, osip_transaction_t *tr, osip_message_t *answer);
|
||||
int _eXosip_pub_find_by_aor(eXosip_pub_t **pub, const char *aor);
|
||||
int _eXosip_pub_init(eXosip_pub_t **pub, const char *aor, const char *exp);
|
||||
void _eXosip_pub_free(eXosip_pub_t *pub);
|
||||
|
||||
typedef struct jauthinfo_t jauthinfo_t;
|
||||
|
||||
struct jauthinfo_t {
|
||||
char username[50];
|
||||
char userid[50];
|
||||
char passwd[50];
|
||||
char ha1[50];
|
||||
char realm[50];
|
||||
jauthinfo_t *parent;
|
||||
jauthinfo_t *next;
|
||||
};
|
||||
|
||||
int
|
||||
__eXosip_create_authorization_header(osip_message_t *previous_answer,
|
||||
const char *rquri, const char *username,
|
||||
const char *passwd,
|
||||
osip_authorization_t **auth);
|
||||
int
|
||||
__eXosip_create_proxy_authorization_header(osip_message_t *previous_answer,
|
||||
const char *rquri,
|
||||
const char *username,
|
||||
const char *passwd,
|
||||
osip_proxy_authorization_t **auth);
|
||||
|
||||
|
||||
eXosip_event_t *eXosip_event_init_for_call(int type, eXosip_call_t *jc,
|
||||
eXosip_dialog_t *jd);
|
||||
int eXosip_event_add_sdp_info(eXosip_event_t *je, osip_message_t *message);
|
||||
|
||||
int eXosip_event_add_status(eXosip_event_t *je, osip_message_t *response);
|
||||
eXosip_event_t *eXosip_event_init_for_subscribe(int type,
|
||||
eXosip_subscribe_t *js,
|
||||
eXosip_dialog_t *jd);
|
||||
eXosip_event_t *eXosip_event_init_for_notify(int type, eXosip_notify_t *jn,
|
||||
eXosip_dialog_t *jd);
|
||||
eXosip_event_t *eXosip_event_init_for_reg(int type, eXosip_reg_t *jr);
|
||||
eXosip_event_t *eXosip_event_init_for_message(int type, osip_transaction_t
|
||||
*tr, osip_message_t *sip);
|
||||
int eXosip_event_init(eXosip_event_t **je, int type);
|
||||
eXosip_call_t *eXosip_event_get_callinfo(eXosip_event_t *je);
|
||||
eXosip_dialog_t *eXosip_event_get_dialoginfo(eXosip_event_t *je);
|
||||
eXosip_reg_t *eXosip_event_get_reginfo(eXosip_event_t *je);
|
||||
eXosip_notify_t *eXosip_event_get_notifyinfo(eXosip_event_t *je);
|
||||
eXosip_subscribe_t *eXosip_event_get_subscribeinfo(eXosip_event_t *je);
|
||||
int eXosip_event_add(eXosip_event_t *je);
|
||||
eXosip_event_t *eXosip_event_wait(int tv_s, int tv_ms);
|
||||
eXosip_event_t *eXosip_event_get(void);
|
||||
|
||||
typedef void (* eXosip_callback_t) (int type, eXosip_event_t *);
|
||||
|
||||
char *strdup_printf(const char *fmt, ...);
|
||||
|
||||
jfriend_t *jfriend_get(void);
|
||||
jsubscriber_t *jsubscriber_get(void);
|
||||
jidentity_t *jidentity_get(void);
|
||||
int jfriend_get_and_set_next_token (char **dest, char *buf,
|
||||
char **next);
|
||||
|
||||
#define eXosip_trace(loglevel,args) do \
|
||||
{ \
|
||||
char *__strmsg; \
|
||||
__strmsg=strdup_printf args ; \
|
||||
OSIP_TRACE(osip_trace(__FILE__,__LINE__,(loglevel),NULL,"%s\n",__strmsg)); \
|
||||
osip_free (__strmsg); \
|
||||
}while (0);
|
||||
|
||||
typedef struct eXosip_t eXosip_t;
|
||||
|
||||
struct eXosip_t {
|
||||
int forced_localip; /* set to 1 when we must always use the default local ip */
|
||||
char *localip; /* default local ip */
|
||||
char *localport;
|
||||
|
||||
char *user_agent;
|
||||
|
||||
FILE *j_input;
|
||||
FILE *j_output;
|
||||
eXosip_call_t *j_calls; /* my calls */
|
||||
eXosip_subscribe_t *j_subscribes; /* my friends */
|
||||
eXosip_notify_t *j_notifies; /* my susbscribers */
|
||||
osip_list_t *j_transactions;
|
||||
|
||||
eXosip_reg_t *j_reg; /* my registrations */
|
||||
eXosip_pub_t *j_pub; /* my publications */
|
||||
|
||||
void *j_cond;
|
||||
void *j_mutexlock;
|
||||
|
||||
osip_t *j_osip;
|
||||
int j_socket;
|
||||
int j_stop_ua;
|
||||
void *j_thread;
|
||||
jpipe_t *j_socketctl;
|
||||
jpipe_t *j_socketctl_event;
|
||||
|
||||
jsubscriber_t *j_subscribers;
|
||||
jfriend_t *j_friends;
|
||||
jidentity_t *j_identitys;
|
||||
|
||||
int j_runtime_mode;
|
||||
eXosip_callback_t j_call_callbacks[EXOSIP_CALLBACK_COUNT];
|
||||
osip_fifo_t *j_events;
|
||||
|
||||
osip_negotiation_t *osip_negotiation;
|
||||
char j_firewall_ip[50];
|
||||
jauthinfo_t *authinfos;
|
||||
|
||||
int ip_family; /* AF_INET6 or AF_INET */
|
||||
char nat_type[16];
|
||||
char forced_proxy[256];
|
||||
char answer_contact[256]; /* conatact header value to use in answers */
|
||||
};
|
||||
|
||||
typedef struct jinfo_t jinfo_t;
|
||||
|
||||
struct jinfo_t {
|
||||
eXosip_dialog_t *jd;
|
||||
eXosip_call_t *jc;
|
||||
eXosip_subscribe_t *js;
|
||||
eXosip_notify_t *jn;
|
||||
};
|
||||
|
||||
int eXosip_guess_ip_for_via (int family, char *address, int size);
|
||||
|
||||
int eXosip_sdp_negotiation_init(osip_negotiation_t **sn);
|
||||
void eXosip_sdp_negotiation_free(osip_negotiation_t *sn);
|
||||
int eXosip_retrieve_sdp_negotiation_result(osip_negotiation_ctx_t *ctx, char *payload_name, int pnsize);
|
||||
|
||||
|
||||
sdp_message_t *eXosip_get_local_sdp_info(osip_transaction_t *invite_tr);
|
||||
sdp_message_t *eXosip_get_remote_sdp_info(osip_transaction_t *invite_tr);
|
||||
sdp_message_t *eXosip_get_local_sdp(osip_transaction_t *transaction);
|
||||
sdp_message_t *eXosip_get_remote_sdp(osip_transaction_t *transaction);
|
||||
|
||||
|
||||
|
||||
int eXosip_set_callbacks(osip_t *osip);
|
||||
char *osip_call_id_new_random(void);
|
||||
char *osip_to_tag_new_random(void);
|
||||
char *osip_from_tag_new_random(void);
|
||||
unsigned int via_branch_new_random(void);
|
||||
void __eXosip_delete_jinfo(osip_transaction_t *transaction);
|
||||
jinfo_t *__eXosip_new_jinfo(eXosip_call_t *jc, eXosip_dialog_t *jd,
|
||||
eXosip_subscribe_t *js, eXosip_notify_t *jn);
|
||||
|
||||
int eXosip_dialog_init_as_uac(eXosip_dialog_t **jd, osip_message_t *_200Ok);
|
||||
int eXosip_dialog_init_as_uas(eXosip_dialog_t **jd, osip_message_t *_invite, osip_message_t *_200Ok);
|
||||
void eXosip_dialog_free(eXosip_dialog_t *jd);
|
||||
void eXosip_dialog_set_state(eXosip_dialog_t *jd, int state);
|
||||
void eXosip_delete_early_dialog(eXosip_dialog_t *jd);
|
||||
|
||||
|
||||
struct __eXosip_sockaddr {
|
||||
u_char ss_len;
|
||||
u_char ss_family;
|
||||
u_char padding[128 - 2];
|
||||
};
|
||||
int eXosip_get_addrinfo (struct addrinfo **addrinfo,
|
||||
char *hostname, int service);
|
||||
int isrfc1918(char *ipaddr);
|
||||
void eXosip_get_localip_from_via(osip_message_t *,char**localip);
|
||||
int generating_initial_subscribe(osip_message_t **message, char *to,
|
||||
char *from, char *route);
|
||||
int generating_message(osip_message_t **message, char *to, char *from,
|
||||
char *route, char *buff);
|
||||
int generating_publish(osip_message_t **message, char *to, char *from,
|
||||
char *route);
|
||||
int generating_cancel(osip_message_t **dest, osip_message_t *request_cancelled);
|
||||
int generating_options_within_dialog(osip_message_t **info, osip_dialog_t *dialog);
|
||||
int generating_info_within_dialog(osip_message_t **info, osip_dialog_t *dialog);
|
||||
int generating_bye(osip_message_t **bye, osip_dialog_t *dialog);
|
||||
int generating_refer(osip_message_t **refer, osip_dialog_t *dialog, char *refer_to);
|
||||
int generating_refer_outside_dialog(osip_message_t **refer, char *refer_to, char *from, char *to, char *proxy);
|
||||
int generating_invite_on_hold(osip_message_t **invite, osip_dialog_t *dialog,
|
||||
char *subject, char *sdp);
|
||||
int generating_invite_off_hold(osip_message_t **invite, osip_dialog_t *dialog,
|
||||
char *subject, char *sdp);
|
||||
int generating_options(osip_message_t **options, char *from, char *to, char *proxy);
|
||||
int generating_ack_for_2xx(osip_message_t **ack, osip_dialog_t *dialog);
|
||||
int generating_info(osip_message_t **info, char *from, char *to, char *proxy);
|
||||
|
||||
int _eXosip_reg_find(eXosip_reg_t **reg, osip_transaction_t *tr);
|
||||
int eXosip_reg_init(eXosip_reg_t **jr, char *from, char *proxy, char *contact, char* route);
|
||||
void eXosip_reg_free(eXosip_reg_t *jreg);
|
||||
int generating_register(osip_message_t **reg, char *transport, char *from, char *proxy, int expires);
|
||||
char *generating_sdp_answer(osip_message_t *request, osip_negotiation_ctx_t *context);
|
||||
|
||||
int eXosip_call_dialog_find(int jid, eXosip_call_t **jc, eXosip_dialog_t **jd);
|
||||
int eXosip_notify_dialog_find(int nid, eXosip_notify_t **jn, eXosip_dialog_t **jd);
|
||||
int eXosip_subscribe_dialog_find(int nid, eXosip_subscribe_t **js, eXosip_dialog_t **jd);
|
||||
int eXosip_call_find(int cid, eXosip_call_t **jc);
|
||||
int eXosip_dialog_set_200ok(eXosip_dialog_t *_jd, osip_message_t *_200Ok);
|
||||
|
||||
int _eXosip2_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer);
|
||||
int _eXosip2_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer);
|
||||
int _eXosip2_answer_invite_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, osip_message_t **answer);
|
||||
int eXosip_answer_invite_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code);
|
||||
int eXosip_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, char *local_sdp_port);
|
||||
int eXosip_answer_invite_2xx_with_body(eXosip_call_t *jc, eXosip_dialog_t *jd, int code,const char*, const char*);
|
||||
int eXosip_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code);
|
||||
int eXosip_answer_options_1xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code);
|
||||
int eXosip_answer_options_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code);
|
||||
int eXosip_answer_options_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code);
|
||||
void eXosip_notify_answer_subscribe_1xx(eXosip_notify_t *jc,
|
||||
eXosip_dialog_t *jd, int code);
|
||||
void eXosip_notify_answer_subscribe_2xx(eXosip_notify_t *jn,
|
||||
eXosip_dialog_t *jd, int code);
|
||||
void eXosip_notify_answer_subscribe_3456xx(eXosip_notify_t *jn,
|
||||
eXosip_dialog_t *jd, int code);
|
||||
|
||||
int eXosip_build_response_default(int jid, int status);
|
||||
int _eXosip_build_response_default(osip_message_t **dest, osip_dialog_t *dialog,
|
||||
int status, osip_message_t *request);
|
||||
int complete_answer_that_establish_a_dialog(osip_message_t *response, osip_message_t *request);
|
||||
int _eXosip_build_request_within_dialog(osip_message_t **dest, char *method_name,
|
||||
osip_dialog_t *dialog, char *transport);
|
||||
int eXosip_build_initial_options(osip_message_t **options, char *to, char *from,
|
||||
char *route);
|
||||
|
||||
void eXosip_kill_transaction(osip_list_t * transactions);
|
||||
int eXosip_remove_transaction_from_call(osip_transaction_t *tr, eXosip_call_t *jc);
|
||||
osip_transaction_t *eXosip_find_last_inc_notify(eXosip_subscribe_t *jn, eXosip_dialog_t *jd);
|
||||
osip_transaction_t *eXosip_find_last_out_notify(eXosip_notify_t *jn, eXosip_dialog_t *jd);
|
||||
osip_transaction_t *eXosip_find_last_inc_subscribe(eXosip_notify_t *jn, eXosip_dialog_t *jd);
|
||||
osip_transaction_t *eXosip_find_last_out_subscribe(eXosip_subscribe_t *js, eXosip_dialog_t *jd );
|
||||
|
||||
osip_transaction_t *eXosip_find_last_out_options(eXosip_call_t *jc, eXosip_dialog_t *jd );
|
||||
osip_transaction_t *eXosip_find_last_inc_options(eXosip_call_t *jc, eXosip_dialog_t *jd );
|
||||
osip_transaction_t *eXosip_find_last_options(eXosip_call_t *jc, eXosip_dialog_t *jd );
|
||||
osip_transaction_t *eXosip_find_last_out_info(eXosip_call_t *jc, eXosip_dialog_t *jd );
|
||||
osip_transaction_t *eXosip_find_last_inc_info(eXosip_call_t *jc, eXosip_dialog_t *jd );
|
||||
osip_transaction_t *eXosip_find_last_info(eXosip_call_t *jc, eXosip_dialog_t *jd );
|
||||
osip_transaction_t *eXosip_find_last_invite(eXosip_call_t *jc, eXosip_dialog_t *jd );
|
||||
osip_transaction_t *eXosip_find_last_inc_invite(eXosip_call_t *jc, eXosip_dialog_t *jd);
|
||||
osip_transaction_t *eXosip_find_last_out_invite(eXosip_call_t *jc, eXosip_dialog_t *jd);
|
||||
osip_transaction_t *eXosip_find_last_refer(eXosip_call_t *jc, eXosip_dialog_t *jd );
|
||||
osip_transaction_t *eXosip_find_last_inc_notify_for_refer(eXosip_call_t *jc, eXosip_dialog_t *jd);
|
||||
osip_transaction_t *eXosip_find_last_out_notify_for_refer(eXosip_call_t *jc, eXosip_dialog_t *jd);
|
||||
osip_transaction_t *eXosip_find_last_inc_bye(eXosip_call_t *jc, eXosip_dialog_t *jd);
|
||||
osip_transaction_t *eXosip_find_last_out_bye(eXosip_call_t *jc, eXosip_dialog_t *jd);
|
||||
osip_transaction_t *eXosip_find_last_inc_refer(eXosip_call_t *jc, eXosip_dialog_t *jd);
|
||||
osip_transaction_t *eXosip_find_last_out_refer(eXosip_call_t *jc, eXosip_dialog_t *jd);
|
||||
|
||||
|
||||
int eXosip_call_init(eXosip_call_t **jc);
|
||||
void eXosip_call_free(eXosip_call_t *jc);
|
||||
void __eXosip_call_remove_dialog_reference_in_call(eXosip_call_t *jc, eXosip_dialog_t *jd);
|
||||
void eXosip_call_set_subject(eXosip_call_t *jc, char *subject);
|
||||
int eXosip_read_message(int max_message_nb, int sec_max, int usec_max);
|
||||
void eXosip_release_terminated_calls ( void );
|
||||
|
||||
|
||||
int eXosip_subscribe_init(eXosip_subscribe_t **js, char *uri);
|
||||
void eXosip_subscribe_free(eXosip_subscribe_t *js);
|
||||
int _eXosip_subscribe_set_refresh_interval(eXosip_subscribe_t *js, osip_message_t *inc_subscribe);
|
||||
int eXosip_subscribe_need_refresh(eXosip_subscribe_t *js, int now);
|
||||
int eXosip_subscribe_send_subscribe(eXosip_subscribe_t *js,
|
||||
eXosip_dialog_t *jd, const char *expires);
|
||||
|
||||
int eXosip_notify_init(eXosip_notify_t **jn, osip_message_t *inc_subscribe);
|
||||
void eXosip_notify_free(eXosip_notify_t *jn);
|
||||
int _eXosip_notify_set_contact_info(eXosip_notify_t *jn, char *uri);
|
||||
int _eXosip_notify_set_refresh_interval(eXosip_notify_t *jn,
|
||||
osip_message_t *inc_subscribe);
|
||||
void _eXosip_notify_add_expires_in_2XX_for_subscribe(eXosip_notify_t *jn,
|
||||
osip_message_t *answer);
|
||||
int _eXosip_notify_add_body(eXosip_notify_t *jn, osip_message_t *notify);
|
||||
int eXosip_notify_add_allowed_subscriber(char *sip_url);
|
||||
int _eXosip_notify_is_a_known_subscriber(osip_message_t *sip);
|
||||
int eXosip_notify_send_notify(eXosip_notify_t *jn, eXosip_dialog_t *jd,
|
||||
int subsciption_status,
|
||||
int online_status);
|
||||
int _eXosip_transfer_send_notify(eXosip_call_t *jc,
|
||||
eXosip_dialog_t *jd,
|
||||
int subscription_status,
|
||||
char *body);
|
||||
|
||||
|
||||
int eXosip_is_public_address(const char *addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
150
linphone/exosip/eXosip_cfg.h
Normal file
150
linphone/exosip/eXosip_cfg.h
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#ifndef __EXOSIP_CFG_H__
|
||||
#define __EXOSIP_CFG_H__
|
||||
|
||||
/**
|
||||
* @defgroup eXosip_cfg eXosip Configuration Management
|
||||
* @ingroup eXosip
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct jfriend_t jfriend_t;
|
||||
|
||||
struct jfriend_t {
|
||||
int f_id;
|
||||
char *f_nick;
|
||||
char *f_home;
|
||||
char *f_work;
|
||||
char *f_email;
|
||||
char *f_e164;
|
||||
|
||||
jfriend_t *next;
|
||||
jfriend_t *parent;
|
||||
};
|
||||
|
||||
typedef struct jidentity_t jidentity_t;
|
||||
|
||||
struct jidentity_t {
|
||||
int i_id;
|
||||
char *i_identity;
|
||||
char *i_registrar;
|
||||
char *i_realm;
|
||||
char *i_userid;
|
||||
char *i_pwd;
|
||||
|
||||
jidentity_t *next;
|
||||
jidentity_t *parent;
|
||||
};
|
||||
|
||||
typedef struct jsubscriber_t jsubscriber_t;
|
||||
|
||||
struct jsubscriber_t {
|
||||
int s_id;
|
||||
char *s_nick;
|
||||
char *s_uri;
|
||||
char *s_allow;
|
||||
|
||||
jsubscriber_t *next;
|
||||
jsubscriber_t *parent;
|
||||
};
|
||||
|
||||
jfriend_t *jfriend_get(void);
|
||||
void jfriend_remove(jfriend_t *fr);
|
||||
|
||||
jsubscriber_t *jsubscriber_get(void);
|
||||
jidentity_t *jidentity_get(void);
|
||||
|
||||
int jfriend_load(void);
|
||||
void jfriend_unload(void);
|
||||
void jfriend_add(char *nickname, char *home,
|
||||
char *work, char *email, char *e164);
|
||||
char *jfriend_get_home(int fid);
|
||||
|
||||
int jsubscriber_load(void);
|
||||
void jsubscriber_unload(void);
|
||||
void subscribers_add(char *nickname, char *uri, int black_list);
|
||||
char *jsubscriber_get_uri(int fid);
|
||||
|
||||
int jidentity_load(void);
|
||||
void jidentity_unload(void);
|
||||
void identitys_add(char *identity, char *registrar, char *realm,
|
||||
char *userid, char *password);
|
||||
char *jidentity_get_identity(int fid);
|
||||
char *jidentity_get_registrar(int fid);
|
||||
|
||||
#define REMOVE_ELEMENT(first_element, element) \
|
||||
if (element->parent==NULL) \
|
||||
{ first_element = element->next; \
|
||||
if (first_element!=NULL) \
|
||||
first_element->parent = NULL; } \
|
||||
else \
|
||||
{ element->parent->next = element->next; \
|
||||
if (element->next!=NULL) \
|
||||
element->next->parent = element->parent; \
|
||||
element->next = NULL; \
|
||||
element->parent = NULL; }
|
||||
|
||||
#define ADD_ELEMENT(first_element, element) \
|
||||
if (first_element==NULL) \
|
||||
{ \
|
||||
first_element = element; \
|
||||
element->next = NULL; \
|
||||
element->parent = NULL; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
element->next = first_element; \
|
||||
element->parent = NULL; \
|
||||
element->next->parent = element; \
|
||||
first_element = element; \
|
||||
}
|
||||
|
||||
#define APPEND_ELEMENT(type_of_element_t, first_element, element) \
|
||||
if (first_element==NULL) \
|
||||
{ first_element = element; \
|
||||
element->next = NULL; /* useless */ \
|
||||
element->parent = NULL; /* useless */ } \
|
||||
else \
|
||||
{ type_of_element_t *f; \
|
||||
for (f=first_element; f->next!=NULL; f=f->next) \
|
||||
{ } \
|
||||
f->next = element; \
|
||||
element->parent = f; \
|
||||
element->next = NULL; \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
278
linphone/exosip/eXutils.c
Normal file
278
linphone/exosip/eXutils.c
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#include <osipparser2/osip_port.h>
|
||||
#include "eXosip2.h"
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
#ifdef WIN32
|
||||
/* You need the Platform SDK to compile this. */
|
||||
#include <Windows.h>
|
||||
|
||||
#else /* sun, *BSD, linux, and other? */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
eXosip_guess_ip_for_via (int family, char *address, int size){
|
||||
char *res=NULL;
|
||||
if (family==AF_INET6)
|
||||
eXosip_get_localip_for("2001:638:500:101:2e0:81ff:fe24:37c6",&res);
|
||||
else
|
||||
eXosip_get_localip_for("15.128.128.93",&res);
|
||||
strncpy(address,res,size);
|
||||
osip_free(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef SM
|
||||
|
||||
void eXosip_get_localip_from_via(osip_message_t *mesg,char **locip){
|
||||
osip_via_t *via=NULL;
|
||||
char *host;
|
||||
via=(osip_via_t*)osip_list_get(mesg->vias,0);
|
||||
if (via==NULL) {
|
||||
host="15.128.128.93";
|
||||
eXosip_trace(OSIP_ERROR,("Could not get via:%s"));
|
||||
}else host=via->host;
|
||||
eXosip_get_localip_for(host,locip);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 1024
|
||||
#endif
|
||||
|
||||
void eXosip_get_localip_for(char *address_to_reach,char **loc){
|
||||
int err,tmp;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res=NULL,*res0=NULL;
|
||||
struct sockaddr_storage addr;
|
||||
int sock;
|
||||
#ifdef __APPLE_CC__
|
||||
int s;
|
||||
#else
|
||||
socklen_t s;
|
||||
#endif
|
||||
|
||||
if (eXosip.forced_localip){
|
||||
*loc=osip_strdup(eXosip.localip);
|
||||
return;
|
||||
}
|
||||
|
||||
*loc=osip_malloc(MAXHOSTNAMELEN);
|
||||
if (eXosip.ip_family==AF_INET)
|
||||
strcpy(*loc,"127.0.0.1"); /* always fallback to local loopback */
|
||||
else strcpy(*loc,"::1");
|
||||
|
||||
memset(&hints,0,sizeof(hints));
|
||||
hints.ai_family=(eXosip.ip_family==AF_INET) ? PF_INET:PF_INET6;
|
||||
hints.ai_socktype=SOCK_DGRAM;
|
||||
/*hints.ai_flags=AI_NUMERICHOST|AI_CANONNAME;*/
|
||||
err=getaddrinfo(address_to_reach,"5060",&hints,&res0);
|
||||
if (err!=0){
|
||||
eXosip_trace(OSIP_ERROR,("Error in getaddrinfo for %s: %s\n",address_to_reach,gai_strerror(err)));
|
||||
return ;
|
||||
}
|
||||
if (res0==NULL){
|
||||
eXosip_trace(OSIP_ERROR,("getaddrinfo reported nothing !"));
|
||||
abort();
|
||||
return ;
|
||||
}
|
||||
for (res=res0;res!=NULL;res=res->ai_next){
|
||||
sock=socket(res->ai_family,SOCK_DGRAM,0);
|
||||
tmp=1;
|
||||
err=setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof(int));
|
||||
if (err<0){
|
||||
eXosip_trace(OSIP_ERROR,("Error in setsockopt: %s\n",strerror(errno)));
|
||||
abort();
|
||||
return ;
|
||||
}
|
||||
err=connect(sock,res->ai_addr,res->ai_addrlen);
|
||||
if (err<0) {
|
||||
eXosip_trace(OSIP_ERROR,("Error in connect: %s\n",strerror(errno)));
|
||||
close(sock);
|
||||
sock=-1;
|
||||
continue;
|
||||
}else break;
|
||||
}
|
||||
freeaddrinfo(res0);
|
||||
if (sock==-1){
|
||||
eXosip_trace(OSIP_WARNING,("Could not find interface to reach %s\n",address_to_reach));
|
||||
return;
|
||||
}
|
||||
res0=NULL;
|
||||
res=NULL;
|
||||
s=sizeof(addr);
|
||||
err=getsockname(sock,(struct sockaddr*)&addr,&s);
|
||||
if (err!=0) {
|
||||
eXosip_trace(OSIP_ERROR,("Error in getsockname: %s\n",strerror(errno)));
|
||||
close(sock);
|
||||
return ;
|
||||
}
|
||||
|
||||
err=getnameinfo((struct sockaddr *)&addr,s,*loc,MAXHOSTNAMELEN,NULL,0,NI_NUMERICHOST);
|
||||
if (err!=0){
|
||||
eXosip_trace(OSIP_ERROR,("getnameinfo error:%s ; while finding local address for %s",strerror(errno), address_to_reach));
|
||||
abort();
|
||||
return ;
|
||||
}
|
||||
close(sock);
|
||||
eXosip_trace(OSIP_INFO1,("Outgoing interface to reach %s is %s.\n",address_to_reach,*loc));
|
||||
return ;
|
||||
}
|
||||
|
||||
char *strdup_printf(const char *fmt, ...)
|
||||
{
|
||||
/* Guess we need no more than 100 bytes. */
|
||||
int n, size = 100;
|
||||
char *p;
|
||||
va_list ap;
|
||||
if ((p = osip_malloc (size)) == NULL)
|
||||
return NULL;
|
||||
while (1)
|
||||
{
|
||||
/* Try to print in the allocated space. */
|
||||
va_start (ap, fmt);
|
||||
#ifdef WIN32
|
||||
n = _vsnprintf (p, size, fmt, ap);
|
||||
#else
|
||||
n = vsnprintf (p, size, fmt, ap);
|
||||
#endif
|
||||
va_end (ap);
|
||||
/* If that worked, return the string. */
|
||||
if (n > -1 && n < size)
|
||||
return p;
|
||||
/* Else try again with more space. */
|
||||
if (n > -1) /* glibc 2.1 */
|
||||
size = n + 1; /* precisely what is needed */
|
||||
else /* glibc 2.0 */
|
||||
size *= 2; /* twice the old size */
|
||||
if ((p = realloc (p, size)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
eXosip_get_addrinfo (struct addrinfo **addrinfo, char *hostname, int service)
|
||||
{
|
||||
#ifndef WIN32
|
||||
struct in_addr addr;
|
||||
struct in6_addr addrv6;
|
||||
#else
|
||||
unsigned long int one_inet_addr;
|
||||
#endif
|
||||
struct addrinfo hints;
|
||||
int error;
|
||||
char portbuf[10];
|
||||
if (service!=0)
|
||||
snprintf(portbuf, sizeof(portbuf), "%i", service);
|
||||
|
||||
memset (&hints, 0, sizeof (hints));
|
||||
#ifndef WIN32
|
||||
if (inet_pton(AF_INET, hostname, &addr)>0)
|
||||
{
|
||||
/* ipv4 address detected */
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
hints.ai_family = PF_INET;
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_INFO2, NULL,
|
||||
"IPv4 address detected: %s\n", hostname));
|
||||
}
|
||||
else if (inet_pton(AF_INET6, hostname, &addrv6)>0)
|
||||
{
|
||||
/* ipv6 address detected */
|
||||
/* Do the resolution anyway */
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = PF_INET6;
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_INFO2, NULL,
|
||||
"IPv6 address detected: %s\n", hostname));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* hostname must be resolved */
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_family = (eXosip.ip_family==AF_INET) ? PF_INET:PF_INET6;
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_INFO2, NULL,
|
||||
"Not an IPv4 or IPv6 address: %s\n", hostname));
|
||||
}
|
||||
#else
|
||||
if ((int)(one_inet_addr = inet_addr(hostname)) == -1)
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
else
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
|
||||
#ifdef IPV6_SUPPORT
|
||||
hints.ai_family = PF_UNSPEC; /* ipv6 support */
|
||||
#else
|
||||
hints.ai_family = PF_INET; /* ipv4 only support */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
if (service==0)
|
||||
{
|
||||
error = getaddrinfo (hostname, "sip", &hints, addrinfo);
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_INFO2, NULL,
|
||||
"SRV resolution with udp-sip-%s\n", hostname));
|
||||
}
|
||||
else
|
||||
{
|
||||
error = getaddrinfo (hostname, portbuf, &hints, addrinfo);
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_INFO2, NULL,
|
||||
"DNS resolution with %s:%i\n", hostname, service));
|
||||
}
|
||||
if (error || *addrinfo == NULL)
|
||||
{
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_INFO2, NULL,
|
||||
"getaddrinfo failure. %s:%s (%s)\n", hostname, portbuf, gai_strerror(error)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
289
linphone/exosip/exosip.dev
Executable file
289
linphone/exosip/exosip.dev
Executable file
|
|
@ -0,0 +1,289 @@
|
|||
[Project]
|
||||
FileName=exosip.dev
|
||||
Name=exosip
|
||||
UnitCount=24
|
||||
Type=2
|
||||
Ver=1
|
||||
ObjFiles=
|
||||
Includes=.
|
||||
Libs=
|
||||
PrivateResource=
|
||||
ResourceIncludes=
|
||||
MakeIncludes=
|
||||
Compiler=-D_WIN32_WINNT=0x501_@@_-DSM_@@_-g_@@_
|
||||
CppCompiler=
|
||||
Linker=
|
||||
IsCpp=0
|
||||
Icon=
|
||||
ExeOutput=
|
||||
ObjectOutput=
|
||||
OverrideOutput=1
|
||||
OverrideOutputName=libexosip.a
|
||||
HostApplication=
|
||||
Folders=
|
||||
CommandLine=
|
||||
UseCustomMakefile=0
|
||||
CustomMakefile=
|
||||
IncludeVersionInfo=0
|
||||
SupportXPThemes=0
|
||||
CompilerSet=0
|
||||
CompilerSettings=0000000000000000000000
|
||||
|
||||
[Unit1]
|
||||
FileName=udp.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit2]
|
||||
FileName=eXosip2.h
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit3]
|
||||
FileName=eXosip.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit4]
|
||||
FileName=eXosip.h
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit5]
|
||||
FileName=eXosip_cfg.h
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit6]
|
||||
FileName=eXutils.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit7]
|
||||
FileName=jauth.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit8]
|
||||
FileName=jcall.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit9]
|
||||
FileName=jcallback.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit10]
|
||||
FileName=jdialog.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit11]
|
||||
FileName=jevents.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit12]
|
||||
FileName=jfreinds.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit13]
|
||||
FileName=jidentity.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit14]
|
||||
FileName=jnotify.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit15]
|
||||
FileName=jpipe.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit16]
|
||||
FileName=jpipe.h
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit17]
|
||||
FileName=jpublish.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit18]
|
||||
FileName=jreg.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit19]
|
||||
FileName=jrequest.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit20]
|
||||
FileName=jresponse.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit21]
|
||||
FileName=jsubscribe.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit22]
|
||||
FileName=jsubscribers.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit23]
|
||||
FileName=misc.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit24]
|
||||
FileName=sdp_offans.c
|
||||
CompileCpp=0
|
||||
Folder=exosip
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[VersionInfo]
|
||||
Major=0
|
||||
Minor=1
|
||||
Release=1
|
||||
Build=1
|
||||
LanguageID=1033
|
||||
CharsetID=1252
|
||||
CompanyName=
|
||||
FileVersion=
|
||||
FileDescription=Developed using the Dev-C++ IDE
|
||||
InternalName=
|
||||
LegalCopyright=
|
||||
LegalTrademarks=
|
||||
OriginalFilename=
|
||||
ProductName=
|
||||
ProductVersion=
|
||||
AutoIncBuildNr=0
|
||||
|
||||
453
linphone/exosip/jauth.c
Normal file
453
linphone/exosip/jauth.c
Normal file
|
|
@ -0,0 +1,453 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#include "eXosip2.h"
|
||||
#include <eXosip.h>
|
||||
#include <eXosip_cfg.h>
|
||||
|
||||
#include <osip2/osip_mt.h>
|
||||
#include <osip2/osip_condv.h>
|
||||
|
||||
/* #include <osip2/global.h> */
|
||||
#include <osipparser2/osip_md5.h>
|
||||
|
||||
/* TAKEN from rcf2617.txt */
|
||||
|
||||
#define HASHLEN 16
|
||||
typedef char HASH[HASHLEN];
|
||||
#define HASHHEXLEN 32
|
||||
typedef char HASHHEX[HASHHEXLEN+1];
|
||||
#define IN
|
||||
#define OUT
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
/* Private functions */
|
||||
static void CvtHex(IN HASH Bin, OUT HASHHEX Hex);
|
||||
static void DigestCalcHA1(IN const char * pszAlg, IN const char * pszUserName,
|
||||
IN const char * pszRealm, IN const char * pszPassword,
|
||||
IN const char * pszNonce, IN const char * pszCNonce,
|
||||
OUT HASHHEX SessionKey);
|
||||
static void DigestCalcResponse(IN HASHHEX HA1,
|
||||
IN const char * pszNonce,
|
||||
IN const char * pszNonceCount,
|
||||
IN const char * pszCNonce,
|
||||
IN const char * pszQop,
|
||||
IN const char * pszMethod,
|
||||
IN const char * pszDigestUri,
|
||||
IN HASHHEX HEntity, OUT HASHHEX Response);
|
||||
|
||||
static void CvtHex(IN HASH Bin,
|
||||
OUT HASHHEX Hex)
|
||||
{
|
||||
unsigned short i;
|
||||
unsigned char j;
|
||||
|
||||
for (i = 0; i < HASHLEN; i++) {
|
||||
j = (Bin[i] >> 4) & 0xf;
|
||||
if (j <= 9)
|
||||
Hex[i*2] = (j + '0');
|
||||
else
|
||||
Hex[i*2] = (j + 'a' - 10);
|
||||
j = Bin[i] & 0xf;
|
||||
if (j <= 9)
|
||||
Hex[i*2+1] = (j + '0');
|
||||
else
|
||||
Hex[i*2+1] = (j + 'a' - 10);
|
||||
};
|
||||
Hex[HASHHEXLEN] = '\0';
|
||||
}
|
||||
|
||||
/* calculate H(A1) as per spec */
|
||||
static void DigestCalcHA1(IN const char * pszAlg,
|
||||
IN const char * pszUserName,
|
||||
IN const char * pszRealm,
|
||||
IN const char * pszPassword,
|
||||
IN const char * pszNonce,
|
||||
IN const char * pszCNonce,
|
||||
OUT HASHHEX SessionKey)
|
||||
{
|
||||
MD5_CTX Md5Ctx;
|
||||
HASH HA1;
|
||||
|
||||
MD5Init(&Md5Ctx);
|
||||
MD5Update(&Md5Ctx, (unsigned char *)pszUserName, strlen(pszUserName));
|
||||
MD5Update(&Md5Ctx, (unsigned char *)":", 1);
|
||||
MD5Update(&Md5Ctx, (unsigned char *)pszRealm, strlen(pszRealm));
|
||||
MD5Update(&Md5Ctx, (unsigned char *)":", 1);
|
||||
MD5Update(&Md5Ctx, (unsigned char *)pszPassword, strlen(pszPassword));
|
||||
MD5Final((unsigned char *)HA1, &Md5Ctx);
|
||||
if ((pszAlg!=NULL)&&osip_strcasecmp(pszAlg, "md5-sess") == 0)
|
||||
{
|
||||
MD5Init(&Md5Ctx);
|
||||
MD5Update(&Md5Ctx, (unsigned char *)HA1, HASHLEN);
|
||||
MD5Update(&Md5Ctx, (unsigned char *)":", 1);
|
||||
MD5Update(&Md5Ctx, (unsigned char *)pszNonce, strlen(pszNonce));
|
||||
MD5Update(&Md5Ctx, (unsigned char *)":", 1);
|
||||
MD5Update(&Md5Ctx, (unsigned char *)pszCNonce, strlen(pszCNonce));
|
||||
MD5Final((unsigned char *)HA1, &Md5Ctx);
|
||||
}
|
||||
CvtHex(HA1, SessionKey);
|
||||
}
|
||||
|
||||
/* calculate request-digest/response-digest as per HTTP Digest spec */
|
||||
static void DigestCalcResponse(IN HASHHEX HA1, /* H(A1) */
|
||||
IN const char * pszNonce, /* nonce from server */
|
||||
IN const char * pszNonceCount,/* 8 hex digits */
|
||||
IN const char * pszCNonce, /* client nonce */
|
||||
IN const char * pszQop, /* qop-value: "", "auth", "auth-int" */
|
||||
IN const char * pszMethod, /* method from the request */
|
||||
IN const char * pszDigestUri, /* requested URL */
|
||||
IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */
|
||||
OUT HASHHEX Response /* request-digest or response-digest */)
|
||||
{
|
||||
MD5_CTX Md5Ctx;
|
||||
HASH HA2;
|
||||
HASH RespHash;
|
||||
HASHHEX HA2Hex;
|
||||
|
||||
int auth_int_flag = 0;
|
||||
|
||||
/* calculate H(A2) */
|
||||
MD5Init(&Md5Ctx);
|
||||
MD5Update(&Md5Ctx, (unsigned char *)pszMethod, strlen(pszMethod));
|
||||
MD5Update(&Md5Ctx, (unsigned char *)":", 1);
|
||||
MD5Update(&Md5Ctx, (unsigned char *)pszDigestUri, strlen(pszDigestUri));
|
||||
|
||||
if (pszQop!=NULL)
|
||||
{
|
||||
char *index = strchr(pszQop,'i');
|
||||
while (index!=NULL&&index-pszQop>=5&&strlen(index)>=3)
|
||||
{
|
||||
if (osip_strncasecmp(index-5, "auth-int",8) == 0)
|
||||
{
|
||||
auth_int_flag = 1;
|
||||
goto auth_withqop;
|
||||
}
|
||||
index = strchr(index+1,'i');
|
||||
}
|
||||
|
||||
index = strchr(pszQop,'a');
|
||||
while (index!=NULL&&strlen(index)>=4)
|
||||
{
|
||||
if (osip_strncasecmp(index, "auth",4) == 0)
|
||||
{
|
||||
/* and in the case of a unknown token
|
||||
like auth1. It is not auth, but this
|
||||
implementation will think it is!??
|
||||
This is may not happen but it's a bug!
|
||||
*/
|
||||
goto auth_withqop;
|
||||
}
|
||||
index = strchr(index+1,'a');
|
||||
}
|
||||
goto auth_withoutqop;
|
||||
}
|
||||
|
||||
auth_withoutqop:
|
||||
MD5Final((unsigned char*)HA2, &Md5Ctx);
|
||||
CvtHex(HA2, HA2Hex);
|
||||
|
||||
/* calculate response */
|
||||
MD5Init(&Md5Ctx);
|
||||
MD5Update(&Md5Ctx, (unsigned char*)HA1, HASHHEXLEN);
|
||||
MD5Update(&Md5Ctx, (unsigned char*)":", 1);
|
||||
MD5Update(&Md5Ctx, (unsigned char*)pszNonce, strlen(pszNonce));
|
||||
MD5Update(&Md5Ctx, (unsigned char*)":", 1);
|
||||
|
||||
goto end;
|
||||
|
||||
auth_withqop:
|
||||
|
||||
if (auth_int_flag)
|
||||
{
|
||||
MD5Update(&Md5Ctx, (unsigned char*)":", 1);
|
||||
MD5Update(&Md5Ctx, (unsigned char*)HEntity, HASHHEXLEN);
|
||||
}
|
||||
|
||||
MD5Final((unsigned char*)HA2, &Md5Ctx);
|
||||
CvtHex(HA2, HA2Hex);
|
||||
|
||||
/* calculate response */
|
||||
MD5Init(&Md5Ctx);
|
||||
MD5Update(&Md5Ctx, (unsigned char*)HA1, HASHHEXLEN);
|
||||
MD5Update(&Md5Ctx, (unsigned char*)":", 1);
|
||||
MD5Update(&Md5Ctx, (unsigned char*)pszNonce, strlen(pszNonce));
|
||||
MD5Update(&Md5Ctx, (unsigned char*)":", 1);
|
||||
MD5Update(&Md5Ctx, (unsigned char*)pszNonceCount, strlen(pszNonceCount));
|
||||
MD5Update(&Md5Ctx, (unsigned char*)":", 1);
|
||||
MD5Update(&Md5Ctx, (unsigned char*)pszCNonce, strlen(pszCNonce));
|
||||
MD5Update(&Md5Ctx, (unsigned char*)":", 1);
|
||||
MD5Update(&Md5Ctx, (unsigned char*)pszQop, strlen(pszQop));
|
||||
MD5Update(&Md5Ctx, (unsigned char*)":", 1);
|
||||
|
||||
end:
|
||||
MD5Update(&Md5Ctx, (unsigned char*)HA2Hex, HASHHEXLEN);
|
||||
MD5Final((unsigned char*)RespHash, &Md5Ctx);
|
||||
CvtHex(RespHash, Response);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
__eXosip_create_authorization_header(osip_message_t *previous_answer,
|
||||
const char *rquri, const char *username,
|
||||
const char *passwd,
|
||||
osip_authorization_t **auth)
|
||||
{
|
||||
static int nc = 1;
|
||||
|
||||
osip_authorization_t *aut;
|
||||
osip_www_authenticate_t *wa=NULL;
|
||||
|
||||
osip_message_get_www_authenticate(previous_answer,0,&wa);
|
||||
|
||||
/* make some test */
|
||||
if (passwd==NULL)
|
||||
return -1;
|
||||
if (wa==NULL||wa->auth_type==NULL
|
||||
||(wa->realm==NULL)||(wa->nonce==NULL)) {
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"www_authenticate header is not acceptable.\n"));
|
||||
return -1;
|
||||
}
|
||||
if (0!=osip_strcasecmp("Digest",wa->auth_type))
|
||||
{
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"Authentication method not supported. (Digest only).\n"));
|
||||
return -1;
|
||||
}
|
||||
/* "MD5" is invalid, but some servers use it. */
|
||||
if (wa->algorithm!=NULL&&0!=osip_strcasecmp("MD5",wa->algorithm)&&0!=osip_strcasecmp("\"MD5\"",wa->algorithm))
|
||||
{
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"Authentication method not supported. (Digest only).\n"));
|
||||
return -1;
|
||||
}
|
||||
if (0!=osip_authorization_init(&aut))
|
||||
{
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"allocation with authorization_init failed.\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* just copy some feilds from response to new request */
|
||||
osip_authorization_set_auth_type(aut,osip_strdup("Digest"));
|
||||
osip_authorization_set_realm(aut,osip_strdup(osip_www_authenticate_get_realm(wa)));
|
||||
osip_authorization_set_nonce(aut,osip_strdup(osip_www_authenticate_get_nonce(wa)));
|
||||
if (osip_www_authenticate_get_opaque(wa)!=NULL)
|
||||
osip_authorization_set_opaque(aut,osip_strdup(osip_www_authenticate_get_opaque(wa)));
|
||||
/* copy the username field in new request */
|
||||
aut->username = osip_malloc(strlen(username)+3);
|
||||
sprintf(aut->username,"\"%s\"",username);
|
||||
|
||||
{
|
||||
char *tmp = osip_malloc(strlen(rquri)+3);
|
||||
sprintf(tmp,"\"%s\"",rquri);
|
||||
osip_authorization_set_uri(aut,tmp);
|
||||
}
|
||||
|
||||
osip_authorization_set_algorithm(aut,osip_strdup("MD5"));
|
||||
|
||||
{
|
||||
char * pszNonce = osip_strdup_without_quote(osip_www_authenticate_get_nonce(wa));
|
||||
char * pszCNonce = osip_strdup_without_quote("abcdefghi");
|
||||
char * pszUser = osip_strdup_without_quote(username);
|
||||
char * pszRealm = osip_strdup_without_quote(osip_authorization_get_realm(aut));
|
||||
const char * pszPass=NULL;
|
||||
char * pszAlg = osip_strdup("MD5");
|
||||
char *szNonceCount = NULL;
|
||||
char * pszMethod = osip_strdup_without_quote(previous_answer->cseq->method);
|
||||
char * pszQop = NULL;
|
||||
char * pszURI = osip_strdup_without_quote(rquri);
|
||||
|
||||
szNonceCount = osip_strdup("00000000");
|
||||
sprintf(szNonceCount, "%08d", nc++);
|
||||
|
||||
HASHHEX HA1;
|
||||
HASHHEX HA2 = "";
|
||||
HASHHEX Response;
|
||||
|
||||
pszPass=passwd;
|
||||
|
||||
if (osip_www_authenticate_get_qop_options(wa)!=NULL)
|
||||
{
|
||||
pszQop = osip_strdup_without_quote(osip_www_authenticate_get_qop_options(wa));
|
||||
|
||||
osip_authorization_set_message_qop(aut,osip_strdup(pszQop));
|
||||
osip_authorization_set_nonce_count(aut,osip_strdup(szNonceCount));
|
||||
osip_authorization_set_cnonce(aut,osip_strdup("\"abcdefghi\""));
|
||||
osip_authorization_set_algorithm(aut,osip_strdup(pszAlg));
|
||||
}
|
||||
|
||||
DigestCalcHA1(pszAlg, pszUser, pszRealm, pszPass, pszNonce,
|
||||
pszCNonce, HA1);
|
||||
DigestCalcResponse(HA1, pszNonce, szNonceCount, pszCNonce, pszQop,
|
||||
pszMethod, pszURI, HA2, Response);
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_INFO4, NULL,
|
||||
"Response in authorization |%s|\n", Response));
|
||||
{
|
||||
char *resp = osip_malloc(35);
|
||||
sprintf(resp,"\"%s\"",Response);
|
||||
osip_authorization_set_response(aut,resp);
|
||||
}
|
||||
osip_free(pszAlg); /* xkd, 2004-5-13*/
|
||||
osip_free(pszNonce);
|
||||
osip_free(pszCNonce);
|
||||
osip_free(pszRealm);
|
||||
osip_free(pszQop);
|
||||
osip_free(szNonceCount);
|
||||
osip_free(pszUser);
|
||||
osip_free(pszMethod);
|
||||
osip_free(pszURI);
|
||||
}
|
||||
|
||||
*auth = aut;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__eXosip_create_proxy_authorization_header(osip_message_t *previous_answer,
|
||||
const char *rquri,
|
||||
const char *username,
|
||||
const char *passwd,
|
||||
osip_proxy_authorization_t **auth)
|
||||
{
|
||||
osip_proxy_authorization_t *aut;
|
||||
osip_proxy_authenticate_t *wa;
|
||||
|
||||
osip_message_get_proxy_authenticate(previous_answer,0,&wa);
|
||||
|
||||
/* make some test */
|
||||
if (passwd==NULL)
|
||||
return -1;
|
||||
if (wa==NULL||wa->auth_type==NULL
|
||||
||(wa->realm==NULL)||(wa->nonce==NULL))
|
||||
{
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"www_authenticate header is not acceptable.\n"));
|
||||
return -1;
|
||||
}
|
||||
if (0!=osip_strcasecmp("Digest",wa->auth_type))
|
||||
{
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"Authentication method not supported. (Digest only).\n"));
|
||||
return -1;
|
||||
}
|
||||
/* "MD5" is invalid, but some servers use it. */
|
||||
if (wa->algorithm!=NULL&&0!=osip_strcasecmp("MD5",wa->algorithm)&&0!=osip_strcasecmp("\"MD5\"",wa->algorithm))
|
||||
{
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"Authentication method not supported. (MD5 Digest only).\n"));
|
||||
return -1;
|
||||
}
|
||||
if (0!=osip_proxy_authorization_init(&aut))
|
||||
{
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"allocation with authorization_init failed.\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* just copy some feilds from response to new request */
|
||||
osip_proxy_authorization_set_auth_type(aut,osip_strdup("Digest"));
|
||||
osip_proxy_authorization_set_realm(aut,osip_strdup(osip_proxy_authenticate_get_realm(wa)));
|
||||
osip_proxy_authorization_set_nonce(aut,osip_strdup(osip_proxy_authenticate_get_nonce(wa)));
|
||||
if (osip_proxy_authenticate_get_opaque(wa)!=NULL)
|
||||
osip_proxy_authorization_set_opaque(aut,osip_strdup(osip_proxy_authenticate_get_opaque(wa)));
|
||||
/* copy the username field in new request */
|
||||
aut->username = osip_malloc(strlen(username)+3);
|
||||
sprintf(aut->username,"\"%s\"",username);
|
||||
|
||||
{
|
||||
char *tmp = osip_malloc(strlen(rquri)+3);
|
||||
sprintf(tmp,"\"%s\"",rquri);
|
||||
osip_proxy_authorization_set_uri(aut,tmp);
|
||||
}
|
||||
osip_proxy_authorization_set_algorithm(aut,osip_strdup("MD5"));
|
||||
|
||||
{
|
||||
char * pszNonce = NULL;
|
||||
char * pszCNonce= NULL ;
|
||||
const char * pszUser = username;
|
||||
char * pszRealm = osip_strdup_without_quote(osip_proxy_authorization_get_realm(aut));
|
||||
const char * pszPass = NULL;
|
||||
char * pszAlg = osip_strdup("MD5");
|
||||
char *szNonceCount = NULL;
|
||||
char * pszMethod = previous_answer->cseq->method;
|
||||
char * pszQop = NULL;
|
||||
const char * pszURI = rquri;
|
||||
|
||||
HASHHEX HA1;
|
||||
HASHHEX HA2 = "";
|
||||
HASHHEX Response;
|
||||
|
||||
pszPass=passwd;
|
||||
|
||||
if (osip_www_authenticate_get_nonce(wa)==NULL)
|
||||
return -1;
|
||||
pszNonce = osip_strdup_without_quote(osip_www_authenticate_get_nonce(wa));
|
||||
|
||||
/* should upgrade szNonceCount */
|
||||
/* should add szNonceCount in aut*/
|
||||
/* should upgrade pszCNonce */
|
||||
/* should add pszCNonce in aut */
|
||||
|
||||
if (osip_proxy_authenticate_get_qop_options(wa)!=NULL)
|
||||
{
|
||||
szNonceCount = osip_strdup("00000001");
|
||||
/* MUST be incremented on each */
|
||||
pszQop = osip_strdup(osip_proxy_authenticate_get_qop_options(wa));
|
||||
pszCNonce = osip_strdup("234abcc436e2667097e7fe6eia53e8dd");
|
||||
}
|
||||
DigestCalcHA1(pszAlg, pszUser, pszRealm, pszPass, pszNonce,
|
||||
pszCNonce, HA1);
|
||||
DigestCalcResponse(HA1, pszNonce, szNonceCount, pszCNonce, pszQop,
|
||||
pszMethod, pszURI, HA2, Response);
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_INFO4, NULL,
|
||||
"Response in proxy_authorization |%s|\n", Response));
|
||||
{
|
||||
char *resp = osip_malloc(35);
|
||||
sprintf(resp,"\"%s\"",Response);
|
||||
osip_proxy_authorization_set_response(aut,resp);
|
||||
}
|
||||
osip_free(pszAlg); /* xkd, 2004-5-13*/
|
||||
osip_free(pszNonce);
|
||||
osip_free(pszCNonce);
|
||||
osip_free(pszRealm);
|
||||
osip_free(pszQop);
|
||||
osip_free(szNonceCount);
|
||||
}
|
||||
|
||||
*auth = aut;
|
||||
return 0;
|
||||
}
|
||||
122
linphone/exosip/jcall.c
Normal file
122
linphone/exosip/jcall.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "eXosip2.h"
|
||||
#include <eXosip_cfg.h>
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
int eXosip_call_find(int cid, eXosip_call_t **jc)
|
||||
{
|
||||
for (*jc=eXosip.j_calls; *jc!=NULL; *jc=(*jc)->next)
|
||||
{
|
||||
if ((*jc)->c_id==cid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*jc = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
eXosip_call_init(eXosip_call_t **jc)
|
||||
{
|
||||
*jc = (eXosip_call_t *)osip_malloc(sizeof(eXosip_call_t));
|
||||
if (*jc == NULL) return -1;
|
||||
memset(*jc, 0, sizeof(eXosip_call_t));
|
||||
|
||||
(*jc)->c_id = -1; /* make sure the eXosip_update will assign a valid id to the call */
|
||||
osip_negotiation_ctx_init(&(*jc)->c_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
__eXosip_call_remove_dialog_reference_in_call(eXosip_call_t *jc, eXosip_dialog_t *jd)
|
||||
{
|
||||
eXosip_dialog_t *_jd;
|
||||
jinfo_t *ji;
|
||||
if (jc==NULL) return;
|
||||
if (jd==NULL) return;
|
||||
|
||||
|
||||
for (_jd = jc->c_dialogs; _jd!=NULL; _jd=jc->c_dialogs)
|
||||
{
|
||||
if (jd==_jd)
|
||||
break;
|
||||
}
|
||||
if (_jd==NULL)
|
||||
{
|
||||
/* dialog not found??? */
|
||||
}
|
||||
|
||||
ji = osip_transaction_get_your_instance(jc->c_inc_tr);
|
||||
if (ji!=NULL && ji->jd==jd)
|
||||
ji->jd=NULL;
|
||||
ji = osip_transaction_get_your_instance(jc->c_out_tr);
|
||||
if (ji!=NULL && ji->jd==jd)
|
||||
ji->jd=NULL;
|
||||
}
|
||||
|
||||
void
|
||||
eXosip_call_free(eXosip_call_t *jc)
|
||||
{
|
||||
/* ... */
|
||||
|
||||
eXosip_dialog_t *jd;
|
||||
|
||||
for (jd = jc->c_dialogs; jd!=NULL; jd=jc->c_dialogs)
|
||||
{
|
||||
REMOVE_ELEMENT(jc->c_dialogs, jd);
|
||||
eXosip_dialog_free(jd);
|
||||
}
|
||||
|
||||
__eXosip_delete_jinfo(jc->c_inc_tr);
|
||||
__eXosip_delete_jinfo(jc->c_out_tr);
|
||||
if (jc->c_inc_tr!=NULL)
|
||||
osip_list_add(eXosip.j_transactions, jc->c_inc_tr, 0);
|
||||
if (jc->c_out_tr!=NULL)
|
||||
osip_list_add(eXosip.j_transactions, jc->c_out_tr, 0);
|
||||
|
||||
__eXosip_delete_jinfo(jc->c_inc_options_tr);
|
||||
__eXosip_delete_jinfo(jc->c_out_options_tr);
|
||||
if (jc->c_inc_options_tr!=NULL)
|
||||
osip_list_add(eXosip.j_transactions, jc->c_inc_options_tr, 0);
|
||||
if (jc->c_out_options_tr!=NULL)
|
||||
osip_list_add(eXosip.j_transactions, jc->c_out_options_tr, 0);
|
||||
|
||||
|
||||
osip_negotiation_ctx_free(jc->c_ctx);
|
||||
osip_free(jc);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
eXosip_call_set_subject(eXosip_call_t *jc, char *subject)
|
||||
{
|
||||
if (jc==NULL||subject==NULL||subject[0]=='\0') return;
|
||||
snprintf(jc->c_subject, 99, "%s", subject);
|
||||
}
|
||||
|
||||
1972
linphone/exosip/jcallback.c
Normal file
1972
linphone/exosip/jcallback.c
Normal file
File diff suppressed because it is too large
Load diff
209
linphone/exosip/jdialog.c
Normal file
209
linphone/exosip/jdialog.c
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#include "eXosip2.h"
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
void eXosip_dialog_set_state(eXosip_dialog_t *jd, int state)
|
||||
{
|
||||
jd->d_STATE = state;
|
||||
}
|
||||
|
||||
int eXosip_call_dialog_find(int jid, eXosip_call_t **jc, eXosip_dialog_t **jd)
|
||||
{
|
||||
for (*jc=eXosip.j_calls; *jc!=NULL; *jc=(*jc)->next)
|
||||
{
|
||||
for (*jd=(*jc)->c_dialogs; *jd!=NULL; *jd=(*jd)->next)
|
||||
{
|
||||
if ((*jd)->d_id==jid)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*jd = NULL;
|
||||
*jc = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int eXosip_notify_dialog_find(int nid, eXosip_notify_t **jn, eXosip_dialog_t **jd)
|
||||
{
|
||||
for (*jn=eXosip.j_notifies; *jn!=NULL; *jn=(*jn)->next)
|
||||
{
|
||||
for (*jd=(*jn)->n_dialogs; *jd!=NULL; *jd=(*jd)->next)
|
||||
{
|
||||
if ((*jd)->d_id==nid)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*jd = NULL;
|
||||
*jn = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int eXosip_subscribe_dialog_find(int sid, eXosip_subscribe_t **js, eXosip_dialog_t **jd)
|
||||
{
|
||||
for (*js=eXosip.j_subscribes; *js!=NULL; *js=(*js)->next)
|
||||
{
|
||||
*jd=NULL;
|
||||
if ((*js)->s_id==sid)
|
||||
return 0;
|
||||
for (*jd=(*js)->s_dialogs; *jd!=NULL; *jd=(*jd)->next)
|
||||
{
|
||||
if ((*jd)->d_id==sid)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*jd = NULL;
|
||||
*js = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int eXosip_dialog_set_200ok(eXosip_dialog_t *jd, osip_message_t *_200Ok)
|
||||
{
|
||||
int i;
|
||||
if (jd==NULL) return -1;
|
||||
i = osip_message_clone(_200Ok, &(jd->d_200Ok));
|
||||
if (i!=0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eXosip_dialog_init_as_uac(eXosip_dialog_t **_jd, osip_message_t *_200Ok)
|
||||
{
|
||||
int i;
|
||||
eXosip_dialog_t *jd;
|
||||
*_jd = NULL;
|
||||
jd = (eXosip_dialog_t *) osip_malloc(sizeof(eXosip_dialog_t));
|
||||
jd->d_id = -1; /* not yet available to user */
|
||||
jd->d_STATE = JD_EMPTY;
|
||||
|
||||
if (MSG_IS_REQUEST(_200Ok))
|
||||
{
|
||||
i = osip_dialog_init_as_uac_with_remote_request(&(jd->d_dialog), _200Ok, -1);
|
||||
}
|
||||
else
|
||||
{ /* normal usage with response */
|
||||
i = osip_dialog_init_as_uac(&(jd->d_dialog), _200Ok);
|
||||
}
|
||||
if (i!=0)
|
||||
{
|
||||
osip_free(jd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
jd->media_lines = (osip_list_t*) osip_malloc(sizeof(osip_list_t));
|
||||
osip_list_init(jd->media_lines);
|
||||
|
||||
jd->d_timer = time(NULL);
|
||||
jd->d_200Ok = NULL;
|
||||
jd->d_ack = NULL;
|
||||
jd->next = NULL;
|
||||
jd->parent = NULL;
|
||||
jd->d_out_trs = (osip_list_t*) osip_malloc(sizeof(osip_list_t));
|
||||
osip_list_init(jd->d_out_trs);
|
||||
jd->d_inc_trs = (osip_list_t*) osip_malloc(sizeof(osip_list_t));
|
||||
osip_list_init(jd->d_inc_trs);
|
||||
|
||||
/* jd->d_bh = sdp_handler_new(); */
|
||||
*_jd = jd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eXosip_dialog_init_as_uas(eXosip_dialog_t **_jd, osip_message_t *_invite, osip_message_t *_200Ok)
|
||||
{
|
||||
int i;
|
||||
eXosip_dialog_t *jd;
|
||||
*_jd = NULL;
|
||||
jd = (eXosip_dialog_t *) osip_malloc(sizeof(eXosip_dialog_t));
|
||||
jd->d_id = -1; /* not yet available to user */
|
||||
jd->d_STATE = JD_EMPTY;
|
||||
i = osip_dialog_init_as_uas(&(jd->d_dialog), _invite, _200Ok);
|
||||
if (i!=0)
|
||||
{
|
||||
osip_free(jd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
jd->media_lines = (osip_list_t*) osip_malloc(sizeof(osip_list_t));
|
||||
osip_list_init(jd->media_lines);
|
||||
|
||||
jd->d_timer = time(NULL);
|
||||
jd->d_200Ok = NULL;
|
||||
jd->d_ack = NULL;
|
||||
jd->next = NULL;
|
||||
jd->parent = NULL;
|
||||
jd->d_out_trs = (osip_list_t*) osip_malloc(sizeof(osip_list_t));
|
||||
osip_list_init(jd->d_out_trs);
|
||||
jd->d_inc_trs = (osip_list_t*) osip_malloc(sizeof(osip_list_t));
|
||||
osip_list_init(jd->d_inc_trs);
|
||||
|
||||
#ifdef SUPPORT_MSN
|
||||
/* bugguy MSN */
|
||||
jd->d_dialog->local_cseq = 1;
|
||||
#endif
|
||||
|
||||
/* jd->d_bh = sdp_handler_new(); */
|
||||
*_jd = jd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eXosip_dialog_free(eXosip_dialog_t *jd)
|
||||
{
|
||||
|
||||
while (!osip_list_eol(jd->d_inc_trs, 0))
|
||||
{
|
||||
osip_transaction_t *tr;
|
||||
tr = (osip_transaction_t*) osip_list_get(jd->d_inc_trs, 0);
|
||||
osip_list_remove(jd->d_inc_trs, 0);
|
||||
__eXosip_delete_jinfo(tr);
|
||||
osip_list_add(eXosip.j_transactions, tr, 0);
|
||||
}
|
||||
|
||||
while (!osip_list_eol(jd->d_out_trs, 0))
|
||||
{
|
||||
osip_transaction_t *tr;
|
||||
tr = (osip_transaction_t*) osip_list_get(jd->d_out_trs, 0);
|
||||
osip_list_remove(jd->d_out_trs, 0);
|
||||
__eXosip_delete_jinfo(tr);
|
||||
osip_list_add(eXosip.j_transactions, tr, 0);
|
||||
}
|
||||
|
||||
osip_message_free(jd->d_200Ok);
|
||||
osip_message_free(jd->d_ack);
|
||||
|
||||
osip_dialog_free(jd->d_dialog);
|
||||
|
||||
while (!osip_list_eol(jd->media_lines, 0))
|
||||
{
|
||||
char *tmp = osip_list_get(jd->media_lines, 0);
|
||||
osip_list_remove(jd->media_lines, 0);
|
||||
osip_free(tmp);
|
||||
}
|
||||
|
||||
osip_free(jd->media_lines);
|
||||
osip_free(jd->d_out_trs);
|
||||
osip_free(jd->d_inc_trs);
|
||||
osip_free(jd);
|
||||
}
|
||||
949
linphone/exosip/jevents.c
Normal file
949
linphone/exosip/jevents.c
Normal file
|
|
@ -0,0 +1,949 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#include "eXosip2.h"
|
||||
#include <eXosip.h>
|
||||
#include <osip2/osip_condv.h>
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
|
||||
static void fill_dialog_params(eXosip_event_t *je, osip_dialog_t *dialog)
|
||||
{
|
||||
char *tmp;
|
||||
if (dialog->remote_uri!=NULL){
|
||||
osip_to_to_str(dialog->remote_uri, &tmp);
|
||||
if (tmp!=NULL)
|
||||
{
|
||||
snprintf(je->remote_uri, 255, "%s", tmp);
|
||||
osip_free(tmp);
|
||||
}
|
||||
}
|
||||
if (dialog->local_uri!=NULL)
|
||||
{
|
||||
osip_to_to_str(dialog->local_uri, &tmp);
|
||||
if (tmp!=NULL)
|
||||
{
|
||||
snprintf(je->local_uri, 255, "%s", tmp);
|
||||
osip_free(tmp);
|
||||
}
|
||||
}
|
||||
if (dialog->remote_contact_uri!=NULL){
|
||||
osip_contact_to_str(dialog->remote_contact_uri,&tmp);
|
||||
if (tmp!=NULL){
|
||||
snprintf(je->remote_contact,255,"%s",tmp);
|
||||
osip_free(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eXosip_event_t *
|
||||
eXosip_event_init_for_call(int type,
|
||||
eXosip_call_t *jc,
|
||||
eXosip_dialog_t *jd)
|
||||
{
|
||||
eXosip_event_t *je;
|
||||
eXosip_event_init(&je, type);
|
||||
if (je==NULL) return NULL;
|
||||
je->jc = jc;
|
||||
je->jd = jd;
|
||||
|
||||
je->cid = jc->c_id;
|
||||
if (jd!=NULL)
|
||||
je->did = jd->d_id;
|
||||
|
||||
je->external_reference = jc->external_reference;
|
||||
|
||||
/* fill in usefull info */
|
||||
if (type==EXOSIP_CALL_NEW
|
||||
|| type==EXOSIP_CALL_ACK
|
||||
|| type==EXOSIP_CALL_NOANSWER
|
||||
|| type==EXOSIP_CALL_PROCEEDING
|
||||
|| type==EXOSIP_CALL_RINGING
|
||||
|| type==EXOSIP_CALL_ANSWERED
|
||||
|| type==EXOSIP_CALL_REDIRECTED
|
||||
|| type==EXOSIP_CALL_REQUESTFAILURE
|
||||
|| type==EXOSIP_CALL_SERVERFAILURE
|
||||
|| type==EXOSIP_CALL_GLOBALFAILURE
|
||||
|
||||
|| type==EXOSIP_OPTIONS_NOANSWER
|
||||
|| type==EXOSIP_OPTIONS_PROCEEDING
|
||||
|| type==EXOSIP_OPTIONS_ANSWERED
|
||||
|| type==EXOSIP_OPTIONS_REDIRECTED
|
||||
|| type==EXOSIP_OPTIONS_REQUESTFAILURE
|
||||
|| type==EXOSIP_OPTIONS_SERVERFAILURE
|
||||
|| type==EXOSIP_OPTIONS_GLOBALFAILURE
|
||||
|| type==EXOSIP_OPTIONS_NEW
|
||||
|
||||
|| type==EXOSIP_INFO_NOANSWER
|
||||
|| type==EXOSIP_INFO_PROCEEDING
|
||||
|| type==EXOSIP_INFO_ANSWERED
|
||||
|| type==EXOSIP_INFO_REDIRECTED
|
||||
|| type==EXOSIP_INFO_REQUESTFAILURE
|
||||
|| type==EXOSIP_INFO_SERVERFAILURE
|
||||
|| type==EXOSIP_INFO_GLOBALFAILURE
|
||||
|| type==EXOSIP_INFO_NEW
|
||||
|
||||
|| type==EXOSIP_CALL_CANCELLED
|
||||
|| type==EXOSIP_CALL_TIMEOUT
|
||||
|| type==EXOSIP_CALL_HOLD
|
||||
|| type==EXOSIP_CALL_OFFHOLD
|
||||
|| type==EXOSIP_CALL_CLOSED
|
||||
|| type==EXOSIP_CALL_STARTAUDIO
|
||||
|
||||
|| type==EXOSIP_CALL_REFERED
|
||||
|| type==EXOSIP_CALL_REFER_STATUS
|
||||
|
||||
|| type==EXOSIP_CALL_RELEASED)
|
||||
{
|
||||
if (jc->c_sdp_port[0]!='\0')
|
||||
je->local_sdp_audio_port = osip_atoi(jc->c_sdp_port);
|
||||
|
||||
if (jd!=NULL&&jd->d_dialog!=NULL)
|
||||
{
|
||||
osip_transaction_t *tr;
|
||||
osip_header_t *subject;
|
||||
char *tmp;
|
||||
|
||||
fill_dialog_params(je,jd->d_dialog);
|
||||
|
||||
if (type==EXOSIP_OPTIONS_NOANSWER
|
||||
|| type==EXOSIP_OPTIONS_PROCEEDING
|
||||
|| type==EXOSIP_OPTIONS_ANSWERED
|
||||
|| type==EXOSIP_OPTIONS_REDIRECTED
|
||||
|| type==EXOSIP_OPTIONS_REQUESTFAILURE
|
||||
|| type==EXOSIP_OPTIONS_SERVERFAILURE
|
||||
|| type==EXOSIP_OPTIONS_GLOBALFAILURE
|
||||
|| type==EXOSIP_OPTIONS_NEW)
|
||||
tr = eXosip_find_last_options(jc, jd);
|
||||
else if (type==EXOSIP_INFO_NOANSWER
|
||||
|| type==EXOSIP_INFO_PROCEEDING
|
||||
|| type==EXOSIP_INFO_ANSWERED
|
||||
|| type==EXOSIP_INFO_REDIRECTED
|
||||
|| type==EXOSIP_INFO_REQUESTFAILURE
|
||||
|| type==EXOSIP_INFO_SERVERFAILURE
|
||||
|| type==EXOSIP_INFO_GLOBALFAILURE
|
||||
|| type==EXOSIP_INFO_NEW)
|
||||
tr = eXosip_find_last_info(jc, jd);
|
||||
else if (type==EXOSIP_CALL_REFERED)
|
||||
tr = eXosip_find_last_refer(jc, jd);
|
||||
else if (type==EXOSIP_CALL_REFER_STATUS)
|
||||
tr = eXosip_find_last_inc_notify_for_refer(jc, jd);
|
||||
else
|
||||
tr = eXosip_find_last_invite(jc, jd);
|
||||
if (tr!=NULL && tr->orig_request!=NULL)
|
||||
{
|
||||
osip_message_get_subject(tr->orig_request, 0, &subject);
|
||||
if (subject!=NULL && subject->hvalue!=NULL && subject->hvalue[0]!='\0')
|
||||
snprintf(je->subject, 255, "%s", subject->hvalue);
|
||||
osip_message_header_get_byname(tr->orig_request, "refer-to", 0,
|
||||
&subject);
|
||||
if (subject!=NULL && subject->hvalue!=NULL && subject->hvalue[0]!='\0')
|
||||
snprintf(je->refer_to, 255, "%s", subject->hvalue);
|
||||
|
||||
osip_uri_to_str(tr->orig_request->req_uri, &tmp);
|
||||
if (tmp!=NULL)
|
||||
{
|
||||
snprintf(je->req_uri, 255, "%s", tmp);
|
||||
osip_free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
osip_transaction_t *tr;
|
||||
char *tmp;
|
||||
tr=eXosip_find_last_invite(jc,NULL);
|
||||
/* no dialog established but we need to fill remote_contact */
|
||||
if (tr!=NULL && tr->last_response!=NULL)
|
||||
{
|
||||
osip_contact_t *ctt=NULL;
|
||||
snprintf(je->reason_phrase, 49, "%s", tr->last_response->reason_phrase);
|
||||
je->status_code = tr->last_response->status_code;
|
||||
osip_message_get_contact(tr->last_response,0,&ctt);
|
||||
if (ctt){
|
||||
tmp=NULL;
|
||||
osip_contact_to_str(ctt,&tmp);
|
||||
if (tmp){
|
||||
strncpy(je->remote_contact,tmp,255);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return je;
|
||||
}
|
||||
|
||||
int
|
||||
eXosip_event_add_status(eXosip_event_t *je, osip_message_t *response)
|
||||
{
|
||||
if (response!=NULL && response->reason_phrase!=NULL)
|
||||
{
|
||||
snprintf(je->reason_phrase, 49, "%s", response->reason_phrase);
|
||||
je->status_code = response->status_code;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eXosip_event_add_sdp_info(eXosip_event_t *je, osip_message_t *message)
|
||||
{
|
||||
osip_content_type_t *ctt;
|
||||
osip_mime_version_t *mv;
|
||||
sdp_message_t *sdp;
|
||||
osip_body_t *oldbody;
|
||||
int pos;
|
||||
int gotpayload = 0;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
search for remote_sdp_audio_port & remote_sdp_audio_ip
|
||||
in the last SIP message
|
||||
extract the payload to be used for connection either from negotioation context
|
||||
or from the last SIP message
|
||||
*/
|
||||
|
||||
|
||||
|
||||
if (message==NULL) return -1;
|
||||
|
||||
/* get content-type info */
|
||||
ctt = osip_message_get_content_type(message);
|
||||
mv = osip_message_get_mime_version(message);
|
||||
if (mv==NULL && ctt==NULL)
|
||||
return 0; /* previous message was not correct or empty */
|
||||
if (mv!=NULL)
|
||||
{
|
||||
/* look for the SDP body */
|
||||
/* ... */
|
||||
}
|
||||
else if (ctt!=NULL)
|
||||
{
|
||||
if (ctt->type==NULL || ctt->subtype==NULL)
|
||||
/* it can be application/sdp or mime... */
|
||||
return -1;
|
||||
if (osip_strcasecmp(ctt->type, "application")!=0 ||
|
||||
osip_strcasecmp(ctt->subtype, "sdp")!=0 )
|
||||
{ return -1; }
|
||||
}
|
||||
|
||||
|
||||
if (je->jc)
|
||||
{
|
||||
int pl = eXosip_retrieve_sdp_negotiation_result(je->jc->c_ctx, je->payload_name, sizeof(je->payload_name));
|
||||
if (pl >= 0)
|
||||
{
|
||||
je->payload = pl;
|
||||
gotpayload = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sdp = NULL;
|
||||
pos = 0;
|
||||
while (!osip_list_eol(message->bodies, pos))
|
||||
{
|
||||
int i;
|
||||
oldbody = (osip_body_t *)osip_list_get(message->bodies, pos);
|
||||
pos++;
|
||||
sdp_message_init(&sdp);
|
||||
i = sdp_message_parse(sdp,oldbody->body);
|
||||
if (i==0)
|
||||
{
|
||||
int len = strlen(oldbody->body);
|
||||
if (len<999)
|
||||
osip_strncpy(je->sdp_body, oldbody->body, len);
|
||||
else
|
||||
osip_strncpy(je->sdp_body, oldbody->body, 999);
|
||||
|
||||
break;
|
||||
}
|
||||
sdp_message_free(sdp);
|
||||
sdp = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (sdp!=NULL)
|
||||
{
|
||||
int j=0;
|
||||
if (sdp->c_connection !=NULL
|
||||
&& sdp->c_connection->c_addr !=NULL )
|
||||
{
|
||||
snprintf(je->remote_sdp_audio_ip, 49, "%s",
|
||||
sdp->c_connection->c_addr);
|
||||
}
|
||||
|
||||
|
||||
for (j=0; !osip_list_eol(sdp->m_medias, j); j++)
|
||||
{
|
||||
sdp_media_t *med = (sdp_media_t*) osip_list_get(sdp->m_medias, j);
|
||||
if (med==NULL)
|
||||
{
|
||||
snprintf(je->remote_sdp_audio_ip, 49, "Y a probleme!");
|
||||
}
|
||||
|
||||
if (med->m_media!=NULL &&
|
||||
0==osip_strcasecmp(med->m_media, "audio"))
|
||||
{
|
||||
sdp_connection_t *conn;
|
||||
int pos_attr;
|
||||
char *payload = (char *) osip_list_get (med->m_payloads, 0);
|
||||
|
||||
if (!gotpayload)
|
||||
je->payload = 0;
|
||||
|
||||
if (!gotpayload && payload!=NULL)
|
||||
{
|
||||
je->payload = osip_atoi(payload);
|
||||
/* copy payload name! */
|
||||
for (pos_attr=0;
|
||||
!osip_list_eol(med->a_attributes, pos_attr);
|
||||
pos_attr++)
|
||||
{
|
||||
sdp_attribute_t *attr;
|
||||
attr = (sdp_attribute_t *)osip_list_get(med->a_attributes, pos_attr);
|
||||
if (0==osip_strncasecmp(attr->a_att_field, "rtpmap", 6))
|
||||
{
|
||||
if ((je->payload<10 &&
|
||||
0==osip_strncasecmp(attr->a_att_value, payload, 1))
|
||||
||(je->payload>9 && je->payload<100 &&
|
||||
0==osip_strncasecmp(attr->a_att_value, payload, 2))
|
||||
||(je->payload>100 && je->payload<128 &&
|
||||
0==osip_strncasecmp(attr->a_att_value, payload, 3)))
|
||||
{
|
||||
snprintf(je->payload_name, 49, "%s", attr->a_att_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
je->remote_sdp_audio_port = osip_atoi(med->m_port);
|
||||
conn = (sdp_connection_t*) osip_list_get(med->c_connections, 0);
|
||||
if (conn!=NULL && conn->c_addr!=NULL)
|
||||
{
|
||||
snprintf(je->remote_sdp_audio_ip, 49, "%s",
|
||||
conn->c_addr);
|
||||
}
|
||||
sdp_message_free(sdp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sdp_message_free(sdp);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
eXosip_event_t *
|
||||
eXosip_event_init_for_subscribe(int type,
|
||||
eXosip_subscribe_t *js,
|
||||
eXosip_dialog_t *jd)
|
||||
{
|
||||
char *tmp;
|
||||
eXosip_event_t *je;
|
||||
eXosip_event_init(&je, type);
|
||||
if (je==NULL) return NULL;
|
||||
je->js = js;
|
||||
je->jd = jd;
|
||||
|
||||
je->sid = js->s_id;
|
||||
if (jd!=NULL)
|
||||
je->did = jd->d_id;
|
||||
|
||||
je->ss_status = js->s_ss_status;
|
||||
je->online_status = js->s_online_status;
|
||||
je->ss_reason = js->s_ss_reason;
|
||||
|
||||
/* je->external_reference = js->external_reference; */
|
||||
|
||||
if (jd!=NULL&&jd->d_dialog!=NULL)
|
||||
{
|
||||
fill_dialog_params(je,jd->d_dialog);
|
||||
}
|
||||
|
||||
/* fill in usefull info */
|
||||
if (type==EXOSIP_SUBSCRIPTION_NEW
|
||||
|| type==EXOSIP_SUBSCRIPTION_NOANSWER
|
||||
|| type==EXOSIP_SUBSCRIPTION_PROCEEDING
|
||||
|| type==EXOSIP_SUBSCRIPTION_ANSWERED
|
||||
|| type==EXOSIP_SUBSCRIPTION_REDIRECTED
|
||||
|| type==EXOSIP_SUBSCRIPTION_REQUESTFAILURE
|
||||
|| type==EXOSIP_SUBSCRIPTION_SERVERFAILURE
|
||||
|| type==EXOSIP_SUBSCRIPTION_GLOBALFAILURE
|
||||
|| type==EXOSIP_SUBSCRIPTION_RELEASED)
|
||||
{
|
||||
if (jd!=NULL&&jd->d_dialog!=NULL)
|
||||
{
|
||||
osip_transaction_t *tr;
|
||||
tr = eXosip_find_last_out_subscribe(js, jd);
|
||||
if (tr!=NULL && tr->orig_request!=NULL)
|
||||
{
|
||||
osip_uri_to_str(tr->orig_request->req_uri, &tmp);
|
||||
if (tmp!=NULL)
|
||||
{
|
||||
snprintf(je->req_uri, 255, "%s", tmp);
|
||||
osip_free(tmp);
|
||||
}
|
||||
}
|
||||
if (tr!=NULL && tr->last_response!=NULL)
|
||||
{
|
||||
snprintf(je->reason_phrase, 49, "%s", tr->last_response->reason_phrase);
|
||||
je->status_code = tr->last_response->status_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type==EXOSIP_SUBSCRIPTION_NOTIFY)
|
||||
{
|
||||
if (jd!=NULL&&jd->d_dialog!=NULL)
|
||||
{
|
||||
osip_transaction_t *tr;
|
||||
tr = eXosip_find_last_inc_notify(js, jd);
|
||||
if (tr!=NULL && tr->orig_request!=NULL)
|
||||
{
|
||||
osip_uri_to_str(tr->orig_request->req_uri, &tmp);
|
||||
if (tmp!=NULL)
|
||||
{
|
||||
snprintf(je->req_uri, 255, "%s", tmp);
|
||||
osip_free(tmp);
|
||||
}
|
||||
}
|
||||
if (tr!=NULL && tr->last_response!=NULL)
|
||||
{
|
||||
snprintf(je->reason_phrase, 49, "%s", tr->last_response->reason_phrase);
|
||||
je->status_code = tr->last_response->status_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return je;
|
||||
}
|
||||
|
||||
eXosip_event_t *
|
||||
eXosip_event_init_for_notify(int type,
|
||||
eXosip_notify_t *jn,
|
||||
eXosip_dialog_t *jd)
|
||||
{
|
||||
eXosip_event_t *je;
|
||||
eXosip_event_init(&je, type);
|
||||
if (je==NULL) return NULL;
|
||||
je->jn = jn;
|
||||
je->jd = jd;
|
||||
|
||||
je->nid = jn->n_id;
|
||||
if (jd!=NULL)
|
||||
je->did = jd->d_id;
|
||||
|
||||
je->ss_status = jn->n_ss_status;
|
||||
je->online_status = jn->n_online_status;
|
||||
je->ss_reason = jn->n_ss_reason;
|
||||
|
||||
/*je->external_reference = jc->external_reference; */
|
||||
|
||||
/* fill in usefull info */
|
||||
if (type==EXOSIP_IN_SUBSCRIPTION_NEW
|
||||
|| type==EXOSIP_IN_SUBSCRIPTION_RELEASED)
|
||||
{
|
||||
if (jd!=NULL&&jd->d_dialog!=NULL)
|
||||
{
|
||||
osip_transaction_t *tr;
|
||||
char *tmp;
|
||||
fill_dialog_params(je,jd->d_dialog);
|
||||
tr = eXosip_find_last_inc_subscribe(jn, jd);
|
||||
if (tr!=NULL && tr->orig_request!=NULL)
|
||||
{
|
||||
osip_uri_to_str(tr->orig_request->req_uri, &tmp);
|
||||
if (tmp!=NULL)
|
||||
{
|
||||
snprintf(je->req_uri, 255, "%s", tmp);
|
||||
osip_free(tmp);
|
||||
}
|
||||
}
|
||||
if (tr!=NULL && tr->last_response!=NULL)
|
||||
{
|
||||
snprintf(je->reason_phrase, 49, "%s", tr->last_response->reason_phrase);
|
||||
je->status_code = tr->last_response->status_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return je;
|
||||
}
|
||||
|
||||
eXosip_event_t *
|
||||
eXosip_event_init_for_reg(int type,
|
||||
eXosip_reg_t *jr)
|
||||
{
|
||||
eXosip_event_t *je;
|
||||
eXosip_event_init(&je, type);
|
||||
if (je==NULL) return NULL;
|
||||
je->jr = jr;
|
||||
je->rid = jr->r_id;
|
||||
snprintf(je->remote_uri, 255, "%s", jr->r_aor);
|
||||
snprintf(je->req_uri, 255, "%s", jr->r_registrar);
|
||||
return je;
|
||||
}
|
||||
|
||||
eXosip_event_t *
|
||||
eXosip_event_init_for_message(int type, osip_transaction_t *tr,
|
||||
osip_message_t *sip)
|
||||
{
|
||||
eXosip_event_t *je;
|
||||
eXosip_event_init(&je, type);
|
||||
if (je==NULL) return NULL;
|
||||
|
||||
/* fill in usefull info */
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
/* Request URI */
|
||||
|
||||
osip_uri_to_str(sip->req_uri, &tmp);
|
||||
if (tmp!=NULL)
|
||||
{
|
||||
snprintf(je->req_uri, 255, "%s", tmp);
|
||||
osip_free(tmp);
|
||||
}
|
||||
|
||||
/* FROM & TO */
|
||||
|
||||
|
||||
if (sip->from != NULL)
|
||||
{
|
||||
osip_from_to_str(sip->from, &tmp);
|
||||
if (tmp!=NULL)
|
||||
{
|
||||
snprintf(je->remote_uri, 255, "%s", tmp);
|
||||
osip_free(tmp);
|
||||
}
|
||||
}
|
||||
if (sip->to != NULL)
|
||||
{
|
||||
osip_to_to_str(sip->to, &tmp);
|
||||
if (tmp!=NULL)
|
||||
{
|
||||
snprintf(je->local_uri, 255, "%s", tmp);
|
||||
osip_free(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return je;
|
||||
}
|
||||
|
||||
int
|
||||
eXosip_event_init(eXosip_event_t **je, int type)
|
||||
{
|
||||
*je = (eXosip_event_t *) osip_malloc(sizeof(eXosip_event_t));
|
||||
if (*je==NULL) return -1;
|
||||
|
||||
memset(*je, 0, sizeof(eXosip_event_t));
|
||||
(*je)->type = type;
|
||||
|
||||
if (type==EXOSIP_CALL_NOANSWER)
|
||||
{
|
||||
sprintf((*je)->textinfo, "No answer for this Call!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_PROCEEDING)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Call is being processed!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_RINGING)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Remote phone is ringing!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_ANSWERED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Remote phone has answered!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_REDIRECTED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Call is redirected!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_REQUESTFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "4xx received for Call!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_SERVERFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "5xx received for Call!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_GLOBALFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "6xx received for Call!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_NEW)
|
||||
{
|
||||
sprintf((*je)->textinfo, "New call received!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_ACK)
|
||||
{
|
||||
sprintf((*je)->textinfo, "ACK received!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_CANCELLED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Call has been cancelled!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_TIMEOUT)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Timeout. Gived up!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_HOLD)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Call is on Hold!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_OFFHOLD)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Call is off Hold!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_CLOSED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Bye Received!");
|
||||
}
|
||||
else if (type==EXOSIP_CALL_RELEASED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Call Context is released!");
|
||||
}
|
||||
else if (type==EXOSIP_REGISTRATION_SUCCESS)
|
||||
{
|
||||
sprintf((*je)->textinfo, "User is successfully registred!");
|
||||
}
|
||||
else if (type==EXOSIP_REGISTRATION_FAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Registration failed!");
|
||||
}
|
||||
else if (type==EXOSIP_OPTIONS_NEW)
|
||||
{
|
||||
sprintf((*je)->textinfo, "New OPTIONS received!");
|
||||
}
|
||||
else if (type==EXOSIP_OPTIONS_NOANSWER)
|
||||
{
|
||||
sprintf((*je)->textinfo, "No answer for this OPTIONS!");
|
||||
}
|
||||
else if (type==EXOSIP_OPTIONS_PROCEEDING)
|
||||
{
|
||||
sprintf((*je)->textinfo, "OPTIONS is being processed!");
|
||||
}
|
||||
else if (type==EXOSIP_OPTIONS_ANSWERED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "2xx received for OPTIONS!");
|
||||
}
|
||||
else if (type==EXOSIP_OPTIONS_REDIRECTED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "3xx received for OPTIONS!");
|
||||
}
|
||||
else if (type==EXOSIP_OPTIONS_REQUESTFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "4xx received for OPTIONS!");
|
||||
}
|
||||
else if (type==EXOSIP_OPTIONS_SERVERFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "5xx received for OPTIONS!");
|
||||
}
|
||||
else if (type==EXOSIP_OPTIONS_GLOBALFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "5xx received for OPTIONS!");
|
||||
}
|
||||
else if (type==EXOSIP_INFO_NEW)
|
||||
{
|
||||
sprintf((*je)->textinfo, "New INFO received!");
|
||||
}
|
||||
else if (type==EXOSIP_INFO_NOANSWER)
|
||||
{
|
||||
sprintf((*je)->textinfo, "No answer for this INFO!");
|
||||
}
|
||||
else if (type==EXOSIP_INFO_PROCEEDING)
|
||||
{
|
||||
sprintf((*je)->textinfo, "INFO is being processed!");
|
||||
}
|
||||
else if (type==EXOSIP_INFO_ANSWERED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "2xx received for INFO!");
|
||||
}
|
||||
else if (type==EXOSIP_INFO_REDIRECTED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "3xx received for INFO!");
|
||||
}
|
||||
else if (type==EXOSIP_INFO_REQUESTFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "4xx received for INFO!");
|
||||
}
|
||||
else if (type==EXOSIP_INFO_SERVERFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "5xx received for INFO!");
|
||||
}
|
||||
else if (type==EXOSIP_INFO_GLOBALFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "6xx received for INFO!");
|
||||
}
|
||||
else if (type==EXOSIP_MESSAGE_NEW)
|
||||
{
|
||||
sprintf((*je)->textinfo, "New MESSAGE received!");
|
||||
}
|
||||
else if (type==EXOSIP_MESSAGE_SUCCESS)
|
||||
{
|
||||
sprintf((*je)->textinfo, "User has successfully received our MESSAGE!");
|
||||
}
|
||||
else if (type==EXOSIP_MESSAGE_FAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Error received for our MESSAGE!");
|
||||
}
|
||||
else if (type==EXOSIP_SUBSCRIPTION_NEW)
|
||||
{
|
||||
sprintf((*je)->textinfo, "New SUBSCRIBE received!");
|
||||
}
|
||||
else if (type==EXOSIP_SUBSCRIPTION_NOANSWER)
|
||||
{
|
||||
sprintf((*je)->textinfo, "No answer for this SUBSCRIBE!");
|
||||
}
|
||||
else if (type==EXOSIP_SUBSCRIPTION_PROCEEDING)
|
||||
{
|
||||
sprintf((*je)->textinfo, "SUBSCRIBE is being processed!");
|
||||
}
|
||||
else if (type==EXOSIP_SUBSCRIPTION_ANSWERED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "2xx received for SUBSCRIBE!");
|
||||
}
|
||||
else if (type==EXOSIP_SUBSCRIPTION_REDIRECTED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "3xx received for SUBSCRIBE!");
|
||||
}
|
||||
else if (type==EXOSIP_SUBSCRIPTION_REQUESTFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "4xx received for SUBSCRIBE!");
|
||||
}
|
||||
else if (type==EXOSIP_SUBSCRIPTION_SERVERFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "5xx received for SUBSCRIBE!");
|
||||
}
|
||||
else if (type==EXOSIP_SUBSCRIPTION_GLOBALFAILURE)
|
||||
{
|
||||
sprintf((*je)->textinfo, "5xx received for SUBSCRIBE!");
|
||||
}
|
||||
else if (type==EXOSIP_SUBSCRIPTION_NOTIFY)
|
||||
{
|
||||
sprintf((*je)->textinfo, "NOTIFY request for subscription!");
|
||||
}
|
||||
else if (type==EXOSIP_SUBSCRIPTION_RELEASED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Subscription has terminate!");
|
||||
}
|
||||
else if (type==EXOSIP_IN_SUBSCRIPTION_NEW)
|
||||
{
|
||||
sprintf((*je)->textinfo, "New incoming SUBSCRIBE!");
|
||||
}
|
||||
else if (type==EXOSIP_IN_SUBSCRIPTION_RELEASED)
|
||||
{
|
||||
sprintf((*je)->textinfo, "Incoming Subscription has terminate!");
|
||||
}
|
||||
else
|
||||
{
|
||||
(*je)->textinfo[0] = '\0';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
eXosip_event_free(eXosip_event_t *je)
|
||||
{
|
||||
if (je==NULL) return;
|
||||
if (je->i_ctt!=NULL)
|
||||
osip_content_type_free(je->i_ctt);
|
||||
if (je->i_bodies!=NULL)
|
||||
{
|
||||
int pos;
|
||||
for (pos=0;!osip_list_eol(je->i_bodies, pos);)
|
||||
{
|
||||
osip_body_t *body;
|
||||
body = (osip_body_t *)osip_list_get(je->i_bodies, pos);
|
||||
osip_list_remove(je->i_bodies, pos);
|
||||
osip_body_free(body);
|
||||
}
|
||||
}
|
||||
osip_free(je);
|
||||
}
|
||||
|
||||
eXosip_call_t *
|
||||
eXosip_event_get_callinfo(eXosip_event_t *je)
|
||||
{
|
||||
return je->jc;
|
||||
}
|
||||
|
||||
eXosip_dialog_t *
|
||||
eXosip_event_get_dialoginfo(eXosip_event_t *je)
|
||||
{
|
||||
return je->jd;
|
||||
}
|
||||
|
||||
eXosip_reg_t *
|
||||
eXosip_event_get_reginfo(eXosip_event_t *je)
|
||||
{
|
||||
return je->jr;
|
||||
}
|
||||
|
||||
eXosip_notify_t *
|
||||
eXosip_event_get_notifyinfo(eXosip_event_t *je)
|
||||
{
|
||||
return je->jn;
|
||||
}
|
||||
|
||||
eXosip_subscribe_t *
|
||||
eXosip_event_get_subscribeinfo(eXosip_event_t *je)
|
||||
{
|
||||
return je->js;
|
||||
}
|
||||
|
||||
int
|
||||
eXosip_event_add(eXosip_event_t *je)
|
||||
{
|
||||
int i = osip_fifo_add(eXosip.j_events, (void *) je);
|
||||
osip_cond_signal((struct osip_cond *)eXosip.j_cond);
|
||||
__eXosip_wakeup_event();
|
||||
return i;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef CLOCK_REALTIME
|
||||
/* if CLOCK_REALTIME exist, then clock_gettime should be defined */
|
||||
|
||||
#define OSIP_CLOCK_REALTIME CLOCK_REALTIME
|
||||
|
||||
void
|
||||
__eXosip_clock_gettime(clockid_t cid, struct timespec *time)
|
||||
{
|
||||
clock_gettime(cid, time);
|
||||
}
|
||||
|
||||
#elif defined (WIN32) || defined (_WIN32_WCE)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/timeb.h>
|
||||
|
||||
#define OSIP_CLOCK_REALTIME 4002
|
||||
|
||||
void
|
||||
__eXosip_clock_gettime(unsigned int clock_id, struct timespec *time)
|
||||
{
|
||||
struct _timeb time_val;
|
||||
|
||||
if (clock_id != OSIP_CLOCK_REALTIME)
|
||||
return;
|
||||
|
||||
_ftime (&time_val);
|
||||
time->tv_sec = time_val.time;
|
||||
time->tv_nsec = time_val.millitm * 1000000;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
eXosip_event_t *
|
||||
eXosip_event_wait(int tv_s, int tv_ms)
|
||||
{
|
||||
eXosip_event_t *je = NULL;
|
||||
|
||||
#if 0 /* this does not seems to work. by now */
|
||||
#if defined (CLOCK_REALTIME) || defined (WIN32) || defined (_WIN32_WCE)
|
||||
int i;
|
||||
|
||||
struct timespec deadline;
|
||||
struct timespec interval;
|
||||
long tot_ms = (tv_s*1000) + tv_ms;
|
||||
|
||||
static struct osip_mutex *mlock = NULL;
|
||||
|
||||
if (mlock==NULL) mlock = osip_mutex_init();
|
||||
|
||||
je = (eXosip_event_t *) osip_fifo_tryget(eXosip.j_events);
|
||||
if(je) return je;
|
||||
|
||||
interval.tv_sec = tot_ms / 1000;
|
||||
interval.tv_nsec = (tot_ms % 1000) * 1000000L;
|
||||
|
||||
__eXosip_clock_gettime(OSIP_CLOCK_REALTIME, &deadline);
|
||||
|
||||
if ((deadline.tv_nsec += interval.tv_nsec) >= 1000000000L)
|
||||
{
|
||||
deadline.tv_nsec -= 1000000000L;
|
||||
deadline.tv_sec += 1;
|
||||
}
|
||||
else
|
||||
deadline.tv_nsec += interval.tv_nsec;
|
||||
|
||||
deadline.tv_sec += interval.tv_sec;
|
||||
|
||||
i = osip_cond_timedwait ((struct osip_cond *)eXosip.j_cond,
|
||||
(struct osip_mutex *)mlock,
|
||||
&deadline);
|
||||
|
||||
#endif
|
||||
#else
|
||||
/* basic replacement */
|
||||
{
|
||||
fd_set fdset;
|
||||
struct timeval tv;
|
||||
int max, i;
|
||||
FD_ZERO(&fdset);
|
||||
#if defined (WIN32) || defined (_WIN32_WCE)
|
||||
FD_SET((unsigned int)jpipe_get_read_descr(eXosip.j_socketctl_event), &fdset);
|
||||
#else
|
||||
FD_SET(jpipe_get_read_descr(eXosip.j_socketctl_event), &fdset);
|
||||
#endif
|
||||
max = jpipe_get_read_descr(eXosip.j_socketctl_event);
|
||||
tv.tv_sec = tv_s;
|
||||
tv.tv_usec = tv_ms*1000;
|
||||
|
||||
je = (eXosip_event_t *) osip_fifo_tryget(eXosip.j_events);
|
||||
if (je!=NULL) return je;
|
||||
|
||||
if (tv_s==0 && tv_ms==0)
|
||||
return NULL;
|
||||
|
||||
i = select(max+1, &fdset, NULL, NULL, &tv);
|
||||
if (i <= 0)
|
||||
return 0;
|
||||
|
||||
if (FD_ISSET (jpipe_get_read_descr(eXosip.j_socketctl_event), &fdset))
|
||||
{
|
||||
char buf[500];
|
||||
jpipe_read (eXosip.j_socketctl_event, buf, 499);
|
||||
}
|
||||
|
||||
je = (eXosip_event_t *) osip_fifo_tryget(eXosip.j_events);
|
||||
if (je!=NULL) return je;
|
||||
}
|
||||
#endif
|
||||
|
||||
return je;
|
||||
}
|
||||
|
||||
eXosip_event_t *
|
||||
eXosip_event_get()
|
||||
{
|
||||
eXosip_event_t *je;
|
||||
je = (eXosip_event_t *) osip_fifo_get(eXosip.j_events);
|
||||
return je;
|
||||
}
|
||||
311
linphone/exosip/jfreinds.c
Normal file
311
linphone/exosip/jfreinds.c
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#include "eXosip2.h"
|
||||
#include <eXosip_cfg.h>
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
#ifndef EXOSIP_ETC_DIR
|
||||
#define EXOSIP_ETC_DIR ".eXosip"
|
||||
#endif
|
||||
|
||||
#ifndef EXOSIP_ADDFRIENDS_SH
|
||||
#define EXOSIP_ADDFRIENDS_SH "eXosip_addfriend.sh"
|
||||
#endif
|
||||
|
||||
|
||||
static int jfriend_init(jfriend_t **fr, char *ch)
|
||||
{
|
||||
char *next;
|
||||
int i;
|
||||
|
||||
*fr = (jfriend_t *)osip_malloc(sizeof(jfriend_t));
|
||||
if (*fr==NULL) return -1;
|
||||
|
||||
i = jfriend_get_and_set_next_token(&((*fr)->f_nick), ch, &next);
|
||||
if (i != 0)
|
||||
goto jf_error1;
|
||||
osip_clrspace ((*fr)->f_nick);
|
||||
ch = next;
|
||||
|
||||
i = jfriend_get_and_set_next_token(&((*fr)->f_home), next, &next);
|
||||
if (i != 0)
|
||||
goto jf_error2;
|
||||
osip_clrspace ((*fr)->f_home);
|
||||
ch = next;
|
||||
|
||||
i = jfriend_get_and_set_next_token(&((*fr)->f_work), ch, &next);
|
||||
if (i != 0)
|
||||
goto jf_error3;
|
||||
osip_clrspace ((*fr)->f_work);
|
||||
ch = next;
|
||||
|
||||
i = jfriend_get_and_set_next_token(&((*fr)->f_email), ch, &next);
|
||||
if (i != 0)
|
||||
goto jf_error4;
|
||||
osip_clrspace ((*fr)->f_email);
|
||||
|
||||
(*fr)->f_e164 = osip_strdup(next);
|
||||
osip_clrspace ((*fr)->f_e164);
|
||||
|
||||
return 0;
|
||||
|
||||
jf_error4:
|
||||
osip_free((*fr)->f_work);
|
||||
jf_error3:
|
||||
osip_free((*fr)->f_home);
|
||||
jf_error2:
|
||||
osip_free((*fr)->f_nick);
|
||||
jf_error1:
|
||||
osip_free(*fr);
|
||||
*fr = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
jfriend_get_and_set_next_token (char **dest, char *buf, char **next)
|
||||
{
|
||||
char *end;
|
||||
char *start;
|
||||
|
||||
*next = NULL;
|
||||
|
||||
/* find first non space and tab element */
|
||||
start = buf;
|
||||
while (((*start == ' ') || (*start == '\t')) && (*start != '\0')
|
||||
&& (*start != '\r') && (*start != '\n') )
|
||||
start++;
|
||||
end = start+1;
|
||||
while ((*end != '\0') && (*end != '\r') && (*end != '\n')
|
||||
&& (*end != '\t') && (*end != '|'))
|
||||
end++;
|
||||
|
||||
if ((*end == '\r') || (*end == '\n'))
|
||||
/* we should continue normally only if this is the separator asked! */
|
||||
return -1;
|
||||
if (end == start)
|
||||
return -1; /* empty value (or several space!) */
|
||||
|
||||
*dest = osip_malloc (end - (start) + 1);
|
||||
osip_strncpy (*dest, start, end - start);
|
||||
|
||||
*next = end + 1; /* return the position right after the separator
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __jfriend_remove(char *nickname, char *home)
|
||||
{
|
||||
char *Home;
|
||||
char command[256];
|
||||
char *tmp = command;
|
||||
int length = 0;
|
||||
if (nickname!=NULL)
|
||||
length = strlen(nickname);
|
||||
|
||||
Home = getenv("HOME");
|
||||
if (Home==NULL)
|
||||
return;
|
||||
length = length + strlen(Home);
|
||||
osip_clrspace(nickname);
|
||||
osip_clrspace(home);
|
||||
|
||||
if (home!=NULL)
|
||||
length = length + strlen(home);
|
||||
else
|
||||
return; /* MUST be set */
|
||||
length = length + strlen(EXOSIP_ETC_DIR);
|
||||
|
||||
length = length + strlen("/jm_contact");
|
||||
if (length>235) /* leave some room for SPACEs and \r\n */
|
||||
return ;
|
||||
|
||||
sprintf(tmp , "%s %s/%s/jm_contact", EXOSIP_ADDFRIENDS_SH,
|
||||
Home, EXOSIP_ETC_DIR);
|
||||
|
||||
tmp = tmp + strlen(tmp);
|
||||
if (nickname!=NULL)
|
||||
sprintf(tmp , " %s", nickname);
|
||||
else
|
||||
sprintf(tmp , " \"\"");
|
||||
|
||||
tmp = tmp + strlen(tmp);
|
||||
if (home!=NULL)
|
||||
sprintf(tmp , " %s", home);
|
||||
else
|
||||
sprintf(tmp , " \"\"");
|
||||
|
||||
sprintf(tmp , "delete");
|
||||
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"%s", command));
|
||||
system(command);
|
||||
}
|
||||
|
||||
void jfriend_add(char *nickname, char *home,
|
||||
char *work, char *email, char *e164)
|
||||
{
|
||||
char *Home;
|
||||
char command[256];
|
||||
char *tmp = command;
|
||||
int length = 0;
|
||||
if (nickname!=NULL)
|
||||
length = strlen(nickname);
|
||||
|
||||
Home = getenv("HOME");
|
||||
if (Home==NULL)
|
||||
return;
|
||||
length = length + strlen(Home);
|
||||
|
||||
osip_clrspace(nickname);
|
||||
osip_clrspace(home);
|
||||
osip_clrspace(work);
|
||||
osip_clrspace(email);
|
||||
osip_clrspace(e164);
|
||||
|
||||
if (home!=NULL)
|
||||
length = length + strlen(home);
|
||||
else
|
||||
return; /* MUST be set */
|
||||
if (work!=NULL)
|
||||
length = length + strlen(work);
|
||||
if (email!=NULL)
|
||||
length = length + strlen(email);
|
||||
if (e164!=NULL)
|
||||
length = length + strlen(e164);
|
||||
length = length + strlen(EXOSIP_ETC_DIR);
|
||||
|
||||
length = length + strlen("/jm_contact");
|
||||
if (length>235) /* leave some room for SPACEs and \r\n */
|
||||
return ;
|
||||
|
||||
sprintf(tmp , "%s %s/%s/jm_contact", EXOSIP_ADDFRIENDS_SH,
|
||||
Home, EXOSIP_ETC_DIR);
|
||||
|
||||
tmp = tmp + strlen(tmp);
|
||||
if (nickname!=NULL)
|
||||
sprintf(tmp , " %s", nickname);
|
||||
else
|
||||
sprintf(tmp , " \"\"");
|
||||
|
||||
tmp = tmp + strlen(tmp);
|
||||
if (home!=NULL)
|
||||
sprintf(tmp , " %s", home);
|
||||
else
|
||||
sprintf(tmp , " \"\"");
|
||||
|
||||
tmp = tmp + strlen(tmp);
|
||||
if (work!=NULL)
|
||||
sprintf(tmp , " %s", work);
|
||||
else
|
||||
sprintf(tmp , " \"\"");
|
||||
|
||||
tmp = tmp + strlen(tmp);
|
||||
if (email!=NULL)
|
||||
sprintf(tmp , " %s", email);
|
||||
else
|
||||
sprintf(tmp , " \"\"");
|
||||
|
||||
tmp = tmp + strlen(tmp);
|
||||
if (e164!=NULL)
|
||||
sprintf(tmp , " %s", e164);
|
||||
else
|
||||
sprintf(tmp , " \"\"");
|
||||
|
||||
/* fprintf(stderr, "%s", command); */
|
||||
system(command);
|
||||
}
|
||||
|
||||
void
|
||||
jfriend_unload()
|
||||
{
|
||||
jfriend_t *fr;
|
||||
if (eXosip.j_friends==NULL) return;
|
||||
for (fr=eXosip.j_friends; fr!=NULL; fr=eXosip.j_friends)
|
||||
{
|
||||
REMOVE_ELEMENT(eXosip.j_friends,fr);
|
||||
osip_free(fr->f_nick);
|
||||
osip_free(fr->f_home);
|
||||
osip_free(fr->f_work);
|
||||
osip_free(fr->f_email);
|
||||
osip_free(fr->f_e164);
|
||||
osip_free(fr);
|
||||
}
|
||||
|
||||
osip_free(eXosip.j_friends);
|
||||
eXosip.j_friends=NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
jfriend_load()
|
||||
{
|
||||
FILE *file;
|
||||
char *s;
|
||||
jfriend_t *fr;
|
||||
int pos;
|
||||
char *home;
|
||||
char filename[255];
|
||||
|
||||
jfriend_unload();
|
||||
home = getenv("HOME");
|
||||
sprintf(filename, "%s/%s/%s", home, EXOSIP_ETC_DIR, "jm_contact");
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (file==NULL) return -1;
|
||||
s = (char *)osip_malloc(255*sizeof(char));
|
||||
pos = 0;
|
||||
while (NULL!=fgets(s, 254, file))
|
||||
{
|
||||
char *tmp = s;
|
||||
while (*tmp!='\0' && *tmp!=' ') tmp++;
|
||||
while (*tmp!='\0' && *tmp==' ') tmp++;
|
||||
while (*tmp!='\0' && *tmp!=' ') tmp++;
|
||||
tmp++; /* first usefull characters */
|
||||
pos++;
|
||||
|
||||
jfriend_init(&fr, tmp);
|
||||
if (fr!=NULL)
|
||||
{ ADD_ELEMENT(eXosip.j_friends, fr); }
|
||||
}
|
||||
osip_free(s);
|
||||
fclose(file);
|
||||
|
||||
return 0; /* ok */
|
||||
}
|
||||
|
||||
char *
|
||||
jfriend_get_home(int fid)
|
||||
{
|
||||
jfriend_t *fr;
|
||||
for (fr = eXosip.j_friends; fr!=NULL ; fr=fr->next)
|
||||
{
|
||||
if (fid==0)
|
||||
return osip_strdup(fr->f_home);
|
||||
fid--;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
277
linphone/exosip/jidentity.c
Normal file
277
linphone/exosip/jidentity.c
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#include "eXosip2.h"
|
||||
#include <eXosip_cfg.h>
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
#ifndef EXOSIP_ETC_DIR
|
||||
#define EXOSIP_ETC_DIR ".eXosip"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef EXOSIP_ADDIDENTITYS_SH
|
||||
#define EXOSIP_ADDIDENTITYS_SH "eXosip_addidentity.sh"
|
||||
#endif
|
||||
|
||||
static int
|
||||
jidentity_get_and_set_next_token (char **dest, char *buf, char **next)
|
||||
{
|
||||
char *end;
|
||||
char *start;
|
||||
|
||||
*next = NULL;
|
||||
|
||||
/* find first non space and tab element */
|
||||
start = buf;
|
||||
while (((*start == ' ') || (*start == '\t')) && (*start != '\0')
|
||||
&& (*start != '\r') && (*start != '\n') )
|
||||
start++;
|
||||
end = start+1;
|
||||
while ((*end != '\0') && (*end != '\r') && (*end != '\n')
|
||||
&& (*end != '\t') && (*end != '|'))
|
||||
end++;
|
||||
|
||||
if ((*end == '\r') || (*end == '\n'))
|
||||
/* we should continue normally only if this is the separator asked! */
|
||||
return -1;
|
||||
if (end == start)
|
||||
return -1; /* empty value (or several space!) */
|
||||
|
||||
*dest = osip_malloc (end - (start) + 1);
|
||||
osip_strncpy (*dest, start, end - start);
|
||||
|
||||
*next = end + 1; /* return the position right after the separator
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jidentity_init(jidentity_t **fr, char *ch)
|
||||
{
|
||||
char *next;
|
||||
int i;
|
||||
|
||||
*fr = (jidentity_t *)osip_malloc(sizeof(jidentity_t));
|
||||
if (*fr==NULL) return -1;
|
||||
|
||||
i = jidentity_get_and_set_next_token(&((*fr)->i_identity), ch, &next);
|
||||
if (i != 0)
|
||||
goto ji_error1;
|
||||
osip_clrspace ((*fr)->i_identity);
|
||||
ch = next;
|
||||
|
||||
i = jidentity_get_and_set_next_token(&((*fr)->i_registrar), next, &next);
|
||||
if (i != 0)
|
||||
goto ji_error2;
|
||||
osip_clrspace ((*fr)->i_registrar);
|
||||
ch = next;
|
||||
|
||||
i = jidentity_get_and_set_next_token(&((*fr)->i_realm), ch, &next);
|
||||
if (i != 0)
|
||||
goto ji_error3;
|
||||
osip_clrspace ((*fr)->i_realm);
|
||||
ch = next;
|
||||
|
||||
i = jidentity_get_and_set_next_token(&((*fr)->i_userid), ch, &next);
|
||||
if (i != 0)
|
||||
goto ji_error4;
|
||||
osip_clrspace ((*fr)->i_userid);
|
||||
|
||||
(*fr)->i_pwd = osip_strdup(next);
|
||||
osip_clrspace ((*fr)->i_pwd);
|
||||
|
||||
if ((*fr)->i_pwd!=NULL && (*fr)->i_pwd[0]!='\0')
|
||||
{
|
||||
eXosip_add_authentication_info((*fr)->i_userid, (*fr)->i_userid,
|
||||
(*fr)->i_pwd, NULL,
|
||||
(*fr)->i_realm);
|
||||
}
|
||||
return 0;
|
||||
|
||||
ji_error4:
|
||||
osip_free((*fr)->i_realm);
|
||||
ji_error3:
|
||||
osip_free((*fr)->i_registrar);
|
||||
ji_error2:
|
||||
osip_free((*fr)->i_identity);
|
||||
ji_error1:
|
||||
osip_free(*fr);
|
||||
*fr = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void identitys_add(char *identity, char *registrar,
|
||||
char *realm, char *userid, char *pwd)
|
||||
{
|
||||
char command[256];
|
||||
char *tmp = command;
|
||||
char *home;
|
||||
|
||||
int length = 0;
|
||||
if (identity==NULL)
|
||||
return ;
|
||||
if (registrar==NULL)
|
||||
return ;
|
||||
|
||||
if (realm!=NULL && *realm=='\0')
|
||||
realm = NULL;
|
||||
if (userid!=NULL && *userid=='\0')
|
||||
userid = NULL;
|
||||
if (pwd!=NULL && *pwd=='\0')
|
||||
pwd = NULL;
|
||||
|
||||
length = strlen(identity) +3;
|
||||
length = length + strlen(registrar) +3;
|
||||
|
||||
if (realm!=NULL && userid!=NULL && pwd!=NULL)
|
||||
{
|
||||
length = length + strlen(realm) +3;
|
||||
length = length + strlen(userid) +3;
|
||||
length = length + strlen(pwd) +3;
|
||||
}
|
||||
else if (realm==NULL && userid==NULL && pwd==NULL)
|
||||
{}
|
||||
else
|
||||
return ;
|
||||
|
||||
home = getenv("HOME");
|
||||
length = length + strlen(home);
|
||||
length = length + strlen(EXOSIP_ETC_DIR) + 3;
|
||||
length = length + strlen("/jm_identity") + 1;
|
||||
|
||||
if (length>235) /* leave some room for SPACEs and \r\n */
|
||||
return ;
|
||||
|
||||
sprintf(tmp , "%s \"%s/%s/jm_identity\"", EXOSIP_ADDIDENTITYS_SH,
|
||||
home, EXOSIP_ETC_DIR);
|
||||
tmp = tmp + strlen(tmp);
|
||||
sprintf(tmp , " \"%s\"", identity);
|
||||
tmp = tmp + strlen(tmp);
|
||||
sprintf(tmp , " \"%s\"", registrar);
|
||||
tmp = tmp + strlen(tmp);
|
||||
|
||||
if (realm!=NULL && userid!=NULL && pwd!=NULL)
|
||||
{
|
||||
sprintf(tmp , " \"%s\"", realm);
|
||||
tmp = tmp + strlen(tmp);
|
||||
sprintf(tmp , " \"%s\"", userid);
|
||||
tmp = tmp + strlen(tmp);
|
||||
sprintf(tmp , " \"%s\"", pwd);
|
||||
}
|
||||
else if (realm==NULL && userid==NULL && pwd==NULL)
|
||||
{
|
||||
sprintf(tmp , " \"\"");
|
||||
tmp = tmp + strlen(tmp);
|
||||
sprintf(tmp , " \"\"");
|
||||
tmp = tmp + strlen(tmp);
|
||||
sprintf(tmp , " \"\"");
|
||||
}
|
||||
|
||||
system(command);
|
||||
}
|
||||
|
||||
void
|
||||
jidentity_unload()
|
||||
{
|
||||
jidentity_t *fr;
|
||||
if (eXosip.j_identitys==NULL) return;
|
||||
for (fr=eXosip.j_identitys; fr!=NULL; fr=eXosip.j_identitys)
|
||||
{
|
||||
REMOVE_ELEMENT(eXosip.j_identitys,fr);
|
||||
osip_free(fr->i_identity);
|
||||
osip_free(fr->i_registrar);
|
||||
osip_free(fr->i_realm);
|
||||
osip_free(fr->i_userid);
|
||||
osip_free(fr->i_pwd);
|
||||
osip_free(fr);
|
||||
}
|
||||
|
||||
osip_free(eXosip.j_identitys);
|
||||
eXosip.j_identitys=NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
jidentity_load()
|
||||
{
|
||||
FILE *file;
|
||||
char *s;
|
||||
jidentity_t *fr;
|
||||
int pos;
|
||||
char *home;
|
||||
char filename[255];
|
||||
jidentity_unload();
|
||||
|
||||
home = getenv("HOME");
|
||||
sprintf(filename, "%s/%s/%s", home, EXOSIP_ETC_DIR, "jm_identity");
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (file==NULL) return -1;
|
||||
s = (char *)osip_malloc(255*sizeof(char));
|
||||
pos = 0;
|
||||
while (NULL!=fgets(s, 254, file))
|
||||
{
|
||||
char *tmp = s;
|
||||
while (*tmp!='\0' && *tmp!=' ') tmp++;
|
||||
while (*tmp!='\0' && *tmp==' ') tmp++;
|
||||
while (*tmp!='\0' && *tmp!=' ') tmp++;
|
||||
tmp++; /* first usefull characters */
|
||||
pos++;
|
||||
|
||||
jidentity_init(&fr, tmp);
|
||||
if (fr!=NULL)
|
||||
{ ADD_ELEMENT(eXosip.j_identitys, fr); }
|
||||
}
|
||||
osip_free(s);
|
||||
fclose(file);
|
||||
|
||||
return 0; /* ok */
|
||||
}
|
||||
|
||||
char *
|
||||
jidentity_get_registrar(int fid)
|
||||
{
|
||||
jidentity_t *fr;
|
||||
for (fr = eXosip.j_identitys; fr!=NULL ; fr=fr->next)
|
||||
{
|
||||
if (fid==0)
|
||||
return osip_strdup(fr->i_registrar);
|
||||
fid--;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
jidentity_get_identity(int fid)
|
||||
{
|
||||
jidentity_t *fr;
|
||||
for (fr = eXosip.j_identitys; fr!=NULL ; fr=fr->next)
|
||||
{
|
||||
if (fid==0)
|
||||
return osip_strdup(fr->i_identity);
|
||||
fid--;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
528
linphone/exosip/jnotify.c
Normal file
528
linphone/exosip/jnotify.c
Normal file
|
|
@ -0,0 +1,528 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "eXosip2.h"
|
||||
#include <eXosip_cfg.h>
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
#if 0
|
||||
int eXosip_notify_find(int sid, eXosip_notify_t **jn)
|
||||
{
|
||||
for (*jn=eXosip.j_notifies; *jn!=NULL; *jn=(*jn)->next)
|
||||
{
|
||||
if ((*jn)->n_id==sid)
|
||||
return 0;
|
||||
}
|
||||
*jn = NULL;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_inc_subscribe(eXosip_notify_t *jn, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
int pos;
|
||||
inc_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_inc_trs, pos))
|
||||
{
|
||||
inc_tr = osip_list_get(jd->d_inc_trs, pos);
|
||||
if (0==strcmp(inc_tr->cseq->method, "SUBSCRIBE"))
|
||||
break;
|
||||
else inc_tr = NULL;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
else
|
||||
inc_tr = NULL;
|
||||
|
||||
if (inc_tr==NULL)
|
||||
return jn->n_inc_tr; /* can be NULL */
|
||||
|
||||
return inc_tr;
|
||||
}
|
||||
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_out_notify(eXosip_notify_t *jn, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *out_tr;
|
||||
int pos;
|
||||
out_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_out_trs, pos))
|
||||
{
|
||||
out_tr = osip_list_get(jd->d_out_trs, pos);
|
||||
if (0==strcmp(out_tr->cseq->method, "NOTIFY"))
|
||||
return out_tr;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
eXosip_notify_init(eXosip_notify_t **jn, osip_message_t *inc_subscribe)
|
||||
{
|
||||
osip_contact_t *co;
|
||||
char *uri;
|
||||
int i;
|
||||
#ifdef SM
|
||||
char *locip;
|
||||
eXosip_get_localip_from_via(inc_subscribe,&locip);
|
||||
#else
|
||||
char locip[50];
|
||||
eXosip_guess_ip_for_via(eXosip.ip_family, locip, 49);
|
||||
#endif
|
||||
if (inc_subscribe==NULL
|
||||
||inc_subscribe->to==NULL
|
||||
||inc_subscribe->to->url==NULL)
|
||||
return -1;
|
||||
co = (osip_contact_t *) osip_list_get(inc_subscribe->contacts, 0);
|
||||
if (co==NULL || co->url==NULL)
|
||||
return -1;
|
||||
|
||||
*jn = (eXosip_notify_t *)osip_malloc(sizeof(eXosip_notify_t));
|
||||
if (*jn == NULL) return -1;
|
||||
memset(*jn, 0, sizeof(eXosip_notify_t));
|
||||
|
||||
i = osip_uri_to_str(co->url, &uri);
|
||||
if (i!=0)
|
||||
{
|
||||
osip_free(*jn);
|
||||
*jn=NULL;
|
||||
return -1;
|
||||
}
|
||||
osip_strncpy((*jn)->n_uri, uri, 254);
|
||||
osip_free(uri);
|
||||
|
||||
if (inc_subscribe->to->url->username!=NULL)
|
||||
{
|
||||
/* SM: allocate a string instead of risking a buffer overflow */
|
||||
if (eXosip.localport==NULL)
|
||||
(*jn)->n_contact_info=strdup_printf("sip:%s@%s",
|
||||
inc_subscribe->to->url->username,
|
||||
locip);
|
||||
else
|
||||
(*jn)->n_contact_info= strdup_printf("sip:%s@%s:%s",
|
||||
inc_subscribe->to->url->username,
|
||||
locip, eXosip.localport);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (eXosip.localport==NULL)
|
||||
(*jn)->n_contact_info=strdup_printf("sip:%s", locip);
|
||||
else
|
||||
(*jn)->n_contact_info=strdup_printf("sip:%s:%s", locip,
|
||||
eXosip.localport);
|
||||
}
|
||||
|
||||
#ifdef SM
|
||||
osip_free(locip);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
__eXosip_notify_remove_dialog_reference_in_notify(eXosip_notify_t *jn, eXosip_dialog_t *jd)
|
||||
{
|
||||
eXosip_dialog_t *_jd;
|
||||
jinfo_t *ji;
|
||||
if (jn==NULL) return;
|
||||
if (jd==NULL) return;
|
||||
|
||||
for (_jd = jn->n_dialogs; _jd!=NULL; _jd=jn->n_dialogs)
|
||||
{
|
||||
if (jd==_jd)
|
||||
break;
|
||||
}
|
||||
if (_jd==NULL)
|
||||
{
|
||||
/* dialog not found??? */
|
||||
}
|
||||
|
||||
ji = osip_transaction_get_your_instance(jn->n_inc_tr);
|
||||
if (ji!=NULL && ji->jd==jd)
|
||||
ji->jd=NULL;
|
||||
ji = osip_transaction_get_your_instance(jn->n_out_tr);
|
||||
if (ji!=NULL && ji->jd==jd)
|
||||
ji->jd=NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
eXosip_notify_free(eXosip_notify_t *jn)
|
||||
{
|
||||
/* ... */
|
||||
|
||||
eXosip_dialog_t *jd;
|
||||
|
||||
for (jd = jn->n_dialogs; jd!=NULL; jd=jn->n_dialogs)
|
||||
{
|
||||
REMOVE_ELEMENT(jn->n_dialogs, jd);
|
||||
eXosip_dialog_free(jd);
|
||||
}
|
||||
|
||||
__eXosip_delete_jinfo(jn->n_inc_tr);
|
||||
__eXosip_delete_jinfo(jn->n_out_tr);
|
||||
if (jn->n_inc_tr!=NULL)
|
||||
osip_list_add(eXosip.j_transactions, jn->n_inc_tr, 0);
|
||||
if (jn->n_out_tr!=NULL)
|
||||
osip_list_add(eXosip.j_transactions, jn->n_out_tr, 0);
|
||||
if (jn->n_contact_info!=NULL) osip_free(jn->n_contact_info);
|
||||
osip_free(jn);
|
||||
}
|
||||
|
||||
int
|
||||
_eXosip_notify_set_refresh_interval(eXosip_notify_t *jn,
|
||||
osip_message_t *inc_subscribe)
|
||||
{
|
||||
osip_header_t *exp;
|
||||
int now;
|
||||
now = time(NULL);
|
||||
if (jn==NULL || inc_subscribe==NULL)
|
||||
return -1;
|
||||
|
||||
osip_message_get_expires(inc_subscribe, 0, &exp);
|
||||
if (exp==NULL || exp->hvalue==NULL)
|
||||
jn->n_ss_expires = now + 600;
|
||||
else
|
||||
{
|
||||
jn->n_ss_expires = osip_atoi(exp->hvalue);
|
||||
if (jn->n_ss_expires!=-1)
|
||||
jn->n_ss_expires = now + jn->n_ss_expires;
|
||||
else /* on error, set it to default */
|
||||
jn->n_ss_expires = now + 600;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eXosip_notify_add_allowed_subscriber(char *sip_url)
|
||||
{
|
||||
/* TODO */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
_eXosip_notify_is_a_known_subscriber(osip_message_t *sip)
|
||||
{
|
||||
/* */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_eXosip_notify_add_body(eXosip_notify_t *jn, osip_message_t *notify)
|
||||
{
|
||||
char buf[1000];
|
||||
#ifdef SUPPORT_MSN
|
||||
int atom_id = 1000;
|
||||
#endif
|
||||
if (jn->n_ss_status!=EXOSIP_SUBCRSTATE_ACTIVE
|
||||
|| jn->n_contact_info==NULL || jn->n_contact_info=='\0') /* mandatory! */
|
||||
return 0; /* don't need a body? */
|
||||
|
||||
#ifdef SUPPORT_MSN
|
||||
|
||||
if (jn->n_online_status==EXOSIP_NOTIFY_ONLINE)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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=\"open\" />\n\
|
||||
<msnsubstatus substatus=\"online\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", jn->n_contact_info, atom_id, jn->n_contact_info);
|
||||
|
||||
}
|
||||
else if (jn->n_online_status==EXOSIP_NOTIFY_BUSY)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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=\"inuse\" />\n\
|
||||
<msnsubstatus substatus=\"busy\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", jn->n_contact_info, atom_id, jn->n_contact_info);
|
||||
|
||||
}
|
||||
else if (jn->n_online_status==EXOSIP_NOTIFY_BERIGHTBACK)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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\
|
||||
<msnsubstatus substatus=\"berightback\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", jn->n_contact_info, atom_id, jn->n_contact_info);
|
||||
|
||||
}
|
||||
else if (jn->n_online_status==EXOSIP_NOTIFY_AWAY)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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\
|
||||
<msnsubstatus substatus=\"away\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", jn->n_contact_info, atom_id, jn->n_contact_info);
|
||||
|
||||
}
|
||||
else if (jn->n_online_status==EXOSIP_NOTIFY_ONTHEPHONE)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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=\"inuse\" />\n\
|
||||
<msnsubstatus substatus=\"onthephone\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", jn->n_contact_info, atom_id, jn->n_contact_info);
|
||||
|
||||
}
|
||||
else if (jn->n_online_status==EXOSIP_NOTIFY_OUTTOLUNCH)
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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\
|
||||
<msnsubstatus substatus=\"outtolunch\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", jn->n_contact_info, atom_id, jn->n_contact_info);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf, "<?xml version=\"1.0\"?>\n\
|
||||
<!DOCTYPE presence\n\
|
||||
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\
|
||||
<msnsubstatus substatus=\"away\" />\n\
|
||||
</address>\n\
|
||||
</atom>\n\
|
||||
</presence>", jn->n_contact_info, atom_id, jn->n_contact_info);
|
||||
}
|
||||
|
||||
osip_message_set_body(notify, buf, strlen(buf));
|
||||
osip_message_set_content_type(notify, "application/xpidf+xml");
|
||||
#else
|
||||
|
||||
if (jn->n_online_status==EXOSIP_NOTIFY_ONLINE)
|
||||
{
|
||||
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>",
|
||||
jn->n_contact_info, jn->n_contact_info);
|
||||
}
|
||||
else if (jn->n_online_status==EXOSIP_NOTIFY_BUSY)
|
||||
{
|
||||
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>",
|
||||
jn->n_contact_info, jn->n_contact_info);
|
||||
}
|
||||
else if (jn->n_online_status==EXOSIP_NOTIFY_BERIGHTBACK)
|
||||
{
|
||||
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>",
|
||||
jn->n_contact_info, jn->n_contact_info);
|
||||
}
|
||||
else if (jn->n_online_status==EXOSIP_NOTIFY_AWAY)
|
||||
{
|
||||
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>",
|
||||
jn->n_contact_info, jn->n_contact_info);
|
||||
}
|
||||
else if (jn->n_online_status==EXOSIP_NOTIFY_ONTHEPHONE)
|
||||
{
|
||||
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>",
|
||||
jn->n_contact_info, jn->n_contact_info);
|
||||
}
|
||||
else if (jn->n_online_status==EXOSIP_NOTIFY_OUTTOLUNCH)
|
||||
{
|
||||
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>",
|
||||
jn->n_contact_info, jn->n_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",
|
||||
jn->n_contact_info,
|
||||
"<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");
|
||||
}
|
||||
osip_message_set_body(notify, buf, strlen(buf));
|
||||
osip_message_set_content_type(notify, "application/pidf+xml");
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_eXosip_notify_add_expires_in_2XX_for_subscribe(eXosip_notify_t *jn, osip_message_t *answer)
|
||||
{
|
||||
char tmp[20];
|
||||
int now;
|
||||
now = time(NULL);
|
||||
|
||||
if (jn->n_ss_expires-now<0)
|
||||
{
|
||||
tmp[0] = '0';
|
||||
tmp[1] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(tmp, "%i", jn->n_ss_expires-now);
|
||||
}
|
||||
osip_message_set_expires(answer, tmp);
|
||||
}
|
||||
221
linphone/exosip/jpipe.c
Normal file
221
linphone/exosip/jpipe.c
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#include "jpipe.h"
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
jpipe_t * jpipe ()
|
||||
{
|
||||
jpipe_t *my_pipe = (jpipe_t *) osip_malloc (sizeof (jpipe_t));
|
||||
if (my_pipe==NULL) return NULL;
|
||||
|
||||
if (0 != pipe (my_pipe->pipes))
|
||||
{
|
||||
osip_free (my_pipe);
|
||||
return NULL;
|
||||
}
|
||||
return my_pipe;
|
||||
}
|
||||
|
||||
int jpipe_close (jpipe_t * apipe)
|
||||
{
|
||||
if (apipe == NULL)
|
||||
return -1;
|
||||
close (apipe->pipes[0]);
|
||||
close (apipe->pipes[1]);
|
||||
osip_free (apipe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write in a pipe.
|
||||
*/
|
||||
int
|
||||
jpipe_write (jpipe_t * apipe, const void *buf, int count)
|
||||
{
|
||||
if (apipe == NULL)
|
||||
return -1;
|
||||
return write (apipe->pipes[1], buf, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read in a pipe.
|
||||
*/
|
||||
int jpipe_read (jpipe_t * apipe, void *buf, int count)
|
||||
{
|
||||
if (apipe == NULL)
|
||||
return -1;
|
||||
return read (apipe->pipes[0], buf, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get descriptor of reading pipe.
|
||||
*/
|
||||
int jpipe_get_read_descr (jpipe_t * apipe)
|
||||
{
|
||||
if (apipe == NULL)
|
||||
return -1;
|
||||
return apipe->pipes[0];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
jpipe_t * jpipe ()
|
||||
{
|
||||
int s = 0;
|
||||
int timeout = 0;
|
||||
static int aport = 10500;
|
||||
struct sockaddr_in raddr;
|
||||
int j;
|
||||
|
||||
jpipe_t *my_pipe = (jpipe_t *) osip_malloc (sizeof (jpipe_t));
|
||||
if (my_pipe==NULL)
|
||||
return NULL;
|
||||
|
||||
s = (int) socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (0 > s)
|
||||
{
|
||||
osip_free (my_pipe);
|
||||
return NULL;
|
||||
}
|
||||
my_pipe->pipes[1] = (int) socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (0 > my_pipe->pipes[1])
|
||||
{
|
||||
closesocket(s);
|
||||
osip_free (my_pipe);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
raddr.sin_addr.s_addr = inet_addr ("127.0.0.1");
|
||||
raddr.sin_family = AF_INET;
|
||||
|
||||
j = 50;
|
||||
while (aport++ && j-- > 0)
|
||||
{
|
||||
raddr.sin_port = htons ((short) aport);
|
||||
if (bind (s, (struct sockaddr *) &raddr, sizeof (raddr)) < 0)
|
||||
{
|
||||
OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL,
|
||||
"Failed to bind one local socket %i!\n",
|
||||
aport));
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == 0)
|
||||
{
|
||||
OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"Failed to bind a local socket, aborting!\n"));
|
||||
closesocket (s);
|
||||
closesocket (my_pipe->pipes[1]);
|
||||
osip_free (my_pipe);
|
||||
}
|
||||
|
||||
j = listen(s,1);
|
||||
if (j != 0)
|
||||
{
|
||||
OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"Failed to listen on a local socket, aborting!\n"));
|
||||
closesocket(s);
|
||||
closesocket(my_pipe->pipes[1]);
|
||||
osip_free (my_pipe);
|
||||
}
|
||||
|
||||
j = setsockopt (my_pipe->pipes[1],
|
||||
SOL_SOCKET,
|
||||
SO_RCVTIMEO, (const char*) &timeout, sizeof (timeout));
|
||||
if (j != NO_ERROR)
|
||||
{
|
||||
/* failed for some reason... */
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"udp plugin; cannot set O_NONBLOCK to the file desciptor!\n"));
|
||||
closesocket(s);
|
||||
closesocket(my_pipe->pipes[1]);
|
||||
osip_free (my_pipe);
|
||||
}
|
||||
|
||||
connect (my_pipe->pipes[1], (struct sockaddr *) &raddr, sizeof (raddr));
|
||||
|
||||
my_pipe->pipes[0] = accept (s, NULL, NULL);
|
||||
|
||||
if (my_pipe->pipes[0]<=0)
|
||||
{
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_ERROR, NULL,
|
||||
"udp plugin; Failed to call accept!\n"));
|
||||
closesocket(s);
|
||||
closesocket(my_pipe->pipes[1]);
|
||||
osip_free (my_pipe);
|
||||
}
|
||||
|
||||
return my_pipe;
|
||||
}
|
||||
|
||||
int jpipe_close (jpipe_t * apipe)
|
||||
{
|
||||
if (apipe == NULL)
|
||||
return -1;
|
||||
closesocket (apipe->pipes[0]);
|
||||
closesocket (apipe->pipes[1]);
|
||||
osip_free (apipe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write in a pipe.
|
||||
*/
|
||||
int
|
||||
jpipe_write (jpipe_t * apipe, const void *buf, int count)
|
||||
{
|
||||
if (apipe == NULL)
|
||||
return -1;
|
||||
return send (apipe->pipes[1], buf, count, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read in a pipe.
|
||||
*/
|
||||
int jpipe_read (jpipe_t * apipe, void *buf, int count)
|
||||
{
|
||||
if (apipe == NULL)
|
||||
return -1;
|
||||
return recv (apipe->pipes[0], buf, count, 0 /* MSG_DONTWAIT */ ); /* BUG?? */
|
||||
}
|
||||
|
||||
/**
|
||||
* Get descriptor of reading pipe.
|
||||
*/
|
||||
int jpipe_get_read_descr (jpipe_t * apipe)
|
||||
{
|
||||
if (apipe == NULL)
|
||||
return -1;
|
||||
return apipe->pipes[0];
|
||||
}
|
||||
|
||||
#endif
|
||||
111
linphone/exosip/jpipe.h
Normal file
111
linphone/exosip/jpipe.h
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 _JPIPE_H_
|
||||
#define _JPIPE_H_
|
||||
|
||||
#include <eXosip.h>
|
||||
|
||||
#ifndef WIN32
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file jpipe.h
|
||||
* @brief PPL Pipe Handling Routines
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup JPIPE Pipe Handling
|
||||
* @ingroup PPL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
/**
|
||||
* Structure for storing a pipe descriptor
|
||||
* @defvar jpipe_t
|
||||
*/
|
||||
typedef struct jpipe_t jpipe_t;
|
||||
|
||||
struct jpipe_t
|
||||
{
|
||||
int pipes[2];
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* Structure for storing a pipe descriptor
|
||||
* @defvar ppl_pipe_t
|
||||
*/
|
||||
typedef struct jpipe_t jpipe_t;
|
||||
|
||||
struct jpipe_t
|
||||
{
|
||||
int pipes[2];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get New pipe pair.
|
||||
*/
|
||||
jpipe_t * jpipe (void);
|
||||
|
||||
/**
|
||||
* Close pipe
|
||||
*/
|
||||
int jpipe_close (jpipe_t * apipe);
|
||||
|
||||
/**
|
||||
* Write in a pipe.
|
||||
*/
|
||||
int jpipe_write (jpipe_t * pipe, const void *buf,
|
||||
int count);
|
||||
|
||||
/**
|
||||
* Read in a pipe.
|
||||
*/
|
||||
int jpipe_read (jpipe_t * pipe, void *buf,
|
||||
int count);
|
||||
|
||||
/**
|
||||
* Get descriptor of reading pipe.
|
||||
*/
|
||||
int jpipe_get_read_descr (jpipe_t * pipe);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
||||
#endif
|
||||
118
linphone/exosip/jpublish.c
Normal file
118
linphone/exosip/jpublish.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#include "eXosip2.h"
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
int _eXosip_pub_update(eXosip_pub_t **pub, osip_transaction_t *tr, osip_message_t *answer)
|
||||
{
|
||||
eXosip_pub_t *jpub;
|
||||
|
||||
*pub = NULL;
|
||||
|
||||
for (jpub = eXosip.j_pub; jpub!=NULL; jpub = jpub->next)
|
||||
{
|
||||
if (jpub->p_last_tr==NULL)
|
||||
{ /*bug? */ }
|
||||
else if (tr==jpub->p_last_tr)
|
||||
{
|
||||
/* update the sip_etag parameter */
|
||||
if (answer==NULL)
|
||||
{ /* bug? */
|
||||
}
|
||||
else if (MSG_IS_STATUS_2XX(answer))
|
||||
{
|
||||
osip_header_t *sip_etag=NULL;
|
||||
osip_message_header_get_byname(answer, "SIP-ETag", 0, &sip_etag);
|
||||
if (sip_etag!=NULL && sip_etag->hvalue!=NULL)
|
||||
snprintf(jpub->p_sip_etag, 64, "%s", sip_etag->hvalue);
|
||||
}
|
||||
*pub=jpub;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _eXosip_pub_find_by_aor(eXosip_pub_t **pub, const char *aor)
|
||||
{
|
||||
eXosip_pub_t *jpub;
|
||||
eXosip_pub_t *ptr;
|
||||
time_t now;
|
||||
|
||||
*pub = NULL;
|
||||
|
||||
/* delete expired publications */
|
||||
now = time(NULL);
|
||||
ptr = eXosip.j_pub;
|
||||
for (jpub = ptr; jpub!=NULL; jpub = ptr)
|
||||
{
|
||||
ptr = jpub->next;
|
||||
if (now-jpub->p_expires>60)
|
||||
{
|
||||
OSIP_TRACE (osip_trace
|
||||
(__FILE__, __LINE__, OSIP_WARNING, NULL,
|
||||
"eXosip: removing expired publication!"));
|
||||
REMOVE_ELEMENT(eXosip.j_pub, jpub);
|
||||
_eXosip_pub_free(jpub);
|
||||
}
|
||||
}
|
||||
|
||||
for (jpub = eXosip.j_pub; jpub!=NULL; jpub = jpub->next)
|
||||
{
|
||||
if (osip_strcasecmp(aor, jpub->p_aor)==0)
|
||||
{
|
||||
*pub=jpub;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _eXosip_pub_init(eXosip_pub_t **pub, const char *aor, const char *exp)
|
||||
{
|
||||
eXosip_pub_t *jpub;
|
||||
|
||||
*pub = NULL;
|
||||
|
||||
jpub = (eXosip_pub_t*) osip_malloc(sizeof(eXosip_pub_t));
|
||||
if (jpub==0)
|
||||
return -1;
|
||||
memset(jpub, 0, sizeof(eXosip_pub_t));
|
||||
snprintf(jpub->p_aor, 256, "%s", aor);
|
||||
|
||||
jpub->p_expires = atoi(exp) + time(NULL);
|
||||
jpub->p_period = atoi(exp);
|
||||
|
||||
*pub = jpub;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _eXosip_pub_free(eXosip_pub_t *pub)
|
||||
{
|
||||
if (pub->p_last_tr!=NULL)
|
||||
osip_list_add(eXosip.j_transactions, pub->p_last_tr, 0);
|
||||
osip_free(pub);
|
||||
}
|
||||
|
||||
106
linphone/exosip/jreg.c
Normal file
106
linphone/exosip/jreg.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#include "eXosip2.h"
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
int eXosip_reg_init(eXosip_reg_t **jr, char *from, char *proxy, char *contact, char* route)
|
||||
{
|
||||
static int r_id;
|
||||
|
||||
*jr = (eXosip_reg_t*) osip_malloc(sizeof(eXosip_reg_t));
|
||||
if (*jr==NULL) return -1;
|
||||
|
||||
if (r_id > 1000000) /* keep it non-negative */
|
||||
r_id = 0;
|
||||
|
||||
(*jr)->r_id = ++r_id;
|
||||
(*jr)->r_reg_period = 3600; /* delay between registration */
|
||||
(*jr)->r_aor = osip_strdup(from); /* sip identity */
|
||||
(*jr)->r_contact = osip_strdup(contact); /* sip identity */
|
||||
(*jr)->r_registrar = osip_strdup(proxy); /* registrar */
|
||||
(*jr)->r_route = osip_strdup(route); /* outbound proxy */
|
||||
#if 0
|
||||
(*jr)->r_realms = NULL; /* list of realms */
|
||||
#endif
|
||||
(*jr)->r_last_tr = NULL;
|
||||
|
||||
(*jr)->next = NULL;
|
||||
(*jr)->parent = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eXosip_reg_free(eXosip_reg_t *jreg)
|
||||
{
|
||||
|
||||
osip_free(jreg->r_aor);
|
||||
osip_free(jreg->r_contact);
|
||||
osip_free(jreg->r_registrar);
|
||||
#if 0
|
||||
osip_free(jreg->r_realms);
|
||||
#endif
|
||||
|
||||
if (jreg->r_last_tr != NULL)
|
||||
{
|
||||
if (jreg->r_last_tr->state==IST_TERMINATED ||
|
||||
jreg->r_last_tr->state==ICT_TERMINATED ||
|
||||
jreg->r_last_tr->state== NICT_TERMINATED ||
|
||||
jreg->r_last_tr->state==NIST_TERMINATED)
|
||||
{
|
||||
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,
|
||||
"Release a terminated transaction\n"));
|
||||
__eXosip_delete_jinfo(jreg->r_last_tr);
|
||||
if (jreg->r_last_tr!=NULL)
|
||||
osip_list_add(eXosip.j_transactions, jreg->r_last_tr, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,
|
||||
"Release a non-terminated transaction\n"));
|
||||
__eXosip_delete_jinfo(jreg->r_last_tr);
|
||||
if (jreg->r_last_tr!=NULL)
|
||||
osip_list_add(eXosip.j_transactions, jreg->r_last_tr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
osip_free(jreg);
|
||||
}
|
||||
|
||||
int _eXosip_reg_find(eXosip_reg_t **reg, osip_transaction_t *tr)
|
||||
{
|
||||
eXosip_reg_t *jreg;
|
||||
*reg = NULL;
|
||||
if (tr==NULL) return -1;
|
||||
|
||||
for (jreg = eXosip.j_reg; jreg!=NULL; jreg = jreg->next)
|
||||
{
|
||||
if (jreg->r_last_tr==tr)
|
||||
{
|
||||
*reg = jreg;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
1158
linphone/exosip/jrequest.c
Normal file
1158
linphone/exosip/jrequest.c
Normal file
File diff suppressed because it is too large
Load diff
1264
linphone/exosip/jresponse.c
Normal file
1264
linphone/exosip/jresponse.c
Normal file
File diff suppressed because it is too large
Load diff
231
linphone/exosip/jsubscribe.c
Normal file
231
linphone/exosip/jsubscribe.c
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "eXosip2.h"
|
||||
#include <eXosip_cfg.h>
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
#if 0
|
||||
int eXosip_subscribe_find(int sid, eXosip_subscribe_t **js)
|
||||
{
|
||||
for (*js=eXosip.j_subscribes; *js!=NULL; *js=(*js)->next)
|
||||
{
|
||||
if ((*js)->s_id==sid)
|
||||
return 0;
|
||||
}
|
||||
*js = NULL;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_out_subscribe(eXosip_subscribe_t *js, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *out_tr;
|
||||
int pos;
|
||||
out_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_out_trs, pos))
|
||||
{
|
||||
out_tr = osip_list_get(jd->d_out_trs, pos);
|
||||
if (0==strcmp(out_tr->cseq->method, "SUBSCRIBE"))
|
||||
break;
|
||||
else out_tr = NULL;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
else
|
||||
out_tr = NULL;
|
||||
|
||||
if (out_tr==NULL)
|
||||
return js->s_out_tr; /* can be NULL */
|
||||
|
||||
return out_tr;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_inc_notify(eXosip_subscribe_t *js, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *out_tr;
|
||||
int pos;
|
||||
out_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_out_trs, pos))
|
||||
{
|
||||
out_tr = osip_list_get(jd->d_out_trs, pos);
|
||||
if (0==strcmp(out_tr->cseq->method, "NOTIFY"))
|
||||
return out_tr;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void
|
||||
__eXosip_subscribe_remove_dialog_reference_in_subscribe(eXosip_subscribe_t *js, eXosip_dialog_t *jd)
|
||||
{
|
||||
eXosip_dialog_t *_jd;
|
||||
jinfo_t *ji;
|
||||
if (js==NULL) return;
|
||||
if (jd==NULL) return;
|
||||
|
||||
|
||||
for (_jd = js->s_dialogs; _jd!=NULL; _jd=js->s_dialogs)
|
||||
{
|
||||
if (jd==_jd)
|
||||
break;
|
||||
}
|
||||
if (_jd==NULL)
|
||||
{
|
||||
/* dialog not found??? */
|
||||
}
|
||||
|
||||
ji = osip_transaction_get_your_instance(js->s_inc_tr);
|
||||
if (ji!=NULL && ji->jd==jd)
|
||||
ji->jd=NULL;
|
||||
ji = osip_transaction_get_your_instance(js->s_out_tr);
|
||||
if (ji!=NULL && ji->jd==jd)
|
||||
ji->jd=NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
eXosip_subscribe_init(eXosip_subscribe_t **js, char *uri)
|
||||
{
|
||||
if (uri==NULL) return -1;
|
||||
*js = (eXosip_subscribe_t *)osip_malloc(sizeof(eXosip_subscribe_t));
|
||||
if (*js == NULL) return -1;
|
||||
memset(*js, 0, sizeof(eXosip_subscribe_t));
|
||||
osip_strncpy((*js)->s_uri, uri, strlen(uri));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
eXosip_subscribe_free(eXosip_subscribe_t *js)
|
||||
{
|
||||
/* ... */
|
||||
|
||||
eXosip_dialog_t *jd;
|
||||
|
||||
for (jd = js->s_dialogs; jd!=NULL; jd=js->s_dialogs)
|
||||
{
|
||||
REMOVE_ELEMENT(js->s_dialogs, jd);
|
||||
eXosip_dialog_free(jd);
|
||||
}
|
||||
|
||||
__eXosip_delete_jinfo(js->s_inc_tr);
|
||||
__eXosip_delete_jinfo(js->s_out_tr);
|
||||
if (js->s_inc_tr!=NULL)
|
||||
osip_list_add(eXosip.j_transactions, js->s_inc_tr, 0);
|
||||
if (js->s_out_tr!=NULL)
|
||||
osip_list_add(eXosip.j_transactions, js->s_out_tr, 0);
|
||||
|
||||
osip_free(js);
|
||||
}
|
||||
|
||||
int
|
||||
_eXosip_subscribe_set_refresh_interval(eXosip_subscribe_t *js,
|
||||
osip_message_t *out_subscribe)
|
||||
{
|
||||
osip_header_t *exp;
|
||||
int now = time(NULL);
|
||||
if (js==NULL || out_subscribe==NULL)
|
||||
return -1;
|
||||
|
||||
osip_message_get_expires(out_subscribe, 0, &exp);
|
||||
if (exp==NULL || exp->hvalue==NULL)
|
||||
js->s_ss_expires = now + 600;
|
||||
else
|
||||
{
|
||||
js->s_ss_expires = osip_atoi(exp->hvalue);
|
||||
if (js->s_ss_expires!=-1)
|
||||
js->s_ss_expires = now + js->s_ss_expires;
|
||||
else /* on error, set it to default */
|
||||
js->s_ss_expires = now + 600;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eXosip_subscribe_need_refresh(eXosip_subscribe_t *js, int now)
|
||||
{
|
||||
if (now-js->s_ss_expires>-120)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int eXosip_subscribe_send_subscribe(eXosip_subscribe_t *js,
|
||||
eXosip_dialog_t *jd, const char *expires)
|
||||
{
|
||||
osip_transaction_t *transaction;
|
||||
osip_message_t *subscribe;
|
||||
osip_event_t *sipevent;
|
||||
int i;
|
||||
transaction = eXosip_find_last_out_subscribe(js, jd);
|
||||
if (transaction!=NULL)
|
||||
{
|
||||
if (transaction->state!=NICT_TERMINATED &&
|
||||
transaction->state!=NIST_TERMINATED)
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = _eXosip_build_request_within_dialog(&subscribe, "SUBSCRIBE",
|
||||
jd->d_dialog, "UDP");
|
||||
if (i!=0)
|
||||
return -2;
|
||||
|
||||
osip_message_set_expires(subscribe, expires);
|
||||
|
||||
i = osip_transaction_init(&transaction,
|
||||
NICT,
|
||||
eXosip.j_osip,
|
||||
subscribe);
|
||||
if (i!=0)
|
||||
{
|
||||
/* TODO: release the j_call.. */
|
||||
osip_message_free(subscribe);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_eXosip_subscribe_set_refresh_interval(js, subscribe);
|
||||
osip_list_add(jd->d_out_trs, transaction, 0);
|
||||
|
||||
sipevent = osip_new_outgoing_sipmessage(subscribe);
|
||||
sipevent->transactionid = transaction->transactionid;
|
||||
|
||||
osip_transaction_add_event(transaction, sipevent);
|
||||
|
||||
osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(NULL, jd, js, NULL));
|
||||
__eXosip_wakeup();
|
||||
return 0;
|
||||
}
|
||||
185
linphone/exosip/jsubscribers.c
Normal file
185
linphone/exosip/jsubscribers.c
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#include "eXosip2.h"
|
||||
#include <eXosip.h>
|
||||
#include <eXosip_cfg.h>
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
#ifndef EXOSIP_ETC_DIR
|
||||
#define EXOSIP_ETC_DIR ".eXosip"
|
||||
#endif
|
||||
|
||||
#ifndef EXOSIP_ADDSUBSCRIBERS_SH
|
||||
#define EXOSIP_ADDSUBSCRIBERS_SH "eXosip_addsubscriber.sh"
|
||||
#endif
|
||||
|
||||
|
||||
static int jsubscriber_init(jsubscriber_t **js, char *ch)
|
||||
{
|
||||
char *next;
|
||||
int i;
|
||||
|
||||
*js = (jsubscriber_t *)osip_malloc(sizeof(jsubscriber_t));
|
||||
if (*js==NULL) return -1;
|
||||
|
||||
i = jfriend_get_and_set_next_token(&((*js)->s_nick), ch, &next);
|
||||
if (i != 0)
|
||||
goto js_error1;
|
||||
osip_clrspace ((*js)->s_nick);
|
||||
ch = next;
|
||||
|
||||
i = jfriend_get_and_set_next_token(&((*js)->s_uri), ch, &next);
|
||||
if (i != 0)
|
||||
goto js_error2;
|
||||
osip_clrspace ((*js)->s_uri);
|
||||
ch = next;
|
||||
|
||||
(*js)->s_allow = osip_strdup(next);
|
||||
osip_clrspace ((*js)->s_allow);
|
||||
|
||||
return 0;
|
||||
|
||||
js_error2:
|
||||
osip_free((*js)->s_nick);
|
||||
js_error1:
|
||||
osip_free(*js);
|
||||
*js = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
jsubscriber_unload()
|
||||
{
|
||||
jsubscriber_t *js;
|
||||
if (eXosip.j_subscribers==NULL) return;
|
||||
for (js=eXosip.j_subscribers; js!=NULL; js=eXosip.j_subscribers)
|
||||
{
|
||||
REMOVE_ELEMENT(eXosip.j_subscribers,js);
|
||||
osip_free(js->s_nick);
|
||||
osip_free(js->s_uri);
|
||||
osip_free(js->s_allow);
|
||||
osip_free(js);
|
||||
}
|
||||
|
||||
osip_free(eXosip.j_subscribers);
|
||||
eXosip.j_subscribers=NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
jsubscriber_load()
|
||||
{
|
||||
FILE *file;
|
||||
char *s;
|
||||
jsubscriber_t *js;
|
||||
int pos;
|
||||
char *home;
|
||||
char filename[255];
|
||||
|
||||
jsubscriber_unload();
|
||||
home = getenv("HOME");
|
||||
sprintf(filename, "%s/%s/%s", home, EXOSIP_ETC_DIR, "jm_subscriber");
|
||||
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (file==NULL) return -1;
|
||||
s = (char *)osip_malloc(255*sizeof(char));
|
||||
pos = 0;
|
||||
while (NULL!=fgets(s, 254, file))
|
||||
{
|
||||
char *tmp = s;
|
||||
while (*tmp!='\0' && *tmp!=' ') tmp++;
|
||||
while (*tmp!='\0' && *tmp==' ') tmp++;
|
||||
while (*tmp!='\0' && *tmp!=' ') tmp++;
|
||||
tmp++; /* first usefull characters */
|
||||
pos++;
|
||||
|
||||
jsubscriber_init(&js, tmp);
|
||||
if (js!=NULL)
|
||||
{ ADD_ELEMENT(eXosip.j_subscribers, js); }
|
||||
}
|
||||
osip_free(s);
|
||||
fclose(file);
|
||||
|
||||
return 0; /* ok */
|
||||
}
|
||||
|
||||
void subscribers_add(char *nickname, char *uri, int black_list)
|
||||
{
|
||||
char *home;
|
||||
char command[256];
|
||||
char *tmp = command;
|
||||
int length = 0;
|
||||
if (nickname!=NULL)
|
||||
length = strlen(nickname);
|
||||
|
||||
if (uri==NULL)
|
||||
return ;
|
||||
home = getenv("HOME");
|
||||
length = length + strlen(home);
|
||||
length = length + strlen(uri);
|
||||
|
||||
length = length + 10; /* for black_list info */
|
||||
length = length + strlen(EXOSIP_ETC_DIR);
|
||||
|
||||
length = length + strlen("/jm_subscriber");
|
||||
if (length>235) /* leave some room for SPACEs and \r\n */
|
||||
return ;
|
||||
|
||||
sprintf(tmp , "%s %s/%s/jm_subscriber", EXOSIP_ADDSUBSCRIBERS_SH, home, EXOSIP_ETC_DIR);
|
||||
|
||||
tmp = tmp + strlen(tmp);
|
||||
if (nickname!=NULL)
|
||||
sprintf(tmp , " %s", nickname);
|
||||
else
|
||||
sprintf(tmp , " \"\"");
|
||||
|
||||
tmp = tmp + strlen(tmp);
|
||||
sprintf(tmp , " %s", uri);
|
||||
|
||||
tmp = tmp + strlen(tmp);
|
||||
if (black_list==0) /* allowed */
|
||||
sprintf(tmp , " allow");
|
||||
else
|
||||
sprintf(tmp , " reject");
|
||||
|
||||
system(command);
|
||||
|
||||
jsubscriber_load();
|
||||
}
|
||||
|
||||
char *
|
||||
jsubscriber_get_uri(int fid)
|
||||
{
|
||||
jsubscriber_t *js;
|
||||
for (js = eXosip.j_subscribers; js!=NULL ; js=js->next)
|
||||
{
|
||||
if (fid==0)
|
||||
return osip_strdup(js->s_uri);
|
||||
fid--;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
436
linphone/exosip/misc.c
Normal file
436
linphone/exosip/misc.c
Normal file
|
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "eXosip2.h"
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
|
||||
/* some methods to extract transaction information from a eXosip_call_t */
|
||||
|
||||
int
|
||||
eXosip_remove_transaction_from_call(osip_transaction_t *tr, eXosip_call_t *jc)
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
osip_transaction_t *out_tr;
|
||||
eXosip_dialog_t *jd;
|
||||
int pos=0;
|
||||
|
||||
if (jc->c_inc_tr==tr)
|
||||
{
|
||||
jc->c_inc_tr = NULL; /* can be NULL */
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (jd=jc->c_dialogs;jd!=NULL;jd=jd->next)
|
||||
{
|
||||
pos=0;
|
||||
while (!osip_list_eol(jd->d_inc_trs, pos))
|
||||
{
|
||||
inc_tr = osip_list_get(jd->d_inc_trs, pos);
|
||||
if (inc_tr==tr)
|
||||
{
|
||||
osip_list_remove(jd->d_inc_trs, pos);
|
||||
return 0;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
if (jc->c_out_tr==tr)
|
||||
{
|
||||
jc->c_out_tr = NULL; /* can be NULL */
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (jd=jc->c_dialogs;jd!=NULL;jd=jd->next)
|
||||
{
|
||||
pos=0;
|
||||
while (!osip_list_eol(jd->d_out_trs, pos))
|
||||
{
|
||||
out_tr = osip_list_get(jd->d_out_trs, pos);
|
||||
if (out_tr==tr)
|
||||
{
|
||||
osip_list_remove(jd->d_out_trs, pos);
|
||||
return 0;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,
|
||||
"eXosip: No information.\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_options(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
osip_transaction_t *out_tr;
|
||||
inc_tr = eXosip_find_last_inc_options(jc, jd);
|
||||
out_tr = eXosip_find_last_out_options(jc, jd);
|
||||
if (inc_tr==NULL)
|
||||
return out_tr;
|
||||
if (out_tr==NULL)
|
||||
return inc_tr;
|
||||
|
||||
if (inc_tr->birth_time>out_tr->birth_time)
|
||||
return inc_tr;
|
||||
return out_tr;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_inc_options(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
int pos;
|
||||
inc_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_inc_trs, pos))
|
||||
{
|
||||
inc_tr = osip_list_get(jd->d_inc_trs, pos);
|
||||
if (0==strcmp(inc_tr->cseq->method, "OPTIONS"))
|
||||
break;
|
||||
else inc_tr = NULL;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
else
|
||||
inc_tr = NULL;
|
||||
|
||||
if (inc_tr==NULL)
|
||||
return jc->c_inc_options_tr; /* can be NULL */
|
||||
|
||||
return inc_tr;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_out_options(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *out_tr;
|
||||
int pos;
|
||||
out_tr = NULL;
|
||||
pos=0;
|
||||
if (jd==NULL && jc==NULL) return NULL;
|
||||
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_out_trs, pos))
|
||||
{
|
||||
out_tr = osip_list_get(jd->d_out_trs, pos);
|
||||
if (0==strcmp(out_tr->cseq->method, "OPTIONS"))
|
||||
break;
|
||||
else out_tr = NULL;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
if (out_tr==NULL)
|
||||
return jc->c_out_options_tr; /* can be NULL */
|
||||
|
||||
return out_tr;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_info(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
osip_transaction_t *out_tr;
|
||||
inc_tr = eXosip_find_last_inc_info(jc, jd);
|
||||
out_tr = eXosip_find_last_out_info(jc, jd);
|
||||
if (inc_tr==NULL)
|
||||
return out_tr;
|
||||
if (out_tr==NULL)
|
||||
return inc_tr;
|
||||
|
||||
if (inc_tr->birth_time>out_tr->birth_time)
|
||||
return inc_tr;
|
||||
return out_tr;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_inc_info(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
int pos;
|
||||
inc_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_inc_trs, pos))
|
||||
{
|
||||
inc_tr = osip_list_get(jd->d_inc_trs, pos);
|
||||
if (0==strcmp(inc_tr->cseq->method, "INFO"))
|
||||
break;
|
||||
else inc_tr = NULL;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
else
|
||||
inc_tr = NULL;
|
||||
|
||||
return inc_tr;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_out_info(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *out_tr;
|
||||
int pos;
|
||||
out_tr = NULL;
|
||||
pos=0;
|
||||
if (jd==NULL && jc==NULL) return NULL;
|
||||
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_out_trs, pos))
|
||||
{
|
||||
out_tr = osip_list_get(jd->d_out_trs, pos);
|
||||
if (0==strcmp(out_tr->cseq->method, "INFO"))
|
||||
break;
|
||||
else out_tr = NULL;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return out_tr;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_refer(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
osip_transaction_t *out_tr;
|
||||
inc_tr = eXosip_find_last_inc_refer(jc, jd);
|
||||
out_tr = eXosip_find_last_out_refer(jc, jd);
|
||||
if (inc_tr==NULL)
|
||||
return out_tr;
|
||||
if (out_tr==NULL)
|
||||
return inc_tr;
|
||||
|
||||
if (inc_tr->birth_time>out_tr->birth_time)
|
||||
return inc_tr;
|
||||
return out_tr;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_invite(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
osip_transaction_t *out_tr;
|
||||
inc_tr = eXosip_find_last_inc_invite(jc, jd);
|
||||
out_tr = eXosip_find_last_out_invite(jc, jd);
|
||||
if (inc_tr==NULL)
|
||||
return out_tr;
|
||||
if (out_tr==NULL)
|
||||
return inc_tr;
|
||||
|
||||
if (inc_tr->birth_time>out_tr->birth_time)
|
||||
return inc_tr;
|
||||
return out_tr;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_inc_invite(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
int pos;
|
||||
inc_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_inc_trs, pos))
|
||||
{
|
||||
inc_tr = osip_list_get(jd->d_inc_trs, pos);
|
||||
if (0==strcmp(inc_tr->cseq->method, "INVITE"))
|
||||
break;
|
||||
else inc_tr = NULL;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
else
|
||||
inc_tr = NULL;
|
||||
|
||||
if (inc_tr==NULL)
|
||||
return jc->c_inc_tr; /* can be NULL */
|
||||
|
||||
return inc_tr;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_out_invite(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *out_tr;
|
||||
int pos;
|
||||
out_tr = NULL;
|
||||
pos=0;
|
||||
if (jd==NULL && jc==NULL) return NULL;
|
||||
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_out_trs, pos))
|
||||
{
|
||||
out_tr = osip_list_get(jd->d_out_trs, pos);
|
||||
if (0==strcmp(out_tr->cseq->method, "INVITE"))
|
||||
break;
|
||||
else out_tr = NULL;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
if (out_tr==NULL)
|
||||
return jc->c_out_tr; /* can be NULL */
|
||||
|
||||
return out_tr;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_inc_bye(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
int pos;
|
||||
inc_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_inc_trs, pos))
|
||||
{
|
||||
inc_tr = osip_list_get(jd->d_inc_trs, pos);
|
||||
if (0==strcmp(inc_tr->cseq->method, "BYE"))
|
||||
return inc_tr;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_out_bye(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *out_tr;
|
||||
int pos;
|
||||
out_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_out_trs, pos))
|
||||
{
|
||||
out_tr = osip_list_get(jd->d_out_trs, pos);
|
||||
if (0==strcmp(out_tr->cseq->method, "BYE"))
|
||||
return out_tr;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_inc_refer(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
int pos;
|
||||
inc_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_inc_trs, pos))
|
||||
{
|
||||
inc_tr = osip_list_get(jd->d_inc_trs, pos);
|
||||
if (0==strcmp(inc_tr->cseq->method, "REFER"))
|
||||
return inc_tr;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_out_refer(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *out_tr;
|
||||
int pos;
|
||||
out_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_out_trs, pos))
|
||||
{
|
||||
out_tr = osip_list_get(jd->d_out_trs, pos);
|
||||
if (0==strcmp(out_tr->cseq->method, "REFER"))
|
||||
return out_tr;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_inc_notify_for_refer(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *inc_tr;
|
||||
int pos;
|
||||
inc_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_inc_trs, pos))
|
||||
{
|
||||
inc_tr = osip_list_get(jd->d_inc_trs, pos);
|
||||
if (0==strcmp(inc_tr->cseq->method, "NOTIFY"))
|
||||
return inc_tr;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
osip_transaction_t *
|
||||
eXosip_find_last_out_notify_for_refer(eXosip_call_t *jc, eXosip_dialog_t *jd )
|
||||
{
|
||||
osip_transaction_t *out_tr;
|
||||
int pos;
|
||||
out_tr = NULL;
|
||||
pos=0;
|
||||
if (jd!=NULL)
|
||||
{
|
||||
while (!osip_list_eol(jd->d_out_trs, pos))
|
||||
{
|
||||
out_tr = osip_list_get(jd->d_out_trs, pos);
|
||||
if (0==strcmp(out_tr->cseq->method, "NOTIFY"))
|
||||
return out_tr;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
333
linphone/exosip/sdp_offans.c
Normal file
333
linphone/exosip/sdp_offans.c
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
/*
|
||||
eXosip - This is the eXtended osip library.
|
||||
Copyright (C) 2002, 2003 Aymeric MOIZARD - jack@atosc.org
|
||||
|
||||
eXosip 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.
|
||||
|
||||
eXosip 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 ENABLE_MPATROL
|
||||
#include <mpatrol.h>
|
||||
#endif
|
||||
|
||||
#include "eXosip2.h"
|
||||
|
||||
extern eXosip_t eXosip;
|
||||
|
||||
osip_list_t *supported_codec = NULL;
|
||||
|
||||
int eXosip_sdp_accept_audio_codec(osip_negotiation_ctx_t *context,
|
||||
char *port, char *number_of_port,
|
||||
int audio_qty, char *payload);
|
||||
int eXosip_sdp_accept_video_codec(osip_negotiation_ctx_t *context,
|
||||
char *port, char *number_of_port,
|
||||
int video_qty, char *payload);
|
||||
int eXosip_sdp_accept_other_codec(osip_negotiation_ctx_t *context,
|
||||
char *type, char *port,
|
||||
char *number_of_port, char *payload);
|
||||
|
||||
char *eXosip_sdp_get_audio_port(osip_negotiation_ctx_t *context, int pos_media);
|
||||
|
||||
int eXosip_sdp_accept_audio_codec(osip_negotiation_ctx_t *context,
|
||||
char *port, char *number_of_port,
|
||||
int audio_qty, char *payload)
|
||||
{
|
||||
int pos;
|
||||
for (pos=0;!osip_list_eol(supported_codec, pos);pos++)
|
||||
{
|
||||
char *_payload;
|
||||
_payload = osip_list_get(supported_codec, pos);
|
||||
if (0==strcmp(payload,_payload))
|
||||
{
|
||||
/*
|
||||
We have to look at the rtpmap attributes in context->remote
|
||||
to check if we support this stuff.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int eXosip_sdp_accept_video_codec(osip_negotiation_ctx_t *context,
|
||||
char *port, char *number_of_port,
|
||||
int video_qty, char *payload)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int eXosip_sdp_accept_other_codec(osip_negotiation_ctx_t *context,
|
||||
char *type, char *port,
|
||||
char *number_of_port, char *payload)
|
||||
{
|
||||
/* ... */
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *eXosip_sdp_get_audio_port(osip_negotiation_ctx_t *context, int pos_media)
|
||||
{
|
||||
eXosip_call_t *jc = (eXosip_call_t*)osip_negotiation_ctx_get_mycontext(context);
|
||||
if (jc==NULL)
|
||||
return osip_strdup("10500");
|
||||
else if (jc->c_sdp_port[0]=='\0')
|
||||
return osip_strdup("10500");
|
||||
else return osip_strdup(jc->c_sdp_port);
|
||||
}
|
||||
|
||||
int eXosip_sdp_negotiation_replace(osip_negotiation_t *sn)
|
||||
{
|
||||
if (eXosip.osip_negotiation!=NULL)
|
||||
osip_negotiation_free(eXosip.osip_negotiation);
|
||||
eXosip.osip_negotiation = sn;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
eXosip_sdp_negotiation_ctx_set_mycontext(struct eXosip_call_t *jc, void *arg)
|
||||
{
|
||||
osip_negotiation_ctx_set_mycontext(jc->c_ctx, arg);
|
||||
}
|
||||
|
||||
void eXosip_sdp_negotiation_remove_audio_payloads()
|
||||
{
|
||||
if (supported_codec==NULL)
|
||||
return;
|
||||
for (;!osip_list_eol(supported_codec, 0);)
|
||||
{
|
||||
char *p;
|
||||
p = (char *) osip_list_get(supported_codec, 0);
|
||||
osip_free(p);
|
||||
osip_list_remove(supported_codec, 0);
|
||||
}
|
||||
osip_negotiation_remove_audio_payloads(eXosip.osip_negotiation);
|
||||
}
|
||||
|
||||
void eXosip_sdp_negotiation_add_codec(char *payload, char *number_of_port,
|
||||
char *proto, char *c_nettype,
|
||||
char *c_addrtype, char *c_addr,
|
||||
char *c_addr_multicast_ttl,
|
||||
char *c_addr_multicast_int,
|
||||
char *a_rtpmap)
|
||||
{
|
||||
osip_negotiation_add_support_for_audio_codec(eXosip.osip_negotiation,
|
||||
payload,
|
||||
number_of_port,
|
||||
proto,
|
||||
c_nettype,
|
||||
c_addrtype,
|
||||
c_addr,
|
||||
c_addr_multicast_ttl,
|
||||
c_addr_multicast_int,
|
||||
a_rtpmap);
|
||||
osip_list_add(supported_codec, osip_strdup(payload), -1);
|
||||
}
|
||||
|
||||
int eXosip_sdp_negotiation_init(osip_negotiation_t **sn)
|
||||
{
|
||||
int i = osip_negotiation_init(sn);
|
||||
if (i!=0) {
|
||||
return -1;
|
||||
}
|
||||
if (supported_codec==NULL)
|
||||
{
|
||||
supported_codec = (osip_list_t*) osip_malloc(sizeof(osip_list_t));
|
||||
osip_list_init(supported_codec);
|
||||
}
|
||||
osip_negotiation_set_o_username(*sn, osip_strdup("userX"));
|
||||
osip_negotiation_set_o_session_id(*sn, osip_strdup("20000001"));
|
||||
osip_negotiation_set_o_session_version(*sn, osip_strdup("20000001"));
|
||||
osip_negotiation_set_o_nettype(*sn, osip_strdup("IN"));
|
||||
osip_negotiation_set_o_addrtype(*sn, osip_strdup("IP4"));
|
||||
osip_negotiation_set_o_addr(*sn, osip_strdup(eXosip.localip));
|
||||
|
||||
osip_negotiation_set_c_nettype(*sn, osip_strdup("IN"));
|
||||
osip_negotiation_set_c_addrtype(*sn, osip_strdup("IP4"));
|
||||
osip_negotiation_set_c_addr(*sn, osip_strdup(eXosip.localip));
|
||||
|
||||
/* ALL CODEC MUST SHARE THE SAME "C=" line and proto as the media
|
||||
will appear on the same "m" line... */
|
||||
|
||||
osip_negotiation_set_fcn_accept_audio_codec(*sn, &eXosip_sdp_accept_audio_codec);
|
||||
osip_negotiation_set_fcn_accept_video_codec(*sn, &eXosip_sdp_accept_video_codec);
|
||||
|
||||
osip_negotiation_set_fcn_accept_other_codec(*sn, &eXosip_sdp_accept_other_codec);
|
||||
osip_negotiation_set_fcn_get_audio_port(*sn, &eXosip_sdp_get_audio_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eXosip_sdp_negotiation_free(osip_negotiation_t *sn)
|
||||
{
|
||||
if (sn==NULL)
|
||||
return;
|
||||
osip_list_ofchar_free(supported_codec);
|
||||
supported_codec = NULL;
|
||||
osip_negotiation_free(sn);
|
||||
}
|
||||
|
||||
sdp_message_t *
|
||||
eXosip_get_local_sdp_info(osip_transaction_t *invite_tr)
|
||||
{
|
||||
osip_content_type_t *ctt;
|
||||
osip_mime_version_t *mv;
|
||||
osip_message_t *message;
|
||||
sdp_message_t *sdp;
|
||||
osip_body_t *oldbody;
|
||||
int pos;
|
||||
|
||||
if (invite_tr->ctx_type == IST)
|
||||
message = invite_tr->last_response;
|
||||
else if (invite_tr->ctx_type == ICT)
|
||||
message = invite_tr->orig_request;
|
||||
else return NULL; /* BUG -> NOT AN INVITE TRANSACTION!! */
|
||||
|
||||
if (message==NULL) return NULL;
|
||||
|
||||
/* get content-type info */
|
||||
ctt = osip_message_get_content_type(message);
|
||||
mv = osip_message_get_mime_version(message);
|
||||
if (mv==NULL && ctt==NULL)
|
||||
return NULL; /* previous message was not correct or empty */
|
||||
if (mv!=NULL)
|
||||
{
|
||||
/* look for the SDP body */
|
||||
/* ... */
|
||||
}
|
||||
else if (ctt!=NULL)
|
||||
{
|
||||
if (ctt->type==NULL || ctt->subtype==NULL)
|
||||
/* it can be application/sdp or mime... */
|
||||
return NULL;
|
||||
if (osip_strcasecmp(ctt->type, "application")!=0 ||
|
||||
osip_strcasecmp(ctt->subtype, "sdp")!=0 )
|
||||
{ return NULL; }
|
||||
}
|
||||
|
||||
pos=0;
|
||||
while (!osip_list_eol(message->bodies, pos))
|
||||
{
|
||||
int i;
|
||||
oldbody = (osip_body_t *) osip_list_get(message->bodies, pos);
|
||||
pos++;
|
||||
sdp_message_init(&sdp);
|
||||
i = sdp_message_parse(sdp,oldbody->body);
|
||||
if (i==0) return sdp;
|
||||
sdp_message_free(sdp);
|
||||
sdp = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sdp_message_t *
|
||||
eXosip_get_remote_sdp_info(osip_transaction_t *invite_tr)
|
||||
{
|
||||
osip_content_type_t *ctt;
|
||||
osip_mime_version_t *mv;
|
||||
osip_message_t *message;
|
||||
sdp_message_t *sdp;
|
||||
osip_body_t *oldbody;
|
||||
int pos;
|
||||
|
||||
if (invite_tr->ctx_type == IST)
|
||||
message = invite_tr->orig_request;
|
||||
else if (invite_tr->ctx_type == ICT)
|
||||
message = invite_tr->last_response;
|
||||
else return NULL; /* BUG -> NOT AN INVITE TRANSACTION!! */
|
||||
|
||||
if (message==NULL) return NULL;
|
||||
|
||||
/* get content-type info */
|
||||
ctt = osip_message_get_content_type(message);
|
||||
mv = osip_message_get_mime_version(message);
|
||||
if (mv==NULL && ctt==NULL)
|
||||
return NULL; /* previous message was not correct or empty */
|
||||
if (mv!=NULL)
|
||||
{
|
||||
/* look for the SDP body */
|
||||
/* ... */
|
||||
}
|
||||
else if (ctt!=NULL)
|
||||
{
|
||||
if (ctt->type==NULL || ctt->subtype==NULL)
|
||||
/* it can be application/sdp or mime... */
|
||||
return NULL;
|
||||
if (osip_strcasecmp(ctt->type, "application")!=0 ||
|
||||
osip_strcasecmp(ctt->subtype, "sdp")!=0 )
|
||||
{ return NULL; }
|
||||
}
|
||||
|
||||
pos=0;
|
||||
while (!osip_list_eol(message->bodies, pos))
|
||||
{
|
||||
int i;
|
||||
oldbody = (osip_body_t *) osip_list_get(message->bodies, pos);
|
||||
pos++;
|
||||
sdp_message_init(&sdp);
|
||||
i = sdp_message_parse(sdp,oldbody->body);
|
||||
if (i==0) return sdp;
|
||||
sdp_message_free(sdp);
|
||||
sdp = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int eXosip_retrieve_sdp_negotiation_result(osip_negotiation_ctx_t *ctx, char *payload_name, int pnsize)
|
||||
{
|
||||
sdp_message_t *local_sdp = 0;
|
||||
int payload_result = -1;
|
||||
|
||||
if (!ctx)
|
||||
return payload_result;
|
||||
|
||||
local_sdp = osip_negotiation_ctx_get_local_sdp(ctx);
|
||||
|
||||
if (local_sdp != NULL)
|
||||
{
|
||||
sdp_media_t *med = (sdp_media_t*) osip_list_get(local_sdp->m_medias, 0);
|
||||
char *payload = (char *) osip_list_get (med->m_payloads, 0);
|
||||
int pos_attr;
|
||||
|
||||
if (payload!=NULL)
|
||||
{
|
||||
payload_result = osip_atoi(payload);
|
||||
|
||||
/* copy payload name! */
|
||||
for (pos_attr=0;
|
||||
!osip_list_eol(med->a_attributes, pos_attr);
|
||||
pos_attr++)
|
||||
{
|
||||
sdp_attribute_t *attr;
|
||||
attr = (sdp_attribute_t *)osip_list_get(med->a_attributes, pos_attr);
|
||||
if (0==osip_strncasecmp(attr->a_att_field, "rtpmap", 6))
|
||||
{
|
||||
if ((payload_result <10 &&
|
||||
0==osip_strncasecmp(attr->a_att_value, payload, 1))
|
||||
||(payload_result>9 && payload_result<100 &&
|
||||
0==osip_strncasecmp(attr->a_att_value, payload, 2))
|
||||
||(payload_result >100 && payload_result<128 &&
|
||||
0==osip_strncasecmp(attr->a_att_value, payload, 3)))
|
||||
{
|
||||
snprintf(payload_name, pnsize, "%s", attr->a_att_value);
|
||||
return payload_result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return payload_result;
|
||||
|
||||
}
|
||||
2635
linphone/exosip/udp.c
Normal file
2635
linphone/exosip/udp.c
Normal file
File diff suppressed because it is too large
Load diff
8
linphone/gnome/.cvsignore
Normal file
8
linphone/gnome/.cvsignore
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
linphone
|
||||
linphone_applet
|
||||
GNOME_LinphoneApplet.server
|
||||
GNOME_LinphoneApplet.server.in
|
||||
32
linphone/gnome/GNOME_LinphoneApplet.server.in.in
Normal file
32
linphone/gnome/GNOME_LinphoneApplet.server.in.in
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<oaf_info>
|
||||
|
||||
<oaf_server iid="OAFIID:GNOME_LinphoneApplet_Factory"
|
||||
type="exe"
|
||||
location="@LIBEXECDIR@/linphone_applet">
|
||||
|
||||
<oaf_attribute name="repo_ids" type="stringv">
|
||||
<item value="IDL:Bonobo/GenericFactory:1.0"/>
|
||||
<item value="IDL:Bonobo/Unknown:1.0"/>
|
||||
</oaf_attribute>
|
||||
<oaf_attribute name="name" type="string" value="Linphone Applet Factory"/>
|
||||
<oaf_attribute name="description" type="string" value="Linphone Applet Factory"/>
|
||||
|
||||
</oaf_server>
|
||||
|
||||
<oaf_server iid="OAFIID:GNOME_LinphoneApplet"
|
||||
type="factory"
|
||||
location="OAFIID:GNOME_LinphoneApplet_Factory">
|
||||
|
||||
<oaf_attribute name="repo_ids" type="stringv">
|
||||
<item value="IDL:GNOME/Vertigo/PanelAppletShell:1.0"/>
|
||||
<item value="IDL:Bonobo/Control:1.0"/>
|
||||
<item value="IDL:Bonobo/Unknown:1.0"/>
|
||||
</oaf_attribute>
|
||||
<oaf_attribute name="name" type="string" _value="Linphone"/>
|
||||
<oaf_attribute name="description" type="string" _value="Linphone"/>
|
||||
<oaf_attribute name="panel:category" type="string" _value="Internet"/>
|
||||
<oaf_attribute name="panel:icon" type="string" value="linphone/linphone2.png"/>
|
||||
|
||||
</oaf_server>
|
||||
|
||||
</oaf_info>
|
||||
7
linphone/gnome/GNOME_LinphoneApplet.xml
Normal file
7
linphone/gnome/GNOME_LinphoneApplet.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<Root>
|
||||
<popups>
|
||||
<popup name="button3">
|
||||
<menuitem name="About" verb="About" _label="_About..." pixtype="stock" pixname="gnome-stock-about"/>
|
||||
</popup>
|
||||
</popups>
|
||||
</Root>
|
||||
80
linphone/gnome/Makefile.am
Normal file
80
linphone/gnome/Makefile.am
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
linphone_common_sources=\
|
||||
linphone.c linphone.h \
|
||||
gui_utils.c gui_utils.h \
|
||||
support.c support.h \
|
||||
interface.c interface.h \
|
||||
callbacks.c callbacks.h \
|
||||
presence.c presence.h \
|
||||
propertybox.c propertybox.h \
|
||||
addressbook.c addressbook.h \
|
||||
friends.c friends.h
|
||||
|
||||
|
||||
if BUILD_GNOME
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)\
|
||||
-I$(top_srcdir)/intl \
|
||||
$(ORTP_CFLAGS) \
|
||||
-I$(top_srcdir)/coreapi \
|
||||
-I$(top_srcdir)/mediastreamer2/include \
|
||||
$(OSIP_CFLAGS)
|
||||
|
||||
|
||||
|
||||
bin_PROGRAMS = linphone
|
||||
|
||||
linphone_SOURCES = \
|
||||
main.c \
|
||||
$(linphone_common_sources)
|
||||
|
||||
linphone_LDADD = $(LIBGNOMEUI_LIBS) $(INTLLIBS) \
|
||||
$(LIBGNOME_LIBS) \
|
||||
$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(OSIP_LIBS)
|
||||
|
||||
endif
|
||||
|
||||
AM_CFLAGS=$(STRICT_OPTIONS) $(LIBGNOMEUI_CFLAGS) $(LIBGNOME_CFLAGS) $(GNOME_APPLETS_CFLAGS) $(IPV6_CFLAGS)
|
||||
|
||||
@INTLTOOL_SERVER_RULE@
|
||||
|
||||
if BUILD_GNOME_APPLET
|
||||
|
||||
gnome_appletdir=$(libexecdir)
|
||||
|
||||
gnome_applet_PROGRAMS = linphone_applet
|
||||
|
||||
linphone_applet_SOURCES = \
|
||||
$(linphone_common_sources)\
|
||||
applet.c
|
||||
|
||||
linphone_applet_CFLAGS=$(AM_CFLAGS) -DLINPHONE_APPLET
|
||||
|
||||
linphone_applet_LDADD = \
|
||||
$(GNOME_APPLETS_LIBS) \
|
||||
$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(OSIP_LIBS)
|
||||
|
||||
|
||||
serverdir = $(libdir)/bonobo/servers
|
||||
server_in_files = GNOME_LinphoneApplet.server.in
|
||||
server_DATA = $(server_in_files:.server.in=.server)
|
||||
|
||||
$(server_in_files): $(server_in_files:.server.in=.server.in.in)
|
||||
sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@
|
||||
|
||||
|
||||
uidir = $(datadir)/gnome-2.0/ui
|
||||
ui_DATA = GNOME_LinphoneApplet.xml
|
||||
|
||||
endif
|
||||
|
||||
EXTRA_DIST = \
|
||||
GNOME_LinphoneApplet.server.in.in \
|
||||
applet.c \
|
||||
$(ui_DATA)
|
||||
|
||||
DISTCLEANFILES=GNOME_LinphoneApplet.server.in GNOME_LinphoneApplet.server
|
||||
306
linphone/gnome/addressbook.c
Normal file
306
linphone/gnome/addressbook.c
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
/***************************************************************************
|
||||
addressbook.c -
|
||||
-------------------
|
||||
begin : Wed Jan 30 2002
|
||||
copyright : (C) 2002 by Simon Morlat
|
||||
email : 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "linphone.h"
|
||||
|
||||
#define get_address_book() (&uiobj->addressbook)
|
||||
#define get_main_window() (&uiobj->main_window)
|
||||
#define get_core() (uiobj->core)
|
||||
#define get_uiobj() (uiobj)
|
||||
|
||||
void fill_address_book(GtkWidget *address_list);
|
||||
|
||||
void ab_destroyed(){
|
||||
get_uiobj()->ab=NULL;
|
||||
}
|
||||
|
||||
void show_address_book(){
|
||||
if (get_uiobj()->ab!=NULL){
|
||||
gtk_window_present(GTK_WINDOW(get_uiobj()->ab));
|
||||
}else{
|
||||
get_uiobj()->ab=create_and_fill_address_book();
|
||||
g_signal_connect(G_OBJECT(get_uiobj()->ab),"destroy",G_CALLBACK(ab_destroyed),NULL);
|
||||
gtk_widget_show(get_uiobj()->ab);
|
||||
}
|
||||
}
|
||||
|
||||
#define GLADE_HOOKUP_OBJECT(component,widget,name) \
|
||||
g_object_set_data_full (G_OBJECT (component), name, \
|
||||
gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
|
||||
|
||||
void contact_draw(GtkWidget *w, LinphoneProxyConfig *cfg){
|
||||
GtkWidget *table=lookup_widget(w,"table10");
|
||||
GtkWidget *combo;
|
||||
combo=proxy_combo_box_new(cfg);
|
||||
gtk_widget_show(combo);
|
||||
gtk_table_attach(GTK_TABLE(table),combo,1,2,2,3, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
||||
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
|
||||
GLADE_HOOKUP_OBJECT(w,combo,"proxy");
|
||||
combo=gtk_combo_box_new_text();
|
||||
gtk_combo_box_append_text(GTK_COMBO_BOX(combo),_("Wait"));
|
||||
gtk_combo_box_append_text(GTK_COMBO_BOX(combo),_("Deny"));
|
||||
gtk_combo_box_append_text(GTK_COMBO_BOX(combo),_("Accept"));
|
||||
gtk_widget_show(combo);
|
||||
gtk_table_attach(GTK_TABLE(table),combo,1,2,3,4, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
|
||||
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
|
||||
GLADE_HOOKUP_OBJECT(w,combo,"pol");
|
||||
}
|
||||
|
||||
GtkWidget * contact_new(LinphoneFriend *lf, GtkWidget *ab){
|
||||
GtkWidget *w=create_contact_box();
|
||||
contact_draw(w,NULL);
|
||||
gtk_widget_show(w);
|
||||
g_object_set_data(G_OBJECT(w),"friend_ref",(gpointer)lf);
|
||||
g_object_set_data(G_OBJECT(w),"address_book",(gpointer)ab);
|
||||
g_object_set_data(G_OBJECT(w),"add",GINT_TO_POINTER(TRUE));
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(lookup_widget(w,"pol")),lf->pol);
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(w,"send_subscribe")),lf->subscribe);
|
||||
return w;
|
||||
}
|
||||
|
||||
GtkWidget * contact_edit(LinphoneFriend *lf, GtkWidget *ab){
|
||||
GtkWidget *w=create_contact_box();
|
||||
gchar *tmpstr;
|
||||
contact_draw(w,lf->proxy);
|
||||
|
||||
g_object_set_data(G_OBJECT(w),"friend_ref",(gpointer)lf);
|
||||
linphone_friend_edit(lf);
|
||||
tmpstr=linphone_friend_get_name(lf);
|
||||
if (tmpstr!=NULL) {
|
||||
gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"name")),tmpstr);
|
||||
g_free(tmpstr);
|
||||
}
|
||||
tmpstr=linphone_friend_get_addr(lf);
|
||||
gtk_entry_set_text(GTK_ENTRY(lookup_widget(w,"sipaddr")),tmpstr);
|
||||
g_free(tmpstr);
|
||||
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(lookup_widget(w,"pol")),lf->pol);
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(w,"send_subscribe")),lf->subscribe);
|
||||
|
||||
gtk_widget_show(w);
|
||||
if (ab!=NULL) g_object_set_data(G_OBJECT(w),"address_book",(gpointer)ab);
|
||||
return w;
|
||||
}
|
||||
|
||||
GtkWidget * subscriber_edit(LinphoneFriend *lf){
|
||||
GtkWidget *w=contact_edit(lf,NULL);
|
||||
g_object_set_data(G_OBJECT(w),"add",GINT_TO_POINTER(TRUE));
|
||||
return w;
|
||||
}
|
||||
|
||||
gint contact_ok(GtkWidget *dialog){
|
||||
gchar *name,*sipaddr;
|
||||
gchar *url;
|
||||
gboolean add=FALSE;
|
||||
GtkWidget *ab;
|
||||
LinphoneFriend *lf;
|
||||
int err;
|
||||
lf=(LinphoneFriend*)g_object_get_data(G_OBJECT(dialog),"friend_ref");
|
||||
add=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(dialog),"add"));
|
||||
name=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"name")),0,-1);
|
||||
sipaddr=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(dialog,"sipaddr")),0,-1);
|
||||
url=g_strdup_printf("%s <%s>",name,sipaddr);
|
||||
/* workaround a bug in osip ? */
|
||||
/* something doesn't like addresses like "machin <<sip:truc@bidule>>" */
|
||||
if (strchr(sipaddr,'<')==NULL){
|
||||
err=linphone_friend_set_sip_addr(lf,url);
|
||||
}else err=-1;
|
||||
if (err<0){
|
||||
linphone_gnome_ui_display_something(get_uiobj(),GTK_MESSAGE_WARNING,_("Bad sip address: a sip address looks like sip:user@domain"));
|
||||
linphone_friend_destroy(lf);
|
||||
g_free(name);
|
||||
g_free(sipaddr);
|
||||
g_free(url);
|
||||
return -1;
|
||||
}
|
||||
g_free(name);
|
||||
g_free(sipaddr);
|
||||
g_free(url);
|
||||
linphone_friend_set_proxy(lf,proxy_combo_box_get_selected(lookup_widget(dialog,"proxy")));
|
||||
linphone_friend_set_inc_subscribe_policy(lf,gtk_combo_box_get_active(GTK_COMBO_BOX(lookup_widget(dialog,"pol"))));
|
||||
linphone_friend_send_subscribe(lf,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(dialog,"send_subscribe"))));
|
||||
if (add){
|
||||
linphone_core_add_friend(get_core(),lf);
|
||||
}
|
||||
else linphone_friend_done(lf);
|
||||
/* ask the address book to redraw itself */
|
||||
ab=g_object_get_data(G_OBJECT(dialog),"address_book");
|
||||
if (ab!=NULL) fill_address_book(lookup_widget(ab,"address_list"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum{
|
||||
SIP_ADDRESS_COLUMN,
|
||||
FRIEND_REFERENCE,
|
||||
AB_NCOLUMNS
|
||||
};
|
||||
|
||||
void choose_address_and_close(GtkWidget *ab){
|
||||
GtkTreeSelection *select;
|
||||
GtkWidget *addressentry=get_main_window()->addressentry;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
gchar *address=NULL;
|
||||
GtkWidget *address_list=lookup_widget(ab,"address_list");
|
||||
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list));
|
||||
if (select==NULL) return;
|
||||
if (gtk_tree_selection_get_selected (select, &model, &iter))
|
||||
{
|
||||
gtk_tree_model_get (model, &iter,SIP_ADDRESS_COLUMN , &address, -1);
|
||||
}
|
||||
if (address!=NULL){
|
||||
gtk_entry_set_text (GTK_ENTRY(addressentry),address);
|
||||
g_free(address);
|
||||
}
|
||||
gtk_widget_destroy(ab);
|
||||
}
|
||||
void
|
||||
address_book_close (GtkWidget *object,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_widget_destroy(gtk_widget_get_toplevel(object));
|
||||
}
|
||||
|
||||
void address_selection_changed_cb(GtkTreeSelection *selection, gpointer data)
|
||||
{
|
||||
|
||||
}
|
||||
gboolean address_button_press(GtkWidget *widget,GdkEventButton *event,gpointer user_data)
|
||||
{
|
||||
GtkWidget *ab=(GtkWidget*)user_data;
|
||||
if (event->type==GDK_2BUTTON_PRESS){
|
||||
choose_address_and_close(ab);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void fill_address_book(GtkWidget *address_list){
|
||||
GtkListStore *store;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
MSList *elem;
|
||||
gchar *tmpstr;
|
||||
/* fill the store */
|
||||
elem=linphone_core_get_friend_list(get_core());
|
||||
model=gtk_tree_view_get_model(GTK_TREE_VIEW(address_list));
|
||||
store=GTK_LIST_STORE(model);
|
||||
gtk_list_store_clear(store);
|
||||
for(;elem!=NULL;elem=ms_list_next(elem)){
|
||||
LinphoneFriend *lf=(LinphoneFriend*)elem->data;
|
||||
tmpstr=linphone_friend_get_url(lf);
|
||||
gtk_list_store_append(store,&iter);
|
||||
gtk_list_store_set(store,&iter,SIP_ADDRESS_COLUMN,tmpstr,FRIEND_REFERENCE,(gpointer)lf,-1);
|
||||
ms_free(tmpstr);
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *create_and_fill_address_book(){
|
||||
GtkListStore *store;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeSelection *select;
|
||||
GtkWidget *address_list;
|
||||
GtkWidget *ret=create_address_book();
|
||||
|
||||
address_list=lookup_widget(ret,"address_list");
|
||||
store = gtk_list_store_new (AB_NCOLUMNS, G_TYPE_STRING,G_TYPE_POINTER);
|
||||
gtk_tree_view_set_model(GTK_TREE_VIEW(address_list),GTK_TREE_MODEL(store));
|
||||
g_object_unref(G_OBJECT(store));
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes (_("Contact list"),
|
||||
renderer,
|
||||
"text", SIP_ADDRESS_COLUMN,
|
||||
NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (address_list), column);
|
||||
|
||||
/* Setup the selection handler */
|
||||
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list));
|
||||
gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
|
||||
g_signal_connect (G_OBJECT (select), "changed",
|
||||
G_CALLBACK (address_selection_changed_cb),
|
||||
NULL);
|
||||
|
||||
/* setup handler for double click */
|
||||
g_signal_connect(G_OBJECT(address_list),"button-press-event",G_CALLBACK(address_button_press),(gpointer)ret);
|
||||
|
||||
fill_address_book(address_list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
on_modify_address_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTreeSelection *select;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
GtkWidget *address_list=lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(button)),"address_list");
|
||||
|
||||
/* change the address in the view */
|
||||
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list));
|
||||
if (gtk_tree_selection_get_selected (select, &model, &iter))
|
||||
{
|
||||
LinphoneFriend *lf=NULL;
|
||||
gtk_tree_model_get(model,&iter,FRIEND_REFERENCE,&lf,-1);
|
||||
contact_edit(lf,gtk_widget_get_toplevel(GTK_WIDGET(button)));
|
||||
}
|
||||
}
|
||||
|
||||
void on_add_address_clicked(GtkButton *button,gpointer user_data)
|
||||
{
|
||||
LinphoneFriend *lf=linphone_friend_new();
|
||||
contact_new(lf,gtk_widget_get_toplevel(GTK_WIDGET(button)));
|
||||
}
|
||||
|
||||
void on_remove_address_clicked(GtkButton *button,gpointer user_data)
|
||||
{
|
||||
GtkTreeSelection *select;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
GtkWidget *address_list=lookup_widget(gtk_widget_get_toplevel(GTK_WIDGET(button)),"address_list");
|
||||
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (address_list));
|
||||
if (gtk_tree_selection_get_selected (select, &model, &iter))
|
||||
{
|
||||
LinphoneFriend *lf=NULL;
|
||||
gtk_tree_model_get(model,&iter,FRIEND_REFERENCE,&lf,-1);
|
||||
linphone_core_remove_friend(get_core(),lf);
|
||||
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
|
||||
}
|
||||
}
|
||||
|
||||
void on_select_address_clicked(GtkButton *button,gpointer user_data)
|
||||
{
|
||||
choose_address_and_close(gtk_widget_get_toplevel(GTK_WIDGET(button)));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_contact_box_response (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
gpointer user_data)
|
||||
{
|
||||
switch (response_id){
|
||||
case GTK_RESPONSE_OK:
|
||||
contact_ok(GTK_WIDGET(dialog));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
gtk_widget_destroy(GTK_WIDGET(dialog));
|
||||
}
|
||||
28
linphone/gnome/addressbook.h
Normal file
28
linphone/gnome/addressbook.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/***************************************************************************
|
||||
addressbook.h -
|
||||
-------------------
|
||||
begin : Wed Jan 30 2002
|
||||
copyright : (C) 2002 by Simon Morlat
|
||||
email : 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef ADDRESSBOOK_H
|
||||
#define ADDRESSBOOK_H
|
||||
|
||||
GtkWidget *create_and_fill_address_book();
|
||||
void show_address_book();
|
||||
GtkWidget * contact_new(LinphoneFriend *lf, GtkWidget *ab);
|
||||
GtkWidget * contact_edit(LinphoneFriend *lf, GtkWidget *ab);
|
||||
GtkWidget * subscriber_edit(LinphoneFriend *lf);
|
||||
|
||||
#endif
|
||||
182
linphone/gnome/applet.c
Normal file
182
linphone/gnome/applet.c
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
/***************************************************************************
|
||||
applet.c - Applet code for linphone's gnome
|
||||
interface
|
||||
-------------------
|
||||
begin : Sat Dec 14 2002
|
||||
copyright : (C) 2001 by Simon Morlat
|
||||
email : 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "linphone.h"
|
||||
#include <panel-applet.h>
|
||||
|
||||
#define get_uiobj() (uiobj)
|
||||
|
||||
LinphoneCore core;
|
||||
LinphoneGnomeUI ui;
|
||||
static int show=0;
|
||||
static gulong signal_ref;
|
||||
static GtkWidget *applet_button=NULL;
|
||||
static GdkPixbuf *original_icon=NULL;
|
||||
static GtkWidget *icon=NULL;
|
||||
|
||||
void draw_icon(GtkWidget *button, int size)
|
||||
{
|
||||
GdkPixbuf *resized;
|
||||
if (original_icon==NULL){
|
||||
original_icon=gdk_pixbuf_new_from_file(PACKAGE_DATA_DIR "/pixmaps/linphone/linphone2.xpm",
|
||||
NULL);
|
||||
g_return_if_fail( original_icon!=NULL);
|
||||
}
|
||||
if (icon!=NULL){
|
||||
gtk_container_remove(GTK_CONTAINER(button),icon);
|
||||
gtk_widget_destroy(icon);
|
||||
}
|
||||
resized=gdk_pixbuf_scale_simple(original_icon,size,size,GDK_INTERP_BILINEAR);
|
||||
g_return_if_fail(resized!=NULL);
|
||||
icon=gtk_image_new_from_pixbuf(resized);
|
||||
g_return_if_fail(icon!=NULL);
|
||||
gdk_pixbuf_unref(resized);
|
||||
gtk_container_add(GTK_CONTAINER(button),icon);
|
||||
gtk_widget_show(icon);
|
||||
}
|
||||
|
||||
void linphone_applet_about_cb(gpointer p)
|
||||
{
|
||||
GtkWidget *about2;
|
||||
about2 = create_about2 ();
|
||||
gtk_widget_show (about2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void applet_change_pixel_size(GtkWidget *applet, int size)
|
||||
{
|
||||
g_return_if_fail(applet_button!=NULL);
|
||||
draw_icon(applet_button,size);
|
||||
}
|
||||
|
||||
static void applet_destroy_cb(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
if (get_uiobj()->main_window.window!=NULL){
|
||||
gtk_widget_destroy(get_uiobj()->main_window.window);
|
||||
}
|
||||
linphone_gnome_uninit(get_uiobj());
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gui_destroy_cb (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
linphone_gnome_ui_uninit(get_uiobj());
|
||||
show=0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean button_press_cb(GtkWidget *applet, GdkEventButton* event, gpointer data)
|
||||
{
|
||||
if (event->button!=1) return FALSE;
|
||||
if (show){
|
||||
g_signal_handlers_disconnect_by_func(G_OBJECT(get_uiobj()->main_window.window),
|
||||
G_CALLBACK(gui_destroy_cb),NULL);
|
||||
linphone_gnome_ui_hide(get_uiobj());
|
||||
|
||||
show=0;
|
||||
}else {
|
||||
linphone_gnome_ui_show(get_uiobj());
|
||||
signal_ref=g_signal_connect(G_OBJECT(get_uiobj()->main_window.window),
|
||||
"destroy",
|
||||
G_CALLBACK(gui_destroy_cb),NULL);
|
||||
show=1;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const BonoboUIVerb linphone_applet_menu_verbs [] = {
|
||||
BONOBO_UI_UNSAFE_VERB ("About", linphone_applet_about_cb),
|
||||
BONOBO_UI_VERB_END
|
||||
};
|
||||
|
||||
static gboolean
|
||||
linphone_applet_fill (PanelApplet *applet)
|
||||
{
|
||||
gint size=panel_applet_get_size(applet);
|
||||
|
||||
applet_button=gtk_frame_new(NULL);
|
||||
gtk_container_add(GTK_CONTAINER(applet),applet_button);
|
||||
gtk_widget_show(applet_button);
|
||||
|
||||
draw_icon(applet_button,size);
|
||||
|
||||
g_signal_connect(G_OBJECT(applet),"button-press-event",G_CALLBACK(button_press_cb),NULL);
|
||||
|
||||
|
||||
g_signal_connect(G_OBJECT(applet),"change_size",
|
||||
G_CALLBACK(applet_change_pixel_size),
|
||||
NULL);
|
||||
|
||||
|
||||
g_signal_connect (G_OBJECT (applet), "destroy",
|
||||
G_CALLBACK (applet_destroy_cb), NULL);
|
||||
|
||||
//sizehint = panel_applet_get_size (PANEL_APPLET (applet));
|
||||
panel_applet_setup_menu_from_file (applet,
|
||||
NULL,
|
||||
"GNOME_LinphoneApplet.xml",
|
||||
NULL,
|
||||
linphone_applet_menu_verbs,
|
||||
NULL);
|
||||
|
||||
/* tracing for osip */
|
||||
TRACE_INITIALIZE(5,stdout);
|
||||
|
||||
linphone_gnome_init(&ui,&core);
|
||||
gtk_widget_show_all (GTK_WIDGET (applet));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
linphone_applet_factory (PanelApplet *applet,
|
||||
const gchar *iid,
|
||||
gpointer data)
|
||||
{
|
||||
static int instances=0;
|
||||
GtkWidget *dialog;
|
||||
if (!strcmp (iid, "OAFIID:GNOME_LinphoneApplet")){
|
||||
if (instances>0){
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW(applet),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_WARNING,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
(const gchar*) _("Cannot run multiples instances of the linphone applet."));
|
||||
/* Destroy the dialog when the user responds to it (e.g. clicks a button) */
|
||||
g_signal_connect_swapped (G_OBJECT (dialog), "response",
|
||||
G_CALLBACK (gtk_widget_destroy),
|
||||
G_OBJECT (dialog));
|
||||
gtk_widget_show(GTK_WIDGET(dialog));
|
||||
return FALSE;
|
||||
}
|
||||
return linphone_applet_fill (applet);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define GNOMELOCALEDIR PACKAGE_LOCALE_DIR
|
||||
|
||||
PANEL_APPLET_BONOBO_FACTORY ("OAFIID:GNOME_LinphoneApplet_Factory",
|
||||
PANEL_TYPE_APPLET,
|
||||
"linphone_applet",
|
||||
"0",
|
||||
linphone_applet_factory,
|
||||
NULL)
|
||||
695
linphone/gnome/callbacks.c
Normal file
695
linphone/gnome/callbacks.c
Normal file
|
|
@ -0,0 +1,695 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr)
|
||||
|
||||
callbacks.c -- gtk callbacks, and osipua callbacks.
|
||||
|
||||
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
|
||||
|
||||
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"
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#define get_core() (uiobj->core)
|
||||
#define get_main_window() (&uiobj->main_window)
|
||||
#define get_uiobj() (uiobj)
|
||||
|
||||
void
|
||||
on_about1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *about2;
|
||||
about2 = create_about2 ();
|
||||
gtk_widget_show (about2);
|
||||
}
|
||||
|
||||
|
||||
gint
|
||||
on_prop1_close (GnomeDialog *gnomedialog,
|
||||
gpointer user_data)
|
||||
{
|
||||
LinphoneMainWindow *obj=get_main_window();
|
||||
gnome_appbar_clear_stack( GNOME_APPBAR(obj->status_bar));
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
on_parametres1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
LinphoneGnomeUI *ui=get_uiobj();
|
||||
linphone_property_box_init(&ui->propbox);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
on_user_manual1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
gnome_help_display("index.xml",NULL,NULL);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
on_play_vol_button_release_event (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
int vol;
|
||||
vol=(gtk_range_get_adjustment(GTK_RANGE(widget)))->value;
|
||||
linphone_core_set_play_level(get_core(),vol);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
on_rec_vol_button_release_event (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
int vol;
|
||||
vol=(gtk_range_get_adjustment(GTK_RANGE(widget)))->value;
|
||||
linphone_core_set_rec_level(get_core(),vol);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
on_ring_vol_button_release_event (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
int vol;
|
||||
vol=(gtk_range_get_adjustment(GTK_RANGE(widget)))->value;
|
||||
linphone_core_set_ring_level(get_core(),vol);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_prop1_help (GnomePropertyBox *gnomepropertybox,
|
||||
gint arg1,
|
||||
gpointer user_data)
|
||||
{
|
||||
gnome_help_display("index.html",NULL,NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
on_fermer1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
linphone_gnome_ui_hide(get_uiobj());
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
/*this is when the panel size changes*/
|
||||
void applet_change_pixel_size(GtkWidget *w, int size, gpointer data)
|
||||
{
|
||||
GtkWidget *pixmap,*button;
|
||||
|
||||
pixmap=gtk_object_get_data(GTK_OBJECT(applet),"applet_pixmap");
|
||||
button=(GtkWidget*)gtk_object_get_data(GTK_OBJECT(applet),"applet_button");
|
||||
if (button==NULL)
|
||||
{
|
||||
printf("Cannot find applet button\n");
|
||||
return;
|
||||
}
|
||||
if (pixmap!=NULL) gtk_widget_destroy(pixmap);
|
||||
pixmap = gnome_pixmap_new_from_xpm_d_at_size(linphone2_xpm,
|
||||
size-4, size-4);
|
||||
gtk_object_set_data(GTK_OBJECT(applet),"applet_pixmap",pixmap);
|
||||
gtk_widget_show(pixmap);
|
||||
gtk_container_add(GTK_CONTAINER(button), pixmap);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
on_adresse_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
show_address_book();
|
||||
}
|
||||
|
||||
void on_address_book_show(GtkWidget *widget,gpointer user_data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
on_showmore_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data)
|
||||
{
|
||||
gint state;
|
||||
GtkWidget *optioncontrols=get_main_window()->optioncontrols;
|
||||
state=gtk_toggle_button_get_active(togglebutton);
|
||||
if (state) gtk_widget_show(optioncontrols);
|
||||
else {
|
||||
gtk_widget_hide(optioncontrols);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_useRPC_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data)
|
||||
{
|
||||
#ifdef VINCENT_MAURY_RSVP
|
||||
LinphoneCore *lc=get_core();
|
||||
gboolean state;
|
||||
state=gtk_toggle_button_get_active(togglebutton);
|
||||
/* change RPC settings according to state */
|
||||
if (state)
|
||||
{
|
||||
if (linphone_core_set_rpc_mode(lc,1)!=0) /* set rpc on */
|
||||
{
|
||||
printf("RPC error. unable to set rpc on !\n");
|
||||
printf("Check to see if RPC server is running\n");
|
||||
gtk_toggle_button_set_active(togglebutton,FALSE);
|
||||
/*linphone_core_set_rpc_mode(lc,0);*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (linphone_core_set_rpc_mode(lc,0)!=0) /* set rpc off */
|
||||
printf("RPC error. That's impossible !!\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
on_useRSVP_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data)
|
||||
{
|
||||
#ifdef VINCENT_MAURY_RSVP
|
||||
LinphoneCore *lc=get_core();
|
||||
LinphoneGnomeUI *ui=get_uiobj();
|
||||
gboolean state;
|
||||
state=gtk_toggle_button_get_active(togglebutton);
|
||||
/* change the QoS settings function of the state */
|
||||
if (state)
|
||||
{
|
||||
linphone_core_set_rsvp_mode(lc,1); /* set RSVP on */
|
||||
gtk_widget_show(lookup_widget(ui->propbox.prop,"useRPC")); /* show RPC checkbox */
|
||||
}
|
||||
else
|
||||
{
|
||||
linphone_core_set_rsvp_mode(lc,0); /* set RSVP off */
|
||||
/* uncheck RPC if necessary and hide RPC checkbox */
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
|
||||
lookup_widget(ui->propbox.prop,"useRPC")),FALSE);
|
||||
gtk_widget_hide(lookup_widget(ui->propbox.prop,"useRPC"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef VINCENT_MAURY_RSVP
|
||||
/* callback called when you click the yes/no dialog box
|
||||
* send yes or no to the core_change_qos which knows the question
|
||||
* and will be able to ajust qos */
|
||||
void dialog_click (GtkDialog *dialog,gint arg1,gpointer user_data)
|
||||
{
|
||||
LinphoneCore *lc=get_core();
|
||||
if (lc->call==NULL)
|
||||
return;
|
||||
|
||||
if (arg1==GTK_RESPONSE_YES)
|
||||
{
|
||||
printf("YES\n");
|
||||
linphone_core_change_qos(lc, 1); /* 1 = yes */
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("NO\n");
|
||||
linphone_core_change_qos(lc, 0); /* 0 = no */
|
||||
}
|
||||
gtk_widget_destroy((GtkWidget*)dialog);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
on_alt_href_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
gchar *url;
|
||||
GtkWidget *label;
|
||||
osip_from_t * from;
|
||||
LinphoneGnomeUI *ui=get_uiobj();
|
||||
label=GTK_BIN(button)->child;
|
||||
gtk_label_get(GTK_LABEL(label),&url);
|
||||
osip_from_init(&from);
|
||||
if ( osip_from_parse(from,url) <0){
|
||||
/* do something here */
|
||||
}else
|
||||
{ /* it was a sip url, so display it in the entry*/
|
||||
gtk_entry_set_text(GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(ui->main_window.addressentry))),url);
|
||||
}
|
||||
osip_from_free(from);
|
||||
}
|
||||
|
||||
void
|
||||
on_alt_href_realize (GtkWidget *widget,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkCursor *cursor = gdk_cursor_new(GDK_HAND2);
|
||||
gdk_window_set_cursor(widget->window, cursor);
|
||||
gdk_cursor_destroy(cursor);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_3_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"3");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dmtf_2_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"2");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_1_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"1");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_4_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"4");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_5_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"5");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_6_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"6");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_7_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"7");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_8_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"8");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_9_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"9");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_star_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"*");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_0_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"0");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_pound_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *dtmf_entry=get_main_window()->dtmfentry;
|
||||
gtk_entry_append_text(GTK_ENTRY(dtmf_entry),"#");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_dtmf_entry_changed (GtkEditable *editable,
|
||||
gpointer user_data)
|
||||
{
|
||||
gchar *dtmfs;
|
||||
gint len;
|
||||
/* get the last entry in the text box and plays it */
|
||||
dtmfs=gtk_editable_get_chars(editable,0,-1);
|
||||
g_return_if_fail(dtmfs!=NULL);
|
||||
len=strlen(dtmfs);
|
||||
if (len>0){
|
||||
g_message("Sending dtmf %c",dtmfs[len-1]);
|
||||
linphone_core_send_dtmf(get_uiobj()->core,dtmfs[len-1]);
|
||||
}
|
||||
g_free(dtmfs);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_exit1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
#ifdef LINPHONE_APPLET
|
||||
#else
|
||||
gtk_widget_destroy(get_uiobj()->main_window.window);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void on_app1_destroy(GtkWidget *app1, gpointer user_data)
|
||||
{
|
||||
#ifdef LINPHONE_APPLET
|
||||
#else
|
||||
gtk_main_quit();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
on_display_ab_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
show_address_book();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_inc_subscr_dialog_response (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
gpointer user_data)
|
||||
{
|
||||
LinphoneFriend *lf=(LinphoneFriend*)g_object_get_data(G_OBJECT(dialog),"friend_ref");
|
||||
switch(response_id){
|
||||
case GTK_RESPONSE_ACCEPT:
|
||||
subscriber_edit(lf);
|
||||
break;
|
||||
case GTK_RESPONSE_REJECT:
|
||||
linphone_core_reject_subscriber(get_core(),lf);
|
||||
break;
|
||||
}
|
||||
gtk_widget_destroy(GTK_WIDGET(dialog));
|
||||
}
|
||||
|
||||
void authentication_dialog_ok(GtkWidget *w)
|
||||
{
|
||||
gchar *realm,*username,*userid,*passwd;
|
||||
LinphoneAuthInfo *info;
|
||||
realm=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"realm")),0,-1);
|
||||
username=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"username")),0,-1);
|
||||
userid=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"userid")),0,-1);
|
||||
passwd=gtk_editable_get_chars(GTK_EDITABLE(lookup_widget(w,"passwd")),0,-1);
|
||||
info=linphone_auth_info_new(username,userid,passwd,NULL,realm);
|
||||
linphone_core_add_auth_info(get_core(),info);
|
||||
g_free(username);
|
||||
g_free(userid);
|
||||
g_free(passwd);
|
||||
g_free(realm);
|
||||
}
|
||||
|
||||
void
|
||||
on_authentication_dialog_response (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
gpointer user_data)
|
||||
{
|
||||
switch(response_id){
|
||||
case GTK_RESPONSE_OK:
|
||||
authentication_dialog_ok(GTK_WIDGET(dialog));
|
||||
gtk_widget_destroy(GTK_WIDGET(dialog));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
on_clear_auth_info_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
linphone_core_clear_all_auth_info(get_core());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_call_history_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data)
|
||||
{
|
||||
linphone_gnome_show_call_logs_window(get_uiobj());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_call_logs_response (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_widget_destroy(GTK_WIDGET(dialog));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_call_logs_destroy (GtkObject *object,
|
||||
gpointer user_data)
|
||||
{
|
||||
get_uiobj()->logs=NULL;
|
||||
}
|
||||
|
||||
|
||||
static void completion_add_text(GtkEntry *entry, const char *text){
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model=gtk_entry_completion_get_model(gtk_entry_get_completion(entry));
|
||||
|
||||
if (gtk_tree_model_get_iter_first(model,&iter)){
|
||||
do {
|
||||
gchar *uri=NULL;
|
||||
gtk_tree_model_get(model,&iter,0,&uri,-1);
|
||||
if (uri!=NULL){
|
||||
if (strcmp(uri,text)==0) {
|
||||
/*remove text */
|
||||
gtk_list_store_remove(GTK_LIST_STORE(model),&iter);
|
||||
g_free(uri);
|
||||
break;
|
||||
}
|
||||
g_free(uri);
|
||||
}
|
||||
}while (gtk_tree_model_iter_next(model,&iter));
|
||||
}
|
||||
/* and prepend it on top of the list */
|
||||
gtk_list_store_prepend(GTK_LIST_STORE(model),&iter);
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,text,-1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_callbutton_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
LinphoneGnomeUI *ui=get_uiobj();
|
||||
LinphoneCore *lc=get_core();
|
||||
GtkEntry *entry=GTK_ENTRY(ui->main_window.addressentry);
|
||||
|
||||
if (lc->call==NULL){
|
||||
const gchar *sipurl=NULL;
|
||||
int err;
|
||||
/* we have no dialog in progress */
|
||||
/* get the url to call */
|
||||
sipurl=gtk_entry_get_text(entry);
|
||||
err=linphone_core_invite(lc,sipurl);
|
||||
if (err==0) completion_add_text(entry,sipurl);
|
||||
}else {
|
||||
linphone_core_accept_call(lc,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
on_hangup_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
LinphoneGnomeUI *ui=get_uiobj();
|
||||
LinphoneCore *lc=get_core();
|
||||
if (lc->call!=NULL){
|
||||
/* same trick here as for linphone_core_accept_dialog: defer it to gtk's idle loop */
|
||||
gtk_window_set_title(GTK_WINDOW(ui->main_window.window),"linphone");
|
||||
linphone_core_terminate_call(lc,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *chatroom_new(const gchar *url, LinphoneChatRoom *cr){
|
||||
GtkWidget *gcr=NULL;
|
||||
if (cr==NULL)
|
||||
cr=linphone_core_create_chat_room(get_core(),url);
|
||||
if (cr!=NULL){
|
||||
gchar *tmp;
|
||||
gcr=create_chatroom();
|
||||
g_object_set_data(G_OBJECT(gcr),"chatroom",(gpointer)cr);
|
||||
linphone_chat_room_set_user_data(cr,(gpointer)gcr);
|
||||
tmp=g_strdup_printf(_("Chat with %s"),url);
|
||||
gtk_window_set_title(GTK_WINDOW(gcr),tmp);
|
||||
g_free(tmp);
|
||||
}
|
||||
return gcr;
|
||||
}
|
||||
|
||||
void chatroom_append(GtkWidget *gcr, const gchar *from, const gchar *message){
|
||||
GtkTextBuffer *tb;
|
||||
gchar *str;
|
||||
GtkTextIter enditer;
|
||||
GtkTextView *tv=GTK_TEXT_VIEW(lookup_widget(gcr,"chattext"));
|
||||
tb=gtk_text_view_get_buffer(tv);
|
||||
g_return_if_fail(tb!=NULL);
|
||||
gtk_text_buffer_get_end_iter(tb,&enditer);
|
||||
str=g_strdup_printf("[%s]\t:%s\n",from,message);
|
||||
gtk_text_buffer_insert(tb,&enditer,str,strlen(str));
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
void chatroom_close(GtkWidget *gcr){
|
||||
LinphoneChatRoom *cr;
|
||||
cr=(LinphoneChatRoom*)g_object_get_data(G_OBJECT(gcr),"chatroom");
|
||||
linphone_chat_room_destroy(cr);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_chat_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
gchar *sipurl;
|
||||
|
||||
sipurl=gtk_editable_get_chars(GTK_EDITABLE(get_main_window()->addressentry),0,-1);
|
||||
GtkWidget *gcr=chatroom_new(sipurl,NULL);
|
||||
if (gcr!=NULL) gtk_widget_show(gcr);
|
||||
g_free(sipurl);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_chatbox_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_widget_destroy(gtk_widget_get_toplevel(GTK_WIDGET(button)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
on_chatentry_activate (GtkEntry *entry,
|
||||
gpointer user_data)
|
||||
{
|
||||
LinphoneChatRoom *cr;
|
||||
gchar *text;
|
||||
text=gtk_editable_get_chars(GTK_EDITABLE(entry),0,-1);
|
||||
if (strlen(text)>0){
|
||||
GtkWidget *gcr=gtk_widget_get_toplevel(GTK_WIDGET(entry));
|
||||
cr=(LinphoneChatRoom*)g_object_get_data(G_OBJECT(gcr),"chatroom");
|
||||
linphone_chat_room_send_message(cr,text);
|
||||
chatroom_append(gcr,linphone_core_get_primary_contact(get_core()),text);
|
||||
gtk_editable_delete_text(GTK_EDITABLE(entry),0,-1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
on_chatroom_destroy (GtkObject *object,
|
||||
gpointer user_data)
|
||||
{
|
||||
chatroom_close(GTK_WIDGET(object));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
on_addressentry_activate (GtkEntry *entry,
|
||||
gpointer user_data)
|
||||
{
|
||||
on_callbutton_clicked(NULL,NULL);
|
||||
}
|
||||
|
||||
void
|
||||
on_addressentry_destroy (GtkObject *object,
|
||||
gpointer user_data)
|
||||
{
|
||||
linphone_gnome_save_uri_history(get_uiobj());
|
||||
}
|
||||
|
||||
void
|
||||
on_video_enabled_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data)
|
||||
{
|
||||
linphone_core_enable_video(get_core(),gtk_toggle_button_get_active(togglebutton));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_echocancelation_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data)
|
||||
{
|
||||
linphone_core_enable_echo_cancelation(get_core(),
|
||||
gtk_toggle_button_get_active(togglebutton));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
540
linphone/gnome/callbacks.h
Normal file
540
linphone/gnome/callbacks.h
Normal file
|
|
@ -0,0 +1,540 @@
|
|||
#include <gnome.h>
|
||||
|
||||
|
||||
void
|
||||
on_app1_destroy (GtkObject *object,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_adresse_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_parametres1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_fermer1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_exit1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_about1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_user_manual1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_greenbutton_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_redbutton_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_showmore_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean
|
||||
on_play_vol_button_release_event (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean
|
||||
on_rec_vol_button_release_event (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean
|
||||
on_ring_vol_button_release_event (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_reachable (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_busy (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_minutesaway_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_away (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_do_not_disturb (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_moved_tmply (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_alt_serv (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_contact_field_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_presence_validate_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_entry_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_3_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dmtf_2_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_1_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_4_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_5_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_6_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_7_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_8_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_9_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_star_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_0_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_dtmf_pound_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_propertybox1_apply (GnomePropertyBox *propertybox,
|
||||
gint page_num,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean
|
||||
on_prop1_close (GnomeDialog *gnomedialog,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_prop1_help (GnomePropertyBox *propertybox,
|
||||
gint page_num,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean
|
||||
on_hscale1_button_release_event (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_audioport_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_sipport_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_user_name_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_domain_name_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_registrar_checked_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_rsvp_checked_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
void
|
||||
on_redirect_button_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_proxy_button_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_obproxy_button_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_registrar_addr_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_reg_passwd_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_address_of_record_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_aucodec_up_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_aucodec_down_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_aucodec_enable_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_aucodec_disable_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_sounddriver_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_source_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_autokill_button1_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_address_book_show (GtkWidget *widget,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_add_address_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_remove_address_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_select_address_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_modify_address_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_alt_href_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_alt_href_realize (GtkWidget *widget,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
void
|
||||
on_exit1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
address_book_close (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_card_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_audio_jittcomp_value_changed (GtkRange *range,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_enable_nat_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_nat_address_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_display_ab_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_ringfileentry_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_ringpreview_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean
|
||||
on_property_box_closed (GnomeDialog *gnomedialog,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_address_book_close (GtkObject *object,
|
||||
gpointer user_data);
|
||||
|
||||
#ifndef VERSION
|
||||
# define VERSION LINPHONE_VERSION
|
||||
#endif
|
||||
|
||||
void
|
||||
on_addfriend_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_removefriend_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_add_adbk_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_addfriend_dialog_response (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_friendlist_row_activated (GtkTreeView *treeview,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *column,
|
||||
gpointer user_data);
|
||||
void
|
||||
on_useRSVP_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_useRPC_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
#ifdef VINCENT_MAURY_RSVP
|
||||
void
|
||||
dialog_click (GtkDialog *dialog,
|
||||
gint arg1,
|
||||
gpointer user_data);
|
||||
#endif
|
||||
|
||||
void
|
||||
on_proxy_config_box_response (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_removeproxy_button_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_addproxy_button_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_editproxy_button_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
void
|
||||
on_contact_box_response (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_inc_subscr_dialog_response (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_ob_proxy_changed (GtkComboBox *combobox,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_authentication_dialog_response (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_clear_auth_info_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_use_sipinfo_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_guess_hostname_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_call_history_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_call_logs_response (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_call_logs_destroy (GtkObject *object,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_enable_ipv6_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_play_card_changed (GtkComboBox *combobox,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_capt_card_changed (GtkComboBox *combobox,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_ring_card_changed (GtkComboBox *combobox,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_callbutton_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_chatbox_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_chatentry_activate (GtkEntry *entry,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_hangup_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_chat_clicked (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_chatroom_destroy (GtkObject *object,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_ring_card_changed (GtkComboBox *combobox,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_addressentry_editing_done (GtkCellEditable *celleditable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_addressentry_destroy (GtkObject *object,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean
|
||||
on_addressentry_key_pressed (GtkWidget *widget,
|
||||
GdkEventKey *event,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_addressentry_changed (GtkComboBox *combobox,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_addressentry_activate (GtkEntry *entry,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_addressentry_destroy (GtkObject *object,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_download_bw_value_changed (GtkSpinButton *spinbutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_download_bw_editing_done (GtkCellEditable *celleditable,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_download_bw_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean
|
||||
on_upload_bw_output (GtkSpinButton *spinbutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_upload_bw_change_value (GtkSpinButton *spinbutton,
|
||||
GtkScrollType scroll,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_upload_bw_value_changed (GtkSpinButton *spinbutton,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean
|
||||
on_upload_bw_leave_notify_event (GtkWidget *widget,
|
||||
GdkEventCrossing *event,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_video_enabled_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_echocancelation_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_no_nat_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_use_stun_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_static_nat_toggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_stun_server_changed (GtkEditable *editable,
|
||||
gpointer user_data);
|
||||
127
linphone/gnome/friends.c
Normal file
127
linphone/gnome/friends.c
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/***************************************************************************
|
||||
friends.c - display of friend's list
|
||||
|
||||
-------------------
|
||||
begin : Mon Dec 17 2001
|
||||
copyright : (C) 2001 by Simon Morlat
|
||||
email : 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "linphone.h"
|
||||
|
||||
|
||||
#define get_friend_list() (&uiobj->main_window.friendlist)
|
||||
#define get_core() (uiobj->core)
|
||||
#define get_main_window() (&uiobj->main_window)
|
||||
|
||||
enum{
|
||||
FRIEND_PRESENCE_IMG,
|
||||
FRIEND_SIP_ADDRESS,
|
||||
FRIEND_PRESENCE_STATUS,
|
||||
FRIEND_ID,
|
||||
FRIEND_LIST_NCOL
|
||||
};
|
||||
|
||||
void friend_list_set_friend_status(FriendList *fl, LinphoneFriend * fid, const gchar *url, const gchar *status, const gchar *img){
|
||||
GtkTreeIter iter;
|
||||
LinphoneFriend *tmp=0;
|
||||
gboolean found=FALSE;
|
||||
GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(fl->friendlist));
|
||||
if (gtk_tree_model_get_iter_first(model,&iter)) {
|
||||
do{
|
||||
gtk_tree_model_get(model,&iter,FRIEND_ID,&tmp,-1);
|
||||
//printf("tmp=%i, fid=%i",tmp,fid);
|
||||
if (fid==tmp) {
|
||||
GdkPixbuf *pixbuf;
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_STATUS,status,-1);
|
||||
pixbuf = create_pixbuf(img);
|
||||
if (pixbuf)
|
||||
{
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_IMG, pixbuf,-1);
|
||||
}
|
||||
found=TRUE;
|
||||
}
|
||||
}while(gtk_tree_model_iter_next(model,&iter));
|
||||
}
|
||||
if (found==FALSE){
|
||||
//printf("Adding new notifier\n");
|
||||
GdkPixbuf *pixbuf;
|
||||
gtk_list_store_append(GTK_LIST_STORE(model),&iter);
|
||||
gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_SIP_ADDRESS, url, FRIEND_PRESENCE_STATUS,status,FRIEND_ID,fid,-1);
|
||||
pixbuf = create_pixbuf(img);
|
||||
if (pixbuf) gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_IMG, pixbuf,-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
on_friendlist_row_activated (GtkTreeView *treeview,
|
||||
GtkTreePath *path,
|
||||
GtkTreeViewColumn *column,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTreeSelection *select;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
gchar* friend;
|
||||
select = gtk_tree_view_get_selection (treeview);
|
||||
if (gtk_tree_selection_get_selected (select, &model, &iter))
|
||||
{
|
||||
gtk_tree_model_get (model, &iter,FRIEND_SIP_ADDRESS , &friend, -1);
|
||||
gtk_entry_set_text(GTK_ENTRY(get_main_window()->addressentry),friend);
|
||||
g_free(friend);
|
||||
}
|
||||
}
|
||||
|
||||
void friend_list_init(FriendList *fl,LinphoneCore *lc,GtkWidget *mainwidget)
|
||||
{
|
||||
GtkListStore *store;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeSelection *select;
|
||||
|
||||
|
||||
store = gtk_list_store_new (FRIEND_LIST_NCOL, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
|
||||
fl->lc=lc;
|
||||
fl->friendlist=lookup_widget(mainwidget,"friendlist");
|
||||
/* need to add friends to the store here ...*/
|
||||
|
||||
gtk_tree_view_set_model(GTK_TREE_VIEW(fl->friendlist),GTK_TREE_MODEL(store));
|
||||
g_object_unref(G_OBJECT(store));
|
||||
|
||||
renderer = gtk_cell_renderer_pixbuf_new();
|
||||
column = gtk_tree_view_column_new_with_attributes (NULL,
|
||||
renderer,
|
||||
"pixbuf", FRIEND_PRESENCE_IMG,
|
||||
NULL);
|
||||
gtk_tree_view_column_set_min_width (column, 29);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (fl->friendlist), column);
|
||||
|
||||
renderer = gtk_cell_renderer_text_new ();
|
||||
column = gtk_tree_view_column_new_with_attributes (_("Name"),
|
||||
renderer,
|
||||
"text", FRIEND_SIP_ADDRESS,
|
||||
NULL);
|
||||
g_object_set (G_OBJECT(column), "resizable", TRUE, NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (fl->friendlist), column);
|
||||
|
||||
column = gtk_tree_view_column_new_with_attributes (_("Presence status"),
|
||||
renderer,
|
||||
"text", FRIEND_PRESENCE_STATUS,
|
||||
NULL);
|
||||
g_object_set (G_OBJECT(column), "resizable", TRUE, NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (fl->friendlist), column);
|
||||
|
||||
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (fl->friendlist));
|
||||
gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
|
||||
|
||||
}
|
||||
29
linphone/gnome/friends.h
Normal file
29
linphone/gnome/friends.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/***************************************************************************
|
||||
friends.h - display of friend's list
|
||||
|
||||
-------------------
|
||||
begin : Mon Dec 17 2001
|
||||
copyright : (C) 2001 by Simon Morlat
|
||||
email : 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <interface.h>
|
||||
|
||||
struct _FriendList {
|
||||
LinphoneCore *lc;
|
||||
GtkWidget *friendlist;
|
||||
};
|
||||
|
||||
typedef struct _FriendList FriendList;
|
||||
|
||||
void friend_list_init(FriendList *fl,LinphoneCore *lc,GtkWidget *mainwidget);
|
||||
void friend_list_set_friend_status(FriendList *fl, LinphoneFriend * fid, const gchar *url, const gchar *status, const gchar *img);
|
||||
102
linphone/gnome/gui_utils.c
Normal file
102
linphone/gnome/gui_utils.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
applet.c - some utils functions that cannot be set in interface.c.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
#include "linphone.h"
|
||||
|
||||
|
||||
/* creates the applet button*
|
||||
GtkWidget *create_applet()
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *button;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *applet;
|
||||
|
||||
applet = applet_widget_new("linphone_applet");
|
||||
|
||||
frame = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
|
||||
gtk_widget_show(frame);
|
||||
|
||||
vbox = gtk_vbox_new(FALSE, FALSE);
|
||||
gtk_container_add(GTK_CONTAINER(frame), vbox);
|
||||
gtk_widget_show(vbox);
|
||||
|
||||
button = gtk_button_new();
|
||||
gtk_widget_ref(button);
|
||||
GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_DEFAULT);
|
||||
GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_FOCUS);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, TRUE, 0);
|
||||
|
||||
|
||||
gtk_widget_show(button);
|
||||
applet_widget_add (APPLET_WIDGET (applet), frame);
|
||||
gtk_object_set_data_full(GTK_OBJECT(applet),"applet_button",button,(GtkDestroyNotify)gtk_widget_unref);
|
||||
gtk_signal_connect(GTK_OBJECT(button), "button_press_event",
|
||||
GTK_SIGNAL_FUNC(on_applet_clicked), NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(applet), "change_pixel_size",
|
||||
GTK_SIGNAL_FUNC(applet_change_pixel_size), NULL);
|
||||
applet_widget_set_tooltip( APPLET_WIDGET (applet),_("linphone"));
|
||||
gtk_widget_show(applet);
|
||||
return(applet);
|
||||
};
|
||||
|
||||
*/
|
||||
/* this just sets level adjustements for startup*/
|
||||
void set_levels(LinphoneGnomeUI *ui,gint reclev, gint playlev, gint ringlev)
|
||||
{
|
||||
GtkWidget *range;
|
||||
GtkWidget *window=ui->main_window.window;
|
||||
return;
|
||||
if (window)
|
||||
{
|
||||
range=lookup_widget(window,"rec_vol");
|
||||
gtk_adjustment_set_value (gtk_range_get_adjustment(GTK_RANGE(range)),(gfloat)reclev);
|
||||
range=lookup_widget(window,"play_vol");
|
||||
gtk_adjustment_set_value (gtk_range_get_adjustment(GTK_RANGE(range)),(gfloat)playlev);
|
||||
range=lookup_widget(window,"ring_vol");
|
||||
gtk_adjustment_set_value (gtk_range_get_adjustment(GTK_RANGE(range)),(gfloat)ringlev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void alt_ressource_display(LinphoneGnomeUI *ui,const gchar *url)
|
||||
{
|
||||
GtkWidget *href;
|
||||
GtkWidget *altdisplay;
|
||||
GtkLabel *label;
|
||||
gchar *pattern;
|
||||
|
||||
altdisplay=create_altressource();
|
||||
g_object_set_data(G_OBJECT(altdisplay),"ui",(gpointer)ui);
|
||||
href=lookup_widget(altdisplay,"alt_href");
|
||||
label=GTK_LABEL(GTK_BIN(href)->child);
|
||||
gtk_label_set_text(label,url);
|
||||
/* pattern used to set underline for string */
|
||||
pattern = g_strnfill(strlen(url), '_');
|
||||
gtk_label_set_pattern(label,pattern);
|
||||
g_free(pattern);
|
||||
gtk_widget_show(altdisplay);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue