void stack::call::relay(thread *thread, session *s) { assert(thread != NULL); assert(s != NULL); int status = thread->sevent->response->status_code; int tid = -1; voip::body_t body = NULL; voip::msg_t reply = NULL; voip::context_t ctx = stack::sip.out_context; Mutex::protect(this); if(s == source && target) { tid = target->tid; ctx = target->context; } else if(s == target) { tid = source->tid; ctx = source->context; } osip_message_get_body(thread->sevent->response, 0, &body); switch(s->state) { case session::REFER: if(status == SIP_ACCEPTED) { set(TRANSFER, 'x', "transfer"); disconnectLocked(); Mutex::release(this); return; } s->state = session::OPEN; break; case session::REINVITE: if(status != SIP_ACCEPTED) s->state = session::OPEN; default: break; } Mutex::release(this); if(tid < 1) return; if(voip::make_answer_response(ctx, tid, status, &reply)) { if(stack::sip_protocol == IPPROTO_UDP) voip::server_requires(reply, "100rel"); voip::header(reply, "RSeq", "1"); if(body && body->body) voip::attach(reply, SDP_BODY, body->body); voip::send_answer_response(ctx, tid, status, reply); } }
int handle_token(const osip_message_t *sip_message, const TokenType toketype_) { osip_body_t *body; osip_message_get_body (sip_message, 0, &body);//body P2PAuthToken *token_request=(P2PAuthToken *)malloc(sizeof(P2PAuthToken)*2); if(body->length < sizeof(P2PAuthToken)*2) { printf("not valid length"); free(token_request); return 0; } memcpy(token_request,body->body, sizeof(P2PAuthToken)*2); decodeFromChar(token_request,sizeof(P2PAuthToken)*2); int i=0; switch(toketype_) { case Auth: i=HandleP2PAuthToken(p2pcc, token_request); break; case Reauth: i=HandleP2PReauthToken(p2pcc, token_request); break; case Byesession: i=HandleP2PByeSessionToken(p2pcc, token_request); break; case Byelink: i=HandleP2PByeLinkToken(p2pcc, token_request); break; default: printf("TokenType error\n"); free(token_request); return 0; break; } if(i<1) { printf("ProcessP2PAuthToken error\n"); free(token_request); return 0; } free(token_request); return 1; }
/* * PROXY_REWRITE_INVITATION_BODY * * rewrites the outgoing INVITATION request or response packet * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */ int proxy_rewrite_invitation_body(osip_message_t *mymsg, int direction){ osip_body_t *body; sdp_message_t *sdp; struct in_addr map_addr, addr_sess, addr_media, outside_addr, inside_addr; int sts; char *bodybuff; int bodybuflen; char clen[8]; /* content length: probably never more than 7 digits !*/ int map_port, msg_port; int media_stream_no; sdp_connection_t *sdp_conn; sdp_media_t *sdp_med; int rtp_direction=0; int have_c_media=0; if (configuration.rtp_proxy_enable == 0) return STS_SUCCESS; /* * get SDP structure */ sts = osip_message_get_body(mymsg, 0, &body); if (sts != 0) { #if 0 if ((MSG_IS_RESPONSE_FOR(mymsg,"INVITE")) && (MSG_IS_STATUS_1XX(mymsg))) { /* 1xx responses *MAY* contain SDP data */ DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: " "no body found in message"); return STS_SUCCESS; } else { /* INVITE request and 200 response *MUST* contain SDP data */ ERROR("rewrite_invitation_body: no body found in message"); return STS_FAILURE; } #else DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: " "no body found in message"); return STS_SUCCESS; #endif } sts = sip_body_to_str(body, &bodybuff, &bodybuflen); if (sts != 0) { ERROR("rewrite_invitation_body: unable to sip_body_to_str"); } sts = sdp_message_init(&sdp); sts = sdp_message_parse (sdp, bodybuff); if (sts != 0) { ERROR("rewrite_invitation_body: unable to sdp_message_parse body"); DUMP_BUFFER(-1, bodybuff, bodybuflen); osip_free(bodybuff); sdp_message_free(sdp); return STS_FAILURE; } osip_free(bodybuff); if (configuration.debuglevel) { /* just dump the buffer */ char *tmp, *tmp2; int tmplen; sts = osip_message_get_body(mymsg, 0, &body); sts = sip_body_to_str(body, &tmp, &tmplen); osip_content_length_to_str(mymsg->content_length, &tmp2); DEBUG("Body before rewrite (clen=%s, strlen=%i):\n%s\n----", tmp2, tmplen, tmp); osip_free(tmp); osip_free(tmp2); } /* * RTP proxy: get ready and start forwarding * start forwarding for each media stream ('m=' item in SIP message) */ /* get outbound address */ if (get_interface_ip(IF_OUTBOUND, &outside_addr) != STS_SUCCESS) { sdp_message_free(sdp); return STS_FAILURE; } /* get inbound address */ if (get_interface_ip(IF_INBOUND, &inside_addr) != STS_SUCCESS) { sdp_message_free(sdp); return STS_FAILURE; } /* figure out what address to use for RTP masquerading */ if (MSG_IS_REQUEST(mymsg)) { if (direction == DIR_INCOMING) { memcpy(&map_addr, &inside_addr, sizeof (map_addr)); rtp_direction = DIR_OUTGOING; } else { memcpy(&map_addr, &outside_addr, sizeof (map_addr)); rtp_direction = DIR_INCOMING; } } else /* MSG_IS_REPONSE(mymsg) */ { if (direction == DIR_INCOMING) { memcpy(&map_addr, &inside_addr, sizeof (map_addr)); rtp_direction = DIR_OUTGOING; } else { memcpy(&map_addr, &outside_addr, sizeof (map_addr)); rtp_direction = DIR_INCOMING; } } DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: SIP[%s %s] RTP[%s %s]", MSG_IS_REQUEST(mymsg)? "RQ" : "RS", (direction==DIR_INCOMING)? "IN" : "OUT", (rtp_direction==DIR_INCOMING)? "IN" : "OUT", utils_inet_ntoa(map_addr)); /* * first, check presence of a 'c=' item on session level */ if (sdp->c_connection==NULL || sdp->c_connection->c_addr==NULL) { /* * No 'c=' on session level, search on media level now * * According to RFC2327, ALL media description must * include a 'c=' item now: */ media_stream_no=0; while (!sdp_message_endof_media(sdp, media_stream_no)) { /* check if n'th media stream is present */ if (sdp_message_c_addr_get(sdp, media_stream_no, 0) == NULL) { ERROR("SDP: have no 'c=' on session level and neither " "on media level (media=%i)",media_stream_no); sdp_message_free(sdp); return STS_FAILURE; } media_stream_no++; } /* while */ } /* Required 'c=' items ARE present */ /* * rewrite 'c=' item on session level if present and not yet done. * remember the original address in addr_sess */ memset(&addr_sess, 0, sizeof(addr_sess)); if (sdp->c_connection && sdp->c_connection->c_addr) { sts = get_ip_by_host(sdp->c_connection->c_addr, &addr_sess); if (sts == STS_FAILURE) { ERROR("SDP: cannot resolve session 'c=' host [%s]", sdp->c_connection->c_addr); sdp_message_free(sdp); return STS_FAILURE; } /* * Rewrite * an IP address of 0.0.0.0 means *MUTE*, don't rewrite such */ if (strcmp(sdp->c_connection->c_addr, "0.0.0.0") != 0) { osip_free(sdp->c_connection->c_addr); sdp->c_connection->c_addr=osip_malloc(HOSTNAME_SIZE); sprintf(sdp->c_connection->c_addr, "%s", utils_inet_ntoa(map_addr)); } else { /* 0.0.0.0 - don't rewrite */ DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: " "got a MUTE c= record (on session level - legal?)"); } } /* * rewrite 'o=' item (originator) on session level if present. */ if (sdp->o_addrtype && sdp->o_addr) { if (strcmp(sdp->o_addrtype, "IP4") != 0) { ERROR("got IP6 in SDP originator - not yet suported by siproxd"); sdp_message_free(sdp); return STS_FAILURE; } osip_free(sdp->o_addr); sdp->o_addr=osip_malloc(HOSTNAME_SIZE); sprintf(sdp->o_addr, "%s", utils_inet_ntoa(map_addr)); } /* * loop through all media descritions, * start RTP proxy and rewrite them */ for (media_stream_no=0;;media_stream_no++) { /* check if n'th media stream is present */ if (sdp_message_m_port_get(sdp, media_stream_no) == NULL) break; /* * check if a 'c=' item is present in this media description, * if so -> rewrite it */ memset(&addr_media, 0, sizeof(addr_media)); have_c_media=0; sdp_conn=sdp_message_connection_get(sdp, media_stream_no, 0); if (sdp_conn && sdp_conn->c_addr) { if (strcmp(sdp_conn->c_addr, "0.0.0.0") != 0) { sts = get_ip_by_host(sdp_conn->c_addr, &addr_media); have_c_media=1; /* have a valid address */ osip_free(sdp_conn->c_addr); sdp_conn->c_addr=osip_malloc(HOSTNAME_SIZE); sprintf(sdp_conn->c_addr, "%s", utils_inet_ntoa(map_addr)); } else { /* 0.0.0.0 - don't rewrite */ DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: got a " "MUTE c= record (media level)"); } } /* start an RTP proxying stream */ if (sdp_message_m_port_get(sdp, media_stream_no)) { msg_port=atoi(sdp_message_m_port_get(sdp, media_stream_no)); if (msg_port > 0) { osip_uri_t *cont_url = NULL; char *client_id=NULL; /* try to get some additional UA specific unique ID. * Try: * 1) User part of Contact header * 2) Host part of Contact header (will be different * between internal UA and external UA) */ if (!osip_list_eol(mymsg->contacts, 0)) cont_url = ((osip_contact_t*)(mymsg->contacts->node->element))->url; if (cont_url) { client_id=cont_url->username; if (client_id == NULL) client_id=cont_url->host; } /* * do we have a 'c=' item on media level? * if not, use the same as on session level */ if (have_c_media == 0) { memcpy(&addr_media, &addr_sess, sizeof(addr_sess)); } /* * Am I running in front of the routing device? Then I cannot * use the external IP to bind a listen socket to, so force * the use of my inbound IP for listening. */ if ((rtp_direction == DIR_INCOMING) && (configuration.outbound_host) && (strcmp(configuration.outbound_host, "")!=0)) { DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: " "in-front-of-NAT-Router"); memcpy(&map_addr, &inside_addr, sizeof (map_addr)); } sts = rtp_start_fwd(osip_message_get_call_id(mymsg), client_id, rtp_direction, media_stream_no, map_addr, &map_port, addr_media, msg_port); if (sts == STS_SUCCESS) { /* and rewrite the port */ sdp_med=osip_list_get(sdp->m_medias, media_stream_no); if (sdp_med && sdp_med->m_port) { osip_free(sdp_med->m_port); sdp_med->m_port=osip_malloc(8); /* 5 digits, \0 + align */ sprintf(sdp_med->m_port, "%i", map_port); DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: " "m= rewrote port to [%i]",map_port); } else { ERROR("rewriting port in m= failed sdp_med=%p, " "m_number_of_port=%p", sdp_med, sdp_med->m_port); } } /* sts == success */ } /* if msg_port > 0 */ } else { /* no port defined - skip entry */ WARN("no port defined in m=(media) stream_no=%i", media_stream_no); continue; } } /* for media_stream_no */ /* remove old body */ sts = osip_list_remove(mymsg->bodies, 0); osip_body_free(body); /* dump new body */ sdp_message_to_str(sdp, &bodybuff); bodybuflen=strlen(bodybuff); /* free sdp structure */ sdp_message_free(sdp); /* include new body */ sip_message_set_body(mymsg, bodybuff, bodybuflen); if (sts != 0) { ERROR("rewrite_invitation_body: unable to sip_message_set_body body"); } /* free content length resource and include new one*/ osip_content_length_free(mymsg->content_length); mymsg->content_length=NULL; sprintf(clen,"%i",bodybuflen); sts = osip_message_set_content_length(mymsg, clen); /* free old body */ osip_free(bodybuff); if (configuration.debuglevel) { /* just dump the buffer */ char *tmp, *tmp2; int tmplen; sts = osip_message_get_body(mymsg, 0, &body); sts = sip_body_to_str(body, &tmp, &tmplen); osip_content_length_to_str(mymsg->content_length, &tmp2); DEBUG("Body after rewrite (clen=%s, strlen=%i):\n%s\n----", tmp2, tmplen, tmp); osip_free(tmp); osip_free(tmp2); } return STS_SUCCESS; }
int uac_key_nego() { eXosip_event_t *g_event; osip_header_t * subject; char to[100]; char from[100]; //key_nego 1 snprintf(to, 50,"sip:%s@%s:%s",device_info.ipc_id,device_info.server_ip,device_info.server_port); snprintf(from, 50,"sip:%s@%s:%s",device_info.ipc_id,device_info.server_ip,device_info.server_port); //uac_send_noSessionMessage(to,from, NULL,"this is no KEY_NAGO1 message","KEY_NAGO1\n"); sessionId id; sip_entity target; memset(&target,0,sizeof(target)); sprintf(target.ip, "%s", device_info.server_ip); target.port=atoi(device_info.server_port); sprintf(target.username, "%s", device_info.ipc_id); alter_message invite_message; memset(&invite_message,0,sizeof(alter_message)); invite_message.body="this is KEY_NAGO1 message"; invite_message.content_type=CONTENT_CODE; invite_message.subject="KEY_NAGO1\n"; uac_sendInvite(&id,&target,&invite_message); //uac_sendInvite(&id,to,"this is no KEY_NAGO1 message","text/code","KEY_NAGO1\n"); //printf("uac_sendInvite sucess\n"); uac_waitfor(&id,EXOSIP_CALL_ANSWERED,&g_event); if(g_event==NULL) { printf("no response\n\n"); return 0; } id.cid=g_event->cid; id.did=g_event->did; if(g_event->type!= EXOSIP_CALL_ANSWERED )//&& g_event->type!=EXOSIP_CALL_MESSAGE_ANSWERED) { //if(g_event->response ) //printf("g_event->response->message:\n"); //if(g_event->response->call_id) //printf("g_event->response->call_id->number:%s\n",g_event->response->call_id->number); printf("g_event->type:%d\n",g_event->type); printf("g_event->cid:%d\n",g_event->cid); printf("not the right response\n"); return 0; } osip_message_t *ack = NULL; eXosip_call_build_ack (id.did, &ack); if(eXosip_call_send_ack (id.did, ack)!=0) { printf("send_ack error\n"); return 0; } osip_message_get_subject(g_event->response,0,&subject); if(subject==NULL) { printf("no subject\n"); return 0; } //printf("subject->hvalue:%s\n",subject->hvalue); if(!strcmp(subject->hvalue,"KEY_NAGO2")) { //do something handle the KEY_NAGO2 osip_body_t *body; osip_message_get_body (g_event->response, 0, &body);//body UnicastKeyNegoRequ *unicast_key_nego_requ_packet_c=(UnicastKeyNegoRequ*)malloc (sizeof(UnicastKeyNegoRequ)*2); if(body->length < sizeof(UnicastKeyNegoRequ)*2) { printf("not valid length"); free(unicast_key_nego_requ_packet_c); return 0; } memcpy(unicast_key_nego_requ_packet_c,body->body, sizeof(UnicastKeyNegoRequ)*2); decodeFromChar(unicast_key_nego_requ_packet_c,sizeof(UnicastKeyNegoRequ)*2); if(HandleUnicastKeyNegoRequest(RegisterCon, unicast_key_nego_requ_packet_c)<1) { printf("HandleUnicastKeyNegoRequest error\n"); free(unicast_key_nego_requ_packet_c); return 0; } id.cid=g_event->cid; id.did=g_event->did; osip_message_t *ack = NULL; printf("id.cid:%d id.did:%d",id.cid,id.did); //eXosip_call_build_ack (id.did, &ack); //eXosip_call_send_ack (id.cid, ack); free(unicast_key_nego_requ_packet_c); eXosip_event_free (g_event); } else { printf("not KEY_NAGO2\n"); printf("g_event->cid:%d\n",g_event->cid); eXosip_event_free (g_event); return 0; } g_event=NULL; UnicastKeyNegoResp *unicast_key_nego_resp_packet_c=(UnicastKeyNegoResp*)malloc (sizeof(UnicastKeyNegoResp)*2); if(ProcessUnicastKeyNegoResponse(RegisterCon, unicast_key_nego_resp_packet_c)<1) { printf("ProcessUnicastKeyNegoResponse error\n"); free(unicast_key_nego_resp_packet_c); return 0; } codeToChar(unicast_key_nego_resp_packet_c,sizeof(UnicastKeyNegoResp)*2); //key_nego 3 alter_message key_nego_message; memset(&key_nego_message,0,sizeof(alter_message)); key_nego_message.body=unicast_key_nego_resp_packet_c; key_nego_message.method_type=METHODMESSAGE; key_nego_message.content_type=CONTENT_CODE; key_nego_message.subject="KEY_NAGO3"; if(uac_send_message(id,&key_nego_message)!=0) { printf("uac_send_message error\n"); free(unicast_key_nego_resp_packet_c); return 0; } free(unicast_key_nego_resp_packet_c); if(!uac_waitfor(&id,EXOSIP_CALL_MESSAGE_ANSWERED,&g_event)) { printf("g_event->type:%d\n",g_event->type); printf("g_event->cid:%d\n",g_event->cid); printf("not the right response\n"); return 0; } if(g_event==NULL) { printf("no response\n\n"); return 0; } osip_message_get_subject(g_event->response,0,&subject); //printf("subject->hvalue:%s",subject->hvalue); if(!strcmp(subject->hvalue,"KEY_NAGO4")) { //do something handle the KEY_NAGO 4 osip_body_t *body; osip_message_get_body (g_event->response, 0, &body); UnicastKeyNegoConfirm *unicast_key_nego_confirm_packet_c=(UnicastKeyNegoConfirm*)malloc (sizeof(UnicastKeyNegoConfirm)*2); if(body->length < sizeof(UnicastKeyNegoConfirm)*2) { printf("not valid length"); free(unicast_key_nego_confirm_packet_c); eXosip_event_free (g_event); return 0; } memcpy(unicast_key_nego_confirm_packet_c,body->body, sizeof(UnicastKeyNegoConfirm)*2); //free(body); decodeFromChar(unicast_key_nego_confirm_packet_c,sizeof(UnicastKeyNegoConfirm)*2); if(HandleUnicastKeyNegoConfirm(RegisterCon, unicast_key_nego_confirm_packet_c)<1) { printf("HandleUnicastKeyNegoConfirm error\n"); free(unicast_key_nego_confirm_packet_c); eXosip_event_free (g_event); return 0; } free(unicast_key_nego_confirm_packet_c); eXosip_event_free (g_event); uac_bye(id); //return 1; } else { printf("not KEY_NAGO4\n"); //printf("g_event->cid:%d\n",g_event->cid); eXosip_event_free (g_event); uac_bye(id); return 0; } //if it is NVR , it will wait for IPC access //if(!strcmp(device_info.ipc_port,"5063")) //{ //user_type=NVR; //printf("user_type is NVR\n"); //} /* if(user_type==NVR) { eXosip_event_t *event; uac_waitfor(NULL, EXOSIP_MESSAGE_NEW,&event); if(event==NULL) { printf("not the right response\n"); return 0; } if(HandleP2PKeyDistribution_request(event)<1) { printf("HandleP2PKeyDistribution_request error\n"); return 0; } } */ printf("uac_key_nego-----finished\n"); return 1; }
int uac_register() { int expires=3600; /* 注册存活时间 */ int ret = 0; /* 注册返回值 */ eXosip_event_t *je = NULL; /* 监听到的消息指针 */ osip_message_t *reg = NULL; /* 注册的消息体指针 */ char from[100];/*sip:主叫用户名@被叫IP地址*/ char proxy[100];/*sip:被叫IP地址:被叫IP端口*/ memset(from, 0, 100); memset(proxy, 0, 100); sprintf(from, "sip:%s@%s", device_info.ipc_id, device_info.server_ip); sprintf(proxy, "sip:%s:%s", device_info.server_ip, device_info.server_port); /*------step 1-----------发送不带认证信息的注册请求-----------------------*/ retry: eXosip_lock(); g_register_id = eXosip_register_build_initial_register(from, proxy, NULL, expires, ®); char mac[12]; memset(mac,0,12); memcpy(mac,RegisterCon->self_MACaddr.macaddr,sizeof(RegisterCon->self_MACaddr.macaddr)); //mac[12]='\n'; //getNetInfo(NULL,mac);//printf("mac:%02x %02x %02x %02x %02x %02x",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); codeToChar(mac,sizeof(mac)); char mac_subject[20]; sprintf(mac_subject,"MAC:%s\r\n",mac); osip_message_set_subject(reg,mac_subject); osip_message_set_authorization(reg, "Capability algorithm=\"H:MD5\""); if (0 > g_register_id) { eXosip_lock(); printf("eXosip_register_build_initial_register error!\r\n"); return -1; } printf("eXosip_register_build_initial_register success!\r\n"); ret = eXosip_register_send_register(g_register_id, reg); eXosip_unlock(); if (0 != ret) { printf("eXosip_register_send_register no authorization error!\r\n"); return -1; } printf("eXosip_register_send_register no authorization success!\r\n"); printf("g_register_id=%d\r\n", g_register_id); for (;;) { je = eXosip_event_wait(10, 500);/*侦听消息的到来*/ if (NULL == je)/*没有接收到消息*/ { continue; } if (EXOSIP_REGISTRATION_FAILURE == je->type)/*注册失败*/ { printf("<EXOSIP_REGISTRATION_FAILURE>\r\n"); printf("je->rid=%d\r\n", je->rid); /*-------step 2---------收到服务器返回的注册失败/401未认证状态------------*/ if ((NULL != je->response)&&(401 == je->response->status_code)) { AuthActive * auth_active_packet_data=NULL; osip_body_t *body; osip_header_t * subject; osip_message_get_subject(je->response,0,&subject); if(subject==NULL) { printf("no subject\n"); return 0; } //printf("subject->hvalue:%s\n",subject->hvalue); char mac[12]; memset(mac, 0, 12); memcpy(mac,subject->hvalue,4); if(!strcmp(mac,"MAC:")) { memcpy(mac,subject->hvalue+4,12); decodeFromChar(mac,12); memcpy(RegisterCon->peer_MACaddr.macaddr,mac,6); } else { printf("subject not match\n"); return 0; } osip_message_get_body (je->response, 0, &body); if(!auth_active_packet_data) { free(auth_active_packet_data); auth_active_packet_data=NULL; } if((sizeof(AuthActive)*2)>(body->length)) { printf("body->length is not enough"); return 0; } auth_active_packet_data=(AuthActive *)malloc (sizeof(AuthActive)*2);//;body->length*sizeof(char)); memset(auth_active_packet_data,0,sizeof(AuthActive)*2); memcpy(auth_active_packet_data,body->body, sizeof(AuthActive)*2); decodeFromChar((char*)auth_active_packet_data,sizeof(AuthActive)*2); if(!HandleWAPIProtocolAuthActive(RegisterCon,auth_active_packet_data)) { printf("HandleWAPIProtocolAuthActive error\n"); return 0; } /* //printf("message:%s\n",message); if(0/*when receive 401Unauthorized package,send ACK and Regester/) { osip_message_t *ack = NULL; int call_id=atoi(reg->call_id->number); printf("je->did:%d\n",je->did); ret=eXosip_call_build_ack(je->rid,&ack); ret=eXosip_call_send_ack(atoi(je->rid),ack); } */ reg = NULL; /*----------step 3-------------发送携带认证信息的注册请求----------------------*/ eXosip_lock(); int return_num; return_num=eXosip_clear_authentication_info();/*清除认证信息*/ printf("return_num:%d\n",return_num); return_num=eXosip_add_authentication_info(device_info.ipc_id, device_info.ipc_id, device_info.ipc_pwd, "MD5", NULL);/*添加主叫用户的认证信息*/ printf("return_num:%d\n",return_num); printf("je->rid:%d expires:%d return num:%d\n",je->rid,expires,eXosip_register_build_register(je->rid, expires, ®)); //if(auth_request_packet_data!=NULL) //{ //free(auth_request_packet_data); //auth_request_packet_data=NULL; //} auth_request_packet_data=(AccessAuthRequ*)malloc(sizeof(AccessAuthRequ)*2); memset(auth_request_packet_data,0, sizeof(AccessAuthRequ)*2); if(ProcessWAPIProtocolAccessAuthRequest(RegisterCon,auth_active_packet_data,auth_request_packet_data)<1) { printf("ProcessWAPIProtocolAccessAuthRequest error\n"); return 0; } codeToChar((char*)auth_request_packet_data,sizeof(AccessAuthRequ)*2); //printf("length:%d",(sizeof(AuthActive)*2)); //printf("length:%d",(sizeof(AccessAuthRequ)*2)); //printf("length:%d",(sizeof(CertificateAuthRequ)*2)); //printf("length:%d",sizeof(CertificateAuthResp)*2); //printf("length:%d",sizeof(AccessAuthResp)*2); printf("111\n"); if(reg==NULL) { printf("reg==NULL\n"); } osip_message_set_body(reg,(char*)auth_request_packet_data,sizeof(AccessAuthRequ)*2);printf("222\n"); printf("333\n"); printf("je->rid:%d\n",je->rid);printf("444\n"); ret = eXosip_register_send_register(je->rid, reg); eXosip_unlock(); decodeFromChar((char *)auth_request_packet_data,sizeof(AccessAuthRequ)*2); if (0 != ret) { printf("eXosip_register_send_register authorization error!\r\n"); return -1; } printf("eXosip_register_send_register authorization success!\r\n"); eXosip_event_free (je); //free(auth_active_packet_data); printf("end\n"); } else/*真正的注册失败*/ { printf("EXOSIP_REGISTRATION_FAILURE error!\r\n"); eXosip_event_free (je); return -1; //goto retry;/*重新注册*/ } } else if (EXOSIP_REGISTRATION_SUCCESS == je->type) {printf("recieve EXOSIP_REGISTRATION_SUCCESS\n"); /*---------step 6-------------收到服务器返回的注册成功--------------------------------*/ AccessAuthResp * access_auth_resp_data; osip_body_t *body; osip_message_get_body (je->response, 0, &body); if(body==NULL) { printf("body==NULL\n"); return 0; } if( body->length<sizeof(AccessAuthResp)*2) { printf("message length is too short:%d\n",body->length); return 0; } access_auth_resp_data=(AccessAuthResp *)malloc (body->length*sizeof(char)); memcpy(access_auth_resp_data,body->body, body->length); decodeFromChar((char*)access_auth_resp_data,sizeof(AccessAuthResp)*2); if(auth_request_packet_data==NULL) { printf("auth_request_packet_data = NULL\n"); } if(HandleWAPIProtocolAccessAuthResp(RegisterCon,auth_request_packet_data,access_auth_resp_data)<1) { printf("HandleWAPIProtocolAccessAuthResp error\n"); return 0; } g_register_id = je->rid;/*保存注册成功的注册ID*/ printf("g_register_id=%d\r\n", g_register_id); printf("<EXOSIP_REGISTRATION_SUCCESS>\r\n"); /* //send key agreement package 发送密钥协商包 osip_message_t * inforequest; ret=eXosip_message_build_request(&inforequest,"MESSAGE",proxy,from,NULL); ret=osip_message_set_body(inforequest,"sssss",6); ret=eXosip_message_send_request(inforequest); */ eXosip_event_free (je); free(auth_request_packet_data); free(access_auth_resp_data); return 1; break; } } return 0; }
int csenn_eXosip_invit(sessionId * id, char * to, char * sdpMessage, char * responseSdp) { osip_message_t *invite; int i;// optionnal route header char to_[100]; snprintf (to_, 100,"sip:%s", to); char from_[100]; snprintf (from_, 100, "sip:%s:%s", device_info.ipc_ip ,device_info.ipc_port ); //snprintf (tmp, 4096, ""); /*i = eXosip_call_build_initial_invite (&invite, "sip:[email protected]:5060", "sip:[email protected]:5060", NULL, "34020000001320000001:1,34020000001180000002:1" );*/ i = eXosip_call_build_initial_invite (&invite, to_, from_, NULL, "This is a call for a conversation" ); //i = eXosip_call_build_initial_invite (&invite,"<sip:[email protected]>", "<sip:[email protected]>",NULL, "This is a call for a conversation" ); if (i != 0) { return -1; } //osip_message_set_supported (invite, "100rel"); { char tmp[4096]; char localip[128]; eXosip_guess_localip (AF_INET, localip, 128); localip[128]=device_info.ipc_ip; i=osip_message_set_body (invite, sdpMessage, strlen (sdpMessage)); i=osip_message_set_content_type (invite, "APPLICATION/SDP"); } eXosip_lock (); i = eXosip_call_send_initial_invite (invite); if (i > 0) { //eXosip_call_set_reference (i, "ssss"); } eXosip_unlock (); int flag1 = 1; while (flag1) { eXosip_event_t *je; je = eXosip_event_wait (0, 1000); if (je == NULL) { printf ("No response or the time is over!\n"); break; } switch (je->type) { case EXOSIP_CALL_INVITE: printf ("a new invite reveived!\n"); break; case EXOSIP_CALL_PROCEEDING: printf ("proceeding!\n"); break; case EXOSIP_CALL_RINGING: printf ("ringing!\n"); //printf ("call_id is %d, dialog_id is %d \n", je->cid, je->did); break; case EXOSIP_CALL_ANSWERED: printf ("ok! connected!\n"); printf ("call_id is %d, dialog_id is %d \n", je->cid, je->did); id->cid=je->cid; id->did=je->did; osip_body_t *body; osip_message_get_body (je->response, 0, &body); //printf ("I get the msg is: %s\n", body->body); //(*responseSdp)=(char *)malloc (body->length*sizeof(char)); if(body!=NULL) snprintf (responseSdp, body->length,"%s", body->body); //response a ack osip_message_t *ack = NULL; eXosip_call_build_ack (je->did, &ack); eXosip_call_send_ack (je->did, ack); flag1 = 0; break; case EXOSIP_CALL_CLOSED: printf ("the other sid closed!\n"); break; case EXOSIP_CALL_ACK: printf ("ACK received!\n"); break; default: printf ("other response!\n"); break; } eXosip_event_free (je); } return 0; }
int HandleP2PKeyDistribution_request(const eXosip_event_t *g_event) { osip_header_t * subject; osip_message_t *message; if(g_event->response!=NULL) { message=g_event->response; } else if(g_event->request!=NULL) { message=g_event->request; } else { printf("no right response or request in HandleP2PKeyDistribution_request\n"); return 0; } osip_message_get_subject(message,0,&subject); if(subject==NULL) { printf("no subject\n"); return 0; } printf("subject->hvalue:%s\n",subject->hvalue); P2PLinkContext *lc; if(!strcmp(subject->hvalue,"KEY_DISTRIBUTE2")) { osip_body_t *body; osip_message_get_body (message, 0, &body); P2PKeyDistribution *p2p_key_dist_packet=(P2PKeyDistribution *)malloc(sizeof(P2PKeyDistribution)*2); if(body->length < sizeof(P2PKeyDistribution)*2) { printf("not valid length"); free(p2p_key_dist_packet); return 0; } memcpy(p2p_key_dist_packet,body->body, sizeof(P2PKeyDistribution)*2); //free(body); decodeFromChar(p2p_key_dist_packet,sizeof(P2PKeyDistribution)*2); //do something handle the KEY_DISTRIBUTE2 lc=(P2PLinkContext *)malloc(sizeof(P2PLinkContext)); //为了避免register 的一个认证bug,该bug于radius有关,现暂时增加这条语句 /* char value[CHARLEN]; get_conf_value( "self_type", value,device_info.cfgFile); if(strcmp(value,"NVR")==0) { Self_type=NVR; }**/ //---------------------------- // 需要改进,因为可能是Client于NVR进行通信 if(user_type==IPC) { P2PLinkContext_Conversion_C(RegisterCon, lc, NVR); } else if(user_type==NVR) { P2PLinkContext_Conversion_C(RegisterCon, lc, IPC); } else printf("user_type:%d",user_type); if(HandleP2PKeyDistribution(lc, p2p_key_dist_packet)<1) { printf("HandleP2PKeyDistribution error\n"); free(lc); return 0; } if(p2pcc!=NULL) { free(p2pcc); } p2pcc=(P2PCommContext *)malloc(sizeof(P2PCommContext)); P2PCommContext_Conversion(lc,p2pcc); free(lc); free(p2p_key_dist_packet); return 1; } else { printf("not KEY_DISTRIBUTE2\n"); return 0; } }
int GB_handle_RCV_REQUEST(GB_CONNECT_STATE *gb_cons, osip_event_t * osip_event) { osip_body_t *mbody = NULL; int pos = 0; int code = -1; void *Req = NULL; if(gb_cons == NULL || osip_event == NULL || osip_event->sip == NULL || osip_event->sip->sip_method == NULL) { return -1; } if(strcmp(osip_event->sip->sip_method, GB_SIP_METHOD_MESSAGE) == 0) { osip_message_get_body(osip_event->sip, pos, &mbody); pos++; if(mbody == NULL || mbody->body == NULL) { GB_Send_Reply(gb_cons,osip_event,400); return -1; } gb_parser_Req_XML(mbody->body, &code, &Req); switch(code) { case Code_Query_Req: { GB_Deal_Query_Req(gb_cons, osip_event, (gb_Query_Req_Struct *)Req); GB_Free_Query_Req((gb_Query_Req_Struct *)Req); } break; case Code_Control_Req: { GB_Deal_Control_Req(gb_cons, osip_event, (gb_Control_Req_Struct *) Req); GB_Free_Control_Req((gb_Control_Req_Struct *) Req); } break; default: { } break; } return 0; } else if(strcmp(osip_event->sip->sip_method, GB_SIP_METHOD_BYE) == 0) { GB_media_session media_session; int chn = -1; osip_uri_param_t *tag = NULL; SN_MEMSET(&media_session,0,sizeof(media_session)); if(osip_event->sip->to == NULL || osip_event->sip->to->url == NULL || osip_event->sip->to->url->username == NULL || osip_event->sip->from == NULL || osip_event->sip->from->url == NULL || osip_event->sip->from->url->username == NULL) { TRACE(SCI_TRACE_NORMAL,MOD_GB,"%s line=%d Something is NULL\n",__FUNCTION__,__LINE__); return -1; } DeviceID2LocalChn(osip_event->sip->to->url->username,&chn); TRACE(SCI_TRACE_NORMAL,MOD_GB,"%s line=%d BYE from:%s to:%s\n",__FUNCTION__,__LINE__, osip_event->sip->from->url->username,osip_event->sip->to->url->username); if(chn <= 0) { TRACE(SCI_TRACE_NORMAL,MOD_GB,"%s Unknow DeviceID(%s)\n",__FUNCTION__,osip_event->sip->req_uri->username); } else { osip_from_get_tag(osip_event->sip->from,&tag); if(tag == NULL || tag->gvalue == NULL) { TRACE(SCI_TRACE_NORMAL,MOD_GB,"%s Can't Find Tag!\n",__FUNCTION__); GB_Send_Reply(gb_cons,osip_event,400); return 0; } else { media_session.chn = chn - 1; media_session.media_session_opt = MEDIA_SESSION_OPT_BYE; SN_STRCPY(media_session.TagID,sizeof(media_session.TagID),tag->gvalue); write(gb_msg_sock.client_fd, (void *)&media_session, sizeof(media_session)); } } GB_Send_Reply(gb_cons,osip_event,200); return 0; } GB_Send_Reply(gb_cons,osip_event,400); return 0; }
void stack::call::reinvite(thread *thread, session *s) { voip::msg_t reply = NULL; voip::body_t body = NULL; voip::did_t did = source->did; voip::context_t ctx = source->context; session *update = source; bool holding = false; char *sdp; int error = 200; assert(thread != NULL); assert(s != NULL); Mutex::protect(this); if(s == source) { update = target; if(target) { ctx = target->context; did = target->did; } else goto unconnected; } s->tid = thread->sevent->tid; body = NULL; osip_message_get_body(thread->sevent->request, 0, &body); switch(state) { case RINGING: case RINGBACK: case TRYING: case ANSWERED: if(s == source) { unconnected: Mutex::release(this); if(voip::make_answer_response(source->context, source->tid, 500, &reply)) { voip::header(reply, "Reply-After", "8"); stack::siplog(reply); voip::send_answer_response(source->context, source->tid, 500, reply); } return; } if(state != ANSWERED && state != RINGBACK) { joinLocked(s); if(state != ANSWERED) set(RINGBACK, 'r', "ringback"); } if(thread->header_expires) { time(&expires); expires += thread->header_expires; arm((timeout_t)(thread->header_expires * 1000l)); } Mutex::release(this); if(voip::make_answer_response(source->context, source->tid, 200, &reply)) { voip::server_requires(reply, "100rel"); voip::header(reply, "RSeq", "1"); if(body && body->body) { sdp = media::reinvite(s, body->body); if(sdp) voip::attach(reply, SDP_BODY, sdp); else error = SIP_TEMPORARILY_UNAVAILABLE; } stack::siplog(reply); voip::send_answer_response(source->context, source->tid, error, reply); } return; case HOLDING: case JOINED: if(holding) set(HOLDING, 'h', "holding"); else set(JOINED, 'j', "joined"); if(thread->header_expires) { time(&expires); expires += thread->header_expires; arm((timeout_t)(thread->header_expires * 1000l)); } Mutex::release(this); if(voip::make_dialog_request(ctx, did, "INVITE", &reply)) { if(stack::sip_protocol == IPPROTO_UDP) voip::server_supports(reply, "100rel,replaces"); if(body && body->body) voip::attach(reply, SDP_BODY, body->body); stack::siplog(reply); voip::send_dialog_message(ctx, did, reply); update->state = session::REINVITE; } if(!reply) goto failed; return; default: break; } Mutex::release(this); failed: shell::debug(2, "reinvite failed for call %08x:%u", source->sequence, source->cid); failed(thread, s); }
/* * Processing. * */ int PLUGIN_PROCESS(int stage, sip_ticket_t *ticket){ /* stage contains the PLUGIN_* value - the stage of SIP processing. */ int sts; char *buff; size_t buflen; osip_body_t *body; sdp_message_t *sdp; int content_length; osip_content_type_t *content_type; char clen[8]; /* content length: probably never more than 7 digits !*/ // // check that we have the expected payload "application/sdp" // // get content length content_length=0; if (ticket->sipmsg && ticket->sipmsg->content_length && ticket->sipmsg->content_length->value) { sts=sscanf(ticket->sipmsg->content_length->value, "%i", &content_length); } // check if we have a content type defined and that payload length >0 content_type=osip_message_get_content_type(ticket->sipmsg); if ((content_length == 0) || (content_type == NULL) || (content_type->type == NULL) || (content_type->subtype == NULL)) { DEBUGC(DBCLASS_PLUGIN, "%s: no content", name); return STS_SUCCESS; } // check content type: must be "application/sdp" if ((strncmp(content_type->type, "application", sizeof("application")) != 0) || (strncmp(content_type->subtype, "sdp", sizeof("sdp")) != 0)) { DEBUGC(DBCLASS_PLUGIN, "%s: unsupported content-type %s/%s", name, content_type->type, content_type->subtype); return STS_SUCCESS; } DEBUGC(DBCLASS_PLUGIN, "%s: content-type %s/%s, size=%i", name, content_type->type, content_type->subtype, content_length); // // parse the payload // // get a pointer to the payload of the SIP packet sts = osip_message_get_body(ticket->sipmsg, 0, &body); if (sts != 0) { DEBUGC(DBCLASS_PLUGIN, "%s: no body found in message", name); return STS_SUCCESS; } // dump it into a buffer sts = sip_body_to_str(body, &buff, &buflen); if (sts != 0) { WARN("%s: unable to sip_body_to_str", name); return STS_SUCCESS; } // and parse it into an SDP structure sts = sdp_message_init(&sdp); sts = sdp_message_parse (sdp, buff); if (sts != 0) { WARN("%s: unable to sdp_message_parse() body", name); DUMP_BUFFER(-1, buff, buflen); osip_free(buff); buff=NULL; sdp_message_free(sdp); return STS_SUCCESS; } osip_free(buff); buff=NULL; // // now do the codec filtering magic... sdp_filter_codec(sdp); // // replace the original payload with the new modified payload // // remove old body from SIP packet sts = osip_list_remove(&(ticket->sipmsg->bodies), 0); osip_body_free(body); body=NULL; // dump new body to buffer sdp_message_to_str(sdp, &buff); buflen=strlen(buff); // free sdp structure (no longer needed) sdp_message_free(sdp); sdp=NULL; // put new body into SIP message sts=sip_message_set_body(ticket->sipmsg, buff, buflen); if (sts != 0) { ERROR("%s: unable to sip_message_set_body body", name); DUMP_BUFFER(-1, buff, buflen); buflen=0; } // free buffer osip_free(buff); buff=NULL; // // set new content length // // remove old content leght field osip_content_length_free(ticket->sipmsg->content_length); ticket->sipmsg->content_length=NULL; // set new content length sprintf(clen,"%ld",(long)buflen); sts = osip_message_set_content_length(ticket->sipmsg, clen); return STS_SUCCESS; }
void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){ SalOp *op=sal_find_out_subscribe(sal,ev->sid); char *tmp; osip_from_t *from=NULL; osip_body_t *body=NULL; SalPresenceStatus estatus=SalPresenceOffline; ms_message("Receiving notify with sid=%i,nid=%i",ev->sid,ev->nid); if (op==NULL){ ms_error("No operation related to this notify !"); return; } if (ev->request==NULL) return; from=ev->request->from; osip_message_get_body(ev->request,0,&body); if (body==NULL){ ms_error("No body in NOTIFY"); return; } osip_from_to_str(from,&tmp); if (strstr(body->body,"pending")!=NULL){ estatus=SalPresenceOffline; }else if (strstr(body->body,"busy")!=NULL){ estatus=SalPresenceBusy; }else if (strstr(body->body,"berightback")!=NULL || strstr(body->body,"in-transit")!=NULL ){ estatus=SalPresenceBerightback; }else if (strstr(body->body,"away")!=NULL || strstr(body->body,"idle")){ estatus=SalPresenceAway; }else if (strstr(body->body,"onthephone")!=NULL || strstr(body->body,"on-the-phone")!=NULL){ estatus=SalPresenceOnthephone; }else if (strstr(body->body,"outtolunch")!=NULL || strstr(body->body,"lunch") != NULL || strstr(body->body,"meal")!=NULL){ estatus=SalPresenceOuttolunch; }else if (strstr(body->body,"closed")!=NULL){ estatus=SalPresenceOffline; }else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) { estatus=SalPresenceOnline; }else if(strstr(body->body,"vacation") != NULL) { estatus = SalPresenceOnVacation; }else{ estatus=SalPresenceOffline; } ms_message("We are notified that %s has online status %i",tmp,estatus); if (ev->ss_status==EXOSIP_SUBCRSTATE_TERMINATED) { sal_remove_out_subscribe(sal,op); op->sid=-1; op->did=-1; ms_message("And outgoing subscription terminated by remote."); } sal->callbacks.notify_presence(op,op->sid!=-1 ? SalSubscribeActive : SalSubscribeTerminated, estatus,NULL); /* try to detect presence message style used by server, * and switch our presence messages to servers style */ if (strstr (body->body, "//IETF//DTD RFCxxxx XPIDF 1.0//EN") != NULL) { presence_style = RFCxxxx; } else if (strstr(body->body,"http://schemas.microsoft.com/2002/09/sip/presence")!=NULL) { presence_style = MSOLDPRES; } osip_free(tmp); }