replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / android / android_api / base / jni / JniOcCloudProvisioning.cpp
1 /*
2 * //******************************************************************
3 * //
4 * // Copyright 2016 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 "JniOcCloudProvisioning.h"
24 #include "oic_malloc.h"
25
26 namespace PH = std::placeholders;
27
28 JniOcCloudProvisioning::JniOcCloudProvisioning(std::shared_ptr<OCCloudProvisioning> p)
29     : m_sharedCloudObject(p)
30 {}
31
32 JniOcCloudProvisioning::~JniOcCloudProvisioning()
33 {
34     LOGD("~JniOcCloudProvisioning");
35     m_sharedCloudObject = nullptr;
36 }
37
38 JniOcCloudResultListener* JniOcCloudProvisioning::AddCloudResultListener(JNIEnv* env,
39         jobject jListener)
40 {
41     JniOcCloudResultListener *resultListener = NULL;
42     resultMapLock.lock();
43
44     for (auto it = resultMap.begin(); it != resultMap.end(); ++it)
45     {
46         if (env->IsSameObject(jListener, it->first))
47         {
48             auto refPair = it->second;
49             resultListener = refPair.first;
50             refPair.second++;
51             it->second = refPair;
52             resultMap.insert(*it);
53             LOGD("Cloud Provision resultListener: ref. count incremented");
54             break;
55         }
56     }
57     if (!resultListener)
58     {
59         resultListener = new JniOcCloudResultListener(env, jListener,
60                 RemoveCallback(std::bind(&JniOcCloudProvisioning::RemoveCloudResultListener,
61                         this, PH::_1, PH::_2)));
62         jobject jgListener = env->NewGlobalRef(jListener);
63
64         resultMap.insert(std::pair < jobject, std::pair < JniOcCloudResultListener*,
65                 int >> (jgListener, std::pair<JniOcCloudResultListener*, int>(resultListener, 1)));
66         LOGD("Cloud Provision resultListener: new listener");
67     }
68     resultMapLock.unlock();
69     return resultListener;
70 }
71
72 void JniOcCloudProvisioning::RemoveCloudResultListener(JNIEnv* env, jobject jListener)
73 {
74     resultMapLock.lock();
75
76     for (auto it = resultMap.begin(); it != resultMap.end(); ++it)
77     {
78         if (env->IsSameObject(jListener, it->first))
79         {
80             auto refPair = it->second;
81             if (refPair.second > 1)
82             {
83                 refPair.second--;
84                 it->second = refPair;
85                 resultMap.insert(*it);
86                 LOGI("Cloud Provision resultListener: ref. count decremented");
87             }
88             else
89             {
90                 env->DeleteGlobalRef(it->first);
91                 JniOcCloudResultListener* listener = refPair.first;
92                 delete listener;
93                 resultMap.erase(it);
94                 LOGI("Cloud Provision resultListener removed");
95             }
96             break;
97         }
98     }
99     resultMapLock.unlock();
100 }
101
102 JniGetAclIdByDeviceListener* JniOcCloudProvisioning::AddGetAclByDeviceListener(JNIEnv* env,
103         jobject jListener)
104 {
105     JniGetAclIdByDeviceListener *resultListener = NULL;
106     aclresultMapLock.lock();
107
108     for (auto it = aclresultMap.begin(); it != aclresultMap.end(); ++it)
109     {
110         if (env->IsSameObject(jListener, it->first))
111         {
112             auto refPair = it->second;
113             resultListener = refPair.first;
114             refPair.second++;
115             it->second = refPair;
116             aclresultMap.insert(*it);
117             LOGD("GetACLByDeviceID Listener: ref. count incremented");
118             break;
119         }
120     }
121     if (!resultListener)
122     {
123         resultListener = new JniGetAclIdByDeviceListener(env, jListener,
124                 RemoveCallback(std::bind(&JniOcCloudProvisioning::RemoveGetAclByDeviceIdListener,
125                         this, PH::_1, PH::_2)));
126         jobject jgListener = env->NewGlobalRef(jListener);
127
128         aclresultMap.insert(std::pair < jobject, std::pair < JniGetAclIdByDeviceListener*,
129                 int >> (jgListener, std::pair<JniGetAclIdByDeviceListener*, int>(resultListener, 1)));
130         LOGD("GetACLByDeviceID Listener: new listener");
131     }
132     aclresultMapLock.unlock();
133     return resultListener;
134 }
135
136 void JniOcCloudProvisioning::RemoveGetAclByDeviceIdListener(JNIEnv* env, jobject jListener)
137 {
138     aclresultMapLock.lock();
139
140     for (auto it = aclresultMap.begin(); it != aclresultMap.end(); ++it)
141     {
142         if (env->IsSameObject(jListener, it->first))
143         {
144             auto refPair = it->second;
145             if (refPair.second > 1)
146             {
147                 refPair.second--;
148                 it->second = refPair;
149                 aclresultMap.insert(*it);
150                 LOGI("GetACLByDeviceID Listener: ref. count decremented");
151             }
152             else
153             {
154                 env->DeleteGlobalRef(it->first);
155                 JniGetAclIdByDeviceListener* listener = refPair.first;
156                 delete listener;
157                 aclresultMap.erase(it);
158                 LOGI("GetACLByDeviceID Listener removed");
159             }
160             break;
161         }
162     }
163     aclresultMapLock.unlock();
164 }
165 JniOcCloudProvisioning * Create_native_object(JNIEnv *env, jobject thiz)
166 {
167     jstring jip = (jstring)env->CallObjectMethod(thiz, g_mid_OcCloudProvisioning_getIP);
168     if (!jip || env->ExceptionCheck())
169     {
170         return nullptr;
171     }
172     const char *str = env->GetStringUTFChars(jip, NULL);
173     std::string ipaddress(str);
174     env->ReleaseStringUTFChars(jip, str);
175
176     jint port = env->CallIntMethod(thiz, g_mid_OcCloudProvisioning_getPort);
177     if (env->ExceptionCheck())
178     {
179         return nullptr;
180     }
181     JniOcCloudProvisioning *cloud = new JniOcCloudProvisioning(
182             std::shared_ptr<OCCloudProvisioning>(new OCCloudProvisioning(ipaddress, (uint16_t)port)));
183     SetHandle<JniOcCloudProvisioning>(env, thiz, cloud);
184     return cloud;
185 }
186
187 JniOcCloudProvisioning* JniOcCloudProvisioning::getJniOcCloudProvisioningPtr(JNIEnv *env, jobject thiz)
188 {
189     JniOcCloudProvisioning *cloud = GetHandle<JniOcCloudProvisioning>(env, thiz);
190
191     if (env->ExceptionCheck())
192     {
193         LOGE("Failed to get native handle from OcCloudProvisioning class");
194     }
195
196     return cloud;
197 }
198
199 OCStackResult JniOcCloudProvisioning::requestCertificate(JNIEnv* env, jobject jListener)
200 {
201     JniOcCloudResultListener *resultListener = AddCloudResultListener(env, jListener);
202
203     ResponseCallBack responseCallBack = [resultListener](OCStackResult result, void *data)
204     {
205         resultListener->CloudResultListenerCB(result, data, ListenerFunc::REQUEST_CERTIFICATE);
206     };
207
208     return m_sharedCloudObject->requestCertificate(responseCallBack);
209 }
210
211 OCStackResult JniOcCloudProvisioning::getIndividualAclInfo(JNIEnv* env, jobject jListener, std::string &aclID)
212 {
213     JniOcCloudResultListener *resultListener = AddCloudResultListener(env, jListener);
214
215     ResponseCallBack responseCallBack = [resultListener](OCStackResult result, void *data)
216     {
217         resultListener->CloudResultListenerCB(result, data, ListenerFunc::GET_ACLINFO);
218     };
219
220     return m_sharedCloudObject->getIndividualAclInfo(aclID, responseCallBack);
221 }
222
223 OCStackResult JniOcCloudProvisioning::getCRL(JNIEnv* env, jobject jListener)
224 {
225     JniOcCloudResultListener *resultListener = AddCloudResultListener(env, jListener);
226
227     ResponseCallBack responseCallBack = [resultListener](OCStackResult result, void *data)
228     {
229         resultListener->CloudResultListenerCB(result, data, ListenerFunc::GET_CRL);
230     };
231
232     return m_sharedCloudObject->getCRL(responseCallBack);
233 }
234
235 OCStackResult JniOcCloudProvisioning::postCRL(JNIEnv* env, const std::string& thisUpdate,
236                                   const std::string& nextUpdate, const OCByteString *crl,
237                                    const stringArray_t *serialNumbers, jobject jListener)
238 {
239     JniOcCloudResultListener *resultListener = AddCloudResultListener(env, jListener);
240
241     ResponseCallBack responseCallBack = [resultListener](OCStackResult result, void *data)
242     {
243         resultListener->CloudResultListenerCB(result, data, ListenerFunc::POST_CRL);
244     };
245
246     return m_sharedCloudObject->postCRL(thisUpdate, nextUpdate, crl, serialNumbers,
247             responseCallBack);
248 }
249
250 OCStackResult JniOcCloudProvisioning::getAclIdByDevice(JNIEnv* env, std::string deviceId,
251         jobject jListener)
252 {
253     JniGetAclIdByDeviceListener *resultListener = AddGetAclByDeviceListener(env, jListener);
254
255     AclIdResponseCallBack aclIdResponseCallBack = [resultListener](OCStackResult result,
256             std::string aclId)
257     {
258         resultListener->GetAclIdByDeviceListenerCB(result, aclId);
259     };
260
261     return m_sharedCloudObject->getAclIdByDevice(deviceId, aclIdResponseCallBack);
262 }
263 /*
264  * Class:     org_iotivity_base_OcCloudProvisioning
265  * Method:    requestCertificate
266  * Signature: (Lorg/iotivity/base/OcCloudProvisioning/RequestCertificateListener;)V
267  */
268 JNIEXPORT void JNICALL Java_org_iotivity_base_OcCloudProvisioning_requestCertificate
269   (JNIEnv* env, jobject thiz, jobject jListener)
270 {
271     LOGD("OcCloudProvisioning_requestCertificate");
272     if (!jListener)
273     {
274         ThrowOcException(OC_STACK_INVALID_CALLBACK, "Listener cannot be null");
275         return;
276     }
277
278     JniOcCloudProvisioning *cloud = JniOcCloudProvisioning::getJniOcCloudProvisioningPtr(env, thiz);
279     if (!cloud)
280     {
281         LOGD("OcCloudProvisioning_requestCertificate, No native object, creating now");
282         cloud = Create_native_object(env, thiz);
283         if (!cloud)
284         {
285             ThrowOcException(OC_STACK_ERROR, "OcCloudProvisioning_requestCertificate,"
286                     "Can not Create Native object");
287             return;
288         }
289     }
290
291     try
292     {
293         OCStackResult result = cloud->requestCertificate(env, jListener);
294         if (OC_STACK_OK != result)
295         {
296             ThrowOcException(result, "OcCloudProvisioning_requestCertificate");
297             return;
298         }
299     }
300     catch (OCException& e)
301     {
302         LOGE("%s", e.reason().c_str());
303         ThrowOcException(e.code(), e.reason().c_str());
304     }
305     return;
306 }
307
308 /*
309  * Class:     org_iotivity_base_OcCloudProvisioning
310  * Method:    getAclIdByDevice
311  * Signature: (Ljava/lang/String;Lorg/iotivity/base/OcCloudProvisioning/GetAclIdByDeviceListener;)V
312  */
313 JNIEXPORT void JNICALL Java_org_iotivity_base_OcCloudProvisioning_getAclIdByDevice
314   (JNIEnv *env, jobject thiz, jstring jdeviceId, jobject jListener)
315 {
316     LOGD("OcCloudProvisioning_getAclIdByDevice");
317     if (!jListener)
318     {
319         ThrowOcException(OC_STACK_INVALID_CALLBACK, "Listener cannot be null");
320         return;
321     }
322
323     if (!jdeviceId)
324     {
325         ThrowOcException(OC_STACK_INVALID_PARAM, "deviceID can not be null");
326         return;
327     }
328     JniOcCloudProvisioning *cloud = JniOcCloudProvisioning::getJniOcCloudProvisioningPtr(env, thiz);
329     if (!cloud)
330     {
331         LOGD("OcCloudProvisioning_getAclIdByDevice, No native object, creating now");
332         cloud = Create_native_object(env, thiz);
333         if (!cloud)
334         {
335             ThrowOcException(OC_STACK_ERROR, "OcCloudProvisioning_getAclIdByDevice,"
336                     "Can not Create Native object");
337             return;
338         }
339     }
340
341     const char *str = env->GetStringUTFChars(jdeviceId, NULL);
342     if (!str || env->ExceptionCheck())
343     {
344         ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_getAclIdByDevice");
345         return;
346     }
347     std::string deviceId(str);
348     env->ReleaseStringUTFChars(jdeviceId, str);
349
350     try
351     {
352         OCStackResult result = cloud->getAclIdByDevice(env, deviceId, jListener);
353         if (OC_STACK_OK != result)
354         {
355             ThrowOcException(result, "OcCloudProvisioning_getAclIdByDevice");
356             return;
357         }
358     }
359     catch (OCException& e)
360     {
361         LOGE("%s", e.reason().c_str());
362         ThrowOcException(e.code(), e.reason().c_str());
363     }
364     return;
365 }
366
367 /*
368  * Class:     org_iotivity_base_OcCloudProvisioning
369  * Method:    getIndividualAclInfo
370  * Signature: (Ljava/lang/String;Lorg/iotivity/base/OcCloudProvisioning/GetIndividualAclInfoListener;)V
371  */
372 JNIEXPORT void JNICALL Java_org_iotivity_base_OcCloudProvisioning_getIndividualAclInfo
373   (JNIEnv *env, jobject thiz, jstring jaclID, jobject jListener)
374 {
375     LOGD("OcCloudProvisioning_getIndividualAclInfo");
376     if (!jListener)
377     {
378         ThrowOcException(OC_STACK_INVALID_CALLBACK, "Listener cannot be null");
379         return;
380     }
381     if (!jaclID)
382     {
383         ThrowOcException(OC_STACK_INVALID_PARAM, "aclID cannot be null");
384         return;
385     }
386
387     JniOcCloudProvisioning *cloud = JniOcCloudProvisioning::getJniOcCloudProvisioningPtr(env, thiz);
388     if (!cloud)
389     {
390         LOGD("OcCloudProvisioning_getIndividualAclInfo, No native object, creating now");
391         cloud = Create_native_object(env, thiz);
392         if (!cloud)
393         {
394             ThrowOcException(OC_STACK_ERROR, "OcCloudProvisioning_getIndividualAclInfo,"
395                     "Can not Create Native object");
396             return;
397         }
398     }
399
400     const char *str = env->GetStringUTFChars(jaclID, NULL);
401     std::string aclID(str);
402     env->ReleaseStringUTFChars(jaclID, str);
403
404     try
405     {
406         OCStackResult result = cloud->getIndividualAclInfo(env, jListener, aclID);
407         if (OC_STACK_OK != result)
408         {
409             ThrowOcException(result, "OcCloudProvisioning_getIndividualAclInf");
410             return;
411         }
412     }
413     catch (OCException& e)
414     {
415         LOGE("%s", e.reason().c_str());
416         ThrowOcException(e.code(), e.reason().c_str());
417     }
418     return;
419 }
420
421 /*
422  * Class:     org_iotivity_base_OcCloudProvisioning
423  * Method:    getCRL
424  * Signature: (Lorg/iotivity/base/OcCloudProvisioning/GetCRLListener;)V
425  */
426 JNIEXPORT void JNICALL Java_org_iotivity_base_OcCloudProvisioning_getCRL
427   (JNIEnv *env, jobject thiz, jobject jListener)
428 {
429     LOGD("OcCloudProvisioning_getCRL");
430     if (!jListener)
431     {
432         ThrowOcException(OC_STACK_INVALID_CALLBACK, "Listener cannot be null");
433         return;
434     }
435
436     JniOcCloudProvisioning *cloud = JniOcCloudProvisioning::getJniOcCloudProvisioningPtr(env, thiz);
437     if (!cloud)
438     {
439         LOGD("OcCloudProvisioning_getCRL, No native object, creating now");
440         cloud = Create_native_object(env, thiz);
441         if (!cloud)
442         {
443             ThrowOcException(OC_STACK_ERROR, "OcCloudProvisioning_getCRL,"
444                     "Can not Create Native object");
445             return;
446         }
447     }
448
449     try
450     {
451         OCStackResult result = cloud->getCRL(env, jListener);
452         if (OC_STACK_OK != result)
453         {
454             ThrowOcException(result, "OcCloudProvisioning_requestCertificate");
455             return;
456         }
457     }
458     catch (OCException& e)
459     {
460         LOGE("%s", e.reason().c_str());
461         ThrowOcException(e.code(), e.reason().c_str());
462     }
463     return;
464 }
465
466 /*
467  * Class:     org_iotivity_base_OcCloudProvisioning
468  * Method:    postCRL0
469  * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/ArrayList;Lorg/iotivity/base/OcCloudProvisioning/PostCRLListener;)V
470  */
471 JNIEXPORT void JNICALL Java_org_iotivity_base_OcCloudProvisioning_postCRL0
472   (JNIEnv *env , jobject thiz, jstring jthisUpdate, jstring jnextUpdate, jstring jcrl,
473    jobjectArray jserialnumArray, jobject jListener)
474 {
475     LOGD("OcCloudProvisioning_postCRL0");
476      if (!jListener)
477     {
478         ThrowOcException(OC_STACK_INVALID_CALLBACK,"Listener can not be null");
479         return;
480     }
481     if (!jthisUpdate || !jnextUpdate || !jserialnumArray)
482     {
483         ThrowOcException(OC_STACK_INVALID_PARAM, " Invalid parameter (NULL param)");
484         return;
485     }
486
487     JniOcCloudProvisioning *cloud = JniOcCloudProvisioning::getJniOcCloudProvisioningPtr(env, thiz);
488     if (!cloud)
489     {
490         LOGD("OcCloudProvisioning_getCRL, No native object, creating now");
491         cloud = Create_native_object(env, thiz);
492         if (!cloud)
493         {
494             ThrowOcException(OC_STACK_ERROR, "OcCloudProvisioning_PostCRL0,"
495                     "Can not Create Native object");
496             return;
497         }
498     }
499
500     const char *str = env->GetStringUTFChars(jthisUpdate, NULL);
501     if (!str || env->ExceptionCheck())
502     {
503         ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_PostCRL0");
504         return;
505     }
506     std::string thisUpdate(str);
507     env->ReleaseStringUTFChars(jthisUpdate, str);
508
509     str = env->GetStringUTFChars(jnextUpdate, NULL);
510     if (!str || env->ExceptionCheck())
511     {
512         ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_PostCRL0");
513         return;
514     }
515     std::string nextUpdate(str);
516     env->ReleaseStringUTFChars(jnextUpdate, str);
517
518     OCByteString *crl = NULL;
519     if (jcrl)
520     {
521         str = env->GetStringUTFChars(jcrl, NULL);
522         if (!str || env->ExceptionCheck())
523         {
524             ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_PostCRL0");
525             return;
526         }
527         crl = (OCByteString*)OICCalloc(1, sizeof(OCByteString));
528         crl->len = (size_t)(strlen(str));
529         crl->bytes = (uint8_t*)OICCalloc(crl->len, sizeof(uint8_t));
530
531         for (size_t i = 0 ; i < crl->len; i++)
532         {
533             crl->bytes[i] = (uint8_t)str[i];
534         }
535     }
536
537     jsize len = env->GetArrayLength(jserialnumArray);
538
539     stringArray_t *serialNumArray = (stringArray_t*)OICCalloc(1, sizeof(stringArray_t));
540     serialNumArray->array = (char**)OICCalloc(len, sizeof(char*));
541     serialNumArray->length = len;
542
543     for (jsize i = 0; i < len; ++i)
544     {
545         jstring jStr = (jstring)env->GetObjectArrayElement(jserialnumArray, i);
546         if (!jStr)
547         {
548             ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_PostCRL0");
549             return;
550         }
551         serialNumArray->array[i] = (char*)env->GetStringUTFChars(jStr, nullptr);
552         if (env->ExceptionCheck())
553         {
554             ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_PostCRL0");
555             return;
556         }
557         env->DeleteLocalRef(jStr);
558     }
559
560     try
561     {
562         OCStackResult result = cloud->postCRL(env, thisUpdate, nextUpdate, crl,
563                 serialNumArray, jListener);
564         if (OC_STACK_OK != result)
565         {
566             ThrowOcException(result, "OcCloudProvisioning_PostCRL0");
567             return;
568         }
569     }
570     catch (OCException& e)
571     {
572         LOGE("%s", e.reason().c_str());
573         ThrowOcException(e.code(), e.reason().c_str());
574     }
575     return;
576 }