struct stasis_app_control *control_create(struct ast_channel *channel) { RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup); int res; control = ao2_alloc(sizeof(*control), control_dtor); if (!control) { return NULL; } res = ast_cond_init(&control->wait_cond, NULL); if (res != 0) { ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n", strerror(errno)); return NULL; } control->command_queue = ao2_container_alloc_list( AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL); if (!control->command_queue) { return NULL; } control->channel = channel; AST_LIST_HEAD_INIT(&control->add_rules); AST_LIST_HEAD_INIT(&control->remove_rules); ao2_ref(control, +1); return control; }
struct stasis_subscription *internal_stasis_subscribe( struct stasis_topic *topic, stasis_subscription_cb callback, void *data, int needs_mailbox, int use_thread_pool) { RAII_VAR(struct stasis_subscription *, sub, NULL, ao2_cleanup); if (!topic) { return NULL; } /* The ao2 lock is used for join_cond. */ sub = ao2_t_alloc(sizeof(*sub), subscription_dtor, stasis_topic_name(topic)); if (!sub) { return NULL; } ast_uuid_generate_str(sub->uniqueid, sizeof(sub->uniqueid)); if (needs_mailbox) { char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1]; /* Create name with seq number appended. */ ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "sub%c:%s", use_thread_pool ? 'p' : 'm', stasis_topic_name(topic)); /* * With a small number of subscribers, a thread-per-sub is * acceptable. For a large number of subscribers, a thread * pool should be used. */ if (use_thread_pool) { sub->mailbox = ast_threadpool_serializer(tps_name, pool); } else { sub->mailbox = ast_taskprocessor_get(tps_name, TPS_REF_DEFAULT); } if (!sub->mailbox) { return NULL; } ast_taskprocessor_set_local(sub->mailbox, sub); /* Taskprocessor has a reference */ ao2_ref(sub, +1); } ao2_ref(topic, +1); sub->topic = topic; sub->callback = callback; sub->data = data; ast_cond_init(&sub->join_cond, NULL); if (topic_add_subscription(topic, sub) != 0) { return NULL; } send_subscription_subscribe(topic, sub); ao2_ref(sub, +1); return sub; }
static int setup_mixmonitor_ds(struct mixmonitor *mixmonitor, struct ast_channel *chan) { struct ast_datastore *datastore = NULL; struct mixmonitor_ds *mixmonitor_ds; if (!(mixmonitor_ds = ast_calloc(1, sizeof(*mixmonitor_ds)))) { return -1; } ast_mutex_init(&mixmonitor_ds->lock); ast_cond_init(&mixmonitor_ds->destruction_condition, NULL); if (!(datastore = ast_datastore_alloc(&mixmonitor_ds_info, NULL))) { ast_mutex_destroy(&mixmonitor_ds->lock); ast_cond_destroy(&mixmonitor_ds->destruction_condition); ast_free(mixmonitor_ds); return -1; } /* No need to lock mixmonitor_ds since this is still operating in the channel's thread */ mixmonitor_ds->chan = chan; mixmonitor_ds->audiohook = &mixmonitor->audiohook; datastore->data = mixmonitor_ds; ast_channel_lock(chan); ast_channel_datastore_add(chan, datastore); ast_channel_unlock(chan); mixmonitor->mixmonitor_ds = mixmonitor_ds; return 0; }
static int setup_mixmonitor_ds(struct mixmonitor *mixmonitor, struct ast_channel *chan, char **datastore_id) { struct ast_datastore *datastore = NULL; struct mixmonitor_ds *mixmonitor_ds; if (!(mixmonitor_ds = ast_calloc(1, sizeof(*mixmonitor_ds)))) { return -1; } if (ast_asprintf(datastore_id, "%p", mixmonitor_ds) == -1) { ast_log(LOG_ERROR, "Failed to allocate memory for MixMonitor ID.\n"); } ast_mutex_init(&mixmonitor_ds->lock); ast_cond_init(&mixmonitor_ds->destruction_condition, NULL); if (!(datastore = ast_datastore_alloc(&mixmonitor_ds_info, *datastore_id))) { ast_mutex_destroy(&mixmonitor_ds->lock); ast_cond_destroy(&mixmonitor_ds->destruction_condition); ast_free(mixmonitor_ds); return -1; } mixmonitor_ds->samp_rate = 8000; mixmonitor_ds->audiohook = &mixmonitor->audiohook; datastore->data = mixmonitor_ds; ast_channel_lock(chan); ast_channel_datastore_add(chan, datastore); ast_channel_unlock(chan); mixmonitor->mixmonitor_ds = mixmonitor_ds; return 0; }
static struct shutdown_data *shutdown_data_create(int dont_wait) { RAII_VAR(struct shutdown_data *, shutdown_data, NULL, ao2_cleanup); shutdown_data = ao2_alloc(sizeof(*shutdown_data), shutdown_data_dtor); if (!shutdown_data) { return NULL; } ast_mutex_init(&shutdown_data->lock); ast_cond_init(&shutdown_data->in, NULL); ast_cond_init(&shutdown_data->out, NULL); shutdown_data->task_stop_waiting = dont_wait; ao2_ref(shutdown_data, +1); return shutdown_data; }
/*! * \brief Initialize global mock resolver data. * * This must be called at the beginning of tests that use the mock resolver */ static void resolver_data_init(void) { test_resolver_data.resolve_called = 0; test_resolver_data.canceled = 0; test_resolver_data.resolution_complete = 0; ast_mutex_init(&test_resolver_data.lock); ast_cond_init(&test_resolver_data.cancel_cond, NULL); }
struct ast_serializer_shutdown_group *ast_serializer_shutdown_group_alloc(void) { struct ast_serializer_shutdown_group *shutdown_group; shutdown_group = ao2_alloc(sizeof(*shutdown_group), serializer_shutdown_group_dtor); if (!shutdown_group) { return NULL; } ast_cond_init(&shutdown_group->cond, NULL); return shutdown_group; }
struct stasis_subscription *internal_stasis_subscribe( struct stasis_topic *topic, stasis_subscription_cb callback, void *data, int needs_mailbox, int use_thread_pool) { RAII_VAR(struct stasis_subscription *, sub, NULL, ao2_cleanup); if (!topic) { return NULL; } /* The ao2 lock is used for join_cond. */ sub = ao2_t_alloc(sizeof(*sub), subscription_dtor, topic->name); if (!sub) { return NULL; } ast_uuid_generate_str(sub->uniqueid, sizeof(sub->uniqueid)); if (needs_mailbox) { /* With a small number of subscribers, a thread-per-sub is * acceptable. For larger number of subscribers, a thread * pool should be used. */ if (use_thread_pool) { sub->mailbox = ast_threadpool_serializer(sub->uniqueid, pool); } else { sub->mailbox = ast_taskprocessor_get(sub->uniqueid, TPS_REF_DEFAULT); } if (!sub->mailbox) { return NULL; } ast_taskprocessor_set_local(sub->mailbox, sub); /* Taskprocessor has a reference */ ao2_ref(sub, +1); } ao2_ref(topic, +1); sub->topic = topic; sub->callback = callback; sub->data = data; ast_cond_init(&sub->join_cond, NULL); if (topic_add_subscription(topic, sub) != 0) { return NULL; } send_subscription_subscribe(topic, sub); ao2_ref(sub, +1); return sub; }
static int init_timing_thread(void) { ast_mutex_init(&timing_thread.lock); ast_cond_init(&timing_thread.cond, NULL); if (ast_pthread_create_background(&timing_thread.thread, NULL, do_timing, NULL)) { ast_log(LOG_ERROR, "Unable to start timing thread.\n"); return -1; } return 0; }
static struct consumer *consumer_create(void) { struct consumer *consumer; consumer = ao2_alloc(sizeof(*consumer), consumer_dtor); if (!consumer) { return NULL; } ast_cond_init(&consumer->out, NULL); consumer_reset(consumer); return consumer; }
static struct recurring_data *recurring_data_alloc(void) { struct recurring_data *rdata; rdata = ao2_alloc(sizeof(*rdata), recurring_data_destructor); if (!rdata) { return NULL; } ast_mutex_init(&rdata->lock); ast_cond_init(&rdata->cond, NULL); return rdata; }
/*! * \brief Allocate and initialize a new worker thread * * This will create, initialize, and start the thread. * * \param pool The threadpool to which the worker will be added * \retval NULL Failed to allocate or start the worker thread * \retval non-NULL The newly-created worker thread */ static struct worker_thread *worker_thread_alloc(struct ast_threadpool *pool) { struct worker_thread *worker = ao2_alloc(sizeof(*worker), worker_thread_destroy); if (!worker) { return NULL; } worker->id = ast_atomic_fetchadd_int(&worker_id_counter, 1); ast_mutex_init(&worker->lock); ast_cond_init(&worker->cond, NULL); worker->pool = pool; worker->thread = AST_PTHREADT_NULL; worker->state = ALIVE; worker->options = pool->options; return worker; }
/*! \brief Create a task_data object */ static struct task_data *task_data_create(void) { struct task_data *task_data = ao2_alloc(sizeof(*task_data), task_data_dtor); if (!task_data) { return NULL; } ast_cond_init(&task_data->cond, NULL); ast_mutex_init(&task_data->lock); task_data->task_complete = 0; task_data->wait_time = 0; return task_data; }
/*! * \internal \brief Dispatch a message to a subscriber * \param sub The subscriber to dispatch to * \param message The message to send * \param synchronous If non-zero, synchronize on the subscriber receiving * the message */ static void dispatch_message(struct stasis_subscription *sub, struct stasis_message *message, int synchronous) { if (!sub->mailbox) { /* Dispatch directly */ subscription_invoke(sub, message); return; } /* Bump the message for the taskprocessor push. This will get de-ref'd * by the task processor callback. */ ao2_bump(message); if (!synchronous) { if (ast_taskprocessor_push_local(sub->mailbox, dispatch_exec_async, message)) { /* Push failed; ugh. */ ast_log(LOG_ERROR, "Dropping async dispatch\n"); ao2_cleanup(message); } } else { struct sync_task_data std; ast_mutex_init(&std.lock); ast_cond_init(&std.cond, NULL); std.complete = 0; std.task_data = message; if (ast_taskprocessor_push_local(sub->mailbox, dispatch_exec_sync, &std)) { /* Push failed; ugh. */ ast_log(LOG_ERROR, "Dropping sync dispatch\n"); ao2_cleanup(message); ast_mutex_destroy(&std.lock); ast_cond_destroy(&std.cond); return; } ast_mutex_lock(&std.lock); while (!std.complete) { ast_cond_wait(&std.cond, &std.lock); } ast_mutex_unlock(&std.lock); ast_mutex_destroy(&std.lock); ast_cond_destroy(&std.cond); } }
int astdb_init(void) { if (db_init()) { return -1; } ast_cond_init(&dbcond, NULL); if (ast_pthread_create_background(&syncthread, NULL, db_sync_thread, NULL)) { return -1; } ast_register_atexit(astdb_atexit); ast_cli_register_multiple(cli_database, ARRAY_LEN(cli_database)); ast_manager_register_xml_core("DBGet", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_dbget); ast_manager_register_xml_core("DBPut", EVENT_FLAG_SYSTEM, manager_dbput); ast_manager_register_xml_core("DBDel", EVENT_FLAG_SYSTEM, manager_dbdel); ast_manager_register_xml_core("DBDelTree", EVENT_FLAG_SYSTEM, manager_dbdeltree); return 0; }
static struct stasis_message *caching_guarantee_create(void) { RAII_VAR(struct caching_guarantee *, guarantee, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); if (!(guarantee = ao2_alloc(sizeof(*guarantee), caching_guarantee_dtor))) { return NULL; } ast_mutex_init(&guarantee->lock); ast_cond_init(&guarantee->cond, NULL); if (!(msg = stasis_message_create(cache_guarantee_type(), guarantee))) { return NULL; } ao2_ref(msg, +1); return msg; }
int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value) { if (pshared) { /* Don't need it... yet */ errno = ENOSYS; return -1; } /* Since value is unsigned, this will also catch attempts to init with * a negative value */ if (value > AST_SEM_VALUE_MAX) { errno = EINVAL; return -1; } sem->count = value; sem->waiters = 0; ast_mutex_init(&sem->mutex); ast_cond_init(&sem->cond, NULL); return 0; }
int astdb_init(void) { ast_cond_init(&dbcond, NULL); if (ast_pthread_create_background(&syncthread, NULL, db_sync_thread, NULL)) { return -1; } ast_mutex_lock(&dblock); /* Ignore check_return warning from Coverity for dbinit below */ dbinit(); ast_mutex_unlock(&dblock); ast_cli_register_multiple(cli_database, ARRAY_LEN(cli_database)); ast_manager_register_xml("DBGet", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_dbget); ast_manager_register_xml("DBPut", EVENT_FLAG_SYSTEM, manager_dbput); ast_manager_register_xml("DBDel", EVENT_FLAG_SYSTEM, manager_dbdel); ast_manager_register_xml("DBDelTree", EVENT_FLAG_SYSTEM, manager_dbdeltree); ast_register_atexit(astdb_shutdown); return 0; }
static struct timespec make_deadline(int timeout_millis) { struct timeval start = ast_tvnow(); struct timeval delta = { .tv_sec = timeout_millis / 1000, .tv_usec = (timeout_millis % 1000) * 1000, }; struct timeval deadline_tv = ast_tvadd(start, delta); struct timespec deadline = { .tv_sec = deadline_tv.tv_sec, .tv_nsec = 1000 * deadline_tv.tv_usec, }; return deadline; } struct stasis_message_sink *stasis_message_sink_create(void) { RAII_VAR(struct stasis_message_sink *, sink, NULL, ao2_cleanup); sink = ao2_alloc(sizeof(*sink), stasis_message_sink_dtor); if (!sink) { return NULL; } ast_mutex_init(&sink->lock); ast_cond_init(&sink->cond, NULL); sink->max_messages = 4; sink->messages = ast_malloc(sizeof(*sink->messages) * sink->max_messages); if (!sink->messages) { return NULL; } ao2_ref(sink, +1); return sink; } /*! * \brief Implementation of the stasis_message_sink_cb() callback. * * Why the roundabout way of exposing this via stasis_message_sink_cb()? Well, * it has to do with how we load modules. * * Modules have their own metadata compiled into them in the module info block * at the end of the file. This includes dependency information in the * \c nonoptreq field. * * Asterisk loads the module, inspects the field, then loads any needed * dependencies. This works because Asterisk passes \c RTLD_LAZY to the initial * dlopen(), which defers binding function references until they are called. * * But when you take the address of a function, that function needs to be * available at load time. So if some module used the address of * message_sink_cb() directly, and \c res_stasis_test.so wasn't loaded yet, then * that module would fail to load. * * The stasis_message_sink_cb() function gives us a layer of indirection so that * the initial lazy binding will still work as expected. */ static void message_sink_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message) { struct stasis_message_sink *sink = data; SCOPED_MUTEX(lock, &sink->lock); if (stasis_subscription_final_message(sub, message)) { sink->is_done = 1; ast_cond_signal(&sink->cond); return; } if (stasis_subscription_change_type() == stasis_message_type(message)) { /* Ignore subscription changes */ return; } if (sink->num_messages == sink->max_messages) { size_t new_max_messages = sink->max_messages * 2; struct stasis_message **new_messages = ast_realloc( sink->messages, sizeof(*new_messages) * new_max_messages); if (!new_messages) { return; } sink->max_messages = new_max_messages; sink->messages = new_messages; } ao2_ref(message, +1); sink->messages[sink->num_messages++] = message; ast_cond_signal(&sink->cond); } stasis_subscription_cb stasis_message_sink_cb(void) { return message_sink_cb; } int stasis_message_sink_wait_for_count(struct stasis_message_sink *sink, int num_messages, int timeout_millis) { struct timespec deadline = make_deadline(timeout_millis); SCOPED_MUTEX(lock, &sink->lock); while (sink->num_messages < num_messages) { int r = ast_cond_timedwait(&sink->cond, &sink->lock, &deadline); if (r == ETIMEDOUT) { break; } if (r != 0) { ast_log(LOG_ERROR, "Unexpected condition error: %s\n", strerror(r)); break; } } return sink->num_messages; } int stasis_message_sink_should_stay(struct stasis_message_sink *sink, int num_messages, int timeout_millis) { struct timespec deadline = make_deadline(timeout_millis); SCOPED_MUTEX(lock, &sink->lock); while (sink->num_messages == num_messages) { int r = ast_cond_timedwait(&sink->cond, &sink->lock, &deadline); if (r == ETIMEDOUT) { break; } if (r != 0) { ast_log(LOG_ERROR, "Unexpected condition error: %s\n", strerror(r)); break; } } return sink->num_messages; } int stasis_message_sink_wait_for(struct stasis_message_sink *sink, int start, stasis_wait_cb cmp_cb, const void *data, int timeout_millis) { struct timespec deadline = make_deadline(timeout_millis); SCOPED_MUTEX(lock, &sink->lock); /* wait for the start */ while (sink->num_messages < start + 1) { int r = ast_cond_timedwait(&sink->cond, &sink->lock, &deadline); if (r == ETIMEDOUT) { /* Timed out waiting for the start */ return -1; } if (r != 0) { ast_log(LOG_ERROR, "Unexpected condition error: %s\n", strerror(r)); return -2; } } while (!cmp_cb(sink->messages[start], data)) { ++start; while (sink->num_messages < start + 1) { int r = ast_cond_timedwait(&sink->cond, &sink->lock, &deadline); if (r == ETIMEDOUT) { return -1; } if (r != 0) { ast_log(LOG_ERROR, "Unexpected condition error: %s\n", strerror(r)); return -2; } } } return start; } struct stasis_message *stasis_test_message_create(void) { RAII_VAR(void *, data, NULL, ao2_cleanup); if (!stasis_test_message_type()) { return NULL; } /* We just need the unique pointer; don't care what's in it */ data = ao2_alloc(1, NULL); if (!data) { return NULL; } return stasis_message_create(stasis_test_message_type(), data); }
static int scheduler(struct ast_test *test, int serialized) { RAII_VAR(struct ast_taskprocessor *, tp1, NULL, ast_taskprocessor_unreference); RAII_VAR(struct test_data *, test_data1, ao2_alloc(sizeof(*test_data1), data_cleanup), ao2_cleanup); RAII_VAR(struct test_data *, test_data2, ao2_alloc(sizeof(*test_data2), data_cleanup), ao2_cleanup); RAII_VAR(struct ast_sip_sched_task *, task1, NULL, ao2_cleanup); RAII_VAR(struct ast_sip_sched_task *, task2, NULL, ao2_cleanup); int duration; int delay; struct timeval task1_start; ast_test_validate(test, test_data1 != NULL); ast_test_validate(test, test_data2 != NULL); test_data1->test = test; test_data1->test_start = ast_tvnow(); test_data1->interval = 2000; test_data1->sleep = 1000; ast_mutex_init(&test_data1->lock); ast_cond_init(&test_data1->cond, NULL); test_data2->test = test; test_data2->test_start = ast_tvnow(); test_data2->interval = 2000; test_data2->sleep = 1000; ast_mutex_init(&test_data2->lock); ast_cond_init(&test_data2->cond, NULL); if (serialized) { ast_test_status_update(test, "This test will take about %3.1f seconds\n", (test_data1->interval + test_data1->sleep + (MAX(test_data1->interval - test_data2->interval, 0)) + test_data2->sleep) / 1000.0); tp1 = ast_sip_create_serializer("test-scheduler-serializer"); ast_test_validate(test, (tp1 != NULL)); } else { ast_test_status_update(test, "This test will take about %3.1f seconds\n", ((MAX(test_data1->interval, test_data2->interval) + MAX(test_data1->sleep, test_data2->sleep)) / 1000.0)); } task1 = ast_sip_schedule_task(tp1, test_data1->interval, task_1, NULL, test_data1, AST_SIP_SCHED_TASK_FIXED); ast_test_validate(test, task1 != NULL); task2 = ast_sip_schedule_task(tp1, test_data2->interval, task_1, NULL, test_data2, AST_SIP_SCHED_TASK_FIXED); ast_test_validate(test, task2 != NULL); waitfor(test_data1); ast_sip_sched_task_cancel(task1); ast_test_validate(test, test_data1->is_servant); duration = ast_tvdiff_ms(test_data1->task_end, test_data1->test_start); ast_test_validate(test, (duration > ((test_data1->interval + test_data1->sleep) * 0.9)) && (duration < ((test_data1->interval + test_data1->sleep) * 1.1))); ast_sip_sched_task_get_times(task1, NULL, &task1_start, NULL); delay = ast_tvdiff_ms(task1_start, test_data1->test_start); ast_test_validate(test, (delay > (test_data1->interval * 0.9) && (delay < (test_data1->interval * 1.1)))); waitfor(test_data2); ast_sip_sched_task_cancel(task2); ast_test_validate(test, test_data2->is_servant); if (serialized) { ast_test_validate(test, test_data1->tid == test_data2->tid); ast_test_validate(test, ast_tvdiff_ms(test_data2->task_start, test_data1->task_end) >= 0); } else { ast_test_validate(test, test_data1->tid != test_data2->tid); } return AST_TEST_PASS; }
OOH323CallData* ooCreateCall(char* type, char*callToken) { OOH323CallData *call=NULL; OOCTXT *pctxt=NULL; OOCTXT *msgctxt=NULL; pctxt = newContext(); if(!pctxt) { OOTRACEERR1("ERROR:Failed to create OOCTXT for new call\n"); return NULL; } msgctxt = newContext(); if(!msgctxt) { OOTRACEERR1("ERROR:Failed to create OOCTXT for new call\n"); return NULL; } ast_mutex_lock(&newCallLock); /* call = (OOH323CallData*)memAlloc(&gH323ep.ctxt, sizeof(OOH323CallData)); */ call = (OOH323CallData*)memAlloc(pctxt, sizeof(OOH323CallData)); ast_mutex_unlock(&newCallLock); if(!call) { OOTRACEERR1("ERROR:Memory - ooCreateCall - call\n"); return NULL; } memset(call, 0, sizeof(OOH323CallData)); ast_cond_init(&call->gkWait, NULL); ast_mutex_init(&call->GkLock); ast_mutex_init(&call->Lock); call->pctxt = pctxt; call->msgctxt = msgctxt; call->callMode = gH323ep.callMode; sprintf(call->callToken, "%s", callToken); sprintf(call->callType, "%s", type); call->callReference = 0; if(gH323ep.callerid) { strncpy(call->ourCallerId, gH323ep.callerid, sizeof(call->ourCallerId)-1); call->ourCallerId[sizeof(call->ourCallerId)-1] = '\0'; } else { call->ourCallerId[0] = '\0'; } memset(&call->callIdentifier, 0, sizeof(H225CallIdentifier)); memset(&call->confIdentifier, 0, sizeof(H225ConferenceIdentifier)); call->flags = 0; if (OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING)) OO_SETFLAG (call->flags, OO_M_TUNNELING); if(gH323ep.gkClient) { if(OO_TESTFLAG(gH323ep.flags, OO_M_GKROUTED)) { OO_SETFLAG(call->flags, OO_M_GKROUTED); } } if (OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART)) OO_SETFLAG (call->flags, OO_M_FASTSTART); if (OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN)) OO_SETFLAG (call->flags, OO_M_MEDIAWAITFORCONN); call->fsSent = FALSE; // May 20090713. Fix it for Video session OO_SETFLAG(call->flags, OO_M_AUDIOSESSION); call->callState = OO_CALL_CREATED; call->callEndReason = OO_REASON_UNKNOWN; call->pCallFwdData = NULL; if(!strcmp(call->callType, "incoming")) { call->callingPartyNumber = NULL; } else{ if(ooUtilsIsStrEmpty(gH323ep.callingPartyNumber)) { call->callingPartyNumber = NULL; } else{ call->callingPartyNumber = (char*) memAlloc(call->pctxt, strlen(gH323ep.callingPartyNumber)+1); if(call->callingPartyNumber) { strcpy(call->callingPartyNumber, gH323ep.callingPartyNumber); } else{ OOTRACEERR3("Error:Memory - ooCreateCall - callingPartyNumber" ".(%s, %s)\n", call->callType, call->callToken); freeContext(pctxt); return NULL; } } } call->calledPartyNumber = NULL; call->h245ConnectionAttempts = 0; call->h245SessionState = OO_H245SESSION_IDLE; call->dtmfmode = gH323ep.dtmfmode; call->mediaInfo = NULL; strcpy(call->localIP, gH323ep.signallingIP); call->pH225Channel = NULL; call->pH245Channel = NULL; call->h245listener = NULL; call->h245listenport = NULL; call->remoteIP[0] = '\0'; call->remotePort = 0; call->remoteH245Port = 0; call->remoteDisplayName = NULL; call->remoteAliases = NULL; call->ourAliases = NULL; call->masterSlaveState = OO_MasterSlave_Idle; call->statusDeterminationNumber = 0; call->localTermCapState = OO_LocalTermCapExchange_Idle; call->remoteTermCapState = OO_RemoteTermCapExchange_Idle; call->ourCaps = NULL; call->remoteCaps = NULL; call->jointCaps = NULL; dListInit(&call->remoteFastStartOLCs); call->remoteTermCapSeqNo =0; call->localTermCapSeqNo = 0; memcpy(&call->capPrefs, &gH323ep.capPrefs, sizeof(OOCapPrefs)); call->logicalChans = NULL; call->noOfLogicalChannels = 0; call->logicalChanNoBase = 1001; call->logicalChanNoMax = 1100; call->logicalChanNoCur = 1001; call->nextSessionID = 4; /* 1,2,3 are reserved for audio, video and data */ dListInit(&call->timerList); call->msdRetries = 0; call->pFastStartRes = NULL; call->usrData = NULL; OOTRACEINFO3("Created a new call (%s, %s)\n", call->callType, call->callToken); /* Add new call to calllist */ ooAddCallToList (call); if(gH323ep.h323Callbacks.onNewCallCreated) gH323ep.h323Callbacks.onNewCallCreated(call); return call; }