示例#1
0
/*
 * rm_create
 *
 * Description:
 *    Allocates and initializes a new resource manager
 *
 * Parameters:
 *    max_element - Maximum number of elements the resource manager
 *                  is required to track
 *
 * Returns:
 *    If successful, pointer to the newly allocated resource manager
 *    If not successful, NULL
 */
resource_manager_t *
rm_create (int16_t max_element)
{
    static const char fname[] = "rm_create";
    resource_manager_t *rm_p;

    if (max_element < 0) {
        PLAT_ERROR(PLAT_COMMON_F_PREFIX"invalid max element %d received.\n", fname,
               max_element);
        return NULL;
    }

    rm_p = (resource_manager_t *) cpr_malloc(sizeof(resource_manager_t));
    if (!rm_p) {
        PLAT_ERROR(PLAT_COMMON_F_PREFIX"unable to allocate resource manager.\n", fname);
        return NULL;
    }

    rm_p->max_element = max_element;
    rm_p->max_index = max_element / RM_NUM_ELEMENTS_PER_MAP + 1;

    rm_p->table = (uint32_t *)
        cpr_malloc(rm_p->max_index * RM_NUM_ELEMENTS_PER_MAP);
    if (!rm_p->table) {
        free(rm_p);
        return NULL;
    }
    rm_clear_all_elements(rm_p);
    return rm_p;
}
/**
 * cprCreateMutex
 *
 * Creates a mutual exclusion block
 *
 * Parameters: name  - name of the mutex
 *
 * Return Value: Mutex handle or NULL if creation failed.
 */
cprMutex_t
cprCreateMutex (const char *name)
{
    cpr_mutex_t *cprMutexPtr;
    static char fname[] = "cprCreateMutex";
	WCHAR* wname;

    /*
     * Malloc memory for a new mutex. CPR has its' own
     * set of mutexes so malloc one for the generic
     * CPR view and one for the CNU specific version.
     */
    cprMutexPtr = (cpr_mutex_t *) cpr_malloc(sizeof(cpr_mutex_t));
    if (cprMutexPtr != NULL) {
        /* Assign name if one was passed in */
        if (name != NULL) {
            cprMutexPtr->name = name;
        }

		wname = cpr_malloc((strlen(name) + 1) * sizeof(WCHAR));
		mbstowcs(wname, name, strlen(name));
        cprMutexPtr->u.handlePtr = CreateMutex(NULL, FALSE, wname);
		cpr_free(wname);

        if (cprMutexPtr->u.handlePtr == NULL) {
            CPR_ERROR("%s - Mutex init failure: %d\n", fname, GetLastError());
            cpr_free(cprMutexPtr);
            cprMutexPtr = NULL;
        }
    }
    return cprMutexPtr;

}
int
sip_platform_msg_timer_subnot_start (uint32_t msec,
                                     sipPlatformUITimer_t *timer_p,
                                     uint32_t id,
                                     char *message_buffer,
                                     int message_buffer_len,
                                     int message_type,
                                     cpr_ip_addr_t *ipaddr,
                                     uint16_t port)
{
    static const char fname[] = "sip_platform_msg_timer_start_subnot";

    sip_platform_msg_timer_subnot_stop(timer_p);

    if (message_buffer_len > SIP_UDP_MESSAGE_SIZE) {
        CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_MSG_BUFFER_TOO_BIG),
                          fname, message_buffer_len);
        return SIP_ERROR;
    }

    if (timer_p->message_buffer == NULL) {
        timer_p->message_buffer = (char *)cpr_malloc(message_buffer_len+1);
        if (timer_p->message_buffer == NULL) return SIP_ERROR;
    }
    else if (timer_p->message_buffer != message_buffer) {
        cpr_free(timer_p->message_buffer);
        timer_p->message_buffer = (char *)cpr_malloc(message_buffer_len+1);
        if (timer_p->message_buffer == NULL) return SIP_ERROR;
    }

    timer_p->message_buffer_len = message_buffer_len;
    timer_p->message_buffer[message_buffer_len] = '\0';
    memcpy(timer_p->message_buffer, message_buffer,
           message_buffer_len);
    timer_p->message_type =
        (sipMethod_t) message_type;
    timer_p->ipaddr = *ipaddr;
    timer_p->port = port;

    if (cprStartTimer(timer_p->timer, msec, (void *)(long)id) == CPR_FAILURE) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX "%s failed\n",
                          fname, "cprStartTimer");
        cpr_free(timer_p->message_buffer);
        timer_p->message_buffer = NULL;
        timer_p->message_buffer_len = 0;
        return SIP_ERROR;
    }

    return SIP_OK;

}
/*
 *  Function: strlib_malloc
 *
 *  PARAMETERS:const char* : string which is to be malloc'ed
               int         : length of string or -1
 *
 *  DESCRIPTION:strlib_malloc : creates a new string and returns a const char*
 *  to the new string. Size of String is equal to length specified or actual
 *  length of the string when length is specified as -1(LEN_UNKNOWN)
 *
 *  RETURNS: Pointer to malloc'ed string
 *
 */
string_t
strlib_malloc (const char *str, int length, const char *fname, int line)
{
    string_block_t *temp;
    int size;

    // if specified length is unknown or invalid... then calculate it
    // Length < 0 is not expected, but since length is an int, it could
    // theoritically be negative.  [ This check accounts for that, and
    // avoids a static analysis warning related to same ]
    if ((length == LEN_UNKNOWN) || (length < 0)) {
        length = strlen(str);
    }

    size = sizeof(string_block_t) + length + 1;
    temp = (string_block_t *) cpr_malloc(size);

    if (!temp) {
        err_msg("Error: Strlib_Malloc() Failed. Requested Size = %d\n", size);
        return (string_t) 0;
    }

    temp->refcount  = 1;
    temp->length    = (uint16_t) length;
    temp->signature = STRING_SIGNATURE;
    temp->fname     = fname;
    temp->line      = line;
    /* There used to be memcpy here which will walk off the end of */
    /* str pointer which is a bad thing to do */
    sstrncpy(temp->data, str, length + 1);
    temp->data[length] = '\0';

    return STRUCT_TO_STR(temp);
}
示例#5
0
int addhash (unsigned int key, void *data)
{
   hash_table_t *newhash;
   hash_table_t *cur_hash;
   unsigned int hashval;

   newhash = (hash_table_t *)(cpr_malloc(sizeof(hash_table_t)));
   if (newhash == NULL) {
     return -1;
   }

   newhash->key = key;

   newhash->data = data;

   hashval = sessionHash(key);

   if (hashtable[hashval] == NULL) {
      hashtable[hashval] = newhash;
      hashtable[hashval]->prev = NULL;
      hashtable[hashval]->next = NULL;
   }
   else {
      cur_hash=hashtable[hashval];
      while(cur_hash->next != NULL) {
         cur_hash=cur_hash->next;
      }
      cur_hash->next = newhash;
      newhash->next = NULL;
      newhash->prev = cur_hash;
   }

   return 0;
}
示例#6
0
/**
 * Add/Get ccapp task listener
 */
