Asterisk Summary - 3

前面两小节讲的都是关于asterisk server,接下来就讲一下asterisk client。

开发asterisk client的话,你可以选择用c/c++ 或者是 java。目前我所用的就是java,不过我首先讲一讲c/c++开发asterisk client的简单例子。

 

iaxclient

 

你可以到这里去下载最新的libclient: http://www.sourceforgecn.net/Projects/i/ia/iaxclient/

我下载的是iaxclient-2.1beta3 和 iaxclient-2.1beta3-binary-win32,

其中iaxclient-2.1beta3 是src文件和一些sample, iaxclient-2.1beta3-binary-win32将包含libiaxclient.dll,libiaxclient.lib和头文件iaxclient.h

 

为了使用里面提供的sample,首先应该设置的的project。在vc6中

tools->options->directories 的include 和 lib 路径中加入你刚下载解压后所在的位置。

打开iaxclient-2.1beta3/simpleclient/testcall/testcall.dsw

project->settings->link tab中的library module 中添加 libiaxclient.lib   -- 导入符号表

 

编译运行就可以啦!

 

运行后你会发现你并不能做任何事,包括打电话和接电话。原来直接不带运行的话是这样的,如果带参数的话将打电话出去。结合上两节所配置的asterisk (iax.conf/sip.conf/extensions.conf)这个打电话的参数应该是 111001:xxxxx@xxx.xxx.xxx.xxx/35693480

 

111001   ->  iax.conf 中的section name,也就是iax 客户端得用户名

xxxxx      ->   iax.conf 中[111001] 注册的密码

xxx.xxx.xxx.xxx   -> 该电话所要连接的asterisk server,也就是你之前配置的asterisk server ip地址

35693480  -> 你所拨打出去的电话号码。

 

这整个运行过程如下:

1. testcall 在asterisk server中注册登陆,identity by your user name and pwd

2. ready to打电话35693480

3. asterisk 通过iax.conf的设置进入extensions.conf的from_iax dialplan

4. 执行该dial plan,通过sip将该电话拨出去 Dial(SIP/${EXTEN}@${2bAcc},30,r)

5. 电话应答或结束

 

想获得更多的帮助信息,请参考以下网站:

http://iaxclient.sourceforge.net/doc/html/

 

以下给出我改写后的testcall 原代码:运行该程序可以在command line 中输入.
./testcall  111001:xxxx@xxx.xxx.xxx.xxx/your_phone_num

嘿,你的电话已经响起来啦!^_^

 


/* testcall.c
 * testcall: make a single test call with IAXCLIENT
 *
 * IAX Support for talking to Asterisk and other Gnophone clients
 *
 * Copyright (C) 1999, Linux Support Services, Inc.
 *
 * Mark Spencer <markster@linux-support.net>
 *
 * This program is free software, distributed under the terms of
 * the GNU Lesser (Library) General Public License
 */

/* #define	PRINTCHUCK //* enable this to indicate chucked incomming packets *// */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <signal.h>

#include "iaxclient.h"

#define LEVEL_INCREMENT	0.10f

/* static int answered_call; */
static char *output_filename = NULL;
static char *username = NULL;
static char *password = NULL;
static char *host = NULL;
int do_levels = 0;
int intercom = 0;
int initialized = 0;
int reg_id = 0;

/* routine called at exit to shutdown audio I/O and close nicely.
NOTE: If all this isnt done, the system doesnt not handle this
cleanly and has to be rebooted. What a pile of doo doo!! */
void killem(void)
{
	if (reg_id){
		   iaxc_unregister(reg_id);
	}
	if (initialized)
		iaxc_shutdown();
	return;
}

void signal_handler(int signum)
{
	if ( signum == SIGTERM || signum == SIGINT ) 
	{
		killem();
		exit(0);
	}
}

void fatal_error(char *err) {
	killem();
	fprintf(stderr, "FATAL ERROR: %s/n", err);
	exit(1);
}

void mysleep(void)
{
	iaxc_millisleep(10);
}

int state_event_callback(struct iaxc_ev_call_state call){
	printf("receive call state event: 0X%p/n",call.state);
    if((call.state & IAXC_CALL_STATE_RINGING))
    {
		if(call.state & IAXC_CALL_STATE_OUTGOING)
		{
			printf("Make outgoing call .../n");
			printf("Remote:[%s][%s] Local:[%s][%s]/n",
				call.remote,call.remote_name,call.local,call.local_context);
		}
		else
		{
			printf("Receiving Incoming Call Request .../n"); 
			printf("Remote:[%s][%s] Local:[%s][%s]/n",
				call.remote,call.remote_name,call.local,call.local_context);
			if ( intercom )
			{
				printf("Intercom mode, answer automatically/n");
				return iaxc_select_call(call.callNo);
			}
		}
    }
	else if(call.state & IAXC_CALL_STATE_COMPLETE   )
	{
		if(call.state & IAXC_CALL_STATE_OUTGOING )
			printf("IAX Out conn - Remote:[%s][%s] Local:[%s][%s]/n",
			call.remote,call.remote_name,call.local,call.local_context);
		else
			printf("IAX In conn - Remote:[%s][%s] Local:[%s][%s]/n",
			call.remote,call.remote_name,call.local,call.local_context);
	}
    return 0;
}
int levels_callback(float input, float output) {
    if(do_levels) fprintf(stderr, "IN: %f OUT: %f/n", input, output);
    return 0;
}

