revise AittOption
authorYoungjae Shin <yj99.shin@samsung.com>
Fri, 16 Dec 2022 03:08:56 +0000 (12:08 +0900)
committerYoungjae Shin <yj99.shin@samsung.com>
Thu, 9 Mar 2023 02:14:41 +0000 (11:14 +0900)
- separate constructor behavior into constructing and applying option
- revise option usage on Aitt C API
- add test case

include/AITT.h
include/AittException.h
include/AittTypes.h
include/aitt_c.h
src/AITT.cc
src/aitt_c.cc
tests/AITT_test.cc

index a384966..dd020eb 100644 (file)
@@ -27,6 +27,7 @@
 
 #define AITT_LOCALHOST "127.0.0.1"
 #define AITT_PORT 1883
+#define AITT_MUST_CALL_READY "Must Call Ready() First"
 
 namespace aitt {
 
@@ -36,10 +37,13 @@ class API AITT {
           std::function<void(MSG *msg, const void *data, const int datalen, void *user_data)>;
     using ConnectionCallback = std::function<void(AITT &, int, void *user_data)>;
 
+    explicit AITT(const std::string notice);
     explicit AITT(const std::string &id, const std::string &ip_addr,
           AittOption option = AittOption(false, false));
     virtual ~AITT(void);
 
+    void Ready(const std::string &id, const std::string &ip_addr,
+          AittOption option = AittOption(false, false));
     void SetWillInfo(const std::string &topic, const void *data, const int datalen, AittQoS qos,
           bool retain);
     void SetConnectionCallback(ConnectionCallback cb, void *user_data = nullptr);
index 688ac27..65dd990 100644 (file)
@@ -31,6 +31,7 @@ class AittException : public std::exception {
         MQTT_ERR,
         NO_DATA_ERR,
         RESOURCE_BUSY_ERR,
+        ALREADY,
     };
 
     AittException(ErrCode err_code);
index 88a1d3e..2f81371 100644 (file)
@@ -70,6 +70,7 @@ enum AittConnectionState {
 #define TIZEN_ERROR_PERMISSION_DENIED -EACCES
 #define TIZEN_ERROR_RESOURCE_BUSY -EBUSY
 #define TIZEN_ERROR_INVALID_PARAMETER -EINVAL
+#define TIZEN_ERROR_ALREADY_IN_PROGRESS -EALREADY
 #define TIZEN_ERROR_TIMED_OUT (-1073741824LL + 1)
 #define TIZEN_ERROR_NOT_SUPPORTED (-1073741824LL + 2)
 #define TIZEN_ERROR_AITT -0x04020000
@@ -81,9 +82,10 @@ enum AittError {
     AITT_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
     AITT_ERROR_RESOURCE_BUSY = TIZEN_ERROR_RESOURCE_BUSY,         /**< Device or resource busy */
     AITT_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
-    AITT_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT,                 /**< Time out */
-    AITT_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED,         /**< Not supported */
-    AITT_ERROR_UNKNOWN = TIZEN_ERROR_AITT | 0x01,                 /**< Unknown Error */
-    AITT_ERROR_SYSTEM = TIZEN_ERROR_AITT | 0x02,                  /**< System errors */
-    AITT_ERROR_NOT_READY = TIZEN_ERROR_AITT | 0x03,               /**< Not available */
+    AITT_ERROR_ALREADY = TIZEN_ERROR_ALREADY_IN_PROGRESS, /**< Operation already in progress */
+    AITT_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT,         /**< Time out */
+    AITT_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */
+    AITT_ERROR_UNKNOWN = TIZEN_ERROR_AITT | 0x01,         /**< Unknown Error */
+    AITT_ERROR_SYSTEM = TIZEN_ERROR_AITT | 0x02,          /**< System errors */
+    AITT_ERROR_NOT_READY = TIZEN_ERROR_AITT | 0x03,       /**< Not available */
 };
index ee77742..4bcfa3e 100644 (file)
@@ -150,7 +150,6 @@ typedef enum {
 
 /**
  * @brief Set the contents of a @c handle related with @c option to @c value
- * @detail The @c value can be NULL for removing the content
  * @privlevel public
  * @param[in] handle Handle of AITT service
  * @param[in] option value of @a aitt_option_e.
index 2b50694..8f3d3bf 100644 (file)
@@ -13,6 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include "AITT.h"
+
 #include <memory>
 #include <random>
 
 #include "aitt_internal.h"
 
 namespace aitt {
+AITT::AITT(const std::string notice)
+{
+    if (notice.empty() || notice != std::string(AITT_MUST_CALL_READY)) {
+        ERR("Invalid Argument(%s)", notice.c_str());
+        throw AittException(AittException::INVALID_ARG);
+    }
+}
 
 AITT::AITT(const std::string &id, const std::string &ip_addr, AittOption option)
 {
+    Ready(id, ip_addr, option);
+}
+
+AITT::~AITT(void)
+{
+}
+
+void AITT::Ready(const std::string &id, const std::string &ip_addr, AittOption option)
+{
+    if (pImpl) {
+        ERR("Already Ready");
+        throw AittException(AittException::ALREADY);
+    }
+
     std::string valid_id = id;
     std::string valid_ip = ip_addr;
 
@@ -45,10 +68,6 @@ AITT::AITT(const std::string &id, const std::string &ip_addr, AittOption option)
     pImpl = std::unique_ptr<AITT::Impl>(new AITT::Impl(*this, valid_id, valid_ip, option));
 }
 
-AITT::~AITT(void)
-{
-}
-
 void AITT::SetWillInfo(const std::string &topic, const void *data, const int datalen, AittQoS qos,
       bool retain)
 {
index 8596681..e290693 100644 (file)
@@ -31,9 +31,9 @@ struct aitt_handle {
 };
 
 struct aitt_option {
+    aitt_option() : my_ip(nullptr) {}
     const char *my_ip;
-    bool clear_session;
-    bool custom_broker;
+    AittOption option;
 };
 
 API aitt_h aitt_new(const char *id, aitt_option_h option)
@@ -42,23 +42,19 @@ API aitt_h aitt_new(const char *id, aitt_option_h option)
     try {
         std::string valid_id;
         std::string valid_ip;
-        AittOption aitt_option;
-        bool custom_broker = false;
 
         if (id)
             valid_id = id;
 
+        handle = new aitt_handle();
         if (option) {
             if (option->my_ip)
                 valid_ip = option->my_ip;
-            aitt_option.SetClearSession(option->clear_session);
-            aitt_option.SetUseCustomMqttBroker(option->custom_broker);
-            custom_broker = option->custom_broker;
+            handle->custom_broker = option->option.GetUseCustomMqttBroker();
+            handle->aitt = new AITT(valid_id, valid_ip, option->option);
+        } else {
+            handle->aitt = new AITT(valid_id, valid_ip);
         }
-
-        handle = new aitt_handle();
-        handle->aitt = new AITT(valid_id, valid_ip, aitt_option);
-        handle->custom_broker = custom_broker;
     } catch (std::exception &e) {
         ERR("new() Fail(%s)", e.what());
         return nullptr;
@@ -69,10 +65,7 @@ API aitt_h aitt_new(const char *id, aitt_option_h option)
 
 API void aitt_destroy(aitt_h handle)
 {
-    if (handle == nullptr) {
-        ERR("handle is NULL");
-        return;
-    }
+    RET_IF(handle == nullptr);
 
     try {
         delete handle->aitt;
@@ -88,9 +81,6 @@ API aitt_option_h aitt_option_new()
 
     try {
         handle = new aitt_option();
-        handle->my_ip = nullptr;
-        handle->clear_session = false;
-        handle->custom_broker = false;
     } catch (std::exception &e) {
         ERR("new() Fail(%s)", e.what());
     }
@@ -100,10 +90,7 @@ API aitt_option_h aitt_option_new()
 
 API void aitt_option_destroy(aitt_option_h handle)
 {
-    if (handle == nullptr) {
-        ERR("handle is NULL");
-        return;
-    }
+    RET_IF(handle == nullptr);
 
     try {
         delete handle;
@@ -112,7 +99,7 @@ API void aitt_option_destroy(aitt_option_h handle)
     }
 }
 
-static int _option_set_bool(const char *value, bool &dest)
+static int _to_boolean(const char *value, bool &dest)
 {
     if (value) {
         dest = (STR_EQ == strcasecmp(value, "true"));
@@ -129,20 +116,23 @@ static int _option_set_bool(const char *value, bool &dest)
 API int aitt_option_set(aitt_option_h handle, aitt_option_e option, const char *value)
 {
     RETV_IF(handle == nullptr, AITT_ERROR_INVALID_PARAMETER);
+    int ret;
+    bool bool_val = false;
 
     switch (option) {
     case AITT_OPT_MY_IP:
-        try {
-            handle->my_ip = value;
-        } catch (std::exception &e) {
-            ERR("string() Fail(%s)", e.what());
-            return AITT_ERROR_SYSTEM;
-        }
+        handle->my_ip = value;
         break;
     case AITT_OPT_CLEAN_SESSION:
-        return _option_set_bool(value, handle->clear_session);
+        ret = _to_boolean(value, bool_val);
+        if (ret == AITT_ERROR_NONE)
+            handle->option.SetClearSession(bool_val);
+        return ret;
     case AITT_OPT_CUSTOM_BROKER:
-        return _option_set_bool(value, handle->custom_broker);
+        ret = _to_boolean(value, bool_val);
+        if (ret == AITT_ERROR_NONE)
+            handle->option.SetUseCustomMqttBroker(bool_val);
+        return ret;
     default:
         ERR("Unknown option(%d)", option);
         return AITT_ERROR_INVALID_PARAMETER;
@@ -159,9 +149,9 @@ API const char *aitt_option_get(aitt_option_h handle, aitt_option_e option)
     case AITT_OPT_MY_IP:
         return handle->my_ip;
     case AITT_OPT_CLEAN_SESSION:
-        return (handle->clear_session) ? "true" : "false";
+        return (handle->option.GetClearSession()) ? "true" : "false";
     case AITT_OPT_CUSTOM_BROKER:
-        return (handle->custom_broker) ? "true" : "false";
+        return (handle->option.GetUseCustomMqttBroker()) ? "true" : "false";
     default:
         ERR("Unknown option(%d)", option);
     }
index 9f0a97f..3d06171 100644 (file)
@@ -385,6 +385,54 @@ TEST_F(AITTTest, Connect_twice_P_Anytime)
     }
 }
 
+TEST_F(AITTTest, Ready_P_Anytime)
+{
+    try {
+        AITT aitt(AITT_MUST_CALL_READY);
+        aitt.Ready(clientId, LOCAL_IP, AittOption(true, false));
+        aitt.Connect();
+
+        AITT aitt1("Must Call Ready() First");
+        aitt1.Ready("", LOCAL_IP, AittOption(true, false));
+        aitt1.Connect();
+    } catch (std::exception &e) {
+        FAIL() << "Unexpected exception: " << e.what();
+    }
+}
+
+TEST_F(AITTTest, Ready_N_Anytime)
+{
+    EXPECT_THROW({ AITT aitt("must call ready() first"); }, aitt::AittException);
+    EXPECT_THROW({ AITT aitt("not ready"); }, aitt::AittException);
+    EXPECT_THROW({ AITT aitt("unknown notice"); }, aitt::AittException);
+
+    EXPECT_THROW(
+          {
+              AITT aitt(AITT_MUST_CALL_READY);
+              aitt.Ready(clientId, LOCAL_IP);
+              aitt.Ready(clientId, LOCAL_IP, AittOption(true, false));
+          },
+          aitt::AittException);
+
+    EXPECT_THROW(
+          {
+              AITT aitt(clientId, LOCAL_IP, AittOption(true, false));
+              aitt.Ready(clientId, LOCAL_IP);
+          },
+          aitt::AittException);
+}
+
+TEST_F(AITTTest, Not_READY_STATUS_N)
+{
+    EXPECT_THROW(
+          {
+              AITT aitt(AITT_MUST_CALL_READY);
+              FAIL() << "MUST NOT use the aitt before calling Ready()";
+              aitt.Connect();
+          },
+          std::exception);
+}
+
 TEST_F(AITTTest, Publish_MQTT_P_Anytime)
 {
     try {