void addCcappListener(appListener* listener, int type) {

    listener_t *alistener = NULL;

    CCAPP_DEBUG(DEB_F_PREFIX"Entered: listenr=0x%x, type=%d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener"),
                listener, type);

    if (listener == NULL)
    {
        CCAPP_ERROR(DEB_F_PREFIX"listener is NULL, returning\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener"));
        return;
    }

    alistener = cpr_malloc(sizeof(listener_t));
    if (alistener == NULL) {
        CCAPP_ERROR(DEB_F_PREFIX"alistener is NULL, returning\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener"));
        return;
    }

    alistener->type = type;
    alistener->listener_p = listener;

    sll_lite_link_tail(&sll_list, (sll_lite_node_t *)alistener);
    CCAPP_DEBUG(DEB_F_PREFIX"Added: listenr=0x%x, type=%d\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "addCcappListener"),
                alistener->listener_p, alistener->type);
}
/**
 * get media stream table
 * @param handle - call handle
 * @return status MediaStreamTable
 */
MediaStreamTable*  CCAPI_CallInfo_getMediaStreams(cc_callinfo_ref_t handle) {
  static const char *fname="CCAPI_CallInfo_getMediaStreams";
  session_data_t *data = (session_data_t *)handle;
  MediaTrack track;
  MediaStreamTable* table = cpr_malloc(sizeof(MediaStreamTable));
  if (!table)
    return NULL;

  CCAPP_DEBUG(DEB_F_PREFIX"Entering", DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname));

  if (data != NULL) {
    table->media_stream_id = data->media_stream_id;
	table->num_tracks = 1;   /* this will change when we have multiple tracks per stream */
	track.media_stream_track_id = data->media_stream_track_id;
	track.video = FALSE;
	table->track[0] = track;

	/*
	 * Partly implemented multi-track handling
	   cc_table = data->media_tracks;
	   table->stream_id = (unsigned int)cc_table->stream_id;
	   table->num_tracks = (unsigned int)cc_table->num_tracks;
	   track.track_id = cc_table->track[0].ref_id;
	   table->track[0] = track;
	*/
    return table;
  }

  return table;
}
示例#8
0
char *
pmhutils_rstream_read_bytes (pmhRstream_t *pmhRstream, int32_t nbytes)
{
    char *ret;

    if (!pmhRstream || !pmhRstream->loc || (pmhRstream->eof == TRUE)) {
        return NULL;
    }

    if (pmhRstream->bytes_read >= pmhRstream->nbytes) {
        pmhRstream->eof = TRUE;
        return NULL;
    }

    if ((pmhRstream->nbytes - pmhRstream->bytes_read) < (int32_t) nbytes) {
        return NULL;
    }
    ret = (char *) cpr_malloc((nbytes + 1) * sizeof(char));
    if (ret == NULL) {
        // Addition of 1 byte (NULL) will save us from strlen errr
        return NULL;
    }
    memcpy(ret, pmhRstream->loc, nbytes);
    ret[nbytes] = 0;              /* ensure null terminating character */
    pmhRstream->bytes_read += nbytes;
    pmhRstream->loc += nbytes;

    return (ret);
}
/**
 * This function will append presence notification to the pending queue.
 *
 * @param[in] event_data_p - pointer to event data.
 *
 * @return none.
 *
 * @pre (event_data_p != NULL)
 */
static void append_notification_to_pending_queue (ccsip_event_data_t *event_data_p)
{
    static const char fname[] = "append_notification_to_pending_queue";
    pres_pending_notify_t *pending_notify_p;
    Presence_ext_t *event_body_p = &(event_data_p->u.presence_rpid);

    /*
     * create pending list if it is not created yet.
     */
    if (s_pending_notify_list == NULL) {
        s_pending_notify_list = sll_create(NULL);
        if (s_pending_notify_list == NULL) {
            CSFLogError("src-common", "MSC: 0/0: %s: out of memory", fname);
            free_event_data(event_data_p);
            return;
        }
    }

    pending_notify_p = (pres_pending_notify_t *)sll_next(s_pending_notify_list, NULL);
    while (pending_notify_p != NULL) {
        if (strncmp(pending_notify_p->presentity, event_body_p->presence_body.entity,
                    CC_MAX_DIALSTRING_LEN - 1) == 0) {
            /* replace the current state with new state */
            free_event_data(pending_notify_p->event_data_p);
            pending_notify_p->event_data_p = event_data_p;
            return;
        }
        pending_notify_p = (pres_pending_notify_t *)sll_next(s_pending_notify_list,
                                                             pending_notify_p);
    }

    /*
     * To protect from DoS attacks, do not allow more than
     * MAX_REG_LINES entries in the list.
     */
    if (sll_count(s_pending_notify_list) == MAX_REG_LINES) {
        CSFLogError("src-common", "MSC: 0/0: %s: ignoring the NOTIFY "
            "to protect from DoS attack", fname);
        free_event_data(event_data_p);
        return;
    }
    pending_notify_p = (pres_pending_notify_t *)
                       cpr_malloc(sizeof(pres_pending_notify_t));
    if (pending_notify_p == NULL) {
        CSFLogError("src-common", "MSC: 0/0: %s: out of memory", fname);
        free_event_data(event_data_p);
        return;
    }
    sstrncpy(pending_notify_p->presentity, event_body_p->presence_body.entity,
             CC_MAX_DIALSTRING_LEN);
    pending_notify_p->event_data_p = event_data_p;
    (void) sll_append(s_pending_notify_list, pending_notify_p);
    return;
}
示例#10
0
/**
 * This function will append the application request in a pending list.
 *
 * @param[in] pcb_p -  pointer to a PCB.
 * @param[in] msg_p -  pointer to an application request.
 *
 * @return  TRUE if it is successful.
 *          Otherwise, FALSE is returned.
 *
 *  @pre    (pcb_p != NULL) and (msg_p != NULL)
 *  @post   ((slink_list_t *)s_pres_req_list->count++)
 */
static boolean append_pending_reqs (ccsip_publish_cb_t *pcb_p, pub_req_t *msg_p)
{
    pub_req_t *temp_msg_p;

    temp_msg_p = (pub_req_t *)cpr_malloc(sizeof(pub_req_t));
    if (temp_msg_p == NULL) {
        return FALSE;
    }
    (*temp_msg_p) = (*msg_p);
    (void) sll_append(pcb_p->pending_reqs, temp_msg_p);
    return TRUE;
}
示例#11
0
/*
 * sipsdp_info_create()
 *
 * Allocates and initializes a SIP SDP structure.  This function does
 * not create the src_sdp, dest_sdp, or streams list.
 *
 * Returns: pointer to SIP SDP structure - if successful
 *          NULL                         - failure to allocate storage
 */
cc_sdp_t *
sipsdp_info_create (void)
{
    cc_sdp_t *sdp_info = (cc_sdp_t *) cpr_malloc(sizeof(cc_sdp_t));

    if (sdp_info) {
        sdp_info->src_sdp = NULL;
        sdp_info->dest_sdp = NULL;
    }

    return (sdp_info);
}
示例#12
0
/**
 * Post message to system message queue
 *
 * @param msgq       - message queue
 * @param msg        - message to post
 * @param ppUserData - ptr to ptr to option user data
 *
 * @return the post result which is CPR_MSGQ_POST_SUCCESS,
 *         CPR_MSGQ_POST_FAILURE or CPR_MSGQ_POST_PENDING
 *
 * @pre (msgq not_eq NULL)
 * @pre (msg not_eq NULL)
 */
