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

📄 folder.c

📁 藍芽電話簿範本
💻 C
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Limited 2006-2009
Part of BlueLab 4.1-Release

DESCRIPTION
	Implementation for for handling folder based functionality
	
FILE
	folder.c
	
*/

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

#include <print.h>
#include <pbap_common.h>
#include <panic.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "main.h"
#include "folder.h"
#include "pb_access.h"
#include "buffer.h"

/* Listing Format constants */

static const uint8 gVCardListHeader[] = {'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"','?','>','\n',
										'<','!','D','O','C','T','Y','P','E',' ','v','c','a','r','d','-','l','i','s','t','i','n','g',' ','S','Y','S','T','E','M',' ','"','v','c','a','r','d','-','l','i','s','t','i','n','g','.','d','t','d','"','>','\n',
										'<','v','C','a','r','d','-','l','i','s','t','i','n','g',' ','v','e','r','s','i','o','n',' ','"','1','.','0','"','>','\n'};
static const uint8 gVCardListFooter[] = {'<','/','v','C','a','r','d','-','l','i','s','t','i','n','g','>','\n'};
static const uint8 gVCardListEntryStart[] = {'<','c','a','r','d',' ','h','a','n','d','l','e',' ','=',' ','"'};
static const uint8 gVCardListEntryMiddle[] = {'.','v','c','f','"',' ','n','a','m','e',' ','=',' ','"'};
static const uint8 gVCardListEntryEnd[] = {'"','/','>','\n'};

/* Local Functions Definitions */

static bool folderFillBuffer(applicationTaskData *pTask);
static bool folderAddToBuffer(applicationTaskData *pTask, uint16 pIndex, const uint8 *pNamePtr, uint16 pSize);

/* Interface Functions */

/*
	Initialise the folder sub-system
*/
void folderInit(applicationTaskData *pTask)
{
	pbap_phone_book lBook;
	
	PRINT(("folderInit\n"));
	
	/* Indicate root as current folder */
	pTask->folderData.current = pbap_b_unknown;
	
	/* Find Supported Phonebooks */
	for (lBook = pbap_pb; lBook < pbap_b_unknown; lBook++)
	{
		PRINT(("    Checking folder %d : ", lBook));
		
		if (pbaPhoneBookSupported(lBook))
		{ /* Phonebook supported */
			PRINT(("Supported\n"));
			pTask->folderData.supBooks |= (1<<lBook);
		}
		else
		{ /* Phonebook unsupported */
			PRINT(("Unsupported\n"));
		}
	}
}

/*
	Set current folder to a child folder
*/
pbaps_set_phonebook_result folderSetChild(applicationTaskData *pTask, pbap_phone_book pBook)
{
	pbaps_set_phonebook_result lRes = pbaps_spb_ok;
	
	switch (pTask->folderData.current)
	{
		case pbap_b_unknown: /* Root Folder */
			if (pBook != pbap_telecom)
			{
				PRINT(("   Change to telecom when not at root, rejecting\n"));
				lRes = pbaps_spb_no_phonebook;
			}
			break; 
		case pbap_telecom:
			if ((pBook >= pbap_pb) && (pBook <= pbap_cch))
			{ /* Check to ensure required phonebook is supported */
				if (!(pTask->folderData.supBooks | (1<<pBook)))
				{
					PRINT(("   Requested phonebook not supported, rejecting\n"));
					lRes = pbaps_spb_no_phonebook;
				}
			}
			else
			{
				PRINT(("    Change to a phonebook when not in telecom, rejecting\n"));
				lRes = pbaps_spb_no_phonebook;
			}
			break;
		case pbap_pb:
		case pbap_ich: 
		case pbap_och: 
		case pbap_mch: 
		case pbap_cch:
		default:
			PRINT(("    Already in a phonebook, no child folders. Rejecting\n"));
			lRes = pbaps_spb_no_phonebook;
			break;
	
	}
	if (lRes == pbaps_spb_ok)
	{
		pTask->folderData.current = pBook;
	}
	
	return lRes;
}

/*
	Set current folder to parent folder
*/
pbaps_set_phonebook_result folderSetParent(applicationTaskData *pTask)
{
	pbaps_set_phonebook_result lRes = pbaps_spb_ok;
	
	switch (pTask->folderData.current)
	{
		case pbap_telecom:
			PRINT(("    Changing to root folder\n"));
			pTask->folderData.current = pbap_b_unknown; /* Root Folder */
			break;
		case pbap_pb:
		case pbap_ich: 
		case pbap_och: 
		case pbap_mch: 
		case pbap_cch:
			PRINT(("    Changing to telecom folder\n"));
			pTask->folderData.current = pbap_telecom;
			break;
		case pbap_b_unknown: /* Root Folder */
		default:
			PRINT(("    Already root, no parent folder. Rejecting\n"));
			lRes = pbaps_spb_no_phonebook;
			break;
	
	}
	
	return lRes;
}

