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;
171 unsigned int ppFlags; //JP-MOD
175 // ----------------------------------
180 void initLocal(int numl,int numr,int nums,int uptm,bool,bool,unsigned int,Channel*,unsigned int,unsigned int);
181 void initLocal_pp(bool isStealth, int numClaps); //JP-MOD
182 XML::Node *createXML();
184 void writeAtoms(AtomStream &,GnuID &);
185 bool writeVariable(Stream &, const String &);
187 void pickNearestIP(Host &);
191 unsigned int numListeners,numRelays,numHops;
192 int clap_pp; //JP-MOD
193 unsigned int time,upTime,lastContact;
195 GnuID sessionID,chanID;
196 unsigned int version;
197 unsigned int version_vp;
199 bool firewalled:1,stable:1,tracker:1,recv:1,yp:1,dead:1,direct:1,relay:1,cin:1;
200 bool relayfull:1,chfull:1,ratefull:1;
207 unsigned int oldestPos,newestPos;
209 unsigned int uphostHops;
211 char version_ex_prefix[2];
212 unsigned int version_ex_number;
214 unsigned int lastSendSeq;
216 // ----------------------------------
223 int contactTrackers(bool,int,int,int);
225 ChanHit *addHit(ChanHit &);
226 void delHit(ChanHit &);
227 void deadHit(ChanHit &);
228 void clearHits(bool);
231 int numClaps(); //JP-MOD
237 unsigned int newestHit();
239 int pickHits(ChanHitSearch &);
240 int pickSourceHits(ChanHitSearch &);
242 bool isUsed() {return used;}
243 int clearDeadHits(unsigned int,bool);
244 XML::Node *createXML(bool addHits = true);
246 ChanHit *deleteHit(ChanHit *);
248 int getTotalListeners();
249 int getTotalRelays();
250 int getTotalFirewalled();
252 unsigned int getSeq();
257 unsigned int lastHitTime;
261 unsigned int riSequence;
263 // ----------------------------------
272 ChanHitSearch() { init(); }
275 ChanHit best[MAX_RESULTS];
277 unsigned int waitDelay;
280 bool useBusyRelays,useBusyControls;
285 int getRelayHost(Host host1, Host host2, GnuID exID, ChanHitList *chl);
288 // ----------------------------------
304 void fromMem(void *,int);
305 void addMem(void *,int);
307 unsigned int len,cnt,startPos;
308 char data[MAX_DATALEN];
313 // ------------------------------------------
314 class RawStream : public ChannelStream
317 virtual void readHeader(Stream &,Channel *);
318 virtual int readPacket(Stream &,Channel *);
319 virtual void readEnd(Stream &,Channel *);
323 // ------------------------------------------
324 class PeercastStream : public ChannelStream
327 virtual void readHeader(Stream &,Channel *);
328 virtual int readPacket(Stream &,Channel *);
329 virtual void readEnd(Stream &,Channel *);
332 // ------------------------------------------
336 virtual ~ChannelSource() {}
337 virtual void stream(Channel *) = 0;
339 virtual int getSourceRate() {return 0;}
342 // ------------------------------------------
343 class PeercastSource : public ChannelSource
348 virtual void stream(Channel *);
353 // ----------------------------------
395 void endThread(bool flg);
397 void startMP3File(char *);
399 void startICY(ClientSocket *,SRC_TYPE);
400 void startURL(const char *);
403 ChannelStream *createSource();
405 void resetPlayTime();
409 return (status == S_NOTFOUND);
414 return (status == S_RECEIVING) || (status == S_BROADCASTING);
419 return (status == S_RECEIVING);
422 bool isBroadcasting()
424 return (status == S_BROADCASTING);
432 void sleepUntil(double);
436 return type != T_NONE;
441 int handshakeFetch();
443 bool isIdle() {return isActive() && (status==S_IDLE);}
445 static THREAD_PROC stream(ThreadInfo *);
446 static THREAD_PROC streamMain(ThreadInfo *);
448 static THREAD_PROC waitFinish(ThreadInfo *);
449 static THREAD_PROC waitFinishMain(ThreadInfo *);
451 void setStatus(STATUS s);
452 const char *getSrcTypeStr() {return srcTypes[srcType];}
453 const char *getStatusStr() {return statusMsgs[status];}
454 const char *getName() {return info.name.cstr();}
455 GnuID getID() {return info.id;}
456 int getBitrate() {return info.bitrate; }
457 void getIDStr(char *s) {info.id.toStr(s);}
458 void getStreamPath(char *);
460 void broadcastTrackerUpdate(GnuID &,bool = false);
461 bool sendPacketUp(ChanPacket &,GnuID &,GnuID &,GnuID &);
463 bool writeVariable(Stream &, const String &,int);
465 bool acceptGIV(ClientSocket *);
467 void updateInfo(ChanInfo &);
469 int readStream(Stream &,ChannelStream *);
471 void checkReadDelay(unsigned int);
473 void processMp3Metadata(char *);
479 XML::Node *createRelayXML(bool);
481 void newPacket(ChanPacket &);
483 int localListeners();
486 int totalClaps(); //JP-MOD
487 int totalListeners();
494 ChanPacketBuffer rawData;
496 ChannelStream *sourceStream;
497 unsigned int streamIndex;
508 bool bump,stayConnected;
509 bool stealth; //JP-MOD
511 unsigned int streamPos;
512 unsigned int skipCount; //JP-EX
514 int overrideMaxRelaysPerChannel; //JP-MOD
518 ChannelSource *sourceData;
524 ThreadInfo *finthread;
526 unsigned int lastIdleTime;
528 static char *statusMsgs[],*srcTypes[];
531 ClientSocket *pushSock;
533 unsigned int lastTrackerUpdate;
534 unsigned int lastMetaUpdate;
536 double startTime,syncTime;
546 unsigned int lastSkipTime;
547 unsigned int lastStopTime;
549 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»)
552 // ----------------------------------
557 MAX_IDLE_CHANNELS = 8, // max. number of channels that can be left idle
558 MAX_METAINT = 8192 // must be at least smaller than ChanPacket data len (ie. about half)
565 Channel *deleteChannel(Channel *);
567 Channel *createChannel(ChanInfo &,const char *);
568 Channel *findChannelByName(const char *);
569 Channel *findChannelByIndex(int);
570 Channel *findChannelByMount(const char *);
571 Channel *findChannelByID(GnuID &);
572 Channel *findChannelByNameID(ChanInfo &);
573 Channel *findPushChannel(int);
574 Channel *findChannelByChannelID(int id);
576 void broadcastTrackerSettings();
577 void setUpdateInterval(unsigned int v);
578 void broadcastRelays(Servent *,int,int);
580 int broadcastPacketUp(ChanPacket &,GnuID &,GnuID &,GnuID &);
581 void broadcastTrackerUpdate(GnuID &,bool = false);
583 bool writeVariable(Stream &, const String &,int);
585 int findChannels(ChanInfo &,Channel **,int);
586 int findChannelsByStatus(Channel **,int,Channel::STATUS);
588 int numIdleChannels();
591 void closeOldestIdle();
595 void addHit(Host &,GnuID &,bool);
596 ChanHit *addHit(ChanHit &);
597 void delHit(ChanHit &);
598 void deadHit(ChanHit &);
599 void setFirewalled(Host &);
601 ChanHitList *findHitList(ChanInfo &);
602 ChanHitList *findHitListByID(GnuID &);
603 ChanHitList *addHitList(ChanInfo &);
605 void clearHitLists();
606 void clearDeadHits(bool);
609 void setBroadcastMsg(::String &);
611 Channel *createRelay(ChanInfo &,bool);
612 Channel *findAndRelay(ChanInfo &);
613 void startSearch(ChanInfo &);
615 void playChannel(ChanInfo &);
616 void findAndPlayChannel(ChanInfo &,bool);
618 bool isBroadcasting(GnuID &);
619 bool isBroadcasting();
621 int pickHits(ChanHitSearch &);
623 bool findParentHit(ChanHit &p);
626 ChanHitList *hitlist;
633 ::String broadcastMsg;
634 unsigned int broadcastMsgInterval;
635 unsigned int lastHit,lastQuery;
636 unsigned int maxUptime;
638 unsigned int deadHitAge;
640 int maxRelaysPerChannel;
642 int minBroadcastTTL,maxBroadcastTTL;
643 int pushTimeout,pushTries,maxPushHops;
644 unsigned int autoQuery;
645 unsigned int prefetchTime;
646 unsigned int lastYPConnect;
647 unsigned int lastYPConnect2;
648 unsigned int icyIndex;
650 unsigned int hostUpdateInterval;
651 unsigned int bufferTime;
653 GnuID currFindAndPlayChannel;
658 // ----------------------------------
672 PlayList(TYPE t, int max)
677 urls = new ::String[max];
678 titles = new ::String[max];
679 contacturls = new ::String[max]; //JP-MOD
686 delete [] contacturls; //JP-MOD
689 void addURL(const char *url, const char *tit, const char *contacturl/*JP-MOD*/)
691 if (numURLs < maxURLs)
693 urls[numURLs].set(url);
694 titles[numURLs].set(tit);
695 contacturls[numURLs].set(contacturl); //JP-MOD
699 void addChannels(const char *,Channel **,int);
700 void addChannel(const char *,ChanInfo &);
702 void writeSCPLS(Stream &);
703 void writePLS(Stream &);
704 void writeASX(Stream &);
705 void writeRAM(Stream &);
707 void readSCPLS(Stream &);
708 void readPLS(Stream &);
709 void readASX(Stream &);
717 case T_SCPLS: readSCPLS(s); break;
718 case T_PLS: readPLS(s); break;
719 case T_ASX: readASX(s); break;
721 }catch(StreamException &) {} // keep pls regardless of errors (eof isn`t handled properly in sockets)
724 void write(Stream &s)
728 case T_SCPLS: writeSCPLS(s); break;
729 case T_PLS: writePLS(s); break;
730 case T_ASX: writeASX(s); break;
731 case T_RAM: writeRAM(s); break;
737 ::String *urls,*titles;
738 ::String *contacturls; //JP-MOD
741 // ----------------------------------
743 extern ChanMgr *chanMgr;
746 bool isIndexTxt(ChanInfo *info);
747 bool isIndexTxt(Channel *ch);
748 int numMaxRelaysIndexTxt(Channel *ch);
749 int canStreamIndexTxt(Channel *ch);