static cpr_msgq_post_result_e
cprPostMessage (cpr_msg_queue_t *msgq, void *msg, void **ppUserData)
{
    cpr_msgq_node_t *node;

    /*
     * Allocate new message queue node
     */
    node = cpr_malloc(sizeof(*node));
    if (!node) {
        errno = ENOMEM;
        return CPR_MSGQ_POST_FAILED;
    }

    pthread_mutex_lock(&msgq->mutex);

    /*
     * Fill in data
     */
    node->msg = msg;
    if (ppUserData != NULL) {
        node->pUserData = *ppUserData;
    } else {
        node->pUserData = NULL;
    }

    /*
     * Push onto list
     */
    node->prev = NULL;
    node->next = msgq->head;
    msgq->head = node;

    if (node->next) {
        node->next->prev = node;
    }

    if (msgq->tail == NULL) {
        msgq->tail = node;
    }
    msgq->currentCount++;

    pthread_cond_signal(&msgq->cond);
    pthread_mutex_unlock(&msgq->mutex);

    return CPR_MSGQ_POST_SUCCESS;

}
示例#13
0
/*
 *      Function responsible to create new data information
 *  for cac.
 *
 *  @param none.
 *
 *  @return cac_data_t *
 *
 */
static cac_data_t *
fsm_get_new_cac_data (void)
{
    static const char *fname="fsm_get_new_cac_data";
    cac_data_t *cac_mem;

    cac_mem = (cac_data_t *) cpr_malloc(sizeof(cac_data_t));

    if (cac_mem == NULL) {
        CAC_ERROR(DEB_F_PREFIX"No memory for CAC data.",
                DEB_F_PREFIX_ARGS("CAC", fname));
        return (NULL);
    }

    memset(cac_mem, 0, sizeof(cac_data_t));
    return (cac_mem);
}
示例#14
0
/**
 * This function will create a PCB. It will also create the PCB linked list.
 *
 * @return  NULL if there are no resources to create a PCB.
 *          Otherwise,  pointer to a new PCB is returned.
 *
 *  @pre     (key != NULL) and (data != NULL)
 */
static ccsip_publish_cb_t *get_new_pcb (void)
{
    ccsip_publish_cb_t *pcb_p;

    /*
     * If PCB list is not created yet, create the list.
     */
    if (s_PCB_list == NULL) {
        s_PCB_list = sll_create(is_matching_pcb);
        if (s_PCB_list == NULL) {
            return NULL;
        }
    }

    pcb_p = (ccsip_publish_cb_t *)cpr_malloc(sizeof(ccsip_publish_cb_t));
    if (pcb_p == NULL) {
        return NULL;
    }
    memset(pcb_p, 0, sizeof(ccsip_publish_cb_t));
    pcb_p->pub_handle = generate_new_pub_handle();
    pcb_p->hb.cb_type = PUBLISH_CB;
    pcb_p->hb.dn_line = 1; // for now set it to primary line. This will change when we do line based PUBLISH.
    /*
     * set up dest & src ip addr and port number.
     */
    ccsip_common_util_set_dest_ipaddr_port(&pcb_p->hb);
    ccsip_common_util_set_src_ipaddr(&pcb_p->hb);
    pcb_p->hb.local_port = sipTransportGetListenPort(pcb_p->hb.dn_line, NULL);
    pcb_p->retry_timer.timer = cprCreateTimer("PUBLISH retry timer",
                                              SIP_PUBLISH_RETRY_TIMER,
                                              TIMER_EXPIRATION,
                                              sip_msgq);
    if (pcb_p->retry_timer.timer == NULL) {
        cpr_free(pcb_p);
        return NULL;
    }
    pcb_p->pending_reqs = sll_create(NULL);
    if (pcb_p->pending_reqs == NULL) {
        (void)cprDestroyTimer(pcb_p->retry_timer.timer);
        cpr_free(pcb_p);
        return NULL;
    }
    (void) sll_append(s_PCB_list, pcb_p);

    return pcb_p;
}
示例#15
0
pmhWstream_t *
pmhutils_wstream_create_with_buf (char *buf, uint32_t nbytes)
{
    pmhWstream_t *pmhWstream = NULL;

    if (buf && nbytes && (nbytes > 0)) {
        pmhWstream = (pmhWstream_t *) cpr_malloc(sizeof(pmhWstream_t));
        if (!pmhWstream) {
            return (NULL);
        }
        pmhWstream->buff = buf;
        pmhWstream->nbytes = 0;
        pmhWstream->total_bytes = nbytes;
        pmhWstream->growable = FALSE;
    }
    return (pmhWstream);
}
示例#16
0
void conf_roster_copy_call_conferance (cc_call_conference_Info_t *dest, cc_call_conference_Info_t * src)
{
    cc_call_conferenceParticipant_Info_t *destParticipant;
    cc_call_conferenceParticipant_Info_t *srcParticipant;
    sll_lite_node_t *iterator;
    sll_lite_return_e sll_ret_val;

    CCAPP_DEBUG(DEB_F_PREFIX"in copy_call_confrerence \n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE"));

    iterator = src->currentParticipantsList.head_p;
    conf_roster_init_call_conference(dest);

    dest->participantMax = src->participantMax;
    dest->participantCount = src->participantCount;
    dest->myParticipantId = strlib_copy(src->myParticipantId);

    while (iterator) {
        srcParticipant = (cc_call_conferenceParticipant_Info_t *)iterator;

        destParticipant = cpr_malloc(sizeof(cc_call_conferenceParticipant_Info_t)); 
        if (destParticipant == NULL) {
            CCAPP_ERROR(DEB_F_PREFIX" Malloc failure for participant\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE"));
            return;
        } else {
            destParticipant->participantName = strlib_copy(srcParticipant->participantName);
            destParticipant->endpointUri = strlib_copy(srcParticipant->endpointUri);
            destParticipant->callid = strlib_copy(srcParticipant->callid);
            
            destParticipant->participantNumber          = strlib_copy(srcParticipant->participantNumber);
            destParticipant->participantSecurity        = srcParticipant->participantSecurity; 
            destParticipant->participantStatus          = srcParticipant->participantStatus; 
            destParticipant->canRemoveOtherParticipants = srcParticipant->canRemoveOtherParticipants;
        }

        sll_ret_val = sll_lite_link_tail(&dest->currentParticipantsList, (sll_lite_node_t *)destParticipant);
        if (sll_ret_val != SLL_LITE_RET_SUCCESS) {
            CCAPP_ERROR(DEB_F_PREFIX" Error while trying to insert in the linked list\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE"));
            cpr_free(destParticipant);
            return;
        }

        iterator = iterator->next_p;
    } 
}
示例#17
0
/*
 *  Function: AddDialTemplate()
 *
 *  Parameters: pattern -
 *              line    -
 *              timeout -
 *              userMode -
 *              rewrite -
 *              routeMode -
 *              tone - array of tones to play when , is hit in the rule
 *              tones_defined - # of tones this rule actually defined
 *
 *  Description: Add a dial template to the known list of templates
 *
 *  Returns: None
 */
