Example #1
0
PJ_DEF(pj_status_t) pj_init(void)
{
    WSADATA wsa;
    char dummy_guid[32]; /* use maximum GUID length */
    pj_str_t guid;

    PJ_LOG(5, ("pj_init", "Initializing PJ Library.."));

    /* Init Winsock.. */
    if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) {
	PJ_LOG(1, ("pj_init", "Winsock initialization has returned an error"));
	return -1;
    }

    /* Init this thread's TLS. */
    if (pj_thread_init() != 0) {
	PJ_LOG(1, ("pj_init", "Thread initialization has returned an error"));
	return -1;
    }
    
    /* Init random seed. */
    srand( GetCurrentProcessId() );

    /* Startup GUID. */
    guid.ptr = dummy_guid;
    pj_generate_unique_string( &guid );

    /* Initialize critical section. */
    if (init_mutex(&critical_section_mutex, "pj%p") != 0)
	return -1;

    return PJ_OK;
}
Example #2
0
PJ_DEF(pj_status_t) pj_init(void)
{
    char dummy_guid[PJ_GUID_LENGTH];
    pj_str_t guid;

    PJ_LOG(5, ("pj_init", "Initializing PJ Library.."));

    /* Init this thread's TLS. */
#if PJ_HAS_THREADS
    if (pj_thread_init() != 0) {
	PJ_LOG(1, ("pj_init", "Thread initialization has returned an error"));
	return -1;
    }

    /* Critical section. */
    if (init_mutex(&critical_section, "critsec", PJ_MUTEX_SIMPLE) != 0)
	return -1;

#endif
    
    /* Init random seed. */
    srand( clock() );

    /* Startup GUID. */
    guid.ptr = dummy_guid;
    pj_generate_unique_string( &guid );


    return PJ_OK;
}
Example #3
0
/*
 * pj_init(void).
 * Init PJLIB!
 */
