⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pb_access.c

📁 pbap_server:bluetooth 可供带有PBAP功能bluetooth手机使用
💻 C
字号:
/****************************************************************************

DESCRIPTION
	Implementation for accessing phonebooks
	
FILE
	pb_access.c
	
*/

/****************************************************************************
    Header files
*/

#include <print.h>
#include <stdlib.h>
#include <panic.h>

#include "main.h"
#include "pb_access.h"

typedef struct
{
	const char *str;
	uint16 len;
} pbaPhonebookNames;

static const char  pbStr[] = "pb.dat";
static const char ichStr[] = "ich.dat";
static const char ochStr[] = "och.dat";
static const char mchStr[] = "mch.dat";
static const char cchStr[] = "cch.dat";

#define PBA_LIST_ENTRY(i) {(i), sizeof((i))-1}

static const pbaPhonebookNames gpbaPhonebookNamesList[] = 
							{ 
								PBA_LIST_ENTRY( pbStr),
								PBA_LIST_ENTRY(ichStr),
								PBA_LIST_ENTRY(ochStr),
								PBA_LIST_ENTRY(mchStr),
								PBA_LIST_ENTRY(cchStr)
							};

#define NAME_CHAR ('N')
#define PHONE_CHAR ('P')
#define MOBILE_CHAR ('M')
#define BUSINESS_CHAR ('B')
#define END_CHAR ('\n')
							
/* Local Function Definitions */

void zeroSearch(pbaSearchResult *pSearch);
uint16 findFields(const uint8 *pBuffer, pbaSearchResult *pSearch);
static bool pbaSearchEntry(applicationTaskData *pTask, pbaSearchResult *pResult);
static bool pbaSearchStr(const uint8 *str1, const uint8 *str2);

/* Interface Functions */

/*
	Check to see if a phonebook is supported
*/
bool pbaPhoneBookSupported(pbap_phone_book pBook)
{
	bool lRet = FALSE;

	if ((pBook >= pbap_pb) && (pBook < pbap_b_unknown))
	{
		FILE_INDEX idx;
		/* pbap_pb = 1, so need to knock 1 off to make list 0 indexed */
		idx = FileFind(FILE_ROOT, gpbaPhonebookNamesList[pBook-1].str, gpbaPhonebookNamesList[pBook-1].len);
		if (idx != FILE_NONE)
		{
			lRet = TRUE;
		}
	}
	else
	{
		PRINT(("    Not a valid phonebook\n"));
	}
	return lRet;
}

/*
	Open Phonebook
*/
bool pbaOpenPhonebook(applicationTaskData *pTask, pbap_phone_book pBook)
{
	bool lRet = FALSE;

	PRINT(("pbaOpenPhonebook\n"));
	if (pTask->phonebookData.open)
	{
		PRINT(("    Phonebook already open\n"));
	}
	else
	{
		if ((pBook >= pbap_pb) && (pBook < pbap_b_unknown))
		{
			FILE_INDEX idx;
			/* pbap_pb = 1, so need to knock 1 off to make list 0 indexed */
			idx = FileFind(FILE_ROOT, gpbaPhonebookNamesList[pBook-1].str, gpbaPhonebookNamesList[pBook-1].len);
			
			if (idx != FILE_NONE)
			{
				pTask->phonebookData.open = TRUE;
				pTask->phonebookData.bookSrc = StreamFileSource(idx);
				/* pbap_pb phone book as a 0 indexed entry, others do not */
				pTask->phonebookData.entry = (pBook == pbap_pb) ? 0 : 1;
				pTask->phonebookData.usedFirst = FALSE;
				lRet = TRUE;
			}
			else
			{
				PRINT(("    Unable to find phonebook\n"));
			}
		}
		else
		{
			PRINT(("    Not a valid phonebook\n"));
		}
	}
	
	return lRet;
}

/*
	Close Phonebook
*/
void pbaClosePhonebook(applicationTaskData *pTask)
{
	uint16 lSize;
	
	lSize = SourceSize(pTask->phonebookData.bookSrc);
	while (lSize>0)
	{
		SourceDrop(pTask->phonebookData.bookSrc, lSize);
		lSize = SourceSize(pTask->phonebookData.bookSrc);
	}
	
	pTask->phonebookData.open = FALSE;
	pTask->phonebookData.bookSrc = 0;
}

