tizen 2.3 release
[framework/system/deviced.git] / src / led / conf.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 <stdio.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <assert.h>
24
25 #include "deviced/dd-led.h"
26 #include "core/log.h"
27 #include "core/list.h"
28 #include "core/config-parser.h"
29 #include "conf.h"
30
31 #define LED_CONF        "/etc/deviced/led.conf"
32 #define LED_STR         "led"
33
34 static const char* led_str[] = {
35         [LED_OFF] = "Off",
36         [LED_LOW_BATTERY] = "Low battery",
37         [LED_CHARGING] = "Charging",
38         [LED_FULLY_CHARGED] = "Fully charged",
39         [LED_CHARGING_ERROR] = "Charging error",
40         [LED_MISSED_NOTI] = "Missed noti",
41         [LED_VOICE_RECORDING] = "Voice recording",
42         [LED_REMOTE_CONTROLLER] = "Remote controller",
43         [LED_AIR_WAKEUP] = "Air Wakeup",
44         [LED_POWER_OFF] = "Power off",
45         [LED_CUSTOM] = "Custom",
46 };
47
48 static dd_list *led_head;
49
50 static int get_selected_lcd_mode(const char *value)
51 {
52         int lcd = 0;
53
54         assert(value);
55
56         if (strstr(value, "on"))
57                 lcd |= DURING_LCD_ON;
58         if (strstr(value, "off"))
59                 lcd |= DURING_LCD_OFF;
60
61         return lcd;
62 }
63
64 static int parse_scenario(struct parse_result *result, void *user_data)
65 {
66         dd_list *head = (dd_list*)led_head;
67         struct led_mode *led;
68         int index;
69
70         for (index = 0; index < LED_MODE_MAX; ++index) {
71                 if (MATCH(result->section, led_str[index]))
72                         break;
73         }
74
75         if (index == LED_MODE_MAX) {
76                 _E("No matched valid scenario : %s", result->section);
77                 return -EINVAL;
78         }
79
80         /* search for matched led_data */
81         led = find_led_data(index);
82         /* If there is no matched data */
83         if (!led) {
84                 /* allocate led_data memory */
85                 led = (struct led_mode*)calloc(1, sizeof(struct led_mode));
86                 if (!led) {
87                         _E("out of memory : %s", strerror(errno));
88                         return -errno;
89                 }
90
91                 /* set default value */
92                 led->mode = index;
93                 led->state = 0;
94                 led->data.wave = false;
95                 led->data.lcd = DURING_LCD_OFF;
96                 led->data.duration = -1;
97
98                 /* Add to list */
99                 DD_LIST_APPEND(led_head, led);
100         }
101
102         /* parse the result data */
103         if (MATCH(result->name, "priority"))
104                 led->data.priority = atoi(result->value);
105         else if (MATCH(result->name, "on"))
106                 led->data.on = atoi(result->value);
107         else if (MATCH(result->name, "off"))
108                 led->data.off = atoi(result->value);
109         else if (MATCH(result->name, "color"))
110                 led->data.color = (unsigned int)strtoul(result->value, NULL, 16);
111         else if (MATCH(result->name, "wave"))
112                 led->data.wave = (!strcmp(result->value, "on") ? true : false);
113         else if (MATCH(result->name, "lcd"))
114                 led->data.lcd = get_selected_lcd_mode(result->value);
115         else if (MATCH(result->name, "duration"))
116                 led->data.duration = atoi(result->value);
117
118         return 0;
119 }
120
121 static int led_load_config(struct parse_result *result, void *user_data)
122 {
123         int ret;
124
125         if (!result)
126                 return 0;
127
128         if (!result->section || !result->name || !result->value)
129                 return 0;
130
131         /* Parsing 'LED' section */
132         if (MATCH(result->section, "LED"))
133                 return 0;
134
135         /* Parsing 'Scenario' section */
136         ret = parse_scenario(result, user_data);
137         if (ret < 0) {
138                 _E("failed to parse %s section", result->section);
139                 return ret;
140         }
141
142         return 0;
143 }
144
145 int get_led_data(void)
146 {
147         int ret;
148
149         /* get configuration file */
150         ret = config_parse(LED_CONF, led_load_config, led_head);
151         if (ret < 0) {
152                 _E("failed to load configuration file(%s) : %d", LED_CONF, ret);
153                 release_led_data();
154                 return ret;
155         }
156
157         /* for debug */
158         print_all_data();
159
160         return 0;
161 }
162
163 void release_led_data(void)
164 {
165         dd_list *l;
166         struct led_mode *node;
167
168         DD_LIST_FOREACH(led_head, l, node) {
169                 _D("node name : %d", node->mode);
170                 DD_LIST_REMOVE(led_head, node);
171                 free(node);
172         }
173 }
174
175 struct led_mode *find_led_data(int mode)
176 {
177         dd_list *l;
178         struct led_mode *node;
179
180         DD_LIST_FOREACH(led_head, l, node) {
181                 if (node->mode == mode)
182                         return node;
183         }
184
185         return NULL;
186 }
187
188 struct led_mode *get_valid_led_data(int lcd_state)
189 {
190         dd_list *l;
191         struct led_mode *node;
192         struct led_mode *cur = NULL;
193         int pr = 3;
194
195         DD_LIST_FOREACH(led_head, l, node) {
196                 if (!node->state)
197                         continue;
198
199                 if (!(node->data.lcd & lcd_state))
200                         continue;
201
202                 if (node->data.priority <= pr) {
203                         pr = node->data.priority;
204                         cur = node;
205                 }
206         }
207
208         return cur;
209 }
210
211 void print_all_data(void)
212 {
213         dd_list *l;
214         struct led_mode *node;
215
216         _D("Mode State priority   on  off    color lcd wave");
217         DD_LIST_FOREACH(led_head, l, node) {
218                 _D("%4d %5d %8d %4d %4d %x %4d %4d",
219                                 node->mode, node->state, node->data.priority,
220                                 node->data.on, node->data.off, node->data.color,
221                                 node->data.lcd, node->data.wave);
222         }
223 }