scripts/compare-raw, server/Makefile.am: Add script for comparing raw audio.
[disorder] / scripts / protocol
index 90ccf1b..f2f9a3d 100755 (executable)
@@ -1,7 +1,7 @@
 #! /usr/bin/perl -w
 #
 # This file is part of DisOrder.
 #! /usr/bin/perl -w
 #
 # This file is part of DisOrder.
-# Copyright (C) 2010-11 Richard Kettlewell
+# Copyright (C) 2010-11, 13 Richard Kettlewell
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -59,7 +59,7 @@ our @eclient_return = (
     ["time_response" => ["time"]],
     ["pair_integer_response" => ["integer", "integer"]],
     ["queue_response" => ["queue"]],
     ["time_response" => ["time"]],
     ["pair_integer_response" => ["integer", "integer"]],
     ["queue_response" => ["queue"]],
-    ["queue_response" => ["queue-one"]],
+    ["playing_response" => ["queue-one"]],
     ["list_response" => ["body"]],
     );
 
     ["list_response" => ["body"]],
     );
 
@@ -194,6 +194,7 @@ sub c_param_docs {
 sub c_return_docs {
     my $returns = shift;
     return () unless defined $returns;
 sub c_return_docs {
     my $returns = shift;
     return () unless defined $returns;
+    my @docs = ();
     for my $return (@$returns) {
         my $type = $return->[0];
         my $name = $return->[1];
     for my $return (@$returns) {
         my $type = $return->[0];
         my $name = $return->[1];
@@ -203,20 +204,25 @@ sub c_return_docs {
            or $type eq 'integer'
            or $type eq 'time'
            or $type eq 'boolean') {
            or $type eq 'integer'
            or $type eq 'time'
            or $type eq 'boolean') {
-            return (" * \@param ${name}p $descr\n");
+            push(@docs,
+                " * \@param ${name}p $descr\n");
         } elsif($type eq 'list' or $type eq 'body') {
         } elsif($type eq 'list' or $type eq 'body') {
-            return (" * \@param ${name}p $descr\n",
-                    " * \@param n${name}p Number of elements in ${name}p\n");
+            push(@docs,
+                " * \@param ${name}p $descr\n",
+                " * \@param n${name}p Number of elements in ${name}p\n");
         } elsif($type eq 'pair-list') {
         } elsif($type eq 'pair-list') {
-            return (" * \@param ${name}p $descr\n");
+            push(@docs,
+                " * \@param ${name}p $descr\n");
         } elsif($type eq 'queue' or $type eq 'queue-one') {
         } elsif($type eq 'queue' or $type eq 'queue-one') {
-            return (" * \@param ${name}p $descr\n");
+            push(@docs,
+                " * \@param ${name}p $descr\n");
         } elsif($type eq 'user') {
         } elsif($type eq 'user') {
-            return ();
+           # nothing
         } else {
             die "$0: c_return_docs: unknown type '$type'\n";
         }
     }
         } else {
             die "$0: c_return_docs: unknown type '$type'\n";
         }
     }
+    return @docs;
 }
 
 # simple(CMD, SUMMARY, DETAIL,
 }
 
 # simple(CMD, SUMMARY, DETAIL,
@@ -242,24 +248,16 @@ sub simple {
         $cmdc =~ s/-/_/g;
     }
     print STDERR "Processing $cmd... ";
         $cmdc =~ s/-/_/g;
     }
     print STDERR "Processing $cmd... ";
-    # C argument types and conversions
+    # C argument types
     my @cargs = ();
     my @cargs = ();
