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 // ----------------------------------
218 int contactTrackers(bool,int,int,int);
220 ChanHit *addHit(ChanHit &);
221 void delHit(ChanHit &);
222 void deadHit(ChanHit &);
223 void clearHits(bool);
231 unsigned int newestHit();
233 int pickHits(ChanHitSearch &);
234 int pickSourceHits(ChanHitSearch &);
236 bool isUsed() {return used;}
237 int clearDeadHits(unsigned int,bool);
238 XML::Node *createXML(bool addHits = true);
240 ChanHit *deleteHit(ChanHit *);
242 int getTotalListeners();
243 int getTotalRelays();
244 int getTotalFirewalled();
249 unsigned int lastHitTime;
254 // ----------------------------------
263 ChanHitSearch() { init(); }
266 ChanHit best[MAX_RESULTS];
268 unsigned int waitDelay;
271 bool useBusyRelays,useBusyControls;
276 int getRelayHost(Host host1, Host host2, GnuID exID, ChanHitList *chl);
279 // ----------------------------------
295 void fromMem(void *,int);
296 void addMem(void *,int);
298 unsigned int len,cnt,startPos;
299 char data[MAX_DATALEN];
304 // ------------------------------------------
305 class RawStream : public ChannelStream
308 virtual void readHeader(Stream &,Channel *);
309 virtual int readPacket(Stream &,Channel *);
310 virtual void readEnd(Stream &,Channel *);
314 // ------------------------------------------
315 class PeercastStream : public ChannelStream
318 virtual void readHeader(Stream &,Channel *);
319 virtual int readPacket(Stream &,Channel *);
320 virtual void readEnd(Stream &,Channel *);
323 // ------------------------------------------
327 virtual ~ChannelSource() {}
328 virtual void stream(Channel *) = 0;
330 virtual int getSourceRate() {return 0;}
333 // ------------------------------------------
334 class PeercastSource : public ChannelSource
339 virtual void stream(Channel *);
344 // ----------------------------------
386 void endThread(bool flg);
388 void startMP3File(char *);
390 void startICY(ClientSocket *,SRC_TYPE);
391 void startURL(const char *);
394 ChannelStream *createSource();
396 void resetPlayTime();
400 return (status == S_NOTFOUND);
405 return (status == S_RECEIVING) || (status == S_BROADCASTING);
410 return (status == S_RECEIVING);
413 bool isBroadcasting()
415 return (status == S_BROADCASTING);
423 void sleepUntil(double);
427 return type != T_NONE;
432 int handshakeFetch();
434 bool isIdle() {return isActive() && (status==S_IDLE);}
436 static THREAD_PROC stream(ThreadInfo *);
438 static THREAD_PROC waitFinish(ThreadInfo *);
440 void setStatus(STATUS s);
441 const char *getSrcTypeStr() {return srcTypes[srcType];}
442 const char *getStatusStr() {return statusMsgs[status];}
443 const char *getName() {return info.name.cstr();}
444 GnuID getID() {return info.id;}
445 int getBitrate() {return info.bitrate; }
446 void getIDStr(char *s) {info.id.toStr(s);}
447 void getStreamPath(char *);
449 void broadcastTrackerUpdate(GnuID &,bool = false);
450 bool sendPacketUp(ChanPacket &,GnuID &,GnuID &,GnuID &);
452 bool writeVariable(Stream &, const String &,int);
454 bool acceptGIV(ClientSocket *);
456 void updateInfo(ChanInfo &);
458 int readStream(Stream &,ChannelStream *);
460 void checkReadDelay(unsigned int);
462 void processMp3Metadata(char *);
468 XML::Node *createRelayXML(bool);
470 void newPacket(ChanPacket &);
472 int localListeners();
475 int totalListeners();
482 ChanPacketBuffer rawData;
484 ChannelStream *sourceStream;
485 unsigned int streamIndex;
496 bool bump,stayConnected;
498 unsigned int streamPos;
499 unsigned int skipCount; //JP-EX
503 ChannelSource *sourceData;
509 ThreadInfo *finthread;
511 unsigned int lastIdleTime;
513 static char *statusMsgs[],*srcTypes[];
516 ClientSocket *pushSock;
518 unsigned int lastTrackerUpdate;
519 unsigned int lastMetaUpdate;
521 double startTime,syncTime;
531 unsigned int lastSkipTime;
532 unsigned int lastStopTime;
535 // ----------------------------------
540 MAX_IDLE_CHANNELS = 8, // max. number of channels that can be left idle
541 MAX_METAINT = 8192 // must be at least smaller than ChanPacket data len (ie. about half)
548 Channel *deleteChannel(Channel *);
550 Channel *createChannel(ChanInfo &,const char *);
551 Channel *findChannelByName(const char *);
552 Channel *findChannelByIndex(int);
553 Channel *findChannelByMount(const char *);
554 Channel *findChannelByID(GnuID &);
555 Channel *findChannelByNameID(ChanInfo &);
556 Channel *findPushChannel(int);
557 Channel *findChannelByChannelID(int id);
559 void broadcastTrackerSettings();
560 void setUpdateInterval(unsigned int v);
561 void broadcastRelays(Servent *,int,int);
563 int broadcastPacketUp(ChanPacket &,GnuID &,GnuID &,GnuID &);
564 void broadcastTrackerUpdate(GnuID &,bool = false);
566 bool writeVariable(Stream &, const String &,int);
568 int findChannels(ChanInfo &,Channel **,int);
569 int findChannelsByStatus(Channel **,int,Channel::STATUS);
571 int numIdleChannels();
574 void closeOldestIdle();
578 void addHit(Host &,GnuID &,bool);
579 ChanHit *addHit(ChanHit &);
580 void delHit(ChanHit &);
581 void deadHit(ChanHit &);
582 void setFirewalled(Host &);
584 ChanHitList *findHitList(ChanInfo &);
585 ChanHitList *findHitListByID(GnuID &);
586 ChanHitList *addHitList(ChanInfo &);
588 void clearHitLists();
589 void clearDeadHits(bool);
592 void setBroadcastMsg(::String &);
594 Channel *createRelay(ChanInfo &,bool);
595 Channel *findAndRelay(ChanInfo &);
596 void startSearch(ChanInfo &);
598 void playChannel(ChanInfo &);
599 void findAndPlayChannel(ChanInfo &,bool);
601 bool isBroadcasting(GnuID &);
602 bool isBroadcasting();
604 int pickHits(ChanHitSearch &);
609 ChanHitList *hitlist;
616 ::String broadcastMsg;
617 unsigned int broadcastMsgInterval;
618 unsigned int lastHit,lastQuery;
619 unsigned int maxUptime;
621 unsigned int deadHitAge;
623 int maxRelaysPerChannel;
625 int minBroadcastTTL,maxBroadcastTTL;
626 int pushTimeout,pushTries,maxPushHops;
627 unsigned int autoQuery;
628 unsigned int prefetchTime;
629 unsigned int lastYPConnect;
630 unsigned int lastYPConnect2;
631 unsigned int icyIndex;
633 unsigned int hostUpdateInterval;
634 unsigned int bufferTime;
636 GnuID currFindAndPlayChannel;
641 // ----------------------------------
655 PlayList(TYPE t, int max)
660 urls = new ::String[max];
661 titles = new ::String[max];
670 void addURL(const char *url, const char *tit)
672 if (numURLs < maxURLs)
674 urls[numURLs].set(url);
675 titles[numURLs].set(tit);
679 void addChannels(const char *,Channel **,int);
680 void addChannel(const char *,ChanInfo &);
682 void writeSCPLS(Stream &);
683 void writePLS(Stream &);
684 void writeASX(Stream &);
685 void writeRAM(Stream &);
687 void readSCPLS(Stream &);
688 void readPLS(Stream &);
689 void readASX(Stream &);
697 case T_SCPLS: readSCPLS(s); break;
698 case T_PLS: readPLS(s); break;
699 case T_ASX: readASX(s); break;
701 }catch(StreamException &) {} // keep pls regardless of errors (eof isn`t handled properly in sockets)
704 void write(Stream &s)
708 case T_SCPLS: writeSCPLS(s); break;
709 case T_PLS: writePLS(s); break;
710 case T_ASX: writeASX(s); break;
711 case T_RAM: writeRAM(s); break;
717 ::String *urls,*titles;
720 // ----------------------------------
722 extern ChanMgr *chanMgr;
725 bool isIndexTxt(ChanInfo *info);
726 bool isIndexTxt(Channel *ch);
727 int numMaxRelaysIndexTxt(Channel *ch);
728 int canStreamIndexTxt(Channel *ch);