[Iotcon] Fix preventing crash. 82/162582/4
authorLukasz Bardeli <l.bardeli@samsung.com>
Mon, 4 Dec 2017 14:49:52 +0000 (15:49 +0100)
committerLukasz Bardeli <l.bardeli@samsung.com>
Mon, 4 Dec 2017 14:49:52 +0000 (15:49 +0100)
Fix with adding id to vector to hold information about possible remote resources.
If id is present in vector then map with remote resources is checked if
pointer exist. If not then callback is ignored

[Verification] Tested in chrome console. TCT auto tests 100%

Change-Id: I2032e0c8c93846ef84ac871944bbf326b8eafac7
Signed-off-by: Lukasz Bardeli <l.bardeli@samsung.com>
src/iotcon/iotcon_client_manager.cc
src/iotcon/iotcon_client_manager.h
src/iotcon/iotcon_instance.cc
src/iotcon/iotcon_utils.h

index bfa83fe903812ac6025a7c1a1b5936cad3f4a372..e34193f3553b62b0d183794e85e5baf85e9d5f54 100644 (file)
@@ -43,6 +43,42 @@ IotconClientManager& IotconClientManager::GetInstance() {
   return instance;
 }
 
+long long* IotconClientManager::Add(long long id) {
+  ScopeLogger();
+  ids_.push_back(new long long(id));
+  return ids_.back();
+}
+
+void IotconClientManager::Remove(long long id) {
+  ScopeLogger();
+  auto it = ids_.end();
+  while (it > ids_.begin()) {
+    --it;
+    if (**it == id) {
+      ids_.erase(it);
+      return;
+    }
+  }
+}
+
+bool IotconClientManager::IfExists(long long id) {
+  ScopeLogger();
+  for (auto v : ids_) {
+    if (*v == id) {
+      return true;
+    }
+  }
+  return false;
+}
+
+FoundRemoteInfoPtr IotconClientManager::GetFoundRemoteInfoPtr(long long id) {
+  ScopeLogger();
+  if (IfExists(id)) {
+    return remotes_map_.at(id);
+  }
+  return nullptr;
+}
+
 void IotconClientManager::PresenceHandler(iotcon_presence_h presence, iotcon_error_e err,
                                           iotcon_presence_response_h response, void* user_data) {
   ScopeLogger();
@@ -118,6 +154,7 @@ picojson::value IotconClientManager::RemoveRemoteResource(FoundRemoteInfoPtr ptr
   ptr->ref_count--;
   if (ptr->ref_count <= 0) {
     LoggerD("Handle not needed anymore, removing from map");
+    Remove(ptr->id);
     remotes_map_.erase(ptr->id);
     return PrepareManageIdAnswer(false);
   }
index 56bd87ed4ca54567fdbc8c8fb00456d02ef5fb04..f3fccefc5821e9c41cf72f4c33e9b69a44c357c7 100644 (file)
@@ -42,6 +42,10 @@ class IotconClientManager {
   picojson::value RemoveRemoteResource(FoundRemoteInfoPtr ptr);
   common::TizenResult GetRemoteById(long long id, FoundRemoteInfoPtr* res_pointer) const;
   picojson::value PrepareManageIdAnswer(bool keep_id, long long id = 0);
+  long long* Add(long long id);
+  void Remove(long long id);
+  bool IfExists(long long id);
+  FoundRemoteInfoPtr GetFoundRemoteInfoPtr(long long id);
 
  private:
   IotconClientManager() = default;
@@ -55,6 +59,7 @@ class IotconClientManager {
 
   PresenceMap presence_map_;
   FoundRemotesMap remotes_map_;
+  IdVector ids_;
 };
 
 }  // namespace iotcon
index c71deebb9aa3c5325624a816bfccd26c196c2ea4..1ca926dd4d61f7d8a27177d143c83de1408a62d6 100644 (file)
@@ -936,9 +936,12 @@ common::TizenResult IotconInstance::RemoteResourceMethodDelete(const picojson::o
 static void ObserveCallback(iotcon_remote_resource_h resource, iotcon_error_e err,
                             int sequence_number, iotcon_response_h response, void* user_data) {
   ScopeLogger();
-  FoundRemoteInfo* ptr = static_cast<FoundRemoteInfo*>(user_data);
+  long long* id = static_cast<long long*>(user_data);
+
+  FoundRemoteInfoPtr ptr = IotconClientManager::GetInstance().GetFoundRemoteInfoPtr(*id);
+
   if (nullptr == ptr) {
-    LoggerE("ObserveCallback() failed.  Ignoring callback");
+    LoggerE("ObserveCallback() failed. Ignoring callback");
     return;
   }
 
@@ -1015,14 +1018,17 @@ common::TizenResult IotconInstance::RemoteResourceStartObserving(const picojson:
     }
   }
 
-  result = IotconUtils::ConvertIotconError(iotcon_remote_resource_observe_register(
-      ptr->handle, observe_policy, query, ObserveCallback, ptr.get()));
+  picojson::value ret = IotconClientManager::GetInstance().StoreRemoteResource(ptr);
+  result = IotconUtils::ConvertIotconError(
+      iotcon_remote_resource_observe_register(ptr->handle, observe_policy, query, ObserveCallback,
+                                              IotconClientManager::GetInstance().Add(ptr->id)));
   if (!result) {
+    IotconClientManager::GetInstance().RemoveRemoteResource(ptr);
     return result;
   }
 
   observing_started_ = true;
-  return common::TizenSuccess{IotconClientManager::GetInstance().StoreRemoteResource(ptr)};
+  return common::TizenSuccess{ret};
 }
 
 common::TizenResult IotconInstance::RemoteResourceStopObserving(const picojson::object& args) {
@@ -1078,9 +1084,12 @@ common::TizenResult IotconInstance::RemoteResourceStopObserving(const picojson::
 static void RepresentationChangedCallback(iotcon_remote_resource_h resource,
                                           iotcon_representation_h representation, void* user_data) {
   ScopeLogger();
-  FoundRemoteInfo* ptr = static_cast<FoundRemoteInfo*>(user_data);
+  long long* id = static_cast<long long*>(user_data);
+
+  FoundRemoteInfoPtr ptr = IotconClientManager::GetInstance().GetFoundRemoteInfoPtr(*id);
+
   if (nullptr == ptr) {
-    LoggerE("RepresentationChangeCallback() failed.  Ignoring callback");
+    LoggerE("RepresentationChangeCallback() failed. Ignoring callback");
     return;
   }
 
@@ -1121,14 +1130,16 @@ common::TizenResult IotconInstance::RemoteResourceStartCaching(const picojson::o
     Post(kRemoteResourceCacheChangeListener, common::TizenSuccess{response});
   };
 
-  result = IotconUtils::ConvertIotconError(
-      iotcon_remote_resource_start_caching(ptr->handle, RepresentationChangedCallback, ptr.get()));
+  picojson::value ret = IotconClientManager::GetInstance().StoreRemoteResource(ptr);
+  result = IotconUtils::ConvertIotconError(iotcon_remote_resource_start_caching(
+      ptr->handle, RepresentationChangedCallback, IotconClientManager::GetInstance().Add(ptr->id)));
   if (!result) {
+    IotconClientManager::GetInstance().RemoveRemoteResource(ptr);
     return result;
   }
 
   caching_started_ = true;
-  return common::TizenSuccess{IotconClientManager::GetInstance().StoreRemoteResource(ptr)};
+  return common::TizenSuccess{ret};
 }
 
 common::TizenResult IotconInstance::RemoteResourceStopCaching(const picojson::object& args) {
@@ -1164,9 +1175,12 @@ common::TizenResult IotconInstance::RemoteResourceStopCaching(const picojson::ob
 static void MonitoringCallback(iotcon_remote_resource_h resource,
                                iotcon_remote_resource_state_e state, void* user_data) {
   ScopeLogger();
-  FoundRemoteInfo* ptr = static_cast<FoundRemoteInfo*>(user_data);
+  long long* id = static_cast<long long*>(user_data);
+
+  FoundRemoteInfoPtr ptr = IotconClientManager::GetInstance().GetFoundRemoteInfoPtr(*id);
+
   if (nullptr == ptr) {
-    LoggerE("MonitoringCallback() failed.  Ignoring callback");
+    LoggerE("MonitoringCallback() failed. Ignoring callback");
     return;
   }
 
@@ -1201,13 +1215,15 @@ common::TizenResult IotconInstance::RemoteResourceSetResourceStateChangeListener
     Post(kRemoteResourceStateChangeListener, common::TizenSuccess{response});
   };
 
-  result = IotconUtils::ConvertIotconError(
-      iotcon_remote_resource_start_monitoring(ptr->handle, MonitoringCallback, ptr.get()));
+  picojson::value ret = IotconClientManager::GetInstance().StoreRemoteResource(ptr);
+  result = IotconUtils::ConvertIotconError(iotcon_remote_resource_start_monitoring(
+      ptr->handle, MonitoringCallback, IotconClientManager::GetInstance().Add(ptr->id)));
   if (!result) {
+    IotconClientManager::GetInstance().RemoveRemoteResource(ptr);
     return result;
   }
   monitoring_started_ = true;
-  return common::TizenSuccess{IotconClientManager::GetInstance().StoreRemoteResource(ptr)};
+  return common::TizenSuccess{ret};
 }
 
 common::TizenResult IotconInstance::RemoteResourceUnsetResourceStateChangeListener(
index aa37b5dc04b1053ca68497c0ccc2e77238c5a77c..47a75c9e80a1f6ad03e611618e00d86ca3857bb5 100644 (file)
@@ -78,6 +78,7 @@ typedef std::shared_ptr<PresenceEvent> PresenceEventPtr;
 typedef std::map<long long, PresenceEventPtr> PresenceMap;
 typedef std::shared_ptr<FoundRemoteInfo> FoundRemoteInfoPtr;
 typedef std::map<long long, FoundRemoteInfoPtr> FoundRemotesMap;
+typedef std::vector<long long*> IdVector;
 
 using ResponsePtr = std::shared_ptr<std::remove_pointer<iotcon_response_h>::type>;