#ifndef __SIP_SERVER_C__ #define __SIP_SERVER_C__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*!Start: @Elementry data type definition. @Modified by: Mohd. Naushad Ahmed @Dated: 17-OCT-2012 */ typedef unsigned char I_U8; typedef char I_S8; typedef unsigned short int I_U16; typedef short int I_S16; typedef unsigned int I_U32; typedef int I_S32; typedef unsigned char * I_PU8; typedef char * I_PS8; typedef int * I_PS32; typedef void I_Void; typedef void * I_PVoid; #define ZERO 0 #define ONE 1 #define TWO 2 #define THREE 3 #define FOUR 4 #define FIVE 5 #define SIX 6 #define OSIP_TYPE_UAC ONE #define OSIP_TYPE_UAS TWO typedef struct cmd_opt_tag { /*! type could have a value of 1 for CLIENT and 2 for SERVER*/ I_S8 type; /*! Remote IP Address*/ I_S8 rIpAddress[20]; /*! Self IP Address*/ I_S8 sIpAddress[20]; /*! UDP Port*/ I_S8 port[FOUR]; }cmd_opt_t; /*!End: @Elementry data type definition. @Modified by: Mohd. Naushad Ahmed @Dated: 17-OCT-2012 */ I_S32 buildSipResponse(const osip_message_t *request, osip_message_t **response) { I_S32 pos = ZERO; I_S32 i; osip_message_t *msg = NULL; osip_message_init(&msg); /*! Filling the Contacts */ osip_from_clone(request->from, &msg->from); osip_to_clone(request->to, &msg->to); osip_cseq_clone(request->cseq, &msg->cseq); osip_call_id_clone(request->call_id, &msg->call_id); /*!Extracting all Vias Field and copying them*/ while (!osip_list_eol (&request->vias, pos)) { osip_via_t *via; osip_via_t *via2; via = (osip_via_t *) osip_list_get (&request->vias, pos); i = osip_via_clone (via, &via2); if (i != 0) { osip_message_free (msg); fprintf(stderr,"osip_via_clone FAILED\n"); return i; } osip_list_add (&(msg->vias), via2, -1); pos++; } /*osip_to_set_tag(msg->to, osip_strdup("19")); */ osip_message_set_version(msg, osip_strdup("SIP/2.0")); osip_message_set_contact(msg, osip_strdup("sip:address@hidden")); /*osip_contact_clone(msg, osip_strdup("sip:address@hidden"));*/ /*osip_message_set_user_agent(msg, osip_strdup("Linphone/3.2.1 (eXosip2/3.3.0)"));*/ *response = msg; return (ZERO); }/*!I_S32 buildSipResponse(const osip_message_t *request, osip_message_t **response)*/ I_S32 sndUdpMessageCallBackFn(osip_transaction_t *tr, osip_message_t *sip, I_PS8 dstIpAddr, I_S32 dstPort, I_S32 srcSocketFd) { I_PS8 txBuff; I_S32 txBuffLen; if( (OSIP_SUCCESS != osip_message_to_str(sip, &txBuff, &txBuffLen)) || (txBuffLen != SendUdpData(srcSocketFd,txBuff,&txBuffLen,dstIpAddr,dstPort))) { fprintf(stderr,"FAILED dstIpAddr=[%s] dstPort=[%d] srcSocketFd=[%d] " "txBuffLen=[%d]\n", dstIpAddr, dstPort, srcSocketFd, txBuffLen); } else { fprintf(stderr,"txBuff=[%s]\n",txBuff); } }/*!I_S32 sndUdpMessageCallBackFn(osip_transaction_t *tr, osip_message_t *sip, I_PS8 *dstIpAddr, I_S32 dstPort, I_S32 srcSocketFd)*/ I_Void RespSipNistRegisterCallBackFn(I_S32 type, osip_transaction_t *osip_tr, osip_message_t *osip_msg) { fprintf(stderr,"RespSipNistRegisterCallBackFn CALLED\n"); osip_message_t *response = NULL; osip_event_t *evt = NULL; buildSipResponse(osip_msg, &response); osip_message_set_status_code(response, SIP_OK); osip_message_set_reason_phrase(response, osip_strdup("OK")); evt = osip_new_outgoing_sipmessage(response); fprintf(stderr,"RespSipNistRegisterCallBackFn SEND-MSG-EVT=[%d]\n",evt->type); osip_transaction_add_event(osip_tr, evt); } I_Void RespSip2xxBuilderCallBackFn (I_S32 type, osip_transaction_t *osip_tr, osip_message_t *osip_msg) { osip_message_t *response = NULL; osip_event_t *evt = NULL; buildSipResponse(osip_msg, &response); osip_message_set_status_code(response, SIP_OK); osip_message_set_reason_phrase(response, osip_strdup("OK")); evt = osip_new_outgoing_sipmessage(response); fprintf(stderr,"RespSip2xxBuilderCallBackFn SEND-MSG-EVT=[%d]\n",evt->type); osip_transaction_add_event(osip_tr, evt); }/*!I_Void RespSip2xxBuilderCallBackFn (I_S32 type, osip_transaction_t *osip_tr, osip_message_t *osip_msg)*/ I_Void ReqSipNistOptionsRecvdCallBackFn(I_S32 type, osip_transaction_t *osip_tr, osip_message_t *osip_msg) { osip_message_t *response = NULL; osip_event_t *evt = NULL; #if 0 buildSipResponse(osip_msg, &response); osip_message_set_status_code(response, SIP_OK); osip_message_set_reason_phrase(response, osip_strdup("OK")); evt = osip_new_outgoing_sipmessage(response); fprintf(stderr,"ReqSipNistOptionsRecvdCallBackFn (EVT) " "=[%d] And capabilities to be Added\n",evt->type); osip_transaction_add_event(osip_tr, evt); #endif /*! 100 TRYING RESPONSE */ buildSipResponse(osip_msg, &response); osip_message_set_status_code(response, SIP_TRYING); evt = osip_new_outgoing_sipmessage(response); osip_message_set_reason_phrase(response, osip_strdup("Trying")); fprintf(stderr,"TRYING=TransactionId=[%d]\n",evt->transactionid); osip_transaction_add_event(osip_tr, evt); fprintf(stderr,"TRYING--RespSipNistOptionCallBackFn EventType=[%d]\n",evt->type); /*! 200 OK RESPONSE */ buildSipResponse(osip_msg, &response); osip_message_set_status_code(response, SIP_OK); evt = osip_new_outgoing_sipmessage(response); osip_message_set_reason_phrase(response, osip_strdup("OK")); fprintf(stderr,"OK=TransactionId=[%d]\n",evt->transactionid); osip_transaction_add_event(osip_tr, evt); } I_Void ReqSipNistStatus1xxSentCallBackFn(I_S32 type, osip_transaction_t *osip_tr, osip_message_t *osip_msg) { osip_message_t *response = NULL; osip_event_t *evt = NULL; fprintf(stderr,"NIST_STATUS_1xx_SENT\n"); /*! 100 TRYING RESPONSE */ buildSipResponse(osip_msg, &response); osip_message_set_status_code(response, SIP_TRYING); osip_message_set_reason_phrase(response, osip_strdup("Trying")); evt = osip_new_outgoing_sipmessage(response); fprintf(stderr,"TRYING=TransactionId=[%d]\n",evt->transactionid); osip_transaction_add_event(osip_tr, evt); fprintf(stderr,"TRYING--RespSipNistStatus1xxSentCallBackFn EventType=[%d]\n",evt->type); /*! 200 OK RESPONSE */ buildSipResponse(osip_msg, &response); osip_message_set_status_code(response, SIP_OK); osip_message_set_reason_phrase(response, osip_strdup("OK")); evt = osip_new_outgoing_sipmessage(response); fprintf(stderr,"OK=TransactionId=[%d]\n",evt->transactionid); osip_transaction_add_event(osip_tr, evt); } I_Void ReqSipNistUnknownRecvdCallBackFn(I_S32 type, osip_transaction_t *osip_tr, osip_message_t *osip_msg) { fprintf(stderr,"UNKNOWN REQUEST RECEIVED\n"); } I_Void ReqSipIstInviteRecvdCallBackFn(I_S32 type, osip_transaction_t *osip_tr, osip_message_t *osip_msg) { osip_message_t *response = NULL; osip_event_t *evt = NULL; /*! 100 TRYING RESPONSE */ buildSipResponse(osip_msg, &response); osip_message_set_status_code(response, SIP_TRYING); osip_message_set_reason_phrase(response, osip_strdup("Trying")); evt = osip_new_outgoing_sipmessage(response); fprintf(stderr,"TRYING=TransactionId=[%d]\n",evt->transactionid); osip_transaction_add_event(osip_tr, evt); fprintf(stderr,"TRYING--RespSipNistRegisterCallBackFn EventType=[%d]\n",evt->type); #if 0 buildSipResponse(osip_msg, &response);//dialog establishement osip_message_set_status_code(response, 101); evt = osip_new_outgoing_sipmessage(response); osip_message_set_reason_phrase(response, osip_strdup("Dialog Establishement")); osip_transaction_add_event(osip_tr, evt); #endif #if 0 /*! 180 RINGING RESPONSE */ buildSipResponse(osip_msg, &response);//ringing osip_message_set_status_code(response, SIP_RINGING); osip_message_set_reason_phrase(response, osip_strdup("Ringing")); evt = osip_new_outgoing_sipmessage(response); osip_transaction_add_event(osip_tr, evt); /*! 200 OK RESPONSE */ buildSipResponse(osip_msg, &response); osip_message_set_status_code(response, SIP_OK); osip_message_set_reason_phrase(response, osip_strdup("OK")); evt = osip_new_outgoing_sipmessage(response); fprintf(stderr,"OK=TransactionId=[%d]\n",evt->transactionid); osip_transaction_add_event(osip_tr, evt); #endif }/*!I_Void ReqSipIstInviteRecvdCallBackFn(I_S32 type, osip_transaction_t *osip_tr, osip_message_t *osip_msg)*/ /*!Registering the call back * */ I_S32 registerSipCallBackFn(osip_t *pOsip) { osip_set_cb_send_message(pOsip, sndUdpMessageCallBackFn); osip_set_message_callback(pOsip, OSIP_IST_INVITE_RECEIVED, ReqSipIstInviteRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_IST_STATUS_2XX_SENT, RespSip2xxBuilderCallBackFn); osip_set_message_callback(pOsip, OSIP_ICT_STATUS_1XX_RECEIVED, ReqSipIstInviteRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_NICT_STATUS_1XX_RECEIVED, ReqSipIstInviteRecvdCallBackFn); /*!Start: address@hidden registration for NIST Request. address@hidden by: Mohd. Naushad Ahmed address@hidden: 24-OCT-2012 * */ osip_set_message_callback(pOsip, OSIP_NIST_REGISTER_RECEIVED, RespSipNistRegisterCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_BYE_RECEIVED, ReqSipIstInviteRecvdCallBackFn); /*!OPTION METHOD received from SIP CLIENT *to Query the Capabilities of SIP SERVER */ #if 0 osip_set_message_callback(pOsip, OSIP_NIST_OPTIONS_RECEIVED, ReqSipIstInviteRecvdCallBackFn); #endif osip_set_message_callback(pOsip, OSIP_NIST_INFO_RECEIVED, ReqSipIstInviteRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_CANCEL_RECEIVED, ReqSipIstInviteRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_NOTIFY_RECEIVED, ReqSipIstInviteRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_SUBSCRIBE_RECEIVED, ReqSipIstInviteRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_UNKNOWN_REQUEST_RECEIVED, ReqSipIstInviteRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_REQUEST_RECEIVED_AGAIN, ReqSipIstInviteRecvdCallBackFn); /*! OPTIONS REQUEST RECEIVED FROM USER AGENT * IT's A FORM OF QUERY TO SIP PROXY SERVER */ osip_set_message_callback(pOsip, OSIP_NIST_OPTIONS_RECEIVED, ReqSipNistOptionsRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_STATUS_1XX_SENT, ReqSipNistStatus1xxSentCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_STATUS_2XX_SENT, ReqSipIstInviteRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_STATUS_2XX_SENT_AGAIN, ReqSipIstInviteRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_STATUS_3XX_SENT, ReqSipIstInviteRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_STATUS_4XX_SENT, ReqSipIstInviteRecvdCallBackFn); osip_set_message_callback(pOsip, OSIP_NIST_UNKNOWN_REQUEST_RECEIVED, ReqSipNistUnknownRecvdCallBackFn); /*!End: address@hidden registration for NIST Request. address@hidden by: Mohd. Naushad Ahmed address@hidden: 24-OCT-2012 * */ /*osip_set_cb_send_message(osip,SendMsg);*/ } I_S32 HandleSipReq(I_PS8 msgPtr, I_PS32 msgLen, I_S32 sockFd, I_PVoid sa, I_PVoid pOsip) { I_S32 retStatus; /*!OSIP Related Data structure...*/ osip_event_t *pEvt; osip_uri_t *pOsipUri; osip_transaction_t *tran; pEvt = osip_parse(msgPtr,*msgLen /*!length of the received buffer*/); if(NULL == pEvt) { fprintf(stderr,"OSIP_PARSED FAILED\n"); return(-ONE); } /*!Setting the Target IP and PORT*/ osip_message_fix_last_via_header(pEvt->sip, (I_PS8)inet_ntoa(((struct sockaddr_in *)sa)->sin_addr), htons(((struct sockaddr_in *)sa)->sin_port)); fprintf(stderr,"IP-ADDR=[%s] PORT=[%d]\n",(I_PS8)inet_ntoa(((struct sockaddr_in *)sa)->sin_addr), htons(((struct sockaddr_in *)sa)->sin_port)); retStatus = osip_find_transaction_and_add_event(pOsip,pEvt); if(OSIP_SUCCESS != retStatus) { fprintf(stderr,"PROCESS NEW REQUEST retStatus=[%d]\n",retStatus); if(RCV_REQUEST == pEvt->type) { fprintf(stderr,"RCV_REQUEST\n"); /*!Possibly to be forwardef to SIP-REGISTRAR SERVER*/ if(OSIP_SUCCESS != osip_transaction_init(&tran, NIST/*IST*/, pOsip, pEvt->sip)) fprintf(stderr,"TRANSACTION-INIT FAILED\n"); } else if(RCV_REQINVITE == pEvt->type) { fprintf(stderr,"RCV_REQINVITE\n"); /*!To be QUERIED for CALLED PARTY*/ if(OSIP_SUCCESS != osip_transaction_init(&tran, IST, pOsip, pEvt->sip)) fprintf(stderr,"TRANSACTION-INIT FAILED\n"); } if(OSIP_SUCCESS != osip_transaction_set_out_socket (tran, sockFd)) fprintf(stderr,"SET_OUT_SOCKET-FAILED\n"); if(OSIP_SUCCESS != osip_transaction_set_your_instance(tran, pOsip)) fprintf(stderr,"SET_YOUR-TRANSACTION-FAILED\n"); if(OSIP_SUCCESS != osip_transaction_add_event(tran, pEvt)) fprintf(stderr,"ADD_EVENT-FAILED\n"); else fprintf(stderr,"Event TYPE=[%d]\n",pEvt->type); } } I_S32 send_sip_message(I_S16 srcSock, I_PS8 ipAddr,I_PS8 port,I_PVoid pOsipT) { I_S8 recvBuff[1024]; I_PS8 pBuff = &recvBuff[ZERO]; I_S16 recvBuffLen = 1024; I_S32 retStatus =-(ONE); struct sockaddr_in to; size_t toLen = sizeof(struct sockaddr_in); to.sin_family = AF_INET; to.sin_addr.s_addr = inet_addr(ipAddr); to.sin_port = htons(atoi(port)); pBuff = "REGISTER sip:192.168.1.2 SIP/2.0\r\n" "Via: SIP/2.0/UDP 192.168.1.2\r\n" "From: ;tag=19\r\n" "To: sip:address@hidden" "Call-ID: address@hidden" "CSeq: 2 REGISTER\r\n" "Expires: 360\r\n" "Contact: sip:192.168.1.2\r\n" "Allow: NOTIFY\r\n" "Allow: REFER\r\n" "Allow: OPTIONS\r\n" "Allow: INVITE\r\n" "Allow: ACK\r\n" "Allow: CANCEL\r\n" "Allow: BYE\r\n" "Content-Length: 0\r\n"; #if 0 pBuff = "INVITE sip:address@hidden SIP/2.0\r\n" "Via: SIP/2.0/UDP client.atlanta.example.com:5060;branch=z9hG4bK74bf9\r\n" "Max-Forwards: 70\r\n" "Route: \r\n" "From: Alice ;tag=9fxced76sl\r\n" "To: Bob \r\n" "Call-ID: address@hidden" "CSeq: 1 INVITE\r\n" "Contact: \r\n" "Proxy-Authorization: Digest username=\"alice\"," "realm=\"atlanta.example.com\"," "nonce=\"ze7k1ee88df84f1cec431ae6cbe5a359\", opaque=\"\"," "uri=\"sip:address@hidden"," "response=\"b00b416324679d7e243f55708d44be7b\"\r\n" "Content-Type: application/sdp\r\n" "Content-Length: 151\r\n" "\r\n\r\n" "v=0\r\n" "o=alice 2890844526 2890844526 IN IP4 client.atlanta.example.com\r\n" "s=-\r\n" "c=IN IP4 192.0.2.101\r\n" "t=0 0\r\n" "m=audio 49172 RTP/AVP 0\r\n" "a=rtpmap:0 PCMU/8000\r\n"; #endif memset((void *)&to.sin_zero, (I_S32)ZERO, (size_t)sizeof(to.sin_zero)); /*!OSIP Related Data structure...*/ osip_event_t *pEvt; osip_t *pOsip; pOsip = (osip_t *)pOsipT; while(ONE) { retStatus = sendto(srcSock,pBuff,strlen(pBuff),ZERO,(struct sockaddr *)&to,(socklen_t)toLen); if(retStatus > ZERO) { memset(recvBuff,'0',1024); retStatus = recvfrom(srcSock,recvBuff,recvBuffLen,ZERO,(struct sockaddr *)&to,&toLen); fprintf(stderr,"RESP=[%s] len=[%d]\n",recvBuff,retStatus); pEvt = osip_parse(recvBuff,retStatus/*!length of the received buffer*/); fprintf(stderr,"METHOD=[%s]\n",osip_message_get_method((osip_message_t *)pEvt->sip)); retStatus = osip_find_transaction_and_add_event(pOsip,pEvt); if(ZERO != retStatus) { fprintf(stderr,"THIS EVENT HAS NO TRANSACTION, CREATE A NEWONE\n"); osip_transaction_t *tran; osip_transaction_init(&tran, NICT, pOsip, pEvt->sip); //osip_transaction_set_in_socket (tran, socket); osip_transaction_set_out_socket (tran, srcSock); //osip_transaction_set_your_instance(tran, pOsip);// store osip in transaction for later usage osip_transaction_add_event(tran, pEvt); }/*!if(ZERO != retStatus)*/ }/*!if(retStatus > ZERO)*/ }/*!while(ONE)*/ }/*!I_S32 send_sip_message(I_S16 srcSock)*/ /*! Command Line Processing Options...*/ I_S32 cmd_processing(I_S32 argc, I_PS8 *argv,I_PVoid cmdOpt) { I_S8 option; cmd_opt_t *cmd_opt = (cmd_opt_t *)cmdOpt; while ( (option = getopt(argc,argv,"cCsSrR:lL:pP:"))!= -1) { switch(option) { case 'c': case 'C': cmd_opt->type = OSIP_TYPE_UAC; fprintf(stderr,"CLIENT=[%d]\n",cmd_opt->type); break; case 's': case 'S': cmd_opt->type = OSIP_TYPE_UAS; fprintf(stderr,"SERVER=[%d]\n",cmd_opt->type); break; case 'r': case 'R': strcpy(cmd_opt->rIpAddress,optarg); fprintf(stderr,"RmoteIp=[%s]\n",cmd_opt->rIpAddress); break; case 'l': case 'L': strcpy(cmd_opt->sIpAddress,optarg); fprintf(stderr,"Local IP=[%s]\n",cmd_opt->sIpAddress); break; case 'p': case 'P': strcpy(cmd_opt->port,optarg); fprintf(stderr,"UDP PORT=[%s]\n",cmd_opt->port); break; default: fprintf(stderr,"DEFAULT CASE:\n"); }/*!switch(option)*/ }/*!while(option >= ZERO)*/ }/*!I_S32 cmd_processing(I_S32 argc, I_PS8 *argv,I_PVoid cmdOpt)*/ /*! * ARGV[0] = PROGRAM NAME * ARGV[1] = IP-ADDRESS * ARGV[2] = PORT NUMBER * */ I_S32 main(I_S32 argc, I_PS8 argv[]) { I_U32 retStatus; ixt_t *pIxt; osip_t *pOsip; /*!NICT=>NON-INVITE CALL TRANSACTION *NICT== REGISTER PHONE(SIP) with SIP-SERVER */ osip_nict_t nict = {ZERO}; I_PS8 dstHost; I_U16 dstPort; /*!Transport related declaration*/ I_S16 srcSock; /*! This instance sis being used for holding the command line options */ cmd_opt_t cmdOpt; cmd_processing(argc, argv,(I_PVoid)&cmdOpt); if (OSIP_TYPE_UAC == cmdOpt.type) { /*!Start: * Registering the Callback */ retStatus = osip_init(&pOsip); registerSipCallBackFn(pOsip); /*!End: * Registration of callbak */ srcSock = CreateBindUdpSocket(cmdOpt.sIpAddress,cmdOpt.port); fprintf(stderr,"INSTANTIATING WITH CLIENT\n"); send_sip_message(srcSock,cmdOpt.rIpAddress,cmdOpt.port,(I_PVoid)pOsip); }/*!if(ZERO == strcmp("-c",argv[THREE]))*/ else if (OSIP_TYPE_UAS == cmdOpt.type) { /*!Start: * Registering the Callback*/ retStatus = osip_init(&pOsip); registerSipCallBackFn(pOsip); /*!End: * Registration of callbak*/ srcSock = CreateBindUdpSocket(cmdOpt.sIpAddress,cmdOpt.port); CreateUdpServer(srcSock,(I_PVoid)pOsip); fprintf(stderr,"INSTANTIATING WITH SERVER\n"); } }/*!I_S32 main(I_S32 argc, I_PS8 argv[])*/ #endif