revise directory organization.
[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         if (record == NULL)
26                 return NET_NFC_NULL_PARAMETER;
27
28         if (record->type_s.buffer != NULL)
29                 _net_nfc_util_free_mem(record->type_s.buffer);
30         if (record->id_s.buffer != NULL)
31                 _net_nfc_util_free_mem(record->id_s.buffer);
32         if (record->payload_s.buffer != NULL)
33                 _net_nfc_util_free_mem(record->payload_s.buffer);
34
35         _net_nfc_util_free_mem(record);
36
37         return NET_NFC_OK;
38 }
39
40 net_nfc_error_e net_nfc_util_create_record(net_nfc_record_tnf_e recordType, data_s *typeName, data_s *id, data_s *payload, ndef_record_s **record)
41 {
42         ndef_record_s *record_temp = NULL;
43
44         if (typeName == NULL || payload == NULL || record == NULL)
45         {
46                 return NET_NFC_NULL_PARAMETER;
47         }
48
49         if (recordType < NET_NFC_RECORD_EMPTY || recordType > NET_NFC_RECORD_UNCHAGNED)
50         {
51                 return NET_NFC_OUT_OF_BOUND;
52         }
53
54         /* empty_tag */
55         if (recordType == NET_NFC_RECORD_EMPTY)
56         {
57                 if ((typeName->buffer != NULL) || (payload->buffer != NULL) || (id->buffer != NULL) || (typeName->length != 0) || (payload->length != 0) || (id->length != 0))
58                         return NET_NFC_NULL_PARAMETER;
59         }
60
61         _net_nfc_util_alloc_mem(record_temp, sizeof(ndef_record_s));
62         if (record_temp == NULL)
63         {
64                 return NET_NFC_ALLOC_FAIL;
65         }
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 (record_temp->type_s.buffer == NULL)
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, record_temp->payload_s.length);
94                 if (record_temp->payload_s.buffer == NULL)
95                 {
96                         _net_nfc_util_free_mem(record_temp->type_s.buffer);
97                         _net_nfc_util_free_mem(record_temp);
98
99                         return NET_NFC_ALLOC_FAIL;
100                 }
101
102                 memcpy(record_temp->payload_s.buffer, payload->buffer, record_temp->payload_s.length);
103         }
104         else
105         {
106                 record_temp->payload_s.buffer = NULL;
107                 record_temp->payload_s.length = 0;
108         }
109
110         if (payload->length < 256)
111         {
112                 record_temp->SR = 1;
113         }
114         else
115         {
116                 record_temp->SR = 0;
117         }
118
119         // set id and id length and IL field
120         if (id != NULL && id->buffer != NULL && id->length > 0)
121         {
122                 record_temp->id_s.length = id->length;
123                 _net_nfc_util_alloc_mem(record_temp->id_s.buffer, record_temp->id_s.length);
124                 if (record_temp->id_s.buffer == NULL)
125                 {
126                         _net_nfc_util_free_mem(record_temp->payload_s.buffer);
127                         _net_nfc_util_free_mem(record_temp->type_s.buffer);
128                         _net_nfc_util_free_mem(record_temp);
129
130                         return NET_NFC_ALLOC_FAIL;
131                 }
132
133                 memcpy(record_temp->id_s.buffer, id->buffer, record_temp->id_s.length);
134                 record_temp->IL = 1;
135         }
136         else
137         {
138                 record_temp->IL = 0;
139                 record_temp->id_s.buffer = NULL;
140                 record_temp->id_s.length = 0;
141         }
142
143         // this is default value
144         record_temp->MB = 1;
145         record_temp->ME = 1;
146
147         record_temp->next = NULL;
148
149         *record = record_temp;
150
151         return NET_NFC_OK;
152 }
153
154 net_nfc_error_e net_nfc_util_create_uri_type_record(const char *uri, net_nfc_schema_type_e protocol_schema, ndef_record_s **record)
155 {
156         net_nfc_error_e error;
157         data_s type_data;
158         data_s payload_data = { NULL, 0 };
159
160         if (uri == NULL)
161         {
162                 return NET_NFC_NULL_PARAMETER;
163         }
164
165         payload_data.length = strlen((char *)uri) + 1;
166         if (payload_data.length == 1)
167         {
168                 return NET_NFC_INVALID_PARAM;
169         }
170
171         _net_nfc_util_alloc_mem(payload_data.buffer, payload_data.length);
172         if (payload_data.buffer == NULL)
173         {
174                 return NET_NFC_ALLOC_FAIL;
175         }
176
177         payload_data.buffer[0] = protocol_schema;       /* first byte of payload is protocol scheme */
178         memcpy(payload_data.buffer + 1, uri, payload_data.length - 1);
179
180         type_data.length = 1;
181         type_data.buffer = (uint8_t *)URI_RECORD_TYPE;
182
183         error = net_nfc_util_create_record(NET_NFC_RECORD_WELL_KNOWN_TYPE, &type_data, NULL, &payload_data, record);
184
185         _net_nfc_util_free_mem(payload_data.buffer);
186
187         return error;
188 }
189
190 net_nfc_error_e net_nfc_util_create_text_type_record(const char *text, const char *lang_code_str, net_nfc_encode_type_e encode, ndef_record_s **record)
191 {
192         data_s type_data;
193         data_s payload_data;
194         int controll_byte;
195         int offset = 0;
196
197         if (text == NULL || lang_code_str == NULL)
198         {
199                 return NET_NFC_NULL_PARAMETER;
200         }
201
202         if ((encode < NET_NFC_ENCODE_UTF_8 || encode > NET_NFC_ENCODE_UTF_16))
203         {
204                 return NET_NFC_OUT_OF_BOUND;
205         }
206
207         payload_data.length = strlen((char *)text) + strlen(lang_code_str) + 1;
208
209         _net_nfc_util_alloc_mem(payload_data.buffer, payload_data.length);
210         if (payload_data.buffer == NULL)
211         {
212                 return NET_NFC_ALLOC_FAIL;
213         }
214
215         controll_byte = strlen(lang_code_str) & 0x3F;
216         if (encode == NET_NFC_ENCODE_UTF_16)
217         {
218                 controll_byte = controll_byte | 0x80;
219         }
220
221         payload_data.buffer[0] = controll_byte;
222
223         offset = 1;
224         memcpy(payload_data.buffer + offset, lang_code_str, strlen(lang_code_str));
225
226         offset = offset + strlen(lang_code_str);
227         memcpy(payload_data.buffer + offset, (char *)text, strlen((char *)text));
228
229         type_data.length = 1;
230         type_data.buffer = (uint8_t *)TEXT_RECORD_TYPE;
231
232         net_nfc_util_create_record(NET_NFC_RECORD_WELL_KNOWN_TYPE, &type_data, NULL, &payload_data, record);
233
234         _net_nfc_util_free_mem(payload_data.buffer);
235
236         return NET_NFC_OK;
237 }
238
239 net_nfc_error_e net_nfc_util_set_record_id(ndef_record_s *record, uint8_t *data, int length)
240 {
241         if (record == NULL || data == NULL)
242         {
243                 return NET_NFC_NULL_PARAMETER;
244         }
245
246         if (length < 1)
247         {
248                 return NET_NFC_OUT_OF_BOUND;
249         }
250
251         if (record->id_s.buffer != NULL && record->id_s.length > 0)
252         {
253                 _net_nfc_util_free_mem(record->id_s.buffer);
254         }
255
256         _net_nfc_util_alloc_mem(record->id_s.buffer, length);
257         if (record->id_s.buffer == NULL)
258         {
259                 return NET_NFC_ALLOC_FAIL;
260         }
261         memcpy(record->id_s.buffer, data, length);
262         record->id_s.length = length;
263         record->IL = 1;
264
265         return NET_NFC_OK;
266 }
267
268 uint32_t net_nfc_util_get_record_length(ndef_record_s *Record)
269 {
270         uint32_t RecordLength = 1;
271
272         if (Record == NULL)
273                 return 0;
274
275         /* Type length is present only for following TNF
276                 NET_NFC_TNF_NFCWELLKNOWN
277                 NET_NFC_TNF_MEDIATYPE
278                 SLP_FRINET_NFC_NDEFRECORD_TNF_ABSURI
279                 SLP_FRINET_NFC_NDEFRECORD_TNF_NFCEXT
280                 */
281
282         /* ++ is for the Type Length Byte */
283         RecordLength++;
284         if (Record->TNF != NET_NFC_NDEF_TNF_EMPTY &&
285                         Record->TNF != NET_NFC_NDEF_TNF_UNKNOWN &&
286                         Record->TNF != NET_NFC_NDEF_TNF_UNCHANGED)
287         {
288                 RecordLength += Record->type_s.length;
289         }
290
291         /* to check if payloadlength is 8bit or 32bit*/
292         if (Record->SR != 0)
293         {
294                 /* ++ is for the Payload Length Byte */
295                 RecordLength++;/* for short record*/
296         }
297         else
298         {
299                 /* + NET_NFC_NDEF_NORMAL_RECORD_BYTE is for the Payload Length Byte */
300                 RecordLength += 4;
301         }
302
303         /* for non empty record */
304         if (Record->TNF != NET_NFC_NDEF_TNF_EMPTY)
305         {
306                 RecordLength += Record->payload_s.length;
307         }
308
309         /* ID and IDlength are present only if IL flag is set*/
310         if (Record->IL != 0)
311         {
312                 RecordLength += Record->id_s.length;
313                 /* ++ is for the ID Length Byte */
314                 RecordLength++;
315         }
316
317         return RecordLength;
318 }
319
320 net_nfc_error_e net_nfc_util_create_uri_string_from_uri_record(ndef_record_s *record, char **uri)
321 {
322         net_nfc_error_e result = NET_NFC_OK;
323
324         if (record == NULL || uri == NULL)
325         {
326                 return NET_NFC_INVALID_PARAM;
327         }
328
329         *uri = NULL;
330
331         if (record->TNF == NET_NFC_RECORD_WELL_KNOWN_TYPE &&
332                         (record->type_s.length == 1 && record->type_s.buffer[0] == 'U'))
333         {
334                 data_s *payload = &record->payload_s;
335
336                 if (payload->length > 0)
337                 {
338                         int length = 0;
339                         const char *scheme = NULL;
340
341                         /* buffer length include a schema byte.
342                          * so it does not need to allocate one more byte for string. */
343                         if ((scheme = net_nfc_util_get_schema_string(payload->buffer[0])) != NULL)
344                         {
345                                 length = strlen(scheme);
346                         }
347
348                         *uri = (char *)calloc(1, length + payload->length);
349                         if (*uri != NULL)
350                         {
351                                 if (length > 0)
352                                         memcpy(*uri, scheme, length);
353                                 memcpy(*uri + length, payload->buffer + 1, payload->length - 1);
354                         }
355                         else
356                         {
357                                 result = NET_NFC_ALLOC_FAIL;
358                         }
359                 }
360                 else
361                 {
362                         DEBUG_ERR_MSG("invalid payload in record");
363                 }
364         }
365         else if (record->TNF == NET_NFC_RECORD_URI)
366         {
367                 data_s *type = &record->type_s;
368
369                 if (type->length > 0)
370                 {
371                         *uri = (char *)calloc(1, type->length + 1);
372
373                         if (*uri != NULL)
374                         {
375                                 memcpy(*uri, type->buffer, type->length);
376                         }
377                         else
378                         {
379                                 result = NET_NFC_ALLOC_FAIL;
380                         }
381                 }
382         }
383         else
384         {
385                 DEBUG_ERR_MSG("no uri record");
386                 result = NET_NFC_NDEF_RECORD_IS_NOT_EXPECTED_TYPE;
387         }
388
389         return result;
390 }