OSDN Git Service

VP27マージ
[peercast-im/PeerCastIM.git] / c: / Git / PeerCast.root / PeerCast / core / common / channel.h
1 // ------------------------------------------------
2 // File : channel.h
3 // Date: 4-apr-2002
4 // Author: giles
5 //
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.
12
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 // ------------------------------------------------
18
19 #ifndef _CHANNEL_H
20 #define _CHANNEL_H
21
22 #include "sys.h"
23 #include "stream.h"
24 #include "gnutella.h"
25 #include "xml.h"
26 #include "asf.h"
27 #include "cstream.h"
28
29 class AtomStream;
30 class ChanHitSearch;
31
32 // --------------------------------------------------
33 struct MP3Header
34 {
35         int lay;
36         int version;
37         int error_protection;
38         int bitrate_index;
39         int sampling_frequency;
40         int padding;
41         int extension;
42         int mode;
43         int mode_ext;
44         int copyright;
45         int original;
46         int emphasis;
47         int stereo;
48 };
49
50 // ----------------------------------
51 class TrackInfo
52 {
53 public:
54         void    clear()
55         {
56                 contact.clear();
57                 title.clear();
58                 artist.clear();
59                 album.clear();
60                 genre.clear();
61         }
62
63         void    convertTo(String::TYPE t)
64         {
65                 contact.convertTo(t);
66                 title.convertTo(t);
67                 artist.convertTo(t);
68                 album.convertTo(t);
69                 genre.convertTo(t);
70         }
71
72         bool    update(TrackInfo &);
73
74         ::String        contact,title,artist,album,genre;
75 };
76
77
78
79 // ----------------------------------
80 class ChanInfo
81 {
82 public:
83         enum TYPE
84         {
85                 T_UNKNOWN,
86
87                 T_RAW,
88                 T_MP3,
89                 T_OGG,
90                 T_OGM,
91                 T_MOV,
92                 T_MPG,
93                 T_NSV,
94
95                 T_WMA,
96                 T_WMV,
97
98                 T_PLS,
99                 T_ASX
100         };
101
102
103         enum PROTOCOL
104         {
105                 SP_UNKNOWN,
106                 SP_PEERCAST,
107                 SP_HTTP,
108                 SP_FILE,
109                 SP_MMS,
110                 SP_PCP
111         };
112
113
114         enum STATUS
115         {
116                 S_UNKNOWN,
117                 S_PLAY
118         };
119
120         ChanInfo() {init();}
121
122         void    init();
123         void    init(const char *);
124         void    init(const char *, GnuID &, TYPE, int);
125         void    init(XML::Node *);
126         void    initNameID(const char *);
127
128         void    updateFromXML(XML::Node *);
129
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 &);
140
141         void    writeInfoAtoms(AtomStream &atom);
142         void    writeTrackAtoms(AtomStream &atom);
143
144         void    readInfoAtoms(AtomStream &,int);
145         void    readTrackAtoms(AtomStream &,int);
146
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);
156
157         ::String        name;
158         GnuID   id,bcID;
159         int             bitrate;
160         TYPE    contentType;
161         PROTOCOL        srcProtocol;
162         unsigned int lastPlayStart,lastPlayEnd;
163         unsigned int numSkips;
164         unsigned int createdTime;
165
166         STATUS  status;
167
168         TrackInfo       track;
169         ::String        desc,genre,url,comment;
170
171         unsigned int ppFlags; //JP-MOD
172 };
173
174
175 // ----------------------------------
176 class ChanHit
177 {
178 public:
179         void    init();
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();
183
184         void    writeAtoms(AtomStream &,GnuID &);
185         bool    writeVariable(Stream &, const String &);
186
187         void    pickNearestIP(Host &);
188
189         Host                            host;
190         Host                            rhost[2];
191         unsigned int            numListeners,numRelays,numHops;
192         int                                     clap_pp;        //JP-MOD
193         unsigned int            time,upTime,lastContact;
194         unsigned int            hitID;
195         GnuID                           sessionID,chanID;
196         unsigned int            version;
197         unsigned int            version_vp;
198
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;
201
202         ChanHit *next;
203
204         int status;
205         int servent_id;
206
207         unsigned int            oldestPos,newestPos;
208         Host uphost;
209         unsigned int            uphostHops;
210
211         char                            version_ex_prefix[2];
212         unsigned int            version_ex_number;
213
214         unsigned int lastSendSeq;
215 };
216 // ----------------------------------
217 class ChanHitList
218 {
219 public:
220         ChanHitList();
221         ~ChanHitList();
222
223         int             contactTrackers(bool,int,int,int);
224
225         ChanHit *addHit(ChanHit &);
226         void    delHit(ChanHit &);
227         void    deadHit(ChanHit &);
228         void    clearHits(bool);
229         int             numHits();
230         int             numListeners();
231         int             numClaps();     //JP-MOD
232         int             numRelays();
233         int             numFirewalled();
234         int             numTrackers();
235         int             closestHit();
236         int             furthestHit();
237         unsigned int            newestHit();
238
239         int                     pickHits(ChanHitSearch &);
240         int                     pickSourceHits(ChanHitSearch &);
241
242         bool    isUsed() {return used;}
243         int             clearDeadHits(unsigned int,bool);
244         XML::Node *createXML(bool addHits = true);
245
246         ChanHit *deleteHit(ChanHit *);
247
248         int             getTotalListeners();
249         int             getTotalRelays();
250         int             getTotalFirewalled();
251
252         bool    used;
253         ChanInfo        info;
254         ChanHit *hit;
255         unsigned int lastHitTime;
256         ChanHitList *next;
257
258
259 };
260 // ----------------------------------
261 class ChanHitSearch
262 {
263 public:
264         enum
265         {
266                 MAX_RESULTS = 8
267         };
268
269         ChanHitSearch() { init(); }
270         void init();
271
272         ChanHit best[MAX_RESULTS];
273         Host    matchHost;
274         unsigned int waitDelay;
275         bool    useFirewalled;
276         bool    trackersOnly;
277         bool    useBusyRelays,useBusyControls;
278         GnuID   excludeID;
279         int             numResults;
280         unsigned int seed;
281
282         int getRelayHost(Host host1, Host host2, GnuID exID, ChanHitList *chl);
283 };
284
285 // ----------------------------------
286 class ChanMeta
287 {
288 public:
289         enum {
290                 MAX_DATALEN = 65536
291         };
292
293         void    init()
294         {
295                 len = 0;
296                 cnt = 0;
297                 startPos = 0;
298         }
299
300         void    fromXML(XML &);
301         void    fromMem(void *,int);
302         void    addMem(void *,int);
303
304         unsigned int len,cnt,startPos;
305         char    data[MAX_DATALEN];
306 };
307
308
309
310 // ------------------------------------------
311 class RawStream : public ChannelStream
312 {
313 public:
314         virtual void readHeader(Stream &,Channel *);
315         virtual int readPacket(Stream &,Channel *);
316         virtual void readEnd(Stream &,Channel *);
317
318 };
319
320 // ------------------------------------------
321 class PeercastStream : public ChannelStream
322 {
323 public:
324         virtual void readHeader(Stream &,Channel *);
325         virtual int  readPacket(Stream &,Channel *);
326         virtual void readEnd(Stream &,Channel *);
327 };
328
329 // ------------------------------------------
330 class ChannelSource
331 {
332 public:
333         virtual ~ChannelSource() {}
334         virtual void stream(Channel *) = 0;
335
336         virtual int getSourceRate() {return 0;}
337
338 };
339 // ------------------------------------------
340 class PeercastSource : public ChannelSource
341 {
342 public:
343
344
345         virtual void stream(Channel *);
346
347 };
348
349
350 // ----------------------------------
351 class Channel
352 {
353 public:
354         
355         enum STATUS
356         {
357                 S_NONE,
358                 S_WAIT,
359                 S_CONNECTING,
360                 S_REQUESTING,
361                 S_CLOSING,
362                 S_RECEIVING,
363                 S_BROADCASTING,
364                 S_ABORT,
365                 S_SEARCHING,
366                 S_NOHOSTS,
367                 S_IDLE,
368                 S_ERROR,
369                 S_NOTFOUND
370         };
371
372         enum TYPE
373         {
374                 T_NONE,
375                 T_ALLOCATED,
376                 T_BROADCAST,
377                 T_RELAY
378         };
379
380         enum SRC_TYPE
381         {
382                 SRC_NONE,
383                 SRC_PEERCAST,
384                 SRC_SHOUTCAST,
385                 SRC_ICECAST,
386                 SRC_URL
387         };
388
389
390         Channel();
391         void    reset();
392         void    endThread(bool flg);
393
394         void    startMP3File(char *);
395         void    startGet();
396         void    startICY(ClientSocket *,SRC_TYPE);
397         void    startURL(const char *);
398
399
400         ChannelStream   *createSource();
401
402         void    resetPlayTime();
403
404         bool    notFound()
405         {
406                 return (status == S_NOTFOUND);
407         }
408
409         bool    isPlaying()
410         {
411                 return (status == S_RECEIVING) || (status == S_BROADCASTING);
412         }
413
414         bool    isReceiving()
415         {
416                 return (status == S_RECEIVING);
417         }
418
419         bool    isBroadcasting()
420         {
421                 return (status == S_BROADCASTING);
422         }
423
424         bool    isFull();
425
426         bool    checkBump();
427
428         bool    checkIdle();
429         void    sleepUntil(double);
430
431         bool    isActive()
432         {
433                 return type != T_NONE;
434         }
435
436
437         void    connectFetch();
438         int             handshakeFetch();
439
440         bool    isIdle() {return isActive() && (status==S_IDLE);}
441
442         static THREAD_PROC      stream(ThreadInfo *);
443
444         static THREAD_PROC  waitFinish(ThreadInfo *);
445
446         void    setStatus(STATUS s);
447         const char  *getSrcTypeStr() {return srcTypes[srcType];}
448         const char      *getStatusStr() {return statusMsgs[status];}
449         const char      *getName() {return info.name.cstr();}
450         GnuID   getID() {return info.id;}
451         int             getBitrate() {return info.bitrate; }
452         void    getIDStr(char *s) {info.id.toStr(s);}
453         void    getStreamPath(char *);
454
455         void    broadcastTrackerUpdate(GnuID &,bool = false);
456         bool    sendPacketUp(ChanPacket &,GnuID &,GnuID &,GnuID &);
457
458         bool    writeVariable(Stream &, const String &,int);
459
460         bool    acceptGIV(ClientSocket *);
461
462         void    updateInfo(ChanInfo &);
463
464         int             readStream(Stream &,ChannelStream *);
465         
466         void    checkReadDelay(unsigned int);
467
468         void    processMp3Metadata(char *);
469
470         void    readHeader();
471
472         void    startStream();
473
474         XML::Node *createRelayXML(bool);
475
476         void    newPacket(ChanPacket &);
477
478         int             localListeners();
479         int             localRelays();
480
481         int             totalClaps();   //JP-MOD
482         int             totalListeners();
483         int             totalRelays();
484
485         ::String mount;
486         ChanMeta        insertMeta;
487         ChanPacket      headPack;
488
489         ChanPacketBuffer        rawData;
490
491         ChannelStream *sourceStream;
492         unsigned int streamIndex;
493         
494
495         ChanInfo        info;
496         ChanHit         sourceHost;
497
498         GnuID           remoteID;
499
500
501         ::String  sourceURL;
502
503         bool    bump,stayConnected;
504         bool    stealth; //JP-MOD
505         int             icyMetaInterval;
506         unsigned int streamPos;
507         unsigned int skipCount; //JP-EX
508         bool    readDelay;
509         int             overrideMaxRelaysPerChannel; //JP-MOD
510         bool    bClap; //JP-MOD
511
512         TYPE    type;
513         ChannelSource *sourceData;
514
515         SRC_TYPE        srcType;
516
517         MP3Header mp3Head;
518         ThreadInfo      thread;
519         ThreadInfo  *finthread;
520
521         unsigned int lastIdleTime;
522         int             status;
523         static  char *statusMsgs[],*srcTypes[];
524
525         ClientSocket    *sock;
526         ClientSocket    *pushSock;
527
528         unsigned int lastTrackerUpdate;
529         unsigned int lastMetaUpdate;
530
531         double  startTime,syncTime;
532
533         WEvent  syncEvent;
534
535         Channel *next;
536
537         int channel_id;
538         ChanHit chDisp;
539         ChanHit trackerHit;
540         bool bumped;
541         unsigned int lastSkipTime;
542         unsigned int lastStopTime;
543
544         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»)
545 };
546
547 // ----------------------------------
548 class ChanMgr
549 {
550 public:
551         enum {
552                 MAX_IDLE_CHANNELS = 8,          // max. number of channels that can be left idle
553                 MAX_METAINT = 8192                      // must be at least smaller than ChanPacket data len (ie. about half)
554                 
555         };
556
557
558         ChanMgr();
559
560         Channel *deleteChannel(Channel *);
561
562         Channel *createChannel(ChanInfo &,const char *);
563         Channel *findChannelByName(const char *);
564         Channel *findChannelByIndex(int);
565         Channel *findChannelByMount(const char *);
566         Channel *findChannelByID(GnuID &);
567         Channel *findChannelByNameID(ChanInfo &);
568         Channel *findPushChannel(int);
569         Channel *findChannelByChannelID(int id);
570
571         void    broadcastTrackerSettings();
572         void    setUpdateInterval(unsigned int v);
573         void    broadcastRelays(Servent *,int,int);
574
575         int             broadcastPacketUp(ChanPacket &,GnuID &,GnuID &,GnuID &);
576         void    broadcastTrackerUpdate(GnuID &,bool = false);
577
578         bool    writeVariable(Stream &, const String &,int);
579
580         int             findChannels(ChanInfo &,Channel **,int);
581         int             findChannelsByStatus(Channel **,int,Channel::STATUS);
582         
583         int             numIdleChannels();
584         int             numChannels();
585
586         void    closeOldestIdle();
587         void    closeAll();
588         void    quit();
589
590         void    addHit(Host &,GnuID &,bool);
591         ChanHit *addHit(ChanHit &);
592         void    delHit(ChanHit &);
593         void    deadHit(ChanHit &);
594         void    setFirewalled(Host &);
595
596         ChanHitList *findHitList(ChanInfo &);
597         ChanHitList *findHitListByID(GnuID &);
598         ChanHitList     *addHitList(ChanInfo &);
599
600         void            clearHitLists();
601         void            clearDeadHits(bool);
602         int                     numHitLists();
603
604         void            setBroadcastMsg(::String &);
605
606         Channel         *createRelay(ChanInfo &,bool);
607         Channel         *findAndRelay(ChanInfo &);
608         void            startSearch(ChanInfo &);
609
610         void            playChannel(ChanInfo &);
611         void            findAndPlayChannel(ChanInfo &,bool);
612
613         bool            isBroadcasting(GnuID &);
614         bool            isBroadcasting();
615
616         int                     pickHits(ChanHitSearch &);
617
618         bool findParentHit(ChanHit &p);
619
620         Channel         *channel;
621         ChanHitList     *hitlist;
622
623         GnuID   broadcastID;
624
625         ChanInfo        searchInfo;
626
627         int             numFinds;
628         ::String        broadcastMsg;
629         unsigned int            broadcastMsgInterval;
630         unsigned int lastHit,lastQuery;
631         unsigned int maxUptime;
632         bool    searchActive;
633         unsigned int            deadHitAge;
634         int             icyMetaInterval;
635         int             maxRelaysPerChannel;
636         WLock   lock;
637         int             minBroadcastTTL,maxBroadcastTTL;
638         int             pushTimeout,pushTries,maxPushHops;
639         unsigned int            autoQuery;
640         unsigned int    prefetchTime;
641         unsigned int    lastYPConnect;
642         unsigned int    lastYPConnect2;
643         unsigned int    icyIndex;
644
645         unsigned int    hostUpdateInterval;
646         unsigned int bufferTime;
647
648         GnuID   currFindAndPlayChannel;
649
650         WLock channellock;
651         WLock hitlistlock;
652 };
653 // ----------------------------------
654 class PlayList
655 {
656 public:
657
658         enum TYPE
659         {
660                 T_NONE,
661                 T_SCPLS,
662                 T_PLS,
663                 T_ASX,
664                 T_RAM,
665         };
666
667         PlayList(TYPE t, int max)
668         {
669                 maxURLs = max;
670                 numURLs = 0;
671                 type = t;
672                 urls = new ::String[max];
673                 titles = new ::String[max];
674                 contacturls = new ::String[max]; //JP-MOD
675         }
676
677         ~PlayList()
678         {
679                 delete [] urls;
680                 delete [] titles;
681                 delete [] contacturls; //JP-MOD
682         }
683
684         void    addURL(const char *url, const char *tit, const char *contacturl/*JP-MOD*/)
685         {
686                 if (numURLs < maxURLs)
687                 {
688                         urls[numURLs].set(url);
689                         titles[numURLs].set(tit);
690                         contacturls[numURLs].set(contacturl); //JP-MOD
691                         numURLs++;
692                 }
693         }
694         void    addChannels(const char *,Channel **,int);
695         void    addChannel(const char *,ChanInfo &);
696
697         void    writeSCPLS(Stream &);
698         void    writePLS(Stream &);
699         void    writeASX(Stream &);
700         void    writeRAM(Stream &);
701
702         void    readSCPLS(Stream &);
703         void    readPLS(Stream &);
704         void    readASX(Stream &);
705
706         void    read(Stream &s)
707         {
708                 try
709                 {
710                         switch (type)
711                         {
712                                 case T_SCPLS: readSCPLS(s); break;
713                                 case T_PLS: readPLS(s); break;
714                                 case T_ASX: readASX(s); break;
715                         }
716                 }catch(StreamException &) {}    // keep pls regardless of errors (eof isn`t handled properly in sockets)
717         }
718
719         void    write(Stream &s)
720         {
721                 switch (type)
722                 {
723                         case T_SCPLS: writeSCPLS(s); break;
724                         case T_PLS: writePLS(s); break;
725                         case T_ASX: writeASX(s); break;
726                         case T_RAM: writeRAM(s); break;
727                 }
728         }
729
730         TYPE    type;
731         int             numURLs,maxURLs;
732         ::String        *urls,*titles;
733         ::String        *contacturls; //JP-MOD
734 };
735
736 // ----------------------------------
737
738 extern ChanMgr *chanMgr;
739
740 // for PCRaw start.
741 bool isIndexTxt(ChanInfo *info);
742 bool isIndexTxt(Channel *ch);
743 int numMaxRelaysIndexTxt(Channel *ch);
744 int canStreamIndexTxt(Channel *ch);
745 // for PCRaw end
746
747 #endif