1/******************************************************************************
2 *
3 *  Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18#include "OverrideLog.h"
19#include "NfcAdaptation.h"
20extern "C"
21{
22    #include "gki.h"
23    #include "nfa_api.h"
24    #include "nfc_int.h"
25}
26#include "config.h"
27
28#define LOG_TAG "NfcAdaptation"
29
30extern "C" void GKI_shutdown();
31extern void resetConfig();
32
33NfcAdaptation* NfcAdaptation::mpInstance = NULL;
34ThreadMutex NfcAdaptation::sLock;
35nfc_nci_device_t* NfcAdaptation::mHalDeviceContext = NULL;
36tHAL_NFC_CBACK* NfcAdaptation::mHalCallback = NULL;
37tHAL_NFC_DATA_CBACK* NfcAdaptation::mHalDataCallback = NULL;
38
39UINT32 ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL; //0x017F00;
40UINT8 appl_trace_level = 0xff;
41char bcm_nfc_location[120];
42
43/*******************************************************************************
44**
45** Function:    NfcAdaptation::NfcAdaptation()
46**
47** Description: class constructor
48**
49** Returns:     none
50**
51*******************************************************************************/
52NfcAdaptation::NfcAdaptation()
53{
54}
55
56/*******************************************************************************
57**
58** Function:    NfcAdaptation::~NfcAdaptation()
59**
60** Description: class destructor
61**
62** Returns:     none
63**
64*******************************************************************************/
65NfcAdaptation::~NfcAdaptation()
66{
67    mpInstance = NULL;
68}
69
70/*******************************************************************************
71**
72** Function:    NfcAdaptation::GetInstance()
73**
74** Description: access class singleton
75**
76** Returns:     pointer to the singleton object
77**
78*******************************************************************************/
79NfcAdaptation& NfcAdaptation::GetInstance()
80{
81    AutoThreadMutex  a(sLock);
82
83    if (!mpInstance)
84        mpInstance = new NfcAdaptation;
85    return *mpInstance;
86}
87
88/*******************************************************************************
89**
90** Function:    NfcAdaptation::Initialize()
91**
92** Description: class initializer
93**
94** Returns:     none
95**
96*******************************************************************************/
97void NfcAdaptation::Initialize ()
98{
99    const char* func = "NfcAdaptation::Initialize";
100    ALOGD("%s: enter\n", func);
101    unsigned long num;
102
103    if ( !GetStrValue ( NAME_NFA_STORAGE, bcm_nfc_location, sizeof ( bcm_nfc_location ) ) )
104        strcpy ( bcm_nfc_location, "/data/nfc" );
105    if ( GetNumValue ( NAME_PROTOCOL_TRACE_LEVEL, &num, sizeof ( num ) ) )
106        ScrProtocolTraceFlag = num;
107    initializeGlobalAppLogLevel ();
108
109    GKI_init ();
110    GKI_enable ();
111    GKI_create_task ((TASKPTR)NFCA_TASK, BTU_TASK, (INT8*)"NFCA_TASK", 0, 0, (pthread_cond_t*)NULL, NULL);
112    {
113        AutoThreadMutex guard(mCondVar);
114        GKI_create_task ((TASKPTR)Thread, MMI_TASK, (INT8*)"NFCA_THREAD", 0, 0, (pthread_cond_t*)NULL, NULL);
115        mCondVar.wait();
116    }
117
118    mHalDeviceContext = NULL;
119    mHalCallback =  NULL;
120    memset (&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
121    InitializeHalDeviceContext ();
122    ALOGD ("%s: exit", func);
123}
124
125/*******************************************************************************
126**
127** Function:    NfcAdaptation::Finalize()
128**
129** Description: class finalizer
130**
131** Returns:     none
132**
133*******************************************************************************/
134void NfcAdaptation::Finalize()
135{
136    const char* func = "NfcAdaptation::Finalize";
137    AutoThreadMutex  a(sLock);
138
139    ALOGD ("%s: enter", func);
140    GKI_shutdown ();
141
142    resetConfig();
143
144    nfc_nci_close(mHalDeviceContext); //close the HAL's device context
145    mHalDeviceContext = NULL;
146    mHalCallback = NULL;
147    memset (&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
148
149    ALOGD ("%s: exit", func);
150    delete this;
151}
152
153/*******************************************************************************
154**
155** Function:    NfcAdaptation::signal()
156**
157** Description: signal the CondVar to release the thread that is waiting
158**
159** Returns:     none
160**
161*******************************************************************************/
162void NfcAdaptation::signal ()
163{
164    mCondVar.signal();
165}
166
167/*******************************************************************************
168**
169** Function:    NfcAdaptation::NFCA_TASK()
170**
171** Description: NFCA_TASK runs the GKI main task
172**
173** Returns:     none
174**
175*******************************************************************************/
176UINT32 NfcAdaptation::NFCA_TASK (UINT32 arg)
177{
178    const char* func = "NfcAdaptation::NFCA_TASK";
179    ALOGD ("%s: enter", func);
180    GKI_run (0);
181    ALOGD ("%s: exit", func);
182    return NULL;
183}
184
185/*******************************************************************************
186**
187** Function:    NfcAdaptation::Thread()
188**
189** Description: Creates work threads
190**
191** Returns:     none
192**
193*******************************************************************************/
194UINT32 NfcAdaptation::Thread (UINT32 arg)
195{
196    const char* func = "NfcAdaptation::Thread";
197    unsigned long num;
198    char temp[120];
199    ALOGD ("%s: enter", func);
200
201    {
202        ThreadCondVar    CondVar;
203        AutoThreadMutex  guard(CondVar);
204        GKI_create_task ((TASKPTR)nfc_task, NFC_TASK, (INT8*)"NFC_TASK", 0, 0, (pthread_cond_t*)CondVar, (pthread_mutex_t*)CondVar);
205        CondVar.wait();
206    }
207
208    NfcAdaptation::GetInstance().signal();
209
210    GKI_exit_task (GKI_get_taskid ());
211    ALOGD ("%s: exit", func);
212    return NULL;
213}
214
215/*******************************************************************************
216**
217** Function:    NfcAdaptation::GetHalEntryFuncs()
218**
219** Description: Get the set of HAL entry points.
220**
221** Returns:     Functions pointers for HAL entry points.
222**
223*******************************************************************************/
224tHAL_NFC_ENTRY* NfcAdaptation::GetHalEntryFuncs ()
225{
226    return &mHalEntryFuncs;
227}
228
229/*******************************************************************************
230**
231** Function:    NfcAdaptation::InitializeHalDeviceContext
232**
233** Description: Ask the generic Android HAL to find the Broadcom-specific HAL.
234**
235** Returns:     None.
236**
237*******************************************************************************/
238void NfcAdaptation::InitializeHalDeviceContext ()
239{
240    const char* func = "NfcAdaptation::InitializeHalDeviceContext";
241    ALOGD ("%s: enter", func);
242    int ret = 0; //0 means success
243    const hw_module_t* hw_module = NULL;
244
245    mHalEntryFuncs.initialize = HalInitialize;
246    mHalEntryFuncs.terminate = HalTerminate;
247    mHalEntryFuncs.open = HalOpen;
248    mHalEntryFuncs.close = HalClose;
249    mHalEntryFuncs.core_initialized = HalCoreInitialized;
250    mHalEntryFuncs.write = HalWrite;
251    mHalEntryFuncs.prediscover = HalPrediscover;
252    mHalEntryFuncs.control_granted = HalControlGranted;
253    mHalEntryFuncs.power_cycle = HalPowerCycle;
254
255    ret = hw_get_module (NFC_NCI_HARDWARE_MODULE_ID, &hw_module);
256    if (ret == 0)
257    {
258        ret = nfc_nci_open (hw_module, &mHalDeviceContext);
259        if (ret != 0)
260            ALOGE ("%s: nfc_nci_open fail", func);
261    }
262    else
263        ALOGE ("%s: fail hw_get_module", func);
264    ALOGD ("%s: exit", func);
265}
266
267/*******************************************************************************
268**
269** Function:    NfcAdaptation::HalInitialize
270**
271** Description: Not implemented because this function is only needed
272**              within the HAL.
273**
274** Returns:     None.
275**
276*******************************************************************************/
277void NfcAdaptation::HalInitialize ()
278{
279    const char* func = "NfcAdaptation::HalInitialize";
280    ALOGD ("%s", func);
281}
282
283/*******************************************************************************
284**
285** Function:    NfcAdaptation::HalTerminate
286**
287** Description: Not implemented because this function is only needed
288**              within the HAL.
289**
290** Returns:     None.
291**
292*******************************************************************************/
293void NfcAdaptation::HalTerminate ()
294{
295    const char* func = "NfcAdaptation::HalTerminate";
296    ALOGD ("%s", func);
297}
298
299/*******************************************************************************
300**
301** Function:    NfcAdaptation::HalOpen
302**
303** Description: Turn on controller, download firmware.
304**
305** Returns:     None.
306**
307*******************************************************************************/
308void NfcAdaptation::HalOpen (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK* p_data_cback)
309{
310    const char* func = "NfcAdaptation::HalOpen";
311    ALOGD ("%s", func);
312    if (mHalDeviceContext)
313    {
314        mHalCallback = p_hal_cback;
315        mHalDataCallback = p_data_cback;
316        mHalDeviceContext->open (mHalDeviceContext, HalDeviceContextCallback, HalDeviceContextDataCallback);
317    }
318}
319
320/*******************************************************************************
321**
322** Function:    NfcAdaptation::HalClose
323**
324** Description: Turn off controller.
325**
326** Returns:     None.
327**
328*******************************************************************************/
329void NfcAdaptation::HalClose ()
330{
331    const char* func = "NfcAdaptation::HalClose";
332    ALOGD ("%s", func);
333    if (mHalDeviceContext)
334    {
335        mHalDeviceContext->close (mHalDeviceContext);
336    }
337}
338
339/*******************************************************************************
340**
341** Function:    NfcAdaptation::HalDeviceContextCallback
342**
343** Description: Translate generic Android HAL's callback into Broadcom-specific
344**              callback function.
345**
346** Returns:     None.
347**
348*******************************************************************************/
349void NfcAdaptation::HalDeviceContextCallback (nfc_event_t event, nfc_status_t event_status)
350{
351    const char* func = "NfcAdaptation::HalDeviceContextCallback";
352    ALOGD ("%s: event=%u", func, event);
353    if (mHalCallback)
354        mHalCallback (event, (tHAL_NFC_STATUS) event_status);
355}
356
357/*******************************************************************************
358**
359** Function:    NfcAdaptation::HalDeviceContextDataCallback
360**
361** Description: Translate generic Android HAL's callback into Broadcom-specific
362**              callback function.
363**
364** Returns:     None.
365**
366*******************************************************************************/
367void NfcAdaptation::HalDeviceContextDataCallback (uint16_t data_len, uint8_t* p_data)
368{
369    const char* func = "NfcAdaptation::HalDeviceContextDataCallback";
370    ALOGD ("%s: len=%u", func, data_len);
371    if (mHalDataCallback)
372        mHalDataCallback (data_len, p_data);
373}
374
375/*******************************************************************************
376**
377** Function:    NfcAdaptation::HalWrite
378**
379** Description: Write NCI message to the controller.
380**
381** Returns:     None.
382**
383*******************************************************************************/
384void NfcAdaptation::HalWrite (UINT16 data_len, UINT8* p_data)
385{
386    const char* func = "NfcAdaptation::HalWrite";
387    ALOGD ("%s", func);
388    if (mHalDeviceContext)
389    {
390        mHalDeviceContext->write (mHalDeviceContext, data_len, p_data);
391    }
392}
393
394/*******************************************************************************
395**
396** Function:    NfcAdaptation::HalCoreInitialized
397**
398** Description: Adjust the configurable parameters in the controller.
399**
400** Returns:     None.
401**
402*******************************************************************************/
403void NfcAdaptation::HalCoreInitialized (UINT8* p_core_init_rsp_params)
404{
405    const char* func = "NfcAdaptation::HalCoreInitialized";
406    ALOGD ("%s", func);
407    if (mHalDeviceContext)
408    {
409        mHalDeviceContext->core_initialized (mHalDeviceContext, p_core_init_rsp_params);
410    }
411}
412
413/*******************************************************************************
414**
415** Function:    NfcAdaptation::HalPrediscover
416**
417** Description:     Perform any vendor-specific pre-discovery actions (if needed)
418**                  If any actions were performed TRUE will be returned, and
419**                  HAL_PRE_DISCOVER_CPLT_EVT will notify when actions are
420**                  completed.
421**
422** Returns:          TRUE if vendor-specific pre-discovery actions initialized
423**                  FALSE if no vendor-specific pre-discovery actions are needed.
424**
425*******************************************************************************/
426BOOLEAN NfcAdaptation::HalPrediscover ()
427{
428    const char* func = "NfcAdaptation::HalPrediscover";
429    ALOGD ("%s", func);
430    BOOLEAN retval = FALSE;
431
432    if (mHalDeviceContext)
433    {
434        mHalDeviceContext->pre_discover (mHalDeviceContext);
435    }
436    return retval;
437}
438
439/*******************************************************************************
440**
441** Function:        HAL_NfcControlGranted
442**
443** Description:     Grant control to HAL control for sending NCI commands.
444**                  Call in response to HAL_REQUEST_CONTROL_EVT.
445**                  Must only be called when there are no NCI commands pending.
446**                  HAL_RELEASE_CONTROL_EVT will notify when HAL no longer
447**                  needs control of NCI.
448**
449** Returns:         void
450**
451*******************************************************************************/
452void NfcAdaptation::HalControlGranted ()
453{
454    const char* func = "NfcAdaptation::HalControlGranted";
455    ALOGD ("%s", func);
456    if (mHalDeviceContext)
457    {
458        mHalDeviceContext->control_granted (mHalDeviceContext);
459    }
460}
461
462/*******************************************************************************
463**
464** Function:    NfcAdaptation::HalPowerCycle
465**
466** Description: Turn off and turn on the controller.
467**
468** Returns:     None.
469**
470*******************************************************************************/
471void NfcAdaptation::HalPowerCycle ()
472{
473    const char* func = "NfcAdaptation::HalPowerCycle";
474    ALOGD ("%s", func);
475    if (mHalDeviceContext)
476    {
477        mHalDeviceContext->power_cycle (mHalDeviceContext);
478    }
479}
480
481/*******************************************************************************
482**
483** Function:    ThreadMutex::ThreadMutex()
484**
485** Description: class constructor
486**
487** Returns:     none
488**
489*******************************************************************************/
490ThreadMutex::ThreadMutex()
491{
492    pthread_mutexattr_t mutexAttr;
493
494    pthread_mutexattr_init(&mutexAttr);
495    pthread_mutex_init(&mMutex, &mutexAttr);
496    pthread_mutexattr_destroy(&mutexAttr);
497}
498
499/*******************************************************************************
500**
501** Function:    ThreadMutex::~ThreadMutex()
502**
503** Description: class destructor
504**
505** Returns:     none
506**
507*******************************************************************************/
508ThreadMutex::~ThreadMutex()
509{
510    pthread_mutex_destroy(&mMutex);
511}
512
513/*******************************************************************************
514**
515** Function:    ThreadMutex::lock()
516**
517** Description: lock kthe mutex
518**
519** Returns:     none
520**
521*******************************************************************************/
522void ThreadMutex::lock()
523{
524    pthread_mutex_lock(&mMutex);
525}
526
527/*******************************************************************************
528**
529** Function:    ThreadMutex::unblock()
530**
531** Description: unlock the mutex
532**
533** Returns:     none
534**
535*******************************************************************************/
536void ThreadMutex::unlock()
537{
538    pthread_mutex_unlock(&mMutex);
539}
540
541/*******************************************************************************
542**
543** Function:    ThreadCondVar::ThreadCondVar()
544**
545** Description: class constructor
546**
547** Returns:     none
548**
549*******************************************************************************/
550ThreadCondVar::ThreadCondVar()
551{
552    pthread_condattr_t CondAttr;
553
554    pthread_condattr_init(&CondAttr);
555    pthread_cond_init(&mCondVar, &CondAttr);
556
557    pthread_condattr_destroy(&CondAttr);
558}
559
560/*******************************************************************************
561**
562** Function:    ThreadCondVar::~ThreadCondVar()
563**
564** Description: class destructor
565**
566** Returns:     none
567**
568*******************************************************************************/
569ThreadCondVar::~ThreadCondVar()
570{
571    pthread_cond_destroy(&mCondVar);
572}
573
574/*******************************************************************************
575**
576** Function:    ThreadCondVar::wait()
577**
578** Description: wait on the mCondVar
579**
580** Returns:     none
581**
582*******************************************************************************/
583void ThreadCondVar::wait()
584{
585    pthread_cond_wait(&mCondVar, *this);
586    pthread_mutex_unlock(*this);
587}
588
589/*******************************************************************************
590**
591** Function:    ThreadCondVar::signal()
592**
593** Description: signal the mCondVar
594**
595** Returns:     none
596**
597*******************************************************************************/
598void ThreadCondVar::signal()
599{
600    AutoThreadMutex  a(*this);
601    pthread_cond_signal(&mCondVar);
602}
603
604/*******************************************************************************
605**
606** Function:    AutoThreadMutex::AutoThreadMutex()
607**
608** Description: class constructor, automatically lock the mutex
609**
610** Returns:     none
611**
612*******************************************************************************/
613AutoThreadMutex::AutoThreadMutex(ThreadMutex &m)
614    : mm(m)
615{
616    mm.lock();
617}
618
619/*******************************************************************************
620**
621** Function:    AutoThreadMutex::~AutoThreadMutex()
622**
623** Description: class destructor, automatically unlock the mutex
624**
625** Returns:     none
626**
627*******************************************************************************/
628AutoThreadMutex::~AutoThreadMutex()
629{
630    mm.unlock();
631}
632