[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