基于eXosip2实现的客户端和服务端

一、源码下载

Index of /download/exosip2/,这里选择libeXosip2-3.5.0.tar.gz和libosip2-3.5.0.tar.gz

二、osip2库编译

cd libosip2-3.5.0/
./configure --enable-static
make
make install

三、eXosip2库编译


cd libeXosip2-3.5.0/
./configure --enable-static
make 
make install

四、eXosip2客户端


#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;


#define LISTEN_ADDR ("192.168.50.57")
#define UACPORT ("5061")
#define UACPORTINT (5061)
#define UACCODE ("100110000201000000")
#define UACPWD ("12345")
#define UAS_ADDR ("192.168.50.57")
#define UAS_PORT ("5060")
#define EXPIS 300

static int iCurrentStatus;

static int iHandle = -1;


class CSipFromToHeader
{
public:
 CSipFromToHeader()
 {
 }
 ~CSipFromToHeader()
 {
 }
 void SetHeader(string addrCod, string addrI, string addrPor)
 {
	 addrCode = addrCod;
	 addrIp = addrI;
	 addrPort = addrPor;
 }
 string GetFormatHeader()
 {
	 std::stringstream stream;
	 stream << "sip: " << addrCode << "@" << addrIp << ":" << addrPort;
	 return stream.str();
 }

 string GetCode()
 {
	 std::stringstream stream;
	 stream << addrCode;
	 return stream.str();
 }

 string GetAddr()
 {
	 std::stringstream stream;
	 stream << addrIp;
	 return stream.str();
 }

 string GetPort()
 {
	 std::stringstream stream;
	 stream << addrPort;
	 return stream.str();
 }

private:
 string addrCode;
 string addrIp;
 string addrPort;
};

class CContractHeader: public CSipFromToHeader
{
public:
 CContractHeader()
 {
 }
 ~CContractHeader()
 {
 }
 void SetContractHeader(string addrCod, string addrI, string addrPor)
 {
	 SetHeader(addrCod, addrI, addrPor);
 }
 string GetContractFormatHeader()
 {

	 std::stringstream stream;
	 stream << "";
	 return stream.str();
 }
};


int SendRegister(int& registerId, CSipFromToHeader &from, CSipFromToHeader &to,
	 CContractHeader &contact, const string& userName, const string& pwd,
	 const int expires, int iType)
{
 cout << "=============================================" << endl;
 if (iType == 0)
 {
	 cout << "注册请求信息:" << endl;
 }
 else if (iType == 1)
 {
	 cout << "刷新注册信息:" << endl;
 }
 else
 {
	 cout << "注销信息:" << endl;
 }
 cout << "registerId " << registerId << endl;
 cout << "from " << from.GetFormatHeader() << endl;
 cout << "to " << to.GetFormatHeader() << endl;
 cout << "contact" << contact.GetContractFormatHeader() << endl;
 cout << "userName" << userName << endl;
 cout << "pwd" << pwd << endl;
 cout << "expires" << expires << endl;
 cout << "=============================================" << endl;

 static osip_message_t *regMsg = 0;
 int ret;

 ::eXosip_add_authentication_info(userName.c_str(), userName.c_str(),
		 pwd.c_str(), "MD5", NULL);
 eXosip_lock();
 if (0 == registerId)
 {
	 registerId = ::eXosip_register_build_initial_register(
			 from.GetFormatHeader().c_str(), to.GetFormatHeader().c_str(),
			 contact.GetContractFormatHeader().c_str(), expires, ®Msg);
	 if (registerId <= 0)
	 {
		 return -1;
	 }
 }
 else
 {
	 ret = ::eXosip_register_build_register(registerId, expires, ®Msg);
	 if (ret != OSIP_SUCCESS)
	 {
		 return ret;
	 }
	 if (expires == 0)
	 {
		 osip_contact_t *contact = NULL;
		 char tmp[128];

		 osip_message_get_contact(regMsg, 0, &contact);
		 {
			 sprintf(tmp, ";expires=0",
					 contact->url->username, contact->url->host,
					 contact->url->port);
		 }
		 //osip_contact_free(contact);
		 //reset contact header
		 osip_list_remove(®Msg->contacts, 0);
		 osip_message_set_contact(regMsg, tmp);
		 osip_message_set_header(regMsg, "Logout-Reason", "logout");
	 }
 }
 ret = ::eXosip_register_send_register(registerId, regMsg);
 if (ret != OSIP_SUCCESS)
 {
	 registerId = 0;
 }eXosip_unlock();

 return ret;
}

