1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* ---- includes ----------------------------------------------------------- */
18
19#include "SDK_Internal.h"
20#include "b_BasicEm/Functions.h"
21
22/* ------------------------------------------------------------------------- */
23
24/* ========================================================================= */
25/*                                                                           */
26/* ---- functions ---------------------------------------------------------- */
27/*                                                                           */
28/* ========================================================================= */
29
30/* ------------------------------------------------------------------------- */
31
32void btk_SDK_init( struct btk_SDK* ptrA )
33{
34	bbs_Context_init( &ptrA->contextE );
35	ptrA->hidE = btk_HID_SDK;
36	ptrA->refCtrE = 0;
37	ptrA->mallocFPtrE = NULL;
38	ptrA->freeFPtrE = NULL;
39	ptrA->errorFPtrE = NULL;
40	ptrA->maxImageWidthE = 0;
41	ptrA->maxImageHeightE = 0;
42}
43
44/* ------------------------------------------------------------------------- */
45
46void btk_SDK_exit( struct btk_SDK* ptrA )
47{
48	bbs_Context_exit( &ptrA->contextE );
49	ptrA->hidE = btk_HID_SDK;
50	ptrA->refCtrE = 0;
51	ptrA->mallocFPtrE = NULL;
52	ptrA->freeFPtrE = NULL;
53	ptrA->errorFPtrE = NULL;
54	ptrA->maxImageWidthE = 0;
55	ptrA->maxImageHeightE = 0;
56}
57
58/* ------------------------------------------------------------------------- */
59
60/* malloc wrapper */
61void* btk_malloc( struct bbs_Context* cpA,
62				  const struct bbs_MemSeg* memSegPtrA,
63				  uint32 sizeA )
64{
65	btk_HSDK hsdkL = ( btk_HSDK )cpA;
66	if( hsdkL->mallocFPtrE != NULL )
67	{
68		return hsdkL->mallocFPtrE( sizeA );
69	}
70	else
71	{
72		return NULL;
73	}
74}
75
76/* ------------------------------------------------------------------------- */
77
78/** error handler wrapper */
79void btk_error( struct bbs_Context* cpA )
80{
81	btk_HSDK hsdkL = ( btk_HSDK )cpA;
82	if( hsdkL->errorFPtrE != NULL )
83	{
84		hsdkL->errorFPtrE( hsdkL );
85	}
86}
87
88/* ------------------------------------------------------------------------- */
89
90btk_SDKCreateParam btk_SDK_defaultParam()
91{
92	btk_SDKCreateParam paramL;
93	paramL.fpError = NULL;
94	paramL.fpMalloc = NULL;
95	paramL.fpFree = NULL;
96	paramL.pExMem = NULL;
97	paramL.sizeExMem = 0;
98	paramL.pShMem = NULL;
99	paramL.sizeShMem = 0;
100	paramL.licenseKey = NULL;
101	paramL.maxImageWidth = 0;
102	paramL.maxImageHeight = 0;
103	return paramL;
104}
105
106/* ------------------------------------------------------------------------- */
107
108btk_Status btk_SDK_create( const btk_SDKCreateParam* pCreateParamA,
109						   btk_HSDK* hpsdkA )
110{
111	btk_HSDK hsdkL = NULL;
112	if( hpsdkA == NULL )	return btk_STATUS_INVALID_HANDLE;
113	if( *hpsdkA != NULL )	return btk_STATUS_INVALID_HANDLE;
114
115	if( pCreateParamA->fpMalloc != NULL )
116	{
117		if( pCreateParamA->fpFree == NULL ) return btk_STATUS_INVALID_HANDLE;
118
119		/* allocate context */
120		hsdkL = ( btk_HSDK )pCreateParamA->fpMalloc( bbs_SIZEOF8( struct btk_SDK ) );
121		if( hsdkL == NULL ) return btk_STATUS_INVALID_HANDLE;
122
123		btk_SDK_init( hsdkL );
124
125		/* initialize SDK context */
126		hsdkL->mallocFPtrE	= pCreateParamA->fpMalloc;
127		hsdkL->freeFPtrE	= pCreateParamA->fpFree;
128		hsdkL->errorFPtrE	= pCreateParamA->fpError;
129
130		/* initialize core context */
131		bbs_Context_quickInit( &hsdkL->contextE, btk_malloc, pCreateParamA->fpFree, btk_error );
132		if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR;
133	}
134	else
135	{
136		uint16* exMemPtrL = ( uint16* )pCreateParamA->pExMem;
137		uint32 exMemSizeL = pCreateParamA->sizeExMem >> 1;
138
139		if( pCreateParamA->pExMem == NULL )					 return btk_STATUS_INVALID_HANDLE;
140		if( pCreateParamA->pShMem == NULL )					 return btk_STATUS_INVALID_HANDLE;
141		if( pCreateParamA->pExMem == pCreateParamA->pShMem ) return btk_STATUS_INVALID_HANDLE;
142
143		if( pCreateParamA->sizeExMem < bbs_SIZEOF16( struct btk_SDK ) ) return btk_STATUS_INVALID_HANDLE;
144
145		/* allocate context */
146		hsdkL = ( btk_HSDK )exMemPtrL;
147		exMemPtrL  += bbs_SIZEOF16( struct btk_SDK );
148		exMemSizeL -= bbs_SIZEOF16( struct btk_SDK );
149
150		btk_SDK_init( hsdkL );
151
152		hsdkL->errorFPtrE	= pCreateParamA->fpError;
153		hsdkL->contextE.errorHandlerE = btk_error;
154
155		/* initialize core context */
156		bbs_Context_addStaticSeg( &hsdkL->contextE, exMemPtrL, exMemSizeL, FALSE, 0 );
157		bbs_Context_addStaticSeg( &hsdkL->contextE, pCreateParamA->pShMem, pCreateParamA->sizeShMem >> 1, TRUE, 0 );
158	}
159
160	hsdkL->maxImageWidthE = pCreateParamA->maxImageWidth;
161	hsdkL->maxImageHeightE = pCreateParamA->maxImageHeight;
162
163	*hpsdkA = hsdkL;
164	return btk_STATUS_OK;
165}
166
167/* ------------------------------------------------------------------------- */
168
169btk_Status btk_SDK_close( btk_HSDK hsdkA )
170{
171	const char* fNameL = "btk_SDK_close";
172
173	if( hsdkA == NULL )							return btk_STATUS_INVALID_HANDLE;
174	if( hsdkA->hidE != btk_HID_SDK )			return btk_STATUS_INVALID_HANDLE;
175	if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_PREEXISTING_ERROR;
176
177	if( hsdkA->refCtrE > 0 )
178	{
179		bbs_Context_pushError( &hsdkA->contextE,
180			                   bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nThis SDK context is still in use by %i objects!\n"
181							                                             "Close all instances of the context scope first.\n",
182																		  fNameL,
183																		  hsdkA->refCtrE ) );
184
185		return btk_STATUS_ERROR;
186	}
187
188	if( hsdkA->freeFPtrE )
189	{
190		btk_fpFree freeFPtrL = hsdkA->freeFPtrE;
191		btk_SDK_exit( hsdkA );
192		freeFPtrL( hsdkA );
193	}
194	else
195	{
196		btk_SDK_exit( hsdkA );
197	}
198
199	/* btk_SDK_exit clears error stack and does not produce an error condition */
200
201	return btk_STATUS_OK;
202}
203
204/* ------------------------------------------------------------------------- */
205
206btk_Error btk_SDK_getError( btk_HSDK hsdkA, char* msgBufA, u32 msgBufSizeA )
207{
208	if( hsdkA == NULL )					return btk_ERR_CORRUPT_DATA;
209	if( hsdkA->hidE != btk_HID_SDK )	return btk_STATUS_INVALID_HANDLE;
210
211	if( bbs_Context_error( &hsdkA->contextE ) )
212	{
213		struct bbs_Error errL = bbs_Context_popError( &hsdkA->contextE );
214		if( msgBufA != NULL ) bbs_strncpy( msgBufA, errL.textE, msgBufSizeA );
215		switch( errL.errorE )
216		{
217			case bbs_ERR_OUT_OF_MEMORY:		return btk_ERR_MEMORY;
218			case bbs_ERR_MEMORY_OVERFLOW:	return btk_ERR_MEMORY;
219			case bbs_ERR_WRONG_VERSION:		return btk_ERR_VERSION;
220			case bbs_ERR_CORRUPT_DATA:		return btk_ERR_CORRUPT_DATA;
221			default:						return btk_ERR_INTERNAL;
222		}
223	}
224
225	return btk_ERR_NO_ERROR;
226}
227
228/* ------------------------------------------------------------------------- */
229
230u32 btk_SDK_exAllocSize( btk_HSDK hsdkA )
231{
232	if( hsdkA == NULL )					return 0;
233	if( hsdkA->hidE != btk_HID_SDK )	return 0;
234	return ( bbs_Context_exclAllocSize( &hsdkA->contextE, 0 ) * 2 ) + bbs_SIZEOF8( struct btk_SDK );
235}
236
237/* ------------------------------------------------------------------------- */
238
239u32 btk_SDK_shAllocSize( btk_HSDK hsdkA )
240{
241	if( hsdkA == NULL )					return 0;
242	if( hsdkA->hidE != btk_HID_SDK )	return 0;
243	return bbs_Context_shrdAllocSize( &hsdkA->contextE, 0 ) * 2;
244}
245
246/* ------------------------------------------------------------------------- */
247
248u32 btk_SDK_allocSize( btk_HSDK hsdkA )
249{
250	return  btk_SDK_exAllocSize( hsdkA ) + btk_SDK_shAllocSize( hsdkA );
251}
252
253/* ------------------------------------------------------------------------- */
254
255btk_Status btk_SDK_paramConsistencyTest( struct btk_SDK* hsdkA,
256										 const void* memPtrA,
257										 u32 memSizeA,
258										 const char* fNameA )
259{
260	const uint16* memPtrL = ( uint16* )memPtrA;
261	uint32 memSizeL;
262	uint32 iL;
263	uint16 sumL = 0;
264
265	if( memSizeA < sizeof( memSizeL ) )
266	{
267		bbs_Context_pushError( &hsdkA->contextE,
268							   bbs_Error_create( bbs_ERR_ERROR, 0, NULL,
269					               "%s:\nCorrupt parameter data.", fNameA ) );
270		return btk_STATUS_ERROR;
271	}
272
273	memPtrL += bbs_memRead32( &memSizeL, memPtrL );
274
275	if( memSizeA < ( memSizeL << 1 ) )
276	{
277		bbs_Context_pushError( &hsdkA->contextE,
278							   bbs_Error_create( bbs_ERR_ERROR, 0, NULL,
279					               "%s:\nCorrupt parameter data.", fNameA ) );
280		return btk_STATUS_ERROR;
281	}
282
283	memPtrL = ( uint16* )memPtrA;
284
285	for( iL = 0; iL < memSizeL; iL++ )
286	{
287		uint16 valL = 0;
288		memPtrL += bbs_memRead16( &valL, memPtrL );
289		sumL += valL;
290	}
291
292    if( sumL != 0xFFFF )
293	{
294		bbs_Context_pushError( &hsdkA->contextE,
295							   bbs_Error_create( bbs_ERR_ERROR, 0, NULL,
296					               "%s:\nChecksum error; corrupt parameter data.", fNameA ) );
297		return btk_STATUS_ERROR;
298	}
299
300	return btk_STATUS_OK;
301}
302
303/* ------------------------------------------------------------------------- */
304
305/* ========================================================================= */
306