⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sip_ctrl.c

📁 linux下的sip voip程序
💻 C
📖 第 1 页 / 共 3 页
字号:
        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 + -