//注册
void Register()
{
 if (iCurrentStatus == 1)
 {
	 cout << "当前已经注册" << endl;
	 return;
 }
 CSipFromToHeader stFrom;
 stFrom.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
 CSipFromToHeader stTo;
 stTo.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
 CContractHeader stContract;
 stContract.SetContractHeader(UACCODE, LISTEN_ADDR, UACPORT);
 //发送注册信息
 int registerId = 0;
 if (0 > SendRegister(registerId, stFrom, stTo, stContract, UACCODE, UACPWD,
		 3000, 0))
 {
	 cout << "发送注册失败" << endl;
	 return;
 }
 iCurrentStatus = 1;
 iHandle = registerId;
}
//刷新注册
void RefreshRegister()
{
 if (iCurrentStatus == 0)
 {
	 cout << "当前未注册,不允许刷新" << endl;
	 return;
 }
 CSipFromToHeader stFrom;
 stFrom.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
 CSipFromToHeader stTo;
 stTo.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
 CContractHeader stContract;
 stContract.SetContractHeader(UACCODE, LISTEN_ADDR, UACPORT);
 //发送注册信息
 if (0 > SendRegister(iHandle, stFrom, stTo, stContract, UACCODE, UACPWD,
		 3000, 1))
 {
	 cout << "发送刷新注册失败" << endl;
	 return;
 }
}
//注销
void UnRegister()
{
 if (iCurrentStatus == 0)
 {
	 cout << "当前未注册,不允许注销" << endl;
	 return;
 }
 CSipFromToHeader stFrom;
 stFrom.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
 CSipFromToHeader stTo;
 stTo.SetHeader(UACCODE, UAS_ADDR, UAS_PORT);
 CContractHeader stContract;
 stContract.SetContractHeader(UACCODE, LISTEN_ADDR, UACPORT);
 //发送注册信息
269     if (0 > SendRegister( iHandle, stFrom, stTo, stContract, UACCODE, UACPWD,
		 0, 2))
 {
	 cout << "发送注销失败" << endl;
	 return;
 }
 iCurrentStatus = 0;
 iHandle = -1;
}
static void help()
{
 const char
		 *b =
 "-------------------------------------------------------------------------------\n"
 "SIP Library test process - uac v 1.0 (June 13, 2014)\n\n"
 "SIP UAC端 注册,刷新注册,注销实现\n\n"
 "Author: 程序人生\n\n"
 "博客地址:http://blog.csdn.net/hiwubihe QQ:1269122125\n\n"
 "-------------------------------------------------------------------------------\n"
 "\n"
 "              0:Register\n"
 "              1:RefreshRegister\n"
 "              2:UnRegister\n"
 "              3:clear scream\n"
 "              4:exit\n"
 "-------------------------------------------------------------------------------\n"
 "\n";
 fprintf(stderr, b, strlen(b));
 cout << "please select method :";
}
//服务处理线程
void *serverHandle(void *pUser)
{
 sleep(3);
 help();
 char ch = getchar();
 getchar();
 while (1)
 {
	 switch (ch)
	 {
	 case '0':
		 //注册
		 Register();
		 break;
	 case '1':
		 //刷新注册
		 RefreshRegister();
		 break;
	 case '2':
		 //注销
		 UnRegister();
		 break;
	 case '3':
		 if (system("clear") < 0)
		 {
			 cout << "clear scream error" << endl;
			 exit(1);
		 }
		 break;
	 case '4':
		 cout << "exit sipserver......" << endl;
		 getchar();
		 exit(0);
	 default:
		 cout << "select error" << endl;
		 break;
	 }
	 cout << "press any key to continue......" << endl;
	 getchar();
	 help();
	 ch = getchar();
	 getchar();
 }
 return NULL;
}