int netstat_callback(struct iaxc_ev_netstats n) {
    static int i;
    if(i++%25 == 0)
	fprintf(stderr, "RTT/t"
	    "Rjit/tRlos%%/tRlosC/tRpkts/tRdel/tRdrop/tRooo/t"
	    "Ljit/tLlos%%/tLlosC/tLpkts/tLdel/tLdrop/tLooo/n"
	    );

    fprintf(stderr, "%d/t"
	  "%d/t%d/t%d/t%d/t%d/t%d/t%d/t"
	  "%d/t%d/t%d/t%d/t%d/t%d/t%d/n",

	    n.rtt,

	    n.remote.jitter,
	    n.remote.losspct,
	    n.remote.losscnt,
	    n.remote.packets,
	    n.remote.delay,
	    n.remote.dropped,
	    n.remote.ooo,

	    n.local.jitter,
	    n.local.losspct,
	    n.local.losscnt,
	    n.local.packets,
	    n.local.delay,
	    n.local.dropped,
	    n.local.ooo
    );

    return 0;
}

int reg_state_call_back(struct iaxc_ev_registration reg)
{
	printf("/nReg event id:[%d]  reply:[0X%p]  msg:[%d]/n",reg.id,reg.reply,reg.msgcount);
	return 0;
}

int iaxc_callback(iaxc_event e)
{
    switch(e.type) {
        case IAXC_EVENT_LEVELS:
            return levels_callback(e.ev.levels.input, e.ev.levels.output);
        case IAXC_EVENT_NETSTAT:
            return netstat_callback(e.ev.netstats);
        case IAXC_EVENT_TEXT:
            return 0; // don't handle
        case IAXC_EVENT_STATE:
            return state_event_callback(e.ev.call);
		case IAXC_EVENT_REGISTRATION:
			return reg_state_call_back(e.ev.reg);
        default:
            return 0;  // not handled
    }
}

void list_devices()
{
    struct iaxc_audio_device *devs;
    int nDevs, input, output, ring;
    int i;

    iaxc_audio_devices_get(&devs,&nDevs, &input, &output, &ring);
    for(i=0;i<nDevs;i++) {
	fprintf(stderr, "DEVICE ID=%d NAME=%s CAPS=%lx/n", devs[i].devID, devs[i].name, devs[i].capabilities);
    }
}

void usage()
{ 
    fprintf(stderr, "Usage: testcall [-?] [-v] [-i] [-s SILENCE_THRESHOLD] [-u USERNAME -p PASSWORD -h HOST] dest/n"
		    "     dest  -  The entity to call in the format of/n"
			"              [user[:password]]@peer[:portno][/exten[@context]]/n"
		   );
    exit(1);
}

