added code to close the netlink socket.
[contrib/iotivity.git] / java / 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 (!jListener)
360     {
361         ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener cannot be null");
362         return;
363     }
364
365     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
366     if (!secureResource)
367     {
368         return;
369     }
370
371     try
372     {
373         OCStackResult result = secureResource->removeDevice(env, timeout, jListener);
374         if (OC_STACK_OK != result)
375         {
376             ThrowOcException(result, "OcSecureResource_removeDevice");
377             return;
378         }
379     }
380     catch (OCException& e)
381     {
382         LOGE("%s", e.reason().c_str());
383         ThrowOcException(e.code(), e.reason().c_str());
384     }
385 }
386
387 /*
388  * Class:     org_iotivity_base_OcSecureResource
389  * Method:    unlinkDevices
390  * Signature: (Lorg/iotivity/base/OcSecureResource/unlinkDevices;)V
391  */
392 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_unlinkDevices
393 (JNIEnv *env, jobject thiz, jobject device2, jobject jListener)
394 {
395     LOGD("OcSecureResource_unlinkDevices");
396     if (!jListener || !device2)
397     {
398         ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener or device2 cannot be null");
399         return;
400     }
401
402     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
403     if (!secureResource)
404     {
405         return;
406     }
407
408     try
409     {
410         OCStackResult result = secureResource->unlinkDevices(env, device2, jListener);
411         if (OC_STACK_OK != result)
412         {
413             ThrowOcException(result, "OcSecureResource_unlinkDevices");
414             return;
415         }
416     }
417     catch (OCException& e)
418     {
419         LOGE("%s", e.reason().c_str());
420         ThrowOcException(e.code(), e.reason().c_str());
421     }
422 }
423
424 /*
425  * Class:     org_iotivity_base_OcSecureResource
426  * Method:    provisionCredentials1
427  * Signature: (Lorg/iotivity/base/OcSecureResource/provisionCredentials;)V
428  */
429 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionCredentials1
430 (JNIEnv *env, jobject thiz, jint type, jint keySize, jobject device2, jobject jListener)
431 {
432     LOGD("OcSecureResource_provisionCredentials");
433     if (!jListener || !device2)
434     {
435         ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener or device2 cannot be null");
436         return;
437     }
438
439     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
440     if (!secureResource)
441     {
442         return;
443     }
444
445     try
446     {
447         OCStackResult result = secureResource->provisionCredentials(env, type, keySize, device2,
448                 jListener);
449         if (OC_STACK_OK != result)
450         {
451             ThrowOcException(result, "OcSecureResource_provisionCredentials");
452             return;
453         }
454     }
455     catch (OCException& e)
456     {
457         LOGE("%s", e.reason().c_str());
458         ThrowOcException(e.code(), e.reason().c_str());
459     }
460 }
461
462 /*
463  * Class:     org_iotivity_base_OcSecureResource
464  * Method:    provisionACL
465  * Signature: (Lorg/iotivity/base/OcSecureResource/provisionACL;)V
466  */
467 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionACL
468 (JNIEnv *env, jobject thiz, jobject acl, jobject jListener)
469 {
470     LOGD("OcSecureResource_provisionACL");
471     if (!jListener || !acl)
472     {
473         ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener or acl cannot be null");
474         return;
475     }
476
477     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
478     if (!secureResource)
479     {
480         return;
481     }
482
483     try
484     {
485         OCStackResult result = secureResource->provisionACL(env, acl, jListener);
486         if (OC_STACK_OK != result)
487         {
488             ThrowOcException(result, "OcSecureResource_provisionACL");
489             return;
490         }
491     }
492     catch (OCException& e)
493     {
494         LOGE("%s", e.reason().c_str());
495         ThrowOcException(e.code(), e.reason().c_str());
496     }
497 }
498
499 /*
500  * Class:     org_iotivity_base_OcSecureResource
501  * Method:    provisionPairwiseDevices1
502  * Signature: (Lorg/iotivity/base/OcSecureResource/provisionPairwiseDevices;)V
503  */
504 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionPairwiseDevices1
505 (JNIEnv *env, jobject thiz, jint type, jint keySize, jobject acl1, jobject device2,
506         jobject acl2, jobject jListener)
507 {
508     LOGD("OcSecureResource_provisionPairwiseDevices");
509     if (!jListener || !device2)
510     {
511         ThrowOcException(OC_STACK_INVALID_PARAM, "Invalid Parameters");
512         return;
513     }
514
515     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
516     if (!secureResource)
517     {
518         return;
519     }
520
521     try
522     {
523         OCStackResult result = secureResource->provisionPairwiseDevices(env, type, keySize,
524                 acl1, device2, acl2, jListener);
525         if (OC_STACK_OK != result)
526         {
527             ThrowOcException(result, "OcSecureResource_provisionPairwiseDevices");
528             return;
529         }
530     }
531     catch (OCException& e)
532     {
533         LOGE("%s", e.reason().c_str());
534         ThrowOcException(e.code(), e.reason().c_str());
535     }
536 }
537
538 /*
539  * Class:     org_iotivity_base_OcSecureResource
540  * Method:    getLinkedDevices
541  * Signature: ()Ljava/util/List;
542  */
543 JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcSecureResource_getLinkedDevices
544 (JNIEnv *env, jobject thiz)
545 {
546     LOGD("OcSecureResource_getLinkedDevices");
547     UuidList_t uuidList;
548
549     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
550     if (!secureResource)
551     {
552         return nullptr;
553     }
554
555     try
556     {
557         OCStackResult result = secureResource->getLinkedDevices(env, uuidList);
558         if (OC_STACK_OK != result)
559         {
560             ThrowOcException(result, "OcSecureResource_getLinkedDevices");
561             return nullptr;
562         }
563         return JniSecureUtils::convertUUIDVectorToJavaStrList(env, uuidList);
564     }
565     catch (OCException& e)
566     {
567         LOGE("%s", e.reason().c_str());
568         ThrowOcException(e.code(), e.reason().c_str());
569         return nullptr;
570     }
571 }
572
573 /*
574  * Class:     org_iotivity_base_OcSecureResource
575  * Method:    getIpAddr
576  * Signature: ()Ljava/lang/String;
577  */
578 JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcSecureResource_getIpAddr
579   (JNIEnv *env, jobject thiz)
580 {
581     LOGD("OcSecureResource_getIpAddr");
582     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
583     if (!secureResource)
584     {
585         return nullptr;
586     }
587
588     return env->NewStringUTF(secureResource->getIpAddr().c_str());
589 }
590
591 /*
592  * Class:     org_iotivity_base_OcSecureResource
593  * Method:    getDeviceID
594  * Signature: ()Ljava/lang/String;
595  */
596 JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcSecureResource_getDeviceID
597   (JNIEnv *env , jobject thiz)
598 {
599     LOGD("OcSecureResource_getDeviceID");
600     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
601     if (!secureResource)
602     {
603         return nullptr;
604     }
605
606     return env->NewStringUTF(secureResource->getDeviceID().c_str());
607 }
608
609 /*
610  * Class:     org_iotivity_base_OcSecureResource
611  * Method:    deviceStatus
612  * Signature: ()I
613  */
614 JNIEXPORT jint JNICALL Java_org_iotivity_base_OcSecureResource_deviceStatus
615   (JNIEnv *env, jobject thiz)
616 {
617     LOGD("OcSecureResource_deviceStatus");
618     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
619     if (!secureResource)
620     {
621         return -1;
622     }
623
624     return secureResource->getDeviceStatus();
625 }
626
627 /*
628  * Class:     org_iotivity_base_OcSecureResource
629  * Method:    ownedStatus
630  * Signature: ()I
631  */
632 JNIEXPORT jint JNICALL Java_org_iotivity_base_OcSecureResource_ownedStatus
633   (JNIEnv *env, jobject thiz)
634 {
635     LOGD("OcSecureResource_ownedStatus");
636     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
637     if (!secureResource)
638     {
639         return -1;
640     }
641
642     return secureResource->getOwnedStatus();
643 }
644
645 /*
646  * Class:     org_iotivity_base_OcSecureResource
647  * Method:    dispose
648  * Signature: ()V
649  */
650 JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_dispose
651   (JNIEnv *env, jobject thiz)
652 {
653     LOGD("OcSecureResource_dispose");
654     JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
655     delete secureResource;
656 }