//事件处理线程
void *eventHandle(void *pUser)
{
 eXosip_event_t* osipEventPtr = (eXosip_event_t*) pUser;
 switch (osipEventPtr->type)
 {
 //需要继续验证REGISTER是什么类型
 case EXOSIP_REGISTRATION_SUCCESS:
 case EXOSIP_REGISTRATION_FAILURE:
 {
	 cout<<"收到状态码:"<response->status_code<<"报文"<response->status_code == 401)
	 {
		 cout<<"发送鉴权报文"<response->status_code == 200)
	 {
		 cout<<"接收成功"<type << endl;
	 break;
 }
 eXosip_event_free(osipEventPtr);
 return NULL;
}

int main()
{
 iCurrentStatus = 0;
 //库处理结果
 int result = OSIP_SUCCESS;
 //初始化库
 if (OSIP_SUCCESS != (result = eXosip_init()))
 {
	 printf("eXosip_init failure.\n");
	 return 1;
 }
 cout << "eXosip_init success." << endl;
 eXosip_set_user_agent(NULL);
 //监听
 if (OSIP_SUCCESS != eXosip_listen_addr(IPPROTO_UDP, NULL, UACPORTINT,
		 AF_INET, 0))
 {
	 printf("eXosip_listen_addr failure.\n");
	 return 1;
 }
 //设置监听网卡
 if (OSIP_SUCCESS != eXosip_set_option(
 EXOSIP_OPT_SET_IPV4_FOR_GATEWAY,
		 LISTEN_ADDR))
 {
	 return -1;
 }
 //开启服务线程
 pthread_t pthser;
 if (0 != pthread_create(&pthser, NULL, serverHandle, NULL))
 {
	 printf("创建主服务失败\n");
	 return -1;
 }
 //事件用于等待
 eXosip_event_t* osipEventPtr = NULL;
 //开启事件循环
 while (true)
 {
	 //等待事件 0的单位是秒,500是毫秒
	 osipEventPtr = ::eXosip_event_wait(0, 200);
	 //处理eXosip库默认处理
	 {
		 usleep(500 * 1000);
		 eXosip_lock();
		 //一般处理401/407采用库默认处理
		 eXosip_default_action(osipEventPtr);
		 eXosip_unlock();
	 }
	 //事件空继续等待
	 if (NULL == osipEventPtr)
	 {
		 continue;
	 }
	 //开启线程处理事件并在事件处理完毕将事件指针释放
	 pthread_t pth;
	 if (0 != pthread_create(&pth, NULL, eventHandle, (void*) osipEventPtr))
	 {
		 printf("创建线程处理事件失败\n");
		 continue;
	 }
	 osipEventPtr = NULL;
 }
}

  g++  test_cli.cpp -o test_cli -I/usr/local/include -L/usr/local/lib -losipparser2 -losip2 -lpthread -leXosip2

四、eXosip2服务端 

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

#define LISTEN_ADDR ("192.168.50.57")
#define UASPORT (5060)


//该系数是由UAS维护的,UAS在接收到UAC的未鉴权报文后,给UAC回复401,在该报文中必须要带相关认证系数和认证方法
//UAS赋值的认证随机数
#define NONCE "9bd055"
//UAS默认加密算法
#define ALGORITHTHM "MD5"

eXosip_t *m_exosip_t;
//SIP From头部
class CSipFromHeader
{
public:
    CSipFromHeader()
    {
    }
    ~CSipFromHeader()
    {
    }
    void SetHeader(string addrCod, string addrI, string addrPor)
    {
        addrCode = addrCod;
        addrIp = addrI;
        addrPort = addrPor;
    }
    string GetFormatHeader()
    {
        std::stringstream stream;
        stream << "";
        return stream.str();
    }
    //主机名称
    string GetRealName()
    {
        std::stringstream stream;
        stream << addrIp;
        return stream.str();
    }
private:
    string addrCode;
    string addrIp;
    string addrPort;
};

//SIP Contract头部
class CContractHeader: public CSipFromHeader
{
public:
    CContractHeader()
    {
    }
    ~CContractHeader()
    {
    }
    void SetContractHeader(string addrCod, string addrI, string addrPor,
            int expire)
    {
        SetHeader(addrCod, addrI, addrPor);
        expires = expire;
    }
    string GetContractFormatHeader(bool bExpires)
    {
        if (!bExpires)
        {
            return GetFormatHeader();
        }
        else
        {
            string sTmp = GetFormatHeader();
            std::stringstream stream;
            stream << ";" << "expires=" << expires;
            sTmp += stream.str();
            return sTmp;
        }

    }
private:
    int expires;
};

struct SipContextInfo
{
    //Sip层返回的请求的标志 响应时返回即可
    int sipRequestId;
    //维护一次注册
    string callId;
    //消息所属的功能方法名字符串
    string method;
    //地址编码@域名或IP地址:连接端口,例如sip:[email protected]:5060
    CSipFromHeader from;
    //地址编码@域名或IP地址:连接端口,例如sip:[email protected]:5060
    CSipFromHeader proxy;
    //地址编码@域名或IP地址:连接端口,例如sip:[email protected]:5060
    CContractHeader contact;
    //消息内容,一般为DDCP消息体XML文档,或者具体协议帧要求的其他字符串文本
    string content;
    //响应状态信息
    string status;
    //超时,时间单位为秒
    int expires;
};

struct SipAuthInfo
{
    //平台主机名
    string digestRealm;
    //平台提供的随机数
    string nonce;
    //用户名
    string userName;
    //密码
    string response;
    //“sip:平台地址”,不需要uac赋值
    string uri;
    //加密算法MD5
    string algorithm;
};

struct sipRegisterInfo
{
    SipContextInfo baseInfo;
    SipAuthInfo authInfo;
    bool isAuthNull;
};

void parserRegisterInfo(osip_message_t*request, int iReqId,
        sipRegisterInfo ®Info)
{
    std::stringstream stream;
    regInfo.baseInfo.method = request->sip_method;
    regInfo.baseInfo.from.SetHeader(request->from->url->username,
            request->from->url->host, request->from->url->port);
    regInfo.baseInfo.proxy.SetHeader(request->to->url->username,
            request->to->url->host, request->to->url->port);
    //获取expires
    osip_header_t* header = NULL;
    {
        osip_message_header_get_byname(request, "expires",
                0, &header);
        if (NULL != header && NULL != header->hvalue)
        {
            regInfo.baseInfo.expires = atoi(header->hvalue);
        }
    }
    //contact字段
    osip_contact_t* contact = NULL;
    osip_message_get_contact(request, 0, &contact);
    if (NULL != contact)
    {
        regInfo.baseInfo.contact.SetContractHeader(contact->url->username,
                contact->url->host, contact->url->port,
                regInfo.baseInfo.expires);
    }
    //注册返回 由发送方维护的请求ID 接收方接收后原样返回即可
    regInfo.baseInfo.sipRequestId = iReqId;
    //CALL_ID
    {
        stream.str("");
        stream << request->call_id->number;
        regInfo.baseInfo.callId = stream.str();
    }
    //解析content消息
    osip_body_t * body = NULL;
    osip_message_get_body(request, 0, &body);
    if (body != NULL)
    {
        stream.str("");
        stream << body->body;
        regInfo.baseInfo.content = stream.str();
    }
    //鉴权信息
    osip_authorization_t* authentication = NULL;
    {
        osip_message_get_authorization(request, 0, &authentication);
        if (NULL == authentication)
        {
            regInfo.isAuthNull = true;
        }
        else
        {
            regInfo.isAuthNull = false;
            stream.str("");
            stream << authentication->username;
            regInfo.authInfo.userName = stream.str();
            stream.str("");
            stream << authentication->algorithm;
            regInfo.authInfo.algorithm = stream.str();
            stream.str("");
            stream << authentication->realm;
            regInfo.authInfo.digestRealm = stream.str();
            stream.str("");
            stream << authentication->nonce;
            regInfo.authInfo.nonce = stream.str();
            stream.str("");
            stream << authentication->response;
            regInfo.authInfo.response = stream.str();
            stream.str("");
            stream << authentication->uri;
            regInfo.authInfo.uri = stream.str();
        }
    }
    authentication = NULL;
}

//打印接收到的响应报文
void printRegisterPkt( sipRegisterInfo&info)
{
    cout<<"接收到报文:"<request, osipEvent->tid, regInfo);
    //打印报文
    printRegisterPkt(regInfo);
    //发送应答报文
    sendRegisterAnswer(regInfo);

}

