77c8dc6df78d4a0364766ec6a23442e67c9059b7
[platform/upstream/iotivity.git] / android / android_api / base / jni / JniOcSecureResource.cpp
1 /*
2 * //******************************************************************
3 * //
4 * // Copyright 2015 Samsung Electronics All Rights Reserved.
5 * //
6 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 * //
8 * // Licensed under the Apache License, Version 2.0 (the "License");
9 * // you may not use this file except in compliance with the License.
10 * // You may obtain a copy of the License at
11 * //
12 * //      http://www.apache.org/licenses/LICENSE-2.0
13 * //
14 * // Unless required by applicable law or agreed to in writing, software
15 * // distributed under the License is distributed on an "AS IS" BASIS,
16 * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * // See the License for the specific language governing permissions and
18 * // limitations under the License.
19 * //
20 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 */
22
23 #include "JniOcSecureResource.h"
24 #include "JniSecureUtils.h"
25 namespace PH = std::placeholders;
26
27 JniOcSecureResource::JniOcSecureResource(std::shared_ptr<OCSecureResource> device)
28     : m_sharedSecureResource(device)
29 {}
30
31 JniOcSecureResource::~JniOcSecureResource()
32 {
33     LOGD("~JniOcSecureResource()");
34     m_sharedSecureResource = nullptr;
35 }
36
37 std::string JniOcSecureResource::getIpAddr()
38 {
39     return m_sharedSecureResource->getDevAddr();
40 }
41
42 std::string JniOcSecureResource::getDeviceID()
43 {
44     return m_sharedSecureResource->getDeviceID();
45 }
46
47 int JniOcSecureResource::getDeviceStatus()
48 {
49     return m_sharedSecureResource->getDeviceStatus();
50 }
51
52 bool JniOcSecureResource::getOwnedStatus()
53 {
54     return m_sharedSecureResource->getOwnedStatus();
55 }
56
57 OCSecureResource* JniOcSecureResource::getDevicePtr()
58 {
59     return m_sharedSecureResource.get();
60 }
61
62 JniOcSecureResource* JniOcSecureResource::getJniOcSecureResourcePtr(JNIEnv *env, jobject thiz)
63 {
64     JniOcSecureResource *secureResource = GetHandle<JniOcSecureResource>(env, thiz);
65     if (env->ExceptionCheck())
66     {
67         LOGE("Failed to get native handle from OcSecureResource");
68     }
69     if (!secureResource)
70     {
71         ThrowOcException(JNI_NO_NATIVE_POINTER, "");
72     }
73     return secureResource;
74 }
75
76 JniProvisionResultListner* JniOcSecureResource::AddProvisionResultListener(JNIEnv* env,
77         jobject jListener)
78 {
79     JniProvisionResultListner *resultListener = NULL;
80     resultMapLock.lock();
81
82     for (auto it = resultMap.begin(); it != resultMap.end(); ++it)
83     {
84         if (env->IsSameObject(jListener, it->first))
85         {
86             auto refPair = it->second;
87             resultListener = refPair.first;
88             refPair.second++;
89             it->second = refPair;
90             resultMap.insert(*it);
91             LOGD("Provision resultListener: ref. count incremented");
92             break;
93         }
94     }
95     if (!resultListener)
96     {
97         resultListener = new JniProvisionResultListner(env, jListener,
98             RemoveCallback(std::bind(&JniOcSecureResource::RemoveProvisionResultListener,
99                     this, PH::_1, PH::_2)));
100         jobject jgListener = env->NewGlobalRef(jListener);
101
102         resultMap.insert(std::pair < jobject, std::pair < JniProvisionResultListner*,
103                 int >> (jgListener, std::pair<JniProvisionResultListner*, int>(resultListener, 1)));
104         LOGD("Provision resultListener: new listener");
105     }
106     resultMapLock.unlock();
107     return resultListener;
108 }
109
110 void JniOcSecureResource::RemoveProvisionResultListener(JNIEnv* env, jobject jListener)
111 {
112     resultMapLock.lock();
113
114     for (auto it = resultMap.begin(); it != resultMap.end(); ++it)
115     {
116         if (env->IsSameObject(jListener, it->first))
117         {
118             auto refPair = it->second;
119             if (refPair.second > 1)
120             {
121                 refPair.second--;
122                 it->second = refPair;
123                 resultMap.insert(*it);
124                 LOGI("Provision resultListener: ref. count decremented");
125             }
126             else
127             {
128                 env->DeleteGlobalRef(it->first);
129                 JniProvisionResultListner* listener = refPair.first;
130                 delete listener;
131                 resultMap.erase(it);
132                 LOGI("Provision resultListener removed");
133             }
134             break;
135         }
136     }
137     resultMapLock.unlock();
138 }
139
140 OCStackResult JniOcSecureResource::doOwnershipTransfer(JNIEnv* env, jobject jListener)
141 {
142     JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
143
144     ResultCallBack resultCallback = [resultListener](PMResultList_t *result, int hasError)
145     {
146         resultListener->ProvisionResultCallback(result, hasError, ListenerFunc::OWNERSHIPTRANSFER);
147     };
148
149     return m_sharedSecureResource->doOwnershipTransfer(resultCallback);
150 }
151
152 OCStackResult JniOcSecureResource::getLinkedDevices(JNIEnv *env, UuidList_t &uuidList)
153 {
154     return m_sharedSecureResource->getLinkedDevices(uuidList);
155 }
156
157 OCStackResult JniOcSecureResource::removeDevice(JNIEnv* env, jint timeout, jobject jListener)
158 {
159     JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
160
161     ResultCallBack resultCallback = [resultListener](PMResultList_t *result, int hasError)
162     {
163         resultListener->ProvisionResultCallback(result, hasError, ListenerFunc::REMOVEDEVICE);
164     };
165
166     return m_sharedSecureResource->removeDevice((int)timeout, resultCallback);
167 }
168
169 OCStackResult JniOcSecureResource::unlinkDevices(JNIEnv* env, jobject _device2, jobject jListener)
170 {
171     JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
172
173     ResultCallBack resultCallback = [resultListener](PMResultList_t *result, int hasError)
174     {
175         resultListener->ProvisionResultCallback(result, hasError, ListenerFunc::UNLINKDEVICES);
176     };
177
178     JniOcSecureResource *device2 = JniOcSecureResource::getJniOcSecureResourcePtr(env, _device2);
179     if (!device2)
180     {
181         return OC_STACK_ERROR;
182     }
183
184     return m_sharedSecureResource->unlinkDevices(*device2->getDevicePtr(), resultCallback);
185 }
186
187 OCStackResult JniOcSecureResource::provisionCredentials(JNIEnv* env, jint type, jint keySize,
188         jobject _device2, jobject jListener)
189 {
190     JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
191
192     ResultCallBack resultCallback = [resultListener](PMResultList_t *result, int hasError)
193     {
194         resultListener->ProvisionResultCallback(result, hasError, ListenerFunc::PROVISIONCREDENTIALS);
195     };
196
197     JniOcSecureResource *device2 = JniOcSecureResource::getJniOcSecureResourcePtr(env, _device2);
198     if (!device2)
199     {
200         return OC_STACK_ERROR;
201     }
202
203     Credential cred((OicSecCredType_t)type, keySize);
204
205     return m_sharedSecureResource->provisionCredentials(cred, *device2->getDevicePtr(),
206             resultCallback);
207 }
208
209 OCStackResult JniOcSecureResource::provisionACL(JNIEnv* env, jobject _acl, jobject jListener)
210 {
211     OCStackResult ret;
212     JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
213     OicSecAcl_t *acl = new OicSecAcl_t;
214
215     if (!acl)
216     {
217         return OC_STACK_NO_MEMORY;
218     }
219
220     acl->next = nullptr;
221
222     if (OC_STACK_OK != JniSecureUtils::convertJavaACLToOCAcl(env, _acl, acl))
223     {
224         delete acl;
225         return OC_STACK_ERROR;
226     }
227
228     ResultCallBack resultCallback = [acl, resultListener](PMResultList_t *result, int hasError)
229     {
230         delete acl;
231         resultListener->ProvisionResultCallback(result, hasError, ListenerFunc::PROVISIONACL);
232     };
233     ret = m_sharedSecureResource->provisionACL(acl, resultCallback);
234
235     if (ret != OC_STACK_OK)
236     {
237         delete acl;
238
239     }
240     return ret;
241 }
242
243 OCStackResult JniOcSecureResource::provisionPairwiseDevices(JNIEnv* env, jint type, jint keySize,
244         jobject _acl1, jobject _device2, jobject _acl2, jobject jListener)
245 {
246     OCStackResult ret;
247
248     JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
249     JniOcSecureResource *device2 = JniOcSecureResource::getJniOcSecureResourcePtr(env, _device2);
250     if (!device2)
251     {
252         return OC_STACK_ERROR;
253     }
254
255     Credential cred((OicSecCredType_t)type, keySize);
256
257     OicSecAcl_t *acl1 = nullptr;
258     OicSecAcl_t *acl2 = nullptr;
259
260     if (_acl1)
261     {
262         acl1 = new OicSecAcl_t;
263         if (!acl1)
264         {
265             return OC_STACK_NO_MEMORY;
266         }
267
268         if (OC_STACK_OK != JniSecureUtils::convertJavaACLToOCAcl(env, _acl1, acl1))
269         {
270             delete acl1;
271             return OC_STACK_ERROR;
272         }
273         acl1->next = nullptr;
274     }
275
276     if (_acl2)
277     {
278         acl2 = new OicSecAcl_t;
279         if (!acl2)
280         {
281             delete acl1;
282             return OC_STACK_NO_MEMORY;
283         }
284
285         if (OC_STACK_OK != JniSecureUtils::convertJavaACLToOCAcl(env, _acl2, acl2))
286         {
287             delete acl2;
288             return OC_STACK_ERROR;
289         }
290         acl2->next = nullptr;
291     }
292
293     ResultCallBack resultCallback = [acl1, acl2, resultListener](PMResultList_t *result,
294             int hasError)
295     {
296         delete acl1;
297         delete acl2;
298         resultListener->ProvisionResultCallback(result, hasError,
299                 ListenerFunc::PROVISIONPAIRWISEDEVICES);
300     };
301
302
303     ret = m_sharedSecureResource->provisionPairwiseDevices(cred, acl1,
304             *device2->getDevicePtr(), acl2, resultCallback);
305     if (ret != OC_STACK_OK)
306     {
307         delete acl1;
308         delete acl2;
309     }
310     return ret;
311 }
312
313 /*
314  * Class:     org_iotivity_base_OcSecureResource
315  * Method:    doOwnershipTransfer
316  * Signature: (Lorg/iotivity/base/OcSecureResource/doOwnershipTransferListener;)V
317  */
318 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_doOwnershipTransfer
319 (JNIEnv *env, jobject thiz, jobject jListener)
320 {
321     LOGD("OcSecureResource_doOwnershipTransfer");
322     if (!jListener)
323     {
324         ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener cannot be null");
325         return;
326     }
327
328     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
329     if (!secureResource)
330     {
331         return;
332     }
333
334     try
335     {
336         OCStackResult result = secureResource->doOwnershipTransfer(env, jListener);
337         if (OC_STACK_OK != result)
338         {
339             ThrowOcException(result, "OcSecureResource_doOwnershipTransfer");
340             return;
341         }
342     }
343     catch (OCException& e)
344     {
345         LOGE("%s", e.reason().c_str());
346         ThrowOcException(e.code(), e.reason().c_str());
347     }
348 }
349
350 /*
351  * Class:     org_iotivity_base_OcSecureResource
352  * Method:    removeDevice
353  * Signature: (ILorg/iotivity/base/OcSecureResource/removeDevice;)V
354  */
355 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_removeDevice
356 (JNIEnv *env, jobject thiz, jint timeout, jobject jListener)
357 {
358     LOGD("OcSecureResource_removeDevice");
359     if (timeout < 0)
360     {
361         ThrowOcException(OC_STACK_INVALID_PARAM, "Timeout value cannot be negative");
362         return;
363     }
364
365     if (!jListener)
366     {
367         ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener cannot be null");
368         return;
369     }
370
371     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
372     if (!secureResource)
373     {
374         return;
375     }
376
377     try
378     {
379         OCStackResult result = secureResource->removeDevice(env, timeout, jListener);
380         if (OC_STACK_OK != result)
381         {
382             ThrowOcException(result, "OcSecureResource_removeDevice");
383             return;
384         }
385     }
386     catch (OCException& e)
387     {
388         LOGE("%s", e.reason().c_str());
389         ThrowOcException(e.code(), e.reason().c_str());
390     }
391 }
392
393 /*
394  * Class:     org_iotivity_base_OcSecureResource
395  * Method:    unlinkDevices
396  * Signature: (Lorg/iotivity/base/OcSecureResource/unlinkDevices;)V
397  */
398 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_unlinkDevices
399 (JNIEnv *env, jobject thiz, jobject device2, jobject jListener)
400 {
401     LOGD("OcSecureResource_unlinkDevices");
402     if (!jListener || !device2)
403     {
404         ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener or device2 cannot be null");
405         return;
406     }
407
408     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
409     if (!secureResource)
410     {
411         return;
412     }
413
414     try
415     {
416         OCStackResult result = secureResource->unlinkDevices(env, device2, jListener);
417         if (OC_STACK_OK != result)
418         {
419             ThrowOcException(result, "OcSecureResource_unlinkDevices");
420             return;
421         }
422     }
423     catch (OCException& e)
424     {
425         LOGE("%s", e.reason().c_str());
426         ThrowOcException(e.code(), e.reason().c_str());
427     }
428 }
429
430 /*
431  * Class:     org_iotivity_base_OcSecureResource
432  * Method:    provisionCredentials1
433  * Signature: (Lorg/iotivity/base/OcSecureResource/provisionCredentials;)V
434  */
435 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionCredentials1
436 (JNIEnv *env, jobject thiz, jint type, jint keySize, jobject device2, jobject jListener)
437 {
438     LOGD("OcSecureResource_provisionCredentials");
439     if (!jListener || !device2)
440     {
441         ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener or device2 cannot be null");
442         return;
443     }
444
445     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
446     if (!secureResource)
447     {
448         return;
449     }
450
451     try
452     {
453         OCStackResult result = secureResource->provisionCredentials(env, type, keySize, device2,
454                 jListener);
455         if (OC_STACK_OK != result)
456         {
457             ThrowOcException(result, "OcSecureResource_provisionCredentials");
458             return;
459         }
460     }
461     catch (OCException& e)
462     {
463         LOGE("%s", e.reason().c_str());
464         ThrowOcException(e.code(), e.reason().c_str());
465     }
466 }
467
468 /*
469  * Class:     org_iotivity_base_OcSecureResource
470  * Method:    provisionACL
471  * Signature: (Lorg/iotivity/base/OcSecureResource/provisionACL;)V
472  */
473 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionACL
474 (JNIEnv *env, jobject thiz, jobject acl, jobject jListener)
475 {
476     LOGD("OcSecureResource_provisionACL");
477     if (!jListener || !acl)
478     {
479         ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener or acl cannot be null");
480         return;
481     }
482
483     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
484     if (!secureResource)
485     {
486         return;
487     }
488
489     try
490     {
491         OCStackResult result = secureResource->provisionACL(env, acl, jListener);
492         if (OC_STACK_OK != result)
493         {
494             ThrowOcException(result, "OcSecureResource_provisionACL");
495             return;
496         }
497     }
498     catch (OCException& e)
499     {
500         LOGE("%s", e.reason().c_str());
501         ThrowOcException(e.code(), e.reason().c_str());
502     }
503 }
504
505 /*
506  * Class:     org_iotivity_base_OcSecureResource
507  * Method:    provisionPairwiseDevices1
508  * Signature: (Lorg/iotivity/base/OcSecureResource/provisionPairwiseDevices;)V
509  */
510 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionPairwiseDevices1
511 (JNIEnv *env, jobject thiz, jint type, jint keySize, jobject acl1, jobject device2,
512         jobject acl2, jobject jListener)
513 {
514     LOGD("OcSecureResource_provisionPairwiseDevices");
515     if (!jListener || !device2)
516     {
517         ThrowOcException(OC_STACK_INVALID_PARAM, "Invalid Parameters");
518         return;
519     }
520
521     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
522     if (!secureResource)
523     {
524         return;
525     }
526
527     try
528     {
529         OCStackResult result = secureResource->provisionPairwiseDevices(env, type, keySize,
530                 acl1, device2, acl2, jListener);
531         if (OC_STACK_OK != result)
532         {
533             ThrowOcException(result, "OcSecureResource_provisionPairwiseDevices");
534             return;
535         }
536     }
537     catch (OCException& e)
538     {
539         LOGE("%s", e.reason().c_str());
540         ThrowOcException(e.code(), e.reason().c_str());
541     }
542 }
543
544 /*
545  * Class:     org_iotivity_base_OcSecureResource
546  * Method:    getLinkedDevices
547  * Signature: ()Ljava/util/List;
548  */
549 JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcSecureResource_getLinkedDevices
550 (JNIEnv *env, jobject thiz)
551 {
552     LOGD("OcSecureResource_getLinkedDevices");
553     UuidList_t uuidList;
554
555     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
556     if (!secureResource)
557     {
558         return nullptr;
559     }
560
561     try
562     {
563         OCStackResult result = secureResource->getLinkedDevices(env, uuidList);
564         if (OC_STACK_OK != result)
565         {
566             ThrowOcException(result, "OcSecureResource_getLinkedDevices");
567             return nullptr;
568         }
569         return JniSecureUtils::convertUUIDVectorToJavaStrList(env, uuidList);
570     }
571     catch (OCException& e)
572     {
573         LOGE("%s", e.reason().c_str());
574         ThrowOcException(e.code(), e.reason().c_str());
575         return nullptr;
576     }
577 }
578
579 /*
580  * Class:     org_iotivity_base_OcSecureResource
581  * Method:    getIpAddr
582  * Signature: ()Ljava/lang/String;
583  */
584 JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcSecureResource_getIpAddr
585   (JNIEnv *env, jobject thiz)
586 {
587     LOGD("OcSecureResource_getIpAddr");
588     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
589     if (!secureResource)
590     {
591         return nullptr;
592     }
593
594     return env->NewStringUTF(secureResource->getIpAddr().c_str());
595 }
596
597 /*
598  * Class:     org_iotivity_base_OcSecureResource
599  * Method:    getDeviceID
600  * Signature: ()Ljava/lang/String;
601  */
602 JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcSecureResource_getDeviceID
603   (JNIEnv *env , jobject thiz)
604 {
605     LOGD("OcSecureResource_getDeviceID");
606     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
607     if (!secureResource)
608     {
609         return nullptr;
610     }
611
612     return env->NewStringUTF(secureResource->getDeviceID().c_str());
613 }
614
615 /*
616  * Class:     org_iotivity_base_OcSecureResource
617  * Method:    deviceStatus
618  * Signature: ()I
619  */
620 JNIEXPORT jint JNICALL Java_org_iotivity_base_OcSecureResource_deviceStatus
621   (JNIEnv *env, jobject thiz)
622 {
623     LOGD("OcSecureResource_deviceStatus");
624     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
625     if (!secureResource)
626     {
627         return -1;
628     }
629
630     return secureResource->getDeviceStatus();
631 }
632
633 /*
634  * Class:     org_iotivity_base_OcSecureResource
635  * Method:    ownedStatus
636  * Signature: ()I
637  */
638 JNIEXPORT jint JNICALL Java_org_iotivity_base_OcSecureResource_ownedStatus
639   (JNIEnv *env, jobject thiz)
640 {
641     LOGD("OcSecureResource_ownedStatus");
642     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
643     if (!secureResource)
644     {
645         return -1;
646     }
647
648     return secureResource->getOwnedStatus();
649 }
650
651 /*
652  * Class:     org_iotivity_base_OcSecureResource
653  * Method:    dispose
654  * Signature: ()V
655  */
656 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_dispose
657   (JNIEnv *env, jobject thiz)
658 {
659     LOGD("OcSecureResource_dispose");
660     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
661     delete secureResource;
662 }