From: Thiago Macieira Date: Mon, 16 May 2016 20:09:22 +0000 (-0700) Subject: Merge branch '1.1-rel' X-Git-Tag: 1.2.0+RC1~355^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=442026128ead8780fa45d0db8a6f17be7c9220e0;hp=-c;p=platform%2Fupstream%2Fiotivity.git Merge branch '1.1-rel' Conflicts: android/examples/settings.gradle android/examples/simplebase/simplebase.iml android/examples/simplebase/src/main/AndroidManifest.xml android/examples/simplebase/src/main/res/values-w820dp/dimens.xml android/examples/simplebase/src/main/res/values/dimens.xml plugins/samples/linux/IotivityandZigbeeClient.c resource/csdk/connectivity/inc/cablockwisetransfer.h resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.c resource/csdk/connectivity/src/bt_le_adapter/android/caleutils.c resource/csdk/connectivity/src/bt_le_adapter/android/caleutils.h resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c resource/csdk/connectivity/src/cablockwisetransfer.c resource/csdk/connectivity/src/ip_adapter/caipserver.c resource/csdk/connectivity/src/tcp_adapter/catcpserver.c resource/csdk/connectivity/util/src/camanager/android/caleconnectionmanager.c resource/csdk/connectivity/util/src/camanager/tizen/caleconnectionmanager.c resource/csdk/security/SConscript resource/csdk/security/include/internal/aclresource.h resource/csdk/security/include/internal/dpairingresource.h resource/csdk/security/include/internal/pconfresource.h resource/csdk/security/include/internal/pstatresource.h resource/csdk/security/include/internal/srmresourcestrings.h resource/csdk/security/include/securevirtualresourcetypes.h resource/csdk/security/provisioning/ck_manager/sample/provisioningclient.c resource/csdk/security/provisioning/sample/SConscript resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.json resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.json resource/csdk/security/provisioning/src/credentialgenerator.c resource/csdk/security/provisioning/src/ownershiptransfermanager.c resource/csdk/security/provisioning/src/secureresourceprovider.c resource/csdk/security/provisioning/unittest/ocprovisioningmanager.cpp resource/csdk/security/provisioning/unittest/secureresourceprovider.cpp resource/csdk/security/src/aclresource.c resource/csdk/security/src/amaclresource.c resource/csdk/security/src/base64.c resource/csdk/security/src/credresource.c resource/csdk/security/src/directpairing.c resource/csdk/security/src/doxmresource.c resource/csdk/security/src/dpairingresource.c resource/csdk/security/src/pconfresource.c resource/csdk/security/src/psinterface.c resource/csdk/security/src/pstatresource.c resource/csdk/security/src/resourcemanager.c resource/csdk/security/src/secureresourcemanager.c resource/csdk/security/src/srmresourcestrings.c resource/csdk/security/src/svcresource.c resource/csdk/security/unittest/aclresourcetest.cpp resource/csdk/security/unittest/credentialresource.cpp resource/csdk/security/unittest/doxmresource.cpp resource/csdk/stack/include/octypes.h resource/csdk/stack/samples/linux/secure/SConscript resource/csdk/stack/samples/linux/secure/occlientdirectpairing.cpp resource/csdk/stack/samples/linux/secure/oic_svr_db_client_directpairing.json resource/csdk/stack/src/ocpayload.c resource/csdk/stack/src/ocpayloadparse.c resource/csdk/stack/src/ocresource.c resource/csdk/stack/src/ocstack.c resource/docs/cpp-doc/Doxyfile resource/docs/cpp-doc/devdox/mainpage.dox resource/provisioning/examples/SConscript resource/provisioning/examples/provisioningclient.cpp resource/unittests/OCPlatformTest.cpp service/easy-setup/enrollee/arduino/onboarding.cpp service/easy-setup/enrollee/inc/onboarding.h service/easy-setup/enrollee/src/easysetup.c service/easy-setup/enrollee/src/easysetupcallbacks.h service/easy-setup/enrollee/src/onboarding.h service/easy-setup/enrollee/src/resourcehandler.c service/easy-setup/enrollee/src/resourcehandler.h service/easy-setup/enrollee/src/softap.c service/easy-setup/enrollee/src/softap.h service/easy-setup/mediator/csdk/unittests/MediatorCSDKTest.cpp service/easy-setup/mediator/richsdk/unittests/MediatorRichTest.cpp service/easy-setup/sampleapp/enrollee/linux/enrolleewifi.c service/easy-setup/sampleapp/mediator/android/EasySetup/app/src/main/assets/oic_svr_db_client.dat service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator_cpp.cpp service/resource-encapsulation/examples/tizen/RESampleClientApp/src/reclient.cpp service/simulator/java/eclipse-plugin/ServiceProviderPlugin/src/oic/simulator/serviceprovider/view/MetaPropertiesView.java tools/tizen/iotivity.spec service/simulator/java/eclipse-plugin/ServiceProviderPlugin/src/oic/simulator/serviceprovider/view/MetaPropertiesView.java Change-Id: I912131cd6905e5758a143fa71d0e32ef4201abab Signed-off-by: Markus Jung Signed-off-by: Jee Hyeok Kim Signed-off-by: Markus Jung Signed-off-by: Randeep Singh Signed-off-by: jihwan.seo Signed-off-by: hyuna0213.jo Signed-off-by: Habib Virji Signed-off-by: jihwan.seo Signed-off-by: Jaewook Jung Signed-off-by: Saurabh Sharma Signed-off-by: Jay Sharma Signed-off-by: jihwan.seo Signed-off-by: Thiago Macieira --- 442026128ead8780fa45d0db8a6f17be7c9220e0 diff --combined android/android_api/base/build.gradle index 38e174e,7deb01c..3e67020 --- a/android/android_api/base/build.gradle +++ b/android/android_api/base/build.gradle @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2015 Intel Corporation. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2015 Intel Corporation. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ apply plugin: 'com.android.library' @@@ -41,7 -41,8 +41,8 @@@ android minSdkVersion 21 targetSdkVersion 21 versionCode 1 - versionName "1.0" + versionName "1.1" + buildConfigField 'int', 'SECURED', SECURED } buildTypes { release { diff --combined android/android_api/base/src/main/java/org/iotivity/base/ErrorCode.java index e05328a,bba664e..a6603ae --- a/android/android_api/base/src/main/java/org/iotivity/base/ErrorCode.java +++ b/android/android_api/base/src/main/java/org/iotivity/base/ErrorCode.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2015 Intel Corporation. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2015 Intel Corporation. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.base; @@@ -61,6 -61,9 +61,9 @@@ public enum ErrorCode PDM_IS_NOT_INITIALIZED("PDM_IS_NOT_INITIALIZED", ""), DUPLICATE_UUID("DUPLICATE_UUID", ""), INCONSISTENT_DB("INCONSISTENT_DB", ""), + /** Error code from OTM */ + AUTHENTICATION_FAILURE("AUTHENTICATION_FAILURE", + "This error is pushed from DTLS interface when handshake failure happens"), /** Insert all new error codes here!.*/ PRESENCE_STOPPED("PRESENCE_STOPPED", ""), PRESENCE_TIMEOUT("PRESENCE_TIMEOUT", ""), diff --combined android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java index f062199,c8678ff..d08b1c6 --- a/android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java @@@ -1,28 -1,29 +1,29 @@@ /* - * //****************************************************************** - * // - * // Copyright 2015 Intel Corporation. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2015 Intel Corporation. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.base; import org.iotivity.ca.CaInterface; + import org.iotivity.base.BuildConfig; import java.util.EnumSet; import java.util.Iterator; @@@ -40,6 -41,10 +41,10 @@@ public final class OcPlatform System.loadLibrary("octbstack"); System.loadLibrary("connectivity_abstraction"); System.loadLibrary("oc"); + if (0 != BuildConfig.SECURED) + { + System.loadLibrary("ocprovision"); + } System.loadLibrary("ocstack-jni"); } diff --combined android/android_api/base/src/main/java/org/iotivity/base/OicSecAcl.java index c8c1854,a47ffaa..abd3a5a --- a/android/android_api/base/src/main/java/org/iotivity/base/OicSecAcl.java +++ b/android/android_api/base/src/main/java/org/iotivity/base/OicSecAcl.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2015 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2015 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.base; @@@ -33,16 -33,16 +33,16 @@@ public class OicSecAcl implements Seria private List resources; private List periods; private List recurrences; - private List owners; + private String rownerID; public OicSecAcl(String subject, List recurrences, List periods, int permission, - List resources, List owners) { + List resources, String rownerID) { this.subject = subject; this.recurrences = recurrences; this.periods = periods; this.permission = permission; this.resources = resources; - this.owners = owners; + this.rownerID = rownerID; } public String getSubject() { @@@ -53,12 -53,9 +53,9 @@@ this.subject = subject; } - public List getOwners() { - return owners; - } - public void setOwners(List owners) { - this.owners = owners; + public void setRownerID(String rownerID) { + this.rownerID = rownerID; } public List getRecurrences() { @@@ -113,11 -110,7 +110,7 @@@ return this.recurrences.get(i); } - public int getOwnersCount() { - return this.owners.size(); - } - - public String getOwners(int i) { - return this.owners.get(i); + public String getRownerID() { + return this.rownerID; } } diff --combined cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java index 81dc5f2,a9d6925..5a0e32b --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServer.java @@@ -1,50 -1,45 +1,45 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.accountserver; import java.net.InetSocketAddress; + import java.util.Scanner; import org.iotivity.cloud.accountserver.resources.AccountResource; import org.iotivity.cloud.accountserver.resources.AuthResource; import org.iotivity.cloud.base.CoapServer; import org.iotivity.cloud.base.ResourceManager; import org.iotivity.cloud.util.Logger; - import org.iotivity.cloud.util.Net; /** - * - * This class is in charge of running account server. - * + * + * This class is in charge of running of account server. + * */ public class AccountServer { public static void main(String[] args) throws Exception { System.out.println("-----Account SERVER-----"); - String hostAddress = Net.getMyIpAddress(); - if (hostAddress.equals("") == true) { - Logger.e("cannot find host address."); - return; - } if (args.length != 1) { Logger.e("coap server port required"); @@@ -65,6 -60,19 +60,19 @@@ coapServer .startServer(new InetSocketAddress(Integer.parseInt(args[0]))); - } + Scanner in = new Scanner(System.in, "UTF-8"); + + System.out.println("press 'q' to terminate"); + + while (!in.nextLine().equals("q")); + + in.close(); + + System.out.println("Terminating..."); + + coapServer.stopServer(); + + System.out.println("Terminated"); + } } diff --combined cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServerManager.java index f69b5a8,b2b29a8..5749a7a --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServerManager.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/AccountServerManager.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.accountserver; @@@ -30,12 -30,21 +30,21 @@@ import org.iotivity.cloud.util.Logger /** * - * This class provides a set of API to handle requests for registering account - * information of authorized user, and publishing and finding resources. + * This class provides a set of APIs to handle requests about account + * information of authorized user. * */ public class AccountServerManager { + /** + * API for requesting user account + * + * @param userId + * user identifier + * @param deviceId + * device identifier + * @return Boolean - true if registered, otherwise false + */ public Boolean registerUserAccount(String userId, String deviceId) { Boolean ret = false; @@@ -47,6 -56,14 +56,14 @@@ return ret; } + /** + * API for requesting user account and getting session code for registered + * user. + * + * @param userId + * user identifier + * @return String - session code for registered user + */ public String registerUserAccount(String userId) { String sessionCode = null; @@@ -60,10 -77,11 +77,11 @@@ } /** - * API for requesting user identifier to interested authorization server - * - * @param accessToeken - * access token + * API for requesting user identifier corresponding with authorization + * information. + * + * @param authCode + * authorization code * @param authServer * authorization server * @return String - user identifier @@@ -78,6 -96,13 +96,13 @@@ return userId; } + /** + * API for requesting user identifier corresponding with session code. + * + * @param sessionCode + * session code + * @return String - user identifier + */ public String requestUserId(String sessionCode) { String userId = null; @@@ -89,10 -114,10 +114,10 @@@ } /** - * API for getting devices according to authorized user from database - * + * API for getting devices corresponding with user identifier. + * * @param userId - * identifier of authorized user + * user identifier * @return ArrayList - list of devices */ public ArrayList requestAccountDevices(String userId) { @@@ -105,20 -130,11 +130,11 @@@ return deviceList; } - /** - * API for requesting access token to interested authorization server - * - * @param authServer - * server name for authorization - * @param authCode - * authorization code - * @return ArrayList - array list of name of authorization servers - */ private String getAccessToken(String authCode, String authServer) { String accessToken = null; - if (authServer.equals(Const.GITHUB)) { + if (authServer.equals(Constants.GITHUB)) { GitHub gitHub = new GitHub(); accessToken = gitHub.requestAccessToken(authCode); @@@ -135,7 -151,7 +151,7 @@@ String userId = null; - if (authServer.equals(Const.GITHUB)) { + if (authServer.equals(Constants.GITHUB)) { GitHub gitHub = new GitHub(); userId = gitHub.requestGetUserInfo(accessToken); @@@ -150,7 -166,7 +166,7 @@@ private String generateSessionCode() { - String sessionCode = ""; + StringBuffer sessionCode = new StringBuffer(); Random random = new Random(); int randomNum = random.nextInt(122); @@@ -164,7 -180,7 +180,7 @@@ || (randomNum >= 97 && randomNum <= 122)) { code = (char) randomNum; - sessionCode += code; + sessionCode.append(code); randomNum = random.nextInt(122); break; @@@ -176,6 -192,6 +192,6 @@@ } } - return sessionCode; + return sessionCode.toString(); } } diff --combined cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java index 9b39474,2d8ab4f..c350789 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/Constants.java @@@ -1,27 -1,27 +1,27 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.accountserver; - public class Const { + public class Constants { // MongoDB public static final String DEVICE_TABLE = "USER_DEVICE"; diff --combined cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AccountDBManager.java index 67fe1a1,8569753..dbb0e20 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AccountDBManager.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/AccountDBManager.java @@@ -1,29 -1,29 +1,29 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.accountserver.db; import java.util.ArrayList; - import org.iotivity.cloud.accountserver.Const; + import org.iotivity.cloud.accountserver.Constants; /** * @@@ -39,10 -39,10 +39,10 @@@ public class AccountDBManager try { - mongoDB = new MongoDB(Const.DB_NAME); + mongoDB = new MongoDB(Constants.DB_NAME); - mongoDB.createTable(Const.DEVICE_TABLE); - mongoDB.createTable(Const.SESSION_TABLE); + mongoDB.createTable(Constants.DEVICE_TABLE); + mongoDB.createTable(Constants.SESSION_TABLE); registerAdminAccount(); @@@ -58,28 -58,14 +58,14 @@@ return accoutDBManager; } - private void registerAdminAccount() { - - String adminId = "admin"; - String adminSessionCode = "00000000"; - - UserSession userSession = new UserSession(); - - userSession.setUserId(adminId); - userSession.setSessionCode(adminSessionCode); - - mongoDB.createResource(userSession); - mongoDB.printResources(); - } - /** - * API for storing session information of authorized user to mongoDB - * + * API for storing session information of authorized user + * * @param userId - * identifier of authorized user + * user identifier * @param sessionCode * session code - * @return Boolean - true if stored, false if not + * @return Boolean - true if stored, otherwise false */ public Boolean registerUserSessionCode(String userId, String sessionCode) { @@@ -94,6 -80,15 +80,15 @@@ return true; } + /** + * API for storing device information of authorized user + * + * @param userId + * user identifier + * @param deviceId + * device identifier + * @return Boolean - true if stored, otherwise false + */ public Boolean registerUserDevice(String userId, String deviceId) { UserDevice userDevice = new UserDevice(); @@@ -107,6 -102,16 +102,16 @@@ return true; } + /** + * API for getting user identifier information corresponding with session + * code + * + * @param userId + * identifier of authorized user + * @param sessionCode + * session code + * @return Boolean - true if stored, otherwise false + */ public String getUserId(String sessionCode) { String userId = null; @@@ -117,18 -122,30 +122,30 @@@ } /** - * API for getting devices according to authorized user - * + * API for getting devices corresponding with user identifier + * * @param userId - * identifier of authorized user + * user identifier * @return ArrayList - list of devices */ public ArrayList getDevices(String userId) { - ArrayList deviceList = new ArrayList(); - - deviceList = mongoDB.getDevices(userId); + ArrayList deviceList = mongoDB.getDevices(userId); return deviceList; } + + private void registerAdminAccount() { + + String adminId = "admin"; + String adminSessionCode = "00000000"; + + UserSession userSession = new UserSession(); + + userSession.setUserId(adminId); + userSession.setSessionCode(adminSessionCode); + + mongoDB.createResource(userSession); + mongoDB.printResources(); + } } diff --combined cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java index 149fb5e,049a3f3..191d17a --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/db/MongoDB.java @@@ -1,30 -1,30 +1,30 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.accountserver.db; import java.util.ArrayList; import org.bson.Document; - import org.iotivity.cloud.accountserver.Const; + import org.iotivity.cloud.accountserver.Constants; import org.iotivity.cloud.util.Logger; import com.mongodb.MongoClient; @@@ -51,6 -51,7 +51,7 @@@ public class MongoDB * @throws Exception */ public MongoDB(String dbname) throws Exception { + mongoClient = new MongoClient(); mongoClient.dropDatabase(dbname); db = mongoClient.getDatabase(dbname); @@@ -63,6 -64,7 +64,7 @@@ * collection name */ public void createTable(String tableName) { + db.createCollection(tableName); } @@@ -73,30 -75,34 +75,34 @@@ * collection name */ public void deleteTable(String tableName) { + db.getCollection(tableName).drop(); } + /** + * API getting database object + * + */ public MongoDatabase getMongoDatabase() { + return db; } /** - * API for storing information of authorized users + * API for storing session information of user * - * @param accountInfo - * information of authorized users - * @param tablename - * table name of mongoDB + * @param UserSession + * session information of user */ public void createResource(UserSession userSession) { Document doc = createDocument(userSession); MongoCollection collection = db - .getCollection(Const.SESSION_TABLE); + .getCollection(Constants.SESSION_TABLE); if (collection.findOneAndReplace(Filters.and( - Filters.eq(Const.USER_ID, doc.get(Const.USER_ID)), - Filters.eq(Const.SESSION_CODE, doc.get(Const.SESSION_CODE))), + Filters.eq(Constants.USER_ID, doc.get(Constants.USER_ID)), + Filters.eq(Constants.SESSION_CODE, doc.get(Constants.SESSION_CODE))), doc) == null) { collection.insertOne(doc); @@@ -105,16 -111,21 +111,21 @@@ return; } + /** + * API for inserting device information of user + * + * @param UserDevice + * device information of user + */ public void createResource(UserDevice userDevice) { Document doc = createDocument(userDevice); MongoCollection collection = db - .getCollection(Const.DEVICE_TABLE); + .getCollection(Constants.DEVICE_TABLE); - if (collection.findOneAndReplace( - Filters.and(Filters.eq(Const.USER_ID, doc.get(Const.USER_ID)), - Filters.eq(Const.DEVICE_ID, doc.get(Const.DEVICE_ID))), - doc) == null) { + if (collection.findOneAndReplace(Filters.and( + Filters.eq(Constants.USER_ID, doc.get(Constants.USER_ID)), + Filters.eq(Constants.DEVICE_ID, doc.get(Constants.DEVICE_ID))), doc) == null) { collection.insertOne(doc); } @@@ -122,51 -133,23 +133,23 @@@ return; } - private Document createDocument(UserSession userSession) { - - Document doc = new Document(Const.USER_ID, userSession.getUserId()) - .append(Const.SESSION_CODE, userSession.getSessionCode()); - - return doc; - } - - private Document createDocument(UserDevice userDevice) { - - Document doc = new Document(Const.USER_ID, userDevice.getUserId()) - .append(Const.DEVICE_ID, userDevice.getDeviceId()); - - return doc; - } - - private UserSession convertSessionDocToResource(Document doc) { - - UserSession userSession = new UserSession(); - - userSession.setUserId(doc.getString(Const.USER_ID)); - userSession.setSessionCode(doc.getString(Const.SESSION_CODE)); - - return userSession; - } - - private UserDevice convertDeviceDocToResource(Document doc) { - - UserDevice userDevice = new UserDevice(); - - userDevice.setUserId(doc.getString(Const.USER_ID)); - userDevice.setDeviceId(doc.getString(Const.DEVICE_ID)); - - return userDevice; - } - + /** + * API for getting user identifier corresponding with session code from + * database + * + * @param sessionCode + * session code + * @return String - user identifier + */ public String getUserId(String sessionCode) { String userId = null; MongoCollection collection = db - .getCollection(Const.SESSION_TABLE); + .getCollection(Constants.SESSION_TABLE); - MongoCursor cursor = collection - .find(Filters.eq(Const.SESSION_CODE, sessionCode)).iterator(); + MongoCursor cursor = collection.find( + Filters.eq(Constants.SESSION_CODE, sessionCode)).iterator(); try { @@@ -188,22 -171,20 +171,20 @@@ } /** - * API for getting devices according to user from mongoDB + * API for getting devices corresponding with user identifier from database * * @param userId * user identifier - * @param tablename - * table name of mongoDB */ public ArrayList getDevices(String userId) { ArrayList deviceList = new ArrayList(); MongoCollection collection = db - .getCollection(Const.DEVICE_TABLE); + .getCollection(Constants.DEVICE_TABLE); - MongoCursor cursor = collection - .find(Filters.eq(Const.USER_ID, userId)).iterator(); + MongoCursor cursor = collection.find( + Filters.eq(Constants.USER_ID, userId)).iterator(); try { @@@ -223,12 -204,77 +204,77 @@@ return deviceList; } + public void printResources() { + + ArrayList dlist = readDeviceResources(); + int size = dlist.size(); + + Logger.i("*Table: " + Constants.DEVICE_TABLE); + for (int i = 0; i < size; i++) { + + UserDevice item = dlist.get(i); + + Logger.i("[" + i + "]" + item.getUserId() + ", " + + item.getDeviceId()); + } + + ArrayList slist = readSessionResources(); + size = slist.size(); + + Logger.i("*Table: " + Constants.SESSION_TABLE); + + for (int i = 0; i < size; i++) { + + UserSession item = slist.get(i); + + Logger.i("[" + i + "]" + item.getUserId() + ", " + + item.getSessionCode()); + + } + } + + private Document createDocument(UserSession userSession) { + + Document doc = new Document(Constants.USER_ID, userSession.getUserId()) + .append(Constants.SESSION_CODE, userSession.getSessionCode()); + + return doc; + } + + private Document createDocument(UserDevice userDevice) { + + Document doc = new Document(Constants.USER_ID, userDevice.getUserId()) + .append(Constants.DEVICE_ID, userDevice.getDeviceId()); + + return doc; + } + + private UserSession convertSessionDocToResource(Document doc) { + + UserSession userSession = new UserSession(); + + userSession.setUserId(doc.getString(Constants.USER_ID)); + userSession.setSessionCode(doc.getString(Constants.SESSION_CODE)); + + return userSession; + } + + private UserDevice convertDeviceDocToResource(Document doc) { + + UserDevice userDevice = new UserDevice(); + + userDevice.setUserId(doc.getString(Constants.USER_ID)); + userDevice.setDeviceId(doc.getString(Constants.DEVICE_ID)); + + return userDevice; + } + private ArrayList readSessionResources() { ArrayList userSessionList = new ArrayList(); MongoCollection collection = db - .getCollection(Const.SESSION_TABLE); + .getCollection(Constants.SESSION_TABLE); MongoCursor cursor = collection.find().iterator(); while (cursor.hasNext()) { @@@ -247,7 -293,7 +293,7 @@@ ArrayList userDeviceList = new ArrayList(); MongoCollection collection = db - .getCollection(Const.DEVICE_TABLE); + .getCollection(Constants.DEVICE_TABLE); MongoCursor cursor = collection.find().iterator(); while (cursor.hasNext()) { @@@ -261,33 -307,4 +307,4 @@@ return userDeviceList; } - public void printResources() { - - ArrayList dlist = readDeviceResources(); - int size = dlist.size(); - - Logger.i("*Table: " + Const.DEVICE_TABLE); - for (int i = 0; i < size; i++) { - - UserDevice item = dlist.get(i); - - Logger.i("[" + i + "]" + item.getUserId() + ", " - + item.getDeviceId()); - } - - ArrayList slist = readSessionResources(); - size = slist.size(); - - Logger.i("*Table: " + Const.SESSION_TABLE); - - for (int i = 0; i < size; i++) { - - UserSession item = slist.get(i); - - Logger.i("[" + i + "]" + item.getUserId() + ", " - + item.getSessionCode()); - - } - } - } diff --combined cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/GitHub.java index d69a8c1,e682257..8e00566 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/GitHub.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/oauth/GitHub.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.accountserver.oauth; @@@ -32,7 -32,7 +32,7 @@@ import org.apache.oltu.oauth2.common.OA import org.apache.oltu.oauth2.common.exception.OAuthProblemException; import org.apache.oltu.oauth2.common.exception.OAuthSystemException; import org.apache.oltu.oauth2.common.message.types.GrantType; - import org.iotivity.cloud.accountserver.util.JSONUtil; + import org.iotivity.cloud.util.JSONUtil; import org.iotivity.cloud.util.Logger; /** @@@ -76,16 -76,21 +76,21 @@@ public class GitHub extends OAuthServe @Override public String requestGetUserInfo(String accessToken) { - String userInfo = "{}"; + String userInfo = null; + + if (accessToken == null) { + Logger.w("accessToken is null!"); + return null; + } try { OAuthClientRequest request = new OAuthBearerClientRequest( resource_url).setAccessToken(accessToken) - .buildQueryMessage(); + .buildQueryMessage(); - OAuthClient oAuthClient = new OAuthClient( - new URLConnectionClient()); + OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient()); + OAuthResourceResponse resourceResponse = oAuthClient.resource( request, OAuth.HttpMethod.GET, OAuthResourceResponse.class); @@@ -96,9 -101,8 +101,8 @@@ e.printStackTrace(); } - JSONUtil util = new JSONUtil(); String userIdKey = "login"; - String userId = util.parseJSON(userInfo, userIdKey); + String userId = JSONUtil.parseJSON(userInfo, userIdKey); return userId; } diff --combined cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AccountResource.java index 0ea3c9c,bde32bf..72f9226 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AccountResource.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AccountResource.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.accountserver.resources; @@@ -26,28 -26,28 +26,28 @@@ import java.util.HashMap import java.util.List; import org.iotivity.cloud.accountserver.AccountServerManager; - import org.iotivity.cloud.accountserver.Const; + import org.iotivity.cloud.accountserver.Constants; import org.iotivity.cloud.accountserver.util.CoapMessageBuilder; - import org.iotivity.cloud.accountserver.util.JSONUtil; import org.iotivity.cloud.base.Resource; import org.iotivity.cloud.base.protocols.coap.CoapRequest; import org.iotivity.cloud.base.protocols.coap.CoapResponse; import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus; + import org.iotivity.cloud.util.JSONUtil; import org.iotivity.cloud.util.Logger; import io.netty.channel.ChannelHandlerContext; /** * - * This class provides a set of APIs to handle requests for publishing and - * finding resources. + * This class provides a set of APIs to manage resources corresponding with user + * account * */ public class AccountResource extends Resource { public AccountResource() { - setUri(Const.ACCOUNT_URI); + setUri(Constants.ACCOUNT_URI); } @Override @@@ -87,19 -87,10 +87,10 @@@ } } - /** - * API for handling GET message - * - * @param ctx - * ChannelHandlerContext of request message - * @param request - * CoAP request message - * @throws Exception - */ private void handleGetRequest(ChannelHandlerContext ctx, CoapRequest request) throws Exception { - String reqType = extractQuery(request, Const.REQ_TYPE); + String reqType = extractQuery(request, Constants.REQ_TYPE); if (reqType == null) throw new IllegalArgumentException( @@@ -108,40 -99,31 +99,31 @@@ CoapResponse response = null; switch (reqType) { - - case Const.TYPE_FIND: + case Constants.TYPE_FIND: response = handleFindRequest(request); break; default: Logger.w("reqType[" + reqType + "] is not supported"); } - - ctx.write(response); + if (response != null) { + ctx.writeAndFlush(response); + } } - /** - * API for handling POST message - * - * @param ctx - * ChannelHandlerContext of request message - * @param request - * CoAP request message - * @throws Exception - */ private void handlePostRequest(ChannelHandlerContext ctx, CoapRequest request) throws Exception { - String reqType = extractQuery(request, Const.REQ_TYPE); + String reqType = extractQuery(request, Constants.REQ_TYPE); if (reqType == null) throw new IllegalArgumentException( "request type is null in query!"); - CoapResponse response = null; + CoapResponse response; switch (reqType) { - case Const.TYPE_PUBLISH: + case Constants.TYPE_PUBLISH: response = handlePublishRequest(request); break; default: @@@ -149,16 -131,25 +131,25 @@@ "request type is not supported"); } - ctx.write(response); + ctx.writeAndFlush(response); } + /** + * API for handling request for publishing resource corresponding with user + * account + * + * @param requeset + * CoAP request message + * @return CoapResponse - CoAP response message with response result + * information + */ private CoapResponse handlePublishRequest(CoapRequest request) { String payload = request.getPayloadString(); - JSONUtil util = new JSONUtil(); - String userId = util.parseJSON(payload, Const.REQUEST_USER_ID); - String deviceId = util.parseJSON(payload, Const.REQUEST_DEVICE_ID); + String userId = JSONUtil.parseJSON(payload, Constants.REQUEST_USER_ID); + String deviceId = JSONUtil.parseJSON(payload, + Constants.REQUEST_DEVICE_ID); Logger.d("userId: " + userId + ", deviceId: " + deviceId); @@@ -169,7 -160,7 +160,7 @@@ Logger.d("status : " + status); CoapMessageBuilder responseMessage = new CoapMessageBuilder(); - CoapResponse coapResponse = null; + CoapResponse coapResponse; if (status) { coapResponse = responseMessage.buildCoapResponse(request.getToken(), @@@ -182,13 -173,22 +173,22 @@@ return coapResponse; } + /** + * API for handling request for finding resource corresponding with user + * account + * + * @param requeset + * CoAP request message + * @return CoapResponse - CoAP response message with response result + * information + */ private CoapResponse handleFindRequest(CoapRequest request) { String payload = request.getPayloadString(); // String payload = getPayloadString(request.getPayload()); JSONUtil util = new JSONUtil(); - String userId = util.parseJSON(payload, Const.REQUEST_USER_ID); + String userId = util.parseJSON(payload, Constants.REQUEST_USER_ID); Logger.d("userId: " + userId); @@@ -214,10 -214,9 +214,9 @@@ HashMap responseMap = new HashMap(); ArrayList deviceList = response.getDeviceList(); - responseMap.put(Const.RESPONSE_DEVICES, deviceList); + responseMap.put(Constants.RESPONSE_DEVICES, deviceList); - JSONUtil jsonUtil = new JSONUtil(); - String responseJson = jsonUtil.writeJSON(responseMap); + String responseJson = JSONUtil.writeJSON(responseMap); return responseJson; } @@@ -228,13 -227,15 +227,15 @@@ List Segments = request.getUriQuerySegments(); - for (String s : Segments) { + if (Segments != null) { + for (String s : Segments) { - String pair[] = s.split("="); + String pair[] = s.split("="); - if (pair[0].equals(key)) { + if (pair[0].equals(key)) { - value = pair[1]; + value = pair[1]; + } } } @@@ -243,9 -244,9 +244,9 @@@ /* * private static String getPayloadString(byte[] payload) { - * + * * if (payload == null) return ""; - * + * * return new String(payload, Charset.forName("UTF-8")); } */ diff --combined cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AuthResource.java index 8a1947d,a88bcf8..71448e4 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AuthResource.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/AuthResource.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.accountserver.resources; @@@ -25,32 -25,33 +25,33 @@@ import java.util.HashMap import java.util.List; import org.iotivity.cloud.accountserver.AccountServerManager; - import org.iotivity.cloud.accountserver.Const; + import org.iotivity.cloud.accountserver.Constants; import org.iotivity.cloud.accountserver.util.CoapMessageBuilder; - import org.iotivity.cloud.accountserver.util.JSONUtil; import org.iotivity.cloud.base.Resource; import org.iotivity.cloud.base.protocols.coap.CoapRequest; import org.iotivity.cloud.base.protocols.coap.CoapResponse; import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus; + import org.iotivity.cloud.util.JSONUtil; import org.iotivity.cloud.util.Logger; import io.netty.channel.ChannelHandlerContext; /** * - * This class provides a set of APIs to register account information of - * authorized user. + * This class provides a set of APIs to manage user account with authorization + * process. * */ public class AuthResource extends Resource { public AuthResource() { - setUri(Const.AUTH_URI); + setUri(Constants.AUTH_URI); } @Override - public void onRequestReceived(ChannelHandlerContext ctx, CoapRequest request) { + public void onRequestReceived(ChannelHandlerContext ctx, + CoapRequest request) { Logger.d("AuthResource IN"); @@@ -77,30 -78,22 +78,22 @@@ } } - /** - * API for handling POST message - * - * @param ctx - * ChannelHandlerContext of request message - * @param request - * CoAP request message - * @throws Exception - */ private void handlePostRequest(ChannelHandlerContext ctx, CoapRequest request) throws Exception { - String reqType = extractQuery(request, Const.REQ_TYPE); + String reqType = extractQuery(request, Constants.REQ_TYPE); if (reqType == null) - throw new IllegalArgumentException("request type is null in query!"); + throw new IllegalArgumentException( + "request type is null in query!"); - CoapResponse response = null; + CoapResponse response; switch (reqType) { - case Const.TYPE_REGISTER: + case Constants.TYPE_REGISTER: response = handleRegisterRequest(request); break; - case Const.TYPE_LOGIN: + case Constants.TYPE_LOGIN: response = handleLoginRequest(request); break; default: @@@ -108,16 -101,23 +101,23 @@@ "request type is not supported"); } - ctx.write(response); + ctx.writeAndFlush(response); } + /** + * API for handling request for login by user account + * + * @param request + * CoAP request message + * @return CoapResponse - CoAP response message with response result + * information + */ private CoapResponse handleLoginRequest(CoapRequest request) { String payload = request.getPayloadString(); - JSONUtil util = new JSONUtil(); - String sessionCode = util - .parseJSON(payload, Const.REQUEST_SESSION_CODE); + String sessionCode = JSONUtil.parseJSON(payload, + Constants.REQUEST_SESSION_CODE); Logger.d("sessionCode: " + sessionCode); @@@ -126,7 -126,7 +126,7 @@@ Logger.d("userId: " + userId); CoapMessageBuilder responseMessage = new CoapMessageBuilder(); - CoapResponse coapResponse = null; + CoapResponse coapResponse; if (userId != null) { @@@ -136,56 -136,74 +136,74 @@@ String responseJson = convertLoginResponseToJson(response); Logger.d("responseJson: " + responseJson); - coapResponse = responseMessage.buildCoapResponse( - request.getToken(), responseJson, CoapStatus.CREATED); + coapResponse = responseMessage.buildCoapResponse(request.getToken(), + responseJson, CoapStatus.CREATED); } else { - coapResponse = responseMessage.buildCoapResponse( - request.getToken(), CoapStatus.INTERNAL_SERVER_ERROR); + coapResponse = responseMessage.buildCoapResponse(request.getToken(), + CoapStatus.INTERNAL_SERVER_ERROR); } return coapResponse; } + /** + * API for handling request for registering user account + * + * @param request + * CoAP request message + * @return CoapResponse - CoAP response message with response result + * information + */ private CoapResponse handleRegisterRequest(CoapRequest request) { String payload = request.getPayloadString(); - JSONUtil util = new JSONUtil(); - String authCode = util.parseJSON(payload, Const.REQUEST_AUTH_CODE); - String authServer = util.parseJSON(payload, Const.REQUEST_AUTH_SERVER); + String authCode = JSONUtil.parseJSON(payload, + Constants.REQUEST_AUTH_CODE); + String authServer = JSONUtil.parseJSON(payload, + Constants.REQUEST_AUTH_SERVER); Logger.d("authCode: " + authCode + ", authServer: " + authServer); AccountServerManager oauthServerManager = new AccountServerManager(); + String userId = null; + if (authCode != null && authServer != null) { + userId = oauthServerManager.requestUserId(authCode, authServer); + } + + CoapMessageBuilder responseMessage = new CoapMessageBuilder(); + CoapResponse coapResponse; - String userId = oauthServerManager.requestUserId(authCode, authServer); - String sessionCode = oauthServerManager.registerUserAccount(userId); + if (userId != null) { + + String sessionCode = oauthServerManager.registerUserAccount(userId); - Logger.d("userId: " + userId + ", sessionCode: " + sessionCode); + Logger.d("userId: " + userId + ", sessionCode: " + sessionCode); - CoapMessageBuilder responseMessage = new CoapMessageBuilder(); - CoapResponse coapResponse = null; + if (sessionCode != null) { - if (userId != null && sessionCode != null) { + ResponseObject response = new ResponseObject(); + response.setSessionCode(sessionCode); + response.setUserId(userId); - ResponseObject response = new ResponseObject(); - response.setSessionCode(sessionCode); - response.setUserId(userId); + String responseJson = convertRegisterResponseToJson(response); + Logger.d("responseJson: " + responseJson); - String responseJson = convertRegisterResponseToJson(response); - Logger.d("responseJson: " + responseJson); - - coapResponse = responseMessage.buildCoapResponse( - request.getToken(), responseJson, CoapStatus.CREATED); + coapResponse = responseMessage.buildCoapResponse( + request.getToken(), responseJson, CoapStatus.CREATED); + } + else { + coapResponse = responseMessage.buildCoapResponse(request.getToken(), + CoapStatus.UNAUTHORIZED); + } } else { - coapResponse = responseMessage.buildCoapResponse( - request.getToken(), CoapStatus.UNAUTHORIZED); - + coapResponse = responseMessage.buildCoapResponse(request.getToken(), + CoapStatus.UNAUTHORIZED); } return coapResponse; @@@ -199,13 -217,12 +217,12 @@@ String userId = response.getUserId(); if (userId != null) - responseMap.put(Const.RESPONSE_USER_ID, userId); + responseMap.put(Constants.RESPONSE_USER_ID, userId); if (sessionCode != null) - responseMap.put(Const.RESPONSE_SESSION_CODE, sessionCode); + responseMap.put(Constants.RESPONSE_SESSION_CODE, sessionCode); - JSONUtil jsonUtil = new JSONUtil(); - String responseJson = jsonUtil.writeJSON(responseMap); + String responseJson = JSONUtil.writeJSON(responseMap); return responseJson; } @@@ -217,10 -234,9 +234,9 @@@ String userId = response.getUserId(); if (userId != null) - responseMap.put(Const.RESPONSE_USER_ID, userId); + responseMap.put(Constants.RESPONSE_USER_ID, userId); - JSONUtil jsonUtil = new JSONUtil(); - String responseJson = jsonUtil.writeJSON(responseMap); + String responseJson = JSONUtil.writeJSON(responseMap); return responseJson; } @@@ -231,13 -247,15 +247,15 @@@ List Segments = request.getUriQuerySegments(); - for (String s : Segments) { + if (Segments != null) { + for (String s : Segments) { - String pair[] = s.split("="); + String pair[] = s.split("="); - if (pair[0].equals(key)) { + if (pair[0].equals(key)) { - value = pair[1]; + value = pair[1]; + } } } @@@ -246,9 -264,9 +264,9 @@@ /* * private static String getPayloadString(byte[] payload) { - * + * * if (payload == null) return ""; - * + * * return new String(payload, Charset.forName("UTF-8")); } */ diff --combined cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/CoapMessageBuilder.java index 190b8a4,47cbe58..30029dc --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/CoapMessageBuilder.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/util/CoapMessageBuilder.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.accountserver.util; @@@ -32,18 -32,39 +32,39 @@@ import org.iotivity.cloud.base.protocol /** * - * This class provides utility for making CoAP request and response. + * This class provides a set of APIs to build build data of CoAP request and + * response type. * */ public class CoapMessageBuilder { public static final int APPLICATION_JSON = 50; + /** + * API for building data of CoAP response type without payload. + * + * @param token + * token + * @param status + * response status + * @return CoapResponse - data of CoAP response type + */ public CoapResponse buildCoapResponse(byte[] token, CoapStatus status) { return buildCoapResponse(token, null, status); } + /** + * API for building data of CoAP response type with payload. + * + * @param token + * token + * @param jsonString + * payload data + * @param status + * response status + * @return CoapResponse - data of CoAP response type + */ public CoapResponse buildCoapResponse(byte[] token, String jsonString, CoapStatus status) { @@@ -62,6 -83,15 +83,15 @@@ return coapResponse; } + /** + * API for building data of CoAP requeset type with payload. + * + * @param token + * token + * @param jsonString + * payload data + * @return CoapRequest - data of CoAP request type + */ public CoapRequest buildCoapRequest(byte[] token, String jsonString) { CoapRequest coapRequest = new CoapRequest(CoapMethod.GET); diff --combined cloud/interface/src/main/java/org/iotivity/cloud/ciserver/CloudInterfaceServer.java index 31513e6,ca6aa00..a165393 --- a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/CloudInterfaceServer.java +++ b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/CloudInterfaceServer.java @@@ -1,27 -1,28 +1,28 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.ciserver; import java.net.InetSocketAddress; + import java.util.Scanner; import org.iotivity.cloud.base.CoapServer; import org.iotivity.cloud.base.ResourceManager; @@@ -31,18 -32,12 +32,12 @@@ import org.iotivity.cloud.ciserver.prot import org.iotivity.cloud.ciserver.resources.KeepAliveResource; import org.iotivity.cloud.util.CoapLogHandler; import org.iotivity.cloud.util.Logger; - import org.iotivity.cloud.util.Net; public class CloudInterfaceServer { public static void main(String[] args) throws Exception { System.out.println("-----CI SERVER-------"); - String hostAddress = Net.getMyIpAddress(); - if (hostAddress.equals("") == true) { - Logger.e("cannot find host address."); - return; - } if (args.length != 5) { Logger.e( @@@ -55,27 -50,62 +50,62 @@@ SessionManager sessionManager = null; CoapServer coapServer = null; + CoapRelayHandler relayHandler = null; + CoapAuthHandler authHandler = null; + + KeepAliveResource keepAliveResource = null; + coapServer = new CoapServer(); sessionManager = new SessionManager(); - resourceManager = new ResourceManager(sessionManager); + resourceManager = new ResourceManager(); + + relayHandler = new CoapRelayHandler(sessionManager); - coapServer.addHandler( - new CoapAuthHandler(args[3], Integer.parseInt(args[4]))); + authHandler = new CoapAuthHandler(); + + keepAliveResource = new KeepAliveResource(sessionManager, + new int[] { 1, 2, 4, 8 }); coapServer.addHandler(new CoapLogHandler()); - // Comment the following one line to make CI server run alone - coapServer.addHandler(new CoapRelayHandler(sessionManager, args[1], - Integer.parseInt(args[2]), args[3], Integer.parseInt(args[4]))); + coapServer.addHandler(authHandler); + + coapServer.addHandler(relayHandler); coapServer.addHandler(resourceManager); - resourceManager.registerResource(new KeepAliveResource(sessionManager, - new int[] { 1, 2, 4, 8 })); + resourceManager.registerResource(keepAliveResource); + + authHandler.startHandler(args[3], Integer.parseInt(args[4])); + + relayHandler.startHandler(args[1], Integer.parseInt(args[2]), args[3], + Integer.parseInt(args[4])); coapServer .startServer(new InetSocketAddress(Integer.parseInt(args[0]))); + + keepAliveResource.startSessionChecker(); + + Scanner in = new Scanner(System.in, "UTF-8"); + + System.out.println("press 'q' to terminate"); + + while (!in.nextLine().equals("q")); + + in.close(); + + System.out.println("Terminating..."); + + keepAliveResource.stopSessionChecker(); + + coapServer.stopServer(); + + relayHandler.stopHandler(); + + authHandler.stopHandler(); + + System.out.println("Terminated"); } } diff --combined cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapRelayHandler.java index 761c2a8,97c6051..533811e --- a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapRelayHandler.java +++ b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/protocols/CoapRelayHandler.java @@@ -1,30 -1,29 +1,29 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.ciserver.protocols; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.util.ArrayList; - import java.util.HashMap; import java.util.List; import org.iotivity.cloud.base.CoapClient; @@@ -35,7 -34,6 +34,6 @@@ import org.iotivity.cloud.base.protocol import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus; import org.iotivity.cloud.ciserver.Constants; import org.iotivity.cloud.util.Logger; - import org.iotivity.cloud.util.Net; import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelHandler.Sharable; @@@ -75,8 -73,8 +73,8 @@@ public class CoapRelayHandler extends C } } - private CoapClient rdClient = new CoapClient(); - /////////// + private CoapClient rdClient = null; + /////////// ////////// Handler for Account Server private static final AttributeKey> keyAccountClient = AttributeKey @@@ -123,36 -121,42 +121,42 @@@ } } - private CoapClient asClient = new CoapClient(); + private CoapClient asClient = null; ////////// private SessionManager sessionManager = null; - public CoapRelayHandler(SessionManager sessionManager, String rdAddress, - int rdPort, String acAddress, int acPort) { + public CoapRelayHandler(SessionManager sessionManager) { this.sessionManager = sessionManager; + rdClient = new CoapClient(); + rdClient.addHandler(new RDHandler()); + asClient = new CoapClient(); + asClient.addHandler(new AccountHandler()); + } - try { - rdClient.startClient(new InetSocketAddress(rdAddress, rdPort)); - asClient.startClient(new InetSocketAddress(acAddress, acPort)); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + public void startHandler(String rdAddress, int rdPort, String acAddress, + int acPort) throws Exception { + rdClient.startClient(new InetSocketAddress(rdAddress, rdPort)); + + asClient.startClient(new InetSocketAddress(acAddress, acPort)); asClient.getChannelFuture().channel().attr(keyAccountClient) .set(new ArrayList()); } + public void stopHandler() throws Exception { + asClient.stopClient(); + + rdClient.stopClient(); + } + private static final AttributeKey keyDevice = AttributeKey .newInstance("deviceCtx"); - private HashMap ciRelayClients = new HashMap(); - @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { @@@ -163,149 -167,157 +167,157 @@@ String uriPath = request.getUriPath(); CoapRequest accountRequest = null; String userId, deviceId, authPayload; - CoapResponse response = null; + CoapResponse response; Logger.d("Request received, URI: " + uriPath); - switch (uriPath) { - case Constants.AUTH_URI: - // This case user wants to logout - if (request.getUriQuery().endsWith("logout")) { - ctx.channel().attr(Constants.Attribute_UserId).remove(); - response = new CoapResponse(CoapStatus.DELETED); - } else { - response = new CoapResponse(CoapStatus.BAD_REQUEST); - } - ctx.writeAndFlush(response); - break; - - case Constants.RD_URI: - // RD POST means publish device to server - switch (request.getRequestMethod()) { - case POST: - userId = ctx.channel() - .attr(Constants.Attribute_UserId).get(); - deviceId = request.decodeDeviceId(); - authPayload = String.format( - "{\"userid\":\"%s\",\"deviceid\":\"%s\"}", - userId, deviceId); - accountRequest = new CoapRequest(CoapMethod.POST); - accountRequest.setUriPath(Constants.ACCOUNT_URI); - accountRequest.setUriQuery("reqtype=publish"); - accountRequest.setToken(request.getToken()); - accountRequest.setPayload(authPayload.getBytes(StandardCharsets.UTF_8)); - - // TODO: deviceId must be registered after session - // granted - Logger.d("Adding deviceId to session: " + deviceId); - sessionManager.addSession(deviceId, ctx); - break; - - default: - Logger.e("Unsupported request type"); - break; - } - - rdClient.getChannelFuture().channel().attr(keyRDClient) - .set(ctx); - - // Add original request to list for future use - asClient.getChannelFuture().channel().attr(keyAccountClient) - .get().add(request); - asClient.sendRequest(accountRequest); - return; - - case Constants.WELL_KNOWN_URI: - switch (request.getRequestMethod()) { - case GET: - userId = ctx.channel() - .attr(Constants.Attribute_UserId).get(); - authPayload = String.format("{\"userid\":\"%s\"}", - userId); - accountRequest = new CoapRequest(CoapMethod.GET); - accountRequest.setUriPath(Constants.ACCOUNT_URI); - accountRequest.setUriQuery("reqtype=find"); - accountRequest.setToken(request.getToken()); - accountRequest.setPayload(authPayload.getBytes()); - break; - - default: - Logger.e("Unsupported request type"); - break; - } - - rdClient.getChannelFuture().channel().attr(keyRDClient) - .set(ctx); - - // Add original request to list for future use - asClient.getChannelFuture().channel().attr(keyAccountClient) - .get().add(request); - asClient.sendRequest(accountRequest); - return; - - case Constants.KEEP_ALIVE_URI: - break; - - default: - List uriPathList = request.getUriPathSegments(); - String originUriPathList = request.getUriPath(); - Logger.i("uriPahtList: " + uriPathList.toString()); - String ciAddress = uriPathList.get(0); - String did = uriPathList.get(1); - - Logger.i("CI address: " + ciAddress); - Logger.i("did: " + did); - - // TODO: getMyIP ? - String hostAddress = Net.getMyIpAddress().replace("/", ""); - Logger.i("hostAddress : " + hostAddress); - // if published CI is mine - if (hostAddress.equals(ciAddress) == true) { - // find ctx about did, and send msg - Logger.d("published CI is mine"); - String resource = new String(); - List pathSegments = uriPathList.subList(2, - uriPathList.size()); - for (String path : pathSegments) { - resource += "/"; - resource += path; - } - Logger.i("resource: " + resource); - request.setUriPath(resource); - - ChannelHandlerContext deviceCtx = sessionManager - .querySession(did); - if (deviceCtx != null) { - deviceCtx.attr(keyDevice).set(ctx); - deviceCtx.writeAndFlush(request); - } else { - Logger.e("deviceCtx is null"); - response = new CoapResponse(CoapStatus.FORBIDDEN); - response.setToken(request.getToken()); + if (uriPath != null) { + switch (uriPath) { + case Constants.AUTH_URI: + // This case user wants to logout + String uriQuery = request.getUriQuery(); + if (uriQuery != null) { + if (uriQuery.endsWith("logout")) { + ctx.channel().attr(Constants.Attribute_UserId) + .remove(); + response = new CoapResponse(CoapStatus.DELETED); + } else { + response = new CoapResponse( + CoapStatus.BAD_REQUEST); + } ctx.writeAndFlush(response); } - } else { - // if CI is not connected, connect and send msg - CoapClient otherCI = null; - synchronized (ciRelayClients) { - otherCI = ciRelayClients.get(ciAddress); - if (otherCI == null) { - otherCI = new CoapClient(); - otherCI.startClient( - new InetSocketAddress(ciAddress, 5683)); - ciRelayClients.put(ciAddress, otherCI); + break; + + case Constants.RD_URI: + // RD POST means publish device to server + switch (request.getRequestMethod()) { + case POST: + userId = ctx.channel() + .attr(Constants.Attribute_UserId).get(); + deviceId = request.decodeDeviceId(); + authPayload = String.format( + "{\"userid\":\"%s\",\"deviceid\":\"%s\"}", + userId, deviceId); + accountRequest = new CoapRequest( + CoapMethod.POST); + accountRequest + .setUriPath(Constants.ACCOUNT_URI); + accountRequest.setUriQuery("reqtype=publish"); + accountRequest.setToken(request.getToken()); + accountRequest.setPayload(authPayload + .getBytes(StandardCharsets.UTF_8)); + + // TODO: deviceId must be registered after + // session + // granted + Logger.d("Adding deviceId to session: " + + deviceId); + sessionManager.addSession(deviceId, ctx); + break; + + default: + Logger.e("Unsupported request type"); + break; + } + + rdClient.getChannelFuture().channel().attr(keyRDClient) + .set(ctx); + + // Add original request to list for future use + asClient.getChannelFuture().channel() + .attr(keyAccountClient).get().add(request); + asClient.sendRequest(accountRequest); + return; + + case Constants.WELL_KNOWN_URI: + switch (request.getRequestMethod()) { + case GET: + userId = ctx.channel() + .attr(Constants.Attribute_UserId).get(); + authPayload = String + .format("{\"userid\":\"%s\"}", userId); + accountRequest = new CoapRequest( + CoapMethod.GET); + accountRequest + .setUriPath(Constants.ACCOUNT_URI); + accountRequest.setUriQuery("reqtype=find"); + accountRequest.setToken(request.getToken()); + accountRequest.setPayload(authPayload + .getBytes(StandardCharsets.UTF_8)); + break; + + default: + Logger.e("Unsupported request type"); + break; + } + + rdClient.getChannelFuture().channel().attr(keyRDClient) + .set(ctx); + + // Add original request to list for future use + asClient.getChannelFuture().channel() + .attr(keyAccountClient).get().add(request); + asClient.sendRequest(accountRequest); + return; + + case Constants.KEEP_ALIVE_URI: + break; + + default: + List uriPathList = request.getUriPathSegments(); + if (uriPathList != null) { + Logger.i("uriPahtList: " + uriPathList.toString()); + + String did = uriPathList.get(0); + + Logger.i("did: " + did); + + // TODO: Clustering algorithm required + // find ctx about did, and send msg + StringBuffer resource = new StringBuffer(); + List pathSegments = uriPathList.subList(1, + uriPathList.size()); + for (String path : pathSegments) { + resource.append("/"); + resource.append(path); + } + Logger.i("resource: " + resource); + request.setUriPath(resource.toString()); + + ChannelHandlerContext deviceCtx = sessionManager + .querySession(did); + if (deviceCtx != null) { + deviceCtx.attr(keyDevice).set(ctx); + deviceCtx.writeAndFlush(request); + } else { + Logger.e("deviceCtx is null"); + response = new CoapResponse( + CoapStatus.FORBIDDEN); + response.setToken(request.getToken()); + ctx.writeAndFlush(response); } } - request.setUriPath(originUriPathList); - otherCI.sendRequest(request); - } - return; + return; + } } } else if (msg instanceof CoapResponse) { - if (ctx.attr(keyDevice).get() != null) { - Logger.i("ctx.channel : " - + ctx.attr(keyDevice).get().channel().toString()); - ctx.attr(keyDevice).get().writeAndFlush(msg); + ChannelHandlerContext resourceClient = ctx.attr(keyDevice).get(); + if (resourceClient != null) { + Logger.i("Forwards message to client"); + + CoapResponse response = (CoapResponse) msg; + + // If response contains path, add di + String did = sessionManager.queryDid(ctx); + if (response.getOption(11) != null && did != null) { + response.getOption(11).add(0, + did.getBytes(StandardCharsets.UTF_8)); + } + + Logger.i( + "ctx.channel : " + resourceClient.channel().toString()); + resourceClient.writeAndFlush(response); return; } } @@@ -314,6 -326,13 +326,13 @@@ } @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + Logger.d("Channel Inactive"); + sessionManager.removeSessionByChannel(ctx); + super.channelInactive(ctx); + } + + @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); diff --combined cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/KeepAliveResource.java index 899f235,c809850..804bf81 --- a/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/KeepAliveResource.java +++ b/cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/KeepAliveResource.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.ciserver.resources; @@@ -69,13 -69,20 +69,20 @@@ public class KeepAliveResource extends this.sessionManager = sessionManager; connectPool = new HashMap(); timer = new Timer(); - timer.schedule(new KeepAliveTask(), 30000, 60000); cbor = new Cbor>(); } + public void startSessionChecker() { + timer.schedule(new KeepAliveTask(), 30000, 60000); + } + + public void stopSessionChecker() { + timer.cancel(); + } + /** * API for receiving message(message to keepalive resource) - * + * * @param ctx * ChannelHandlerContext of request message * @param request @@@ -100,14 -107,17 +107,17 @@@ case PUT: HashMap payloadData = null; payloadData = cbor.parsePayloadFromCbor(request.getPayload(), - new HashMap().getClass()); + HashMap.class); Logger.d("Receive payloadData : " + payloadData); - Logger.d("interval : " + payloadData.get("in")); - - connectPool.put(ctx, System.currentTimeMillis() - + (payloadData.get("in") * (long) 60000)); + if (payloadData != null) { + if (payloadData.containsKey("in")) { + Logger.d("interval : " + payloadData.get("in")); + connectPool.put(ctx, System.currentTimeMillis() + + (payloadData.get("in") * (long) 60000)); + } + } response = makeResponse(request); break; @@@ -123,7 -133,7 +133,7 @@@ /** * API for making response to Resource - * + * * @param request * ChannelHandlerContext of request message */ @@@ -136,7 -146,7 +146,7 @@@ /** * API for making interval and first response to Resource - * + * * @param request * ChannelHandlerContext of request message */ @@@ -174,12 -184,18 +184,18 @@@ // check interval while (iterator.hasNext()) { ChannelHandlerContext key = iterator.next(); - Long lifeTime = (Long) map.get(key); - Logger.d("KeepAliveTask Operating : " - + key.channel().toString() + ", Time : " - + (lifeTime - currentTime)); - if (lifeTime < currentTime) { - deleteList.add(key); + if (map.containsKey(key)) { + if (map.get(key) != null) { + Long lifeTime = (Long) map.get(key); + if (lifeTime != null) { + Logger.d("KeepAliveTask Operating : " + + key.channel().toString() + ", Time : " + + (lifeTime - currentTime)); + if (lifeTime < currentTime) { + deleteList.add(key); + } + } + } } } diff --combined cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/MongoDB.java index 04500d5,890e116..889b9ce --- a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/MongoDB.java +++ b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/MongoDB.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.rdserver; @@@ -124,29 -124,101 +124,101 @@@ public class MongoDB LinksPayloadFormat linksPayloadFormat = new LinksPayloadFormat(); ArrayList list = new ArrayList(); - publishPayloadFormat - .setDeviceName(doc.getString(Constants.RS_DEVICE_NAME)); - publishPayloadFormat.setDi(doc.getString(Constants.RS_DEVICE_ID)); - publishPayloadFormat.setBaseUri(doc.getString(Constants.RS_BASE_URI)); - publishPayloadFormat.setBitmap(doc.getInteger(Constants.RS_BITMAP)); - publishPayloadFormat.setPort(doc.getInteger(Constants.RS_HOSTING_PORT)); - publishPayloadFormat.setIns(doc.getInteger(Constants.RS_INS)); - publishPayloadFormat.setRts(doc.getString(Constants.RS_RTS)); - publishPayloadFormat.setDrel(doc.getString(Constants.RS_DREL)); - publishPayloadFormat.setTtl(doc.getInteger(Constants.RS_TTL)); - - linksPayloadFormat.setHref(doc.getString(Constants.RS_HREF)); - linksPayloadFormat - .setRt((ArrayList) doc.get(Constants.RS_RESOURCE_TYPE)); - linksPayloadFormat - .setItf((ArrayList) doc.get(Constants.RS_INTERFACE)); - linksPayloadFormat.setRel(doc.getString(Constants.RS_REL)); - linksPayloadFormat.setObs(doc.getBoolean(Constants.RS_OBS)); - linksPayloadFormat.setTitle(doc.getString(Constants.RS_TITLE)); - linksPayloadFormat.setUri(doc.getString(Constants.RS_URI)); - linksPayloadFormat.setIns(doc.getInteger(Constants.RS_INS)); - linksPayloadFormat - .setMt((ArrayList) doc.get(Constants.RS_MEDIA_TYPE)); + Object tmp = null; + + tmp = doc.get(Constants.RS_DEVICE_NAME); + if(tmp != null) { + publishPayloadFormat + .setDeviceName(tmp.toString()); + } + + tmp = doc.get(Constants.RS_DEVICE_ID); + if(tmp != null) { + publishPayloadFormat.setDi(tmp.toString()); + } + + tmp = doc.get(Constants.RS_BASE_URI); + if(tmp != null) { + publishPayloadFormat.setBaseUri(tmp.toString()); + } + + tmp = doc.get(Constants.RS_BITMAP); + if(tmp != null) { + publishPayloadFormat.setBitmap((int)tmp); + } + + tmp = doc.get(Constants.RS_HOSTING_PORT); + if(tmp != null) { + publishPayloadFormat.setPort((int)tmp); + } + + tmp = doc.get(Constants.RS_INS); + if(tmp != null) { + publishPayloadFormat.setIns((int)tmp); + } + + tmp = doc.get(Constants.RS_RTS); + if(tmp != null) { + publishPayloadFormat.setRts(tmp.toString()); + } + + tmp = doc.get(Constants.RS_DREL); + if(tmp != null) { + publishPayloadFormat.setDrel(tmp.toString()); + } + + tmp = doc.get(Constants.RS_TTL); + if(tmp != null) { + publishPayloadFormat.setTtl((int)tmp); + } + + tmp = doc.get(Constants.RS_HREF); + if(tmp != null) { + linksPayloadFormat.setHref(tmp.toString()); + } + + tmp = doc.get(Constants.RS_RESOURCE_TYPE); + if(tmp != null) { + linksPayloadFormat + .setRt((ArrayList) tmp); + } + + tmp = doc.get(Constants.RS_INTERFACE); + if(tmp != null) { + linksPayloadFormat + .setItf((ArrayList) tmp); + } + + tmp = doc.get(Constants.RS_REL); + if(tmp != null) { + linksPayloadFormat.setRel(tmp.toString()); + } + + tmp = doc.get(Constants.RS_OBS); + if(tmp != null) { + linksPayloadFormat.setObs((boolean)tmp); + } + + tmp = doc.get(Constants.RS_TITLE); + if(tmp != null) { + linksPayloadFormat.setTitle(tmp.toString()); + } + + tmp = doc.get(Constants.RS_URI); + if(tmp != null) { + linksPayloadFormat.setUri(tmp.toString()); + } + + tmp = doc.get(Constants.RS_INS); + if(tmp != null) { + linksPayloadFormat.setIns((int)tmp); + } + + tmp = doc.get(Constants.RS_MEDIA_TYPE); + if(tmp != null) { + linksPayloadFormat + .setMt((ArrayList) tmp); + } list.add(linksPayloadFormat); publishPayloadFormat.setLinks(list); diff --combined cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/ResourceDirectoryServer.java index 732e4d4,8f58000..c420525 --- a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/ResourceDirectoryServer.java +++ b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/ResourceDirectoryServer.java @@@ -1,44 -1,39 +1,39 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.rdserver; import java.net.InetSocketAddress; + import java.util.Scanner; import org.iotivity.cloud.base.CoapServer; import org.iotivity.cloud.base.ResourceManager; import org.iotivity.cloud.rdserver.resources.ResourceDirectoryResource; import org.iotivity.cloud.util.Logger; - import org.iotivity.cloud.util.Net; public class ResourceDirectoryServer { public static void main(String[] args) throws Exception { System.out.println("-----RD SERVER-----"); - String hostAddress = Net.getMyIpAddress(); - if (hostAddress.equals("") == true) { - Logger.e("cannot find host address."); - return; - } if (args.length != 1) { Logger.e("coap server port required"); @@@ -59,6 -54,19 +54,19 @@@ coapServer .startServer(new InetSocketAddress(Integer.parseInt(args[0]))); - } + Scanner in = new Scanner(System.in, "UTF-8"); + + System.out.println("press 'q' to terminate"); + + while (!in.nextLine().equals("q")); + + in.close(); + + System.out.println("Terminating..."); + + coapServer.stopServer(); + + System.out.println("Terminated"); + } } diff --combined cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/ResourceDirectoryResource.java index d26b2c5,09d3471..ce96b64 --- a/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/ResourceDirectoryResource.java +++ b/cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/ResourceDirectoryResource.java @@@ -1,27 -1,26 +1,26 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.rdserver.resources; - import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@@ -36,11 -35,10 +35,10 @@@ import org.iotivity.cloud.base.protocol import org.iotivity.cloud.base.protocols.coap.enums.CoapOption; import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus; import org.iotivity.cloud.rdserver.Constants; - import org.iotivity.cloud.rdserver.JSONUtil; import org.iotivity.cloud.rdserver.MongoDB; import org.iotivity.cloud.util.Cbor; + import org.iotivity.cloud.util.JSONUtil; import org.iotivity.cloud.util.Logger; - import org.iotivity.cloud.util.Net; import io.netty.channel.ChannelHandlerContext; @@@ -173,7 -171,8 +171,8 @@@ public class ResourceDirectoryResource for (HashMap segmentPayload : discoverPayload) { String stringDi = segmentPayload.get(Constants.RS_DEVICE_ID) .toString(); - segmentPayload.put(Constants.RS_DEVICE_ID, stringDi.getBytes(StandardCharsets.UTF_8)); + segmentPayload.put(Constants.RS_DEVICE_ID, + stringDi.getBytes(StandardCharsets.UTF_8)); } Logger.i("discoverPayload :" + discoverPayload.toString()); @@@ -264,8 -263,7 +263,7 @@@ "st is not null, so this is the get msg about private devices"); // parse payload byte[] payload = request.getPayload(); - JSONUtil util = new JSONUtil(); - ArrayList deviceList = util.parseJSON(payload, + ArrayList deviceList = JSONUtil.parseJSON(payload, Constants.RS_DEVICE_LIST_KEY); if (deviceList == null) { throw new IllegalArgumentException("deviceList is null"); @@@ -325,17 -323,14 +323,14 @@@ PublishPayloadFormat pubPayload = new PublishPayloadFormat(); - String ciAddress = ((InetSocketAddress) ctx.channel() - .remoteAddress()).getAddress().getHostAddress(); - - if (ciAddress.equalsIgnoreCase("127.0.0.1")) { - ciAddress = Net.getMyIpAddress().replace("/", ""); - } - ArrayList payloadData = cbor.parsePayloadFromCbor( request.getPayload(), ArrayList.class); - Logger.i("payloadData: " + payloadData.toString()); + if (payloadData == null) { + throw new IllegalArgumentException("parsed payload is null"); + } else { + Logger.i("payloadData: " + payloadData.toString()); + } HashMap tags = (HashMap) payloadData .get(0); @@@ -344,54 -339,61 +339,61 @@@ throw new IllegalArgumentException("tags is null!"); } - if (tags.get(Constants.RS_DEVICE_ID) != null) { - pubPayload.setDi(tags.get(Constants.RS_DEVICE_ID).toString()); + Object di = tags.get(Constants.RS_DEVICE_ID); + if (di != null) { + pubPayload.setDi(di.toString()); Logger.i("di : " + pubPayload.getDi()); } else { throw new IllegalArgumentException("device id is null!"); } - if (tags.get(Constants.RS_DEVICE_NAME) != null) { - pubPayload.setDeviceName( - tags.get(Constants.RS_DEVICE_NAME).toString()); + Object deviceName = tags.get(Constants.RS_DEVICE_NAME); + if (deviceName != null) { + pubPayload.setDeviceName(deviceName.toString()); Logger.i("device name : " + pubPayload.getDeviceName()); } - if (tags.get(Constants.RS_BASE_URI) != null) { - pubPayload - .setBaseUri(tags.get(Constants.RS_BASE_URI).toString()); + Object baseUri = tags.get(Constants.RS_BASE_URI); + if (baseUri != null) { + pubPayload.setBaseUri(baseUri.toString()); Logger.i("baseURI : " + pubPayload.getBaseUri()); } - if (tags.get(Constants.RS_BITMAP) != null) { - pubPayload.setBitmap((int) tags.get(Constants.RS_BITMAP)); + Object bitMap = tags.get(Constants.RS_BITMAP); + if (bitMap != null) { + pubPayload.setBitmap((int) bitMap); Logger.i("bm : " + pubPayload.getBitmap()); } - if (tags.get(Constants.RS_HOSTING_PORT) != null) { - pubPayload.setPort((int) tags.get(Constants.RS_HOSTING_PORT)); + Object hostingPort = tags.get(Constants.RS_HOSTING_PORT); + if (hostingPort != null) { + pubPayload.setPort((int) hostingPort); Logger.i("port : " + pubPayload.getPort()); } - if (tags.get(Constants.RS_INS) != null) { - pubPayload.setIns((int) tags.get(Constants.RS_INS)); + Object ins = tags.get(Constants.RS_INS); + if (ins != null) { + pubPayload.setIns((int) ins); Logger.i("ins : " + pubPayload.getIns()); } - if (tags.get(Constants.RS_RTS) != null) { - pubPayload.setRts(tags.get(Constants.RS_RTS).toString()); + Object rts = tags.get(Constants.RS_RTS); + if (rts != null) { + pubPayload.setRts(rts.toString()); Logger.i("rts : " + pubPayload.getRts()); } - if (tags.get(Constants.RS_DREL) != null) { - pubPayload.setDrel(tags.get(Constants.RS_DREL).toString()); + Object drel = tags.get(Constants.RS_DREL); + if (drel != null) { + pubPayload.setDrel(drel.toString()); Logger.i("drel : " + pubPayload.getDrel()); } - if (tags.get(Constants.RS_TTL) != null) { - pubPayload.setTtl((int) tags.get(Constants.RS_TTL)); - Logger.i("ttl : " + pubPayload.getTtl()); - } + // Object ttl = tags.get(Constants.RS_TTL); + // if (ttl != null) { + // pubPayload.setTtl((int) ttl); + // Logger.i("ttl : " + pubPayload.getTtl()); + // } ArrayList> publishLinks = (ArrayList>) payloadData .get(1); @@@ -404,54 -406,80 +406,80 @@@ LinksPayloadFormat storeLinks = new LinksPayloadFormat(); - if (o.get(Constants.RS_HREF) != null) { - String prefix = "/" + ciAddress + "/" + pubPayload.getDi(); - storeLinks.setHref( - prefix + o.get(Constants.RS_HREF).toString()); + Object href = o.get(Constants.RS_HREF); + if (href != null) { + String prefix = "/" + pubPayload.getDi(); + storeLinks.setHref(prefix + href.toString()); Logger.i("href : " + storeLinks.getHref()); } if (o.get(Constants.RS_RESOURCE_TYPE) != null) { - storeLinks.setRt((ArrayList) o - .get(Constants.RS_RESOURCE_TYPE)); - Logger.i("rt : " + storeLinks.getRt().toString()); + Object obj = o.get(Constants.RS_RESOURCE_TYPE); + if (obj != null) { + storeLinks.setRt((ArrayList) obj); + } + Object rt = storeLinks.getRt(); + if (rt != null) { + Logger.i("rt : " + storeLinks.getRt().toString()); + } } if (o.get(Constants.RS_INTERFACE) != null) { storeLinks.setItf( (ArrayList) o.get(Constants.RS_INTERFACE)); - Logger.i("if : " + storeLinks.getItf().toString()); + Object itf = storeLinks.getItf(); + if (itf != null) { + Logger.i("if : " + storeLinks.getItf().toString()); + } } - if (o.get(Constants.RS_REL) != null) { - storeLinks.setRel(o.get(Constants.RS_REL).toString()); + Object rel = o.get(Constants.RS_REL); + if (rel != null) { + storeLinks.setRel(rel.toString()); Logger.i("rel : " + storeLinks.getRel()); } if (o.get(Constants.RS_OBS) != null) { - storeLinks.setObs((boolean) o.get(Constants.RS_OBS)); + Object obj = o.get(Constants.RS_OBS); + if (obj != null) { + storeLinks.setObs((boolean) obj); + } Logger.i("obs : " + storeLinks.isObs()); } if (o.get(Constants.RS_TITLE) != null) { - storeLinks.setTitle(o.get(Constants.RS_TITLE).toString()); + Object obj = o.get(Constants.RS_TITLE); + if (obj != null) { + storeLinks.setTitle(obj.toString()); + } Logger.i("title : " + storeLinks.getTitle()); } if (o.get(Constants.RS_URI) != null) { - storeLinks.setUri(o.get(Constants.RS_URI).toString()); + Object obj = o.get(Constants.RS_URI); + if (obj != null) { + storeLinks.setUri(obj.toString()); + } Logger.i("uri : " + storeLinks.getUri()); } if (o.get(Constants.RS_INS) != null) { - storeLinks.setIns((int) (o.get(Constants.RS_INS))); + Object obj = o.get(Constants.RS_INS); + if (obj != null) { + storeLinks.setIns((int) obj); + } Logger.i("ins : " + storeLinks.getIns()); } if (o.get(Constants.RS_MEDIA_TYPE) != null) { - storeLinks.setMt( - (ArrayList) o.get(Constants.RS_MEDIA_TYPE)); - Logger.i("mt : " + storeLinks.getMt().toString()); + Object obj = o.get(Constants.RS_MEDIA_TYPE); + if (obj != null) { + storeLinks.setMt((ArrayList) obj); + } + Object mt = storeLinks.getMt(); + if (mt != null) { + Logger.i("mt : " + mt.toString()); + } } pubPayload.links.add(storeLinks); diff --combined cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/RDServerTest.java index 08406e0,bf8ada3..5295d35 --- a/cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/RDServerTest.java +++ b/cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/RDServerTest.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.testrdserver; @@@ -33,9 -33,9 +33,9 @@@ import org.iotivity.cloud.base.protocol import org.iotivity.cloud.base.protocols.coap.CoapResponse; import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; import org.iotivity.cloud.rdserver.Constants; - import org.iotivity.cloud.rdserver.JSONUtil; import org.iotivity.cloud.rdserver.resources.ResourceDirectoryResource; import org.iotivity.cloud.util.Cbor; + import org.iotivity.cloud.util.JSONUtil; import org.junit.Test; import io.netty.channel.ChannelHandlerContext; @@@ -78,6 -78,9 +78,9 @@@ public class RDServerTest CoapClientHandler coapHandler = new CoapClientHandler(); coapClient.addHandler(coapHandler); coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683)); + if (coapHandler.connectCtx == null) { + throw new IllegalArgumentException("connectCtx is null"); + } return coapHandler.connectCtx; } @@@ -85,7 -88,7 +88,7 @@@ CoapRequest request = new CoapRequest(CoapMethod.POST); request.setUriPath(Constants.RD_URI); - request.setUriQuery("rt=oic.wk.rdPub"); + request.setUriQuery("rt=oic.wk.rdpub"); request.setToken("1234".getBytes(StandardCharsets.UTF_8)); ArrayList payload = new ArrayList(); @@@ -185,9 -188,13 +188,13 @@@ ArrayList didList = new ArrayList(); didList.add("98f7483c-5a31-4161-ba7e-9c13e0d"); data.put("devices", didList); - JSONUtil util = new JSONUtil(); - byte[] payload = util.writeJSON(data); - request.setPayload(payload); + String payload = JSONUtil.writeJSON(data); + if (payload != null) { + request.setPayload(payload.getBytes(StandardCharsets.UTF_8)); + } + else { + throw new IllegalArgumentException("payload writeJson error"); + } startServer(); ChannelHandlerContext ctx = startClient(); diff --combined cloud/stack/src/main/java/org/iotivity/cloud/base/CoapClient.java index 2675919,d038565..0cf6142 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/CoapClient.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/CoapClient.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.base; @@@ -28,6 -28,7 +28,7 @@@ import java.util.List import org.iotivity.cloud.base.protocols.coap.CoapDecoder; import org.iotivity.cloud.base.protocols.coap.CoapEncoder; import org.iotivity.cloud.base.protocols.coap.CoapRequest; + import org.iotivity.cloud.util.Logger; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; @@@ -69,7 -70,9 +70,9 @@@ public class CoapClient } } - private ChannelFuture channelFuture; + ChannelFuture channelFuture; + + EventLoopGroup connectorGroup = new NioEventLoopGroup(); CoAPClientInitializer initializer = new CoAPClientInitializer(); @@@ -79,15 -82,10 +82,10 @@@ public void startClient(final InetSocketAddress inetSocketAddress) throws InterruptedException { - // Create bootstrap - - EventLoopGroup bossGroup = new NioEventLoopGroup(); - // bossGroup = new - // EpollEventLoopGroup(Runtime.getRuntime().availableProcessors() * 2); - + try { Bootstrap b = new Bootstrap(); - b.group(bossGroup); + b.group(connectorGroup); b.channel(NioSocketChannel.class); b.option(ChannelOption.TCP_NODELAY, true); b.option(ChannelOption.SO_KEEPALIVE, true); @@@ -102,7 -100,7 +100,7 @@@ @Override public void operationComplete(ChannelFuture future) throws Exception { - System.out.println( + Logger.d( "Connection status of TCP CoAP CLIENT : " + future.isSuccess()); } @@@ -119,26 -117,7 +117,7 @@@ channelFuture.channel().writeAndFlush(request); } - /** - * stop connection - */ - public void stopClient() { - - try { - if (channelFuture != null) { - channelFuture.channel().disconnect().sync().addListener( - new GenericFutureListener() { - - public void operationComplete(ChannelFuture future) - throws Exception { - System.out.println( - "DisConnection status of TCP CoAP CLIENT : " - + future.isSuccess()); - } - }); - } - } catch (InterruptedException e1) { - e1.printStackTrace(); - } + public void stopClient() throws Exception { + connectorGroup.shutdownGracefully().await(); } } diff --combined cloud/stack/src/main/java/org/iotivity/cloud/base/CoapServer.java index 6f51c61,9274f1e..849701d --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/CoapServer.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/CoapServer.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.base; @@@ -30,6 -30,7 +30,7 @@@ import javax.net.ssl.SSLException import org.iotivity.cloud.base.protocols.coap.CoapDecoder; import org.iotivity.cloud.base.protocols.coap.CoapEncoder; + import org.iotivity.cloud.util.Logger; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; @@@ -73,12 -74,12 +74,12 @@@ public class CoapServer } } - EventLoopGroup bossGroup = new NioEventLoopGroup(1); + EventLoopGroup acceptorGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); CoAPServerInitializer initializer = new CoAPServerInitializer(); - + public void addHandler(ChannelHandler handler) { initializer.addHandler(handler); } @@@ -88,7 -89,7 +89,7 @@@ try { ServerBootstrap b = new ServerBootstrap(); - b.group(bossGroup, workerGroup); + b.group(acceptorGroup, workerGroup); b.channel(NioServerSocketChannel.class); b.option(ChannelOption.TCP_NODELAY, true); b.option(ChannelOption.SO_KEEPALIVE, true); @@@ -96,47 -97,23 +97,23 @@@ b.childHandler(initializer); - ChannelFuture ch = b.bind(inetSocketAddress).sync(); - ch.addListener(new GenericFutureListener() { + ChannelFuture channelFuture = b.bind(inetSocketAddress).sync(); + channelFuture.addListener(new GenericFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { // TODO Auto-generated method stub - System.out - .println("Connection status of TCP CoAP SERVER : " + Logger.d("Connection status of TCP CoAP SERVER : " + future.isSuccess()); } - }); } finally { } - } - public void stopServer() { - // shut down all event loops - if (bossGroup != null) { - bossGroup.shutdownGracefully(); - - try { - bossGroup.terminationFuture().sync(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - if (workerGroup != null) { - workerGroup.shutdownGracefully(); - - try { - workerGroup.terminationFuture().sync(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + public void stopServer() throws Exception { + acceptorGroup.shutdownGracefully().await(); + workerGroup.shutdownGracefully().await(); } - } diff --combined cloud/stack/src/main/java/org/iotivity/cloud/base/HttpClient.java index d7e7c63,add75a4..e71fb19 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpClient.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpClient.java @@@ -1,207 -1,200 +1,207 @@@ /* - * //****************************************************************** // // - * Copyright 2016 Samsung Electronics All Rights Reserved. // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // // - * Licensed under the Apache License, Version 2.0 (the "License"); // you may - * not use this file except in compliance with the License. // You may obtain a - * copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // - * Unless required by applicable law or agreed to in writing, software // - * distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the - * License for the specific language governing permissions and // limitations - * under the License. // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ - package org.iotivity.cloud.base; - - import java.net.URI; - import java.net.URISyntaxException; - - import javax.net.ssl.SSLException; - - import io.netty.bootstrap.Bootstrap; - import io.netty.channel.Channel; - import io.netty.channel.ChannelHandlerContext; - import io.netty.channel.ChannelInitializer; - import io.netty.channel.ChannelPipeline; - import io.netty.channel.EventLoopGroup; - import io.netty.channel.SimpleChannelInboundHandler; - import io.netty.channel.nio.NioEventLoopGroup; - import io.netty.channel.socket.SocketChannel; - import io.netty.channel.socket.nio.NioSocketChannel; - import io.netty.handler.codec.http.ClientCookieEncoder; - import io.netty.handler.codec.http.DefaultCookie; - import io.netty.handler.codec.http.DefaultFullHttpRequest; - import io.netty.handler.codec.http.HttpClientCodec; - import io.netty.handler.codec.http.HttpContent; - import io.netty.handler.codec.http.HttpContentDecompressor; - import io.netty.handler.codec.http.HttpHeaders; - import io.netty.handler.codec.http.HttpMethod; - import io.netty.handler.codec.http.HttpObject; - import io.netty.handler.codec.http.HttpRequest; - import io.netty.handler.codec.http.HttpResponse; - import io.netty.handler.codec.http.HttpVersion; - import io.netty.handler.codec.http.LastHttpContent; - import io.netty.handler.ssl.SslContext; - import io.netty.handler.ssl.SslContextBuilder; - import io.netty.handler.ssl.util.InsecureTrustManagerFactory; - import io.netty.util.CharsetUtil; - - public class HttpClient { - - private static class HttpClientInitializer - extends ChannelInitializer { - - public static class HttpSnoopClientHandler - extends SimpleChannelInboundHandler { - - @Override - public void channelRead0(ChannelHandlerContext ctx, - HttpObject msg) { - if (msg instanceof HttpResponse) { - HttpResponse response = (HttpResponse) msg; - - System.err.println("STATUS: " + response.getStatus()); - System.err.println( - "VERSION: " + response.getProtocolVersion()); - System.err.println(); - - if (!response.headers().isEmpty()) { - for (String name : response.headers().names()) { - for (String value : response.headers() - .getAll(name)) { - System.err.println( - "HEADER: " + name + " = " + value); - } - } - System.err.println(); - } - - if (HttpHeaders.isTransferEncodingChunked(response)) { - System.err.println("CHUNKED CONTENT {"); - } else { - System.err.println("CONTENT {"); - } - } - if (msg instanceof HttpContent) { - HttpContent content = (HttpContent) msg; - - System.err.print( - content.content().toString(CharsetUtil.UTF_8)); - System.err.flush(); - - if (content instanceof LastHttpContent) { - System.err.println("} END OF CONTENT"); - ctx.close(); - } - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, - Throwable cause) { - cause.printStackTrace(); - ctx.close(); - } - } - - private final SslContext sslCtx; - - public HttpClientInitializer(SslContext sslCtx) { - this.sslCtx = sslCtx; - } - - @Override - public void initChannel(SocketChannel ch) { - ChannelPipeline p = ch.pipeline(); - - // Enable HTTPS if necessary. - if (sslCtx != null) { - p.addLast(sslCtx.newHandler(ch.alloc())); - } - - p.addLast(new HttpClientCodec()); - - // Remove the following line if you don't want automatic content - // decompression. - p.addLast(new HttpContentDecompressor()); - - // Uncomment the following line if you don't want to handle - // HttpContents. - // p.addLast(new HttpObjectAggregator(1048576)); - - p.addLast(new HttpSnoopClientHandler()); - } - } - - public void connect(String strUrl) - throws URISyntaxException, InterruptedException, SSLException { - URI uri = new URI(strUrl); - - String scheme = uri.getScheme() == null ? "http" : uri.getScheme(); - String host = uri.getHost() == null ? "127.0.0.1" : uri.getHost(); - - int port = uri.getPort(); - - if (port == -1) { - if ("http".equalsIgnoreCase(scheme)) { - port = 80; - } else if ("https".equalsIgnoreCase(scheme)) { - port = 443; - } - } - - if (!"http".equalsIgnoreCase(scheme) - && !"https".equalsIgnoreCase(scheme)) { - return; - } - - final boolean ssl = "https".equalsIgnoreCase(scheme); - final SslContext sslCtx; - - if (ssl) { - sslCtx = SslContextBuilder.forClient() - .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); - } else { - sslCtx = null; - } - - EventLoopGroup group = new NioEventLoopGroup(); - - try { - Bootstrap b = new Bootstrap(); - b.group(group); - b.channel(NioSocketChannel.class); - b.handler(new HttpClientInitializer(sslCtx)); - - Channel ch = b.connect(host, port).sync().channel(); - - HttpRequest request = new DefaultFullHttpRequest( - HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath()); - request.headers().set(HttpHeaders.Names.HOST, host); - request.headers().set(HttpHeaders.Names.CONNECTION, - HttpHeaders.Values.CLOSE); - request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, - HttpHeaders.Values.GZIP); - - request.headers().set(HttpHeaders.Names.COOKIE, - ClientCookieEncoder.encode( - new DefaultCookie("my-cookie", "foo"), - new DefaultCookie("another-cookie", "bar"))); - - ch.writeAndFlush(request); - - ch.closeFuture().sync(); - } finally { - group.shutdownGracefully(); - } - } - - } + // package org.iotivity.cloud.base; + // + // import java.net.URI; + // import java.net.URISyntaxException; + // + // import javax.net.ssl.SSLException; + // + // import io.netty.bootstrap.Bootstrap; + // import io.netty.channel.Channel; + // import io.netty.channel.ChannelHandlerContext; + // import io.netty.channel.ChannelInitializer; + // import io.netty.channel.ChannelPipeline; + // import io.netty.channel.EventLoopGroup; + // import io.netty.channel.SimpleChannelInboundHandler; + // import io.netty.channel.nio.NioEventLoopGroup; + // import io.netty.channel.socket.SocketChannel; + // import io.netty.channel.socket.nio.NioSocketChannel; + // import io.netty.handler.codec.http.ClientCookieEncoder; + // import io.netty.handler.codec.http.DefaultCookie; + // import io.netty.handler.codec.http.DefaultFullHttpRequest; + // import io.netty.handler.codec.http.HttpClientCodec; + // import io.netty.handler.codec.http.HttpContent; + // import io.netty.handler.codec.http.HttpContentDecompressor; + // import io.netty.handler.codec.http.HttpHeaders; + // import io.netty.handler.codec.http.HttpMethod; + // import io.netty.handler.codec.http.HttpObject; + // import io.netty.handler.codec.http.HttpRequest; + // import io.netty.handler.codec.http.HttpResponse; + // import io.netty.handler.codec.http.HttpVersion; + // import io.netty.handler.codec.http.LastHttpContent; + // import io.netty.handler.ssl.SslContext; + // import io.netty.handler.ssl.SslContextBuilder; + // import io.netty.handler.ssl.util.InsecureTrustManagerFactory; + // import io.netty.util.CharsetUtil; + // + // public class HttpClient { + // + // private static class HttpClientInitializer + // extends ChannelInitializer { + // + // public static class HttpSnoopClientHandler + // extends SimpleChannelInboundHandler { + // + // @Override + // public void channelRead0(ChannelHandlerContext ctx, + // HttpObject msg) { + // if (msg instanceof HttpResponse) { + // HttpResponse response = (HttpResponse) msg; + // + // System.err.println("STATUS: " + response.getStatus()); + // System.err.println( + // "VERSION: " + response.getProtocolVersion()); + // System.err.println(); + // + // if (!response.headers().isEmpty()) { + // for (String name : response.headers().names()) { + // for (String value : response.headers() + // .getAll(name)) { + // System.err.println( + // "HEADER: " + name + " = " + value); + // } + // } + // System.err.println(); + // } + // + // if (HttpHeaders.isTransferEncodingChunked(response)) { + // System.err.println("CHUNKED CONTENT {"); + // } else { + // System.err.println("CONTENT {"); + // } + // } + // if (msg instanceof HttpContent) { + // HttpContent content = (HttpContent) msg; + // + // System.err.print( + // content.content().toString(CharsetUtil.UTF_8)); + // System.err.flush(); + // + // if (content instanceof LastHttpContent) { + // System.err.println("} END OF CONTENT"); + // ctx.close(); + // } + // } + // } + // + // @Override + // public void exceptionCaught(ChannelHandlerContext ctx, + // Throwable cause) { + // cause.printStackTrace(); + // ctx.close(); + // } + // } + // + // private final SslContext sslCtx; + // + // public HttpClientInitializer(SslContext sslCtx) { + // this.sslCtx = sslCtx; + // } + // + // @Override + // public void initChannel(SocketChannel ch) { + // ChannelPipeline p = ch.pipeline(); + // + // // Enable HTTPS if necessary. + // if (sslCtx != null) { + // p.addLast(sslCtx.newHandler(ch.alloc())); + // } + // + // p.addLast(new HttpClientCodec()); + // + // // Remove the following line if you don't want automatic content + // // decompression. + // p.addLast(new HttpContentDecompressor()); + // + // // Uncomment the following line if you don't want to handle + // // HttpContents. + // // p.addLast(new HttpObjectAggregator(1048576)); + // + // p.addLast(new HttpSnoopClientHandler()); + // } + // } + // + // public void connect(String strUrl) + // throws URISyntaxException, InterruptedException, SSLException { + // URI uri = new URI(strUrl); + // + // String scheme = uri.getScheme() == null ? "http" : uri.getScheme(); + // String host = uri.getHost() == null ? "127.0.0.1" : uri.getHost(); + // + // int port = uri.getPort(); + // + // if (port == -1) { + // if ("http".equalsIgnoreCase(scheme)) { + // port = 80; + // } else if ("https".equalsIgnoreCase(scheme)) { + // port = 443; + // } + // } + // + // if (!"http".equalsIgnoreCase(scheme) + // && !"https".equalsIgnoreCase(scheme)) { + // return; + // } + // + // final boolean ssl = "https".equalsIgnoreCase(scheme); + // final SslContext sslCtx; + // + // if (ssl) { + // sslCtx = SslContextBuilder.forClient() + // .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); + // } else { + // sslCtx = null; + // } + // + // EventLoopGroup group = new NioEventLoopGroup(); + // + // try { + // Bootstrap b = new Bootstrap(); + // b.group(group); + // b.channel(NioSocketChannel.class); + // b.handler(new HttpClientInitializer(sslCtx)); + // + // Channel ch = b.connect(host, port).sync().channel(); + // + // HttpRequest request = new DefaultFullHttpRequest( + // HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath()); + // request.headers().set(HttpHeaders.Names.HOST, host); + // request.headers().set(HttpHeaders.Names.CONNECTION, + // HttpHeaders.Values.CLOSE); + // request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, + // HttpHeaders.Values.GZIP); + // + // request.headers().set(HttpHeaders.Names.COOKIE, + // ClientCookieEncoder.encode( + // new DefaultCookie("my-cookie", "foo"), + // new DefaultCookie("another-cookie", "bar"))); + // + // ch.writeAndFlush(request); + // + // ch.closeFuture().sync(); + // } finally { + // group.shutdownGracefully(); + // } + // } + // + // } diff --combined cloud/stack/src/main/java/org/iotivity/cloud/base/HttpServer.java index 25b5b66,3f4498f..55b5ab8 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpServer.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/HttpServer.java @@@ -1,145 -1,139 +1,146 @@@ /* - * //****************************************************************** // // - * Copyright 2016 Samsung Electronics All Rights Reserved. // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // // - * Licensed under the Apache License, Version 2.0 (the "License"); // you may - * not use this file except in compliance with the License. // You may obtain a - * copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // - * Unless required by applicable law or agreed to in writing, software // - * distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the - * License for the specific language governing permissions and // limitations - * under the License. // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ - package org.iotivity.cloud.base; - - import java.net.InetSocketAddress; - import java.security.cert.CertificateException; - import java.util.ArrayList; - import java.util.List; - - import javax.net.ssl.SSLException; - - import io.netty.bootstrap.ServerBootstrap; - import io.netty.channel.ChannelFuture; - import io.netty.channel.ChannelHandler; - import io.netty.channel.ChannelInitializer; - import io.netty.channel.ChannelPipeline; - import io.netty.channel.EventLoopGroup; - import io.netty.channel.nio.NioEventLoopGroup; - import io.netty.channel.socket.SocketChannel; - import io.netty.channel.socket.nio.NioServerSocketChannel; - import io.netty.handler.codec.http.HttpRequestDecoder; - import io.netty.handler.codec.http.HttpResponseEncoder; - import io.netty.handler.logging.LogLevel; - import io.netty.handler.logging.LoggingHandler; - import io.netty.util.concurrent.GenericFutureListener; - - public class HttpServer { - - private static class HttpServerInitializer - extends ChannelInitializer { - - private List additionalHandlers = new ArrayList(); - - public HttpServerInitializer() { - } - - public void addHandler(ChannelHandler handler) { - additionalHandlers.add(handler); - } - - @Override - public void initChannel(SocketChannel ch) { - ChannelPipeline p = ch.pipeline(); - /* - * if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc())); } - */ - p.addLast(new HttpRequestDecoder()); - // Uncomment the following line if you don't want to handle - // HttpChunks. - // p.addLast(new HttpObjectAggregator(1048576)); - p.addLast(new HttpResponseEncoder()); - // Remove the following line if you don't want automatic content - // compression. - // p.addLast(new HttpContentCompressor()); - for (ChannelHandler handler : additionalHandlers) { - p.addLast(handler); - } - } - - } - - EventLoopGroup bossGroup = new NioEventLoopGroup(1); - - EventLoopGroup workerGroup = new NioEventLoopGroup(); - - HttpServerInitializer initializer = new HttpServerInitializer(); - - public void addHandler(ChannelHandler handler) { - initializer.addHandler(handler); - } - - public void startServer(InetSocketAddress inetSocketAddress) - throws CertificateException, SSLException, InterruptedException { - - try { - ServerBootstrap b = new ServerBootstrap(); - b.group(bossGroup, workerGroup); - b.channel(NioServerSocketChannel.class); - b.handler(new LoggingHandler(LogLevel.INFO)); - - b.childHandler(initializer); - - ChannelFuture ch = b.bind(inetSocketAddress).sync(); - ch.addListener(new GenericFutureListener() { - - @Override - public void operationComplete(ChannelFuture future) - throws Exception { - // TODO Auto-generated method stub - System.out - .println("Connection status of TCP Http SERVER : " - + future.isSuccess()); - } - - }); - } finally { - } - - } - - public void stopServer() { - // shut down all event loops - if (bossGroup != null) { - bossGroup.shutdownGracefully(); - - try { - bossGroup.terminationFuture().sync(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - if (workerGroup != null) { - workerGroup.shutdownGracefully(); - - try { - workerGroup.terminationFuture().sync(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - - } + // package org.iotivity.cloud.base; + // + // import java.net.InetSocketAddress; + // import java.security.cert.CertificateException; + // import java.util.ArrayList; + // import java.util.List; + // + // import javax.net.ssl.SSLException; + // + // import io.netty.bootstrap.ServerBootstrap; + // import io.netty.channel.ChannelFuture; + // import io.netty.channel.ChannelHandler; + // import io.netty.channel.ChannelInitializer; + // import io.netty.channel.ChannelPipeline; + // import io.netty.channel.EventLoopGroup; + // import io.netty.channel.nio.NioEventLoopGroup; + // import io.netty.channel.socket.SocketChannel; + // import io.netty.channel.socket.nio.NioServerSocketChannel; + // import io.netty.handler.codec.http.HttpRequestDecoder; + // import io.netty.handler.codec.http.HttpResponseEncoder; + // import io.netty.handler.logging.LogLevel; + // import io.netty.handler.logging.LoggingHandler; + // import io.netty.util.concurrent.GenericFutureListener; + // + // public class HttpServer { + // + // private static class HttpServerInitializer + // extends ChannelInitializer { + // + // private List additionalHandlers = new + // ArrayList(); + // + // public HttpServerInitializer() { + // } + // + // public void addHandler(ChannelHandler handler) { + // additionalHandlers.add(handler); + // } + // + // @Override + // public void initChannel(SocketChannel ch) { + // ChannelPipeline p = ch.pipeline(); + // /* + // * if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc())); } + // */ + // p.addLast(new HttpRequestDecoder()); + // // Uncomment the following line if you don't want to handle + // // HttpChunks. + // // p.addLast(new HttpObjectAggregator(1048576)); + // p.addLast(new HttpResponseEncoder()); + // // Remove the following line if you don't want automatic content + // // compression. + // // p.addLast(new HttpContentCompressor()); + // for (ChannelHandler handler : additionalHandlers) { + // p.addLast(handler); + // } + // } + // + // } + // + // EventLoopGroup bossGroup = new NioEventLoopGroup(1); + // + // EventLoopGroup workerGroup = new NioEventLoopGroup(); + // + // HttpServerInitializer initializer = new HttpServerInitializer(); + // + // public void addHandler(ChannelHandler handler) { + // initializer.addHandler(handler); + // } + // + // public void startServer(InetSocketAddress inetSocketAddress) + // throws CertificateException, SSLException, InterruptedException { + // + // try { + // ServerBootstrap b = new ServerBootstrap(); + // b.group(bossGroup, workerGroup); + // b.channel(NioServerSocketChannel.class); + // b.handler(new LoggingHandler(LogLevel.INFO)); + // + // b.childHandler(initializer); + // + // ChannelFuture ch = b.bind(inetSocketAddress).sync(); + // ch.addListener(new GenericFutureListener() { + // + // @Override + // public void operationComplete(ChannelFuture future) + // throws Exception { + // // TODO Auto-generated method stub + // System.out + // .println("Connection status of TCP Http SERVER : " + // + future.isSuccess()); + // } + // + // }); + // } finally { + // } + // + // } + // + // public void stopServer() { + // // shut down all event loops + // if (bossGroup != null) { + // bossGroup.shutdownGracefully(); + // + // try { + // bossGroup.terminationFuture().sync(); + // } catch (InterruptedException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + // } + // + // if (workerGroup != null) { + // workerGroup.shutdownGracefully(); + // + // try { + // workerGroup.terminationFuture().sync(); + // } catch (InterruptedException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + // } + // } + // + // } diff --combined cloud/stack/src/main/java/org/iotivity/cloud/base/ResourceManager.java index 693d64b,0ca806f..c2700df --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/ResourceManager.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/ResourceManager.java @@@ -1,30 -1,29 +1,29 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.base; import java.util.ArrayList; import org.iotivity.cloud.base.protocols.coap.CoapRequest; - import org.iotivity.cloud.util.Logger; import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandlerContext; @@@ -33,35 -32,7 +32,7 @@@ import io.netty.channel.SimpleChannelIn @Sharable public class ResourceManager extends SimpleChannelInboundHandler { - private ArrayList resources = new ArrayList(); - SessionManager sessionManager = null; - - public ResourceManager() { - - } - - public ResourceManager(SessionManager sessionManager) { - this.sessionManager = sessionManager; - } - - @Override - public void channelReadComplete(ChannelHandlerContext ctx) { - ctx.flush(); - } - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - Logger.d("Channel Inactive"); - sessionManager.removeSessionByChannel(ctx); - super.channelInactive(ctx); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - - cause.printStackTrace(); - ctx.close(); - } + private ArrayList resources = new ArrayList(); @Override public void channelRead0(ChannelHandlerContext ctx, CoapRequest request) diff --combined cloud/stack/src/main/java/org/iotivity/cloud/base/SessionManager.java index cf95a44,ca371f7..9b795c3 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/SessionManager.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/SessionManager.java @@@ -1,32 -1,31 +1,31 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.base; import java.util.ArrayList; import java.util.HashMap; - import java.util.Iterator; import java.util.List; - - import org.iotivity.cloud.util.Logger; + import java.util.Map.Entry; + import java.util.Objects; import io.netty.channel.ChannelHandlerContext; @@@ -48,22 -47,10 +47,10 @@@ public class SessionManager } public void removeSessionByChannel(ChannelHandlerContext ctx) { - synchronized (sessions) { - if (!isThereCtxChannel(ctx)) { - Logger.d("Already Session Removed : " - + ctx.channel().toString()); - return; - } - Iterator iterator = sessions.keySet().iterator(); - while (iterator.hasNext()) { - String key = (String) iterator.next(); - if (ctx.channel().toString() - .equals(querySession(key).channel().toString())) { - Logger.d("Session Remove : " + ctx.channel().toString()); - removeSession(key); - break; - } - } + + String did = queryDid(ctx); + if (did != null) { + removeSession(did); } } @@@ -77,29 -64,23 +64,23 @@@ return ctx; } - public boolean isThereCtx(ChannelHandlerContext ctx) { - + public String queryDid(ChannelHandlerContext ctx) { synchronized (sessions) { - return sessions.containsValue(ctx); - } - } - - public boolean isThereCtxChannel(ChannelHandlerContext ctx) { - - synchronized (sessions) { - Iterator iterator = sessions.keySet().iterator(); - while (iterator.hasNext()) { - String key = (String) iterator.next(); - if (ctx.channel().toString() - .equals(querySession(key).channel().toString())) { - return true; + for (Entry entry : sessions + .entrySet()) { + if (Objects.equals(ctx, entry.getValue())) { + return entry.getKey(); } } - return false; } + + return null; } public List getSessions() { - return new ArrayList(sessions.keySet()); + synchronized (sessions) { + List list = new ArrayList(sessions.keySet()); + return list; + } } } diff --combined cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapEncoder.java index ab289a6,2aee0dd..654ce1a --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapEncoder.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapEncoder.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.base.protocols.coap; @@@ -100,9 -100,16 +100,16 @@@ public class CoapEncoder extends Messag for (int i = 0; i < 40; i++) { List values = coapMessage.getOption(i); if (values != null) { - for (byte[] value : values) { - writeOption(i - preOptionNum, - value != null ? value.length : 0, byteBuf, value); + if (values.size() > 0) { + for (byte[] value : values) { + writeOption(i - preOptionNum, + value != null ? value.length : 0, byteBuf, + value); + preOptionNum = i; + } + + } else { + writeOption(i - preOptionNum, 0, byteBuf, null); preOptionNum = i; } } diff --combined cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapMessage.java index ae66819,fb77b06..e1db80c --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapMessage.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapMessage.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.base.protocols.coap; @@@ -33,11 -33,11 +33,11 @@@ import org.iotivity.cloud.util.Logger public class CoapMessage { - private int tokenLength = 0; - protected int code = 0; - private byte[] token = null; + private int tokenLength = 0; + protected int code = 0; + private byte[] token = null; - private byte[] payload = null; + private byte[] payload = null; // Option fields protected List if_match = null; @@@ -55,7 -55,7 +55,7 @@@ protected byte[] proxy_uri = null; protected byte[] proxy_scheme = null; protected byte[] size1 = null; - protected boolean observe = false; + protected byte[] observe = null; public CoapMessage() { } @@@ -186,7 -186,7 +186,7 @@@ // OBSERVE case 6: - observe = true; + observe = value; break; } } @@@ -236,7 -236,7 +236,7 @@@ // ACCEPT case 17: - return accept != null ? Arrays.asList(content_format) : null; + return accept != null ? Arrays.asList(accept) : null; // LOCATION_QUERY case 20: @@@ -257,7 -257,7 +257,7 @@@ // OBSERVE case 6: - return observe == true ? new ArrayList() : null; + return observe != null ? Arrays.asList(observe) : null; } return null; @@@ -302,18 -302,19 +302,19 @@@ else { decodedPayload = cbor.parsePayloadFromCbor(payload, ArrayList.class); + String deviceId = null; + if (decodedPayload != null) { + HashMap tags = (HashMap) decodedPayload + .get(0); - HashMap tags = (HashMap) decodedPayload - .get(0); + deviceId = tags.get("di").toString(); - String deviceId = tags.get("di").toString(); + if (deviceId == null) { + throw new IllegalArgumentException("deviceId is null"); + } - if (deviceId == null) { - throw new IllegalArgumentException("deviceId is null"); + Logger.i("deviceId : " + deviceId); } - - Logger.i("deviceId : " + deviceId); - return deviceId; } } diff --combined cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapRequest.java index 8ad1f4d,3a1f013..4f80e4e --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapRequest.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/coap/CoapRequest.java @@@ -1,23 -1,23 +1,23 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.base.protocols.coap; @@@ -66,11 -66,12 +66,12 @@@ public class CoapRequest extends CoapMe } public List getUriPathSegments() { + if (uri_path == null) { + return null; + } List segments = new ArrayList(); - if (uri_path != null) { - for (byte[] pathSegment : uri_path) { - segments.add(new String(pathSegment, StandardCharsets.UTF_8)); - } + for (byte[] pathSegment : uri_path) { + segments.add(new String(pathSegment, StandardCharsets.UTF_8)); } return segments; } @@@ -101,6 -102,9 +102,9 @@@ } public List getUriQuerySegments() { + if (uri_query == null) { + return null; + } List segments = new ArrayList(); for (byte[] querySegment : uri_query) { segments.add(new String(querySegment, StandardCharsets.UTF_8)); @@@ -109,10 -113,8 +113,8 @@@ } public void clearUriPath() { - uri_path.clear(); - } - - public void setAccept(byte[] accepts) { - accept = accepts; + if (uri_path != null) { + uri_path.clear(); + } } -} +} diff --combined cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/proxy/CoapHttpProxyHandler.java index 6878bae,2ac4109..bdc1282 --- a/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/proxy/CoapHttpProxyHandler.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/base/protocols/proxy/CoapHttpProxyHandler.java @@@ -1,209 -1,204 +1,211 @@@ /* - * //****************************************************************** // // - * Copyright 2016 Samsung Electronics All Rights Reserved. // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // // - * Licensed under the Apache License, Version 2.0 (the "License"); // you may - * not use this file except in compliance with the License. // You may obtain a - * copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // - * Unless required by applicable law or agreed to in writing, software // - * distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the - * License for the specific language governing permissions and // limitations - * under the License. // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ - package org.iotivity.cloud.base.protocols.proxy; - - import java.nio.charset.StandardCharsets; - import java.util.HashMap; - import java.util.List; - import java.util.Map.Entry; - - import org.iotivity.cloud.base.SessionManager; - import org.iotivity.cloud.base.protocols.coap.CoapRequest; - import org.iotivity.cloud.base.protocols.coap.CoapResponse; - import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; - import org.iotivity.cloud.util.Cbor; - import org.iotivity.cloud.util.Logger; - - import io.netty.buffer.Unpooled; - import io.netty.channel.ChannelDuplexHandler; - import io.netty.channel.ChannelFutureListener; - import io.netty.channel.ChannelHandler.Sharable; - import io.netty.channel.ChannelHandlerContext; - import io.netty.handler.codec.http.DefaultFullHttpResponse; - import io.netty.handler.codec.http.HttpHeaders; - import io.netty.handler.codec.http.HttpMethod; - import io.netty.handler.codec.http.HttpRequest; - import io.netty.handler.codec.http.HttpResponse; - import io.netty.handler.codec.http.HttpResponseStatus; - import io.netty.handler.codec.http.HttpVersion; - import io.netty.handler.codec.http.QueryStringDecoder; - import io.netty.util.AttributeKey; - import io.netty.util.CharsetUtil; - - @Sharable - public class CoapHttpProxyHandler extends ChannelDuplexHandler { - - // Proxy converts http request to coaprequest and coapresponse to - // httpresponse - private SessionManager sessionManager = null; - - private static final AttributeKey keyHttpCtx = AttributeKey - .newInstance("httpCtx"); - - public CoapHttpProxyHandler(SessionManager sessionManager) { - this.sessionManager = sessionManager; - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) - throws Exception { - - // in case of Receive Request from http - if (msg instanceof HttpRequest) { - // Check uri query param that contains coap device uuid - // then search those and create coapRequest and send - HttpRequest httpRequest = (HttpRequest) msg; - QueryStringDecoder queryStringDecoder = new QueryStringDecoder( - httpRequest.getUri()); - - List didList = queryStringDecoder.parameters().get("di"); - - if (didList != null) { - ChannelHandlerContext coapClient = sessionManager - .querySession(didList.get(0)); - - if (coapClient != null) { - List uriList = queryStringDecoder.parameters() - .get("href"); - if (uriList != null) { - coapClient.channel().attr(keyHttpCtx).set(ctx); - coapClient.writeAndFlush(httpRequestToCoAPRequest( - uriList.get(0), (HttpRequest) msg)); - - return; - } - } else { - Logger.d("Unable to find session: " + didList.get(0)); - } - } - - // Prints available sessions to html - - ctx.writeAndFlush(printsAvailableSessions()) - .addListener(ChannelFutureListener.CLOSE); - return; - } - - if (msg instanceof CoapResponse) { - ctx.channel().attr(keyHttpCtx).get() - .writeAndFlush( - coapResponseToHttpResponse((CoapResponse) msg)) - .addListener(ChannelFutureListener.CLOSE); - return; - } - - // Pass to upper-layer - super.channelRead(ctx, msg); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - cause.printStackTrace(); - ctx.close(); - } - - HttpResponse printsAvailableSessions() { - - StringBuilder strBuilder = new StringBuilder(); - List sessions = sessionManager.getSessions(); - - strBuilder.append(""); - strBuilder.append("Available sessions
"); - - for (String session : sessions) { - strBuilder.append(session); - strBuilder.append("
"); - } - - strBuilder.append(""); - - HttpResponse response = new DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, HttpResponseStatus.OK, - Unpooled.copiedBuffer(strBuilder.toString(), - CharsetUtil.UTF_8)); - response.headers().set(HttpHeaders.Names.CONTENT_TYPE, - "text/html; charset=UTF-8"); - - return response; - } - - HttpResponse httpRequestToSendError() { - HttpResponse response = new DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND, - Unpooled.copiedBuffer( - "Failure: " + HttpResponseStatus.NOT_FOUND + "\r\n", - CharsetUtil.UTF_8)); - response.headers().set(HttpHeaders.Names.CONTENT_TYPE, - "text/html; charset=UTF-8"); - - return response; - } - - CoapRequest httpRequestToCoAPRequest(String uri, HttpRequest httpRequest) { - CoapRequest coapRequest; - - // TODO: coapRequest converter required - // coapRequest.getOptions().setUriQuery(); - if (httpRequest.getMethod() == HttpMethod.GET) { - coapRequest = new CoapRequest(CoapMethod.GET); - } else if (httpRequest.getMethod() == HttpMethod.PUT) { - coapRequest = new CoapRequest(CoapMethod.PUT); - } else if (httpRequest.getMethod() == HttpMethod.POST) { - coapRequest = new CoapRequest(CoapMethod.POST); - } else if (httpRequest.getMethod() == HttpMethod.DELETE) { - coapRequest = new CoapRequest(CoapMethod.DELETE); - } else { - throw new IllegalArgumentException(); - } - - coapRequest.setUriPath(uri); - - return coapRequest; - } - - HttpResponse coapResponseToHttpResponse(CoapResponse coapResponse) { - - Cbor> cbor = new Cbor>(); - - HashMap rep = cbor - .parsePayloadFromCbor(coapResponse.getPayload(), HashMap.class); - - StringBuilder strBuilder = new StringBuilder(); - - for (Entry entry : rep.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue().toString(); - strBuilder.append("Key: " + key + " Value: " + value + "
"); - } - - HttpResponse httpResponse = new DefaultFullHttpResponse( - HttpVersion.HTTP_1_1, HttpResponseStatus.OK, - Unpooled.wrappedBuffer(strBuilder.toString().getBytes(StandardCharsets.UTF_8))); - - httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE, - "text/html; charset=UTF-8"); - - // TODO: httpResponse converter required - - return httpResponse; - } - } + // package org.iotivity.cloud.base.protocols.proxy; + // + // import java.nio.charset.StandardCharsets; + // import java.util.HashMap; + // import java.util.List; + // import java.util.Map.Entry; + // + // import org.iotivity.cloud.base.SessionManager; + // import org.iotivity.cloud.base.protocols.coap.CoapRequest; + // import org.iotivity.cloud.base.protocols.coap.CoapResponse; + // import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; + // import org.iotivity.cloud.util.Cbor; + // import org.iotivity.cloud.util.Logger; + // + // import io.netty.buffer.Unpooled; + // import io.netty.channel.ChannelDuplexHandler; + // import io.netty.channel.ChannelFutureListener; + // import io.netty.channel.ChannelHandler.Sharable; + // import io.netty.channel.ChannelHandlerContext; + // import io.netty.handler.codec.http.DefaultFullHttpResponse; + // import io.netty.handler.codec.http.HttpHeaders; + // import io.netty.handler.codec.http.HttpMethod; + // import io.netty.handler.codec.http.HttpRequest; + // import io.netty.handler.codec.http.HttpResponse; + // import io.netty.handler.codec.http.HttpResponseStatus; + // import io.netty.handler.codec.http.HttpVersion; + // import io.netty.handler.codec.http.QueryStringDecoder; + // import io.netty.util.AttributeKey; + // import io.netty.util.CharsetUtil; + // + // @Sharable + // public class CoapHttpProxyHandler extends ChannelDuplexHandler { + // + // // Proxy converts http request to coaprequest and coapresponse to + // // httpresponse + // private SessionManager sessionManager = null; + // + // private static final AttributeKey keyHttpCtx = + // AttributeKey + // .newInstance("httpCtx"); + // + // public CoapHttpProxyHandler(SessionManager sessionManager) { + // this.sessionManager = sessionManager; + // } + // + // @Override + // public void channelRead(ChannelHandlerContext ctx, Object msg) + // throws Exception { + // + // // in case of Receive Request from http + // if (msg instanceof HttpRequest) { + // // Check uri query param that contains coap device uuid + // // then search those and create coapRequest and send + // HttpRequest httpRequest = (HttpRequest) msg; + // QueryStringDecoder queryStringDecoder = new QueryStringDecoder( + // httpRequest.getUri()); + // + // List didList = queryStringDecoder.parameters().get("di"); + // + // if (didList != null) { + // ChannelHandlerContext coapClient = sessionManager + // .querySession(didList.get(0)); + // + // if (coapClient != null) { + // List uriList = queryStringDecoder.parameters() + // .get("href"); + // if (uriList != null) { + // coapClient.channel().attr(keyHttpCtx).set(ctx); + // coapClient.writeAndFlush(httpRequestToCoAPRequest( + // uriList.get(0), (HttpRequest) msg)); + // + // return; + // } + // } else { + // Logger.d("Unable to find session: " + didList.get(0)); + // } + // } + // + // // Prints available sessions to html + // + // ctx.writeAndFlush(printsAvailableSessions()) + // .addListener(ChannelFutureListener.CLOSE); + // return; + // } + // + // if (msg instanceof CoapResponse) { + // ctx.channel().attr(keyHttpCtx).get() + // .writeAndFlush( + // coapResponseToHttpResponse((CoapResponse) msg)) + // .addListener(ChannelFutureListener.CLOSE); + // return; + // } + // + // // Pass to upper-layer + // super.channelRead(ctx, msg); + // } + // + // @Override + // public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + // cause.printStackTrace(); + // ctx.close(); + // } + // + // HttpResponse printsAvailableSessions() { + // + // StringBuilder strBuilder = new StringBuilder(); + // List sessions = sessionManager.getSessions(); + // + // strBuilder.append(""); + // strBuilder.append("Available sessions
"); + // + // for (String session : sessions) { + // strBuilder.append(session); + // strBuilder.append("
"); + // } + // + // strBuilder.append(""); + // + // HttpResponse response = new DefaultFullHttpResponse( + // HttpVersion.HTTP_1_1, HttpResponseStatus.OK, + // Unpooled.copiedBuffer(strBuilder.toString(), + // CharsetUtil.UTF_8)); + // response.headers().set(HttpHeaders.Names.CONTENT_TYPE, + // "text/html; charset=UTF-8"); + // + // return response; + // } + // + // HttpResponse httpRequestToSendError() { + // HttpResponse response = new DefaultFullHttpResponse( + // HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND, + // Unpooled.copiedBuffer( + // "Failure: " + HttpResponseStatus.NOT_FOUND + "\r\n", + // CharsetUtil.UTF_8)); + // response.headers().set(HttpHeaders.Names.CONTENT_TYPE, + // "text/html; charset=UTF-8"); + // + // return response; + // } + // + // CoapRequest httpRequestToCoAPRequest(String uri, HttpRequest httpRequest) { + // CoapRequest coapRequest; + // + // // TODO: coapRequest converter required + // // coapRequest.getOptions().setUriQuery(); + // if (httpRequest.getMethod() == HttpMethod.GET) { + // coapRequest = new CoapRequest(CoapMethod.GET); + // } else if (httpRequest.getMethod() == HttpMethod.PUT) { + // coapRequest = new CoapRequest(CoapMethod.PUT); + // } else if (httpRequest.getMethod() == HttpMethod.POST) { + // coapRequest = new CoapRequest(CoapMethod.POST); + // } else if (httpRequest.getMethod() == HttpMethod.DELETE) { + // coapRequest = new CoapRequest(CoapMethod.DELETE); + // } else { + // throw new IllegalArgumentException(); + // } + // + // coapRequest.setUriPath(uri); + // + // return coapRequest; + // } + // + // HttpResponse coapResponseToHttpResponse(CoapResponse coapResponse) { + // + // Cbor> cbor = new Cbor>(); + // + // HashMap rep = cbor + // .parsePayloadFromCbor(coapResponse.getPayload(), HashMap.class); + // + // StringBuilder strBuilder = new StringBuilder(); + // + // for (Entry entry : rep.entrySet()) { + // String key = entry.getKey(); + // String value = entry.getValue().toString(); + // strBuilder.append("Key: " + key + " Value: " + value + "
"); + // } + // + // HttpResponse httpResponse = new DefaultFullHttpResponse( + // HttpVersion.HTTP_1_1, HttpResponseStatus.OK, + // Unpooled.wrappedBuffer(strBuilder.toString() + // .getBytes(StandardCharsets.UTF_8))); + // + // httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE, + // "text/html; charset=UTF-8"); + // + // // TODO: httpResponse converter required + // + // return httpResponse; + // } + // } diff --combined cloud/stack/src/main/java/org/iotivity/cloud/util/CoapLogHandler.java index 73fb549,f12a807..56633a0 --- a/cloud/stack/src/main/java/org/iotivity/cloud/util/CoapLogHandler.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/util/CoapLogHandler.java @@@ -1,26 -1,28 +1,28 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.util; + import java.nio.charset.StandardCharsets; + import org.iotivity.cloud.base.protocols.coap.CoapMessage; import org.iotivity.cloud.base.protocols.coap.CoapRequest; @@@ -70,7 -72,7 +72,7 @@@ public class CoapLogHandler extends Cha Logger.d(strBuilder.toString()); ByteBuf outByteBuf = ctx.alloc().buffer(); - outByteBuf.writeBytes(message.getBytes()); + outByteBuf.writeBytes(message.getBytes(StandardCharsets.UTF_8)); } ctx.write(msg); diff --combined cloud/stack/src/main/java/org/iotivity/cloud/util/JSONUtil.java index 3d60acd,3f7e061..2e99157 --- a/cloud/stack/src/main/java/org/iotivity/cloud/util/JSONUtil.java +++ b/cloud/stack/src/main/java/org/iotivity/cloud/util/JSONUtil.java @@@ -1,27 -1,28 +1,28 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.util; import java.io.IOException; + import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@@ -51,6 -52,25 +52,25 @@@ public class JSONUtil @SuppressWarnings("unchecked") Map jsonMap = mapper.readValue(jsonString, Map.class); + value = jsonMap.get(key); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + + return value; + } + + public static ArrayList parseJSON(byte[] payload, String key) { + + if (payload == null) + return null; + + ArrayList value = null; + + try { + @SuppressWarnings("unchecked") + Map> jsonMap = mapper.readValue(payload, + Map.class); value = jsonMap.get(key); } catch (IOException ioe) { ioe.printStackTrace(); diff --combined cloud/stack/src/test/java/org/iotivity/cloud/base/CoapClientTest.java index 350dbf4,4003cfe..6aa7b6f --- a/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapClientTest.java +++ b/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapClientTest.java @@@ -1,53 -1,42 +1,42 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.base; import java.net.InetSocketAddress; + import java.nio.charset.StandardCharsets; import org.iotivity.cloud.base.protocols.coap.CoapRequest; import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod; + import org.iotivity.cloud.util.CoapLogHandler; import org.junit.Test; - import io.netty.channel.ChannelHandlerContext; - import io.netty.channel.SimpleChannelInboundHandler; - public class CoapClientTest { - - private static class CoapHandler - extends SimpleChannelInboundHandler { - @Override - protected void channelRead0(ChannelHandlerContext ctx, CoapRequest msg) - throws Exception { - // TODO Auto-generated method stub - } - } - @Test public void testAddHandler() throws Exception { CoapServer coapServer = new CoapServer(); coapServer.startServer(new InetSocketAddress(5683)); CoapClient coapClient = new CoapClient(); coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683)); - coapClient.addHandler(new CoapHandler()); + coapClient.addHandler(new CoapLogHandler()); coapClient.stopClient(); coapServer.stopServer(); } @@@ -59,26 -48,26 +48,26 @@@ CoapClient coapClient = new CoapClient(); coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683)); - coapClient.addHandler(new CoapHandler()); + coapClient.addHandler(new CoapLogHandler()); CoapRequest request = new CoapRequest(CoapMethod.GET); coapClient.sendRequest(request); CoapRequest request2 = new CoapRequest(CoapMethod.GET); - request2.setToken("1234".getBytes()); + request2.setToken("1234".getBytes(StandardCharsets.UTF_8)); coapClient.sendRequest(request2); CoapRequest request3 = new CoapRequest(CoapMethod.GET); - request3.setPayload("sample1".getBytes()); + request3.setPayload("sample1".getBytes(StandardCharsets.UTF_8)); coapClient.sendRequest(request3); CoapRequest request4 = new CoapRequest(CoapMethod.GET); - request4.setToken("5576".getBytes()); - request4.setPayload("sample2".getBytes()); + request4.setToken("5576".getBytes(StandardCharsets.UTF_8)); + request4.setPayload("sample2".getBytes(StandardCharsets.UTF_8)); coapClient.sendRequest(request4); CoapRequest request5 = new CoapRequest(CoapMethod.GET); - request5.setToken("565761".getBytes()); + request5.setToken("565761".getBytes(StandardCharsets.UTF_8)); coapClient.sendRequest(request5); CoapRequest request6 = new CoapRequest(CoapMethod.GET); diff --combined cloud/stack/src/test/java/org/iotivity/cloud/base/CoapServerTest.java index 585919b,f2162ec..3e9876a --- a/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapServerTest.java +++ b/cloud/stack/src/test/java/org/iotivity/cloud/base/CoapServerTest.java @@@ -1,49 -1,37 +1,37 @@@ /* - * //****************************************************************** - * // - * // Copyright 2016 Samsung Electronics All Rights Reserved. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - * // - * // Licensed under the Apache License, Version 2.0 (the "License"); - * // you may not use this file except in compliance with the License. - * // You may obtain a copy of the License at - * // - * // http://www.apache.org/licenses/LICENSE-2.0 - * // - * // Unless required by applicable law or agreed to in writing, software - * // distributed under the License is distributed on an "AS IS" BASIS, - * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * // See the License for the specific language governing permissions and - * // limitations under the License. - * // - * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ******************************************************************* + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ package org.iotivity.cloud.base; import java.net.InetSocketAddress; - import org.iotivity.cloud.base.protocols.coap.CoapRequest; + import org.iotivity.cloud.util.CoapLogHandler; import org.junit.Test; - import io.netty.channel.ChannelHandlerContext; - import io.netty.channel.SimpleChannelInboundHandler; - public class CoapServerTest { - private static class CoapHandler - extends SimpleChannelInboundHandler { - @Override - protected void channelRead0(ChannelHandlerContext ctx, CoapRequest msg) - throws Exception { - // TODO Auto-generated method stub - } - } - @Test public void testAddHandler() throws Exception { CoapServer server = new CoapServer(); server.startServer(new InetSocketAddress(5683)); - server.addHandler(new CoapHandler()); + server.addHandler(new CoapLogHandler()); server.stopServer(); } diff --combined plugins/samples/linux/IotivityandZigbeeClient.c index 2c0de60,c781891..2c39b90 --- a/plugins/samples/linux/IotivityandZigbeeClient.c +++ b/plugins/samples/linux/IotivityandZigbeeClient.c @@@ -199,7 -199,7 +199,8 @@@ OCPayload* getChangeBulbTempLevelPayloa errno = 0; size_t sizeValue = sizeof(value); int strRet = snprintf(value, sizeValue, "%d", level); - if (strRet < 0 || (size_t)strRet >= sizeValue) ++ + if (strRet < 0 || strRet >= (int)sizeValue) { OIC_LOG_V(ERROR, TAG, "Failed to parse string due to errno: %d", errno); exit(1); diff --combined resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.h index 34b6256,43edafa..483c90a --- a/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.h +++ b/resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.h @@@ -50,17 -50,29 +50,17 @@@ void CAEDRServerJniInit() CAResult_t CAEDRServerStartAcceptThread(); /** - * Start unicast server. + * Start receive thread. * @param[in] isSecured unicast server type. * @return ::CA_STATUS_OK or Appropriate error code. */ -CAResult_t CAEDRStartUnicastServer(bool isSecured); +CAResult_t CAEDRStartReceiveThread(bool isSecured); /** - * Start multicast server. + * Stop receive thread. * @return ::CA_STATUS_OK or Appropriate error code. */ -CAResult_t CAEDRStartMulticastServer(); - -/** - * Stop unicast server. - * @return ::CA_STATUS_OK or Appropriate error code. - */ -CAResult_t CAEDRStopUnicastServer(); - -/** - * Stop multicast server. - * @return ::CA_STATUS_OK or Appropriate error code. - */ -CAResult_t CAEDRStopMulticastServer(); +CAResult_t CAEDRStopReceiveThread(); /** * This function will read the data from remote device. @@@ -84,14 -96,14 +84,6 @@@ void CANativeStartListenTask(JNIEnv *en jobject CAEDRNativeListen(JNIEnv *env); /** -- * This function will listen the connection from remote device. -- * @param[in] env JNI interface pointer. -- * @param[in] socket server socket object. -- * @return JNI_TRUE or JNI_FALSE. -- */ --jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket); -- --/** * This function will accept the connection from remote device. * @param[in] env JNI interface pointer. * @param[in] severSocketObject server socket object. diff --combined resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c index 5773e6c,dd953de..338d679 --- a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c @@@ -95,7 -95,6 +95,7 @@@ static ca_mutex g_deviceScanRetryDelayM static ca_cond g_deviceScanRetryDelayCond = NULL; static ca_mutex g_scanMutex = NULL; +static ca_mutex g_threadSendStateMutex = NULL; static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL; @@@ -170,24 -169,6 +170,24 @@@ CAResult_t CALECreateJniInterfaceObject isAttached = true; } + jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context", + "getApplicationContext", + "()Landroid/content/Context;"); + + if (!mid_getApplicationContext) + { + OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method"); + return CA_STATUS_FAILED; + } + + jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context, + mid_getApplicationContext); + if (!jApplicationContext) + { + OIC_LOG(ERROR, TAG, "Could not get application context"); + return CA_STATUS_FAILED; + } + jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface"); if (!jni_LEInterface) { @@@ -203,7 -184,7 +203,7 @@@ goto error_exit; } - (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context); + (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext); OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface"); if (isAttached) @@@ -800,30 -781,12 +800,30 @@@ CAResult_t CALEClientSendUnicastMessage { OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed"); ca_mutex_unlock(g_threadSendMutex); - return res; + return ret; } ca_mutex_unlock(g_threadSendMutex); OIC_LOG(INFO, TAG, "unicast - send logic has finished"); - return CALECheckSendState(address); + if (CALEClientIsValidState(address, CA_LE_SEND_STATE, + STATE_SEND_SUCCESS)) + { + ret = CA_STATUS_OK; + } + else + { + ret = CA_SEND_FAILED; + } + + // reset send state + ret = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE, + STATE_SEND_NONE); + if (CA_STATUS_OK != ret) + { + OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed"); + } + + return ret; // error label. error_exit: @@@ -838,7 -801,7 +838,7 @@@ { (*g_jvm)->DetachCurrentThread(g_jvm); } - return res; + return ret; } if (isAttached) @@@ -846,6 -809,10 +846,6 @@@ (*g_jvm)->DetachCurrentThread(g_jvm); } - if (g_clientErrorCallback) - { - g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED); - } ca_mutex_unlock(g_threadSendMutex); return CA_SEND_FAILED; } @@@ -967,6 -934,31 +967,6 @@@ error_exit return CA_SEND_FAILED; } -CAResult_t CALECheckSendState(const char* address) -{ - VERIFY_NON_NULL(address, TAG, "address is null"); - - ca_mutex_lock(g_deviceStateListMutex); - CALEState_t* state = CALEClientGetStateInfo(address); - if (NULL == state) - { - OIC_LOG(ERROR, TAG, "state is null"); - ca_mutex_unlock(g_deviceStateListMutex); - return CA_SEND_FAILED; - } - - if (STATE_SEND_SUCCESS != state->sendState) - { - OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS"); - ca_mutex_unlock(g_deviceStateListMutex); - return CA_SEND_FAILED; - } - - OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS"); - ca_mutex_unlock(g_deviceStateListMutex); - return CA_STATUS_OK; -} - CAResult_t CALEClientSendData(JNIEnv *env, jobject device) { OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData"); @@@ -989,6 -981,7 +989,6 @@@ ca_mutex_lock(g_deviceStateListMutex); state = CALEClientGetStateInfo(address); ca_mutex_unlock(g_deviceStateListMutex); - (*env)->ReleaseStringUTFChars(env, jni_address, address); } if (!state) @@@ -999,6 -992,13 +999,6 @@@ // if there is gatt object in g_gattObjectList. if (jni_address) { - address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL); - if (!address) - { - OIC_LOG(ERROR, TAG, "address is not available"); - return CA_STATUS_FAILED; - } - jobject gatt = CALEClientGetGattObjInList(env, address); if (gatt) { @@@ -1022,10 -1022,21 +1022,10 @@@ } else { - if (STATE_CONNECTED == state->connectedState) + if (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE, + STATE_SERVICE_CONNECTED)) { OIC_LOG(INFO, TAG, "GATT has already connected"); - if (!jni_address) - { - OIC_LOG(ERROR, TAG, "jni_address is not available"); - return CA_STATUS_FAILED; - } - - address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL); - if (!address) - { - OIC_LOG(ERROR, TAG, "address is not available"); - return CA_STATUS_FAILED; - } jobject gatt = CALEClientGetGattObjInList(env, address); if (!gatt) @@@ -1044,13 -1055,7 +1044,13 @@@ } (*env)->ReleaseStringUTFChars(env, jni_address, address); } - else + else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE, + STATE_CONNECTED)) + { + OIC_LOG(INFO, TAG, "service connecting..."); + } + else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE, + STATE_DISCONNECTED)) { OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE"); @@@ -1058,6 -1063,13 +1058,6 @@@ // if there is gatt object in g_gattObjectList. if (jni_address) { - address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL); - if (!address) - { - OIC_LOG(ERROR, TAG, "address is not available"); - return CA_STATUS_FAILED; - } - jobject gatt = CALEClientGetGattObjInList(env, address); if (gatt) { @@@ -1072,8 -1084,7 +1072,9 @@@ OIC_LOG(DEBUG, TAG, "start to connect LE"); jobject gatt = CALEClientConnect(env, device, - CALEClientGetAutoConnectFlag(env, jni_address)); + CALEClientGetFlagFromState(env, jni_address, + CA_LE_AUTO_CONNECT_FLAG)); ++ if (NULL == gatt) { OIC_LOG(ERROR, TAG, "CALEClientConnect has failed"); @@@ -1090,8 -1101,8 +1091,8 @@@ jstring CALEClientGetAddressFromGattObj VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL); VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL); - jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice", - "()Landroid/bluetooth/BluetoothDevice;"); + jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice", + "()Landroid/bluetooth/BluetoothDevice;"); if (!jni_mid_getDevice) { OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null"); @@@ -1127,7 -1138,7 +1128,7 @@@ CAResult_t CALEClientGattClose(JNIEnv * // get BluetoothGatt method OIC_LOG(DEBUG, TAG, "get BluetoothGatt method"); - jmethodID jni_mid_closeGatt = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V"); + jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V"); if (!jni_mid_closeGatt) { OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null"); @@@ -1266,16 -1277,15 +1267,16 @@@ CAResult_t CALEClientStartScanImpl(JNIE } // call start le scan method + OIC_LOG(INFO, TAG, "CALL API - startLeScan"); jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_startLeScan, callback); if (!jni_obj_startLeScan) { - OIC_LOG(INFO, TAG, "startLeScan is failed"); + OIC_LOG(INFO, TAG, "startLeScan has failed"); } else { - OIC_LOG(DEBUG, TAG, "startLeScan is started"); + OIC_LOG(DEBUG, TAG, "LeScan has started"); CALEClientSetScanFlag(true); } @@@ -1331,16 -1341,15 +1332,16 @@@ CAResult_t CALEClientStartScanWithUUIDI } // call start le scan method + OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)"); jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_startLeScan, uuids, callback); if (!jni_obj_startLeScan) { - OIC_LOG(INFO, TAG, "startLeScan With UUID is failed"); + OIC_LOG(INFO, TAG, "startLeScan has failed"); } else { - OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started"); + OIC_LOG(DEBUG, TAG, "LeScan has started"); CALEClientSetScanFlag(true); } @@@ -1491,7 -1500,7 +1492,7 @@@ CAResult_t CALEClientStopScanImpl(JNIEn return CA_STATUS_FAILED; } - OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan"); + OIC_LOG(INFO, TAG, "CALL API - stopLeScan"); // call start le scan method (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback); if ((*env)->ExceptionCheck(env)) @@@ -1505,9 -1514,9 +1506,9 @@@ return CA_STATUS_OK; } -CAResult_t CALEClientSetAutoConnectFlag(JNIEnv *env, jstring jni_address, jboolean flag) +CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag) { - OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag"); + OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState"); VERIFY_NON_NULL(env, TAG, "env"); VERIFY_NON_NULL(jni_address, TAG, "jni_address"); @@@ -1530,30 -1539,20 +1531,30 @@@ ca_mutex_unlock(g_deviceStateListMutex); return CA_STATUS_FAILED; } - OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag); + OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag); - curState->autoConnectFlag = flag; + switch(state_idx) + { + case CA_LE_AUTO_CONNECT_FLAG: + curState->autoConnectFlag = flag; + break; + case CA_LE_DESCRIPTOR_FOUND: + curState->isDescriptorFound = flag; + break; + default: + break; + } } (*env)->ReleaseStringUTFChars(env, jni_address, address); ca_mutex_unlock(g_deviceStateListMutex); - OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag"); + OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState"); return CA_STATUS_OK; } -jboolean CALEClientGetAutoConnectFlag(JNIEnv *env, jstring jni_address) +jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx) { - OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag"); + OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState"); VERIFY_NON_NULL_RET(env, TAG, "env", false); VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false); @@@ -1563,36 -1562,24 +1564,36 @@@ if (!address) { OIC_LOG(ERROR, TAG, "address is not available"); + ca_mutex_unlock(g_deviceStateListMutex); return JNI_FALSE; } CALEState_t* curState = CALEClientGetStateInfo(address); + (*env)->ReleaseStringUTFChars(env, jni_address, address); if(!curState) { OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false"); - (*env)->ReleaseStringUTFChars(env, jni_address, address); ca_mutex_unlock(g_deviceStateListMutex); return JNI_FALSE; } - OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag); - (*env)->ReleaseStringUTFChars(env, jni_address, address); + jboolean ret = JNI_FALSE; + switch(state_idx) + { + case CA_LE_AUTO_CONNECT_FLAG: + ret = curState->autoConnectFlag; + break; + case CA_LE_DESCRIPTOR_FOUND: + ret = curState->isDescriptorFound; + break; + default: + break; + } ca_mutex_unlock(g_deviceStateListMutex); - OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag"); - return curState->autoConnectFlag; + OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret); + OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState"); + return ret; } jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect) @@@ -1681,11 -1668,11 +1682,11 @@@ jobject CALEClientGattConnect(JNIEnv *e // get BluetoothDevice method OIC_LOG(DEBUG, TAG, "get BluetoothDevice method"); - jmethodID jni_mid_connectGatt = CALEGetJNIMethodID(env, "android/bluetooth/BluetoothDevice", - "connectGatt", - "(Landroid/content/Context;ZLandroid/" - "bluetooth/BluetoothGattCallback;)" - "Landroid/bluetooth/BluetoothGatt;"); + jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice", + "connectGatt", + "(Landroid/content/Context;ZLandroid/" + "bluetooth/BluetoothGattCallback;)" + "Landroid/bluetooth/BluetoothGatt;"); if (!jni_mid_connectGatt) { OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null"); @@@ -1796,8 -1783,8 +1797,8 @@@ CAResult_t CALEClientDisconnect(JNIEnv // get BluetoothGatt method OIC_LOG(DEBUG, TAG, "get gatt disconnect method"); - jmethodID jni_mid_disconnectGatt = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, - "disconnect", "()V"); + jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, + "disconnect", "()V"); if (!jni_mid_disconnectGatt) { OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null"); @@@ -1805,7 -1792,7 +1806,7 @@@ } // call disconnect gatt method - OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt"); + OIC_LOG(INFO, TAG, "CALL API - disconnect"); (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt); if ((*env)->ExceptionCheck(env)) { @@@ -1933,8 -1920,8 +1934,8 @@@ CAResult_t CALEClientDiscoverServices(J // get BluetoothGatt.discoverServices method OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method"); - jmethodID jni_mid_discoverServices = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, - "discoverServices", "()Z"); + jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, + "discoverServices", "()Z"); if (!jni_mid_discoverServices) { OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null"); @@@ -1942,7 -1929,7 +1943,7 @@@ } // call disconnect gatt method - OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services"); + OIC_LOG(INFO, TAG, "CALL API - discoverServices"); jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices); if (!ret) { @@@ -1988,49 -1975,9 +1989,49 @@@ static void CALEWriteCharacteristicThre CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt) { + OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic"); + VERIFY_NON_NULL(gatt, TAG, "gatt is null"); VERIFY_NON_NULL(env, TAG, "env is null"); + jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); + if (!jni_address) + { + CALEClientSendFinish(env, gatt); + return CA_STATUS_FAILED; + } + + const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); + if (!address) + { + CALEClientSendFinish(env, gatt); + return CA_STATUS_FAILED; + } + + ca_mutex_lock(g_threadSendStateMutex); + + if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING)) + { + OIC_LOG(INFO, TAG, "current state is SENDING"); + (*env)->ReleaseStringUTFChars(env, jni_address, address); + ca_mutex_unlock(g_threadSendStateMutex); + return CA_STATUS_OK; + } + + if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE, + STATE_SENDING)) + { + OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed"); + (*env)->ReleaseStringUTFChars(env, jni_address, address); + CALEClientSendFinish(env, gatt); + ca_mutex_unlock(g_threadSendStateMutex); + return CA_STATUS_FAILED; + } + + (*env)->ReleaseStringUTFChars(env, jni_address, address); + + ca_mutex_unlock(g_threadSendStateMutex); + // send data jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer); if (!jni_obj_character) @@@ -2104,10 -2051,10 +2105,10 @@@ CAResult_t CALEClientWriteCharacteristi // get BluetoothGatt.write characteristic method OIC_LOG(DEBUG, TAG, "write characteristic method"); - jmethodID jni_mid_writeCharacteristic = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, - "writeCharacteristic", - "(Landroid/bluetooth/" - "BluetoothGattCharacteristic;)Z"); + jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, + "writeCharacteristic", + "(Landroid/bluetooth/" + "BluetoothGattCharacteristic;)Z"); if (!jni_mid_writeCharacteristic) { OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null"); @@@ -2115,7 -2062,7 +2116,7 @@@ } // call disconnect gatt method - OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic"); + OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic"); jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeCharacteristic, gattCharacteristic); @@@ -2158,10 -2105,10 +2159,10 @@@ CAResult_t CALEClientReadCharacteristic } OIC_LOG(DEBUG, TAG, "read characteristic method"); - jmethodID jni_mid_readCharacteristic = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, - "readCharacteristic", - "(Landroid/bluetooth/" - "BluetoothGattCharacteristic;)Z"); + jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, + "readCharacteristic", + "(Landroid/bluetooth/" + "BluetoothGattCharacteristic;)Z"); if (!jni_mid_readCharacteristic) { OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null"); @@@ -2169,7 -2116,7 +2170,7 @@@ } // call disconnect gatt method - OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic"); + OIC_LOG(INFO, TAG, "CALL API - readCharacteristic"); jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic, jni_obj_GattCharacteristic); if (ret) @@@ -2200,26 -2147,25 +2201,26 @@@ CAResult_t CALEClientSetCharacteristicN // get BluetoothGatt.setCharacteristicNotification method OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification"); - jmethodID jni_mid_setNotification = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, - "setCharacteristicNotification", - "(Landroid/bluetooth/" - "BluetoothGattCharacteristic;Z)Z"); + jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, + "setCharacteristicNotification", + "(Landroid/bluetooth/" + "BluetoothGattCharacteristic;Z)Z"); if (!jni_mid_setNotification) { OIC_LOG(ERROR, TAG, "jni_mid_getService is null"); return CA_STATUS_FAILED; } + OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification"); jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification, characteristic, JNI_TRUE); if (JNI_TRUE == ret) { - OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success"); + OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success"); } else { - OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed"); + OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed"); return CA_STATUS_FAILED; } @@@ -2240,10 -2186,10 +2241,10 @@@ jobject CALEClientGetGattService(JNIEn // get BluetoothGatt.getService method OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService"); - jmethodID jni_mid_getService = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, - "getService", - "(Ljava/util/UUID;)Landroid/bluetooth/" - "BluetoothGattService;"); + jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, + "getService", + "(Ljava/util/UUID;)Landroid/bluetooth/" + "BluetoothGattService;"); if (!jni_mid_getService) { OIC_LOG(ERROR, TAG, "jni_mid_getService is null"); @@@ -2268,12 -2214,12 +2269,12 @@@ } // get bluetooth gatt service method - jmethodID jni_mid_getCharacteristic = CALEGetJNIMethodID(env, "android/bluetooth/" - "BluetoothGattService", - "getCharacteristic", - "(Ljava/util/UUID;)" - "Landroid/bluetooth/" - "BluetoothGattCharacteristic;"); + jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/" + "BluetoothGattService", + "getCharacteristic", + "(Ljava/util/UUID;)" + "Landroid/bluetooth/" + "BluetoothGattCharacteristic;"); if (!jni_mid_getCharacteristic) { OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null"); @@@ -2396,9 -2342,9 +2397,9 @@@ jbyteArray CALEClientGetValueFromCharac return NULL; } - jmethodID jni_mid_getValue = CALEGetJNIMethodID(env, "android/bluetooth/" - "BluetoothGattCharacteristic", - "getValue", "()[B"); + jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/" + "BluetoothGattCharacteristic", + "getValue", "()[B"); if (!jni_mid_getValue) { OIC_LOG(ERROR, TAG, "jni_mid_getValue is null"); @@@ -2492,11 -2438,11 +2493,11 @@@ CAResult_t CALEClientSetUUIDToDescripto } OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor"); - jmethodID jni_mid_getDescriptor = CALEGetJNIMethodID(env, "android/bluetooth/" - "BluetoothGattCharacteristic", - "getDescriptor", - "(Ljava/util/UUID;)Landroid/bluetooth/" - "BluetoothGattDescriptor;"); + jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/" + "BluetoothGattCharacteristic", + "getDescriptor", + "(Ljava/util/UUID;)Landroid/bluetooth/" + "BluetoothGattDescriptor;"); if (!jni_mid_getDescriptor) { OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null"); @@@ -2558,17 -2504,17 +2559,17 @@@ return CA_STATUS_FAILED; } - jmethodID jni_mid_writeDescriptor = CALEGetJNIMethodID(env, "android/bluetooth/BluetoothGatt", - "writeDescriptor", - "(Landroid/bluetooth/" - "BluetoothGattDescriptor;)Z"); + jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt", + "writeDescriptor", + "(Landroid/bluetooth/" + "BluetoothGattDescriptor;)Z"); if (!jni_mid_writeDescriptor) { OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null"); return CA_STATUS_FAILED; } - OIC_LOG(DEBUG, TAG, "request to write descriptor"); + OIC_LOG(INFO, TAG, "CALL API - writeDescriptor"); jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor, jni_obj_descriptor); if (jni_ret) @@@ -2612,7 -2558,7 +2613,7 @@@ CAResult_t CALEClientAddScanDeviceToLis OIC_LOG(ERROR, TAG, "gdevice_list is null"); CALEClientSetScanFlag(false); - if(CA_STATUS_OK != CALEClientStopScan()) + if (CA_STATUS_OK != CALEClientStopScan()) { OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed"); } @@@ -2642,7 -2588,7 +2643,7 @@@ jobject gdevice = (*env)->NewGlobalRef(env, device); u_arraylist_add(g_deviceList, gdevice); ca_cond_signal(g_deviceDescCond); - OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress); + OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress); } (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress); @@@ -2695,7 -2641,7 +2696,7 @@@ bool CALEClientIsDeviceInScanDeviceList (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress); } - OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add"); + OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in scanned device list", remoteAddress); return false; } @@@ -2818,7 -2764,7 +2819,7 @@@ CAResult_t CALEClientRemoveDeviceInScan CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt) { - OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList"); + OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList"); VERIFY_NON_NULL(env, TAG, "env is null"); VERIFY_NON_NULL(gatt, TAG, "gatt is null"); @@@ -2847,12 -2793,12 +2848,12 @@@ return CA_STATUS_FAILED; } - OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress); + OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress); if (!CALEClientIsGattObjInList(env, remoteAddress)) { jobject newGatt = (*env)->NewGlobalRef(env, gatt); u_arraylist_add(g_gattObjectList, newGatt); - OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element"); + OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList"); } (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress); @@@ -3152,7 -3098,7 +3153,7 @@@ CAResult_t CALEClientRemoveGattObjForAd jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice) { - OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice"); + OIC_LOG(DEBUG, TAG, "CALEClientGetLEAddressFromBTDevice"); VERIFY_NON_NULL_RET(env, TAG, "env", NULL); VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL); @@@ -3173,8 -3119,8 +3174,8 @@@ } // get method ID of getDevice() - jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, - "getDevice", METHODID_BT_DEVICE); + jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, + "getDevice", METHODID_BT_DEVICE); if (!jni_mid_getDevice) { OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null"); @@@ -3182,27 -3128,21 +3183,27 @@@ return NULL; } + ca_mutex_lock(g_gattObjectMutex); + size_t length = u_arraylist_length(g_gattObjectList); + OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length); + OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress); + for (size_t index = 0; index < length; index++) { jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index); if (!jarrayObj) { + ca_mutex_unlock(g_gattObjectMutex); OIC_LOG(ERROR, TAG, "jarrayObj is null"); (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress); return NULL; } - OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()"); jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice); if (!jni_obj_device) { + ca_mutex_unlock(g_gattObjectMutex); OIC_LOG(ERROR, TAG, "jni_obj_device is null"); (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress); return NULL; @@@ -3211,7 -3151,6 +3212,7 @@@ jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device); if (!jni_btAddress) { + ca_mutex_unlock(g_gattObjectMutex); OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed"); (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress); return NULL; @@@ -3220,13 -3159,13 +3221,13 @@@ const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL); if (!btAddress) { + ca_mutex_unlock(g_gattObjectMutex); OIC_LOG(ERROR, TAG, "btAddress is not available"); (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress); return NULL; } - OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress); - OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress); + OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index); if (!strcmp(targetAddress, btAddress)) { OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device"); @@@ -3237,7 -3176,6 +3238,7 @@@ { OIC_LOG(ERROR, TAG, "jni_LEAddress is null"); } + ca_mutex_unlock(g_gattObjectMutex); (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress); (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress); (*env)->DeleteLocalRef(env, jni_btAddress); @@@ -3248,10 -3186,8 +3249,10 @@@ (*env)->DeleteLocalRef(env, jni_btAddress); (*env)->DeleteLocalRef(env, jni_obj_device); } + ca_mutex_unlock(g_gattObjectMutex); - OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice"); + (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress); + OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress); return NULL; } @@@ -3259,24 -3195,48 +3260,24 @@@ * BT State List */ -CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState, - uint16_t notificationState, uint16_t sendState) +CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type, + uint16_t target_state) { VERIFY_NON_NULL(address, TAG, "address is null"); - - CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate)); - if (!newstate) - { - OIC_LOG(ERROR, TAG, "out of memory"); - return CA_MEMORY_ALLOC_FAILED; - } - - if (strlen(address) > CA_MACADDR_SIZE) - { - OIC_LOG(ERROR, TAG, "address is not proper"); - OICFree(newstate); - return CA_STATUS_FAILED; - } - - OICStrcpy(newstate->address, sizeof(newstate->address), address); - newstate->connectedState = connectedState; - newstate->notificationState = notificationState; - newstate->sendState = sendState; - return CALEClientAddDeviceStateToList(newstate); -} - -CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state) -{ - VERIFY_NON_NULL(state, TAG, "state is null"); - - ca_mutex_lock(g_deviceStateListMutex); + VERIFY_NON_NULL(address, TAG, "state_type is null"); + VERIFY_NON_NULL(address, TAG, "target_state is null"); if (!g_deviceStateList) { OIC_LOG(ERROR, TAG, "gdevice_list is null"); - ca_mutex_unlock(g_deviceStateListMutex); return CA_STATUS_FAILED; } - if (CALEClientIsDeviceInList(state->address)) + ca_mutex_lock(g_deviceStateListMutex); + + if (CALEClientIsDeviceInList(address)) { - CALEState_t* curState = CALEClientGetStateInfo(state->address); + CALEState_t* curState = CALEClientGetStateInfo(address); if(!curState) { OIC_LOG(ERROR, TAG, "curState is null"); @@@ -3284,62 -3244,27 +3285,61 @@@ return CA_STATUS_FAILED; } - if (STATE_CHARACTER_NO_CHANGE == state->notificationState) + switch(state_type) { - state->notificationState = curState->notificationState; + case CA_LE_CONNECTION_STATE: + curState->connectedState = target_state; + break; + case CA_LE_SEND_STATE: + curState->sendState = target_state; + break; + default: + break; + } + OIC_LOG_V(INFO, TAG, "update state - addr : %s, conn : %d, send : %d, ACFlag : %d", + curState->address, curState->connectedState, curState->sendState, + curState->autoConnectFlag); + } + else /** state is added newly **/ + { + if (strlen(address) > CA_MACADDR_SIZE) + { + OIC_LOG(ERROR, TAG, "address is not proper"); + ca_mutex_unlock(g_deviceStateListMutex); + return CA_STATUS_INVALID_PARAM; } - state->autoConnectFlag = curState->autoConnectFlag; - // delete previous state for update new state - CAResult_t res = CALEClientRemoveDeviceState(state->address); - if (CA_STATUS_OK != res) + CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate)); + if (!newstate) { - OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed"); + OIC_LOG(ERROR, TAG, "out of memory"); ca_mutex_unlock(g_deviceStateListMutex); - return res; + return CA_MEMORY_ALLOC_FAILED; } - } - u_arraylist_add(g_deviceStateList, state); // update new state - OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s, %d", - state->connectedState, state->notificationState, - state->address, state->autoConnectFlag); + OICStrcpy(newstate->address, sizeof(newstate->address), address); + + switch(state_type) + { + case CA_LE_CONNECTION_STATE: + newstate->connectedState = target_state; + newstate->sendState = STATE_SEND_NONE; + break; + case CA_LE_SEND_STATE: + newstate->connectedState = STATE_DISCONNECTED; + newstate->sendState = target_state; + break; + default: + break; + } + OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, " + "conn : %d, send : %d, ACFlag : %d", + newstate->address, newstate->connectedState, newstate->sendState, + newstate->autoConnectFlag); + u_arraylist_add(g_deviceStateList, newstate); // update new state + } - ca_mutex_unlock(g_deviceStateListMutex); + return CA_STATUS_OK; } @@@ -3434,6 -3359,7 +3434,6 @@@ CAResult_t CALEClientResetDeviceStateFo // autoConnectFlag value will be not changed, // since it has reset only termination case. state->connectedState = STATE_DISCONNECTED; - state->notificationState = STATE_CHARACTER_UNSET; state->sendState = STATE_SEND_NONE; } ca_mutex_unlock(g_deviceStateListMutex); @@@ -3484,6 -3410,7 +3484,6 @@@ CAResult_t CALEClientRemoveDeviceState( CALEState_t* CALEClientGetStateInfo(const char* remoteAddress) { - OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo"); VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL); if (!g_deviceStateList) @@@ -3493,8 -3420,7 +3493,8 @@@ } uint32_t length = u_arraylist_length(g_deviceStateList); - OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length); + OIC_LOG_V(DEBUG, TAG, "length of deviceStateList : %d", length); + OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress); for (uint32_t index = 0; index < length; index++) { @@@ -3505,24 -3431,21 +3505,24 @@@ continue; } - OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress); - OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address); + OIC_LOG_V(DEBUG, TAG, "state address : %s (idx: %d)", state->address, index); if (!strcmp(state->address, remoteAddress)) { - OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress); + OIC_LOG(DEBUG, TAG, "found state"); return state; } } + + OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress); return NULL; } -bool CALEClientIsConnectedDevice(const char* remoteAddress) +bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type, + uint16_t target_state) { - OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice"); + OIC_LOG_V(DEBUG, TAG, "CALEClientIsValidState : type[%d], target state[%d]", + state_type, target_state); VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false); ca_mutex_lock(g_deviceStateListMutex); @@@ -3533,36 -3456,74 +3533,36 @@@ return false; } - uint32_t length = u_arraylist_length(g_deviceStateList); - for (uint32_t index = 0; index < length; index++) + CALEState_t* state = CALEClientGetStateInfo(remoteAddress); + if (NULL == state) { - CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index); - if (!state) - { - OIC_LOG(ERROR, TAG, "CALEState_t object is null"); - continue; - } - - if (!strcmp(state->address, remoteAddress)) - { - OIC_LOG(DEBUG, TAG, "check whether it is connected or not"); - - if (STATE_CONNECTED == state->connectedState) - { - ca_mutex_unlock(g_deviceStateListMutex); - return true; - } - else - { - ca_mutex_unlock(g_deviceStateListMutex); - return false; - } - } + OIC_LOG(ERROR, TAG, "state is null"); + ca_mutex_unlock(g_deviceStateListMutex); + return false; } - ca_mutex_unlock(g_deviceStateListMutex); - return false; -} -bool CALEClientIsSetCharacteristic(const char* remoteAddress) -{ - OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic"); - VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false); + uint16_t curValue = 0; + switch(state_type) + { + case CA_LE_CONNECTION_STATE: + curValue = state->connectedState; + break; + case CA_LE_SEND_STATE: + curValue = state->sendState; + break; + default: + break; + } - ca_mutex_lock(g_deviceStateListMutex); - if (!g_deviceStateList) + if (target_state == curValue) { - OIC_LOG(ERROR, TAG, "g_deviceStateList is null"); ca_mutex_unlock(g_deviceStateListMutex); - return false; + return true; } - - uint32_t length = u_arraylist_length(g_deviceStateList); - for (uint32_t index = 0; index < length; index++) + else { - CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index); - if (!state) - { - OIC_LOG(ERROR, TAG, "CALEState_t object is null"); - continue; - } - - if (!strcmp(state->address, remoteAddress)) - { - OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState); - - if (STATE_CHARACTER_SET == state->notificationState) - { - ca_mutex_unlock(g_deviceStateListMutex); - return true; - } - else - { - ca_mutex_unlock(g_deviceStateListMutex); - return false; - } - } + ca_mutex_unlock(g_deviceStateListMutex); + return false; } ca_mutex_unlock(g_deviceStateListMutex); @@@ -3741,16 -3702,6 +3741,16 @@@ CAResult_t CALEClientInitGattMutexVarai } } + if (NULL == g_threadSendStateMutex) + { + g_threadSendStateMutex = ca_mutex_new(); + if (NULL == g_threadSendStateMutex) + { + OIC_LOG(ERROR, TAG, "ca_mutex_new has failed"); + return CA_STATUS_FAILED; + } + } + return CA_STATUS_OK; } @@@ -3782,9 -3733,6 +3782,9 @@@ void CALEClientTerminateGattMutexVariab ca_mutex_free(g_deviceScanRetryDelayMutex); g_deviceScanRetryDelayMutex = NULL; + + ca_mutex_free(g_threadSendStateMutex); + g_threadSendStateMutex = NULL; } void CALEClientSetSendFinishFlag(bool flag) @@@ -3914,9 -3862,9 +3914,9 @@@ void CATerminateLEGattClient( CALEClientTerminate(); } -CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data, - uint32_t dataLen, CALETransferType_t type, - int32_t position) +CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data, + uint32_t dataLen, CALETransferType_t type, + int32_t position) { OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage"); VERIFY_NON_NULL(data, TAG, "data is null"); @@@ -4004,8 -3952,8 +4004,8 @@@ static jstring CALEClientGetAddressFrom VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL); VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL); - jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, - "getDevice", METHODID_BT_DEVICE); + jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, + "getDevice", METHODID_BT_DEVICE); if (!jni_mid_getDevice) { OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null"); @@@ -4037,81 -3985,87 +4037,81 @@@ */ JNIEXPORT void JNICALL Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env, - jobject obj, - jobject gatt, - jint status, - jint newstate) + jobject obj, + jobject gatt, + jint status, + jint newstate) { - OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status, - newstate); + OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status, + newstate); VERIFY_NON_NULL_VOID(env, TAG, "env is null"); VERIFY_NON_NULL_VOID(obj, TAG, "obj is null"); VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null"); jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED"); - jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED"); - jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS"); - if (gatt_success == status && state_connected == newstate) // le connected + jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); + if (!jni_address) { - jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); - if (!jni_address) - { - goto error_exit; - } + OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed"); + goto error_exit; + } - const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); - if (address) + const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); + if (!address) + { + OIC_LOG(ERROR, TAG, "address is null"); + goto error_exit; + } + OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address); + + CAResult_t res; + if (state_connected == newstate) + { + OIC_LOG(DEBUG, TAG, "LE is connected"); + if (GATT_SUCCESS == status) { - CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, - STATE_CHARACTER_NO_CHANGE, - STATE_SEND_NONE); + res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, STATE_CONNECTED); + (*env)->ReleaseStringUTFChars(env, jni_address, address); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed"); - (*env)->ReleaseStringUTFChars(env, jni_address, address); goto error_exit; } - OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address); - (*env)->ReleaseStringUTFChars(env, jni_address, address); - } + res = CALEClientAddGattobjToList(env, gatt); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed"); + goto error_exit; + } - CAResult_t res = CALEClientAddGattobjToList(env, gatt); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed"); - goto error_exit; + res = CALEClientDiscoverServices(env, gatt); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed"); + goto error_exit; + } } - - res = CALEClientDiscoverServices(env, gatt); - if (CA_STATUS_OK != res) + else { - OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed"); - goto error_exit; + OIC_LOG(INFO, TAG, "unknown status"); + (*env)->ReleaseStringUTFChars(env, jni_address, address); } } - else if (state_disconnected == newstate) // le disconnected + else // STATE_DISCONNECTED == newstate { - jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); - if (!jni_address) - { - OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed"); - goto error_exit; - } + OIC_LOG(DEBUG, TAG, "LE is disconnected"); - const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); - if (address) + res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, STATE_DISCONNECTED); + (*env)->ReleaseStringUTFChars(env, jni_address, address); + if (CA_STATUS_OK != res) { - CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED, - STATE_CHARACTER_UNSET, - STATE_SEND_NONE); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed"); - (*env)->ReleaseStringUTFChars(env, jni_address, address); - goto error_exit; - } - OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address); - - (*env)->ReleaseStringUTFChars(env, jni_address, address); + OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed"); + goto error_exit; } - CAResult_t res = CALEClientGattClose(env, gatt); + res = CALEClientGattClose(env, gatt); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed"); @@@ -4158,7 -4112,7 +4158,7 @@@ { // other reason except for gatt_success is expected to running // background connection in BT platform. - OIC_LOG(INFO, TAG, "unknown state or manual disconnected state"); + OIC_LOG(INFO, TAG, "unknown status or manual disconnected state"); CALEClientUpdateSendCnt(env); return; } @@@ -4174,6 -4128,7 +4174,6 @@@ // error label. error_exit: - CALEClientSendFinish(env, gatt); return; } @@@ -4185,16 -4140,16 +4185,16 @@@ */ JNIEXPORT void JNICALL Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env, - jobject obj, - jobject gatt, - jint status) + jobject obj, + jobject gatt, + jint status) { - OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status); + OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status); VERIFY_NON_NULL_VOID(env, TAG, "env is null"); VERIFY_NON_NULL_VOID(obj, TAG, "obj is null"); VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null"); - if (0 != status) // discovery error + if (GATT_SUCCESS != status) // discovery error { CALEClientSendFinish(env, gatt); return; @@@ -4214,48 -4169,55 +4214,48 @@@ return; } - if (!CALEClientIsSetCharacteristic(address)) + jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID); + if (!jni_uuid) { - jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID); - if (!jni_uuid) - { - OIC_LOG(ERROR, TAG, "jni_uuid is null"); - goto error_exit; - } + OIC_LOG(ERROR, TAG, "jni_uuid is null"); + goto error_exit; + } - jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid); - if (!jni_obj_GattCharacteristic) - { - OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null"); - goto error_exit; - } + jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid); + if (!jni_obj_GattCharacteristic) + { + OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null"); + goto error_exit; + } - CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt, - jni_obj_GattCharacteristic); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed"); - goto error_exit; - } + CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt, + jni_obj_GattCharacteristic); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed"); + goto error_exit; + } + + res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic); + if (CA_STATUS_OK != res) + { + OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res); - res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic); + res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE); if (CA_STATUS_OK != res) { - OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res); - if (g_sendBuffer) - { - CAResult_t res = CALEClientWriteCharacteristic(env, gatt); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed"); - goto error_exit; - } - } + OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed"); + goto error_exit; } - res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET, - STATE_SEND_NONE); + res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, + STATE_SERVICE_CONNECTED); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed"); goto error_exit; } - } - else - { + if (g_sendBuffer) { CAResult_t res = CALEClientWriteCharacteristic(env, gatt); @@@ -4266,16 -4228,6 +4266,16 @@@ } } } + else + { + res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed"); + goto error_exit; + } + } + OIC_LOG(INFO, TAG, "ServicesDiscovery is successful"); (*env)->ReleaseStringUTFChars(env, jni_address, address); return; @@@ -4295,9 -4247,10 +4295,9 @@@ error_exit */ JNIEXPORT void JNICALL Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback( - JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, - jint status) + JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status) { - OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status); + OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status); VERIFY_NON_NULL_VOID(env, TAG, "env is null"); VERIFY_NON_NULL_VOID(obj, TAG, "obj is null"); VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null"); @@@ -4315,7 -4268,8 +4315,7 @@@ goto error_exit; } - jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS"); - if (gatt_success != status) // error case + if (GATT_SUCCESS != status) // error case { OIC_LOG(ERROR, TAG, "send failure"); @@@ -4329,8 -4283,9 +4329,8 @@@ ca_cond_signal(g_threadWriteCharacteristicCond); ca_mutex_unlock(g_threadWriteCharacteristicMutex); - CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, - STATE_CHARACTER_SET, - STATE_SEND_FAILED); + CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE, + STATE_SEND_FAIL); if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed"); @@@ -4342,14 -4297,14 +4342,14 @@@ g_clientErrorCallback(address, data, length, CA_SEND_FAILED); } - CALEClientSendFinish(env, gatt); + (*env)->ReleaseStringUTFChars(env, jni_address, address); goto error_exit; } } else { OIC_LOG(DEBUG, TAG, "send success"); - CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET, + CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE, STATE_SEND_SUCCESS); if (CA_STATUS_OK != res) { @@@ -4384,7 -4339,7 +4384,7 @@@ JNIEXPORT void JNICAL Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback( JNIEnv *env, jobject obj, jobject gatt, jbyteArray data) { - OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback"); + OIC_LOG(INFO, TAG, "CALeGattCharacteristicChangedCallback"); VERIFY_NON_NULL_VOID(env, TAG, "env is null"); VERIFY_NON_NULL_VOID(obj, TAG, "obj is null"); VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null"); @@@ -4428,9 -4383,10 +4428,9 @@@ OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d", receivedData, length); - ca_mutex_lock(g_bleServerBDAddressMutex); uint32_t sentLength = 0; - g_CABLEClientDataReceivedCallback(address, receivedData, length, - &sentLength); + ca_mutex_lock(g_bleServerBDAddressMutex); + g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength); ca_mutex_unlock(g_bleServerBDAddressMutex); (*env)->ReleaseStringUTFChars(env, jni_address, address); @@@ -4446,34 -4402,14 +4446,34 @@@ Java_org_iotivity_ca_CaLeClientInterfac jobject gatt, jint status) { - OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status); + OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status); VERIFY_NON_NULL_VOID(env, TAG, "env is null"); VERIFY_NON_NULL_VOID(obj, TAG, "obj is null"); VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null"); - jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS"); - if (gatt_success != status) // error + if (GATT_SUCCESS != status) // error + { + goto error_exit; + } + + jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt); + if (!jni_address) + { + goto error_exit; + } + + const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL); + if (!address) + { + goto error_exit; + } + + CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, + STATE_SERVICE_CONNECTED); + (*env)->ReleaseStringUTFChars(env, jni_address, address); + if (CA_STATUS_OK != res) { + OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed"); goto error_exit; } diff --combined resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c index ca42cb4,63705b8..f07482c --- a/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c @@@ -29,6 -29,10 +29,10 @@@ #ifndef SINGLE_THREAD #include "caqueueingthread.h" #endif + #if defined(__TIZEN__) || defined(__ANDROID__) + #include "caleserver.h" + #include "caleclient.h" + #endif #include "oic_malloc.h" #include "oic_string.h" #include "caremotehandler.h" @@@ -69,12 -73,7 +73,12 @@@ typedef enu /** * Callback to provide the status of the network change to CA layer. */ -static CANetworkChangeCallback g_networkCallback = NULL; +static CAAdapterChangeCallback g_networkCallback = NULL; + +/** + * Callback to provide the status of the connection change to CA layer. + */ +static CAConnectionChangeCallback g_connectionCallback = NULL; /** * bleAddress of the local adapter. Value will be initialized to zero, @@@ -150,10 -149,8 +154,10 @@@ static CAErrorHandleCallback g_errorHan /** * Register network change notification callback. * - * @param[in] netCallback CANetworkChangeCallback callback which will - * be set for the change in network. + * @param[in] netCallback CAAdapterChangeCallback callback which will + * be set for the change in adapter. + * @param[in] connCallback CAConnectionChangeCallback callback which will + * be set for the change in connection. * * @return 0 on success otherwise a positive error value. * @retval ::CA_STATUS_OK Successful. @@@ -161,8 -158,7 +165,8 @@@ * @retval ::CA_STATUS_FAILED Operation failed. * */ -static CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback); +static CAResult_t CALERegisterNetworkNotifications(CAAdapterChangeCallback netCallback, + CAConnectionChangeCallback connCallback); /** * Set the thread pool handle which is required for spawning new @@@ -1725,8 -1721,7 +1729,8 @@@ static CAResult_t CALEAdapterGattClient CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, CANetworkPacketReceivedCallback reqRespCallback, - CANetworkChangeCallback netCallback, + CAAdapterChangeCallback netCallback, + CAConnectionChangeCallback connCallback, CAErrorHandleCallback errorCallback, ca_thread_pool_t handle) { @@@ -1736,7 -1731,6 +1740,7 @@@ VERIFY_NON_NULL(registerCallback, CALEADAPTER_TAG, "RegisterConnectivity callback is null"); VERIFY_NON_NULL(reqRespCallback, CALEADAPTER_TAG, "PacketReceived Callback is null"); VERIFY_NON_NULL(netCallback, CALEADAPTER_TAG, "NetworkChange Callback is null"); + VERIFY_NON_NULL(connCallback, CALEADAPTER_TAG, "ConnectionChange Callback is null"); CAResult_t result = CA_STATUS_OK; result = CAInitLEAdapterMutex(); @@@ -1778,7 -1772,7 +1782,7 @@@ CASetBLEClientErrorHandleCallback(CALEErrorHandler); CASetBLEServerErrorHandleCallback(CALEErrorHandler); - CALERegisterNetworkNotifications(netCallback); + CALERegisterNetworkNotifications(netCallback, connCallback); g_errorHandler = errorCallback; @@@ -1847,7 -1841,7 +1851,7 @@@ static void CATerminateLE( CASetLEReqRespServerCallback(NULL); CASetLEReqRespClientCallback(NULL); - CALERegisterNetworkNotifications(NULL); + CALERegisterNetworkNotifications(NULL, NULL); CASetLEReqRespAdapterCallback(NULL); CATerminateLENetworkMonitor(); @@@ -2163,14 -2157,12 +2167,14 @@@ static CAResult_t CAGetLEInterfaceInfor return CA_STATUS_OK; } -static CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback) +static CAResult_t CALERegisterNetworkNotifications(CAAdapterChangeCallback netCallback, + CAConnectionChangeCallback connCallback) { OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); ca_mutex_lock(g_bleNetworkCbMutex); g_networkCallback = netCallback; + g_connectionCallback = connCallback; ca_mutex_unlock(g_bleNetworkCbMutex); CAResult_t res = CA_STATUS_OK; if (netCallback) @@@ -2180,6 -2172,12 +2184,6 @@@ { OIC_LOG(ERROR, CALEADAPTER_TAG, "CASetLEAdapterStateChangedCb failed!"); } - - res = CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCb); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, CALEADAPTER_TAG, "CALEConnectionStateChangedCb failed!"); - } } else { @@@ -2190,15 -2188,6 +2194,15 @@@ } } + if (g_connectionCallback) + { + res = CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCb); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "CASetLENWConnectionStateChangedCb failed!"); + } + } + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return res; } @@@ -2261,16 -2250,6 +2265,16 @@@ static void CALEConnectionStateChangedC #endif } + CAEndpoint_t localEndpoint = { .adapter = CA_ADAPTER_GATT_BTLE }; + OICStrcpy(localEndpoint.addr, sizeof(localEndpoint.addr), address); + + ca_mutex_lock(g_bleNetworkCbMutex); + if (g_connectionCallback) + { + g_connectionCallback(&localEndpoint, isConnected); + } + ca_mutex_unlock(g_bleNetworkCbMutex); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); } @@@ -2278,6 -2257,15 +2282,6 @@@ static void CALEDeviceStateChangedCb(CA { OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CALEDeviceStateChangedCb"); - VERIFY_NON_NULL_VOID(g_localBLEAddress, CALEADAPTER_TAG, "g_localBLEAddress is null"); - CAEndpoint_t localEndpoint = { .adapter = CA_ADAPTER_GATT_BTLE }; - - ca_mutex_lock(g_bleLocalAddressMutex); - OICStrcpy(localEndpoint.addr, - sizeof(localEndpoint.addr), - g_localBLEAddress); - ca_mutex_unlock(g_bleLocalAddressMutex); - if (CA_ADAPTER_ENABLED == adapter_state) { ca_mutex_lock(g_bleIsServerMutex); @@@ -2322,7 -2310,7 +2326,7 @@@ ca_mutex_lock(g_bleNetworkCbMutex); if (NULL != g_networkCallback) { - g_networkCallback(&localEndpoint, adapter_state); + g_networkCallback(CA_ADAPTER_GATT_BTLE, adapter_state); } else { @@@ -2649,7 -2637,7 +2653,7 @@@ static void CALERemoveSendQueueData(CAQ static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList, const char* address) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALERemoveSendQueueData"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALERemoveReceiveQueueData"); VERIFY_NON_NULL_VOID(dataInfoList, CALEADAPTER_TAG, "dataInfoList"); VERIFY_NON_NULL_VOID(address, CALEADAPTER_TAG, "address"); diff --combined resource/csdk/connectivity/src/cablockwisetransfer.c index f94e9e4,f214067..a78aa06 --- a/resource/csdk/connectivity/src/cablockwisetransfer.c +++ b/resource/csdk/connectivity/src/cablockwisetransfer.c @@@ -40,7 -40,6 +40,7 @@@ #include "caremotehandler.h" #include "cablockwisetransfer.h" #include "oic_malloc.h" +#include "oic_string.h" #include "camutex.h" #include "logger.h" @@@ -113,7 -112,6 +113,7 @@@ CAResult_t CATerminateBlockWiseTransfer if (g_context.dataList) { + CARemoveAllBlockDataFromList(); u_arraylist_free(&g_context.dataList); } @@@ -1233,7 -1231,7 +1233,7 @@@ CAResult_t CASetMoreBitFromBlock(size_ } CAResult_t CANegotiateBlockSize(CABlockData_t *currData, coap_block_t *block, - coap_pdu_t *pdu, uint16_t blockType) + const coap_pdu_t *pdu, uint16_t blockType) { OIC_LOG(DEBUG, TAG, "IN-NegotiateBlockSize"); @@@ -1441,6 -1439,8 +1441,8 @@@ CAResult_t CAAddBlockOption(coap_pdu_t if (!coap_add_data(*pdu, dataLength, (const unsigned char *) info->payload)) { OIC_LOG(INFO, TAG, "it have to use block"); + res = CA_STATUS_FAILED; + goto exit; } else { @@@ -2030,20 -2030,11 +2032,20 @@@ CAData_t* CACreateNewDataSet(const coap // get resource uri information from received response message // to send next request message to remote device - CAResponseInfo_t resInfo = { 0 }; - CAGetResponseInfoFromPDU(pdu, &resInfo, endpoint); + CAResponseInfo_t* resInfo = (CAResponseInfo_t*)OICCalloc(1, sizeof(*resInfo)); + if (!resInfo) + { + OIC_LOG(ERROR, TAG, "memory allocation failed"); + OICFree(requestData.token); + return NULL; + } + CAGetResponseInfoFromPDU(pdu, resInfo, endpoint); requestInfo->method = CA_GET; - requestInfo->info.resourceUri = resInfo.info.resourceUri; + requestInfo->info.resourceUri = OICStrdup(resInfo->info.resourceUri); + + // after copying the resource uri, destroy response info. + CADestroyResponseInfoInternal(resInfo); } CAData_t *data = (CAData_t *) OICCalloc(1, sizeof(CAData_t)); @@@ -2611,33 -2602,6 +2613,33 @@@ CAResult_t CARemoveBlockDataFromList(co return CA_STATUS_OK; } +CAResult_t CARemoveAllBlockDataFromList() +{ + OIC_LOG(DEBUG, TAG, "CARemoveAllBlockDataFromList"); + + ca_mutex_lock(g_context.blockDataListMutex); + + size_t len = u_arraylist_length(g_context.dataList); + for (size_t i = len; i > 0; i--) + { + CABlockData_t *removedData = u_arraylist_remove(g_context.dataList, i - 1); + if (removedData) + { + // destroy memory + if (removedData->sentData) + { + CADestroyDataSet(removedData->sentData); + } + CADestroyBlockID(removedData->blockDataId); + OICFree(removedData->payload); + OICFree(removedData); + } + } + ca_mutex_unlock(g_context.blockDataListMutex); + + return CA_STATUS_OK; +} + void CADestroyDataSet(CAData_t* data) { VERIFY_NON_NULL_VOID(data, TAG, "data"); @@@ -2719,30 -2683,3 +2721,30 @@@ void CALogBlockInfo(coap_block_t *block OIC_LOG_V(DEBUG, TAG, "block option-szx : %d", block->szx); } + +CAResult_t CARemoveBlockDataFromListWithSeed(const CAToken_t token, uint8_t tokenLength, + uint16_t portNumber) +{ + CABlockDataID_t* blockDataID = CACreateBlockDatablockId(token, tokenLength, portNumber); + if (NULL == blockDataID || blockDataID->idLength < 1) + { + OIC_LOG(ERROR, TAG, "blockId is null"); + CADestroyBlockID(blockDataID); + return CA_STATUS_FAILED; + } + + CAResult_t res = CA_STATUS_OK; + + if (NULL != CAGetBlockDataFromBlockDataList(blockDataID)) + { + res = CARemoveBlockDataFromList(blockDataID); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CARemoveBlockDataFromList failed"); + } + } + + CADestroyBlockID(blockDataID); + + return res; +} diff --combined resource/csdk/connectivity/src/cainterfacecontroller.c index 64b3f68,a21f5b5..7ae093c --- a/resource/csdk/connectivity/src/cainterfacecontroller.c +++ b/resource/csdk/connectivity/src/cainterfacecontroller.c @@@ -49,15 -49,15 +49,15 @@@ #define CA_MEMORY_ALLOC_CHECK(arg) {if (arg == NULL) \ {OIC_LOG(ERROR, TAG, "memory error");goto memory_error_exit;} } - - static CAConnectivityHandler_t *g_adapterHandler = NULL; static uint32_t g_numberOfAdapters = 0; static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL; -static CANetworkChangeCallback g_networkChangeCallback = NULL; +static CAAdapterChangeCallback g_adapterChangeCallback = NULL; + +static CAConnectionChangeCallback g_connChangeCallback = NULL; static CAErrorHandleCallback g_errorHandleCallback = NULL; @@@ -124,24 -124,13 +124,24 @@@ static void CAReceivedPacketCallback(co } } -static void CANetworkChangedCallback(const CAEndpoint_t *info, CANetworkStatus_t status) +static void CAAdapterChangedCallback(CATransportAdapter_t adapter, CANetworkStatus_t status) +{ + // Call the callback. + if (g_adapterChangeCallback != NULL) + { + g_adapterChangeCallback(adapter, status); + } + OIC_LOG_V(DEBUG, TAG, "[%d]adapter status is changed to [%d]", adapter, status); +} + +static void CAConnectionChangedCallback(const CAEndpoint_t *info, bool isConnected) { // Call the callback. - if (g_networkChangeCallback != NULL) + if (g_connChangeCallback != NULL) { - g_networkChangeCallback(info, status); + g_connChangeCallback(info, isConnected); } + OIC_LOG_V(DEBUG, TAG, "[%s] connection status is changed to [%d]", info->addr, isConnected); } static void CAAdapterErrorHandleCallback(const CAEndpoint_t *endpoint, @@@ -163,32 -152,32 +163,32 @@@ void CAInitializeAdapters(ca_thread_poo // Initialize adapters and register callback. #ifdef IP_ADAPTER - CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, + CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback, CAAdapterErrorHandleCallback, handle); #endif /* IP_ADAPTER */ #ifdef EDR_ADAPTER - CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, - CAAdapterErrorHandleCallback, handle); + CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback, + CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle); #endif /* EDR_ADAPTER */ #ifdef LE_ADAPTER - CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, - CAAdapterErrorHandleCallback, handle); + CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback, + CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle); #endif /* LE_ADAPTER */ #ifdef RA_ADAPTER - CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, + CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback, handle); #endif /* RA_ADAPTER */ #ifdef TCP_ADAPTER - CAInitializeTCP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, - CAAdapterErrorHandleCallback, handle); + CAInitializeTCP(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback, + CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle); #endif /* TCP_ADAPTER */ #ifdef NFC_ADAPTER - CAInitializeNFC(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, + CAInitializeNFC(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback, CAAdapterErrorHandleCallback, handle); #endif /* NFC_ADAPTER */ } @@@ -200,13 -189,11 +200,13 @@@ void CASetPacketReceivedCallback(CANetw g_networkPacketReceivedCallback = callback; } -void CASetNetworkChangeCallback(CANetworkChangeCallback callback) +void CASetNetworkMonitorCallbacks(CAAdapterChangeCallback adapterCB, + CAConnectionChangeCallback connCB) { - OIC_LOG(DEBUG, TAG, "Set network handle callback"); + OIC_LOG(DEBUG, TAG, "Set network monitoring callback"); - g_networkChangeCallback = callback; + g_adapterChangeCallback = adapterCB; + g_connChangeCallback = connCB; } void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback) @@@ -308,7 -295,10 +308,10 @@@ CAResult_t CAGetNetworkInfo(CAEndpoint_ { return res; } - return CA_STATUS_FAILED; + else + { + return CA_STATUS_FAILED; + } } // #3. add data into result diff --combined resource/csdk/connectivity/src/ip_adapter/caipserver.c index da0375f,c49b064..c64fcb5 --- a/resource/csdk/connectivity/src/ip_adapter/caipserver.c +++ b/resource/csdk/connectivity/src/ip_adapter/caipserver.c @@@ -168,12 -168,6 +168,12 @@@ void CADeInitializeIPGlobals( close(caglobals.ip.m4s.fd); caglobals.ip.m4s.fd = -1; } + + if (caglobals.ip.netlinkFd != -1) + { + close(caglobals.ip.netlinkFd); + caglobals.ip.netlinkFd = -1; + } } static void CAReceiveHandler(void *data) @@@ -250,12 -244,7 +250,12 @@@ static void CASelectReturned(fd_set *re else ISSET(m4s, readFds, CA_MULTICAST | CA_IPV4 | CA_SECURE) else if (FD_ISSET(caglobals.ip.netlinkFd, readFds)) { - CAHandleNetlink(); + CAInterface_t *ifchanged = CAFindInterfaceChange(); + if (ifchanged) + { + CAProcessNewInterface(ifchanged); + OICFree(ifchanged); + } break; } else if (FD_ISSET(caglobals.ip.shutdownFds[0], readFds)) @@@ -266,6 -255,13 +266,6 @@@ { continue; } - - CAInterface_t *ifchanged = CAFindInterfaceChange(); - if (ifchanged) - { - CAProcessNewInterface(ifchanged); - OICFree(ifchanged); - } break; } else @@@ -834,19 -830,65 +834,16 @@@ static void CAProcessNewInterface(CAInt OIC_LOG(DEBUG, TAG, "ifitem is null"); return; } - - applyMulticastToInterface6(ifitem->index); - struct in_addr inaddr = { .s_addr = ifitem->ipv4addr }; - applyMulticastToInterface4(inaddr); -} -static void CAHandleNetlink() -{ -#ifdef __linux__ - char buf[4096]; - struct nlmsghdr *nh; - struct sockaddr_nl sa; - struct iovec iov = { buf, sizeof (buf) }; - struct msghdr msg = { (void *)&sa, sizeof (sa), &iov, 1, NULL, 0, 0 }; - - size_t len = recvmsg(caglobals.ip.netlinkFd, &msg, 0); - - for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) + if (ifitem->family == AF_INET6) { - if (nh != NULL && nh->nlmsg_type != RTM_NEWLINK) - { - continue; - } - - struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(nh); - if (!ifi || (ifi->ifi_flags & IFF_LOOPBACK) || !(ifi->ifi_flags & IFF_RUNNING)) - { - continue; - } - - int newIndex = ifi->ifi_index; - - u_arraylist_t *iflist = CAIPGetInterfaceInformation(newIndex); - if (!iflist) - { - OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno)); - return; - } - - uint32_t listLength = u_arraylist_length(iflist); - for (uint32_t i = 0; i < listLength; i++) - { - CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i); - if (!ifitem) - { - continue; - } - - if ((int)ifitem->index != newIndex) - { - continue; - } - - CAProcessNewInterface(ifitem); - break; // we found the one we were looking for - } - u_arraylist_destroy(iflist); + applyMulticastToInterface6(ifitem->index); + } + if (ifitem->family == AF_INET) + { + struct in_addr inaddr = { .s_addr = ifitem->ipv4addr }; + applyMulticastToInterface4(inaddr); } -#endif // __linux__ } - static void CAHandleNetlink() - { - } void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback) { @@@ -858,11 -900,6 +855,11 @@@ void CAIPSetExceptionCallback(CAIPExcep g_exceptionCallback = callback; } +void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback) +{ + CAIPSetNetworkMonitorCallback(callback); +} + static void sendData(int fd, const CAEndpoint_t *endpoint, const void *data, uint32_t dlen, const char *cast, const char *fam) diff --combined resource/csdk/connectivity/src/tcp_adapter/catcpserver.c index 3d9ef2f,5334502..257c6e0 --- a/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c +++ b/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c @@@ -20,16 -20,17 +20,16 @@@ #include #include +#include #include +#include #include #include -#include #include -#include #include #include #include #include -#include #ifndef WITH_ARDUINO #include @@@ -61,6 -62,11 +61,6 @@@ #define TCP_MAX_HEADER_LEN 6 /** - * Accept server file descriptor. - */ -static int g_acceptServerFD = -1; - -/** * Mutex to synchronize device object list. */ static ca_mutex g_mutexObjectList = NULL; @@@ -83,14 -89,14 +83,14 @@@ static CATCPErrorHandleCallback g_TCPEr /** * Connected Callback to pass the connection information to RI. */ -static CATCPKeepAliveHandleCallback g_keepaliveCallback = NULL; +static CATCPConnectionHandleCallback g_connectionCallback = NULL; static CAResult_t CATCPCreateMutex(); static void CATCPDestroyMutex(); static CAResult_t CATCPCreateCond(); static void CATCPDestroyCond(); -static CAResult_t CACreateAcceptSocket(); -static void CAAcceptConnection(); +static int CACreateAcceptSocket(int family, CASocket_t *sock); +static void CAAcceptConnection(CATransportFlags_t flag, CASocket_t *sock); static void CAFindReadyMessage(); static void CASelectReturned(fd_set *readFds, int ret); static void CAReceiveMessage(int fd); @@@ -172,13 -178,9 +172,13 @@@ static void CAFindReadyMessage( FD_ZERO(&readFds); - if (-1 != g_acceptServerFD) + if (-1 != caglobals.tcp.ipv4.fd) { - FD_SET(g_acceptServerFD, &readFds); + FD_SET(caglobals.tcp.ipv4.fd, &readFds); + } + if (-1 != caglobals.tcp.ipv6.fd) + { + FD_SET(caglobals.tcp.ipv6.fd, &readFds); } if (-1 != caglobals.tcp.shutdownFds[0]) { @@@ -221,33 -223,28 +221,48 @@@ static void CASelectReturned(fd_set *readFds, int ret) { - (void)ret; + VERIFY_NON_NULL_VOID(readFds, TAG, "readFds is NULL"); - if (g_acceptServerFD != -1 && FD_ISSET(g_acceptServerFD, readFds)) + if (caglobals.tcp.ipv4.fd != -1 && FD_ISSET(caglobals.tcp.ipv4.fd, readFds)) + { + CAAcceptConnection(CA_IPV4, &caglobals.tcp.ipv4); + return; + } + else if (caglobals.tcp.ipv6.fd != -1 && FD_ISSET(caglobals.tcp.ipv6.fd, readFds)) + { + CAAcceptConnection(CA_IPV6, &caglobals.tcp.ipv6); + return; + } + else if (-1 != caglobals.tcp.connectionFds[0] && + FD_ISSET(caglobals.tcp.connectionFds[0], readFds)) { - CAAcceptConnection(); + // new connection was created from remote device. + // exit the function to update read file descriptor. + char buf[MAX_ADDR_STR_SIZE_CA] = {0}; + ssize_t len = read(caglobals.tcp.connectionFds[0], buf, sizeof (buf)); + if (-1 == len) + { + return; + } + OIC_LOG_V(DEBUG, TAG, "Received new connection event with [%s]", buf); + FD_CLR(caglobals.tcp.connectionFds[0], readFds); return; } + else if (-1 != caglobals.tcp.connectionFds[0] && + FD_ISSET(caglobals.tcp.connectionFds[0], readFds)) + { + // new connection was created from remote device. + // exit the function to update read file descriptor. + char buf[MAX_ADDR_STR_SIZE_CA] = {0}; + ssize_t len = read(caglobals.tcp.connectionFds[0], buf, sizeof (buf)); + if (-1 == len) + { + return; + } + OIC_LOG_V(DEBUG, TAG, "Received new connection event with [%s]", buf); + FD_CLR(caglobals.tcp.connectionFds[0], readFds); + return; + } else { uint32_t length = u_arraylist_length(caglobals.tcp.svrlist); @@@ -267,14 -264,13 +282,14 @@@ } } -static void CAAcceptConnection() +static void CAAcceptConnection(CATransportFlags_t flag, CASocket_t *sock) { + VERIFY_NON_NULL_VOID(sock, TAG, "sock is NULL"); + struct sockaddr_storage clientaddr; socklen_t clientlen = sizeof (struct sockaddr_in); - int sockfd = accept(g_acceptServerFD, (struct sockaddr *)&clientaddr, - &clientlen); + int sockfd = accept(sock->fd, (struct sockaddr *)&clientaddr, &clientlen); if (-1 != sockfd) { CATCPSessionInfo_t *svritem = @@@ -287,7 -283,6 +302,7 @@@ } svritem->fd = sockfd; + svritem->sep.endpoint.flags = flag; CAConvertAddrToName((struct sockaddr_storage *)&clientaddr, clientlen, (char *) &svritem->sep.endpoint.addr, &svritem->sep.endpoint.port); @@@ -402,171 -397,94 +417,171 @@@ static void CAWakeUpForReadFdsUpdate(co } } +static CAResult_t CATCPConvertNameToAddr(int family, const char *host, uint16_t port, + struct sockaddr_storage *sockaddr) +{ + struct addrinfo *addrs = NULL; + struct addrinfo hints = { .ai_family = family, + .ai_protocol = IPPROTO_TCP, + .ai_socktype = SOCK_STREAM, + .ai_flags = AI_NUMERICHOST }; + + int r = getaddrinfo(host, NULL, &hints, &addrs); + if (r) + { + if (EAI_SYSTEM == r) + { + OIC_LOG_V(ERROR, TAG, "getaddrinfo failed: errno %s", strerror(errno)); + } + else + { + OIC_LOG_V(ERROR, TAG, "getaddrinfo failed: %s", gai_strerror(r)); + } + freeaddrinfo(addrs); + return CA_STATUS_FAILED; + } + // assumption: in this case, getaddrinfo will only return one addrinfo + // or first is the one we want. + if (addrs[0].ai_family == AF_INET6) + { + memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in6)); + ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons(port); + } + else + { + memcpy(sockaddr, addrs[0].ai_addr, sizeof (struct sockaddr_in)); + ((struct sockaddr_in *)sockaddr)->sin_port = htons(port); + } + freeaddrinfo(addrs); + return CA_STATUS_OK; +} + static int CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem) { - // create tcp socket + // #1. create tcp socket. int fd = socket(family, SOCK_STREAM, IPPROTO_TCP); if (-1 == fd) { OIC_LOG_V(ERROR, TAG, "create socket failed: %s", strerror(errno)); - goto exit; + return -1; } + // #2. convert address from string to binary. struct sockaddr_storage sa = { .ss_family = family }; - CAConvertNameToAddr(svritem->sep.endpoint.addr, svritem->sep.endpoint.port, &sa); - socklen_t socklen = sizeof (struct sockaddr_in); + CAResult_t res = CATCPConvertNameToAddr(family, svritem->sep.endpoint.addr, + svritem->sep.endpoint.port, &sa); + if (CA_STATUS_OK != res) + { + close(fd); + return -1; + } - // connect to TCP server - int ret = connect(fd, (struct sockaddr *)&sa, socklen); - if (0 == ret) + // #3. set socket length. + socklen_t socklen; + if (sa.ss_family == AF_INET6) { - OIC_LOG(DEBUG, TAG, "connect socket success"); - CAWakeUpForReadFdsUpdate(svritem->sep.endpoint.addr); + struct sockaddr_in6 *sock6 = (struct sockaddr_in6 *)&sa; + if (!sock6->sin6_scope_id) + { + sock6->sin6_scope_id = svritem->sep.endpoint.interface; + } + socklen = sizeof(struct sockaddr_in6); } else { - OIC_LOG(ERROR, TAG, "failed to connect socket"); - goto exit; + socklen = sizeof(struct sockaddr_in); } - return fd; - -exit: - if (fd >= 0) + // #4. connect to remote server device. + if (connect(fd, (struct sockaddr *)&sa, socklen) < 0) { + OIC_LOG_V(ERROR, TAG, "failed to connect socket, %s", strerror(errno)); close(fd); + return -1; } - return -1; + + OIC_LOG(DEBUG, TAG, "connect socket success"); + CAWakeUpForReadFdsUpdate(svritem->sep.endpoint.addr); + return fd; } -static CAResult_t CACreateAcceptSocket() +static int CACreateAcceptSocket(int family, CASocket_t *sock) { - if (g_acceptServerFD != -1) + VERIFY_NON_NULL_RET(sock, TAG, "sock", -1); + + if (sock->fd != -1) { OIC_LOG(DEBUG, TAG, "accept socket created already"); - return CA_STATUS_OK; + return sock->fd; } - int reuse = 1; - struct sockaddr_in server = { .sin_addr.s_addr = INADDR_ANY, - .sin_family = AF_INET, - .sin_port = htons(SERVER_PORT), - .sin_zero = { 0 } }; + socklen_t socklen; + struct sockaddr_storage server = { .ss_family = family }; - g_acceptServerFD = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (g_acceptServerFD < 0) + int fd = socket(family, SOCK_STREAM, IPPROTO_TCP); + if (fd < 0) { OIC_LOG(ERROR, TAG, "Failed to create socket"); goto exit; } - if (-1 == setsockopt(g_acceptServerFD, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) + if (family == AF_INET6) + { + // the socket is re‐stricted to sending and receiving IPv6 packets only. + int on = 1; + if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on))) + { + OIC_LOG_V(ERROR, TAG, "IPV6_V6ONLY failed: %s", strerror(errno)); + goto exit; + } + ((struct sockaddr_in6 *)&server)->sin6_port = htons(sock->port); + socklen = sizeof (struct sockaddr_in6); + } + else + { + ((struct sockaddr_in *)&server)->sin_port = htons(sock->port); + socklen = sizeof (struct sockaddr_in); + } + + int reuse = 1; + if (-1 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) { OIC_LOG(ERROR, TAG, "setsockopt SO_REUSEADDR"); goto exit; } - int serverlen = sizeof(server); - if (-1 == bind(g_acceptServerFD, (struct sockaddr *)&server, serverlen)) + if (-1 == bind(fd, (struct sockaddr *)&server, socklen)) { - OIC_LOG(ERROR, TAG, "bind() error"); + OIC_LOG_V(ERROR, TAG, "bind socket failed: %s", strerror(errno)); goto exit; } - if (listen(g_acceptServerFD, caglobals.tcp.listenBacklog) != 0) + if (listen(fd, caglobals.tcp.listenBacklog) != 0) { OIC_LOG(ERROR, TAG, "listen() error"); goto exit; } - CHECKFD(g_acceptServerFD); + if (!sock->port) // return the assigned port + { + if (-1 == getsockname(fd, (struct sockaddr *)&server, &socklen)) + { + OIC_LOG_V(ERROR, TAG, "getsockname failed: %s", strerror(errno)); + goto exit; + } + sock->port = ntohs(family == AF_INET6 ? + ((struct sockaddr_in6 *)&server)->sin6_port : + ((struct sockaddr_in *)&server)->sin_port); + } - return CA_STATUS_OK; + return fd; exit: - if (g_acceptServerFD >= 0) + if (fd >= 0) { - close(g_acceptServerFD); - g_acceptServerFD = -1; + close(fd); } - return CA_STATUS_FAILED; + return -1; } static void CAInitializePipe(int *fds) @@@ -611,10 -529,6 +626,10 @@@ CAResult_t CATCPStartServer(const ca_th { caglobals.tcp.ipv4tcpenabled = true; // only needed to run CA tests } + if (!caglobals.tcp.ipv6tcpenabled) + { + caglobals.tcp.ipv6tcpenabled = true; // only needed to run CA tests + } CAResult_t res = CATCPCreateMutex(); if (CA_STATUS_OK == res) @@@ -636,15 -550,12 +651,15 @@@ if (caglobals.server) { - res = CACreateAcceptSocket(); - if (CA_STATUS_OK != res) - { - OIC_LOG(ERROR, TAG, "failed to create accept socket"); - return res; - } + caglobals.tcp.ipv4.fd = CACreateAcceptSocket(AF_INET, &caglobals.tcp.ipv4); + CHECKFD(caglobals.tcp.ipv4.fd); + caglobals.tcp.ipv6.fd = CACreateAcceptSocket(AF_INET6, &caglobals.tcp.ipv6); + CHECKFD(caglobals.tcp.ipv6.fd); + + OIC_LOG_V(DEBUG, TAG, "IPv4 socket fd=%d, port=%d", + caglobals.tcp.ipv4.fd, caglobals.tcp.ipv4.port); + OIC_LOG_V(DEBUG, TAG, "IPv6 socket fd=%d, port=%d", + caglobals.tcp.ipv6.fd, caglobals.tcp.ipv6.port); } // create pipe for fast shutdown @@@ -698,16 -609,10 +713,16 @@@ void CATCPStopServer( // mutex unlock ca_mutex_unlock(g_mutexObjectList); - if (-1 != g_acceptServerFD) + if (-1 != caglobals.tcp.ipv4.fd) { - close(g_acceptServerFD); - g_acceptServerFD = -1; + close(caglobals.tcp.ipv4.fd); + caglobals.tcp.ipv4.fd = -1; + } + + if (-1 != caglobals.tcp.ipv6.fd) + { + close(caglobals.tcp.ipv6.fd); + caglobals.tcp.ipv6.fd = -1; } CATCPDisconnectAll(); @@@ -720,9 -625,9 +735,9 @@@ void CATCPSetPacketReceiveCallback(CATC g_packetReceivedCallback = callback; } -void CATCPSetKeepAliveCallback(CATCPKeepAliveHandleCallback keepaliveHandler) +void CATCPSetConnectionChangedCallback(CATCPConnectionHandleCallback connHandler) { - g_keepaliveCallback = keepaliveHandler; + g_connectionCallback = connHandler; } static size_t CACheckPayloadLength(const void *data, size_t dlen) @@@ -761,8 -666,8 +776,8 @@@ return payloadLen; } -static void sendData(const CAEndpoint_t *endpoint, - const void *data, size_t dlen) +static void sendData(const CAEndpoint_t *endpoint, const void *data, + size_t dlen, const char *fam) { // #1. get TCP Server object from list size_t index = 0; @@@ -818,7 -723,7 +833,7 @@@ remainLen -= len; } while (remainLen > 0); - OIC_LOG_V(INFO, TAG, "unicast ipv4tcp sendTo is successful: %zu bytes", dlen); + OIC_LOG_V(INFO, TAG, "unicast %stcp sendTo is successful: %zu bytes", fam, dlen); } void CATCPSendData(CAEndpoint_t *endpoint, const void *data, uint32_t datalen, @@@ -829,13 -734,9 +844,13 @@@ if (!isMulticast) { - if (caglobals.tcp.ipv4tcpenabled && (endpoint->adapter & CA_ADAPTER_TCP)) + if (caglobals.tcp.ipv6tcpenabled && (endpoint->flags & CA_IPV6)) + { + sendData(endpoint, data, datalen, "ipv6"); + } + if (caglobals.tcp.ipv4tcpenabled && (endpoint->flags & CA_IPV4)) { - sendData(endpoint, data, datalen); + sendData(endpoint, data, datalen, "ipv4"); } } } @@@ -861,41 -762,41 +876,41 @@@ CATCPSessionInfo_t *CAConnectTCPSession } memcpy(svritem->sep.endpoint.addr, endpoint->addr, sizeof(svritem->sep.endpoint.addr)); svritem->sep.endpoint.port = endpoint->port; + svritem->sep.endpoint.flags = endpoint->flags; + svritem->sep.endpoint.interface = endpoint->interface; // #2. create the socket and connect to TCP server - if (caglobals.tcp.ipv4tcpenabled) + int family = (svritem->sep.endpoint.flags & CA_IPV6) ? AF_INET6 : AF_INET; + int fd = CATCPCreateSocket(family, svritem); + if (-1 == fd) { - int fd = CATCPCreateSocket(AF_INET, svritem); - if (-1 == fd) + OICFree(svritem); + return NULL; + } + + // #3. add TCP connection info to list + svritem->fd = fd; + ca_mutex_lock(g_mutexObjectList); + if (caglobals.tcp.svrlist) + { + bool res = u_arraylist_add(caglobals.tcp.svrlist, svritem); + if (!res) { + OIC_LOG(ERROR, TAG, "u_arraylist_add failed."); + close(svritem->fd); OICFree(svritem); + ca_mutex_unlock(g_mutexObjectList); return NULL; } + } + ca_mutex_unlock(g_mutexObjectList); - // #3. add TCP connection info to list - svritem->fd = fd; - ca_mutex_lock(g_mutexObjectList); - if (caglobals.tcp.svrlist) - { - bool res = u_arraylist_add(caglobals.tcp.svrlist, svritem); - if (!res) - { - OIC_LOG(ERROR, TAG, "u_arraylist_add failed."); - close(svritem->fd); - OICFree(svritem); - ca_mutex_unlock(g_mutexObjectList); - return NULL; - } - } - ca_mutex_unlock(g_mutexObjectList); - - CHECKFD(fd); + CHECKFD(fd); - // pass the connection information to RI for keepalive. - if (g_keepaliveCallback) - { - g_keepaliveCallback(svritem->sep.endpoint.addr, svritem->sep.endpoint.port, true); - } + // pass the connection information to CA Common Layer. + if (g_connectionCallback) + { + g_connectionCallback(svritem->sep.endpoint.addr, svritem->sep.endpoint.port, true); } return svritem; @@@ -914,16 -815,15 +929,16 @@@ CAResult_t CADisconnectTCPSession(CATCP } u_arraylist_remove(caglobals.tcp.svrlist, index); OICFree(svritem->recvData); - OICFree(svritem); - ca_mutex_unlock(g_mutexObjectList); - // pass the connection information to RI for keepalive. - if (g_keepaliveCallback) + // pass the connection information to CA Common Layer. + if (g_connectionCallback) { - g_keepaliveCallback(svritem->sep.endpoint.addr, svritem->sep.endpoint.port, false); + g_connectionCallback(svritem->sep.endpoint.addr, svritem->sep.endpoint.port, false); } + OICFree(svritem); + ca_mutex_unlock(g_mutexObjectList); + return CA_STATUS_OK; } @@@ -947,7 -847,8 +962,7 @@@ void CATCPDisconnectAll( ca_mutex_unlock(g_mutexObjectList); } -CATCPSessionInfo_t *CAGetTCPSessionInfoFromEndpoint(const CAEndpoint_t *endpoint, - size_t *index) +CATCPSessionInfo_t *CAGetTCPSessionInfoFromEndpoint(const CAEndpoint_t *endpoint, size_t *index) { VERIFY_NON_NULL_RET(endpoint, TAG, "endpoint is NULL", NULL); VERIFY_NON_NULL_RET(index, TAG, "index is NULL", NULL); @@@ -965,8 -866,7 +980,8 @@@ if (!strncmp(svritem->sep.endpoint.addr, endpoint->addr, sizeof(svritem->sep.endpoint.addr)) - && (svritem->sep.endpoint.port == endpoint->port)) + && (svritem->sep.endpoint.port == endpoint->port) + && (svritem->sep.endpoint.flags & endpoint->flags)) { *index = i; return svritem; diff --combined resource/csdk/logger/src/logger.c index 3ea4e64,295ac5f..cc30d58 --- a/resource/csdk/logger/src/logger.c +++ b/resource/csdk/logger/src/logger.c @@@ -78,6 -78,7 +78,7 @@@ static const uint16_t LINE_BUFFER_SIZE #elif defined ARDUINO #include #include "Arduino.h" + #include "oic_string.h" PROGMEM const char level0[] = "DEBUG"; PROGMEM const char level1[] = "INFO"; @@@ -90,57 -91,17 +91,57 @@@ static void OCLogString(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logStr); #ifdef ARDUINO_ARCH_AVR //Mega2560 and other 8-bit AVR microcontrollers - #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_word(addr));} + #define GET_PROGMEM_BUFFER(buffer, addr) { OICStrcpy(buffer, sizeof(buffer), (char*)pgm_read_word(addr));} #elif defined ARDUINO_ARCH_SAM //Arduino Due and other 32-bit ARM micro-controllers - #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_dword(addr));} + #define GET_PROGMEM_BUFFER(buffer, addr) { OICStrcpy(buffer, sizeof(buffer), (char*)pgm_read_dword(addr));} #else #define GET_PROGMEM_BUFFER(buffer, addr) { buffer[0] = '\0';} #endif #endif // __ANDROID__ - #ifndef ARDUINO + +/** + * Output the contents of the specified buffer (in hex) with the specified priority level. + * + * @param level - DEBUG, INFO, WARNING, ERROR, FATAL + * @param tag - Module name + * @param buffer - pointer to buffer of bytes + * @param bufferSize - max number of byte in buffer + */ +void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize) +{ + if (!buffer || !tag || (bufferSize == 0)) + { + return; + } + + // No idea why the static initialization won't work here, it seems the compiler is convinced + // that this is a variable-sized object. + char lineBuffer[LINE_BUFFER_SIZE]; + memset(lineBuffer, 0, sizeof lineBuffer); + int lineIndex = 0; + int i; + for (i = 0; i < bufferSize; i++) + { + // Format the buffer data into a line + snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]); + lineIndex++; + // Output 16 values per line + if (((i+1)%16) == 0) + { + OCLogv(level, tag, "%s", lineBuffer); + memset(lineBuffer, 0, sizeof lineBuffer); + lineIndex = 0; + } + } + // Output last values in the line, if any + if (bufferSize % 16) + { + OCLogv(level, tag, "%s", lineBuffer); + } +} #ifndef __TIZEN__ void OCLogConfig(oc_log_ctx_t *ctx) { @@@ -242,6 -203,47 +243,6 @@@ void OCLog(LogLevel level, const char } #endif } - -/** - * Output the contents of the specified buffer (in hex) with the specified priority level. - * - * @param level - DEBUG, INFO, WARNING, ERROR, FATAL - * @param tag - Module name - * @param buffer - pointer to buffer of bytes - * @param bufferSize - max number of byte in buffer - */ -void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize) -{ - if (!buffer || !tag || (bufferSize == 0)) - { - return; - } - - // No idea why the static initialization won't work here, it seems the compiler is convinced - // that this is a variable-sized object. - char lineBuffer[LINE_BUFFER_SIZE]; - memset(lineBuffer, 0, sizeof lineBuffer); - int lineIndex = 0; - int i; - for (i = 0; i < bufferSize; i++) - { - // Format the buffer data into a line - snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]); - lineIndex++; - // Output 16 values per line - if (((i+1)%16) == 0) - { - OCLog(level, tag, lineBuffer); - memset(lineBuffer, 0, sizeof lineBuffer); - lineIndex = 0; - } - } - // Output last values in the line, if any - if (bufferSize % 16) - { - OCLog(level, tag, lineBuffer); - } -} #endif //__TIZEN__ #endif //ARDUINO #ifdef ARDUINO diff --combined resource/csdk/security/include/internal/amsmgr.h index 9604ff2,e07b442..de5a9cc --- a/resource/csdk/security/include/internal/amsmgr.h +++ b/resource/csdk/security/include/internal/amsmgr.h @@@ -21,17 -21,18 +21,18 @@@ #ifndef IOTVT_SRM_AMSMGR_H #define IOTVT_SRM_AMSMGR_H + #include + #include + #include "ocstack.h" #include "logger.h" #include "policyengine.h" #include "securevirtualresourcetypes.h" #include "cainterface.h" - #include - #include typedef struct PEContext PEContext_t; /** - * @brief The AMS context.. + * The AMS context. */ typedef struct AmsMgrContext { @@@ -40,95 -41,95 +41,88 @@@ CARequestInfo_t *requestInfo; } AmsMgrContext_t; - /** - * @brief This method updates AmsMgr context's endpoint & requestInfo + * This method updates AmsMgr context's endpoint & requestInfo. + * + * @param context is the policy engine context. + * @param endpoint is the CA Endpoint info of the requester. + * @param requestInfo is the CA RequestInfo of the requester. * - * @param context Policy engine context. - * @param endpoint CA Endpoint info of the requester - * @param requestInfo CA RequestInfo of the requester + * @return ::OC_STACK_OK if successful, else other value in case of error. */ - OCStackResult UpdateAmsMgrContext(PEContext_t *context, const CAEndpoint_t *endpoint, - const CARequestInfo_t *requestInfo); + OCStackResult UpdateAmsMgrContext(PEContext_t *context, + const CAEndpoint_t *endpoint, + const CARequestInfo_t *requestInfo); /** - * * This method is called by PolicyEngine to Discover AMS service. * It sends muticast discovery request such as * /oic/sec/doxm?deviceid="AMSSrvcDeviceID" to discover AMS service - * with deviceId="AMSSrvcDeviceID" - * - * @param context Policy engine context. + * with deviceId="AMSSrvcDeviceID". * - * @retval - * OC_STACK_OK If able to successfully send multicast discovery request. - * OC_STACK_ERROR If unable to successfully send multicast discovery request due to error. + * @param context is the policy engine context. * + * @return ::OC_STACK_OK,If able to successfully send multicast discovery request. + * else ::OC_STACK_ERROR, If unable to successfully send multicast discovery request + * due to error. */ OCStackResult DiscoverAmsService(PEContext_t *context); - /** - * * This method sends unicast request to retrieve the secured port info of the * discovered AMS service. It sends unicast discovery request such as - * /oic/res?rt="oic.sec.doxm" to the discovered AMS service - * - * @param context Policy engine context. + * /oic/res?rt="oic.sec.doxm" to the discovered AMS service. * - * @retval - * OC_STACK_OK If able to successfully send unicast discovery request - * OC_STACK_ERROR If unable to successfully send unicast discovery request due to error + * @param context is the policy engine context. * + * @return ::OC_STACK_OK,If able to successfully send unicast discovery request. + * else ::OC_STACK_ERROR, If unable to successfully send unicast discovery request + * due to error. */ - OCStackResult SendUnicastSecurePortDiscovery(PEContext_t *context,OCDevAddr *devAddr, - OCConnectivityType connType); - + OCStackResult SendUnicastSecurePortDiscovery(PEContext_t *context, + OCDevAddr *devAddr, + OCConnectivityType connType); /** - * * This method sends unicast request to AMS service to get ACL for * the Subject and/or Resource. It sends unicast request such as * /oic/sec/acl?sub="subjectId";rsrc="/a/led" to get the ACL for - * the subject & resource + * the subject & resource. * - * @param context Policy engine context. + * @param context is the policy engine context. * - * @retval - * OC_STACK_OK If able to successfully send unicast ACL request - * OC_STACK_ERROR If unable to successfully send unicast ACL request due to error + * @return ::OC_STACK_OK, If able to successfully send unicast ACL request. + * ::OC_STACK_ERROR, If unable to successfully send unicast ACL request due to error. * */ - OCStackResult SendAclReq(PEContext_t *context, OCDevAddr *devAddr, OCConnectivityType connType, - uint16_t securedPort); + OCStackResult SendAclReq(PEContext_t *context, + OCDevAddr *devAddr, + OCConnectivityType connType, + uint16_t securedPort); /* - * Cleanup CARequestInfo_t object. - * - * @param requestInfo is the pointer to @ref CARequestInfo_t. - */ -void FreeCARequestInfo(CARequestInfo_t *requestInfo); - -/* * This method is used by Policy engine to checks Amacl resource. * If Amacl is found then it fills up context->amsMgrContext->amsDeviceId * with amsID of the Amacl else leaves it empty. * - * @param context Policy engine context. + * @param context is the policy engine context. * - * @return true if AMacl for the resource is found - * false if AMacl for the resource is not found + * @return true, if Amacl for the resource is found. false, if Amacl for the + * resource is not found */ bool FoundAmaclForRequest(PEContext_t *context); - /* - * This method is used by Policy engine to process AMS request - * - * @param context Policy engine context. + * This method is used by Policy engine to process AMS request. * + * @param context is the policy engine context. */ void ProcessAMSRequest(PEContext_t *context); - /* - * This method is used by Policy engine to free AMS context requestInfo - * - * @param requestInfo pointer to CARequestInfo_t. + * This method is used by Policy engine to free AMS context requestInfo/ * + * @param requestInfo is the pointer to @ref CARequestInfo_t. */ void FreeCARequestInfo(CARequestInfo_t *requestInfo); diff --combined resource/csdk/security/provisioning/include/internal/secureresourceprovider.h index df55c0b,cc1f689..c6769e8 --- a/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h +++ b/resource/csdk/security/provisioning/include/internal/secureresourceprovider.h @@@ -41,17 -41,30 +41,42 @@@ extern "C */ OCStackResult SRPProvisionACL(void *ctx, const OCProvisionDev_t *selectedDeviceInfo, OicSecAcl_t *acl, OCProvisionResultCB resultCallback); + + #ifdef __WITH_X509__ + /** + * API to send CRL information to resource. + * + * @param[in] selectedDeviceInfo Selected target device. + * @param[in] crl CRL to provision. + * @param[in] resultCallback callback provided by API user, callback will be called when + * provisioning request recieves a response from resource server. + * @return OC_STACK_OK in case of success and other value otherwise. + */ + OCStackResult SRPProvisionCRL(void *ctx, const OCProvisionDev_t *selectedDeviceInfo, + OicSecCrl_t *crl, OCProvisionResultCB resultCallback); + #endif // __WITH_X509__ + /** + * API to send Direct-Pairing Configuration to a device. + * + * @param[in] selectedDeviceInfo Selected target device. + * @param[in] pconf PCONF pointer. + * @param[in] resultCallback callback provided by API user, callback will be called when + * provisioning request recieves a response from resource server. + * @return OC_STACK_OK in case of success and other value otherwise. + */ + OCStackResult SRPProvisionDirectPairing(void *ctx, const OCProvisionDev_t *selectedDeviceInfo, ++ OicSecPconf_t *pconf, OCProvisionResultCB resultCallback); + +/** + * API to send Direct-Pairing Configuration to a device. + * + * @param[in] selectedDeviceInfo Selected target device. + * @param[in] pconf PCONF pointer. + * @param[in] resultCallback callback provided by API user, callback will be called when + * provisioning request recieves a response from resource server. + * @return OC_STACK_OK in case of success and other value otherwise. + */ +OCStackResult SRPProvisionDirectPairing(void *ctx, const OCProvisionDev_t *selectedDeviceInfo, OicSecPconf_t *pconf, OCProvisionResultCB resultCallback); /** diff --combined resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.json index 8dc08f6,59b56a7..59b56a7 mode 100755,100644..100755 --- a/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.json +++ b/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.json @@@ -1,58 -1,128 +1,128 @@@ - { - "acl": [ - { - "sub": "Kg==", - "rsrc": [ - "/oic/res", - "/oic/res/d", - "/oic/res/types/d", - "/oic/presence" - ], - "perms": 2, - "ownrs" : [ - "anVzdHdvcmtzRGV2VVVJRA==" - ] - }, - { - "sub": "Kg==", - "rsrc": [ - "/oic/sec/doxm", - "/oic/sec/pstat", - "/oic/sec/acl", - "/oic/sec/cred" - ], - "perms": 6, - "ownrs" : [ - "anVzdHdvcmtzRGV2VVVJRA==" - ] - }, - { - "sub": "Kg==", - "rsrc": [ - "/oic/sec/pconf", - "/oic/sec/dpairing" - ], - "perms": 6, - "ownrs" : [ - "anVzdHdvcmtzRGV2VVVJRA==" - ] - } - ], - "pstat": { - "isop": false, - "deviceid": "anVzdHdvcmtzRGV2VVVJRA==", - "commithash": 0, - "cm": 0, - "tm": 0, - "om": 3, - "sm": [3] - }, - "doxm": { - "oxm": [0], - "oxmsel": 0, - "sct": 1, - "owned": false, - "deviceid": "anVzdHdvcmtzRGV2VVVJRA==", - "dpc": true - } - } + { + "acl": { + "aclist": { + "aces": [ + { + "subjectuuid": "*", + "resources": [ + { + "href": "/oic/res", + "rel": "", + "rt": "", + "if": "" + },{ + "href": "/oic/d", + "rel": "", + "rt": "", + "if": "" + },{ + "href": "/oic/p", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/res/d", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/res/types/d", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/presence", + "rel": "", + "rt": "", + "if": "" + } + ], + "permission": 2 + }, + { + "subjectuuid": "*", + "resources": [ + { + "href": "/oic/sec/doxm", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/sec/pstat", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/sec/acl", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/sec/cred", + "rel": "", + "rt": "", + "if": "" + } + ], + "permission": 6 + }, + { + "subjectuuid": "*", + "resources": [ + { + "href": "/oic/sec/pconf", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/sec/dpairing", + "rel": "", + "rt": "", + "if": "" + } + ], + "permission": 6 + }, + { + "subjectuuid": "*", + "resources": [ + { + "href": "/oic/sec/ver", + "rel": "", + "rt": "", + "if": "" + } + ], + "permission": 2 + } + ] + }, + "rowneruuid" : "6A757374-776F-726B-4465-765575696430" + }, + "pstat": { + "isop": false, + "deviceuuid": "6A757374-776F-726B-4465-765575696430", + "rowneruuid": "6A757374-776F-726B-4465-765575696430", + "cm": 2, + "tm": 0, + "om": 3, + "sm": 3 + }, + "doxm": { + "oxms": [0], + "oxmsel": 0, + "sct": 1, + "owned": false, + "deviceuuid": "6A757374-776F-726B-4465-765575696430", + "devowneruuid": "", + "rowneruuid": "6A757374-776F-726B-4465-765575696430", + "dpc": true + } + } diff --combined resource/csdk/security/src/amsmgr.c index b43b69c,9486f90..4ead7a3 --- a/resource/csdk/security/src/amsmgr.c +++ b/resource/csdk/security/src/amsmgr.c @@@ -18,6 -18,7 +18,7 @@@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + #include #include "oic_malloc.h" #include "amsmgr.h" #include "resourcemanager.h" @@@ -34,11 -35,9 +35,9 @@@ #include "policyengine.h" #include "oic_string.h" #include "caremotehandler.h" - #include #define TAG "SRM-AMSMGR" - //Callback for AMS service multicast discovery request. static OCStackApplicationResult AmsMgrDiscoveryCallback(void *ctx, OCDoHandle handle, OCClientResponse * clientResponse); @@@ -51,7 -50,6 +50,6 @@@ static OCStackApplicationResult SecureP static OCStackApplicationResult AmsMgrAclReqCallback(void *ctx, OCDoHandle handle, OCClientResponse * clientResponse); - OCStackResult DiscoverAmsService(PEContext_t *context) { OIC_LOG(INFO, TAG, "IN DiscoverAmsService"); @@@ -60,16 -58,11 +58,11 @@@ const char DOXM_DEVICEID_QUERY_FMT[] = "%s?%s=%s"; char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {}; OCCallbackData cbData = {.context=NULL}; - char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {}; - uint32_t outLen = 0; - B64Result b64Ret; VERIFY_NON_NULL(TAG, context, ERROR); - b64Ret = b64Encode(context->amsMgrContext->amsDeviceId.id, - sizeof(context->amsMgrContext->amsDeviceId.id), base64Buff, sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR); snprintf(uri, sizeof(uri), DOXM_DEVICEID_QUERY_FMT, OIC_RSRC_DOXM_URI, - OIC_JSON_DEVICE_ID_NAME, base64Buff); + OIC_JSON_DEVICE_ID_NAME, + context->amsMgrContext->amsDeviceId.id); cbData.cb = &AmsMgrDiscoveryCallback; cbData.context = (void*)context; @@@ -89,7 -82,6 +82,6 @@@ exit return ret; } - static OCStackApplicationResult AmsMgrDiscoveryCallback(void *ctx, OCDoHandle handle, OCClientResponse * clientResponse) { @@@ -114,15 -106,17 +106,17 @@@ } OicSecDoxm_t *doxm = NULL; + OIC_LOG_V(INFO, TAG, "Doxm DeviceId Discovery response = %s\n", ((OCSecurityPayload*)clientResponse->payload)->securityData); - doxm = JSONToDoxmBin(((OCSecurityPayload*)clientResponse->payload)->securityData); + uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData; + size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize; //As doxm is NULL amsmgr can't test if response from trusted AMS service //so keep the transaction. - if(NULL == doxm) + if (OC_STACK_OK == CBORPayloadToDoxm(payload, size, &doxm)) { - OIC_LOG_V(ERROR, TAG, "%s : Unable to convert JSON to Binary",__func__); + OIC_LOG_V(ERROR, TAG, "%s : Unable to convert CBOR to Binary",__func__); return OC_STACK_KEEP_TRANSACTION; } @@@ -138,7 -132,7 +132,7 @@@ { OIC_LOG(INFO, TAG, "AMS Manager Sending unicast discovery to get secured port info"); //Sending Unicast discovery to get secure port information - if(OC_STACK_OK == SendUnicastSecurePortDiscovery(context, &clientResponse->devAddr, + if (OC_STACK_OK == SendUnicastSecurePortDiscovery(context, &clientResponse->devAddr, clientResponse->connType)) { context->retVal = ACCESS_WAITING_FOR_AMS; @@@ -150,7 -144,6 +144,6 @@@ return OC_STACK_DELETE_TRANSACTION; } - OCStackResult SendUnicastSecurePortDiscovery(PEContext_t *context,OCDevAddr *devAddr, OCConnectivityType connType) { @@@ -198,7 -191,7 +191,7 @@@ static OCStackApplicationResult SecureP return OC_STACK_DELETE_TRANSACTION; } - OCResourcePayload* resPayload = ((OCDiscoveryPayload*)clientResponse->payload)->resources; + OCResourcePayload *resPayload = ((OCDiscoveryPayload*)clientResponse->payload)->resources; //Verifying if the ID of the sender is an AMS service that this device trusts. if(resPayload && @@@ -228,7 -221,6 +221,6 @@@ return OC_STACK_DELETE_TRANSACTION; } - OCStackResult SendAclReq(PEContext_t *context, OCDevAddr *devAddr, OCConnectivityType connType, uint16_t securedPort) { @@@ -240,17 -232,22 +232,22 @@@ OCCallbackData cbData = {.context=NULL}; OCDevAddr destAddr = {.adapter = OC_ADAPTER_IP}; B64Result b64Ret; + char *subID = NULL; VERIFY_NON_NULL(TAG, context, ERROR); VERIFY_NON_NULL(TAG, devAddr, ERROR); - b64Ret = b64Encode(context->subject.id, sizeof(context->subject.id), - base64Buff, sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR); + ret = ConvertUuidToStr(&context->subject, &subID); + if(OC_STACK_OK != ret) + { + OIC_LOG(ERROR, TAG, "SendAclReq : Failed to canonical UUID encoding"); + return OC_STACK_ERROR; + } snprintf(uri, sizeof(uri), GET_ACE_QUERY_FMT, OIC_RSRC_ACL_URI, - OIC_JSON_SUBJECT_NAME, base64Buff, + OIC_JSON_SUBJECTID_NAME, subID, OIC_JSON_RESOURCES_NAME, context->resource); + OICFree(subID); cbData.cb = &AmsMgrAclReqCallback; cbData.context = context; @@@ -269,7 -266,6 +266,6 @@@ exit return ret; } - static OCStackApplicationResult AmsMgrAclReqCallback(void *ctx, OCDoHandle handle, OCClientResponse * clientResponse) { @@@ -305,8 -301,9 +301,9 @@@ memcmp(context->amsMgrContext->amsDeviceId.id, clientResponse->identity.id, sizeof(context->amsMgrContext->amsDeviceId.id)) == 0) { + size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize; OCStackResult ret = - InstallNewACL(((OCSecurityPayload*)clientResponse->payload)->securityData); + InstallNewACL(((OCSecurityPayload*)clientResponse->payload)->securityData, size); VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR); OIC_LOG_V(INFO, TAG, "%s : Calling checkPermission", __func__); @@@ -325,20 -322,14 +322,19 @@@ exit return OC_STACK_DELETE_TRANSACTION; } - OCStackResult UpdateAmsMgrContext(PEContext_t *context, const CAEndpoint_t *endpoint, const CARequestInfo_t *requestInfo) { OCStackResult ret = OC_STACK_ERROR; + if (!context->amsMgrContext) + { + goto exit; + } + //The AmsMgr context endpoint and requestInfo will be free from , //AmsMgrAclReqCallback function - if(context->amsMgrContext->endpoint) + if (context->amsMgrContext->endpoint) { OICFree(context->amsMgrContext->endpoint); context->amsMgrContext->endpoint = NULL; @@@ -347,7 -338,7 +343,7 @@@ VERIFY_NON_NULL(TAG, context->amsMgrContext->endpoint, ERROR); *context->amsMgrContext->endpoint = *endpoint; - if(context->amsMgrContext->requestInfo) + if (context->amsMgrContext->requestInfo) { FreeCARequestInfo(context->amsMgrContext->requestInfo); context->amsMgrContext->requestInfo = NULL; @@@ -363,7 -354,7 +359,7 @@@ void FreeCARequestInfo(CARequestInfo_t { if (NULL == requestInfo) { - OIC_LOG_V(ERROR, TAG, "%s: Can't free memory. Received NULL requestInfo", __func__); + OIC_LOG_V(DEBUG, TAG, "%s: Can't free memory. Received NULL requestInfo", __func__); return; } OICFree(requestInfo->info.token); @@@ -385,7 -376,7 +381,7 @@@ bool FoundAmaclForRequest(PEContext_t * memset(&context->amsMgrContext->amsDeviceId, 0, sizeof(context->amsMgrContext->amsDeviceId)); //Call amacl resource function to get the AMS service deviceID for the resource - if(OC_STACK_OK == AmaclGetAmsDeviceId(context->resource, &context->amsMgrContext->amsDeviceId)) + if (OC_STACK_OK == AmaclGetAmsDeviceId(context->resource, &context->amsMgrContext->amsDeviceId)) { OIC_LOG_V(INFO, TAG, "%s:AMACL found for the requested resource %s", __func__, context->resource); @@@ -402,12 -393,11 +398,11 @@@ return ret; } - void ProcessAMSRequest(PEContext_t *context) { OicUuid_t emptyUuid = {.id={}}; OIC_LOG_V(INFO, TAG, "Entering %s", __func__); - if(NULL != context) + if (NULL != context) { if((false == context->matchingAclFound) && (false == context->amsProcessing)) { diff --combined resource/csdk/security/src/dpairingresource.c index ca01c1d,0c5c03f..0c5c03f mode 100755,100644..100755 --- a/resource/csdk/security/src/dpairingresource.c +++ b/resource/csdk/security/src/dpairingresource.c @@@ -1,668 -1,762 +1,762 @@@ - /* ***************************************************************** - * - * Copyright 2016 Samsung Electronics All Rights Reserved. - * - * - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * *****************************************************************/ - - #include - #include - #include "ocstack.h" - #include "logger.h" - #include "oic_malloc.h" - #include "oic_string.h" - #include "cJSON.h" - #include "base64.h" - #include "resourcemanager.h" - #include "dpairingresource.h" - #include "psinterface.h" - #include "utlist.h" - #include "srmresourcestrings.h" - #include "cainterface.h" - #include "doxmresource.h" - #include "pconfresource.h" - #include "credresource.h" - #include "aclresource.h" - #include "srmutility.h" - #include "ocserverrequest.h" - #include - #ifdef WITH_ARDUINO - #include - #else - #include - #endif - - #ifdef __WITH_DTLS__ - #include "global.h" - #endif - - #define TAG "SRM-DPAIRING" - - - static OicSecDpairing_t *gDpair = NULL; - static OCResourceHandle gDpairHandle = NULL; - static OicSecDpairing_t gDefaultDpair = - { - PRM_NOT_ALLOWED, /* OicSecPrm_t spm */ - {.id = {0}}, /* OicUuid_t pdeviceID */ - {.id = {0}}, /* OicUuid_t rowner */ - }; - - void DeleteDpairingBinData(OicSecDpairing_t* dpair) - { - if (dpair) - { - //Clean dpairing itself - OICFree(dpair); - } - } - - /** - * Get the default value. - * @retval the gDefaultDpair pointer; - */ - static OicSecDpairing_t* GetDpairingDefault() - { - OIC_LOG (DEBUG, TAG, "GetDpairingDefault"); - - return &gDefaultDpair; - } - - /** - * This method is used by SRM to retrieve Dpairing resource data.. - */ - void SetDpairingResourceOwner(OicUuid_t *rowner) - { - OIC_LOG (DEBUG, TAG, "SetDpairingResourceOwner"); - if (gDpair) - { - memcpy(&gDpair->rowner, rowner, sizeof(OicUuid_t)); - } - } - - #ifdef __WITH_DTLS__ - /** - * Function to save PairingPSK. - * - * @param[in] endpoint current endpoint. - * @param[in] peerDevID peer device indentitiy. - * @param[in] isPairingServer indicate if it generates PairingPSK for server or client. - * - * @return OC_STACK_OK on success - */ - OCStackResult SavePairingPSK(OCDevAddr *endpoint, - OicUuid_t *peerDevID, OicUuid_t *owner, bool isPairingServer) - { - OIC_LOG(DEBUG, TAG, "IN SavePairingPSK"); - - if(NULL == endpoint || NULL == peerDevID || NULL == owner) - { - OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__); - return OC_STACK_INVALID_PARAM; - } - - OCStackResult res = OC_STACK_ERROR; - - OicUuid_t ptDeviceID = {.id={0}}; - if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID)) - { - OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID"); - return res; - } - - uint8_t pairingPSK[OWNER_PSK_LENGTH_128] = {0}; - - //Generating PairingPSK using OwnerPSK scheme - CAResult_t pskRet = CAGenerateOwnerPSK((const CAEndpoint_t *)endpoint, - (uint8_t *)OIC_RSRC_TYPE_SEC_DPAIRING, - strlen(OIC_RSRC_TYPE_SEC_DPAIRING), - (isPairingServer ? ptDeviceID.id : peerDevID->id), sizeof(OicUuid_t), // server - (isPairingServer ? peerDevID->id : ptDeviceID.id), sizeof(OicUuid_t), // client - pairingPSK, OWNER_PSK_LENGTH_128); - - if (CA_STATUS_OK == pskRet) - { - OIC_LOG(INFO, TAG, "pairingPSK dump:\n"); - OIC_LOG_BUFFER(INFO, TAG, pairingPSK, OWNER_PSK_LENGTH_128); - //Generating new credential for direct-pairing client - size_t ownLen = 1; - uint32_t outLen = 0; - - char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(pairingPSK)) + 1] = {}; - B64Result b64Ret = b64Encode(pairingPSK, sizeof(pairingPSK), base64Buff, sizeof(base64Buff), - &outLen); - VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR); - - OicSecCred_t *cred = GenerateCredential(peerDevID, - SYMMETRIC_PAIR_WISE_KEY, NULL, - base64Buff, ownLen, owner); - VERIFY_NON_NULL(TAG, cred, ERROR); - - res = AddCredential(cred); - if(res != OC_STACK_OK) - { - DeleteCredList(cred); - return res; - } - } - else - { - OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed"); - } - - OIC_LOG(DEBUG, TAG, "OUT SavePairingPSK"); - exit: - return res; - } - #endif // __WITH_DTLS__ - - /* - * This internal method converts DPairing data into JSON format. - * Does not error-check here, but check it in caller - * - * Note: Caller needs to invoke 'free' when finished done using - * return string. - */ - char * BinToDpairingJSON(const OicSecDpairing_t * dpair) - { - OIC_LOG(DEBUG, TAG, "BinToDpairingJSON() IN"); - - if (NULL == dpair) - { - return NULL; - } - - char *jsonStr = NULL; - cJSON *jsonDpair = NULL; - char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {}; - uint32_t outLen = 0; - B64Result b64Ret = B64_OK; - - cJSON *jsonRoot = cJSON_CreateObject(); - VERIFY_NON_NULL(TAG, jsonRoot, ERROR); - - jsonDpair = cJSON_CreateObject(); - VERIFY_NON_NULL(TAG, jsonDpair, ERROR); - cJSON_AddItemToObject(jsonRoot, OIC_JSON_DPAIRING_NAME, jsonDpair ); - - //SPM -- Mandatory - if(PRM_RANDOM_PIN >= dpair->spm) // don't need to check "PRM_NOT_ALLOWED <= dpair->spm" because of always true - { - cJSON_AddNumberToObject(jsonDpair, OIC_JSON_SPM_NAME, (int)dpair->spm); - } - - //PDeviceID -- Mandatory - //There may not be paired devices if it did not be received pairing request - if ('\0' != (char)dpair->pdeviceID.id[0]) - { - outLen = 0; - b64Ret = b64Encode(dpair->pdeviceID.id, sizeof(dpair->pdeviceID.id), base64Buff, - sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); - cJSON_AddStringToObject(jsonDpair, OIC_JSON_PDEVICE_ID_NAME, base64Buff); - } - - //ROwner -- Mandatory - if ('\0' != (char)dpair->rowner.id[0]) - { - outLen = 0; - b64Ret = b64Encode(dpair->rowner.id, sizeof(dpair->rowner.id), base64Buff, - sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); - cJSON_AddStringToObject(jsonDpair, OIC_JSON_ROWNER_NAME, base64Buff); - } - - - jsonStr = cJSON_PrintUnformatted(jsonRoot); - - exit: - if (jsonRoot) - { - cJSON_Delete(jsonRoot); - } - return jsonStr; - } - - /* - * This internal method converts JSON Dpairing into binary Dpairing. - * Does not error-check here, but check it in caller - */ - OicSecDpairing_t* JSONToDpairingBin(const char * jsonStr) - { - OIC_LOG(DEBUG, TAG, "JSONToDpairingBin() IN"); - - OCStackResult ret = OC_STACK_ERROR; - OicSecDpairing_t *dpair = NULL; - cJSON *jsonRoot = NULL; - cJSON *jsonDpair = NULL; - cJSON *jsonObj = NULL; - - unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {}; - uint32_t outLen = 0; - B64Result b64Ret = B64_OK; - - - VERIFY_NON_NULL(TAG, jsonStr, ERROR); - - jsonRoot = cJSON_Parse(jsonStr); - VERIFY_NON_NULL(TAG, jsonRoot, ERROR); - - jsonDpair = cJSON_GetObjectItem(jsonRoot, OIC_JSON_DPAIRING_NAME); - VERIFY_NON_NULL(TAG, jsonDpair, ERROR); - - dpair = (OicSecDpairing_t*)OICCalloc(1, sizeof(OicSecDpairing_t)); - VERIFY_NON_NULL(TAG, dpair, ERROR); - - //SPM -- Mandatory - jsonObj = cJSON_GetObjectItem(jsonDpair, OIC_JSON_SPM_NAME); - if (jsonObj && cJSON_Number == jsonObj->type) - { - dpair->spm = (OicSecPrm_t)jsonObj->valueint; - OIC_LOG_V (DEBUG, TAG, "jsonObj->valueint = %d", jsonObj->valueint); - OIC_LOG_V (DEBUG, TAG, "dpair->spm = %d", dpair->spm); - - // don't need to check "PRM_NOT_ALLOWED <= dpair->spm" because of always true - VERIFY_SUCCESS(TAG, (PRM_RANDOM_PIN >= dpair->spm), ERROR); - } - else - { - dpair->spm = PRM_NOT_ALLOWED; - } - - //PDeviceId -- Mandatory - outLen = 0; - jsonObj = cJSON_GetObjectItem(jsonDpair, OIC_JSON_PDEVICE_ID_NAME); - if (jsonObj && cJSON_String == jsonObj->type) - { - b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff, - sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(dpair->pdeviceID.id)), ERROR); - memcpy(dpair->pdeviceID.id, base64Buff, outLen); - } - else - { - memset(&dpair->pdeviceID, 0, sizeof(OicUuid_t)); - } - - // ROwner -- Mandatory - outLen = 0; - jsonObj = cJSON_GetObjectItem(jsonDpair, OIC_JSON_ROWNER_NAME); - if (jsonObj && cJSON_String == jsonObj->type) - { - b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff, - sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(dpair->rowner.id)), ERROR); - memcpy(dpair->rowner.id, base64Buff, outLen); - } - else - { - memset(&dpair->rowner, 0, sizeof(OicUuid_t)); - } - - ret = OC_STACK_OK; - - exit: - cJSON_Delete(jsonRoot); - if (OC_STACK_OK != ret) - { - DeleteDpairingBinData(dpair); - dpair = NULL; - } - - OIC_LOG(DEBUG, TAG, "JSONToDpairingBin() OUT"); - return dpair; - } - - /** - * Function to handle the handshake result in Direct-Pairing. - * This function will be invoked after DTLS handshake - * @param endPoint [IN] The remote endpoint. - * @param errorInfo [IN] Error information from the endpoint. - * @return NONE - */ - void DPairingDTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info) - { - OIC_LOG_V(INFO, TAG, "IN DPairingDTLSHandshakeCB"); - - if(gDpair && endpoint && info) - { - OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d", - endpoint->addr, endpoint->port, info->result); - - if(CA_STATUS_OK == info->result) - { - OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Connection success."); - } - else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result) - { - OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Authentication failed"); - - } - - #ifdef __WITH_DTLS__ - CARegisterDTLSHandshakeCallback(NULL); - #endif // __WITH_DTLS__ - - // delete temporary key - RemoveCredential(&gDpair->pdeviceID); - } - - OIC_LOG_V(INFO, TAG, "OUT DPairingDTLSHandshakeCB"); - } - - static OCEntityHandlerResult HandleDpairingPostRequest (const OCEntityHandlerRequest * ehRequest) - { - OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle processing POST request"); - OCEntityHandlerResult ehRet = OC_EH_ERROR; - OicSecDpairing_t* newDpair = NULL; - - const OicSecPconf_t *pconf = GetPconfResourceData(); - if (true == pconf->edp) - { - // Convert JSON DPAIRING data into binary. This will also validate the DPAIRING data received. - newDpair = JSONToDpairingBin(((OCSecurityPayload*)ehRequest->payload)->securityData); - } - else - { - OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled"); - ehRet = OC_EH_ERROR; - } - - if (newDpair && false == IsPairedDevice(&newDpair->pdeviceID)) - { - // Check if valid Post request - bool prmMached = false; - for (size_t i=0; iprmLen; i++) - { - if (newDpair->spm == pconf->prm[i]) - { - prmMached = true; - break; - } - } - OIC_LOG_V(DEBUG, TAG, "Parsed spm is %s", prmMached ? "valid" : "invalid, send error response"); - - // Update local Dpairing with new Dpairing & prepare dtls session - if (prmMached && '\0' != (char)newDpair->pdeviceID.id[0]) - { - if(!gDpair) - { - gDpair = GetDpairingDefault(); - } - gDpair->spm = newDpair->spm; - memcpy(&gDpair->pdeviceID, &newDpair->pdeviceID, sizeof(OicUuid_t)); - memcpy(&gDpair->rowner, &pconf->rowner, sizeof(OicUuid_t)); - - #ifdef __WITH_DTLS__ - // Add temporary psk - OCStackResult res; - OicUuid_t subjectId = {.id={0}}; - res = AddTmpPskWithPIN(&gDpair->pdeviceID, - SYMMETRIC_PAIR_WISE_KEY, - (char*)pconf->pin.val, DP_PIN_LENGTH, - 1, &gDpair->rowner, &subjectId); - if(res != OC_STACK_OK || - memcmp(&gDpair->pdeviceID, &subjectId, sizeof(OicUuid_t))) - { - OIC_LOG_V(ERROR, TAG, "Failed to save the temporal PSK : %d", res); - goto exit; - } - - // Prepare to establish a secure channel with Pin-based PSK cipher suite - if (CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false) || - CA_STATUS_OK != CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256)) - { - OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256"); - goto exit; - } - - if(CA_STATUS_OK != CARegisterDTLSHandshakeCallback(DPairingDTLSHandshakeCB)) - { - OIC_LOG(WARNING, TAG, "DirectPairingHandler : Failed to register DTLS handshake callback."); - goto exit; - } - #endif // __WITH_DTLS__ - - // should be lock /oic/sec/dpairing resource if Direct-Pairing starts normally ? - OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource created"); - - ehRet = OC_EH_RESOURCE_CREATED; - } - else - { - OIC_LOG(ERROR, TAG, "Error in request check"); - } - } - - - #ifdef __WITH_DTLS__ - exit: - #endif // __WITH_DTLS__ - - if (OC_EH_ERROR == ehRet && gDpair) - { - RemoveCredential(&gDpair->pdeviceID); - gDpair = NULL; - } - - // Send payload to request originator - if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL)) - { - OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDpairingPostRequest"); - } - - DeleteDpairingBinData(newDpair); - OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet); - return ehRet; - } - - static OCEntityHandlerResult HandleDpairingPutRequest (const OCEntityHandlerRequest * ehRequest) - { - OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle processing PUT request (Comfirmation)"); - - OCEntityHandlerResult ehRet = OC_EH_ERROR; - OicSecDpairing_t* newDpair = NULL; - - const OicSecPconf_t *pconf = GetPconfResourceData(); - if (true == pconf->edp) - { - // Convert JSON DPAIRING data into binary. This will also validate the DPAIRING data received. - newDpair = JSONToDpairingBin(((OCSecurityPayload*)ehRequest->payload)->securityData); - } - else - { - OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled"); - ehRet = OC_EH_ERROR; - } - - if (gDpair && newDpair) - { - OIC_LOG(DEBUG, TAG, "Received direct-pairing finalization request"); - - // Check if valid Put request - VERIFY_SUCCESS(TAG, PRM_NOT_ALLOWED == newDpair->spm, ERROR); - - const OicSecPconf_t *pconf = GetPconfResourceData(); - VERIFY_NON_NULL(TAG, pconf, ERROR); - - #ifdef __WITH_DTLS__ - OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle; - VERIFY_SUCCESS(TAG, (request->devAddr.flags | OC_FLAG_SECURE), ERROR); - - //Generate new credential - OIC_LOG_V(INFO, TAG, "SavePairingPSK for %s(%d)", request->devAddr.addr, request->devAddr.port); - OCStackResult res = SavePairingPSK(&request->devAddr, &newDpair->pdeviceID, - (OicUuid_t *)&pconf->rowner, true); - VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR); - #endif //__WITH_DTLS__ - - //Generate new acl - OicSecPdAcl_t *pdAcl; - LL_FOREACH(pconf->pdacls, pdAcl) - { - OicSecAcl_t acl; - memset(&acl, 0, sizeof(OicSecAcl_t)); - memcpy(&acl.subject, &gDpair->pdeviceID, sizeof(OicUuid_t)); - acl.resources = pdAcl->resources; - acl.resourcesLen = pdAcl->resourcesLen; - acl.owners = (OicUuid_t*)&pconf->rowner; - acl.ownersLen = 1; - acl.permission = pdAcl->permission; - acl.periods = pdAcl->periods; - acl.recurrences = pdAcl->recurrences; - acl.prdRecrLen = pdAcl->prdRecrLen; - - char* aclJson = BinToAclJSON(&acl); - if (aclJson) - { - InstallNewACL(aclJson); - OICFree(aclJson); - } - } - - //update pconf device list - AddPairedDevice(&newDpair->pdeviceID); - - //Initialize dpairing resource - gDpair = NULL; - - OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource updated, direct-pairing finalization success"); - ehRet = OC_EH_OK; - } - - exit: - - //Send payload to request originator - if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL)) - { - OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDpairingPutRequest"); - } - - DeleteDpairingBinData(newDpair); - OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet); - return ehRet; - } - /* - * This internal method is the entity handler for Dpairing resources and - * will handle REST request (GET/POST) for them. - */ - OCEntityHandlerResult DpairingEntityHandler (OCEntityHandlerFlag flag, - OCEntityHandlerRequest * ehRequest, - void* callbackParameter) - { - OIC_LOG(DEBUG, TAG, "Received request DpairingEntityHandler"); - (void)callbackParameter; - OCEntityHandlerResult ehRet = OC_EH_ERROR; - - if (!ehRequest) - { - return ehRet; - } - - if (flag & OC_REQUEST_FLAG) - { - OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG"); - switch (ehRequest->method) - { - case OC_REST_GET: - break; - - case OC_REST_POST: - ehRet = HandleDpairingPostRequest(ehRequest); - break; - - case OC_REST_PUT: - ehRet = HandleDpairingPutRequest(ehRequest); - break; - - case OC_REST_DELETE: - break; - - default: - ehRet = OC_EH_ERROR; - SendSRMResponse(ehRequest, ehRet, NULL); - } - } - - return ehRet; - } - - /* - * This internal method is used to create '/oic/sec/dpairing' resource. - */ - OCStackResult CreateDpairingResource() - { - OCStackResult ret; - - ret = OCCreateResource(&gDpairHandle, - OIC_RSRC_TYPE_SEC_DPAIRING, - OIC_MI_DEF, - OIC_RSRC_DPAIRING_URI, - DpairingEntityHandler, - NULL, - OC_SECURE | OC_EXPLICIT_DISCOVERABLE); - - if (OC_STACK_OK != ret) - { - OIC_LOG (ERROR, TAG, "Unable to instantiate Dpairing resource"); - DeInitDpairingResource(); - } - return ret; - } - - /** - * Initialize Dpairing resource by loading data from persistent storage. - * - * @retval OC_STACK_OK for Success, otherwise some error value - */ - OCStackResult InitDpairingResource() - { - OCStackResult ret = OC_STACK_ERROR; - - // Instantiate 'oic.sec.dpairing' - ret = CreateDpairingResource(); - if (OC_STACK_OK != ret) - { - DeInitDpairingResource(); - } - return ret; - } - - /** - * Perform cleanup for Dpairing resources. - * - * @return - * OC_STACK_OK - no error - * OC_STACK_ERROR - stack process error - * - */ - OCStackResult DeInitDpairingResource() - { - OCStackResult ret = OCDeleteResource(gDpairHandle); - gDpair = NULL; - - if(OC_STACK_OK == ret) - { - return OC_STACK_OK; - } - else - { - return OC_STACK_ERROR; - } - } - - - + /* ***************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * *****************************************************************/ + + #include + #include + #include "ocstack.h" + #include "logger.h" + #include "oic_malloc.h" + #include "oic_string.h" + #include "cJSON.h" + #include "base64.h" + #include "resourcemanager.h" + #include "dpairingresource.h" + #include "psinterface.h" + #include "utlist.h" + #include "srmresourcestrings.h" + #include "cainterface.h" + #include "doxmresource.h" + #include "pconfresource.h" + #include "credresource.h" + #include "aclresource.h" + #include "srmutility.h" + #include "ocserverrequest.h" + #include "ocpayloadcbor.h" + #include "ocpayload.h" + #include "payload_logging.h" + #include + #ifdef WITH_ARDUINO + #include + #else + #include + #endif + + #ifdef __WITH_DTLS__ + #include "global.h" + #endif + + #define TAG "SRM-DPAIRING" + + /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory. + * The value of payload size is increased until reaching belox max cbor size. */ + static const uint16_t CBOR_SIZE = 1024; + + /** Max cbor size payload. */ + static const uint16_t CBOR_MAX_SIZE = 4400; + + /** DOXM Map size - Number of mandatory items. */ + static const uint8_t DPAIR_MAP_SIZE = 3; + + static OicSecDpairing_t *gDpair = NULL; + static OCResourceHandle gDpairHandle = NULL; + static OicSecDpairing_t gDefaultDpair = + { + PRM_NOT_ALLOWED, /* OicSecPrm_t spm */ + {.id = {0}}, /* OicUuid_t pdeviceID */ + {.id = {0}}, /* OicUuid_t rowner */ + }; + + void DeleteDpairingBinData(OicSecDpairing_t* dpair) + { + if (dpair) + { + //Clean dpairing itself + OICFree(dpair); + } + } + + /** + * Get the default value. + * @retval the gDefaultDpair pointer; + */ + static OicSecDpairing_t* GetDpairingDefault() + { + OIC_LOG (DEBUG, TAG, "GetDpairingDefault"); + + return &gDefaultDpair; + } + + /** + * This method is used by SRM to retrieve Dpairing resource data.. + */ + void SetDpairingResourceOwner(OicUuid_t *rowner) + { + OIC_LOG (DEBUG, TAG, "SetDpairingResourceOwner"); + if (gDpair) + { + memcpy(&gDpair->rownerID, rowner, sizeof(OicUuid_t)); + } + } + + #ifdef __WITH_DTLS__ + /** + * Function to save PairingPSK. + * + * @param[in] endpoint current endpoint. + * @param[in] peerDevID peer device indentitiy. + * @param[in] isPairingServer indicate if it generates PairingPSK for server or client. + * + * @return OC_STACK_OK on success + */ + OCStackResult SavePairingPSK(OCDevAddr *endpoint, + OicUuid_t *peerDevID, OicUuid_t *owner, bool isPairingServer) + { + OIC_LOG(DEBUG, TAG, "IN SavePairingPSK"); + + if(NULL == endpoint || NULL == peerDevID || NULL == owner) + { + OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__); + return OC_STACK_INVALID_PARAM; + } + + OCStackResult res = OC_STACK_ERROR; + + OicUuid_t ptDeviceID = {.id={0}}; + if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID)) + { + OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID"); + return res; + } + + uint8_t pairingPSK[OWNER_PSK_LENGTH_128] = {0}; + OicSecKey_t pairingKey = {pairingPSK, OWNER_PSK_LENGTH_128}; + + //Generating PairingPSK using OwnerPSK scheme + CAResult_t pskRet = CAGenerateOwnerPSK((const CAEndpoint_t *)endpoint, + (uint8_t *)OIC_RSRC_TYPE_SEC_DPAIRING, + strlen(OIC_RSRC_TYPE_SEC_DPAIRING), + (isPairingServer ? ptDeviceID.id : peerDevID->id), sizeof(OicUuid_t), // server + (isPairingServer ? peerDevID->id : ptDeviceID.id), sizeof(OicUuid_t), // client + pairingPSK, OWNER_PSK_LENGTH_128); + + if (CA_STATUS_OK == pskRet) + { + OIC_LOG(INFO, TAG, "pairingPSK dump:\n"); + OIC_LOG_BUFFER(INFO, TAG, pairingPSK, OWNER_PSK_LENGTH_128); + //Generating new credential for direct-pairing client + + OicSecCred_t *cred = GenerateCredential(peerDevID, + SYMMETRIC_PAIR_WISE_KEY, NULL, + &pairingKey, owner); + VERIFY_NON_NULL(TAG, cred, ERROR); + + res = AddCredential(cred); + if(res != OC_STACK_OK) + { + DeleteCredList(cred); + return res; + } + } + else + { + OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed"); + } + + OIC_LOG(DEBUG, TAG, "OUT SavePairingPSK"); + exit: + return res; + } + #endif // __WITH_DTLS__ + + OCStackResult DpairingToCBORPayload(const OicSecDpairing_t *dpair, uint8_t **payload, size_t *size) + { + if (NULL == dpair || NULL == payload || NULL != *payload || NULL == size) + { + return OC_STACK_INVALID_PARAM; + } + + size_t cborLen = *size; + if (0 == cborLen) + { + cborLen = CBOR_SIZE; + } + + *payload = NULL; + *size = 0; + + OCStackResult ret = OC_STACK_ERROR; + + CborEncoder encoder; + CborEncoder dpairMap; + + int64_t cborEncoderResult = CborNoError; + uint8_t mapSize = DPAIR_MAP_SIZE; + + uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen); + VERIFY_NON_NULL(TAG, outPayload, ERROR); + cbor_encoder_init(&encoder, outPayload, cborLen, 0); + + cborEncoderResult = cbor_encoder_create_map(&encoder, &dpairMap, mapSize); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating DPAIRING Map"); + + //spm -- Mandatory + cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_SPM_NAME, + strlen(OIC_JSON_SPM_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SPM name tag"); + cborEncoderResult = cbor_encode_int(&dpairMap, dpair->spm); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SPM value"); + + //PDEVICEID -- Mandatory + cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_PDEVICE_ID_NAME, + strlen(OIC_JSON_PDEVICE_ID_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PDeviceID tag"); + { + char *deviceId = NULL; + ret = ConvertUuidToStr(&dpair->pdeviceID, &deviceId); + VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); + cborEncoderResult = cbor_encode_text_string(&dpairMap, deviceId, strlen(deviceId)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode PDeviceID value"); + OICFree(deviceId); + } + + //ROWNER -- Mandatory + { + char *rowner = NULL; + cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_ROWNERID_NAME, + strlen(OIC_JSON_ROWNERID_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROWNER tag"); + ret = ConvertUuidToStr(&dpair->rownerID, &rowner); + VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); + cborEncoderResult = cbor_encode_text_string(&dpairMap, rowner, strlen(rowner)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Rowner ID value"); + OICFree(rowner); + } + + cborEncoderResult = cbor_encoder_close_container(&encoder, &dpairMap); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close dpairMap"); + + if (CborNoError == cborEncoderResult) + { + *size = encoder.ptr - outPayload; + *payload = outPayload; + ret = OC_STACK_OK; + } + + exit: + if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE)) + { + // reallocate and try again! + OICFree(outPayload); + // Since the allocated initial memory failed, double the memory. + cborLen += encoder.ptr - encoder.end; + cborEncoderResult = CborNoError; + ret = DpairingToCBORPayload(dpair, payload, &cborLen); + *size = cborLen; + } + + if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret)) + { + OICFree(outPayload); + outPayload = NULL; + *payload = NULL; + *size = 0; + ret = OC_STACK_ERROR; + } + + return ret; + } + + OCStackResult CBORPayloadToDpair(const uint8_t *cborPayload, size_t size, + OicSecDpairing_t **secDpair) + { + if (NULL == cborPayload || NULL == secDpair || NULL != *secDpair || 0 == size) + { + return OC_STACK_INVALID_PARAM; + } + + OCStackResult ret = OC_STACK_ERROR; + *secDpair = NULL; + + CborValue dpairCbor = { .parser = NULL }; + CborParser parser = { .end = NULL }; + CborError cborFindResult = CborNoError; + + cbor_parser_init(cborPayload, size, 0, &parser, &dpairCbor); + CborValue dpairMap = { .parser = NULL }; + OicSecDpairing_t *dpair = NULL; + cborFindResult = cbor_value_enter_container(&dpairCbor, &dpairMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering DPairing Map"); + + dpair = (OicSecDpairing_t *)OICCalloc(1, sizeof(*dpair)); + VERIFY_NON_NULL(TAG, dpair, ERROR); + + while (cbor_value_is_valid(&dpairMap)) + { + char *name = NULL; + size_t len = 0; + CborType type = CborInvalidType; + cborFindResult = cbor_value_dup_text_string(&dpairMap, &name, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding tag name"); + cborFindResult = cbor_value_advance(&dpairMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a value in DPair map"); + + type = cbor_value_get_type(&dpairMap); + if (0 == strcmp(OIC_JSON_SPM_NAME, name)) + { + cborFindResult = cbor_value_get_int(&dpairMap, (int *) &dpair->spm); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SPM Value"); + } + + if (0 == strcmp(OIC_JSON_PDEVICE_ID_NAME, name)) + { + char *id = NULL; + cborFindResult = cbor_value_dup_text_string(&dpairMap, &id, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PDeviceID value"); + ret = ConvertStrToUuid(id, &dpair->pdeviceID); + VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); + OICFree(id); + } + + if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name)) + { + char *id = NULL; + cborFindResult = cbor_value_dup_text_string(&dpairMap, &id, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RownerID value"); + ret = ConvertStrToUuid(id, &dpair->rownerID); + VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR); + OICFree(id); + } + + if (CborMapType != type && cbor_value_is_valid(&dpairMap)) + { + cborFindResult = cbor_value_advance(&dpairMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Dpair Map"); + } + OICFree(name); + } + + *secDpair = dpair; + ret = OC_STACK_OK; + + exit: + if (CborNoError != cborFindResult) + { + OIC_LOG (ERROR, TAG, "CBORPayloadToDoxm failed"); + DeleteDpairingBinData(dpair); + dpair = NULL; + *secDpair = NULL; + ret = OC_STACK_ERROR; + } + return ret; + } + /** + * Function to handle the handshake result in Direct-Pairing. + * This function will be invoked after DTLS handshake + * @param endPoint [IN] The remote endpoint. + * @param errorInfo [IN] Error information from the endpoint. + * @return NONE + */ + void DPairingDTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info) + { + OIC_LOG_V(INFO, TAG, "IN DPairingDTLSHandshakeCB"); + + if(gDpair && endpoint && info) + { + OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d", + endpoint->addr, endpoint->port, info->result); + + if(CA_STATUS_OK == info->result) + { + OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Connection success."); + } + else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result) + { + OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Authentication failed"); + + } + + #ifdef __WITH_DTLS__ + CARegisterDTLSHandshakeCallback(NULL); + #endif // __WITH_DTLS__ + + // delete temporary key + RemoveCredential(&gDpair->pdeviceID); + } + + OIC_LOG_V(INFO, TAG, "OUT DPairingDTLSHandshakeCB"); + } + + static OCEntityHandlerResult HandleDpairingPostRequest (const OCEntityHandlerRequest * ehRequest) + { + OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle processing POST request"); + OCEntityHandlerResult ehRet = OC_EH_ERROR; + OicSecDpairing_t* newDpair = NULL; + OCStackResult res = OC_STACK_OK; + + const OicSecPconf_t *pconf = GetPconfResourceData(); + if (true == pconf->edp) + { + uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData; + size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize; + if (payload) + { + res = CBORPayloadToDpair(payload, size, &newDpair); + } + } + else + { + OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled"); + ehRet = OC_EH_ERROR; + } + + if (OC_STACK_OK == res && newDpair && false == IsPairedDevice(&newDpair->pdeviceID)) + { + // Check if valid Post request + bool prmMached = false; + for (size_t i=0; iprmLen; i++) + { + if (newDpair->spm == pconf->prm[i]) + { + prmMached = true; + break; + } + } + OIC_LOG_V(DEBUG, TAG, "Parsed spm is %s", prmMached ? "valid" : + "invalid, send error response"); + + // Update local Dpairing with new Dpairing & prepare dtls session + if (prmMached && '\0' != (char)newDpair->pdeviceID.id[0]) + { + if(!gDpair) + { + gDpair = GetDpairingDefault(); + } + gDpair->spm = newDpair->spm; + memcpy(&gDpair->pdeviceID, &newDpair->pdeviceID, sizeof(OicUuid_t)); + memcpy(&gDpair->rownerID, &pconf->rownerID, sizeof(OicUuid_t)); + + #ifdef __WITH_DTLS__ + // Add temporary psk + OCStackResult res; + OicUuid_t subjectId = {.id={0}}; + res = AddTmpPskWithPIN(&gDpair->pdeviceID, + SYMMETRIC_PAIR_WISE_KEY, + (char*)pconf->pin.val, DP_PIN_LENGTH, + &gDpair->rownerID, &subjectId); + if(res != OC_STACK_OK || + memcmp(&gDpair->pdeviceID, &subjectId, sizeof(OicUuid_t))) + { + OIC_LOG_V(ERROR, TAG, "Failed to save the temporal PSK : %d", res); + goto exit; + } + + // Prepare to establish a secure channel with Pin-based PSK cipher suite + if (CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false) || + CA_STATUS_OK != CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256)) + { + OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256"); + goto exit; + } + + if(CA_STATUS_OK != CARegisterDTLSHandshakeCallback(DPairingDTLSHandshakeCB)) + { + OIC_LOG(WARNING, TAG, "DirectPairingHandler : Failed to register" + " DTLS handshake callback."); + goto exit; + } + #endif // __WITH_DTLS__ + + // should be lock /oic/sec/dpairing resource if Direct-Pairing starts normally ? + OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource created"); + + ehRet = OC_EH_RESOURCE_CREATED; + } + else + { + OIC_LOG(ERROR, TAG, "Error in request check"); + } + } + + + #ifdef __WITH_DTLS__ + exit: + #endif // __WITH_DTLS__ + + // Send payload to request originator + if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0)) + { + ehRet = OC_EH_ERROR; + OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDpairingPostRequest"); + } + + if (OC_EH_ERROR == ehRet && gDpair) + { + RemoveCredential(&gDpair->pdeviceID); + gDpair = NULL; + } + + DeleteDpairingBinData(newDpair); + OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet); + return ehRet; + } + + static OCEntityHandlerResult HandleDpairingPutRequest (const OCEntityHandlerRequest * ehRequest) + { + OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle processing PUT request (Comfirmation)"); + + OCEntityHandlerResult ehRet = OC_EH_ERROR; + OicSecDpairing_t* newDpair = NULL; + OCStackResult res = OC_STACK_OK; + + const OicSecPconf_t *pconf = GetPconfResourceData(); + if (true == pconf->edp) + { + uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData; + size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize; + if (payload) + { + res = CBORPayloadToDpair(payload, size, &newDpair); + } + + } + else + { + OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled"); + ehRet = OC_EH_ERROR; + } + + + if ((OC_STACK_OK == res) && gDpair && newDpair) + { + OIC_LOG(DEBUG, TAG, "Received direct-pairing finalization request"); + + // Check if valid Put request + VERIFY_SUCCESS(TAG, PRM_NOT_ALLOWED == newDpair->spm, ERROR); + + const OicSecPconf_t *pconf = GetPconfResourceData(); + VERIFY_NON_NULL(TAG, pconf, ERROR); + + #ifdef __WITH_DTLS__ + OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle; + VERIFY_SUCCESS(TAG, (request->devAddr.flags | OC_FLAG_SECURE), ERROR); + + //Generate new credential + OIC_LOG_V(INFO, TAG, "SavePairingPSK for %s(%d)", request->devAddr.addr, + request->devAddr.port); + OCStackResult res = SavePairingPSK(&request->devAddr, &newDpair->pdeviceID, + (OicUuid_t *)&pconf->rownerID, true); + VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR); + #endif //__WITH_DTLS__ + + //Generate new acl + OicSecPdAcl_t *pdAcl; + LL_FOREACH(pconf->pdacls, pdAcl) + { + OicSecAcl_t acl; + memset(&acl, 0, sizeof(OicSecAcl_t)); + memcpy(&acl.subject, &gDpair->pdeviceID, sizeof(OicUuid_t)); + acl.resources = pdAcl->resources; + acl.resourcesLen = pdAcl->resourcesLen; + memcpy(&acl.rownerID, &pconf->rownerID, sizeof(OicUuid_t)); + acl.permission = pdAcl->permission; + acl.periods = pdAcl->periods; + acl.recurrences = pdAcl->recurrences; + acl.prdRecrLen = pdAcl->prdRecrLen; + + size_t size = 0; + uint8_t *payload = NULL; + if (OC_STACK_OK == AclToCBORPayload(&acl, &payload, &size)) + { + InstallNewACL(payload, size); + OICFree(payload); + } + } + + //update pconf device list + AddPairedDevice(&newDpair->pdeviceID); + + //Initialize dpairing resource + gDpair = NULL; + + OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource updated," + "direct-pairing finalization success"); + ehRet = OC_EH_OK; + } + + exit: + + //Send payload to request originator + if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0)) + { + ehRet = OC_EH_ERROR; + OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDpairingPutRequest"); + } + + DeleteDpairingBinData(newDpair); + OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet); + return ehRet; + } + /* + * This internal method is the entity handler for Dpairing resources and + * will handle REST request (GET/POST) for them. + */ + OCEntityHandlerResult DpairingEntityHandler (OCEntityHandlerFlag flag, + OCEntityHandlerRequest * ehRequest, + void* callbackParameter) + { + OIC_LOG(DEBUG, TAG, "Received request DpairingEntityHandler"); + (void)callbackParameter; + OCEntityHandlerResult ehRet = OC_EH_ERROR; + + if (!ehRequest) + { + return ehRet; + } + + if (flag & OC_REQUEST_FLAG) + { + OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG"); + switch (ehRequest->method) + { + case OC_REST_GET: + break; + + case OC_REST_POST: + ehRet = HandleDpairingPostRequest(ehRequest); + break; + + case OC_REST_PUT: + ehRet = HandleDpairingPutRequest(ehRequest); + break; + + case OC_REST_DELETE: + break; + + default: + ehRet = OC_EH_ERROR; + SendSRMResponse(ehRequest, ehRet, NULL, 0); + } + } + + return ehRet; + } + + /* + * This internal method is used to create '/oic/sec/dpairing' resource. + */ + OCStackResult CreateDpairingResource() + { + OCStackResult ret; + + ret = OCCreateResource(&gDpairHandle, + OIC_RSRC_TYPE_SEC_DPAIRING, + OIC_MI_DEF, + OIC_RSRC_DPAIRING_URI, + DpairingEntityHandler, + NULL, + OC_SECURE | OC_EXPLICIT_DISCOVERABLE); + + if (OC_STACK_OK != ret) + { + OIC_LOG (ERROR, TAG, "Unable to instantiate Dpairing resource"); + DeInitDpairingResource(); + } + return ret; + } + + /** + * Initialize Dpairing resource by loading data from persistent storage. + * + * @retval OC_STACK_OK for Success, otherwise some error value + */ + OCStackResult InitDpairingResource() + { + OCStackResult ret = OC_STACK_ERROR; + + // Instantiate 'oic.sec.dpairing' + ret = CreateDpairingResource(); + if (OC_STACK_OK != ret) + { + DeInitDpairingResource(); + } + return ret; + } + + /** + * Perform cleanup for Dpairing resources. + * + * @return + * OC_STACK_OK - no error + * OC_STACK_ERROR - stack process error + * + */ + OCStackResult DeInitDpairingResource() + { + OCStackResult ret = OCDeleteResource(gDpairHandle); + gDpair = NULL; + + if(OC_STACK_OK == ret) + { + return OC_STACK_OK; + } + else + { + return OC_STACK_ERROR; + } + } + + OCStackResult SetDpairingRownerId(const OicUuid_t* newROwner) + { + OCStackResult ret = OC_STACK_ERROR; + uint8_t *cborPayload = NULL; + size_t size = 0; + OicUuid_t prevId = {.id={0}}; + + if(NULL == newROwner) + { + ret = OC_STACK_INVALID_PARAM; + } + if(NULL == gDpair) + { + ret = OC_STACK_NO_RESOURCE; + } + + if(newROwner && gDpair) + { + memcpy(prevId.id, gDpair->rownerID.id, sizeof(prevId.id)); + memcpy(gDpair->rownerID.id, newROwner->id, sizeof(newROwner->id)); + + ret = DpairingToCBORPayload(gDpair, &cborPayload, &size); + VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR); + + ret = UpdateSecureResourceInPS(OIC_JSON_DPAIRING_NAME, cborPayload, size); + VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR); + + OICFree(cborPayload); + } + + return ret; + + exit: + OICFree(cborPayload); + memcpy(gDpair->rownerID.id, prevId.id, sizeof(prevId.id)); + return ret; + } + + OCStackResult GetDpairingRownerId(OicUuid_t *rowneruuid) + { + OCStackResult retVal = OC_STACK_ERROR; + if (gDpair) + { + *rowneruuid = gDpair->rownerID; + retVal = OC_STACK_OK; + } + return retVal; + } diff --combined resource/csdk/security/src/policyengine.c index 1e20b40,04f0fc3..4a4694d --- a/resource/csdk/security/src/policyengine.c +++ b/resource/csdk/security/src/policyengine.c @@@ -17,6 -17,7 +17,7 @@@ // limitations under the License. // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + #include #include "oic_malloc.h" #include "policyengine.h" @@@ -29,17 -30,18 +30,18 @@@ #include "srmutility.h" #include "doxmresource.h" #include "iotvticalendar.h" - #include + #include "pstatresource.h" + #include "dpairingresource.h" + #include "pconfresource.h" + #include "amaclresource.h" + #include "credresource.h" #define TAG "SRM-PE" - /** - * Return the uint16_t CRUDN permission corresponding to passed CAMethod_t. - */ uint16_t GetPermissionFromCAMethod_t(const CAMethod_t method) { uint16_t perm = 0; - switch(method) + switch (method) { case CA_GET: perm = (uint16_t)PERMISSION_READ; @@@ -59,16 -61,22 +61,22 @@@ } /** - * @brief Compares two OicUuid_t structs. + * Compares two OicUuid_t structs. + * * @return true if the two OicUuid_t structs are equal, else false. */ - bool UuidCmp(OicUuid_t *firstId, OicUuid_t *secondId) + static bool UuidCmp(OicUuid_t *firstId, OicUuid_t *secondId) { // TODO use VERIFY macros to check for null when they are merged. if(NULL == firstId || NULL == secondId) { return false; } + // Check empty uuid string + if('\0' == firstId->id[0] || '\0' == secondId->id[0]) + { + return false; + } for(int i = 0; i < UUID_LENGTH; i++) { if(firstId->id[i] != secondId->id[i]) @@@ -79,12 -87,9 +87,9 @@@ return true; } - /** - * Set the state and clear other stateful context vars. - */ void SetPolicyEngineState(PEContext_t *context, const PEState_t state) { - if(NULL == context) + if (NULL == context) { return; } @@@ -97,43 -102,111 +102,117 @@@ context->amsProcessing = false; context->retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR; - FreeCARequestInfo(context->amsMgrContext->requestInfo); - OICFree(context->amsMgrContext->endpoint); - memset(context->amsMgrContext, 0, sizeof(AmsMgrContext_t)); + if (context->amsMgrContext) + { + if (context->amsMgrContext->requestInfo) + { + FreeCARequestInfo(context->amsMgrContext->requestInfo); + } + OICFree(context->amsMgrContext->endpoint); + memset(context->amsMgrContext, 0, sizeof(AmsMgrContext_t)); + } // Set state. context->state = state; } /** - * @brief Compare the request's subject to DevOwner. + * Compare the request's subject to DevOwner. * - * @return true if context->subjectId == GetDoxmDevOwner(), else false + * @return true if context->subjectId == GetDoxmDevOwner(), else false. */ - bool IsRequestFromDevOwner(PEContext_t *context) + static bool IsRequestFromDevOwner(PEContext_t *context) { bool retVal = false; - OicUuid_t owner; + OicUuid_t ownerid; if(NULL == context) { - return OC_STACK_ERROR; + return retVal; } - if(OC_STACK_OK == GetDoxmDevOwnerId(&owner)) + if(OC_STACK_OK == GetDoxmDevOwnerId(&ownerid)) { - retVal = UuidCmp(&context->subject, &owner); + retVal = UuidCmp(&context->subject, &ownerid); } return retVal; } + // TODO - remove these function placeholders as they are implemented + // in the resource entity handler code. + // Note that because many SVRs do not have a rowner, in those cases we + // just return "OC_STACK_ERROR" which results in a "false" return by + // IsRequestFromResourceOwner(). + // As these SVRs are revised to have a rowner, these functions should be + // replaced (see pstatresource.c for example of GetPstatRownerId). + + OCStackResult GetCrlRownerId(OicUuid_t *rowner) + { + rowner = NULL; + return OC_STACK_ERROR; + } + + OCStackResult GetSaclRownerId(OicUuid_t *rowner) + { + rowner = NULL; + return OC_STACK_ERROR; + } + + OCStackResult GetSvcRownerId(OicUuid_t *rowner) + { + rowner = NULL; + return OC_STACK_ERROR; + } + + static GetSvrRownerId_t GetSvrRownerId[OIC_SEC_SVR_TYPE_COUNT] = { + GetAclRownerId, + GetAmaclRownerId, + GetCredRownerId, + GetCrlRownerId, + GetDoxmRownerId, + GetDpairingRownerId, + GetPconfRownerId, + GetPstatRownerId, + GetSaclRownerId, + GetSvcRownerId + }; + + /** + * Compare the request's subject to resource.ROwner. + * + * @return true if context->subjectId equals SVR rowner id, else return false + */ + bool IsRequestFromResourceOwner(PEContext_t *context) + { + bool retVal = false; + OicUuid_t resourceOwner; + + if(NULL == context) + { + return false; + } + + if((OIC_R_ACL_TYPE <= context->resourceType) && \ + (OIC_SEC_SVR_TYPE_COUNT > context->resourceType)) + { + if(OC_STACK_OK == GetSvrRownerId[(int)context->resourceType](&resourceOwner)) + { + retVal = UuidCmp(&context->subject, &resourceOwner); + } + } + + if(true == retVal) + { + OIC_LOG(INFO, TAG, "PE.IsRequestFromResourceOwner(): returning true"); + } + else + { + OIC_LOG(INFO, TAG, "PE.IsRequestFromResourceOwner(): returning false"); + } + + return retVal; + } inline static bool IsRequestSubjectEmpty(PEContext_t *context) { @@@ -148,17 -221,18 +227,18 @@@ true : false; } - /** * Bitwise check to see if 'permission' contains 'request'. - * @param permission The allowed CRUDN permission. - * @param request The CRUDN permission being requested. + * + * @param permission is the allowed CRUDN permission. + * @param request is the CRUDN permission being requested. + * * @return true if 'permission' bits include all 'request' bits. */ static inline bool IsPermissionAllowingRequest(const uint16_t permission, const uint16_t request) { - if(request == (request & permission)) + if (request == (request & permission)) { return true; } @@@ -170,6 -244,7 +250,7 @@@ /** * Compare the passed subject to the wildcard (aka anonymous) subjectId. + * * @return true if 'subject' is the wildcard, false if it is not. */ static inline bool IsWildCardSubject(OicUuid_t *subject) @@@ -193,15 -268,14 +274,14 @@@ /** * Copy the subject, resource and permission into the context fields. */ - void CopyParamsToContext( - PEContext_t *context, - const OicUuid_t *subjectId, - const char *resource, - const uint16_t requestedPermission) + static void CopyParamsToContext(PEContext_t *context, + const OicUuid_t *subjectId, + const char *resource, + const uint16_t requestedPermission) { size_t length = 0; - if(NULL == context || NULL == subjectId || NULL == resource) + if (NULL == context || NULL == subjectId || NULL == resource) { return; } @@@ -210,7 -284,7 +290,7 @@@ // Copy the resource string into context. length = strlen(resource) + 1; - if(0 < length) + if (0 < length) { strncpy(context->resource, resource, length); context->resource[length - 1] = '\0'; @@@ -220,32 -294,32 +300,32 @@@ context->permission = requestedPermission; } - /** * Check whether 'resource' is getting accessed within the valid time period. - * @param acl The ACL to check. - * @return - * true if access is within valid time period or if the period or recurrence is not present. - * false if period and recurrence present and the access is not within valid time period. + * + * @param acl is the ACL to check. + * + * @return true if access is within valid time period or if the period or recurrence is not present. + * false if period and recurrence present and the access is not within valid time period. */ static bool IsAccessWithinValidTime(const OicSecAcl_t *acl) { #ifndef WITH_ARDUINO //Period & Recurrence not supported on Arduino due //lack of absolute time - if(NULL== acl || NULL == acl->periods || 0 == acl->prdRecrLen) + if (NULL== acl || NULL == acl->periods || 0 == acl->prdRecrLen) { return true; } //periods & recurrences rules are paired. - if(NULL == acl->recurrences) + if (NULL == acl->recurrences) { return false; } - for(size_t i = 0; i < acl->prdRecrLen; i++) + for (size_t i = 0; i < acl->prdRecrLen; i++) { - if(IOTVTICAL_VALID_ACCESS == IsRequestWithinValidTime(acl->periods[i], + if (IOTVTICAL_VALID_ACCESS == IsRequestWithinValidTime(acl->periods[i], acl->recurrences[i])) { OIC_LOG(INFO, TAG, "Access request is in allowed time period"); @@@ -262,21 -336,23 +342,23 @@@ /** * Check whether 'resource' is in the passed ACL. - * @param resource The resource to search for. - * @param acl The ACL to check. + * + * @param resource is the resource being searched. + * @param acl is the ACL to check. + * * @return true if 'resource' found, otherwise false. */ - bool IsResourceInAcl(const char *resource, const OicSecAcl_t *acl) + static bool IsResourceInAcl(const char *resource, const OicSecAcl_t *acl) { - if(NULL== acl || NULL == resource) + if (NULL== acl || NULL == resource) { return false; } - for(size_t n = 0; n < acl->resourcesLen; n++) + for (size_t n = 0; n < acl->resourcesLen; n++) { - if(0 == strcmp(resource, acl->resources[n]) || // TODO null terms? - 0 == strcmp(WILDCARD_RESOURCE_URI, acl->resources[n])) + if (0 == strcmp(resource, acl->resources[n]) || // TODO null terms? + 0 == strcmp(WILDCARD_RESOURCE_URI, acl->resources[n])) { return true; } @@@ -290,16 -366,14 +372,14 @@@ * Search each ACL for requested resource. * If resource found, check for context->permission and period validity. * If the ACL is not found locally and AMACL for the resource is found - * then sends the request to AMS service for the ACL + * then sends the request to AMS service for the ACL. * Set context->retVal to result from first ACL found which contains * correct subject AND resource. - * - * @retval void */ - void ProcessAccessRequest(PEContext_t *context) + static void ProcessAccessRequest(PEContext_t *context) { OIC_LOG(DEBUG, TAG, "Entering ProcessAccessRequest()"); - if(NULL != context) + if (NULL != context) { const OicSecAcl_t *currentAcl = NULL; OicSecAcl_t *savePtr = NULL; @@@ -314,7 -388,7 +394,7 @@@ OIC_LOG_V(DEBUG, TAG, "%s: getting ACL..." ,__func__); currentAcl = GetACLResourceData(&context->subject, &savePtr); - if(NULL != currentAcl) + if (NULL != currentAcl) { // Found the subject, so how about resource? OIC_LOG_V(DEBUG, TAG, "%s:found ACL matching subject" ,__func__); @@@ -322,17 -396,17 +402,17 @@@ // Subject was found, so err changes to Rsrc not found for now. context->retVal = ACCESS_DENIED_RESOURCE_NOT_FOUND; OIC_LOG_V(DEBUG, TAG, "%s:Searching for resource..." ,__func__); - if(IsResourceInAcl(context->resource, currentAcl)) + if (IsResourceInAcl(context->resource, currentAcl)) { OIC_LOG_V(INFO, TAG, "%s:found matching resource in ACL" ,__func__); context->matchingAclFound = true; // Found the resource, so it's down to valid period & permission. context->retVal = ACCESS_DENIED_INVALID_PERIOD; - if(IsAccessWithinValidTime(currentAcl)) + if (IsAccessWithinValidTime(currentAcl)) { context->retVal = ACCESS_DENIED_INSUFFICIENT_PERMISSION; - if(IsPermissionAllowingRequest(currentAcl->permission, context->permission)) + if (IsPermissionAllowingRequest(currentAcl->permission, context->permission)) { context->retVal = ACCESS_GRANTED; } @@@ -343,10 -417,9 +423,9 @@@ { OIC_LOG_V(INFO, TAG, "%s:no ACL found matching subject for resource %s",__func__, context->resource); } - } - while((NULL != currentAcl) && (false == context->matchingAclFound)); + } while ((NULL != currentAcl) && (false == context->matchingAclFound)); - if(IsAccessGranted(context->retVal)) + if (IsAccessGranted(context->retVal)) { OIC_LOG_V(INFO, TAG, "%s:Leaving ProcessAccessRequest(ACCESS_GRANTED)", __func__); } @@@ -361,20 -434,10 +440,10 @@@ } } - /** - * Check whether a request should be allowed. - * @param context Pointer to (Initialized) Policy Engine context to use. - * @param subjectId Pointer to Id of the requesting entity. - * @param resource Pointer to URI of Resource being requested. - * @param permission Requested permission. - * @return ACCESS_GRANTED if request should go through, - * otherwise some flavor of ACCESS_DENIED - */ - SRMAccessResponse_t CheckPermission( - PEContext_t *context, - const OicUuid_t *subjectId, - const char *resource, - const uint16_t requestedPermission) + SRMAccessResponse_t CheckPermission(PEContext_t *context, + const OicUuid_t *subjectId, + const char *resource, + const uint16_t requestedPermission) { SRMAccessResponse_t retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR; @@@ -385,9 -448,9 +454,9 @@@ // Each state machine context can only be processing one request at a time. // Therefore if the context is not in AWAITING_REQUEST or AWAITING_AMS_RESPONSE // state, return error. Otherwise, change to BUSY state and begin processing request. - if(AWAITING_REQUEST == context->state || AWAITING_AMS_RESPONSE == context->state) + if (AWAITING_REQUEST == context->state || AWAITING_AMS_RESPONSE == context->state) { - if(AWAITING_REQUEST == context->state) + if (AWAITING_REQUEST == context->state) { SetPolicyEngineState(context, BUSY); CopyParamsToContext(context, subjectId, resource, requestedPermission); @@@ -395,10 -458,16 +464,16 @@@ // Before doing any processing, check if request coming // from DevOwner and if so, always GRANT. - if(IsRequestFromDevOwner(context)) + if (IsRequestFromDevOwner(context)) + { + context->retVal = ACCESS_GRANTED; + } + // Then check if request is for a SVR and coming from rowner + else if (IsRequestFromResourceOwner(context)) { context->retVal = ACCESS_GRANTED; } + // Else request is a "normal" request that must be tested against ACL else { OicUuid_t saveSubject = {.id={}}; @@@ -407,7 -476,7 +482,7 @@@ ProcessAccessRequest(context); // If matching ACL not found, and subject != wildcard, try wildcard. - if((false == context->matchingAclFound) && \ + if ((false == context->matchingAclFound) && \ (false == IsWildCardSubject(&context->subject))) { //Saving subject for Amacl check @@@ -424,7 -493,7 +499,7 @@@ } //No local ACE found for the request so checking Amacl resource - if(ACCESS_GRANTED != context->retVal) + if (ACCESS_GRANTED != context->retVal) { //If subject is not empty then restore the original subject //else keep the subject to WILDCARD_SUBJECT_ID @@@ -451,7 -520,7 +526,7 @@@ // Capture retVal before resetting state for next request. retVal = context->retVal; - if(!context->amsProcessing) + if (!context->amsProcessing) { OIC_LOG(INFO, TAG, "Resetting PE context and PE State to AWAITING_REQUEST"); SetPolicyEngineState(context, AWAITING_REQUEST); @@@ -461,11 -530,6 +536,6 @@@ exit return retVal; } - /** - * Initialize the Policy Engine. Call this before calling CheckPermission(). - * @param context Pointer to Policy Engine context to initialize. - * @return OC_STACK_OK for Success, otherwise some error value - */ OCStackResult InitPolicyEngine(PEContext_t *context) { if(NULL == context) @@@ -483,12 -547,6 +553,6 @@@ return OC_STACK_OK; } - /** - * De-Initialize the Policy Engine. Call this before exiting to allow Policy - * Engine to do cleanup on context. - * @param context Pointer to Policy Engine context to de-initialize. - * @return none - */ void DeInitPolicyEngine(PEContext_t *context) { if(NULL != context) diff --combined resource/csdk/stack/include/ocpayload.h index fdcaf15,c8a7cfc..4b62813 mode 100755,100644..100644 --- a/resource/csdk/stack/include/ocpayload.h +++ b/resource/csdk/stack/include/ocpayload.h @@@ -219,11 -219,11 +219,11 @@@ void OCRepPayloadDestroy(OCRepPayload* // Discovery Payload OCDiscoveryPayload* OCDiscoveryPayloadCreate(); - OCSecurityPayload* OCSecurityPayloadCreate(const char* securityData); + OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size); void OCSecurityPayloadDestroy(OCSecurityPayload* payload); void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res, - uint16_t port); + uint16_t securePort, uint16_t tcpPort); void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res); bool OCResourcePayloadAddStringLL(OCStringLL **payload, const char* type); diff --combined resource/csdk/stack/include/octypes.h index 7ac930b,c7bd0f9..3335d95 --- a/resource/csdk/stack/include/octypes.h +++ b/resource/csdk/stack/include/octypes.h @@@ -197,9 -197,6 +197,9 @@@ extern "C" /** Port. */ #define OC_RSRVD_HOSTING_PORT "port" +/** TCP Port. */ +#define OC_RSRVD_TCP_PORT "tcp" + /** For Server instance ID.*/ #define OC_RSRVD_SERVER_INSTANCE_ID "sid" @@@ -336,18 -333,6 +336,18 @@@ #define OC_RSRVD_RESOURCE_TYPE_RDPUBLISH "oic.wk.rdpub" /** + * Mark a parameter as unused. Used to prevent unused variable compiler warnings. + * Used in three cases: + * 1. in callbacks when one of the parameters are unused + * 2. when due to code changes a functions parameter is no longer + * used but must be left in place for backward compatibility + * reasons. + * 3. a variable is only used in the debug build variant and would + * give a build warning in release mode. + */ +#define OC_UNUSED(x) (void)(x) + +/** * These enums (OCTransportAdapter and OCTransportFlags) must * be kept synchronized with OCConnectivityType (below) as well as * CATransportAdapter and CATransportFlags (in CACommon.h). @@@ -389,10 -374,10 +389,10 @@@ typedef enu OC_FLAG_SECURE = (1 << 4), /** IPv4 & IPv6 auto-selection is the default.*/ - /** IP adapter only.*/ + /** IP & TCP adapter only.*/ OC_IP_USE_V6 = (1 << 5), - /** IP adapter only.*/ + /** IP & TCP adapter only.*/ OC_IP_USE_V4 = (1 << 6), /** internal use only.*/ @@@ -590,11 -575,11 +590,11 @@@ typedef enu /** De-register observation, intended for internal use.*/ OC_REST_CANCEL_OBSERVE = (1 << 6), - #ifdef WITH_PRESENCE +#ifdef WITH_PRESENCE /** Subscribe for all presence notifications of a particular resource.*/ OC_REST_PRESENCE = (1 << 7), - #endif +#endif /** Allows OCDoResource caller to do discovery.*/ OC_REST_DISCOVER = (1 << 8) } OCMethod; @@@ -751,16 -736,16 +751,16 @@@ typedef enu /** * Error code from OTM - * This error is plused from DTLS interface when handshake failure happens + * This error is pushed from DTLS interface when handshake failure happens */ OC_STACK_AUTHENTICATION_FAILURE, /** Insert all new error codes here!.*/ - #ifdef WITH_PRESENCE +#ifdef WITH_PRESENCE OC_STACK_PRESENCE_STOPPED = 128, OC_STACK_PRESENCE_TIMEOUT, OC_STACK_PRESENCE_DO_NOT_HANDLE, - #endif +#endif /** ERROR in stack.*/ OC_STACK_ERROR = 255 /** Error status code - END HERE.*/ @@@ -809,6 -794,7 +809,7 @@@ typedef enu * Persistent storage handlers. An APP must provide OCPersistentStorage handler pointers * when it calls OCRegisterPersistentStorageHandler. * Persistent storage open handler points to default file path. + * It should check file path and whether the file is symbolic link or no. * Application can point to appropriate SVR database path for it's IoTivity Server. */ typedef struct { @@@ -974,19 -960,33 +975,33 @@@ typedef struc /** Enum to describe the type of object held by the OCPayload object.*/ typedef enum { + /** Contents of the payload are invalid */ PAYLOAD_TYPE_INVALID, + /** The payload is an OCDiscoveryPayload */ PAYLOAD_TYPE_DISCOVERY, + /** The payload is an OCDevicePayload */ PAYLOAD_TYPE_DEVICE, + /** The payload is an OCPlatformPayload */ PAYLOAD_TYPE_PLATFORM, + /** The payload is an OCRepPayload */ PAYLOAD_TYPE_REPRESENTATION, + /** The payload is an OCSecurityPayload */ PAYLOAD_TYPE_SECURITY, + /** The payload is an OCPresencePayload */ PAYLOAD_TYPE_PRESENCE, + /** The payload is an OCRDPayload */ PAYLOAD_TYPE_RD } OCPayloadType; + /** + * A generic struct representing a payload returned from a resource operation + * + * A pointer to OCPayLoad can be cast to a more specific struct to access members + * for the its type. + */ typedef struct { - // The type of message that was received + /** The type of message that was received */ OCPayloadType type; } OCPayload; @@@ -1073,9 -1073,6 +1088,9 @@@ typedef struct OCResourcePayloa uint8_t bitmap; bool secure; uint16_t port; +#ifdef TCP_ADAPTER + uint16_t tcpPort; +#endif struct OCResourcePayload* next; } OCResourcePayload; @@@ -1236,8 -1233,10 +1251,10 @@@ typedef struc typedef struct { OCPayload base; - char* securityData; + uint8_t* securityData; + size_t payloadSize; } OCSecurityPayload; + #ifdef WITH_PRESENCE typedef struct { @@@ -1367,11 -1366,16 +1384,16 @@@ typedef enu } OCEntityHandlerFlag; /** - * Possible returned values from client application. + * Possible return values from client application callback + * + * A client application callback returns an OCStackApplicationResult to indicate whether + * the stack should continue to keep the callback registered. */ typedef enum { + /** Make no more calls to the callback and call the OCClientContextDeleter for this callback */ OC_STACK_DELETE_TRANSACTION = 0, + /** Keep this callback registered and call it if an apropriate event occurs */ OC_STACK_KEEP_TRANSACTION } OCStackApplicationResult; diff --combined resource/csdk/stack/samples/linux/secure/occlientdirectpairing.cpp index 827342f,0979901..fd7d8ee --- a/resource/csdk/stack/samples/linux/secure/occlientdirectpairing.cpp +++ b/resource/csdk/stack/samples/linux/secure/occlientdirectpairing.cpp @@@ -49,8 -49,8 +49,8 @@@ static char DISCOVERY_QUERY[] = "%s/oic //Secure Virtual Resource database for Iotivity Client application //It contains Client's Identity and the PSK credentials //of other devices which the client trusts - static char CRED_FILE[] = "oic_svr_db_client_directpairing.json"; -static char CRED_FILE[] = "oic_svr_db_client_directpairing.dat"; -- ++static char CRED_FILE[] = "oic_svr_db_client_directpairing.dat"; ++ static const OCDPDev_t *discoveredDevs = NULL; static const OCDPDev_t *pairedDevs = NULL; @@@ -514,8 -514,8 +514,8 @@@ void *CLInterface(void *data OIC_LOG(ERROR, TAG, "Invalid PIN"); continue; } - sscanf(input, "%9s", pinNumber); - sscanf(input, "%8s", pinNumber); -- printf("\n"); ++ sscanf(input, "%8s", pinNumber); ++ printf("\n"); ret = DoDirectPairing(peer, pmSel, pinNumber); if (OC_STACK_OK != ret) @@@ -636,6 -636,6 +636,3 @@@ int main(void return 0; } -- -- -- diff --combined resource/csdk/stack/samples/linux/secure/oic_svr_db_client_directpairing.json index e819a71,588ac54..d2e33a0 --- a/resource/csdk/stack/samples/linux/secure/oic_svr_db_client_directpairing.json +++ b/resource/csdk/stack/samples/linux/secure/oic_svr_db_client_directpairing.json @@@ -1,46 -1,100 +1,100 @@@ -{ +{ - "acl": [ - { - "sub": "Kg==", - "rsrc": [ - "/oic/res", - "/oic/res/d", - "/oic/res/types/d", - "/oic/presence" - ], - "perms": 2, - "ownrs" : [ - "ZGlyZWN0cGFpcmluZ0Rldg==" - ] - }, - { - "sub": "Kg==", - "rsrc": [ - "/oic/sec/doxm", - "/oic/sec/pstat", - "/oic/sec/acl", - "/oic/sec/cred" - ], - "perms": 6, - "ownrs" : [ - "ZGlyZWN0cGFpcmluZ0Rldg==" - ] - } - ], - "pstat": { - "isop": false, - "deviceid": "ZGlyZWN0cGFpcmluZ0Rldg==", - "commithash": 0, - "cm": 0, - "tm": 0, - "om": 3, - "sm": [3] - }, - "doxm": { - "oxm": [0], - "oxmsel": 0, - "sct": 1, - "owned": false, - "deviceid": "ZGlyZWN0cGFpcmluZ0Rldg==" - } - } + "acl": { + "aclist": { + "aces": [ + { + "subjectuuid": "*", + "resources": [ + { + "href": "/oic/res", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/d", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/p", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/res/d", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/res/types/d", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/presence", + "rel": "", + "rt": "", + "if": "" + } + ], + "permission": 2 + }, + { + "subjectuuid": "*", + "resources": [ + { + "href": "/oic/sec/doxm", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/sec/pstat", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/sec/acl", + "rel": "", + "rt": "", + "if": "" + }, + { + "href": "/oic/sec/cred", + "rel": "", + "rt": "", + "if": "" + } + ], + "permission": 6 + } + ] + }, + "rowneruuid" : "64697265-6374-7061-6972-696e67446576" + }, + "pstat": { + "isop": false, + "deviceuuid": "64697265-6374-7061-6972-696e67446576", + "rowneruuid": "64697265-6374-7061-6972-696e67446576", + "cm": 2, + "tm": 0, + "om": 3, + "sm": 3 + }, + "doxm": { + "oxms": [0], + "oxmsel": 0, + "sct": 1, + "owned": false, + "deviceuuid": "64697265-6374-7061-6972-696e67446576", + "devowneruuid": "", + "rowneruuid": "64697265-6374-7061-6972-696e67446576", + "dpc": false + } + } diff --combined resource/csdk/stack/src/ocpayload.c index 0cccc05,3c302a3..2ad55b2 mode 100755,100644..100644 --- a/resource/csdk/stack/src/ocpayload.c +++ b/resource/csdk/stack/src/ocpayload.c @@@ -131,18 -131,22 +131,22 @@@ static void OCCopyPropertyValueArray(OC { case OCREP_PROP_INT: dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t)); + VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory"); memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t)); break; case OCREP_PROP_DOUBLE: dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double)); + VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory"); memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double)); break; case OCREP_PROP_BOOL: dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool)); + VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory"); memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool)); break; case OCREP_PROP_STRING: dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*)); + VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory"); for(size_t i = 0; i < dimTotal; ++i) { dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]); @@@ -150,6 -154,7 +154,7 @@@ break; case OCREP_PROP_OBJECT: dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*)); + VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory"); for(size_t i = 0; i < dimTotal; ++i) { dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]); @@@ -157,6 -162,7 +162,7 @@@ break; case OCREP_PROP_ARRAY: dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*)); + VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory"); for(size_t i = 0; i < dimTotal; ++i) { dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]); @@@ -166,6 -172,8 +172,8 @@@ OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type"); break; } + exit: + return; } static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source) @@@ -543,13 -551,21 +551,21 @@@ bool OCRepPayloadGetPropDouble(const OC { OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name); - if (!val || val->type != OCREP_PROP_DOUBLE) + if (val) { - return false; + if (val->type == OCREP_PROP_DOUBLE) + { + *value = val->d; + return true; + } + else if (val->type == OCREP_PROP_INT) + { + *value = val->i; + return true; + } } - *value = val->d; - return true; + return false; } bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value) @@@ -937,7 -953,8 +953,8 @@@ bool OCRepPayloadGetDoubleArray(const O { OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name); - if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_DOUBLE + if (!val || val->type != OCREP_PROP_ARRAY || + (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT) || !val->arr.dArray) { return false; @@@ -954,7 -971,19 +971,19 @@@ return false; } - memcpy(*array, val->arr.dArray, dimTotal * sizeof(double)); + if (val->arr.type != OCREP_PROP_DOUBLE) + { + memcpy(*array, val->arr.dArray, dimTotal * sizeof(double)); + } + else + { + /* need to convert from integer */ + size_t n = 0; + for ( ; n < dimTotal; ++n) + { + (*array)[n] = val->arr.iArray[n]; + } + } memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t)); return true; } @@@ -1296,7 -1325,7 +1325,7 @@@ OCDiscoveryPayload* OCDiscoveryPayloadC return payload; } - OCSecurityPayload* OCSecurityPayloadCreate(const char* securityData) + OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size) { OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload)); @@@ -1306,7 -1335,14 +1335,14 @@@ } payload->base.type = PAYLOAD_TYPE_SECURITY; - payload->securityData = OICStrdup(securityData); + payload->securityData = (uint8_t *)OICCalloc(1, size); + if (!payload->securityData) + { + OICFree(payload); + return NULL; + } + memcpy(payload->securityData, (uint8_t *)securityData, size); + payload->payloadSize = size; return payload; } @@@ -1350,8 -1386,7 +1386,8 @@@ OCResourcePayload* OCDiscoveryPayloadGe return NULL; } -static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t port) +static OCResourcePayload* OCCopyResource(const OCResource* res, uint16_t securePort, + uint16_t tcpPort) { OCResourcePayload* pl = (OCResourcePayload*)OICCalloc(1, sizeof(OCResourcePayload)); if (!pl) @@@ -1446,17 -1481,15 +1482,17 @@@ pl->bitmap = res->resourceProperties & (OC_OBSERVABLE | OC_DISCOVERABLE); pl->secure = (res->resourceProperties & OC_SECURE) != 0; - pl->port = port; - + pl->port = securePort; +#ifdef TCP_ADAPTER + pl->tcpPort = tcpPort; +#endif return pl; } void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res, - uint16_t port) + uint16_t securePort, uint16_t tcpPort) { - OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, port)); + OCDiscoveryPayloadAddNewResource(payload, OCCopyResource(res, securePort, tcpPort)); } bool OCResourcePayloadAddStringLL(OCStringLL **stringLL, const char *value) @@@ -1468,7 -1501,7 +1504,7 @@@ if (!*stringLL) { *stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL)); - VERIFY_PARAM_NON_NULL(TAG, dup, "Failed allocating memory"); + VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory"); (*stringLL)->value = dup; return true; } @@@ -1639,13 -1672,6 +1675,13 @@@ OCPlatformPayload* OCPlatformPayloadCre payload->base.type = PAYLOAD_TYPE_PLATFORM; + payload->interfaces = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL)); + if (!payload->interfaces) + { + return NULL; + } + payload->interfaces->value = OICStrdup(OC_RSRVD_INTERFACE_READ); + payload->rt = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM); payload->info = *platformInfo; return payload; @@@ -1661,11 -1687,11 +1697,11 @@@ OCPlatformPayload* OCPlatformPayloadCre } payload->base.type = PAYLOAD_TYPE_PLATFORM; + payload->rt = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM); OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_DEFAULT); OCResourcePayloadAddStringLL(&payload->interfaces, OC_RSRVD_INTERFACE_READ); - payload->rt = OICStrdup(OC_RSRVD_RESOURCE_TYPE_PLATFORM); OCCopyPlatformInfo(platformInfo, payload); return payload; diff --combined resource/csdk/stack/src/ocpayloadconvert.c index ae90763,9f1bde6..7eee7b9 --- a/resource/csdk/stack/src/ocpayloadconvert.c +++ b/resource/csdk/stack/src/ocpayloadconvert.c @@@ -79,9 -79,20 +79,20 @@@ OCStackResult OCConvertPayload(OCPayloa VERIFY_PARAM_NON_NULL(TAG, size, "size parameter is NULL"); OIC_LOG_V(INFO, TAG, "Converting payload of type %d", payload->type); - - out = (uint8_t *)OICCalloc(1, curSize); - VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate payload"); + if (PAYLOAD_TYPE_SECURITY == payload->type) + { + size_t securityPayloadSize = ((OCSecurityPayload *)payload)->payloadSize; + if (securityPayloadSize > 0) + { + out = (uint8_t *)OICCalloc(1, ((OCSecurityPayload *)payload)->payloadSize); + VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate security payload"); + } + } + if (out == NULL) + { + out = (uint8_t *)OICCalloc(1, curSize); + VERIFY_PARAM_NON_NULL(TAG, out, "Failed to allocate payload"); + } err = OCConvertPayloadHelper(payload, out, &curSize); ret = OC_STACK_NO_MEMORY; @@@ -103,7 -114,7 +114,7 @@@ if (err == CborNoError) { - if (curSize < INIT_SIZE) + if (curSize < INIT_SIZE && PAYLOAD_TYPE_SECURITY != payload->type) { uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize); VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size"); @@@ -112,7 -123,8 +123,8 @@@ *size = curSize; *outPayload = out; - OIC_LOG_V(DEBUG, TAG, "Payload Size: %zd Payload : %s \n", *size, *outPayload); + OIC_LOG_V(DEBUG, TAG, "Payload Size: %zd Payload : ", *size); + OIC_LOG_BUFFER(DEBUG, TAG, *outPayload, *size); return OC_STACK_OK; } @@@ -170,24 -182,10 +182,10 @@@ static int64_t checkError(int64_t err, static int64_t OCConvertSecurityPayload(OCSecurityPayload* payload, uint8_t* outPayload, size_t* size) { - CborEncoder encoder; - cbor_encoder_init(&encoder, outPayload, *size, 0); - - CborEncoder map; - int64_t err = cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength); - VERIFY_CBOR_SUCCESS(TAG, err, "Creating security map"); - - if (payload->securityData) - { - err |= cbor_encode_text_string(&map, payload->securityData, - strlen(payload->securityData)); - VERIFY_CBOR_SUCCESS(TAG, err, "Retrieving security data"); - } + memcpy(outPayload, payload->securityData, payload->payloadSize); + *size = payload->payloadSize; - err |= cbor_encoder_close_container(&encoder, &map); - VERIFY_CBOR_SUCCESS(TAG, err, "closing security map"); - exit: - return checkError(err, &encoder, outPayload, size); + return CborNoError; } static int64_t OCStringLLJoin(CborEncoder *map, char *type, OCStringLL *val) @@@ -360,14 -358,6 +358,14 @@@ static int64_t OCConvertDiscoveryPayloa VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding secure port value"); } +#ifdef TCP_ADAPTER + err |= cbor_encode_text_string(&policyMap, OC_RSRVD_TCP_PORT, + sizeof(OC_RSRVD_TCP_PORT) - 1); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port tag"); + err |= cbor_encode_uint(&policyMap, resource->tcpPort); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed adding tcp port value"); +#endif + err |= cbor_encoder_close_container(&linkMap, &policyMap); VERIFY_CBOR_SUCCESS(TAG, err, "Failed closing policy map"); diff --combined resource/csdk/stack/src/ocpayloadparse.c index f577a17,4763299..6373767 mode 100755,100644..100755 --- a/resource/csdk/stack/src/ocpayloadparse.c +++ b/resource/csdk/stack/src/ocpayloadparse.c @@@ -44,7 -44,7 +44,7 @@@ static OCStackResult OCParsePlatformPay static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *repParent, bool isRoot); static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *arrayVal); static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *arrayVal); - static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, CborValue * rrayVal); + static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, const uint8_t *payload, size_t size); OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType, const uint8_t *payload, size_t payloadSize) @@@ -55,7 -55,9 +55,9 @@@ VERIFY_PARAM_NON_NULL(TAG, outPayload, "Conversion of outPayload failed"); VERIFY_PARAM_NON_NULL(TAG, payload, "Invalid cbor payload value"); - OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu", payloadSize); + OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu of Payload Type: %d, Payload:", + payloadSize, payloadType); + OIC_LOG_BUFFER(DEBUG, TAG, payload, payloadSize); CborParser parser; CborValue rootValue; @@@ -81,7 -83,7 +83,7 @@@ result = OCParsePresencePayload(outPayload, &rootValue); break; case PAYLOAD_TYPE_SECURITY: - result = OCParseSecurityPayload(outPayload, &rootValue); + result = OCParseSecurityPayload(outPayload, payload, payloadSize); break; case PAYLOAD_TYPE_RD: result = OCRDCborToPayload(&rootValue, outPayload); @@@ -100,33 -102,18 +102,18 @@@ exit void OCFreeOCStringLL(OCStringLL* ll); - static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* rootValue) + static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, const uint8_t *payload, + size_t size) { - OCStackResult ret = OC_STACK_MALFORMED_RESPONSE; - CborError err; - char *securityData = NULL; - - VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid parameter"); - VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid cbor"); - - CborValue strVal; - - err = cbor_value_enter_container(rootValue, &strVal); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering container"); - if (cbor_value_is_text_string(&strVal)) + if (size > 0) { - size_t len = 0; - err = cbor_value_dup_text_string(&strVal, &securityData, &len, NULL); - VERIFY_CBOR_SUCCESS(TAG, err, "Failed reading security data"); - *outPayload = (OCPayload *)OCSecurityPayloadCreate(securityData); - VERIFY_PARAM_NON_NULL(TAG, *outPayload, "Invalid cbor"); - ret = OC_STACK_OK; + *outPayload = (OCPayload *)OCSecurityPayloadCreate(payload, size); } - - exit: - OICFree(securityData); - return ret; - + else + { + *outPayload = NULL; + } + return OC_STACK_OK; } static char* InPlaceStringTrim(char* str) @@@ -353,16 -340,6 +340,16 @@@ static OCStackResult OCParseDiscoveryPa VERIFY_CBOR_SUCCESS(TAG, err, "to find port value"); } +#ifdef TCP_ADAPTER + // TCP Port + err = cbor_value_map_find_value(&policyMap, OC_RSRVD_TCP_PORT, &curVal); + if (cbor_value_is_valid(&curVal)) + { + err = cbor_value_get_int(&curVal, (int *)&resource->tcpPort); + VERIFY_CBOR_SUCCESS(TAG, err, "to find tcp port value"); + } +#endif + err = cbor_value_advance(&resourceMap); VERIFY_CBOR_SUCCESS(TAG, err, "to advance resource map"); @@@ -379,8 -356,6 +366,8 @@@ } *outPayload = (OCPayload *)out; + OIC_LOG_PAYLOAD(DEBUG, *outPayload); + return OC_STACK_OK; exit: @@@ -409,6 -384,7 +396,8 @@@ static OCStackResult OCParseDevicePaylo CborValue curVal; // Resource Type err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag"); ++ if (cbor_value_is_valid(&curVal)) { err = OCParseStringLL(rootValue, OC_RSRVD_RESOURCE_TYPE, &out->types); @@@ -425,6 -401,7 +414,7 @@@ // Device ID size_t len = 0; err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag"); if (cbor_value_is_valid(&curVal)) { if (cbor_value_is_byte_string(&curVal)) @@@ -440,6 -417,7 +430,7 @@@ } // Device Name err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find device name tag"); if (cbor_value_is_valid(&curVal)) { err = cbor_value_dup_text_string(&curVal, &out->deviceName, &len, NULL); @@@ -447,6 -425,7 +438,7 @@@ } // Device Spec Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &curVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find spec ver tag"); if (cbor_value_is_valid(&curVal)) { err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL); @@@ -454,6 -433,7 +446,7 @@@ } // Data Model Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find data model ver tag"); if (cbor_value_is_valid(&curVal)) { err = cbor_value_dup_text_string(&curVal, &out->dataModelVersion, &len, NULL); @@@ -490,6 -470,7 +483,7 @@@ static OCStackResult OCParsePlatformPay // Platform ID err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find platform id tag"); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL); @@@ -497,6 -478,7 +491,7 @@@ } // MFG Name err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg name tag"); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL); @@@ -504,6 -486,7 +499,7 @@@ } // MFG URL err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg url tag"); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL); @@@ -511,6 -494,7 +507,7 @@@ } // Model Num err = cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find model num tag"); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL); @@@ -518,6 -502,7 +515,7 @@@ } // Date of Mfg err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg date tag"); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL); @@@ -525,6 -510,7 +523,7 @@@ } // Platform Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find platform ver tag"); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL); @@@ -532,6 -518,7 +531,7 @@@ } // OS Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find os ver tag"); if (cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL); @@@ -539,6 -526,7 +539,7 @@@ } // Hardware Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find hw ver tag"); if(cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL); @@@ -546,6 -534,7 +547,7 @@@ } // Firmware Version err = cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find fw ver tag"); if(cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL); @@@ -553,6 -542,7 +555,7 @@@ } // Support URL err = cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find support url tag"); if(cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL); @@@ -560,6 -550,7 +563,7 @@@ } // System Time err = cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find sys time tag"); if(cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL); @@@ -568,6 -559,7 +572,8 @@@ // Resource type err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag"); ++ if(cbor_value_is_valid(&repVal)) { err = cbor_value_dup_text_string(&repVal, &rt, &len, NULL); @@@ -576,6 -568,7 +582,8 @@@ // Interface Types err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &repVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find interface tag"); ++ if(cbor_value_is_valid(&repVal)) { err = OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &interfaces); @@@ -589,9 -582,7 +597,7 @@@ out->rt = rt; out->interfaces = interfaces; *outPayload = (OCPayload *)out; - OIC_LOG_PAYLOAD(DEBUG, *outPayload); - return OC_STACK_OK; } @@@ -610,6 -601,7 +616,7 @@@ static OCRepPayloadPropType DecodeCborT case CborIntegerType: return OCREP_PROP_INT; case CborDoubleType: + case CborFloatType: return OCREP_PROP_DOUBLE; case CborBooleanType: return OCREP_PROP_BOOL; @@@ -756,7 -748,19 +763,19 @@@ static CborError OCParseArrayFillArray( case OCREP_PROP_DOUBLE: if (dimensions[1] == 0) { - err = cbor_value_get_double(&insideArray, &(((double*)targetArray)[i])); + double *d = &(((double*)targetArray)[i]); + if (cbor_value_get_type(&insideArray) == CborDoubleType) + { + err = cbor_value_get_double(&insideArray, d); + } + else + { + /* must be float */ + float f; + err = cbor_value_get_float(&insideArray, &f); + if (!err) + *d = f; + } } else { @@@ -837,8 -841,8 +856,10 @@@ exit static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container) { void *arr = NULL; - OCRepPayloadPropType type; - size_t dimensions[MAX_REP_ARRAY_DEPTH]; ++ + OCRepPayloadPropType type = OCREP_PROP_NULL; + size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 }; ++ size_t dimTotal = 0; size_t allocSize = 0; bool res = true; @@@ -1067,6 -1071,7 +1088,7 @@@ static OCStackResult OCParseRepPayload( if (cbor_value_is_array(root)) { err = cbor_value_enter_container(root, &rootMap); + VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap"); } while (cbor_value_is_valid(&rootMap)) { @@@ -1085,6 -1090,7 +1107,7 @@@ if (cbor_value_is_map(&rootMap)) { err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag"); if (cbor_value_is_valid(&curVal)) { size_t len = 0; @@@ -1184,6 -1190,7 +1207,7 @@@ static OCStackResult OCParsePresencePay // Resource type name err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal); + VERIFY_CBOR_SUCCESS(TAG, err, "to find res type tag"); if (cbor_value_is_valid(&curVal)) { size_t len = 0; diff --combined resource/csdk/stack/src/ocresource.c index c5053cc,d109ba3..29dff7f --- a/resource/csdk/stack/src/ocresource.c +++ b/resource/csdk/stack/src/ocresource.c @@@ -111,29 -111,6 +111,29 @@@ static OCStackResult GetSecurePortInfo( return OC_STACK_OK; } +#ifdef TCP_ADAPTER +/* This method will retrieve the tcp port */ +static OCStackResult GetTCPPortInfo(OCDevAddr *endpoint, uint16_t *port) +{ + uint16_t p = 0; + + if (endpoint->adapter == OC_ADAPTER_IP) + { + if (endpoint->flags & OC_IP_USE_V4) + { + p = caglobals.tcp.ipv4.port; + } + else if (endpoint->flags & OC_IP_USE_V6) + { + p = caglobals.tcp.ipv6.port; + } + } + + *port = p; + return OC_STACK_OK; +} +#endif + /* * Function will extract 0, 1 or 2 filters from query. * More than 2 filters or unsupported filters will result in error. @@@ -314,29 -291,21 +314,29 @@@ OCStackResult BuildVirtualResourceRespo { return OC_STACK_INVALID_PARAM; } - uint16_t port = 0; + uint16_t securePort = 0; if (resourcePtr->resourceProperties & OC_SECURE) { - if (GetSecurePortInfo(devAddr, &port) != OC_STACK_OK) + if (GetSecurePortInfo(devAddr, &securePort) != OC_STACK_OK) { - port = 0; + securePort = 0; } } if (rdResponse) { - port = devAddr->port; + securePort = devAddr->port; } - OCDiscoveryPayloadAddResource(payload, resourcePtr, port); + uint16_t tcpPort = 0; +#ifdef TCP_ADAPTER + if (GetTCPPortInfo(devAddr, &tcpPort) != OC_STACK_OK) + { + tcpPort = 0; + } +#endif + + OCDiscoveryPayloadAddResource(payload, resourcePtr, securePort, tcpPort); return OC_STACK_OK; } @@@ -738,7 -707,12 +738,13 @@@ static OCStackResult HandleVirtualResou OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload; discPayload->sid = (char *)OICCalloc(1, UUID_STRING_SIZE); VERIFY_NON_NULL(discPayload->sid, ERROR, OC_STACK_NO_MEMORY); - memcpy(discPayload->sid, OCGetServerInstanceIDString(), UUID_STRING_SIZE); ++ + const char* uid = OCGetServerInstanceIDString(); - if(uid) ++ if (uid) + { + memcpy(discPayload->sid, uid, UUID_STRING_SIZE); + } + if (!resourceTypeQuery && interfaceQuery && (0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL))) { for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next) diff --combined resource/csdk/stack/src/ocstack.c index b306054,5ca4deb..6b18641 --- a/resource/csdk/stack/src/ocstack.c +++ b/resource/csdk/stack/src/ocstack.c @@@ -1353,7 -1353,7 +1353,7 @@@ void OCHandleResponse(const CAEndpoint_ { OIC_LOG(INFO, TAG, "Received a message without callbacks. Sending RESET"); SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY, - CA_MSG_RESET, 0, NULL, NULL, 0, NULL); + CA_MSG_RESET, 0, NULL, NULL, 0, NULL); } } @@@ -1676,11 -1676,6 +1676,11 @@@ void OCHandleRequests(const CAEndpoint_ { serverRequest.reqTotalSize = requestInfo->info.payloadSize; serverRequest.payload = (uint8_t *) OICMalloc(requestInfo->info.payloadSize); + if (!serverRequest.payload) + { + OIC_LOG(ERROR, TAG, "Allocation for payload failed."); + return; + } memcpy (serverRequest.payload, requestInfo->info.payload, requestInfo->info.payloadSize); } @@@ -1793,10 -1788,13 +1793,13 @@@ requestResult = HandleStackRequests (&serverRequest); // Send ACK to client as precursor to slow response - if(requestResult == OC_STACK_SLOW_RESOURCE) + if (requestResult == OC_STACK_SLOW_RESOURCE) { - SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_EMPTY, - CA_MSG_ACKNOWLEDGE,0, NULL, NULL, 0, NULL); + if (requestInfo->info.type == CA_MSG_CONFIRM) + { + SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_EMPTY, + CA_MSG_ACKNOWLEDGE,0, NULL, NULL, 0, NULL); + } } else if(requestResult != OC_STACK_OK) { @@@ -2041,7 -2039,7 +2044,7 @@@ OCStackResult OCInit1(OCMode mode, OCTr VERIFY_SUCCESS(result, OC_STACK_OK); #ifdef TCP_ADAPTER - CARegisterKeepAliveHandler(HandleKeepAliveConnCB, HandleKeepAliveDisconnCB); + CARegisterKeepAliveHandler(HandleKeepAliveConnCB); #endif #ifdef WITH_PRESENCE @@@ -2074,7 -2072,7 +2077,7 @@@ #endif #ifdef TCP_ADAPTER - if(result == OC_STACK_OK) + if (result == OC_STACK_OK) { result = InitializeKeepAlive(myStackMode); } @@@ -2296,15 -2294,7 +2299,15 @@@ static OCStackResult ParseRequestUri(co { colon = close + 1; } - adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_IP); + + if (istcp) + { + adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_TCP); + } + else + { + adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_IP); + } flags = (OCTransportFlags)(flags | OC_IP_USE_V6); } else @@@ -2316,15 -2306,14 +2319,15 @@@ end = (colon && colon < slash) ? colon : slash; if (istcp) - { // coap over tcp + { + // coap over tcp adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_TCP); } else { adapter = (OCTransportAdapter)(adapter | OC_ADAPTER_IP); - flags = (OCTransportFlags)(flags | OC_IP_USE_V4); } + flags = (OCTransportFlags)(flags | OC_IP_USE_V4); } else { // MAC address @@@ -2485,13 -2474,6 +2488,6 @@@ OCStackResult OCDoResource(OCDoHandle * char *resourceUri = NULL; char *resourceType = NULL; - // This validation is broken, but doesn't cause harm - size_t uriLen = strlen(requestUri ); - if ((result = verifyUriQueryLength(requestUri , uriLen)) != OC_STACK_OK) - { - goto exit; - } - /* * Support original behavior with address on resourceUri argument. */ @@@ -2742,11 -2724,9 +2738,11 @@@ OCStackResult OCCancel(OCDoHandle handl case OC_REST_OBSERVE: case OC_REST_OBSERVE_ALL: - OIC_LOG_V(INFO, TAG, "Canceling observation for resource %s", - clientCB->requestUri); - if (qos != OC_HIGH_QOS) + OIC_LOG_V(INFO, TAG, "Canceling observation for resource %s", clientCB->requestUri); + + CopyDevAddrToEndpoint(clientCB->devAddr, &endpoint); + + if ((endpoint.adapter & CA_ADAPTER_IP) && qos != OC_HIGH_QOS) { FindAndDeleteClientCB(clientCB); break; @@@ -2766,6 -2746,7 +2762,6 @@@ requestInfo.info.numOptions = numOptions + 1; requestInfo.info.resourceUri = OICStrdup (clientCB->requestUri); - CopyDevAddrToEndpoint(clientCB->devAddr, &endpoint); ret = OCSendRequest(&endpoint, &requestInfo); @@@ -3943,17 -3924,17 +3939,17 @@@ OCStackResult OCDoDirectPairing(OCDPDev OCDirectPairingCB resultCallback) { OIC_LOG(INFO, TAG, "Start OCDoDirectPairing"); - if(NULL == peer) + if(NULL == peer || NULL == pinNumber) { OIC_LOG(ERROR, TAG, "Invalid parameters"); return OC_STACK_INVALID_PARAM; } - -- if(NULL == resultCallback) ++ if (NULL == resultCallback) { - OIC_LOG(ERROR, TAG, "Invalid parameters"); + OIC_LOG(ERROR, TAG, "Invalid callback"); return OC_STACK_INVALID_CALLBACK; } + gDirectpairingCallback = resultCallback; return DPDirectPairing((OCDirectPairingDev_t*)peer, (OicSecPrm_t)pmSel, pinNumber, DirectPairingCB); @@@ -4262,11 -4243,7 +4258,11 @@@ void insertResourceType(OCResource *res previous = pointer; pointer = pointer->next; } - previous->next = resourceType; + + if (previous) + { + previous->next = resourceType; + } } resourceType->next = NULL; diff --combined resource/csdk/stack/test/stacktests.cpp index a5b9fe4,037edcd..a5b9fe4 mode 100755,100644..100644 --- a/resource/csdk/stack/test/stacktests.cpp +++ b/resource/csdk/stack/test/stacktests.cpp @@@ -453,7 -453,7 +453,7 @@@ TEST(StackResource, CreateResourceBadUr OIC_LOG(INFO, TAG, "Starting CreateResourceBadUri test"); InitStack(OC_SERVER); - const char *uri65 = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKL"; + const char *uri257 = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVW"; OCResourceHandle handle; @@@ -476,7 -476,7 +476,7 @@@ EXPECT_EQ(OC_STACK_INVALID_URI, OCCreateResource(&handle, "core.led", "core.rw", - uri65, //"/a/led", + uri257, //"/a/led", 0, 0, OC_DISCOVERABLE|OC_OBSERVABLE)); diff --combined resource/docs/cpp-doc/Doxyfile index 989ee66,112c4b3..f5e55e8 --- a/resource/docs/cpp-doc/Doxyfile +++ b/resource/docs/cpp-doc/Doxyfile @@@ -660,30 -660,27 +660,26 @@@ WARN_LOGFILE = ./doxygen.lo # with spaces. INPUT = . \ - ../include/OCApi.h \ - ../include/OCPlatform.h \ - ../include/OCRepresentation.h \ - ../include/OCResourceRequest.h \ - ../include/OCResourceResponse.h \ - ../include/OCResource.h \ - ../include/OCProvisioningManager.h \ - ../csdk/stack/include/octypes.h \ - ../csdk/stack/include/ocstackconfig.h \ + ../../include/OCApi.h \ + ../../include/OCPlatform.h \ + ../../include/OCRepresentation.h \ + ../../include/OCResourceRequest.h \ + ../../include/OCResourceResponse.h \ + ../../include/OCResource.h \ + ../../include/OCProvisioningManager.h \ + ../../csdk/stack/include/octypes.h \ + ../../csdk/stack/include/ocstackconfig.h \ guides \ - ../../service/resource-encapsulation/include \ - ../../service/resource-hosting/include \ - ../../service/resource-container/include \ - ../../service/resource-container/bundle-api/include \ - ../../service/things-manager/sdk/inc/ThingsConfiguration.h \ - ../../service/things-manager/sdk/inc/ThingsMaintenance.h \ - ../../service/easy-setup/mediator/richsdk/inc/ \ - ../../service/easy-setup/enrollee/inc \ - ../../service/easy-setup/enrollee/src/softap.h \ - ../../service/easy-setup/inc \ - ../../service/resource-directory/include \ - ../../service/scene-manager/include \ - + ../../../service/resource-encapsulation/include \ + ../../../service/resource-hosting/include \ + ../../../service/resource-container/include \ + ../../../service/resource-container/bundle-api/include \ + ../../../service/things-manager/sdk/inc/ThingsConfiguration.h \ + ../../../service/things-manager/sdk/inc/ThingsMaintenance.h \ + ../../../service/easy-setup/mediator/richsdk/inc/ \ + ../../../service/easy-setup/inc \ + ../../../service/scene-manager/include \ - # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built @@@ -1708,7 -1705,7 +1704,7 @@@ UML_LOOK = N # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more -# managable. Set this to 0 for no limit. Note that the threshold may be +# manageable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 diff --combined resource/examples/SConscript index e14fa05,9fad828..5d84295 --- a/resource/examples/SConscript +++ b/resource/examples/SConscript @@@ -50,12 -50,7 +50,12 @@@ if target_os not in ['windows', 'winrt' examples_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) examples_env.AppendUnique(RPATH = [env.get('BUILD_DIR')]) -examples_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'coap']) +examples_env.PrependUnique(LIBS = ['coap']) +examples_env.AppendUnique(LIBS = ['connectivity_abstraction']) +examples_env.AppendUnique(LIBS = ['oc_logger']) +examples_env.AppendUnique(LIBS = ['octbstack']) +examples_env.AppendUnique(LIBS = ['oc']) + if env.get('SECURED') == '1': examples_env.AppendUnique(LIBS = ['tinydtls']) @@@ -93,9 -88,9 +93,9 @@@ devicediscoveryclient = examples_env.Pr threadingsample = examples_env.Program('threadingsample', 'threadingsample.cpp') clientjson = examples_env.Install(env.get('BUILD_DIR') + '/resource/examples/', - env.get('SRC_DIR') + '/resource/examples/' + 'oic_svr_db_client.json') + env.get('SRC_DIR') + '/resource/examples/' + 'oic_svr_db_client.dat') serverjson = examples_env.Install(env.get('BUILD_DIR') + '/resource/examples/', - env.get('SRC_DIR') + '/resource/examples/' + 'oic_svr_db_server.json') + env.get('SRC_DIR') + '/resource/examples/' + 'oic_svr_db_server.dat') Alias("examples", [simpleserver, simpleclient, simpleserverHQ, simpleclientHQ, fridgeserver, fridgeclient, diff --combined service/easy-setup/enrollee/arduino/resourcehandler.cpp index 7f2fc8e,6168606..0d32276 mode 100755,100644..100755 --- a/service/easy-setup/enrollee/arduino/resourcehandler.cpp +++ b/service/easy-setup/enrollee/arduino/resourcehandler.cpp @@@ -58,9 -58,9 +58,9 @@@ OCEntityHandlerResult ProcessPutRequest OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload); OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest); - ResourceEventCallback gNetworkInfoProvEventCb = NULL; + ESEnrolleeResourceEventCallback gNetworkInfoProvEventCb = NULL; - void RegisterResourceEventCallBack(ResourceEventCallback cb) + void RegisterResourceEventCallBack(ESEnrolleeResourceEventCallback cb) { gNetworkInfoProvEventCb = cb; } @@@ -166,24 -166,6 +166,24 @@@ OCEntityHandlerResult ProcessPostReques return ehResult; } + char* tnn; + if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_TNN, &tnn)) + { + OICStrcpy(gProvResource.tnn, sizeof(gProvResource.tnn), tnn); + OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.tnn %s", gProvResource.tnn); + + gProvResource.ps = ES_PS_PROVISIONING_COMPLETED; + } + + char* cd; + if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd)) + { + OICStrcpy(gProvResource.cd, sizeof(gProvResource.cd), cd); + OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.cd %s", gProvResource.cd); + } + + OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.ps %lld", gProvResource.ps); + int64_t tr; if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_TR, &tr)) { @@@ -205,7 -187,6 +205,7 @@@ } else { + gProvResource.tr = ES_PS_TRIGGER_INIT_VALUE; OIC_LOG(ERROR, ES_RH_TAG, "gNetworkInfoProvEventCb is NULL." "Network handler not registered. Failed to connect to the network"); ehResult = OC_EH_ERROR; @@@ -223,6 -204,29 +223,6 @@@ OIC_LOG(DEBUG, ES_RH_TAG, "Provisioning the network information to the Enrollee."); } - OICStrcpy(gProvResource.tnn, sizeof(gProvResource.tnn), ""); - OICStrcpy(gProvResource.cd, sizeof(gProvResource.cd), ""); - - char* tnn; - if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_TNN, &tnn)) - { - OICStrcpy(gProvResource.tnn, sizeof(gProvResource.tnn), tnn); - OIC_LOG(INFO, ES_RH_TAG, "got ssid"); - } - - OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.tnn %s", gProvResource.tnn); - - char* cd; - if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd)) - { - OICStrcpy(gProvResource.cd, sizeof(gProvResource.cd), cd); - OIC_LOG(INFO, ES_RH_TAG, "got password"); - }OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.cd %s", gProvResource.cd); - - gProvResource.ps = ES_PS_PROVISIONING_COMPLETED; - - OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.ps %lld", gProvResource.ps); - OCRepPayload *getResp = constructResponse(ehRequest); if (!getResp) { diff --combined service/easy-setup/enrollee/src/easysetupcallbacks.h index bf552f0,f21c1e1..dc8303b --- a/service/easy-setup/enrollee/src/easysetupcallbacks.h +++ b/service/easy-setup/enrollee/src/easysetupcallbacks.h @@@ -21,7 -21,7 +21,7 @@@ /** * @file * -- * This file contains private internal callback function ++ * This file contains private internal callback function * prototypes for Easy setup [Enrollee] */ @@@ -38,26 -38,26 +38,26 @@@ extern "C" // Private internal callback function prototypes for Easy setup [Enrollee] //----------------------------------------------------------------------------- - /* + /* * Callback for on boarding */ - void OnboardingCallback(ESResult esResult); + void ESOnboardingCallback(ESResult esResult); - /* + /* * Callback for provisioning */ - void ProvisioningCallback(ESResult SSSS); + void ESProvisioningCallback(ESResult SSSS); - /* + /* * Callback for on boarding target Network */ - void OnboardingCallbackTargetNet(ESResult esResult); + void ESOnboardingCallbackTargetNet(ESResult esResult); - /* - * Function for validating the parameter for InitEasySetup API + /* + * Function for validating the parameter for ESInitEnrollee API */ - static bool ValidateParam(OCConnectivityType networkType, const char *ssid, const char *passwd, - EventCallback cb); + static bool ESEnrolleeValidateParam(OCConnectivityType networkType, const char *ssid, + const char *passwd, ESEnrolleeEventCallback cb); #ifdef __cplusplus } diff --combined service/easy-setup/enrollee/src/resourcehandler.c index f3856f2,833e31e..249d586 mode 100755,100644..100755 --- a/service/easy-setup/enrollee/src/resourcehandler.c +++ b/service/easy-setup/enrollee/src/resourcehandler.c @@@ -58,9 -58,9 +58,9 @@@ OCEntityHandlerResult ProcessPutRequest OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload); OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest); - ResourceEventCallback gNetworkInfoProvEventCb = NULL; + ESEnrolleeResourceEventCallback gNetworkInfoProvEventCb = NULL; - void RegisterResourceEventCallBack(ResourceEventCallback cb) + void RegisterResourceEventCallBack(ESEnrolleeResourceEventCallback cb) { gNetworkInfoProvEventCb = cb; } @@@ -166,24 -166,6 +166,24 @@@ OCEntityHandlerResult ProcessPostReques return ehResult; } + char* tnn; + if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_TNN, &tnn)) + { + OICStrcpy(gProvResource.tnn, sizeof(gProvResource.tnn), tnn); + OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.tnn %s", gProvResource.tnn); + + gProvResource.ps = ES_PS_PROVISIONING_COMPLETED; + } + + char* cd; + if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd)) + { + OICStrcpy(gProvResource.cd, sizeof(gProvResource.cd), cd); + OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.cd %s", gProvResource.cd); + } + + OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.ps %lld", gProvResource.ps); + int64_t tr; if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_TR, &tr)) { @@@ -205,7 -187,6 +205,7 @@@ } else { + gProvResource.tr = ES_PS_TRIGGER_INIT_VALUE; OIC_LOG(ERROR, ES_RH_TAG, "gNetworkInfoProvEventCb is NULL." "Network handler not registered. Failed to connect to the network"); ehResult = OC_EH_ERROR; @@@ -223,6 -204,29 +223,6 @@@ OIC_LOG(DEBUG, ES_RH_TAG, "Provisioning the network information to the Enrollee."); } - OICStrcpy(gProvResource.tnn, sizeof(gProvResource.tnn), ""); - OICStrcpy(gProvResource.cd, sizeof(gProvResource.cd), ""); - - char* tnn; - if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_TNN, &tnn)) - { - OICStrcpy(gProvResource.tnn, sizeof(gProvResource.tnn), tnn); - OIC_LOG(INFO, ES_RH_TAG, "got ssid"); - } - - OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.tnn %s", gProvResource.tnn); - - char* cd; - if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd)) - { - OICStrcpy(gProvResource.cd, sizeof(gProvResource.cd), cd); - OIC_LOG(INFO, ES_RH_TAG, "got password"); - }OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.cd %s", gProvResource.cd); - - gProvResource.ps = ES_PS_PROVISIONING_COMPLETED; - - OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.ps %lld", gProvResource.ps); - OCRepPayload *getResp = constructResponse(ehRequest); if (!getResp) { diff --combined service/easy-setup/enrollee/src/softap.c index 8784350,4199e9a..00df2a9 --- a/service/easy-setup/enrollee/src/softap.c +++ b/service/easy-setup/enrollee/src/softap.c @@@ -20,12 -20,12 +20,12 @@@ void ESCreateSoftapCallback(int result, const char *ip, const char* mac_addr, const char* device_name ); - NetworkEventCallback gCallback; + ESEnrolleeNetworkEventCallback gCallback; /** * It will return Device which is creating Soft AP. * i.e.Enrollee or Mediator. -- * This decesion is based on, what is the value set for ES_SOFTAP_MODE in build command as well as ++ * This decision is based on, what is the value set for ES_SOFTAP_MODE in build command as well as * in iotivity.spec file. */ DeviceRole ESSoftapHost() @@@ -76,7 -76,7 +76,7 @@@ void ESCreateSoftapCallback(int result /** * This API will create the softap at enrollee */ - void ESCreateSoftap(const char * ssid, const char* passwd, NetworkEventCallback cb) + void ESCreateSoftap(const char * ssid, const char* passwd, ESEnrolleeNetworkEventCallback cb) { gCallback = cb; diff --combined service/easy-setup/mediator/csdk/unittests/MediatorCSDKTest.cpp index 057a392,9c0c57a..e0aded4 --- a/service/easy-setup/mediator/csdk/unittests/MediatorCSDKTest.cpp +++ b/service/easy-setup/mediator/csdk/unittests/MediatorCSDKTest.cpp @@@ -53,8 -53,9 +53,9 @@@ class MediatorCSDKTest: public TestWith }; //callbacks - void OCProvisioningStatusCallback(EasySetupInfo *easySetupInfo) { - OC_UNUSED(easySetupInfo); -void OCProvisioningStatusCallback(EasySetupInfo *easySetupInfo) ++void OCProvisioningStatusCallback(EasySetupInfo *easySetupInfo) + { + (void) easySetupInfo; } /* Test cases for prov_adapter*/ diff --combined service/easy-setup/mediator/richsdk/SConscript index 54c1875,f631761..1624ff1 --- a/service/easy-setup/mediator/richsdk/SConscript +++ b/service/easy-setup/mediator/richsdk/SConscript @@@ -63,7 -63,7 +63,7 @@@ if target_os not in ['windows', 'winrt' easy_setup_env.AppendUnique(CXXFLAGS = ['-Wall', '-std=c++0x']) if target_os in ['linux']: -- easy_setup_env.AppendUnique(LIBS = ['pthread', 'dl']) ++ easy_setup_env.AppendUnique(LIBS = ['pthread', 'dl', 'coap']) if target_os in ['android']: easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) @@@ -71,12 -71,7 +71,7 @@@ easy_setup_env.AppendUnique(LIBPATH = [env.get('SRC_DIR')+'/android/android_api/base/libs/armeabi']) easy_setup_env.AppendUnique(RPATH = [env.get('BUILD_DIR')]) easy_setup_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions']) - easy_setup_env.PrependUnique(LIBS = ['coap']) - easy_setup_env.AppendUnique(LIBS = ['connectivity_abstraction']) - easy_setup_env.AppendUnique(LIBS = ['oc_logger']) - easy_setup_env.AppendUnique(LIBS = ['octbstack']) - easy_setup_env.AppendUnique(LIBS = ['oc']) - easy_setup_env.AppendUnique(LIBS = ['gnustl_shared']) + easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'gnustl_shared']) if env.get('SECURED') == '1': easy_setup_env.AppendUnique(LIBS = ['ocpmapi','ocprovision']) if not env.get('RELEASE'): @@@ -86,12 -81,7 +81,7 @@@ if target_os in ['linux'] easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) easy_setup_env.AppendUnique(RPATH = [env.get('BUILD_DIR')]) easy_setup_env.AppendUnique(CXXFLAGS = ['-pthread']) - easy_setup_env.PrependUnique(LIBS = ['coap']) - easy_setup_env.AppendUnique(LIBS = ['connectivity_abstraction']) - easy_setup_env.AppendUnique(LIBS = ['oc_logger']) - easy_setup_env.AppendUnique(LIBS = ['octbstack']) - easy_setup_env.AppendUnique(LIBS = ['oc']) - easy_setup_env.AppendUnique(LIBS = ['pthread']) - easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'pthread', 'connectivity_abstraction']) ++ easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger']) if env.get('SECURED') == '1': easy_setup_env.AppendUnique(LIBS = ['ocpmapi', 'ocprovision']) diff --combined service/easy-setup/mediator/richsdk/unittests/SConscript index 0b27415,480df19..099eddb --- a/service/easy-setup/mediator/richsdk/unittests/SConscript +++ b/service/easy-setup/mediator/richsdk/unittests/SConscript @@@ -77,16 -77,16 +77,13 @@@ if target_os not in ['windows', 'winrt' if env.get('SECURED') == '1': -- mediator_rich_test_env.PrependUnique(LIBS = ['tinydtls','ocprovision', 'ocpmapi']) ++ mediator_rich_test_env.PrependUnique(LIBS = ['tinydtls','ocprovision', 'ocpmapi', 'timer']) mediator_rich_test_env.PrependUnique(LIBS = [ - 'coap', - 'connectivity_abstraction', - 'oc_logger', - 'oc_logger_core', - 'octbstack', - 'oc', + 'ESMediatorRich', + 'oc', + 'octbstack', + 'oc_logger', - 'oc_logger_core', - 'connectivity_abstraction', - 'coap', - 'ESMediatorRich', gtest, gtest_main]) @@@ -105,4 -105,4 +102,4 @@@ if env.get('TEST') == '1' target_os = env.get('TARGET_OS') if target_os == 'linux': from tools.scons.RunTest import * - run_test(mediator_rich_test_env, '', 'service/easy-setup/mediator/richsdk/unittests/mediator_richsdk_test') + run_test(mediator_rich_test_env, '', 'service/easy-setup/mediator/richsdk/unittests/mediator_richsdk_test') diff --combined service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript index a792b7a,ef24ed2..cc66800 --- a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript +++ b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript @@@ -42,11 -42,11 +42,11 @@@ env.AppendUnique(CPPDEFINES = ['CPP_MED if target_os not in ['windows', 'winrt']: mediator_env.AppendUnique(CXXFLAGS = ['-Wall', '-std=c++0x']) -- ++ mediator_env.PrependUnique(CPPPATH = [ env.get('SRC_DIR') + '/resource/include', env.get('SRC_DIR') + '/resource/oc_logger/include', -- env.get('SRC_DIR') + '/resource/csdk/ocmalloc/include', ++ env.get('SRC_DIR') + '/resource/csdk/ocmalloc/include', env.get('SRC_DIR') + '/resource/csdk/stack/include', env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include', env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/internal', @@@ -58,14 -58,7 +58,11 @@@ env.get('SRC_DIR') + '/service/easy-setup/mediator/richsdk/src', env.get('SRC_DIR') + '/service/easy-setup/inc']) - mediator_env.PrependUnique(LIBS = ['coap']) - mediator_env.AppendUnique(LIBS = ['connectivity_abstraction']) - mediator_env.AppendUnique(LIBS = ['oc_logger']) - mediator_env.AppendUnique(LIBS = ['octbstack']) - mediator_env.AppendUnique(LIBS = ['oc']) - mediator_env.AppendUnique(LIBS = ['pthread']) - mediator_env.AppendUnique(LIBS = ['ESMediatorRich']) -mediator_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'pthread', 'connectivity_abstraction', 'coap', 'ESMediatorRich']) ++if env.get('SECURED') == '1': ++ mediator_env.PrependUnique(LIBS = ['tinydtls', 'timer']) ++ ++mediator_env.PrependUnique(LIBS = ['ESMediatorRich', 'oc', 'octbstack', 'oc_logger']) + if env.get('SECURED') == '1': mediator_env.PrependUnique(LIBS = ['ocpmapi', 'ocprovision']) diff --combined service/resource-container/src/ResourceContainerImpl.cpp index 1cbbd62,ff04522..5042f0c --- a/service/resource-container/src/ResourceContainerImpl.cpp +++ b/service/resource-container/src/ResourceContainerImpl.cpp @@@ -421,7 -421,7 +421,7 @@@ namespace OI } } - OIC_LOG_V(INFO, CONTAINER_TAG, "Container get request for %s finished, %d attributes",strResourceUri.c_str(), attr.size()); + OIC_LOG_V(INFO, CONTAINER_TAG, "Container get request for %s finished, %zu attributes",strResourceUri.c_str(), attr.size()); return RCSGetResponse::create(std::move(attr), 200); } @@@ -433,7 -433,7 +433,7 @@@ std::list lstAttributes; std::string strResourceUri = request.getResourceUri(); - OIC_LOG_V(INFO, CONTAINER_TAG, "Container set request for %s, %d attributes",strResourceUri.c_str(), attributes.size()); + OIC_LOG_V(INFO, CONTAINER_TAG, "Container set request for %s, %zu attributes",strResourceUri.c_str(), attributes.size()); if (m_mapServers.find(strResourceUri) != m_mapServers.end() && m_mapResources.find(strResourceUri) != m_mapResources.end()) @@@ -816,11 -816,10 +816,10 @@@ { OIC_LOG_V(DEBUG, CONTAINER_TAG, "Discover input resource %s", outputResourceUri.c_str()); auto foundOutputResource = m_mapResources.find(outputResourceUri); - // auto resourceProperty = foundOutputResource->second->m_mapResourceProperty; resourceInfo info; m_config->getResourceConfiguration(foundOutputResource->second->m_bundleId, - foundOutputResource->second->m_name, &info); + outputResourceUri, &info); map< string, vector< map< string, string > > > resourceProperty = info.resourceProperty; try