static void
AddDialTemplate (const char *pattern, const line_t line,
                 int timeout, UserMode userMode,
                 const char *rewrite, RouteMode routeMode,
                 vcm_tones_t tone[MAX_TONES], int tones_defined)
{
    struct DialTemplate *pnewtemplate;
    int patternlen = strlen(pattern);
    int rewritelen = strlen(rewrite);
    int counter;

    pnewtemplate = (struct DialTemplate *)
        cpr_malloc(sizeof(struct DialTemplate) + patternlen + rewritelen +
                   2);
    if (pnewtemplate != NULL) {
        pnewtemplate->next = NULL;
        pnewtemplate->pattern = (char *) (pnewtemplate + 1);
        sstrncpy(pnewtemplate->pattern, (char *) pattern, patternlen + 1);
        pnewtemplate->rewrite = pnewtemplate->pattern + patternlen + 1;
        sstrncpy(pnewtemplate->rewrite, (char *) rewrite, rewritelen + 1);
        pnewtemplate->line = line;
        pnewtemplate->timeout = timeout;
        pnewtemplate->userMode = userMode;
        pnewtemplate->routeMode = routeMode;
        pnewtemplate->tones_defined = tones_defined;
        for (counter = 0; counter < MAX_TONES; counter++) {
            pnewtemplate->tone[counter] = tone[counter];
        }

        /*
         * Now add it to the end of all the templates
         */
        if (basetemplate == NULL) {
            basetemplate = pnewtemplate;
        } else {
            struct DialTemplate *base = basetemplate;

            while (base->next != NULL) {
                base = base->next;
            }
            base->next = pnewtemplate;
        }
    }
}
示例#18
0
/**
 * cprCreateThread
 *
 * Create a thread
 *
 * Parameters: name         - name of the thread created
 *             startRoutine - function where thread execution begins
 *             stackSize    - size of the thread's stack (IGNORED)
 *             priority     - thread's execution priority (IGNORED)
 *             data         - parameter to pass to startRoutine
 *
 *
 * Return Value: Thread handle or NULL if creation failed.
 */
cprThread_t
cprCreateThread(const char* name,
                cprThreadStartRoutine startRoutine,
                uint16_t stackSize,
                uint16_t priority,
                void* data)
{
    cpr_thread_t* threadPtr;
    static char fname[] = "cprCreateThread";
	unsigned long result;
	CEvent serialize_lock;

    /* Malloc memory for a new thread */
    threadPtr = (cpr_thread_t *)cpr_malloc(sizeof(cpr_thread_t));
    if (threadPtr != NULL) {
		
        /* Assign name to CPR and CNU if one was passed in */
        if (name != NULL) {
            threadPtr->name = name;
        }

		threadPtr->u.handlePtr = AfxBeginThread((AFX_THREADPROC)startRoutine, data, priority, stackSize);
		  
        if (threadPtr->u.handlePtr != NULL) {
			PostThreadMessage(((CWinThread *)(threadPtr->u.handlePtr))->m_nThreadID, MSG_ECHO_EVENT, (unsigned long)&serialize_lock, 0);
			result = WaitForSingleObject(serialize_lock, 1000);
			serialize_lock.ResetEvent();
		}
		else
		{
			CPR_ERROR("%s - Thread creation failure: %d\n", fname, GetLastError());
			cpr_free(threadPtr);
            threadPtr = NULL;
			
        }
    } else {
        /* Malloc failed */
        CPR_ERROR("%s - Malloc for new thread failed.\n", fname);
    }
	return(threadPtr);
};
示例#19
0
cpr_status_e ccappTaskPostMsg(unsigned int msgId, void * data, uint16_t len, int appId)
{
    cprBuffer_t *msg;
    static const char fname[] = "ccappPostMsg";
    cpr_status_e retval = CPR_SUCCESS;

    msg = (cprBuffer_t *) cpr_malloc(len);
    if (msg == NULL) {
        CCAPP_ERROR(DEB_F_PREFIX"failed to allocate message.\n",
                    DEB_F_PREFIX_ARGS(SIP_CC_PROV, fname));
        return CPR_FAILURE;
    }

    memcpy(msg, data, len);

    if ((retval=ccappTaskSendMsg(msgId, msg, len, appId)) == CPR_FAILURE) {
        cpr_free(msg);
    }

    return retval;
}
示例#20
0
pmhRstream_t *
pmhutils_rstream_create (char *buf, uint32_t nbytes)
{
    pmhRstream_t *pmhRstream;

    if (!buf || (nbytes == 0)) {
        return NULL;
    }

    pmhRstream = (pmhRstream_t *) cpr_malloc(sizeof(pmhRstream_t));
    if (!pmhRstream) {
        return NULL;
    }

    pmhRstream->eof = pmhRstream->error = FALSE;
    pmhRstream->buff = pmhRstream->loc = buf;
    pmhRstream->nbytes = nbytes;
    pmhRstream->bytes_read = 0;

    return pmhRstream;
}
示例#21
0
/*
 * ccsip_store_call_info
 *
 * Description: Used for storing call_info received from GSM
 *
 * Store specified call info structure in ccb.
 */
void
ccsip_store_call_info (cc_call_info_t *call_info_p, ccsipCCB_t *ccb)
{
    if (!ccb) {
        return;
    }

    if (ccb->out_call_info) {
        ccsip_free_call_info_header(ccb->out_call_info);
        ccb->out_call_info = NULL;
    }

    if (call_info_p->type != CC_FEAT_NONE) {
        ccb->out_call_info = (cc_call_info_t *)
            cpr_malloc(sizeof(cc_call_info_t));
        if (ccb->out_call_info) {
            memcpy(ccb->out_call_info, call_info_p, sizeof(cc_call_info_t));
        } else {
            ccb->out_call_info = NULL;
        }
    }
}
示例#22
0
/**
 * cpr_strdup
 *
 * @brief The CPR wrapper for strdup

 * The cpr_strdup shall return a pointer to a new string, which is a duplicate
 * of the string pointed to by "str" argument. A null pointer is returned if the
 * new string cannot be created.
 *
 * @param[in] str  - The string that needs to be duplicated
 *
 * @return The duplicated string or NULL in case of no memory
 *
 */
char *
cpr_strdup (const char *str)
{
    char *dup;
    size_t len;

    if (!str) {
        return (char *) NULL;
    }

    len = strlen(str);
    if (len == 0) {
        return (char *) NULL;
    }
    len++;

    dup = cpr_malloc(len * sizeof(char));
    if (!dup) {
        return (char *) NULL;
    }
    (void) memcpy(dup, str, len);
    return dup;
}
示例#23
0
/*
 * ccsip_encode_call_info_hdr
 *
 * Description:
 *
 * Encode the call info header using the passed in feature id and
 * feature specific data.
 *
 * The miscParms parameter will usually be null.  It exists in case
 * you want to toss in an additional string parm without using the
 * encoding mechanism.  An example would be "extraParm= text".
 *
 * Remember to delete the store in the return parm.  It is the
 * caller's responsibility.
 */
