基于eXosip的SIP客户端
来源:互联网 发布:网页代码编写软件 编辑:程序博客网 时间:2024/05/20 00:36
SipContact.h:
#ifndef _SIP_CONTACT_H_#define _SIP_CONTACT_H_#include "SoftPhoneDataDef.h"#include <eXosip2/eXosip.h>class CSipContact{public: CSipContact(void); ~CSipContact(void);public: void Start();private: //注册操作 eXosip_event_type_t Registeration(int nLisPort,int expires);public: //取消注册操作 eXosip_event_type_t UnRegisteration(); //发起呼叫 int Invite(const char* destUserid); //接听 void Answer(); //挂断 void Hold(); //退出 void Exit();private: struct UserMrg m_sUser;//登录用户 int m_nAdTrPort; //音频传输端口 //int nCall_id; //呼叫id //int nDlg_id; //回话id};#endif
SipContact.cpp:
#include "SipContact.h"#include <winsock2.h>#include <osip2/osip_mt.h>#include <osip2/osip.h>#include <osipparser2/osip_message.h>#include <osipparser2/osip_parser.h>#include <osipparser2/osip_md5.h>#include <eXosip2/eX_call.h>#include "jcalls.h"static int m_nCall_id = -1; //呼叫idstatic int m_nDlg_id = -1; //绘话idstatic int m_nt_id = -1; void invite_answer(){ sdp_message_t *remote_sdp = NULL; osip_message_t *answer = NULL; char tmp[4096]; char localip[128]; int pos = 0; //初始化sip if (-1 == m_nt_id) { return; } remote_sdp = eXosip_get_remote_sdp (m_nt_id); eXosip_lock (); //eXosip_call_send_answer (m_nt_id, 180, NULL); int i = eXosip_call_build_answer (m_nt_id, 200, &answer); if (i != 0) { printf ("This request msg is invalid!Cann't response!\n"); eXosip_call_send_answer (m_nt_id, 400, NULL); } else { eXosip_guess_localip (AF_INET, localip, 128); // 获取本地IP //SDP格式 snprintf (tmp, 4096, "v=0\r\n" "o=josua 0 0 IN IP4 %s\r\n"// 用户名、ID、版本、网络类型、地址类型、IP地址 "s=conversation\r\n" "t=0 0\r\n" "a=username:%s\r\n" "a=password:%s\r\n" "m=audio %d RTP/AVP 0 8 101\r\n" // 音频、传输端口、传输类型、格式列表 "a=rtpmap:0 PCMU/8000\r\n" // 以下为具体描述格式列表中的 "a=rtpmap:8 PCMA/8000\r\n" "a=rtpmap:101 telephone-event/8000\r\n" "a=fmtp:101 0-11\r\n", localip,remote_sdp->o_username,remote_sdp->o_addr,2056); osip_message_set_body (answer, tmp, strlen(tmp)); osip_message_set_content_type (answer, "application/sdp"); eXosip_call_send_answer (m_nt_id, 200, answer); printf ("send 200 over!\n"); } eXosip_unlock (); //显示出在sdp消息体中的 attribute 的内容,里面计划存放我们的信息 printf ("the INFO is :\n"); while (!osip_list_eol (&remote_sdp->a_attributes, pos)) { sdp_attribute_t *at; at = (sdp_attribute_t *) osip_list_get (&remote_sdp->a_attributes, pos); printf ("%s : %s\n", at->a_att_field, at->a_att_value); //这里解释了为什么在SDP消息体中属性a里面存放必须是两列 pos ++; } }int josua_event_get(){ int counter = 0; /* use events to print some info */ eXosip_event_t *je; osip_message_t *ack = NULL; osip_message_t *answer = NULL; for (;;) { je = eXosip_event_wait (0, 50); eXosip_lock (); eXosip_default_action (je); eXosip_automatic_refresh (); eXosip_unlock (); if (je == NULL) break; counter++; switch(je->type) { case EXOSIP_MESSAGE_NEW://新的消息到来 printf ("EXOSIP_MESSAGE_NEW!\n"); eXosip_lock (); if (MSG_IS_MESSAGE (je->request))//如果接受到的消息类型是MESSAGE { osip_body_t *body; osip_message_get_body (je->request, 0, &body); printf ("I get the msg is: %s\n", body->body); //printf ("the cid is %s, did is %s\n", je->did, je->cid); } //按照规则,需要回复200 OK信息 eXosip_message_build_answer (je->tid, 200,&answer); eXosip_message_send_answer (je->tid, 200,answer); eXosip_unlock (); break; case EXOSIP_REGISTRATION_SUCCESS:// 注册成功 printf("EXOSIP_REGISTRATION_SUCCESS\n"); printf("je->rid=%d\n", je->rid); break; case EXOSIP_REGISTRATION_FAILURE:// 注册失败 printf("EXOSIP_REGISTRATION_FAILURE\n"); printf("je->rid=%d\n", je->rid); call_serverfailure(je); break; case EXOSIP_CALL_INVITE: //printf ("a new invite reveived!\n"); printf ("Received a INVITE msg from %s:%s, UserName is %s, password is %s\n", je->request->req_uri->host, je->request->req_uri->port, je->request->req_uri->username, je->request->req_uri->password); //得到消息体,认为该消息就是SDP格式. m_nt_id = je->tid; m_nCall_id = je->cid; m_nDlg_id = je->did; printf ("call_id is %d, dialog_id is %d \n", je->cid, je->did); /*eXosip_lock (); eXosip_call_send_answer (m_nt_id, 180, NULL); eXosip_unlock (); */ call_new (je);// //invite_answer(); break; case EXOSIP_CALL_PROCEEDING: printf ("proceeding!\n"); call_proceeding (je);// break; case EXOSIP_CALL_RINGING: printf ("ringing!\n"); printf ("call_id is %d, dialog_id is %d \n", je->cid, je->did); call_ringing(je);// break; case EXOSIP_CALL_ANSWERED: printf ("ok! connected!\n"); m_nCall_id = je->cid; m_nDlg_id = je->did; printf ("call_id is %d, dialog_id is %d \n", je->cid, je->did); call_answered(je);// //eXosip_call_build_ack (je->did, &ack); //eXosip_call_send_ack (je->did, ack); break; case EXOSIP_CALL_NOANSWER: printf ("no answer!\n"); break; case EXOSIP_CALL_CLOSED: printf ("the other sid closed!\n"); /*{ int i = eXosip_call_build_answer (je->tid, 200, &answer); if (i != 0) { printf ("This request msg is invalid!Cann't response!\n"); eXosip_call_send_answer (je->tid, 400, NULL); } else { eXosip_call_send_answer (je->tid, 200, answer); printf ("bye send 200 over!\n"); } }*/ call_closed (je);// break; case EXOSIP_CALL_ACK: printf ("ACK received!\n"); call_ack(je);// break; case EXOSIP_CALL_REQUESTFAILURE: printf ("%s\n",je->textinfo); call_requestfailure (je); break; case EXOSIP_CALL_RELEASED: printf ("%s\n",je->textinfo); call_closed (je);// break; default: printf ("other response!\n"); break; } eXosip_event_free (je); } if (counter > 0) return 0; return -1;}//事件监听线程DWORD WINAPI EventThread(LPVOID pParam){ while(true) { josua_event_get(); }}CSipContact::CSipContact(void){ strcpy_s(m_sUser.chServerIP,"172.23.50.184"); strcpy_s(m_sUser.chUserName,"wangconglin"); strcpy_s(m_sUser.chUserId,"6666"); strcpy_s(m_sUser.chUserPwd,"123456"); m_sUser.unServerPort = 5060; m_nAdTrPort = 2056; //nCall_id = -1; //nDlg_id = -1;}CSipContact::~CSipContact(void){ //Exit();}//注册操作eXosip_event_type_t CSipContact::Registeration(int nLisPort,int expires){ //初始化环境 if (eXosip_init ()) { printf("eXosip_init failed\n"); return EXOSIP_REGISTRATION_TERMINATED; } int i = eXosip_listen_addr (IPPROTO_UDP, NULL, nLisPort, AF_INET, 0); if (i!=0) { eXosip_quit(); printf("could not initialize transport layer\n"); return EXOSIP_REGISTRATION_TERMINATED; } //鉴权 eXosip_clear_authentication_info(); if (eXosip_add_authentication_info (m_sUser.chUserName, m_sUser.chUserId, m_sUser.chUserPwd, NULL, NULL)) { return EXOSIP_REGISTRATION_TERMINATED; } //接收线程 HANDLE pEventThread; DWORD nEventThreadID; pEventThread = ::CreateThread(NULL,0, EventThread, NULL, 0, &nEventThreadID); int ret=0; osip_message_t *reg = NULL; char *from; char *proxy; proxy = (char*)malloc(100); from = (char*)malloc(100); sprintf(from, "sip:%s@%s", m_sUser.chUserId, m_sUser.chServerIP); sprintf(proxy, "sip:%s:%d", m_sUser.chServerIP, m_sUser.unServerPort); eXosip_lock (); int reg_id = eXosip_register_build_initial_register(from, proxy, NULL,expires,®); if (reg_id< 0) { eXosip_unlock(); eXosip_quit(); printf("could not initialize register\n"); return EXOSIP_REGISTRATION_TERMINATED; } ret = eXosip_register_send_register (reg_id, reg); eXosip_unlock (); if ( ret != 0) { printf("eXosip_register_send_register error!\n"); free(from); free(proxy); return EXOSIP_REGISTRATION_TERMINATED; } else printf("eXosip_register_send_register success!\n"); free(proxy); free(from); return EXOSIP_REGISTRATION_SUCCESS;}//发起呼叫int CSipContact::Invite(const char* destUserid){ osip_message_t *invite = NULL; char localip[128]; char tmp[4096]; char *source_call; char *dest_call; source_call = (char*)malloc(100); dest_call = (char*)malloc(100); sprintf(source_call, "sip:%s@%s", m_sUser.chUserId, m_sUser.chServerIP); sprintf(dest_call, "sip:%s@%s", destUserid, m_sUser.chServerIP); int i = eXosip_call_build_initial_invite (&invite, dest_call, source_call, NULL, "This si a call for a conversation"); if (i != 0) { printf ("Intial INVITE failed!\n"); return -1; } osip_message_set_supported (invite, "100rel"); eXosip_guess_localip (AF_INET, localip, 128); // 获取本地IP //SDP格式 snprintf (tmp, 4096, "v=0\r\n" "o=josua 0 0 IN IP4 %s\r\n"// 用户名、ID、版本、网络类型、地址类型、IP地址 "s=conversation\r\n" "t=0 0\r\n" "a=username:%s\r\n" "a=password:%s\r\n" "m=audio %d RTP/AVP 0 8 101\r\n" // 音频、传输端口、传输类型、格式列表 "a=rtpmap:0 PCMU/8000\r\n" // 以下为具体描述格式列表中的 "a=rtpmap:8 PCMA/8000\r\n" "a=rtpmap:101 telephone-event/8000\r\n" "a=fmtp:101 0-11\r\n", localip,m_sUser.chUserName,m_sUser.chUserPwd,m_nAdTrPort); osip_message_set_body (invite, tmp, strlen(tmp)); osip_message_set_content_type (invite, "application/sdp"); eXosip_lock (); i = eXosip_call_send_initial_invite (invite); eXosip_unlock (); return 0;}void CSipContact::Start(){ if (EXOSIP_REGISTRATION_TERMINATED == Registeration(5060,1800)) { printf("eXosip register terminated!\n"); }}//挂断void CSipContact::Hold(){ printf ("Holded !\n"); eXosip_lock (); eXosip_call_terminate (m_nCall_id, m_nDlg_id); eXosip_unlock ();}//退出void CSipContact::Exit(){ eXosip_quit (); printf ("Exit the setup!\n");}//接听void CSipContact::Answer(){ invite_answer();}//取消注册操作eXosip_event_type_t CSipContact::UnRegisteration(){ int ret=0; osip_message_t *reg = NULL; char *from; char *proxy; proxy = (char*)malloc(100); from = (char*)malloc(100); sprintf(from, "sip:%s@%s", m_sUser.chUserId, m_sUser.chServerIP); sprintf(proxy, "sip:%s:%d", m_sUser.chServerIP, m_sUser.unServerPort); eXosip_lock (); int reg_id = eXosip_register_build_initial_register(from, proxy, NULL,0,®); if (reg_id< 0) { eXosip_unlock(); eXosip_quit(); printf("could not initialize register\n"); return EXOSIP_REGISTRATION_TERMINATED; } ret = eXosip_register_send_register (reg_id, reg); eXosip_unlock (); if ( ret != 0) { printf("eXosip_register_send_register error!\n"); free(from); free(proxy); return EXOSIP_REGISTRATION_TERMINATED; } else printf("eXosip_register_send_register success!\n"); free(proxy); free(from); return EXOSIP_REGISTRATION_SUCCESS;}
wave音频采集与播放及G729a的编解码:
/* * josua - Jack's open sip User Agent * * Copyright (C) 2002,2003 Aymeric Moizard <jack@atosc.org> * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with dpkg; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "jcalls.h"#include "sdptools.h"#include <osip2/osip_mt.h>#ifdef WIN32#include <windows.h>#include <mmsystem.h>#include <mmreg.h>#include <msacm.h>#pragma comment(lib, "Winmm.lib") WAVEFORMATEX wfx;#define MAX_IN_BUFFERS 32#define USED_IN_BUFFERS 6#define MAX_OUT_BUFFERS 32#define USED_OUT_BUFFERS 32unsigned int waveoutDeviceID = WAVE_MAPPER;WAVEHDR waveHdrOut[MAX_OUT_BUFFERS];HWAVEOUT hWaveOut;char dataBufferOut[MAX_OUT_BUFFERS][3200];unsigned int waveinDeviceID = WAVE_MAPPER;HWAVEIN hWaveIn;WAVEHDR waveHdrIn[MAX_IN_BUFFERS];char dataBufferIn[MAX_IN_BUFFERS][3200];call_t *current_call = NULL;extern "C" void va_g729a_init_encoder();extern "C" void va_g729a_encoder(short *speech, unsigned char *bitstream);extern "C" void va_g729a_init_decoder();extern "C" void va_g729a_decoder(unsigned char *bitstream, short *synth_short, int bfi);static void CALLBACKSpeakerCallback (HWAVEOUT _hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2){ WAVEHDR *wHdr; switch (uMsg) { case WOM_OPEN: fprintf (stderr, "SpeakerCallback : WOM_OPEN\n"); break; case WOM_CLOSE: fprintf (stderr, "SpeakerCallback : WOM_CLOSE\n"); break; case WOM_DONE: fprintf (stderr, "SpeakerCallback : WOM_DONE\n"); wHdr = (WAVEHDR *) dwParam1; break; default: break; }}static void CALLBACKWaveInCallback (HWAVEIN hWaveIn, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2){ WAVEHDR *wHdr; MMRESULT mr = NOERROR; char szSendBuffer[1024]; int nLen = sizeof(szSendBuffer); switch (uMsg) { case WIM_OPEN: break; case WIM_CLOSE: break; case WIM_DATA: wHdr = (WAVEHDR *) dwParam1; if (current_call == NULL) return; mr = waveInAddBuffer (hWaveIn, &(waveHdrIn[wHdr->dwUser]), sizeof (waveHdrIn[wHdr->dwUser])); if (mr == MMSYSERR_NOERROR) { static int timestamp = 0; if (current_call) { EncodeAudioData(wHdr->lpData, wHdr->dwBytesRecorded, szSendBuffer,&nLen); rtp_session_send_with_ts (current_call->rtp_session, (BYTE*)szSendBuffer, nLen, timestamp); timestamp += nLen; } } break; default: break; }}bool EncodeAudioData(char *pin,int len,char* pout,int* lenr){ bool bRet = false; va_g729a_encoder((short*)pin,(BYTE*)pout); va_g729a_encoder((short*)(pin+320),(BYTE*)pout+20); va_g729a_encoder((short*)(pin+640),(BYTE*)pout+40); va_g729a_encoder((short*)(pin+800),(BYTE*)pout+50); *lenr = 60; bRet = true;RET: return bRet;}bool DecodeAudioData(char *pin,int len,char* pout,int* lenr){ bool bRet = false; va_g729a_decoder((BYTE*)pin,(short*)(pout),0); va_g729a_decoder((BYTE*)pin+20,(short*)(pout+320),0); va_g729a_decoder((BYTE*)pin+40,(short*)(pout+640),0); va_g729a_decoder((BYTE*)pin+50,(short*)(pout+800),0); *lenr=960; bRet=true;RET: return bRet;}int os_sound_init (){ ortp_init (); ortp_scheduler_init (); va_g729a_init_encoder(); va_g729a_init_decoder(); return 0;}int open_sndcard (int format){ MMRESULT mr = NOERROR; WAVEFORMATEX wfx; wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 1; wfx.nSamplesPerSec = 8000; wfx.nAvgBytesPerSec = 1 * 8000 * 16 / 8; wfx.nBlockAlign = 16 * 1 / 8; wfx.wBitsPerSample = 16; wfx.cbSize = 0; mr = waveOutOpen (&hWaveOut, waveoutDeviceID, &wfx,(DWORD)0,0,CALLBACK_NULL); if (mr == NOERROR) { int i; for (i = 0; i < USED_OUT_BUFFERS; i++) { memset (&(waveHdrOut[i]), 0, sizeof (waveHdrOut[i])); waveHdrOut[i].lpData = dataBufferOut[i]; waveHdrOut[i].dwBufferLength = 960; /* frameSize */ waveHdrOut[i].dwFlags = 0; waveHdrOut[i].dwUser = i; mr = waveOutPrepareHeader (hWaveOut, &(waveHdrOut[i]),sizeof (waveHdrOut[i])); } } mr = waveInOpen (&hWaveIn, waveinDeviceID, &wfx, (DWORD) WaveInCallback, 0, CALLBACK_FUNCTION); if (mr == MMSYSERR_NOERROR) { int i; for (i = 0; i < MAX_IN_BUFFERS; i++) { waveHdrIn[i].lpData = dataBufferIn[i]; waveHdrIn[i].dwBufferLength = 960; /* frameSize */ waveHdrIn[i].dwFlags = 0; waveHdrIn[i].dwUser = i; mr = waveInPrepareHeader (hWaveIn, &(waveHdrIn[i]), sizeof (waveHdrIn[i])); if (mr == MMSYSERR_NOERROR) { mr = waveInAddBuffer (hWaveIn, &(waveHdrIn[i]), sizeof (waveHdrIn[i])); } } mr = waveInStart (hWaveIn); if (mr != MMSYSERR_NOERROR) { exit (-1); return -1; } } return 0;}void * os_sound_start_thread (void *_ca){ int pos_whdr = 0; call_t *ca = (call_t *) _ca; char data_in[3000]; char szBuffer[2048]; int nLen = 2048; int have_more; int timestamp = 0; int i; current_call = ca; while (ca->enable_audio != -1) { int length; static int sound_played = 0; static int cpt = 0; memset (data_in, 0, 3000); if (ca->payload == 3) length = 260; /* 280 ?? */ else length = 160; i = rtp_session_recv_with_ts (ca->rtp_session, (unsigned char*)data_in, length, timestamp, &have_more); if (i > 0) { MMRESULT mr = NOERROR; DecodeAudioData(data_in,i,szBuffer,&nLen); memset (waveHdrOut[pos_whdr].lpData, 0, length); memcpy (waveHdrOut[pos_whdr].lpData, szBuffer, nLen); waveHdrOut[pos_whdr].dwBufferLength = nLen; mr = waveOutWrite (hWaveOut, &waveHdrOut[pos_whdr], sizeof (waveHdrOut[pos_whdr])); pos_whdr++; if (pos_whdr == USED_OUT_BUFFERS) { pos_whdr = 0; /* loop over the prepared blocks */ } if (mr != MMSYSERR_NOERROR) switch (mr) { case MMSYSERR_INVALHANDLE: fprintf (stderr, "__call_free: waveOutWrite: 0x%i MMSYSERR_INVALHANDLE\n", mr); break; case MMSYSERR_NODRIVER: fprintf (stderr, "__call_free: waveOutWrite: 0x%i MMSYSERR_NODRIVER\n", mr); break; case MMSYSERR_NOMEM: fprintf (stderr, "__call_free: waveOutWrite: 0x%i MMSYSERR_NOMEM\n", mr); break; case WAVERR_UNPREPARED: fprintf (stderr, "__call_free: waveOutWrite: 0x%i WAVERR_UNPREPARED\n", mr); break; case WAVERR_STILLPLAYING: fprintf (stderr, "__call_free: waveOutWrite: 0x%i WAVERR_STILLPLAYING\n", mr); default: fprintf (stderr, "__call_free: waveOutWrite: 0x%i\n", mr); } else ++sound_played; fprintf (stderr, "sound played = %i\n", sound_played); fprintf (stderr, "cpt = %i\n", ++cpt); } timestamp += length; } current_call = NULL; return NULL;}intos_sound_start (call_t * ca, int port){ int format = WAVE_FORMAT_MULAW; char localip[128]; eXosip_guess_localip (AF_INET, localip, 128); if (open_sndcard (format) != 0) return -1; ca->rtp_session = rtp_session_new (RTP_SESSION_SENDRECV); rtp_session_set_scheduling_mode (ca->rtp_session, 1); /* yes */ rtp_session_set_blocking_mode (ca->rtp_session, 1); rtp_session_set_profile (ca->rtp_session, &av_profile); rtp_session_set_jitter_compensation (ca->rtp_session, 60); rtp_session_set_local_addr (ca->rtp_session, localip, port); rtp_session_set_remote_addr (ca->rtp_session, ca->remote_sdp_audio_ip, ca->remote_sdp_audio_port); rtp_session_set_payload_type (ca->rtp_session, ca->payload); rtp_session_signal_connect (ca->rtp_session, "telephone-event", (RtpCallback) rcv_telephone_event, /*ca*/0); ca->audio_thread = osip_thread_create (20000, os_sound_start_thread, ca); return 0;}voidos_sound_close (call_t * ca){ osip_thread_join (ca->audio_thread); osip_free (ca->audio_thread); rtp_session_signal_disconnect_by_callback (ca->rtp_session, "telephone-event", (RtpCallback) rcv_telephone_event); rtp_session_destroy (ca->rtp_session);/* waveInReset (hWaveIn); waveInClose (hWaveIn); waveOutReset (hWaveOut); waveOutClose (hWaveOut);*/}#endif
ortp操作:
/* This source has been formatted by an unregistered SourceFormatX *//* If you want to remove this info, please register this shareware *//* Please visit http://www.textrush.com to get more information *//*The antisipc program is a modular SIP softphone (SIP -rfc3261-)Copyright (C) 2005 Aymeric MOIZARD - <jack@atosc.org>*/#include <winsock2.h>#include <osip2/osip_mt.h>#include <osip2/osip.h>//#include <osip2/osip_negotiation.h>#include <osipparser2/osip_message.h>#include <osipparser2/osip_parser.h>#include <osipparser2/osip_md5.h>#include <eXosip2/eXosip.h>#include <eXosip2/eX_call.h>#include <ortp/ortp.h>#include "jcalls.h"#include "sdptools.h"call_t calls[MAX_NUMBER_OF_CALLS];static int ___call_init = 0;static int __call_init(){ int k; for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { memset(&(calls[k]), 0, sizeof(call_t)); calls[k].state = NOT_USED; _snprintf(calls[k].wav_file, 256, "%s", "ringback.wav"); }#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) return os_sound_init();#else return 0;#endif}#if defined(ORTP_SUPPORT)void rcv_telephone_event(RtpSession *rtp_session, call_t *ca){ /* telephone-event received! */}#endifint call_get_number_of_pending_calls(void){ int pos = 0; int k; for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED) { pos++; } } return pos;}call_t *call_get_call(int pos){ return &calls[pos];}int call_get_callpos(call_t *ca){ return ca - calls;}call_t *call_locate_call_by_cid(int cid){ int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == cid) return &calls[k]; } return 0;}call_t *call_create_call(int cid){ int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state == NOT_USED) { memset(&(calls[k]), 0, sizeof(call_t)); _snprintf(calls[k].wav_file, 256, "%s", "ringback.wav"); calls[k].cid = cid; calls[k].did = - 1; calls[k].state = - 1; return &calls[k]; } } return 0;}call_t *call_locate_call(eXosip_event_t *je, int createit){ call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == je->cid && calls[k].did == je->did) break; } if (k == MAX_NUMBER_OF_CALLS) { if (!createit) return 0; for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state == NOT_USED) break; } if (k == MAX_NUMBER_OF_CALLS) return NULL; ca = &(calls[k]); memset(&(calls[k]), 0, sizeof(call_t)); _snprintf(calls[k].wav_file, 256, "%s", "ringback.wav"); ca->cid = je->cid; ca->did = je->did; if (ca->did < 1 && ca->cid < 1) { exit(0); return NULL; /* not enough information for this event?? */ } } ca = &(calls[k]); osip_strncpy(ca->textinfo, je->textinfo, 255); ca->state = je->type; return ca;}call_t *call_find_call(int pos){ int k; for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED) { if (pos == 0) return &(calls[k]); pos--; } } return NULL;}int call_new(eXosip_event_t *je){ sdp_message_t *remote_sdp = NULL; call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state == NOT_USED) break; } if (k == MAX_NUMBER_OF_CALLS) return - 1; ca = &(calls[k]); memset(&(calls[k]), 0, sizeof(call_t)); _snprintf(calls[k].wav_file, 256, "%s", "ringback.wav"); ca->cid = je->cid; ca->did = je->did; ca->tid = je->tid; if (ca->did < 1 && ca->cid < 1) { return - 1; /* not enough information for this event?? */ } osip_strncpy(ca->textinfo, je->textinfo, 255); if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf(ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_from_to_str(je->request->from, &tmp); if (tmp != NULL) { _snprintf(ca->remote_uri, 256, "%s", tmp); osip_free(tmp); } }#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) os_sound_init();#endif /* negotiate payloads */ if (je->request != NULL) { remote_sdp = eXosip_get_sdp_info(je->request); } if (remote_sdp == NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "missing SDP in INVITE request\n")); } if (remote_sdp != NULL) /* TODO: else build an offer */ { sdp_connection_t *conn; sdp_media_t *remote_med; char *tmp = NULL; if (remote_sdp == NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "No remote SDP body found for call\n")); eXosip_call_send_answer(ca->tid, 400, NULL); sdp_message_free(remote_sdp); return 0; } conn = eXosip_get_audio_connection(remote_sdp); if (conn != NULL && conn->c_addr != NULL) { _snprintf(ca->remote_sdp_audio_ip, 50, conn->c_addr); } remote_med = eXosip_get_audio_media(remote_sdp); if (remote_med == NULL || remote_med->m_port == NULL) { /* no audio media proposed */ eXosip_call_send_answer(ca->tid, 415, NULL); sdp_message_free(remote_sdp); return 0; } ca->remote_sdp_audio_port = atoi(remote_med->m_port); if (ca->remote_sdp_audio_port > 0 && ca->remote_sdp_audio_ip[0] != '\0') { int pos; OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection found: %s:%i\n", ca->remote_sdp_audio_ip, ca ->remote_sdp_audio_port)); pos = 0; while (!osip_list_eol(&(remote_med->m_payloads), pos)) { tmp = (char*)osip_list_get(&remote_med->m_payloads, pos); if (tmp != NULL && (0 == osip_strcasecmp(tmp, "0") || 0 == osip_strcasecmp(tmp, "8"))) { break; } tmp = NULL; pos++; } } if (tmp != NULL) { ca->payload = atoi(tmp); } else { eXosip_call_send_answer(ca->tid, 415, NULL); sdp_message_free(remote_sdp); return 0; } if (tmp != NULL && (ca->payload == 0 || ca->payload == 8) && ca ->remote_sdp_audio_port > 0 && ca->remote_sdp_audio_ip[0] != '\0') { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection: (payload=%i) -> %s:%i\n", ca->payload, ca ->remote_sdp_audio_ip, ca->remote_sdp_audio_port)); } }#ifndef TEST_PRACK_SUPPORT eXosip_lock(); eXosip_call_send_answer(ca->tid, 180, NULL); eXosip_unlock();#else if (remote_sdp != NULL) /* TODO: else build an offer */ { osip_message_t *answer; int i; eXosip_lock(); i = eXosip_call_build_answer(ca->tid, 183, &answer); if (i == 0) { osip_message_set_require(answer, "100rel"); osip_message_set_header(answer, "RSeq", "1"); //i = sdp_complete_message(ca->did, remote_sdp, answer); if (i != 0) { osip_message_free(answer); eXosip_call_send_answer(ca->tid, 415, NULL); } else { /* start sending audio */ if (ca->enable_audio > 0) { ca->enable_audio = - 1;#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) os_sound_close(ca);#endif } if (ca->enable_audio != 1) /* audio is started */ { sdp_message_t *local_sdp; local_sdp = eXosip_get_sdp_info(answer); if (remote_sdp != NULL && local_sdp != NULL) { sdp_connection_t *conn; sdp_media_t *local_med; sdp_media_t *remote_med; char *tmp = NULL; int audio_port = 0; conn = eXosip_get_audio_connection(remote_sdp); if (conn != NULL && conn->c_addr != NULL) { _snprintf(ca->remote_sdp_audio_ip, 50, conn ->c_addr); } remote_med = eXosip_get_audio_media(remote_sdp); if (remote_med != NULL && remote_med->m_port != NULL) { ca->remote_sdp_audio_port = atoi(remote_med ->m_port); } local_med = eXosip_get_audio_media(local_sdp); if (local_med != NULL && local_med->m_port != NULL) { audio_port = atoi(local_med->m_port); } if (ca->remote_sdp_audio_port > 0 && ca ->remote_sdp_audio_ip[0] != '\0' && local_med != NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection found: %s:%i\n", ca ->remote_sdp_audio_ip, ca ->remote_sdp_audio_port)); tmp = (char*)osip_list_get(local_med ->m_payloads, 0); } if (tmp != NULL) { ca->payload = atoi(tmp); } if (tmp != NULL && audio_port > 0 && ca ->remote_sdp_audio_port > 0 && ca ->remote_sdp_audio_ip[0] != '\0') { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection: (payload=%i) %i -> %s:%i\n", ca->payload, audio_port, ca->remote_sdp_audio_ip, ca->remote_sdp_audio_port)); /* search if stream is sendonly or recvonly */ ca->remote_sendrecv = _sdp_analyse_attribute (remote_sdp, remote_med); ca->local_sendrecv = _sdp_analyse_attribute (local_sdp, local_med); if (ca->local_sendrecv == _SENDRECV) { if (ca->remote_sendrecv == _SENDONLY) ca->local_sendrecv = _RECVONLY; else if (ca->remote_sendrecv == _RECVONLY) ca->local_sendrecv = _SENDONLY; }#if defined(ORTP_SUPPORT) || defined (UCL_SUPPORT) if (0 == os_sound_start(ca, audio_port)) { ca->enable_audio = 1; /* audio is started */ }#endif } } sdp_message_free(local_sdp); } i = eXosip_call_send_answer(ca->tid, 183, answer); } if (i != 0) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "cannot send 183 progress?\n")); } } eXosip_unlock(); }#endif sdp_message_free(remote_sdp); ca->state = je->type; return 0;}int call_ack(eXosip_event_t *je){ call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == je->cid && calls[k].did == je->did) break; } if (k == MAX_NUMBER_OF_CALLS) return - 1; ca = &(calls[k]); if (je->ack != NULL) { sdp_message_t *remote_sdp; remote_sdp = eXosip_get_sdp_info(je->ack); if (remote_sdp != NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO2, NULL, "SDP detected in ACK!\n")); } else { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO2, NULL, "no SDP detected in ACK!\n")); } } if (ca->enable_audio != 1) /* audio is started */ { sdp_message_t *remote_sdp; sdp_message_t *local_sdp; remote_sdp = eXosip_get_remote_sdp(ca->did); local_sdp = eXosip_get_local_sdp(ca->did); if (remote_sdp == NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "No remote SDP body found for call\n")); } if (remote_sdp != NULL && local_sdp != NULL) { sdp_connection_t *conn; sdp_media_t *local_med; sdp_media_t *remote_med; char *tmp = NULL; int audio_port = 0; conn = eXosip_get_audio_connection(remote_sdp); if (conn != NULL && conn->c_addr != NULL) { _snprintf(ca->remote_sdp_audio_ip, 50, conn->c_addr); } remote_med = eXosip_get_audio_media(remote_sdp); if (remote_med != NULL && remote_med->m_port != NULL) { ca->remote_sdp_audio_port = atoi(remote_med->m_port); } local_med = eXosip_get_audio_media(local_sdp); if (local_med != NULL && local_med->m_port != NULL) { audio_port = atoi(local_med->m_port); } if (ca->remote_sdp_audio_port > 0 && ca->remote_sdp_audio_ip[0] != '\0' && local_med != NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection found: %s:%i\n", ca->remote_sdp_audio_ip, ca->remote_sdp_audio_port)); tmp = (char*)osip_list_get(&local_med->m_payloads, 0); } if (tmp != NULL) { ca->payload = atoi(tmp); } if (tmp != NULL && audio_port > 0 && ca->remote_sdp_audio_port > 0 && ca->remote_sdp_audio_ip[0] != '\0') { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection: (payload=%i) %i -> %s:%i\n", ca->payload, audio_port, ca->remote_sdp_audio_ip, ca ->remote_sdp_audio_port)); /* search if stream is sendonly or recvonly */ ca->remote_sendrecv = _sdp_analyse_attribute(remote_sdp, remote_med); ca->local_sendrecv = _sdp_analyse_attribute(local_sdp, local_med); if (ca->local_sendrecv == _SENDRECV) { if (ca->remote_sendrecv == _SENDONLY) ca->local_sendrecv = _RECVONLY; else if (ca->remote_sendrecv == _RECVONLY) ca->local_sendrecv = _SENDONLY; }#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) if (0 == os_sound_start(ca, audio_port)) { ca->enable_audio = 1; /* audio is started */ }#endif } } sdp_message_free(local_sdp); sdp_message_free(remote_sdp); } ca->state = je->type; return 0;}int call_remove(call_t *ca){ if (ca == NULL) return - 1; if (ca->enable_audio > 0) { ca->enable_audio = - 1;#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) os_sound_close(ca);#endif } ca->state = NOT_USED; return 0;}int call_proceeding(eXosip_event_t *je){ call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == je->cid && calls[k].did == je->did) break; } if (k == MAX_NUMBER_OF_CALLS) { for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state == NOT_USED) break; } if (k == MAX_NUMBER_OF_CALLS) return - 1; ca = &(calls[k]); memset(&(calls[k]), 0, sizeof(call_t)); _snprintf(calls[k].wav_file, 256, "%s", "ringback.wav"); ca->cid = je->cid; ca->did = je->did; if (ca->did < 1 || ca->cid < 1) { return - 1; /* not enough information for this event?? */ } } ca = &(calls[k]); osip_strncpy(ca->textinfo, je->textinfo, 255); if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf(ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_from_to_str(je->request->from, &tmp); if (tmp != NULL) { _snprintf(ca->remote_uri, 256, "%s", tmp); osip_free(tmp); } } ca->state = je->type; return 0;}int call_ringing(eXosip_event_t *je){ call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == je->cid && calls[k].did == je->did) break; } if (k == MAX_NUMBER_OF_CALLS) { for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state == NOT_USED) break; } if (k == MAX_NUMBER_OF_CALLS) return - 1; ca = &(calls[k]); memset(&(calls[k]), 0, sizeof(call_t)); _snprintf(calls[k].wav_file, 256, "%s", "ringback.wav"); ca->cid = je->cid; ca->did = je->did; if (ca->did < 1 || ca->cid < 1) { return - 1; /* not enough information for this event?? */ } } ca = &(calls[k]); ca->cid = je->cid; ca->did = je->did; ca->tid = je->tid; osip_strncpy(ca->textinfo, je->textinfo, 255); if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf(ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_from_to_str(je->request->from, &tmp); if (tmp != NULL) { _snprintf(ca->remote_uri, 256, "%s", tmp); osip_free(tmp); } } if (ca->enable_audio == 1 && je->response != NULL) { sdp_message_t *sdp = eXosip_get_sdp_info(je->response); if (sdp != NULL) { /* audio is started and session may just have been modified */ sdp_message_free(sdp); } } { osip_header_t *rseq; osip_message_header_get_byname(je->response, "RSeq", 0, &rseq); if (rseq != NULL && rseq->hvalue != NULL) { /* try sending a PRACK */ osip_message_t *prack = NULL; int i; eXosip_lock(); i = eXosip_call_build_prack(ca->tid, &prack); if (i != 0) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "Failed to build PRACK request\n")); } else { eXosip_call_send_prack(ca->tid, prack); } eXosip_unlock(); } } if (ca->enable_audio != 1) /* audio is started */ { sdp_message_t *remote_sdp; sdp_message_t *local_sdp; local_sdp = eXosip_get_sdp_info(je->request); remote_sdp = eXosip_get_sdp_info(je->response); if (remote_sdp == NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "No remote SDP body found for call\n")); /* TODO: remote_sdp = retreive from ack above */ } if (local_sdp == NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "SDP body was probably in the ACK (TODO)\n")); } if (remote_sdp != NULL && local_sdp != NULL) { sdp_connection_t *conn; sdp_media_t *local_med; sdp_media_t *remote_med; char *tmp = NULL; int audio_port = 0; conn = eXosip_get_audio_connection(remote_sdp); if (conn != NULL && conn->c_addr != NULL) { _snprintf(ca->remote_sdp_audio_ip, 50, conn->c_addr); } remote_med = eXosip_get_audio_media(remote_sdp); if (remote_med != NULL && remote_med->m_port != NULL) { ca->remote_sdp_audio_port = atoi(remote_med->m_port); } local_med = eXosip_get_audio_media(local_sdp); if (local_med != NULL && local_med->m_port != NULL) { audio_port = atoi(local_med->m_port); } if (ca->remote_sdp_audio_port > 0 && ca->remote_sdp_audio_ip[0] != '\0' && remote_med != NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection found: %s:%i\n", ca->remote_sdp_audio_ip, ca->remote_sdp_audio_port)); tmp = (char*)osip_list_get(&remote_med->m_payloads, 0); } if (tmp != NULL) { ca->payload = atoi(tmp); } if (tmp != NULL && audio_port > 0 && ca->remote_sdp_audio_port > 0 && ca->remote_sdp_audio_ip[0] != '\0') { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection: (payload=%i) %i -> %s:%i\n", ca->payload, audio_port, ca->remote_sdp_audio_ip, ca ->remote_sdp_audio_port)); /* search if stream is sendonly or recvonly */ ca->remote_sendrecv = _sdp_analyse_attribute(remote_sdp, remote_med); ca->local_sendrecv = _sdp_analyse_attribute(local_sdp, local_med); if (ca->local_sendrecv == _SENDRECV) { if (ca->remote_sendrecv == _SENDONLY) ca->local_sendrecv = _RECVONLY; else if (ca->remote_sendrecv == _RECVONLY) ca->local_sendrecv = _SENDONLY; }#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) if (0 == os_sound_start(ca, audio_port)) { ca->enable_audio = 1; /* audio is started */ }#endif } } sdp_message_free(local_sdp); sdp_message_free(remote_sdp); } ca->state = je->type; return 0;}int call_answered(eXosip_event_t *je){ call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == je->cid && calls[k].did == je->did) break; } if (k == MAX_NUMBER_OF_CALLS) { for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state == NOT_USED) break; } if (k == MAX_NUMBER_OF_CALLS) return - 1; ca = &(calls[k]); memset(&(calls[k]), 0, sizeof(call_t)); _snprintf(calls[k].wav_file, 256, "%s", "ringback.wav"); ca->cid = je->cid; ca->did = je->did; if (ca->did < 1 && ca->cid < 1) { exit(0); return - 1; /* not enough information for this event?? */ } } ca = &(calls[k]); osip_strncpy(ca->textinfo, je->textinfo, 255); if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf(ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_from_to_str(je->request->from, &tmp); if (tmp != NULL) { _snprintf(ca->remote_uri, 256, "%s", tmp); osip_free(tmp); } } eXosip_lock(); { osip_message_t *ack = NULL; int i; i = eXosip_call_build_ack(ca->did, &ack); if (i != 0) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "Cannot build ACK for call!\n")); } else { sdp_message_t *local_sdp = NULL; sdp_message_t *remote_sdp = NULL; if (je->request != NULL && je->response != NULL) { local_sdp = eXosip_get_sdp_info(je->request); remote_sdp = eXosip_get_sdp_info(je->response); } if (local_sdp == NULL && remote_sdp != NULL) { /* sdp in ACK */ i = sdp_complete_message(ca->did, remote_sdp, ack); if (i != 0) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "Cannot complete ACK with sdp body?!\n")); } } sdp_message_free(local_sdp); sdp_message_free(remote_sdp); eXosip_call_send_ack(ca->did, ack); } } eXosip_unlock(); if (ca->enable_audio == 1 && je->response != NULL) { sdp_message_t *sdp = eXosip_get_sdp_info(je->response); if (sdp != NULL) { /* audio is started and session has just been modified */ ca->enable_audio = - 1;#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) os_sound_close(ca);#endif sdp_message_free(sdp); } } if (ca->enable_audio != 1) /* audio is started */ { sdp_message_t *remote_sdp; sdp_message_t *local_sdp; local_sdp = eXosip_get_sdp_info(je->request); remote_sdp = eXosip_get_sdp_info(je->response); if (remote_sdp == NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "No remote SDP body found for call\n")); /* TODO: remote_sdp = retreive from ack above */ } if (local_sdp == NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "SDP body was probably in the ACK (TODO)\n")); } if (remote_sdp != NULL && local_sdp != NULL) { sdp_connection_t *conn; sdp_media_t *local_med; sdp_media_t *remote_med; char *tmp = NULL; int audio_port = 0; conn = eXosip_get_audio_connection(remote_sdp); if (conn != NULL && conn->c_addr != NULL) { _snprintf(ca->remote_sdp_audio_ip, 50, conn->c_addr); } remote_med = eXosip_get_audio_media(remote_sdp); if (remote_med != NULL && remote_med->m_port != NULL) { ca->remote_sdp_audio_port = atoi(remote_med->m_port); } local_med = eXosip_get_audio_media(local_sdp); if (local_med != NULL && local_med->m_port != NULL) { audio_port = atoi(local_med->m_port); } if (ca->remote_sdp_audio_port > 0 && ca->remote_sdp_audio_ip[0] != '\0' && remote_med != NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection found: %s:%i\n", ca->remote_sdp_audio_ip, ca->remote_sdp_audio_port)); tmp = (char*)osip_list_get(&remote_med->m_payloads, 0); } if (tmp != NULL) { ca->payload = atoi(tmp); } if (tmp != NULL && audio_port > 0 && ca->remote_sdp_audio_port > 0 && ca->remote_sdp_audio_ip[0] != '\0') { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection: (payload=%i) %i -> %s:%i\n", ca->payload, audio_port, ca->remote_sdp_audio_ip, ca ->remote_sdp_audio_port)); /* search if stream is sendonly or recvonly */ ca->remote_sendrecv = _sdp_analyse_attribute(remote_sdp, remote_med); ca->local_sendrecv = _sdp_analyse_attribute(local_sdp, local_med); if (ca->local_sendrecv == _SENDRECV) { if (ca->remote_sendrecv == _SENDONLY) ca->local_sendrecv = _RECVONLY; else if (ca->remote_sendrecv == _RECVONLY) ca->local_sendrecv = _SENDONLY; }#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) if (0 == os_sound_start(ca, audio_port)) { ca->enable_audio = 1; /* audio is started */ }#endif } } sdp_message_free(local_sdp); sdp_message_free(remote_sdp); } ca->state = je->type; return 0;}int call_redirected(eXosip_event_t *je){ call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == je->cid && calls[k].did == je->did) break; } if (k == MAX_NUMBER_OF_CALLS) return - 1; ca = &(calls[k]); if (ca->enable_audio > 0) { ca->enable_audio = - 1;#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) os_sound_close(ca);#endif } ca->state = NOT_USED; return 0;}int call_requestfailure(eXosip_event_t *je){ call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == je->cid && calls[k].did == je->did) break; } if ((je->response != NULL && je->response->status_code == 407) || (je ->response != NULL && je->response->status_code == 401)) { /* try authentication */ return 0; } if (k == MAX_NUMBER_OF_CALLS) return - 1; ca = &(calls[k]); if (ca->enable_audio > 0) { ca->enable_audio = - 1;#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) os_sound_close(ca);#endif } if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf(ca->reason_phrase, 50, je->response->reason_phrase); } ca->state = NOT_USED; return 0;}int call_serverfailure(eXosip_event_t *je){ call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == je->cid && calls[k].did == je->did) break; } if (k == MAX_NUMBER_OF_CALLS) return - 1; ca = &(calls[k]); if (ca->enable_audio > 0) { ca->enable_audio = - 1;#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) os_sound_close(ca);#endif } if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf(ca->reason_phrase, 50, je->response->reason_phrase); } ca->state = NOT_USED; return 0;}int call_globalfailure(eXosip_event_t *je){ call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == je->cid && calls[k].did == je->did) break; } if (k == MAX_NUMBER_OF_CALLS) return - 1; ca = &(calls[k]); if (ca->enable_audio > 0) { ca->enable_audio = - 1;#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) os_sound_close(ca);#endif } if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf(ca->reason_phrase, 50, je->response->reason_phrase); } ca->state = NOT_USED; return 0;}int call_closed(eXosip_event_t *je){ call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == je->cid) break; } if (k == MAX_NUMBER_OF_CALLS) return - 1; ca = &(calls[k]); if (ca->enable_audio > 0) { ca->enable_audio = - 1;#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) os_sound_close(ca);#endif } ca->state = NOT_USED; return 0;}int call_modified(eXosip_event_t *je){ call_t *ca; int k; if (___call_init == 0) { ___call_init = - 1; __call_init(); } for (k = 0; k < MAX_NUMBER_OF_CALLS; k++) { if (calls[k].state != NOT_USED && calls[k].cid == je->cid && calls[k].did == je->did) break; } if (k == MAX_NUMBER_OF_CALLS) return - 1; ca = &(calls[k]); ca->tid = je->tid; osip_strncpy(ca->textinfo, je->textinfo, 255); if (je->response != NULL) { ca->status_code = je->response->status_code; _snprintf(ca->reason_phrase, 50, je->response->reason_phrase); } if (je->request != NULL) { char *tmp = NULL; osip_from_to_str(je->request->from, &tmp); if (tmp != NULL) { _snprintf(ca->remote_uri, 256, "%s", tmp); osip_free(tmp); } } ca->state = je->type; eXosip_lock(); { osip_message_t *answer = NULL; int i; i = eXosip_call_build_answer(ca->tid, 200, &answer); if (i != 0) { eXosip_call_send_answer(ca->tid, 400, NULL); eXosip_unlock(); return 0; } else { sdp_message_t *remote_sdp = NULL; if (je->request != NULL) remote_sdp = eXosip_get_sdp_info(je->request); if (remote_sdp == NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "No remote SDP body found for call\n")); /* TODO: sdp in 200 & ACK */ eXosip_call_send_answer(ca->tid, 200, answer); } else { i = sdp_complete_message(ca->did, remote_sdp, answer); if (i != 0) { sdp_message_free(remote_sdp); osip_message_free(answer); eXosip_call_send_answer(ca->tid, 415, NULL); eXosip_unlock(); return 0; } else eXosip_call_send_answer(ca->tid, 200, answer); sdp_message_free(remote_sdp); } } } eXosip_unlock(); if (ca->enable_audio > 0) { ca->enable_audio = - 1;#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) os_sound_close(ca);#endif } if (ca->enable_audio != 1) /* audio is started */ { sdp_message_t *remote_sdp; sdp_message_t *local_sdp; remote_sdp = eXosip_get_remote_sdp(ca->did); local_sdp = eXosip_get_local_sdp(ca->did); if (remote_sdp == NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "No remote SDP body found for call\n")); } if (remote_sdp != NULL && local_sdp != NULL) { sdp_connection_t *conn; sdp_media_t *local_med; sdp_media_t *remote_med; char *tmp = NULL; int audio_port = 0; conn = eXosip_get_audio_connection(remote_sdp); if (conn != NULL && conn->c_addr != NULL) { _snprintf(ca->remote_sdp_audio_ip, 50, conn->c_addr); } remote_med = eXosip_get_audio_media(remote_sdp); if (remote_med != NULL && remote_med->m_port != NULL) { ca->remote_sdp_audio_port = atoi(remote_med->m_port); } local_med = eXosip_get_audio_media(local_sdp); if (local_med != NULL && local_med->m_port != NULL) { audio_port = atoi(local_med->m_port); } if (ca->remote_sdp_audio_port > 0 && ca->remote_sdp_audio_ip[0] != '\0' && local_med != NULL) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection found: %s:%i\n", ca->remote_sdp_audio_ip, ca->remote_sdp_audio_port)); tmp = (char*)osip_list_get(&local_med->m_payloads, 0); } if (tmp != NULL) { ca->payload = atoi(tmp); } if (tmp != NULL && audio_port > 0 && ca->remote_sdp_audio_port > 0 && ca->remote_sdp_audio_ip[0] != '\0') { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "audio connection: (payload=%i) %i -> %s:%i\n", ca->payload, audio_port, ca->remote_sdp_audio_ip, ca ->remote_sdp_audio_port)); /* search if stream is sendonly or recvonly */ ca->remote_sendrecv = _sdp_analyse_attribute(remote_sdp, remote_med); ca->local_sendrecv = _sdp_analyse_attribute(local_sdp, local_med); if (ca->local_sendrecv == _SENDRECV) { if (ca->remote_sendrecv == _SENDONLY) ca->local_sendrecv = _RECVONLY; else if (ca->remote_sendrecv == _RECVONLY) ca->local_sendrecv = _SENDONLY; }#if defined(ORTP_SUPPORT) || defined(UCL_SUPPORT) if (0 == os_sound_start(ca, audio_port)) { ca->enable_audio = 1; /* audio is started */ }#endif } } sdp_message_free(local_sdp); sdp_message_free(remote_sdp); } return 0;}
0 0
- 基于eXosip的SIP客户端
- 一个基于exosip的软电话例子
- 一个基于exosip的软电话例子
- 一个基于exosip的软电话例子
- 一个基于exosip的软电话例子
- Python的SIP客户端
- 关于sip和sip的客户端
- 基于pjsip和webrtc封装sip客户端
- linux下的sip客户端
- SIP客户端的相关资料
- 基于VOCAL branch开发自己的sip-based 视频通信客户端
- 基于SIP的VoIP系统
- linux下一个用eXosip实现的sip通信的UAC和UAS的例子(调试成功)
- 基于pjsip和webrtc封装sip客户端 技术选型
- PPC版的Sip Phone 客户端
- exosip的注册方法
- 一个使用了 osip 和 eXosip 库的 UAC 代理客户端的演示程序
- exosip
- helloword的忠实追随者
- 数组 冒泡排序 , 快速排序
- java foreach循环中调用remove 抛出java.util.ConcurrentModificationException
- 记录一下C++和C#中的字符串处理与编码格式的问题
- 字符串识别和过滤_华为SO挑战赛初赛试题2015年8月
- 基于eXosip的SIP客户端
- 数组
- OS-->使用GITHub搭建 个人(组织)网站 和 项目网站
- CSS制作图片水平垂直居中
- 1047. Student List for Course (25)
- 【OpenCV】边缘检测:Sobel、拉普拉斯算子
- soapUI接口测试工具所有版本下载地址
- Android ListView中使用CheckBox等的混乱问题
- Git 使用规范流程