68ec7af5c890e6ebb9d2e384d6341a64ab97a4b6
[platform/adaptation/bluetooth-firmware-sprd.git] / src / hal-backend-bluetooth.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <errno.h>
5 #include <dlog.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <hal/hal-bluetooth-interface.h>
9
10 #undef LOG_TAG
11 #define LOG_TAG "HALAPI_BLUETOOTH"
12
13 #define EXPORT __attribute__ ((visibility("default")))
14
15 #define WIFI_CP2_FIRMWARE_STATE_PATH "/tmp/.wifi-firmware-loaded"
16 #define BT_CP2_FIRMWARE_STATE_PATH "/tmp/.bt-firmware-loaded"
17 #define BT_CP2_FIRMWARE_PATH "/hal/bin/cp2-downloader"
18 #define MAX_SIZE_ERROR_BUFFER 256
19
20 int __bt_execute_file(const char *file_path,
21                 char *const args[], char *const envs[])
22 {
23         pid_t pid = 0;
24         int status = 0;
25         int rv = 0;
26         errno = 0;
27         register unsigned int index = 0;
28         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
29
30         while (args[index] != NULL) {
31                 LOGD("%s", args[index]);
32                 index++;
33         }
34
35         if (!(pid = fork())) {
36                 LOGD("pid(%d), ppid (%d)", getpid(), getppid());
37                 LOGD("Inside child, exec (%s) command", file_path);
38
39                 errno = 0;
40                 if (execve(file_path, args, envs) == -1) {
41                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
42                         LOGE("Fail to execute command (%s)", error_buf);
43                         exit(1);
44                 }
45         } else if (pid > 0) {
46                 if (waitpid(pid, &status, 0) == -1)
47                         LOGD("wait pid (%u) status (%d)", pid, status);
48
49                 if (WIFEXITED(status)) {
50                         rv = WEXITSTATUS(status);
51                         LOGD("exited, status=%d", rv);
52                 } else if (WIFSIGNALED(status)) {
53                         LOGD("killed by signal %d", WTERMSIG(status));
54                 } else if (WIFSTOPPED(status)) {
55                         LOGD("stopped by signal %d", WSTOPSIG(status));
56                 } else if (WIFCONTINUED(status)) {
57                         LOGD("continued");
58                 }
59
60                 return rv;
61         }
62
63         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
64         LOGD("failed to fork(%s)", error_buf);
65         return -EIO;
66 }
67
68 static void __bt_firmware_update_state(void)
69 {
70     int fd;
71     mode_t mode = S_IRGRP | S_IWUSR | S_IXGRP;
72
73     fd = creat(BT_CP2_FIRMWARE_STATE_PATH, mode);
74     if (fd >= 0)
75         close(fd);
76     else
77         LOGE("Failed to create bt firmware state file");
78 }
79
80 static int bluetooth_tm1_start(void)
81 {
82         int ret;
83         char *const args[] = {BT_CP2_FIRMWARE_PATH, NULL};
84         char *const envs[] = {NULL};
85
86         if (access(WIFI_CP2_FIRMWARE_STATE_PATH, F_OK) != 0
87                         && access(BT_CP2_FIRMWARE_STATE_PATH, F_OK) != 0) {
88                 ret = __bt_execute_file(BT_CP2_FIRMWARE_PATH, args, envs);
89                 if (ret < 0) {
90                         LOGE("bt firmware download failed");
91                         return HAL_BACKEND_ERROR_INTERNAL;
92                 }
93                 __bt_firmware_update_state();
94                 LOGD("bt firmware download succeeded");
95         }
96
97         ret = system("/hal/etc/bluetooth/bt-dev-start.sh");
98         if (ret == 0x100) {
99                 LOGE("script internal failed");
100                 return HAL_BACKEND_ERROR_INTERNAL;
101         } else if (ret == 0x200) {
102                 LOGE("script timeout failed");
103                 return HAL_BACKEND_ERROR_TIMEOUT;
104         }
105         LOGD("script started successfully");
106         return HAL_BACKEND_ERROR_NONE;
107 }
108
109 static int bluetooth_tm1_stop(void)
110 {
111         int ret;
112         ret = system("/hal/etc/bluetooth/bt-dev-end.sh");
113         if (ret == 0x100) {
114                 LOGE("script internal failed");
115                 return HAL_BACKEND_ERROR_INTERNAL;
116         } else if (ret == 0x200) {
117                 LOGE("script timeout failed");
118                 return HAL_BACKEND_ERROR_TIMEOUT;
119         }
120         LOGD("script started successfully");
121         return HAL_BACKEND_ERROR_NONE;
122 }
123
124 static int bluetooth_tm1_init(void **data)
125 {
126         hal_backend_bluetooth_funcs *bluetooth_funcs;
127
128         bluetooth_funcs = calloc(1, sizeof(hal_backend_bluetooth_funcs));
129         if (!bluetooth_funcs)
130                 return -ENOMEM;
131
132         bluetooth_funcs->start = bluetooth_tm1_start;
133         bluetooth_funcs->stop = bluetooth_tm1_stop;
134
135         *data = (void *)bluetooth_funcs;
136
137         return 0;
138 }
139
140 static int bluetooth_tm1_exit(void *data)
141 {
142         if (!data)
143                 return -EINVAL;
144         free(data);
145
146         return 0;
147 }
148
149 hal_backend EXPORT hal_backend_bluetooth_data = {
150         .name = "bluetooth-spreadtrum",
151         .vendor = "Spreadtrum",
152         .abi_version = HAL_ABI_VERSION_TIZEN_6_5,
153         .init = bluetooth_tm1_init,
154         .exit = bluetooth_tm1_exit,
155 };