/* Get current entry */
void pbaGetCurrentEntry(applicationTaskData *pTask, pbaSearchResult *pResult)
{
	const uint8 *lSrc = SourceMap(pTask->phonebookData.bookSrc);
	
	PRINT(("pbaGetCurrentEntry\n"));
	
	if (!pTask->phonebookData.open)
	{
		PRINT(("    PHONEBOOK NOT OPEN\n"));
		return;
	}
	
	zeroSearch(pResult);
	pResult->index = pTask->phonebookData.entry;
	findFields(lSrc, pResult);
}

/* Find next entry (uses search data) */
bool pbaFindNextEntry(applicationTaskData *pTask, pbaSearchResult *pResult)
{
	bool lFound = FALSE;
	const uint8 *lSrc = SourceMap(pTask->phonebookData.bookSrc);
	uint16 lSize;
	
	PRINT(("pbaFindNextEntry\n"));
	
	if (!pTask->phonebookData.open)
	{
		PRINT(("    PHONEBOOK NOT OPEN\n"));
		return FALSE;
	}
	
	if (pTask->phonebookData.usedFirst)
	{
		/* Drop entry that has just been used */
		lSize = findFields(lSrc, pResult);
		SourceDrop(pTask->phonebookData.bookSrc, lSize);
		pTask->phonebookData.entry++;
	}
	else
	{ /* Indicate that the first entry has been processed */
		pTask->phonebookData.usedFirst = TRUE;
	}
	
	while ((SourceSize(pTask->phonebookData.bookSrc)>0) && (!lFound))
	{
		zeroSearch(pResult);
		pResult->index = pTask->phonebookData.entry;
		lSize = findFields(lSrc, pResult);
		
		/* Perform Search */
		lFound = pbaSearchEntry(pTask, pResult);
		
		if (!lFound)
		{
			SourceDrop(pTask->phonebookData.bookSrc, lSize);
			pTask->phonebookData.entry++;
		}
	}
	
	return lFound;
}

/*
	Goto entry
*/
bool pbaGotoEntry(applicationTaskData *pTask, uint16 pEntry)
{
	const uint8 *lSrc = SourceMap(pTask->phonebookData.bookSrc);
	pbaSearchResult lSearch;
	uint16 lSize;
	
	PRINT(("pbaGotoEntry\n"));
	
	while ((SourceSize(pTask->phonebookData.bookSrc)>0) && (pTask->phonebookData.entry < pEntry))
	{
		lSize = findFields(lSrc, &lSearch);
		
		if (pTask->phonebookData.entry < pEntry)
		{
			SourceDrop(pTask->phonebookData.bookSrc, lSize);
		}
		pTask->phonebookData.entry++;
	}
	/* Indicate the current entry should be examined during searching */
	pTask->phonebookData.usedFirst = FALSE;

	return (pTask->phonebookData.entry >= pEntry) ? TRUE : FALSE;
}

/* 
	Goto next entry
*/
bool pbaGotoNextEntry(applicationTaskData *pTask, pbaSearchResult *pResult)
{
	const uint8 *lSrc = SourceMap(pTask->phonebookData.bookSrc);
	uint16 lSize;
	bool lComplete = FALSE;
	
	PRINT(("pbaGotoNextEntry\n"));

	/* Remove Current entry */	
	lSize = findFields(lSrc, pResult);
	SourceDrop(pTask->phonebookData.bookSrc, lSize);
	pTask->phonebookData.entry++;
	
	/* Fill Out  Current entry */	
	if (SourceSize(pTask->phonebookData.bookSrc) > 0)
	{
		zeroSearch(pResult);
		lSize = findFields(lSrc, pResult);
		lComplete = TRUE;
	}

	return lComplete;
}

