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 const char *getTypeStr();
152 const char *getTypeExt();
153 const char *getMIMEType();
154 static const char *getTypeStr(TYPE);
155 static const char *getProtocolStr(PROTOCOL);
156 static const char *getTypeExt(TYPE);
157 static const char *getMIMEType(TYPE);
158 static TYPE getTypeFromStr(const char *str);
159 static PROTOCOL getProtocolFromStr(const char *str);
165 ::String contentTypeStr,streamType,streamExt;
166 PROTOCOL srcProtocol;
167 unsigned int lastPlayStart,lastPlayEnd;
168 unsigned int numSkips;
169 unsigned int createdTime;
174 ::String desc,genre,url,comment;
176 unsigned int ppFlags; //JP-MOD
180 // ----------------------------------
185 void initLocal(int numl,int numr,int nums,int uptm,bool,bool,unsigned int,Channel*,unsigned int,unsigned int);
186 void initLocal_pp(bool isStealth, int numClaps); //JP-MOD
187 XML::Node *createXML();
189 void writeAtoms(AtomStream &,GnuID &);
190 bool writeVariable(Stream &, const String &);
192 void pickNearestIP(Host &);
196 unsigned int numListeners,numRelays,numHops;
197 int clap_pp; //JP-MOD
198 unsigned int time,upTime,lastContact;
200 GnuID sessionID,chanID;
201 unsigned int version;
202 unsigned int version_vp;
204 bool firewalled:1,stable:1,tracker:1,recv:1,yp:1,dead:1,direct:1,relay:1,cin:1;
205 bool relayfull:1,chfull:1,ratefull:1;
212 unsigned int oldestPos,newestPos;
214 unsigned int uphostHops;
216 char version_ex_prefix[2];
217 unsigned int version_ex_number;
219 unsigned int lastSendSeq;
221 // ----------------------------------
228 int contactTrackers(bool,int,int,int);
230 ChanHit *addHit(ChanHit &);
231 void delHit(ChanHit &);
232 void deadHit(ChanHit &);
233 void clearHits(bool);
236 int numClaps(); //JP-MOD
242 unsigned int newestHit();
244 int pickHits(ChanHitSearch &);
245 int pickSourceHits(ChanHitSearch &);
247 bool isUsed() {return used;}
248 int clearDeadHits(unsigned int,bool);
249 XML::Node *createXML(bool addHits = true);
251 ChanHit *deleteHit(ChanHit *);
253 int getTotalListeners();
254 int getTotalRelays();
255 int getTotalFirewalled();
257 unsigned int getSeq();
262 unsigned int lastHitTime;
266 unsigned int riSequence;
268 // ----------------------------------
277 ChanHitSearch() { init(); }
280 ChanHit best[MAX_RESULTS];
282 unsigned int waitDelay;
285 bool useBusyRelays,useBusyControls;
290 int getRelayHost(Host host1, Host host2, GnuID exID, ChanHitList *chl);
293 // ----------------------------------
309 void fromMem(void *,int);
310 void addMem(void *,int);
312 unsigned int len,cnt,startPos;
313 char data[MAX_DATALEN];
318 // ------------------------------------------
319 class RawStream : public ChannelStream
322 virtual void readHeader(Stream &,Channel *);
323 virtual int readPacket(Stream &,Channel *);
324 virtual void readEnd(Stream &,Channel *);
328 // ------------------------------------------
329 class PeercastStream : public ChannelStream
332 virtual void readHeader(Stream &,Channel *);
333 virtual int readPacket(Stream &,Channel *);
334 virtual void readEnd(Stream &,Channel *);
337 // ------------------------------------------
341 virtual ~ChannelSource() {}
342 virtual void stream(Channel *) = 0;
344 virtual int getSourceRate() {return 0;}
347 // ------------------------------------------
348 class PeercastSource : public ChannelSource
353 virtual void stream(Channel *);
358 // ----------------------------------
400 void endThread(bool flg);
402 void startMP3File(char *);
404 void startICY(ClientSocket *,SRC_TYPE);
405 void startURL(const char *);
408 ChannelStream *createSource();
410 void resetPlayTime();
414 return (status == S_NOTFOUND);
419 return (status == S_RECEIVING) || (status == S_BROADCASTING);
424 return (status == S_RECEIVING);
427 bool isBroadcasting()
429 return (status == S_BROADCASTING);
437 void sleepUntil(double);
441 return type != T_NONE;
446 int handshakeFetch();
448 bool isIdle() {return isActive() && (status==S_IDLE);}
450 static THREAD_PROC stream(ThreadInfo *);
451 static THREAD_PROC streamMain(ThreadInfo *);
453 static THREAD_PROC waitFinish(ThreadInfo *);
454 static THREAD_PROC waitFinishMain(ThreadInfo *);
456 void setStatus(STATUS s);
457 const char *getSrcTypeStr() {return srcTypes[srcType];}
458 const char *getStatusStr() {return statusMsgs[status];}
459 const char *getName() {return info.name.cstr();}
460 GnuID getID() {return info.id;}
461 int getBitrate() {return info.bitrate; }
462 void getIDStr(char *s) {info.id.toStr(s);}
463 void getStreamPath(char *);
465 void broadcastTrackerUpdate(GnuID &,bool = false);
466 bool sendPacketUp(ChanPacket &,GnuID &,GnuID &,GnuID &);
468 bool writeVariable(Stream &, const String &,int);
470 bool acceptGIV(ClientSocket *);
472 void updateInfo(ChanInfo &);
474 int readStream(Stream &,ChannelStream *);
476 void checkReadDelay(unsigned int);
478 void processMp3Metadata(char *);
484 XML::Node *createRelayXML(bool);
486 void newPacket(ChanPacket &);
488 int localListeners();
491 int totalClaps(); //JP-MOD
492 int totalListeners();
499 ChanPacketBuffer rawData;
501 ChannelStream *sourceStream;
502 unsigned int streamIndex;
513 bool bump,stayConnected;
514 bool stealth; //JP-MOD
516 unsigned int streamPos;
517 unsigned int skipCount; //JP-EX
519 int overrideMaxRelaysPerChannel; //JP-MOD
523 ChannelSource *sourceData;
529 ThreadInfo *finthread;
531 unsigned int lastIdleTime;
533 static char *statusMsgs[],*srcTypes[];
536 ClientSocket *pushSock;
538 unsigned int lastTrackerUpdate;
539 unsigned int lastMetaUpdate;
541 double startTime,syncTime;
551 unsigned int lastSkipTime;
552 unsigned int lastStopTime;
554 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»)
557 // ----------------------------------
562 MAX_IDLE_CHANNELS = 8, // max. number of channels that can be left idle
563 MAX_METAINT = 8192 // must be at least smaller than ChanPacket data len (ie. about half)
570 Channel *deleteChannel(Channel *);
572 Channel *createChannel(ChanInfo &,const char *);
573 Channel *findChannelByName(const char *);
574 Channel *findChannelByIndex(int);
575 Channel *findChannelByMount(const char *);
576 Channel *findChannelByID(GnuID &);
577 Channel *findChannelByNameID(ChanInfo &);
578 Channel *findPushChannel(int);
579 Channel *findChannelByChannelID(int id);
581 void broadcastTrackerSettings();
582 void setUpdateInterval(unsigned int v);
583 void broadcastRelays(Servent *,int,int);
585 int broadcastPacketUp(ChanPacket &,GnuID &,GnuID &,GnuID &);
586 void broadcastTrackerUpdate(GnuID &,bool = false);
588 bool writeVariable(Stream &, const String &,int);
590 int findChannels(ChanInfo &,Channel **,int);
591 int findChannelsByStatus(Channel **,int,Channel::STATUS);
593 int numIdleChannels();
596 void closeOldestIdle();
600 void addHit(Host &,GnuID &,bool);
601 ChanHit *addHit(ChanHit &);
602 void delHit(ChanHit &);
603 void deadHit(ChanHit &);
604 void setFirewalled(Host &);
606 ChanHitList *findHitList(ChanInfo &);
607 ChanHitList *findHitListByID(GnuID &);
608 ChanHitList *addHitList(ChanInfo &);
610 void clearHitLists();
611 void clearDeadHits(bool);
614 void setBroadcastMsg(::String &);
616 Channel *createRelay(ChanInfo &,bool);
617 Channel *findAndRelay(ChanInfo &);
618 void startSearch(ChanInfo &);
620 void playChannel(ChanInfo &);
621 void findAndPlayChannel(ChanInfo &,bool);
623 bool isBroadcasting(GnuID &);
624 bool isBroadcasting();
626 int pickHits(ChanHitSearch &);
628 bool findParentHit(ChanHit &p);
631 ChanHitList *hitlist;
638 ::String broadcastMsg;
639 unsigned int broadcastMsgInterval;
640 unsigned int lastHit,lastQuery;
641 unsigned int maxUptime;
643 unsigned int deadHitAge;
645 int maxRelaysPerChannel;
647 int minBroadcastTTL,maxBroadcastTTL;
648 int pushTimeout,pushTries,maxPushHops;
649 unsigned int autoQuery;
650 unsigned int prefetchTime;
651 unsigned int lastYPConnect;
652 unsigned int lastYPConnect2;
653 unsigned int icyIndex;
655 unsigned int hostUpdateInterval;
656 unsigned int bufferTime;
658 GnuID currFindAndPlayChannel;
663 // ----------------------------------
677 PlayList(TYPE t, int max)
682 urls = new ::String[max];
683 titles = new ::String[max];
684 contacturls = new ::String[max]; //JP-MOD
691 delete [] contacturls; //JP-MOD
694 void addURL(const char *url, const char *tit, const char *contacturl/*JP-MOD*/)
696 if (numURLs < maxURLs)
698 urls[numURLs].set(url);
699 titles[numURLs].set(tit);
700 contacturls[numURLs].set(contacturl); //JP-MOD
704 void addChannels(const char *,Channel **,int);
705 void addChannel(const char *,ChanInfo &);
707 void writeSCPLS(Stream &);
708 void writePLS(Stream &);
709 void writeASX(Stream &);
710 void writeRAM(Stream &);
712 void readSCPLS(Stream &);
713 void readPLS(Stream &);
714 void readASX(Stream &);
722 case T_SCPLS: readSCPLS(s); break;
723 case T_PLS: readPLS(s); break;
724 case T_ASX: readASX(s); break;
726 }catch(StreamException &) {} // keep pls regardless of errors (eof isn`t handled properly in sockets)
729 void write(Stream &s)
733 case T_SCPLS: writeSCPLS(s); break;
734 case T_PLS: writePLS(s); break;
735 case T_ASX: writeASX(s); break;
736 case T_RAM: writeRAM(s); break;
742 ::String *urls,*titles;
743 ::String *contacturls; //JP-MOD
746 // ----------------------------------
748 extern ChanMgr *chanMgr;
751 bool isIndexTxt(ChanInfo *info);
752 bool isIndexTxt(Channel *ch);
753 int numMaxRelaysIndexTxt(Channel *ch);
754 int canStreamIndexTxt(Channel *ch);