Example #1
0
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);
    }
}
Example #2
0
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;
}
Example #3
0
File: proxy.c Project: OPSF/uClinux
/*
 * 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;
}
Example #4
0
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;
}
Example #5
0
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, &reg);
		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, &reg));

					//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;
}
Example #6
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;

}
Example #7
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;
	}


}
Example #8
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;
}
Example #9
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);
}