Get the latest NFC state from neard
[platform/core/connectivity/nfc-manager-neard.git] / common / net_nfc_util_ndef_record.c
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "net_nfc_debug_internal.h"
18 #include "net_nfc_util_defines.h"
19 #include "net_nfc_util_internal.h"
20 #include "net_nfc_util_ndef_message.h"
21 #include "net_nfc_util_ndef_record.h"
22
23 net_nfc_error_e net_nfc_util_free_record(ndef_record_s *record)
24 {
25         RETV_IF(NULL == record, NET_NFC_NULL_PARAMETER);
26
27         if (record->type_s.buffer != NULL)
28                 _net_nfc_util_free_mem(record->type_s.buffer);
29         if (record->id_s.buffer != NULL)
30                 _net_nfc_util_free_mem(record->id_s.buffer);
31         if (record->payload_s.buffer != NULL)
32                 _net_nfc_util_free_mem(record->payload_s.buffer);
33
34         _net_nfc_util_free_mem(record);
35
36         return NET_NFC_OK;
37 }
38
39 net_nfc_error_e net_nfc_util_create_record(net_nfc_record_tnf_e recordType,
40                 const data_s *typeName, const data_s *id, const data_s *payload,
41                 ndef_record_s **record)
42 {
43         ndef_record_s *record_temp = NULL;
44
45         RETV_IF(NULL == typeName, NET_NFC_NULL_PARAMETER);
46         RETV_IF(NULL == payload, NET_NFC_NULL_PARAMETER);
47         RETV_IF(NULL == record, NET_NFC_NULL_PARAMETER);
48
49         RETV_IF(recordType < NET_NFC_RECORD_EMPTY, NET_NFC_OUT_OF_BOUND);
50         RETV_IF(recordType > NET_NFC_RECORD_UNCHAGNED, NET_NFC_OUT_OF_BOUND);
51
52         /* empty_tag */
53         if (NET_NFC_RECORD_EMPTY == recordType)
54         {
55                 if ((typeName->buffer != NULL) || (payload->buffer != NULL)
56                                 || (id->buffer != NULL) || (typeName->length != 0) || (payload->length != 0)
57                                 || (id->length != 0))
58                 {
59                         return NET_NFC_NULL_PARAMETER;
60                 }
61         }
62
63         _net_nfc_util_alloc_mem(record_temp, sizeof(ndef_record_s));
64         if (NULL == record_temp)
65                 return NET_NFC_ALLOC_FAIL;
66
67         // set type name and length and  TNF field
68         record_temp->TNF = recordType;
69         record_temp->type_s.length = typeName->length;
70
71         if(record_temp->type_s.length > 0)
72         {
73                 _net_nfc_util_alloc_mem(record_temp->type_s.buffer, record_temp->type_s.length);
74                 if (NULL == record_temp->type_s.buffer)
75                 {
76                         _net_nfc_util_free_mem(record_temp);
77
78                         return NET_NFC_ALLOC_FAIL;
79                 }
80
81                 memcpy(record_temp->type_s.buffer, typeName->buffer, record_temp->type_s.length);
82         }
83         else
84         {
85                 record_temp->type_s.buffer = NULL;
86                 record_temp->type_s.length = 0;
87         }
88
89         // set payload
90         record_temp->payload_s.length = payload->length;
91         if(payload->length >0)
92         {
93                 _net_nfc_util_alloc_mem(record_temp->payload_s.buffer,
94                         record_temp->payload_s.length);
95
96                 if (NULL == record_temp->payload_s.buffer)
97                 {
98                         _net_nfc_util_free_mem(record_temp->type_s.buffer);
99                         _net_nfc_util_free_mem(record_temp);
100
101                         return NET_NFC_ALLOC_FAIL;
102                 }
103
104                 memcpy(record_temp->payload_s.buffer, payload->buffer,
105                         record_temp->payload_s.length);
106         }
107         else
108         {
109                 record_temp->payload_s.buffer = NULL;
110                 record_temp->payload_s.length = 0;
111         }
112
113         if (payload->length < 256)
114                 record_temp->SR = 1;
115         else
116                 record_temp->SR = 0;
117
118         // set id and id length and IL field
119         if (id != NULL && id->buffer != NULL && id->length > 0)
120         {
121                 record_temp->id_s.length = id->length;
122                 _net_nfc_util_alloc_mem(record_temp->id_s.buffer, record_temp->id_s.length);
123                 if (NULL == record_temp->id_s.buffer)
124                 {
125                         _net_nfc_util_free_mem(record_temp->payload_s.buffer);
126                         _net_nfc_util_free_mem(record_temp->type_s.buffer);
127                         _net_nfc_util_free_mem(record_temp);
128
129                         return NET_NFC_ALLOC_FAIL;
130                 }
131
132                 memcpy(record_temp->id_s.buffer, id->buffer, record_temp->id_s.length);
133                 record_temp->IL = 1;
134         }
135         else
136         {
137                 record_temp->IL = 0;
138                 record_temp->id_s.buffer = NULL;
139                 record_temp->id_s.length = 0;
140         }
141
142         // this is default value
143         record_temp->MB = 1;
144         record_temp->ME = 1;
145
146         record_temp->next = NULL;
147
148         *record = record_temp;
149
150         return NET_NFC_OK;
151 }
152
153 net_nfc_error_e net_nfc_util_create_uri_type_record(const char *uri,
154                 net_nfc_schema_type_e protocol_schema, ndef_record_s **record)
155 {
156         data_s type_data;
157         net_nfc_error_e error;
158         data_s payload_data = { NULL, 0 };
159
160         RETV_IF(NULL == uri, NET_NFC_NULL_PARAMETER);
161
162         payload_data.length = strlen((char *)uri) + 1;
163
164         RETV_IF(1 == payload_data.length, NET_NFC_INVALID_PARAM);
165
166         _net_nfc_util_alloc_mem(payload_data.buffer, payload_data.length);
167         if (NULL == payload_data.buffer)
168                 return NET_NFC_ALLOC_FAIL;
169
170         payload_data.buffer[0] = protocol_schema;       /* first byte of payload is protocol scheme */
171         memcpy(payload_data.buffer + 1, uri, payload_data.length - 1);
172
173         type_data.length = 1;
174         type_data.buffer = (uint8_t *)URI_RECORD_TYPE;
175
176         error = net_nfc_util_create_record(NET_NFC_RECORD_WELL_KNOWN_TYPE,
177                         &type_data, NULL, &payload_data, record);
178
179         _net_nfc_util_free_mem(payload_data.buffer);
180
181         return error;
182 }
183
184 net_nfc_error_e net_nfc_util_create_text_type_record(const char *text,
185         const char *lang_code_str, net_nfc_encode_type_e encode, ndef_record_s **record)
186 {
187         int offset = 0;
188         data_s type_data;
189         int controll_byte;
190         data_s payload_data;
191
192         RETV_IF(NULL == text, NET_NFC_NULL_PARAMETER);
193         RETV_IF(NULL == lang_code_str, NET_NFC_NULL_PARAMETER);
194
195         RETVM_IF(encode < NET_NFC_ENCODE_UTF_8 || NET_NFC_ENCODE_UTF_16 < encode ,
196                 NET_NFC_OUT_OF_BOUND, "encode(%d) is invalid", encode);
197
198         payload_data.length = strlen((char *)text) + strlen(lang_code_str) + 1;
199
200         _net_nfc_util_alloc_mem(payload_data.buffer, payload_data.length);
201         if (NULL == payload_data.buffer)
202         {
203                 return NET_NFC_ALLOC_FAIL;
204         }
205
206         controll_byte = strlen(lang_code_str) & 0x3F;
207         if (NET_NFC_ENCODE_UTF_16 == encode)
208         {
209                 controll_byte = controll_byte | 0x80;
210         }
211
212         payload_data.buffer[0] = controll_byte;
213
214         offset = 1;
215         memcpy(payload_data.buffer + offset, lang_code_str, strlen(lang_code_str));
216
217         offset = offset + strlen(lang_code_str);
218         memcpy(payload_data.buffer + offset, (char *)text, strlen((char *)text));
219
220         type_data.length = 1;
221         type_data.buffer = (uint8_t *)TEXT_RECORD_TYPE;
222
223         net_nfc_util_create_record(NET_NFC_RECORD_WELL_KNOWN_TYPE, &type_data, NULL,
224                 &payload_data, record);
225
226         _net_nfc_util_free_mem(payload_data.buffer);
227
228         return NET_NFC_OK;
229 }
230
231 net_nfc_error_e net_nfc_util_set_record_id(ndef_record_s *record,
232         uint8_t *data, int length)
233 {
234         RETV_IF(NULL == data, NET_NFC_NULL_PARAMETER);
235         RETV_IF(NULL == record, NET_NFC_NULL_PARAMETER);
236         RETV_IF(length < 1, NET_NFC_OUT_OF_BOUND);
237
238         if (record->id_s.buffer != NULL && record->id_s.length > 0)
239                 _net_nfc_util_free_mem(record->id_s.buffer);
240
241         _net_nfc_util_alloc_mem(record->id_s.buffer, length);
242
243         if (record->id_s.buffer == NULL)
244                 return NET_NFC_ALLOC_FAIL;
245
246         memcpy(record->id_s.buffer, data, length);
247         record->id_s.length = length;
248         record->IL = 1;
249
250         return NET_NFC_OK;
251 }
252
253 uint32_t net_nfc_util_get_record_length(ndef_record_s *Record)
254 {
255         uint32_t RecordLength = 1;
256
257         RETV_IF(NULL == Record, 0);
258
259         /* Type length is present only for following TNF
260            NET_NFC_TNF_NFCWELLKNOWN
261            NET_NFC_TNF_MEDIATYPE
262            SLP_FRINET_NFC_NDEFRECORD_TNF_ABSURI
263            SLP_FRINET_NFC_NDEFRECORD_TNF_NFCEXT
264            */
265
266         /* ++ is for the Type Length Byte */
267         RecordLength++;
268         if (Record->TNF != NET_NFC_NDEF_TNF_EMPTY &&
269                         Record->TNF != NET_NFC_NDEF_TNF_UNKNOWN &&
270                         Record->TNF != NET_NFC_NDEF_TNF_UNCHANGED)
271         {
272                 RecordLength += Record->type_s.length;
273         }
274
275         /* to check if payloadlength is 8bit or 32bit*/
276         if (Record->SR != 0)
277         {
278                 /* ++ is for the Payload Length Byte */
279                 RecordLength++;/* for short record*/
280         }
281         else
282         {
283                 /* + NET_NFC_NDEF_NORMAL_RECORD_BYTE is for the Payload Length Byte */
284                 RecordLength += 4;
285         }
286
287         /* for non empty record */
288         if (Record->TNF != NET_NFC_NDEF_TNF_EMPTY)
289                 RecordLength += Record->payload_s.length;
290
291         /* ID and IDlength are present only if IL flag is set*/
292         if (Record->IL != 0)
293         {
294                 RecordLength += Record->id_s.length;
295                 /* ++ is for the ID Length Byte */
296                 RecordLength++;
297         }
298
299         return RecordLength;
300 }
301
302 net_nfc_error_e net_nfc_util_create_uri_string_from_uri_record(
303         ndef_record_s *record, char **uri)
304 {
305         net_nfc_error_e result = NET_NFC_OK;
306
307         RETV_IF(NULL == uri, NET_NFC_INVALID_PARAM);
308         RETV_IF(NULL == record, NET_NFC_INVALID_PARAM);
309
310         *uri = NULL;
311
312         if (NET_NFC_RECORD_WELL_KNOWN_TYPE == record->TNF &&
313                         (record->type_s.length == 1 && record->type_s.buffer[0] == 'U'))
314         {
315                 data_s *payload = &record->payload_s;
316
317                 if (payload->length > 0)
318                 {
319                         int length = 0;
320                         const char *scheme = NULL;
321
322                         /* buffer length include a schema byte.
323                          * so it does not need to allocate one more byte for string. */
324                         if ((scheme = net_nfc_util_get_schema_string(payload->buffer[0])) != NULL)
325                                 length = strlen(scheme);
326
327                         *uri = (char *)calloc(1, length + payload->length);
328                         if (*uri != NULL)
329                         {
330                                 if (length > 0)
331                                         memcpy(*uri, scheme, length);
332                                 memcpy(*uri + length, payload->buffer + 1, payload->length - 1);
333                         }
334                         else
335                         {
336                                 result = NET_NFC_ALLOC_FAIL;
337                         }
338                 }
339                 else
340                 {
341                         NFC_ERR("invalid payload in record");
342                 }
343         }
344         else if (NET_NFC_RECORD_URI == record->TNF)
345         {
346                 data_s *type = &record->type_s;
347
348                 if (type->length > 0)
349                 {
350                         *uri = (char *)calloc(1, type->length + 1);
351
352                         if (*uri != NULL)
353                                 memcpy(*uri, type->buffer, type->length);
354                         else
355                                 result = NET_NFC_ALLOC_FAIL;
356                 }
357         }
358         else
359         {
360                 NFC_ERR("no uri record");
361                 result = NET_NFC_NDEF_RECORD_IS_NOT_EXPECTED_TYPE;
362         }
363
364         return result;
365 }