/*
	Get the number of elements in a phonebook
*/
uint16 pbaGetNumberElements(applicationTaskData *pTask, pbap_phone_book pBook)
{
	const uint8 *lSrc;
	uint16 lNumEntries = 0;
	uint16 lSize;
	pbaSearchResult lSearch;

	PRINT(("pbaGetNumberElements\n"));
	
	pbaOpenPhonebook(pTask, pBook);
	lSrc = SourceMap(pTask->phonebookData.bookSrc);
	
	while (SourceSize(pTask->phonebookData.bookSrc)>0)
	{
		lSize = findFields(lSrc, &lSearch);
		SourceDrop(pTask->phonebookData.bookSrc, lSize);
		lNumEntries++;
	}
	
	pbaClosePhonebook(pTask);
	PRINT(("    Num Entries %d\n",lNumEntries));
		
	return lNumEntries;
}

/* Local Function Implementations */

void zeroSearch(pbaSearchResult *pSearch)
{
	pSearch->namePtr = NULL;
	pSearch->phonePtr = NULL;
	pSearch->mobilePtr = NULL;
	pSearch->businessPtr = NULL;
	pSearch->nameSize = 0;
	pSearch->phoneSize = 0;
	pSearch->mobileSize = 0;
	pSearch->businessSize = 0;
	pSearch->index = 0;
}

uint16 findFields(const uint8 *pBuffer, pbaSearchResult *pSearch)
{
	const uint8 *lCurr = pBuffer, *lField = pBuffer;
	uint16 lLength = 0;
	
	PRINT(("findFields\n"));
	
	while (*lField != END_CHAR)
	{
		while (*lCurr != END_CHAR)
			lCurr++;
		lLength = lCurr - lField - 1;
		switch (*lField)
		{
			case NAME_CHAR:
				pSearch->namePtr = lField+1;
				pSearch->nameSize = lLength;
				break;
			case PHONE_CHAR:
				pSearch->phonePtr = lField+1;
				pSearch->phoneSize = lLength;
				break;
			case MOBILE_CHAR:
				pSearch->mobilePtr = lField+1;
				pSearch->mobileSize = lLength;
				break;
			case BUSINESS_CHAR:
				pSearch->businessPtr = lField+1;
				pSearch->businessSize = lLength;
				break;
			default:
				PRINT(("    UNKNOWN FIELD\n"));
				Panic();
				break;
		}
		lCurr ++;
		lField = lCurr;
	}
	
	return lCurr - pBuffer + 1;
}

static bool pbaSearchEntry(applicationTaskData *pTask, pbaSearchResult *pResult)
{
	bool lFound = FALSE;
	
	if (pTask->srchData.srchVal)
	{
		switch (pTask->srchData.srchAttr)
		{
			case pbap_search_name:
			case pbap_search_sound:  /* Deliberate Fallthrough */
				{
					if (pResult->namePtr)
					{
						lFound = pbaSearchStr(pResult->namePtr, pTask->srchData.srchVal);
					}
					break;
				}
			case pbap_search_number:
				{
					if (pResult->phonePtr)
					{
						lFound = pbaSearchStr(pResult->phonePtr, pTask->srchData.srchVal);
					}
					if ((pResult->mobilePtr) && !lFound)
					{
						lFound = pbaSearchStr(pResult->mobilePtr, pTask->srchData.srchVal);
					}
					if ((pResult->businessPtr) && !lFound)
					{
						lFound = pbaSearchStr(pResult->businessPtr, pTask->srchData.srchVal);
					}
					break;
				}
			default:
				PRINT(("    UNKNOWN SEARCH CATAGORY\n"));
				Panic();
				break;
		}
	}
	else
		lFound = TRUE;
	return lFound;
}

static bool pbaSearchStr(const uint8 *str1, /* '\n' terminated */
							const uint8 *str2) /* Null terminated */
{
        const uint8 *cp = str1;
        const uint8 *s1, *s2;
        bool lFound = FALSE;

        if ( *str2 )
        {
	        while (*cp != '\n' && !lFound)
	        {
	                s1 = cp;
	                s2 = str2;
	
	                while ( *s1 != '\n' && *s2 && !(*s1-*s2) )
	                        s1++, s2++;
	
	                if (!*s2)
	                        lFound = TRUE;
	
	                cp++;
	        }
        }

        return lFound;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -