Add new internal APIs 82/264282/10
authorChanggyu Choi <changyu.choi@samsung.com>
Wed, 15 Sep 2021 10:34:37 +0000 (19:34 +0900)
committerChanggyu Choi <changyu.choi@samsung.com>
Fri, 24 Sep 2021 04:27:29 +0000 (13:27 +0900)
Adds:
 - rpc_port_disconnect()
 - rpc_port_parcel_get_header()
 - rpc_port_parcel_header_set_tag()
 - rpc_port_parcel_header_get_tag()
 - rpc_port_parcel_header_set_seq_num()
 - rpc_port_porcel_header_get_seq_num()
 - rpc_port_parcel_header_get_timestamp()

Change-Id: I74770678bc63a1edf12e208c95ef14dfaa5bbd59
Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
17 files changed:
CMakeLists.txt
include/rpc-port-internal.h
include/rpc-port-parcel-internal.h
include/rpc-port-parcel.h
include/rpc-port.h
src/parcel-header-internal.cc [new file with mode: 0644]
src/parcel-header-internal.hh [new file with mode: 0644]
src/parcel-internal.cc
src/parcel-internal.h
src/port-internal.cc
src/port-internal.h
src/rpc-port-parcel.cc
src/rpc-port.cc
unit_tests/CMakeLists.txt
unit_tests/src/rpc_port_parcel_test.cc
unit_tests/src/rpc_port_test.cc
utils/CMakeLists.txt

index 82d5c9e..278492e 100644 (file)
@@ -18,7 +18,7 @@ ENDFOREACH(flag)
 SET(EXTRA_CFLAGS  "${EXTRA_CFLAGS} -Wall" )
 
 ## SET C COMPILER FLAGS
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror -fvisibility=hidden")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -fvisibility=hidden")
 SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
 
 ## SET CPP COMPILER FLAGS
index b370e0a..b359313 100644 (file)
@@ -27,6 +27,17 @@ int rpc_port_proxy_create_mockup(rpc_port_proxy_h *h);
 
 int rpc_port_stub_create_mockup(rpc_port_stub_h *h, const char *port_name);
 
