/* * Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved. * Contact: http://philzimmermann.com * For licensing and other legal details, see the file zrtp_legal.c. */ #include #include #include #include #include #include #include #include extern "C" { /** * @brief Get kernel-generated random number * @bug seems not work * @return 32 random bits */ uint32_t zrtp_symbian_kernel_random(); /** * @brief Pseudo random number: sum of pid's shifted and xored by number of precceses * @return */ uint32_t zrtp_sum_of_pid_and_number_of_poccesses(); /** * @brief Number of milisecond past from particular date and time * @return */ uint64_t zrtp_get_system_time_crazy(); /** * @brief Current procces PID * @return PID */ unsigned int zrtp_get_pid(); /** * @brief Availible memory * @return memory availible on heap */ uint32_t zrtp_get_availible_heap(); } //----------------------------------------------------------------------------- zrtp_status_t zrtp_mutex_init(zrtp_mutex_t **mutex) { RMutex *rmutex = new RMutex(); //rmutex->CreateLocal(); was before rmutex->CreateGlobal(KNullDesC); *mutex = (zrtp_mutex_t*) rmutex; return zrtp_status_ok; } zrtp_status_t zrtp_mutex_lock(zrtp_mutex_t* mutex) { RMutex *rmutex = (RMutex *) mutex; rmutex->Wait(); return zrtp_status_ok; } zrtp_status_t zrtp_mutex_unlock(zrtp_mutex_t* mutex) { RMutex *rmutex = (RMutex *) mutex; rmutex->Signal(); return zrtp_status_ok; } zrtp_status_t zrtp_mutex_destroy(zrtp_mutex_t* mutex) { RMutex *rmutex = (RMutex *) mutex; if (rmutex) { rmutex->Close(); delete rmutex; } return zrtp_status_ok; } //----------------------------------------------------------------------------- zrtp_status_t zrtp_sem_init(zrtp_sem_t** sem, uint32_t value, uint32_t limit) { RSemaphore *rsem = new RSemaphore(); //rsem->CreateLocal(value); rsem->CreateGlobal(KNullDesC,value); *sem = (zrtp_sem_t*) rsem; return zrtp_status_ok; } zrtp_status_t zrtp_sem_destroy(zrtp_sem_t* sem) { RSemaphore *rsem = (RSemaphore *) sem; if (rsem) { rsem->Close(); delete rsem; } return zrtp_status_ok; } zrtp_status_t zrtp_sem_wait(zrtp_sem_t* sem) { RSemaphore *rsem = (RSemaphore *) sem; rsem->Wait(); return zrtp_status_ok; } zrtp_status_t zrtp_sem_trtwait(zrtp_sem_t* sem) { RSemaphore *rsem = (RSemaphore *) sem; rsem->Wait(1000); return zrtp_status_ok; } zrtp_status_t zrtp_sem_post(zrtp_sem_t* sem) { RSemaphore *rsem = (RSemaphore *) sem; rsem->Signal(); return zrtp_status_ok; } //----------------------------------------------------------------------------- int zrtp_sleep(unsigned int msec) { TTimeIntervalMicroSeconds32 i(msec *1000); User::After(i); return 0; } int zrtp_thread_create(zrtp_thread_routine_t start_routine, void *arg) { RThread h; TBuf<64> thName=_L("zrtp_thread"); h.Create(thName, start_routine, KDefaultStackSize*2, NULL, arg) ; h.Resume(); h.Close(); return NULL; } //----------------------------------------------------------------------------- // For Scheduler #if (defined(ZRTP_USE_BUILTIN_SCEHDULER) && (ZRTP_USE_BUILTIN_SCEHDULER ==1)) #include "DelayRuner.h" #include "zrtp_error.h" mlist_t tasks_head_s; static uint8_t inited = 0 ; static uint8_t is_running = 0; typedef struct { zrtp_stream_t *ctx; /** ZRTP stream context associated with the task */ zrtp_retry_task_t *ztask; /** ZRTP stream associated with the task */ mlist_t _mlist; CDelayRuner* ao; // Active object } zrtp_sched_task_s_t; zrtp_status_t zrtp_def_scheduler_init(zrtp_global_t* zrtp) { zrtp_status_t status = zrtp_status_ok; ZRTP_LOG(3,("symbian","Init start")); if (inited) { return zrtp_status_ok; } do { init_mlist(&tasks_head_s); is_running = 1; inited = 1; } while (0); ZRTP_LOG(3,("symbian","Init end")); return status; } void zrtp_def_scheduler_down() { ZRTP_LOG(3,("symbian","Down start")); mlist_t *node = 0, *tmp = 0; if (!inited) { return; } /* Stop main thread */ is_running = 0; // zrtp_sem_post(count); /* Then destroy tasks queue and realease all other resources */ //zrtp_mutex_lock(protector); mlist_for_each_safe(node, tmp, &tasks_head_s) { zrtp_sched_task_s_t* task = mlist_get_struct(zrtp_sched_task_s_t, _mlist, node); if (task->ao!=NULL) { delete task->ao; } zrtp_sys_free(task); } init_mlist(&tasks_head_s); // zrtp_mutex_unlock(protector); // zrtp_mutex_destroy(protector); // zrtp_sem_destroy(count); ZRTP_LOG(3,("symbian","Down end")); inited = 0; } void zrtp_def_scheduler_call_later(zrtp_stream_t *ctx, zrtp_retry_task_t* ztask) { // ZRTP_LOG(3,("symbian","CallLater start")); //mlist_t *node=0, *tmp=0; mlist_t* last = &tasks_head_s; //zrtp_mutex_lock(protector); if (!ztask->_is_enabled) { //zrtp_mutex_unlock(protector); return; } do { zrtp_sched_task_s_t* new_task = (zrtp_sched_task_s_t*)zrtp_sys_alloc(sizeof(zrtp_sched_task_s_t)); if (!new_task) { break; } new_task->ctx = ctx; new_task->ztask = ztask; new_task->ao = CDelayRuner::NewL(); mlist_insert(last, &new_task->_mlist); new_task->ao->StartL(ctx,ztask); //zrtp_sem_post(count); } while (0); //ZRTP_LOG(3,("symbian","CallLater end")); //zrtp_mutex_unlock(protector); } void zrtp_def_scheduler_cancel_call_later(zrtp_stream_t* ctx, zrtp_retry_task_t* ztask) { mlist_t *node=0, *tmp=0; ZRTP_LOG(3,("symbian","CancelcallLater start")); // zrtp_mutex_lock(protector); mlist_for_each_safe(node, tmp, &tasks_head_s) { zrtp_sched_task_s_t* task = mlist_get_struct(zrtp_sched_task_s_t, _mlist, node); if ((task->ctx == ctx) && ((task->ztask == ztask) || !ztask)) { task->ao->Cancel(); delete task->ao; // Cancel and delete task mlist_del(&task->_mlist); zrtp_sys_free(task); //zrtp_sem_trtwait(count); if (ztask) { break; } } } ZRTP_LOG(3,("symbian","CancelCallLater done")); // zrtp_mutex_unlock(protector); } void zrtp_internal_delete_task_from_list(zrtp_stream_t* ctx, zrtp_retry_task_t* ztask) { mlist_t *node=0, *tmp=0; ZRTP_LOG(3,("symbian","DelTask begin")); mlist_for_each_safe(node, tmp, &tasks_head_s) { zrtp_sched_task_s_t* task = mlist_get_struct(zrtp_sched_task_s_t, _mlist, node); if ((task->ctx == ctx) && ((task->ztask == ztask) || !ztask)) { delete task->ao; // Cancel and delete task mlist_del(&task->_mlist); zrtp_sys_free(task); ZRTP_LOG(3,("symbian","DelTask Del")); //zrtp_sem_trtwait(count); if (ztask) { break; } } } ZRTP_LOG(3,("symbian","DelTask end")); } void zrtp_def_scheduler_wait_call_later(zrtp_stream_t* ctx) { } #endif // ZRTP_USE_BUILTIN_SCEHDULER //----------------------------------------------------------------------------- unsigned int zrtp_get_pid() { return getpid(); } uint64_t zrtp_get_system_time_crazy() { TTime time; return time.MicroSecondsFrom(TTime(TDateTime (491,EAugust,7,3,37,17,347))).Int64(); } uint32_t zrtp_sum_of_pid_and_number_of_poccesses() { TFindProcess fp; RProcess procces; TFullName proccesName; uint_32t idsum=1; uint_32t proccesCount=0; fp.Find(KNullDesC); while (fp.Next(proccesName)==KErrNone) { if (procces.Open(proccesName,EOwnerProcess)==KErrNone) { idsum+=procces.Id(); proccesCount++; procces.Close(); } } idsum = (idsum << 3) xor proccesCount; return idsum; } uint32_t zrtp_get_availible_heap() { return User::Heap().MaxLength(); } uint32_t zrtp_symbian_kernel_random() { return Math::Random(); }