/*
	Set current folder to root folder
*/
pbaps_set_phonebook_result folderSetRoot(applicationTaskData *pTask)
{
	pTask->folderData.current = pbap_b_unknown; /* Root Folder */
	return pbaps_spb_ok;
}

/*
	Return the current folder
*/
pbap_phone_book folderCurrentFolder(applicationTaskData *pTask)
{
	return pTask->folderData.current;
}

/*
	Get first vCard list buffer
*/
bool folderGetFirstListBuffer(applicationTaskData *pTask, uint16 pStartPos)
{
	bool lFinished = FALSE;
	uint16 lToCopy;
	
	PRINT(("folderGetFirstListBuffer\n"));
	/* Setup buffer */
	if (!allocBuffer(pTask, PBAPS_MIN_BUFFER_SIZE))
	{
		PRINT(("    Cannot Allocate Buffer\n"));
		Panic();
	}
	/* Open phonebook */
	if (!pbaOpenPhonebook(pTask, pTask->folderData.current))
	{
		PRINT(("    Cannot open phonebook\n"));
		Panic();
	}
	
	/* Copy preamble to buffer */
	lToCopy = (pTask->buffer.sizeBuffer <= sizeof(gVCardListHeader)) ? pTask->buffer.sizeBuffer : sizeof(gVCardListHeader);
	memcpy(pTask->buffer.buffer, gVCardListHeader, lToCopy);
	pTask->buffer.freeSpace -= lToCopy;
	pTask->buffer.nextPos += lToCopy;
	pTask->buffer.used += lToCopy;
	pTask->folderData.listLeft = sizeof(gVCardListHeader) - lToCopy;
	
	/* Ensure we start with a search */
	pTask->folderData.sentCurrent = TRUE;
	
	if (pStartPos>0)
	{
		pbaGotoEntry(pTask, pStartPos);
	}
	
	if (pTask->buffer.freeSpace >= 0)
	{
		lFinished = folderFillBuffer(pTask);
	}
	
	return lFinished;
}

/*
	Get next vCard list buffer
*/
bool folderGetNextListBuffer(applicationTaskData *pTask)
{
	bool lFinished = TRUE;

	resetBuffer(pTask);
	
	if (pTask->folderData.listLeft > 0)
	{
		uint16 lToCopy;
		uint16 lStart = sizeof(gVCardListHeader) - pTask->folderData.listLeft;
		lToCopy = (pTask->buffer.sizeBuffer <= pTask->folderData.listLeft) ? pTask->buffer.sizeBuffer : pTask->folderData.listLeft;
		
		memcpy(pTask->buffer.buffer, &gVCardListHeader[lStart], lToCopy);
		pTask->buffer.freeSpace -= lToCopy;
		pTask->buffer.nextPos += lToCopy;
		pTask->buffer.used += lToCopy;
		pTask->folderData.listLeft = pTask->folderData.listLeft - lToCopy;
	}
	
	if (pTask->buffer.freeSpace >= 0)
	{
		lFinished = folderFillBuffer(pTask);
	}
	
	return lFinished;
}

/*
	Clean up from downloading the vCard list
*/
void folderCleanupListBuffer(applicationTaskData *pTask)
{
	freeBuffer(pTask);
	pbaClosePhonebook(pTask);
}

/* Local Function Implementation */

