1 #ifndef __RTMP_H__
2 #define __RTMP_H__
3 /*
4  *      Copyright (C) 2005-2008 Team XBMC
5  *      http://www.xbmc.org
6  *      Copyright (C) 2008-2009 Andrej Stepanchuk
7  *      Copyright (C) 2009-2010 Howard Chu
8  *
9  *  This file is part of librtmp.
10  *
11  *  librtmp is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU Lesser General Public License as
13  *  published by the Free Software Foundation; either version 2.1,
14  *  or (at your option) any later version.
15  *
16  *  librtmp is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU Lesser General Public License
22  *  along with librtmp see the file COPYING.  If not, write to
23  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24  *  Boston, MA  02110-1301, USA.
25  *  http://www.gnu.org/copyleft/lgpl.html
26  */
27 
28 #if !defined(NO_CRYPTO) && !defined(CRYPTO)
29 #define CRYPTO
30 #endif
31 
32 #include <errno.h>
33 #include <stdint.h>
34 #include <stddef.h>
35 
36 #include "amf.h"
37 
38 #ifdef __cplusplus
39 extern "C"
40 {
41 #endif
42 
43 #define RTMP_LIB_VERSION	0x020300	/* 2.3 */
44 
45 #define RTMP_FEATURE_HTTP	0x01
46 #define RTMP_FEATURE_ENC	0x02
47 #define RTMP_FEATURE_SSL	0x04
48 #define RTMP_FEATURE_MFP	0x08	/* not yet supported */
49 #define RTMP_FEATURE_WRITE	0x10	/* publish, not play */
50 #define RTMP_FEATURE_HTTP2	0x20	/* server-side rtmpt */
51 
52 #define RTMP_PROTOCOL_UNDEFINED	-1
53 #define RTMP_PROTOCOL_RTMP      0
54 #define RTMP_PROTOCOL_RTMPE     RTMP_FEATURE_ENC
55 #define RTMP_PROTOCOL_RTMPT     RTMP_FEATURE_HTTP
56 #define RTMP_PROTOCOL_RTMPS     RTMP_FEATURE_SSL
57 #define RTMP_PROTOCOL_RTMPTE    (RTMP_FEATURE_HTTP|RTMP_FEATURE_ENC)
58 #define RTMP_PROTOCOL_RTMPTS    (RTMP_FEATURE_HTTP|RTMP_FEATURE_SSL)
59 #define RTMP_PROTOCOL_RTMFP     RTMP_FEATURE_MFP
60 
61 #define RTMP_DEFAULT_CHUNKSIZE	128
62 
63 /* needs to fit largest number of bytes recv() may return */
64 #define RTMP_BUFFER_CACHE_SIZE (16*1024)
65 
66 #define	RTMP_CHANNELS	65600
67 
68   extern const char RTMPProtocolStringsLower[][7];
69   extern const AVal RTMP_DefaultFlashVer;
70   extern int RTMP_ctrlC;
71 
72   uint32_t RTMP_GetTime(void);
73 
74 /*      RTMP_PACKET_TYPE_...                0x00 */
75 #define RTMP_PACKET_TYPE_CHUNK_SIZE         0x01
76 /*      RTMP_PACKET_TYPE_...                0x02 */
77 #define RTMP_PACKET_TYPE_BYTES_READ_REPORT  0x03
78 #define RTMP_PACKET_TYPE_CONTROL            0x04
79 #define RTMP_PACKET_TYPE_SERVER_BW          0x05
80 #define RTMP_PACKET_TYPE_CLIENT_BW          0x06
81 /*      RTMP_PACKET_TYPE_...                0x07 */
82 #define RTMP_PACKET_TYPE_AUDIO              0x08
83 #define RTMP_PACKET_TYPE_VIDEO              0x09
84 /*      RTMP_PACKET_TYPE_...                0x0A */
85 /*      RTMP_PACKET_TYPE_...                0x0B */
86 /*      RTMP_PACKET_TYPE_...                0x0C */
87 /*      RTMP_PACKET_TYPE_...                0x0D */
88 /*      RTMP_PACKET_TYPE_...                0x0E */
89 #define RTMP_PACKET_TYPE_FLEX_STREAM_SEND   0x0F
90 #define RTMP_PACKET_TYPE_FLEX_SHARED_OBJECT 0x10
91 #define RTMP_PACKET_TYPE_FLEX_MESSAGE       0x11
92 #define RTMP_PACKET_TYPE_INFO               0x12
93 #define RTMP_PACKET_TYPE_SHARED_OBJECT      0x13
94 #define RTMP_PACKET_TYPE_INVOKE             0x14
95 /*      RTMP_PACKET_TYPE_...                0x15 */
96 #define RTMP_PACKET_TYPE_FLASH_VIDEO        0x16
97 
98 #define RTMP_MAX_HEADER_SIZE 18
99 
100 #define RTMP_PACKET_SIZE_LARGE    0
101 #define RTMP_PACKET_SIZE_MEDIUM   1
102 #define RTMP_PACKET_SIZE_SMALL    2
103 #define RTMP_PACKET_SIZE_MINIMUM  3
104 
105   typedef struct RTMPChunk
106   {
107     int c_headerSize;
108     int c_chunkSize;
109     char *c_chunk;
110     char c_header[RTMP_MAX_HEADER_SIZE];
111   } RTMPChunk;
112 
113   typedef struct RTMPPacket
114   {
115     uint8_t m_headerType;
116     uint8_t m_packetType;
117     uint8_t m_hasAbsTimestamp;	/* timestamp absolute or relative? */
118     int m_nChannel;
119     uint32_t m_nTimeStamp;	/* timestamp */
120     int32_t m_nInfoField2;	/* last 4 bytes in a long header */
121     uint32_t m_nBodySize;
122     uint32_t m_nBytesRead;
123     RTMPChunk *m_chunk;
124     char *m_body;
125   } RTMPPacket;
126 
127   typedef struct RTMPSockBuf
128   {
129     int sb_socket;
130     int sb_size;		/* number of unprocessed bytes in buffer */
131     char *sb_start;		/* pointer into sb_pBuffer of next byte to process */
132     char sb_buf[RTMP_BUFFER_CACHE_SIZE];	/* data read from socket */
133     int sb_timedout;
134     void *sb_ssl;
135   } RTMPSockBuf;
136 
137   void RTMPPacket_Reset(RTMPPacket *p);
138   void RTMPPacket_Dump(RTMPPacket *p);
139   int RTMPPacket_Alloc(RTMPPacket *p, uint32_t nSize);
140   void RTMPPacket_Free(RTMPPacket *p);
141 
142 #define RTMPPacket_IsReady(a)	((a)->m_nBytesRead == (a)->m_nBodySize)
143 
144   typedef struct RTMP_LNK
145   {
146     AVal hostname;
147     AVal sockshost;
148 
149     AVal playpath0;	/* parsed from URL */
150     AVal playpath;	/* passed in explicitly */
151     AVal tcUrl;
152     AVal swfUrl;
153     AVal pageUrl;
154     AVal app;
155     AVal auth;
156     AVal flashVer;
157     AVal subscribepath;
158     AVal usherToken;
159     AVal token;
160     AVal pubUser;
161     AVal pubPasswd;
162     AMFObject extras;
163     int edepth;
164 
165     int seekTime;
166     int stopTime;
167 
168 #define RTMP_LF_AUTH	0x0001	/* using auth param */
169 #define RTMP_LF_LIVE	0x0002	/* stream is live */
170 #define RTMP_LF_SWFV	0x0004	/* do SWF verification */
171 #define RTMP_LF_PLST	0x0008	/* send playlist before play */
172 #define RTMP_LF_BUFX	0x0010	/* toggle stream on BufferEmpty msg */
173 #define RTMP_LF_FTCU	0x0020	/* free tcUrl on close */
174 #define RTMP_LF_FAPU	0x0040	/* free app on close */
175     int lFlags;
176 
177     int swfAge;
178 
179     int protocol;
180     int timeout;		/* connection timeout in seconds */
181 
182     int pFlags;			/* unused, but kept to avoid breaking ABI */
183 
184     unsigned short socksport;
185     unsigned short port;
186 
187 #ifdef CRYPTO
188 #define RTMP_SWF_HASHLEN	32
189     void *dh;			/* for encryption */
190     void *rc4keyIn;
191     void *rc4keyOut;
192 
193     uint32_t SWFSize;
194     uint8_t SWFHash[RTMP_SWF_HASHLEN];
195     char SWFVerificationResponse[RTMP_SWF_HASHLEN+10];
196 #endif
197   } RTMP_LNK;
198 
199   /* state for read() wrapper */
200   typedef struct RTMP_READ
201   {
202     char *buf;
203     char *bufpos;
204     unsigned int buflen;
205     uint32_t timestamp;
206     uint8_t dataType;
207     uint8_t flags;
208 #define RTMP_READ_HEADER	0x01
209 #define RTMP_READ_RESUME	0x02
210 #define RTMP_READ_NO_IGNORE	0x04
211 #define RTMP_READ_GOTKF		0x08
212 #define RTMP_READ_GOTFLVK	0x10
213 #define RTMP_READ_SEEKING	0x20
214     int8_t status;
215 #define RTMP_READ_COMPLETE	-3
216 #define RTMP_READ_ERROR	-2
217 #define RTMP_READ_EOF	-1
218 #define RTMP_READ_IGNORE	0
219 
220     /* if bResume == TRUE */
221     uint8_t initialFrameType;
222     uint32_t nResumeTS;
223     char *metaHeader;
224     char *initialFrame;
225     uint32_t nMetaHeaderSize;
226     uint32_t nInitialFrameSize;
227     uint32_t nIgnoredFrameCounter;
228     uint32_t nIgnoredFlvFrameCounter;
229   } RTMP_READ;
230 
231   typedef struct RTMP_METHOD
232   {
233     AVal name;
234     int num;
235   } RTMP_METHOD;
236 
237   typedef struct RTMP
238   {
239     int m_inChunkSize;
240     int m_outChunkSize;
241     int m_nBWCheckCounter;
242     int m_nBytesIn;
243     int m_nBytesInSent;
244     int m_nBufferMS;
245     int m_stream_id;		/* returned in _result from createStream */
246     int m_mediaChannel;
247     uint32_t m_mediaStamp;
248     uint32_t m_pauseStamp;
249     int m_pausing;
250     int m_nServerBW;
251     int m_nClientBW;
252     uint8_t m_nClientBW2;
253     uint8_t m_bPlaying;
254     uint8_t m_bSendEncoding;
255     uint8_t m_bSendCounter;
256 
257     int m_numInvokes;
258     int m_numCalls;
259     RTMP_METHOD *m_methodCalls;	/* remote method calls queue */
260 
261     int m_channelsAllocatedIn;
262     int m_channelsAllocatedOut;
263     RTMPPacket **m_vecChannelsIn;
264     RTMPPacket **m_vecChannelsOut;
265     int *m_channelTimestamp;	/* abs timestamp of last packet */
266 
267     double m_fAudioCodecs;	/* audioCodecs for the connect packet */
268     double m_fVideoCodecs;	/* videoCodecs for the connect packet */
269     double m_fEncoding;		/* AMF0 or AMF3 */
270 
271     double m_fDuration;		/* duration of stream in seconds */
272 
273     int m_msgCounter;		/* RTMPT stuff */
274     int m_polling;
275     int m_resplen;
276     int m_unackd;
277     AVal m_clientID;
278 
279     RTMP_READ m_read;
280     RTMPPacket m_write;
281     RTMPSockBuf m_sb;
282     RTMP_LNK Link;
283   } RTMP;
284 
285   int RTMP_ParseURL(const char *url, int *protocol, AVal *host,
286 		     unsigned int *port, AVal *playpath, AVal *app);
287 
288   void RTMP_ParsePlaypath(AVal *in, AVal *out);
289   void RTMP_SetBufferMS(RTMP *r, int size);
290   void RTMP_UpdateBufferMS(RTMP *r);
291 
292   int RTMP_SetOpt(RTMP *r, const AVal *opt, AVal *arg);
293   int RTMP_SetupURL(RTMP *r, char *url);
294   void RTMP_SetupStream(RTMP *r, int protocol,
295 			AVal *hostname,
296 			unsigned int port,
297 			AVal *sockshost,
298 			AVal *playpath,
299 			AVal *tcUrl,
300 			AVal *swfUrl,
301 			AVal *pageUrl,
302 			AVal *app,
303 			AVal *auth,
304 			AVal *swfSHA256Hash,
305 			uint32_t swfSize,
306 			AVal *flashVer,
307 			AVal *subscribepath,
308 			AVal *usherToken,
309 			int dStart,
310 			int dStop, int bLiveStream, long int timeout);
311 
312   int RTMP_Connect(RTMP *r, RTMPPacket *cp);
313   struct sockaddr;
314   int RTMP_Connect0(RTMP *r, struct sockaddr *svc);
315   int RTMP_Connect1(RTMP *r, RTMPPacket *cp);
316   int RTMP_Serve(RTMP *r);
317   int RTMP_TLS_Accept(RTMP *r, void *ctx);
318 
319   int RTMP_ReadPacket(RTMP *r, RTMPPacket *packet);
320   int RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue);
321   int RTMP_SendChunk(RTMP *r, RTMPChunk *chunk);
322   int RTMP_IsConnected(RTMP *r);
323   int RTMP_Socket(RTMP *r);
324   int RTMP_IsTimedout(RTMP *r);
325   double RTMP_GetDuration(RTMP *r);
326   int RTMP_ToggleStream(RTMP *r);
327 
328   int RTMP_ConnectStream(RTMP *r, int seekTime);
329   int RTMP_ReconnectStream(RTMP *r, int seekTime);
330   void RTMP_DeleteStream(RTMP *r);
331   int RTMP_GetNextMediaPacket(RTMP *r, RTMPPacket *packet);
332   int RTMP_ClientPacket(RTMP *r, RTMPPacket *packet);
333 
334   void RTMP_Init(RTMP *r);
335   void RTMP_Close(RTMP *r);
336   RTMP *RTMP_Alloc(void);
337   void RTMP_Free(RTMP *r);
338   void RTMP_EnableWrite(RTMP *r);
339 
340   void *RTMP_TLS_AllocServerContext(const char* cert, const char* key);
341   void RTMP_TLS_FreeServerContext(void *ctx);
342 
343   int RTMP_LibVersion(void);
344   void RTMP_UserInterrupt(void);	/* user typed Ctrl-C */
345 
346   int RTMP_SendCtrl(RTMP *r, short nType, unsigned int nObject,
347 		     unsigned int nTime);
348 
349   /* caller probably doesn't know current timestamp, should
350    * just use RTMP_Pause instead
351    */
352   int RTMP_SendPause(RTMP *r, int DoPause, int dTime);
353   int RTMP_Pause(RTMP *r, int DoPause);
354 
355   int RTMP_FindFirstMatchingProperty(AMFObject *obj, const AVal *name,
356 				      AMFObjectProperty * p);
357 
358   int RTMPSockBuf_Fill(RTMPSockBuf *sb);
359   int RTMPSockBuf_Send(RTMPSockBuf *sb, const char *buf, int len);
360   int RTMPSockBuf_Close(RTMPSockBuf *sb);
361 
362   int RTMP_SendCreateStream(RTMP *r);
363   int RTMP_SendSeek(RTMP *r, int dTime);
364   int RTMP_SendServerBW(RTMP *r);
365   int RTMP_SendClientBW(RTMP *r);
366   void RTMP_DropRequest(RTMP *r, int i, int freeit);
367   int RTMP_Read(RTMP *r, char *buf, int size);
368   int RTMP_Write(RTMP *r, const char *buf, int size);
369 
370 /* hashswf.c */
371   int RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
372 		   int age);
373 
374 #ifdef __cplusplus
375 };
376 #endif
377 
378 #endif
379