PJ_DEF(pj_status_t) pj_init(void)
{
    char dummy_guid[PJ_GUID_MAX_LENGTH];
    pj_str_t guid;
    pj_status_t rc;

#if PJ_HAS_THREADS
    /* Init this thread's TLS. */
    if ((rc=pj_thread_init()) != 0) {
	return rc;
    }

    /* Critical section. */
    if ((rc=init_mutex(&critical_section, "critsec", PJ_MUTEX_RECURSE)) != 0)
	return rc;

#endif

    /* Init logging */
    pj_log_init();

    /* Initialize exception ID for the pool. 
     * Must do so after critical section is configured.
     */
    rc = pj_exception_id_alloc("PJLIB/No memory", &PJ_NO_MEMORY_EXCEPTION);
    if (rc != PJ_SUCCESS)
        return rc;
    
    /* Init random seed. */
    /* Or probably not. Let application in charge of this */
    /* pj_srand( clock() ); */

    /* Startup GUID. */
    guid.ptr = dummy_guid;
    pj_generate_unique_string( &guid );

    /* Startup timestamp */
#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
    {
	pj_timestamp dummy_ts;
	if ((rc=pj_get_timestamp(&dummy_ts)) != 0) {
	    return rc;
	}
    }
#endif   

    PJ_LOG(4,(THIS_FILE, "pjlib %s for POSIX initialized",
	      PJ_VERSION));

    return PJ_SUCCESS;
}
Example #4
0
PJ_DEF(pj_str_t) pjsip_calculate_branch_id( pjsip_rx_data *rdata )
{
    pj_md5_context ctx;
    pj_uint8_t digest[16];
    pj_str_t branch;
    pj_str_t rfc3261_branch = {PJSIP_RFC3261_BRANCH_ID, 
                               PJSIP_RFC3261_BRANCH_LEN};

    /* If incoming request does not have RFC 3261 branch value, create
     * a branch value from GUID .
     */
    if (pj_strncmp(&rdata->msg_info.via->branch_param, 
		   &rfc3261_branch, PJSIP_RFC3261_BRANCH_LEN) != 0 ) 
    {
	pj_str_t tmp;

	branch.ptr = (char*)
		     pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_BRANCH_LEN);
	branch.slen = PJSIP_RFC3261_BRANCH_LEN;
	pj_memcpy(branch.ptr, PJSIP_RFC3261_BRANCH_ID, 
	          PJSIP_RFC3261_BRANCH_LEN);

	tmp.ptr = branch.ptr + PJSIP_RFC3261_BRANCH_LEN + 2;
	*(tmp.ptr-2) = (pj_int8_t)(branch.slen+73); 
	*(tmp.ptr-1) = (pj_int8_t)(branch.slen+99);
	pj_generate_unique_string( &tmp );

	branch.slen = PJSIP_MAX_BRANCH_LEN;
	return branch;
    }

    /* Create branch ID for new request by calculating MD5 hash
     * of the branch parameter in top-most Via header.
     */
    pj_md5_init(&ctx);
    pj_md5_update(&ctx, (pj_uint8_t*)rdata->msg_info.via->branch_param.ptr,
		  rdata->msg_info.via->branch_param.slen);
    pj_md5_final(&ctx, digest);

    branch.ptr = (char*)
    		 pj_pool_alloc(rdata->tp_info.pool, 
			       34 + PJSIP_RFC3261_BRANCH_LEN);
    pj_memcpy(branch.ptr, PJSIP_RFC3261_BRANCH_ID, PJSIP_RFC3261_BRANCH_LEN);
    branch.slen = PJSIP_RFC3261_BRANCH_LEN;
    *(branch.ptr+PJSIP_RFC3261_BRANCH_LEN) = (pj_int8_t)(branch.slen+73);
    *(branch.ptr+PJSIP_RFC3261_BRANCH_LEN+1) = (pj_int8_t)(branch.slen+99);
    digest2str(digest, branch.ptr+PJSIP_RFC3261_BRANCH_LEN+2);
    branch.slen = 34 + PJSIP_RFC3261_BRANCH_LEN;

    return branch;
}
Example #5
0
/// Substitutes the branch identifier in the top Via header with a new unique
/// identifier.  This is used when forking requests and when retrying requests
/// to alternate servers.  This code is taken from pjsip_generate_branch_id
/// for the case when the branch ID is calculated from a GUID.
void PJUtils::generate_new_branch_id(pjsip_tx_data* tdata)
{
  pjsip_via_hdr* via = (pjsip_via_hdr*)
                             pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
  via->branch_param.ptr = (char*)
                              pj_pool_alloc(tdata->pool, PJSIP_MAX_BRANCH_LEN);
  via->branch_param.slen = PJSIP_RFC3261_BRANCH_LEN;
  pj_memcpy(via->branch_param.ptr,
            PJSIP_RFC3261_BRANCH_ID,
            PJSIP_RFC3261_BRANCH_LEN);

  pj_str_t tmp;
  tmp.ptr = via->branch_param.ptr + PJSIP_RFC3261_BRANCH_LEN + 2;
  // Add "Pj" between the RFC3261 prefix and the random string to be consistent
  // with branch IDs generated by PJSIP.
  *(tmp.ptr-2) = 'P';
  *(tmp.ptr-1) = 'j';
  pj_generate_unique_string(&tmp);

  via->branch_param.slen = PJSIP_MAX_BRANCH_LEN;
}
Example #6
0
/*
 * Add RPID element into existing PIDF document.
 */
