2
// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4
// This program is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 3 of the License, or
7
// (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
#include "gnashconfig.h"
22
//#ifdef HAVE_DEJAGNU_H
24
#include <sys/types.h>
31
extern int optind, getopt(int, char *const *, const char *);
34
#include <sys/types.h>
48
using namespace gnash;
51
static void usage (void);
57
// These are used to print more intelligent debug messages
58
const char *astype_str[] = {
79
main(int argc, char *argv[])
85
//gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
86
//dbglogfile.setVerbosity(1);
88
memset(buffer, 0, 300);
90
while ((c = getopt (argc, argv, "hdvsm:")) != -1) {
106
// get the file name from the command line
108
string filespec = argv[optind];
109
cout << "Will use \"" << filespec << "\" for test " << endl;
114
unsigned char buf[AMF_PACKET_SIZE+1];
115
unsigned char *tmpptr;
116
AMF::amf_element_t el;
118
// First see if we can read strings. This file is produced by
119
// using a network packet sniffer, and should be binary correct.
120
memset(buf, 0, AMF_PACKET_SIZE+1);
121
string filespec = SRCDIR;
122
filespec += "/connect-object.amf";
124
fd = open(filespec.c_str(), O_RDONLY);
125
ret = read(fd, buf, AMF_PACKET_SIZE);
128
amf_obj.parseHeader(buf);
129
if (amf_obj.getTotalSize() == 269) {
130
runtest.pass("Message Header Total Size");
132
runtest.fail("Message Header Total Size");
135
if (amf_obj.getHeaderSize() == 12) {
136
runtest.pass("Message Header Size");
138
runtest.fail("Message Header Size");
141
if (amf_obj.getMysteryWord() == 0) {
142
runtest.pass("Message Mystery Word");
144
runtest.fail("Message Mystery Word");
147
if (amf_obj.getRouting() == 0) {
148
runtest.pass("Message Routing");
150
runtest.fail("Message Routing");
153
// amf_obj.parseBody(buf + amf_obj.getHeaderSize(), amf_obj.getTotalSize());
155
// This extracts a "connect" message from the RTMP data stream. We
156
// look for everything ourselves to be the most accurate.
157
tmpptr = buf + amf_obj.getHeaderSize();
158
int8_t *str = amf_obj.extractString(tmpptr);
159
if (strcmp(reinterpret_cast<const char *>(str), "connect") == 0) {
160
runtest.pass("Extracted \"connect\" string");
162
runtest.fail("Extracted \"connect\" string");
165
tmpptr += strlen(reinterpret_cast<const char *>(str)) + AMF_HEADER_SIZE;
166
amfnum_t *num = amf_obj.extractNumber(tmpptr);
167
char *numptr = (char *)num;
168
if ((numptr[6] == -16)
169
&& (numptr[7] == 0x3f)) {
170
runtest.pass("Extracted \"connect\" number");
172
runtest.fail("Extracted \"connect\" number");
174
tmpptr += AMF_NUMBER_SIZE + 2;
176
tmpptr = amf_obj.extractVariable(&el, tmpptr);
177
if (el.name == "app") {
178
runtest.pass("Extracted \"app\" variable");
180
runtest.fail("Extracted \"app\" variable");
182
// cerr << el.name << endl;
184
tmpptr = amf_obj.extractVariable(&el, tmpptr);
185
if (el.name == "flashVer") {
186
runtest.pass("Extracted \"flashVer\" variable");
188
runtest.fail("Extracted \"flashVer\" variable");
190
// cerr << el.name << endl;
192
tmpptr = amf_obj.extractVariable(&el, tmpptr);
193
if (el.name == "swfUrl") {
194
runtest.pass("Extracted \"swfUrl\" variable");
196
runtest.fail("Extracted \"swfUrl\" variable");
198
// cerr << el.name << endl;
200
tmpptr = amf_obj.extractVariable(&el, tmpptr);
201
if (el.name == "tcUrl") {
202
runtest.pass("Extracted \"tcUrl\" variable");
204
runtest.fail("Extracted \"tcUrl\" variable");
206
// cerr << el.name << endl;
208
tmpptr = amf_obj.extractVariable(&el, tmpptr);
209
if (el.name == "fpad") {
210
runtest.pass("Extracted \"fpad\" variable");
212
runtest.fail("Extracted \"fpad\" variable");
214
// cerr << el.name << endl;
216
tmpptr = amf_obj.extractVariable(&el, tmpptr);
217
if (el.name == "audioCodecs") {
218
runtest.pass("Extracted \"audioCodecs\" variable");
220
runtest.fail("Extracted \"audioCodecs\" variable");
222
// cerr << el.name << endl;
224
tmpptr = amf_obj.extractVariable(&el, tmpptr);
225
if (el.name == "videoCodecs") {
226
runtest.pass("Extracted \"videoCodecs\" variable");
228
runtest.fail("Extracted \"videoCodecs\" variable");
230
// cerr << el.name << endl;
232
tmpptr = amf_obj.extractVariable(&el, tmpptr);
233
if (el.name == "videoFunction") {
234
runtest.pass("Extracted \"videoFunction\" variable");
236
runtest.fail("Extracted \"videoFunction\" variable");
238
// cerr << el.name << endl;
240
tmpptr = amf_obj.extractVariable(&el, tmpptr);
241
if (el.name == "pageUrl") {
242
runtest.pass("Extracted \"pageURL\" variable");
244
runtest.fail("Extracted \"pageURL\" variable");
246
// cerr << el.name << endl;
248
amf_obj.extractVariable(&el, tmpptr);
249
if (el.name == "objectEncoding") {
250
runtest.pass("Extracted \"objectEncoding\" variable");
252
runtest.fail("Extracted \"objectEncoding\" variable");
254
// cerr << el.name << endl;
256
// Now build our own connect message with the same data, which
257
// should give us an exact copy.
258
int amf_index = amf_obj.getAMFIndex();
259
AMF::amf_headersize_e head_size = AMF::HEADER_12;
260
int total_size = amf_obj.getTotalSize();
261
AMF::content_types_e type = AMF::INVOKE;
262
amfsource_e routing = amf_obj.getRouting();
265
// First build and test the header. This uses the same data as the
267
unsigned char *out = reinterpret_cast<unsigned char *>(rtmp.encodeRTMPHeader(amf_index, head_size, total_size, type, routing));
269
rtmp.parseHeader(out);
270
if (rtmp.getTotalSize() == 269) {
271
runtest.pass("New Message Header Total Size");
273
runtest.fail("New Message Header Total Size");
276
if (rtmp.getHeaderSize() == 12) {
277
runtest.pass("New Message Header Size");
279
runtest.fail("New Message Header Size");
282
if (rtmp.getMysteryWord() == 0) {
283
runtest.pass("New Message Mystery Word");
285
runtest.fail("Message Mystery Word");
288
if (rtmp.getRouting() == CLIENT) {
289
runtest.pass("New Message Routing");
291
runtest.fail("New Message Routing");
294
check_equals(rtmp.getHeaderSize(), 12);
296
if (memcmp(out, buf, 12) == 0) {
297
runtest.pass("RTMP Headers match");
300
runtest.fail("RTMP Headers mismatch");
301
cerr << "buf is: 0x" << hexify(buf, s, true) << endl;
302
cerr << "out is: 0x" << hexify(out, s, true) << endl;
305
tmpptr += rtmp.getHeaderSize();
307
// Now build up a body of a connect message
310
var = (unsigned char *)rtmp.encodeString("connect");
311
int8_t *c_out = rtmp.extractString(var);
314
runtest.fail("Encoded \"connect\" string could not be extracted");
318
std::string s_in("connect");
319
std::string s_out(reinterpret_cast<const char *>(c_out));
322
runtest.pass("Encoded \"connect\" string");
324
runtest.fail("Encoded \"connect\" string");
325
cerr << "Encoded 'connect' returned as as" << s_out << endl;
328
tmpptr = rtmp.appendPtr(tmpptr, var, strlen("connect") + 3);
331
amfnum_t bignum = 0x3ff0000000000000LL;
332
numptr = (char *)&bignum;
333
var = (unsigned char *)rtmp.encodeNumber(bignum);
334
if (*rtmp.extractNumber(var) == bignum) {
335
runtest.pass("Encoded \"connect\" number");
337
runtest.fail("Encoded \"connect\" number");
340
tmpptr = rtmp.appendPtr(tmpptr, var, AMF_NUMBER_SIZE + 1);
344
*tmpptr++ = AMF::OBJECT;
346
var = (unsigned char *)rtmp.encodeVariable("app", "oflaDemo");
347
rtmp.extractVariable(&el, var);
348
if ((el.name == "app") && (strncmp((char *)el.data, "oflaDemo", 8) == 0)) {
349
runtest.pass("Encoded \"app\" variable");
351
runtest.fail("Encoded \"app\" variable");
353
tmpptr = rtmp.appendPtr(tmpptr, var, el.length + strlen("app") + 5);
356
var = (unsigned char *)rtmp.encodeVariable("flashVer", "LNX 9,0,31,0");
357
rtmp.extractVariable(&el, var);
358
if ((el.name == "flashVer") && (strncmp((char *)el.data, "LNX 9,0,31,0", el.length) == 0)) {
359
runtest.pass("Encoded \"flashVer\" variable");
361
runtest.fail("Encoded \"flashVer\" variable");
363
tmpptr = rtmp.appendPtr(tmpptr, var, el.length + strlen("flashVer") + 5);
366
var = (unsigned char *)rtmp.encodeVariable("swfUrl", "http://www.red5.nl/tools/publisher/publisher.swf");
367
rtmp.extractVariable(&el, var);
368
if ((el.name == "swfUrl") && (strncmp((char *)el.data, "http://www.red5.nl/tools/publisher/publisher.swf", el.length) == 0)) {
369
runtest.pass("Encoded \"swfUrl\" variable");
371
runtest.fail("Encoded \"swfUrl\" variable");
373
tmpptr = rtmp.appendPtr(tmpptr, var, el.length + strlen("swfUrl") + 5);
376
var = (unsigned char *)rtmp.encodeVariable("tcUrl", "rtmp://localhost/oflaDemo");
377
rtmp.extractVariable(&el, var);
378
if ((el.name == "tcUrl") && (strncmp((char *)el.data, "rtmp://localhost/oflaDemo", 25) == 0)) {
379
runtest.pass("Encoded \"tcUrl\" variable");
381
runtest.fail("Encoded \"tcUrl\" variable");
383
tmpptr = rtmp.appendPtr(tmpptr, var, el.length + strlen("tcUrl") + 5);
386
var = (unsigned char *)rtmp.encodeVariable("fpad", false);
387
rtmp.extractVariable(&el, var);
388
if ((el.name == "fpad") && (*el.data == 0)) {
389
runtest.pass("Encoded \"fpad\" Boolean variable");
391
runtest.fail("Encoded \"fpad\" Boolean variable");
393
tmpptr = rtmp.appendPtr(tmpptr, var, 1 + strlen("fpad") + 3);
397
numptr = (char *)&bignum;
398
var = (unsigned char *)rtmp.encodeVariable("audioCodecs", bignum);
399
rtmp.extractVariable(&el, var);
401
if ((el.type == amf::AMF::NUMBER)
402
&& (el.name == "audioCodecs")
403
&& (el.data[5] == 0x38)
404
&& (el.data[6] == 0x83)
405
&& (el.data[7] == 0x40)) {
406
runtest.pass("Encoded \"audioCodecs\" variable");
408
runtest.fail("Encoded \"audioCodecs\" variable");
410
tmpptr = rtmp.appendPtr(tmpptr, var, el.name.size() + AMF_NUMBER_SIZE + 3);
414
numptr = (char *)&bignum;
415
var = (unsigned char *)rtmp.encodeVariable("videoCodecs", bignum);
416
rtmp.extractVariable(&el, var);
418
if ((el.type == amf::AMF::NUMBER)
419
&& (el.name == "videoCodecs")
420
&& (el.data[6] == 0x5f)
421
&& (el.data[7] == 0x40)) {
422
runtest.pass("Encoded \"videoCodecs\" variable");
424
runtest.fail("Encoded \"videoCodecs\" variable");
426
tmpptr = rtmp.appendPtr(tmpptr, var, el.name.size() + AMF_NUMBER_SIZE + 3);
430
numptr = (char *)&bignum;
431
var = (unsigned char *)rtmp.encodeVariable("videoFunction", bignum);
432
rtmp.extractVariable(&el, var);
434
if ((el.type == amf::AMF::NUMBER)
435
&& (el.name == "videoFunction")
436
&& (el.data[6] == 0xf0)
437
&& (el.data[7] == 0x3f)) {
438
runtest.pass("Encoded \"videoFunction\" variable");
440
runtest.fail("Encoded \"videoFunction\" variable");
442
tmpptr = rtmp.appendPtr(tmpptr, var, el.name.size() + AMF_NUMBER_SIZE + 3);
445
var = (unsigned char *)rtmp.encodeVariable("pageUrl");
446
rtmp.extractVariable(&el, var);
447
if ((el.type == amf::AMF::UNDEFINED)
448
&& (el.name == "pageUrl")) {
449
runtest.pass("Encoded \"pageUrl\" undefined variable");
451
runtest.fail("Encoded \"pageUrl\" undefined variable");
453
tmpptr = rtmp.appendPtr(tmpptr, var, el.name.size() + 3);
457
numptr = (char *)&bignum;
458
var = (unsigned char *)rtmp.encodeVariable("objectEncoding", bignum);
459
rtmp.extractVariable(&el, var);
461
if ((el.type == amf::AMF::NUMBER)
462
&& (el.name == "objectEncoding")
463
&& (el.data[6] == 0x0)
464
&& (el.data[7] == 0x0)) {
465
runtest.pass("Encoded \"objectEncoding\" variable");
467
runtest.fail("Encoded \"objectEncoding\" variable");
469
tmpptr = rtmp.appendPtr(tmpptr, var, el.name.size() + AMF_NUMBER_SIZE + 3);
473
*tmpptr++ = AMF::OBJECT_END;
475
if (memcmp(buf, out, amf_obj.getTotalSize()) == 0) {
476
runtest.pass("Object Packets match");
478
runtest.fail("Object Packets mismatch");
481
size_t hexsize = std::max(AMF_PACKET_SIZE, amf_obj.getTotalSize())*2;
482
cerr << "buf is: 0x" << hexify(buf, amf_obj.getTotalSize() + 10, true) << ", size is: " << amf_obj.getTotalSize() << endl;
483
cerr << "out is: 0x" << hexify(out, rmtp.getTotalSize() + 10, true) << ", size is: " << rtmp.getTotalSize() << endl;
491
cerr << "This program tests Shared Object support in the AMF library." << endl;
492
cerr << "Usage: test_object [hv]" << endl;
493
cerr << "-h\tHelp" << endl;
494
cerr << "-v\tVerbose" << endl;
501
main(int /*argc*/, char /* *argv[]*/)