+/**
+ * @brief Disconnects the port.
+ * @since_tizen 6.0
+ * @param[in] port The rpc port handle
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int rpc_port_disconnect(rpc_port_h port);
+
 #ifdef __cplusplus
 }
 #endif
index a4f8323..ab8e80d 100644 (file)
@@ -31,6 +31,87 @@ int rpc_port_parcel_to_array(rpc_port_parcel_h h, void **array,
 int rpc_port_parcel_from_array(rpc_port_parcel_h h, const void *array,
     unsigned int size);
 
+/**
+ * @brief Gets the header handle of the rpc port parcel.
+ * @since_tizen 6.0
+ * @remarks The @a header is managed by the platform and will be released when rpc_port_parcel_destroy() is called.
+ * @param[in] h The rpc port parcel handle
+ * @param[out] header The header handle of the rpc port parcel
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int rpc_port_parcel_get_header(rpc_port_parcel_h h, rpc_port_parcel_header_h *header);
+
+/**
+ * @brief Sets the tag to the header handle of the rpc port parcel.
+ * @since_tizen 6.0
+ * @param[in] header The header handle of the rpc port parcel
+ * @param[in] tag The tag
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see rpc_port_parcel_header_get_tag()
+ */
+int rpc_port_parcel_header_set_tag(rpc_port_parcel_header_h header, const char *tag);
+
+/**
+ * @brief Gets the tag from the header handle of the rpc port parcel.
+ * @since_tizen 6.0
+ * @remarks The @a tag should be released using free().
+ * @param[in] header The header handle of the rpc port parcel
+ * @param[out] tag The tag
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see rpc_port_parcel_header_set_tag()
+ */
+int rpc_port_parcel_header_get_tag(rpc_port_parcel_header_h header, char **tag);
+
+/**
+ * @brief Sets the sequence number to the header handle of the rpc port parcel.
+ * @since_tizen 6.0
+ * @param[in] header The header handle of the rpc port parcel
+ * @param[in] seq_num The sequence number
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see rpc_port_parcel_header_get_seq_num()
+ */
+int rpc_port_parcel_header_set_seq_num(rpc_port_parcel_header_h header, int seq_num);
+
+/**
+ * @brief Gets the sequence number from the header handle of the rpc port parcel.
+ * @since_tizen 6.0
+ * @param[in] header The header handle of the rpc port parcel
+ * @param[out] seq_num The sequence number
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see rpc_port_parcel_header_set_seq_num()
+ */
+int rpc_port_parcel_header_get_seq_num(rpc_port_parcel_header_h header, int *seq_num);
+
+/**
+ * @brief Gets the timestamp from the header handle of the rpc port parcel.
+ * @since_tizen 6.0
+ * @remarks The @a timestamp represents monotonic time since some unspecified starting point.
+ *          To get elapsed time properly, you have to get the timestamp using the clock_gettime() with CLOCK_MONITONIC_RAW.
+ * @param[in] header The header handle of the rpc port parcel
+ * @param[out] timestamp The timestamp
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int rpc_port_parcel_header_get_timestamp(rpc_port_parcel_header_h header, struct timespec *timestamp);
+
 #ifdef __cplusplus
 }
 #endif
index 202086b..6bf31b5 100644 (file)
@@ -1,14 +1,14 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2018 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
  *
- * Licensed under the Apache License, Version 2.0 (the License);
+ * 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,
+ * 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.
@@ -18,6 +18,8 @@
 #define __TIZEN_APPFW_RPC_PORT_PARCEL_INCLUDE_H__
 
 #include <stdbool.h>
+#include <sys/time.h>
+
 #include <bundle.h>
 #include <rpc-port.h>
 
@@ -37,12 +39,18 @@ extern "C" {
 typedef void *rpc_port_parcel_h;
 
 /**
+ * @brief The header handle of the rpc port parcel.
+ * @since_tizen 6.0
+ */
+typedef void *rpc_port_parcel_header_h;
+
+/**
  * @brief The interface for converting data to/from a parcel.
  * @since_tizen @if MOBILE 4.0 @elseif WEARABLE 5.0 @endif
  */
 typedef struct __rpc_port_parcelable {
-       void (*to)(rpc_port_parcel_h h, void *data);
-       void (*from)(rpc_port_parcel_h h, void *data);
+       void (*to)(rpc_port_parcel_h h, void *data);  /**< The function pointer to read from parcel */
+       void (*from)(rpc_port_parcel_h h, void *data);  /**< The function pointer to write to parcel */
 } rpc_port_parcelable_t;
 
 /**
@@ -394,7 +402,6 @@ int rpc_port_parcel_read_array_count(rpc_port_parcel_h h, int *count);
  */
 int rpc_port_parcel_read(rpc_port_parcel_h h, rpc_port_parcelable_t *parcelable, void *data);
 
-
 /**
  * @brief Reads bytes from rpc port parcel handle.
  * @since_tizen @if MOBILE 4.0 @elseif WEARABLE 5.0 @endif
index 93c9983..86b175d 100644 (file)
@@ -1,14 +1,14 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2018 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
  *
- * Licensed under the Apache License, Version 2.0 (the License);
+ * 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,
+ * 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.
diff --git a/src/parcel-header-internal.cc b/src/parcel-header-internal.cc
new file mode 100644 (file)
index 0000000..754162a
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * 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 "parcel-header-internal.hh"
+
+#include <atomic>
+#include <climits>
+#include <limits>
+#include <string>
+#include <utility>
+
+namespace rpc_port {
+namespace internal {
+
+ParcelHeader::ParcelHeader() : seq_num_(GenerateSeqNum()) {
+  clock_gettime(CLOCK_MONOTONIC_RAW, &time_stamp_);
+}
+
+void ParcelHeader::SetTag(std::string tag) {
+  tag_ = std::move(tag);
+}
+
+const std::string& ParcelHeader::GetTag() const {
+  return tag_;
+}
+
+void ParcelHeader::SetSeqNum(int seq_num) {
+  seq_num_ = seq_num;
+}
+
+int ParcelHeader::GetSeqNum() const {
+  return seq_num_;
+}
+
+struct timespec ParcelHeader::GetTimeStamp() const {
+  return time_stamp_;
+}
+
+void ParcelHeader::SetTimeStamp(struct timespec time_stamp) {
+  time_stamp_ = time_stamp;
+}
+
+int ParcelHeader::GenerateSeqNum() {
+  static std::atomic<unsigned int> num{0};
+  ++num;
+  return static_cast<int>(num & INT_MAX);
+}
+
+}  // namespace internal
+}  // namespace rpc_port
diff --git a/src/parcel-header-internal.hh b/src/parcel-header-internal.hh
new file mode 100644 (file)
index 0000000..135b2bd
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+#ifndef PARCEL_HEADER_INTERNAL_H_
+#define PARCEL_HEADER_INTERNAL_H_
+
+#include <time.h>
+
+#include <string>
+
+namespace rpc_port {
+namespace internal {
+
+class ParcelHeader {
+ public:
+  ParcelHeader();
+
+  void SetTag(std::string tag);
+  const std::string& GetTag() const;
+  void SetSeqNum(int seq_num);
+  int GetSeqNum() const;
+  struct timespec GetTimeStamp() const;
+  void SetTimeStamp(struct timespec time_stamp);
+  static int GenerateSeqNum();
+
+ private:
+  std::string tag_;
+  int seq_num_;
+  struct timespec time_stamp_;
+};
+
+}  // namespace internal
+}  // namespace rpc_port
+
+#endif  // PARCEL_HEADER_INTERNAL_H_
index 319b921..2778e57 100644 (file)
  */
 #include <cstring>
 
