15c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen/******************************************************************************
25c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *
35c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *  Copyright (C) 1999-2012 Broadcom Corporation
45c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *
55c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *  Licensed under the Apache License, Version 2.0 (the "License");
65c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *  you may not use this file except in compliance with the License.
75c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *  You may obtain a copy of the License at:
85c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *
95c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *  http://www.apache.org/licenses/LICENSE-2.0
105c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *
115c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *  Unless required by applicable law or agreed to in writing, software
125c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *  distributed under the License is distributed on an "AS IS" BASIS,
135c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *  See the License for the specific language governing permissions and
155c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *  limitations under the License.
165c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen *
175c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen ******************************************************************************/
185c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
195c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen/******************************************************************************
205c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen * Construct a buffer that contains multiple Type-Length-Value contents
215c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen * that is used by the HAL in a CORE_SET_CONFIG NCI command.
225c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen ******************************************************************************/
235c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
245c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#define LOG_TAG "NfcNciHal"
255c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "OverrideLog.h"
265c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "StartupConfig.h"
275c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
285c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
295c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenconst UINT8 StartupConfig::mMaxLength = 255;
305c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
315c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
325c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen/*******************************************************************************
335c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
345c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Function:        initialize
355c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
365c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Description:     Initialize all member variables.
375c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
385c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Returns:         None
395c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
405c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen*******************************************************************************/
415c65c3a0f42e174e47fecd4e569606003217ff4eMartijn CoenenStartupConfig::StartupConfig ()
425c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen{
435c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    //set first byte to 0, which is length of payload
445c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    mBuffer.append ((uint8_string::size_type) 1, (uint8_string::value_type) 0);
455c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen}
465c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
475c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
485c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen/*******************************************************************************
495c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
505c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Function:        initialize
515c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
525c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Description:     Reset all member variables.
535c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
545c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Returns:         None
555c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
565c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen*******************************************************************************/
575c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenvoid StartupConfig::initialize ()
585c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen{
595c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    mBuffer.clear ();
605c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    //set first byte to 0, which is length of payload
615c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    mBuffer.append ((uint8_string::size_type) 1, (uint8_string::value_type) 0);
625c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen}
635c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
645c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
655c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen/*******************************************************************************
665c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
675c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Function:        getInternalBuffer
685c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
695c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Description:     Get the pointer to buffer that contains multiple
705c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**                  Type-Length-Value contents.
715c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
725c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Returns:         Pointer to buffer.
735c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
745c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen*******************************************************************************/
755c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenconst UINT8* StartupConfig::getInternalBuffer ()
765c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen{
775c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    return mBuffer.data ();
785c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen}
795c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
805c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
815c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen/*******************************************************************************
825c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
835c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Function:        append
845c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
855c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Description:     Append new config data to internal buffer.
865c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**                  newContent: buffer containing new content; newContent[0] is
875c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**                          payload length; newContent[1..end] is payload.
88a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu**                  newContentLen: total length of newContent.
895c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
905c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Returns:         True if ok.
915c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
925c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen*******************************************************************************/
93a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chubool StartupConfig::append (const UINT8* newContent, UINT8 newContentLen)
945c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen{
955c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    static const char fn [] = "StartupConfig::append";
96a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu    if ((newContentLen+mBuffer.size()) > mMaxLength)
975c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    {
985c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        ALOGE ("%s: exceed max length", fn);
995c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        return false;
1005c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    }
101a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu
102a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu    ALOGD ("%s: try append %u bytes", fn, (uint8_string::size_type) (newContentLen));
1035c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    //append new payload into private buffer
104a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu    mBuffer.append (newContent+1, (uint8_string::size_type) (newContentLen-1));
1055c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    //increase size counter of payload in private buffer
106a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu    mBuffer[0] = mBuffer[0] + newContentLen-1;
1075c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    ALOGD ("%s: new size %u bytes", fn, mBuffer[0]);
1085c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    return true;
1095c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen};
1105c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
1115c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
1125c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen/*******************************************************************************
1135c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
1145c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Function:        disableSecureElement
1155c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
1165c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Description:     Adjust a TLV to disable secure element(s).  The TLV's type is 0xC2.
1175c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**                  bitmask: 0xC0 = do not detect any secure element.
1185c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**                           0x40 = do not detect secure element in slot 0.
1195c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**                           0x80 = do not detect secure element in slot 1.
1205c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
1215c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen** Returns:         True if ok.
1225c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen**
1235c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen*******************************************************************************/
1245c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenbool StartupConfig::disableSecureElement (UINT8 bitmask)
1255c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen{
1265c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    const UINT8 maxLen = mBuffer[0];
1275c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    UINT8 index = 1, tlvType = 0, tlvLen = 0;
1285c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    bool found0xC2 = false;
1295c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
1305c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    while (true)
1315c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    {
1325c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        if (index > maxLen)
1335c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen            break;
1345c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        tlvType = mBuffer [index];
1355c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        index++;
1365c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        tlvLen = mBuffer [index];
1375c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        index++;
1385c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        if (tlvType == 0xC2) //this TLV controls secure elements
1395c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        {
1405c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen            index++; //index of second byte in TLV's value
1415c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen            mBuffer [index] = mBuffer [index] | bitmask; //turn on certain bits
1425c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen            found0xC2 = true;
1435c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        }
1445c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        else
1455c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen            index += tlvLen;
1465c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    }
1475c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen
1485c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    if (found0xC2 == false)
1495c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    {
1505c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        UINT8 tlv [] = {0x04, 0xC2, 0x02, 0x61, 0x00};
1515c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen        tlv [4] = tlv [4] | bitmask;
152a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu        found0xC2 = append (tlv, 5);
1535c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    }
1545c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen    return found0xC2;
1555c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen}
156