PJ_DEF(pj_status_t) pjrpid_add_element(pjpidf_pres *pres, 
				       pj_pool_t *pool,
				       unsigned options,
				       const pjrpid_element *elem)
{
    pj_xml_node *nd_person, *nd_activities, *nd_activity, *nd_note;
    pj_xml_attr *attr;

    PJ_ASSERT_RETURN(pres && pool && options==0 && elem, PJ_EINVAL);

    PJ_UNUSED_ARG(options);

    /* Check if we need to add RPID information into the PIDF document. */
    if (elem->id.slen==0 && 
	elem->activity==PJRPID_ACTIVITY_UNKNOWN &&
	elem->note.slen==0)
    {
	/* No RPID information to be added. */
	return PJ_SUCCESS;
    }

    /* Add <note> to <tuple> */
    if (elem->note.slen != 0) {
	pj_xml_node *nd_tuple;

	nd_tuple = find_node(pres, "tuple");

	if (nd_tuple) {
	    nd_note = pj_xml_node_new(pool, &NOTE);
	    pj_strdup(pool, &nd_note->content, &elem->note);
	    pj_xml_add_node(nd_tuple, nd_note);
	    nd_note = NULL;
	}
    }

    /* Update namespace */
    update_namespaces(pres, pool);

    /* Add <person> */
    nd_person = pj_xml_node_new(pool, &DM_PERSON);
    if (elem->id.slen != 0) {
	attr = pj_xml_attr_new(pool, &ID, &elem->id);
    } else {
	pj_str_t person_id;
	/* xs:ID must start with letter */
	//pj_create_unique_string(pool, &person_id);
	person_id.ptr = (char*)pj_pool_alloc(pool, PJ_GUID_STRING_LENGTH+2);
	person_id.ptr += 2;
	pj_generate_unique_string(&person_id);
	person_id.ptr -= 2;
	person_id.ptr[0] = 'p';
	person_id.ptr[1] = 'j';
	person_id.slen += 2;

	attr = pj_xml_attr_new(pool, &ID, &person_id);
    }
    pj_xml_add_attr(nd_person, attr);
    pj_xml_add_node(pres, nd_person);

    /* Add <activities> */
    nd_activities = pj_xml_node_new(pool, &RPID_ACTIVITIES);
    pj_xml_add_node(nd_person, nd_activities);

    /* Add the activity */
    switch (elem->activity) {
    case PJRPID_ACTIVITY_AWAY:
	nd_activity = pj_xml_node_new(pool, &RPID_AWAY);
	break;
    case PJRPID_ACTIVITY_BUSY:
	nd_activity = pj_xml_node_new(pool, &RPID_BUSY);
	break;
    case PJRPID_ACTIVITY_UNKNOWN:
    default:
	nd_activity = pj_xml_node_new(pool, &RPID_UNKNOWN);
	break;
    }
    pj_xml_add_node(nd_activities, nd_activity);

    /* Add custom text if required. */
    if (elem->note.slen != 0) {
	nd_note = pj_xml_node_new(pool, &DM_NOTE);
	pj_strdup(pool, &nd_note->content, &elem->note);
	pj_xml_add_node(nd_person, nd_note);
    }

    /* Done */
    return PJ_SUCCESS;
}
Example #7
0
pjsip_tx_data* PJUtils::clone_tdata(pjsip_tx_data* tdata)
{
  pjsip_tx_data* cloned_tdata;
  pj_status_t status;

  status = pjsip_endpt_create_tdata(stack_data.endpt, &cloned_tdata);
  if (status != PJ_SUCCESS)
  {
    return NULL;
  }

  // Always increment ref counter to 1.
  pjsip_tx_data_add_ref(cloned_tdata);

  // Clone the message from the supplied tdata.
  cloned_tdata->msg = pjsip_msg_clone(cloned_tdata->pool, tdata->msg);

  if (cloned_tdata->msg == NULL)
  {
    pjsip_tx_data_dec_ref(cloned_tdata);
    cloned_tdata = NULL;
  }

  // Copy the trail identifier to the cloned message.
  set_trail(cloned_tdata, get_trail(tdata));

  if (tdata->msg->type == PJSIP_REQUEST_MSG)
  {
    // Substitute the branch value in the top Via header with a unique
    // branch identifier.
    pjsip_via_hdr* via = (pjsip_via_hdr*)
                         pjsip_msg_find_hdr(cloned_tdata->msg, PJSIP_H_VIA, NULL);
    via->branch_param.ptr = (char*)
                            pj_pool_alloc(cloned_tdata->pool, PJSIP_MAX_BRANCH_LEN);
    via->branch_param.slen = PJSIP_RFC3261_BRANCH_LEN;
    pj_memcpy(via->branch_param.ptr,
              PJSIP_RFC3261_BRANCH_ID, PJSIP_RFC3261_BRANCH_LEN);

    pj_str_t tmp;
    tmp.ptr = via->branch_param.ptr + PJSIP_RFC3261_BRANCH_LEN + 2;
    // I have absolutely no idea what the following two lines do, but it
    // doesn't seem to work without them!
    *(tmp.ptr-2) = (pj_int8_t)(via->branch_param.slen+73);
    *(tmp.ptr-1) = (pj_int8_t)(via->branch_param.slen+99);
    pj_generate_unique_string( &tmp );

    via->branch_param.slen = PJSIP_MAX_BRANCH_LEN;
  }

  // If the original message already had a specified transport set this
  // on the clone.  (Must use pjsip_tx_data_set_transport to ensure
  // reference counts get updated.)
  if (tdata->tp_sel.type == PJSIP_TPSELECTOR_TRANSPORT)
  {
    pjsip_tx_data_set_transport(cloned_tdata, &tdata->tp_sel);
  }

  // If the message has any addr in dest_info, copy that
  if (tdata->dest_info.addr.count != 0)
  {
    pj_memcpy(&cloned_tdata->dest_info, &tdata->dest_info, sizeof(cloned_tdata->dest_info));
  }

  return cloned_tdata;
}
Example #8
0
/*
 * This is a utility function to create PIDF message body from PJSIP
 * presence status (pjsip_pres_status).
 */
