Add the spp infinite test 82/227482/4 accepted/tizen/unified/20200316.221052 submit/tizen/20200316.050457
authorDoHyun Pyun <dh79.pyun@samsung.com>
Thu, 12 Mar 2020 06:49:18 +0000 (15:49 +0900)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Mon, 16 Mar 2020 04:55:24 +0000 (13:55 +0900)
Change-Id: I2e50e5f5e0813d3f9a9610848b83aead5224041c
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
packaging/capi-network-bluetooth.spec
test/CMakeLists.txt
test/bt_infinite_spp_test.c [new file with mode: 0644]
test/bt_infinite_spp_test_server.service [new file with mode: 0644]
test/spp_test_addr [new file with mode: 0644]

index 84a3bda..cbb0314 100644 (file)
@@ -43,7 +43,6 @@ Requires: %{name} = %{version}-%{release}
 %description test
 This package is C-API test application.
 
-
 %if 0%{?gcov:1}
 %package gcov
 Summary:  Network Bluetooth Framework library(gcov)
@@ -107,6 +106,9 @@ mkdir -p %{buildroot}%{_datadir}/gcov/obj
 install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj
 %endif
 
+mkdir -p %{buildroot}%{_unitdir}
+install -m 0644 test/bt_infinite_spp_test_server.service %{buildroot}%{_unitdir}/bt_infinite_spp_test_server.service
+
 %post -p /sbin/ldconfig
 
 %postun -p /sbin/ldconfig
@@ -122,6 +124,8 @@ install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj
 %{_bindir}/bt_onoff
 %{_bindir}/ble_mouse
 %{_bindir}/hid_keyboard
+%{_bindir}/bt_infinite_spp_test
+%{_unitdir}/bt_infinite_spp_test_server.service
 #/etc/smack/accesses.d/capi-network-bluetooth-test.efl
 
 %files devel
index 34d5dd4..a8d35f9 100644 (file)
@@ -20,3 +20,4 @@ INSTALL(TARGETS bt_unit_test DESTINATION bin)
 INSTALL(TARGETS bt_onoff DESTINATION bin)
 INSTALL(TARGETS ble_mouse DESTINATION bin)
 INSTALL(TARGETS hid_keyboard DESTINATION bin)
