aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/contrib/utils
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/contrib/utils')
-rw-r--r--trunk/contrib/utils/README.rawplayer37
-rw-r--r--trunk/contrib/utils/eagi_proxy.c419
-rw-r--r--trunk/contrib/utils/rawplayer.c46
-rw-r--r--trunk/contrib/utils/zones2indications.c153
4 files changed, 655 insertions, 0 deletions
diff --git a/trunk/contrib/utils/README.rawplayer b/trunk/contrib/utils/README.rawplayer
new file mode 100644
index 000000000..146898a5c
--- /dev/null
+++ b/trunk/contrib/utils/README.rawplayer
@@ -0,0 +1,37 @@
+rawplayer is a simple C applet to stream raw music files in place of mpg123
+
+INSTALL
+
+compile the .c file and install:
+gcc -O2 rawplayer.c -o /usr/bin/rawplayer
+
+
+
+Converting MP3 to RAW
+
+Make track01.mp3 into track01.raw with sox (if compiled with mp3 support).
+sox -c 1 track01.mp3 -t raw -r 8000 -c 1 -s -w track01.raw
+
+Otherwise, use whatever app to turn track01.mp3 into track01.wav then use sox on the wav.
+sox -c 1 track01.wav -t raw -r 8000 -c 1 -s -w track01.raw
+
+
+Once you have the raw files put them in any dir on your system (eg /var/lib/asterisk/holdmusic_raw).
+and set up a class in musiconhold.conf like so:
+
+[classes]
+default => custom:/var/lib/asterisk/holdmusic_raw,/usr/bin/rawplayer
+
+
+This is the most efficient way to implement moh because no cpu usage is required to
+explode the very compressed mp3 data then downsample the music to the 8khz mono on the fly
+instead the data is already stored on the disk in the format that asterisk needs it to be
+and the player does little more than pick up frames from the file and hand them to right
+to the asterisk pipe where the audio is shared into all the channels who require it.
+
+
+If you have cpu to spare and want a simple mp3 solution consider the format_mp3 from
+asterisk-addons and the files based moh.
+
+
+
diff --git a/trunk/contrib/utils/eagi_proxy.c b/trunk/contrib/utils/eagi_proxy.c
new file mode 100644
index 000000000..03c7e0640
--- /dev/null
+++ b/trunk/contrib/utils/eagi_proxy.c
@@ -0,0 +1,419 @@
+/*
+ * Asterisk EAGI -> TCP/IP proxy
+ * by Danijel Korzinek (devil_slayer _at_ hotmail.com)
+ *
+ * This simple C application allows you to control asterisk thru one TCP/IP
+ * socket and listen to the conversation thru another socket.
+ *
+ * Great for ASR or wizzard-of-oz telephony systems!
+ *
+ * HOWTO:
+ * The program is compiled using the following command:
+ * gcc eagi_proxy.c -o eagi_proxy -lpthread
+ *
+ * In the dialplan, you can add something like this to the main context:
+ * exten => s,1,Answer
+ * exten => s,n,EAGI(/path/to/eagi_proxy)
+ * exten => s,n,Hangup
+ *
+ * To test the program you can use the netcat utility:
+ * (http://netcat.sourceforge.net/)
+ *
+ * -in one console run:
+ * nc -vv -l -p 8418 > /path/to/file.raw
+ * -in another run:
+ * nc -vv -l -p 8417
+ * -you can use any file for the signal or even /dev/null
+ * -you can change the port numbers in the sourcecode below
+ *
+ * Once you make the call, both programs will accept the incoming
+ * connection. The program on port 8417 will print out the enviornemnt
+ * (unless the appropriate define below is commented) and you can write
+ * any AGI command there (http://www.voip-info.org/wiki-Asterisk+AGI),
+ * e.g.:
+ * GET DATA /path/to/gsm/file 10000 4
+ *
+ * Finally, you can open the RAW file in any sound editor. The format is:
+ * RAW little-endian 8kHz 16bit
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include <pthread.h>
+
+/* DEFINES */
+#define SIGNAL_PORT 8418
+#define COMMAND_PORT 8417
+#define SEND_ENVIORNMENT /*send the enviornment thru the socket*/
+/************************/
+
+
+#define BUFSIZE 1024
+char buf[BUFSIZE];
+
+#define WINSIZE 400 /* 25 ms @ 8 kHz and 16bit */
+char window[WINSIZE];
+
+#define WINBUF_NUM 2400 /* number of WINSIZE windows = 1 minute */
+char* winbuf;
+char *end, *bs, *be;
+/* winbuf - start of buffer
+ * end - end of buffer
+ * bs - start of data
+ * be - end of data
+ */
+
+int command_desc; /* command transfer descriptor */
+int speech_desc; /* speech signal descrriptor */
+char connected=1; /* connection state */
+
+int connect_to_host(char* host, int port); /* connect to a given host (name or IP) and given port number in nonblocking mode returning socket descriptor*/
+
+void read_full(int file, char* buffer, int num); /* read EXACTLY "num" ammount of bytes from "file" descriptor to "buffer"*/
+int read_some(int file, char* buffer, int size); /* read AT MOST "size" ammount of bytes */
+
+void write_buf(int file, char* buffer, int num); /* write "num" ammount of bytes to "file" descriptor and buffer the surplus if the write would block */
+int write_amap(int file, char* buffer, int num); /*write AT MOST "num" ammount of bytes and return ammount that was written*/
+
+void setnonblocking(int desc); /*sets the socket non-blocking; for polling */
+
+void finalize(); /* this function is run at exit */
+
+pthread_mutex_t command_mutex;/* command socket mutex */
+pthread_t stdin_thread,signal_thread;
+void* readStdin(void* ptr);
+void* readSignal(void* ptr);
+
+/* The program creates 3 threads:
+ * 1) Main thread - reads commands from the socket and sends them to asterisk
+ * 2) stdin_thread - reads asterisk output and sends it to the command socket
+ * 3) signal_thread - reads the sound from asterisk and sends it to the signal socket
+ */
+
+int main()
+{
+ int ret;
+
+ atexit(finalize);
+
+ setlinebuf(stdin);
+ setlinebuf(stdout);
+
+ winbuf=(char*)malloc(WINSIZE*WINBUF_NUM);
+ end=winbuf+WINSIZE*WINBUF_NUM;
+ bs=be=winbuf;
+
+ speech_desc=connect_to_host("localhost",SIGNAL_PORT);
+ if(speech_desc<0)
+ {
+ perror("signal socket");
+ return -1;
+ }
+
+
+ command_desc=connect_to_host("localhost",COMMAND_PORT);
+ if(command_desc<0)
+ {
+ perror("command socket");
+ return -1;
+ }
+
+ pthread_mutex_init(&command_mutex,NULL);
+ pthread_create(&stdin_thread,NULL,readStdin,NULL);
+ pthread_create(&signal_thread,NULL,readSignal,NULL);
+
+ while(connected)
+ {
+ pthread_mutex_lock(&command_mutex);
+ ret=read_some(command_desc,buf,BUFSIZE);
+ pthread_mutex_unlock(&command_mutex);
+ if(ret>0)
+ {
+ buf[ret]=0;
+ printf("%s",buf);
+ }
+ }
+
+ return 0;
+}
+
+void finalize()
+{
+ close(command_desc);
+ close(speech_desc);
+ free(winbuf);
+}
+
+void* readStdin(void* ptr)
+{
+ while(1)/*read enviornment*/
+ {
+ fgets(buf,BUFSIZE,stdin);
+ #ifdef SEND_ENVIORNMENT
+ pthread_mutex_lock(&command_mutex);
+ write_buf(command_desc,buf,strlen(buf));
+ pthread_mutex_unlock(&command_mutex);
+ #endif
+ if(feof(stdin) || buf[0]=='\n')
+ {
+ break;
+ }
+ }
+
+ while(connected)
+ {
+ fgets(buf,BUFSIZE,stdin);
+ pthread_mutex_lock(&command_mutex);
+ write_buf(command_desc,buf,strlen(buf));
+ pthread_mutex_unlock(&command_mutex);
+ }
+
+ pthread_exit(NULL);
+}
+
+void* readSignal(void* ptr)
+{
+ while(connected)
+ {
+ read_full(3,window,WINSIZE);
+ write_buf(speech_desc,window,WINSIZE);
+ }
+
+ pthread_exit(NULL);
+}
+
+
+void read_full(int file, char* buffer, int num)
+{
+ int count,pos=0;
+
+ while(num)
+ {
+ count=read(file,buffer+pos,num);
+ if(count==0 || (count<0 && errno!=EAGAIN))
+ {
+ connected=0;
+ return;
+ }
+ num-=count;
+ pos+=count;
+ }
+}
+
+int connect_to_host(char* name, int port)
+{
+ int address;
+ struct hostent* host_entity;
+ int res,desc;
+ int opts;
+ struct sockaddr_in host;
+
+
+ /* get adress */
+ if(!strcmp(name,"localhost"))
+ address=htonl(2130706433); /*127.0.0.1*/
+ else
+ {
+ address=inet_addr(name); /* check if it's an IP that's written in the string */
+ if(address==(in_addr_t)-1)
+ {
+ host_entity = gethostbyname(name); /* search for the host under this name */
+
+ if(!host_entity)
+ {
+ fprintf(stderr,"EAGI proxy: Wrong address!\n"); /* can't find anything*/
+ return -1;
+ }
+ address=*((int*)host_entity->h_addr);
+ }
+ }
+
+ desc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
+ if(desc<0)
+ {
+ fprintf(stderr,"EAGI proxy: Cannot create socket!\n");
+ return -1;
+ }
+
+ memset((void*)&host,0,sizeof(struct sockaddr_in));
+
+ host.sin_family=AF_INET;
+ host.sin_port=htons(port);
+ host.sin_addr.s_addr=address;
+
+ res=connect(desc,(struct sockaddr*)&host,sizeof(host));
+ if(res<0)
+ {
+ fprintf(stderr,"EAGI proxy: Cannot connect!\n");
+ return -1;
+ }
+
+ /* set to non-blocking mode */
+ opts = fcntl(desc,F_GETFL);
+ if (opts < 0) {
+ perror("fcntl(F_GETFL)");
+ exit(EXIT_FAILURE);
+ }
+ opts = (opts | O_NONBLOCK);
+ if (fcntl(desc,F_SETFL,opts) < 0) {
+ perror("fcntl(F_SETFL)");
+ exit(EXIT_FAILURE);
+ }
+
+
+ return desc;
+}
+
+int read_some(int desc, char* buffer, int size)
+{
+ unsigned char c;
+ int res,i=0;
+
+ for(;;)
+ {
+ res=read(desc,&c,1);
+ if(res<1)
+ {
+ if(errno!=EAGAIN)
+ {
+ perror("Error reading");
+ connected=0;
+ }
+ break;
+ }
+ if(res==0)
+ {
+ connected=0;
+ break;
+ }
+
+ buffer[i]=c;
+ i++;
+ }
+
+ return i;
+}
+
+/* This is a tricky function! */
+void write_buf(int desc, char* buf, int size)
+{
+ int ret;
+
+ /*NOTE: AMAP -> as much as possible */
+
+ if(be!=bs)/* if data left in buffer */
+ {
+ if(be>bs)/* if buffer not split */
+ {
+ ret=write_amap(desc,bs,be-bs);/* write AMAP */
+ bs+=ret;/* shift the start of the buffer */
+ }
+ else/* if buffer is split */
+ {
+ ret=write_amap(desc,bs,end-bs);/* write higher part first */
+ if(ret==end-bs)/* if wrote whole of the higher part */
+ {
+ ret=write_amap(desc,winbuf,be-winbuf);/* write lower part */
+ bs=winbuf+ret;/* shift start to new position */
+ }
+ else bs+=ret;/* if not wrote whole of higher part, only shift start */
+ }
+ }
+
+ if(be==bs)/* if buffer is empty now */
+ {
+ ret=write_amap(desc,buf,size);/* write AMAP of the new data */
+ buf+=ret;/* shift start of new data */
+ size-=ret;/* lower size of new data */
+ }
+
+ if(size)/* if new data still remains unsent */
+ {
+ if(be>=bs)/* if data not split */
+ {
+ if(size>end-be)/* if new data size doesn't fit higher end */
+ {
+ size-=end-be;/* reduce new data size by the higher end size */
+ memcpy(be,buf,end-be);/* copy to higher end */
+ be=winbuf;/* shift end to begining of buffer */
+ buf+=end-be;/* shift start of new data */
+ }
+ else/* if new data fits the higher end */
+ {
+ memcpy(be,buf,size);/* copy to higher end */
+ be+=size;/* shift end by size */
+ if(be>=end)/* if end goes beyond the buffer */
+ be=winbuf;/* restart */
+ size=0;/* everything copied */
+ }
+ }
+
+ if(size)/* if new data still remains */
+ {
+ if(size>=bs-be)/* if new data doesn't fit between end and start */
+ {
+ fprintf(stderr,"Buffer overflow!\n");
+ size=bs-be-1;/* reduce the size that we can copy */
+ }
+
+ if(size)/* if we can copy anything */
+ {
+ memcpy(be,buf,size);/* copy the new data between end and start */
+ be+=size;/* shift end by size */
+ }
+ }
+ }
+}
+
+int write_amap(int desc, char* buf, int size)
+{
+ int ret;
+ ret=write(desc,buf,size);
+ if(ret<0)
+ {
+ if(errno!=EAGAIN)
+ {
+ perror("Error writing");
+ connected=0;
+ }
+ return 0;
+ }
+ if(ret==0)
+ connected=0;
+
+ return ret;
+}
+
+
+void setnonblocking(int desc)
+{
+ int opts;
+
+ opts = fcntl(desc,F_GETFL);
+ if(opts < 0)
+ {
+ perror("fcntl(F_GETFL)");
+ exit(-1);
+ }
+
+ opts = (opts | O_NONBLOCK );
+ if(fcntl(desc,F_SETFL,opts) < 0)
+ {
+ perror("fcntl(F_SETFL)");
+ exit(-1);
+ }
+}
diff --git a/trunk/contrib/utils/rawplayer.c b/trunk/contrib/utils/rawplayer.c
new file mode 100644
index 000000000..2733264a0
--- /dev/null
+++ b/trunk/contrib/utils/rawplayer.c
@@ -0,0 +1,46 @@
+/*
+ Rawplayer.c simple raw file stdout player
+ (c) Anthony C Minessale II <anthmct@yahoo.com>
+
+ 2006-03-10: Bruno Rocha <bruno@3gnt.net>
+ - include <stdlib.h> to remove compiler warning on some platforms
+ - check for read/write errors (avoid 100% CPU usage in some asterisk failures)
+*/
+
+#define BUFLEN 320
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+static int deliver_file(char *path, int fdout) {
+ int fd = 0, bytes = 0, error = 0;
+ short buf[BUFLEN];
+
+ if ((fd = open(path,O_RDONLY))) {
+ while ((bytes=read(fd, buf, BUFLEN)) > 0) {
+ if(write(fdout, buf, bytes) < 0){
+ error = -2;
+ break;
+ }
+ }
+ if(fd)
+ close(fd);
+ } else
+ return -1;
+
+ return error;
+}
+
+
+int main(int argc, char *argv[]) {
+ int x = 0, fdout = 0;
+ fdout = fileno(stdout);
+ for (;;)
+ for (x = 1; x < argc ; x++) {
+ if(deliver_file(argv[x], fdout))
+ exit(1);
+ }
+}
+
diff --git a/trunk/contrib/utils/zones2indications.c b/trunk/contrib/utils/zones2indications.c
new file mode 100644
index 000000000..645cd0ed5
--- /dev/null
+++ b/trunk/contrib/utils/zones2indications.c
@@ -0,0 +1,153 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Tzafrir Cohen <tzafrir.cohen@xorcom.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief print libtonozone data as Asterisk indications.conf
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <zaptel/tonezone.h>
+#include <unistd.h>
+
+#define PROGRAM "zones2indication"
+
+void print_tone_zone_sound(struct ind_tone_zone *zone_data, const char* name,
+ int toneid) {
+ int i;
+ for (i=0; i<ZT_TONE_MAX; i++) {
+ if (zone_data->tones[i].toneid == toneid){
+ printf("%s = %s\n", name, zone_data->tones[i].data);
+ break;
+ }
+ }
+}
+
+void print_indications(struct ind_tone_zone *zone_data) {
+ int i;
+
+ printf (
+ "[%s]\n"
+ "; Source: libtonezone.\n"
+ "description = %s\n"
+ "\n",
+ zone_data->country, zone_data->description
+ );
+
+ printf(
+ "ringcadence = "
+ );
+ for(i=0; ; i++) {
+ if (zone_data->ringcadence[i] == 0)
+ break;
+ if (i != 0)
+ putchar(',');
+ printf("%d",zone_data->ringcadence[i]);
+ }
+ putchar('\n');
+
+ print_tone_zone_sound(zone_data, "dial", ZT_TONE_DIALTONE);
+ print_tone_zone_sound(zone_data, "busy", ZT_TONE_BUSY);
+ print_tone_zone_sound(zone_data, "ring", ZT_TONE_RINGTONE);
+ print_tone_zone_sound(zone_data, "congestion", ZT_TONE_CONGESTION);
+ print_tone_zone_sound(zone_data, "callwaiting", ZT_TONE_CALLWAIT);
+ print_tone_zone_sound(zone_data, "dialrecall", ZT_TONE_DIALRECALL);
+ print_tone_zone_sound(zone_data, "record", ZT_TONE_RECORDTONE);
+ print_tone_zone_sound(zone_data, "info", ZT_TONE_INFO);
+ print_tone_zone_sound(zone_data, "stutter", ZT_TONE_STUTTER);
+ printf("\n\n");
+}
+
+int print_zone_by_id(int zone_num) {
+ struct tone_zone *zone_data = tone_zone_find_by_num(zone_num);
+
+ if (zone_data == NULL)
+ return 1;
+
+ print_indications(zone_data);
+
+ return 0;
+}
+
+int print_zone_by_country(char* country) {
+ struct tone_zone *zone_data = tone_zone_find(country);
+
+ if (zone_data == NULL)
+ return 1;
+
+ print_indications(zone_data);
+
+ return 0;
+}
+
+int print_all() {
+ int i;
+ /* loop over all possible zones */
+ for (i=0; ; i++) {
+ if (print_zone_by_id(i))
+ break;
+ }
+ return 0;
+}
+
+void usage() {
+ fprintf(stderr,
+ PROGRAM ": print libtonozone data as Asterisk indications.conf\n"
+ "\n"
+ "Usage:\n"
+ " " PROGRAM " -a Print all countries\n"
+ " " PROGRAM " -c <code> Select country by two-letter country code\n"
+ " " PROGRAM " -n <num> Select country by its internal libtonezone number\n"
+ " " PROGRAM " -h Print this text.\n"
+ );
+}
+
+int main(int argc, char* argv[]){
+ int country_code = -1;
+ int opt_print_all = 0;
+ int opt;
+ char* endptr = NULL;
+
+ while((opt = getopt(argc, argv, "ac:hn:")) != -1) {
+ switch(opt) {
+ case 'a':
+ return print_all();
+ case 'c':
+ return print_zone_by_country(optarg);
+ case 'h':
+ usage();
+ return 0;
+ case 'n':
+ printf("number is %s.\n", optarg);
+ country_code = strtol(optarg, &endptr, 10);
+ return print_zone_by_id(country_code);
+ /* FIXME: what if this is not a number?
+ if (endptr != NULL) {
+ fprintf(stderr, "Error: Invalid country code %s, %d.\n",optarg, country_code);
+ usage();
+ exit(1);
+ }
+ */
+ break;
+ }
+ }
+
+ /* If we got here, the user selected no option */
+ usage();
+ return 2;
+}