2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
20 * @file nfc_condition_candler.cpp
21 * @brief This is the implementation file of the _AlarmConditionHandler class.
28 #include <FBaseColHashMap.h>
29 #include <FBaseUtilRegularExpression.h>
30 #include <FBaseUtilUrlEncoder.h>
32 #include <FBaseSysLog.h>
33 #include <FBase_StringConverter.h>
35 #include <FApp_AppLaunchConditionHandlerBase.h>
38 #ifdef _NfcSysTryLogReturn
39 #undef _NfcSysTryLogReturn
42 #define _NfcSysTryLogReturn(condition, returnValue, ...) \
44 SetLastResult(E_INVALID_FORMAT); \
45 SysLog(NID_APP, __VA_ARGS__); \
50 using namespace Tizen::App;
51 using namespace Tizen::Base;
52 using namespace Tizen::Base::Collection;
53 using namespace Tizen::Base::Utility;
54 using namespace Tizen::System;
58 * @class _NfcConditionHandler
59 * @brief This class implements conditional app launch for alarm condition. (NFC)
62 class _NfcConditionHandler:
63 public _AppLaunchConditionHandlerBase
66 _NfcConditionHandler(void) :
69 // Makes the URI scheme table which is consist of well-known URI schemes the underlying NFC system supports
70 uriSchemeMap.Construct();
71 uriSchemeMap.Add(*(new String(L"http")), *(new String(L"http")));
72 uriSchemeMap.Add(*(new String(L"https")), *(new String(L"https")));
73 uriSchemeMap.Add(*(new String(L"ftp")), *(new String(L"ftp")));
74 uriSchemeMap.Add(*(new String(L"sftp")), *(new String(L"sftp")));
75 uriSchemeMap.Add(*(new String(L"smb")), *(new String(L"smb")));
76 uriSchemeMap.Add(*(new String(L"nfs")), *(new String(L"nfs")));
77 uriSchemeMap.Add(*(new String(L"telnet")), *(new String(L"telnet")));
78 uriSchemeMap.Add(*(new String(L"file")), *(new String(L"file")));
79 uriSchemeMap.Add(*(new String(L"ssh")), *(new String(L"ssh")));
80 uriSchemeMap.Add(*(new String(L"tel")), *(new String(L"tel")));
81 uriSchemeMap.Add(*(new String(L"mailto")), *(new String(L"mailto")));
82 uriSchemeMap.Add(*(new String(L"news")), *(new String(L"news")));
83 uriSchemeMap.Add(*(new String(L"sip")), *(new String(L"sip")));
84 uriSchemeMap.Add(*(new String(L"sips")), *(new String(L"sips")));
85 uriSchemeMap.Add(*(new String(L"tftp")), *(new String(L"tftp")));
86 uriSchemeMap.Add(*(new String(L"imap")), *(new String(L"imap")));
87 uriSchemeMap.Add(*(new String(L"pop")), *(new String(L"pop")));
88 uriSchemeMap.Add(*(new String(L"market")), *(new String(L"market")));
89 uriSchemeMap.Add(*(new String(L"rtsp")), *(new String(L"rtsp")));
92 virtual ~_NfcConditionHandler(void)
94 uriSchemeMap.RemoveAll(true);
97 virtual result Register(_AppLaunchCondition& operation)
99 // TODO: The following pattern is temporary.
100 // It should be changed to cover all NFC conditions according to the NDEF specifications.
101 String pattern(L"([A-Za-z]*)='([0-9A-Za-z&=_\\-\\.\\:\\/\\\\]*)'");
102 String buf(operation.GetConditionString());
106 Utility::RegularExpression regex;
107 char* pOriginalCondition = null;
108 char* pTranslatedCondition = null;
109 result r = E_SUCCESS;
114 r = regex.Construct(pattern);
115 SysTryReturn(NID_APP, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] Failed to regex.Construct(%ls).", GetErrorMessage(r), pattern.GetPointer());
117 ret = regex.Consume(buf, &list);
119 SysTryReturn(NID_APP, ret == true, E_INVALID_FORMAT, E_INVALID_FORMAT, "[%s] Failed to parse the condition (%ls).", GetErrorMessage(r),
122 field = *(String*)list.GetAt(1);
123 value = *(String*)list.GetAt(2);
124 list.RemoveAll(true);
128 pOriginalCondition = _StringConverter::CopyToCharArrayN(value);
129 SysTryReturnResult(NID_APP, pOriginalCondition != null, E_SYSTEM, "Failed to parse the condition.");
131 // Translates OSP condition to SLP service condition
132 pTranslatedCondition = GetNfcAulConditionN(pOriginalCondition);
133 delete[] pOriginalCondition;
135 SysTryReturnResult(NID_APP, pTranslatedCondition != null, E_SYSTEM, "Failed to translate the condition.");
137 r = _Aul::_DesktopFile::UpdateService(operation.GetAppId(), pTranslatedCondition);
139 operation.SetUserData(new String(pTranslatedCondition));
141 delete[] pTranslatedCondition;
151 virtual result Unregister(_AppLaunchCondition& operation)
153 String* pHandle = null;
154 // char* pOriginalCondition = null;
155 char* pTranslatedCondition = null;
156 result r = E_SUCCESS;
158 pHandle = dynamic_cast<String*>(operation.GetUserData());
159 SysTryReturnResult(NID_APP, pHandle != null, E_INVALID_ARG, "Invalid conditional operation.");
161 pTranslatedCondition = _StringConverter::CopyToCharArrayN(*pHandle);
162 SysTryReturnResult(NID_APP, pTranslatedCondition != null, E_SYSTEM, "Failed to parse the condition.");
164 // Translates OSP condition to SLP service condition
165 // pTranslatedCondition = GetNfcAulConditionN(pOriginalCondition);
166 // delete[] pOriginalCondition;
167 // SysTryReturnResult(NID_APP, pTranslatedCondition != null, E_SYSTEM, "Failed to translate the condition.");
169 r = _Aul::_DesktopFile::RemoveService(operation.GetAppId(), pTranslatedCondition); // only operation name is required to remove service.
171 delete[] pTranslatedCondition;
177 char* GetNfcAulConditionN(char* pConditionValue)
179 //-------------------------------------------------------------------------
180 // The BNF format of the OSP NFC condition is as follows:
181 // <condition> ::= <tnf_field>"&"<type_field>["&"<code_field>]
182 // <tnf_field> ::= "tnf="<tnf_value>
183 // <tnf_value> ::= "rtd"|"mime"|"uri"|"ext"
184 // <type_field> ::= "type="<type_string>
185 // <type_string> ::= <String of US_ASCII characters>
186 // <code_field> ::= "code="<uri_code>
187 // <uri_code> ::= "0x"<hexa_digit><hexa_digit>
188 // <hexa_digit> ::= "0".."9"|"A".."F"
190 // AUL translation rules according to <tnf_field> are as follows:
191 // "tnf=rtd" --> "NFC_SERVICE_WELL_KNOWN_TYPE:NULL:"<type_string>"/"{<uri_code>|"*"}
192 // "tnf=ext" --> "NFC_SERVICE_EXTERNAL_TYPE:NULL:"<uri_scheme>"/"<type_string>
193 // "tnf=uri" --> "NFC_SERVICE_URI_TYPE:NULL:"<uri_scheme>"/"<type_string>
194 // "tnf=mime" --> "NFC_SERVICE_MIME_TYPE:NULL:"<type_string>
195 // <uri_scheme> is the head part of <type_string> and delimited by colon(:) and one of the wellknown types
196 // <type_string> of "tnf=ext" and "tnf=mime" must be decapitalized for case-insensitive matching
197 // <type_string> of "tnf=ext" and "tnf=uri" must be percent-encoded
202 // tnf=rtd&type=U&code=0x05
203 // tnf=ext&type=Bordeaux_Wine:1996
204 // tnf=uri&type=http://www.tizen.org
205 // tnf=mime&type=text/x-vcard
207 // NFC_SERVICE_WELL_KNOWN_TYPE:NULL:Sp/*
208 // NFC_SERVICE_WELL_KNOWN_TYPE:NULL:U/0x05
209 // NFC_SERVICE_EXTERNAL_TYPE:NULL:unknown/bordeauxwine%3A1996
210 // NFC_SERVICE_URI_TYPE:http/http%3A%2F%2Fwww.tizen.org
211 // NFC_SERVICE_MIME_TYPE:NULL:text/x-vcard
212 //-------------------------------------------------------------------------
214 String tnfValue; // <tnf_value>
215 String typeString; // <type_string>
216 String uriCode(L'*'); // <uri_code>
217 int delimiterIndex = -1;
219 String originalCondition(pConditionValue);
220 String aulFormatCondition;
221 char* pTranslatedCondition = null;
223 result r = E_SUCCESS;
227 // Check whether the condition includes the tnf field.
228 isOk = originalCondition.StartsWith(L"tnf=", 0);
229 _NfcSysTryLogReturn(isOk == true, null, "Illegal format (%ls) - No tnf field.", originalCondition.GetPointer() );
231 // Search the index of the type field.
232 r = originalCondition.IndexOf(L'&', 0, delimiterIndex);
233 _NfcSysTryLogReturn(r == E_SUCCESS, null, "Illegal format (%ls)- No type field.", originalCondition.GetPointer() );
236 // The length of <tnf_value> is (delimiterIndex - 4).
237 r = originalCondition.SubString(4, delimiterIndex - 4, tnfValue);
238 _NfcSysTryLogReturn(r == E_SUCCESS, null, "Parsing error. (%ls)", originalCondition.GetPointer() );
240 // Check whether the condition includes the type field.
241 isOk = originalCondition.StartsWith(L"type=", delimiterIndex + 1);
242 _NfcSysTryLogReturn(isOk == true, null, "Illegal format (%ls)- No type field.", originalCondition.GetPointer() );
244 // Read <type_string>.
245 r = originalCondition.SubString(delimiterIndex + 6, typeString);
246 _NfcSysTryLogReturn(r == E_SUCCESS, null, "Parsing error. (%ls)", originalCondition.GetPointer() );
248 if (tnfValue.CompareTo(L"rtd") == 0)
250 // Search the index of the code field.
251 // The code field is optional.
252 r = typeString.IndexOf(L'&', 0, delimiterIndex);
255 String fullTypeString(typeString);
257 r = fullTypeString.SubString(0, delimiterIndex, typeString);
258 _NfcSysTryLogReturn(r == E_SUCCESS, null, "Parsing error. (%ls)", originalCondition.GetPointer() );
260 if (typeString.CompareTo(L"U") == 0)
262 // Check whether the condition includes the type field.
263 isOk = fullTypeString.StartsWith(L"code=", delimiterIndex + 1);
264 _NfcSysTryLogReturn(isOk == true, null, "Illegal format (%ls)- No code field after the second '&'.", originalCondition.GetPointer() );
267 r = fullTypeString.SubString(delimiterIndex + 6, uriCode);
268 _NfcSysTryLogReturn(r == E_SUCCESS, null, "Parsing error. (%ls)", originalCondition.GetPointer() );
272 aulFormatCondition = L"NFC_SERVICE_WELL_KNOWN_TYPE:NULL:";
273 aulFormatCondition.Append(typeString);
274 aulFormatCondition.Append(L'/');
275 aulFormatCondition.Append(uriCode); // The default value of 'uriCode' is '*'
277 else if ((tnfValue.CompareTo(L"ext") == 0) || (tnfValue.CompareTo(L"uri") == 0))
279 if (tnfValue.CompareTo(L"ext") == 0)
281 aulFormatCondition = L"NFC_SERVICE_EXTERNAL_TYPE:NULL:";
282 // Convert all the letters to lower case.
283 typeString.ToLowerCase();
287 aulFormatCondition = L"NFC_SERVICE_URI_TYPE:NULL:";
290 r = typeString.IndexOf(L':', 0, delimiterIndex);
295 // Extract the URI scheme from <type_string>.
296 r = typeString.SubString(0, delimiterIndex, uriScheme);
297 _NfcSysTryLogReturn(r == E_SUCCESS, null, "Parsing error.");
299 // if the URI scheme is one of the registered keywords
300 (void) uriSchemeMap.GetValue(uriScheme);
304 aulFormatCondition.Append(uriScheme);
308 aulFormatCondition.Append(L"unknown");
313 aulFormatCondition.Append(L"unknown");
316 String encodedTypeString;
318 // Encode <type_string> using UTF-8 encoding scheme.
319 r = UrlEncoder::Encode(typeString, L"UTF-8", encodedTypeString);
320 _NfcSysTryLogReturn(r == E_SUCCESS, null, "Failed to UTF-8 Encoding.");
322 aulFormatCondition.Append(L'/');
323 aulFormatCondition.Append(encodedTypeString);
325 else if (tnfValue.CompareTo(L"mime") == 0)
327 typeString.ToLowerCase();
329 aulFormatCondition = L"NFC_SERVICE_MIME_TYPE:NULL:";
330 aulFormatCondition.Append(typeString);
334 SysLog(NID_APP, "Illegal format (%ls) - Invalid TNF value", originalCondition.GetPointer() );
338 pTranslatedCondition = _StringConverter::CopyToCharArrayN(aulFormatCondition);
339 _NfcSysTryLogReturn(pTranslatedCondition != null, null, "String conversion error.");
341 return pTranslatedCondition;
345 HashMap uriSchemeMap;
346 }; //_NfcConditionHandler
349 /////////////////////////////////////////////////////////////////////////
350 // All plugins must provide both a creation and a destruction function
351 /////////////////////////////////////////////////////////////////////////
354 _OSP_EXPORT_ _AppLaunchConditionHandlerBase*
357 return new (std::nothrow) _NfcConditionHandler;
361 DestroyPlugin(_AppLaunchConditionHandlerBase* p)