Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

IceCast2.cpp

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------------
00002 
00003    Copyright (c) 2000 Tyrell Corporation. All rights reserved.
00004 
00005    Tyrell DarkIce
00006 
00007    File     : IceCast2.cpp
00008    Version  : $Revision: 1.13 $
00009    Author   : $Author: darkeye $
00010    Location : $Source: /cvsroot/darkice/darkice/src/IceCast2.cpp,v $
00011    
00012    Copyright notice:
00013 
00014     This program is free software; you can redistribute it and/or
00015     modify it under the terms of the GNU General Public License  
00016     as published by the Free Software Foundation; either version 2
00017     of the License, or (at your option) any later version.
00018    
00019     This program is distributed in the hope that it will be useful,
00020     but WITHOUT ANY WARRANTY; without even the implied warranty of 
00021     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
00022     GNU General Public License for more details.
00023    
00024     You should have received a copy of the GNU General Public License
00025     along with this program; if not, write to the Free Software
00026     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00027 
00028 ------------------------------------------------------------------------------*/
00029 
00030 /* ============================================================ include files */
00031 
00032 #ifdef HAVE_CONFIG_H
00033 #include "config.h"
00034 #endif
00035 
00036 #ifdef HAVE_STDIO_H
00037 #include <stdio.h>
00038 #else
00039 #error need stdio.h
00040 #endif
00041 
00042 #ifdef HAVE_STRING_H
00043 #include <string.h>
00044 #else
00045 #error need string.h
00046 #endif
00047 
00048 #ifdef HAVE_MATH_H
00049 #include <math.h>
00050 #else
00051 #error need math.h
00052 #endif
00053 
00054 
00055 #include "Exception.h"
00056 #include "Source.h"
00057 #include "Sink.h"
00058 #include "Util.h"
00059 #include "IceCast2.h"
00060 
00061 
00062 /* ===================================================  local data structures */
00063 
00064 
00065 /* ================================================  local constants & macros */
00066 
00067 /*------------------------------------------------------------------------------
00068  *  File identity
00069  *----------------------------------------------------------------------------*/
00070 static const char fileid[] = "$Id: IceCast2.cpp,v 1.13 2006/01/25 22:47:15 darkeye Exp $";
00071 
00072 
00073 /*------------------------------------------------------------------------------
00074  *  Size of string conversion buffer
00075  *----------------------------------------------------------------------------*/
00076 #define STRBUF_SIZE         32
00077 
00078 
00079 /*------------------------------------------------------------------------------
00080  *  Expected positive response from server begins like this.
00081  *----------------------------------------------------------------------------*/
00082 static const char responseOK[] = "HTTP/1.0 200";
00083 
00084 
00085 /* ===============================================  local function prototypes */
00086 
00087 
00088 /* =============================================================  module code */
00089 
00090 /*------------------------------------------------------------------------------
00091  *  Initialize the object
00092  *----------------------------------------------------------------------------*/
00093 void
00094 IceCast2 :: init (  StreamFormat            format,
00095                     const char            * mountPoint,
00096                     const char            * description )
00097                                                         throw ( Exception )
00098 {
00099     this->format         = format;
00100     this->mountPoint     = Util::strDup( mountPoint);
00101     this->description    = description    ? Util::strDup( description) : 0;
00102 }
00103 
00104 
00105 /*------------------------------------------------------------------------------
00106  *  De-initialize the object
00107  *----------------------------------------------------------------------------*/
00108 void
00109 IceCast2 :: strip ( void )                           throw ( Exception )
00110 {
00111     delete[] mountPoint;
00112     if ( description ) {
00113         delete[] description;
00114     }
00115 }
00116 
00117 
00118 /*------------------------------------------------------------------------------
00119  *  Log in to the IceCast2 server
00120  *----------------------------------------------------------------------------*/
00121 bool
00122 IceCast2 :: sendLogin ( void )                           throw ( Exception )
00123 {
00124     Sink          * sink   = getSink();
00125     Source        * source = getSocket();
00126     const char    * str;
00127     char            resp[STRBUF_SIZE];
00128     unsigned int    len;
00129     unsigned int    lenExpected;
00130 
00131     if ( !source->isOpen() ) {
00132         return false;
00133     }
00134     if ( !sink->isOpen() ) {
00135         return false;
00136     }
00137 
00138     // send the request, a string like:
00139     // "SOURCE <mountpoint> ICE/1.0"
00140     str = "SOURCE /";
00141     sink->write( str, strlen( str));
00142     str = getMountPoint();
00143     sink->write( str, strlen( str));
00144     str = " HTTP/1.0";
00145     sink->write( str, strlen( str));
00146 
00147     // send the content type, Ogg Vorbis
00148     str = "\nContent-type: ";
00149     sink->write( str, strlen( str));
00150     switch ( format ) {
00151         case mp3:
00152         case mp2:
00153             str = "audio/mpeg";
00154             break;
00155 
00156         case oggVorbis:
00157             str = "application/ogg";
00158             break;
00159 
00160         case aac:
00161             str = "audio/aac";
00162             break;
00163 
00164         default:
00165             throw Exception( __FILE__, __LINE__,
00166                              "unsupported stream format", format);
00167             break;
00168     }
00169     sink->write( str, strlen( str));
00170 
00171     // send the authentication info
00172     str = "\nAuthorization: Basic ";
00173     sink->write( str, strlen(str));
00174     {
00175         // send source:<password> encoded as base64
00176         char        * source = "source:";
00177         const char  * pwd    = getPassword();
00178         char        * tmp    = new char[Util::strLen(source) +
00179                                         Util::strLen(pwd) + 1];
00180         Util::strCpy( tmp, source);
00181         Util::strCat( tmp, pwd);
00182         char  * base64 = Util::base64Encode( tmp);
00183         delete[] tmp;
00184         sink->write( base64, strlen(base64));
00185         delete[] base64;
00186     }
00187 
00188     // send user agent info
00189     str = "\nUser-Agent: DarkIce/" VERSION " (http://darkice.sourceforge.net/)";
00190     sink->write( str, strlen( str));
00191 
00192     // send the ice- headers
00193     str = "\nice-bitrate: ";
00194     sink->write( str, strlen( str));
00195     if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) {
00196         throw Exception( __FILE__, __LINE__,
00197                          "bitrate does not fit string buffer", getBitRate());
00198     }
00199     sprintf( resp, "%d", getBitRate());
00200     sink->write( resp, strlen( resp));
00201 
00202     str = "\nice-public: ";
00203     sink->write( str, strlen( str));
00204     str = getIsPublic() ? "1" : "0";
00205     sink->write( str, strlen( str));
00206 
00207     if ( getName() ) {
00208         str = "\nice-name: ";
00209         sink->write( str, strlen( str));
00210         str = getName();
00211         sink->write( str, strlen( str));
00212     }
00213 
00214     if ( getDescription() ) {
00215         str = "\nice-description: ";
00216         sink->write( str, strlen( str));
00217         str = getDescription();
00218         sink->write( str, strlen( str));
00219     }
00220 
00221     if ( getUrl() ) {
00222         str = "\nice-url: ";
00223         sink->write( str, strlen( str));
00224         str = getUrl();
00225         sink->write( str, strlen( str));
00226     }
00227 
00228     if ( getGenre() ) {
00229         str = "\nice-genre: ";
00230         sink->write( str, strlen( str));
00231         str = getGenre();
00232         sink->write( str, strlen( str));
00233     }
00234 
00235     str = "\n\n";
00236     sink->write( str, strlen( str));
00237     sink->flush();
00238 
00239     // read the response, expected response begins with responseOK
00240     lenExpected = Util::strLen( responseOK);
00241     if ( (len = source->read( resp, STRBUF_SIZE-1)) < lenExpected ) {
00242         return false;
00243     }
00244     resp[lenExpected] = 0;
00245     if ( !Util::strEq( resp, responseOK) ) {
00246         return false;
00247     }
00248     
00249     // suck anything that the other side has to say
00250     while ( source->canRead( 0, 0) && 
00251            (len = source->read( resp, STRBUF_SIZE-1)) );
00252 
00253     return true;
00254 }
00255 
00256 
00257 
00258 /*------------------------------------------------------------------------------
00259  
00260   $Source: /cvsroot/darkice/darkice/src/IceCast2.cpp,v $
00261 
00262   $Log: IceCast2.cpp,v $
00263   Revision 1.13  2006/01/25 22:47:15  darkeye
00264   added mpeg2 support, thanks to Nicholas J Humfrey
00265 
00266   Revision 1.12  2005/04/16 21:57:34  darkeye
00267   added AAC support through the faac codec, http://www.audiocoding.com/
00268 
00269   Revision 1.11  2005/04/11 18:32:32  darkeye
00270   changed MIME type to application/ogg, which is now official
00271 
00272   Revision 1.10  2002/11/29 08:14:47  darkeye
00273   fixed minor bug in IcecCast2.cpp, which could have lead to a buffer
00274   overflow
00275 
00276   Revision 1.9  2002/10/20 21:09:35  darkeye
00277   added processing of server response
00278 
00279   Revision 1.8  2002/08/20 20:16:59  darkeye
00280   added User-Agent header to HTTP login
00281 
00282   Revision 1.7  2002/08/20 19:34:43  darkeye
00283   minor fix
00284 
00285   Revision 1.6  2002/08/20 18:39:13  darkeye
00286   added HTTP Basic authentication for icecast2 logins
00287 
00288   Revision 1.5  2002/05/28 12:35:41  darkeye
00289   code cleanup: compiles under gcc-c++ 3.1, using -pedantic option
00290 
00291   Revision 1.4  2002/02/20 10:35:35  darkeye
00292   updated to work with Ogg Vorbis libs rc3 and current IceCast2 cvs
00293 
00294   Revision 1.3  2002/02/19 15:24:26  darkeye
00295   send Content-type header when logging in to icecast2 servers
00296 
00297   Revision 1.2  2001/11/20 09:06:18  darkeye
00298   fixed public stream reporting
00299 
00300   Revision 1.1  2001/09/14 19:31:06  darkeye
00301   added IceCast2 / vorbis support
00302 
00303 
00304   
00305 ------------------------------------------------------------------------------*/
00306 

Generated on Fri May 19 15:36:48 2006 for DarkIce by  doxygen 1.4.4