char *
ccsip_encode_call_info_hdr (cc_call_info_t *call_info_p,
                            const char *misc_parms_p)
{
    static const char *fname = "ccsip_encode_call_info_hdr";
    char *header;

    header = (char *) cpr_malloc(MAX_SIP_HEADER_LENGTH);
    if (!header) {
        return NULL;
    }

    if (!call_info_p) {
        cpr_free(header);
        return NULL;
    }

    snprintf(header, MAX_SIP_HEADER_LENGTH, "<%s", URN_REMOTECC);

    switch (call_info_p->type) {
    case CC_FEAT_HOLD:
    case CC_FEAT_RESUME:
        if (call_info_p->type == CC_FEAT_HOLD) {
            sstrncat(header, SIP_CI_HOLD_STR,
                    MAX_SIP_HEADER_LENGTH - strlen(header));
        } else {
            sstrncat(header, SIP_CI_RESUME_STR,
                    MAX_SIP_HEADER_LENGTH - strlen(header));
        }
        sstrncat(header, ">", MAX_SIP_HEADER_LENGTH - strlen(header));

        switch (call_info_p->data.hold_resume_reason) {
        case CC_REASON_NONE:
        case CC_REASON_INTERNAL:
        case CC_REASON_SWAP:
            break;
        case CC_REASON_XFER:
            sstrncat(header, "; reason= ",
                    MAX_SIP_HEADER_LENGTH - strlen(header));
            sstrncat(header, SIP_CI_HOLD_REASON_XFER,
                    MAX_SIP_HEADER_LENGTH - strlen(header));
            break;
        case CC_REASON_CONF:
            sstrncat(header, "; reason= ",
                    MAX_SIP_HEADER_LENGTH - strlen(header));
            sstrncat(header, SIP_CI_HOLD_REASON_CONF,
                    MAX_SIP_HEADER_LENGTH - strlen(header));
            break;
        default:
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX  "unsupported hold_resume_reason",
                              fname);
            cpr_free(header);
            return NULL;
        }

        /* Add swap information */
        if (call_info_p->data.call_info_feat_data.swap == TRUE) {
            sstrncat(header, "; operation= swap",
                    MAX_SIP_HEADER_LENGTH - strlen(header));
        }

        if (call_info_p->data.call_info_feat_data.protect == TRUE) {
            sstrncat(header, "; protect= true; noholdreversion",
                    MAX_SIP_HEADER_LENGTH - strlen(header));
        }

        break;

    case CC_FEAT_INIT_CALL:
        /* Add global call id here */
        if (call_info_p->data.initcall.gcid[0] != '\0') {
            sstrncat(header, "callinfo>; gci= ",
                    MAX_SIP_HEADER_LENGTH - strlen(header));
            sstrncat(header, call_info_p->data.initcall.gcid,
                    MAX_SIP_HEADER_LENGTH - strlen(header));
        } else {
            cpr_free(header);
            return NULL;
        }
        /* Add the monitor mode here if it exists */
        if (call_info_p->data.initcall.monitor_mode != CC_MONITOR_NONE) {
            sstrncat(header, "; mode=",
                    MAX_SIP_HEADER_LENGTH - strlen(header));

            switch (call_info_p->data.initcall.monitor_mode) {

            case CC_MONITOR_SILENT :
                sstrncat(header, SIP_CI_SILENT_STR,
                        MAX_SIP_HEADER_LENGTH - strlen(header));
                break;

            case CC_MONITOR_COACHING :
                sstrncat(header, SIP_CI_COACHING_STR,
                        MAX_SIP_HEADER_LENGTH - strlen(header));
                break;

            default:
                break;
            }
        }
        break;

    case CC_FEAT_TOGGLE_TO_WHISPER_COACHING:
        sstrncat(header, "callinfo>",
        	MAX_SIP_HEADER_LENGTH - strlen(header));
        sstrncat(header, "; mode=",
            MAX_SIP_HEADER_LENGTH - strlen(header));
        sstrncat(header, SIP_CI_COACHING_STR,
            MAX_SIP_HEADER_LENGTH - strlen(header));

        break;

    case CC_FEAT_TOGGLE_TO_SILENT_MONITORING:
        sstrncat(header, "callinfo>",
            MAX_SIP_HEADER_LENGTH - strlen(header));
        sstrncat(header, "; mode=",
            MAX_SIP_HEADER_LENGTH - strlen(header));
        sstrncat(header, SIP_CI_SILENT_STR,
            MAX_SIP_HEADER_LENGTH - strlen(header));

        break;

    default:
        cpr_free(header);
        return NULL;
    }


    if (misc_parms_p) {
        sstrncat(header, misc_parms_p,
                MAX_SIP_HEADER_LENGTH - strlen(header));
    }
    sstrncat(header, "\0", MAX_SIP_HEADER_LENGTH - strlen(header));
    return (header);
}
/**
 * cprCreateTimer
 *
 * @brief Initialize a timer
 *
 * The cprCreateTimer function is called to allow the OS to perform whatever
 * work is needed to create a timer. The input name parameter is optional. If present, CPR assigns
 * this name to the timer to assist in debugging. The callbackMsgQueue is the
 * address of a message queue created with cprCreateMsgQueue. This is the
 * queue where the timer expire message will be sent.
 * So, when this timer expires a msg of type "applicationMsgId" will be sent to the msg queue
 * "callbackMsgQueue" indicating that timer applicationTimerId has expired.
 *
 * @param[in]   name               -  name of the timer
 * @param[in]   applicationTimerId - ID for this timer from the application's
 *                                  perspective
 * @param[in]   applicationMsgId   - ID for syshdr->cmd when timer expire msg
 *                                  is sent
 * @param[in]   callBackMsgQueue   - where to send a msg when this timer expires
 *
 * @return  Timer handle or NULL if creation failed.
 */
cprTimer_t
cprCreateTimer (const char *name,
                uint16_t applicationTimerId,
                uint16_t applicationMsgId,
                cprMsgQueue_t callBackMsgQueue)
{
    static const char fname[] = "cprCreateTimer";
    static uint32_t cprTimerId = 0;
    cpr_timer_t *cprTimerPtr;
    timerBlk *timerPtr;

    /*
     * Malloc memory for a new timer. Need to
     * malloc memory for the generic CPR view and
     * one for the CNU specific version.
     */
    cprTimerPtr = (cpr_timer_t *) cpr_malloc(sizeof(cpr_timer_t));
    timerPtr = (timerBlk *) cpr_malloc(sizeof(timerBlk));
    if ((cprTimerPtr != NULL) && (timerPtr != NULL)) {
        /* Assign name (Optional) */
        cprTimerPtr->name = name;

        /* Set timer ids, msg id and callback msg queue (Mandatory) */
        cprTimerPtr->applicationTimerId = applicationTimerId;
        cprTimerPtr->applicationMsgId = applicationMsgId;
        cprTimerPtr->cprTimerId = cprTimerId++;
        if (callBackMsgQueue == NULL) {
            CPR_ERROR("%s - Callback msg queue for timer %s is NULL.\n",
                      fname, name);
            cpr_free(timerPtr);
            cpr_free(cprTimerPtr);
            return NULL;
        }
        cprTimerPtr->callBackMsgQueue = callBackMsgQueue;

        /*
         * Set remaining values in both structures to defaults
         */
        timerPtr->next = NULL;
        timerPtr->previous = NULL;
        timerPtr->duration = -1;
        timerPtr->timerActive = FALSE;
        cprTimerPtr->data = NULL;

        /*
         * TODO - It would be nice for CPR to keep a linked
         * list of active timers for debugging purposes
         * such as a show command or walking the list to ensure
         * that an application does not attempt to create
         * the same timer twice.
         *
         * TODO - It would be nice to initialize of pool of
         * timers at init time and have this function just
         * return a timer from the pool. Then when the
         * timer expired or cancel the code would not free
         * it, but just return it to the pool.
         */
        timerPtr->cprTimerPtr = cprTimerPtr;
        cprTimerPtr->u.handlePtr = timerPtr;
        //CPR_INFO("cprTimerCreate: timer_t=%x blk=%x\n",cprTimerPtr, timerPtr);

        return cprTimerPtr;
    }

    /*
     * If we get here there has been a malloc failure.
     */
    if (timerPtr) {
        cpr_free(timerPtr);
    }
    if (cprTimerPtr) {
        cpr_free(cprTimerPtr);
    }

    /* Malloc failed */
    CPR_ERROR("%s - Malloc for timer %s failed.\n", fname, name);
    errno = ENOMEM;
    return NULL;
}
/**
 *
 * Process the timers expired. Generally this is called when head timer
 * has expired.
 * @note we need to process the list as there could be
 * other timers too in the list which have expired.
 *
 */
