Andorid(JNI) Implementation for Cloud Provisioning.
[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_PARAM, "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 || !jdeviceId)
318     {
319         ThrowOcException(OC_STACK_INVALID_PARAM, "Listener and deviceID cannot be null");
320         return;
321     }
322
323     JniOcCloudProvisioning *cloud = JniOcCloudProvisioning::getJniOcCloudProvisioningPtr(env, thiz);
324     if (!cloud)
325     {
326         LOGD("OcCloudProvisioning_getAclIdByDevice, No native object, creating now");
327         cloud = Create_native_object(env, thiz);
328         if (!cloud)
329         {
330             ThrowOcException(OC_STACK_ERROR, "OcCloudProvisioning_getAclIdByDevice,"
331                     "Can not Create Native object");
332             return;
333         }
334     }
335
336     const char *str = env->GetStringUTFChars(jdeviceId, NULL);
337     if (!str || env->ExceptionCheck())
338     {
339         ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_getAclIdByDevice");
340         return;
341     }
342     std::string deviceId(str);
343     env->ReleaseStringUTFChars(jdeviceId, str);
344
345     try
346     {
347         OCStackResult result = cloud->getAclIdByDevice(env, deviceId, jListener);
348         if (OC_STACK_OK != result)
349         {
350             ThrowOcException(result, "OcCloudProvisioning_getAclIdByDevice");
351             return;
352         }
353     }
354     catch (OCException& e)
355     {
356         LOGE("%s", e.reason().c_str());
357         ThrowOcException(e.code(), e.reason().c_str());
358     }
359     return;
360 }
361
362 /*
363  * Class:     org_iotivity_base_OcCloudProvisioning
364  * Method:    getIndividualAclInfo
365  * Signature: (Ljava/lang/String;Lorg/iotivity/base/OcCloudProvisioning/GetIndividualAclInfoListener;)V
366  */
367 JNIEXPORT void JNICALL Java_org_iotivity_base_OcCloudProvisioning_getIndividualAclInfo
368   (JNIEnv *env, jobject thiz, jstring jaclID, jobject jListener)
369 {
370     LOGD("OcCloudProvisioning_getIndividualAclInfo");
371     if (!jListener || !jaclID)
372     {
373         ThrowOcException(OC_STACK_INVALID_PARAM, "Listener/aclID cannot be null");
374         return;
375     }
376
377     JniOcCloudProvisioning *cloud = JniOcCloudProvisioning::getJniOcCloudProvisioningPtr(env, thiz);
378     if (!cloud)
379     {
380         LOGD("OcCloudProvisioning_getIndividualAclInfo, No native object, creating now");
381         cloud = Create_native_object(env, thiz);
382         if (!cloud)
383         {
384             ThrowOcException(OC_STACK_ERROR, "OcCloudProvisioning_getIndividualAclInfo,"
385                     "Can not Create Native object");
386             return;
387         }
388     }
389
390     const char *str = env->GetStringUTFChars(jaclID, NULL);
391     std::string aclID(str);
392     env->ReleaseStringUTFChars(jaclID, str);
393
394     try
395     {
396         OCStackResult result = cloud->getIndividualAclInfo(env, jListener, aclID);
397         if (OC_STACK_OK != result)
398         {
399             ThrowOcException(result, "OcCloudProvisioning_getIndividualAclInf");
400             return;
401         }
402     }
403     catch (OCException& e)
404     {
405         LOGE("%s", e.reason().c_str());
406         ThrowOcException(e.code(), e.reason().c_str());
407     }
408     return;
409 }
410
411 /*
412  * Class:     org_iotivity_base_OcCloudProvisioning
413  * Method:    getCRL
414  * Signature: (Lorg/iotivity/base/OcCloudProvisioning/GetCRLListener;)V
415  */
416 JNIEXPORT void JNICALL Java_org_iotivity_base_OcCloudProvisioning_getCRL
417   (JNIEnv *env, jobject thiz, jobject jListener)
418 {
419     LOGD("OcCloudProvisioning_getCRL");
420     if (!jListener)
421     {
422         ThrowOcException(OC_STACK_INVALID_PARAM, "Listener cannot be null");
423         return;
424     }
425
426     JniOcCloudProvisioning *cloud = JniOcCloudProvisioning::getJniOcCloudProvisioningPtr(env, thiz);
427     if (!cloud)
428     {
429         LOGD("OcCloudProvisioning_getCRL, No native object, creating now");
430         cloud = Create_native_object(env, thiz);
431         if (!cloud)
432         {
433             ThrowOcException(OC_STACK_ERROR, "OcCloudProvisioning_getCRL,"
434                     "Can not Create Native object");
435             return;
436         }
437     }
438
439     try
440     {
441         OCStackResult result = cloud->getCRL(env, jListener);
442         if (OC_STACK_OK != result)
443         {
444             ThrowOcException(result, "OcCloudProvisioning_requestCertificate");
445             return;
446         }
447     }
448     catch (OCException& e)
449     {
450         LOGE("%s", e.reason().c_str());
451         ThrowOcException(e.code(), e.reason().c_str());
452     }
453     return;
454 }
455
456 /*
457  * Class:     org_iotivity_base_OcCloudProvisioning
458  * Method:    postCRL0
459  * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/ArrayList;Lorg/iotivity/base/OcCloudProvisioning/PostCRLListener;)V
460  */
461 JNIEXPORT void JNICALL Java_org_iotivity_base_OcCloudProvisioning_postCRL0
462   (JNIEnv *env , jobject thiz, jstring jthisUpdate, jstring jnextUpdate, jstring jcrl,
463    jobjectArray jserialnumArray, jobject jListener)
464 {
465     LOGD("OcCloudProvisioning_postCRL0");
466     if (!jListener || !jthisUpdate || !jnextUpdate || !jserialnumArray)
467     {
468         ThrowOcException(OC_STACK_INVALID_PARAM, " Invalid parameter (NULL param)");
469         return;
470     }
471
472     JniOcCloudProvisioning *cloud = JniOcCloudProvisioning::getJniOcCloudProvisioningPtr(env, thiz);
473     if (!cloud)
474     {
475         LOGD("OcCloudProvisioning_getCRL, No native object, creating now");
476         cloud = Create_native_object(env, thiz);
477         if (!cloud)
478         {
479             ThrowOcException(OC_STACK_ERROR, "OcCloudProvisioning_PostCRL0,"
480                     "Can not Create Native object");
481             return;
482         }
483     }
484
485     const char *str = env->GetStringUTFChars(jthisUpdate, NULL);
486     if (!str || env->ExceptionCheck())
487     {
488         ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_PostCRL0");
489         return;
490     }
491     std::string thisUpdate(str);
492     env->ReleaseStringUTFChars(jthisUpdate, str);
493
494     str = env->GetStringUTFChars(jnextUpdate, NULL);
495     if (!str || env->ExceptionCheck())
496     {
497         ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_PostCRL0");
498         return;
499     }
500     std::string nextUpdate(str);
501     env->ReleaseStringUTFChars(jnextUpdate, str);
502
503     OCByteString *crl = NULL;
504     if (jcrl)
505     {
506         str = env->GetStringUTFChars(jcrl, NULL);
507         if (!str || env->ExceptionCheck())
508         {
509             ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_PostCRL0");
510             return;
511         }
512         crl = (OCByteString*)OICCalloc(1, sizeof(OCByteString));
513         crl->len = (size_t)(strlen(str));
514         crl->bytes = (uint8_t*)OICCalloc(crl->len, sizeof(uint8_t));
515
516         for (size_t i = 0 ; i < crl->len; i++)
517         {
518             crl->bytes[i] = (uint8_t)str[i];
519         }
520     }
521
522     jsize len = env->GetArrayLength(jserialnumArray);
523
524     stringArray_t *serialNumArray = (stringArray_t*)OICCalloc(1, sizeof(stringArray_t));
525     serialNumArray->array = (char**)OICCalloc(len, sizeof(char*));
526     serialNumArray->length = len;
527
528     for (jsize i = 0; i < len; ++i)
529     {
530         jstring jStr = (jstring)env->GetObjectArrayElement(jserialnumArray, i);
531         if (!jStr)
532         {
533             ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_PostCRL0");
534             return;
535         }
536         serialNumArray->array[i] = (char*)env->GetStringUTFChars(jStr, nullptr);
537         if (env->ExceptionCheck())
538         {
539             ThrowOcException(OC_STACK_ERROR,"OcCloudProvisioning_PostCRL0");
540             return;
541         }
542         env->DeleteLocalRef(jStr);
543     }
544
545     try
546     {
547         OCStackResult result = cloud->postCRL(env, thisUpdate, nextUpdate, crl,
548                 serialNumArray, jListener);
549         if (OC_STACK_OK != result)
550         {
551             ThrowOcException(result, "OcCloudProvisioning_PostCRL0");
552             return;
553         }
554     }
555     catch (OCException& e)
556     {
557         LOGE("%s", e.reason().c_str());
558         ThrowOcException(e.code(), e.reason().c_str());
559     }
560     return;
561 }