static bool folderFillBuffer(applicationTaskData *pTask)
{
	bool lComplete = FALSE, lSent = TRUE, lEntry = TRUE;
	pbaSearchResult *lSrchRes;
	
	
	PRINT(("folderFillBuffer\n"));
	
	lSrchRes = PanicUnlessMalloc(sizeof(pbaSearchResult));
	
	if (!pTask->folderData.sentCurrent)
	{
		PRINT(("    Sending Current\n"));
		/* Get current entry */
		pbaGetCurrentEntry(pTask, lSrchRes);
		/* Add to buffer */
		lSent = folderAddToBuffer(pTask, lSrchRes->index,  lSrchRes->namePtr, lSrchRes->nameSize);
		if (!lSent)
		{
			PRINT(("    Unable to add single entry\n"));
			Panic();
		}
		else
		{
			pTask->srchData.maxList--;
			if (pTask->srchData.maxList == 0)
			{
				lEntry = FALSE;
			}
		}
	}
	
	if (pTask->folderData.sendFooter)
	{
		PRINT(("    SENDING FOOTER\n"));
		memcpy(pTask->buffer.buffer, gVCardListFooter, sizeof(gVCardListFooter));
		pTask->buffer.freeSpace -= sizeof(gVCardListFooter);
		pTask->buffer.nextPos += sizeof(gVCardListFooter);
		pTask->buffer.used += sizeof(gVCardListFooter);
		lComplete = TRUE;
		pTask->folderData.sendFooter = FALSE;
	}
	else
	{	
		lSent = TRUE;
		/* Get next entry */
		if (lEntry)
		{
			lEntry = pbaFindNextEntry(pTask, lSrchRes);
		}
		while (lEntry && lSent)
		{
			lSent = folderAddToBuffer(pTask, lSrchRes->index,  lSrchRes->namePtr, lSrchRes->nameSize);
			if (lSent)
			{
				pTask->srchData.maxList--;
				if (pTask->srchData.maxList == 0)
				{
					lEntry = FALSE;
				}
				else
				{
					/* Get next Entry */
					lEntry = pbaFindNextEntry(pTask, lSrchRes);
				}
			}
		}
		if (!lEntry)
		{ /* No more entries to read */
			PRINT(("    Closing phonebook\n"));
			/* Close phonebook */
			pbaClosePhonebook(pTask);
			
			if (sizeof(gVCardListFooter) <= pTask->buffer.freeSpace)
			{ /* Add footer to buffer */
				memcpy(&pTask->buffer.buffer[pTask->buffer.nextPos], gVCardListFooter, sizeof(gVCardListFooter));
				pTask->buffer.freeSpace -= sizeof(gVCardListFooter);
				pTask->buffer.nextPos += sizeof(gVCardListFooter);
				pTask->buffer.used += sizeof(gVCardListFooter);
				lComplete = TRUE;
				pTask->folderData.sendFooter = FALSE;
			}
			else
			{ /* remember finished and not sent footer */
				pTask->folderData.sendFooter = TRUE;
			}
		}
	}
	
	free(lSrchRes);
	
	return lComplete;
}

static bool folderAddToBuffer(applicationTaskData *pTask, uint16 pIndex,  const uint8 *pNamePtr, uint16 pSize)
{
	bool lFit = TRUE;
	uint16 lSpaceNeeded = sizeof(gVCardListEntryStart) + sizeof(gVCardListEntryMiddle) + sizeof(gVCardListEntryEnd) + pSize;
	char lIndex[10];
	uint16 lSizeIndex;
	
	/* Calculate the size */
	sprintf(lIndex, "%X", pIndex);
	lSizeIndex = strlen(lIndex);
	lSpaceNeeded += lSizeIndex;
	
	if (lSpaceNeeded <= pTask->buffer.freeSpace)
	{
		/* Copy Header */
		memcpy(&pTask->buffer.buffer[pTask->buffer.nextPos], gVCardListEntryStart, sizeof(gVCardListEntryStart));
		pTask->buffer.nextPos += sizeof(gVCardListEntryStart);
		/* Create Index */
		memcpy(&pTask->buffer.buffer[pTask->buffer.nextPos], lIndex, lSizeIndex);
		pTask->buffer.nextPos += lSizeIndex;
		/* Copy Middle */
		memcpy(&pTask->buffer.buffer[pTask->buffer.nextPos], gVCardListEntryMiddle, sizeof(gVCardListEntryMiddle));
		pTask->buffer.nextPos += sizeof(gVCardListEntryMiddle);
		/* Copy Name */
		if (pSize > 0)
		{
			memcpy(&pTask->buffer.buffer[pTask->buffer.nextPos], pNamePtr, pSize);
			pTask->buffer.nextPos += pSize;
		}
		/* Copy End */
		memcpy(&pTask->buffer.buffer[pTask->buffer.nextPos], gVCardListEntryEnd, sizeof(gVCardListEntryEnd));
		pTask->buffer.nextPos += sizeof(gVCardListEntryEnd);

		/* Update counters */
		pTask->buffer.freeSpace -= lSpaceNeeded;
		pTask->buffer.used += lSpaceNeeded;
		
		pTask->folderData.sentCurrent = TRUE;
	}
	else
	{
		lFit = FALSE;
		pTask->folderData.sentCurrent = FALSE;
	}
		
	
	return lFit;
}

⌨️ 快捷键说明

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