void process_expired_timers() {
    static const char fname[] = "process_expired_timer";
    cprCallBackTimerMsg_t *timerMsg;
    void *syshdr;
    boolean processingTimers;

    /* nothing to do if no timers running */
    if (timerListHead == NULL) {
        return;
    }

    /* nothing to do if head has not expired */
    if (timerListHead->duration > 0) {
        return;
    }


    /* There are one or more expired timers on the list */
    processingTimers = TRUE;
    while (processingTimers) {
        if (timerListHead != NULL) {
            /*
             * Send msg to queue to indicate this timer has expired
             */
            if (timerListHead->duration <= 0) {
                timerMsg = (cprCallBackTimerMsg_t *)
                    cpr_malloc(sizeof(cprCallBackTimerMsg_t));
                if (timerMsg) {
                    timerMsg->expiredTimerName =
                        timerListHead->cprTimerPtr->name;
                    //CPR_INFO("%s: timer %s expired..\n",fname,
                    //       timerMsg->expiredTimerName);

                    timerMsg->expiredTimerId =
                        timerListHead->cprTimerPtr->applicationTimerId;
                    timerMsg->usrData =
                        timerListHead->cprTimerPtr->data;
                    syshdr = cprGetSysHeader(timerMsg);
                    if (syshdr) {
                        fillInSysHeader(syshdr,
                                        timerListHead->cprTimerPtr->applicationMsgId,
                                        sizeof(cprCallBackTimerMsg_t), timerMsg);
                        if (cprSendMessage(timerListHead->cprTimerPtr->callBackMsgQueue,
                                           timerMsg, (void **) &syshdr) == CPR_FAILURE) {
                            cprReleaseSysHeader(syshdr);
                            cpr_free(timerMsg);
                            CPR_ERROR("%s - Call to cprSendMessage failed\n", fname);
                            CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
                                      fname, timerListHead->cprTimerPtr->name);
                        }
                    } else {
                        cpr_free(timerMsg);
                        CPR_ERROR("%s - Call to cprGetSysHeader failed\n", fname);
                        CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
                                  fname, timerListHead->cprTimerPtr->name);
                    }
                } else {
                    CPR_ERROR("%s - Call to cpr_malloc failed\n", fname);
                    CPR_ERROR("%s - Unable to send timer %s expiration msg\n",
                              fname, timerListHead->cprTimerPtr->name);
                }
                (void) removeTimer(timerListHead->cprTimerPtr);
            } else {
                /* The rest of the timers on the list have not yet expired */
                processingTimers = FALSE;
            }
        } else {
            /* The timer list is now empty */
            processingTimers = FALSE;
        }
    } /* still more to process */
}
示例#26
0
/*
 *  Function: get_state()
 *
 *  Parameters: request_id - unique id assigned by the platform to this subscription. Platform
 *                           uses this to track the status updates and to make subsequent termination
 *                           request.
 *              duration - how long the subscription is requested to be valid.
 *              watcher - entity that is requesting the presence state.
 *              presentity - entity whose presence state is requested.
 *              app_id - application that is making the subscription.
 *                       0: indicates call list blf application.
 *                       1..n: indicates the speeddial/blf associated with (1..n)th line button.
 *              feature_mask - indicates the additional features enabled.
 *
 *  Description:  is invoked by platform side whenever it needs to susbcribe
 *                for presence state of a presentity. This stores the susbcription
 *                data in a linked list and posts SIPSPI_EV_CC_SUBSCRIBE
 *                to SIP stack. We need to store the subscription data so that
 *                SUBSCRIBE response and NOTIFYs can be mapped to subscriptions.
 *
 *  Returns: void
 */
static void
get_state (int request_id,
           int duration,
           const char *watcher,
           const char *presentity,
           int app_id,
           int feature_mask)
{
    static const char fname[] = "get_state";
    pres_subscription_req_t *sub_req_p;

    DEF_DEBUG(DEB_F_PREFIX"REQ %d: TM %d: WTR %s: PRT %s: FMSK %d: APP %d",
         DEB_F_PREFIX_ARGS(BLF_INFO, fname),
         request_id, duration, watcher, presentity, feature_mask, app_id);
    /*
     * if there is no subscription list yet, create one.
     */
    if (s_pres_req_list == NULL) {
        s_pres_req_list = sll_create(find_matching_node);
        if (s_pres_req_list == NULL) {
            /* let platform know that we can not continue */
            ui_BLF_notification(request_id, CC_SIP_BLF_REJECTED, app_id);
            BLF_ERROR(MISC_F_PREFIX"Exiting : request list creation failed", fname);
            return;
        }
    }
    /*
     * check if a request is already created by walking through the list. if not, create one.
     */
    if ((sub_req_p = (pres_subscription_req_t *)
                sll_find(s_pres_req_list, &request_id)) == NULL) {
        /*
         * populate subscription request and append it to the list.
         */
        sub_req_p = (pres_subscription_req_t *)
            cpr_malloc(sizeof(pres_subscription_req_t));
        if (sub_req_p == NULL) {
            BLF_ERROR(MISC_F_PREFIX"Exiting : malloc failed", fname);
            return;
        }

        sub_req_p->request_id = request_id;
        sub_req_p->sub_id = CCSIP_SUBS_INVALID_SUB_ID;
        sub_req_p->highest_cseq = 0;
        sub_req_p->duration = duration;
        sstrncpy(sub_req_p->presentity, presentity, CC_MAX_DIALSTRING_LEN);
        sstrncpy(sub_req_p->watcher, watcher, CC_MAX_DIALSTRING_LEN);
        sub_req_p->app_id = app_id;
        sub_req_p->feature_mask = feature_mask;
        sub_req_p->blf_state = CC_SIP_BLF_UNKNOWN;

        (void) sll_append(s_pres_req_list, sub_req_p);
    } else { /* already exists. just update the duration */
        sub_req_p->duration = duration;
    }

    /*
     * post SIPSPI_EV_CC_SUBSCRIBE to SIP stack
     */
    if (send_subscribe_ev_to_sip_task(sub_req_p) != CC_RC_SUCCESS) {
        /*
         * remove the node from the list of subscriptions.
         */
        free_sub_request(sub_req_p);
        /* let platform know that we can not continue */
        ui_BLF_notification(request_id, CC_SIP_BLF_REJECTED, app_id);
        BLF_ERROR(MISC_F_PREFIX"Exiting : Unable to send SUBSCRIBE", fname);
        return;
    }

    BLF_DEBUG(DEB_F_PREFIX"Exiting : request made successfully", DEB_F_PREFIX_ARGS(BLF, fname));
    return;
}
示例#27
0
/*
 * parse_user_node
 *
 * Do user node specific parsing.
 *
 * Assumes a_node, info are not null.
 */
