1 // ------------------------------------------------
6 // (c) 2002 peercast.org
7 // ------------------------------------------------
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 // ------------------------------------------------
32 // --------------------------------------------------
39 int sampling_frequency;
50 // ----------------------------------
63 void convertTo(String::TYPE t)
72 bool update(TrackInfo &);
74 ::String contact,title,artist,album,genre;
79 // ----------------------------------
123 void init(const char *);
124 void init(const char *, GnuID &, TYPE, int);
125 void init(XML::Node *);
126 void initNameID(const char *);
128 void updateFromXML(XML::Node *);
130 void readTrackXML(XML::Node *);
131 void readServentXML(XML::Node *);
132 bool update(ChanInfo &);
133 XML::Node *createQueryXML();
134 XML::Node *createChannelXML();
135 XML::Node *createRelayChannelXML();
136 XML::Node *createTrackXML();
137 bool match(XML::Node *);
138 bool match(ChanInfo &);
139 bool matchNameID(ChanInfo &);
141 void writeInfoAtoms(AtomStream &atom);
142 void writeTrackAtoms(AtomStream &atom);
144 void readInfoAtoms(AtomStream &,int);
145 void readTrackAtoms(AtomStream &,int);
147 unsigned int getUptime();
148 unsigned int getAge();
149 bool isActive() {return id.isSet();}
150 bool isPrivate() {return bcID.getFlags() & 1;}
151 static const char *getTypeStr(TYPE);
152 static const char *getProtocolStr(PROTOCOL);
153 static const char *getTypeExt(TYPE);
154 static TYPE getTypeFromStr(const char *str);
155 static PROTOCOL getProtocolFromStr(const char *str);
161 PROTOCOL srcProtocol;
162 unsigned int lastPlayStart,lastPlayEnd;
163 unsigned int numSkips;
164 unsigned int createdTime;
169 ::String desc,genre,url,comment;
174 // ----------------------------------
179 void initLocal(int numl,int numr,int nums,int uptm,bool,bool,unsigned int,Channel*,unsigned int,unsigned int);
180 XML::Node *createXML();
182 void writeAtoms(AtomStream &,GnuID &);
183 bool writeVariable(Stream &, const String &);
185 void pickNearestIP(Host &);
189 unsigned int numListeners,numRelays,numHops;
190 unsigned int time,upTime,lastContact;
192 GnuID sessionID,chanID;
193 unsigned int version;
194 unsigned int version_vp;
196 bool firewalled:1,stable:1,tracker:1,recv:1,yp:1,dead:1,direct:1,relay:1,cin:1;
197 bool relayfull:1,chfull:1,ratefull:1;
204 unsigned int oldestPos,newestPos;
206 unsigned int uphostHops;
208 char version_ex_prefix[2];
209 unsigned int version_ex_number;
211 unsigned int lastSendSeq;
213 // ----------------------------------
220 int contactTrackers(bool,int,int,int);
222 ChanHit *addHit(ChanHit &);
223 void delHit(ChanHit &);
224 void deadHit(ChanHit &);
225 void clearHits(bool);
233 unsigned int newestHit();
235 int pickHits(ChanHitSearch &);
236 int pickSourceHits(ChanHitSearch &);
238 bool isUsed() {return used;}
239 int clearDeadHits(unsigned int,bool);
240 XML::Node *createXML(bool addHits = true);
242 ChanHit *deleteHit(ChanHit *);
244 int getTotalListeners();
245 int getTotalRelays();
246 int getTotalFirewalled();
251 unsigned int lastHitTime;
256 // ----------------------------------
265 ChanHitSearch() { init(); }
268 ChanHit best[MAX_RESULTS];
270 unsigned int waitDelay;
273 bool useBusyRelays,useBusyControls;
278 int getRelayHost(Host host1, Host host2, GnuID exID, ChanHitList *chl);
281 // ----------------------------------
297 void fromMem(void *,int);
298 void addMem(void *,int);
300 unsigned int len,cnt,startPos;
301 char data[MAX_DATALEN];
306 // ------------------------------------------
307 class RawStream : public ChannelStream
310 virtual void readHeader(Stream &,Channel *);
311 virtual int readPacket(Stream &,Channel *);
312 virtual void readEnd(Stream &,Channel *);
316 // ------------------------------------------
317 class PeercastStream : public ChannelStream
320 virtual void readHeader(Stream &,Channel *);
321 virtual int readPacket(Stream &,Channel *);
322 virtual void readEnd(Stream &,Channel *);
325 // ------------------------------------------
329 virtual ~ChannelSource() {}
330 virtual void stream(Channel *) = 0;
332 virtual int getSourceRate() {return 0;}
335 // ------------------------------------------
336 class PeercastSource : public ChannelSource
341 virtual void stream(Channel *);
346 // ----------------------------------
388 void endThread(bool flg);
390 void startMP3File(char *);
392 void startICY(ClientSocket *,SRC_TYPE);
393 void startURL(const char *);
396 ChannelStream *createSource();
398 void resetPlayTime();
402 return (status == S_NOTFOUND);
407 return (status == S_RECEIVING) || (status == S_BROADCASTING);
412 return (status == S_RECEIVING);
415 bool isBroadcasting()
417 return (status == S_BROADCASTING);
425 void sleepUntil(double);
429 return type != T_NONE;
434 int handshakeFetch();
436 bool isIdle() {return isActive() && (status==S_IDLE);}
438 static THREAD_PROC stream(ThreadInfo *);
440 static THREAD_PROC waitFinish(ThreadInfo *);
442 void setStatus(STATUS s);
443 const char *getSrcTypeStr() {return srcTypes[srcType];}
444 const char *getStatusStr() {return statusMsgs[status];}
445 const char *getName() {return info.name.cstr();}
446 GnuID getID() {return info.id;}
447 int getBitrate() {return info.bitrate; }
448 void getIDStr(char *s) {info.id.toStr(s);}
449 void getStreamPath(char *);
451 void broadcastTrackerUpdate(GnuID &,bool = false);
452 bool sendPacketUp(ChanPacket &,GnuID &,GnuID &,GnuID &);
454 bool writeVariable(Stream &, const String &,int);
456 bool acceptGIV(ClientSocket *);
458 void updateInfo(ChanInfo &);
460 int readStream(Stream &,ChannelStream *);
462 void checkReadDelay(unsigned int);
464 void processMp3Metadata(char *);
470 XML::Node *createRelayXML(bool);
472 void newPacket(ChanPacket &);
474 int localListeners();
477 int totalListeners();
484 ChanPacketBuffer rawData;
486 ChannelStream *sourceStream;
487 unsigned int streamIndex;
498 bool bump,stayConnected;
500 unsigned int streamPos;
501 unsigned int skipCount; //JP-EX
505 ChannelSource *sourceData;
511 ThreadInfo *finthread;
513 unsigned int lastIdleTime;
515 static char *statusMsgs[],*srcTypes[];
518 ClientSocket *pushSock;
520 unsigned int lastTrackerUpdate;
521 unsigned int lastMetaUpdate;
523 double startTime,syncTime;
533 unsigned int lastSkipTime;
534 unsigned int lastStopTime;
536 int maxRelays; //
\83`
\83\83\83\93\83l
\83\8b\8cÅ
\97L
\82Ì
\83\8a\83\8c\81[
\8dÅ
\91å
\90\94(
\83R
\83\93\83X
\83g
\83\89\83N
\83^
\82Å
\8f\89\8aú
\89»)
539 // ----------------------------------
544 MAX_IDLE_CHANNELS = 8, // max. number of channels that can be left idle
545 MAX_METAINT = 8192 // must be at least smaller than ChanPacket data len (ie. about half)
552 Channel *deleteChannel(Channel *);
554 Channel *createChannel(ChanInfo &,const char *);
555 Channel *findChannelByName(const char *);
556 Channel *findChannelByIndex(int);
557 Channel *findChannelByMount(const char *);
558 Channel *findChannelByID(GnuID &);
559 Channel *findChannelByNameID(ChanInfo &);
560 Channel *findPushChannel(int);
561 Channel *findChannelByChannelID(int id);
563 void broadcastTrackerSettings();
564 void setUpdateInterval(unsigned int v);
565 void broadcastRelays(Servent *,int,int);
567 int broadcastPacketUp(ChanPacket &,GnuID &,GnuID &,GnuID &);
568 void broadcastTrackerUpdate(GnuID &,bool = false);
570 bool writeVariable(Stream &, const String &,int);
572 int findChannels(ChanInfo &,Channel **,int);
573 int findChannelsByStatus(Channel **,int,Channel::STATUS);
575 int numIdleChannels();
578 void closeOldestIdle();
582 void addHit(Host &,GnuID &,bool);
583 ChanHit *addHit(ChanHit &);
584 void delHit(ChanHit &);
585 void deadHit(ChanHit &);
586 void setFirewalled(Host &);
588 ChanHitList *findHitList(ChanInfo &);
589 ChanHitList *findHitListByID(GnuID &);
590 ChanHitList *addHitList(ChanInfo &);
592 void clearHitLists();
593 void clearDeadHits(bool);
596 void setBroadcastMsg(::String &);
598 Channel *createRelay(ChanInfo &,bool);
599 Channel *findAndRelay(ChanInfo &);
600 void startSearch(ChanInfo &);
602 void playChannel(ChanInfo &);
603 void findAndPlayChannel(ChanInfo &,bool);
605 bool isBroadcasting(GnuID &);
606 bool isBroadcasting();
608 int pickHits(ChanHitSearch &);
610 bool findParentHit(ChanHit &p);
613 ChanHitList *hitlist;
620 ::String broadcastMsg;
621 unsigned int broadcastMsgInterval;
622 unsigned int lastHit,lastQuery;
623 unsigned int maxUptime;
625 unsigned int deadHitAge;
627 int maxRelaysPerChannel;
629 int minBroadcastTTL,maxBroadcastTTL;
630 int pushTimeout,pushTries,maxPushHops;
631 unsigned int autoQuery;
632 unsigned int prefetchTime;
633 unsigned int lastYPConnect;
634 unsigned int lastYPConnect2;
635 unsigned int icyIndex;
637 unsigned int hostUpdateInterval;
638 unsigned int bufferTime;
640 GnuID currFindAndPlayChannel;
645 // ----------------------------------
659 PlayList(TYPE t, int max)
664 urls = new ::String[max];
665 titles = new ::String[max];
674 void addURL(const char *url, const char *tit)
676 if (numURLs < maxURLs)
678 urls[numURLs].set(url);
679 titles[numURLs].set(tit);
683 void addChannels(const char *,Channel **,int);
684 void addChannel(const char *,ChanInfo &);
686 void writeSCPLS(Stream &);
687 void writePLS(Stream &);
688 void writeASX(Stream &);
689 void writeRAM(Stream &);
691 void readSCPLS(Stream &);
692 void readPLS(Stream &);
693 void readASX(Stream &);
701 case T_SCPLS: readSCPLS(s); break;
702 case T_PLS: readPLS(s); break;
703 case T_ASX: readASX(s); break;
705 }catch(StreamException &) {} // keep pls regardless of errors (eof isn`t handled properly in sockets)
708 void write(Stream &s)
712 case T_SCPLS: writeSCPLS(s); break;
713 case T_PLS: writePLS(s); break;
714 case T_ASX: writeASX(s); break;
715 case T_RAM: writeRAM(s); break;
721 ::String *urls,*titles;
724 // ----------------------------------
726 extern ChanMgr *chanMgr;
729 bool isIndexTxt(ChanInfo *info);
730 bool isIndexTxt(Channel *ch);
731 int numMaxRelaysIndexTxt(Channel *ch);
732 int canStreamIndexTxt(Channel *ch);