PJ_DEF(pj_status_t) pjsip_pres_create_pidf( pj_pool_t *pool,
					    const pjsip_pres_status *status,
					    const pj_str_t *entity,
					    pjsip_msg_body **p_body )
{
    pjpidf_pres *pidf;
    pjsip_msg_body *body;
    unsigned i;

    /* Create <presence>. */
    pidf = pjpidf_create(pool, entity);

    /* Create <tuple> */
    for (i=0; i<status->info_cnt; ++i) {

	pjpidf_tuple *pidf_tuple;
	pjpidf_status *pidf_status;
	pj_str_t id;

	/* Add tuple id. */
	if (status->info[i].id.slen == 0) {
	    /* xs:ID must start with letter */
	    //pj_create_unique_string(pool, &id);
	    id.ptr = (char*)pj_pool_alloc(pool, PJ_GUID_STRING_LENGTH+2);
	    id.ptr += 2;
	    pj_generate_unique_string(&id);
	    id.ptr -= 2;
	    id.ptr[0] = 'p';
	    id.ptr[1] = 'j';
	    id.slen += 2;
	} else {
	    id = status->info[i].id;
	}

	pidf_tuple = pjpidf_pres_add_tuple(pool, pidf, &id);

	/* Set <contact> */
	if (status->info[i].contact.slen)
	    pjpidf_tuple_set_contact(pool, pidf_tuple, 
				     &status->info[i].contact);


	/* Set basic status */
	pidf_status = pjpidf_tuple_get_status(pidf_tuple);
	pjpidf_status_set_basic_open(pidf_status, 
				     status->info[i].basic_open);

	/* Add <timestamp> if configured */
#if defined(PJSIP_PRES_PIDF_ADD_TIMESTAMP) && PJSIP_PRES_PIDF_ADD_TIMESTAMP
	if (PJSIP_PRES_PIDF_ADD_TIMESTAMP) {
	  char buf[50];
	  int tslen = 0;
	  pj_time_val tv;
	  pj_parsed_time pt;

	  pj_gettimeofday(&tv);
	  /* TODO: convert time to GMT! (unsupported by pjlib) */
	  pj_time_decode( &tv, &pt);

	  tslen = pj_ansi_snprintf(buf, sizeof(buf),
				   "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ",
				   pt.year, pt.mon+1, pt.day, 
				   pt.hour, pt.min, pt.sec, pt.msec);
	  if (tslen > 0 && tslen < sizeof(buf)) {
	      pj_str_t time = pj_str(buf);
	      pjpidf_tuple_set_timestamp(pool, pidf_tuple, &time);
	  }
	}
#endif
    }

    /* Create <person> (RPID) */
    if (status->info_cnt) {
	pjrpid_add_element(pidf, pool, 0, &status->info[0].rpid);
    }

    body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);
    body->data = pidf;
    body->content_type.type = STR_APPLICATION;
    body->content_type.subtype = STR_PIDF_XML;
    body->print_body = &pres_print_body;
    body->clone_data = &xml_clone_data;

    *p_body = body;

    return PJ_SUCCESS;    
}
Example #9
0
/*
 * pj_init(void).
 * Init PJLIB!
 */
