From e1c9572b15974ffa98eff8b8f4bd77444d44dbd9 Mon Sep 17 00:00:00 2001 From: blogic Date: Mon, 27 Aug 2007 20:10:35 +0000 Subject: added libjson-c. added driver, webinterface and userspace daemon for the fonera mp3-hack git-svn-id: svn://svn.openwrt.org/openwrt/trunk@8509 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/fonera-mp3/src/cgi/Makefile | 13 ++ package/fonera-mp3/src/cgi/json.h | 31 ++++ package/fonera-mp3/src/cgi/json.js | 141 ++++++++++++++++++ package/fonera-mp3/src/cgi/main.c | 237 ++++++++++++++++++++++++++++++ package/fonera-mp3/src/cgi/stylesheet.css | 31 ++++ 5 files changed, 453 insertions(+) create mode 100644 package/fonera-mp3/src/cgi/Makefile create mode 100644 package/fonera-mp3/src/cgi/json.h create mode 100644 package/fonera-mp3/src/cgi/json.js create mode 100644 package/fonera-mp3/src/cgi/main.c create mode 100644 package/fonera-mp3/src/cgi/stylesheet.css (limited to 'package/fonera-mp3/src/cgi') diff --git a/package/fonera-mp3/src/cgi/Makefile b/package/fonera-mp3/src/cgi/Makefile new file mode 100644 index 000000000..b8119c043 --- /dev/null +++ b/package/fonera-mp3/src/cgi/Makefile @@ -0,0 +1,13 @@ +PROGS = mp3.cgi + +OBJS = main.o + + +all: $(PROGS) +$(PROGS): + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $(PROGS) main.c $(LDLIBS) + $(STRIP) $(PROGS) + +clean: + rm -f $(PROGS) *.o core + diff --git a/package/fonera-mp3/src/cgi/json.h b/package/fonera-mp3/src/cgi/json.h new file mode 100644 index 000000000..a5a3432b2 --- /dev/null +++ b/package/fonera-mp3/src/cgi/json.h @@ -0,0 +1,31 @@ +/* + * $Id: json.h,v 1.6 2006/01/26 02:16:28 mclark Exp $ + * + * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. + * Michael Clark + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See COPYING for details. + * + */ + +#ifndef _json_h_ +#define _json_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "bits.h" +#include "debug.h" +#include "linkhash.h" +#include "arraylist.h" +#include "json_util.h" +#include "json_object.h" +#include "json_tokener.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/package/fonera-mp3/src/cgi/json.js b/package/fonera-mp3/src/cgi/json.js new file mode 100644 index 000000000..721d5273e --- /dev/null +++ b/package/fonera-mp3/src/cgi/json.js @@ -0,0 +1,141 @@ +var alpmp3_playtime = 0; +var alpmp3_state = 0; +var alpmp3_ip = ""; +var obj_volume; +var obj_bass; +var obj_playtime; +var obj_sate; +var obj_filename; +var MP3Object; +var is_setup = 0; + +function alpmp3_ajax_new_data(){ + obj_bass.firstChild.nodeValue = MP3Object.alpmp3.bass; + obj_volume.firstChild.nodeValue = MP3Object.alpmp3.volume; + obj_state.firstChild.nodeValue = MP3Object.alpmp3.type; + obj_filename.firstChild.nodeValue = MP3Object.alpmp3.filename; + alpmp3_state = MP3Object.alpmp3.state; + if(Math.abs(alpmp3_playtime - MP3Object.alpmp3.playtime) > 1){ + alpmp3_playtime = MP3Object.alpmp3.playtime; + } +} + +function alpmp3_update_data(url){ + var data; + var http_request = new XMLHttpRequest(); + http_request.open("GET", url, true); + http_request.onreadystatechange = function () { + if (http_request.readyState == 4) { + if (http_request.status == 200) { + MP3Object = eval("(" + http_request.responseText + ")"); + alpmp3_ajax_new_data(); + } else { + alert("There was a problem with the URL."); + } + http_request = null; + } + } + http_request.send(null); + self.setTimeout("alpmp3_update_data('mp3_json.cgi');", 4000); +} + +function alpmp3_remote(cmd){ + var doit = ""; + switch(cmd){ + case 'volup': + if(MP3Object.alpmp3.volume < 30){ + MP3Object.alpmp3.volume++; + } + doit = "?vol=" + MP3Object.alpmp3.volume; + break; + case 'voldown': + if(MP3Object.alpmp3.volume > 0){ + MP3Object.alpmp3.volume--; + } + doit = "?vol=" + MP3Object.alpmp3.volume; + break; + case 'bassup': + if(MP3Object.alpmp3.bass < 30){ + MP3Object.alpmp3.bass++; + } + doit = "?bass=" + MP3Object.alpmp3.bass; + break; + case 'bassdown': + if(MP3Object.alpmp3.volume < 30){ + MP3Object.alpmp3.bass--; + } + doit = "?bass=" + MP3Object.alpmp3.bass; + break; + case 'stop': + doit = "?stop=1"; + break; + case 'start': + doit = "?start=1"; + break; + case 'next': + doit = "?next=1"; + break; + case 'back': + doit = "?back=1"; + break; + } + if(doit != ""){ + var http_request2 = new XMLHttpRequest(); + http_request2.open("GET", 'mp3_cmd.cgi'+doit, true); + http_request2.onreadystatechange = function () { + if (http_request2.readyState == 4) { + if (http_request2.status == 200) { + alpmp3_ajax_new_data(); + } else { + alert("There was a problem with the URL."); + } + http_request2 = null; + } + } + http_request2.send(null); + } + +} + +function alpmp3_timeout(){ + alpmp3_state = 0; + alert(alpmp3_playtime); +} + +function alpmp3_playtime_update(){ + self.setTimeout("alpmp3_playtime_update()", 1000); + if(alpmp3_state > 0){ + alpmp3_playtime ++; + } else { + alpmp3_playtime = 0; + } + var s = alpmp3_playtime; + var h = 0; + var m = 0; + while(s > 3599){ + h++; + s -= 3600; + } + while(s > 59){ + m++; + s -= 60; + } + ptime = ((m < 10) ? "0" : "") + m + ":" + ((s < 10) ? "0" : "") + s; + if(h > 0){ + ptime = ((h < 10) ? "0" : "") + h + ":" + ptime; + } + obj_playtime.firstChild.nodeValue = ptime; +} + +function alpmp3_setup($ip){ + if(is_setup == 0){ + obj_volume = document.getElementById("alpmp3_volume"); + obj_bass = document.getElementById("alpmp3_bass"); + obj_state = document.getElementById("alpmp3_state"); + obj_filename = document.getElementById("alpmp3_filename"); + obj_playtime = document.getElementById("alpmp3_playtime"); + is_setup = 1; + } + self.setTimeout("alpmp3_update_data('mp3_json.cgi');", 4000); + self.setTimeout("alpmp3_playtime_update()", 1000); +} diff --git a/package/fonera-mp3/src/cgi/main.c b/package/fonera-mp3/src/cgi/main.c new file mode 100644 index 000000000..0499e0eee --- /dev/null +++ b/package/fonera-mp3/src/cgi/main.c @@ -0,0 +1,237 @@ +/* +* FOXMP3 +* Copyright (c) 2007 acmesystems.it - john@acmesystems.it +* +* 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 +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA +* +* Feedback, Bugs... info@acmesystems.it +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SOCKET_PATH "/tmp/foxmp3" + +void print_http_header(){ + printf("Content-type: text/html\n\n"); +} + +int read_parameter(char *name, char *value, int maxlen){ + char *pos1, *pos2; + char *query_string = getenv("QUERY_STRING"); + int success = 0; + + if(query_string){ + pos1 = strstr(query_string, name); + if(pos1){ + pos1 += strlen(name) + 1; + pos2 = strstr(pos1, "&"); + if(pos2){ + *pos2 = '\0'; + } + if(strlen(pos1) >= maxlen){ + pos1[maxlen] = '\0'; + } + strcpy(value, pos1); + success = 1; + } + } + return success; +} + + +int issue_command(unsigned char *str){ + int s, t, len; + struct sockaddr_un remote; + + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + exit(1); + } + remote.sun_family = AF_UNIX; + strcpy(remote.sun_path, SOCKET_PATH); + len = strlen(remote.sun_path) + sizeof(remote.sun_family); + if (connect(s, (struct sockaddr *)&remote, len) == -1) { + return 1; + } + if (send(s, str, strlen(str), 0) == -1) { + return 1; + } + unsigned char loop = 1; + while(loop){ + if ((t=recv(s, str, 2048, 0)) > 0) { + str[t] = '\0'; + if((strstr(str, "OK\n")) || (strstr(str, "ERROR\n"))){ + loop = 0; + } + } else { + return 1; + } + } + close(s); + return 0; +} + +void handle_cmd(){ + unsigned char param[128]; + unsigned char cmd[256]; + int i; + *cmd = '\0'; + if(read_parameter("vol", param, 128)){ + i = atoi(param); + i = 120 - (i * 4); + sprintf(cmd, "VOLUME %d", i); + } + if(read_parameter("bass", param, 128)){ + i = atoi(param); + sprintf(cmd, "BASS %d", i); + } + if(read_parameter("start", param, 128)){ + sprintf(cmd, "START"); + } + if(read_parameter("stop", param, 128)){ + sprintf(cmd, "STOP"); + } + if(read_parameter("next", param, 128)){ + sprintf(cmd, "NEXT"); + } + if(read_parameter("back", param, 128)){ + sprintf(cmd, "BACK"); + } + if(*cmd){ + issue_command(cmd); + } +} + +void print_html_remote(){ + char name[128]; + gethostname(name, 128); + printf("foxmp3 - %s - remote"); + printf("

