[asterisk-commits] russell: branch group/xcon_bfcp r52582 - in
/team/group/xcon_bfcp: apps/xcon_...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Mon Jan 29 12:07:06 MST 2007
Author: russell
Date: Mon Jan 29 13:07:05 2007
New Revision: 52582
URL: http://svn.digium.com/view/asterisk?view=rev&rev=52582
Log:
add missing files from issue 7838
Added:
team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.c (with props)
team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.h (with props)
team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_gw.c (with props)
team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_gw.h (with props)
team/group/xcon_bfcp/apps/xcon_bfcp/xcon_scheduler.c (with props)
team/group/xcon_bfcp/apps/xcon_bfcp/xcon_scheduler.h (with props)
team/group/xcon_bfcp/configs/dcon.conf.sample (with props)
team/group/xcon_bfcp/configs/xcon.conf.sample (with props)
Added: team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.c
URL: http://svn.digium.com/view/asterisk/team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.c?view=auto&rev=52582
==============================================================================
--- team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.c (added)
+++ team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.c Mon Jan 29 13:07:05 2007
@@ -1,0 +1,605 @@
+/*********************************************************************\
+
+MODULE NAME: b64.c
+
+AUTHOR: Bob Trower 08/04/01
+
+PROJECT: Crypt Data Packaging
+
+COPYRIGHT: Copyright (c) Trantor Standard Systems Inc., 2001
+
+NOTE: This source code may be used as you wish, subject to
+ the MIT license. See the LICENCE section below.
+
+DESCRIPTION:
+ This little utility implements the Base64
+ Content-Transfer-Encoding standard described in
+ RFC1113 (http://www.faqs.org/rfcs/rfc1113.html).
+
+ This is the coding scheme used by MIME to allow
+ binary data to be transferred by SMTP mail.
+
+ Groups of 3 bytes from a binary stream are coded as
+ groups of 4 bytes in a text stream.
+
+ The input stream is 'padded' with zeros to create
+ an input that is an even multiple of 3.
+
+ A special character ('=') is used to denote padding so
+ that the stream can be decoded back to its exact size.
+
+ Encoded output is formatted in lines which should
+ be a maximum of 72 characters to conform to the
+ specification. This program defaults to 72 characters,
+ but will allow more or less through the use of a
+ switch. The program enforces a minimum line size
+ of 4 characters.
+
+ Example encoding:
+
+ The stream 'ABCD' is 32 bits long. It is mapped as
+ follows:
+
+ ABCD
+
+ A (65) B (66) C (67) D (68) (None) (None)
+ 01000001 01000010 01000011 01000100
+
+ 16 (Q) 20 (U) 9 (J) 3 (D) 17 (R) 0 (A) NA (=) NA (=)
+ 010000 010100 001001 000011 010001 000000 000000 000000
+
+
+ QUJDRA==
+
+ Decoding is the process in reverse. A 'decode' lookup
+ table has been created to avoid string scans.
+
+DESIGN GOALS: Specifically:
+ Code is a stand-alone utility to perform base64
+ encoding/decoding. It should be genuinely useful
+ when the need arises and it meets a need that is
+ likely to occur for some users.
+ Code acts as sample code to show the author's
+ design and coding style.
+
+ Generally:
+ This program is designed to survive:
+ Everything you need is in a single source file.
+ It compiles cleanly using a vanilla ANSI C compiler.
+ It does its job correctly with a minimum of fuss.
+ The code is not overly clever, not overly simplistic
+ and not overly verbose.
+ Access is 'cut and paste' from a web page.
+ Terms of use are reasonable.
+
+VALIDATION: Non-trivial code is never without errors. This
+ file likely has some problems, since it has only
+ been tested by the author. It is expected with most
+ source code that there is a period of 'burn-in' when
+ problems are identified and corrected. That being
+ said, it is possible to have 'reasonably correct'
+ code by following a regime of unit test that covers
+ the most likely cases and regression testing prior
+ to release. This has been done with this code and
+ it has a good probability of performing as expected.
+
+ Unit Test Cases:
+
+ case 0:empty file:
+ CASE0.DAT -> ->
+ (Zero length target file created
+ on both encode and decode.)
+
+ case 1:One input character:
+ CASE1.DAT A -> QQ== -> A
+
+ case 2:Two input characters:
+ CASE2.DAT AB -> QUJD -> AB
+
+ case 3:Three input characters:
+ CASE3.DAT ABC -> QUJD -> ABC
+
+ case 4:Four input characters:
+ case4.dat ABCD -> QUJDRA== -> ABCD
+
+ case 5:All chars from 0 to ff, linesize set to 50:
+
+ AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj
+ JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH
+ SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr
+ bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P
+ kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz
+ tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX
+ 2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7
+ /P3+/w==
+
+ case 6:Mime Block from e-mail:
+ (Data same as test case 5)
+
+ case 7: Large files:
+ Tested 28 MB file in/out.
+
+ case 8: Random Binary Integrity:
+ This binary program (b64.exe) was encoded to base64,
+ back to binary and then executed.
+
+ case 9 Stress:
+ All files in a working directory encoded/decoded
+ and compared with file comparison utility to
+ ensure that multiple runs do not cause problems
+ such as exhausting file handles, tmp storage, etc.
+
+ -------------
+
+ Syntax, operation and failure:
+ All options/switches tested. Performs as
+ expected.
+
+ case 10:
+ No Args -- Shows Usage Screen
+ Return Code 1 (Invalid Syntax)
+ case 11:
+ One Arg (invalid) -- Shows Usage Screen
+ Return Code 1 (Invalid Syntax)
+ case 12:
+ One Arg Help (-?) -- Shows detailed Usage Screen.
+ Return Code 0 (Success -- help request is valid).
+ case 13:
+ One Arg Help (-h) -- Shows detailed Usage Screen.
+ Return Code 0 (Success -- help request is valid).
+ case 14:
+ One Arg (valid) -- Uses stdin/stdout (filter)
+ Return Code 0 (Sucess)
+ case 15:
+ Two Args (invalid file) -- shows system error.
+ Return Code 2 (File Error)
+ case 16:
+ Encode non-existent file -- shows system error.
+ Return Code 2 (File Error)
+ case 17:
+ Out of disk space -- shows system error.
+ Return Code 3 (File I/O Error)
+
+ -------------
+
+ Compile/Regression test:
+ gcc compiled binary under Cygwin
+ Microsoft Visual Studio under Windows 2000
+ Microsoft Version 6.0 C under Windows 2000
+
+DEPENDENCIES: None
+
+LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated
+ documentation files (the "Software"), to deal in the
+ Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall
+ be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+VERSION HISTORY:
+ Bob Trower 08/04/01 -- Create Version 0.00.00B
+
+\******************************************************************* */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "bfcp_base64.h"
+
+/*
+** Translation Table as described in RFC1113
+*/
+static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/*
+** Translation Table to decode (created by author)
+*/
+static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
+
+/*
+** encodeblock
+**
+** encode 3 8-bit binary bytes as 4 '6-bit' characters
+*/
+void encodeblock( unsigned char in[3], unsigned char out[4], int len )
+{
+ out[0] = cb64[ in[0] >> 2 ];
+ out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
+ out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
+ out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
+}
+
+/*
+** encode
+**
+** base64 encode a stream adding padding and line breaks as per spec.
+*/
+void encode( FILE *infile, FILE *outfile, int linesize )
+{
+ unsigned char in[3], out[4];
+ int i, len, blocksout = 0;
+
+ while( !feof( infile ) ) {
+ len = 0;
+ for( i = 0; i < 3; i++ ) {
+ in[i] = (unsigned char) getc( infile );
+ if( !feof( infile ) ) {
+ len++;
+ }
+ else {
+ in[i] = 0;
+ }
+ }
+ if( len ) {
+ encodeblock( in, out, len );
+ for( i = 0; i < 4; i++ ) {
+ putc( out[i], outfile );
+ }
+ blocksout++;
+ }
+ if( blocksout >= (linesize/4) || feof( infile ) ) {
+ if( blocksout ) {
+ fprintf( outfile, "\r\n" );
+ }
+ blocksout = 0;
+ }
+ }
+}
+
+/*
+** encode_to_base64
+**
+** encode a BFCP message to Base64
+*/
+char *encode_to_base64( bfcp_message *message )
+{
+ if( !message )
+ return NULL;
+ if( message->lenght < 1 )
+ return NULL;
+
+ char *base64 = calloc( (message->lenght/2)*3, sizeof(char) );
+ if( !base64 )
+ return NULL;
+ char *temp64 = base64;
+
+ unsigned char in[3], out[4];
+ int i, len, blocksout = 0;
+
+ message->position = 0;
+
+ while( message->position <= message->lenght ) {
+ len = 0;
+ for( i = 0; i < 3; i++ ) {
+ in[i] = (unsigned char) *(message->buffer + message->position);
+ message->position++;
+ if( message->position <= message->lenght )
+ len++;
+ else
+ in[i] = 0;
+ }
+ if( len ) {
+ encodeblock( in, out, len );
+ for( i = 0; i < 4; i++ ) {
+ memcpy( temp64, &out[i], 1 );
+ temp64++;
+ }
+ blocksout++;
+ }
+ }
+ char ch='\0';
+ memcpy( temp64, &ch, 1 );
+ return base64;
+}
+
+/*
+** decodeblock
+**
+** decode 4 '6-bit' characters into 3 8-bit binary bytes
+*/
+void decodeblock( unsigned char in[4], unsigned char out[3] )
+{
+ out[ 0 ] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
+ out[ 1 ] = (unsigned char ) (in[1] << 4 | in[2] >> 2);
+ out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
+}
+
+/*
+** decode
+**
+** decode a base64 encoded stream discarding padding, line breaks and noise
+*/
+void decode( FILE *infile, FILE *outfile )
+{
+ unsigned char in[4], out[3], v;
+ int i, len;
+
+ while( !feof( infile ) ) {
+ for( len = 0, i = 0; i < 4 && !feof( infile ); i++ ) {
+ v = 0;
+ while( !feof( infile ) && v == 0 ) {
+ v = (unsigned char) getc( infile );
+ v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);
+ if( v ) {
+ v = (unsigned char) ((v == '$') ? 0 : v - 61);
+ }
+ }
+ if( !feof( infile ) ) {
+ len++;
+ if( v ) {
+ in[ i ] = (unsigned char) (v - 1);
+ }
+ }
+ else {
+ in[i] = 0;
+ }
+ }
+ if( len ) {
+ decodeblock( in, out );
+ for( i = 0; i < len - 1; i++ ) {
+ putc( out[i], outfile );
+ }
+ }
+ }
+}
+
+/*
+** decode_from_base64
+**
+** decode Base64 to a BFCP message
+*/
+bfcp_message *decode_from_base64( char *base64 )
+{
+ if( !base64 )
+ return NULL;
+ int base64_pos = 0, base64_len = strlen( base64 );
+ if( !base64_len )
+ return NULL;
+
+ char *bfcp_buffer = calloc( (base64_len/4)*3, sizeof(char) );
+ if( !bfcp_buffer )
+ return NULL;
+ char *temp_buffer = bfcp_buffer;
+
+ unsigned char in[4], out[3], v;
+ int i, len;
+
+ while( base64_pos <= base64_len ) {
+ for( len = 0, i = 0; i < 4 && ( base64_pos <= base64_len ); i++ ) {
+ v = 0;
+ while( ( base64_pos <= base64_len ) && v == 0 ) {
+ v = (unsigned char) *(base64 + base64_pos);
+ base64_pos++;
+ v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);
+ if( v )
+ v = (unsigned char) ((v == '$') ? 0 : v - 61);
+ }
+ if( base64_pos <= base64_len ) {
+ len++;
+ if( v )
+ in[ i ] = (unsigned char) (v - 1);
+ } else
+ in[i] = 0;
+ }
+ if( len ) {
+ decodeblock( in, out );
+ for( i = 0; i < len - 1; i++ ) {
+ memcpy( temp_buffer, &out[i], 1 );
+ temp_buffer++;
+ }
+ }
+ }
+ bfcp_message *message = bfcp_new_message( bfcp_buffer, temp_buffer - bfcp_buffer );
+ return message;
+}
+
+/*
+** returnable errors
+**
+** Error codes returned to the operating system.
+**
+*/
+#define B64_SYNTAX_ERROR 1
+#define B64_FILE_ERROR 2
+#define B64_FILE_IO_ERROR 3
+#define B64_ERROR_OUT_CLOSE 4
+#define B64_LINE_SIZE_TO_MIN 5
+
+/*
+** b64_message
+**
+** Gather text messages in one place.
+**
+*/
+char *b64_message( int errcode )
+{
+ #define B64_MAX_MESSAGES 6
+ char *msgs[ B64_MAX_MESSAGES ] = {
+ "b64:000:Invalid Message Code.",
+ "b64:001:Syntax Error -- check help for usage.",
+ "b64:002:File Error Opening/Creating Files.",
+ "b64:003:File I/O Error -- Note: output file not removed.",
+ "b64:004:Error on output file close.",
+ "b64:004:linesize set to minimum."
+ };
+ char *msg = msgs[ 0 ];
+
+ if( errcode > 0 && errcode < B64_MAX_MESSAGES ) {
+ msg = msgs[ errcode ];
+ }
+
+ return( msg );
+}
+
+/*
+** b64
+**
+** 'engine' that opens streams and calls encode/decode
+*/
+
+int b64( int opt, char *infilename, char *outfilename, int linesize )
+{
+ FILE *infile;
+ int retcode = B64_FILE_ERROR;
+
+ if( !infilename ) {
+ infile = stdin;
+ }
+ else {
+ infile = fopen( infilename, "rb" );
+ }
+ if( !infile ) {
+ perror( infilename );
+ }
+ else {
+ FILE *outfile;
+ if( !outfilename ) {
+ outfile = stdout;
+ }
+ else {
+ outfile = fopen( outfilename, "wb" );
+ }
+ if( !outfile ) {
+ perror( outfilename );
+ }
+ else {
+ if( opt == 'e' ) {
+ encode( infile, outfile, linesize );
+ }
+ else {
+ decode( infile, outfile );
+ }
+ if (ferror( infile ) || ferror( outfile )) {
+ retcode = B64_FILE_IO_ERROR;
+ }
+ else {
+ retcode = 0;
+ }
+ if( outfile != stdout ) {
+ if( fclose( outfile ) != 0 ) {
+ perror( b64_message( B64_ERROR_OUT_CLOSE ) );
+ retcode = B64_FILE_IO_ERROR;
+ }
+ }
+ }
+ if( infile != stdin ) {
+ fclose( infile );
+ }
+ }
+
+ return( retcode );
+}
+
+/*
+** showuse
+**
+** display usage information, help, version info
+*/
+void showuse( int morehelp )
+{
+ {
+ printf( "\n" );
+ printf( " b64 (Base64 Encode/Decode) Bob Trower 08/03/01 \n" );
+ printf( " (C) Copr Bob Trower 1986-01. Version 0.00B \n" );
+ printf( " Usage: b64 -option [ -l num ] [<FileIn> [<FileOut>]] \n" );
+ printf( " Purpose: This program is a simple utility that implements\n" );
+ printf( " Base64 Content-Transfer-Encoding (RFC1113). \n" );
+ }
+ if( !morehelp ) {
+ printf( " Use -h option for additional help. \n" );
+ }
+ else {
+ printf( " Options: -e encode to Base64 -h This help text. \n" );
+ printf( " -d decode from Base64 -? This help text. \n" );
+ printf( " Note: -l use to change line size (from 72 characters)\n" );
+ printf( " Returns: 0 = success. Non-zero is an error code. \n" );
+ printf( " ErrCode: 1 = Bad Syntax, 2 = File Open, 3 = File I/O \n" );
+ printf( " Example: b64 -e binfile b64file <- Encode to b64 \n" );
+ printf( " b64 -d b64file binfile <- Decode from b64 \n" );
+ printf( " b64 -e -l40 infile outfile <- Line Length of 40 \n" );
+ printf( " Note: Will act as a filter, but this should only be \n" );
+ printf( " used on text files due to translations made by \n" );
+ printf( " operating systems. \n" );
+ printf( " Release: 0.00.00, Tue Aug 7 2:00:00 2001, ANSI-SOURCE C\n" );
+ }
+}
+
+#define B64_DEF_LINE_SIZE 72
+#define B64_MIN_LINE_SIZE 4
+
+#define THIS_OPT(ac, av) (ac > 1 ? av[1][0] == '-' ? av[1][1] : 0 : 0)
+
+/*
+** main
+**
+** parse and validate arguments and call b64 engine or help
+
+int main( int argc, char **argv )
+{
+ int opt = 0;
+ int retcode = 0;
+ int linesize = B64_DEF_LINE_SIZE;
+ char *infilename = NULL, *outfilename = NULL;
+
+ while( THIS_OPT( argc, argv ) ) {
+ switch( THIS_OPT(argc, argv) ) {
+ case 'l':
+ linesize = atoi( &(argv[1][2]) );
+ if( linesize < B64_MIN_LINE_SIZE ) {
+ linesize = B64_MIN_LINE_SIZE;
+ printf( "%s\n", b64_message( B64_LINE_SIZE_TO_MIN ) );
+ }
+ break;
+ case '?':
+ case 'h':
+ opt = 'h';
+ break;
+ case 'e':
+ case 'd':
+ opt = THIS_OPT(argc, argv);
+ break;
+ default:
+ opt = 0;
+ break;
+ }
+ argv++;
+ argc--;
+ }
+ switch( opt ) {
+ case 'e':
+ case 'd':
+ infilename = argc > 1 ? argv[1] : NULL;
+ outfilename = argc > 2 ? argv[2] : NULL;
+ retcode = b64( opt, infilename, outfilename, linesize );
+ break;
+ case 0:
+ retcode = B64_SYNTAX_ERROR;
+ case 'h':
+ showuse( opt );
+ break;
+
+ }
+ if( retcode ) {
+ printf( "%s\n", b64_message( retcode ) );
+ }
+
+ return( retcode );
+}
+*/
Propchange: team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.h
URL: http://svn.digium.com/view/asterisk/team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.h?view=auto&rev=52582
==============================================================================
--- team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.h (added)
+++ team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.h Mon Jan 29 13:07:05 2007
@@ -1,0 +1,15 @@
+#ifndef _BFCP_BASE_64_H
+#define _BFCP_BASE_64_H
+
+#include "bfcp_messages.h"
+
+/*
+ Slightly modified version of the http://base64.sourceforge.net/
+ Base64 Content-Transfer-Encoding utility to enable library-style
+ encoding/decoding to/from Base64 of binary BFCP Messages
+*/
+
+char *encode_to_base64( bfcp_message *message );
+bfcp_message *decode_from_base64( char *base64 );
+
+#endif
Propchange: team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_base64.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_gw.c
URL: http://svn.digium.com/view/asterisk/team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_gw.c?view=auto&rev=52582
==============================================================================
--- team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_gw.c (added)
+++ team/group/xcon_bfcp/apps/xcon_bfcp/bfcp_gw.c Mon Jan 29 13:07:05 2007
@@ -1,0 +1,2221 @@
+#include "bfcp_gw.h"
+#include "bfcp_base64.h"
+
+
+
+/* Wrapper to increment the UserID counter and return it */
+unsigned short int bfcp_new_user_id()
+{
+ unsigned short int userID = bfcp_user_id;
+ bfcp_user_id++;
+ return userID;
+}
+
+/* Wrapper to get direct access to the BFCP Server list */
+bfcp bfcp_gw_get_list()
+{
+ return bfcp_server_list;
+}
+
+/* Gateway functionality initialization */
+void bfcp_gw_initialize(int dcon_enabled, int( *notify_about_dispatcher)(int update, ...))
+{
+ is_dcon_enabled = dcon_enabled; /* Enable/disable DCON functionality */
+
+ if(is_dcon_enabled) {
+ bfcp_user_id = 1; /* Start the UserID counter */
+ bfcp_gw_channel = 1; /* Start the channel counter */
+ routing_table = NULL; /* No routing info yet */
+ gw_conferences = NULL; /* No conferences either */
+ bfcp_gw_dispatcher.callback_func = notify_about_dispatcher;
+ }
+}
+
+
+/* Scheduler functionality initialization */
+int xcon_gw_scheduler_initialize(unsigned short int port, int( *notify_about_scheduler)(int message, ...))
+{
+ scheduler_callback = notify_about_scheduler;
+
+ if(is_dcon_enabled)
+ return xcon_scheduler_initialize(port, scheduler_gw_notifications);
+ else
+ return xcon_scheduler_initialize(port, scheduler_callback);
+}
+
+int xcon_gw_scheduler_setup_admin(char *admin, char *password)
+{
+ if(!admin || !password)
+ return -1;
+
+ return xcon_scheduler_setup_admin(admin, password);
+}
+
+
+/* Transaction constructor */
+bfcp_gw_transaction *bfcp_gw_new_transaction(bfcp_message *message, int fd)
+{
+ bfcp_gw_transaction *transaction = calloc(sizeof(bfcp_gw_transaction), sizeof(char));
+ if(!transaction)
+ return NULL;
+
+ transaction->message = message;
+ transaction->fd = fd;
+
+ return transaction;
+}
+
+
+
+/* bfcp_server wrappers */
+int bfcp_gw_initialize_bfcp_server(int Max_conf, unsigned short int port_server, int( *notify_to_app_meetme)(bfcp_arguments *arguments, int outgoing_msg),
+ char *ip_gw_fcs, unsigned short int port_gw_fcs, unsigned short int port_dispatcher)
+{
+ if(!is_dcon_enabled) { /* No DCON, the gateway will just act as a proxy for BFCP server methods */
+ bfcp_server_list = bfcp_initialize_bfcp_server(Max_conf, port_server, notify_to_app_meetme);
+ if(!bfcp_server_list)
+ return -1;
+ } else { /* Enable DCON-compliant Floor Control Server gateway */
+ /* The real FCS will listen on another port: the gateway will be its proxy and will
+ receive notification callbacks regarding BFCP messages from the real FCS too */
+ bfcp_server_list = bfcp_initialize_bfcp_server(Max_conf, port_gw_fcs, bfcp_gw_notifications);
+ if(!bfcp_server_list)
+ return -1;
+
+ /* Start the Gateway, acting as a proxy towards the FCS and Users */
+ bfcp_gw_fcs.callback_func = notify_to_app_meetme;
+ if(bfcp_gw_fcs_listen(port_server, ip_gw_fcs, port_gw_fcs) < 0)
+ return -1;
+ /* Start the server which will talk to the DCON Dispatcher */
+ if(bfcp_gw_dispatcher_listen(port_dispatcher) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+int bfcp_gw_destroy_bfcp_server()
+{
+ if(is_dcon_enabled) {
+ bfcp_gw_dispatcher_remove_all_confs();
+ bfcp_gw_dispatcher_remove_all_users();
+ bfcp_gw_conferences_free();
+ bfcp_gw_rt_free_channels();
+ }
+ /* When bfcp_server_list is destroyed, the threads kill themselves */
+ int res = bfcp_destroy_bfcp_server(&bfcp_server_list);
+ bfcp_server_list = NULL;
+
+ return res;
+}
+
+int bfcp_gw_initialize_conference_server(int conf_type, unsigned long int ConferenceID, int Max_Num_Floors, int Max_Number_Floor_Request, int automatic_accepted_deny_policy, long int chair_wait_request)
+{
+ if(!is_dcon_enabled && (conf_type == XCON_REMOTE_CONFERENCE))
+ return -1;
+
+ int res = 0;
+ if(conf_type == XCON_LOCAL_CONFERENCE) { /* Conference running on this focus */
+ res = bfcp_initialize_conference_server(bfcp_server_list, ConferenceID, Max_Num_Floors, Max_Number_Floor_Request, automatic_accepted_deny_policy, chair_wait_request);
+ if(res < 0)
+ return res;
+ }
+ if(is_dcon_enabled) { /* Only add conference and notify dispatcher if DCON is enabled */
+ res = bfcp_gw_conferences_add(conf_type, ConferenceID);
+ if(res < 0)
+ return res;
+ res = bfcp_gw_dispatcher_add_conf(conf_type, ConferenceID);
+ if(res < 0)
+ return res;
+ }
+
+ return 0;
+}
+
+int bfcp_gw_destroy_conference_server(int conf_type, unsigned long int ConferenceID)
+{
+ if(!is_dcon_enabled && (conf_type == XCON_REMOTE_CONFERENCE))
+ return -1;
+
+ int res = 0;
+ if(conf_type == XCON_LOCAL_CONFERENCE) { /* Conference running on this focus */
+ res = bfcp_destroy_conference_server(bfcp_server_list, ConferenceID);
+ if(res < 0)
+ return res;
+ }
+ if(is_dcon_enabled) { /* Only remove conference and notify dispatcher if DCON is enabled */
+ res = bfcp_gw_conferences_remove(ConferenceID);
+ if(res < 0)
+ return res;
+ res = bfcp_gw_dispatcher_remove_conf(conf_type, ConferenceID);
+ if(res < 0)
+ return res;
+ }
+
+ return 0;
+}
+
+int bfcp_gw_change_number_bfcp_conferences_server(int Num)
+{
+ return bfcp_change_number_bfcp_conferences_server(bfcp_server_list, Num);
+}
+
+int bfcp_gw_change_number_granted_floor_server(unsigned long int ConferenceID, unsigned int FloorID, int limit_granted_floor)
+{
+ return bfcp_change_number_granted_floor_server(bfcp_server_list, ConferenceID, FloorID, limit_granted_floor);
+}
+
+int bfcp_gw_change_user_req_floors_server(int Max_Number_Floor_Request)
+{
+ return bfcp_change_user_req_floors_server(bfcp_server_list, Max_Number_Floor_Request);
+}
+
+int bfcp_gw_change_chair_policy(unsigned long int ConferenceID, int automatic_accepted_deny_policy, long int chair_wait_request)
+{
+ return bfcp_change_chair_policy(bfcp_server_list, ConferenceID, automatic_accepted_deny_policy, chair_wait_request);
+}
+
+int bfcp_gw_add_floor_server(unsigned long int ConferenceID, int floor_type, unsigned int FloorID, unsigned int ChairID, int limit_granted_floor)
+{
+ int res = bfcp_add_floor_server(bfcp_server_list, ConferenceID, FloorID, ChairID, limit_granted_floor);
+ if(res < 0) { /* Before returning an error, check if the floor already exists */
+ if((bfcp_gw_conferences_get_floor(AUDIO_FLOOR, ConferenceID) == FloorID) ||
+ (bfcp_gw_conferences_get_floor(VIDEO_FLOOR, ConferenceID) == FloorID))
+ return bfcp_gw_conferences_set_floor(floor_type, ConferenceID, FloorID);
+ else
+ return res;
+ }
+
+ return bfcp_gw_conferences_set_floor(floor_type, ConferenceID, FloorID);
+}
+
+int bfcp_gw_delete_floor_server(unsigned long int ConferenceID, unsigned int FloorID)
+{
+ return bfcp_delete_floor_server(bfcp_server_list, ConferenceID, FloorID);
+}
+
+int bfcp_gw_add_chair_server(unsigned long int ConferenceID, unsigned int FloorID, unsigned int ChairID)
+{
+ return bfcp_add_chair_server(bfcp_server_list, ConferenceID, FloorID, ChairID);
+}
+
+int bfcp_gw_delete_chair_server(unsigned long int ConferenceID, unsigned int FloorID)
+{
+ return bfcp_delete_chair_server(bfcp_server_list, ConferenceID, FloorID);
+}
+
+int bfcp_gw_add_user_server(int conf_type, unsigned long int ConferenceID, unsigned int userID, char *user_URI, char *user_display_name)
+{
+ if(!is_dcon_enabled && (conf_type == XCON_REMOTE_CONFERENCE))
+ return -1;
+
+ int res = 0;
+ if(conf_type == XCON_LOCAL_CONFERENCE) { /* Conference running on this focus */
+ /* We don't notify the Dispatcher, since the two peers (User-FCS) will both be loal */
+ res = bfcp_add_user_server(bfcp_server_list, ConferenceID, userID, user_URI, user_display_name);
+ if(res < 0)
+ return res;
+
+ /* Create a new channel in the routing table:
+ the client will be a local user, the server the local FCS */
+ unsigned long int channel = bfcp_gw_rt_new_channel(0);
+ if(!channel) /* Could not create channel */
+ return -1;
+ res |= bfcp_gw_rt_set_ids(channel, ConferenceID, userID);
+ res |= bfcp_gw_rt_set_details(channel, user_URI, user_display_name);
+ res |= bfcp_gw_rt_set_client_leg(channel, BFCP_GW_USER);
+ res |= bfcp_gw_rt_set_server_leg(channel, BFCP_GW_FCS);
+ } else { /* Conference running on remote focus */
+ /* Create a new channel in the routing table:
+ the client will be a local user, the server the Dispatcher */
+ unsigned long int channel = bfcp_gw_rt_new_channel(0);
+ if(!channel) /* Could not create channel */
+ return -1;
+ /* We don't setup the IDs yet (we'll wait for the remotre focus to reply) */
+ res |= bfcp_gw_rt_set_client_leg(channel, BFCP_GW_USER);
+ res |= bfcp_gw_rt_set_server_leg(channel, BFCP_GW_DISPATCHER);
+ res |= bfcp_gw_rt_set_server_fd(channel, bfcp_gw_dispatcher.dispatcher);
+
+ /* We notify the Dispatcher about the new user, since the focus hosting the
+ conference is remote, and it's the remote focus that will decide the BFCP UserID
+ (which is 0 for now) for this local user; besides, the Dispatcher will take care of
+ forwarding the messages running between the local user and the remote focus */
+ res |= bfcp_gw_dispatcher_add_user(channel, ConferenceID, user_URI, user_display_name);
+ }
+
+ return res;
+}
+
+int bfcp_gw_delete_user_server(int conf_type, unsigned long int ConferenceID, unsigned int userID)
+{
+ if(!is_dcon_enabled && (conf_type == XCON_REMOTE_CONFERENCE))
+ return -1;
+
+ int res = 0;
+
+ unsigned long int channel = bfcp_gw_rt_get_channel_from_ids(ConferenceID, userID);
+ if(conf_type == XCON_LOCAL_CONFERENCE) { /* Conference running on this focus */
+ res = bfcp_delete_user_server(bfcp_server_list, ConferenceID, userID);
+ if(res < 0)
+ return res;
+ }
+ res = bfcp_gw_dispatcher_remove_user(channel, ConferenceID, userID);
+ if(res < 0)
+ return res;
+
+ return bfcp_gw_rt_remove_channel(channel);
+}
+
+
+
+/* Conferences list manipulation methods */
+int bfcp_gw_conferences_add(int conf_type, unsigned long int conferenceID)
+{
+ bfcp_mutex_lock(&bfcp_gw_conferences_list);
+ /* First of all look if such a conference already exists */
+ bfcp_gw_conferences *temp = NULL, *previous = NULL;
+ temp = gw_conferences;
+ if(temp) {
+ while(temp) {
+ if(temp->conferenceID == conferenceID) {
+ temp->conference_type = conf_type; /* Update */
+ break;
+ }
+ previous = temp;
+ temp = temp->next;
+ }
+ }
+ if(temp) {
+ bfcp_mutex_unlock(&bfcp_gw_conferences_list);
+ return 0;
+ }
+ temp = calloc(sizeof(bfcp_gw_conferences),sizeof(char));
+ if(!temp) {
+ bfcp_mutex_unlock(&bfcp_gw_conferences_list);
+ return -1;
+ }
+ temp->conferenceID = conferenceID;
+ temp->conference_type = conf_type;
+ temp->next = NULL;
+ if(!gw_conferences) /* First add */
+ gw_conferences = temp;
+ else /* Append */
+ previous->next = temp;
+ bfcp_mutex_unlock(&bfcp_gw_conferences_list);
+
+ return 0;
+}
+
+int bfcp_gw_conferences_set_floor(int floor_type, unsigned long int conferenceID, unsigned short int floorID)
+{
+ if(!gw_conferences)
+ return -1;
+ bfcp_mutex_lock(&bfcp_gw_conferences_list);
+ /* Look if it exists */
+ bfcp_gw_conferences *temp = gw_conferences;
+ while(temp) {
+ if(temp->conferenceID == conferenceID) {
+ switch(floor_type) {
+ case AUDIO_FLOOR:
+ temp->audioFloorID = floorID;
+ break;
+ case VIDEO_FLOOR:
+ temp->videoFloorID = floorID;
+ break;
+ default:
+ break;
+ }
+ break; /* Found */
+ }
+ temp = temp->next;
+ }
+ bfcp_mutex_unlock(&bfcp_gw_conferences_list);
+ if(temp)
+ return 0;
+ else
+ return -1;
+}
+
+unsigned short int bfcp_gw_conferences_get_floor(int floor_type, unsigned long int conferenceID)
+{
+ if(!gw_conferences)
+ return -1;
+ bfcp_mutex_lock(&bfcp_gw_conferences_list);
+ /* Look if it exists */
+ bfcp_gw_conferences *temp = gw_conferences;
+ while(temp) {
+ if(temp->conferenceID == conferenceID)
+ break; /* Found */
+ temp = temp->next;
+ }
+ bfcp_mutex_unlock(&bfcp_gw_conferences_list);
+ if(temp) {
+ switch(floor_type) {
+ case AUDIO_FLOOR:
+ return temp->audioFloorID;
+ case VIDEO_FLOOR:
+ return temp->videoFloorID;
+ default:
+ return 0;
+ }
+ } else
+ return 0;
+}
+
+
+int bfcp_gw_conferences_get_type(unsigned long int conferenceID)
+{
+ if(!gw_conferences)
+ return -1;
+ bfcp_mutex_lock(&bfcp_gw_conferences_list);
+ /* Look if it exists */
+ bfcp_gw_conferences *temp = gw_conferences;
+ while(temp) {
+ if(temp->conferenceID == conferenceID)
+ break; /* Found */
+ temp = temp->next;
+ }
+ bfcp_mutex_unlock(&bfcp_gw_conferences_list);
+ if(temp)
+ return temp->conference_type;
+ else
+ return -1;
+}
+
+int bfcp_gw_conferences_remove(unsigned long int conferenceID)
+{
+ if(!gw_conferences)
+ return -1;
+ bfcp_mutex_lock(&bfcp_gw_conferences_list);
+ /* First of all look if it exists */
+ bfcp_gw_conferences *temp = NULL, *previous = NULL;
+ temp = gw_conferences;
+ while(temp) {
+ if(temp->conferenceID == conferenceID) {
+ if(!previous) /* First in the list */
+ gw_conferences = temp->next;
+ else /* Not first in the list */
+ previous->next = temp->next;
+ free(temp); /* Remove */
+ temp = NULL;
+ break;
+ }
+ previous = temp;
+ temp = temp->next;
+ }
+ bfcp_mutex_unlock(&bfcp_gw_conferences_list);
+
+ return 0;
+}
+
+int bfcp_gw_conferences_free()
+{
+ if(!gw_conferences)
+ return -1;
+ bfcp_gw_conferences *temp = gw_conferences, *next = NULL;
+ while(temp) {
+ next = temp->next;
+ bfcp_gw_conferences_remove(temp->conferenceID);
+ temp = next;
+ }
+ return 0;
+}
+
+
+
+/* Routing table manipulation methods */
+unsigned long int bfcp_gw_rt_new_channel(unsigned long int channel)
+{
+ if(!channel) { /* We create one ourselves */
+ channel = bfcp_gw_channel;
+ bfcp_gw_channel++;
+ }
+
+ bfcp_mutex_lock(&bfcp_gw_routing_table_list);
+ /* First of all look if such a channel already exists */
+ bfcp_gw_routing_table *temp = routing_table, *previous = NULL;
+ if(temp) {
+ while(temp) {
+ if(temp->channel == channel)
+ break;
+ previous = temp;
+ temp = temp->next;
+ }
+ }
+ if(temp) { /* Channel already exist */
+ bfcp_mutex_unlock(&bfcp_gw_routing_table_list);
+ return 0; /* 0 is a failure */
+ }
+ temp = calloc(sizeof(bfcp_gw_routing_table),sizeof(char));
+ if(!temp) { /* Could not create new channel */
+ bfcp_mutex_unlock(&bfcp_gw_routing_table_list);
+ return 0; /* 0 is a failure */
+ }
+ temp->channel = channel; /* Set up the new channel */
+ temp->conferenceID = 0;
+ temp->userID = 0;
+ temp->server_leg = BFCP_GW_NONE;
+ temp->server_fd = -1;
+ temp->client_leg = BFCP_GW_NONE;
+ temp->client_fd = -1;
+ temp->next = NULL;
+ if(!routing_table) /* First add */
+ routing_table = temp;
+ else /* Append */
+ previous->next = temp;
+ bfcp_mutex_unlock(&bfcp_gw_routing_table_list);
+
+ return temp->channel;
+
+}
+
+int bfcp_gw_rt_set_ids(unsigned long int channel, unsigned long int conferenceID, unsigned short int userID)
+{
+ if(!channel || !routing_table)
+ return -1;
+
+ bfcp_mutex_lock(&bfcp_gw_routing_table_list);
+ /* First of all look if such a channel already exists */
+ bfcp_gw_routing_table *temp = routing_table, *previous = NULL;
+ while(temp) {
+ if(temp->channel == channel) { /* Found */
+ temp->conferenceID = conferenceID;
+ temp->userID = userID;
+ break;
+ }
+ previous = temp;
+ temp = temp->next;
+ }
+ bfcp_mutex_unlock(&bfcp_gw_routing_table_list);
+
+ if(!temp) /* Channel not found */
+ return -1;
+
+ return 0;
+}
+
+int bfcp_gw_rt_set_details(unsigned long int channel, char *uri, char *display)
+{
+ if(!channel || !routing_table)
+ return -1;
+
+ bfcp_mutex_lock(&bfcp_gw_routing_table_list);
+ /* First of all look if such a channel already exists */
+ bfcp_gw_routing_table *temp = routing_table, *previous = NULL;
+ while(temp) {
+ if(temp->channel == channel) { /* Found */
+ temp->uri = uri;
+ temp->display = display;
+ break;
+ }
+ previous = temp;
+ temp = temp->next;
+ }
+ bfcp_mutex_unlock(&bfcp_gw_routing_table_list);
+
+ if(!temp) /* Channel not found */
+ return -1;
+
+ return 0;
+}
+
+char *bfcp_gw_rt_get_uri(unsigned long int channel)
+{
+ if(!channel || !routing_table)
+ return NULL;
+
+ bfcp_mutex_lock(&bfcp_gw_routing_table_list);
+ /* First of all look if such a channel already exists */
+ bfcp_gw_routing_table *temp = routing_table, *previous = NULL;
+ while(temp) {
+ if(temp->channel == channel) /* Found */
+ break;
+ previous = temp;
+ temp = temp->next;
+ }
+ bfcp_mutex_unlock(&bfcp_gw_routing_table_list);
+
+ if(!temp) /* Channel not found */
+ return NULL;
+
+ return temp->uri;
+}
+
+char *bfcp_gw_rt_get_display(unsigned long int channel)
+{
+ if(!channel || !routing_table)
+ return NULL;
+
+ bfcp_mutex_lock(&bfcp_gw_routing_table_list);
+ /* First of all look if such a channel already exists */
+ bfcp_gw_routing_table *temp = routing_table, *previous = NULL;
+ while(temp) {
+ if(temp->channel == channel) /* Found */
+ break;
+ previous = temp;
+ temp = temp->next;
+ }
+ bfcp_mutex_unlock(&bfcp_gw_routing_table_list);
+
+ if(!temp) /* Channel not found */
+ return NULL;
+
+ return temp->display;
+}
+
+int bfcp_gw_rt_set_server_leg(unsigned long int channel, int leg)
+{
+ if(!channel || !routing_table)
[... 2710 lines stripped ...]
More information about the asterisk-commits
mailing list