+#include "parcel-header-internal.hh"
 #include "parcel-internal.h"
 
 namespace rpc_port {
+namespace internal {
+
+Parcel::Parcel() {}
 
 Parcel::Parcel(const unsigned char* buf, unsigned int size)
-    : data_(buf, buf + size) {}
+    : data_(buf, buf + size) {
+  ReadParcelHeader();
+}
 
 void Parcel::WriteByte(char b) {
   Write<char>(b);
@@ -72,6 +78,16 @@ void Parcel::WriteArrayCount(int count) {
   Write<int>(count);
 }
 
+const std::vector<unsigned char> Parcel::MakeHeaderRaw() {
+  Parcel header_raw;
+  header_raw.WriteString(header_.GetTag().c_str());
+  header_raw.WriteInt32(header_.GetSeqNum());
+  header_raw.WriteInt64(static_cast<int64_t>(header_.GetTimeStamp().tv_sec));
+  header_raw.WriteInt64(static_cast<int64_t>(header_.GetTimeStamp().tv_nsec));
+
+  return std::move(header_raw.GetRaw());
+}
+
 char Parcel::ReadByte() {
   return Read<char>();
 }
@@ -136,6 +152,21 @@ int Parcel::ReadArrayCount() {
   return Read<int>();
 }
 
+void Parcel::ReadParcelHeader() {
+  header_.SetTag(std::move(ReadString()));
+  int seq_num = ReadInt32();
+  header_.SetSeqNum(seq_num);
+
+  struct timespec time_stamp {};
+  int64_t tv_sec = ReadInt64();
+  time_stamp.tv_sec = tv_sec & std::numeric_limits<time_t>::max();
+
+  int64_t tv_nsec = ReadInt64();
+  time_stamp.tv_nsec = tv_nsec & std::numeric_limits<long>::max();
+
+  header_.SetTimeStamp(time_stamp);
+}
+
 const std::vector<unsigned char>& Parcel::GetRaw() {
   return data_;
 }
@@ -171,4 +202,9 @@ void Parcel::Reset(const unsigned char* buf, unsigned int size) {
 }
 // LCOV_EXCL_STOP
 
+const ParcelHeader* Parcel::GetParcelHeader() {
+  return &header_;
+}
+
+}  // namespace internal
 }  // namespace rpc_port
index 991fe17..505bf76 100644 (file)
 #include <algorithm>
 #include <string>
 
+#include "parcel-header-internal.hh"
+
 namespace rpc_port {
+namespace internal {
 
 class Parcel {
  public:
-  Parcel() = default;
+  Parcel();
   Parcel(const unsigned char* buf, unsigned int size);
 
   void Write(const unsigned char* buf, unsigned int size);
@@ -57,6 +60,9 @@ class Parcel {
   void ResetReader();
   void Clear();
   void Reset(const unsigned char* buf, unsigned int size);
+  const ParcelHeader* GetParcelHeader();
+  const std::vector<unsigned char> MakeHeaderRaw();
+  void ReadParcelHeader();
 
  private:
   template<typename T>
@@ -79,10 +85,12 @@ class Parcel {
   }
 
  private:
+  ParcelHeader header_;
   std::vector<unsigned char> data_;
   unsigned int reader_ = 0;
 };
 
+}  // namespace internal
 }  // namespace rpc_port
 
 #endif  // PARCEL_INTERNAL_H_
index 8cba7dc..dcb9095 100644 (file)
@@ -103,6 +103,15 @@ int Port::UnsetPrivateSharing() {
   return RPC_PORT_ERROR_NONE;
 }
 
+void Port::Disconnect() {
+  std::lock_guard<std::recursive_mutex> lock(mutex_);
+  if (fd_ > 0) {
+    _W("Close fd(%d)", fd_);
+    close(fd_);
+    fd_ = -1;
+  }
+}
+
 int Port::Read(void* buf, unsigned int size) {
   unsigned int left = size;
   ssize_t nb;
index 4cab83b..05ed4de 100644 (file)
@@ -39,6 +39,7 @@ class Port {
   int SetPrivateSharing(const char* paths[], unsigned int size);
   int SetPrivateSharing(const char* path);
   int UnsetPrivateSharing();
+  void Disconnect();
 
   int Read(void* buf, unsigned int size);
   int Write(const void* buf, unsigned int size);
index 13b7cc2..10bb557 100644 (file)
@@ -32,7 +32,7 @@ RPC_API int rpc_port_parcel_create(rpc_port_parcel_h* h) {
   if (h == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = new Parcel();
+  internal::Parcel* p = new internal::Parcel();
 
   *h = p;
 
@@ -64,7 +64,7 @@ RPC_API int rpc_port_parcel_create_from_port(rpc_port_parcel_h* h,
     }
   }
 
-  Parcel* p = new Parcel(buf, len);
+  internal::Parcel* p = new internal::Parcel(buf, len);
   delete[] buf;
 
   *h = p;
@@ -76,20 +76,21 @@ RPC_API int rpc_port_parcel_send(rpc_port_parcel_h h, rpc_port_h port) {
   if (h == nullptr || port == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
-  int len = p->GetRaw().size();
-
-  if (len <= 0)
-    return RPC_PORT_ERROR_INVALID_PARAMETER;
-
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
   internal::Port* pt = static_cast<internal::Port*>(port);
   {
     std::lock_guard<std::recursive_mutex> lock(pt->GetMutex());
+    auto send_data = p->MakeHeaderRaw();
+    send_data.insert(send_data.end(), p->GetRaw().begin(), p->GetRaw().end());
+    int len = send_data.size();
+    if (len <= 0)
+      return RPC_PORT_ERROR_INVALID_PARAMETER;
+
     int ret = rpc_port_write(port, &len, 4);
     if (ret != 0)
       return ret;
 
-    ret = rpc_port_write(port, &*(p->GetRaw().cbegin()), len);
+    ret = rpc_port_write(port, &*(send_data.cbegin()), len);
     if (ret != 0)
       return ret;
   }
@@ -101,7 +102,7 @@ RPC_API int rpc_port_parcel_destroy(rpc_port_parcel_h h) {
   if (h == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  delete static_cast<Parcel*>(h);
+  delete static_cast<internal::Parcel*>(h);
 
   return RPC_PORT_ERROR_NONE;
 }
@@ -110,7 +111,7 @@ RPC_API int rpc_port_parcel_write_byte(rpc_port_parcel_h h, char b) {
   if (h == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->WriteByte(b);
 
@@ -121,7 +122,7 @@ RPC_API int rpc_port_parcel_write_int16(rpc_port_parcel_h h, short i) {
   if (h == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->WriteInt16(i);
 
@@ -132,7 +133,7 @@ RPC_API int rpc_port_parcel_write_int32(rpc_port_parcel_h h, int i) {
   if (h == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->WriteInt32(i);
 
@@ -143,7 +144,7 @@ RPC_API int rpc_port_parcel_write_int64(rpc_port_parcel_h h, long long i) {
   if (h == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->WriteInt64(i);
 
@@ -154,7 +155,7 @@ RPC_API int rpc_port_parcel_write_float(rpc_port_parcel_h h, float f) {
   if (h == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->WriteFloat(f);
 
@@ -165,7 +166,7 @@ RPC_API int rpc_port_parcel_write_double(rpc_port_parcel_h h, double d) {
   if (h == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->WriteDouble(d);
 
@@ -176,7 +177,7 @@ RPC_API int rpc_port_parcel_write_string(rpc_port_parcel_h h, const char* str) {
   if (h == nullptr || str == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->WriteString(str);
 
@@ -187,7 +188,7 @@ RPC_API int rpc_port_parcel_write_bool(rpc_port_parcel_h h, bool b) {
   if (h == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->WriteBool(b);
 
@@ -198,7 +199,7 @@ RPC_API int rpc_port_parcel_write_bundle(rpc_port_parcel_h h, bundle* b) {
   if (h == nullptr || b == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->WriteBundle(b);
 
@@ -209,7 +210,7 @@ RPC_API int rpc_port_parcel_write_array_count(rpc_port_parcel_h h, int count) {
   if (h == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->WriteArrayCount(count);
 
@@ -233,7 +234,7 @@ RPC_API int rpc_port_parcel_read_byte(rpc_port_parcel_h h, char* b) {
   if (h == nullptr || b == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   *b = p->ReadByte();
 
@@ -244,7 +245,7 @@ RPC_API int rpc_port_parcel_read_int16(rpc_port_parcel_h h, short* i) {
   if (h == nullptr || i == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   *i = p->ReadInt16();
 
@@ -255,7 +256,7 @@ RPC_API int rpc_port_parcel_read_int32(rpc_port_parcel_h h, int* i) {
   if (h == nullptr || i == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   *i = p->ReadInt32();
 
@@ -266,7 +267,7 @@ RPC_API int rpc_port_parcel_read_int64(rpc_port_parcel_h h, long long* i) {
   if (h == nullptr || i == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   *i = p->ReadInt64();
 
@@ -277,7 +278,7 @@ RPC_API int rpc_port_parcel_read_float(rpc_port_parcel_h h, float* f) {
   if (h == nullptr || f == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   *f = p->ReadFloat();
 
@@ -288,7 +289,7 @@ RPC_API int rpc_port_parcel_read_double(rpc_port_parcel_h h, double* d) {
   if (h == nullptr || d == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   *d = p->ReadDouble();
 
@@ -299,7 +300,7 @@ RPC_API int rpc_port_parcel_read_string(rpc_port_parcel_h h, char** str) {
   if (h == nullptr || str == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
   const char* read = p->ReadString();
   *str = read == nullptr ? strdup("") : strdup(read);
 
@@ -310,7 +311,7 @@ RPC_API int rpc_port_parcel_read_bool(rpc_port_parcel_h h, bool* b) {
   if (h == nullptr || b == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   *b = p->ReadBool();
 
@@ -321,7 +322,7 @@ RPC_API int rpc_port_parcel_read_bundle(rpc_port_parcel_h h, bundle** b) {
   if (h == nullptr || b == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
   bundle* read = p->ReadBundle();
 
   *b = read == nullptr ? bundle_create() : read;
@@ -333,7 +334,7 @@ RPC_API int rpc_port_parcel_read_array_count(rpc_port_parcel_h h, int* count) {
   if (h == nullptr || count == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   *count = p->ReadArrayCount();
 
@@ -358,7 +359,7 @@ RPC_API int rpc_port_parcel_burst_read(rpc_port_parcel_h h, unsigned char *buf,
   if (h == nullptr || buf == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->Read(buf, size);
 
@@ -370,7 +371,7 @@ RPC_API int rpc_port_parcel_burst_write(rpc_port_parcel_h h,
   if (h == nullptr || buf == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->Write(buf, size);
 
@@ -382,7 +383,7 @@ RPC_API int rpc_port_parcel_reset_reader(rpc_port_parcel_h h) {
   if (h == nullptr)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->ResetReader();
 
@@ -396,7 +397,7 @@ RPC_API int rpc_port_parcel_to_array(rpc_port_parcel_h h, void **array,
   if (h == nullptr || !array || !size)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   const auto& ptr = p->GetRaw();
   void* array_ptr = malloc(ptr.size());
@@ -417,10 +418,87 @@ RPC_API int rpc_port_parcel_from_array(rpc_port_parcel_h h, const void *array,
   if (h == nullptr || !array || size == 0)
     return RPC_PORT_ERROR_INVALID_PARAMETER;
 
-  Parcel* p = static_cast<Parcel*>(h);
+  internal::Parcel* p = static_cast<internal::Parcel*>(h);
 
   p->Reset(reinterpret_cast<const unsigned char*>(array), size);
 
   return RPC_PORT_ERROR_NONE;
 }
 // LCOV_EXCL_STOP
+
+// LCOV_EXCL_START
+RPC_API int rpc_port_parcel_get_header(rpc_port_parcel_h h,
+                                       rpc_port_parcel_header_h* header) {
+  if (h == nullptr || header == nullptr)
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+  auto* parcel = static_cast<internal::Parcel*>(h);
+  auto* parcel_header = parcel->GetParcelHeader();
+  *header = reinterpret_cast<rpc_port_parcel_header_h>(
+      const_cast<internal::ParcelHeader*>(parcel_header));
+  return RPC_PORT_ERROR_NONE;
+}
+// LCOV_EXCL_STOP
+
+// LCOV_EXCL_START
+RPC_API int rpc_port_parcel_header_set_tag(rpc_port_parcel_header_h header,
+                                           const char* tag) {
+  if (header == nullptr || tag == nullptr)
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+  auto* parcel_header = static_cast<internal::ParcelHeader*>(header);
+  parcel_header->SetTag(tag);
+  return RPC_PORT_ERROR_NONE;
+}
+// LCOV_EXCL_STOP
+
+// LCOV_EXCL_START
+RPC_API int rpc_port_parcel_header_get_tag(rpc_port_parcel_header_h header,
+                                           char** tag) {
+  if (header == nullptr || tag == nullptr)
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+  auto* parcel_header = static_cast<internal::ParcelHeader*>(header);
+  const std::string& raw_tag = parcel_header->GetTag();
+
+  *tag = strdup(raw_tag.c_str());
+  if (*tag == nullptr) return RPC_PORT_ERROR_OUT_OF_MEMORY;
+
+  return RPC_PORT_ERROR_NONE;
+}
+// LCOV_EXCL_STOP
+
+// LCOV_EXCL_START
+RPC_API int rpc_port_parcel_header_set_seq_num(rpc_port_parcel_header_h header,
+                                               int seq_num) {
+  if (header == nullptr) return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+  auto* parcel_header = static_cast<internal::ParcelHeader*>(header);
+  parcel_header->SetSeqNum(seq_num);
+  return RPC_PORT_ERROR_NONE;
+}
+// LCOV_EXCL_STOP
+
+// LCOV_EXCL_START
+RPC_API int rpc_port_parcel_header_get_seq_num(rpc_port_parcel_header_h header,
+                                               int* seq_num) {
+  if (header == nullptr || seq_num == nullptr)
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+  auto* parcel_header = static_cast<internal::ParcelHeader*>(header);
+  *seq_num = parcel_header->GetSeqNum();
+  return RPC_PORT_ERROR_NONE;
+}
+// LCOV_EXCL_STOP
+
+// LCOV_EXCL_START
+RPC_API int rpc_port_parcel_header_get_timestamp(
+    rpc_port_parcel_header_h header, struct timespec* timestamp) {
+  if (header == nullptr || timestamp == nullptr)
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+  auto* parcel_header = static_cast<internal::ParcelHeader*>(header);
+  *timestamp = parcel_header->GetTimeStamp();
+  return RPC_PORT_ERROR_NONE;
+}
+// LCOV_EXCL_STOP
index 81362f6..e6b1fd1 100644 (file)
@@ -536,3 +536,15 @@ RPC_API int rpc_port_unset_private_sharing(rpc_port_h h) {
 
   return port->UnsetPrivateSharing();
 }
+
+// LCOV_EXCL_START
+RPC_API int rpc_port_disconnect(rpc_port_h h) {
+  if (h == nullptr)
+    return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+  auto port = static_cast<Port*>(h);
+  port->Disconnect();
+
+  return RPC_PORT_ERROR_NONE;
+}
+// LCOV_EXCL_STOP
index dac0b21..aa7cff6 100644 (file)
@@ -11,7 +11,7 @@ pkg_check_modules(rpc-port_unittests REQUIRED
 FOREACH(flag ${rpc-port_unittests_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall")
 
 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++11")
 SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
index 2b67502..5860cab 100644 (file)
@@ -21,7 +21,7 @@
 #include <stdbool.h>
 #include <stdexcept>
 
-#include "rpc-port-parcel.h"
+#include "rpc-port-parcel-internal.h"
 
 using ::testing::AtLeast;
 
@@ -320,3 +320,148 @@ TEST_F(ParcelTest, rpc_port_parcel_burst_read_write_P) {
     ASSERT_EQ(buf[i], buf2[i]);
   }
 }
+
+/*
+ * @testcase rpc_port_parcel_get_header_P
+ * @description Gets the header handle from the rpc port parcel handle (internal)
+ * @apicovered rpc_port_parcel_get_header
+ */
+TEST_F(ParcelTest, rpc_port_parcel_get_header_P) {
+  rpc_port_parcel_header_h header = nullptr;
+  int ret = rpc_port_parcel_get_header(handle_, &header);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+  ASSERT_NE(header, nullptr);
+}
+
+/*
+ * @testcase rpc_port_parcel_get_header_N
+ * @description Gets the header handle from the rpc port parcel handle (internal)
+ * @apicovered rpc_port_parcel_get_header
+ */
+TEST_F(ParcelTest, rpc_port_parcel_get_header_N) {
+  int ret = rpc_port_parcel_get_header(nullptr, nullptr);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase rpc_port_parcel_header_set_get_tag_P
+ * @description Sets and gets the tag (internal)
+ * @apicovered rpc_port_parcel_header_set_tag, rpc_port_parcel_header_get_tag
+ */
+TEST_F(ParcelTest, rpc_port_parcel_header_set_get_tag_P) {
+  rpc_port_parcel_header_h header = nullptr;
+  int ret = rpc_port_parcel_get_header(handle_, &header);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+
+  const char tag[] = "1.5.0";
+  ret = rpc_port_parcel_header_set_tag(header, tag);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+
+  char* out_tag = nullptr;
+  ret = rpc_port_parcel_header_get_tag(header, &out_tag);
+  std::unique_ptr<char, decltype(std::free)*> auto_free(out_tag, std::free);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+  ASSERT_STREQ(tag, out_tag);
+}
+
+/*
+ * @testcase rpc_port_parcel_header_set_get_tag_without_set_tag_P
+ * @description gets the tag without set tag. (internal)
+ * @apicovered rpc_port_parcel_header_get_tag
+ */
+TEST_F(ParcelTest, rpc_port_parcel_header_set_get_tag_without_set_tag_P) {
+  rpc_port_parcel_header_h header = nullptr;
+  int ret = rpc_port_parcel_get_header(handle_, &header);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+
+  char* out_tag = nullptr;
+  ret = rpc_port_parcel_header_get_tag(header, &out_tag);
+  std::unique_ptr<char, decltype(std::free)*> auto_free(out_tag, std::free);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+  ASSERT_STREQ(out_tag, "");
+}
+
+/*
+ * @testcase rpc_port_parcel_header_set_get_tag_N
+ * @description Sets and gets the tag (internal)
+ * @apicovered rpc_port_parcel_header_set_tag, rpc_port_parcel_header_get_tag
+ */
+TEST_F(ParcelTest, rpc_port_parcel_header_set_get_tag_N) {
+  rpc_port_parcel_header_h header = nullptr;
+  int ret = rpc_port_parcel_get_header(handle_, &header);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+
+  const char tag[] = "1.5.0";
+  ret = rpc_port_parcel_header_set_tag(nullptr, tag);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER);
+
+  ret = rpc_port_parcel_header_set_tag(header, nullptr);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER);
+
+  char* out_tag = nullptr;
+  ret = rpc_port_parcel_header_get_tag(nullptr, &out_tag);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER);
+
+  ret = rpc_port_parcel_header_get_tag(header, nullptr);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase rpc_port_parcel_header_set_get_seq_num_P
+ * @description Sets and gets the sequence number (internal)
+ * @apicovered rpc_port_parcel_header_set_seq_num, rpc_port_parcel_header_get_seq_num
+ */
+TEST_F(ParcelTest, rpc_port_parcel_header_set_get_seq_num_P) {
+  rpc_port_parcel_header_h header = nullptr;
+  int ret = rpc_port_parcel_get_header(handle_, &header);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+
+  ret = rpc_port_parcel_header_set_seq_num(header, 100);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+
+  int seq_num = 0;
+  ret = rpc_port_parcel_header_get_seq_num(header, &seq_num);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+  ASSERT_EQ(seq_num, 100);
+}
+
+/*
+ * @testcase rpc_port_parcel_header_set_get_seq_num_N
+ * @description Sets and gets the sequence number (internal)
+ * @apicovered rpc_port_parcel_header_set_seq_num, rpc_port_parcel_header_get_seq_num
+ */
+TEST_F(ParcelTest, rpc_port_parcel_header_set_get_seq_num_N) {
+  int ret = rpc_port_parcel_header_set_seq_num(nullptr, -1);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER);
+
+  ret = rpc_port_parcel_header_get_seq_num(nullptr, nullptr);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER);
+}
+
+/*
+ * @testcase rpc_port_parcel_header_get_timestamp_P
+ * @description Gets the timestamp from the header handle of the rpc port parcel (internal)
+ * @apicovered rpc_port_parcel_header_get_timestamp
+ */
+TEST_F(ParcelTest, rpc_port_parcel_header_get_timestamp_P) {
+  rpc_port_parcel_header_h header = nullptr;
+  int ret = rpc_port_parcel_get_header(handle_, &header);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+
+  struct timespec timestamp = { 0, };
+  ret = rpc_port_parcel_header_get_timestamp(header, &timestamp);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+
+  ASSERT_NE(timestamp.tv_sec, 0);
+  ASSERT_NE(timestamp.tv_nsec, 0);
+}
+
+/*
+ * @testcase rpc_port_parcel_header_get_timestamp_N
+ * @description Gets the timestamp from the header handle of the rpc port parcel (internal)
+ * @apicovered rpc_port_parcel_header_get_timestamp
+ */
+TEST_F(ParcelTest, rpc_port_parcel_header_get_timestamp_N) {
+  int ret = rpc_port_parcel_header_get_timestamp(nullptr, nullptr);
+  ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER);
+}
index 2694d7c..6dd2e92 100644 (file)
@@ -116,10 +116,15 @@ class RpcPortConnection : public RpcPortBase {
 
     ret = rpc_port_stub_add_disconnected_event_cb(stub_handle_,
         [](const char* sender, const char* instance, void *data) {
-          RpcPortConnection* p = static_cast<RpcPortConnection*>(data);
+          auto* p = static_cast<RpcPortConnection*>(data);
           p->touch_stub_disconnected_event_cb_ = true;
-          p->Finish();
-        }, this);
+          g_timeout_add(1, [](void* data) -> gboolean {
+            auto* p = static_cast<RpcPortConnection*>(data);
+            p->Finish();
+            return G_SOURCE_REMOVE;
+          }, p);
+        },
+        this);
     ASSERT_EQ(ret, 0);
 
     ret = rpc_port_stub_add_privilege(stub_handle_,
@@ -141,11 +146,16 @@ class RpcPortConnection : public RpcPortBase {
     ASSERT_EQ(ret, 0);
 
     ret = rpc_port_proxy_add_disconnected_event_cb(proxy_handle_,
-        [](const char *ep, const char *port_name, void *data) {
-          RpcPortConnection* p = static_cast<RpcPortConnection*>(data);
+        [](const char* ep, const char* port_name, void* data) {
+          auto* p = static_cast<RpcPortConnection*>(data);
           p->touch_proxy_disconnected_event_cb_ = true;
-          p->Finish();
-        }, this);
+          g_timeout_add(1, [](void* data) -> gboolean {
+            auto* p = static_cast<RpcPortConnection*>(data);
+            p->Finish();
+            return G_SOURCE_REMOVE;
+          }, p);
+        },
+        this);
     ASSERT_EQ(ret, 0);
 
     ret = rpc_port_proxy_add_received_event_cb(proxy_handle_,
@@ -357,3 +367,29 @@ TEST_F(RpcPortConnection, rpc_port_stub_disconnected_N) {
 
   ASSERT_TRUE(touch_stub_disconnected_event_cb_);
 }
+
+/*
+ * @testcase rpc_port_disconnect_P
+ * @description disconnect the port. (internal)
+ *              And then, checks whether the disconnected event callback is invoked or not.
+ * @apicovered rpc_port_disconnect
+ */
+TEST_F(RpcPortConnection, rpc_port_disconnect_P) {
+  char res[] = "test";
+  if (proxy_port_ == nullptr)
+    RunMainLoop();
+
+  ASSERT_NE(proxy_port_, nullptr);
+  int ret = rpc_port_write(proxy_port_, res, sizeof(res));
+  ASSERT_EQ(ret, RPC_PORT_ERROR_NONE);
+
+  if (stub_port_ == nullptr)
+    RunMainLoop();
+
+  ret = rpc_port_disconnect(stub_port_);
+  EXPECT_EQ(ret, RPC_PORT_ERROR_NONE);
+
+  RunMainLoop();
+  ASSERT_TRUE(touch_stub_disconnected_event_cb_);
+  ASSERT_TRUE(touch_proxy_disconnected_event_cb_);
+}
index c639ff2..b3b3b29 100644 (file)
@@ -12,7 +12,7 @@ pkg_check_modules(rpc-port-util REQUIRED
 FOREACH(flag ${rpc-port-util_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline -fPIE")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -fPIE")
 
 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++14")
 SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")