"); + printf(""); + printf("", name); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf(""); + printf("
FOXMP3 - %s
Action0
Filename0
Playtime0
Volume0Up  Down
Bass0Up  Down
Start Stop Back Next 
"); + printf("

"); + printf(""); +} + + + +void print_json_info(){ + unsigned char str[2048]; + sprintf(str, "STATE"); + if(issue_command(str) == 0){ + int state = 0; + int volume = 0; + int bass = 0; + int playtime = 0; + unsigned char filename[1024]; + unsigned char *p1, *p2; + + memset(filename, 0, 1024); + p1 = str; + while(p1){ + p2 = strstr(p1, "\n"); + if(p2){ + *p2 = '\0'; + p2 ++; + // printf("parsing %s\n", p1); + if(strncmp(p1, "VOLUME", strlen("VOLUME")) == 0){ + volume = atoi(&p1[strlen("VOLUME") + 1]); + if(volume > 120) + volume = 120; + volume = 120 - volume; + volume /= 4; + //printf("vol = %d\n", volume); + } else if(strncmp(p1, "BASS", strlen("BASS")) == 0){ + bass = atoi(&p1[strlen("BASS") + 1]); + //printf("bass = %d\n", bass); + } else if(strncmp(p1, "PLAYTIME", strlen("PLAYTIME")) == 0){ + playtime = atoi(&p1[strlen("PLAYTIME") + 1]); + //printf("playtime = %d\n", playtime); + } else if(strncmp(p1, "STATE", strlen("STATE")) == 0){ + if(strstr(p1, "MP3_STATE_IDLE")){ + state = 0; + } else if(strstr(p1, "MP3_STATE_FILE")){ + state = 1; + } else if(strstr(p1, "MP3_STATE_STREAM")){ + state = 2; + } + //printf("state = %d\n", state); + } else if(strncmp(p1, "STREAM", strlen("STREAM")) == 0){ + strcpy(filename, &p1[strlen("STREAM") + 1]); + //printf("filename = %s\n", filename); + } else if(strncmp(p1, "FILE", strlen("FILE")) == 0){ + strcpy(filename, &p1[strlen("FILE") + 1]); + //printf("filename = %s\n", filename); + } + + p1 = p2; + } else { + p1 = 0; + } + } + + struct json_object *alpmp3 = json_object_new_object(); + json_object_object_add(alpmp3, "state", json_object_new_int(state)); + switch(state){ + case 1: + json_object_object_add(alpmp3, "type", json_object_new_string("file")); + break; + case 2: + json_object_object_add(alpmp3, "type", json_object_new_string("stream")); + break; + default: + json_object_object_add(alpmp3, "type", json_object_new_string("idle")); + break; + } + json_object_object_add(alpmp3, "volume", json_object_new_int(volume)); + json_object_object_add(alpmp3, "bass", json_object_new_int(bass)); + json_object_object_add(alpmp3, "playtime", json_object_new_int(playtime)); + json_object_object_add(alpmp3, "filename", json_object_new_string(filename)); + struct json_object *jo = json_object_new_object(); + json_object_object_add(jo, "alpmp3", alpmp3); + printf("\n%s\n", json_object_to_json_string(jo)); + } +} + +int main(int argc, char **argv){ + print_http_header(); + + if(strstr(argv[0], "mp3_remote.cgi")){ + print_html_remote(); + } else if(strstr(argv[0], "mp3_json.cgi")){ + print_json_info(); + } else if(strstr(argv[0], "mp3_cmd.cgi")){ + handle_cmd(); + } else { + printf("Unknown command"); + } + return 0; +} diff --git a/package/fonera-mp3/src/cgi/stylesheet.css b/package/fonera-mp3/src/cgi/stylesheet.css new file mode 100644 index 000000000..d58d47e24 --- /dev/null +++ b/package/fonera-mp3/src/cgi/stylesheet.css @@ -0,0 +1,31 @@ +body { + background-color:#FFFFFF; +} + +font { font-family: Verdana, Arial, Helvetica, sans-serif } +td { font-family: Arial, Helvetica, sans-serif; font-size: 12px } +th { font-family: Arial, Helvetica, sans-serif } +P { font-family: Arial, Helvetica, sans-serif } +hr { height: 0px; border-top-width: 1px;} +TH.surlink { font-family: Arial, Helvetica, sans-serif; color: #000000 } + +TH { background-color: #99CCCC; height: 0px; font-size: 11px; line-height : 100%; font-weight: bold; color: #000000 } +TR.cellone { background-color: #FFFFCC; height: 16px; font-size: 12px; line-height : 100%; color: #000000 } +TR.celltwo { background-color: #FFFF99; height: 16px; font-size: 12px; line-height : 100%; color: #000000 } +TR.cellhead { background-color: #FFFF44; height: 16px; font-size: 12px; line-height : 100%; color: #000000 } + +.copyright { font-family: Verdana, Arial, Helvetica, sans-serif; color: #000000; font-size: 10px; letter-spacing: -1px;} +.copyright a { color: #CC0000; text-decoration: none;} +.copyright a:hover { color: #FF0000; text-decoration: underline;} + +.error_table { border-spacing:0px;border: 1px solid #000000;} +.error_t {color:#000000;background-color:#FFFFDD;border-spacing:0px;border: 0px} + +a { color: #0000FF; text-decoration: underline;} +a:hover { color: #FF0000; text-decoration: none;} +.box { + background-color: #FFFFFF; + border: 1px solid #999900; + font-family: Verdana; + font-size: 10px; + } -- cgit v1.2.3