summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaromil <jaromil@dyne.org>2011-04-15 13:51:45 (GMT)
committer Jaromil <jaromil@dyne.org>2011-04-15 13:51:45 (GMT)
commite9769fc16aee9d075c4cfa7bb749f4768f70b7b0 (patch)
treef7f2f98a78b13d2031b72cdcce1afb103c650e09
parent7c32ba4d1be78cd05fd43ee1076a57896587eafe (diff)
added load function
and more fixes
-rw-r--r--configure.ac12
-rw-r--r--src/avremote.c49
-rw-r--r--src/avremote.h44
-rw-r--r--src/cmdline.c35
4 files changed, 101 insertions, 39 deletions
diff --git a/configure.ac b/configure.ac
index 0614b09..49814d8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -32,16 +32,6 @@ AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
-
-dnl Fortunately we have Solaris...
-AC_CHECK_HEADERS(sys/sockio.h)
-
-AC_CHECK_FUNCS(srandom random)
-if test $ac_cv_func_srandom = no; then
- # let's try with the older srand/rand functions
- AC_CHECK_FUNCS(srand rand)
-fi
-
dnl Advanced network address translating functions
AC_CHECK_FUNCS(inet_pton inet_ntop)
@@ -53,7 +43,7 @@ dnl Check if it is available the RFC2292 IPv4 extension and in_port_t.
AC_CHECK_TYPES([struct in_pktinfo, in_port_t], , , [#include <sys/types.h>
#include <netinet/in.h>])
-dnl AC_CHECK_HEADERS([stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h])
+AC_CHECK_HEADERS([stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h])
dnl ==============================================================
diff --git a/src/avremote.c b/src/avremote.c
index 7b49274..6bb5ce0 100644
--- a/src/avremote.c
+++ b/src/avremote.c
@@ -34,6 +34,8 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
+
+#include <libgen.h>
#include <errno.h>
@@ -47,11 +49,12 @@ upnp_t *create_upnp() {
upnp->port = -1;
upnp->sockfd = -1;
- upnp->msg = (char*) calloc(1024,sizeof(char));
+ upnp->msg = (char*) calloc(2048,sizeof(char));
upnp->msglen = 0;
upnp->hdr = (char*) calloc(512,sizeof(char));
upnp->hdrlen = 0;
upnp->res = (char*) calloc(1401,sizeof(char));
+ upnp->meta = (char*) calloc(1024,sizeof(char));
return(upnp);
@@ -67,6 +70,7 @@ void free_upnp(upnp_t *upnp) {
if(upnp->msg) free(upnp->msg);
if(upnp->hdr) free(upnp->hdr);
if(upnp->res) free(upnp->res);
+ if(upnp->meta) free(upnp->meta);
free(upnp);
}
@@ -128,24 +132,44 @@ int connect_upnp(upnp_t *upnp, char *hostname, int port) {
return(sockfd);
}
-void render_file_meta() {
- /*
- "<DIDL-Lite xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite\""
- "xmlns:dc=\"http://purl.org/dc/elements/1.1/\""
- "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">"
- "<item id=\"2$file\" parentID=\"2$parentDir\" restricted=\"0\">"
- "<dc:title>$fileName</dc:title><dc:date></dc:date><upnp:class>object.item.imageItem</upnp:class><dc:creator></dc:creator><upnp:genre></upnp:genre><upnp:artist></upnp:artist><upnp:album></upnp:album><res protocolInfo=\"file-get:*:*:*:DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=00000000001000000000000000000000\" protection=\"\" tokenType=\"0\" bitrate=\"0\" duration=\"\" size=\"$fileSize\" colorDepth=\"0\" ifoFileURI=\"\" resolution=\"\">$uri</res></item></DIDL-Lite>"
- */
+void render_uri_meta(upnp_t *upnp, char *path) {
+ char dir[1024];
+ char *pdir;
+ char file[1024];
+ char *pfile;
+ char url[1024];
+ size_t filesize;
+
+ // TODO: streams
+
+ struct stat fs;
+ if( stat(path,&fs) < 0 ) {
+ fprintf(stderr,"error: cannot load file %s (%s)\n", path, strerror(errno));
+ filesize = 0;
+ } else
+ filesize = fs.st_size;
+
+ strncpy(dir,path,1023);
+ pdir = dirname(dir);
+ strncpy(file,path,1023);
+ pfile = basename(file);
+ snprintf(url,1023,"file://%s",path);
+
+
+ snprintf(upnp->meta,1023,UPNP_META_FORMAT, url,
+ pfile, pdir, pfile, filesize, url);
+
+
}
void render_upnp(upnp_t *upnp, char *action, char *arg) {
// blank message first
- snprintf(upnp->msg,1023,UPNP_MSG_FORMAT,
+ snprintf(upnp->msg,2047,UPNP_MSG_FORMAT,
action, arg, action);
upnp->msglen = strlen(upnp->msg);
- snprintf(upnp->hdr,1023,UPNP_HDR_FORMAT,
+ snprintf(upnp->hdr,511,UPNP_HDR_FORMAT,
action, upnp->hostname, upnp->port, upnp->msglen);
upnp->hdrlen = strlen(upnp->hdr);
@@ -168,9 +192,6 @@ int send_upnp(upnp_t *upnp) {
int recv_upnp(upnp_t *upnp) {
int res;
res = read(upnp->sockfd, upnp->res,1400);
-#ifdef DEBUG
- fprintf(stderr,"response:\n\n%s\n",upnp->res);
-#endif
return(1);
}
diff --git a/src/avremote.h b/src/avremote.h
index 0d1fa9c..1ee9b6e 100644
--- a/src/avremote.h
+++ b/src/avremote.h
@@ -32,6 +32,9 @@ typedef struct {
size_t msglen;
char *res;
+ size_t reslen;
+
+ char *meta;
} upnp_t;
@@ -50,10 +53,51 @@ typedef struct {
"Content-Length: %u\r\n" \
"\r\n"
+#define UPNP_META_FORMAT "<CurrentURI>%s</CurrentURI>" \
+ "<CurrentURIMetaData><DIDL-Lite xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite\"" \
+ "xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" \
+ "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">" \
+ "<item id=\"2%s\" parentID=\"2%s\" restricted=\"0\">" \
+ "<dc:title>%s</dc:title><dc:date></dc:date>" \
+ "<upnp:class>object.item.imageItem</upnp:class><dc:creator></dc:creator>" \
+ "<upnp:genre></upnp:genre><upnp:artist></upnp:artist><upnp:album></upnp:album>" \
+ "<res protocolInfo=\"file-get:*:*:*:DLNA.ORG_OP=01;DLNA.ORG_CI=0;" \
+ "DLNA.ORG_FLAGS=00000000001000000000000000000000\" protection=\"\" tokenType=\"0\" " \
+ "bitrate=\"0\" duration=\"\" size=\"%u\" colorDepth=\"0\" ifoFileURI=\"\" " \
+ "resolution=\"\">%s</res></item></DIDL-Lite></CurrentURIMetaData>"
+
upnp_t *create_upnp();
void free_upnp(upnp_t *upnp);
int connect_upnp(upnp_t *upnp, char *hostname, int port);
+
+/*
+Available AVTransport actions:
+
+GetCurrentTransportActions
+GetDeviceCapabilities
+GetMediaInfo
+GetPositionInfo
+GetTransportInfo
+GetTransportSettings
+Next
+Pause
+Play
+Previous
+Seek <SeekMode> <SeekTarget> (allowed SeekMode: "X_DLNA_REL_BYTE", "REL_TIME", "TRACK_NR")
+SetAVTransportURI <URI> <URIMetaData> (allowed URI: "http://server/file", "file:///folder/file"
+SetPlayMode <NewPlayMode> (allowed NewPlayMode = "NORMAL", "REPEAT_ONE", "REPEAT_ALL", "RANDOM")
+Stop
+X_DLNA_GetBytePositionInfo
+
+Available RenderingControl actions:
+
+GetMute
+GetVolume
+SetMute <DesiredMute> (allowed DesiredMute = 0 or 1)
+SetVolume <DesiredVolume> (allowed DesiredVolume = 1 to 100)
+*/
+
void render_upnp(upnp_t *upnp, char *action, char *arg);
int send_upnp(upnp_t *upnp);
diff --git a/src/cmdline.c b/src/cmdline.c
index fc2f350..5f7abf6 100644
--- a/src/cmdline.c
+++ b/src/cmdline.c
@@ -85,15 +85,10 @@ void cmdline(int argc, char **argv) {
break;
case 1:
- {
- struct stat filestatus;
- if( stat(optarg,&filestatus) >= 0 ) { // its a file
- snprintf(filename,511,"%s",optarg);
- } else {
- snprintf(command,63,"%s",optarg);
- fprintf(stderr,"executing command '%s'\n",command);
- }
- }
+ if(!command[0]) {
+ snprintf(command,63,"%s",optarg);
+ } else
+ snprintf(filename,511,"%s",optarg);
break;
default:
break;
@@ -122,17 +117,16 @@ void cmdline(int argc, char **argv) {
}
int main(int argc, char **argv) {
- int sock, port, n;
+ upnp_t *upnp;
cmdline(argc, argv);
- upnp_t *upnp;
upnp = create_upnp();
if(!dry_run) {
if ( connect_upnp(upnp, server, port) < 0 ) {
- fprintf(stderr,"can't connect to server %s: operation aborted.\n", server);
+ fprintf(stderr,"can't connect to %s:%u: operation aborted.\n", server, port);
exit(ERR);
}
@@ -146,6 +140,14 @@ int main(int argc, char **argv) {
// command parsing is a cascade switch on single letters
// this is supposedly faster than strcmp
switch(command[0]) {
+
+ case 'l': // load url
+ // render_upnp(upnp,"SetPlayMode", "<NewPlayMode>NORMAL</NewPlayMode>");
+ // send_upnp(upnp);
+ render_uri_meta(upnp,filename);
+ render_upnp(upnp,"SetAVTransportURI", upnp->meta);
+ break;
+
case 'p':
if(command[1]=='l') { // 'pl*' is play
@@ -159,12 +161,14 @@ int main(int argc, char **argv) {
}
break;
- case 's':
+ case 's': // stop
render_upnp(upnp,"Stop","");
break;
+
case 'g':
render_upnp(upnp,"GetTransportInfo","");
break;
+
default:
fprintf(stderr,"error: command not understood.\n");
free_upnp(upnp);
@@ -173,9 +177,12 @@ int main(int argc, char **argv) {
if(dry_run)
print_upnp(upnp);
- else
+ else {
send_upnp(upnp);
+ recv_upnp(upnp);
+ fprintf(stderr,"response:\n\n%s\n",upnp->res);
+ }
// TODO recv when needed
free_upnp(upnp);