static void 
parse_user_node (xmlNode * a_node, cc_call_conference_Info_t *info) 
{
    xmlChar *data;
    xmlNode *cur_node;
    cc_call_conferenceParticipant_Info_t *participant;
    sll_lite_return_e sll_ret_val;

    //allocate a new participant
    participant = cpr_malloc(sizeof(cc_call_conferenceParticipant_Info_t)); 
    if (participant == NULL) {
        CCAPP_ERROR(DEB_F_PREFIX" Malloc failure for participant\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE"));
        return;
    } else {
        participant->participantName            = strlib_empty();
        participant->endpointUri                = strlib_empty();
        participant->callid                     = strlib_empty();
        participant->participantNumber          = strlib_empty();
        participant->participantSecurity        = CC_SECURITY_NONE; 
        participant->participantStatus          = CCAPI_CONFPARTICIPANT_UNKNOWN; 
        participant->canRemoveOtherParticipants = FALSE;
    }

    sll_ret_val = sll_lite_link_tail(&info->currentParticipantsList, (sll_lite_node_t *)participant);
    if (sll_ret_val != SLL_LITE_RET_SUCCESS) {
        CCAPP_ERROR(DEB_F_PREFIX" Error while trying to insert in the linked list\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE"));
        cpr_free(participant);
        return;
    }

    data = xmlGetProp(a_node, (const xmlChar *) "entity");
    if (data != NULL) {
    	char *tmp2;
    	char *tmp1;
        participant->endpointUri = strlib_update(participant->endpointUri, (const char*)data);

        // Parse the endpoint URI, to get the Participant number

        tmp1 = (char *) strstr((const char*)data, "sip:");
        if (tmp1) {
            tmp1 += 4;
            tmp2 = (char *) strchr(tmp1, '@');
            if (tmp2) {
                *tmp2 = 0;
                participant->participantNumber = strlib_update(participant->participantNumber, (const char*)tmp1);
            }
        }
        xmlFree(data);
    } else {
        //continue parsing other elements
        CCAPP_ERROR(DEB_F_PREFIX" Error while trying to find the endpoint URI\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE"));
    }

    for (cur_node = a_node->children; cur_node != NULL; cur_node = cur_node->next) {
        if (cur_node->type == XML_ELEMENT_NODE) {
            if (xmlStrcmp(cur_node->name, (const xmlChar *) "endpoint") == 0) {
                parse_user_endpoint_node(cur_node, participant, info);
            } else if (xmlStrcmp(cur_node->name, (const xmlChar *) "display-text") == 0) { 
                data = xmlNodeGetContent(cur_node); 
                if (data != NULL) {
                    participant->participantName = strlib_update(participant->participantName, (const char*)data);
                    xmlFree(data);
                } else {
                    //No display text - continue parsing other elements -
                    CCAPP_ERROR(DEB_F_PREFIX" Error while trying to get the display text\n", DEB_F_PREFIX_ARGS(SIP_CC_PROV, "CCAPI-CONFPARSE"));
                }
            }
        }
    }
}
/**
 * cprCreateThread
 *
 * @brief Create a thread
 *
 *  The cprCreateThread function creates another execution thread within the
 *  current process. If the input parameter "name" is present, then this is used
 *  for debugging purposes. The startRoutine is the address of the function where
 *  the thread execution begins. The start routine prototype is defined as
 *  follows
 *  @code
 *     int32_t (*cprThreadStartRoutine)(void* data)
 *  @endcode
 *
 * @param[in]  name         - name of the thread created (optional)
 * @param[in]  startRoutine - function where thread execution begins
 * @param[in]  stackSize    - size of the thread's stack
 * @param[in]  priority     - thread's execution priority
 * @param[in]  data         - parameter to pass to startRoutine
 *
 * Return Value: Thread handle or NULL if creation failed.
 */
cprThread_t
cprCreateThread (const char *name,
                 cprThreadStartRoutine startRoutine,
                 uint16_t stackSize,
                 uint16_t priority,
                 void *data)
{
    static const char fname[] = "cprCreateThread";
    static uint16_t id = 0;
    cpr_thread_t *threadPtr;
    pthread_t threadId;
    pthread_attr_t attr;

    CPR_INFO("%s: creating '%s' thread\n", fname, name);

    /* Malloc memory for a new thread */
    threadPtr = (cpr_thread_t *)cpr_malloc(sizeof(cpr_thread_t));
    if (threadPtr != NULL) {
        if (pthread_attr_init(&attr) != 0) {

            CPR_ERROR("%s - Failed to init attribute for thread %s\n",
                      fname, name);
            cpr_free(threadPtr);
            return (cprThread_t)NULL;
        }

        if (pthread_attr_setstacksize(&attr, stackSize) != 0) {
            CPR_ERROR("%s - Invalid stacksize %d specified for thread %s\n",
                      fname, stackSize, name);
            cpr_free(threadPtr);
            return (cprThread_t)NULL;
        }

        if (pthread_create(&threadId, &attr, startRoutine, data) != 0) {
            CPR_ERROR("%s - Creation of thread %s failed: %d\n",
                      fname, name, errno);
            cpr_free(threadPtr);
            return (cprThread_t)NULL;
        }

        /* Assign name to CPR if one was passed in */
        if (name != NULL) {
            threadPtr->name = name;
        }

        /*
         * TODO - It would be nice for CPR to keep a linked
         * list of running threads for debugging purposes
         * such as a show command or walking the list to ensure
         * that an application does not attempt to create
         * the same thread twice.
         */
        threadPtr->u.handleInt = (uint64_t)threadId;
        threadPtr->threadId = ++id;
        return (cprThread_t)threadPtr;
    }

    /* Malloc failed */
    CPR_ERROR("%s - Malloc for thread %s failed.\n", fname, name);
    errno = ENOMEM;
    return (cprThread_t)NULL;
}
示例#29
0
/**
 * This function will process the response to PUBLISH request sent by us.
 *
 * @param[in] pSipMessage -  pointer to received SIP response msg
 *
 * @return SIP_OK if it successfully processes the response.
 *         SIP_ERROR if it fails to process the response.
 *
 * @pre    (pSipMessage != NULL)
 */
