Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mbed-os-nfc04a1 Wiagro-Lanza34-XDot
Revision 0:de13951f30f6, committed 2019-11-14
- Comitter:
- DiegoOstuni
- Date:
- Thu Nov 14 10:34:11 2019 +0000
- Commit message:
- Add files
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.gitignore Thu Nov 14 10:34:11 2019 +0000 @@ -0,0 +1,32 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENSE Thu Nov 14 10:34:11 2019 +0000 @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/NDEFcommon.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,85 @@
+/**
+ ******************************************************************************
+ * @file common.h
+ * @author MMY Application Team
+ * @version $Revision: 3343 $
+ * @date $Date: 2017-01-24 16:07:22 +0100 (Tue, 24 Jan 2017) $
+ * @brief Header for main.c module
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2017 STMicroelectronics</center></h2>
+ *
+ * Licensed under MMY-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __COMMON_H
+#define __COMMON_H
+
+/* Includes ------------------------------------------------------------------*/
+//#include "x_nucleo_nfc04a1_nfctag.h"
+#include <string.h>
+#include "stdint.h"
+
+/* Exported types ------------------------------------------------------------*/
+//typedef uint8_t boolean;
+
+/**
+ * @brief GPO status information structure definition
+ */
+typedef struct
+{
+ uint8_t WritenEEPROM;
+ uint8_t RfBusy;
+ uint8_t FieldOn;
+ uint8_t FieldOff;
+ uint8_t MsgInMailbox;
+ uint8_t MailboxMsgRead;
+ uint8_t RfInterrupt;
+ uint8_t Rfuser;
+} IT_GPO_STATUS;
+
+/* Exported macro ------------------------------------------------------------*/
+#ifndef MIN
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+#endif
+
+/*
+#undef FAIL
+#define FAIL 0
+
+#undef PASS
+#define PASS !FAIL
+*/
+
+#define NFCTAG_4K_SIZE ((uint32_t) 0x200)
+#define NFCTAG_16K_SIZE ((uint32_t) 0x800)
+#define NFCTAG_64K_SIZE ((uint32_t) 0x2000)
+
+/* Exported constants --------------------------------------------------------*/
+#define MAX_NDEF_MEM 0x200
+#define ST25DV_MAX_SIZE NFCTAG_4K_SIZE
+#define ST25DV_NDEF_MAX_SIZE MIN(ST25DV_MAX_SIZE,MAX_NDEF_MEM)
+#define NFC_DEVICE_MAX_NDEFMEMORY ST25DV_NDEF_MAX_SIZE
+
+#define RESULTOK 0x00
+#define ERRORCODE_GENERIC 1
+
+/* Exported functions ------------------------------------------------------- */
+
+#endif /* __COMMON_H */
+
+/************************ (C) COPYRIGHT 2017 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.md Thu Nov 14 10:34:11 2019 +0000 @@ -0,0 +1,4 @@ +# libNDEF +libNDEF is a library used for STMicroelectronics X-NUCLEO-NFC04A1 expansion board. +# Overview +It is the library used to manage the content of the TAG (data). But also the specific feature of the tag, for instance: password, gpo, and so on.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,749 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF.c
+ * @author MMY Application Team
+ * @version $Revision: 3210 $
+ * @date $Date: 2016-12-05 15:37:48 +0100 (Mon, 05 Dec 2016) $
+ * @brief This file help to manage NDEF file, to parse and identify them.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+#include "lib_NDEF_Bluetooth.h"
+#include "lib_NDEF_Handover.h"
+#include "lib_NDEF_Wifi.h"
+#include "mbed.h"
+
+/** @addtogroup NFC_libraries
+ * @{
+ * @brief <b>This is the library used to manage the content of the TAG (data)
+ * But also the specific feature of the tag, for instance
+ * password, gpo... </b>
+ */
+
+
+/** @addtogroup libNFC_FORUM
+ * @{
+ * @brief This part of the library manage data which follow NFC forum organisation.
+ */
+
+/** @defgroup libNDEF_Private_Functions
+ * @{
+ */
+
+
+static uint16_t NDEF_IsNDEFPresent( I2C* mi2cChannel );
+static uint16_t NDEF_ParseRecordHeader( sRecordInfo_t *pRecordStruct );
+static void NDEF_ParseWellKnownType( sRecordInfo_t *pRecordStruct );
+static void NDEF_ParseMediaType( sRecordInfo_t *pRecordStruct );
+static void NDEF_ParseForumExternalType( sRecordInfo_t *pRecordStruct );
+static void NDEF_ParseURI( sRecordInfo_t *pRecordStruct );
+static void NDEF_ParseSP( sRecordInfo_t *pRecordStruct );
+static uint16_t NDEF_IdentifySPRecord( sRecordInfo_t *pRecordStruct, uint8_t* pPayload );
+
+/** @brief This buffer is used to store the data sent/received by the TAG. */
+uint8_t NDEF_Buffer [NDEF_MAX_SIZE];
+/** @brief Size of the buffer used to build the NDEF messages. */
+uint32_t NDEF_Buffer_size = NDEF_MAX_SIZE;
+/** @brief This buffer is used when it's required to prepare a record before adding it to the NDEF_Buffer. */
+uint8_t NDEF_Record_Buffer [NDEF_RECORD_MAX_SIZE];
+/** @brief Size of the buffer used when a record has to be prepared. */
+uint32_t NDEF_Record_Buffer_size = NDEF_RECORD_MAX_SIZE;
+
+/* In case of smart Poster composed with different record, 3 records supported so far */
+sRecordInfo_t SPRecordStruct1, SPRecordStruct2, SPRecordStruct3, SPRecordStruct4;
+sRecordInfo_t *SPRecordStructAdd[SP_MAX_RECORD] = { &SPRecordStruct1, &SPRecordStruct2, &SPRecordStruct3, &SPRecordStruct4 };
+
+/**
+ * @brief This function checks that the tag contain a NDEF message.
+ * @retval NDEF_OK : There is a NDEF file stored in tag.
+ * @retval NDEF_ERROR : No NDEF in the tag.
+ */
+static uint16_t NDEF_IsNDEFPresent( I2C* mi2cChannel )
+{
+ uint16_t FileSize;
+
+ /* Check NDEF existence */
+ NfcTag_GetLength(&FileSize, mi2cChannel);
+
+ if( FileSize != 0 )
+ return NDEF_OK;
+ else
+ return NDEF_ERROR;
+}
+
+/**
+ * @brief This function identify the type of record.
+ * @param pRecordStruct : pointer on the record structure to fill.
+ * @param pPayload : pointer on the payload.
+ * @retval Status : Status of the operation.
+ */
+static uint16_t NDEF_IdentifySPRecord( sRecordInfo_t *pRecordStruct, uint8_t* pPayload )
+{
+ uint16_t status = NDEF_ERROR;
+ uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
+
+ /* Is ID length field present */
+ if( (*pPayload) & IL_Mask )
+ {
+ IDLengthField = ID_LENGTH_FIELD;
+ }
+ else
+ {
+ IDLengthField = 0;
+ }
+
+ /* it's a SR */
+ if( (*pPayload) & SR_Mask )
+ {
+ TypeNbByte = pPayload[1];
+ PayloadLengthField = 1;
+ if( IDLengthField == ID_LENGTH_FIELD )
+ IDNbByte = pPayload[3];
+ else
+ IDNbByte = 0;
+ }
+ else
+ {
+ TypeNbByte = pPayload[1];
+ PayloadLengthField = 4;
+ if( IDLengthField == ID_LENGTH_FIELD )
+ IDNbByte = pPayload[6];
+ else
+ IDNbByte = 0;
+ }
+
+ SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
+
+ /* it's a SR */
+ if( pPayload[0] & SR_Mask )
+ {
+ pRecordStruct->RecordFlags = pPayload[0];
+ pRecordStruct->TypeLength = TypeNbByte;
+ pRecordStruct->PayloadLength = pPayload[2];
+ pRecordStruct->IDLength = IDNbByte;
+ memcpy( pRecordStruct->Type, &pPayload[3+IDNbByte], TypeNbByte );
+ memcpy( pRecordStruct->ID, &pPayload[3+IDNbByte+TypeNbByte], IDNbByte );
+ pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+ }
+ else
+ {
+ pRecordStruct->RecordFlags = pPayload[0];
+ pRecordStruct->TypeLength = TypeNbByte;
+ pRecordStruct->PayloadLength = ( ((uint32_t)pPayload[2]) << 24 ) |
+ ( ((uint32_t)pPayload[3]) << 16 ) |
+ ( ((uint32_t)pPayload[4]) << 8 )
+ | pPayload[5] ;
+ pRecordStruct->IDLength = IDNbByte;
+ memcpy( pRecordStruct->Type, &pPayload[6+IDNbByte], TypeNbByte );
+ memcpy( pRecordStruct->ID, &pPayload[6+IDNbByte+TypeNbByte], IDNbByte );
+ pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+ }
+
+ pRecordStruct->PayloadBufferAdd = pPayload + SizeOfRecordHeader ;
+
+ status = NDEF_ParseRecordHeader( pRecordStruct );
+
+ return status;
+}
+
+/**
+ * @brief This function parse the record header and dispatch regarding TNF value.
+ * @param pRecordStruct : pointer on the record structure to fill.
+ * @retval NDEF_OK : record identified and structure filled.
+ * @retval NDEF_ERROR : Not supported.
+ */
+static uint16_t NDEF_ParseRecordHeader( sRecordInfo_t *pRecordStruct )
+{
+ uint16_t status = NDEF_OK;
+
+ switch( (pRecordStruct->RecordFlags & TNF_Mask) )
+ {
+ case TNF_WellKnown:
+ NDEF_ParseWellKnownType( pRecordStruct );
+ break;
+
+ case TNF_MediaType:
+ NDEF_ParseMediaType( pRecordStruct );
+ break;
+
+ case TNF_NFCForumExternal:
+ NDEF_ParseForumExternalType( pRecordStruct);
+ break;
+
+ default:
+ /* currently not supported or unknown*/
+ pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+ status = NDEF_ERROR;
+ }
+ return status;
+}
+
+/**
+ * @brief This function parse the Well Known type record.
+ * @param pRecordStruct : pointer on the record structure to fill.
+ */
+static void NDEF_ParseWellKnownType( sRecordInfo_t *pRecordStruct )
+{
+ uint8_t* pPayload;
+
+ pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
+
+ if( !memcmp( &(pRecordStruct->Type), SMART_POSTER_TYPE_STRING, pRecordStruct->TypeLength ) )
+ {
+ /* special case where we have to parse others records */
+ pRecordStruct->NDEF_Type = SMARTPOSTER_TYPE;
+ NDEF_ParseSP( pRecordStruct );
+ }
+
+ else if( !memcmp( &(pRecordStruct->Type), URI_TYPE_STRING, pRecordStruct->TypeLength ) )
+ {
+ /* it's an URI Type check if it's an URL or SMS or ... */
+ /* check identifier */
+ if( *pPayload == URI_ID_0x00 )
+ {
+ NDEF_ParseURI( pRecordStruct );
+ }
+ else if( (*pPayload > URI_ID_0x00) && (*pPayload < URI_RFU) )
+ {
+ /* email special case */
+ if( *pPayload == (uint8_t) URI_ID_0x06 )
+ {
+ pRecordStruct->NDEF_Type = URI_EMAIL_TYPE;
+ }
+ else
+ {
+ pRecordStruct->NDEF_Type = WELL_KNOWN_ABRIDGED_URI_TYPE;
+ }
+ }
+ else
+ {
+ pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+ }
+ }
+
+ else if( !memcmp( &(pRecordStruct->Type), TEXT_TYPE_STRING, pRecordStruct->TypeLength ) )
+ {
+ pRecordStruct->NDEF_Type = TEXT_TYPE;
+ } else if ((!memcmp( &(pRecordStruct->Type), NDEF_HANDOVER_SELECT_TYPE_STR, pRecordStruct->TypeLength )) ||
+ (!memcmp( &(pRecordStruct->Type), NDEF_HANDOVER_REQUEST_TYPE_STR, pRecordStruct->TypeLength ) ))
+ {
+ pRecordStruct->NDEF_Type = HANDOVER_TYPE;
+ }
+ else
+ pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+}
+
+/**
+ * @brief This function parse the Media type record.
+ * @param pRecordStruct : pointer on the record structure to fill.
+ */
+static void NDEF_ParseMediaType( sRecordInfo_t *pRecordStruct )
+{
+ if( !memcmp( &(pRecordStruct->Type), VCARD_TYPE_STRING, pRecordStruct->TypeLength ) )
+ pRecordStruct->NDEF_Type = VCARD_TYPE;
+ else if( !memcmp( &(pRecordStruct->Type), XVCARD_TYPE_STRING, pRecordStruct->TypeLength ) )
+ pRecordStruct->NDEF_Type = VCARD_TYPE;
+ else if( !memcmp( &(pRecordStruct->Type), XVCARD2_TYPE_STRING, pRecordStruct->TypeLength ) )
+ pRecordStruct->NDEF_Type = VCARD_TYPE;
+ else if (!memcmp(&pRecordStruct->Type, NDEF_BLUETOOTH_BREDR_MIME_TYPE, pRecordStruct->TypeLength))
+ pRecordStruct->NDEF_Type = BT_TYPE;
+ else if (!memcmp(&pRecordStruct->Type, NDEF_BLUETOOTH_BLE_MIME_TYPE, pRecordStruct->TypeLength))
+ pRecordStruct->NDEF_Type = BLE_TYPE;
+ else if (!memcmp(&pRecordStruct->Type, WIFITOKEN_TYPE_STRING, pRecordStruct->TypeLength))
+ pRecordStruct->NDEF_Type = URI_WIFITOKEN_TYPE;
+ else
+ pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+}
+
+/**
+ * @brief This function parse the Forum External type record.
+ * @param pRecordStruct : pointer on the record structure to fill.
+ */
+static void NDEF_ParseForumExternalType( sRecordInfo_t *pRecordStruct )
+{
+ if( !memcmp( &(pRecordStruct->Type), M24SR_DISCOVERY_APP_STRING, pRecordStruct->TypeLength ) )
+ pRecordStruct->NDEF_Type = M24SR_DISCOVERY_APP_TYPE;
+ else
+ pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+}
+
+/**
+ * @brief This function parse the URI type record.
+ * @param pRecordStruct : pointer on the record structure to fill.
+ */
+static void NDEF_ParseURI( sRecordInfo_t *pRecordStruct )
+{
+ uint8_t* pPayload;
+
+ pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
+ pPayload++; /* to skip URI identifier first URI payload byte */
+
+ if( !memcmp( pPayload, SMS_TYPE_STRING, strlen(SMS_TYPE_STRING) ) )
+ {
+ pRecordStruct->NDEF_Type = URI_SMS_TYPE;
+ }
+ else if( !memcmp( pPayload, GEO_TYPE_STRING, strlen(GEO_TYPE_STRING) ) )
+ {
+ pRecordStruct->NDEF_Type = URI_GEO_TYPE;
+ }
+ else
+ pRecordStruct->NDEF_Type = UNKNOWN_TYPE;
+}
+
+/**
+ * @brief This function parse the Smart Poster.
+ * @param pRecordStruct : pointer on the record structure to fill.
+ */
+static void NDEF_ParseSP( sRecordInfo_t *pRecordStruct )
+{
+ uint8_t* pPayload;
+ uint32_t PayloadSize = 0;
+ uint32_t SPPayloadSize = 0;
+ uint32_t OffsetInSPPayload = 0;
+ uint32_t RecordPosition = 0;
+ sRecordInfo_t *pSPRecordStruct;
+
+ /* initialize variable with size of the payload and poiter on data */
+ PayloadSize = pRecordStruct->PayloadLength;
+
+ pPayload = (uint8_t*)( pRecordStruct->PayloadBufferAdd );
+
+ pSPRecordStruct = SPRecordStructAdd[0];
+
+ /* Initailize the number of record find in the SP payload */
+ pRecordStruct->NbOfRecordInSPPayload = 0;
+
+ do
+ {
+ pSPRecordStruct = SPRecordStructAdd[RecordPosition];
+ /* identify the record in the SP payload */
+ if( NDEF_IdentifySPRecord( pSPRecordStruct, pPayload ) == NDEF_OK )
+ {
+ /* store add of structure that will contain the other record information */
+ pRecordStruct->NbOfRecordInSPPayload++;
+ pRecordStruct->SPRecordStructAdd[RecordPosition] = pSPRecordStruct;
+
+ /* After SPRecord + First Record check if we are at the end of NDEF file */
+ SPPayloadSize = pSPRecordStruct->PayloadLength;
+
+ OffsetInSPPayload += pSPRecordStruct->PayloadOffset + SPPayloadSize;
+ pPayload += OffsetInSPPayload;
+ }
+ else /* Recommended Action Record for example */
+ {
+ SPPayloadSize = 0;
+ }
+ RecordPosition++;
+ }
+ while( (OffsetInSPPayload < PayloadSize) && RecordPosition<SP_MAX_RECORD); /* there is another record */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup libNDEF_Public_Functions
+ * @{
+ */
+
+
+/**
+ * @brief This function identify the NDEF message stored in tag.
+ * @param pRecordStruct : Structure to fill with record information.
+ * @param pNDEF : pointer on the NDEF message data.
+ * @retval NDEF_OK : record struct filled.
+ * @retval NDEF_ERROR : record struct not updated.
+ */
+uint16_t NDEF_IdentifyNDEF( sRecordInfo_t *pRecordStruct, uint8_t* pNDEF, I2C* mi2cChannel )
+{
+ uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
+
+ /* check NDEF present */
+ if( NDEF_IsNDEFPresent(mi2cChannel) != NDEF_OK )
+ {
+ return NDEF_ERROR;
+ }
+
+ /* Read the NDEF file */
+ NfcTag_ReadNDEF( pNDEF, mi2cChannel );
+
+ /* Is ID length field present */
+ if( (*pNDEF) & IL_Mask )
+ {
+ IDLengthField = ID_LENGTH_FIELD;
+ }
+ else
+ {
+ IDLengthField = 0;
+ }
+
+ /* it's a SR */
+ if( (*pNDEF) & SR_Mask )
+ {
+ /* Analyse short record layout */
+ TypeNbByte = pNDEF[1];
+ PayloadLengthField = 1;
+ if( IDLengthField == ID_LENGTH_FIELD )
+ IDNbByte = pNDEF[3];
+ else
+ IDNbByte = 0;
+ }
+ else
+ {
+ /* Analyse normal record layout */
+ TypeNbByte = pNDEF[1];
+ PayloadLengthField = 4;
+ if( IDLengthField == ID_LENGTH_FIELD )
+ IDNbByte = pNDEF[6];
+ else
+ IDNbByte = 0;
+ }
+
+ SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
+
+ /* Read record header */
+ /* it's a SR */
+ if( pNDEF[0] & SR_Mask )
+ {
+ pRecordStruct->RecordFlags = pNDEF[0];
+ pRecordStruct->TypeLength = TypeNbByte;
+ pRecordStruct->PayloadLength = pNDEF[2];
+ pRecordStruct->IDLength = IDNbByte;
+ memcpy( pRecordStruct->Type, &pNDEF[3+IDNbByte], TypeNbByte );
+ memcpy( pRecordStruct->ID, &pNDEF[3+IDNbByte+TypeNbByte], IDNbByte );
+ pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+ }
+ else
+ {
+ pRecordStruct->RecordFlags = pNDEF[0];
+ pRecordStruct->TypeLength = TypeNbByte;
+ pRecordStruct->PayloadLength = ( ((uint32_t)pNDEF[2]) << 24 ) |
+ ( ((uint32_t)pNDEF[3]) << 16 ) |
+ ( ((uint32_t)pNDEF[4]) << 8 )
+ | pNDEF[5] ;
+ pRecordStruct->IDLength = IDNbByte;
+ memcpy( pRecordStruct->Type, &pNDEF[6+IDNbByte], TypeNbByte );
+ memcpy( pRecordStruct->ID, &pNDEF[6+IDNbByte+TypeNbByte], IDNbByte );
+ pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+ }
+
+ pRecordStruct->PayloadBufferAdd = pNDEF;
+
+ NDEF_ParseRecordHeader( pRecordStruct );
+
+ return NDEF_OK;
+}
+
+/**
+ * @brief This function read the NDEF content of the TAG.
+ * @param pNDEF : pointer on the buffer to store NDEF data.
+ * @retval NDEF_OK : NDEF file data retrieve and store in the buffer.
+ * @retval NDEF_ERROR : not able to read NDEF from tag.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot read tag.
+ * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be read.
+ */
+uint16_t NDEF_ReadNDEF( uint8_t* pNDEF, I2C* mi2cChannel )
+{
+ return NfcTag_ReadNDEF( pNDEF, mi2cChannel );
+}
+
+
+
+/**
+ * @brief This function read the NDEF size of the TAG.
+ * @param Size : pointer to a 16-bit Size (in bytes) to be returned.
+ * @retval NDEF_OK : NDEF file data retrieve and store in the buffer.
+ * @retval NDEF_ERROR : not able to read NDEF from tag.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot read tag.
+ * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be read.
+ */
+uint16_t NDEF_getNDEFSize(uint16_t* Size, I2C* mi2cChannel)
+{
+ return NfcTag_GetLength(Size, mi2cChannel);
+}
+/**
+ * @brief This function write the NDEF in the TAG.
+ * @param pNDEF : pointer on the buffer containing the NDEF data.
+ * @retval NDEF_OK : NDEF file data written in the tag.
+ * @retval NDEF_ERROR : not able to store NDEF in tag.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+ * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+ */
+uint16_t NDEF_WriteNDEF( uint16_t NDEF_Size, uint8_t *pNDEF, I2C* mi2cChannel )
+{
+ return NfcTag_WriteNDEF( NDEF_Size, pNDEF, mi2cChannel );
+
+}
+
+/**
+ * @brief This function append the record to an the NDEF in the TAG.
+ * @param pRecord : pointer on the record with data to be written.
+ * @retval NDEF_OK : NDEF file data written in the tag.
+ * @retval NDEF_ERROR : not able to store NDEF in tag.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+ * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+ */
+uint16_t NDEF_AppendRecord(sRecordInfo_t *Record, I2C* mi2cChannel )
+{
+ uint16_t status;
+ uint16_t NDEF_Size = 0;
+ uint8_t* pData = NDEF_Buffer;
+
+ status = NDEF_getNDEFSize(&NDEF_Size, mi2cChannel);
+ if(status != NDEF_OK) return status ;
+
+ if(NDEF_Size != 0)
+ {
+ // There are already records in the NDEF
+ Record->RecordFlags &= ~MB_Mask;
+
+ status = NfcTag_ReadNDEF(pData, mi2cChannel);
+ if(status != NDEF_OK) return status ;
+
+ uint8_t* pNdefRecord;
+ sRecordInfo_t LastRecord;
+ do {
+ pNdefRecord = pData;
+ NDEF_IdentifyBuffer(&LastRecord,pData);
+ pData += LastRecord.PayloadOffset + LastRecord.PayloadLength;
+ // TO DO: add a security condition to avoid infinite loop if NDEF file is corrupted
+ } while(!(LastRecord.RecordFlags & ME_Mask));
+ LastRecord.RecordFlags &= ~ME_Mask;
+ *pNdefRecord = LastRecord.RecordFlags;
+ } else {
+ // This will be the first message in memory
+ Record->RecordFlags |= MB_Mask;
+ }
+ Record->RecordFlags |= ME_Mask;
+ uint32_t RecordLength = NDEF_WriteRecord(Record,pData, mi2cChannel);
+
+
+ return NfcTag_WriteNDEF( NDEF_Size + RecordLength, NDEF_Buffer, mi2cChannel );
+
+}
+
+
+
+/**
+ * @brief This function identify the NDEF message stored in tag.
+ * @param pRecordStruct : Structure to fill with record information.
+ * @param pNDEF : pointer on the NDEF message data.
+ * @retval NDEF_OK : record struct filled.
+ * @retval NDEF_ERROR : record struct not updated.
+ */
+uint16_t NDEF_IdentifyBuffer( sRecordInfo_t *pRecordStruct, uint8_t* pNDEF )
+{
+ uint16_t SizeOfRecordHeader, TypeNbByte, PayloadLengthField, IDLengthField, IDNbByte;
+
+ /* Is ID length field present */
+ if( (*pNDEF) & IL_Mask )
+ {
+ IDLengthField = ID_LENGTH_FIELD;
+ }
+ else
+ {
+ IDLengthField = 0;
+ }
+
+ /* it's a SR */
+ if( (*pNDEF) & SR_Mask )
+ {
+ /* Analyse short record layout */
+ TypeNbByte = pNDEF[1];
+ PayloadLengthField = 1;
+ if( IDLengthField == ID_LENGTH_FIELD )
+ IDNbByte = pNDEF[3];
+ else
+ IDNbByte = 0;
+ }
+ else
+ {
+ /* Analyse normal record layout */
+ TypeNbByte = pNDEF[1];
+ PayloadLengthField = 4;
+ if( IDLengthField == ID_LENGTH_FIELD )
+ IDNbByte = pNDEF[6];
+ else
+ IDNbByte = 0;
+ }
+
+ SizeOfRecordHeader = RECORD_FLAG_FIELD + TYPE_LENGTH_FIELD + PayloadLengthField + IDLengthField + TypeNbByte + IDNbByte;
+
+ /* it's a SR */
+ if( pNDEF[0] & SR_Mask )
+ {
+ pRecordStruct->RecordFlags = pNDEF[0];
+ pRecordStruct->TypeLength = TypeNbByte;
+ pRecordStruct->PayloadLength = pNDEF[2];
+ pRecordStruct->IDLength = IDNbByte;
+ memcpy( pRecordStruct->Type, &pNDEF[3+IDLengthField], TypeNbByte );
+ memcpy( pRecordStruct->ID, &pNDEF[3+IDLengthField+TypeNbByte], IDNbByte );
+ pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+ }
+ else
+ {
+ pRecordStruct->RecordFlags = pNDEF[0];
+ pRecordStruct->TypeLength = TypeNbByte;
+ pRecordStruct->PayloadLength = ( ((uint32_t)pNDEF[2]) << 24 ) |
+ ( ((uint32_t)pNDEF[3]) << 16 ) |
+ ( ((uint32_t)pNDEF[4]) << 8 )
+ | pNDEF[5] ;
+ pRecordStruct->IDLength = IDNbByte;
+ memcpy( pRecordStruct->Type, &pNDEF[6+IDNbByte], TypeNbByte );
+ memcpy( pRecordStruct->ID, &pNDEF[6+IDNbByte+TypeNbByte], IDNbByte );
+ pRecordStruct->PayloadOffset = SizeOfRecordHeader;
+ }
+
+ pRecordStruct->PayloadBufferAdd = &pNDEF[pRecordStruct->PayloadOffset];
+
+ NDEF_ParseRecordHeader( pRecordStruct );
+
+ return NDEF_OK;
+}
+
+/**
+ * @brief This function writes a record into a NDEF buffer. (update SR flag if required)
+ * @param pRecord : Structure with record information to be written.
+ * @param pNDEF : pointer on the NDEF buffer.
+ * @retval Length : Length of the written data (in bytes)
+ */
+uint32_t NDEF_WriteRecord( sRecordInfo_t *pRecord, uint8_t* pNDEF, I2C* mi2cChannel )
+{
+ /************************************/
+/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
+/*----------------------------------*/
+/* MB ME CF SR IL TNF */
+/*----------------------------------*/
+/* TYPE LENGTH */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 3 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 2 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 1 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 0 */
+/*----------------------------------*/
+/* ID LENGTH */
+/*----------------------------------*/
+/* TYPE */
+/*----------------------------------*/
+/* ID */
+/*----------------------------------*/
+/* PAYLOAD */
+/************************************/
+ uint8_t * start = pNDEF;
+
+ // start by considering payload length
+ if(pRecord->PayloadLength <= 0xFF)
+ pRecord->RecordFlags |= SR_Mask;
+ else
+ pRecord->RecordFlags &= ~SR_Mask;
+
+ // Then start writing!
+ *pNDEF++ = pRecord->RecordFlags;
+
+ *pNDEF++ = pRecord->TypeLength;
+
+ if (!(pRecord->RecordFlags & SR_Mask))
+ {
+ *pNDEF++ = (pRecord->PayloadLength >> 24) & 0xFF;
+ *pNDEF++ = (pRecord->PayloadLength >> 16) & 0xFF ;
+ *pNDEF++ = (pRecord->PayloadLength >> 8) & 0xFF;
+ }
+ *pNDEF++ = (pRecord->PayloadLength) & 0xFF;
+
+ if(pRecord->RecordFlags & IL_Mask)
+ *pNDEF++ = (pRecord->IDLength);
+
+ memcpy(pNDEF,pRecord->Type,pRecord->TypeLength);
+ pNDEF += pRecord->TypeLength;
+
+ if(pRecord->RecordFlags & IL_Mask)
+ {
+ memcpy(pNDEF,pRecord->ID,pRecord->IDLength);
+ pNDEF += pRecord->IDLength;
+ }
+
+ memcpy(pNDEF,pRecord->PayloadBufferAdd,pRecord->PayloadLength);
+ pNDEF += pRecord->PayloadLength;
+
+ return (pNDEF - start);
+}
+
+/**
+ * @brief This function return the length a record data (update SR flag if required)
+ * @param pRecord : Structure with record information
+ * @retval Length : Length of the data (in bytes)
+ */
+uint32_t NDEF_GetRecordLength( sRecordInfo_t *pRecord )
+{
+ // start by considering payload length
+ if(pRecord->PayloadLength <= 0xFF)
+ pRecord->RecordFlags |= SR_Mask;
+ else
+ pRecord->RecordFlags &= ~SR_Mask;
+
+ // Then compute the length
+ uint32_t length = 1 + // Flags
+ 1 + // Type length
+ ((pRecord->RecordFlags & SR_Mask)? 1 : 4) + // Payload length
+ ((pRecord->RecordFlags & IL_Mask)? 1 : 0) + // ID length
+ pRecord->TypeLength + // Type
+ ((pRecord->RecordFlags & IL_Mask)? pRecord->IDLength : 0) + // ID
+ pRecord->PayloadLength; // Payload;
+
+ return length;
+}
+
+/**
+ * @brief This function clears the NDEF file
+ * @retval NDEF Status
+ */
+uint16_t NDEF_ClearNDEF(I2C* mi2cChannel)
+{
+ return NDEF_WriteNDEF(0 , NULL, mi2cChannel);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,268 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF.h
+ * @author MMY Application Team
+ * @version $Revision: 2762 $
+ * @date $Date: 2016-08-10 16:40:40 +0200 (Wed, 10 Aug 2016) $
+ * @brief This file help to manage NDEF file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_H
+#define __LIB_NDEF_H
+
+/* Includes ------------------------------------------------------------------*/
+/* include file which match the HW configuration */
+#include "lib_wrapper.h"
+#include <string.h>
+
+
+
+#define NDEF_ACTION_COMPLETED 0x9000
+
+#ifndef errorchk
+#define errorchk(fCall) if (status = (fCall), status != NDEF_ACTION_COMPLETED) \
+ {goto Error;} else
+#endif
+
+/* Error codes for Higher level */
+#define NDEF_OK RESULTOK
+#define NDEF_ERROR ERRORCODE_GENERIC
+#define NDEF_ERROR_MEMORY_TAG 2
+#define NDEF_ERROR_MEMORY_INTERNAL 3
+#define NDEF_ERROR_LOCKED 4
+#define NDEF_ERROR_NOT_FORMATED 5
+
+//#define NDEF_MAX_SIZE NFC_DEVICE_MAX_NDEFMEMORY
+//#define NDEF_RECORD_MAX_SIZE (512)
+#define NDEF_MAX_SIZE (100)
+#define NDEF_RECORD_MAX_SIZE (100)
+
+#define NDEF_SIZE_OFFSET 0
+#define FIRST_RECORD_OFFSET 0
+
+#define RECORD_FLAG_FIELD 1
+#define TYPE_LENGTH_FIELD 1
+#define ID_LENGTH_FIELD 1
+
+
+#define MB_Mask ((uint8_t)(0x80))
+#define ME_Mask ((uint8_t)(0x40))
+#define CF_Mask ((uint8_t)(0x20))
+#define SR_Mask ((uint8_t)(0x10))
+#define IL_Mask ((uint8_t)(0x08))
+#define TNF_Mask ((uint8_t)(0x07))
+
+#define TNF_Empty 0x00
+#define TNF_WellKnown 0x01
+#define TNF_MediaType 0x02
+#define TNF_AbsoluteURI 0x03
+#define TNF_NFCForumExternal 0x04
+#define TNF_Unknown 0x05
+#define TNF_Unchanged 0x06
+#define TNF_Reserved 0x07
+
+#define SP_MAX_RECORD 4
+
+#define AAR_TYPE_STRING "android.com:pkg"
+#define AAR_TYPE_STRING_LENGTH 15
+
+#define M24SR_DISCOVERY_APP_STRING "st.com:m24sr_discovery_democtrl"
+#define M24SR_DISCOVERY_APP_STRING_LENGTH 31
+
+#define VCARD_TYPE_STRING "text/vcard"
+#define VCARD_TYPE_STRING_LENGTH 10
+
+#define XVCARD_TYPE_STRING "text/x-vCard"
+#define XVCARD_TYPE_STRING_LENGTH 12
+
+#define XVCARD2_TYPE_STRING "text/x-vcard"
+#define XVCARD2_TYPE_STRING_LENGTH 12
+
+#define SMART_POSTER_TYPE_STRING "Sp"
+#define SMART_POSTER_TYPE_STRING_LENGTH 2
+
+#define URI_TYPE_STRING "U"
+#define URI_TYPE_STRING_LENGTH 1
+
+#define SMS_TYPE_STRING "sms:"
+#define SMS_TYPE_STRING_LENGTH 4
+
+#define GEO_TYPE_STRING "geo:"
+#define GEO_TYPE_STRING_LENGTH 4
+
+#define URI_LATITUDE_END ","
+#define URI_LATITUDE_END_LENGTH 1
+
+#define EMAIL_TYPE_STRING "mailto:"
+#define EMAIL_TYPE_STRING_LENGTH 7
+
+#define URI_FIRST_DATA_END "?"
+#define URI_FIRST_DATA_END_LENGTH 1
+
+#define SUBJECT_BEGIN_STRING "subject="
+#define SUBJECT_BEGIN_STRING_LENGTH 8
+
+#define MESSAGE_BEGIN_STRING "body="
+#define MESSAGE_BEGIN_STRING_LENGTH 5
+
+#define URI_SECOND_DATA_END "&"
+#define URI_SECOND_DATA_END_LENGTH 1
+
+#define TEXT_TYPE_STRING "T"
+#define TEXT_TYPE_STRING_LENGTH 1
+
+#define ISO_ENGLISH_CODE_STRING "en"
+#define ISO_ENGLISH_CODE_STRING_LENGTH 2
+
+
+#define URI_ID_0x00 0x00
+#define URI_ID_0x01 0x01
+#define URI_ID_0x02 0x02
+#define URI_ID_0x03 0x03
+#define URI_ID_0x04 0x04
+#define URI_ID_0x05 0x05
+#define URI_ID_0x06 0x06
+#define URI_ID_0x07 0x07
+#define URI_ID_0x08 0x08
+#define URI_ID_0x09 0x09
+#define URI_ID_0x0A 0x0A
+#define URI_ID_0x0B 0x0B
+#define URI_ID_0x0C 0x0C
+#define URI_ID_0x0D 0x0D
+#define URI_ID_0x0E 0x0E
+#define URI_ID_0x0F 0x0F
+#define URI_ID_0x10 0x10
+#define URI_ID_0x11 0x11
+#define URI_ID_0x12 0x12
+#define URI_ID_0x13 0x13
+#define URI_ID_0x14 0x14
+#define URI_ID_0x15 0x15
+#define URI_ID_0x16 0x16
+#define URI_ID_0x17 0x17
+#define URI_ID_0x18 0x18
+#define URI_ID_0x19 0x19
+#define URI_ID_0x1A 0x1A
+#define URI_ID_0x1B 0x1B
+#define URI_ID_0x1C 0x1C
+#define URI_ID_0x1D 0x1D
+#define URI_ID_0x1E 0x1E
+#define URI_ID_0x1F 0x1F
+#define URI_ID_0x20 0x20
+#define URI_ID_0x21 0x21
+#define URI_ID_0x22 0x22
+#define URI_ID_0x23 0x23
+#define URI_RFU 0x24
+
+#define URI_ID_0x01_STRING "http://www.\0"
+#define URI_ID_0x02_STRING "https://www.\0"
+#define URI_ID_0x03_STRING "http://\0"
+#define URI_ID_0x04_STRING "https://\0"
+#define URI_ID_0x05_STRING "tel:\0"
+#define URI_ID_0x06_STRING "mailto:\0"
+#define URI_ID_0x07_STRING "ftp://anonymous:anonymous@\0"
+#define URI_ID_0x08_STRING "ftp://ftp.\0"
+#define URI_ID_0x09_STRING "ftps://\0"
+#define URI_ID_0x0A_STRING "sftp://\0"
+#define URI_ID_0x0B_STRING "smb://\0"
+#define URI_ID_0x0C_STRING "nfs://\0"
+#define URI_ID_0x0D_STRING "ftp://\0"
+#define URI_ID_0x0E_STRING "dav://\0"
+#define URI_ID_0x0F_STRING "news:\0"
+#define URI_ID_0x10_STRING "telnet://\0"
+#define URI_ID_0x11_STRING "imap:\0"
+#define URI_ID_0x12_STRING "rtsp://\0"
+#define URI_ID_0x13_STRING "urn:\0"
+#define URI_ID_0x14_STRING "pop:\0"
+#define URI_ID_0x15_STRING "sip:\0"
+#define URI_ID_0x16_STRING "sips:\0"
+#define URI_ID_0x17_STRING "tftp:\0"
+#define URI_ID_0x18_STRING "btspp://\0"
+#define URI_ID_0x19_STRING "btl2cap://\0"
+#define URI_ID_0x1A_STRING "btgoep://\0"
+#define URI_ID_0x1B_STRING "tcpobex://\0"
+#define URI_ID_0x1C_STRING "irdaobex://\0"
+#define URI_ID_0x1D_STRING "file://\0"
+#define URI_ID_0x1E_STRING "urn:epc:id:\0"
+#define URI_ID_0x1F_STRING "urn:epc:tag\0"
+#define URI_ID_0x20_STRING "urn:epc:pat:\0"
+#define URI_ID_0x21_STRING "urn:epc:raw:\0"
+#define URI_ID_0x22_STRING "urn:epc:\0"
+#define URI_ID_0x23_STRING "urn:nfc:\0"
+
+// exported variables
+extern uint8_t NDEF_Buffer[NDEF_MAX_SIZE];
+extern uint32_t NDEF_Buffer_size;
+extern uint8_t NDEF_Record_Buffer [NDEF_RECORD_MAX_SIZE];
+extern uint32_t NDEF_Record_Buffer_size;
+
+typedef enum
+{
+ UNKNOWN_TYPE = 0,
+ VCARD_TYPE,
+ WELL_KNOWN_ABRIDGED_URI_TYPE,
+ URI_SMS_TYPE,
+ URI_GEO_TYPE,
+ URI_EMAIL_TYPE,
+ SMARTPOSTER_TYPE,
+ URL_TYPE,
+ TEXT_TYPE,
+ HANDOVER_TYPE,
+ /* list of "external type" known by this demo, other external type will be addressed as UNKNWON_TYPE */
+ M24SR_DISCOVERY_APP_TYPE,
+ BT_TYPE,
+ BLE_TYPE,
+ URI_WIFITOKEN_TYPE
+} NDEF_TypeDef;
+
+typedef struct sRecordInfo sRecordInfo_t;
+
+struct sRecordInfo
+{
+ uint8_t RecordFlags;
+ uint8_t TypeLength;
+ uint32_t PayloadLength;
+ uint8_t IDLength;
+ uint8_t Type[20];
+ uint8_t ID[20];
+ uint16_t PayloadOffset;
+ uint8_t* PayloadBufferAdd; /* add where payload content has been stored */
+ NDEF_TypeDef NDEF_Type; /* to store identification ID for application */
+ sRecordInfo_t *SPRecordStructAdd[SP_MAX_RECORD]; /*in case of smart poster array to store add of other sRecordInfo struct */
+ uint8_t NbOfRecordInSPPayload;
+};
+
+uint16_t NDEF_IdentifyNDEF( sRecordInfo_t *pRecordStruct, uint8_t* pNDEF, I2C* mi2cChannel );
+uint16_t NDEF_IdentifyBuffer( sRecordInfo_t *pRecordStruct, uint8_t* pNDEF );
+uint16_t NDEF_ReadNDEF( uint8_t *pNDEF, I2C* mi2cChannel );
+uint16_t NDEF_WriteNDEF( uint16_t NDEF_Size, uint8_t *pNDEF, I2C* mi2cChannel );
+uint16_t NDEF_ClearNDEF(I2C* mi2cChannel);
+uint16_t NDEF_getNDEFSize(uint16_t* Size, I2C* mi2cChannel);
+uint32_t NDEF_WriteRecord( sRecordInfo_t *pRecord, uint8_t* pNDEF, I2C* mi2cChannel );
+uint16_t NDEF_AppendRecord(sRecordInfo_t *Record, I2C* mi2cChannel );
+uint32_t NDEF_GetRecordLength( sRecordInfo_t *pRecord );
+
+#endif /* __LIB_NDEF_H */
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_AAR.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,133 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_AAR.c
+ * @author MMY Application Team
+ * @version $Revision: 3210 $
+ * @date $Date: 2016-12-05 15:37:48 +0100 (Mon, 05 Dec 2016) $
+ * @brief This file help to add AAR to NDEF file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_AAR.h"
+
+/** @addtogroup NFC_libraries
+ * @{
+ * @brief <b>This is the library used to manage the content of the TAG (data)
+ * But also the specific feature of the tag, for instance
+ * password, gpo... </b>
+ */
+
+
+/** @addtogroup libNFC_FORUM
+ * @{
+ * @brief This part of the library manage data which follow NFC forum organisation.
+ */
+
+/**
+ * @brief This buffer contains the data send/received by TAG
+ */
+extern uint8_t NDEF_Buffer [];
+
+/** @defgroup libAAR_Private_Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup libAAR_Public_Functions
+ * @{
+ * @brief This file is used to manage AAR (stored or loaded in tag)
+ */
+
+
+/**
+ * @brief This function add AAR (Android Application Record) in the tag.
+ * @param pAARStruct : pointer on structure that contain AAR information.
+ * @retval NDEF_OK : AAR added.
+ * @retval NDEF_ERROR : not able to store NDEF in tag.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+ * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+ */
+uint16_t NDEF_AddAAR( const sAARInfo *pAARStruct, I2C* mi2cChannel )
+{
+ uint16_t status = NDEF_ERROR;
+
+/* AAR: External Type Record Header */
+/************************************/
+/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
+/*----------------------------------*/
+/* MB ME CF SR IL TNF */ /* <---- IL=0, CF=0 and SR=1 TNF=4 NFC Forum external type*/
+/*----------------------------------*/
+/* TYPE LENGTH */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 3 */ /* <---- Not Used */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 2 */ /* <---- Not Used */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 1 */ /* <---- Not Used */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 0 */
+/*----------------------------------*/
+/* ID LENGTH */ /* <---- Not Used */
+/*----------------------------------*/
+/* TYPE */ /* android.com:pkg */
+/*----------------------------------*/
+/* ID */ /* <---- Not Used */
+/************************************/
+
+ /* Do we have to add AAR to an existing NDEF message */
+ /* retrieve current NDEF size and current record flag*/
+ sRecordInfo_t AARrecord;
+
+ /* fill AAR record header */
+ AARrecord.RecordFlags = SR_Mask | TNF_NFCForumExternal;
+ AARrecord.TypeLength = AAR_TYPE_STRING_LENGTH;
+
+ memcpy( AARrecord.Type, AAR_TYPE_STRING, AAR_TYPE_STRING_LENGTH );
+
+ /* fill AAR payload */
+ AARrecord.PayloadBufferAdd = (uint8_t*)pAARStruct->PackageName;
+ AARrecord.PayloadLength= strlen(pAARStruct->PackageName) ;
+
+ status = NDEF_AppendRecord(&AARrecord, mi2cChannel);
+
+ return status;
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_AAR.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,49 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_AAR.h
+ * @author MMY Application Team
+ * @version $Revision: 3210 $
+ * @date $Date: 2016-12-05 15:37:48 +0100 (Mon, 05 Dec 2016) $
+ * @brief This file help to manage AAR.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_AAR_H
+#define __LIB_NDEF_AAR_H
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+typedef struct
+{
+ char PackageName[80];
+}sAARInfo;
+
+uint16_t NDEF_AddAAR( const sAARInfo *pAARStruct, I2C* mi2cChannel );
+
+
+
+#endif /* __LIB_NDEF_AAR_H */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Bluetooth.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,554 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Bluetooth.c
+ * @author MMY Application Team
+ * @version $Revision: 2702 $
+ * @date $Date: 2016-07-13 18:45:05 +0200 (Wed, 13 Jul 2016) $
+ * @ingroup LibNDEF_Bluetooth
+ * @brief This file help to manage a NDEF file representing a Bluetooth pairing info.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_Bluetooth.h"
+
+
+
+/** @addtogroup lib_NDEF_Bluetooth Bluetooth OOB library
+ * @ingroup libNDEF
+ * @{
+ * @brief This module is used to manage a Bluetooth Out-Of-Band NDEF message, to start a communication based on Bluetooth.
+ * @details The Bluetooth OOB format is described by the Bluetooth v4.0 core specification.
+ * It consists in a list of Extended Inquiry Responses formated as length-type-value.
+ * This module allows to build, write & read such data embedded in a NDEF message.
+ * @section Bluetooth_Library_Usage Bluetooth NDEF Library usage
+ * @subsection Bluetooth_Write_BrEdr How to write a Bluetooth Br/Edr OOB
+ * 1. Instanciate & initialize a `Ndef_Bluetooth_OOB_t` structure, specifying:
+ * - the `NDEF_BLUETOOTH_BREDR` type.
+ * - the mandatory Device Address field.
+ * - any other optional EIRs.
+ *
+ * Ndef_Bluetooth_OOB_t w_bredr_oob = { .Type = NDEF_BLUETOOTH_BREDR,
+ * .DeviceAddress = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
+ * .OptionalMask = NDEF_BLUETOOTH_OPTION(BLUETOOTH_EIR_COMPLETE_LOCAL_NAME) |
+ * NDEF_BLUETOOTH_OPTION(BLUETOOTH_EIR_DEVICE_CLASS) |
+ * NDEF_BLUETOOTH_OPTION(BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_16),
+ * .LocalName = "MyDevice",
+ * .nbUUID16 = 2,
+ * .ClassUUID16 = {0x111E,0x110B},
+ * .DeviceClass = {0x04,0x04,0x20}
+ * };
+ * 2. Clear the NDEF message and call the `NDEF_AppendBluetoothOOB` function to write the OOB:
+ *
+ * NDEF_ClearNDEF();
+ * NDEF_AppendBluetoothOOB ( &w_bredr_oob, NULL );
+ * @note Second parameter of `NDEF_AppendBluetoothOOB` can be used to specify an ID for the OOB record (useful for the NDEF Handover message, where specifying an ID is mandatory)
+ * @subsection Bluetooth_Write_Ble How to write a Bluetooth LE OOB
+ * 1. Instanciate & initialize a `Ndef_Bluetooth_OOB_t` structure, specifying:
+ * - the `NDEF_BLUETOOTH_BLE` type.
+ * - the mandatory Device Address & LE Role fields.
+ * - any other optional EIRs.
+ *
+ * Ndef_Bluetooth_OOB_t w_ble_oob = { .Type = NDEF_BLUETOOTH_BLE,
+ * .DeviceAddress = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
+ * .DeviceAddressType = NDEF_BLE_PUBLIC_ADDRESS_TYPE,
+ * .Role = NDEF_BLE_ROLE_PERIPH_ONLY,
+ * .OptionalMask = NDEF_BLUETOOTH_OPTION(BLUETOOTH_EIR_COMPLETE_LOCAL_NAME),
+ * .LocalName = "MyDeviceName",
+ * };
+ *
+ * 2. Clear the NDEF message and call the `NDEF_AppendBluetoothOOB` function to write the OOB:
+ *
+ * NDEF_ClearNDEF();
+ * NDEF_AppendBluetoothOOB ( &w_ble_oob, NULL );
+ * @note Second parameter of `NDEF_AppendBluetoothOOB` can be used to specify an ID for the OOB record (useful for the NDEF Handover message, where specifying an ID is mandatory)
+ *
+ * @subsection Bluetooth_Read How to read a Bluetooth OOB
+ * 1. Read the 1st record of the NDEF message:
+ *
+ * sRecordInfo_t record;
+ * NDEF_ReadNDEF(NDEF_Buffer);
+ * NDEF_IdentifyBuffer(record,NDEF_Buffer);
+ * 2. Decode the Bluetooth OOB:
+ *
+ * Ndef_Bluetooth_OOB_t bluetooth_oob;
+ * NDEF_ReadBluetoothOOB(&record,&bluetooth_oob);
+ * 3. Use the data from the `Ndef_Bluetooth_OOB_t` structure to start a Bluetooth connexion.
+ *
+ *
+ *
+ */
+
+
+/**
+ * @brief This function copies an array, changing its endianness, usefull to convert data to BLE endianess.
+ * @param dst Pointer on 1st element of the destination array.
+ * @param src pointer on 1st element of the source array .
+ * @param length Number of element to copy.
+ * @return Pointer to the destination array.
+ */
+uint8_t* NDEF_BluetoothCopy(uint8_t* dst, uint8_t* src, uint32_t length)
+{
+ uint32_t index;
+ for(index = 0 ; index < length; index++)
+ {
+ dst[index] = src[length - index - 1];
+ }
+ return dst;
+}
+
+/**
+ * @brief This function reads a NDEF record and retrieves Bluetooth (BR/EDR or BLE) OOB information if present.
+ * @param pRecord Pointer on the record structure.
+ * @param pBluetooth Pointer on the structure to fill .
+ * @retval NDEF_OK OOB information has been retrieved from the NDEF record.
+ * @retval NDEF_ERROR OOB information cannot be retrieved.
+ */
+uint16_t NDEF_ReadBluetoothOOB( sRecordInfo_t *pRecord, Ndef_Bluetooth_OOB_t *pBluetooth )
+{
+ uint8_t* pData = pRecord->PayloadBufferAdd;
+ uint8_t* OOBEnd = pRecord->PayloadBufferAdd + pRecord->PayloadLength;
+
+ pBluetooth->OptionalMask = 0;
+ pBluetooth->nbServiceData = 0;
+ pBluetooth->Role = NDEF_BLE_ROLE_UNDEF;
+ pBluetooth->DeviceAddressType = NDEF_BLE_UNDEF_ADDRESS_TYPE;
+ pBluetooth->nbUUID16 = 0;
+ pBluetooth->nbUUID32 = 0;
+ pBluetooth->nbUUID128 = 0;
+ pBluetooth->nbServiceSolicitation16 = 0;
+ pBluetooth->nbServiceSolicitation128 = 0;
+
+ if((pRecord->TypeLength == strlen(NDEF_BLUETOOTH_BREDR_MIME_TYPE)) &&
+ !memcmp(pRecord->Type,NDEF_BLUETOOTH_BREDR_MIME_TYPE,strlen(NDEF_BLUETOOTH_BREDR_MIME_TYPE)))
+ {
+ pBluetooth->Type = NDEF_BLUETOOTH_BREDR;
+ /* Retrieve mandatory OOB data: */
+ /* 2 bytes for length and 6 bytes for device addr */
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->DeviceAddress,&pData[2],sizeof(pBluetooth->DeviceAddress));
+ pData += 8;
+ } else if ((pRecord->TypeLength == strlen(NDEF_BLUETOOTH_BLE_MIME_TYPE)) &&
+ !memcmp(pRecord->Type,NDEF_BLUETOOTH_BLE_MIME_TYPE,strlen(NDEF_BLUETOOTH_BLE_MIME_TYPE)))
+ {
+ pBluetooth->Type = NDEF_BLUETOOTH_BLE;
+ /* for BLE, mandatory fields are in EIR */
+ } else {
+ /* This is an unknown MIME type */
+ return NDEF_ERROR;
+ }
+
+ /* EIR format: 1 byte for length, 1 byte for type, n bytes for data */
+ while (pData < OOBEnd)
+ {
+ NDEF_EIR_t* rEIR = (NDEF_EIR_t*)pData;
+ /* +1 for EIR length byte */
+ pData += rEIR->length + 1;
+
+ /* keep track of all EIR found */
+ if(rEIR->type < 0x20)
+ NDEF_BLUETOOTH_SET_OPTIONAL_MASK(pBluetooth,rEIR->type);
+
+ switch (rEIR->type)
+ {
+ case BLUETOOTH_EIR_FLAGS:
+ pBluetooth->Flags = *rEIR->value;
+ break;
+
+ case BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_16:
+ case BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_16:
+ pBluetooth->nbUUID16 = (rEIR->length - 1) / 2 ;
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->ClassUUID16,rEIR->value,rEIR->length-1);
+ break;
+
+ case BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_32:
+ case BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_32:
+ pBluetooth->nbUUID32 = (rEIR->length - 1) / 4 ;
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->ClassUUID32,rEIR->value,rEIR->length-1);
+ break;
+
+ case BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_128:
+ case BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_128:
+ pBluetooth->nbUUID128 = (rEIR->length - 1) / 16 ;
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->ClassUUID128,rEIR->value,rEIR->length-1);
+ break;
+
+ case BLUETOOTH_EIR_SHORT_LOCAL_NAME:
+ case BLUETOOTH_EIR_COMPLETE_LOCAL_NAME:
+ /* No worry about name length as max EIR length is 0xff using 1 byte for the type metadata */
+ memcpy(pBluetooth->LocalName,rEIR->value,rEIR->length-1);
+ pBluetooth->LocalName[rEIR->length] = '\0';
+ break;
+
+ case BLUETOOTH_EIR_TX_POWER_LEVEL:
+ pBluetooth->TxPowerLevel = *rEIR->value;
+ break;
+
+ case BLUETOOTH_EIR_DEVICE_CLASS:
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->DeviceClass,rEIR->value,sizeof(pBluetooth->DeviceClass));
+ break;
+
+ case BLUETOOTH_EIR_SIMPLE_PAIRING_HASH:
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->SimplePairingHash,rEIR->value,sizeof(pBluetooth->SimplePairingHash));
+ break;
+
+ case BLUETOOTH_EIR_SIMPLE_PAIRING_RANDOMIZER:
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->SimplePairingRandomizer,rEIR->value,sizeof(pBluetooth->SimplePairingRandomizer));
+ break;
+
+ case BLUETOOTH_EIR_SECURITY_MANAGER_TK_VALUE:
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->SecureManagerTK,rEIR->value,sizeof(pBluetooth->SecureManagerTK));
+ break;
+
+ case BLUETOOTH_EIR_SECURITY_MANAGER_FLAGS:
+ pBluetooth->SMFlags = *rEIR->value;
+ break;
+
+ case BLUETOOTH_EIR_SLAVE_CONNECTION_INTERVAL_RANGE:
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->SlaveConnIntervalRange,rEIR->value,sizeof(pBluetooth->SlaveConnIntervalRange));
+ break;
+
+ case BLUETOOTH_EIR_SERVICE_SOLICITATION_16:
+ pBluetooth->nbServiceSolicitation16 = (rEIR->length - 1) / 2 ;
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->ServiceSolicitation16,rEIR->value,rEIR->length-1);
+ break;
+
+ case BLUETOOTH_EIR_SERVICE_SOLICITATION_128:
+ pBluetooth->nbServiceSolicitation128 = (rEIR->length - 1) / 16 ;
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->ServiceSolicitation128,rEIR->value,rEIR->length-1);
+ break;
+
+ case BLUETOOTH_EIR_SERVICE_DATA:
+ /* a specific function should be used for this EIR */
+ pBluetooth->nbServiceData++;
+ break;
+
+ case BLUETOOTH_EIR_MANUFACTURER_DATA:
+ /* a specific function should be used for this EIR */
+ pBluetooth->nbManufacturerData++;
+ break;
+
+ case BLUETOOTH_EIR_APPEARANCE:
+ pBluetooth->Appearance = *(uint16_t *)rEIR->value;
+ break;
+
+ case BLUETOOTH_EIR_BLE_DEVICE_ADDRESS:
+ NDEF_BluetoothCopy((uint8_t*)pBluetooth->DeviceAddress,rEIR->value,sizeof(pBluetooth->DeviceAddress));
+ pBluetooth->DeviceAddressType = (Ndef_BLE_Address_Type_t)rEIR->value[sizeof(pBluetooth->DeviceAddress)];
+ break;
+
+ case BLUETOOTH_EIR_BLE_ROLE:
+ pBluetooth->Role = (Ndef_BLE_Role_t) *rEIR->value;
+ break;
+
+ default:
+ pBluetooth->nbUnknown++;
+ break;
+ } /* switch rEIR->type */
+ } /* while (pData < OOBEnd) */
+ /* Check that BLE mandatory fields are there */
+ if((pBluetooth->Type == NDEF_BLUETOOTH_BLE) &&
+ (!NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_BLE_DEVICE_ADDRESS) ||
+ !NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_BLE_ROLE)))
+ return NDEF_ERROR;
+
+ return NDEF_OK;
+}
+
+/**
+ * @brief This function appends a Bluetooth OOB record to the NDEF message, using the OOB data given in the input structure.
+ * @param pBluetooth Pointer on a `Ndef_Bluetooth_OOB_t` structure containing the OOB information.
+ * @param RecordID ID to be used for this record (required for Handover case, can be set to NULL in other cases).
+ * @retval NDEF_OK The Bluetooth OOB record has been appended.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL The Bluetooth OOB record cannot be appended due to memory size limitation.
+ * @retval NDEF_ERROR The Bluetooth OOB record cannot be appended.
+ */
+uint16_t NDEF_AppendBluetoothOOB( Ndef_Bluetooth_OOB_t *pBluetooth, char* RecordID, I2C* mi2cChannel )
+{
+ sRecordInfo_t Record;
+ uint16_t status;
+
+ Record.RecordFlags = TNF_MediaType;
+ Record.RecordFlags |= (RecordID != NULL) ? IL_Mask : 0;
+ Record.IDLength = strlen(RecordID);
+ memcpy(Record.ID,RecordID,Record.IDLength);
+
+ if(pBluetooth->Type == NDEF_BLUETOOTH_BREDR)
+ {
+ Record.TypeLength = strlen(NDEF_BLUETOOTH_BREDR_MIME_TYPE);
+ memcpy(Record.Type, NDEF_BLUETOOTH_BREDR_MIME_TYPE, Record.TypeLength);
+ }
+ else if (pBluetooth->Type == NDEF_BLUETOOTH_BLE)
+ {
+ Record.TypeLength = strlen(NDEF_BLUETOOTH_BLE_MIME_TYPE);
+ memcpy(Record.Type, NDEF_BLUETOOTH_BLE_MIME_TYPE, Record.TypeLength);
+ }
+ else
+ {
+ return NDEF_ERROR;
+ }
+
+ /* Generate OOB payload */
+ Record.PayloadLength = NDEF_GetBluetoothOOBLength(pBluetooth);
+ Record.PayloadBufferAdd = NDEF_Record_Buffer;
+ if(Record.PayloadLength > NDEF_RECORD_MAX_SIZE)
+ return NDEF_ERROR_MEMORY_INTERNAL;
+
+ /* pData: pointer to ease increment of record buffer address (byte granularity) */
+ uint8_t* pData = Record.PayloadBufferAdd;
+
+ /* for BR-EDR Device address & length are managed outside EIR */
+ if(pBluetooth->Type == NDEF_BLUETOOTH_BREDR)
+ {
+ *pData = Record.PayloadLength;
+ pData += 2;
+ NDEF_BluetoothCopy(pData,(uint8_t*)pBluetooth->DeviceAddress,sizeof(pBluetooth->DeviceAddress));
+ pData+=sizeof(pBluetooth->DeviceAddress);
+ }
+
+ /* wEIR: pointer to ease write to the buffer.
+ * length always set with an additional +1 corresponding to the EIR type byte.
+ * pData increment is always done with an additional +1 corresponding to the EIR length byte.
+ */
+ NDEF_EIR_t* wEIR;
+
+
+ if(pBluetooth->Type == NDEF_BLUETOOTH_BLE)
+ {
+ /* following EIR are mandatory for BLE */
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = sizeof(pBluetooth->DeviceAddress) + sizeof(pBluetooth->DeviceAddressType) + 1;
+ wEIR->type = BLUETOOTH_EIR_BLE_DEVICE_ADDRESS;
+ NDEF_BluetoothCopy(wEIR->value, (uint8_t*)pBluetooth->DeviceAddress,sizeof(pBluetooth->DeviceAddress));
+ wEIR->value[sizeof(pBluetooth->DeviceAddress)] = pBluetooth->DeviceAddressType;
+ pData += wEIR->length + 1;
+
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = sizeof(pBluetooth->Role) + 1;
+ wEIR->type = BLUETOOTH_EIR_BLE_ROLE;
+ wEIR->value[0] = pBluetooth->Role;
+ pData += wEIR->length + 1;
+
+ }
+
+ /* Rely on the optional mask to know if a EIR is required or not */
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_FLAGS))
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = sizeof(pBluetooth->Flags) + 1;
+ wEIR->type = BLUETOOTH_EIR_FLAGS;
+ wEIR->value[0] = pBluetooth->Flags;
+ pData += wEIR->length + 1;
+ }
+
+ if(pBluetooth->nbUUID16 > 0)
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = 2 * pBluetooth->nbUUID16 + 1;
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_16))
+ wEIR->type = BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_16;
+ else
+ wEIR->type = BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_16;
+ NDEF_BluetoothCopy(wEIR->value, (uint8_t*) pBluetooth->ClassUUID16, 2 * pBluetooth->nbUUID16);
+ pData += wEIR->length + 1;
+
+ }
+
+ if(pBluetooth->nbUUID32 > 0)
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = 4 * pBluetooth->nbUUID32 + 1;
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_32))
+ wEIR->type = BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_32;
+ else
+ wEIR->type = BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_32;
+ NDEF_BluetoothCopy(wEIR->value, (uint8_t*)pBluetooth->ClassUUID32, 4 * pBluetooth->nbUUID32);
+ pData += wEIR->length + 1;
+
+ }
+
+ if(pBluetooth->nbUUID128 > 0)
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = 16 * pBluetooth->nbUUID128 + 1;
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_128))
+ wEIR->type = BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_128;
+ else
+ wEIR->type = BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_128;
+ NDEF_BluetoothCopy(wEIR->value, (uint8_t*) pBluetooth->ClassUUID128, 16 * pBluetooth->nbUUID128);
+ pData += wEIR->length + 1;
+
+ }
+
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SHORT_LOCAL_NAME) ||
+ NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_COMPLETE_LOCAL_NAME))
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = strlen(pBluetooth->LocalName) + 1;
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SHORT_LOCAL_NAME))
+ wEIR->type = BLUETOOTH_EIR_SHORT_LOCAL_NAME;
+ else
+ wEIR->type = BLUETOOTH_EIR_COMPLETE_LOCAL_NAME;
+ memcpy(wEIR->value, pBluetooth->LocalName,strlen(pBluetooth->LocalName));
+ pData += wEIR->length + 1;
+
+ }
+
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_TX_POWER_LEVEL))
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = sizeof(pBluetooth->TxPowerLevel) + 1;
+ wEIR->type = BLUETOOTH_EIR_TX_POWER_LEVEL;
+ wEIR->value[0] = pBluetooth->TxPowerLevel;
+ pData += wEIR->length + 1;
+ }
+
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_DEVICE_CLASS))
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = sizeof(pBluetooth->DeviceClass) + 1;
+ wEIR->type = BLUETOOTH_EIR_DEVICE_CLASS;
+ NDEF_BluetoothCopy(wEIR->value, pBluetooth->DeviceClass,sizeof(pBluetooth->DeviceClass));
+ pData += wEIR->length + 1;
+
+ }
+
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SIMPLE_PAIRING_HASH))
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = sizeof(pBluetooth->SimplePairingHash) + 1;
+ wEIR->type = BLUETOOTH_EIR_SIMPLE_PAIRING_HASH;
+ NDEF_BluetoothCopy(wEIR->value, pBluetooth->SimplePairingHash,sizeof(pBluetooth->SimplePairingHash));
+ pData += wEIR->length + 1;
+
+ }
+
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SIMPLE_PAIRING_RANDOMIZER))
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = sizeof(pBluetooth->SimplePairingRandomizer) + 1;
+ wEIR->type = BLUETOOTH_EIR_SIMPLE_PAIRING_RANDOMIZER;
+ NDEF_BluetoothCopy(wEIR->value, pBluetooth->SimplePairingRandomizer,sizeof(pBluetooth->SimplePairingRandomizer));
+ pData += wEIR->length + 1;
+
+ }
+
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SECURITY_MANAGER_TK_VALUE))
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = sizeof(pBluetooth->SecureManagerTK) + 1;
+ wEIR->type = BLUETOOTH_EIR_SECURITY_MANAGER_TK_VALUE;
+ NDEF_BluetoothCopy(wEIR->value, pBluetooth->SecureManagerTK,sizeof(pBluetooth->SecureManagerTK));
+ pData += wEIR->length + 1;
+
+ }
+
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SECURITY_MANAGER_FLAGS))
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = sizeof(pBluetooth->SMFlags) + 1;
+ wEIR->type = BLUETOOTH_EIR_SECURITY_MANAGER_FLAGS;
+ wEIR->value[0] = pBluetooth->SMFlags;
+ pData += wEIR->length + 1;
+
+ }
+
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SLAVE_CONNECTION_INTERVAL_RANGE))
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = sizeof(pBluetooth->SlaveConnIntervalRange) + 1;
+ wEIR->type = BLUETOOTH_EIR_SLAVE_CONNECTION_INTERVAL_RANGE;
+ NDEF_BluetoothCopy(wEIR->value, (uint8_t*)pBluetooth->SlaveConnIntervalRange,sizeof(pBluetooth->SlaveConnIntervalRange));
+ pData += wEIR->length + 1;
+
+ }
+
+ if(pBluetooth->nbServiceSolicitation16 > 0)
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = 2 * pBluetooth->nbServiceSolicitation16 + 1;
+ wEIR->type = BLUETOOTH_EIR_SERVICE_SOLICITATION_16;
+ NDEF_BluetoothCopy(wEIR->value, (uint8_t*)pBluetooth->ServiceSolicitation16, 16 * pBluetooth->nbServiceSolicitation16);
+ pData += wEIR->length + 1;
+
+ }
+
+ if(pBluetooth->nbServiceSolicitation128 > 0)
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = 16 * pBluetooth->nbServiceSolicitation128 + 1;
+ wEIR->type = BLUETOOTH_EIR_SERVICE_SOLICITATION_128;
+ NDEF_BluetoothCopy(wEIR->value, (uint8_t*) pBluetooth->ServiceSolicitation128, 16 * pBluetooth->nbServiceSolicitation128);
+ pData += wEIR->length + 1;
+
+ }
+
+ if(NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_APPEARANCE))
+ {
+ wEIR = (NDEF_EIR_t*)pData;
+ wEIR->length = sizeof(pBluetooth->Appearance) + 1;
+ wEIR->type = BLUETOOTH_EIR_APPEARANCE;
+ wEIR->value[0] = pBluetooth->Appearance;
+ pData += wEIR->length + 1;
+
+ }
+
+
+ status = NDEF_AppendRecord(&Record, mi2cChannel);
+ if(status != NDEF_OK) return status;
+
+ return NDEF_OK;
+}
+
+/**
+ * @brief This function computeS the payload size for the OOB, using the data given in the input `Ndef_Bluetooth_OOB_t` structure.
+ * @param pBluetooth Pointer on a `Ndef_Bluetooth_OOB_t` structure containing the OOB information.
+ * @return Computed length in bytes.
+ */
+uint32_t NDEF_GetBluetoothOOBLength( Ndef_Bluetooth_OOB_t *pBluetooth )
+{
+ uint32_t length = (pBluetooth->Type == NDEF_BLUETOOTH_BREDR) ? sizeof(pBluetooth->DeviceAddress) + 2 : 0; // +2 is for BR/EDR mandatory length
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_FLAGS)? sizeof(pBluetooth->Flags) + 2 : 0 ;
+ length += pBluetooth->nbUUID16 ? pBluetooth->nbUUID16 * 2 + 2 : 0;
+ length += pBluetooth->nbUUID32 ? pBluetooth->nbUUID32 * 4 + 2 : 0;
+ length += pBluetooth->nbUUID128 ? pBluetooth->nbUUID128 * 16 + 2 : 0;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SHORT_LOCAL_NAME)? strlen(pBluetooth->LocalName) + 2 : 0 ;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_COMPLETE_LOCAL_NAME)? strlen(pBluetooth->LocalName) + 2 : 0 ;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_TX_POWER_LEVEL)? sizeof(pBluetooth->TxPowerLevel + 2) : 0 ;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_DEVICE_CLASS)? sizeof(pBluetooth->DeviceClass) + 2 : 0 ;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SIMPLE_PAIRING_HASH)? sizeof(pBluetooth->SimplePairingHash) + 2 : 0 ;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SIMPLE_PAIRING_RANDOMIZER)? sizeof(pBluetooth->SimplePairingRandomizer) + 2 : 0 ;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SECURITY_MANAGER_TK_VALUE)? sizeof(pBluetooth->SecureManagerTK) + 2 : 0 ;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SECURITY_MANAGER_FLAGS)? sizeof(pBluetooth->SMFlags) + 2 : 0 ;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SLAVE_CONNECTION_INTERVAL_RANGE)? sizeof(pBluetooth->SlaveConnIntervalRange) + 2 : 0 ;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SERVICE_SOLICITATION_16)? pBluetooth->nbServiceSolicitation16 * 2 + 2 : 0 ;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_SERVICE_SOLICITATION_128)? pBluetooth->nbServiceSolicitation128 * 16 + 2 : 0 ;
+ length += NDEF_BLUETOOTH_GET_OPTIONAL_MASK(pBluetooth,BLUETOOTH_EIR_APPEARANCE)? sizeof(pBluetooth->Appearance) + 2 : 0 ;
+ length += (pBluetooth->Type == NDEF_BLUETOOTH_BLE)? sizeof(pBluetooth->DeviceAddress) + sizeof(pBluetooth->DeviceAddressType) + 2 : 0 ;
+ length += (pBluetooth->Type == NDEF_BLUETOOTH_BLE)? sizeof(pBluetooth->Role) + 2 : 0;
+
+ return length;
+}
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Bluetooth.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,204 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Bluetooth.h
+ * @author MMY Application Team
+ * @version $Revision: 2475 $
+ * @date $Date: 2016-06-24 12:11:59 +0200 (Fri, 24 Jun 2016) $
+ * @brief This file help to manage a NDEF file representing a Bluetooth pairing info.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_BLUETOOTH_H
+#define __LIB_NDEF_BLUETOOTH_H
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+/** @addtogroup lib_NDEF_Bluetooth
+ * @{
+ */
+
+/** @brief MIME type for the Bluetooth BR/EDR Out-Of-Band data. */
+#define NDEF_BLUETOOTH_BREDR_MIME_TYPE "application/vnd.bluetooth.ep.oob"
+/** @brief MIME type for the Bluetooth Low Energy Out-Of-Band data. */
+#define NDEF_BLUETOOTH_BLE_MIME_TYPE "application/vnd.bluetooth.le.oob"
+
+
+/** @brief Enumerates the Extended Inquiry Responses, as defined in the Bluetooth v4.0 core specification. */
+typedef enum {
+ BLUETOOTH_EIR_FLAGS = 0x01, /**< Bluetooth flags:\n
+ b0: LE limited Discoverable Mode,\n
+ b1: LE general Discoverable Mode,\n
+ b2: BR/EDR not supported,\n
+ b3: Simultaneous LE & BR/EDR Conroller,\n
+ b4: Simultaneous LE & BR/EDR Host
+ */
+ BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_16 = 0x02, /**< Bluetooth service UUID on 16-bits (partial list) */
+ BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_16 = 0x03, /**< Bluetooth service UUID on 16-bits (complete list) */
+ BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_32 = 0x04, /**< Bluetooth service UUID on 32-bits (partial list) */
+ BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_32 = 0x05, /**< Bluetooth service UUID on 32-bits (complete list) */
+ BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_128 = 0x06, /**< Bluetooth service UUID on 128-bits (partial list) */
+ BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_128 = 0x07, /**< Bluetooth service UUID on 128-bits (complete list) */
+ BLUETOOTH_EIR_SHORT_LOCAL_NAME = 0x08, /**< Shortened local name */
+ BLUETOOTH_EIR_COMPLETE_LOCAL_NAME = 0x09, /**< Complete local name */
+ BLUETOOTH_EIR_TX_POWER_LEVEL = 0x0A, /**< TX Power Level (1 byte): 0xXX:-127 to +127dBm */
+ BLUETOOTH_EIR_DEVICE_CLASS = 0x0D, /**< Class of device, Format defined in Assigned Numbers */
+ BLUETOOTH_EIR_SIMPLE_PAIRING_HASH = 0x0E, /**< Simple Pairing Hash C (16 octets), Format defined in [Vol. 2], Part H Section 7.2.2*/
+ BLUETOOTH_EIR_SIMPLE_PAIRING_RANDOMIZER = 0x0F, /**< Simple Pairing Randomizer R (16 octets), Format defined in[Vol. 2], Part H Section 7.2.2 */
+ BLUETOOTH_EIR_SECURITY_MANAGER_TK_VALUE = 0x10, /**< TK Value: Value as used in pairing over LE Physical channel. Format defined in [Vol. 3], Part H Section 2.3*/
+ BLUETOOTH_EIR_SECURITY_MANAGER_FLAGS = 0x11, /**< Flags (1 octet):\n
+ b0: OOB Flags Field (0 = OOB data not present, 1 = OOB data present),\n
+ b1: LE supported (Host) (i.e. bit 65 of LMP Extended Feature bits Page 1),\n
+ b2: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)\n
+ b3: Address type (0 = Public Address, 1 = Random Address)
+ */
+ BLUETOOTH_EIR_SLAVE_CONNECTION_INTERVAL_RANGE = 0x12, /**< Slave Connection Interval Range: The first 2 octets defines the minimum value for the connection interval, The second 2 octets defines the maximum value for the connection interval */
+ BLUETOOTH_EIR_SERVICE_SOLICITATION_16 = 0x14, /**< Service UUIDs: List of 16 bit Service UUIDs*/
+ BLUETOOTH_EIR_SERVICE_SOLICITATION_128 = 0x15, /**< Service UUIDs: List of 128 bit Service UUID*/
+ BLUETOOTH_EIR_SERVICE_DATA = 0x16, /**< Service Data (2 or more octets): The first 2 octets contain the 16 bit Service UUID followed by additional service data */
+ BLUETOOTH_EIR_APPEARANCE = 0x19, /**< UUID for `Appearance`: The Appearance characteristic value shall be the enumerated value as defined by Bluetooth Assigned Numbers document. */
+ BLUETOOTH_EIR_BLE_DEVICE_ADDRESS = 0x1B, /**< 6 LSB bytes: Device address, 7th byte: Address type (Public/Random) */
+ BLUETOOTH_EIR_BLE_ROLE = 0x1C, /**< Device Role: Periph only, Central only, Periph prefered, Central prefered */
+ BLUETOOTH_EIR_MANUFACTURER_DATA = 0xFF /**< Manufacturer Specific Data (2 or more octets): The first 2 octets contain the Company Identifier Code followed by additional manufacturer specific data */
+} Ndef_Bluetooth_Eir_Types_t;
+
+
+/** @brief Bluetooth Flag field: LE limited discovery. */
+#define NDEF_BLE_LIMITED_DISCOVERY_FLAG (0x1)
+/** @brief Bluetooth Flag field: LE general discovery. */
+#define NDEF_BLE_GENERAL_DISCOVERY_FLAG (0x2)
+/** @brief Bluetooth Flag field: BR/EDR compliant. */
+#define NDEF_BLE_NOT_BREDR_COMPLIANT_FLAG (0x4)
+/** @brief Bluetooth Flag field: LE & BR/EDR simultaneous support. */
+#define NDEF_BLE_LE_BREDR_SIMULTANEOUS_FLAG (0x8)
+
+/** @brief Enumerates the Bluetooth LE address types. */
+typedef enum {
+ NDEF_BLE_PUBLIC_ADDRESS_TYPE = 0x0, /**< Public Device Address. */
+ NDEF_BLE_RANDOM_ADDRESS_TYPE = 0x1, /**< Random Device Address. */
+ NDEF_BLE_UNDEF_ADDRESS_TYPE = 0xff /**< Device Address is undefined. */
+} Ndef_BLE_Address_Type_t;
+
+/** @brief Enumerates Bluetooth LE Roles */
+typedef enum {
+ NDEF_BLE_ROLE_PERIPH_ONLY = 0x0, /**< Only Peripheral Role supported. */
+ NDEF_BLE_ROLE_CENTRAL_ONLY = 0x1, /**< Only Central Role supported. */
+ NDEF_BLE_ROLE_PERIPH_PREFERRED = 0x2, /**< Peripheral and Central Role supported, Peripheral Role preferred for connection establishment. */
+ NDEF_BLE_ROLE_CENTRAL_PREFERRED = 0x3, /**< Peripheral and Central Role supported, Central Role preferred for connection establishment. */
+ NDEF_BLE_ROLE_UNDEF = 0xff /**< LE Role is undefined. */
+} Ndef_BLE_Role_t;
+
+/** @brief Enumerates Bluetooth protocols */
+typedef enum {
+ NDEF_BLUETOOTH_BREDR, /**< Standard bluetooth */
+ NDEF_BLUETOOTH_BLE /**< Bluetooth Low Energy */
+} Ndef_Bluetooth_type_t;
+
+/** @brief Helper macro to set a particular EIR in the EIR mask of a `Ndef_Bluetooth_OOB_t` instance.
+ * @param bt Pointer to a `Ndef_Bluetooth_OOB_t` struct
+ * @param option Index of the option based on the `Ndef_Bluetooth_Eir_Types_t` */
+#define NDEF_BLUETOOTH_SET_OPTIONAL_MASK(bt,option) do { bt->OptionalMask |= (1<<(option)); } while (0)
+
+/** @brief Helper macro to unset a particular EIR in the EIR mask of a `Ndef_Bluetooth_OOB_t` instance.
+ * @param bt Pointer to a `Ndef_Bluetooth_OOB_t` struct
+ * @param option Index of the option based on the `Ndef_Bluetooth_Eir_Types_t` */
+#define NDEF_BLUETOOTH_UNSET_OPTIONAL_MASK(bt,option) do {bt->OptionalMask &= ~(1<<(option)); } while (0)
+
+/** @brief Helper macro to know if a particular EIR is present in the EIR mask of a `Ndef_Bluetooth_OOB_t` instance.
+ * @param bt Pointer to a `Ndef_Bluetooth_OOB_t` struct
+ * @param option Index of the option based on the `Ndef_Bluetooth_Eir_Types_t` */
+#define NDEF_BLUETOOTH_GET_OPTIONAL_MASK(bt,option) ((bt->OptionalMask & (1<<(option))) >> (option))
+
+/** @brief Helper macro to create a mask for a particular EIR.
+ * @param option Index of the option based on the `Ndef_Bluetooth_Eir_Types_t` */
+#define NDEF_BLUETOOTH_OPTION(option) (1<<(option))
+
+/** @brief Bluetooth Out-Of-Band data structure.
+ * @details Some fields are shared by both Br/Edr & LE Bluetooth, some are specific...
+ * No union used here to comply with the Cube coding guidelines, despite the fact that it could have save memory space.
+ */
+typedef struct
+{
+ /* Mandatory fields */
+ Ndef_Bluetooth_type_t Type; /**< *Mandatory*: Bluetooth type (Br/Edr or LE). */
+ char DeviceAddress[6]; /**< *Mandatory*: Device address. For LE: 6 LSB of Device Address EIR. */
+ /* Optionnal common fields */
+ uint32_t OptionalMask; /**< This Mask is used to keep track of EIRs present in the OOB: each bit index corresponds to a `Ndef_Bluetooth_Eir_Types_t` value. */
+ uint8_t Flags; /**< Flags from BLUETOOTH_EIR_FLAGS. */
+
+ uint16_t ClassUUID16[0xff/2]; /**< UUIDs from BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_16 or BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_16. */
+ uint32_t ClassUUID32[0xff/4]; /**< UUIDs from BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_32 or BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_32. */
+ uint32_t ClassUUID128[0xff/16][4]; /**< UUIDs from BLUETOOTH_EIR_SERVICE_CLASS_UUID_PARTIAL_128 or BLUETOOTH_EIR_SERVICE_CLASS_UUID_COMPLETE_128. */
+ uint8_t nbUUID16; /**< Number of UUIDs speficied in ClassUUID16. */
+ uint8_t nbUUID32; /**< Number of UUIDs speficied in ClassUUID32. */
+ uint8_t nbUUID128; /**< Number of UUIDs speficied in ClassUUID128. */
+
+ char LocalName[0xff]; /**< Device local name from BLUETOOTH_EIR_SHORT_LOCAL_NAME or BLUETOOTH_EIR_COMPLETE_LOCAL_NAME. */
+ uint8_t DeviceClass[3]; /**< Class of device from BLUETOOTH_EIR_DEVICE_CLASS. */
+ // if no TPL, TPL is unknown
+ uint8_t TxPowerLevel; /**< TX power Level from BLUETOOTH_EIR_TX_POWER_LEVEL. */
+
+ uint8_t SMFlags; /**< Security Manager Flags from BLUETOOTH_EIR_SECURITY_MANAGER_FLAGS. */
+ uint16_t SlaveConnIntervalRange[2]; /**< Slave Connection Interval Range from BLUETOOTH_EIR_SLAVE_CONNECTION_INTERVAL_RANGE. */
+ uint16_t ServiceSolicitation16[0xff/2]; /**< Service Solicitation from BLUETOOTH_EIR_SERVICE_SOLICITATION_16. */
+ uint32_t ServiceSolicitation128[0xff/16][4]; /**< Service Solicitation from BLUETOOTH_EIR_SERVICE_SOLICITATION_128. */
+ uint8_t nbServiceSolicitation16; /**< Number of UUIDs in ServiceSolicitation16. */
+ uint8_t nbServiceSolicitation128; /**< Number of UUIDs in ServiceSolicitation128. */
+ /* for br/edr only */
+ uint8_t SimplePairingHash[16]; /**< *For Br/Edr only*: Simple Pairing Hash from BLUETOOTH_EIR_SIMPLE_PAIRING_HASH. */
+ uint8_t SimplePairingRandomizer[16]; /**< *For Br/Edr only*: Simple Pairing Randomizer from BLUETOOTH_EIR_SIMPLE_PAIRING_RANDOMIZER. */
+ /* BLE mandatory fields */
+ Ndef_BLE_Address_Type_t DeviceAddressType; /**< *For LE only*, *Mandatory*: Address Type, MSB of the Device Address EIR (Public or Random) */
+ Ndef_BLE_Role_t Role; /**< *For LE only*, *Mandatory*: LE Role from BLUETOOTH_EIR_BLE_ROLE and defined in `Ndef_BLE_Role_t`. */
+ /* BLE optional fields */
+ uint8_t SecureManagerTK[16]; /**< *For LE only*: Security Manager TK from BLUETOOTH_EIR_SECURITY_MANAGER_TK_VALUE. */
+ uint16_t Appearance; /**< *For LE only*: Appearance from BLUETOOTH_EIR_APPEARANCE. */
+ /* track number of unparsed EIR */
+ uint8_t nbUnknown; /**< Number of EIRs not parsed because of an unknown EIR type. */
+ uint8_t nbServiceData; /**< Number of EIRs not parsed because being of type BLUETOOTH_EIR_SERVICE_DATA. */
+ uint8_t nbManufacturerData; /**< Number of EIRs not parsed because being of type BLUETOOTH_EIR_MANUFACTURER_DATA. */
+} Ndef_Bluetooth_OOB_t ;
+
+/** @brief Extended Inquiry Response format.
+ * @details This structure is used to parse/build EIRs in the Bluetooth OOB.
+ */
+typedef struct {
+ uint8_t length; /**< Length of the EIRs, including the type field (1 byte). */
+ uint8_t type; /**< EIR type as defined in `Ndef_Bluetooth_Eir_Types_t`. */
+ uint8_t value[1]; /**< single-element array, to keep track of the address of the EIR data */
+} NDEF_EIR_t ;
+
+uint16_t NDEF_ReadBluetoothOOB( sRecordInfo_t *pRecordStruct, Ndef_Bluetooth_OOB_t *pBluetooth );
+uint16_t NDEF_AppendBluetoothOOB( Ndef_Bluetooth_OOB_t *pBluetooth, char* RecordID, I2C* mi2cChannel );
+void NDEF_PrepareBluetoothMessage(Ndef_Bluetooth_OOB_t *pBluetooth, uint8_t *pNDEFMessage, uint16_t *size );
+uint32_t NDEF_GetBluetoothOOBLength( Ndef_Bluetooth_OOB_t *pBluetooth );
+
+
+
+/** @}
+ */
+
+#endif /* __LIB_NDEF_BLUETOOTH_H */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Email.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,438 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Email.c
+ * @author MMY Application Team
+ * @version $Revision: 2702 $
+ * @date $Date: 2016-07-13 18:45:05 +0200 (Wed, 13 Jul 2016) $
+ * @brief This file help to manage NDEF file that represent Email.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_Email.h"
+#include "stdlib.h"
+
+/** @addtogroup NFC_libraries
+ * @{
+ * @brief <b>This is the library used to manage the content of the TAG (data)
+ * But also the specific feature of the tag, for instance
+ * password, gpo... </b>
+ */
+
+
+/** @addtogroup libNFC_FORUM
+ * @{
+ * @brief This part of the library manage data which follow NFC forum organisation.
+ */
+
+/**
+ * @brief This buffer contains the data send/received by TAG
+ */
+extern uint8_t NDEF_Buffer [];
+
+
+/** @defgroup libEmail_Private_Functions
+ * @{
+ */
+
+
+static void NDEF_FillEmailStruct( uint8_t* pPayload, uint32_t PayloadSize, sEmailInfo *pEmailStruct );
+static void NDEF_ReadURI_Email( sRecordInfo_t *pRecordStruct, sEmailInfo *pEmailStruct );
+
+/**
+ * @brief This function fill Email structure with information of NDEF message
+ * @param pPayload : pointer on the payload data of the NDEF message
+ * @param PayloadSize : number of data in the payload
+ * @param pEmailStruct : pointer on the structure to fill
+ * @retval NONE
+ */
+static void NDEF_FillEmailStruct( uint8_t* pPayload, uint32_t PayloadSize, sEmailInfo *pEmailStruct )
+{
+ uint8_t* pLastByteAdd, *pLook4Word, *pEndString;
+ uint32_t SizeOfKeyWord = 0;
+
+ pEndString = 0;
+
+ /* First character force to NULL in case not matching found */
+#ifdef NDEF_DYN_ALLOC
+ pEmailStruct->EmailAdd = NULL;
+ pEmailStruct->Subject = NULL;
+ pEmailStruct->Message = NULL;
+ pEmailStruct->Information = NULL;
+#else
+ *pEmailStruct->EmailAdd = 0;
+ *pEmailStruct->Subject = 0;
+ *pEmailStruct->Message = 0;
+#endif
+
+ /* Interesting information are stored before picture if any */
+ /* Moreover picture is not used in this demonstration SW */
+ pLastByteAdd = (uint8_t*)(pPayload + PayloadSize);
+
+ /* first byte should be the "mailto:" well know URI type, skip it */
+ pLook4Word = ++pPayload;
+
+ /* Retrieve email add */
+ if( pLook4Word != pLastByteAdd )
+ {
+ pEndString = pLook4Word;
+ while( memcmp( pEndString, URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH ) && (pEndString < pLastByteAdd) )
+ {
+ pEndString++;
+ }
+ if( ( !memcmp( pEndString, URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH ) ) || (pEndString == pLastByteAdd) )
+ {
+#ifdef NDEF_DYN_ALLOC
+ pEmailStruct->EmailAdd = malloc(pEndString-pLook4Word + 1);
+ if(pEmailStruct->EmailAdd != NULL)
+#endif
+ {
+ memcpy( pEmailStruct->EmailAdd, pLook4Word, pEndString-pLook4Word);
+ /* add end of string character */
+ pEmailStruct->EmailAdd[pEndString-pLook4Word] = 0;
+ }
+ }
+ }
+
+ pEndString += URI_FIRST_DATA_END_LENGTH;
+ pLook4Word = pEndString;
+
+ /* check if e-mail subject is present */
+ if( !memcmp( pLook4Word, SUBJECT_BEGIN_STRING, SUBJECT_BEGIN_STRING_LENGTH ) )
+ {
+ SizeOfKeyWord = SUBJECT_BEGIN_STRING_LENGTH;
+
+ /* Retrieve subject */
+ if( pLook4Word != pLastByteAdd )
+ {
+ pLook4Word += SizeOfKeyWord;
+ pEndString = pLook4Word;
+ while( memcmp( pEndString, URI_SECOND_DATA_END, URI_SECOND_DATA_END_LENGTH ) && (pEndString < pLastByteAdd) )
+ {
+ pEndString++;
+ }
+ if( ( !memcmp( pEndString, URI_SECOND_DATA_END, URI_SECOND_DATA_END_LENGTH ) ) || (pEndString == pLastByteAdd) )
+ {
+#ifdef NDEF_DYN_ALLOC
+ pEmailStruct->Subject = malloc(pEndString-pLook4Word + 1);
+ if(pEmailStruct->Subject != NULL)
+#endif
+ {
+ memcpy( pEmailStruct->Subject, pLook4Word, pEndString-pLook4Word );
+ /* add end of string character */
+ pEmailStruct->Subject[pEndString-pLook4Word] = 0;
+ }
+ }
+ pEndString += URI_SECOND_DATA_END_LENGTH;
+ }
+ }
+
+ pLook4Word = pEndString;
+
+ /* check if e-mail message is present */
+ if( !memcmp( pLook4Word, MESSAGE_BEGIN_STRING, MESSAGE_BEGIN_STRING_LENGTH ) )
+ {
+ pEndString += MESSAGE_BEGIN_STRING_LENGTH;
+ /* Retrieve message */
+#ifdef NDEF_DYN_ALLOC
+ pEmailStruct->Message = malloc(PayloadSize - (pEndString - pPayload + 1) + 1);
+ if(pEmailStruct->Message != NULL)
+#endif
+ {
+ memcpy( pEmailStruct->Message, pEndString, PayloadSize - (pEndString - pPayload + 1) );
+ /* add end of string character */
+ pEmailStruct->Message[PayloadSize-(pEndString-pPayload+1)] = 0;
+ }
+ }
+}
+
+/**
+ * @brief This function read the Email and store data in a structure.
+ * @param pRecordStruct : Pointer on the record structure.
+ * @param pEmailStruct : pointer on the structure to fill.
+ */
+static void NDEF_ReadURI_Email( sRecordInfo_t *pRecordStruct, sEmailInfo *pEmailStruct )
+{
+ uint8_t* pPayload;
+ uint32_t PayloadSize;
+
+ PayloadSize = pRecordStruct->PayloadLength;
+
+ /* Read record header */
+ pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
+
+ if( pRecordStruct->NDEF_Type == URI_EMAIL_TYPE )
+ NDEF_FillEmailStruct( pPayload , PayloadSize, pEmailStruct );
+
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup libEmail_Public_Functions
+ * @{
+ * @brief This file is used to manage Email (stored or loaded in tag)
+ */
+
+/**
+ * @brief This function read NDEF and retrieve Eamil information if any.
+ * @param pRecordStruct : Pointer on the record structure.
+ * @param pEmailStruct : pointer on the structure to fill .
+ * @retval NDEF_OK : Email information from NDEF have been retrieved.
+ * @retval NDEF_ERROR : not able to read NDEF in tag.
+ */
+uint16_t NDEF_ReadEmail( sRecordInfo_t *pRecordStruct, sEmailInfo *pEmailStruct )
+{
+ uint16_t status = NDEF_ERROR;
+ sRecordInfo_t *pSPRecordStruct;
+ uint32_t PayloadSize, RecordPosition;
+ uint8_t* pData;
+
+
+ if( pRecordStruct->NDEF_Type == URI_EMAIL_TYPE )
+ {
+ NDEF_ReadURI_Email( pRecordStruct, pEmailStruct );
+ status = NDEF_OK;
+ }
+ else if( pRecordStruct->NDEF_Type == SMARTPOSTER_TYPE )
+ {
+ for( RecordPosition = 0; RecordPosition < pRecordStruct->NbOfRecordInSPPayload; RecordPosition++ )
+ {
+ pSPRecordStruct = pRecordStruct->SPRecordStructAdd[RecordPosition];
+ if( pSPRecordStruct->NDEF_Type == URI_EMAIL_TYPE )
+ {
+ NDEF_ReadURI_Email( pSPRecordStruct, pEmailStruct );
+ status = NDEF_OK;
+ }
+ if( pSPRecordStruct->NDEF_Type == TEXT_TYPE )
+ {
+ PayloadSize = pSPRecordStruct->PayloadLength;
+
+ /* The instruction content the UTF-8 language code that is not used here */
+ pData = (uint8_t*)pSPRecordStruct->PayloadBufferAdd;
+ PayloadSize -= *pData + 1; /* remove not usefull data */
+ pData += *pData + 1;
+
+ memcpy( pEmailStruct->Information, pData, PayloadSize );
+ }
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief This function write the NDEF file with the Email data given in the structure.
+ * @param pEmailStruct : pointer on structure that contain the Email information.
+ * @retval NDEF_OK : the function is successful.
+ * @retval NDEF_ERROR : not able to store NDEF in tag.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+ * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+ */
+uint16_t NDEF_WriteEmail( sEmailInfo *pEmailStruct, I2C * mi2cChannel )
+{
+ uint16_t status = NDEF_ERROR, Offset = 0;
+
+ NDEF_PrepareEmailMessage( pEmailStruct, NDEF_Buffer, &Offset );
+
+ status = NfcTag_WriteNDEF( Offset, NDEF_Buffer, mi2cChannel );
+
+ return status;
+}
+
+/**
+ * @brief This function write the NDEF file with the Email data given in the structure.
+ * @param pEmailStruct : pointer on structure that contain the Email information.
+ * @param pNDEFMessage : pointer on the NDEF message.
+ * @param size : to store the size of the NDEF message generated.
+ */
+void NDEF_PrepareEmailMessage( sEmailInfo *pEmailStruct, uint8_t *pNDEFMessage, uint16_t *size )
+{
+ uint16_t Offset = 0;
+ uint32_t emailSize = 0;
+ uint32_t infoSize = 0;
+ uint32_t totalSize = 0;
+
+ /* Email is an URI but can be included in a smart poster to add text to give instruction to user for instance */
+
+ /* Email (smart poster) Record Header */
+/************************************/
+/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
+/*----------------------------------*/
+/* MB ME CF SR IL TNF */ /* <---- CF=0, IL=0 and SR=1 TNF=1 NFC Forum Well-known type*/
+/*----------------------------------*/
+/* TYPE LENGTH */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 3 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 2 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 1 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 0 */
+/*----------------------------------*/
+/* ID LENGTH */ /* <---- Not Used */
+/*----------------------------------*/
+/* TYPE */
+/*----------------------------------*/
+/* ID */ /* <---- Not Used */
+/************************************/
+
+ /* Email : 1+@+1+subject+1+message */
+ emailSize = 1 + strlen( pEmailStruct->EmailAdd ) + URI_FIRST_DATA_END_LENGTH + SUBJECT_BEGIN_STRING_LENGTH +
+ strlen( pEmailStruct->Subject ) + URI_SECOND_DATA_END_LENGTH + MESSAGE_BEGIN_STRING_LENGTH + strlen( pEmailStruct->Message );
+
+ /* Check if a Smart poster is needed */
+ if( pEmailStruct->Information[0] != '\0' )
+ {
+ /* Info : 1+2+info */
+ infoSize = 1 + ISO_ENGLISH_CODE_STRING_LENGTH + strlen( pEmailStruct->Information );
+ /* Total */
+ totalSize = 4 + emailSize + 4 + infoSize;
+ if( emailSize > 255 ) totalSize += 3; /* Normal Email size */
+ if( infoSize > 255 ) totalSize += 3; /* Normal Info size */
+
+ /* SmartPoster header */
+ if( totalSize > 255 )
+ {
+ pNDEFMessage[Offset++] = 0xC1;
+ pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (totalSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (totalSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (totalSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = totalSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = 0xD1;
+ pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (uint8_t)totalSize;
+ }
+ memcpy( &pNDEFMessage[Offset], SMART_POSTER_TYPE_STRING, SMART_POSTER_TYPE_STRING_LENGTH );
+ Offset += SMART_POSTER_TYPE_STRING_LENGTH;
+ }
+
+ /* Email header */
+ pNDEFMessage[Offset] = 0x81;
+ if( emailSize < 256 ) pNDEFMessage[Offset] |= 0x10; // Set the SR bit
+ if( pEmailStruct->Information[0] == '\0' ) pNDEFMessage[Offset] |= 0x40; // Set the ME bit
+ Offset++;
+
+ pNDEFMessage[Offset++] = URI_TYPE_STRING_LENGTH;
+ if( emailSize > 255 )
+ {
+ pNDEFMessage[Offset++] = (emailSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (emailSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (emailSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = emailSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = (uint8_t)emailSize;
+ }
+ memcpy( &pNDEFMessage[Offset], URI_TYPE_STRING, URI_TYPE_STRING_LENGTH );
+ Offset += URI_TYPE_STRING_LENGTH;
+
+ /* Email pay load */
+ pNDEFMessage[Offset++] = URI_ID_0x06;
+ memcpy( &pNDEFMessage[Offset], pEmailStruct->EmailAdd, strlen(pEmailStruct->EmailAdd) );
+ Offset += strlen( pEmailStruct->EmailAdd );
+ memcpy( &pNDEFMessage[Offset], URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH );
+ Offset += URI_FIRST_DATA_END_LENGTH;
+
+ memcpy( &pNDEFMessage[Offset], SUBJECT_BEGIN_STRING, SUBJECT_BEGIN_STRING_LENGTH );
+ Offset += SUBJECT_BEGIN_STRING_LENGTH;
+ memcpy( &pNDEFMessage[Offset], pEmailStruct->Subject, strlen(pEmailStruct->Subject) );
+ Offset += strlen( pEmailStruct->Subject );
+ memcpy( &pNDEFMessage[Offset], URI_SECOND_DATA_END, URI_SECOND_DATA_END_LENGTH );
+ Offset += URI_SECOND_DATA_END_LENGTH;
+
+ memcpy( &pNDEFMessage[Offset], MESSAGE_BEGIN_STRING, MESSAGE_BEGIN_STRING_LENGTH );
+ Offset += MESSAGE_BEGIN_STRING_LENGTH;
+ memcpy( &pNDEFMessage[Offset], pEmailStruct->Message, strlen(pEmailStruct->Message) );
+ Offset += strlen( pEmailStruct->Message );
+
+ /* Information header */
+ if( pEmailStruct->Information[0] != '\0' )
+ {
+ if( infoSize > 255 )
+ {
+ pNDEFMessage[Offset++] = 0x41;
+ pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (infoSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (infoSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (infoSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = infoSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = 0x51;
+ pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (uint8_t)infoSize;
+ }
+
+ memcpy( &pNDEFMessage[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
+ Offset += TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH; /* UTF-8 with x byte language code */
+ memcpy( &pNDEFMessage[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
+ Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
+
+ /* Information payload */
+ memcpy( &pNDEFMessage[Offset], pEmailStruct->Information, strlen(pEmailStruct->Information) );
+ Offset += strlen( pEmailStruct->Information );
+
+ }
+
+ *size = (uint16_t)(Offset);
+
+}
+
+/**
+ * @brief This function close a NDEF Email buffer freeing associated memory.
+ * @param pEmailStruct : pointer on structure that contain the Email information.
+ */
+void NDEF_closeEmail( sEmailInfo *pEmailStruct)
+{
+#ifdef NDEF_DYN_ALLOC
+ if(pEmailStruct->EmailAdd != NULL) free(pEmailStruct->EmailAdd);
+ if(pEmailStruct->Information != NULL) free(pEmailStruct->Information);
+ if(pEmailStruct->Message != NULL) free(pEmailStruct->Message);
+ if(pEmailStruct->Subject != NULL) free(pEmailStruct->Subject);
+#endif
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Email.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,65 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Email.h
+ * @author MMY Application Team
+ * @version $Revision: 2688 $
+ * @date $Date: 2016-07-12 16:57:52 +0200 (Tue, 12 Jul 2016) $
+ * @brief This file help to manage Email NDEF file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_EMAIL_H
+#define __LIB_NDEF_EMAIL_H
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+/* "mailto:customer.service@st.com?subject=M24SR S/N 754FHFGJF46G329 WARRANTY&body=this is an auomatic warranty activation email" */
+
+#ifdef NDEF_DYN_ALLOC
+typedef struct
+{
+ char *EmailAdd;
+ char *Subject;
+ char *Message;
+ char *Information;
+}sEmailInfo;
+#else
+typedef struct
+{
+ char EmailAdd[64];
+ char Subject[100];
+ char Message[2000];
+ char Information[400];
+}sEmailInfo;
+#endif
+uint16_t NDEF_ReadEmail( sRecordInfo_t *pRecordStruct, sEmailInfo *pEmailStruct );
+uint16_t NDEF_WriteEmail( sEmailInfo *pEmailStruct, I2C* mi2cChannel );
+void NDEF_PrepareEmailMessage( sEmailInfo *pEmailStruct, uint8_t *pNDEFMessage, uint16_t *size );
+void NDEF_closeEmail( sEmailInfo *pEmailStruct);
+
+
+#endif /* __LIB_NDEF_EMAIL_H */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Geo.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,358 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Geo.c
+ * @author MMY Application Team
+ * @version $Revision: 2702 $
+ * @date $Date: 2016-07-13 18:45:05 +0200 (Wed, 13 Jul 2016) $
+ * @brief This file help to manage NDEF file that represent geolocation.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_Geo.h"
+
+/** @addtogroup NFC_libraries
+ * @{
+ * @brief <b>This is the library used to manage the content of the TAG (data)
+ * But also the specific feature of the tag, for instance
+ * password, gpo... </b>
+ */
+
+
+/** @addtogroup libNFC_FORUM
+ * @{
+ * @brief This part of the library manage data which follow NFC forum organisation.
+ */
+
+/**
+ * @brief This buffer contains the data send/received by TAG
+ */
+extern uint8_t NDEF_Buffer [];
+
+/** @defgroup libGeo_Private_Functions
+ * @{
+ */
+
+static void NDEF_FillGeoStruct( uint8_t* pPayload, uint32_t PayloadSize, sGeoInfo *pGeoStruct );
+static void NDEF_ReadURI_Geo( sRecordInfo_t *pRecordStruct, sGeoInfo *pGeoStruct );
+
+/**
+ * @brief This function fill Geo structure with information of NDEF message.
+ * @param pPayload : pointer on the payload data of the NDEF message.
+ * @param PayloadSize : number of data in the payload.
+ * @param pGeoStruct : pointer on the structure to fill.
+ */
+static void NDEF_FillGeoStruct( uint8_t* pPayload, uint32_t PayloadSize, sGeoInfo *pGeoStruct )
+{
+ uint8_t* pLastByteAdd, *pLook4Word, *pEndString;
+ char* pKeyWord;
+ uint32_t SizeOfKeyWord;
+ pEndString = 0;
+
+ pKeyWord = GEO_TYPE_STRING;
+ SizeOfKeyWord = GEO_TYPE_STRING_LENGTH;
+
+ /* First character force to NULL in case not matching found */
+ *pGeoStruct->Latitude = 0;
+ *pGeoStruct->Longitude = 0;
+
+ /* Interresting information are stored before picture if any */
+ /* Moreover picture is not used in this demonstration SW */
+ pLastByteAdd = (uint8_t*)(pPayload + PayloadSize);
+
+ pLook4Word = pPayload;
+ while( memcmp( pLook4Word, pKeyWord, SizeOfKeyWord ) && (pLook4Word < pLastByteAdd) )
+ {
+ pLook4Word++;
+ }
+
+ /* Retrieve phone number */
+ if( pLook4Word != pLastByteAdd )
+ {
+ pLook4Word += SizeOfKeyWord;
+ pEndString = pLook4Word;
+ while( memcmp( pEndString, URI_LATITUDE_END, URI_LATITUDE_END_LENGTH ) && (pEndString < pLastByteAdd) )
+ {
+ pEndString++;
+ }
+ if( pEndString != pLastByteAdd )
+ {
+ memcpy( pGeoStruct->Latitude, pLook4Word, pEndString-pLook4Word );
+ /* add end of string character */
+ pGeoStruct->Latitude[pEndString-pLook4Word] = 0;
+ }
+ }
+ pEndString += URI_LATITUDE_END_LENGTH;
+ pLook4Word = pEndString;
+
+ memcpy( pGeoStruct->Longitude, pEndString, PayloadSize - (pEndString - pPayload) );
+ /* add end of string character */
+ pGeoStruct->Longitude[PayloadSize-(pEndString-pPayload)] = 0;
+
+}
+
+/**
+ * @brief This function read the geoloccation information and store data in a structure.
+ * @param pRecordStruct : Pointer on the record structure.
+ * @param pGeoStruct : pointer on the structure to fill.
+ */
+static void NDEF_ReadURI_Geo( sRecordInfo_t *pRecordStruct, sGeoInfo *pGeoStruct )
+{
+ uint8_t* pPayload;
+ uint32_t PayloadSize;
+
+ PayloadSize = pRecordStruct->PayloadLength;
+
+ /* Read record header */
+ pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
+
+ if( pRecordStruct->NDEF_Type == URI_GEO_TYPE )
+ NDEF_FillGeoStruct( pPayload , PayloadSize, pGeoStruct );
+
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup libGeo_Public_Functions
+ * @{
+ * @brief This file is used to manage geolocation (stored or loaded in tag)
+ */
+
+/**
+ * @brief This function read NDEF and retrieve Geo information if any.
+ * @param pRecordStruct : Pointer on the record structure.
+ * @param pGeoStruct : pointer on the structure to fill .
+ * @retval NDEF_OK : Geolocation information from NDEF have been retrieved.
+ * @retval NDEF_ERROR : not able to read NDEF from tag.
+ */
+uint16_t NDEF_ReadGeo( sRecordInfo_t *pRecordStruct, sGeoInfo *pGeoStruct )
+{
+ uint16_t status = NDEF_ERROR;
+ sRecordInfo_t *pSPRecordStruct;
+ uint32_t PayloadSize, RecordPosition;
+ uint8_t* pData;
+
+ if( pRecordStruct->NDEF_Type == URI_GEO_TYPE )
+ {
+ NDEF_ReadURI_Geo( pRecordStruct, pGeoStruct );
+ status = NDEF_OK;
+ }
+ else if( pRecordStruct->NDEF_Type == SMARTPOSTER_TYPE )
+ {
+ for( RecordPosition = 0; RecordPosition < pRecordStruct->NbOfRecordInSPPayload; RecordPosition++ )
+ {
+ pSPRecordStruct = pRecordStruct->SPRecordStructAdd[RecordPosition];
+ if( pSPRecordStruct->NDEF_Type == URI_GEO_TYPE )
+ {
+ NDEF_ReadURI_Geo( pSPRecordStruct, pGeoStruct );
+ status = NDEF_OK;
+ }
+ if( pSPRecordStruct->NDEF_Type == TEXT_TYPE )
+ {
+ PayloadSize = pSPRecordStruct->PayloadLength;
+
+ /* The instruction content the UTF-8 language code that is not used here */
+ pData = (uint8_t*)pSPRecordStruct->PayloadBufferAdd;
+ PayloadSize -= *pData + 1; /* remove not usefull data */
+ pData += *pData + 1; /* set pointer on usefull data */
+
+ memcpy( pGeoStruct->Information, pData, PayloadSize );
+ /* add end of string character */
+ pGeoStruct->Information[PayloadSize] = 0;
+ }
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief This function write the NDEF file with the geolocation data given in the structure.
+ * @param pGeoStruct : pointer on structure that contain the geolocation information.
+ * @retval NDEF_OK : the function is succesful.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+ * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+ */
+uint16_t NDEF_WriteGeo( sGeoInfo *pGeoStruct, I2C* mi2cChannel )
+{
+ uint16_t status = NDEF_ERROR,Offset = 0;
+
+ NDEF_PrepareGeoMessage( pGeoStruct, NDEF_Buffer, &Offset );
+
+ status = NfcTag_WriteNDEF( Offset, NDEF_Buffer, mi2cChannel );
+
+ return status;
+}
+
+/**
+ * @brief This function write the NDEF file with the geolocation data given in the structure.
+ * @param pGeoStruct : pointer on structure that contain the geolocation information.
+ * @param pNDEFMessage : pointer on the NDEF message.
+ * @param size : to store the size of the NDEF message generated.
+ */
+void NDEF_PrepareGeoMessage( sGeoInfo *pGeoStruct, uint8_t *pNDEFMessage, uint16_t *size )
+{
+ uint16_t Offset = 0;
+ uint32_t geoSize = 0;
+ uint32_t infoSize = 0;
+ uint32_t totalSize = 0;
+
+ /* GEO is an URI but can be included in a smart poster to add text to give instruction to user for instance */
+
+ /* GEO (smart poster) Record Header */
+/************************************/
+/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
+/*----------------------------------*/
+/* MB ME CF SR IL TNF */ /* <---- CF=0, IL=0 and SR=1 TNF=1 NFC Forum Well-known type*/
+/*----------------------------------*/
+/* TYPE LENGTH */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 3 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 2 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 1 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 0 */
+/*----------------------------------*/
+/* ID LENGTH */ /* <---- Not Used */
+/*----------------------------------*/
+/* TYPE */
+/*----------------------------------*/
+/* ID */ /* <---- Not Used */
+/************************************/
+
+ /* GEO : 1+geo:+latitude+1+longitude */
+ geoSize = 1 + GEO_TYPE_STRING_LENGTH + strlen(pGeoStruct->Latitude) + URI_LATITUDE_END_LENGTH + strlen(pGeoStruct->Longitude);
+
+ /* Check if a Smart poster is needed */
+ if( pGeoStruct->Information[0] != '\0' )
+ {
+ /* Info : 1+2+info */
+ infoSize = 1 + ISO_ENGLISH_CODE_STRING_LENGTH + strlen(pGeoStruct->Information);
+ /* Total */
+ totalSize = 4 + geoSize + 4 + infoSize;
+ if( geoSize > 255 ) totalSize += 3; /* Normal Geo size */
+ if( infoSize > 255 ) totalSize += 3; /* Normal Info size */
+
+ /* SmartPoster header */
+ if( totalSize > 255 )
+ {
+ pNDEFMessage[Offset++] = 0xC1;
+ pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (totalSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (totalSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (totalSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = totalSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = 0xD1;
+ pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (uint8_t)totalSize;
+ }
+ memcpy( &pNDEFMessage[Offset], SMART_POSTER_TYPE_STRING, SMART_POSTER_TYPE_STRING_LENGTH );
+ Offset += SMART_POSTER_TYPE_STRING_LENGTH;
+ }
+
+ /* GEO header */
+ pNDEFMessage[Offset] = 0x81;
+ if( geoSize < 256 ) pNDEFMessage[Offset] |= 0x10; // Set the SR bit
+ if( pGeoStruct->Information[0] == '\0' ) pNDEFMessage[Offset] |= 0x40; // Set the ME bit
+ Offset++;
+
+ pNDEFMessage[Offset++] = URI_TYPE_STRING_LENGTH;
+ if( geoSize > 255 )
+ {
+ pNDEFMessage[Offset++] = (geoSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (geoSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (geoSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = geoSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = (uint8_t)geoSize;
+ }
+ memcpy( &pNDEFMessage[Offset], URI_TYPE_STRING, URI_TYPE_STRING_LENGTH );
+ Offset += URI_TYPE_STRING_LENGTH;
+
+ /* GEO payload */
+ pNDEFMessage[Offset++] = URI_ID_0x00; /* URI identifier no abbreviation */
+ memcpy( &pNDEFMessage[Offset], GEO_TYPE_STRING, GEO_TYPE_STRING_LENGTH );
+ Offset += GEO_TYPE_STRING_LENGTH;
+ memcpy( &pNDEFMessage[Offset], pGeoStruct->Latitude, strlen(pGeoStruct->Latitude) );
+ Offset += strlen( pGeoStruct->Latitude );
+ memcpy( &pNDEFMessage[Offset], URI_LATITUDE_END, URI_LATITUDE_END_LENGTH );
+ Offset += URI_LATITUDE_END_LENGTH;
+ memcpy( &pNDEFMessage[Offset], pGeoStruct->Longitude, strlen(pGeoStruct->Longitude) );
+ Offset += strlen( pGeoStruct->Longitude );
+
+ /* Information header */
+ if( pGeoStruct->Information[0] != '\0' )
+ {
+ if( infoSize > 255 )
+ {
+ pNDEFMessage[Offset++] = 0x41;
+ pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (infoSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (infoSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (infoSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = infoSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = 0x51;
+ pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (uint8_t)infoSize;
+ }
+
+ memcpy( &pNDEFMessage[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
+ Offset += TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH; /* UTF-8 with x byte language code */
+ memcpy( &pNDEFMessage[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
+ Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
+
+ /* Information payload */
+ memcpy( &pNDEFMessage[Offset], pGeoStruct->Information, strlen(pGeoStruct->Information) );
+ Offset += strlen( pGeoStruct->Information );
+ }
+
+ *size = (uint16_t)(Offset);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Geo.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,52 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Geo.h
+ * @author MMY Application Team
+ * @version $Revision: 2475 $
+ * @date $Date: 2016-06-24 12:11:59 +0200 (Fri, 24 Jun 2016) $
+ * @brief This file help to manage Geolocation NDEF file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_GEO_H
+#define __LIB_NDEF_GEO_H
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+typedef struct
+{
+ char Latitude[20];
+ char Longitude[20];
+ char Information[100];
+}sGeoInfo;
+
+uint16_t NDEF_ReadGeo( sRecordInfo_t *pRecordStruct, sGeoInfo *pGeoStruct );
+uint16_t NDEF_WriteGeo( sGeoInfo *pGeoStruct, I2C* mi2cChannel );
+void NDEF_PrepareGeoMessage( sGeoInfo *pGeoStruct, uint8_t *pNDEFMessage, uint16_t *size );
+
+
+#endif /* __LIB_NDEF_GEO_H */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Handover.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,509 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Bluetooth.c
+ * @author MMY Application Team
+ * @version $Revision: 2702 $
+ * @date $Date: 2016-07-13 18:45:05 +0200 (Wed, 13 Jul 2016) $
+ * @brief This file helps to manage a NDEF Handover message.
+ * @ingroup libNDEF_Handover
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_Handover.h"
+
+/** @addtogroup lib_NDEF_Handover NDEF Handover library
+ * @ingroup libNDEF
+ * @brief This module is used to manage the NDEF Handover messages, to negociate the switch to a non-nfc protocol of communication.
+ * @details
+ * The NDEF Handover process is described by the NFC Forum Connection Handover specification.
+ * It consists in a specific NDEF message construct, as:
+ * - NDEF 1st record: Handover Request or Handover Select record
+ * - Version
+ * - Collision Resolution (nested record, optional)
+ * - Random number
+ * - Alternative Carrier 1 (nested record)
+ * - Power state
+ * - Reference Data
+ * - Auxiliary Data Reference 1
+ * - ...
+ * - Auxiliary Data Reference N
+ * - ...
+ * - Alternative Carrier N (nested record)
+ * - NDEF record 2+: Alternative Carrier or Auxiliary Data: Connection details for one of the AC (record ID is the AC Reference Data or an Auxiliary Data Reference).
+ * - ...
+ * - NDEF record N: Alternative Carrier or Auxiliary Data: Connection details for one of the AC (record ID is the AC Reference Data or an Auxiliary Data Reference).
+ * _________________
+ * @section Handover_Library_Usage NDEF Handover Library usage:
+ * @subsection Static_Handover Static Handover
+ * The Static Handover is used when a device is only equipped with a NFC Tag (no peer-to-peer) to directly propose a set of Alternative Carriers (ACs: bluetooth, wifi,...)
+ * without running the full handover request-select process.\n
+ * The Handover Select record use in that case is similar to the one used during a regular Handover negociation.\n
+ * 1. Declare & initialize an instance of `Ndef_Handover_t`, such as:
+ *
+ * Ndef_Handover_t wHandover = {.type = NDEF_HANDOVER_SELECT_TYPE, .version = NDEF_HANDOVER_VERSION_1_2};
+ * 2. Declare a `sRecordInfo_t` instance:
+ *
+ * sRecordInfo_t HandoverRecord;
+ * 3. Call the `NDEF_CreateHandover` function, to start preparing the Handover Select record
+ *
+ * NDEF_CreateHandover(&wHandover,&HandoverRecord);
+ * 4. Call the `NDEF_AddAlternativeCarrier` for each Alternative Carrier (such as Bluetooth, Wifi, ...)
+ * 5. Declare and initialize as many `Ndef_Handover_alternative_carrier_t` instances as the number of non-NFC protocol available.
+ * And then call the `NDEF_AddAlternativeCarrier` for each of them.
+ *
+ * Ndef_Handover_alternative_carrier_t wAC_BREDR = {.cps = NDEF_HANDOVER_AC_CPS_ACTIVE,
+ * .aux_data_ref_count = 0};
+ * Ndef_Handover_alternative_carrier_t wAC_BLE = {.cps = NDEF_HANDOVER_AC_CPS_ACTIVE,
+ * .aux_data_ref_count = 0};
+ * Ndef_Handover_alternative_carrier_t wAC_Wifi = {.cps = NDEF_HANDOVER_AC_CPS_ACTIVE,
+ * .aux_data_ref_count = 0};
+ *
+ * NDEF_AddAlternativeCarrier(&wAC_BREDR,"urn:nfc:handover:bredr", NULL,&HandoverRecord );
+ * NDEF_AddAlternativeCarrier(&wAC_BLE,"urn:nfc:handover:ble", NULL,&HandoverRecord );
+ * NDEF_AddAlternativeCarrier(&wAC_Wifi,"urn:nfc:handover:wifi", NULL,&HandoverRecord );
+ * @note
+ * 1. In this example a single `Ndef_Handover_alternative_carrier_t` could have been used, as the parameters are the same for all ACs.
+ * 2. If more than one NDEF record is required to provide the AC connection details, the `aux_data_ref_count` must specify the number of additional records.
+ *
+ * Ndef_Handover_alternative_carrier_t wAC_Wifi = {.cps = NDEF_HANDOVER_AC_CPS_ACTIVE,
+ * .aux_data_ref_count = 2};
+ * Then, it's required to initialize an array of pointers to these Auxiliary Data Reference, as:
+ *
+ * char *aux_data_ref1 = "urn:nfc:handover:wifi:aux_data_ref1";
+ * char *aux_data_ref2 = "urn:nfc:handover:wifi:aux_data_ref2";
+ * char *wifi_aux_ref_data_array[2] = {aux_data_ref1,aux_data_ref2};
+ * And then provide this array as the 3rd argument to the 'NDEF_AddAlternativeCarrier' function:
+ *
+ * NDEF_AddAlternativeCarrier(&wAC_Wifi,"urn:nfc:handover:wifi", wifi_aux_ref_data_array,&HandoverRecord );
+ * 6. Call the `NDEF_WriteHandover` function to finalize the NDEF message and write it to the tag.
+ *
+ * NDEF_WriteHandover(&HandoverRecord, NDEF_Buffer);
+ * 7. Then call other functions (from the libNDEF or not) to add records, describing the Alternative Carriers, to the NDEF message:
+ *
+ * NDEF_AppendBluetoothOOB ( &w_ble_oob, "urn:nfc:handover:ble" );
+ * NDEF_AppendBluetoothOOB ( &w_bredr_oob, "urn:nfc:handover:bredr" );
+ * @note
+ * 1. The ID of these additional records (2nd argument in the above example) must match the Data Reference provided within the Handover record.
+ * 2. If Auxiliary Data References are expected they must also be added to the NDEF message, with their ID matching the ID provided to the Alternative Carrier record.
+ *
+ * @section Reading_Handover Reading through a Handover Request message
+ * 1. Read the 1st record of the NDEF message:
+ *
+ * sRecordInfo_t rRecord;
+ * NDEF_ReadNDEF(NDEF_Buffer);
+ * NDEF_IdentifyBuffer(rRecord,NDEF_Buffer);
+ * 2. Decode the handover:
+ *
+ * Ndef_Handover_t rHandover;
+ * NDEF_ReadHandover(&rRecord , &rHandover );
+ * 3. Read all Alternative Carrier records, and their Auxiliary Data References if any.
+ *
+ * uint8_t ac_index, aux_index;
+ * for(ac_index=0;ac_index<rHandover.nb_alternative_carrier;ac_index++)
+ * {
+ * Ndef_Handover_alternative_carrier_t rAC;
+ * NDEF_ReadAC( ac_index, &rHandover , &rAC );
+ * for(aux_index = 0; aux_index < rAC.aux_data_ref_count; aux_index++)
+ * {
+ * sRecordInfo_t AuxRecord;
+ * NDEF_ReadAuxData( aux_index, &rAC, &AuxRecord );
+ * // Do something with this Auxiliary Data
+ * }
+ * // Process this AC (Extract OOB/or whatever data), and decide if this Carrier is supported or not.
+ * }
+ * 4. Choose the prefered Carrier and write a Handover Select record with the prefered AC as described in the @ref Static_Handover section.
+ * @{
+ */
+
+
+
+/**
+ * @brief This function searches the NDEF message to retrieve the nth Auxiliary Data record if present.
+ * @param aux_data_nb Position of the Auxiliary Data Reference in the Alternative Carrier.
+ * @param pAC Pointer on the Alternative Carrier structure where to find the Auxiliary Data Reference.
+ * @param pRecord Pointer to return the output Auxiliary Data record.
+ * @retval NDEF_OK The Auxiliary Data record has been retrieved.
+ * @retval NDEF_ERROR Not able to find the Auxiliary Data in the NDEF message.
+ */
+uint16_t NDEF_ReadAuxData( uint8_t aux_data_nb, Ndef_Handover_alternative_carrier_t *pAC, sRecordInfo_t *pRecord )
+{
+ uint16_t status;
+ uint8_t* pData = pAC->aux_data_ref_start;
+ uint8_t current_aux = 0;
+ uint8_t* aux_id;
+ uint8_t aux_id_length;
+
+ if((pAC->aux_data_ref_start == NULL) ||
+ (pAC->aux_data_ref_end == NULL) ||
+ (pAC->aux_data_ref_count == 0) ||
+ (aux_data_nb >= pAC->aux_data_ref_count))
+ return NDEF_ERROR;
+
+
+ while((current_aux < aux_data_nb) && (pData < pAC->aux_data_ref_end))
+ {
+ aux_id_length = *pData++;
+ aux_id = pData;
+ pData += aux_id_length;
+ current_aux++;
+ }
+
+ pData = pAC->aux_data_ref_end;
+ /* if ac has been found */
+ if(current_aux == aux_data_nb)
+ {
+ /* let's now look for the corresponding record - must be after the Handover record */
+ do {
+ status = NDEF_IdentifyBuffer(pRecord,pData);
+ if(status != NDEF_OK) return status;
+ pData = pAC->ac_record.PayloadBufferAdd;
+
+ if((pRecord->IDLength == aux_id_length) &&
+ !memcmp(pRecord->ID, aux_id,aux_id_length))
+ {
+ /* this is the record we were looking for, so exit */
+ return NDEF_OK;
+ }
+
+ // go to next record
+ pData = pRecord->PayloadBufferAdd + pRecord->PayloadLength;
+
+ } while (!(pRecord->RecordFlags & MB_Mask));
+
+ }
+ // if we go there, it means that the record ID is not found
+ return NDEF_ERROR;
+}
+
+
+
+/**
+ * @brief This function reads the NDEF message and retrieves the nth Alternative Carrier record if present.
+ * @param ac_nb Position of the Alternative Carrier Reference in the Handover record.
+ * @param pHandover Pointer to the Handover record where to find the AC Reference Data.
+ * @param pAC Pointer used to return the output Alternative Carrier record.
+ * @retval NDEF_OK The Alternative Carrier record has been retrieved.
+ * @retval NDEF_ERROR Not able to find the Alternative Carrier in the NDEF message.
+ */
+uint16_t NDEF_ReadAC( uint8_t ac_nb, Ndef_Handover_t *pHandover , Ndef_Handover_alternative_carrier_t *pAC )
+{
+ uint16_t status;
+ uint8_t* pData = pHandover->ac_start;
+ uint8_t current_ac = 0;
+ uint8_t* ac_id;
+ uint8_t ac_id_length;
+ sRecordInfo_t NestedRecord;
+ uint8_t ac_found = 0;
+
+ if((pHandover->ac_start == NULL) ||
+ (pHandover->ac_end == NULL) ||
+ (pHandover->nb_alternative_carrier == 0) ||
+ (ac_nb >= pHandover->nb_alternative_carrier))
+ return NDEF_ERROR;
+
+ // Default handover init
+ pAC->aux_data_ref_count = 0;
+
+ while((current_ac <= ac_nb)&&(current_ac <= pHandover->nb_alternative_carrier) && (pData < pHandover->ac_end))
+ {
+ status = NDEF_IdentifyBuffer(&NestedRecord,pData);
+ if(status != NDEF_OK) return status;
+ // go to payload address
+ pData = NestedRecord.PayloadBufferAdd;
+
+ if(!memcmp(NestedRecord.Type,NDEF_HANDOVER_ALTERNATIVE_CARRIER_TYPE_STR,strlen(NDEF_HANDOVER_ALTERNATIVE_CARRIER_TYPE_STR)))
+ {
+ if(current_ac == ac_nb)
+ {
+ // parse the AC now
+ pAC->cps = pData[0] & NDEF_HANDOVER_AC_CPS_MASK;
+ ac_id_length = pData[1];
+ ac_id = &pData[2];
+ pAC->aux_data_ref_count = pData[2 + ac_id_length];
+ pAC->aux_data_ref_start = &pData[3 + ac_id_length];
+ pAC->aux_data_ref_end = pData + NestedRecord.PayloadLength;
+ ac_found = 1;
+ }
+ current_ac++;
+ }
+ // go to next record
+ pData += NestedRecord.PayloadLength;
+ }
+ pData = pHandover->ac_end;
+ /* if ac has been found */
+ if(ac_found)
+ {
+ /* let's now look for the corresponding record - must be after the Handover record */
+ do {
+ status = NDEF_IdentifyBuffer(&pAC->ac_record,pData);
+ if(status != NDEF_OK) return status;
+ pData = pAC->ac_record.PayloadBufferAdd;
+
+ if((pAC->ac_record.IDLength == ac_id_length) &&
+ !memcmp(pAC->ac_record.ID, ac_id,ac_id_length))
+ {
+ /* this is the record we were looking for, so exit */
+ return NDEF_OK;
+ }
+
+ // go to next record
+ pData = pAC->ac_record.PayloadBufferAdd + pAC->ac_record.PayloadLength;
+ // TO DO: add a security condition to avoid infinite loop if NDEF file is corrupted
+ } while (!(pAC->ac_record.RecordFlags & ME_Mask));
+
+ }
+ // if we go there, it means that the record ID is not found
+ return NDEF_ERROR;
+}
+
+
+/**
+ * @brief This function reads a record and retrieves the Handover information if present.
+ * @param pRecord Pointer on the record structure to be read.
+ * @param pHandover Pointer used to return the Handover information.
+ * @retval NDEF_OK Handover information has been retrieved from the record.
+ * @retval NDEF_ERROR Not able to read the Handover information from the record.
+ */
+uint16_t NDEF_ReadHandover(sRecordInfo_t *pRecord , Ndef_Handover_t *pHandover )
+{
+ uint16_t status;
+ uint8_t* pData = pRecord->PayloadBufferAdd;
+ uint8_t* pEnd = pData + pRecord->PayloadLength;
+ sRecordInfo_t NestedRecord;
+
+ /* Default Handover Structure init */
+ pHandover->version =0;
+ pHandover->nb_alternative_carrier =0;
+ pHandover->has_cr = 0;
+ pHandover->ac_start = NULL;
+ pHandover->ac_end = NULL;
+
+ /* A Handover record should never be the end of the NDEF message */
+ if(pRecord->RecordFlags & ME_Mask)
+ return NDEF_ERROR;
+
+ if( !memcmp(pRecord->Type,NDEF_HANDOVER_REQUEST_TYPE_STR,strlen(NDEF_HANDOVER_REQUEST_TYPE_STR)) )
+ {
+ pHandover->type = NDEF_HANDOVER_REQUEST_TYPE;
+ } else if ( !memcmp(pRecord->Type,NDEF_HANDOVER_SELECT_TYPE_STR,strlen(NDEF_HANDOVER_SELECT_TYPE_STR)) )
+ {
+ pHandover->type = NDEF_HANDOVER_SELECT_TYPE;
+ } else {
+ /* This is not a Handover record! */
+ return NDEF_ERROR;
+ }
+
+ pHandover->version = *pData++;
+
+ /* Following records are nested into Hr/s record */
+ while (pData < pEnd)
+ {
+ status = NDEF_IdentifyBuffer(&NestedRecord,pData);
+ if(status != NDEF_OK) return status;
+ /* save record address */
+ uint8_t* pACRecord = pData;
+ /* go to payload address */
+ pData = NestedRecord.PayloadBufferAdd;
+
+ /* Parse Collision Resolution if Handover request */
+ if(pHandover->type == NDEF_HANDOVER_REQUEST_TYPE)
+ {
+
+ if(!memcmp(NestedRecord.Type,NDEF_HANDOVER_COLLISION_RESOLUTION_TYPE_STR,strlen(NDEF_HANDOVER_COLLISION_RESOLUTION_TYPE_STR)))
+ {
+ pHandover->has_cr = 1;
+ pHandover->cr_random_number = *(uint16_t*)pData;
+ }
+ }
+
+ /* Parse AlternativeCarriers just to know how many they are */
+ else if(!memcmp(NestedRecord.Type,NDEF_HANDOVER_ALTERNATIVE_CARRIER_TYPE_STR,strlen(NDEF_HANDOVER_ALTERNATIVE_CARRIER_TYPE_STR)))
+ {
+ pHandover->nb_alternative_carrier++;
+ if(pHandover->ac_start == NULL)
+ pHandover->ac_start = pACRecord;
+ pHandover->ac_end = pData + NestedRecord.PayloadLength;
+ /* don't parse the AC now */
+ }
+ else {
+ /* this is an unexpected type, just ignore it */
+ }
+ /* go to next record */
+ pData += NestedRecord.PayloadLength;
+
+ }
+
+ return NDEF_OK;
+}
+
+/**
+ * @brief This function prepares the Handover record with the data given in the Handover structure.
+ * @param pHandover Pointer on structure containing the handover basic information.
+ * @param pRecord Pointer used to return the prepared Handover record.
+ * @retval NDEF_OK The record has been prepared.
+ * @retval NDEF_ERROR The record has not been prepared.
+ */
+uint16_t NDEF_CreateHandover(Ndef_Handover_t *pHandover, sRecordInfo_t* pRecord )
+{
+ uint16_t status = NDEF_ERROR;
+
+ /* Use a static buffer to prepare the Handover record */
+ pRecord->PayloadBufferAdd = NDEF_Record_Buffer;
+ /* Alternative, where the user must first allocate the Payload buffer in the record:
+ * if (pRecord->PayloadBufferAdd == NULL)
+ * return NDEF_ERROR;
+ */
+
+ /* Handover MUST be the first record (SR mask to be updated when actually writing the record) */
+ pRecord->RecordFlags = MB_Mask | ME_Mask | TNF_WellKnown;
+
+ if(pHandover->type == NDEF_HANDOVER_SELECT_TYPE)
+ {
+ pRecord->TypeLength = strlen(NDEF_HANDOVER_SELECT_TYPE_STR);
+ memcpy(pRecord->Type, NDEF_HANDOVER_SELECT_TYPE_STR,pRecord->TypeLength);
+ }
+ else if (pHandover->type == NDEF_HANDOVER_REQUEST_TYPE)
+ {
+ pRecord->TypeLength = strlen(NDEF_HANDOVER_SELECT_TYPE_STR);
+ memcpy(pRecord->Type, NDEF_HANDOVER_REQUEST_TYPE_STR,pRecord->TypeLength);
+ }
+ else
+ return NDEF_ERROR;
+
+ pRecord->PayloadLength = sizeof(pHandover->version);
+ *pRecord->PayloadBufferAdd = pHandover->version;
+
+ /* Don't write the record for now, additionnal Alternative Carriers to come as nested records. */
+
+ return status;
+}
+
+
+/**
+ * @brief This function adds an Alternative Carrier record to a Handover record using the data given in the AC structure.
+ * @param pAC Pointer on input AC structure.
+ * @param CarrierDataRef String with the Alternative Carrier Data Reference (ID of the corresponding record in the NDEF message).
+ * @param AuxDataRefID Array with pointers to the Auxiliary Data References (as many as defined in pAC structure).
+ * @param pRecord Pointer on the Handover record to be filled with the AC data, must have been previously initialized with the NDEF_CreateHandover function.
+ * @retval NDEF_OK The Handover record has been updated with AC information.
+ * @retval NDEF_ERROR The Handover record cannot be updated with the AC information.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL The internal buffer for records is too small to add the AC information.
+ */
+uint16_t NDEF_AddAlternativeCarrier(Ndef_Handover_alternative_carrier_t *pAC,char *CarrierDataRef, char **AuxDataRefID, sRecordInfo_t* pRecord, I2C* mi2cChannel )
+{
+ /* Specific buffer to prepare the Alternative Carrier record */
+ uint8_t NDEF_AlternativeCarrier_Buffer[NDEF_AC_BUFFER_SIZE];
+
+ /* check that there is enough space in the buffers */
+ pAC->ac_record.PayloadLength = NDEF_GetACDataLength(pAC,CarrierDataRef,AuxDataRefID);
+ if(((pRecord->PayloadLength + pAC->ac_record.PayloadLength) > NDEF_RECORD_MAX_SIZE) ||
+ (pAC->ac_record.PayloadLength > NDEF_AC_BUFFER_SIZE))
+ return NDEF_ERROR_MEMORY_INTERNAL;
+
+ /* Use specific buffer to prepare the nested record */
+ uint8_t *pData = NDEF_AlternativeCarrier_Buffer;
+ pAC->ac_record.PayloadBufferAdd = pData;
+ /* Following line is an alternative where the user must allocate the payload buffer of the ac_record:
+ * uint8_t* pData = pAC->ac_record.PayloadBufferAdd ;
+ */
+
+ if ((pRecord->PayloadBufferAdd == NULL) ||
+ (pRecord->PayloadLength == 0))
+ return NDEF_ERROR;
+
+ /* AC is not the first record */
+ pAC->ac_record.RecordFlags = TNF_WellKnown;
+
+ pAC->ac_record.TypeLength = strlen(NDEF_HANDOVER_ALTERNATIVE_CARRIER_TYPE_STR);
+ memcpy(pAC->ac_record.Type, NDEF_HANDOVER_ALTERNATIVE_CARRIER_TYPE_STR,pAC->ac_record.TypeLength);
+
+ /* Length : cps byte + data ref length byte + auxiliary data ref count byte + data ref length */
+ *pData++ = pAC->cps & NDEF_HANDOVER_AC_CPS_MASK;
+ *pData++ = strlen(CarrierDataRef);
+ memcpy(pData, CarrierDataRef, strlen(CarrierDataRef));
+ pData += strlen(CarrierDataRef);
+ *pData++ = pAC->aux_data_ref_count;
+
+ uint8_t AuxDataIndex;
+ for(AuxDataIndex = 0;AuxDataIndex<pAC->aux_data_ref_count;AuxDataIndex++)
+ {
+ *pData++ = strlen(AuxDataRefID[AuxDataIndex]);
+ memcpy(pData, AuxDataRefID[AuxDataIndex], strlen(AuxDataRefID[AuxDataIndex]));
+ pData += strlen(AuxDataRefID[AuxDataIndex]);
+ }
+
+ /* Append the nested record right after the Handover record - increase its length accordingly */
+ pRecord->PayloadLength += NDEF_WriteRecord(&pAC->ac_record,pRecord->PayloadBufferAdd + pRecord->PayloadLength, mi2cChannel);
+ return NDEF_OK;
+}
+
+
+/**
+ * @brief This function returns the length of an Alternative Carrier record data (excluding the record metadata).
+ * @param pAC Pointer on the input AC structure.
+ * @param CarrierDataRef String with the Alternative Carrier Data Reference.
+ * @param AuxDataRefID Array with the Auxiliary Data References (as many as defined in the pAC structure).
+ * @return The computed length in bytes corresponding to the provided Alternative Carrier information.
+ */
+uint32_t NDEF_GetACDataLength(Ndef_Handover_alternative_carrier_t *pAC,char *CarrierDataRef, char **AuxDataRefID)
+{
+ uint8_t AuxDataIndex;
+
+ /* First compute the Data length */
+ uint32_t length = 1 + // cps
+ 1 + // Carrier data ref length
+ strlen(CarrierDataRef) + // Carrier data ref
+ 1 + // auxiliary data count
+ pAC->aux_data_ref_count * 1; // auxiliary data lengths
+
+ /* Then adds the length of the Auxiliary Data */
+ for(AuxDataIndex = 0;AuxDataIndex<pAC->aux_data_ref_count;AuxDataIndex++)
+ {
+ length += strlen(AuxDataRefID[AuxDataIndex]);
+ }
+
+ return length;
+}
+
+/**
+ * @brief This function writes the Handover record into the memory.
+ * @param pRecord Pointer on the input Handover record.
+ * @param pNdef Pointer to a NDEF buffer (used to prepare the data before actual writing to the memory).
+ * @retval NDEF_OK The memory has been written.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL Cannot write to tag.
+ * @retval NDEF_ERROR_NOT_FORMATED CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED Tag locked, cannot be write.
+ */
+uint16_t NDEF_WriteHandover( sRecordInfo_t* pRecord , uint8_t* pNdef, I2C* mi2cChannel)
+{
+ /* Note: in case of Handover Select for no matching alternative carrier, the ME bit flag must be set by the caller */
+
+ uint32_t Size = NDEF_WriteRecord(pRecord,pNdef, mi2cChannel);
+ return NDEF_WriteNDEF(Size,pNdef, mi2cChannel);
+}
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Handover.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,116 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Bluetooth.h
+ * @author MMY Application Team
+ * @version $Revision: 2475 $
+ * @date $Date: 2016-06-24 12:11:59 +0200 (Fri, 24 Jun 2016) $
+ * @brief This file help to manage Bluetooth NDEF file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_HANDOVER_H
+#define __LIB_NDEF_HANDOVER_H
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+
+/** @addtogroup lib_NDEF_Handover NDEF Handover library
+ * @{
+ */
+
+/** @brief SIze of the buffer used to store an Alternative Carrier (allocated on the stack).
+ * @details 128 bytes should be enough, the specification recommends to use short URIs as AC identifiers.
+ */
+#define NDEF_AC_BUFFER_SIZE (128)
+
+/** @brief NFC Forum Well-Known Type name for a Handover Select record */
+#define NDEF_HANDOVER_SELECT_TYPE_STR "Hs"
+/** @brief NFC Forum Well-Known Type name for a Handover Request record */
+#define NDEF_HANDOVER_REQUEST_TYPE_STR "Hr"
+/** @brief NFC Forum Well-Known Type name for a Handover Select Select (ascii value) */
+#define NDEF_HANDOVER_SELECT_TYPE 0x4872
+/** @brief NFC Forum Well-Known Type name for a Handover Request record (ascii value) */
+#define NDEF_HANDOVER_REQUEST_TYPE 0x4873
+/** @brief NFC Forum Handover record implemented version */
+#define NDEF_HANDOVER_VERSION_1_2 0x12
+
+/** @brief NFC Forum Well-Known Type name for a Colision Resolution record */
+#define NDEF_HANDOVER_COLLISION_RESOLUTION_TYPE_STR "cr"
+/** @brief NFC Forum Well-Known Type name for an Alternative Carrier record */
+#define NDEF_HANDOVER_ALTERNATIVE_CARRIER_TYPE_STR "ac"
+
+/** @brief NFC Forum Power States values mask */
+#define NDEF_HANDOVER_AC_CPS_MASK (0x3)
+/** @brief Enumerates the NFC Forum Power States possible values */
+typedef enum {
+ NDEF_HANDOVER_AC_CPS_INACTIVE = 0x0, /**< The HW for this Alternative Carrier has to be switch on before proceeding. */
+ NDEF_HANDOVER_AC_CPS_ACTIVE = 0x1, /**< The HW for this Alternative Carrier is currently running. */
+ NDEF_HANDOVER_AC_CPS_ACTIVATING = 0x2, /**< The HW for this Alternative Carrier is being activated. */
+ NDEF_HANDOVER_AC_CPS_UNKNOWN = 0x3 /**< The HW for this Alternative Carrier is unknown. */
+} Ndef_Handover_ac_cps_t;
+
+
+
+typedef struct {
+ uint8_t cps; /**< Current Power State for this Alternative Carrier Hardware. */
+ sRecordInfo_t ac_record; /**< The record structure used to store/build the Alternative Carrier record. */
+ uint8_t aux_data_ref_count; /**< The number of Auxiliary Data Reference for this Alternative Carrier. */
+ /* following fields are only used when reading NDEF */
+ uint8_t* aux_data_ref_start; /**< Internal field, managed by the library, to keep track of the Auxiliary Data Reference start address in the AC record. */
+ uint8_t* aux_data_ref_end; /**< Internal field, managed by the library, to keep track of the Auxiliary Data Reference end address in the AC record. */
+} Ndef_Handover_alternative_carrier_t;
+
+
+typedef struct {
+ uint16_t type; /**< Handover type: could be Select or Request. */
+ uint8_t version; /**< Version of the Handover record. */
+ /* following fields are only used when reading NDEF */
+ uint8_t has_cr; /**< Boolean, if true this Handover has a Collision Resolution nested record. */
+ uint16_t cr_random_number; /**< Random number for the Collision Resolution. */
+ uint8_t nb_alternative_carrier; /**< Number of Alternative Carrier nested records un this Handover. */
+ uint8_t* ac_start; /**< Internal field, managed by the library, to keep track of the Alternative Carrier Reference Data start address in the Handover record. */
+ uint8_t* ac_end; /**< Internal field, managed by the library, to keep track of the Alternative Carrier Reference Data end address in the Handover record. */
+} Ndef_Handover_t;
+
+
+
+uint16_t NDEF_ReadHandover(sRecordInfo_t *pRecord , Ndef_Handover_t *pHandover );
+uint16_t NDEF_ReadAC( uint8_t ac_nb, Ndef_Handover_t *pHandover , Ndef_Handover_alternative_carrier_t *pAC );
+uint16_t NDEF_ReadAuxData( uint8_t aux_data_nb, Ndef_Handover_alternative_carrier_t *pAC, sRecordInfo_t *pRecord );
+
+uint16_t NDEF_CreateHandover(Ndef_Handover_t *pHandover, sRecordInfo_t* pRecord );
+uint16_t NDEF_AddAlternativeCarrier(Ndef_Handover_alternative_carrier_t *pAC, char* CarrierDataRef, char **AuxDataRefID, sRecordInfo_t* pRecord );
+uint16_t NDEF_WriteHandover( sRecordInfo_t* pRecord , uint8_t* pNdef, I2C* mi2cChannel);
+
+uint32_t NDEF_GetACDataLength(Ndef_Handover_alternative_carrier_t *pAC,char *CarrierDataRef, char **AuxDataRefID);
+
+
+
+/** @}
+ */
+
+#endif /* __LIB_NDEF_HANDOVER_H */
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_MyApp.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,277 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_MyApp.c
+ * @author MMY Application Team
+ * @version $Revision: 2762 $
+ * @date $Date: 2016-08-10 16:40:40 +0200 (Wed, 10 Aug 2016) $
+ * @brief This file help to manage the NDEF file of a private application.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_MyApp.h"
+
+
+/** @addtogroup NFC_libraries
+ * @{
+ * @brief <b>This is the library used to manage the content of the TAG (data)
+ * But also the specific feature of the tag, for instance
+ * password, gpio... </b>
+ */
+
+
+/** @addtogroup libNFC_FORUM
+ * @{
+ * @brief This part of the library manage data which follow NFC forum organisation.
+ */
+
+/**
+ * @brief This buffer contains the data send/received by TAG
+ */
+extern uint8_t NDEF_Buffer [];
+
+/** @defgroup libMyApp_Private_Functions
+ * @{
+ */
+
+static void NDEF_Extract_M24SRDiscoveryApp_Input( sRecordInfo_t *pRecordStruct, sMyAppInfo *pMyAppStruct );
+
+/**
+ * @brief This function read the NDEF file and store application data in a structure.
+ * @param pRecordStruct : Pointer on the record structure.
+ * @param pMyAppStruct : pointer on the structure to fill.
+ */
+static void NDEF_Extract_M24SRDiscoveryApp_Input( sRecordInfo_t *pRecordStruct, sMyAppInfo *pMyAppStruct )
+{
+ uint8_t* pPayload;
+ uint8_t* pLook4Word;
+ uint16_t BackGroundColor, FontColor;
+ uint8_t i;
+
+ /* Read record header */
+ pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
+
+ /* initialize struct in case not matching found */
+ for( i = 0; i < 8; i++ )
+ {
+ /* Set the Back Color */
+ pMyAppStruct->LineX[i].BackGroundColor = 0xFFFF;
+ /* Set the Text Color */
+ pMyAppStruct->LineX[i].FontColor = 0x0000;
+ /* Set the line number */
+ pMyAppStruct->LineX[i].LineNb = i + 1;
+ /* Set the line content */
+ memcpy( pMyAppStruct->LineX[i].String, " ", 20 );
+ }
+
+ pLook4Word = pPayload;
+
+ for( i = 0; i < 4; i++ )
+ {
+ pMyAppStruct->LedBlinkConf.LedConf[i] = *pLook4Word;
+ pLook4Word++;
+ }
+ pMyAppStruct->LedBlinkConf.Speed = *pLook4Word;
+ pLook4Word++;
+
+ for( i = 0; i < 8; i++ )
+ {
+ /* Set the line number */
+ pMyAppStruct->LineX[i].LineNb = *pLook4Word;
+ pLook4Word++;
+ /* Set the Back Color */
+ BackGroundColor = (uint16_t)(*pLook4Word << 8);
+ BackGroundColor = BackGroundColor | (uint16_t)(*++pLook4Word );
+ pMyAppStruct->LineX[i].BackGroundColor = BackGroundColor;
+ pLook4Word++;
+ /* Set the Text Color */
+ FontColor = (uint16_t)(*pLook4Word << 8);
+ FontColor = FontColor | (uint16_t)(*++pLook4Word);
+ pMyAppStruct->LineX[i].FontColor = FontColor;
+ pLook4Word++;
+ /* Set the line content */
+ memcpy( pMyAppStruct->LineX[i].String, (char*)pLook4Word, 20 );
+ pLook4Word += 20;
+ }
+
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup libMyApp_Public_Functions
+ * @{
+ * @brief This file is used to manage proprietary NDEF (stored or loaded in tag)
+ */
+
+/**
+ * @brief This function read NDEF and retrieve Application information if any.
+ * @param pRecordStruct : Pointer on the record structure.
+ * @param pMyAppStruct : pointer on the structure to fill.
+ * @retval NDEF_OK : NDEF file data read in the tag.
+ * @retval NDEF_ERROR : not able to read NDEF in tag.
+ */
+uint16_t NDEF_ReadMyApp( sRecordInfo_t *pRecordStruct, sMyAppInfo *pMyAppStruct )
+{
+ uint16_t status = NDEF_ERROR;
+
+ if( pRecordStruct->NDEF_Type == M24SR_DISCOVERY_APP_TYPE )
+ {
+ NDEF_Extract_M24SRDiscoveryApp_Input( pRecordStruct, pMyAppStruct );
+ status = NDEF_OK;
+ }
+ else
+ {
+ status = NDEF_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief This function write the NDEF file with the Application data given in the structure.
+ * @brief Only used for debug purpose in this firmware version.
+ * @param pMyAppStruct : pointer on structure that contain the application information.
+ * @retval NDEF_OK : NDEF file data written in the tag.
+ * @retval NDEF_ERROR : not able to store NDEF in tag.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+ * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+ */
+uint16_t NDEF_WriteMyApp( sMyAppInfo *pMyAppStruct, I2C * mi2cChannel )
+{
+ uint16_t status = NDEF_ERROR;
+ uint16_t DataSize;
+ uint32_t PayloadSize;
+ uint8_t i;
+ uint8_t* pPayload;
+
+
+/* External Type Record Header */
+/************************************/
+/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
+/*----------------------------------*/
+/* MB ME CF SR IL TNF */ /* <---- IL=0, CF=0 and SR=1 TNF=4 NFC Forum external type*/
+/*----------------------------------*/
+/* TYPE LENGTH */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 3 */ /* <---- Not Used */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 2 */ /* <---- Not Used */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 1 */ /* <---- Not Used */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 0 */ /* The payload will always be 5 + 25*8=205 bytes for this application */
+/*----------------------------------*/
+/* ID LENGTH */ /* <---- Not Used */
+/*----------------------------------*/
+/* TYPE */ /* st.com:m24sr_discovery_democtrl */
+/*----------------------------------*/
+/* ID */ /* <---- Not Used */
+/************************************/
+
+
+ /* fill URI record header */
+ NDEF_Buffer[0] = 0xD4; /* Record Flag */
+ NDEF_Buffer[1] = M24SR_DISCOVERY_APP_STRING_LENGTH;
+ NDEF_Buffer[2] = 0x00; /* Will be filled at the end when payload size is known */
+
+ memcpy( &NDEF_Buffer[3], M24SR_DISCOVERY_APP_STRING, M24SR_DISCOVERY_APP_STRING_LENGTH );
+
+ pPayload = &NDEF_Buffer[ 3 + M24SR_DISCOVERY_APP_STRING_LENGTH];
+ PayloadSize = 0;
+
+ /**************************************************************/
+ /* BLINK CONFIG data */
+
+ /* led 1 blinking */
+ *pPayload = 0x03;
+ pPayload++;
+ /* led 2 blinking */
+ *pPayload = 0x02;
+ pPayload++;
+ /* led 3 blinking */
+ *pPayload = 0x02;
+ pPayload++;
+ /* led 4 blinking */
+ *pPayload = 0x03;
+ pPayload++;
+ /* speed */
+ *pPayload = 0x03;
+ pPayload++;
+
+ PayloadSize += 5;
+
+ /**************************************************************/
+
+ /**************************************************************/
+ /* SCREEN config data */
+ for( i = 0; i < 8; i++ )
+ {
+ /* Line number */
+ *pPayload = (uint8_t)(i + 1);
+ pPayload++;
+ /* Background color */
+ *pPayload = 0xFF - (0xFF/i);
+ pPayload++;
+ *pPayload = 0xFF - (0xFF/i);
+ pPayload++;
+ /* Font Color */
+ *pPayload = 0xFF/i;
+ pPayload++;
+ *pPayload = 0xFF/i;
+ pPayload++;
+ /* String */
+ memcpy( pPayload, "ABCDEFGHIJKLMNOPQRST", 20 );
+ pPayload += 20;
+
+ PayloadSize += 25;
+
+ }
+
+ NDEF_Buffer[2] = PayloadSize & 0x000000FF;
+
+ DataSize = PayloadSize + 5 + M24SR_DISCOVERY_APP_STRING_LENGTH;
+
+ /* Write NDEF */
+ status = NfcTag_WriteNDEF( DataSize, NDEF_Buffer, mi2cChannel );
+
+
+ return status;
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_MyApp.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,81 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_MyApp.h
+ * @author MMY Application Team
+ * @version $Revision: 2822 $
+ * @date $Date: 2016-09-05 16:18:16 +0200 (Mon, 05 Sep 2016) $
+ * @brief This file illustrate how to use M24SR with a proprietary protocol.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_MYAPP_H
+#define __LIB_NDEF_MYAPP_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+#define BLINK_CONFIG "<BLINK_CONFIG>"
+#define BLINK_CONFIG_STRING_SIZE 14
+#define BLINK_CONFIG_END "<\\BLINK_CONFIG>"
+#define BLINK_CONFIG_END_STRING_SIZE 15
+
+#define LINE_DESCR "<LINE_DESCR>"
+#define LINE_DESCR_STRING_SIZE 12
+#define LINE_DESCR_END "<\\LINE_DESCR>"
+#define LINE_DESCR_END_STRING_SIZE 13
+
+#define BLINKING_NONE 0x00
+#define BLINKING_SLOW 0x01
+#define BLINKING_MEDIUM 0x02
+#define BLINKING_FAST 0x03
+
+#define MYAPP_NB_LINES ((uint8_t)8)
+#define MYAPP_LED_CONF_INITAL_STATE ((uint8_t) 0x1)
+#define MYAPP_LED_CONF_BLINKING ((uint8_t) 0x2)
+
+typedef struct
+{
+ uint8_t LedConf[4];
+ uint8_t Speed;
+}sLedBlinkConfig;
+
+typedef struct
+{
+ uint8_t LineNb;
+ uint16_t BackGroundColor;
+ uint16_t FontColor;
+ char String[20];
+}sLineConfig;
+
+typedef struct
+{
+ sLedBlinkConfig LedBlinkConf;
+ sLineConfig LineX[MYAPP_NB_LINES];
+}sMyAppInfo;
+
+uint16_t NDEF_ReadMyApp( sRecordInfo_t *pRecordStruct, sMyAppInfo *pMyAppStruct );
+uint16_t NDEF_WriteMyApp( sMyAppInfo *pMyAppStruct, I2C * mi2cChannel );
+
+#endif /* __LIB_NDEF_MYAPP_H */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_SMS.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,370 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_SMS.c
+ * @author MMY Application Team
+ * @version $Revision: 2702 $
+ * @date $Date: 2016-07-13 18:45:05 +0200 (Wed, 13 Jul 2016) $
+ * @brief This file help to manage NDEF file that represent SMS.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_SMS.h"
+
+
+/** @addtogroup NFC_libraries
+ * @{
+ * @brief <b>This is the library used to manage the content of the TAG (data)
+ * But also the specific feature of the tag, for instance
+ * password, gpo... </b>
+ */
+
+
+/** @addtogroup libNFC_FORUM
+ * @{
+ * @brief This part of the library manage data which follow NFC forum organisation.
+ */
+
+/**
+ * @brief This buffer contains the data send/received by TAG
+ */
+extern uint8_t NDEF_Buffer [];
+
+/** @defgroup libSMS_Private_Functions
+ * @{
+ */
+
+static void NDEF_FillSMSStruct( uint8_t* pPayload, uint32_t PayloadSize, sSMSInfo *pSMSStruct );
+static void NDEF_ReadURI_SMS( sRecordInfo_t *pRecordStruct, sSMSInfo *pSMSStruct );
+
+/**
+ * @brief This function fill SMS structure with information of NDEF message.
+ * @param pPayload : pointer on the payload data of the NDEF message.
+ * @param PayloadSize : number of data in the payload.
+ * @param pSMSStruct : pointer on the structure to fill.
+ */
+static void NDEF_FillSMSStruct( uint8_t* pPayload, uint32_t PayloadSize, sSMSInfo *pSMSStruct )
+{
+ uint8_t* pLastByteAdd, *pLook4Word, *pEndString;
+ char* pKeyWord;
+ uint32_t SizeOfKeyWord;
+ pEndString = 0;
+
+ pKeyWord = SMS_TYPE_STRING;
+ SizeOfKeyWord = SMS_TYPE_STRING_LENGTH;
+
+ /* First character force to NULL in case not matching found */
+ *pSMSStruct->PhoneNumber = 0;
+ *pSMSStruct->Message = 0;
+
+ /* Interesting information are stored before picture if any */
+ /* Moreover picture is not used in this demonstration SW */
+ pLastByteAdd = (uint8_t*)(pPayload + PayloadSize);
+
+ pLook4Word = pPayload;
+ while( memcmp( pLook4Word, pKeyWord, SizeOfKeyWord ) && (pLook4Word < pLastByteAdd) )
+ {
+ pLook4Word++;
+ }
+
+ /* Retrieve phone number */
+ if( pLook4Word != pLastByteAdd )
+ {
+ pLook4Word += SizeOfKeyWord;
+ pEndString = pLook4Word;
+ while( memcmp( pEndString, URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH ) && (pEndString < pLastByteAdd) )
+ {
+ pEndString++;
+ }
+ if( pEndString != pLastByteAdd )
+ {
+ memcpy( pSMSStruct->PhoneNumber, pLook4Word, pEndString-pLook4Word );
+ /* add end of string character */
+ pSMSStruct->PhoneNumber[pEndString-pLook4Word] = 0;
+ }
+ }
+ pEndString += URI_FIRST_DATA_END_LENGTH;
+ pLook4Word = pEndString;
+
+ /* check if e-mail subject is present */
+ if( !memcmp( pLook4Word, MESSAGE_BEGIN_STRING, MESSAGE_BEGIN_STRING_LENGTH ) )
+ {
+ pEndString += MESSAGE_BEGIN_STRING_LENGTH;
+ /* Retrieve message */
+ memcpy( pSMSStruct->Message, pEndString, PayloadSize - (pEndString - pPayload) );
+ /* add end of string character */
+ pSMSStruct->Message[PayloadSize-(pEndString-pPayload)] = 0;
+ }
+}
+
+/**
+ * @brief This function read the SMS and store data in a structure.
+ * @param pRecordStruct : Pointer on the record structure.
+ * @param pSMSStruct : pointer on the structure to fill.
+ */
+static void NDEF_ReadURI_SMS( sRecordInfo_t *pRecordStruct, sSMSInfo *pSMSStruct )
+{
+ uint8_t* pPayload;
+ uint32_t PayloadSize;
+
+ PayloadSize = pRecordStruct->PayloadLength;
+
+ /* Read record header */
+ pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
+
+ if( pRecordStruct->NDEF_Type == URI_SMS_TYPE )
+ NDEF_FillSMSStruct( pPayload , PayloadSize, pSMSStruct );
+
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup libSMS_Public_Functions
+ * @{
+ * @brief This file is used to manage SMS (stored or loaded in tag)
+ */
+
+/**
+ * @brief This function read NDEF and retrieve SMS information if any.
+ * @param pRecordStruct : Pointer on the record structure.
+ * @param pSMSStruct : pointer on the structure to fill.
+ * @retval NDEF_OK : SMS information from NDEF have been retrieve.
+ * @retval NDEF_ERROR : Not able to retrieve SMS information.
+ */
+uint16_t NDEF_ReadSMS( sRecordInfo_t *pRecordStruct, sSMSInfo *pSMSStruct )
+{
+ uint16_t status = NDEF_ERROR;
+ sRecordInfo_t *pSPRecordStruct;
+ uint32_t PayloadSize, RecordPosition;
+ uint8_t* pData;
+
+ if( pRecordStruct->NDEF_Type == URI_SMS_TYPE )
+ {
+ NDEF_ReadURI_SMS( pRecordStruct, pSMSStruct );
+ status = NDEF_OK;
+ }
+ else if( pRecordStruct->NDEF_Type == SMARTPOSTER_TYPE )
+ {
+ for( RecordPosition = 0; RecordPosition < pRecordStruct->NbOfRecordInSPPayload; RecordPosition++ )
+ {
+ pSPRecordStruct = pRecordStruct->SPRecordStructAdd[RecordPosition];
+ if( pSPRecordStruct->NDEF_Type == URI_SMS_TYPE )
+ {
+ NDEF_ReadURI_SMS( pSPRecordStruct, pSMSStruct );
+ status = NDEF_OK;
+ }
+ if( pSPRecordStruct->NDEF_Type == TEXT_TYPE )
+ {
+ PayloadSize = pSPRecordStruct->PayloadLength;
+
+ /* The instruction content the UTF-8 language code that is not used here */
+ pData = (uint8_t*)pSPRecordStruct->PayloadBufferAdd;
+ PayloadSize -= *pData + 1; /* remove not usefull data */
+ pData += *pData + 1; /* set pointer on usefull data */
+
+ memcpy( pSMSStruct->Information, pData, PayloadSize );
+ /* add end of string character */
+ pSMSStruct->Information[PayloadSize] = 0;
+ }
+ }
+ }
+
+ return status;
+}
+
+/**
+ * @brief This function write the NDEF file with the SMS data given in the structure.
+ * @param pSMSStruct : pointer on structure that contain the SMS information.
+ * @retval NDEF_OK : NDEF file data written in the tag.
+ * @retval NDEF_ERROR : not able to store NDEF in tag.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+ * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+ */
+uint16_t NDEF_WriteSMS( sSMSInfo *pSMSStruct, I2C* mi2cChannel )
+{
+ uint16_t status = NDEF_ERROR, Offset = 0;
+
+ NDEF_PrepareSMSMessage( pSMSStruct, NDEF_Buffer, &Offset );
+
+ status = NfcTag_WriteNDEF( Offset , NDEF_Buffer, mi2cChannel );
+
+ return status;
+}
+
+/**
+ * @brief This function write the NDEF file with the SMS data given in the structure.
+ * @param pSMSStruct : pointer on structure that contain the SMS information.
+ * @param pNDEFMessage : pointer on the NDEF message.
+ * @param size : to store the size of the NDEF message generated.
+ */
+void NDEF_PrepareSMSMessage( sSMSInfo *pSMSStruct, uint8_t *pNDEFMessage, uint16_t *size )
+{
+ uint16_t Offset = 0;
+ uint32_t smsSize = 0;
+ uint32_t infoSize= 0;
+ uint32_t totalSize = 0;
+
+ /* SMS is an URI but can be included in a smart poster to add text to give instruction to user for instance */
+
+ /* SMS (smart poster) Record Header */
+/************************************/
+/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
+/*----------------------------------*/
+/* MB ME CF SR IL TNF */ /* <---- CF=0, IL=0 and SR=1 TNF=1 NFC Forum Well-known type*/
+/*----------------------------------*/
+/* TYPE LENGTH */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 3 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 2 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 1 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 0 */
+/*----------------------------------*/
+/* ID LENGTH */ /* <---- Not Used */
+/*----------------------------------*/
+/* TYPE */
+/*----------------------------------*/
+/* ID */ /* <---- Not Used */
+/************************************/
+
+ /* SMS : 1+sms:+tel+1+body=+message */
+ smsSize = 1 + SMS_TYPE_STRING_LENGTH + strlen(pSMSStruct->PhoneNumber) + URI_FIRST_DATA_END_LENGTH +
+ MESSAGE_BEGIN_STRING_LENGTH + strlen(pSMSStruct->Message);
+
+ /* Check if a Smart poster is needed */
+ if( pSMSStruct->Information[0] != '\0' )
+ {
+ /* Info : 1+2+info */
+ infoSize = 1 + ISO_ENGLISH_CODE_STRING_LENGTH + strlen(pSMSStruct->Information);
+ /* Total */
+ totalSize = 4 + smsSize + 4 + infoSize;
+ if( smsSize > 255 ) totalSize += 3; /* Normal Email size */
+ if( infoSize > 255 ) totalSize += 3; /* Normal Info size */
+
+ /* SmartPoster header */
+ if( totalSize > 255 )
+ {
+ pNDEFMessage[Offset++] = 0xC1;
+ pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (totalSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (totalSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (totalSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = totalSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = 0xD1;
+ pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (uint8_t)totalSize;
+ }
+ memcpy( &pNDEFMessage[Offset], SMART_POSTER_TYPE_STRING, SMART_POSTER_TYPE_STRING_LENGTH );
+ Offset += SMART_POSTER_TYPE_STRING_LENGTH;
+ }
+
+ /* SMS header */
+ pNDEFMessage[Offset] = 0x81;
+ if( smsSize < 256 ) pNDEFMessage[Offset] |= 0x10; // Set the SR bit
+ if( pSMSStruct->Information[0] == '\0' ) pNDEFMessage[Offset] |= 0x40; // Set the ME bit
+ Offset++;
+
+ pNDEFMessage[Offset++] = URI_TYPE_STRING_LENGTH;
+ if( smsSize > 255 )
+ {
+ pNDEFMessage[Offset++] = (smsSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (smsSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (smsSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = smsSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = (uint8_t)smsSize;
+ }
+ memcpy( &pNDEFMessage[Offset], URI_TYPE_STRING, URI_TYPE_STRING_LENGTH );
+ Offset += URI_TYPE_STRING_LENGTH;
+
+ /* SMS payload */
+ pNDEFMessage[Offset++] = URI_ID_0x00;
+ memcpy( &pNDEFMessage[Offset], SMS_TYPE_STRING, SMS_TYPE_STRING_LENGTH );
+ Offset += SMS_TYPE_STRING_LENGTH;
+ memcpy( &pNDEFMessage[Offset], pSMSStruct->PhoneNumber, strlen(pSMSStruct->PhoneNumber) );
+ Offset += strlen( pSMSStruct->PhoneNumber );
+ memcpy( &pNDEFMessage[Offset], URI_FIRST_DATA_END, URI_FIRST_DATA_END_LENGTH );
+ Offset += URI_FIRST_DATA_END_LENGTH;
+
+ memcpy( &pNDEFMessage[Offset], MESSAGE_BEGIN_STRING, MESSAGE_BEGIN_STRING_LENGTH );
+ Offset += MESSAGE_BEGIN_STRING_LENGTH;
+ memcpy( &pNDEFMessage[Offset], pSMSStruct->Message, strlen(pSMSStruct->Message) );
+ Offset += strlen( pSMSStruct->Message );
+
+ /* Information header */
+ if( pSMSStruct->Information[0] != '\0' )
+ {
+ if( infoSize > 255 )
+ {
+ pNDEFMessage[Offset++] = 0x41;
+ pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (infoSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (infoSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (infoSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = infoSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = 0x51;
+ pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (uint8_t)infoSize;
+ }
+
+ memcpy( &pNDEFMessage[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
+ Offset += TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH; /* UTF-8 with x byte language code */
+ memcpy( &pNDEFMessage[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
+ Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
+
+ /* Information payload */
+ memcpy( &pNDEFMessage[Offset], pSMSStruct->Information, strlen(pSMSStruct->Information) );
+ Offset += strlen( pSMSStruct->Information );
+ }
+
+ *size = (uint16_t)(Offset);
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_SMS.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,53 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_SMS.h
+ * @author MMY Application Team
+ * @version $Revision: 2475 $
+ * @date $Date: 2016-06-24 12:11:59 +0200 (Fri, 24 Jun 2016) $
+ * @brief This file help to manage SMS NDEF file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_SMS_H
+#define __LIB_NDEF_SMS_H
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+
+typedef struct
+{
+ char PhoneNumber[16];
+ char Message[400];
+ char Information[400];
+}sSMSInfo;
+
+uint16_t NDEF_ReadSMS( sRecordInfo_t *pRecordStruct, sSMSInfo *pSMSStruct );
+uint16_t NDEF_WriteSMS( sSMSInfo *pSMSStruct, I2C* mi2cChannel );
+void NDEF_PrepareSMSMessage( sSMSInfo *pSMSStruct, uint8_t *pNDEFMessage, uint16_t *size );
+
+
+#endif /* __LIB_NDEF_SMS_H */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Text.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,175 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Text.h
+ * @author MMY Application Team
+ * @version $Revision: 3210 $
+ * @date $Date: 2016-12-05 15:37:48 +0100 (Mon, 05 Dec 2016) $
+ * @brief This file help to manage Text NDEF file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_Text.h"
+
+/** @addtogroup NFC_libraries
+ * @{
+ * @brief <b>This is the library used to manage the content of the TAG (data)
+ * But also the specific feature of the tag, for instance
+ * password, gpo... </b>
+ */
+
+
+/** @addtogroup libNFC_FORUM
+ * @{
+ * @brief This part of the library manage data which follow NFC forum organisation.
+ */
+
+/**
+ * @brief This buffer contains the data send/received by TAG
+ */
+extern uint8_t NDEF_Buffer [];
+
+/**
+ * @}
+ */
+
+/** @defgroup libEmail_Public_Functions
+ * @{
+ * @brief This file is used to manage Email (stored or loaded in tag)
+ */
+
+/**
+ * @brief This function write the text in the TAG.
+ * @param text : text to write.
+ * @retval NDEF_OK : NDEF file data written in the tag.
+ * @retval NDEF_ERROR : not able to store NDEF in tag.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+ * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+ */
+uint16_t NDEF_WriteText( char *text, I2C * mi2cChannel )
+{
+ uint16_t status = NDEF_ERROR;
+ uint32_t textSize, Offset = 0;
+
+
+ /* TEXT : 1+en+message */
+ textSize = 3 + strlen(text);
+
+ /* TEXT header */
+ NDEF_Buffer[Offset] = 0xD1;
+ if( textSize < 256 ) NDEF_Buffer[Offset] |= 0x10; // Set the SR bit
+ Offset++;
+
+ NDEF_Buffer[Offset++] = TEXT_TYPE_STRING_LENGTH;
+ if( textSize > 255 )
+ {
+ NDEF_Buffer[Offset++] = (textSize & 0xFF000000) >> 24;
+ NDEF_Buffer[Offset++] = (textSize & 0x00FF0000) >> 16;
+ NDEF_Buffer[Offset++] = (textSize & 0x0000FF00) >> 8;
+ NDEF_Buffer[Offset++] = textSize & 0x000000FF;
+ }
+ else
+ {
+ NDEF_Buffer[Offset++] = (uint8_t)textSize;
+ }
+ memcpy( &NDEF_Buffer[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
+ Offset += TEXT_TYPE_STRING_LENGTH;
+
+ /* TEXT payload */
+ NDEF_Buffer[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH;
+ memcpy( &NDEF_Buffer[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
+ Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
+
+ memcpy( &NDEF_Buffer[Offset], text, strlen(text) );
+ Offset += strlen(text);
+
+ status = NfcTag_WriteNDEF( Offset , NDEF_Buffer, mi2cChannel );
+
+ return status;
+}
+
+
+/**
+ * @brief This function the Text information in a record if any.
+ * @param pRecordStruct Pointer on a NDEF record structure.
+ * @param pText A pointer on a text information structure, used to return the text & its metadata.
+ * @retval NDEF_OK Text information has been retrieved.
+ * @retval NDEF_ERROR The record is not a Text record.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL Language code or Text length is too big for the buffers.
+ */
+uint16_t NDEF_ReadText( sRecordInfo_t *pRecordStruct, NDEF_Text_info_t *pText )
+{
+ uint16_t status = NDEF_ERROR;
+
+ if( pRecordStruct->NDEF_Type == TEXT_TYPE )
+ {
+ /* Get the text metadata (status byte (encoding & language code length) + language code) */
+ NDEF_Text_metadata_t *text_record_info = (NDEF_Text_metadata_t *)pRecordStruct->PayloadBufferAdd;
+
+ uint32_t text_length = pRecordStruct->PayloadLength /* record length */
+ - text_record_info->language_length /* minus language code length */
+ - sizeof(uint8_t); /* minus the status byte length */
+
+ if((text_record_info->language_length >= NDEF_TEXT_LANGUAGE_CODE_MAX_LENGTH) ||
+ (text_length >= NDEF_TEXT_MAX_LENGTH))
+ {
+ /* One of the text info structure buffer is too small */
+ return NDEF_ERROR_MEMORY_INTERNAL;
+ }
+
+ /* Retrieve the encoding */
+ pText->encoding = (NDEF_Text_encoding_t)text_record_info->encoding;
+
+ /* Save the language code string (adding null char at the end) */
+ memcpy(&pText->language_code,text_record_info->language,text_record_info->language_length);
+ pText->language_code[text_record_info->language_length] = '\0';
+
+ /* Copy the text string itself (adding null char at the end) */
+ memcpy(&pText->text, text_record_info->language + text_record_info->language_length,text_length);
+ pText->text[text_length] = '\0';
+
+ status = NDEF_OK;
+ }
+ else
+ {
+ /* Not a text record, exit in error */
+ status = NDEF_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Text.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,70 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Text.h
+ * @author MMY Application Team
+ * @version $Revision: 3210 $
+ * @date $Date: 2016-12-05 15:37:48 +0100 (Mon, 05 Dec 2016) $
+ * @brief This file help to manage Text NDEF file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_TEXT_H
+#define __LIB_NDEF_TEXT_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+/** @brief NDEF Text buffer length. */
+#define NDEF_TEXT_MAX_LENGTH 40
+/** @brief NDEF Language code buffer length. */
+#define NDEF_TEXT_LANGUAGE_CODE_MAX_LENGTH 10
+
+/** @brief NDEF Text encoding possible values. */
+typedef enum {
+ NDEF_TEXT_UTF8 = 0,
+ NDEF_TEXT_UTF16 = 1
+} NDEF_Text_encoding_t;
+
+/** @brief This structure is used to handle information from a NDEF Text record. */
+typedef struct {
+ NDEF_Text_encoding_t encoding; /**< metadata: UTF-8 / UTF-16. */
+ char language_code[NDEF_TEXT_LANGUAGE_CODE_MAX_LENGTH]; /**< metadata: Language code as specified by IANA. */
+ char text[NDEF_TEXT_MAX_LENGTH]; /**< The text itself. */
+} NDEF_Text_info_t;
+
+
+/** @brief This structure is used to parse the raw data from a text record and access its metadata. */
+typedef struct {
+ uint8_t language_length:4; /**< Language code length. */
+ uint8_t rfu:3; /**< reserved for futur usage */
+ uint8_t encoding:1; /**< UTF-8 (0) or UTF-16 (1) encoding. */
+ char language[1]; /**< IANA language code. */
+} NDEF_Text_metadata_t;
+
+uint16_t NDEF_WriteText( char *text, I2C * mi2cChannel );
+uint16_t NDEF_ReadText( sRecordInfo_t *pRecordStruct, NDEF_Text_info_t *pText );
+
+
+#endif /* __LIB_NDEF_TEXT_H */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_URI.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,538 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_URI.c
+ * @author MMY Application Team
+ * @version $Revision: 2702 $
+ * @date $Date: 2016-07-13 18:45:05 +0200 (Wed, 13 Jul 2016) $
+ * @brief This file help to manage NDEF file that represent URI.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_URI.h"
+
+/** @addtogroup NFC_libraries
+ * @{
+ * @brief <b>This is the library used to manage the content of the TAG (data)
+ * But also the specific feature of the tag, for instance
+ * password, gpo... </b>
+ */
+
+
+/** @addtogroup libNFC_FORUM
+ * @{
+ * @brief This part of the library manage data which follow NFC forum organisation.
+ */
+
+/**
+ * @brief This buffer contains the data send/received by TAG
+ */
+extern uint8_t NDEF_Buffer [];
+
+/** @defgroup libURI_Private_Functions
+ * @{
+ */
+
+static void NDEF_Parse_WellKnowType( sRecordInfo_t *pRecordStruct, sURI_Info* pURI );
+
+/**
+ * @brief This function read the URI information and store data in a structure.
+ * @param pRecordStruct : Pointer on the record structure.
+ * @param pURI : pointer on the structure to fill.
+ */
+static void NDEF_Parse_WellKnowType( sRecordInfo_t *pRecordStruct, sURI_Info* pURI )
+{
+ uint32_t PayloadSize;
+ uint8_t Offset;
+ uint8_t* pPayload;
+
+ pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
+
+ switch( *pPayload )
+ {
+ case URI_ID_0x01:
+ memcpy( pURI->protocol, URI_ID_0x01_STRING, strlen(URI_ID_0x01_STRING) );
+ Offset = strlen( URI_ID_0x01_STRING );
+ break;
+
+ case URI_ID_0x02:
+ memcpy( pURI->protocol, URI_ID_0x02_STRING, strlen(URI_ID_0x02_STRING) );
+ Offset = strlen( URI_ID_0x02_STRING );
+ break;
+ case URI_ID_0x03:
+ memcpy( pURI->protocol, URI_ID_0x03_STRING, strlen(URI_ID_0x03_STRING) );
+ Offset = strlen( URI_ID_0x03_STRING );
+ break;
+
+ case URI_ID_0x04:
+ memcpy( pURI->protocol, URI_ID_0x04_STRING, strlen(URI_ID_0x04_STRING) );
+ Offset = strlen( URI_ID_0x04_STRING );
+ break;
+
+ case URI_ID_0x05:
+ memcpy( pURI->protocol, URI_ID_0x05_STRING, strlen(URI_ID_0x05_STRING) );
+ Offset = strlen( URI_ID_0x05_STRING );
+ break;
+
+ case URI_ID_0x06:
+ memcpy( pURI->protocol, URI_ID_0x06_STRING, strlen(URI_ID_0x06_STRING) );
+ Offset = strlen( URI_ID_0x06_STRING );
+ break;
+
+ case URI_ID_0x07:
+ memcpy( pURI->protocol, URI_ID_0x07_STRING, strlen(URI_ID_0x07_STRING) );
+ Offset = strlen( URI_ID_0x07_STRING );
+ break;
+
+ case URI_ID_0x08:
+ memcpy( pURI->protocol, URI_ID_0x08_STRING, strlen(URI_ID_0x08_STRING) );
+ Offset = strlen( URI_ID_0x08_STRING );
+ break;
+
+ case URI_ID_0x09:
+ memcpy( pURI->protocol, URI_ID_0x09_STRING, strlen(URI_ID_0x09_STRING) );
+ Offset = strlen( URI_ID_0x09_STRING );
+ break;
+
+ case URI_ID_0x0A:
+ memcpy( pURI->protocol, URI_ID_0x0A_STRING, strlen(URI_ID_0x0A_STRING) );
+ Offset = strlen( URI_ID_0x0A_STRING );
+ break;
+
+ case URI_ID_0x0B:
+ memcpy( pURI->protocol, URI_ID_0x0B_STRING, strlen(URI_ID_0x0B_STRING) );
+ Offset = strlen( URI_ID_0x0B_STRING );
+ break;
+
+ case URI_ID_0x0C:
+ memcpy( pURI->protocol, URI_ID_0x0C_STRING, strlen(URI_ID_0x0C_STRING) );
+ Offset = strlen( URI_ID_0x0C_STRING );
+ break;
+
+ case URI_ID_0x0D:
+ memcpy( pURI->protocol, URI_ID_0x0D_STRING, strlen(URI_ID_0x0D_STRING) );
+ Offset = strlen( URI_ID_0x0D_STRING );
+ break;
+
+ case URI_ID_0x0E:
+ memcpy( pURI->protocol, URI_ID_0x0E_STRING, strlen(URI_ID_0x0E_STRING) );
+ Offset = strlen( URI_ID_0x0E_STRING );
+ break;
+
+ case URI_ID_0x0F:
+ memcpy( pURI->protocol, URI_ID_0x0F_STRING, strlen(URI_ID_0x0F_STRING) );
+ Offset = strlen( URI_ID_0x0F_STRING );
+ break;
+
+ case URI_ID_0x10:
+ memcpy( pURI->protocol, URI_ID_0x10_STRING, strlen(URI_ID_0x10_STRING) );
+ Offset = strlen( URI_ID_0x10_STRING );
+ break;
+
+ case URI_ID_0x11:
+ memcpy( pURI->protocol, URI_ID_0x11_STRING, strlen(URI_ID_0x11_STRING) );
+ Offset = strlen( URI_ID_0x11_STRING );
+ break;
+
+ case URI_ID_0x12:
+ memcpy( pURI->protocol, URI_ID_0x12_STRING, strlen(URI_ID_0x12_STRING) );
+ Offset = strlen( URI_ID_0x12_STRING );
+ break;
+
+ case URI_ID_0x13:
+ memcpy( pURI->protocol, URI_ID_0x13_STRING, strlen(URI_ID_0x13_STRING) );
+ Offset = strlen( URI_ID_0x13_STRING );
+ break;
+
+ case URI_ID_0x14:
+ memcpy( pURI->protocol, URI_ID_0x14_STRING, strlen(URI_ID_0x14_STRING) );
+ Offset = strlen( URI_ID_0x14_STRING );
+ break;
+
+ case URI_ID_0x15:
+ memcpy( pURI->protocol, URI_ID_0x15_STRING, strlen(URI_ID_0x15_STRING) );
+ Offset = strlen( URI_ID_0x15_STRING );
+ break;
+
+ case URI_ID_0x16:
+ memcpy( pURI->protocol, URI_ID_0x16_STRING, strlen(URI_ID_0x16_STRING) );
+ Offset = strlen( URI_ID_0x16_STRING );
+ break;
+
+ case URI_ID_0x17:
+ memcpy( pURI->protocol, URI_ID_0x17_STRING, strlen(URI_ID_0x17_STRING) );
+ Offset = strlen( URI_ID_0x17_STRING );
+ break;
+
+ case URI_ID_0x18:
+ memcpy( pURI->protocol, URI_ID_0x18_STRING, strlen(URI_ID_0x18_STRING) );
+ Offset = strlen( URI_ID_0x18_STRING );
+ break;
+
+ case URI_ID_0x19:
+ memcpy( pURI->protocol, URI_ID_0x19_STRING, strlen(URI_ID_0x19_STRING) );
+ Offset = strlen( URI_ID_0x19_STRING );
+ break;
+
+ case URI_ID_0x1A:
+ memcpy( pURI->protocol, URI_ID_0x1A_STRING, strlen(URI_ID_0x1A_STRING) );
+ Offset = strlen( URI_ID_0x1A_STRING );
+ break;
+
+ case URI_ID_0x1B:
+ memcpy( pURI->protocol, URI_ID_0x1B_STRING, strlen(URI_ID_0x1B_STRING) );
+ Offset = strlen( URI_ID_0x1B_STRING );
+ break;
+
+ case URI_ID_0x1C:
+ memcpy( pURI->protocol, URI_ID_0x1C_STRING, strlen(URI_ID_0x1C_STRING) );
+ Offset = strlen( URI_ID_0x1C_STRING );
+ break;
+
+ case URI_ID_0x1D:
+ memcpy( pURI->protocol, URI_ID_0x1D_STRING, strlen(URI_ID_0x1D_STRING) );
+ Offset = strlen( URI_ID_0x1D_STRING );
+ break;
+
+ case URI_ID_0x1E:
+ memcpy( pURI->protocol, URI_ID_0x1E_STRING, strlen(URI_ID_0x1E_STRING) );
+ Offset = strlen( URI_ID_0x1E_STRING );
+ break;
+
+ case URI_ID_0x1F:
+ memcpy( pURI->protocol, URI_ID_0x1F_STRING, strlen(URI_ID_0x1F_STRING) );
+ Offset = strlen( URI_ID_0x1F_STRING );
+ break;
+
+ case URI_ID_0x20:
+ memcpy( pURI->protocol, URI_ID_0x20_STRING, strlen(URI_ID_0x20_STRING) );
+ Offset = strlen( URI_ID_0x20_STRING );
+ break;
+
+ case URI_ID_0x21:
+ memcpy( pURI->protocol, URI_ID_0x21_STRING, strlen(URI_ID_0x21_STRING) );
+ Offset = strlen( URI_ID_0x21_STRING );
+ break;
+
+ case URI_ID_0x22:
+ memcpy( pURI->protocol, URI_ID_0x22_STRING, strlen(URI_ID_0x22_STRING) );
+ Offset = strlen( URI_ID_0x22_STRING );
+ break;
+
+ case URI_ID_0x23:
+ memcpy( pURI->protocol, URI_ID_0x23_STRING, strlen(URI_ID_0x23_STRING) );
+ Offset = strlen( URI_ID_0x23_STRING );
+ break;
+ default:
+ Offset = 0;
+ /* Should not happened */
+ break;
+ }
+ /* add end of string character */
+ pURI->protocol[Offset] = '\0';
+
+ pPayload++; /* go after well know byte */
+
+ PayloadSize = pRecordStruct->PayloadLength;
+
+ PayloadSize = PayloadSize - 1; /* remove well know byte */
+
+ memcpy( pURI->URI_Message, pPayload, PayloadSize );
+ /* add end of string character */
+ pURI->URI_Message[PayloadSize] = '\0';
+
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup libURI_Public_Functions
+ * @{
+ * @brief This file is used to manage URI (stored or loaded in tag)
+ */
+
+/**
+ * @brief This function read NDEF and retrieve URI information if any.
+ * @param pRecordStruct : Pointer on the record structure.
+ * @param pURI : pointer on the structure to fill.
+ * @retval NDEF_OK : URI information from NDEF have been retrieved.
+ * @retval NDEF_ERROR : Not able to retrieve URI information.
+ */
+uint16_t NDEF_ReadURI( sRecordInfo_t *pRecordStruct, sURI_Info *pURI )
+{
+ uint16_t status = NDEF_ERROR;
+ sRecordInfo_t *pSPRecordStruct;
+ uint32_t PayloadSize, RecordPosition;
+ uint8_t* pData;
+
+ if( pRecordStruct->NDEF_Type == WELL_KNOWN_ABRIDGED_URI_TYPE )
+ {
+ NDEF_Parse_WellKnowType( pRecordStruct, pURI );
+ status = NDEF_OK;
+ }
+ else if( pRecordStruct->NDEF_Type == SMARTPOSTER_TYPE )
+ {
+ for( RecordPosition = 0; RecordPosition < pRecordStruct->NbOfRecordInSPPayload; RecordPosition++ )
+ {
+ pSPRecordStruct = pRecordStruct->SPRecordStructAdd[RecordPosition];
+ if( pSPRecordStruct->NDEF_Type == WELL_KNOWN_ABRIDGED_URI_TYPE )
+ {
+ NDEF_Parse_WellKnowType( pSPRecordStruct, pURI );
+ status = NDEF_OK;
+ }
+ if( pSPRecordStruct->NDEF_Type == TEXT_TYPE )
+ {
+ PayloadSize = pSPRecordStruct->PayloadLength;
+
+ /* The instruction content the UTF-8 language code that is not used here */
+ pData = (uint8_t*)pSPRecordStruct->PayloadBufferAdd;
+ PayloadSize -= *pData + 1; /* remove not usefull data */
+ pData += *pData + 1;
+
+ memcpy( pURI->Information, pData, PayloadSize );
+ }
+ }
+ }
+ else
+ {
+ status = NDEF_ERROR;
+ }
+
+ return status;
+}
+
+/**
+ * @brief This function prepare the NDEF message with the URI data given in the structure.
+ * @param pURI : pointer on structure that contain the URI information.
+ * @param pNDEFMessage : pointer on the NDEF message.
+ * @param size : to store the size of the NDEF message generated.
+ */
+void NDEF_PrepareURIMessage( sURI_Info *pURI, uint8_t *pNDEFMessage, uint16_t *size )
+{
+ uint32_t uriSize, totalSize, Offset = 0;
+ uint32_t infoSize = 0;
+ char type;
+
+ /* An URI can be included in a smart poster to add text to give instruction to user for instance */
+
+ /* URI (smart poster) Record Header */
+/************************************/
+/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
+/*----------------------------------*/
+/* MB ME CF SR IL TNF */ /* <---- CF=0, IL=0 and SR=1 TNF=1 NFC Forum Well-known type*/
+/*----------------------------------*/
+/* TYPE LENGTH */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 3 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 2 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 1 */ /* <---- Used only if SR=0 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 0 */
+/*----------------------------------*/
+/* ID LENGTH */ /* <---- Not Used */
+/*----------------------------------*/
+/* TYPE */
+/*----------------------------------*/
+/* ID */ /* <---- Not Used */
+/************************************/
+
+ /* We need to know the URI type in order to define if an abreviation is available */
+ type = getUriType( pURI->protocol );
+
+ /* URI : 1+URI for abreviate protocol*/
+ if( type != URI_ID_0x00 )
+ uriSize = 1 + strlen(pURI->URI_Message);
+ else /*: 1+protocol+URI else*/
+ uriSize = 1 + strlen(pURI->protocol) + strlen(pURI->URI_Message);
+
+ /* Check if a Smart poster is needed */
+ if( pURI->Information[0] != '\0' )
+ {
+ /* Info : 1+2+info */
+ infoSize = 1 + ISO_ENGLISH_CODE_STRING_LENGTH + strlen(pURI->Information);
+ /* Total */
+ totalSize = 4 + uriSize + 4 + infoSize;
+ if( uriSize > 255 ) totalSize += 3; /* Normal URI size */
+ if( infoSize > 255 ) totalSize += 3; /* Normal Info size */
+
+ /* SmartPoster header */
+ if( totalSize > 255 )
+ {
+ pNDEFMessage[Offset++] = 0xC1;
+ pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (totalSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (totalSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (totalSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = totalSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = 0xD1;
+ pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (uint8_t)totalSize;
+ }
+ memcpy( &pNDEFMessage[Offset], SMART_POSTER_TYPE_STRING, SMART_POSTER_TYPE_STRING_LENGTH );
+ Offset += SMART_POSTER_TYPE_STRING_LENGTH;
+ }
+
+ /* URI header */
+ pNDEFMessage[Offset] = 0x81;
+ if( uriSize < 256 ) pNDEFMessage[Offset] |= 0x10; // Set the SR bit
+ if( pURI->Information[0] == '\0' ) pNDEFMessage[Offset] |= 0x40; // Set the ME bit
+ Offset++;
+
+ pNDEFMessage[Offset++] = URI_TYPE_STRING_LENGTH;
+ if( uriSize > 255 )
+ {
+ pNDEFMessage[Offset++] = (uriSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (uriSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (uriSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = uriSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = (uint8_t)uriSize;
+ }
+ memcpy( &pNDEFMessage[Offset], URI_TYPE_STRING, URI_TYPE_STRING_LENGTH );
+ Offset += URI_TYPE_STRING_LENGTH;
+
+ pNDEFMessage[Offset++] = type;
+ if( type == URI_ID_0x00 ) // No abreviation
+ {
+ memcpy( &pNDEFMessage[Offset], pURI->protocol, strlen(pURI->protocol) );
+ Offset += strlen(pURI->protocol);
+ }
+
+ memcpy( &pNDEFMessage[Offset], pURI->URI_Message, strlen(pURI->URI_Message) );
+ Offset += strlen(pURI->URI_Message);
+
+ /* Information header */
+ if( pURI->Information[0] != '\0' )
+ {
+ if( infoSize > 255 )
+ {
+ pNDEFMessage[Offset++] = 0x41;
+ pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (infoSize & 0xFF000000) >> 24;
+ pNDEFMessage[Offset++] = (infoSize & 0x00FF0000) >> 16;
+ pNDEFMessage[Offset++] = (infoSize & 0x0000FF00) >> 8;
+ pNDEFMessage[Offset++] = infoSize & 0x000000FF;
+ }
+ else
+ {
+ pNDEFMessage[Offset++] = 0x51;
+ pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = (uint8_t)infoSize;
+ }
+
+ memcpy( &pNDEFMessage[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH );
+ Offset+=TEXT_TYPE_STRING_LENGTH;
+ pNDEFMessage[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH; /* UTF-8 with x byte language code */
+ memcpy( &pNDEFMessage[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH );
+ Offset += ISO_ENGLISH_CODE_STRING_LENGTH;
+
+ /* Information payload */
+ memcpy( &pNDEFMessage[Offset], pURI->Information, strlen(pURI->Information) );
+ Offset += strlen(pURI->Information);
+ }
+
+ *size = Offset;
+
+}
+/**
+ * @brief This function write the NDEF file with the URI data given in the structure.
+ * @param pURI : pointer on structure that contain the URI information.
+ * @retval NDEF_OK : NDEF file data written in the tag.
+ * @retval NDEF_ERROR : not able to store NDEF in tag.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL : Cannot write to tag.
+ * @retval NDEF_ERROR_NOT_FORMATED : CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG : Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED : Tag locked, cannot be write.
+ */
+uint16_t NDEF_WriteURI( sURI_Info *pURI, I2C* mi2cChannel )
+{
+ uint16_t status = NDEF_ERROR, Offset = 0;
+
+ NDEF_PrepareURIMessage( pURI, NDEF_Buffer, &Offset );
+
+
+ status = NfcTag_WriteNDEF( Offset , NDEF_Buffer, mi2cChannel );
+
+ return status;
+}
+
+char getUriType( char *protocol )
+{
+ if( !memcmp( protocol, URI_ID_0x01_STRING, strlen(URI_ID_0x01_STRING) ) ) return URI_ID_0x01;
+ else if( !memcmp( protocol, URI_ID_0x02_STRING, strlen(URI_ID_0x02_STRING) ) ) return URI_ID_0x02;
+ else if( !memcmp( protocol, URI_ID_0x03_STRING, strlen(URI_ID_0x03_STRING) ) ) return URI_ID_0x03;
+ else if( !memcmp( protocol, URI_ID_0x04_STRING, strlen(URI_ID_0x04_STRING) ) ) return URI_ID_0x04;
+ else if( !memcmp( protocol, URI_ID_0x05_STRING, strlen(URI_ID_0x05_STRING) ) ) return URI_ID_0x05;
+ else if( !memcmp( protocol, URI_ID_0x06_STRING, strlen(URI_ID_0x06_STRING) ) ) return URI_ID_0x06;
+ else if( !memcmp( protocol, URI_ID_0x07_STRING, strlen(URI_ID_0x07_STRING) ) ) return URI_ID_0x07;
+ else if( !memcmp( protocol, URI_ID_0x08_STRING, strlen(URI_ID_0x08_STRING) ) ) return URI_ID_0x08;
+ else if( !memcmp( protocol, URI_ID_0x09_STRING, strlen(URI_ID_0x09_STRING) ) ) return URI_ID_0x09;
+ else if( !memcmp( protocol, URI_ID_0x0A_STRING, strlen(URI_ID_0x0A_STRING) ) ) return URI_ID_0x0A;
+ else if( !memcmp( protocol, URI_ID_0x0B_STRING, strlen(URI_ID_0x0B_STRING) ) ) return URI_ID_0x0B;
+ else if( !memcmp( protocol, URI_ID_0x0C_STRING, strlen(URI_ID_0x0C_STRING) ) ) return URI_ID_0x0C;
+ else if( !memcmp( protocol, URI_ID_0x0D_STRING, strlen(URI_ID_0x0D_STRING) ) ) return URI_ID_0x0D;
+ else if( !memcmp( protocol, URI_ID_0x0E_STRING, strlen(URI_ID_0x0E_STRING) ) ) return URI_ID_0x0E;
+ else if( !memcmp( protocol, URI_ID_0x0F_STRING, strlen(URI_ID_0x0F_STRING) ) ) return URI_ID_0x0F;
+ else if( !memcmp( protocol, URI_ID_0x10_STRING, strlen(URI_ID_0x10_STRING) ) ) return URI_ID_0x10;
+ else if( !memcmp( protocol, URI_ID_0x11_STRING, strlen(URI_ID_0x11_STRING) ) ) return URI_ID_0x11;
+ else if( !memcmp( protocol, URI_ID_0x12_STRING, strlen(URI_ID_0x12_STRING) ) ) return URI_ID_0x12;
+ else if( !memcmp( protocol, URI_ID_0x13_STRING, strlen(URI_ID_0x13_STRING) ) ) return URI_ID_0x13;
+ else if( !memcmp( protocol, URI_ID_0x14_STRING, strlen(URI_ID_0x14_STRING) ) ) return URI_ID_0x14;
+ else if( !memcmp( protocol, URI_ID_0x15_STRING, strlen(URI_ID_0x15_STRING) ) ) return URI_ID_0x15;
+ else if( !memcmp( protocol, URI_ID_0x16_STRING, strlen(URI_ID_0x16_STRING) ) ) return URI_ID_0x16;
+ else if( !memcmp( protocol, URI_ID_0x17_STRING, strlen(URI_ID_0x17_STRING) ) ) return URI_ID_0x17;
+ else if( !memcmp( protocol, URI_ID_0x18_STRING, strlen(URI_ID_0x18_STRING) ) ) return URI_ID_0x18;
+ else if( !memcmp( protocol, URI_ID_0x19_STRING, strlen(URI_ID_0x19_STRING) ) ) return URI_ID_0x19;
+ else if( !memcmp( protocol, URI_ID_0x1A_STRING, strlen(URI_ID_0x1A_STRING) ) ) return URI_ID_0x1A;
+ else if( !memcmp( protocol, URI_ID_0x1B_STRING, strlen(URI_ID_0x1B_STRING) ) ) return URI_ID_0x1B;
+ else if( !memcmp( protocol, URI_ID_0x1C_STRING, strlen(URI_ID_0x1C_STRING) ) ) return URI_ID_0x1C;
+ else if( !memcmp( protocol, URI_ID_0x1D_STRING, strlen(URI_ID_0x1D_STRING) ) ) return URI_ID_0x1D;
+ else if( !memcmp( protocol, URI_ID_0x1E_STRING, strlen(URI_ID_0x1E_STRING) ) ) return URI_ID_0x1E;
+ else if( !memcmp( protocol, URI_ID_0x1F_STRING, strlen(URI_ID_0x1F_STRING) ) ) return URI_ID_0x1F;
+ else if( !memcmp( protocol, URI_ID_0x20_STRING, strlen(URI_ID_0x20_STRING) ) ) return URI_ID_0x20;
+ else if( !memcmp( protocol, URI_ID_0x21_STRING, strlen(URI_ID_0x21_STRING) ) ) return URI_ID_0x21;
+ else if( !memcmp( protocol, URI_ID_0x22_STRING, strlen(URI_ID_0x22_STRING) ) ) return URI_ID_0x22;
+ else if( !memcmp( protocol, URI_ID_0x23_STRING, strlen(URI_ID_0x23_STRING) ) ) return URI_ID_0x23;
+ else return URI_ID_0x00; // No abreviation for this protocol
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_URI.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,57 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_URI.h
+ * @author MMY Application Team
+ * @version $Revision: 2475 $
+ * @date $Date: 2016-06-24 12:11:59 +0200 (Fri, 24 Jun 2016) $
+ * @brief This file help to manage URI NDEF file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_URI_H
+#define __LIB_NDEF_URI_H
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+typedef struct
+{
+// char protocol[80];
+// char URI_Message[400];
+// char Information[400];
+ char protocol[20];
+ char URI_Message[100];
+ char Information[20];
+}sURI_Info;
+
+uint16_t NDEF_ReadURI(sRecordInfo_t *pRecordStruct, sURI_Info *pURI);
+uint16_t NDEF_WriteURI(sURI_Info *pURI, I2C* mi2cChannel);
+
+void NDEF_PrepareURIMessage( sURI_Info *pURI, uint8_t *pNDEFMessage, uint16_t *size );
+char getUriType( char *protocol );
+
+
+#endif /* __LIB_NDEF_URI_H */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Vcard.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,620 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Vcard.c
+ * @author MMY Application Team
+ * @version $Revision: 3210 $
+ * @date $Date: 2016-12-05 15:37:48 +0100 (Mon, 05 Dec 2016) $
+ * @brief This file help to manage NDEF file that represent Vcard.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_Vcard.h"
+
+
+/** @addtogroup lib_NDEF_Vcard
+ * @ingroup libNDEF
+ * @{
+ * @brief This part of the library manage the data which follow NFC forum organisation.
+ */
+
+/* This buffer contains the data sent/received by TAG */
+extern uint8_t NDEF_Buffer [];
+
+static void NDEF_FillVcardStruct( uint8_t* pPayload, uint32_t PayloadSize, char* pKeyWord, uint32_t SizeOfKeyWord, uint8_t* pString );
+static void NDEF_ExtractVcard( sRecordInfo_t *pRecordStruct, sVcardInfo *pVcardStruct );
+
+/**
+ * @brief This function extracts a Vcard particular property from a vCard.
+ * @param pPayload Pointer on the vCard payload data of the vCard record.
+ * @param PayloadSize Number of bytes in the vCard payload.
+ * @param pKeyWord Pointer on the vCard property keyword to look for.
+ * @param SizeOfKeyWord Number of bytes of the vCard property keyword we are looking for.
+ * @param pString Pointer on a string used to return the vCard property read.
+ */
+static void NDEF_FillVcardStruct( uint8_t* pPayload, uint32_t PayloadSize, char* pKeyWord, uint32_t SizeOfKeyWord, uint8_t* pString )
+{
+ uint8_t* pLastByteAdd, *pLook4Word, *pEndString;
+
+ /* First character force to NULL in case not matching found */
+ *pString = 0;
+
+ /* Interresting information are stored before picture if any */
+ /* Moreover picture is not used in this demonstration SW */
+ pLastByteAdd = pPayload;
+ while( memcmp( pLastByteAdd, JPEG, JPEG_STRING_SIZE ) && (pLastByteAdd < (pPayload + PayloadSize)) )
+ {
+ pLastByteAdd++;
+ }
+
+ pLook4Word = pPayload;
+ while( memcmp( pLook4Word, pKeyWord, SizeOfKeyWord ) && (pLook4Word < pLastByteAdd) )
+ {
+ pLook4Word++;
+ }
+
+ /* Word found */
+ if( pLook4Word != pLastByteAdd )
+ {
+ pLook4Word += SizeOfKeyWord;
+ pEndString = pLook4Word;
+ while( memcmp( pEndString, LIMIT, LIMIT_STRING_SIZE ) && (pEndString < pLastByteAdd) )
+ {
+ pEndString++;
+ }
+ if( pEndString != pLastByteAdd )
+ {
+ memcpy( pString, pLook4Word, pEndString-pLook4Word );
+ /* add end of string character */
+ pString += pEndString - pLook4Word;
+ *pString = '\0';
+ }
+ }
+}
+
+/**
+ * @brief This function reads a Vcard record and stores data in a `sVcardInfo` structure.
+ * @param pRecordStruct Pointer on the vCard record structure.
+ * @param pVcardStruct Pointer on the `sCardInfo` structure to fill.
+ */
+static void NDEF_ExtractVcard( sRecordInfo_t *pRecordStruct, sVcardInfo *pVcardStruct )
+{
+ uint32_t PayloadSize;
+ uint8_t* pPayload;
+
+
+ PayloadSize = pRecordStruct->PayloadLength;
+
+ /* Read record header */
+ pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
+
+ NDEF_FillVcardStruct( pPayload, PayloadSize, VERSION, VERSION_STRING_SIZE, (uint8_t*)(pVcardStruct->Version) );
+ if( !memcmp( pVcardStruct->Version, VCARD_VERSION_2_1, VCARD_VERSION_2_1_SIZE ) )
+ {
+ NDEF_FillVcardStruct( pPayload, PayloadSize, FIRSTNAME, FIRSTNAME_STRING_SIZE, (uint8_t*)(pVcardStruct->FirstName) );
+ NDEF_FillVcardStruct( pPayload, PayloadSize, TITLE, TITLE_STRING_SIZE, (uint8_t*)(pVcardStruct->Title) );
+ NDEF_FillVcardStruct( pPayload, PayloadSize, ORG, ORG_STRING_SIZE, (uint8_t*)(pVcardStruct->Org) );
+ NDEF_FillVcardStruct( pPayload, PayloadSize, HOME_ADDRESS, HOME_ADDRESS_STRING_SIZE, (uint8_t*)(pVcardStruct->HomeAddress) );
+ NDEF_FillVcardStruct( pPayload, PayloadSize, GEN_ADDRESS, strlen(GEN_ADDRESS), (uint8_t*)(pVcardStruct->Address) );
+ NDEF_FillVcardStruct( pPayload, PayloadSize, WORK_ADDRESS, WORK_ADDRESS_STRING_SIZE, (uint8_t*)(pVcardStruct->WorkAddress) );
+ NDEF_FillVcardStruct( pPayload, PayloadSize, HOME_TEL, HOME_TEL_STRING_SIZE, (uint8_t*)(pVcardStruct->HomeTel) );
+ NDEF_FillVcardStruct( pPayload, PayloadSize, WORK_TEL, WORK_TEL_STRING_SIZE, (uint8_t*)(pVcardStruct->WorkTel) );
+ NDEF_FillVcardStruct( pPayload, PayloadSize, CELL_TEL, CELL_TEL_STRING_SIZE, (uint8_t*)(pVcardStruct->CellTel) );
+ NDEF_FillVcardStruct( pPayload, PayloadSize, HOME_EMAIL, HOME_EMAIL_STRING_SIZE, (uint8_t*)(pVcardStruct->HomeEmail) );
+ NDEF_FillVcardStruct( pPayload, PayloadSize, GEN_EMAIL, strlen(GEN_EMAIL), (uint8_t*)(pVcardStruct->Email) );
+ NDEF_FillVcardStruct( pPayload, PayloadSize, WORK_EMAIL, WORK_EMAIL_STRING_SIZE, (uint8_t*)(pVcardStruct->WorkEmail) );
+ }
+ else if( !memcmp( pVcardStruct->Version, VCARD_VERSION_3_0, VCARD_VERSION_3_0_SIZE ) )
+ {
+ /* need to be implemented */
+ }
+ else
+ {
+ /* maybe new version but not supported in this sw */
+ }
+
+}
+
+/**
+ * @brief This function reads a Vcard record and stores data in a `sVcardInfo` structure.
+ * @param pRecordStruct Pointer on the vCard record structure.
+ * @param pVcardStruct Pointer on the `sCardInfo` structure to fill.
+ * @retval NDEF_OK The Vcard information has been retrieved.
+ * @retval NDEF_ERROR Not able to retrieve the Vcard information.
+ */
+uint16_t NDEF_ReadVcard( sRecordInfo_t *pRecordStruct, sVcardInfo *pVcardStruct )
+{
+ uint16_t status = NDEF_ERROR;
+
+ if( pRecordStruct->NDEF_Type == VCARD_TYPE )
+ {
+ NDEF_ExtractVcard( pRecordStruct, pVcardStruct );
+ status = NDEF_OK;
+ }
+
+ return status;
+}
+
+/**
+ * @brief This function writes a NDEF message to the NFC tag with the Vcard data given in a `sVcardInfo` structure.
+ * @param pVcardStruct Pointer on a `sVcardInfo` structure containing the Vcard information.
+ * @retval NDEF_OK NDEF file data written in the tag.
+ * @retval NDEF_ERROR Not able to store the NDEF in tag.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL Cannot write to tag.
+ * @retval NDEF_ERROR_NOT_FORMATED CCFile data not supported or not present.
+ * @retval NDEF_ERROR_MEMORY_TAG Size not compatible with memory.
+ * @retval NDEF_ERROR_LOCKED Tag locked, cannot be write.
+ */
+uint16_t NDEF_WriteVcard( sVcardInfo *pVcardStruct, I2C* mi2cChannel )
+{
+ uint16_t status = NDEF_ERROR, Offset = 0;
+
+ NDEF_PrepareVcardMessage( pVcardStruct, NDEF_Buffer, &Offset );
+
+ status = NfcTag_WriteNDEF( Offset , NDEF_Buffer, mi2cChannel );
+
+ return status;
+}
+
+/**
+ * @brief This function computes the size of a Vcard record from the data given in the `sVcardInfo` structure.
+ * @param pVcardStruct Pointer on a `sVcardInfo` structure containing the Vcard information.
+ * @return vCard record data size in bytes (excluding record metadata).
+ */
+uint32_t NDEF_GetVcardLength( sVcardInfo *pVcardStruct)
+{
+
+ uint32_t PayloadSize = 0;
+
+ /* "BEGIN:VCARD\r\n" */
+ PayloadSize += BEGIN_STRING_SIZE;
+ PayloadSize += VCARD_STRING_SIZE;
+ PayloadSize += LIMIT_STRING_SIZE;
+
+ /* "VERSION:2.1\r\n" */
+ PayloadSize += VERSION_STRING_SIZE;
+ PayloadSize += VCARD_VERSION_2_1_SIZE;
+ PayloadSize += LIMIT_STRING_SIZE;
+
+ /* "N:\r\n" */
+ if(*pVcardStruct->Name != '\0')
+ {
+ PayloadSize += VCARD_NAME_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->Name );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ /* "FN:\r\n" */
+ if(*pVcardStruct->FirstName != '\0')
+ {
+ PayloadSize += FIRSTNAME_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->FirstName );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->Title != '\0')
+ {
+ /* "TITLE:\r\n" */
+ PayloadSize += TITLE_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->Title );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->Org != '\0')
+ {
+ /* "ORG:\r\n" */
+ PayloadSize += ORG_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->Org );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->Url != '\0')
+ {
+ /* "URL:\r\n" */
+ PayloadSize += URL_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->Url );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->HomeAddress != '\0')
+ {
+ /* "ADR;HOME:\r\n" */
+ PayloadSize += HOME_ADDRESS_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->HomeAddress );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->WorkAddress != '\0')
+ {
+ /* "ADR;WORK:\r\n" */
+ PayloadSize += WORK_ADDRESS_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->WorkAddress );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->HomeTel != '\0')
+ {
+ /* "TEL;HOME:\r\n" */
+ PayloadSize += HOME_TEL_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->HomeTel );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->WorkTel != '\0')
+ {
+ /* "TEL;WORK:\r\n" */
+ PayloadSize += WORK_TEL_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->WorkTel );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->CellTel != '\0')
+ {
+ /* "TEL;CELL:\r\n" */
+ PayloadSize += CELL_TEL_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->CellTel );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->HomeEmail != '\0')
+ {
+ /* "EMAIL;HOME:\r\n" */
+ PayloadSize += HOME_EMAIL_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->HomeEmail );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->WorkEmail != '\0')
+ {
+ /* "EMAIL;WORK:\r\n" */
+ PayloadSize += WORK_EMAIL_STRING_SIZE;
+ PayloadSize += strlen( pVcardStruct->WorkEmail );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ /* "END:VCARD\r\n" */
+ PayloadSize += END_STRING_SIZE;
+ PayloadSize += VCARD_STRING_SIZE;
+ /* PayloadSize += LIMIT_STRING_SIZE;*/
+
+ return PayloadSize;
+
+}
+
+/**
+ * @brief This function write the NDEF file with the Vcard data given in the structure.
+ * @param pVcardStruct : pointer on structure that contain the Vcard information.
+ * @param pNDEFMessage : pointer on the NDEF message.
+ * @param size : to store the size of the NDEF message generated.
+ */
+void NDEF_PrepareVcardMessage( sVcardInfo *pVcardStruct, uint8_t *pNDEFMessage, uint16_t *size )
+{
+
+ uint32_t PayloadSize = 0;
+
+ /* Vcard Record Header */
+/************************************/
+/* 7 | 6 | 5 | 4 | 3 | 2 1 0 */
+/*----------------------------------*/
+/* MB ME CF SR IL TNF */ /* <---- CF=0, IL=0 and SR=0 TNF=2 NFC Forum Media type*/
+/*----------------------------------*/
+/* TYPE LENGTH */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 3 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 2 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 1 */
+/*----------------------------------*/
+/* PAYLOAD LENGTH 0 */
+/*----------------------------------*/
+/* ID LENGTH */ /* <---- Not Used */
+/*----------------------------------*/
+/* TYPE */
+/*----------------------------------*/
+/* ID */ /* <---- Not Used */
+/************************************/
+
+ /* As we don't have embedded a jpeg encoder/decoder in this firmware */
+ /* We have made the choice to manage only string content of the vCard */
+ /* For demonstration purpose in order to fill the 8kB of the M24SR */
+ /* We have embedded a NDEF vCard in the STM32 to be able to fill M24SR */
+
+ /* fill record header */
+ uint32_t length = NDEF_GetVcardLength(pVcardStruct);
+ if(length >= 0xFF)
+ {
+ pNDEFMessage[0] = 0xC2; /* Record Flag */
+ pNDEFMessage[1] = XVCARD_TYPE_STRING_LENGTH;
+ pNDEFMessage[5] = length & 0xff;
+ pNDEFMessage[4] = (length>>8) & 0xff;
+ pNDEFMessage[3] = (length>>16) & 0xff;
+ pNDEFMessage[2] = length>>24;
+ memcpy( &pNDEFMessage[6], XVCARD_TYPE_STRING, XVCARD_TYPE_STRING_LENGTH );
+
+ /* Payload is positionned in the NDEF after record header */
+ PayloadSize = 6 + XVCARD_TYPE_STRING_LENGTH;
+ } else {
+ pNDEFMessage[0] = 0xD2; /* Record Flag */
+ pNDEFMessage[1] = XVCARD_TYPE_STRING_LENGTH;
+ pNDEFMessage[2] = length;
+ memcpy( &pNDEFMessage[3], XVCARD_TYPE_STRING, XVCARD_TYPE_STRING_LENGTH );
+
+ /* Payload is positionned in the NDEF after record header */
+ PayloadSize = 3 + XVCARD_TYPE_STRING_LENGTH;
+ }
+
+ /* "BEGIN:VCARD\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], BEGIN, BEGIN_STRING_SIZE );
+ PayloadSize += BEGIN_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], VCARD,VCARD_STRING_SIZE );
+ PayloadSize += VCARD_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+
+ /* "VERSION:2.1\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], VERSION, VERSION_STRING_SIZE );
+ PayloadSize += VERSION_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], VCARD_VERSION_2_1, VCARD_VERSION_2_1_SIZE );
+ PayloadSize += VCARD_VERSION_2_1_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+
+ /* "N:\r\n" */
+ if(*pVcardStruct->Name != '\0')
+ {
+ memcpy( &pNDEFMessage[PayloadSize], VCARD_NAME, VCARD_NAME_STRING_SIZE );
+ PayloadSize += VCARD_NAME_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->Name, strlen(pVcardStruct->Name) );
+ PayloadSize += strlen( pVcardStruct->Name );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ /* "FN:\r\n" */
+ if(*pVcardStruct->FirstName != '\0')
+ {
+ memcpy( &pNDEFMessage[PayloadSize], FIRSTNAME, FIRSTNAME_STRING_SIZE );
+ PayloadSize += FIRSTNAME_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->FirstName, strlen(pVcardStruct->FirstName) );
+ PayloadSize += strlen( pVcardStruct->FirstName );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->HomeTel != '\0')
+ {
+
+ /* "TEL;HOME:\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], HOME_TEL, HOME_TEL_STRING_SIZE );
+ PayloadSize += HOME_TEL_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->HomeTel, strlen(pVcardStruct->HomeTel) );
+ PayloadSize += strlen( pVcardStruct->HomeTel );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->WorkTel != '\0')
+ {
+
+ /* "TEL;WORK:\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], WORK_TEL, WORK_TEL_STRING_SIZE );
+ PayloadSize += WORK_TEL_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->WorkTel, strlen(pVcardStruct->WorkTel) );
+ PayloadSize += strlen( pVcardStruct->WorkTel );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->CellTel != '\0')
+ {
+
+ /* "TEL;CELL:\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], CELL_TEL, CELL_TEL_STRING_SIZE );
+ PayloadSize += CELL_TEL_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->CellTel, strlen(pVcardStruct->CellTel) );
+ PayloadSize += strlen( pVcardStruct->CellTel );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->HomeEmail != '\0')
+ {
+
+ /* "EMAIL;HOME:\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], HOME_EMAIL, HOME_EMAIL_STRING_SIZE );
+ PayloadSize += HOME_EMAIL_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->HomeEmail, strlen(pVcardStruct->HomeEmail) );
+ PayloadSize += strlen( pVcardStruct->HomeEmail );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->WorkEmail != '\0')
+ {
+
+ /* "EMAIL;WORK:\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], WORK_EMAIL, WORK_EMAIL_STRING_SIZE );
+ PayloadSize += WORK_EMAIL_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->WorkEmail, strlen(pVcardStruct->WorkEmail) );
+ PayloadSize += strlen( pVcardStruct->WorkEmail );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->HomeAddress != '\0')
+ {
+
+ /* "ADR;HOME:\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], HOME_ADDRESS, HOME_ADDRESS_STRING_SIZE );
+ PayloadSize += HOME_ADDRESS_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->HomeAddress, strlen(pVcardStruct->HomeAddress) );
+ PayloadSize += strlen( pVcardStruct->HomeAddress );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->WorkAddress != '\0')
+ {
+
+ /* "ADR;WORK:\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], WORK_ADDRESS, WORK_ADDRESS_STRING_SIZE );
+ PayloadSize += WORK_ADDRESS_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->WorkAddress, strlen(pVcardStruct->WorkAddress) );
+ PayloadSize += strlen( pVcardStruct->WorkAddress );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->Org != '\0')
+ {
+
+ /* "ORG:\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], ORG, ORG_STRING_SIZE );
+ PayloadSize += ORG_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->Org, strlen(pVcardStruct->Org) );
+ PayloadSize += strlen( pVcardStruct->Org );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->Title != '\0')
+ {
+ /* "TITLE:\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], TITLE, TITLE_STRING_SIZE );
+ PayloadSize += TITLE_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->Title, strlen(pVcardStruct->Title) );
+ PayloadSize += strlen( pVcardStruct->Title );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+ if(*pVcardStruct->Url != '\0')
+ {
+ /* "URL:\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], URL, URL_STRING_SIZE );
+ PayloadSize += URL_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], pVcardStruct->Url, strlen(pVcardStruct->Url) );
+ PayloadSize += strlen( pVcardStruct->Url );
+ memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+ PayloadSize += LIMIT_STRING_SIZE;
+ }
+
+ /* "END:VCARD\r\n" */
+ memcpy( &pNDEFMessage[PayloadSize], END, END_STRING_SIZE );
+ PayloadSize += END_STRING_SIZE;
+ memcpy( &pNDEFMessage[PayloadSize], VCARD, VCARD_STRING_SIZE );
+ PayloadSize += VCARD_STRING_SIZE;
+// memcpy( &pNDEFMessage[PayloadSize], LIMIT, LIMIT_STRING_SIZE );
+// PayloadSize += LIMIT_STRING_SIZE;
+
+ *size = (uint16_t)(PayloadSize); /* Must not count the 2 byte that represent the NDEF size */
+/*
+ PayloadSize -= 6 + VCARD_TYPE_STRING_LENGTH;
+
+ pNDEFMessage[2] = (PayloadSize & 0xFF000000) >> 24;
+ pNDEFMessage[3] = (PayloadSize & 0x00FF0000) >> 16;
+ pNDEFMessage[4] = (PayloadSize & 0x0000FF00) >> 8;
+ pNDEFMessage[5] = PayloadSize & 0x000000FF;
+ */
+}
+
+
+/**
+ * @brief This function extracts binary data from a base64 representation.
+ * @param input64 : pointer on the input data in base64.
+ * @param binary : returned binary data.
+ * @return Updated pointer on the input64 buffer (normal increment is 4 base64 char for 3 bytes of binary data, but special char are ignored)
+*/
+static uint8_t* from_base64(uint8_t *input64, uint32_t* binary)
+{
+ /* Read 4 base64 character & translate them into 3 bytes binary */
+ *binary = 0;
+ uint8_t base64_6bits;
+ int i = 0;
+ while(i<4)
+ {
+
+ if((*input64 >= 'A') && (*input64 <= 'Z'))
+ {
+ base64_6bits = *(input64++) - 'A';
+ } else if ((*input64 >= 'a') && (*input64 <= 'z'))
+ {
+ base64_6bits = *(input64++) - 'a' + 26;
+ } else if ((*input64 >= '0') && (*input64 <= '9')) {
+ base64_6bits = *(input64++) - '0' + 52;
+ } else if (*input64 == '+')
+ {
+ base64_6bits = 62;
+ input64++;
+ } else if (*input64 == '/')
+ {
+ base64_6bits = 63;
+ input64++;
+ } else if (*input64 == '=') {
+ base64_6bits = 0;
+ input64++;
+ } else {
+ input64++;
+ continue;
+ }
+
+ *binary |= base64_6bits << (6*(3-i));
+ i++;
+ }
+ *binary = ((*binary & 0xFF0000)>>16) | ((*binary & 0xFF)<<16) | (*binary & 0xFF00);
+ return input64;
+}
+
+
+/**
+ * @brief This function return the picture stored in a VCARD.
+ * @param pPayload : pointer on the payload data of the NDEF message.
+ * @param PayloadSize : number of data in the payload.
+ * @param pPict : Pointer on the dpicture buffer (must be big enough to contain the picture - warning: no check is done in the function).
+ */
+int NDEF_getVcardPicture( uint8_t* pPayload, uint32_t PayloadSize, uint8_t* pPict )
+{
+ uint8_t* pSrcPict;
+
+
+ /* Let's find the picture */
+ pSrcPict = pPayload;
+ while( memcmp( pSrcPict, JPEG, JPEG_STRING_SIZE ) && (pSrcPict < (pPayload + PayloadSize)) )
+ {
+ pSrcPict++;
+ }
+ while( (*pSrcPict != ':') && (pSrcPict < (pPayload + PayloadSize)) )
+ {
+ pSrcPict++;
+ }
+ /* Picture start at next char */
+ pSrcPict++;
+
+
+ /* Word found */
+ while( memcmp( pSrcPict, LIMIT, LIMIT_STRING_SIZE ) && (pSrcPict < (pPayload + PayloadSize) ) )
+ {
+ uint32_t binary24;
+ pSrcPict = from_base64(pSrcPict, &binary24);
+ /* copy the 3 bytes read from the base64 data */
+ memcpy( pPict, &binary24, 3);
+ pPict += 3;
+ /* Ignore any line breaks */
+ while (*pSrcPict == 0x0A)
+ {
+ pSrcPict++;
+ }
+ }
+
+ if(pSrcPict >= (pPayload + PayloadSize))
+ {
+ /* problem when parsing the picture */
+ return 1;
+ } else {
+ /* picture found */
+ return 0;
+ }
+}
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Vcard.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,119 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Vcard.h
+ * @author MMY Application Team
+ * @version $Revision: 2892 $
+ * @date $Date: 2016-09-19 11:03:26 +0200 (Mon, 19 Sep 2016) $
+ * @brief This file help to manage Vcard NDEF file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_VCARD_H
+#define __LIB_NDEF_VCARD_H
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+
+#define VCARD_VERSION_2_1 "2.1"
+#define VCARD_VERSION_2_1_SIZE 3
+
+#define VCARD_VERSION_3_0 "3.0"
+#define VCARD_VERSION_3_0_SIZE 3
+
+
+#define BEGIN "BEGIN:"
+#define VCARD "VCARD"
+#define VERSION "VERSION:"
+#define VCARD_NAME "N:"
+ // TODO: rename FIRSTNAME into FORMATTEDNAME
+#define FIRSTNAME "FN:"
+#define HOME_TEL "TEL;HOME:"
+#define WORK_TEL "TEL;WORK:"
+#define CELL_TEL "TEL;CELL:"
+#define HOME_EMAIL "EMAIL;HOME:"
+#define WORK_EMAIL "EMAIL;WORK:"
+#define GEN_EMAIL "EMAIL:"
+#define HOME_ADDRESS "ADR;HOME:"
+#define WORK_ADDRESS "ADR;WORK:"
+#define GEN_ADDRESS "ADR:"
+#define TITLE "TITLE:"
+#define ORG "ORG:"
+#define URL "URL:"
+#define END "END:"
+#define JPEG "JPEG"
+
+#define LIMIT "\r\n"
+
+#define BEGIN_STRING_SIZE 6
+#define VCARD_STRING_SIZE 5
+#define VERSION_STRING_SIZE 8
+#define VCARD_NAME_STRING_SIZE 2
+ // TODO: rename FIRSTNAME into FORMATTEDNAME
+#define FIRSTNAME_STRING_SIZE 3
+#define HOME_TEL_STRING_SIZE 9
+#define WORK_TEL_STRING_SIZE 9
+#define CELL_TEL_STRING_SIZE 9
+#define HOME_EMAIL_STRING_SIZE 11
+#define WORK_EMAIL_STRING_SIZE 11
+#define HOME_ADDRESS_STRING_SIZE 9
+#define WORK_ADDRESS_STRING_SIZE 9
+#define TITLE_STRING_SIZE 6
+#define ORG_STRING_SIZE 4
+#define URL_STRING_SIZE 4
+#define END_STRING_SIZE 4
+#define JPEG_STRING_SIZE 4
+
+#define LIMIT_STRING_SIZE 2
+
+typedef struct
+{
+ char Version [10];
+ char Name[80];
+ // TODO: rename FirstName into FormattedName
+ char FirstName[80];
+ char Title[80];
+ char Org[80];
+ char HomeAddress[80];
+ char WorkAddress[80];
+ char Address[80];
+ char HomeTel[40];
+ char WorkTel[40];
+ char CellTel[40];
+ char HomeEmail[80];
+ char WorkEmail[80];
+ char Email[80];
+ char Url[80];
+}sVcardInfo;
+
+uint16_t NDEF_ReadVcard( sRecordInfo_t *pRecordStruct, sVcardInfo *pVcardStruct );
+uint16_t NDEF_WriteVcard( sVcardInfo *pVcardStruct, I2C* mi2cChannel );
+void NDEF_PrepareVcardMessage( sVcardInfo *pVcardStruct, uint8_t *pNDEFMessage, uint16_t *size );
+int NDEF_getVcardPicture( uint8_t* pPayload, uint32_t PayloadSize, uint8_t* pPict );
+
+
+#endif /* __LIB_NDEF_VCARD_H */
+
+
+/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Wifi.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,367 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_Wifi.c
+ * @author Central LAB
+ * @version V1.0.0
+ * @date 7-October-2015
+ * @ingroup LibNDEF_Wifi
+ * @brief This file helps to manage a NDEF message representing a Wifi Token.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF_Wifi.h"
+#define ATTRIBUTE_ID_SSID_LSB 0X10
+#define ATTRIBUTE_ID_SSID_MSB 0X45
+
+
+#define ATTRIBUTE_ID_NETWORK_LSB 0X10
+#define ATTRIBUTE_ID_NETWORK_MSB 0X27
+
+
+/** @addtogroup lib_NDEF_Wifi Wifi OOB library (WPS)
+ * @ingroup libNDEF
+ * @brief This module is used to manage a Wifi Out-Of-Band NDEF message, to start a communication based on Wifi.
+ * @details The Wifi OOB format is described by the Wifi Protected Setup specification.
+ * It consists in a list of data elements formated as type-length-value.
+ * This module allows to build, write & read such data embedded in a NDEF message.
+ * @section Wifi_Library_Usage Wifi NDEF library usage
+ * @subsection Write_Wifi_OOB How to write a Wifi OOB
+ * The Wifi OOB written in a NDEF record by this module has the following structure:
+ * - Version
+ * - Credential
+ - Network index
+ - SSID
+ - Authentication Type
+ - Encryption Type
+ - Network Key
+ - MAC Address
+ - Vendor Extension
+ - Network Key Shareable
+ - Vendor Extension
+ - Version2
+
+ To write a Wifi OOB, the user must:
+ 1. Instanciate & initialize a `sWifiTokenInfo` structure, such as:
+
+ sWifiTokenInfo wps_oob = {.NetworkSSID = "MY_SSID",
+ .AuthenticationType = NDEF_WIFI_AUTHENTICATION_NONE,
+ .EncryptionType = NDEF_WIFI_ENCRYPTION_NONE,
+ .NetworkKey = "01234567"};
+ @note
+ 1. `AuthenticationType` & `EncryptionType` fields must respectively be values from enums: `Ndef_Wifi_Authentication_t` & `Ndef_Wifi_Encryption_t`.
+ 2. If the `Network key` is set to an empty string, the library sets it to `00000000`.\n
+ Even if 0-length Network Key is supposed to be supported, smartphones dont necessarily accept it.
+
+ 2. Call the `NDEF_WriteWifiToken` function on a pointer on the previous struct instance:
+
+ NDEF_WriteWifiToken(&wps_oob);
+ * @subsection Read_Wifi_OOB How to read a Wifi OOB
+ * 1. Read the 1st record of the NDEF message:
+ *
+ * sRecordInfo_t rRecord;
+ * NDEF_ReadNDEF(NDEF_Buffer);
+ * NDEF_IdentifyBuffer(rRecord,NDEF_Buffer);
+ * 2. Decode the Wifi OOB:
+ *
+ * sWifiTokenInfo wps;
+ * NDEF_ReadWifiToken(&record, &wps);
+ * @note
+ * Only the `NetworkSSID` & `NetworkKey` are extracted from the Wifi OOB, other fields of the `sWifiTokenInfo` structure are left un-initialized.
+ * @{
+ */
+
+/* This buffer contains the data send/received by the TAG */
+extern uint8_t NDEF_Buffer [NDEF_MAX_SIZE];
+
+
+static void NDEF_FillWifiTokenStruct( uint8_t* pPayload, uint32_t PayloadSize, sWifiTokenInfo *pWifiTokenStruct);
+static void NDEF_Read_WifiToken ( struct sRecordInfo *pRecordStruct, sWifiTokenInfo *pWifiTokenStruct );
+
+/**
+ * @brief This function fills a WifiToken structure with information from the NDEF message.
+ * @param pPayload Pointer on the payload data of the NDEF message.
+ * @param PayloadSize number of data in the payload.
+ * @param pWifiTokenStruct pointer on the structure to fill.
+ * @retval NONE
+ */
+static void NDEF_FillWifiTokenStruct( uint8_t* pPayload, uint32_t PayloadSize, sWifiTokenInfo *pWifiTokenStruct)
+{
+ uint8_t* pLastByteAdd,data1,data2,*temp,*temp_br ;
+ uint16_t SSIDLen,NetWorkKeyLen;
+ uint8_t *dbg,dbg1;
+
+
+ pLastByteAdd = (uint8_t*)(pPayload + PayloadSize);
+ pPayload--;
+
+ while(pPayload++ != pLastByteAdd)
+ {
+ uint8_t attribute = *pPayload;
+ temp_br = pPayload;
+ switch(attribute)
+ {
+
+ case ATTRIBUTE_ID_SSID_LSB:
+ temp = pPayload;
+ dbg = temp;
+ dbg1 = *++dbg;
+ if(dbg1 == ATTRIBUTE_ID_SSID_MSB )
+ {
+ data1 = *++dbg;
+ data2 = *++dbg;
+ SSIDLen = data1;
+ SSIDLen = SSIDLen << 8;
+ SSIDLen |= data2;
+ pPayload += 4;
+ memcpy( pWifiTokenStruct->NetworkSSID, pPayload, SSIDLen);
+ /* add end of string charactere */
+ pWifiTokenStruct->NetworkSSID[SSIDLen] = '\0';
+ pPayload += SSIDLen - 1;
+ }
+ else if(dbg1 == ATTRIBUTE_ID_NETWORK_MSB )
+ {
+ data1 = *++dbg;
+ data2 = *++dbg;
+ NetWorkKeyLen = data1;
+ NetWorkKeyLen = NetWorkKeyLen << 8;
+ NetWorkKeyLen |= data2;
+ pPayload += 4;
+ memcpy( pWifiTokenStruct->NetworkKey, pPayload, NetWorkKeyLen);
+ /* add end of string charactere */
+ pWifiTokenStruct->NetworkKey[NetWorkKeyLen] = '\0';
+ pPayload += NetWorkKeyLen -1;
+ }
+ else
+ {
+ pPayload = temp_br;
+ }
+
+ break;
+
+ default :
+ ;
+ }
+ }
+
+}
+
+/**
+ * @brief This fonction reads the WifiToken and store data in a structure.
+ * @param pRecordStruct Pointer on the record structure.
+ * @param pWifiTokenStruct Pointer on the structure to fill.
+ * @retval NONE
+ */
+static void NDEF_Read_WifiToken ( struct sRecordInfo *pRecordStruct, sWifiTokenInfo *pWifiTokenStruct )
+{
+ uint8_t* pPayload;
+ uint32_t PayloadSize;
+
+ PayloadSize = pRecordStruct->PayloadLength;
+
+ /* Read record header */
+ pPayload = (uint8_t*)(pRecordStruct->PayloadBufferAdd);
+
+ if( pRecordStruct->NDEF_Type == URI_WIFITOKEN_TYPE)
+ NDEF_FillWifiTokenStruct(pPayload , PayloadSize, pWifiTokenStruct);
+
+}
+
+
+/**
+ * @brief This fonction reads a NDEF record and retrieves a WifiToken information if any.
+ * @param pRecordStruct Pointer on the record structure.
+ * @param pWifiTokenStruct Pointer on a `sWifiTokenInfo` structure to fill with the WifiToken information.
+ * @retval NDEF_OK WifiToken information from NDEF have been retrieved.
+ * @retval NDEF_ERROR Not able to retrieve the WifiToken information.
+ */
+uint16_t NDEF_ReadWifiToken(struct sRecordInfo *pRecordStruct, sWifiTokenInfo *pWifiTokenStruct)
+{
+ uint16_t status = NDEF_ERROR;
+
+ if( pRecordStruct->NDEF_Type == URI_WIFITOKEN_TYPE )
+ {
+ NDEF_Read_WifiToken(pRecordStruct, pWifiTokenStruct );
+ status = NDEF_OK;
+ }
+
+ return status;
+}
+
+
+/**
+ * @brief This fonction writes a NDEF message built with the WifiToken data given in the structure.
+ * @param pWifiTokenStruct Pointer on the structure containing the WifiToken information.
+ * @retval NDEF_OK The NDEF message has been successfully written.
+ * @retval NDEF_ERROR Not able to store the NDEF message inside the tag.
+ */
+uint16_t NDEF_WriteWifiToken ( sWifiTokenInfo *pWifiTokenStruct, I2C* mi2cChannel )
+{
+ uint16_t status = NDEF_ERROR;
+ uint8_t* pPayload,initStage = 0;
+ uint16_t DataSize;
+ uint32_t PayloadSize,SSIDSize,SSIDKeySize;
+
+ if(pWifiTokenStruct->NetworkKey[0] == '\0')
+ {
+ /* Empty network key is not supported by Phones */
+ strcpy(pWifiTokenStruct->NetworkKey, NDEF_WIFI_DEFAULT_NETWORK_KEY);
+ }
+
+ uint8_t configToken1[] = {0x10,0x4A, /* Attribute ID : Version*/
+ 0x00,0x01, /* Attribute ID Length*/
+ 0x10, /* Version 1.0*/
+ 0x10,0x0E, /* Attribute ID Credential*/
+ 0x00,0x48, /* Attribute ID Length*/
+ 0x10,0x26, /* Attribute ID : Network Index*/
+ 0x00,0x01, /* Attribute Length*/
+ 0x01, /* Index */
+ 0x10,0x45, /* Attribute ID :SSID*/
+
+ };
+
+ /* Fill SSID length + SSID between configToken1 and configToken3*/
+
+ uint8_t configToken3[] = {0x10,0x03, /* Attribute ID :Authentication Type*/
+ 0x00,0x02, /* Attribute Length*/
+ 0x00,0x01, /* Attribute Type : Open*/
+ 0x10,0x0F, /* Attribute ID : Encryption Type*/
+ 0x00,0x02, /* Attribute Length*/
+ 0x00,0x01, /* Encryption Type : None*/
+ 0x10,0x27}; /* Attribute ID : Network Key */
+
+
+ /*Fill SSID KEY Length and SSID Key between configToken3 and configToken5*/
+
+ uint8_t configToken5[] = {0x10,0x20, /* Attribute ID : MAC Address */
+ 0x00,0x06, /* Attribute Length*/
+ 0, /*MAC-ADDRESS*/
+ 0, /*MAC-ADDRESS*/
+ 0, /*MAC-ADDRESS*/
+ 0, /*MAC-ADDRESS*/
+ 0, /*MAC-ADDRESS*/
+ 0, /*MAC-ADDRESS*/
+ 0x10,0x49, /* Attribute ID : Vendor Extension */
+ 0x00,0x06, /* Attribute Length*/
+ 0x00,0x37,0x2A, /* Vendor ID:WFA*/
+ 0x02, /* Subelement ID:Network Key Shareable*/
+ 0x01, /* Subelement Length*/
+ 0x01, /*Network Key Shareable : TRUE*/
+ 0x10,0x49, /* Attribute ID : Vendor Extension */
+ 0x00,0x06,/* Attribute Length*/
+ 0x00,0x37,0x2A,/* Vendor ID:WFA*/
+ 0x00, /* Subelement ID:Version2*/
+ 0x01, /* Subelement Length:1*/
+ 0x20 /* Version2*/
+ };
+
+
+ /* Set size of the tokens */
+ const uint32_t CONFIG_TOKEN_1 = sizeof(configToken1);
+ const uint32_t CONFIG_TOKEN_3 = sizeof(configToken3);
+ const uint32_t CONFIG_TOKEN_5 = sizeof(configToken5);
+
+ /* Update Token3 for Autentication & Encryption Types, their default value is coded in token3 */
+ configToken3[CONFIG_TOKEN_3_AUTHENTICATION_TYPE_INDEX] = pWifiTokenStruct->AuthenticationType & 0xFF;
+ configToken3[CONFIG_TOKEN_3_ENCRYPTION_TYPE_INDEX] = pWifiTokenStruct->EncryptionType & 0xFF;
+
+ /* fill Wifi record header */
+ NDEF_Buffer[FIRST_RECORD_OFFSET] = 0xD2; /* Record Flag */
+ NDEF_Buffer[FIRST_RECORD_OFFSET+1] = WIFITOKEN_TYPE_STRING_LENGTH;
+ NDEF_Buffer[FIRST_RECORD_OFFSET+2] = 76; /* needs to be autocalculated - done at the end */
+
+ memcpy(&NDEF_Buffer[FIRST_RECORD_OFFSET+3], WIFITOKEN_TYPE_STRING, WIFITOKEN_TYPE_STRING_LENGTH);
+
+ pPayload = &NDEF_Buffer[FIRST_RECORD_OFFSET+3+WIFITOKEN_TYPE_STRING_LENGTH];
+ PayloadSize = 0;
+
+ /* Compute credential length */
+
+ uint16_t credential_length = 5 + // Network index
+ 4 + // SSID type + length
+ strlen(pWifiTokenStruct->NetworkSSID) + // SSID
+ CONFIG_TOKEN_3 +
+ 2 + // Network key length
+ strlen(pWifiTokenStruct->NetworkKey) + // Network KEY
+ CONFIG_TOKEN_5;
+
+ /* update credential length */
+ configToken1[CONFIG_TOKEN_1_CREDENTIAL_LENGTH_INDEX + 1] = credential_length & 0xff;
+ configToken1[CONFIG_TOKEN_1_CREDENTIAL_LENGTH_INDEX] = credential_length>>8;
+
+
+ for(initStage=0;initStage<CONFIG_TOKEN_1;initStage++)
+ {
+ *pPayload =configToken1[initStage];
+ pPayload++;
+ }
+
+ /*Fill SSID length and SSID value*/
+ SSIDSize = strlen(pWifiTokenStruct->NetworkSSID);
+ *pPayload = 0x00; pPayload++;
+ *pPayload = SSIDSize & 0x000000FF; pPayload++;
+
+ strcpy((char*)pPayload,pWifiTokenStruct->NetworkSSID);
+ pPayload = pPayload + strlen(pWifiTokenStruct->NetworkSSID);
+
+ for(initStage=0;initStage<CONFIG_TOKEN_3;initStage++)
+ {
+ *pPayload =configToken3[initStage];
+ pPayload++;
+ }
+
+ /* Fill the SSIDKey length and SSIDKey value */
+ SSIDKeySize = strlen(pWifiTokenStruct->NetworkKey);
+ *pPayload = 0x00; pPayload++;
+ *pPayload = SSIDKeySize & 0x000000FF; pPayload++;
+
+ memcpy((char*)pPayload,pWifiTokenStruct->NetworkKey,SSIDKeySize);
+ pPayload = pPayload + SSIDKeySize;
+
+ for(initStage=0;initStage<CONFIG_TOKEN_5;initStage++)
+ {
+ *pPayload =configToken5[initStage];
+ pPayload++;
+ }
+
+ PayloadSize += CONFIG_TOKEN_1 + CONFIG_TOKEN_3 + CONFIG_TOKEN_5 + SSIDSize + SSIDKeySize + 4 ; // +4 is for SSID & Key length fields
+
+ NDEF_Buffer[FIRST_RECORD_OFFSET+2] = (PayloadSize & 0x000000FF);
+
+ DataSize = PayloadSize + 3 + WIFITOKEN_TYPE_STRING_LENGTH;
+
+ /* Write NDEF */
+ status = NDEF_WriteNDEF(DataSize , NDEF_Buffer, mi2cChannel);
+
+ return status;
+}
+
+
+/**
+ * @}
+ */
+
+
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib_NDEF_Wifi.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,110 @@
+/**
+ ******************************************************************************
+ * @file lib_NDEF_WifiToken.h
+ * @author Central LAB
+ * @version V1.0.0
+ * @date 7-October-2015
+ * @brief This file helps to manage the NDEF message representing a Wifi Token.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __LIB_NDEF_WIFIT_H
+#define __LIB_NDEF_WIFIT_H
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+/** @addtogroup lib_NDEF_Wifi Wifi OOB library (WPS)
+ * @ingroup libNDEF
+ * @{
+ */
+
+
+/* Exported types ------------------------------------------------------------*/
+/** @brief This index points to the position of the credential length value in Token1.
+ * Its value may require to be updated if the token1 is modified.
+ */
+#define CONFIG_TOKEN_1_CREDENTIAL_LENGTH_INDEX 7
+
+/** @brief This index points to the position of the Authentication type value in Token3.
+ * Its value may require to be updated if the token3 is modified.
+ */
+#define CONFIG_TOKEN_3_AUTHENTICATION_TYPE_INDEX ((uint32_t)5)
+/** @brief This index points to the position of the Encryption type value in Token3.
+ * Its value may require to be updated if the token3 is modified.
+ */
+#define CONFIG_TOKEN_3_ENCRYPTION_TYPE_INDEX ((uint32_t)11)
+
+/** @brief MIME type for the Wifi OOB token.
+ */
+#define WIFITOKEN_TYPE_STRING "application/vnd.wfa.wsc"
+/** @brief Length of the MIME type for the Wifi OOB token.
+ */
+#define WIFITOKEN_TYPE_STRING_LENGTH ((uint32_t)23)
+
+/**
+ * @brief Network key to be used when the Authentication is set to None.
+ * Althought WPS defines a 0 length network key in such case,
+ * with tested phones a 8 digit value is required.
+ */
+#define NDEF_WIFI_DEFAULT_NETWORK_KEY "00000000"
+
+typedef enum {
+ NDEF_WIFI_ENCRYPTION_NONE = 0x0000, /**< WPS No Encryption (set to 0 for Android native support / should be 1) */
+ NDEF_WIFI_ENCRYPTION_WEP = 0x0002, /**< WPS Encryption based on WEP */
+ NDEF_WIFI_ENCRYPTION_TKIP = 0x0003, /**< WPS Encryption based on TKIP */
+ NDEF_WIFI_ENCRYPTION_AES = 0x0004 /**< WPS Encryption based on AES */
+} Ndef_Wifi_Encryption_t;
+
+typedef enum {
+ NDEF_WIFI_AUTHENTICATION_NONE = 0x0000, /**< WPS No Authentication (set to 0 for Android native support / should be 1) */
+ NDEF_WIFI_AUTHENTICATION_WPAPSK = 0x0002, /**< WPS Authentication based on WPAPSK */
+ NDEF_WIFI_AUTHENTICATION_SHARED = 0x0003, /**< WPS Authentication based on ?? */
+ NDEF_WIFI_AUTHENTICATION_WPA = 0x0004, /**< WPS Authentication based on WPA */
+ NDEF_WIFI_AUTHENTICATION_WPA2 = 0x0005, /**< WPS Authentication based on WPA2 */
+ NDEF_WIFI_AUTHENTICATION_WPA2PSK = 0x0006 /**< WPS Authentication based on WPA2PSK */
+} Ndef_Wifi_Authentication_t;
+
+/**
+ * @brief WifiToken structure, to store Network SSID, Authentication Type, Encryption Type and Network Key.
+ */
+typedef struct
+{
+ char NetworkSSID[32]; /**< Store the Network SSID. */
+ Ndef_Wifi_Authentication_t AuthenticationType; /**< Store the Authentication type to be used. */
+ Ndef_Wifi_Encryption_t EncryptionType; /**< Store the Encryption to be used. */
+ char NetworkKey[32]; /**< Store the Network Key. */
+}sWifiTokenInfo;
+
+
+uint16_t NDEF_ReadWifiToken(struct sRecordInfo *pRecordStruct, sWifiTokenInfo *pWifiTokenStruct);
+uint16_t NDEF_WriteWifiToken( sWifiTokenInfo *pWifiTokenStruct, I2C* mi2cChannel );
+
+/**
+ * @}
+ */
+
+#endif /* __LIB_NDEF_WIFIT_H */
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib_wrapper.h Thu Nov 14 10:34:11 2019 +0000 @@ -0,0 +1,49 @@ +/** + ****************************************************************************** + * @file lib_wrapper.h + * @author MMY Application Team + * @version $Revision: 2702 $ + * @date $Date: 2016-07-13 18:45:05 +0200 (Wed, 13 Jul 2016) $ + * @brief This file help to have upper layer independent from HW + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + * + * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/myliberty + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __LIB_WRAPPER_H +#define __LIB_WRAPPER_H + +/* Includes ------------------------------------------------------------------*/ +#include "NDEFcommon.h" +#include "mbed.h" + + + + +uint16_t NfcTag_ReadNDEF( uint8_t* pData, I2C* mi2cChannel ); +uint16_t NfcTag_WriteNDEF(uint16_t Length, uint8_t* pData, I2C* mi2cChannel ); +uint16_t NfcTag_WriteProprietary(uint16_t Length, uint8_t* pData, I2C* mi2cChannel ); +uint16_t NfcTag_GetLength(uint16_t* Length, I2C* mi2cChannel); + +#endif /* __LIB_WRAPPER_H */ + + +/******************* (C) COPYRIGHT 2015 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tagtype5_wrapper.cpp Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,517 @@
+/**
+ ******************************************************************************
+ * @file tagtype5_wrapper.c
+ * @author MMY Application Team
+ * @version $Revision: 3210 $
+ * @date $Date: 2016-12-05 15:37:48 +0100 (Mon, 05 Dec 2016) $
+ * @brief This file provides an abstraction layer to the libNDEF for the NFC Forum Type5 Tag.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+/* Includes ------------------------------------------------------------------*/
+#include "tagtype5_wrapper.h"
+#include "BSP/x_nucleo_nfc04a1_nfctag.h"
+
+//void printDbg(char *str);
+//char tmp[40];
+/*
+typedef enum
+{
+ NFCTAG_OK = 0,
+ NFCTAG_ERROR = 1,
+ NFCTAG_BUSY = 2,
+ NFCTAG_TIMEOUT = 3,
+ NFCTAG_NACK = 4
+} NFCTAG_StatusTypeDef;
+*/
+/** @addtogroup Tag_Type_5 Type 5 Tag library
+ * @ingroup libNFC_FORUM
+ * @{
+ * @brief This module provides an abstraction layer to the NDEF library for the NFC Forum Type5 Tag.
+ * @details These functions manage the specificities of the Type5 Tag accesses.\n
+ * The NFC Forum defines specific Capability Containers for the Type5 Tags.
+ * The Capability Container provides basic information on how a tag can be accessed.
+ * Depending on the memory size of the tag, 2 different CC will be used:
+ * 1. 4-bytes Capability Container (Memory Size < 16kbits):
+ * |Byte0 |Byte1 |Byte2 |Byte3 |
+ * |:------------:|:---------------------------:|:-----------:|:--------------:|
+ * | Magic Number | Version & Access Conditions | Memory Size | NFC Type 5 Tag |
+ * 2. 8-bytes Capability Container (Memory Size > 16kbits):
+ * |Byte0 |Byte1 |Byte2|Byte3 |Byte4|Byte5|Byte6 |Byte7 |
+ * |:------------:|:---------------------------:|:---:|:--------------:|:---:|:---:|:---------:|:---------:|
+ * | Magic Number | Version & Access Conditions | 00h | NFC Type 5 Tag |RFU |RFU |Memory Size|Memory Size|
+ * @section Type5_Tag_Usage How to write a Type5 Tag Capability Container
+ * 1. Initialize the Capacity Container structure with the Tag compliant values:
+ - Example for a 4kbits memory tag:
+
+ CCFileStruct.MagicNumber = NFCT5_MAGICNUMBER_E1_CCFILE;
+ CCFileStruct.Version = NFCT5_VERSION_V1_0;
+ CCFileStruct.MemorySize = 0x40;
+ CCFileStruct.TT5Tag = 0x0;
+
+ - Example for a 64kbits memory tag:
+
+ CCFileStruct.MagicNumber = NFCT5_MAGICNUMBER_E2_CCFILE;
+ CCFileStruct.Version = NFCT5_VERSION_V1_0;
+ CCFileStruct.MemorySize = NFCT5_EXTENDED_CCFILE;
+ CCFileStruct.ExtMemorySize = 0x400;
+ CCFileStruct.TT5Tag = 0x1;
+
+ 2. Call the `NfcType5_TT5Init` function to write the Capability Container to the Tag:
+
+ NfcType5_TT5Init();
+
+ */
+
+/** @brief Capability Container structure instance (global). */
+sCCFileInfo CCFileStruct;
+
+/**
+ * @brief This function reads the data stored in the NDEF message.
+ * @param pData Pointer on the buffer used to store the read data.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL The buffer is too small for the NDEF message.
+ * @retval NDEF_ERROR_NOT_FORMATED No Capability Container detected.
+ * @retval NDEF_ERROR Error when reading the NDEF message.
+ * @retval NDEF_OK NDEF message successfully read.
+ */
+uint16_t NfcTag_ReadNDEF( uint8_t* pData, I2C* mi2cChannel )
+{
+ uint16_t status = NDEF_ERROR;
+ TT5_TLV_t tlv;
+ uint8_t tlv_size = 0;
+ uint16_t DataLength;
+
+ /* Detect NDEF message in memory */
+ status = NfcType5_NDEFDetection( mi2cChannel );
+ if( status != NDEF_OK )
+ {
+ return status;
+ }
+
+ /* Read TL of Type 5 */
+ status = BSP_NFCTAG_ReadData( (uint8_t*)&tlv, CCFileStruct.NDEF_offset, sizeof(TT5_TLV_t), mi2cChannel );
+ if( status != NDEF_OK )
+ {
+ return status;
+ }
+
+ /* Check if L is on 3 or 1 byte and update length in buffer */
+ if( tlv.Length == NFCT5_3_BYTES_L_TLV )
+ {
+ tlv_size = 4;
+ DataLength = ((tlv.Length16 >> 8)&0xff) | ((tlv.Length16&0xff)<<8);
+ }
+ else
+ {
+ tlv_size = 2;
+ DataLength = tlv.Length;
+ }
+ /* If too many data to write return error */
+ if( DataLength > NDEF_MAX_SIZE )
+ {
+ return NDEF_ERROR_MEMORY_INTERNAL;
+ }
+
+ /* Check CC file is in the correct mode to proceed */
+ if( CCFileStruct.State == TT5_INITIALIZED )
+ {
+ return NDEF_ERROR;
+ }
+
+ if( DataLength > 0 )
+ {
+ /* Read NDEF */
+ if( BSP_NFCTAG_ReadData( (pData), CCFileStruct.NDEF_offset + tlv_size, DataLength, mi2cChannel ) != NFCTAG_OK )
+ {
+ return NDEF_ERROR;
+ }
+ }
+
+ return NDEF_OK;
+}
+uint32_t BSP_NFCTAG_GetByteSize( I2C* mi2cChannel );
+
+/**
+ * @brief This function writes data in the NFC Tag.
+ * @param Type Type of the data: NDEF or Proprietary
+ * @param Length Number of bytes to write.
+ * @param pData Pointer on the buffer to copy.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL Memory size is too small for the data.
+ * @retval NDEF_ERROR_NOT_FORMATED No Capability Container detected.
+ * @retval NDEF_ERROR Error when writing the Tag.
+ * @retval NDEF_OK The data has been successfully written.
+ */
+uint16_t NfcTag_WriteData(uint8_t Type, uint16_t Length , uint8_t *pData, I2C* mi2cChannel )
+{
+ TT5_TLV_t tlv;
+ uint8_t tlv_size;
+ uint32_t offset;
+ uint8_t NfcT5_Terminator = NFCT5_TERMINATOR_TLV;
+
+ uint32_t max_length = BSP_NFCTAG_GetByteSize( mi2cChannel) /* Memory size */
+ - ((Length >= 0xFF) ? 4 : 2) /* - TLV length */
+ - sizeof(NfcT5_Terminator) /* - Terminator TLV */
+ - CCFileStruct.NDEF_offset; /* - CCfile length */
+
+ /* If too many data to write return error */
+ if( Length > max_length )
+ {
+ return NDEF_ERROR_MEMORY_TAG;
+ }
+
+ /* Detect NDEF message in memory */
+ if( NfcType5_NDEFDetection( mi2cChannel ) != NDEF_OK )
+ {
+ return NDEF_ERROR;
+ }
+
+ /* Prepare TLV */
+ tlv.Type = Type;
+ if(Length >= 0xFF)
+ {
+ tlv.Length = NFCT5_3_BYTES_L_TLV;
+ tlv.Length16 = ((Length&0xff)<<8) | ((Length>>8)&0xff) ;
+ tlv_size = 4;
+
+ } else {
+ tlv.Length = Length;
+ tlv_size = 2;
+ }
+
+
+ offset = CCFileStruct.NDEF_offset;
+ /* Start write TLV to EEPROM */
+ if(BSP_NFCTAG_WriteData( (uint8_t*)&tlv, offset, tlv_size, mi2cChannel )!= NFCTAG_OK)
+ return NDEF_ERROR;
+ offset += tlv_size;
+
+ BSP_NFCTAG_WriteData( pData , offset, 4, mi2cChannel );
+
+
+
+ /* Continue write TLV data to EEPROM */
+ if(BSP_NFCTAG_WriteData( pData , offset, Length, mi2cChannel ) != NFCTAG_OK )
+ return NDEF_ERROR;
+ offset +=Length;
+
+
+ /* Write Terminator TLV */
+ if(BSP_NFCTAG_WriteData( &NfcT5_Terminator, offset, sizeof(NfcT5_Terminator), mi2cChannel ) != NFCTAG_OK)
+ return NDEF_ERROR;
+
+ return NDEF_OK;
+
+}
+
+/**
+ * @brief This function writes a NDEF message in the NFC Tag.
+ * @param Length Number of bytes to write.
+ * @param pData Pointer on the buffer to copy.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL Memory size is too small for the data.
+ * @retval NDEF_ERROR_NOT_FORMATED No Capability Container detected.
+ * @retval NDEF_ERROR Error when writing the Tag.
+ * @retval NDEF_OK The data has been successfully written.
+ */
+uint16_t NfcTag_WriteNDEF(uint16_t Length , uint8_t *pData, I2C* mi2cChannel )
+{
+ return NfcTag_WriteData(NFCT5_NDEF_MSG_TLV,Length,pData, mi2cChannel);
+}
+
+/**
+ * @brief This function writes a Proprietary message to the NFC Tag.
+ * @param Length Number of byte to write.
+ * @param pData Pointer on the buffer to copy.
+ * @retval NDEF_ERROR_MEMORY_INTERNAL Memory size is too small for the data.
+ * @retval NDEF_ERROR_NOT_FORMATED No Capability Container detected.
+ * @retval NDEF_ERROR Error when writing the Tag.
+ * @retval NDEF_OK The data has been successfully written.
+ */
+uint16_t NfcTag_WriteProprietary(uint16_t Length , uint8_t *pData, I2C* mi2cChannel )
+{
+ return NfcTag_WriteData(NFCT5_PROPRIETARY_TLV,Length,pData, mi2cChannel);
+}
+
+
+/**
+ * @brief This functions writes the Capability Container in the NFC Tag.
+ * @param pCCBuffer Pointer on the buffer containnig the Capability Container.
+ * @retval NDEF_ERROR Error when writing the Tag.
+ * @retval NDEF_OK The CC has been successfully written.
+ */
+uint16_t NfcType5_WriteCCFile( const uint8_t * const pCCBuffer, I2C* mi2cChannel )
+{
+ NFCTAG_StatusTypeDef ret_value;
+
+ /* Write first block of CCFile */
+ ret_value = BSP_NFCTAG_WriteData( pCCBuffer, 0x00, 0x4, mi2cChannel );
+
+ /* If extended memory writes the next 4 bytes */
+ if( (pCCBuffer[2] == 0x00) && (ret_value == NFCTAG_OK) )
+ {
+ ret_value = BSP_NFCTAG_WriteData( pCCBuffer + 4, 0x04, 4, mi2cChannel );
+ }
+
+ if( ret_value != NFCTAG_OK )
+ {
+ return NDEF_ERROR;
+ }
+
+ return NDEF_OK;
+}
+
+/**
+ * @brief This functions reads the Capability Container from the NFC Tag.
+ * @param pCCBuffer Pointer on the buffer used to store the CC.
+ * @retval NDEF_ERROR Error when reading the Tag.
+ * @retval NDEF_OK The CC has been successfully read.
+ */
+uint16_t NfcType5_ReadCCFile( uint8_t * const pCCBuffer, I2C* mi2cChannel )
+{
+ NFCTAG_StatusTypeDef ret_value;
+
+ /* Read 4 bytes of CC File */
+ ret_value = BSP_NFCTAG_ReadData( pCCBuffer, 0x00, 4, mi2cChannel );
+
+ /* If extended memory reads the next 4 bytes */
+ if( (pCCBuffer[2] == 0x00) && (ret_value == NFCTAG_OK) )
+ {
+ ret_value = BSP_NFCTAG_ReadData( pCCBuffer + 4, 0x04, 4, mi2cChannel );
+ }
+
+ if( ret_value != NFCTAG_OK )
+ {
+ return NDEF_ERROR;
+ }
+
+ return NDEF_OK;
+}
+
+/**
+ * @brief This function initializes the Capability Container and an empty NDEF message in a NFC Tag.
+ * @details The Capability Container content is defined by the global variable `CCFileStruct`.
+ * @retval NDEF_ERROR The Tag has not been initialized.
+ * @retval NDEF_OK The Tag has been successfully initialized.
+ */
+uint16_t NfcType5_TT5Init( I2C* mi2cChannel )
+{
+ NFCTAG_StatusTypeDef ret_value = NFCTAG_OK;
+ uint16_t status;
+ uint8_t accbuffer[8];
+ uint8_t cdata;
+
+ /* Prepare buffer to update CCFile */
+ accbuffer[0] = CCFileStruct.MagicNumber;
+ accbuffer[1] = CCFileStruct.Version;
+ accbuffer[2] = CCFileStruct.MemorySize;
+ accbuffer[3] = CCFileStruct.TT5Tag;
+ CCFileStruct.NDEF_offset = 0x04;
+
+ /* If extended memory prepare the length bytes */
+ if( CCFileStruct.MemorySize == NFCT5_EXTENDED_CCFILE )
+ {
+ accbuffer[6] = (uint8_t)(CCFileStruct.ExtMemorySize >> 8);
+ accbuffer[7] = (uint8_t)(CCFileStruct.ExtMemorySize & 0xFF);
+ CCFileStruct.NDEF_offset = 0x08;
+ }
+
+ /* Update CCFile */
+ status = NfcType5_WriteCCFile( accbuffer, mi2cChannel );
+
+
+ if( status != NDEF_OK )
+ {
+ return status;
+ }
+
+ /* Update NDEF TLV for INITIALIZED state */
+ /* Update T */
+ cdata = NFCT5_NDEF_MSG_TLV;
+ ret_value = BSP_NFCTAG_WriteData( &cdata, CCFileStruct.NDEF_offset, 1, mi2cChannel );
+ if( ret_value != NFCTAG_OK )
+ {
+ return NDEF_ERROR;
+ }
+
+ /* Update L */
+ cdata = 0x00;
+ ret_value = BSP_NFCTAG_WriteData( &cdata, (CCFileStruct.NDEF_offset + 1), 1, mi2cChannel );
+ if( ret_value != NFCTAG_OK )
+ {
+ return NDEF_ERROR;
+ }
+
+ return NDEF_OK;
+}
+
+/**
+ * @brief This function detects a NDEF message in a Type 5 Tag.
+ * @details It first detects the Capability Container and then look for the NDEF TLV.
+ * The `CCfileStruct` global variable is updated accordingly with what is detected.
+ * @retval NDEF_OK NDEF message Tag Type 5 detected.
+ * @retval NDEF_ERROR_NOT_FORMATED Device is not a NFC Tag Type 5 Tag.
+ */
+uint16_t NfcType5_NDEFDetection( I2C* mi2cChannel )
+{
+ uint8_t acc_buffer[8];
+ TT5_TLV_t tlv_detect;
+ uint16_t status;
+ uint32_t memory_size;
+
+ CCFileStruct.State = TT5_NO_NDEF;
+
+ /* Read CCFile */
+ status = NfcType5_ReadCCFile( acc_buffer, mi2cChannel );
+
+ if( status != NDEF_OK )
+ {
+ return status;
+ }
+
+ /* Check Byte 0 is equal to magic number */
+ if( ( acc_buffer[0] != NFCT5_MAGICNUMBER_E1_CCFILE ) && ( acc_buffer[0] != NFCT5_MAGICNUMBER_E2_CCFILE ) )
+ {
+ return NDEF_ERROR_NOT_FORMATED;
+ }
+ /* Check Version number */
+ else if( ( (acc_buffer[1]&0xFC) != 0x40 ) )
+ {
+ return NDEF_ERROR_NOT_FORMATED;
+ }
+
+ /* Check if CCFile is on 4 Bytes or 8 Bytes */
+ if( acc_buffer[2] == 0x00 )
+ {
+ /* Update CCFIle structure */
+ CCFileStruct.MemorySize = 0x0;
+ CCFileStruct.ExtMemorySize = (uint16_t)acc_buffer[6];
+ CCFileStruct.ExtMemorySize = ( CCFileStruct.ExtMemorySize << 8 ) | acc_buffer[7];
+ memory_size = CCFileStruct.ExtMemorySize;
+ CCFileStruct.NDEF_offset = 8;
+ }
+ else
+ {
+ /* Update CCFIle structure */
+ CCFileStruct.MemorySize = acc_buffer[2];
+ CCFileStruct.ExtMemorySize = 0x0;
+ memory_size = CCFileStruct.MemorySize;
+ CCFileStruct.NDEF_offset = 4;
+ }
+
+ /* Update CCFIle structure */
+ CCFileStruct.MagicNumber = (TT5_MagicNumber_t)acc_buffer[0];
+ CCFileStruct.Version = acc_buffer[1];
+ CCFileStruct.TT5Tag = acc_buffer[3];
+
+ /* Search for position of NDEF TLV in memory and tag status */
+ while( ( BSP_NFCTAG_ReadData( (uint8_t *)&tlv_detect, CCFileStruct.NDEF_offset, sizeof(TT5_TLV_t), mi2cChannel ) == NFCTAG_OK ) && ( CCFileStruct.NDEF_offset < memory_size ) )
+ {
+ /* Detect first NDEF Message in memory */
+ if( tlv_detect.Type == NFCT5_NDEF_MSG_TLV )
+ {
+ if( tlv_detect.Length == 0x00 )
+ {
+ CCFileStruct.State = TT5_INITIALIZED;
+ }
+ else
+ {
+ if( CCFileStruct.Version & 0x3 )
+ {
+ CCFileStruct.State = TT5_READ;
+ }
+ else
+ {
+ CCFileStruct.State = TT5_READ_WRITE;
+ }
+ }
+ return NDEF_OK;
+ }
+ /* If Proprietary NDEF jump to end of proprietary message */
+ else if( tlv_detect.Type == NFCT5_PROPRIETARY_TLV )
+ {
+ if( tlv_detect.Length == NFCT5_3_BYTES_L_TLV )
+ {
+ CCFileStruct.NDEF_offset = CCFileStruct.NDEF_offset + tlv_detect.Length16;
+ continue;
+ }
+ else
+ {
+ CCFileStruct.NDEF_offset = CCFileStruct.NDEF_offset + tlv_detect.Length;
+ continue;
+ }
+ }
+ /* if Terminator no NDEF detected */
+ else if( tlv_detect.Type == NFCT5_TERMINATOR_TLV )
+ {
+ return NDEF_ERROR_NOT_FORMATED;
+ }
+
+ CCFileStruct.NDEF_offset++;
+ }
+
+ return NDEF_ERROR_NOT_FORMATED;
+}
+
+
+
+/**
+ * @brief This function reads and return the size of the NDEF message in the NFC tag.
+ * @param Length Pointer on the NDEF size to be returned.
+ * @retval NDEF_ERROR_NOT_FORMATED Device is not a NFC Tag Type 5 Tag.
+ * @retval NDEF_ERROR The NDEF message size has not been read.
+ * @retval NDEF_OK The NDEF message size has been retrieved.
+ */
+uint16_t NfcTag_GetLength(uint16_t* Length, I2C* mi2cChannel)
+{
+
+ uint16_t status = NDEF_ERROR;
+ TT5_TLV_t tlv;
+
+ /* Detect NDEF message in memory */
+ status = NfcType5_NDEFDetection( mi2cChannel );
+ if( status != NDEF_OK )
+ {
+ return status;
+ }
+
+ /* Read TL of Type 5 */
+ status = BSP_NFCTAG_ReadData( (uint8_t*)&tlv, CCFileStruct.NDEF_offset, sizeof(TT5_TLV_t), mi2cChannel );
+ if( status != NFCTAG_OK )
+ {
+ return NDEF_ERROR;
+ }
+
+ if(tlv.Length != NFCT5_3_BYTES_L_TLV)
+ {
+ *Length = tlv.Length;
+ } else {
+ *Length = ((tlv.Length16 >> 8)&0xff) | ((tlv.Length16 & 0xff) << 8);
+ }
+
+ return NDEF_OK;
+
+}
+
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tagtype5_wrapper.h Thu Nov 14 10:34:11 2019 +0000
@@ -0,0 +1,126 @@
+/**
+ ******************************************************************************
+ * @file tagtype5_wrapper.h
+ * @author MMY Application Team
+ * @version $Revision: 3310 $
+ * @date $Date: 2017-01-13 11:22:18 +0100 (Fri, 13 Jan 2017) $
+ * @brief This file provides an abstraction layer to the libNDEF for the NFC Forum Type5 Tag.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
+ *
+ * Licensed under ST MYLIBERTY SOFTWARE LICENSE AGREEMENT (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/myliberty
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ * AND SPECIFICALLY DISCLAIMING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TAGTYPE5_WRAPPER_H
+#define __TAGTYPE5_WRAPPER_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "lib_NDEF.h"
+
+/** @addtogroup Tag_Type_5
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/**
+ * @brief Tag Type 5 State enumeration definition.
+ */
+typedef enum
+{
+ TT5_NO_NDEF = 0, /**< No data detected in the tag. */
+ TT5_INITIALIZED, /**< Capability container detected. */
+ TT5_READ_WRITE, /**< Read-Write data detected. */
+ TT5_READ /**< Read-Only data message detected. */
+} TT5_State;
+
+/** @brief Type5 Tag Capability Container Magic numbers as defined by the NFC Forum. */
+typedef enum {
+ NFCT5_MAGICNUMBER_E1_CCFILE = 0xE1, /**< Complete data area can be read by 1-byte block adrdess commands. */
+ NFCT5_MAGICNUMBER_E2_CCFILE = 0xE2 /**< Last part of the data area can be only read by 2-bytes block address commands.\n
+ The first 256 blocks can be read by 1-byte block address commands. */
+} TT5_MagicNumber_t;
+
+/**
+ * @brief Type5 Tag Capability Container structure.
+ */
+typedef struct
+{
+ TT5_MagicNumber_t MagicNumber; /**< CCfile[0]: Magic Number should be E1h or E2h (for extended API) */
+ uint8_t Version; /**< CCfile[1]: Capability container version (b7-b4) and access conditions (b3-b0) */
+ uint8_t MemorySize; /**< CCfile[2]: Memory size, expressed in 8 bytes blocks, set to 0 if tag size is greater than 16kbits. */
+ uint8_t TT5Tag; /**< CCfile[3]: Additionnal information on the Type5 Tag:\n
+ b0: supports `read multiple block` commands\n
+ b1: RFU\n
+ b2: RFU\n
+ b3: supports `lock block` commands\n
+ b4: requires the `special frame` format
+ */
+ uint8_t rsved1; /**< RFU */
+ uint8_t rsved2; /**< RFU */
+ uint16_t ExtMemorySize; /**< CCfile[6],CCfile[7]: Memory size, expressed in 8 bytes blocks, when tag size is greater than 16kbits. */
+ TT5_State State; /**< Indicates if a NDEF message is present. */
+ uint32_t NDEF_offset; /**< Indicates the address of a NDEF message in the tag. */
+}sCCFileInfo;
+
+/** @brief Type5 Tag Type-Length-Value structure as defined by the NFC Forum */
+typedef struct
+{
+ uint8_t Type; /**< NFC Forum message Type */
+ uint8_t Length; /**< Message length if lesser than 255 bytes */
+ uint16_t Length16; /**< Message length if greater than or equal to 255 bytes */
+} TT5_TLV_t;
+
+
+/* Exported constants --------------------------------------------------------*/
+/** @brief Memory size value indicating that this is a 8-bytes Capability Container */
+#define NFCT5_EXTENDED_CCFILE 0x00
+/** @brief Capability container version 1.0 */
+#define NFCT5_VERSION_V1_0 0x40
+/** @brief Read access condition mask for the Capability Container byte1 */
+#define NFCT5_READ_ACCESS 0x0C
+/** @brief Write access condition mask for the Capability Container byte1 */
+#define NFCT5_WRITE_ACCESS 0x03
+
+/** @brief Type5 Tag NDEF message TLV-Type. */
+#define NFCT5_NDEF_MSG_TLV ((uint8_t) 0x03)
+/** @brief Type5 Tag Proprietary message TLV-Type. */
+#define NFCT5_PROPRIETARY_TLV ((uint8_t) 0xFD)
+/** @brief Type5 Tag Terminator TLV-Type. */
+#define NFCT5_TERMINATOR_TLV ((uint8_t) 0xFE)
+/** @brief TLV-Length indicating a 4-bytes TLV (Length coded on 2 bytes). */
+#define NFCT5_3_BYTES_L_TLV ((uint8_t) 0xFF)
+
+/* Exported macro ------------------------------------------------------------*/
+/* External variables --------------------------------------------------------*/
+extern sCCFileInfo CCFileStruct;
+
+/* Exported functions ------------------------------------------------------- */
+uint16_t NfcType5_WriteCCFile( const uint8_t * const pCCBuffer, I2C* mi2cChannel );
+uint16_t NfcType5_ReadCCFile( uint8_t * const pCCBuffer, I2C* mi2cChannel );
+uint16_t NfcType5_TT5Init( I2C* mi2cChannel );
+uint16_t NfcType5_NDEFDetection( I2C* mi2cChannel );
+
+
+#endif /* __TAGTYPE5_WRAPPER_H */
+
+/* @}
+ */
+
+/******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/