a3290abdf426126faadae77b463e3546fbf6d0c9
[platform/core/api/peripheral-io.git] / src / gdbus / peripheral_gdbus_i2c.c
1 /*
2  * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <gio/gunixfdlist.h>
20
21 #include "peripheral_io.h"
22 #include "peripheral_gdbus.h"
23 #include "peripheral_common.h"
24 #include "peripheral_internal.h"
25 #include "peripheral_io_gdbus.h"
26
27 #define I2C_FD_INDEX 0
28
29 static PeripheralIoGdbusI2c *i2c_proxy = NULL;
30
31 void i2c_proxy_init(void)
32 {
33         GError *error = NULL;
34
35         if (i2c_proxy != NULL) {
36                 g_object_ref(i2c_proxy);
37                 return;
38         }
39
40         i2c_proxy = peripheral_io_gdbus_i2c_proxy_new_for_bus_sync(
41                 G_BUS_TYPE_SYSTEM,
42                 G_DBUS_PROXY_FLAGS_NONE,
43                 PERIPHERAL_GDBUS_NAME,
44                 PERIPHERAL_GDBUS_I2C_PATH,
45                 NULL,
46                 &error);
47 }
48
49 void i2c_proxy_deinit()
50 {
51         if (i2c_proxy) {
52                 g_object_unref(i2c_proxy);
53                 if (!G_IS_OBJECT(i2c_proxy))
54                         i2c_proxy = NULL;
55         }
56 }
57
58 int peripheral_gdbus_i2c_open(peripheral_i2c_h i2c, int bus, int address)
59 {
60         GError *error = NULL;
61         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
62         GUnixFDList *fd_list = NULL;
63
64         if (i2c_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
65
66         if (peripheral_io_gdbus_i2c_call_open_sync(
67                         i2c_proxy,
68                         bus,
69                         address,
70                         NULL,
71                         &i2c->handle,
72                         &ret,
73                         &fd_list,
74                         NULL,
75                         &error) == FALSE) {
76                 _E("Error in %s() : %s", __func__, error->message);
77                 g_error_free(error);
78                 return PERIPHERAL_ERROR_UNKNOWN;
79         }
80
81         i2c->fd = g_unix_fd_list_get(fd_list, I2C_FD_INDEX, &error);
82         if (i2c->fd < 0) {
83                 _E("Failed to get fd for i2c : %s", error->message);
84                 g_error_free(error);
85                 ret = PERIPHERAL_ERROR_UNKNOWN;
86         }
87
88         g_object_unref(fd_list);
89
90         return ret;
91 }
92
93 int peripheral_gdbus_i2c_close(peripheral_i2c_h i2c)
94 {
95         GError *error = NULL;
96         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
97
98         if (i2c_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
99
100         if (peripheral_io_gdbus_i2c_call_close_sync(
101                         i2c_proxy,
102                         i2c->handle,
103                         &ret,
104                         NULL,
105                         &error) == FALSE) {
106                 _E("Error in %s() : %s", __func__, error->message);
107                 g_error_free(error);
108                 return PERIPHERAL_ERROR_UNKNOWN;
109         }
110
111         return ret;
112 }
113
114 int peripheral_gdbus_i2c_read(peripheral_i2c_h i2c, uint8_t *data, int length)
115 {
116         GError *error = NULL;
117         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
118         GVariant *data_array;
119         GVariantIter *iter;
120         guint8 str;
121         int i = 0;
122
123         if (i2c_proxy == NULL || data == NULL) return PERIPHERAL_ERROR_UNKNOWN;
124
125         if (peripheral_io_gdbus_i2c_call_read_sync(
126                         i2c_proxy,
127                         i2c->handle,
128                         length,
129                         &data_array,
130                         &ret,
131                         NULL,
132                         &error) == FALSE) {
133                 _E("Error in %s() : %s", __func__, error->message);
134                 g_error_free(error);
135                 return PERIPHERAL_ERROR_UNKNOWN;
136         }
137
138         g_variant_get(data_array, "a(y)", &iter);
139         while (g_variant_iter_loop(iter, "(y)", &str)) {
140                 data[i] = str;
141                 if (i++ == length) break;
142         }
143         g_variant_iter_free(iter);
144         g_variant_unref(data_array);
145
146         return ret;
147 }
148
149 int peripheral_gdbus_i2c_write(peripheral_i2c_h i2c, uint8_t *data, int length)
150 {
151         GError *error = NULL;
152         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
153         GVariantBuilder *builder;
154         GVariant *g_data;
155         int i = 0;
156
157         if (i2c_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
158
159         builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)"));
160
161         for (i = 0; i < length; i++)
162                 g_variant_builder_add(builder, "(y)", data[i]);
163         g_variant_builder_add(builder, "(y)", 0x00);
164
165         g_data = g_variant_new("a(y)", builder);
166         g_variant_builder_unref(builder);
167
168         if (peripheral_io_gdbus_i2c_call_write_sync(
169                         i2c_proxy,
170                         i2c->handle,
171                         length,
172                         g_data,
173                         &ret,
174                         NULL,
175                         &error) == FALSE) {
176                 _E("Error in %s() : %s", __func__, error->message);
177                 g_error_free(error);
178                 return PERIPHERAL_ERROR_UNKNOWN;
179         }
180
181         return ret;
182 }
183
184 int peripheral_gdbus_i2c_smbus_ioctl(peripheral_i2c_h i2c, uint8_t read_write, uint8_t command, uint32_t size, uint16_t data_in, uint16_t *data_out)
185 {
186         GError *error = NULL;
187         peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
188
189         if (i2c_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
190
191         if (peripheral_io_gdbus_i2c_call_smbus_ioctl_sync(
192                         i2c_proxy,
193                         i2c->handle,
194                         read_write,
195                         command,
196                         size,
197                         data_in,
198                         data_out,
199                         &ret,
200                         NULL,
201                         &error) == FALSE) {
202                 _E("Error in %s() : %s", __func__, error->message);
203                 g_error_free(error);
204                 return PERIPHERAL_ERROR_UNKNOWN;
205         }
206
207         return ret;
208 }