📄 folder.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 + -