tizen 2.3 release
[framework/system/deviced.git] / src / board / board-info.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <fcntl.h>
21
22 #include "core/log.h"
23 #include "core/devices.h"
24 #include "core/edbus-handler.h"
25 #include "core/common.h"
26
27 #define FILE_BUFF_MAX   1024
28 #define NOT_INITIALIZED (-1)
29
30 #define METHOD_GET_NUM  "GetNum"
31 #define METHOD_GET_SERIAL       "GetSerial"
32 #define SERIAL_PATH_NAME        "/csa/imei/serialno.dat"
33
34 #define METHOD_GET_REVISION     "GetHWRev"
35 #define PATH_NAME               "/proc/cpuinfo"
36 #define REVISION_NAME   "Revision"
37 #define SERIAL_NAME             "Serial"
38 #define SERIAL_TOK_DELIMITER ","
39 #define TOK_DELIMITER   ":"
40 #define END_DELIMITER   " \n"
41
42 #define CONVERT_TYPE    10
43 #define REVISION_SIZE   4
44
45 struct serial_info {
46         char serial[FILE_BUFF_MAX];
47         char num[FILE_BUFF_MAX];
48 };
49
50 static struct serial_info info;
51
52 static int read_from_file(const char *path, char *buf, size_t size)
53 {
54         int fd;
55         size_t count;
56
57         if (!path)
58                 return -1;
59
60         fd = open(path, O_RDONLY, 0);
61         if (fd == -1) {
62                 _E("Could not open '%s'", path);
63                 return -1;
64         }
65
66         count = read(fd, buf, size);
67
68         if (count > 0) {
69                 count = (count < size) ? count : size - 1;
70                 while (count > 0 && buf[count - 1] == '\n')
71                         count--;
72                 buf[count] = '\0';
73         } else {
74                 buf[0] = '\0';
75         }
76
77         close(fd);
78
79         return 0;
80 }
81
82 static int get_revision(char *rev)
83 {
84         char buf[FILE_BUFF_MAX];
85         char *tag;
86         char *start, *ptr;
87         long rev_num;
88         const int radix = 16;
89
90         if (rev == NULL) {
91                 _E("Invalid argument !\n");
92                 return -1;
93         }
94
95         if (read_from_file(PATH_NAME, buf, FILE_BUFF_MAX) < 0) {
96                 _E("fail to read %s\n", PATH_NAME);
97                 return -1;
98         }
99
100         tag = strstr(buf, REVISION_NAME);
101         if (tag == NULL) {
102                 _E("cannot find Hardware in %s\n", PATH_NAME);
103                 return -1;
104         }
105
106         start = strstr(tag, TOK_DELIMITER);
107         if (start == NULL) {
108                 _E("cannot find Hardware in %s\n", PATH_NAME);
109                 return -1;
110         }
111
112         start ++;
113         ptr = strtok(start, END_DELIMITER);
114         ptr += strlen(ptr);
115         ptr -=2;
116
117         memset(rev, 0x00, REVISION_SIZE);
118         rev_num = strtol(ptr, NULL, radix);
119         sprintf(rev, "%d", rev_num);
120
121         return 0;
122 }
123
124 static int get_cpuinfo_serial(void)
125 {
126         char buf[FILE_BUFF_MAX];
127         char *tag;
128         char *start, *ptr;
129
130         if (read_from_file(PATH_NAME, buf, FILE_BUFF_MAX) < 0) {
131                 _E("fail to read %s\n", PATH_NAME);
132                 return -1;
133         }
134
135         tag = strstr(buf, SERIAL_NAME);
136         if (tag == NULL) {
137                 _E("cannot find Hardware in %s\n", PATH_NAME);
138                 return -1;
139         }
140
141         start = strstr(tag, TOK_DELIMITER);
142         if (start == NULL) {
143                 _E("cannot find Hardware in %s\n", PATH_NAME);
144                 return -1;
145         }
146
147         start ++;
148         ptr = strtok(start, END_DELIMITER);
149         strncpy(info.serial, ptr, strlen(ptr));
150         _D("%s", info.serial);
151         return 0;
152 }
153
154 static DBusMessage *dbus_revision_handler(E_DBus_Object *obj, DBusMessage *msg)
155 {
156         DBusMessageIter iter;
157         DBusMessage *reply;
158         char rev[FILE_BUFF_MAX];
159         char *ptr;
160         static int ret = NOT_INITIALIZED;
161
162         if (ret != NOT_INITIALIZED)
163                 goto out;
164         ret = get_revision(rev);
165         if (ret == 0)
166                 ret = strtol(rev, &ptr, CONVERT_TYPE);
167 out:
168         _D("rev : %d", ret);
169
170         reply = dbus_message_new_method_return(msg);
171         dbus_message_iter_init_append(reply, &iter);
172         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
173         return reply;
174 }
175
176 static int get_serial(void)
177 {
178         static int ret = -EIO;
179         int fd;
180         int r;
181         char *tag;
182         char *serial;
183         char buf[FILE_BUFF_MAX];
184
185         if (ret == 0)
186                 return ret;
187
188         fd = open(SERIAL_PATH_NAME, O_RDONLY, 0);
189         if (fd < 0)
190                 return -ENOENT;
191
192         r = read(fd, buf, FILE_BUFF_MAX);
193         if (r < 0 || r >= FILE_BUFF_MAX)
194                 goto out;
195         buf[r] = '\0';
196         tag = buf;
197         serial = strstr(buf, SERIAL_TOK_DELIMITER);
198         if (serial) {
199                 serial = strtok(tag, SERIAL_TOK_DELIMITER);
200                 if (!serial)
201                         goto out;
202                 r = strlen(serial);
203                 strncpy(info.serial, serial, r);
204         } else {
205                 strncpy(info.serial, buf, r);
206         }
207         _D("%s %d", info.serial, r);
208         ret = 0;
209 out:
210         close(fd);
211         return ret;
212 }
213
214 static int get_num(void)
215 {
216         static int ret = -EIO;
217         int fd;
218         int r;
219         char *tag;
220         char *num;
221         char buf[FILE_BUFF_MAX];
222
223         if (ret == 0)
224                 return ret;
225
226         fd = open(SERIAL_PATH_NAME, O_RDONLY, 0);
227         if (fd < 0)
228                 return -ENOENT;
229
230         r = read(fd, buf, FILE_BUFF_MAX);
231         if (r < 0 || r >= FILE_BUFF_MAX)
232                 goto out;
233         buf[r] = '\0';
234         num = strstr(buf, SERIAL_TOK_DELIMITER);
235         if (!num)
236                 goto out;
237         tag = buf;
238         strtok(tag, SERIAL_TOK_DELIMITER);
239         strtok(NULL, SERIAL_TOK_DELIMITER);
240         num = strtok(NULL, END_DELIMITER);
241         if (!num)
242                 goto out;
243         r = strlen(num);
244         strncpy(info.num, num, r);
245         _D("%s %d", info.num, r);
246         ret = 0;
247 out:
248         close(fd);
249         return ret;
250 }
251
252 static DBusMessage *dbus_serial_handler(E_DBus_Object *obj, DBusMessage *msg)
253 {
254         DBusMessageIter iter, arr;
255         DBusMessage *reply;
256         static int len = 0;
257         static int ret = NOT_INITIALIZED;
258         char buf[FILE_BUFF_MAX];
259         char *param = buf;
260
261         ret = get_serial();
262         if (ret < 0)
263                 ret = get_cpuinfo_serial();
264         if (ret == 0) {
265                 len = strlen(info.serial);
266                 strncpy(buf, info.serial, len);
267                 _D("%s %d", buf, len);
268                 goto out;
269         }
270         _E("fail to get serial");
271 out:
272         reply = dbus_message_new_method_return(msg);
273         dbus_message_iter_init_append(reply, &iter);
274         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &param);
275         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
276         return reply;
277 }
278
279 static DBusMessage *dbus_num_handler(E_DBus_Object *obj, DBusMessage *msg)
280 {
281         DBusMessageIter iter, arr;
282         DBusMessage *reply;
283         static int len = 0;
284         static char buf[FILE_BUFF_MAX];
285         static char *param = buf;
286         static int ret = NOT_INITIALIZED;
287
288         ret = get_num();
289         if (ret == 0) {
290                 len = strlen(info.num);
291                 strncpy(buf, info.num, len);
292                 _D("%s %d", buf, len);
293                 goto out;
294         }
295         _E("fail to get num");
296 out:
297         reply = dbus_message_new_method_return(msg);
298         dbus_message_iter_init_append(reply, &iter);
299         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &param);
300         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
301         return reply;
302 }
303
304 static const struct edbus_method edbus_methods[] = {
305         { METHOD_GET_SERIAL,   NULL, "si", dbus_serial_handler },
306         { METHOD_GET_REVISION,   NULL, "i", dbus_revision_handler },
307         { METHOD_GET_NUM,   NULL, "si", dbus_num_handler },
308 };
309
310 static void board_init(void *data)
311 {
312         int ret;
313
314         ret = register_edbus_method(DEVICED_PATH_BOARD, edbus_methods, ARRAY_SIZE(edbus_methods));
315         if (ret < 0)
316                 _E("fail to init edbus method(%d)", ret);
317         ret = get_serial();
318         if (ret < 0)
319                 _E("fail to get serial info(%d)", ret);
320         ret = get_num();
321         if (ret < 0)
322                 _E("fail to get num info(%d)", ret);
323 }
324
325 static const struct device_ops board_device_ops = {
326         .priority = DEVICE_PRIORITY_NORMAL,
327         .name     = "board",
328         .init     = board_init,
329 };
330
331 DEVICE_OPS_REGISTER(&board_device_ops)