int main()
{

    int result = OSIP_SUCCESS;
	m_exosip_t = eXosip_malloc();
    // init exosip.
    if (OSIP_SUCCESS != (result = eXosip_init(m_exosip_t)))
    {
        printf("eXosip_init failure.\n");
        return 1;
    }
    cout << "eXosip_init success." << endl;
    //
    //        if (null_ptr != this->receiveSipMessageCallback || null_ptr
    //                != this->sendSipMessageCallback)
    //        {
    //            if (OSIP_SUCCESS != (result = ::eXosip_set_cbsip_message(
    //                    &Sip::MessageCallback)))
    //            {
    //                return;
    //            }
    //        }
    eXosip_set_user_agent(m_exosip_t,NULL);

    if (OSIP_SUCCESS != eXosip_listen_addr(m_exosip_t, IPPROTO_UDP, NULL, UASPORT, AF_INET,
            0))
    {
        printf("eXosip_listen_addr failure.\n");
        return 1;
    }

    if (OSIP_SUCCESS != eXosip_set_option(m_exosip_t,
    EXOSIP_OPT_SET_IPV4_FOR_GATEWAY,
            LISTEN_ADDR))
    {
        return -1;
    }
    //开启循环消息,实际应用中可以开启多线程同时接收信号
    eXosip_event_t* osipEventPtr = NULL;

    while (true)
    {
        // Wait the osip event.
        osipEventPtr = ::eXosip_event_wait(m_exosip_t, 0, 200);// 0的单位是秒,500是毫秒
        // If get nothing osip event,then continue the loop.
        if (NULL == osipEventPtr)
        {
            continue;
        }
        // 事件处理

        switch (osipEventPtr->type)
        {

        //需要继续验证REGISTER是什么类型
        //case EXOSIP_REGISTRATION_NEW:
            //OnRegister(osipEventPtr);
            //break;
        case EXOSIP_MESSAGE_NEW:
        {
            if (!strncmp(osipEventPtr->request->sip_method, "REGISTER",
                    strlen("REGISTER")))
            {
                OnRegister(osipEventPtr);
            }
            else if (!strncmp(osipEventPtr->request->sip_method, "MESSAGE",
                    strlen("MESSAGE")))
            {
                //
            }
        }
            break;
        default:
            cout
                    << "The sip event type that not be precessed.the event "
                            "type is : "
                    << osipEventPtr->type;
            break;
        }
        //ProcessSipEvent(this->osipEventPtrParam);
        eXosip_event_free(osipEventPtr);
        osipEventPtr = NULL;
    }

    return 0;
}

g++ test_srv.cpp -o test_srv -I/usr/local/include -L/usr/local/lib -losipparser2 -losip2 -lpthread -leXosip2 

你可能感兴趣的:(sip,exosip)