PJSIP交叉编译

 

 

1、安装一些必要的依赖库
       apt-get install build-essential git-core checkinstall yasm texi2html libvorbis-dev libx11-dev libvpx-dev libxfixes-dev zlib1g-dev
       apt-get install pkg-config netcat libncurses5-dev
       apt-get install nasm libx264-dev
       apt-get install libv4l-dev
       apt-get install libasound2-dev
       apt-get install libsdl2-dev
       apt-get install libxext-devhtml

2、交叉编译asoundlinux

       先下载alsa-lib-1.2.1.2.tar.bz2解压缩。c++

      而后./configure CC=arm-linux-gnueabihf-gcc --host=arm-linux-gnueabihf git

              makeweb

              make installide

3、编译pjsip函数

        ./configure CC=arm-linux-gnueabihf-gcc --host=arm-linux-gnueabihf  --disable-libwebrtc --disable-ssl --disable-openh264 --disable-libyuv --enable-static --prefix=/system/binoop

        makeui

       make installes5

 

4、使用pjsip静态库编译一个demo

       makefile以下

        

OBJ= main 

CC= arm-linux-gnueabihf-gcc 

CFLAGS= -Wall -O -O2 -DPJ_IS_BIG_ENDIAN=0 -DPJ_IS_LITTLE_ENDIAN=1
VPATH= ./
#LIBS= -lpthread -lm 

INCLUDE= -I$(VPATH)include
LIB_DIR= -L$(VPATH)lib 

LIB= -lpjsua2-arm-unknown-linux-gnueabihf -lstdc++ -lpjsua-arm-unknown-linux-gnueabihf -lpjsip-ua-arm-unknown-linux-gnueabihf -lpjsip-simple-arm-unknown-linux-gnueabihf -lpjsip-arm-unknown-linux-gnueabihf -lpjmedia-codec-arm-unknown-linux-gnueabihf -lpjmedia-arm-unknown-linux-gnueabihf -lpjmedia-videodev-arm-unknown-linux-gnueabihf -lpjmedia-audiodev-arm-unknown-linux-gnueabihf -lpjmedia-arm-unknown-linux-gnueabihf -lpjnath-arm-unknown-linux-gnueabihf -lpjlib-util-arm-unknown-linux-gnueabihf  -lsrtp-arm-unknown-linux-gnueabihf -lresample-arm-unknown-linux-gnueabihf -lgsmcodec-arm-unknown-linux-gnueabihf -lspeex-arm-unknown-linux-gnueabihf -lilbccodec-arm-unknown-linux-gnueabihf -lg7221codec-arm-unknown-linux-gnueabihf  -lpj-arm-unknown-linux-gnueabihf -lrt -lpthread  -lasound -ldl -lm

$(OBJ):
    $(CC) -o main.o main.c -Wall $(INCLUDE) $(LIB_DIR) $(LIB) -static 

clean:
    rm -f main 
#include "pj/log.h"
#include "pjlib.h"
#include "pjlib-util.h"
#include "pjnath.h"
#include "pjmedia.h"
#include "pjsip.h"
#include "pjsip_simple.h"
#include "pjsip_ua.h"
#include "pjsua-lib/pjsua.h"
#include "pjmedia-codec.h"

#define THIS_FILE "#### windaka_log"
#define SIP_DOMAIN "10.10.5.250"
#define SIP_USER   "01010011"
#define SIP_PASSWD "0000"

#define current_acc	pjsua_acc_get_default()

/*####获取全部声卡设备的结构####*/
typedef struct pjmedia_aud_sount_cnt{
    int devcnt;
    char name[32][32];
    unsigned devid[32];
}pjmedia_aud_sound_cnt;

/*####收到呼叫后的回调函数####*/
static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
			     pjsip_rx_data *rdata)
{
    pjsua_call_info ci;

    PJ_UNUSED_ARG(acc_id);
    PJ_UNUSED_ARG(rdata);

    /*####获取主叫信息####*/
    pjsua_call_get_info(call_id, &ci);

	/*####打印出主叫的URL####*/
    PJ_LOG(3,(THIS_FILE, "#### ---->Incoming call from %.*s!!",
			 (int)ci.remote_info.slen,
			 ci.remote_info.ptr));

    /*####收到呼叫后的应答函数接口####*/
    pjsua_call_answer(call_id, 200, NULL, NULL);
}

/* Callback called by the library when call's state has changed */
static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
    pjsua_call_info ci;

    PJ_UNUSED_ARG(e);

    pjsua_call_get_info(call_id, &ci);
    PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s,state=%d,last_status=%d", call_id,
			 (int)ci.state_text.slen,
			 ci.state_text.ptr,ci.state,ci.last_status));
}

/* Callback called by the library when call's media state has changed */
static void on_call_media_state(pjsua_call_id call_id)
{
    pjsua_call_info ci;

    pjsua_call_get_info(call_id, &ci);

    if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
	// When media is active, connect call to sound device.
	pjsua_conf_connect(ci.conf_slot, 0);
	pjsua_conf_connect(0, ci.conf_slot);
    }
}

/*####程序异常退出接口####*/
static void error_exit(const char *title, pj_status_t status)
{
    pjsua_perror(THIS_FILE, title, status);
    pjsua_destroy();
    exit(1);
}