-    my @conversions = ();
     for my $arg (@$args) {
         if($arg->[0] eq 'body' or $arg->[0] eq 'list') {
     for my $arg (@$args) {
         if($arg->[0] eq 'body' or $arg->[0] eq 'list') {
-            push(@cargs, "disorder_$arg->[0]", $arg->[1], "n$arg->[1]");
+            push(@cargs, "disorder__$arg->[0]", $arg->[1], "n$arg->[1]");
         } elsif($arg->[0] eq 'string') {
             push(@cargs, $arg->[1]);
         } elsif($arg->[0] eq 'string') {
             push(@cargs, $arg->[1]);
-        } elsif($arg->[0] eq 'integer') {
-            push(@cargs, "buf_$arg->[1]");
-            push(@conversions,
-                "  char buf_$arg->[1]\[16];\n",
-                 "  byte_snprintf(buf_$arg->[1], sizeof buf_$arg->[1], \"%ld\", $arg->[1]);\n");
-        } elsif($arg->[0] eq 'time') {
-            push(@cargs, "buf_$arg->[1]");
-            push(@conversions,
-                "  char buf_$arg->[1]\[16];\n",
-                 "  byte_snprintf(buf_$arg->[1], sizeof buf_$arg->[1], \"%lld\", (long long)$arg->[1]);\n");
+        } elsif($arg->[0] eq 'integer'
+               or $arg->[0] eq 'time') {
+            push(@cargs, "disorder__$arg->[0]", "$arg->[1]");
         } elsif($arg->[0] eq 'literal') {
             push(@cargs, "\"$arg->[1]\"");
         } else {
         } elsif($arg->[0] eq 'literal') {
             push(@cargs, "\"$arg->[1]\"");
         } else {
@@ -287,8 +285,7 @@ sub simple {
         join(", ", "disorder_client *c",
                    map(c_in_decl($_), @$args),
                     map(c_out_decl($_), @$returns)),
         join(", ", "disorder_client *c",
                    map(c_in_decl($_), @$args),
                     map(c_out_decl($_), @$returns)),
-        ") {\n",
-       @conversions);
+        ") {\n");
     if(!defined $returns or scalar @$returns == 0) {
         # Simple case
        push(@c, "  return disorder_simple(",
     if(!defined $returns or scalar @$returns == 0) {
         # Simple case
        push(@c, "  return disorder_simple(",
@@ -408,17 +405,37 @@ sub simple {
             " * $detail\n",
             " *\n",
             " * \@param c Client\n",
             " * $detail\n",
             " *\n",
             " * \@param c Client\n",
-            c_param_docs($args),
             " * \@param completed Called upon completion\n",
             " * \@param completed Called upon completion\n",
+            c_param_docs($args),
+            " * \@param v Passed to \@p completed\n",
             " * \@return 0 if the command was queued successfuly, non-0 on error\n",
             " */\n",
             "int disorder_eclient_$cmdc(",
             join(", ", "disorder_eclient *c",
             " * \@return 0 if the command was queued successfuly, non-0 on error\n",
             " */\n",
             "int disorder_eclient_$cmdc(",
             join(", ", "disorder_eclient *c",
+                 "disorder_eclient_$variant *completed",
                  map(c_in_decl($_), @$args),
                  map(c_in_decl($_), @$args),
-                 "disorder_eclient_$variant *completed"),
+                 "void *v"),
             ");\n\n");
 
             ");\n\n");
 
-# TODO implementation
+       print STDERR "AC ";
+       push(@ac,
+            "int disorder_eclient_$cmdc(",
+            join(", ", "disorder_eclient *c",
+                 "disorder_eclient_$variant *completed",
+                 map(c_in_decl($_), @$args),
+                 "void *v"),
+            ") {\n");
+       push(@ac, "  return simple(",
+            join(", ", 
+                 "c",
+                 "${variant}_opcallback",
+                 "(void (*)())completed",
+                 "v",
+                 "\"$cmd\"",
+                 @cargs,
+                 "(char *)0"),
+            ");\n");
+       push(@ac, "}\n\n");
     } else {
        push(@missing, "disorder_eclient_$cmdc");
     }
     } else {
        push(@missing, "disorder_eclient_$cmdc");
     }
@@ -463,17 +480,33 @@ our @gpl = ("/*\n",
 push(@h, @generated, @gpl,
      "#ifndef CLIENT_STUBS_H\n",
      "#define CLIENT_STUBS_H\n",
 push(@h, @generated, @gpl,
      "#ifndef CLIENT_STUBS_H\n",
      "#define CLIENT_STUBS_H\n",
+     "/** \@file lib/client-stubs.h\n",
+     " * \@brief Generated client API\n",
+     " *\n",
+     " * Don't include this file directly - use \@ref lib/client.h instead.\n",
+     " */\n",
      "\n");
 
 push(@c, @generated, @gpl,
      "\n");
 
 push(@c, @generated, @gpl,
+     "/** \@file lib/client-stubs.c\n",
+     " * \@brief Generated client API implementation\n",
+     " */\n",
      "\n");
 
 push(@ah, @generated, @gpl,
      "#ifndef ECLIENT_STUBS_H\n",
      "#define ECLIENT_STUBS_H\n",
      "\n");
 
 push(@ah, @generated, @gpl,
      "#ifndef ECLIENT_STUBS_H\n",
      "#define ECLIENT_STUBS_H\n",
+     "/** \@file lib/client-stubs.h\n",
+     " * \@brief Generated asynchronous client API\n",
+     " *\n",
+     " * Don't include this file directly - use \@ref lib/eclient.h instead.\n",
+     " */\n",
      "\n");
 
 push(@ac, @generated, @gpl,
      "\n");
 
 push(@ac, @generated, @gpl,
+     "/** \@file lib/client-stubs.c\n",
+     " * \@brief Generated asynchronous client API implementation\n",
+     " */\n",
      "\n");
 
 # The protocol ----------------------------------------------------------------
      "\n");
 
 # The protocol ----------------------------------------------------------------
@@ -768,6 +801,17 @@ simple("rtp-address",
        [["string", "address", "Where to store hostname or address"],
         ["string", "port", "Where to store service name or port number"]]);
 
        [["string", "address", "Where to store hostname or address"],
         ["string", "port", "Where to store service name or port number"]]);
 
+simple("rtp-cancel",
+       "Cancel RTP stream",
+       "",
+       []);
+
+simple("rtp-request",
+       "Request a unicast RTP stream",
+       "",
+       [["string", "address", "Destination address"],
+        ["string", "port", "Destination port number"]]);
+
 simple("scratch",
        "Terminate the playing track.",
        "Requires one of the 'scratch mine', 'scratch random' or 'scratch any' rights depending on how the track came to be added to the queue.",
 simple("scratch",
        "Terminate the playing track.",
        "Requires one of the 'scratch mine', 'scratch random' or 'scratch any' rights depending on how the track came to be added to the queue.",