int main(int argc, char **argv)
{
	FILE *f;
	char c;
	int i;
	char dest[256],tmpbuff[256];
	float silence_threshold = -99.0f;
	float level;

	f = stdout;
	memset(dest,0x00,sizeof(dest));
	memset(tmpbuff,0x00,sizeof(tmpbuff));

	for(i=1;i<argc;i++)
	{
	   if(argv[i][0] == '-') 
	   {
	      switch(tolower(argv[i][1]))
	      {
		case '?':
		  usage();
		  break;
		case 'v':
		  do_levels = 1;
		  break;
		case 'i':
		  intercom = 1;
		  break;
		case 's':	//silence threshold
		  if(i+1 >= argc) usage();
		  silence_threshold = (float)atof(argv[++i]);
		  break;
		case 'u':	//username
		  if(i+1 >= argc) usage();
		  username = argv[++i];
		  break;
		case 'p':	//password
		  if(i+1 >= argc) usage();
		  password = argv[++i];
		  break;
		case 'h':	//host
		  if(i+1 >= argc) usage();
		  host = argv[++i];
		  break;

		default:
		  usage();
	      }
	    } else {
	      strcpy(dest,argv[i]);
	    }
	}


	printf("settings: /n");
	printf("/tsilence threshold: %f/n", silence_threshold);
	printf("/tlevel output: %s/n", do_levels ? "on" : "off");

	/* activate the exit handler */
	atexit(killem);
	
	/* install signal handler to catch CRTL-Cs */
	signal(SIGINT, signal_handler);
	signal(SIGTERM, signal_handler);
	
	if ( iaxc_initialize(1) ) // init iax client lib
		fatal_error("cannot initialize iaxclient!");
	initialized = 1;

//	iaxc_set_formats(IAXC_FORMAT_SPEEX,IAXC_FORMAT_ULAW|IAXC_FORMAT_GSM|IAXC_FORMAT_SPEEX);
//	iaxc_set_formats(IAXC_FORMAT_SPEEX,IAXC_FORMAT_SPEEX);
	iaxc_set_formats(IAXC_FORMAT_GSM,IAXC_FORMAT_GSM);
	//iaxc_set_formats(IAXC_FORMAT_ULAW,IAXC_FORMAT_ULAW);
	//iaxc_set_formats(IAXC_FORMAT_ULAW,IAXC_FORMAT_ILBC|IAXC_FORMAT_ULAW|IAXC_FORMAT_GSM|IAXC_FORMAT_SPEEX);

	// The threshold value in dB. A value of 0.0f effectively mutes audio input.  
	iaxc_set_silence_threshold(silence_threshold);

	list_devices();

	//if(do_levels)
	  iaxc_set_event_callback(iaxc_callback); 


	fprintf(f, "/n/
	    TestCall accept some keyboard input while it's running./n/
	    You must hit 'enter' for your keypresses to be recognized,/n/
	    although you can type more than one key on a line/n/
/n/
	    q: hangup and exit./n/
	    a: answer incoming call/n/
	    d: dial out number/n/
	    t: terminate call/n/
	    0-9 * or #: dial those DTMF digits./n/
	    g: increase input level/n/
	    b: decrease input level/n/
	    h: increase output level/n/
	    n: decrease output level/n/
	    Enter: display current audio levels/n");
	if(strlen(dest)) {
	    fprintf(f, "Calling %s/n", dest);

		//dest  The entity to call in the format of 
		//[user[:password]]@peer[:portno][/exten[@context]] 
	    iaxc_call(dest);	
		
	}

	iaxc_start_processing_thread();

	if (username && password && host)
	{
		reg_id = iaxc_register(username, password, host);
		
		if(reg_id == -1)
			fprintf(f,"Reg fail: %s %s %s/n",username, password, host);
		else
			fprintf(f,"Reg OK ID:%d/n",reg_id);
	}
/*
Registers the IAXClient instance with an IAX server.
Parameters:
 user  The username to register as  
 pass  The password to register with  
 host  The address of the host/peer to register with 

Returns:
The registration id number upon success; -1 otherwise. 
*/

	printf("ready for keyboard input/n");
	
	if(output_filename) {
	    for(;;)
	      iaxc_millisleep(10*1000);
	}
	while((c = getc(stdin))) 
	{
	    switch (tolower(c)) 
	    {
	    case 'a':
			printf("Answering call 0/n");
			iaxc_select_call(0);
	      	break;	
	    case 'g':
	    	level = iaxc_input_level_get();
	    	level += LEVEL_INCREMENT;
	    	if ( level > 1.00 ) level = 1.00;
	    	printf("Increasing input level to %f/n", level);
	    	iaxc_input_level_set(level);
	    	break;
	    case 'b':
	    	level = iaxc_input_level_get();
	    	level -= LEVEL_INCREMENT;
	    	if ( level < 0 ) level = 0.00;
	    	printf("Decreasing input level to %f/n", level);
	    	iaxc_input_level_set(level);
	    	break;
		case 'd':
	    	//dial number
			printf("input phone number: ");
			fflush(stdin);
			fgets(dest,sizeof(dest),stdin);
			
			if(dest[strlen(dest)-1] == '/n')
				dest[strlen(dest)-1] = '/0';
			if(dest[strlen(dest)-1] == '/r')
				dest[strlen(dest)-1] = '/0';
			printf("call - [%s]",dest);
			if(strlen(dest))
			{
				if(username && password && host)
				{
					sprintf(tmpbuff,"%s:%s@%s/%s",username,password,host,dest);
					strcpy(dest,tmpbuff);
				}
				iaxc_call(dest);
			}
			
	    	break;
	    case 'h': 
	    	level = iaxc_output_level_get();
	    	level += LEVEL_INCREMENT;
	    	if ( level > 1.00 ) level = 1.00;
	    	printf("Increasing output level to %f/n", level);
	    	iaxc_output_level_set(level);
	    	break;
	    case 'n':
	    	level = iaxc_output_level_get();
	    	level -= LEVEL_INCREMENT;
	    	if ( level < 0 ) level = 0.00;
	    	printf("Decreasing output level to %f/n", level);
	    	iaxc_output_level_set(level);
	    	break;
	    case 'q':
			printf("Hanging up and exiting/n");
			iaxc_dump_call();
			iaxc_millisleep(1000);
			iaxc_stop_processing_thread();
			exit(0);
	      	break;
		case 't':
			 printf("Terminating call 0/n");
			 iaxc_dump_call();
			 break;
	    case '1': case '2': case '3': case '4': case '5':
	    case '6': case '7': case '8': case '9': case '0':
	    case '#': case '*':
			printf ("sending %c/n", c);
			iaxc_send_dtmf(c);
	      	break;
	    case '/r':
	    	break;
	    case '/n':
	    	printf("Input level = %f -- Output level = %f/n", iaxc_input_level_get(), iaxc_output_level_get());
	    	break;
	    default:
	    	printf("Unknown command '%c'/n", c);
	    }
	}

	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值