+INSTALL(TARGETS bt_infinite_spp_test DESTINATION bin)
diff --git a/test/bt_infinite_spp_test.c b/test/bt_infinite_spp_test.c
new file mode 100644 (file)
index 0000000..97326d8
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd 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 <stdio.h>
+#include <dlog.h>
+#include <glib.h>
+#include <sys/time.h>
+#include <bluetooth.h>
+#include <bluetooth_internal.h>
+
+#undef LOG_TAG
+#define LOG_TAG "BLUETOOTH_SPP_TEST"
+
+#define BT_DBG(fmt, args...) \
+        SLOGD(fmt, ##args)
+#define BT_INFO(fmt, args...) \
+        SLOGI(fmt, ##args)
+#define BT_ERR(fmt, args...) \
+        SLOGE(fmt, ##args)
+
+typedef enum
+{
+       BT_SPP_TEST_ROLE_SERVER = 0x00,
+       BT_SPP_TEST_ROLE_CLIENT,
+} bt_spp_test_role_e;
+
+#define BT_INFINITE_SPP_TEST_REMOTE_ADDRESS_FILE_PATH "/opt/usr/home/owner/media/Downloads/spp_test_addr"
+#define BT_INFINITE_SPP_TEST_RESULT_FILE_PATH "/opt/usr/home/owner/media/Downloads/spp_result.log"
+
+bool __bt_connect_spp(void);
+static gboolean __bt_send_data(gpointer user_data);
+bool __bt_verify_data(char *data, int data_size);
+bool __bt_bond_remote_device(void);
+bool __bt_is_paired(void);
+
+static GMainLoop* g_mainloop = NULL;
+
+static bt_spp_test_role_e spp_role = BT_SPP_TEST_ROLE_SERVER;
+static char remote_addr[18] = {0,};
+static bt_adapter_state_e bt_state = BT_ADAPTER_DISABLED;
+
+const char *spp_secure_uuid = "fa87c0d0-afac-11de-8a39-0800200c9a66";
+static int server_fd = -1;
+static int socket_fd = -1;
+static bool is_receive_complete = false;
+
+static int packet_size = 65536;
+static char *buf = NULL;
+static int total_count = 32;
+static int sent_count = 0;
+static int receive_count = 0;
+static int receive_index = 0;
+
+static struct timeval start_time = {0,};
+static struct timeval end_time = {0,};
+static struct timeval diff_time = {0,};
+
+static int sum_time_ms = 0;
+static int avg_time_ms = 0;
+static int total_test_count = 0;
+
+void __bt_create_log_dump(void)
+{
+       char *argv[] = {"/usr/bin/crashctl", "dump_log", "normal", NULL};
+       execv("/usr/bin/crashctl", argv);
+
+       BT_ERR("Fail to verify data");
+
+#if 0
+       if (g_mainloop)
+               g_main_loop_quit(g_mainloop);
+       else
+               exit(0);
+#endif
+}
+
+static void __bt_socket_data_received_cb(bt_socket_received_data_s *data, void *user_data)
+{
+       if (data == NULL) {
+               BT_ERR("data is NULL");
+               return;
+       }
+       BT_INFO("FD = %d, Buffer len = %d", data->socket_fd, data->data_size);
+
+       if (__bt_verify_data(data->data, data->data_size) == false)
+               __bt_create_log_dump();
+
+       if (is_receive_complete == true)
+               g_idle_add(__bt_send_data, NULL);
+}
+
+static void __bt_device_bond_created_cb(int result, bt_device_info_s *device_info, void *user_data)
+{
+       if (result != BT_ERROR_NONE) {
+               BT_ERR("result[0x%X]", result);
+               return;
+       }
+
+       if (strcmp(device_info->remote_address, remote_addr) == 0) {
+               if (__bt_connect_spp() == false)
+                       BT_ERR("__bt_connect_spp() failed.");
+       }
+}
+
+static bool __bt_adapter_bonded_device_cb(bt_device_info_s *device_info, void *user_data)
+{
+       bool *is_paired = (bool*)user_data;
+
+       if (strcmp(device_info->remote_address, remote_addr) == 0) {
+               BT_INFO("remote_addr is exist.");
+               *is_paired = true;
+               return false;
+       }
+
+       return true;
+}
+
+void __bt_adapter_state_changed_cb(int result, bt_adapter_state_e adapter_state, void *user_data)
+{
+       BT_INFO("result [0x%04x] state = %d", result, adapter_state);
+
+       if (result == BT_ERROR_NONE) {
+               bt_state = adapter_state;
+               if (adapter_state == BT_ADAPTER_ENABLED) {
+                       if (__bt_is_paired() == true)
+                               __bt_connect_spp();
+                       else
+                               __bt_bond_remote_device();
+               }
+       }
+}
+
+void __bt_socket_connection_state_changed_cb(int result, bt_socket_connection_state_e connection_state, bt_socket_connection_s *connection, void *user_data)
+{
+       if (connection_state == BT_SOCKET_CONNECTED) {
+               BT_INFO("RFCOMM connected, result [0x%04x] Fd = %d, device add = %s, Role = %s",
+                               result, connection->socket_fd, connection->remote_address,
+                               (connection->local_role == BT_SOCKET_SERVER) ? "SERVER" : "CLIENT");
+
+               if (connection->socket_fd > 0) {
+                       socket_fd = connection->socket_fd;
+                       if (spp_role == BT_SPP_TEST_ROLE_CLIENT)
+                               g_idle_add(__bt_send_data, NULL);
+               } else {
+                       BT_ERR("socket_fd is INVALID");
+               }
+       } else {
+               BT_INFO("RFCOMM disconnected, result [0x%04x] Fd = %d, device add = %s",
+                               result, connection->socket_fd, connection->remote_address);
+               __bt_create_log_dump();
+       }
+}
+
+void __bt_spp_calc_speed(void)
+{
+       int total_time_ms;
+       FILE *fp = NULL;
+       static char str_speed[30] = "\0";
+       int speed;
+
+       diff_time.tv_sec = end_time.tv_sec - start_time.tv_sec;
+       diff_time.tv_usec = end_time.tv_usec - start_time.tv_usec;
+
+       if(diff_time.tv_usec < 0)
+       {
+               diff_time.tv_sec = diff_time.tv_sec - 1;
+               diff_time.tv_usec = diff_time.tv_usec + 1000000;
+       }
+
+       fp = fopen(BT_INFINITE_SPP_TEST_RESULT_FILE_PATH, "a+");
+       /* Fix : NULL_RETURNS */
+       if (fp == NULL) {
+               BT_ERR("Cannot open file: %s\n", BT_INFINITE_SPP_TEST_RESULT_FILE_PATH);
+               return;
+       }
+       total_time_ms = (diff_time.tv_sec * 1000);
+       total_time_ms += diff_time.tv_usec / 1000;
+
+       speed = (packet_size * total_count * 8) / total_time_ms;
+
+       BT_INFO("%s @ %d kbps", "2MB", speed);
+       snprintf(str_speed, 30, "%s @ %d kbps", "2MB", speed);
+       fprintf(fp, "%s\n", str_speed);
+
+       total_test_count++;
+       sum_time_ms += total_time_ms;
+       if (total_test_count % 10 == 0) {
+               avg_time_ms = sum_time_ms / total_test_count;
+               speed = (packet_size * total_count * 8) / avg_time_ms;
+               BT_INFO("[AVG(%d times)] %d kbps", total_test_count, speed);
+               snprintf(str_speed, 30, "[AVG(%d times)] %d kbps", total_test_count, speed);
+               fprintf(fp, "%s\n", str_speed);
+       }
+
+       if (total_test_count == 1000) {
+               sum_time_ms = 0;
+               avg_time_ms = 0;
+               total_test_count = 0;
+       }
+
+       fclose(fp);
+}
+
+void __bt_make_data(void)
+{
+       int i;
+       int j;
+       char w = 0x20;
+
+       memset(buf, 0x00, packet_size);
+       for (i = 0; i < packet_size / 256; i++) {
+               for (j = 0; j < 256; j++) {
+                       buf[i * 256 + j] = w;
+               }
+
+               w++;
+               if (w > 0x7e)
+                       w = 0x20;
+       }
+}
+
+bool __bt_verify_data(char *data, int data_size)
+{
+       int i;
+
+       if (receive_count == 0 && receive_index == 0)
+               gettimeofday(&start_time, NULL);
+
+       for (i = 0; i < data_size; i++) {
+               if (data[i] != buf[receive_index]) {
+                       BT_ERR("data error. rcv_cnt=%d, data[%d]=%d, buf[%d]=%d", receive_count, i, data[i], receive_index, buf[receive_index]);
+                       return false;
+               }
+
+               receive_index++;
+               if (receive_index == packet_size) {
+                       receive_index = 0;
+                       receive_count++;
+
+                       if (receive_count == total_count)
+                               is_receive_complete = true;
+               }
+       }
+
+       if (is_receive_complete == true) {
+               gettimeofday(&end_time, NULL);
+               __bt_spp_calc_speed();
+               receive_count = 0;
+               receive_index = 0;
+       }
+
+       return true;
+}
+
+static gboolean __bt_send_data(gpointer user_data)
+{
+       int ret = BT_ERROR_NONE;
+       int write = 0;
+       int state = 0;
+       struct timeval tv_write_timeout = {0, };
+       fd_set wfds;
+       int fail_count = 0;
+
+       tv_write_timeout.tv_sec = 1;
+
+       is_receive_complete = false;
+
+       if (sent_count == 0)
+               gettimeofday(&start_time, NULL);
+
+       while (write < packet_size) {
+               FD_ZERO(&wfds);
+               FD_SET(socket_fd, &wfds);
+               state = select(socket_fd + 1, NULL, &wfds, NULL, &tv_write_timeout);
+               if (state == -1) {
+                       BT_ERR("select() error.[0x%X]", ret);
+                       __bt_create_log_dump();
+                       return FALSE;
+               } else {
+                       if (FD_ISSET(socket_fd, &wfds)) {
+                               ret = bt_socket_send_data(socket_fd, buf + write, packet_size - write);
+                               if(ret <= 0) {
+                                               BT_ERR("bt_socket_send_data() failed.[0x%X]", ret);
+                                               __bt_create_log_dump();
+                                               return FALSE;
+                               } else {
+                                       write += ret;
+                               }
+                               fail_count = 0;
+                       } else {
+                               BT_ERR("socket is NOT ready.(fail_count = %d)", fail_count);
+                               if (fail_count++ == 10) {
+                                       BT_ERR("__bt_send_data failed.");
+                                       __bt_create_log_dump();
+                                       return FALSE;
+                               }
+                       }
+               }
+       }
+
+       sent_count++;
+       if (sent_count == total_count) {
+               BT_INFO("Last packet.");
+               gettimeofday(&end_time, NULL);
+               __bt_spp_calc_speed();
+               sent_count = 0;
+       } else {
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+static bool __bt_adapter_foreach_bonded_device_cb(bt_device_info_s *device_info, void *user_data)
+{
+       if (device_info != NULL) {
+               if (bt_device_set_authorization(device_info->remote_address, BT_DEVICE_AUTHORIZED) != BT_ERROR_NONE)
+                       BT_ERR("Fail to authorize");
+       }
+
+       return true;
+}
+
+bool __bt_connect_spp(void)
+{
+       int ret = BT_ERROR_NONE;
+
+       if (spp_role == BT_SPP_TEST_ROLE_SERVER) {
+               if (bt_adapter_foreach_bonded_device(__bt_adapter_foreach_bonded_device_cb, NULL) != BT_ERROR_NONE)
+                       BT_ERR("Fail to get bonded devices");
+
+               if (server_fd < 0) {
+                       ret = bt_socket_create_rfcomm(spp_secure_uuid, &server_fd);
+                       if (ret != BT_ERROR_NONE) {
+                               BT_ERR("bt_socket_create_rfcomm() failed.[0x%X]", ret);
+                               return false;
+                       }
+               }
+
+               ret = bt_socket_listen_and_accept_rfcomm(server_fd, 1);
+               if (ret != BT_ERROR_NONE) {
+                       BT_ERR("bt_socket_listen_and_accept_rfcomm() failed.[0x%X]", ret);
+                       return false;
+               }
+       } else {
+               ret = bt_socket_connect_rfcomm(remote_addr, spp_secure_uuid);
+               if (ret != BT_ERROR_NONE) {
+                       BT_ERR("bt_socket_connect_rfcomm() failed.[0x%X]", ret);
+                       bt_socket_destroy_rfcomm(server_fd);
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+bool __bt_bond_remote_device(void)
+{
+       int ret = BT_ERROR_NONE;
+
+       ret = bt_device_set_bond_created_cb(__bt_device_bond_created_cb, NULL);
+       if (ret != BT_ERROR_NONE) {
+               BT_ERR("bt_device_set_bond_created_cb() failed.[0x%X]", ret);
+               return false;
+       }
+
+       if (spp_role == BT_SPP_TEST_ROLE_CLIENT) {
+               ret = bt_device_create_bond(remote_addr);
+               if (ret != BT_ERROR_NONE) {
+                       BT_ERR("bt_device_create_bond() failed.[0x%X]", ret);
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+bool __bt_is_paired(void)
+{
+       int ret = BT_ERROR_NONE;
+       bool is_paired = false;
+
+       ret = bt_adapter_foreach_bonded_device(__bt_adapter_bonded_device_cb, &is_paired);
+       if (ret != BT_ERROR_NONE) {
+               BT_ERR("bt_adapter_foreach_bonded_device() failed.[0x%X]", ret);
+               return false;
+       }
+
+       return is_paired;
+}
+
+bool __bt_init(void)
+{
+       int ret = BT_ERROR_NONE;
+
+       ret = bt_initialize();
+       if(ret != BT_ERROR_NONE) {
+               BT_ERR("bt_initialize() failed.[0x%X]", ret);
+               return false;
+       }
+
+       ret = bt_adapter_get_state(&bt_state);
+       if(ret != BT_ERROR_NONE) {
+               BT_ERR("bt_adapter_get_state() failed.[0x%X]", ret);
+               return false;
+       }
+
+       ret = bt_adapter_set_state_changed_cb(__bt_adapter_state_changed_cb, NULL);
+       if(ret != BT_ERROR_NONE) {
+               BT_ERR("bt_adapter_get_state() failed.[0x%X]", ret);
+               return false;
+       }
+
+       ret = bt_socket_set_connection_state_changed_cb(__bt_socket_connection_state_changed_cb, NULL);
+       if (ret != BT_ERROR_NONE) {
+               BT_ERR("bt_socket_set_connection_state_changed_cb() failed.[0x%X]", ret);
+               return false;
+       }
+
+       ret = bt_socket_set_data_received_cb(__bt_socket_data_received_cb, NULL);
+       if (ret != BT_ERROR_NONE) {
+               BT_ERR("bt_socket_set_data_received_cb() failed.[0x%X]", ret);
+               return false;
+       }
+
+       if (buf == NULL) {
+               buf = malloc(packet_size);
+               if (buf == NULL) {
+                       BT_ERR("Out of memory");
+                       return false;
+               }
+               __bt_make_data();
+       }
+
+       return true;
+}
+
+void __bt_deinit(void)
+{
+       int ret = BT_ERROR_NONE;
+
+       if (buf)
+               free(buf);
+
+       if (server_fd >= 0)
+               bt_socket_destroy_rfcomm(server_fd);
+
+       ret = bt_socket_unset_data_received_cb();
+       if (ret != BT_ERROR_NONE)
+               BT_ERR("bt_socket_unset_data_received_cb() failed.[0x%X]", ret);
+
+       ret = bt_socket_unset_connection_state_changed_cb();
+       if (ret != BT_ERROR_NONE)
+               BT_ERR("bt_socket_unset_connection_state_changed_cb() failed.[0x%X]", ret);
+
+       ret = bt_device_unset_bond_created_cb();
+       if (ret != BT_ERROR_NONE)
+               BT_ERR("bt_device_unset_bond_created_cb() failed.[0x%X]", ret);
+
+       ret = bt_deinitialize();
+       if(ret != BT_ERROR_NONE)
+               BT_ERR("bt_deinitialize() failed.[0x%X]", ret);
+}
+
+bool __bt_set_remote_address(void)
+{
+       FILE *fp = NULL;
+
+       if ((fp = fopen(BT_INFINITE_SPP_TEST_REMOTE_ADDRESS_FILE_PATH, "r")) == NULL) {
+               BT_ERR("remote_addr file is NOT exist.");
+               return false;
+       }
+
+       if (fgets(remote_addr, 18, fp) == NULL) {
+               BT_ERR("remote_addr is INVALID.");
+               fclose(fp);
+               return false;
+       }
+
+       fclose(fp);
+       return true;
+}
+
+int main(int argc, char *argv[])
+{
+       if (argc == 2 && strcmp(argv[1], "client") == 0)
+               spp_role = BT_SPP_TEST_ROLE_CLIENT;
+       BT_INFO("SPP test role is %s", spp_role==BT_SPP_TEST_ROLE_SERVER?"SERVER":"CLIENT");
+
+       if (spp_role == BT_SPP_TEST_ROLE_CLIENT) {
+               if (__bt_set_remote_address() == false)
+                       return -1;
+       }
+
+       if (__bt_init() == false)
+               goto fail;
+
+       if (bt_state == BT_ADAPTER_ENABLED) {
+               if (spp_role == BT_SPP_TEST_ROLE_SERVER) {
+                       if (bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, 0) != BT_ERROR_NONE)
+                               BT_ERR("Fail to set visibility");
+
+                       __bt_connect_spp();
+               } else {
+                       if (__bt_is_paired() == true) {
+                               if (__bt_connect_spp() == false)
+                                       goto fail;
+                       } else {
+                               if (__bt_bond_remote_device() == false)
+                                       goto fail;
+                       }
+               }
+       }
+
+       g_mainloop = g_main_loop_new(NULL, FALSE);
+       g_main_loop_run(g_mainloop);
+
+fail:
+       if (g_mainloop)
+               g_main_loop_unref(g_mainloop);
+
+       __bt_deinit();
+
+       return 0;
+}
diff --git a/test/bt_infinite_spp_test_server.service b/test/bt_infinite_spp_test_server.service
new file mode 100644 (file)
index 0000000..f622aee
--- /dev/null
@@ -0,0 +1,7 @@
+[Unit]
+Description=BT SPP test infinitely
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/bt_infinite_spp_test
+RemainAfterExit=yes
diff --git a/test/spp_test_addr b/test/spp_test_addr
new file mode 100644 (file)
index 0000000..5dd70bf
--- /dev/null
@@ -0,0 +1 @@
+E4:FA:ED:75:D7:11