void get_device_sound_name(char *pathName,char *sound_name){
    FILE *fp;
    char tmp[32];

    if(pathName == NULL){
        return ;
    }

    fp = fopen(pathName,"r");
    if(fp == NULL){
        return ;
    }

    memset(tmp,0,sizeof(tmp));
    fread(tmp,1,32,fp);
    strcpy(sound_name,tmp);
    fclose(fp);
    return ;
}

void del_str_line(char *str){
    char *p = str;

    while('\n' != *p){
        p++;
	if(*p =='\0'){
            return ;
	}
    }
    *p = '\0';
    return ;
}

int main(int argc,char *argv[]){
    pjsua_acc_id acc_id;
    pj_status_t status;

    /*####建立pjsua####*/
    status = pjsua_create();
    if (status != PJ_SUCCESS){
		error_exit("Error in pjsua_create()", status);
	}

    /*####初始化pjsua####*/
    {
        pjsua_config cfg;
        pjsua_logging_config log_cfg;

        pjsua_config_default(&cfg);
        cfg.cb.on_incoming_call = &on_incoming_call;
	cfg.cb.on_call_media_state = &on_call_media_state;
	cfg.cb.on_call_state = &on_call_state;

	pjsua_logging_config_default(&log_cfg);
	log_cfg.console_level = 4;

	status = pjsua_init(&cfg, &log_cfg, NULL);
	if (status != PJ_SUCCESS){
	       	error_exit("Error in pjsua_init()", status);
        }
    }

    /*####设置pjsua使用的本地端口####*/
    {
        pjsua_transport_config cfg;

	pjsua_transport_config_default(&cfg);
	/*####本地使用5061端口####*/
	cfg.port = 5060;
	status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL);
	if (status != PJ_SUCCESS){
	    error_exit("Error creating transport", status);
	}
    }

    /* Initialization is done, now start pjsua */
    status = pjsua_start();
    if (status != PJ_SUCCESS){
	error_exit("Error starting pjsua", status);
    }

    /* Register to SIP server by creating SIP account. */
    {
        pjsua_acc_config cfg;

        pjsua_acc_config_default(&cfg);
        int iloop = 0;
        char devName[32];
        unsigned devId = 0;
	static pjmedia_aud_sound_cnt *p = NULL;

	/*####获取系统指定声卡的name####*/
	memset(devName,0,sizeof(devName));
        //get_device_sound_name("/proc/asound/card0/id",devName); 

	/*####获取设备全部的声卡信息####*/
        //printf("#### ---->get_card_calc_dev() \n");
        //p = get_card_calc_dev();
        //printf("#### ---->p->devcnt=[%d]\n",p->devcnt);

#if 0
	char tmp[64];
	memset(tmp,0,sizeof(tmp));
	strcpy(tmp,"default:CARD=");
	strcat(tmp,devName);
        del_str_line(tmp);

	/*####根据指定声卡的name获取声卡的ID####*/
	printf("#### ---->p->devcnt = [%d]\n",p->devcnt);
	for(iloop = 0; iloop < p->devcnt;iloop++){
            printf("#### ---->tmp=[%s],p->name[iloop]=[%s]\n",tmp,p->name[iloop]);
   	    if(strcmp(tmp,p->name[iloop]) == 0){
                devId = p->devid[iloop];
                printf("#### ---->get device [%s],id = [%d]\n",p->name[iloop],devId);
		break;
	    }
	}
	/*####指定设备使用哪一个声卡####*/
	pjsua_set_snd_dev(devId,devId);
#endif
        /*####设置SIP帐号信息####*/
        cfg.vid_out_auto_transmit = PJ_TRUE;
        cfg.id = pj_str("sip:" SIP_USER "@" SIP_DOMAIN);
        cfg.reg_uri = pj_str("sip:" SIP_DOMAIN);
        cfg.cred_count = 1;
        cfg.cred_info[0].realm = pj_str("*");
        cfg.cred_info[0].scheme = pj_str("digest");
        cfg.cred_info[0].username = pj_str(SIP_USER);
        cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
        cfg.cred_info[0].data = pj_str(SIP_PASSWD);

	/*####添加SIP帐号####*/
        status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
        if (status != PJ_SUCCESS){
	    error_exit("Error adding account", status);
	}
    }

    /* Wait until user press "q" to quit. */
    for (;;) {
        char option[10];

        puts("\n'h' to hangup all calls\n'q' to quit\n'm' is call 17001010101\n'r' is register\n");
        if (fgets(option, sizeof(option), stdin) == NULL) {
            puts("EOF while reading stdin, will quit now..");
	    break;
	}

        if(option[0] == 'r'){
            pjsua_acc_set_registration(current_acc,PJ_TRUE);
        }

        if(option[0] == 'm'){
            pj_str_t uri=pj_str("sip:01010301@10.10.5.250");
            status = pjsua_call_make_call(acc_id,&uri,0,NULL,NULL,NULL);
            if(status != PJ_SUCCESS){
                printf("#### make call Error\n");
            }
        }
	if (option[0] == 'q'){
	    break;
	}

	if (option[0] == 'h'){
	    /*####挂断接口####*/
	    pjsua_call_hangup_all();
	}
    }

    /* Destroy pjsua */
    pjsua_destroy();

    return 0;
}