4c92aebf12ef2995df3b775a60564bc53387572b
[framework/web/wrt-plugins-tizen.git] / src / NFC / NFCConverter.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18
19
20 #include <dpl/log/log.h>
21 #include <CommonsJavaScript/Validator.h>
22 #include <CommonsJavaScript/ScopedJSStringRef.h>
23 #include <CommonsJavaScript/JSUtils.h>
24 #include "NFCFactory.h"
25 #include "NFCConverter.h"
26 #include "JSNdefRecord.h"
27 #include "JSNdefRecordText.h"
28 #include "JSNdefRecordURI.h"
29 #include "JSNdefRecordMedia.h"
30 #include "JSNdefMessage.h"
31
32 using namespace std;
33 using namespace WrtDeviceApis::CommonsJavaScript;
34 using namespace WrtDeviceApis;
35
36
37 #define NFC_FILTER_ATTRIBUTE_TAG_TYPES "tagTypes"
38
39 #define NFC_CHANGED_CALLBACK_ONATTATCH "onattach"
40 #define NFC_CHANGED_CALLBACK_ONDETACH "ondetach"
41
42 namespace DeviceAPI {
43 namespace NFC {
44
45 vector<std::string> NFCConverter::m_allowedTagFilterProperties;
46
47 NFCConverter::NFCConverter(JSContextRef context) : Converter(context)
48 {
49     LogDebug("entered");
50     static bool init = initializeAllowedProperties();
51     (void) init;
52 }
53
54 NFCConverter::~NFCConverter()
55 {
56     LogDebug("entered");
57 }
58
59 TagFilterPtr NFCConverter::toNFCTagFilter(JSValueRef jsValue)
60 {
61     LogDebug("entered");
62     if (JSValueIsNull(m_context, jsValue) ||
63         JSValueIsUndefined(m_context, jsValue)) {
64         return TagFilterPtr(); //empty filter
65     }
66     TagFilterPtr filter(new TagFilter());
67
68     Validator validator(m_context);
69
70     if (!JSValueIsUndefined(m_context, jsValue)) {
71         vector<std::string> filter_values(toVectorOfStrings(jsValue));
72
73         LogDebug("NFCConverter, start setting filter values, tag_types.size() : " << filter_values.size());
74           for (unsigned int i=0; i<filter_values.size(); i++) {
75                 nfcTagType filterValue = toNfcTagType(filter_values.at(i));
76
77                 filter->addTagTypeValue(filterValue);
78                   LogDebug("NFCConverter,  tag_types.at(i): " << filter_values.at(i));
79           }
80     }
81     LogDebug("NFCConverter,  filter size == " << filter->getFilterSize());
82
83     return filter;
84 }
85
86
87 nfcTagType NFCConverter::toNfcTagType(std::string typeString) {
88         if (typeString == "GENERIC_TARGET")
89                 return NFC_TAGTYPE_GENERIC_PICC;
90         else if (typeString == "ISO14443_A")
91                 return NFC_TAGTYPE_ISO14443_A_PICC;
92         else if (typeString == "ISO14443_4A")
93                 return NFC_TAGTYPE_ISO14443_4A_PICC;
94         else if (typeString == "ISO14443_3A")
95                 return NFC_TAGTYPE_ISO14443_3A_PICC;
96         else if (typeString == "MIFARE_MINI")
97                 return NFC_TAGTYPE_MIFARE_MINI_PICC;
98         else if (typeString == "MIFARE_1K")
99                 return NFC_TAGTYPE_MIFARE_1K_PICC;
100         else if (typeString == "MIFARE_4K")
101                 return NFC_TAGTYPE_MIFARE_4K_PICC;
102         else if (typeString == "MIFARE_ULTRA")
103                 return NFC_TAGTYPE_MIFARE_ULTRA_PICC;
104         else if (typeString == "MIFARE_DESFIRE")
105                 return NFC_TAGTYPE_MIFARE_DESFIRE_PICC;
106         else if (typeString == "ISO14443_B")
107                 return NFC_TAGTYPE_ISO14443_B_PICC;
108         else if (typeString == "ISO14443_4B")
109                 return NFC_TAGTYPE_ISO14443_4B_PICC;
110         else if (typeString == "ISO14443_BPRIME")
111                 return NFC_TAGTYPE_ISO14443_BPRIME_PICC;
112         else if (typeString == "FELICA")
113                 return NFC_TAGTYPE_FELICA_PICC;
114         else if (typeString == "JEWEL")
115                 return NFC_TAGTYPE_JEWEL_PICC;
116         else if (typeString == "ISO15693")
117                 return NFC_TAGTYPE_ISO15693_PICC;
118         else if (typeString == "UNKNOWN_TARGET")
119                 return NFC_TAGTYPE_UNKNOWN_TARGET;
120         else
121                 ThrowMsg(Commons::ConversionException, "No Match Tag Type");
122 }
123
124 std::string NFCConverter::toNfcTagTypeString(nfcTagType type) {
125         switch (type) {
126                 case NFC_TAGTYPE_GENERIC_PICC:
127                         return "GENERIC_TARGET";
128                         break;
129                 case NFC_TAGTYPE_ISO14443_A_PICC:
130                         return "ISO14443_A";
131                         break;
132                 case NFC_TAGTYPE_ISO14443_4A_PICC:
133                         return "ISO14443_4A";
134                         break;
135                 case NFC_TAGTYPE_ISO14443_3A_PICC:
136                         return "ISO14443_3A";
137                         break;
138                 case NFC_TAGTYPE_MIFARE_MINI_PICC:
139                         return "MIFARE_MINI";
140                         break;
141                 case NFC_TAGTYPE_MIFARE_1K_PICC:
142                         return "MIFARE_1K";
143                         break;
144                 case NFC_TAGTYPE_MIFARE_4K_PICC:
145                         return "MIFARE_4K";
146                         break;
147                 case NFC_TAGTYPE_MIFARE_ULTRA_PICC:
148                         return "MIFARE_ULTRA";
149                         break;
150                 case NFC_TAGTYPE_MIFARE_DESFIRE_PICC:
151                         return "MIFARE_DESFIRE";
152                         break;
153                 case NFC_TAGTYPE_ISO14443_B_PICC:
154                         return "ISO14443_B";
155                         break;
156                 case NFC_TAGTYPE_ISO14443_4B_PICC:
157                         return "ISO14443_4B";
158                         break;
159                 case NFC_TAGTYPE_ISO14443_BPRIME_PICC:
160                         return "ISO14443_BPRIME";
161                         break;
162                 case NFC_TAGTYPE_FELICA_PICC:
163                         return "FELICA";
164                         break;
165                 case NFC_TAGTYPE_JEWEL_PICC:
166                         return "JEWEL";
167                         break;
168                 case NFC_TAGTYPE_ISO15693_PICC:
169                         return "ISO15693";
170                         break;
171                 case NFC_TAGTYPE_UNKNOWN_TARGET:
172                 default:
173                         return "UNKNOWN_TARGET";
174                         break;
175         }
176 }
177
178 nfcTextEncodeUTF NFCConverter::toNfcTextEncodeUTF(std::string encodeString) {
179         if (encodeString == "UTF8")
180                 return NFC_TEXT_ENCODE_UTF_8;
181         else if (encodeString == "UTF16")
182                 return NFC_TEXT_ENCODE_UTF_16;
183         else
184                 Throw(ConversionException);
185 }
186
187 std::string NFCConverter::toNfcTextEncodeUTFString(nfcTextEncodeUTF encode) {
188         switch(encode) {
189                 case NFC_TEXT_ENCODE_UTF_8:
190                         return "UTF8";
191                         break;
192                 case NFC_TEXT_ENCODE_UTF_16:
193                         return "UTF16";
194                         break;
195                 default:
196                         Throw(ConversionException);
197         }
198 }
199
200 nfcTNF NFCConverter::toNfcTNF(const JSValueRef& arg) {
201         long value = toLong(arg);
202         LogDebug("toNfcTNF,  value == " << value);
203
204         if ((value < NFC_TNF_EMPTY) || (value > NFC_TNF_UNCHANGED)) {
205                 ThrowMsg(InvalidArgumentException, "It is not a correct tnf value");
206         }
207
208         return static_cast<nfcTNF>(value);
209 }
210
211 bool NFCConverter::initializeAllowedProperties()
212 {
213     LogDebug("entered");
214     //NFC Filter properties
215     m_allowedTagFilterProperties.push_back(NFC_FILTER_ATTRIBUTE_TAG_TYPES);
216      return true;
217 }
218
219 JSValueRef NFCConverter::toJSValueRef(const std::vector<unsigned char>& arg) {
220     JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
221
222     if (NULL == jsResult) {
223         ThrowMsg(Commons::UnknownException, "Could not create js array object");
224     }
225
226     for (std::size_t i = 0; i < arg.size(); ++i) {
227         JSValueRef tmpVal = JSValueMakeNumber(m_context, arg[i]);
228         if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
229             ThrowMsg(Commons::UnknownException, "Could not insert value into js array");
230         }
231     }
232
233     return jsResult;
234 }
235
236 JSValueRef NFCConverter::toJSValueRef(NdefRecordData arg) {
237         if (arg.properties.tnf == NFC_TNF_MIME_MEDIA)
238                 return JSNdefRecordMedia::createJSObject(m_context, arg.properties, arg.payload);
239         if (arg.properties.tnf == NFC_TNF_WELL_KNOWN) {
240                 if (arg.properties.typeName.size() > 0) {
241                         if (arg.properties.typeName[0] == 0x54)
242                                 return JSNdefRecordText::createJSObject(m_context, arg.properties, arg.payload);
243                         if (arg.properties.typeName[0] == 0x55)
244                                 return JSNdefRecordURI::createJSObject(m_context, arg.properties, arg.payload);
245                 }
246         }
247         return JSNdefRecord::createJSObject(m_context, arg.properties, arg.payload);
248 }
249
250 JSValueRef NFCConverter::toJSValueRef(std::vector<NFCTagProperties> props) {
251         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
252         if (NULL == jsResult) {
253                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
254                          "Could not create js array object");
255         }
256
257         for (std::size_t i = 0; i < props.size(); ++i) {
258                 JSValueRef tmpVal = toJSValueRef(props[i].value);
259                 if (!JSSetArrayElementInArrayList(m_context, jsResult, props[i].key.c_str(), tmpVal)) {
260                         ThrowMsg(WrtDeviceApis::Commons::UnknownException,
261                                  "Could not insert value into js array");
262                 }
263         }
264         return jsResult;
265 }
266
267 bool NFCConverter::isNdefRecord(const JSValueRef& arg) {
268         LogDebug("Entered");
269         if (JSValueIsNull(m_context, arg) || JSValueIsUndefined(m_context, arg)) {
270                 LogDebug("Object is Null or Undefied");
271                 return false;
272         }
273         if (JSValueIsObjectOfClass(m_context, arg, JSNdefRecord::getClassRef())
274                 || JSValueIsObjectOfClass(m_context, arg, JSNdefRecordText::getClassRef())
275                 || JSValueIsObjectOfClass(m_context, arg, JSNdefRecordURI::getClassRef())
276                 || JSValueIsObjectOfClass(m_context, arg, JSNdefRecordMedia::getClassRef()))
277                 return true;
278
279         return false;
280 }
281
282 std::vector<void *> NFCConverter::toVectorOfRecordHandles(const JSValueRef& arg) {
283     if (JSValueIsNull(m_context, arg) || JSValueIsUndefined(m_context, arg)) {
284                 ThrowMsg(Commons::ConversionException,
285                          "NdefRecordArray is JS null or JS undefined.");
286     }
287
288     if (!JSIsArrayValue(m_context, arg)) {
289         ThrowMsg(Commons::ConversionException, "Argument is not an JS array.");
290     }
291
292     std::vector<void *> result;
293     JSObjectRef objArg = toJSObjectRef(arg);
294     for (std::size_t i = 0; i < JSGetArrayLength(m_context, objArg); ++i) {
295         JSValueRef element = JSGetArrayElement(m_context, objArg, i);
296         if (isNdefRecord(element))
297                 result.push_back(getRecordHandle(element));
298         else
299                 ThrowMsg(Commons::ConversionException, "JS array has no record.");
300     }
301     return result;
302 }
303
304 std::string NFCConverter::toRecordClassName(NdefRecordData arg) {
305         if (arg.properties.tnf == NFC_TNF_MIME_MEDIA)
306                 return JSNdefRecordMedia::getClassInfo()->className;
307         if (arg.properties.tnf == NFC_TNF_WELL_KNOWN) {
308                 if (arg.properties.typeName.size() > 0) {
309                         if (arg.properties.typeName[0] == 0x54)
310                                 return JSNdefRecordText::getClassInfo()->className;
311                         if (arg.properties.typeName[0] == 0x55)
312                                 return JSNdefRecordURI::getClassInfo()->className;
313                 }
314         }
315         return JSNdefRecord::getClassInfo()->className;
316 }
317
318 void *NFCConverter::getRecordHandle(const JSValueRef& arg) {
319         LogDebug("Entered");
320         if (!isNdefRecord(arg)) {
321                 ThrowMsg(Commons::ConversionException,
322                          "Message is JS null or JS undefined.");
323         }
324         JSObjectRef obj = toJSObjectRef(arg);
325         
326         if (!obj) {
327                 LogError("Object is null");
328                 ThrowMsg(Commons::ConversionException, "Object is null");
329         }
330         NdefRecordPrivObject* privateObject = static_cast<NdefRecordPrivObject*>(JSObjectGetPrivate(obj));
331         if (!privateObject) {
332                 LogError("Private object is not set.");
333                 ThrowMsg(Commons::ConversionException, "Private object not set");
334         }
335
336         INdefRecordPtr record = privateObject->getObject();
337
338         return record->getHandle();
339 }
340
341 void *NFCConverter::getMessageHandle(const JSValueRef& arg) {
342         if (JSValueIsNull(m_context, arg) || JSValueIsUndefined(m_context, arg) ||
343                 (!JSValueIsObjectOfClass(m_context, arg, JSNdefMessage::getClassRef()))) {
344                 ThrowMsg(Commons::ConversionException,
345                          "Message is JS null or JS undefined.");
346         }
347         JSObjectRef obj = toJSObjectRef(arg);
348         
349         if (!obj) {
350                 LogError("Object is null");
351                 ThrowMsg(Commons::ConversionException, "Object is null");
352         }
353         NdefMessagePrivObject* privateObject = static_cast<NdefMessagePrivObject*>(JSObjectGetPrivate(obj));
354         if (!privateObject) {
355                 LogError("Private object is not set.");
356                 ThrowMsg(Commons::ConversionException, "Private object is not set");
357         }
358
359         INdefMessagePtr message = privateObject->getObject();
360
361         return message->getHandle();
362 }
363
364 NFCChangedCallback NFCConverter::toNFCChangedCallback(const JSValueRef& arg) {
365         LogDebug("Entered");
366     JSObjectRef object = toJSObjectRef(arg);
367
368     NFCChangedCallback result;
369     Validator validator(m_context);
370
371     result.onattach= JSUtils::getJSPropertyOrUndefined(
372             m_context, object, NFC_CHANGED_CALLBACK_ONATTATCH
373             );
374     if (!validator.isNullOrUndefined(result.onattach) &&
375         !validator.isCallback(result.onattach)) {
376         ThrowMsg(Commons::ConversionException, "Not a valid callback.");
377     }
378
379     result.ondetach= JSUtils::getJSPropertyOrUndefined(
380             m_context, object, NFC_CHANGED_CALLBACK_ONDETACH
381             );
382     if (!validator.isNullOrUndefined(result.ondetach) &&
383         !validator.isCallback(result.ondetach)) {
384         ThrowMsg(Commons::ConversionException, "Not a valid callback.");
385     }
386
387     if (validator.isNullOrUndefined(result.onattach) && validator.isNullOrUndefined(result.ondetach))
388         ThrowMsg(Commons::ConversionException, "Not a valid callback.");
389
390     return result;
391 }
392
393 EventNFCSEType NFCConverter::toSEType(JSValueRef arg) {
394         std::string seType = toString(arg);
395         if (seType == "NONE")
396                 return NFC_SE_NONE;
397         else if (seType == "ESE")
398                 return NFC_SE_ESE;
399         else if (seType == "UICC")
400                 return NFC_SE_UICC;
401         else
402                 ThrowMsg(Commons::ConversionException, "No Match SE Type");
403 }
404
405 JSValueRef NFCConverter::toJSValueRefSEType(EventNFCSEType type) {
406         if (type == NFC_SE_NONE)
407                 return toJSValueRef("NONE");
408         else if (type == NFC_SE_ESE)
409                 return toJSValueRef("ESE");
410         else if (type == NFC_SE_UICC)
411                 return toJSValueRef("UICC");
412         else
413                 ThrowMsg(Commons::ConversionException, "No Match SE Type");
414 }
415
416 }
417 }