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.12 $
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.12 2005/04/16 21:57:34 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             str = "audio/mpeg";
00153             break;
00154 
00155         case oggVorbis:
00156             str = "application/ogg";
00157             break;
00158 
00159         case aac:
00160             str = "audio/aac";
00161             break;
00162 
00163         default:
00164             throw Exception( __FILE__, __LINE__,
00165                              "unsupported stream format", format);
00166             break;
00167     }
00168     sink->write( str, strlen( str));
00169 
00170     // send the authentication info
00171     str = "\nAuthorization: Basic ";
00172     sink->write( str, strlen(str));
00173     {
00174         // send source:<password> encoded as base64
00175         char        * source = "source:";
00176         const char  * pwd    = getPassword();
00177         char        * tmp    = new char[Util::strLen(source) +
00178                                         Util::strLen(pwd) + 1];
00179         Util::strCpy( tmp, source);
00180         Util::strCat( tmp, pwd);
00181         char  * base64 = Util::base64Encode( tmp);
00182         delete[] tmp;
00183         sink->write( base64, strlen(base64));
00184         delete[] base64;
00185     }
00186 
00187     // send user agent info
00188     str = "\nUser-Agent: DarkIce/" VERSION " (http://darkice.sourceforge.net/)";
00189     sink->write( str, strlen( str));
00190 
00191     // send the ice- headers
00192     str = "\nice-bitrate: ";
00193     sink->write( str, strlen( str));
00194     if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) {
00195         throw Exception( __FILE__, __LINE__,
00196                          "bitrate does not fit string buffer", getBitRate());
00197     }
00198     sprintf( resp, "%d", getBitRate());
00199     sink->write( resp, strlen( resp));
00200 
00201     str = "\nice-public: ";
00202     sink->write( str, strlen( str));
00203     str = getIsPublic() ? "1" : "0";
00204     sink->write( str, strlen( str));
00205 
00206     if ( getName() ) {
00207         str = "\nice-name: ";
00208         sink->write( str, strlen( str));
00209         str = getName();
00210         sink->write( str, strlen( str));
00211     }
00212 
00213     if ( getDescription() ) {
00214         str = "\nice-description: ";
00215         sink->write( str, strlen( str));
00216         str = getDescription();
00217         sink->write( str, strlen( str));
00218     }
00219 
00220     if ( getUrl() ) {
00221         str = "\nice-url: ";
00222         sink->write( str, strlen( str));
00223         str = getUrl();
00224         sink->write( str, strlen( str));
00225     }
00226 
00227     if ( getGenre() ) {
00228         str = "\nice-genre: ";
00229         sink->write( str, strlen( str));
00230         str = getGenre();
00231         sink->write( str, strlen( str));
00232     }
00233 
00234     str = "\n\n";
00235     sink->write( str, strlen( str));
00236     sink->flush();
00237 
00238     // read the response, expected response begins with responseOK
00239     lenExpected = Util::strLen( responseOK);
00240     if ( (len = source->read( resp, STRBUF_SIZE-1)) < lenExpected ) {
00241         return false;
00242     }
00243     resp[lenExpected] = 0;
00244     if ( !Util::strEq( resp, responseOK) ) {
00245         return false;
00246     }
00247     
00248     // suck anything that the other side has to say
00249     while ( source->canRead( 0, 0) && 
00250            (len = source->read( resp, STRBUF_SIZE-1)) );
00251 
00252     return true;
00253 }
00254 
00255 
00256 
00257 /*------------------------------------------------------------------------------
00258  
00259   $Source: /cvsroot/darkice/darkice/src/IceCast2.cpp,v $
00260 
00261   $Log: IceCast2.cpp,v $
00262   Revision 1.12  2005/04/16 21:57:34  darkeye
00263   added AAC support through the faac codec, http://www.audiocoding.com/
00264 
00265   Revision 1.11  2005/04/11 18:32:32  darkeye
00266   changed MIME type to application/ogg, which is now official
00267 
00268   Revision 1.10  2002/11/29 08:14:47  darkeye
00269   fixed minor bug in IcecCast2.cpp, which could have lead to a buffer
00270   overflow
00271 
00272   Revision 1.9  2002/10/20 21:09:35  darkeye
00273   added processing of server response
00274 
00275   Revision 1.8  2002/08/20 20:16:59  darkeye
00276   added User-Agent header to HTTP login
00277 
00278   Revision 1.7  2002/08/20 19:34:43  darkeye
00279   minor fix
00280 
00281   Revision 1.6  2002/08/20 18:39:13  darkeye
00282   added HTTP Basic authentication for icecast2 logins
00283 
00284   Revision 1.5  2002/05/28 12:35:41  darkeye
00285   code cleanup: compiles under gcc-c++ 3.1, using -pedantic option
00286 
00287   Revision 1.4  2002/02/20 10:35:35  darkeye
00288   updated to work with Ogg Vorbis libs rc3 and current IceCast2 cvs
00289 
00290   Revision 1.3  2002/02/19 15:24:26  darkeye
00291   send Content-type header when logging in to icecast2 servers
00292 
00293   Revision 1.2  2001/11/20 09:06:18  darkeye
00294   fixed public stream reporting
00295 
00296   Revision 1.1  2001/09/14 19:31:06  darkeye
00297   added IceCast2 / vorbis support
00298 
00299 
00300   
00301 ------------------------------------------------------------------------------*/
00302 

Generated on Sat Oct 22 13:17:04 2005 for DarkIce by  doxygen 1.4.4