最近比较闲,以前的项目是一个可以打软电话的,很好奇电话是怎么打出去的。于是利用空余时间看了下以前的源代码,顺便找了点SIP的资料,下面是一个小小的总结。还有很多不足的地方。以后有机会再慢慢补充。
SIP其实就是一个新型的协议,是受现在互联网发展而诞生出来更适应当今网络潮流的一个信令控制协议,用在voip电话中。现在还不是很成熟,但是精简,扩展性好,未来有很好的发展前景。
SIP是一个应用层的信令控制协议,用来创建,修改和释放一个或多个参与者的会话。
SIP的3种呼叫方式:直接呼叫,重定向呼叫,代理呼叫
SIP的6种信令:REGISTER,INVITE,ACK,OPTIONS,CANCLE,BYE
SIP的5种信令功能:
用户定位,
用户通信能力协商(用户以什么方式打电话),
用户意愿交互(用户是否愿意接听呼叫)
建立呼叫
呼叫处理控制。
使用exosip实现SIP呼叫。
初始化exosip库:
eXosip_init()
监听一个指定的端口:
int exosip_listen_addr (int transport, const char *addr, int port, int family, int secure);
设置SIP包头域,即SIP客户端的名称:
void eXosip_set_user_agent (const char *user_agent);
清除认证信息
int eXosip_clear_authentication_info (void);
添加认证信息:
eXosieXosip_add_authentication_info(m_strUserName.c_str(),m_strAuthName.c_str(),m_strPassword.c_str(), "md5", NULL);
初始化一个注册ID并生成一个注册包
int eXosip_register_build_initial_register (const char *from, const char *proxy,
const char *contact, int expires,
osip_message_t ** reg);
发送注册请求:invite
eXosip_register_send_register(nRegID, pRegMsg);
等待exosip注册结果事件返回
eXosip_event_t *eXosip_event_wait (int tv_s, int tv_ms);
第一次会返回一个401或407的错误,要求对终端用户进行验证,这时需要发送一个默认请求(包括ACK和INVITE)
eXosip_default_action(pEvent);
继续等待返回结果:
eXosip_event_t *eXosip_event_wait (int tv_s, int tv_ms);
如果邀请成功EXOSIP_REGISTRATION_SUCCESS
获取返回的消息结构体
sdp_message_t *pMsg = eXosip_get_remote_sdp(pEvent->did);
根据消息里的类型判断,
1)如果是正在接通中EXOSIP_CALL_PROCEEDING或EXOSIP_CALL_RINGING
从消息结构体中获取媒体声音用于使对方振铃
sdp_media* pMediaRemote = eXosip_get_audio_media(pMsg);
使对方振铃
2)如果对方已经接听了EXOSIP_CALL_ANSWERED
从消息结构体中获取媒体声音用于使对方振铃
sdp_media* pMediaRemote = eXosip_get_audio_media(pMsg);
之后构建并发送一个ACK请求告知 200OK已经收到
eXosip_call_build_ack(pEvent->did,&pOsipMsg);
eXosip_call_send_ack(pEvent->did,pOsipMsg);
结束通话发送bye请求int eXosip_call_terminate (int cid, int did);