serval-dna/asterisk_app.c

244 lines
6.7 KiB
C

/*
* 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 Connect with Serval Distributed Numbering Architecture for Mesh Calling
*
* Paul Gardner-Stephen (paul@servalproject.org)
*
* \ingroup applications
*/
#include "asterisk.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision: Serval $")
#include <sys/types.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <pthread.h>
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/features.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/localtime.h"
#include "asterisk/cdr.h"
#include "asterisk/options.h"
#include "serval.c"
#undef inet_ntoa
#define inet_ntoa ast_inet_ntoa
static char *sdnalookup_descrip =
" SDNALookup(): Resolves a telephone number into SIP address via Serval Distributed Numbering Architecture\n";
static char *sdnalookup_app = "SDNALookup";
static char *sdnalookup_synopsis = "Resolve DID into SIP address via Serval DNA";
static char *handle_cli_sdnalookup(int fd, int argc, char *argv[])
{
char *did=NULL;
char *sid=NULL;
unsigned char buffer[65535];
int len=0;
int instance=0;
if (argc != 4) {
ast_cli(fd, "You did not provide an argument to serval dna lookup\n\n");
return RESULT_FAILURE;
}
did=argv[3];
if (requestItem(did,sid,"locations",instance,buffer,sizeof(buffer),&len,NULL))
{
ast_cli(fd,"Serval DNA Lookup: requestItem() failed (len=%d).\n\n",len);
return RESULT_FAILURE;
}
buffer[len]=0;
ast_cli(fd,"%s resolves to %s (len=%d)\n",did,buffer,len);
return RESULT_SUCCESS;
}
static char *handle_cli_sdnapeers(int fd, int argc, char *argv[])
{
int i;
if (argc != 3) {
ast_cli(fd, "serval dna peers does not argue about arguments.\n\n");
return RESULT_FAILURE;
}
getPeerList();
ast_cli(fd,"%d peers reachable:\n",peer_count);
for(i=0;i<peer_count;i++)
{
unsigned char *c=(unsigned char *)&peers[i];
ast_cli(fd," %d.%d.%d.%d\n",c[0],c[1],c[2],c[3]);
}
return RESULT_SUCCESS;
}
static char *handle_cli_sdnagate(int fd, int argc, char *argv[])
{
unsigned char buffer[65535];
int len=0;
int instance=0;
if (gatewayspec) free(gatewayspec);
gatewayspec=NULL;
if (argc == 3 ) {
ast_cli(fd,"Serval DNA Gateway Function OFF.\n\n",len);
return RESULT_SUCCESS;
}
if (argc != 4) {
ast_cli(fd, "You did not provide an argument to serval dna gateway\n\n");
return RESULT_FAILURE;
}
gatewayspec=strdup(argv[3]);
ast_cli(fd,"Serval DNA Gateway Function ON (trunk spec is %s).\n\n",gatewayspec);
return RESULT_SUCCESS;
}
static char *handle_cli_sdnadebug(int fd, int argc, char *argv[])
{
if (argc != 3) {
ast_cli(fd, "You did not provide an argument to serval debug\n\n");
return RESULT_FAILURE;
}
debug=atoi(argv[2]);
ast_cli(fd,"Serval debug level set to %d\n",debug);
return RESULT_SUCCESS;
}
static char sdnalookup_usage[]=
"Usage: serval dna lookup <did>\n"
" Attempt to resolve a DID into a SIP address via Serval DNA.\n"
"Examples:\n"
" serval dna lookup 0427679796\n";
static char sdnapeers_usage[]=
"Usage: serval dna peers\n"
" Ask DNA to list the peers currently reachable on the mesh.\n"
"Examples:\n"
" serval dna peers\n";
static char sdnadebug_usage[]=
"Usage: serval debug <debug level>\n"
" Set Serval debug level (0-3 are useful values).\n"
"Examples:\n"
" serval debug 3\n";
static char sdnagate_usage[]=
"Usage: serval dna gateway [gateway uri]\n"
" Offer Serval DNA gateway services to allow other BatPhones to use our SIP trunk.\n"
"Examples:\n"
" serval dna gateway 4000@10.130.1.101\n";
static struct ast_cli_entry cli_sdnalookup[] = {
{ { "serval","dna","lookup" }, handle_cli_sdnalookup,
"Resolve a telephone number via Serval DNA", sdnalookup_usage },
{ { "serval","dna","peers" }, handle_cli_sdnapeers,
"Ask DNA to list peers reachable on the mesh", sdnapeers_usage },
{ { "serval","debug" }, handle_cli_sdnadebug,
"Set Serval debug level", sdnadebug_usage },
{ { "serval","dna","gateway" }, handle_cli_sdnagate,
"Enable DNA Gateway ", sdnagate_usage },
};
static int sdnalookup_exec(struct ast_channel *chan, void *data)
{
char *did=data;
char *sid=NULL;
unsigned char buffer[65535];
int len=0;
int instance=0;
char status[256] = "INVALIDARGS";
/* Clear Serval DNA set variables */
pbx_builtin_setvar_helper(chan, "SDNADID", "");
pbx_builtin_setvar_helper(chan, "SDNASID", "");
pbx_builtin_setvar_helper(chan, "SDNALOCATION", "");
pbx_builtin_setvar_helper(chan, "SDNASIG", "");
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "SDNALookup requires an argument (number)\n");
pbx_builtin_setvar_helper(chan, "SDNASTATUS", status);
if (debug) fprintf(stderr,"SDNASTATUS=%s (a)\n",status);
return -1;
}
/* XXX - Simple version for now. Should really use a derivation of the core code from the function below to:
(a) provide more meaningful errors;
(b) retrieve the SID for the DID for further use
(c) fetch the voicesig as well if requested
*/
if (requestItem(did,sid,"locations",instance,buffer,sizeof(buffer),&len,NULL))
{
pbx_builtin_setvar_helper(chan,"SNASTATUS","FAILED");
if (debug) fprintf(stderr,"SDNASTATUS=FAILED\n");
return -1;
}
/* It worked, so set appropriate variables and return happily */
pbx_builtin_setvar_helper(chan,"SNADID",did);
if (debug) fprintf(stderr,"SNADID=%s\n",did);
if (sid) {
pbx_builtin_setvar_helper(chan,"SNASID",sid);
if (debug) fprintf(stderr,"SNASID=%s\n",sid);
}
if (len) {
buffer[len]=0;
pbx_builtin_setvar_helper(chan,"SDNALOCATION",(char*)buffer);
if (debug) fprintf(stderr,"SNALOCATION=%s\n",buffer);
}
return 0;
}
static int unload_module(void)
{
int res;
ast_cli_unregister_multiple(cli_sdnalookup, ARRAY_LEN(cli_sdnalookup));
res = ast_unregister_application(sdnalookup_app);
return res;
}
static int load_module(void)
{
batman_peerfile=NULL;
ast_cli_register_multiple(cli_sdnalookup, ARRAY_LEN(cli_sdnalookup));
return ast_register_application(sdnalookup_app, sdnalookup_exec, sdnalookup_synopsis, sdnalookup_descrip);
}
#define AST_MODULE "app_serval"
AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Serval Mesh Telephony Adapter and Serval DNA Resolver");