int publish_handle_ev_sip_response (sipMessage_t *pSipMessage)
{
    static const char fname[] = "publish_handle_ev_sip_response";
    const char     *callID_p = NULL;
    int             response_code = 0;
    const char     *expires = NULL;
    const char     *sip_etag = NULL;
    long            expiry_time;
    pub_req_t      *msg_p;
    ccsip_publish_cb_t *pcb_p;
    int entity_tag_size;

    callID_p = sippmh_get_cached_header_val(pSipMessage, CALLID);
    if (!callID_p) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Cannot obtain SIP Call ID.\n", fname);
        return SIP_ERROR;
    }

    /*
     * Find PCB by Call-ID. The Call-IDs generated by the phone ae unique.
     */
    pcb_p = find_pcb_by_sip_callid(callID_p);
    if (pcb_p == NULL) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"No matching PCB found\n", fname);
        return SIP_ERROR;
    }

    /*
     * Cancel the retry_timer and set the retx_flag to FALSE.
     */
    sip_platform_msg_timer_subnot_stop(&(pcb_p->retry_timer));
    pcb_p->hb.retx_flag = FALSE;
    
    // Parse the return code
    (void) sipGetResponseCode(pSipMessage, &response_code);

    if (response_code >= 200) {
        pcb_p->outstanding_trxn = FALSE;
    }


    if ((response_code == SIP_CLI_ERR_UNAUTH) ||
        (response_code == SIP_CLI_ERR_PROXY_REQD)) {
        CCSIP_DEBUG_TASK(DEB_F_PREFIX"Authentication Required\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname));
        if (ccsip_common_util_generate_auth(pSipMessage, &pcb_p->hb, SIP_METHOD_PUBLISH,
                                            response_code, pcb_p->full_ruri) == TRUE) {
            if (sipSPISendPublish(pcb_p, TRUE) == TRUE) {
                pcb_p->outstanding_trxn = TRUE;
                CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with Auth header\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname));
                return SIP_OK;
             }
        }
        /*
         * Since we failed to resend the PUBLISH request, free up the PCB and let the app know.
         */
        send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle,
                         pcb_p->callback_task, pcb_p->resp_msg_id);
        free_pcb (pcb_p);
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to auth challenge\n", fname);
        return SIP_ERROR;
    }

    /*
     * if response code is 423, grab Min-Expires and send new PUBLISH with new expires value
     */
    if (response_code == SIP_CLI_ERR_INTERVAL_TOO_SMALL) {
        expires = sippmh_get_header_val(pSipMessage,
                                        (const char *)SIP_HEADER_MIN_EXPIRES,
                                        NULL);
        if (expires) {
            expiry_time = strtoul(expires, NULL, 10);
            //ensure new Min-Expires is > what we set before in Expires
            if ((long) expiry_time > pcb_p->hb.expires) {
                pcb_p->hb.expires = expiry_time;
                pcb_p->hb.orig_expiration = expiry_time;
            }
            if (sipSPISendPublish(pcb_p, FALSE) == TRUE) {
                pcb_p->outstanding_trxn = TRUE;
                CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent request with increased expires\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname));
                return SIP_OK;
             }
        }
        /*
         * Since we failed to resend the PUBLISH request, free up the PCB and let the app know.
         */
        send_resp_to_app(PUBLISH_FAILED_SEND, pcb_p->pub_handle, pcb_p->app_handle,
                         pcb_p->callback_task, pcb_p->resp_msg_id);
        free_pcb (pcb_p);
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to respond to 423\n", fname);
        return SIP_ERROR;
    }
    
    /*
     * if the response_code is > 299, free up the PCB and let the app know.
     */
    if (response_code > 299) {
        send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle,
                         pcb_p->callback_task, pcb_p->resp_msg_id);
        free_pcb (pcb_p);
        CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code);
        return SIP_OK;
    }

    /*
     * if the response is < 200, do nothing.
     */
    if (response_code < 200) {
        CCSIP_DEBUG_TASK(DEB_F_PREFIX"received %d response\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code);
        return SIP_OK;
    }
    
    /*
     * If it is PUBLISH remove operation, free up PCB
     */
    if (pcb_p->hb.orig_expiration == 0) {
        send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle,
                         pcb_p->callback_task, pcb_p->resp_msg_id);
        free_pcb (pcb_p);
        CCSIP_DEBUG_TASK(DEB_F_PREFIX"removed PCB as this was a terminating PUBLISH\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname));
        return SIP_OK;
    }

    /*
     * extract Expires and SIP-ETag headers and save them.
     */
    expires = sippmh_get_header_val(pSipMessage, SIP_HEADER_EXPIRES, NULL);
    if (expires) {
        expiry_time = strtoul(expires, NULL, 10);
        pcb_p->hb.expires = expiry_time;
    }
    sip_etag = sippmh_get_header_val(pSipMessage, SIP_HEADER_SIPETAG, NULL);
    if (sip_etag != NULL) {
        cpr_free(pcb_p->entity_tag);
        entity_tag_size = strlen(sip_etag) + 1;
        pcb_p->entity_tag = cpr_malloc(entity_tag_size);
        if (pcb_p->entity_tag != NULL) {
            sstrncpy(pcb_p->entity_tag, sip_etag, entity_tag_size);
        } else {
            free_pcb (pcb_p);
            send_resp_to_app(PUBLISH_FAILED_NORESOURCE, pcb_p->pub_handle, pcb_p->app_handle,
                             pcb_p->callback_task, pcb_p->resp_msg_id);
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX"memory allocation failed\n", fname);
            return SIP_ERROR;
            
        }
    }

    /*
     * If there are no pending requests, provide the response to the application.
     */
    msg_p = (pub_req_t *)sll_next(pcb_p->pending_reqs, NULL);
    if (msg_p != NULL) {
        (void)sll_remove(pcb_p->pending_reqs, msg_p);
        (void)publish_handle_ev_app_publish(msg_p);
        cpr_free(msg_p);
        return SIP_OK;
    }
    send_resp_to_app(response_code, pcb_p->pub_handle, pcb_p->app_handle,
                     pcb_p->callback_task, pcb_p->resp_msg_id);
    CCSIP_DEBUG_TASK(DEB_F_PREFIX"sent response %d to app\n", DEB_F_PREFIX_ARGS(SIP_PUB, fname), response_code);
    return SIP_OK;
}
int
sip_platform_msg_timer_start (uint32_t msec,
                              void *data,
                              int idx,
                              char *message_buffer,
                              int message_buffer_len,
                              int message_type,
                              cpr_ip_addr_t *ipaddr,
                              uint16_t port,
                              boolean isRegister)
{
    static const char fname[] = "sip_platform_msg_timer_start";
    cprTimer_t timer;

    /* validate index */
    if ((idx < MIN_TEL_LINES) || (idx >= MAX_CCBS)) {
        CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_LINE_NUMBER_INVALID),
                          fname, idx);
        return SIP_ERROR;
    }

    /* validate length */
    if (message_buffer_len >= SIP_UDP_MESSAGE_SIZE) {
        CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_MSG_BUFFER_TOO_BIG),
                          fname, message_buffer_len);
        return SIP_ERROR;
    }

    /* stop the timer if it is running */
    if (cprCancelTimer(sipPlatformUISMTimers[idx].timer) == CPR_FAILURE) {
        CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED),
                          idx, 0, fname, "cprCancelTimer");
        return SIP_ERROR;
    }
    if (cprCancelTimer(sipPlatformUISMTimers[idx].reg_timer) == CPR_FAILURE) {
        CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED),
                          idx, 0, fname, "cprCancelTimer");
        return SIP_ERROR;
    }

    if (sipPlatformUISMTimers[idx].message_buffer == NULL) {
        sipPlatformUISMTimers[idx].message_buffer = (char *)cpr_malloc(message_buffer_len+1);
        if (sipPlatformUISMTimers[idx].message_buffer == NULL) return SIP_ERROR;
    }
    else if (message_buffer != sipPlatformUISMTimers[idx].message_buffer) {
        cpr_free(sipPlatformUISMTimers[idx].message_buffer);
        sipPlatformUISMTimers[idx].message_buffer = (char *)cpr_malloc(message_buffer_len+1);
        if (sipPlatformUISMTimers[idx].message_buffer == NULL) return SIP_ERROR;
    }

    sipPlatformUISMTimers[idx].message_buffer_len = message_buffer_len;
    sipPlatformUISMTimers[idx].message_buffer[message_buffer_len] = '\0';
    memcpy(sipPlatformUISMTimers[idx].message_buffer, message_buffer,
           message_buffer_len);
    sipPlatformUISMTimers[idx].message_type = (sipMethod_t) message_type;
    sipPlatformUISMTimers[idx].ipaddr = *ipaddr;
    sipPlatformUISMTimers[idx].port = port;

    /* start the timer */
    if (isRegister) {
        timer = sipPlatformUISMTimers[idx].reg_timer;
    } else {
        timer = sipPlatformUISMTimers[idx].timer;
    }

    if (cprStartTimer(timer, msec, data) == CPR_FAILURE) {
        CCSIP_DEBUG_STATE(get_debug_string(DEBUG_SIP_FUNCTIONCALL_FAILED),
                          idx, 0, fname, "cprStartTimer");
        cpr_free(sipPlatformUISMTimers[idx].message_buffer);
        sipPlatformUISMTimers[idx].message_buffer = NULL;
        sipPlatformUISMTimers[idx].message_buffer_len = 0;
        return SIP_ERROR;
    }
    sipPlatformUISMTimers[idx].outstanding = TRUE;
    return SIP_OK;
}