Exemple #1
0
static NotificationAttributes * LookupNotificationAttributes(struct ListHead * attributesList, int shortServerID, ObjectIDType objectID,
                                                             ObjectInstanceIDType objectInstanceID, ResourceIDType resourceID)
{
    NotificationAttributes * result = NULL;
    if (attributesList != NULL)
    {
        struct ListHead * i;
        ListForEach(i, attributesList)
        {
            NotificationAttributes * attributes = ListEntry(i, NotificationAttributes, list);
            if ((attributes != NULL) &&
                (attributes->ShortServerID == shortServerID) &&
                (attributes->ObjectID == objectID) &&
                (attributes->ObjectInstanceID == objectInstanceID) &&
                (attributes->ResourceID == resourceID))
            {
                result = attributes;
                break;
            }
        }
        if (result == NULL)
        {
            // doesn't exist yet, so create
            result = malloc(sizeof(NotificationAttributes));
            memset(result, 0, sizeof(NotificationAttributes));
            memset(result->Valid, 0, sizeof(result->Valid));
            result->ObjectID = objectID;
            result->ObjectInstanceID = objectInstanceID;
            result->ResourceID = resourceID;
            result->ShortServerID = shortServerID;
            ListAdd(&result->list, attributesList);
        }
    }
Exemple #2
0
////////////////////////////////////////////////////
// 功能:
// 输入:
// 输出:
// 返回:
// 说明:
////////////////////////////////////////////////////
int MediaSrvRegistCallback(int type, DWORD device, PMEDIA_CALLBACK callback)
{
	PLIST n;
	PLIST head;
	PCALLBACK_LINK check;
	PCALLBACK_LINK link;

	// 申请节点,并初始化
	link = kmalloc(sizeof(CALLBACK_LINK));
	if(link == NULL)
		return -1;
	kmemcpy(&link->Callback, callback, sizeof(MEDIA_CALLBACK));
	link->Type = type;
	link->Device = device;
	ListInit(&link->Link);
	
	// 检查设备是否已经注册
	head = &MediaCallbackList;
	for(n=ListFirst(head); n!=head; n=ListNext(n))
	{
		check = ListEntry(n, CALLBACK_LINK, Link);
		if(&check->Callback == callback)
		{
			kfree(link);
			return -1;
		}
	}
	ListInsert(&MediaCallbackList, &link->Link);		
	return 0;
}
Exemple #3
0
////////////////////////////////////////////////////
// 功能: 结束某一任务的媒体播放,并锁定媒体播放任务
// 输入:
// 输出:
// 返回:
// 说明:
////////////////////////////////////////////////////
void MediaTerminateLock(HANDLE htask)
{
	PMEDIA_OBJECT obj;
	PLIST list;
	
	kMutexWait(hMediaMutex);
	list = &MediaObjList;
	if(!ListEmpty(list))
	{
		// 获取正在音频任务节点
		obj = ListEntry(ListFirst(list), MEDIA_OBJECT, Link);
		
		if(obj->hTask == htask)
		{
			// 结束当前正在录放的音频任务
			obj->Cb.MediaClose(obj->Media, 1);
			obj->Cb.MediaDestroy(obj->Media);
			
			ListRemove(&obj->Link);
			HandleDestroy(obj->Header.Handle, MEDIA_MAGIC);
			if(obj->MediaInfo)
				kfree(obj->MediaInfo);
			kfree(obj);
		}
	}
}
Exemple #4
0
////////////////////////////////////////////////////
// 功能:
// 输入:
// 输出:
// 返回:
// 说明:
////////////////////////////////////////////////////
int MediaSrvDestroyNotify(void *media)
{
	PLIST head;
	PLIST n;
	PMEDIA_OBJECT obj;
	
//	kMutexWait(hMediaMutex);
	head = &MediaObjList;
	
	// 搜索指定音频任务
	for(n = ListFirst(head); n != head; n = ListNext(n))
	{
		obj = ListEntry(n, MEDIA_OBJECT, Link);
		if(obj->Media == media)
		{
			// 释放当前节点
			kdebug(mod_media, PRINT_INFO, "CLOSE Notify: 0x%x\n", obj->Header.Handle);
			ListRemove(&obj->Link);
			HandleDestroy(obj->Header.Handle, MEDIA_MAGIC);			
			if(obj->MediaInfo)
				kfree(obj->MediaInfo);
			kfree(obj);
			
			// 启动下一个等待任务
			n = ListFirst(head);
			if(n != head)
			{
				obj = ListEntry(n, MEDIA_OBJECT, Link);
				if(obj->Mode == MEDIA_MODE_WAIT)
				{
					if(obj->Cb.MediaOpen(obj->Media) < 0)
					{
						ListRemove(&obj->Link);
						HandleDestroy(obj->Header.Handle, MEDIA_MAGIC);
						if(obj->MediaInfo)
							kfree(obj->MediaInfo);
						kfree(obj);
					}
				}
			}
//			kMutexRelease(hMediaMutex);
			return 0;
		}
	}
//	kMutexRelease(hMediaMutex);
	return -1;	
}
Exemple #5
0
 void for_each(T const &fn)
 {
     struct udev_list_entry *entry;
     udev_list_entry_foreach(entry, p) {
         if (!fn(ListEntry(entry)))
             break;
     }
 }
Exemple #6
0
void Array_Free(struct ListHead * ValueList, AwaResourceType resourceType)
{
    struct ListHead * current, * next;
    ListForEachSafe(current, next, ValueList)
    {
        ArrayItem * valueItem = ListEntry(current, ArrayItem, List);
        ListRemove(current);
        Array_FreeItem(valueItem, resourceType);
    }
Exemple #7
0
int MediaSrvDestroy(HANDLE hmedia)
#endif
{
	PMEDIA_OBJECT obj;
	int playback;

	kMutexWait(hMediaMutex);
	
	// 获取音频对象
	obj = (PMEDIA_OBJECT)HandleGet(hmedia, MEDIA_MAGIC);
	if(obj == NULL)
	{
		kdebug(mod_media, PRINT_ERROR, "CLOSE NULL: 0x%x\n", hmedia);
		kMutexRelease(hMediaMutex);
		return -1;
	}
	kdebug(mod_media, PRINT_INFO, "CLOSE: 0x%x\n", hmedia);
	
	// 结束当前正在录放的音频任务
	playback = obj->Cb.MediaClose(obj->Media, 1);
	obj = (PMEDIA_OBJECT)HandleGet(hmedia, MEDIA_MAGIC);
	if(obj == NULL)
	{
		kdebug(mod_media, PRINT_ERROR, "CLOSE NULL NULL: 0x%x\n", hmedia);
		kMutexRelease(hMediaMutex);
		return -1;
	}
	obj->Cb.MediaDestroy(obj->Media);
	
	// 释放当前节点
	ListRemove(&obj->Link);
	HandleDestroy(hmedia, MEDIA_MAGIC);
	if(obj->MediaInfo)
		kfree(obj->MediaInfo);
	kfree(obj);
	
	// 启动下一个等待任务
	if(!ListEmpty(&MediaObjList))
	{
		obj = ListEntry(ListFirst(&MediaObjList), MEDIA_OBJECT, Link);
		if(playback && (obj->Mode == MEDIA_MODE_WAIT))
		{
			if(obj->Cb.MediaOpen(obj->Media) < 0)
			{
				HandleDestroy(obj->Header.Handle, MEDIA_MAGIC);
				if(obj->MediaInfo)
					kfree(obj->MediaInfo);
				kfree(obj);
			}
		}
	}
	kMutexRelease(hMediaMutex);
	return 0;
}
static Lwm2mServerType * GetServerObjectByObjectInstanceID(Lwm2mContextType * context, int objectInstanceID)
{
    Lwm2mServerType * serverObject = NULL;
    struct ListHead * i;
    ListForEach(i, Lwm2mCore_GetServerList(context))
    {
        Lwm2mServerType * server = ListEntry(i, Lwm2mServerType, list);
        if (server->ServerObjectInstanceID == objectInstanceID)
        {
            serverObject = server;
        }
    }
static Lwm2mObserverType * LookupObserver(void * ctxt, AddressType * addr, ObjectIDType objectID, ObjectInstanceIDType objectInstanceID, ResourceIDType resourceID)
{
    Lwm2mContextType * context = (Lwm2mContextType *) ctxt;
    struct ListHead * i, *n;
    ListForEachSafe(i, n, Lwm2mCore_GetObserverList(context))
    {
        Lwm2mObserverType * observer = ListEntry(i, Lwm2mObserverType, list);

        if ((observer->ObjectID == objectID) &&
            (observer->ObjectInstanceID == objectInstanceID) &&
            (observer->ResourceID == resourceID) &&
            (memcmp(&observer->Address, addr, sizeof(AddressType)) == 0))
        {
            return observer;
        }
    }
Exemple #10
0
//Performs the user mode memory checks on the current memory context
static bool MemChecks(unsigned int addr, unsigned int length, unsigned int flagsReqd)
{
	//Kernel checks handled separately
	if(addr >= 0xC0000000)
	{
		//Return true if not wrapping around
		return (addr + length) >= addr;
	}

	//Find first region
	MemContext * context = ProcCurrProcess->memContext;
	MemRegion * region = MemRegionFind(context, (void *) addr);

	while(region != NULL && (region->flags & flagsReqd) == flagsReqd)
	{
		//Calculate data left
		unsigned int end = region->start + region->length;
		unsigned int lengthLeft = end - addr;

		if(lengthLeft >= length)
		{
			//Passed (since we known this region is readable)
			return true;
		}

		//Move to next region if it is continuous
		if(region->listItem.next == &context->regions)
		{
			//This is the last region, fail
			return false;
		}

		region = ListEntry(region->listItem.next, MemRegion, listItem);

		if (region->start == end)
		{
			//Not continuous, fail
			return false;
		}

		//Update parameters
		addr = region->start;
		length -= lengthLeft;
	}

	return false;
}
Exemple #11
0
////////////////////////////////////////////////////
// 功能: 根据媒体类型,获取媒体回调函数
// 输入:
// 输出:
// 返回:
// 说明:
////////////////////////////////////////////////////
static int MediaSrvGetCallback(int type, PMEDIA_CALLBACK callback)
{
	PLIST n;
	PLIST head;
	PCALLBACK_LINK link;

	// 检查设备是否已经注册
	head = &MediaCallbackList;
	for(n=ListFirst(head); n!=head; n=ListNext(n))
	{
		link = ListEntry(n, CALLBACK_LINK, Link);
		if((link->Type & type) == type)
		{
			kmemcpy(callback, &link->Callback, sizeof(MEDIA_CALLBACK));
			return 0;
		}
	}
	return -1;
}
Exemple #12
0
//Sets the PROCESS alarm
TimerTime TimerSetAlarm(TimerTime time)
{
	TimerTime timeLeft;
	TimerQueue * queueHead;

	//First, remove previous alarm
	if(ProcCurrProcess->alarmPtr != NULL)
	{
		//Get time left
		queueHead = ListEntry(ProcCurrProcess->alarmPtr, TimerQueue, list);
		timeLeft = queueHead->endTime - currentTime;

		//Remove from list + free
		ListDelete(&queueHead->list);
		MemKFree(queueHead);

		//Wipe from process
		ProcCurrProcess->alarmPtr = NULL;
	}
	else
	{
		timeLeft = 0;
	}

	//If time is not 0, create new alarm
	if(time != 0)
	{
		//Create alarm
		queueHead = MemKAlloc(sizeof(TimerQueue));
		queueHead->process = ProcCurrProcess;
		queueHead->endTime = time;

		//Add to list
		AddTimerToQueue(queueHead, &alarmQueueHead);

		//Add to process
		ProcCurrProcess->alarmPtr = &queueHead->list;
	}

	return timeLeft;
}
Exemple #13
0
////////////////////////////////////////////////////
// 功能: 得到BUF里剩余数据的时间
// 输入: 
// 输出:
// 返回: 
// 说明: 
////////////////////////////////////////////////////
int GetDacSpaceCount()
{
	int i;
	int len;
	PLIST head, n;
	PDAC_DEVICE dac;
	PRESAMPLE presample;

	kMutexWait(hDacMutex);
	len = 0;
	head = &DacList;
	if( head )
	{
		n=ListFirst(head);
		dac = ListEntry(n, DAC_DEVICE, Link);
		if( dac )
		{
			presample = &dac->Resample;
			for( i = 0 ; i < MAX_PCMBUFS ; i++ )
			{
				if( presample->BufFlag[i] == DAC_BUF_WRITE )
					len +=DAC_PCMBUF_SIZE;
			}
		}
	}
	
	presample = &DacDevice;
	for( i = 0 ; i < MAX_PCMBUFS ; i++ )
	{
		if( presample->BufFlag[i] == DAC_BUF_WRITE )
			len +=DAC_PCMBUF_SIZE;
	}
	kMutexRelease(hDacMutex);

	len = ((long long)len * nMplayerSamplerate * nMplayerChannels * 2) / (DAC_SAMPLE_RATIO * 2 * 2);
	len = len & (~0x03);
	return len;
}
Exemple #14
0
////////////////////////////////////////////////////
// 功能: 
// 输入: 
// 输出:
// 返回: 
// 说明: 
////////////////////////////////////////////////////
static void DacWriteThread(DWORD p)
{
	int bopen;
	char play_flag;
	short *pcm;
	short gvol;

	pcm = NULL;
	bopen = 0;
	gvol = 0;
	for(;;)
	{	
		PLIST head, n;
		short *src[4];
		short vol[4];
		PDAC_DEVICE dac[4];
		int chs;
		int i, j;
		int tmp;

		// 等待DAC设备创建
		if(!bopen)
		{
			kSemaWait(hDacSema, 0);
			bopen = 1;
			pcm = (short*)kmalloc(DAC_PCMBUF_SIZE);
		}

		// 检查DAC是否已经关闭
		kMutexWait(hDacMutex);
		if(ListEmpty(&DacList))
		{
			if(pcm)
			{
				kfree(pcm);
				pcm = NULL;
			}
			bopen = 0;
			kMutexRelease(hDacMutex);
			continue;
		}

		// 检查缓冲区是否获取
		if(pcm == NULL)
		{
			kMutexRelease(hDacMutex);
			sTimerSleep(1000, NULL);
			continue;
		}

		// 获取采样数据到临时缓冲区
		head = &DacList;
		chs = play_flag = 0;
		for(n=ListFirst(head); n!=head; n=ListNext(n))
		{
			dac[chs] = ListEntry(n, DAC_DEVICE, Link);
			src[chs] = DacGetPcmBuf(dac[chs]);
			vol[chs] = dac[chs]->Volume * DacGetGloalVolume()  / 10;

			if( dac[chs]->fThreadStart )
				play_flag = 1;
			if(++chs == 4)
				break;		// 最多合成4通道
		}

		// 检查是否存在有效数据
		for(i=0; i<chs; i++)
		{
			if(src[i])
				break;
		}

		if( play_flag == 0 )
		{
			kMutexRelease(hDacMutex);
			sTimerSleep(10, NULL);
			continue;
		}

		if(i == chs )
		{
			kMutexRelease(hDacMutex);
			sTimerSleep(10, NULL);
			continue;
		}

		if(chs > 1)
		{
			// 强制同步合成声音. 注意:
			// 1. 两路声音, 单独播放时不会卡, 但是合成播放卡, 可能是因为这两路声音s
			// 产生数据的 速率 不同造成的. 当其中一路很快, 另外一路很慢,
			// 就会以 速率 快的一路来合成声音, 导致 速率 慢的一路声音卡.
			// 2. 解决方法是强制快的一路等待慢的一路.
			// 3. 但是声音暂停和声音在停止过程中这两种情况, 不需要同步.
			for(i = 0; i < chs; i++)
			{
				//kprintf("src[%d]:0x%08x, Pause:%d, fThreadStart:%d, vol[%d]:%d\n", i, src[i], dac[i]->Pause, dac[i]->fThreadStart, i, vol[i]);
				// 无数据, 非暂停, 已经开始合成, 声音不是在停止的过程中
				if( !src[i] && !dac[i]->Pause && dac[i]->fThreadStart == 1 )
				{
					break;
				}
			}

			// 表示有某路声音没有数据, 但是不表示这路声音会卡.
			if(i != chs)
			{
				int buf_cnt = 0;
				PRESAMPLE presample;

				// 求DAC输出缓冲中还有多少个 有数据 的缓冲.
				presample = &DacDevice;
				for( j = 0 ; j < MAX_PCMBUFS ; j++ )
				{
					if( presample->BufFlag[j] == DAC_BUF_READ )
						buf_cnt++;
				}

				// 如果DAC缓冲少, 认为 有可能 会造成所有声音都卡, 所以合成有
				// 数据的声音. 其结果是没有数据的那路声音一定会卡,
				// 即使这路声音本身 已经存有(缓冲中) 的数据播放是不会卡的.
				// DAC缓冲多, 那么睡眠, 等待没有数据的那路声音.
				if(buf_cnt <= 11)
				{
					//kprintf("bufcount:%d\n", buf_cnt);
				}
				else
				{
					//kprintf("bufcount:%d\n", buf_cnt);
					kMutexRelease(hDacMutex);
					sTimerSleep(10, NULL);
					continue;
				}
			}
		}

		// 合成多通道音频数据
		if(chs > 1)
		{
			for(i=0; i<DAC_PCMBUF_SIZE/sizeof(short); i++)
			{
				tmp = 0;
				for(j=0; j<chs; j++)
				{
					if(src[j] && vol[j])
						tmp += src[j][i] * vol[j];
				}
				tmp /= 1024;
				if(tmp >= 32767)
				{
					pcm[i] = 32767;
					nErrorData++;
				}
				else if(tmp < -32767)
				{
					pcm[i] = -32767;
					nErrorData++;
				}
				else
					pcm[i] = (short)tmp;
			}
		}
		else	// 处理单通道音频数据
		{
			short volume;

			volume = vol[0];
			for(i=0; i<DAC_PCMBUF_SIZE/sizeof(short); i++)
				pcm[i] = (short)((src[0][i] * volume) / 1024);
		}

		DacOutDeviceSet();

		// 写入音频数据到DMA处理缓冲
		if(SavePcmData(pcm))
		{
			// 设置缓冲区读取完毕
			for(i=0; i<chs; i++)
			{
				if(src[i] != NULL)
					DacGetPcmOk(dac[i]);
			}

			if( fBeginDma == INIT_DMA_TRANS )
			{
				fBeginDma = RUNING_DMA_TRANS;
			}
			kMutexRelease(hDacMutex);
		}
		else
		{
			kMutexRelease(hDacMutex);
			sTimerSleep(10, NULL);
		}
	}
}
Exemple #15
0
//Timer interrupt
static void TimerInterrupt(IntrContext * iContext)
{
	IGNORE_PARAM iContext;

	//Update system time
	currentTime += PIT_TICKS_PER_INTERRUPT;

	//Decrement quantum
	if(TimerQuantum > 0)
	{
		--TimerQuantum;
	}

	//Stop beep if run out of time
	if(beepEndTime != 0 && currentTime >= beepEndTime)
	{
		TimerBeepStop();
	}

	//Process sleep queue
	if(!ListEmpty(&sleepQueueHead))
	{
		TimerQueue * head = ListEntry(sleepQueueHead.next, TimerQueue, list);
		TimerQueue * newHead;

		while(currentTime >= head->endTime)
		{
			//Wake up head
			ProcWakeUp(head->thread);

			//Get next head
			newHead = ListEntry(head->list.next, TimerQueue, list);

			//Remove current from queue
			ListDelete(&head->list);
			MemKFree(head);

			//Next head
			head = newHead;

			//Check wrapped
			if(ListEmpty(&sleepQueueHead))
			{
				break;
			}
		}
	}

	//Process alarm queue
	if(!ListEmpty(&alarmQueueHead))
	{
		TimerQueue * head = ListEntry(alarmQueueHead.next, TimerQueue, list);
		TimerQueue * newHead;

		while(currentTime >= head->endTime)
		{
			//Send signal and remove process pointer
			ProcSignalSendProcess(head->process, SIGALRM);
			head->process->alarmPtr = NULL;

			//Get next head
			newHead = ListEntry(head->list.next, TimerQueue, list);

			//Remove current from queue
			ListDelete(&head->list);
			MemKFree(head);

			//Next head
			head = newHead;

			//Check wrapped
			if(ListEmpty(&alarmQueueHead))
			{
				break;
			}
		}
	}
}
Exemple #16
0
HANDLE MediaSrvCreate(void *media, char *name, int type, int preempt)
#endif
{
	PLIST head;
	PLIST n;
	PMEDIA_OBJECT obj;

	// 参数检查
	if(media == NULL)
		return NULL;

	// 检查当前是否存在录放任务
	kMutexWait(hMediaMutex);
	head = &MediaObjList;
	if(!ListEmpty(head) && (preempt != MEDIA_MODE_NORMAL))
	{
		// 检查是否强行结束正在录放的音频
		if(preempt == MEDIA_MODE_PREEMPTIVE)
		{
			// 获取正在音频任务节点
			n = ListFirst(head);
			obj = ListEntry(n, MEDIA_OBJECT, Link);

			// 结束当前正在录放的音频任务
			obj->Cb.MediaClose(obj->Media, 1);
			obj->Cb.MediaDestroy(obj->Media);

			// 释放当前节点
			ListRemove(&obj->Link);
			HandleDestroy(obj->Header.Handle, MEDIA_MAGIC);
			if(obj->MediaInfo)
				kfree(obj->MediaInfo);
			kfree(obj);

			// 申请并初始化节点
			obj = MediaSrvObjCreate(media, name, type);
			if(obj == NULL)
			{
				kMutexRelease(hMediaMutex);
				return NULL;
			}

			// 启动新的播放任务
			if(obj->Cb.MediaOpen(obj->Media) < 0)
			{
				if(obj->MediaInfo)
					kfree(obj->MediaInfo);
				kfree(obj);
				kMutexRelease(hMediaMutex);
				return NULL;
			}

			// 把节点插入任务队列
			ListInsert(head, &obj->Link);
		}
		else
		{
			// 申请并初始化节点
			obj = MediaSrvObjCreate(media, name, type);
			if(obj == NULL)
			{
				kMutexRelease(hMediaMutex);
				return NULL;
			}

			// 把当前音频插入等待队列尾部
			ListInsert(ListPrev(head), &obj->Link);
		}
	}
	else
	{
		// 申请并初始化节点
		obj = MediaSrvObjCreate(media, name, type);
		if(obj == NULL)
		{
			kMutexRelease(hMediaMutex);
			return NULL;
		}

		// 启动新的录放任务
		if(obj->Cb.MediaOpen(obj->Media) < 0)
		{
			if(obj->MediaInfo)
				kfree(obj->MediaInfo);
			kfree(obj);
			kMutexRelease(hMediaMutex);
			return NULL;
		}
		
		// 把当前音频插入等待队列尾部
		ListInsert(head, &obj->Link);
	}
	
	kMutexRelease(hMediaMutex);
	{
		HANDLE hret = HandleSet(obj, MEDIA_MAGIC, sMediaSrvDestroy);
		kdebug(mod_media, PRINT_INFO, "OPEN: 0x%x\n", hret);
		return hret;
	}
}
Exemple #17
0
int MediaSrvMaster(char *process, int max, int type)
#endif
{
	PMEDIA_OBJECT obj;
	PLIST head;
	PLIST n;
	int tasks;
	int owners;
	int len;

	// 获取媒体使用的设备
	kMutexWait(hMediaMutex);
//	if(ListEmpty(&MediaObjList))
//	{
//		kMutexRelease(hMediaMutex);
//		return 0;
//	}
	
	// 循环获取所有正在播放的音频任务名称,并用分隔符返回
	if(process)
		kstrcpy(process, "");
	tasks = 0;
	len = 0;
	head = &MediaObjList;
	for(n=ListFirst(head); n!=head; n=ListNext(n))
	{
		// 获取打开设备对象
		obj = ListEntry(n, MEDIA_OBJECT, Link);
		if(process)
		{
			if(tasks)
			{
				len++;
				if(len < max)
					kstrcat(process, ";");
			}
			if(obj->MediaInfo)
			{
				len += kstrlen(obj->MediaInfo);
				if(len < max)
					kstrcat(process, obj->MediaInfo);
			}
			else
			{
				len += 6;
				if(len < max)
					kstrcat(process, "<NULL>");
			}
		}
		tasks++;
	}
	
	// 获取打开DAC设备情况
	owners = DacGetOwners();
	if(owners > tasks)
	{
		if(process)
		{
			if(tasks)
			{
				len++;
				if(len < max)
					kstrcat(process, ";");
			}
			len += 8;
			if(len < max)
				kstrcat(process, "<DIRECT>");
		}
		tasks = owners;	
	}
	kMutexRelease(hMediaMutex);
	return tasks;
}