PJ_DEF(pj_status_t) pj_init(void)
{
    WSADATA wsa;
    char dummy_guid[32]; /* use maximum GUID length */
    pj_str_t guid;
    pj_status_t rc;

    /* Check if PJLIB have been initialized */
    if (initialized) {
	++initialized;
	return PJ_SUCCESS;
    }

    /* Init Winsock.. */
    if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) {
	return PJ_RETURN_OS_ERROR(WSAGetLastError());
    }

    /* Init this thread's TLS. */
    if ((rc=pj_thread_init()) != PJ_SUCCESS) {
	return rc;
    }
    
    /* Init logging */
    pj_log_init();

    /* Init random seed. */
    /* Or probably not. Let application in charge of this */
    /* pj_srand( GetCurrentProcessId() ); */

    /* Initialize critical section. */
    if ((rc=init_mutex(&critical_section_mutex, "pj%p")) != PJ_SUCCESS)
	return rc;

    /* Startup GUID. */
    guid.ptr = dummy_guid;
    pj_generate_unique_string( &guid );

    /* Initialize exception ID for the pool. 
     * Must do so after critical section is configured.
     */
    rc = pj_exception_id_alloc("PJLIB/No memory", &PJ_NO_MEMORY_EXCEPTION);
    if (rc != PJ_SUCCESS)
        return rc;

    /* Startup timestamp */
#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
    {
	pj_timestamp dummy_ts;
	if ((rc=pj_get_timestamp_freq(&dummy_ts)) != PJ_SUCCESS) {
	    return rc;
	}
	if ((rc=pj_get_timestamp(&dummy_ts)) != PJ_SUCCESS) {
	    return rc;
	}
    }
#endif   

    /* Flag PJLIB as initialized */
    ++initialized;
    pj_assert(initialized == 1);

    PJ_LOG(4,(THIS_FILE, "pjlib %s for win32 initialized",
	      PJ_VERSION));

    return PJ_SUCCESS;
}
Example #10
0
/*
 * pj_sem_create()
 */
PJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool, 
				   const char *name,
				   unsigned initial, 
				   unsigned max,
				   pj_sem_t **ptr_sem)
{
#if PJ_HAS_THREADS
    pj_sem_t *sem;

    PJ_CHECK_STACK();
    PJ_ASSERT_RETURN(pool != NULL && ptr_sem != NULL, PJ_EINVAL);

    sem = PJ_POOL_ALLOC_T(pool, pj_sem_t);
    PJ_ASSERT_RETURN(sem, PJ_ENOMEM);

#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
    /* MacOS X doesn't support anonymous semaphore */
    {
	char sem_name[PJ_GUID_MAX_LENGTH+1];
	pj_str_t nam;

	/* We should use SEM_NAME_LEN, but this doesn't seem to be 
	 * declared anywhere? The value here is just from trial and error
	 * to get the longest name supported.
	 */
#	define MAX_SEM_NAME_LEN	23

	/* Create a unique name for the semaphore. */
	if (PJ_GUID_STRING_LENGTH <= MAX_SEM_NAME_LEN) {
	    nam.ptr = sem_name;
	    pj_generate_unique_string(&nam);
	    sem_name[nam.slen] = '\0';
	} else {
	    pj_create_random_string(sem_name, MAX_SEM_NAME_LEN);
	    sem_name[MAX_SEM_NAME_LEN] = '\0';
	}

	/* Create semaphore */
	sem->sem = sem_open(sem_name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, 
			    initial);
	if (sem->sem == SEM_FAILED)
	    return PJ_RETURN_OS_ERROR(pj_get_native_os_error());

	/* And immediately release the name as we don't need it */
	sem_unlink(sem_name);
    }
#else
    sem->sem = PJ_POOL_ALLOC_T(pool, sem_t);
    if (sem_init( sem->sem, 0, initial) != 0) 
	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
#endif
    
    /* Set name. */
    if (!name) {
	name = "sem%p";
    }
    if (strchr(name, '%')) {
	pj_ansi_snprintf(sem->obj_name, PJ_MAX_OBJ_NAME, name, sem);
    } else {
	strncpy(sem->obj_name, name, PJ_MAX_OBJ_NAME);
	sem->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
    }

    PJ_LOG(6, (sem->obj_name, "Semaphore created"));

    *ptr_sem = sem;
    return PJ_SUCCESS;
#else
    *ptr_sem = (pj_sem_t*)1;
    return PJ_SUCCESS;
#endif
}
Example #11
0
PJ_DEF(void) pj_create_unique_string(pj_pool_t *pool, pj_str_t *str)
{
    str->ptr = (char*)pj_pool_alloc(pool, PJ_GUID_STRING_LENGTH);
    pj_generate_unique_string(str);
}