📄 sip_ctrl.c
字号:
char field[MAX_FIELD]; memset(field, 0, MAX_FIELD); get_CSeq( r_msg, field); ret = set_CSeq( msg, field); if(ret<0){ debug("Error!!SendAck set_CSeq failed.\n"); return -1; } } /* Content-Length */ ret = set_Contentlength(msg, 0); if(ret<0){ debug("Error!!SendBusy set_Contentlength failed.\n"); return -1; } debug("<----- send Busy Here response\n"); ret = SendSipMessage(msg); if(ret < 0){ debug("SendSipMessage failed.\n"); } return 0;}/* 487 Request Terminateを侯喇する */int SendRequestTerminate(char* msg){ int ret; /* スタ〖トライン */ ret = set_Startline(Method_RequestTerminate, msg, NULL); if(ret<0){ debug("Error!!SendRequestTerminate set_Startline failed.\n"); return -1; } /* Via */ ret = set_Via(msg, g_SipMsg.save_Via); if(ret<0){ debug("Error!!SendRequestTerminate set_Via failed.\n"); return -1; } /* Max-Forwards */ ret = set_Maxforwards(msg, MAX_COUNT); if(ret<0){ debug("Error!!SendRequestTerminate set_Maxforwards failed.\n"); return -1; } /* From */ ret = set_From( msg, g_SipMsg.save_From); if(ret<0){ debug("Error!!SendRequestTerminate set_From failed.\n"); return -1; } /* To */ ret = set_To( msg, g_SipMsg.save_To); if(ret<0){ debug("Error!!SendRequestTerminate set_To failed.\n"); return -1; } /* Call-ID */ ret = set_CallID( msg, g_SipMsg.save_CallID); if(ret<0){ debug("Error!!SendRequestTerminate set_CallID failed.\n"); return -1; } /* CSeq */ { int seqnum; char field[MAX_FIELD]; memset(field, 0, MAX_FIELD); seqnum = get_CSeqnum(g_SipMsg.save_Cseq); sprintf(field, "%d %s", seqnum, METHOD_INVITE); ret = set_CSeq( msg, field); if(ret<0){ debug("Error!!SendRequestTerminate set_CSeq failed.\n"); return -1; } } /* Content-Length */ ret = set_Contentlength(msg, 0); if(ret<0){ debug("Error!!SendRequestTerminate set_Contentlength failed.\n"); return -1; } debug("<----- send Request Terminate response\n"); ret = SendSipMessage(msg); if(ret < 0){ debug("SendSipMessage failed.\n"); } return 0;}/* 减慨したリクエストの硷侍を豺老し借妄する */int RecvRequest(enum method request, char* msg, RECV_INFO* info){ int ret; switch(request){ /* INVITE减慨 */ case Method_Invite:{ debug("\n-----> received INVITE request\n"); ret = RecvInvite(msg, info); if(ret<0){ debug("RecvInvite failed\n"); return -1; } }break; /* ACK减慨 */ case Method_Ack:{ debug("\n-----> received ACK request \n"); ret = RecvAck(msg, info); if(ret < 0){ debug("RecvAck failed\n"); return -1; } }break; /* BYE减慨 */ case Method_Bye:{ debug("\n-----> received BYE request \n"); ret = RecvBye(msg, info); if(ret<0){ debug("RecvBye failed\n"); return -1; } }break; /* CANCEL减慨 */ case Method_Cancel:{ debug("\n-----> received CANCEL request \n"); ret = RecvCancel(msg, info); if(ret<0){ debug("RecvCancel failed\n"); return -1; } }break; /* 澈碰急侍戎规なし */ default:{ debug("Error!!Receive request undefined.\n"); return -1; } } return 0;}/* 减慨したレスポンスの硷侍を豺老し借妄する */int RecvResponse(enum method response, char* msg, RECV_INFO* info){ int ret; switch(response){ /* 100 Trying减慨 */ case Method_Trying:{ debug("\n-----> received Trying response\n"); }break; /* 180 Ringing减慨 */ case Method_Ringing:{ debug("\n-----> received Ringing response\n"); }break; /* 200 OK减慨 */ case Method_OK:{ debug("\n-----> received OK response\n"); ret = RecvOK(msg, info); if(ret<0){ debug("RecvOK failed\n"); return -1; } }break; /* 486 Busy Here减慨 */ case Method_Busy:{ char ack[MAX_MESSAGE]; debug("\n-----> received BusyHere response\n"); ret = SendAck(ack); if(ret<0){ debug("SendAck failed\n"); return -1; } Finish(info->pmsg, info->pinfo); }break; /* 487 Request Terminate减慨 */ case Method_RequestTerminate:{ char ack[MAX_MESSAGE]; debug("\n-----> received RequestTerminate response\n"); ret = SendAck(ack); if(ret<0){ debug("SendAck failed\n"); return -1; } Finish(info->pmsg, info->pinfo); }break; /* 澈碰急侍戎规なし */ default:{ debug("Error!!Receive responce undefined.\n"); return -1; } } return 0;}/* INVITE减慨箕の借妄を乖う */int RecvInvite(char* msg, RECV_INFO* info){ int ret; char line[MAX_FIELD]; char trying[MAX_MESSAGE]; char ringing[MAX_MESSAGE]; char hostname[MAX_NAME]; struct hostent host; struct hostent* phost = &host; char* addrbuff; /* アイドル觉轮でない */ if(info->pinfo->state != eSIdle){ debug("Error!!Invalid state.\n"); if(info->pinfo->state == eSBusy|| info->pinfo->state == eSWaitBusy){ char busy[MAX_MESSAGE]; ret = SendBusy(busy, msg); if(ret<0){ debug("SendBusy failed.\n"); return -1; } return 0; } return -1; } if(g_StackInfo.server_flag == eRNull){ gethostname(hostname, MAX_NAME); phost = gethostbyname(hostname); strcpy(info->pinfo->fqdn, phost->h_name); addrbuff = inet_ntoa(*(struct in_addr*)phost->h_addr_list[0]); strcpy(info->pinfo->addr, addrbuff); } /* 觉轮恃构 */ info->pinfo->session_flag = eCReceiver; info->pinfo->state = eSWaitBusy; /* 减慨したメッセ〖ジを攫鼠妥燎ごとに瘦赂する */ /* INVITEメッセ〖ジを瘦赂 */ save_message(msg, info->pmsg); memset(line, 0, MAX_FIELD); /* Viaヘッダ〖の攫鼠 */ get_Via(msg, line); strcpy(info->pmsg->save_Via, line); if(g_StackInfo.server_flag == eRRegister){ get_Via2nd(msg, line); strcpy(info->pmsg->save_Via2nd, line); }else{ *(info->pmsg->save_Via2nd) = '\0'; } memset(line, 0, MAX_FIELD); /* Fromヘッダ〖の攫鼠 */ get_From(msg, line); strcpy(info->pmsg->save_From, line); memset(line, 0, MAX_FIELD); /* Toヘッダ〖の攫鼠 */ get_To(msg, line); strcpy(info->pmsg->save_To, line); memset(line, 0, MAX_FIELD); /* Call-IDの攫鼠 */ get_CallID(msg, line); strcpy(info->pmsg->save_CallID, line); memset(line, 0, MAX_FIELD); /* CSeqの攫鼠 */ get_CSeq(msg, line); strcpy(info->pmsg->save_Cseq, line); get_rtpaddr(msg, info->pinfo->rtp_addr); get_rtpport(msg, info->pinfo->y_rtpport);{ char buf[MAX_FIELD]; sprintf(buf, "RTP destination(calling) IP addr is %s\n", info->pinfo->rtp_addr); debug(buf); sprintf(buf, "RTP destination(calling) port is %s\n", info->pinfo->y_rtpport); debug(buf); } ret = SendTrying(trying); /* 100 Trying流慨*/ if(ret<0){ debug("SendTrying failed\n"); return -1; } ret = SendRinging(ringing); /* 180 Ringing流慨 */ if(ret<0){ debug("SendRinging failed.\n"); return -1; } incomingcall(); return 0;}/* 200 OK减慨箕の借妄を乖う */int RecvOK(char* msg, RECV_INFO* info){ int ret; switch(info->pinfo->state){ case eSRegister:{ info->pinfo->state = eSIdle; }break; case eSWaitBusy:{ char callid[MAX_FIELD]; char line[MAX_FIELD]; char ack[MAX_MESSAGE]; /* 极眉琐が券慨荚であることを澄千する */ if(info->pinfo->session_flag != eCSender){ debug("Error!!Invalid state.\n"); return -1; } get_CSeq(msg, callid); /* CSeqが赖しいかどうか孺秤する */ if(0 != strcmp(info->pmsg->save_Cseq, callid)){ debug("Receive message's CSeq is different saved one.\n"); return -1; } /* 减慨したSIPメッセ〖ジの攫鼠妥燎を瘦赂 */ get_To(msg, line); /* 瘦赂しているToの攫鼠を介袋步 */ memset(info->pmsg->save_To, 0, MAX_FIELD); /* OKのToの攫鼠を瘦赂 */ strcpy(info->pmsg->save_To, line); get_rtpaddr(msg, info->pinfo->rtp_addr); get_rtpport(msg, info->pinfo->y_rtpport); ret = SendAck(ack); if(ret<0){ debug("SendAck failed\n"); return -1; } info->pinfo->state = eSBusy; connection(); }break; case eSWaitDisc:{ enum method emethod; emethod = Search_Method(info->pmsg->save_Msg); if(emethod == Method_Bye){ /* 钙豺庶借妄 */ disconnect(); Finish(info->pmsg, info->pinfo); } }break; case eSIdle:{ printf("Unregister done.\n"); }break; default:{ printf("eSWaitDisc %d: state %d\n", eSWaitDisc, info->pinfo->state); debug("Error!!Invalid state.\n"); return -1; } } return 0;}/* ACK减慨箕の借妄を乖う */int RecvAck(char* msg, RECV_INFO* info){ char cid[MAX_FIELD]; /* Call-IDチェック */ get_CallID( msg, cid); /* Call-IDが般う眷圭 */ if(0 != strcmp(cid, info->pmsg->save_CallID)){ /* 486に滦するACKかもしれないので部もしないで提る */ return 0; } /* 极眉琐が缅慨荚であることを澄千する */ if(info->pinfo->session_flag != eCReceiver){ debug("Error!!Invalid state.\n"); return -1; } switch(info->pinfo->state){ /* 儡鲁面の眷圭、奶厦を倡幌する */ case eSWaitBusy: info->pinfo->state = eSBusy; printf("if you send audio rtp, please input 's'.\n"); printf("if you want to disconnect this call, please input 'b'.\n"); break; /* 磊们借妄面の眷圭、钙豺庶借妄を乖う */ case eSWaitDisc: disconnect(); Finish(info->pmsg, info->pinfo); break; default: debug("Error!!Invalid state.\n"); return -1; break; } return 0;}/* BYE减慨箕の借妄を乖う */int RecvBye(char* msg, RECV_INFO* info){ int ret; char line[MAX_FIELD]; char ok[MAX_MESSAGE]; memset(ok, 0, MAX_MESSAGE); if(info->pinfo->state != eSBusy && info->pinfo->state != eSWaitBusy){ debug("Error!!Invalid state.\n"); return -1; } info->pinfo->state = eSWaitDisc; save_message(msg, info->pmsg); /* Viaヘッダの攫鼠 */ memset(line, 0, MAX_FIELD); memset(info->pmsg->save_Via, 0, MAX_FIELD); get_Via(msg, line); strcpy(info->pmsg->save_Via, line); if(g_StackInfo.server_flag == eRRegister){ get_Via2nd(msg, line); strcpy(info->pmsg->save_Via2nd, line); }else{ *(info->pmsg->save_Via2nd) = '\0'; } /* CSeqの攫鼠 */ memset(line, 0, MAX_FIELD); memset(info->pmsg->save_Cseq, 0, MAX_FIELD); get_CSeq(msg, line); strcpy(info->pmsg->save_Cseq, line); *(info->psend_switch) = ng; ret = SendOK(ok); if(ret < 0){ debug("SendOK failed\n"); return -1; } disconnect(); Finish(info->pmsg, info->pinfo); return 0;}/* CANCEL减慨箕の借妄を乖う */int RecvCancel(char* msg, RECV_INFO* info){ int ret; char line[MAX_FIELD]; char ok[MAX_MESSAGE]; char terminate[MAX_MESSAGE]; if(info->pinfo->state != eSWaitBusy){ debug("Error!!Invalid state.\n"); return -1; } /* 极眉琐が缅慨荚であることを澄千する */ if(info->pinfo->session_flag != eCReceiver){ debug("Error!!Invalid state.\n"); return -1; } info->pinfo->state = eSWaitDisc; memset(line, 0, MAX_FIELD); get_CSeq(msg, line); /* CSeqが赖しいかどうか孺秤する */ if(get_CSeqnum(line) != get_CSeqnum(info->pmsg->save_Cseq)){ debug("Receive message's CSeq was invalid.\n"); return -1; } info->pinfo->state = eSWaitDisc; /* メッセ〖ジを瘦赂する */ save_message(msg, info->pmsg); /* CSeqの攫鼠を瘦赂 */ memset(info->pmsg->save_Cseq, 0, MAX_FIELD); strcpy(info->pmsg->save_Cseq, line); ret = SendOK(ok); if(ret < 0){ debug("SendOK failed\n"); return -1; } ret = SendRequestTerminate(terminate); if(ret < 0){ debug("SendRequestTerminate failed\n"); return -1; } return 0;}/* Viaヘッダを侯喇する */void Make_Via(char* via, char* addr, int seq){ int time; long timestamp; struct timeval tv; struct timezone tz; if (-1 == gettimeofday(&tv, &tz)){ return; }else{ time = tv.tv_sec*1000 + tv.tv_usec/1000; } timestamp = (long) (time & 0x7FFFFFFF); sprintf(via, "%s/%s %s:%d;branch=z9hG4bK-%d-%d", SIP_VERSION, PROTOCOL_UDP, addr, SIP_PORT, timestamp, seq);}/* 钙姜位箕に瘦赂している攫鼠を豺庶する */void Finish(SAVE_MSG* msg, STACK_INFO* s_info){ /* 瘦赂攫鼠の介袋步 */ memset(msg->save_Msg, 0, MAX_MESSAGE); memset(msg->save_beforMsg, 0, MAX_MESSAGE); memset(msg->save_Via, 0, MAX_FIELD); memset(msg->save_From, 0, MAX_FIELD); memset(msg->save_To, 0, MAX_FIELD); memset(msg->save_CallID, 0, MAX_FIELD); memset(msg->save_Cseq, 0, MAX_FIELD); s_info->session_flag = eCNull; s_info->state = eSIdle;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -