Updated package changelog.
[profile/ivi/ico-uxf-homescreen.git] / apps_controller / ico_syc_apc_regulation.c
1 /*
2  * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9 /**
10  * @brief   Regulation controller
11  *
12  * @date    Feb-28-2013
13  */
14
15 #include    <stdio.h>
16 #include    <stdlib.h>
17 #include    <unistd.h>
18 #include    <stdbool.h>
19 #include    <string.h>
20 #include    <errno.h>
21 #include    <pthread.h>
22 #include    <sys/ioctl.h>
23 #include    <sys/time.h>
24 #include    <fcntl.h>
25
26 #include    <wayland-client.h>
27 #include    <ico_window_mgr-client-protocol.h>
28 #include    <dbus/dbus.h>
29 #include    <Ecore.h>
30 #include    "ico_apf.h"
31 #include    "ico_syc_apc.h"
32 #include    "ico_syc_apc_private.h"
33
34 /*==============================================================================*/
35 /* static tables                                                                */
36 /*==============================================================================*/
37 /* callback function            */
38 static ico_apc_regulation_cb_t  regulation_cb = NULL;
39 static void                     *regulation_cb_user_data = NULL;
40
41 /* Ecore/D-Bus static valiables */
42 static Ecore_Timer *vehicle_timer = NULL;
43 static DBusConnection *dbus_connection = NULL;
44 static ico_apc_reguration_control_t control[ICO_UXF_CATEGORY_MAX];
45
46 /* vehicle information          */
47 static const struct _vehicle_info_property {
48     int     key;                        /* Vehicle Information key                  */
49     char    *property;                  /* D-Bus property name                      */
50     char    *path;                      /* D-Bus path name                          */
51     char    *interface;                 /* D-Bus interface name                     */
52 }                   vehicle_info[] = {
53     { ICO_SYC_VEHICLEINFO_VEHICLE_SPEED, "VehicleSpeed",
54       "/org/automotive/runningstatus/vehicleSpeed", "org.automotive.vehicleSpeed" },
55     { ICO_SYC_VEHICLEINFO_SHIFT_POSITION, "ShiftPosition",
56       "/org/automotive/runningstatus/transmission", "org.automotive.transmission" },
57     { ICO_SYC_VEHICLEINFO_TURN_SIGNAL, "TurnSignal",
58       "/org/automotive/runningstatus/turnSignal", "org.automotive.turnSignal" },
59     { 0, "\0", "\0", "\0" }
60 };
61
62 /* Vehicle information data     */
63 static struct _vehicle_info_data    {
64     int             key;                /* Vehicle Information key                  */
65     DBusPendingCall *pending;
66     int             request;
67     int             errcount;
68     double          val;
69 }                   vehicle_data[ICO_UXF_REGULATION_VIC_MAX];
70
71 /* system configuration         */
72 static Ico_Uxf_Sys_Config       *confsys = NULL;
73 static int      ncategory;
74 static Ico_Uxf_conf_category    *category;
75
76 /*==============================================================================*/
77 /* define static function prototype                                             */
78 /*==============================================================================*/
79 static int request_vehicle_info(void);
80 static int get_vehicle_info(void);
81 static Eina_Bool rule_engine_wake(void *user_data);
82
83 /*--------------------------------------------------------------------------*/
84 /**
85  * @brief   request_vehicle_info: request to AMB(static function)
86  *
87  * @param       none
88  * @return      result
89  * @retval      ICO_SYC_EOK     success
90  * @retval      ICO_SYC_EIO     error(D-Bus send error)
91  */
92 /*--------------------------------------------------------------------------*/
93 static int
94 request_vehicle_info(void)
95 {
96     DBusMessage *dbus_message = NULL;
97     int     idx;
98     int     ret = ICO_SYC_EOK;
99
100     for (idx = 0; vehicle_info[idx].key; idx++) {
101
102         /* set vehicle info key     */
103         vehicle_data[idx].key = vehicle_info[idx].key;
104
105         if (vehicle_data[idx].pending)  {
106             apfw_trace("request_vehicle_info: (%s) not complite",
107                        vehicle_info[idx].property);
108             continue;
109         }
110
111         if (vehicle_info[idx].path[0] == 0) {
112             /* currently not support this vehicle information   */
113             continue;
114         }
115
116         /* Create send message      */
117         dbus_message = dbus_message_new_method_call(DBUS_SERVICE, vehicle_info[idx].path,
118                                                     DBUS_INTERFACE, DBUS_METHOD);
119         if (! dbus_message) {
120             apfw_warn("request_vehicle_info: ERROR dbus_message_new_method_call" );
121             ret = ICO_SYC_EIO;
122         }
123         /* Set parameters into message  */
124         else if (! dbus_message_append_args(
125                             dbus_message,
126                             DBUS_TYPE_STRING, &vehicle_info[idx].interface,
127                             DBUS_TYPE_STRING, &vehicle_info[idx].property,
128                             DBUS_TYPE_INVALID)) {
129             apfw_warn("request_vehicle_info: ERROR dbus_message_append_args" );
130             ret = ICO_SYC_EIO;
131         }
132         /* Set destination              */
133         else if (! dbus_message_set_destination(dbus_message, DBUS_SERVICE))    {
134             apfw_warn("request_vehicle_info: ERROR dbus_message_set_destination" );
135             ret = ICO_SYC_EIO;
136         }
137         /* Send message                 */
138         else if (! dbus_connection_send_with_reply(
139                             dbus_connection, dbus_message,
140                             &vehicle_data[idx].pending, 200))    {
141             apfw_warn("request_vehicle_info: ERROR dbus_connection_send" );
142             vehicle_data[idx].pending = NULL;
143             ret = ICO_SYC_EIO;
144         }
145         if (dbus_message)   {
146             /* Release message                  */
147             dbus_message_unref(dbus_message);
148         }
149     }
150
151     /* dispatch if data queue exist         */
152     do  {
153         dbus_connection_read_write_dispatch(dbus_connection, 0);
154     } while (dbus_connection_get_dispatch_status(dbus_connection)
155              == DBUS_DISPATCH_DATA_REMAINS);
156
157     return(ret);
158 }
159
160 /*--------------------------------------------------------------------------*/
161 /**
162  * @brief   get_vehicle_info: get vercle information from AMB(static function)
163  *
164  * @param       none
165  * @return      always ICO_SYC_EOK(success)
166  */
167 /*--------------------------------------------------------------------------*/
168 static int
169 get_vehicle_info(void)
170 {
171     DBusMessage *dbus_message = NULL;
172     DBusMessageIter iter_head;
173     DBusMessageIter iter;
174     int         idx;
175     char        type;
176     int32_t     i32;
177     int16_t     i16;
178     uint32_t    u32;
179     uint16_t    u16;
180     dbus_bool_t b;
181     uint8_t     u8;
182     double      d64;
183
184     /* dispatch if data queue exist         */
185     do {
186         dbus_connection_read_write_dispatch(dbus_connection, 0);
187     } while (dbus_connection_get_dispatch_status(dbus_connection)
188              == DBUS_DISPATCH_DATA_REMAINS);
189
190     /* analize reply datas                  */
191     for (idx = 0; vehicle_info[idx].key; idx++) {
192         if (! vehicle_data[idx].pending)    {
193             continue;
194         }
195         if (! dbus_pending_call_get_completed(vehicle_data[idx].pending))   {
196             apfw_trace("get_vehicle_info: (%s) NOT complite",
197                        vehicle_info[idx].property);
198             continue;
199         }
200
201         dbus_message = dbus_pending_call_steal_reply(vehicle_data[idx].pending);
202         if (! dbus_message) {
203             apfw_trace("get_vehicle_info: (%s) NO reply", vehicle_info[idx].property);
204             continue;
205         }
206
207         if (dbus_message_get_type(dbus_message) == DBUS_MESSAGE_TYPE_ERROR) {
208             dbus_message_unref(dbus_message);
209             dbus_pending_call_unref(vehicle_data[idx].pending);
210             vehicle_data[idx].pending = NULL;
211             vehicle_data[idx].errcount ++;
212             if (vehicle_data[idx].errcount <= 5)    {
213                 apfw_trace("get_vehicle_info: (%s) reply error", vehicle_info[idx].property);
214             }
215             continue;
216         }
217
218         dbus_message_iter_init(dbus_message, &iter_head);
219         dbus_message_iter_recurse(&iter_head, &iter);
220
221         type = dbus_message_iter_get_arg_type(&iter);
222         switch (type)   {
223         case DBUS_TYPE_INT32:
224             dbus_message_iter_get_basic(&iter, &i32);
225             vehicle_data[idx].val = (double)i32;
226             break;
227         case DBUS_TYPE_INT16:
228             dbus_message_iter_get_basic(&iter, &i16);
229             vehicle_data[idx].val = (double)i16;
230             break;
231         case DBUS_TYPE_UINT32:
232             dbus_message_iter_get_basic(&iter, &u32);
233             vehicle_data[idx].val = (double)u32;
234             break;
235         case DBUS_TYPE_UINT16:
236             dbus_message_iter_get_basic(&iter, &u16);
237             vehicle_data[idx].val = (double)u16;
238             break;
239         case DBUS_TYPE_BOOLEAN:
240             dbus_message_iter_get_basic(&iter, &b);
241             if (b)      vehicle_data[idx].val = (double)1.0;
242             else        vehicle_data[idx].val = (double)0.0;
243             break;
244         case DBUS_TYPE_BYTE:
245             dbus_message_iter_get_basic(&iter, &u8);
246             vehicle_data[idx].val = (double)u8;
247             break;
248         case DBUS_TYPE_DOUBLE:
249             dbus_message_iter_get_basic(&iter, &d64);
250             vehicle_data[idx].val = (double)d64;
251             break;
252         default:
253             apfw_warn("get_vehicle_info: (%s) illegal data type(0x%02x)",
254                       vehicle_info[idx].property, ((int)type) & 0x0ff);
255             break;
256         }
257         /* free message and pending     */
258         dbus_message_unref(dbus_message);
259         dbus_pending_call_unref(vehicle_data[idx].pending);
260         vehicle_data[idx].pending = NULL;
261     };
262     return ICO_SYC_EOK;
263 }
264
265 /*--------------------------------------------------------------------------*/
266 /**
267  * @brief   rule_engine_wake: judge a run regulation state(static function)
268  *
269  * @param[in]   user_data       user data(unused)
270  * @return      always ECORE_CALLBACK_RENEW(periodic timer)
271  */
272 /*--------------------------------------------------------------------------*/
273 static Eina_Bool
274 rule_engine_wake(void *user_data)
275 {
276     int     idx;
277     ico_apc_reguration_control_t    wkcontrol[ICO_UXF_CATEGORY_MAX];
278     ico_apc_reguration_control_t    change;
279     double  VehicleSpeed = 0.0;
280     int     ShiftPosition = 0;
281     int     Blinker = 0;
282
283     memset(wkcontrol, 0, sizeof(ico_apc_reguration_control_t) * ncategory);
284
285     /* get reply (vehicle ifno) */
286     get_vehicle_info();
287
288     /* get vehicle info values  */
289     for (idx = 0; vehicle_data[idx].key; idx++)   {
290         if (vehicle_data[idx].key == ICO_SYC_VEHICLEINFO_VEHICLE_SPEED)   {
291             VehicleSpeed = (double)vehicle_data[idx].val;
292         }
293         else if (vehicle_data[idx].key == ICO_SYC_VEHICLEINFO_SHIFT_POSITION) {
294             ShiftPosition = (int)vehicle_data[idx].val;
295         }
296         else if (vehicle_data[idx].key == ICO_SYC_VEHICLEINFO_TURN_SIGNAL) {
297             Blinker = (int)vehicle_data[idx].val;
298         }
299     }
300
301     /* Make control code            */
302     memcpy(wkcontrol, control, sizeof(ico_apc_reguration_control_t) * ncategory);
303
304     /* Check Vehicle Speed          */
305     for (idx = 0; idx < ncategory; idx++)   {
306         switch (category[idx].view) {
307         case ICO_UXF_POLICY_ALWAYS:
308             wkcontrol[idx].display = ICO_SYC_APC_REGULATION_NOREGULATION;
309             break;
310         case ICO_UXF_POLICY_RUNNING:
311             if (VehicleSpeed >= ICO_SYC_APC_REGULATION_SPEED_RUNNING)
312                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_NOREGULATION;
313             else
314                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_REGULATION;
315             break;
316         case ICO_UXF_POLICY_PARKED:
317             if (VehicleSpeed >= ICO_SYC_APC_REGULATION_SPEED_RUNNING)
318                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_REGULATION;
319             else
320                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_NOREGULATION;
321             break;
322         case ICO_UXF_POLICY_SHIFT_PARKING:
323             if ((VehicleSpeed < ICO_SYC_APC_REGULATION_SPEED_RUNNING) &&
324                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_PARKING))
325                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_REGULATION;
326             else
327                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_NOREGULATION;
328             break;
329         case ICO_UXF_POLICY_SHIFT_REVERSES:
330             if (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_REVERSES)
331                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_NOREGULATION;
332             else
333                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_REGULATION;
334             break;
335         case ICO_UXF_POLICY_BLINKER_LEFT:
336             if ((Blinker != ICO_SYC_APC_REGULATION_BLINKER_LEFT) ||
337                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_PARKING) ||
338                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_REVERSES))
339                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_REGULATION;
340             else
341                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_NOREGULATION;
342             break;
343         case ICO_UXF_POLICY_BLINKER_RIGHT:
344             if ((Blinker != ICO_SYC_APC_REGULATION_BLINKER_RIGHT) ||
345                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_PARKING) ||
346                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_REVERSES))
347                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_REGULATION;
348             else
349                 wkcontrol[idx].display = ICO_SYC_APC_REGULATION_NOREGULATION;
350             break;
351         default:
352             apfw_trace("rule_engine_wake: category(%d) has unknown view(%d)",
353                        idx, category[idx].view);
354             break;
355         }
356
357         switch (category[idx].sound)    {
358         case ICO_UXF_POLICY_ALWAYS:
359             wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_NOREGULATION;
360             break;
361         case ICO_UXF_POLICY_RUNNING:
362             if (VehicleSpeed >= ICO_SYC_APC_REGULATION_SPEED_RUNNING)
363                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_NOREGULATION;
364             else
365                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_REGULATION;
366             break;
367         case ICO_UXF_POLICY_PARKED:
368             if (VehicleSpeed >= ICO_SYC_APC_REGULATION_SPEED_RUNNING)
369                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_REGULATION;
370             else
371                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_NOREGULATION;
372             break;
373         case ICO_UXF_POLICY_SHIFT_PARKING:
374             if (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_PARKING)
375                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_NOREGULATION;
376             else
377                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_REGULATION;
378             break;
379         case ICO_UXF_POLICY_SHIFT_REVERSES:
380             if (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_REVERSES)
381                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_NOREGULATION;
382             else
383                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_REGULATION;
384             break;
385         case ICO_UXF_POLICY_BLINKER_LEFT:
386             if ((Blinker != ICO_SYC_APC_REGULATION_BLINKER_LEFT) ||
387                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_PARKING) ||
388                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_REVERSES))
389                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_REGULATION;
390             else
391                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_NOREGULATION;
392             break;
393         case ICO_UXF_POLICY_BLINKER_RIGHT:
394             if ((Blinker != ICO_SYC_APC_REGULATION_BLINKER_RIGHT) ||
395                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_PARKING) ||
396                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_REVERSES))
397                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_REGULATION;
398             else
399                 wkcontrol[idx].sound = ICO_SYC_APC_REGULATION_NOREGULATION;
400             break;
401         default:
402             apfw_trace("rule_engine_wake: category(%d) has unknown sound(%d)",
403                        idx, category[idx].sound);
404             break;
405         }
406
407         switch (category[idx].input)    {
408         case ICO_UXF_POLICY_ALWAYS:
409             wkcontrol[idx].input = ICO_SYC_APC_REGULATION_NOREGULATION;
410             break;
411         case ICO_UXF_POLICY_RUNNING:
412             if (VehicleSpeed >= ICO_SYC_APC_REGULATION_SPEED_RUNNING)
413                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_NOREGULATION;
414             else
415                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_REGULATION;
416             break;
417         case ICO_UXF_POLICY_PARKED:
418             if (VehicleSpeed >= ICO_SYC_APC_REGULATION_SPEED_RUNNING)
419                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_REGULATION;
420             else
421                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_NOREGULATION;
422             break;
423         case ICO_UXF_POLICY_SHIFT_PARKING:
424             if (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_PARKING)
425                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_NOREGULATION;
426             else
427                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_REGULATION;
428             break;
429         case ICO_UXF_POLICY_SHIFT_REVERSES:
430             if (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_REVERSES)
431                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_NOREGULATION;
432             else
433                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_REGULATION;
434             break;
435         case ICO_UXF_POLICY_BLINKER_LEFT:
436             if ((Blinker != ICO_SYC_APC_REGULATION_BLINKER_LEFT) ||
437                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_PARKING) ||
438                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_REVERSES))
439                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_REGULATION;
440             else
441                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_NOREGULATION;
442             break;
443         case ICO_UXF_POLICY_BLINKER_RIGHT:
444             if ((Blinker != ICO_SYC_APC_REGULATION_BLINKER_RIGHT) ||
445                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_PARKING) ||
446                 (ShiftPosition == ICO_SYC_APC_REGULATION_SHIFT_REVERSES))
447                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_REGULATION;
448             else
449                 wkcontrol[idx].input = ICO_SYC_APC_REGULATION_NOREGULATION;
450             break;
451         default:
452             apfw_trace("rule_engine_wake: category(%d) has unknown input(%d)",
453                        idx, category[idx].input);
454             break;
455         }
456     }
457
458     for (idx = 0; idx < ncategory; idx++) {
459         if ((control[idx].display != wkcontrol[idx].display) ||
460             (control[idx].sound != wkcontrol[idx].sound) ||
461             (control[idx].input != wkcontrol[idx].input))   {
462             apfw_trace("rule_engine_wake: Category.%d view.%d>%d sound.%d>%d inp.%d>%d",
463                        idx, control[idx].display, wkcontrol[idx].display,
464                        control[idx].sound, wkcontrol[idx].sound,
465                        control[idx].input, wkcontrol[idx].input);
466
467             if (regulation_cb)  {
468                 if (control[idx].display != wkcontrol[idx].display)
469                     change.display = wkcontrol[idx].display;
470                 else
471                     change.display = ICO_SYC_APC_REGULATION_NOCHANGE;
472                 if (control[idx].sound != wkcontrol[idx].sound)
473                     change.sound = wkcontrol[idx].sound;
474                 else
475                     change.sound = ICO_SYC_APC_REGULATION_NOCHANGE;
476                 if (control[idx].input != wkcontrol[idx].input)
477                     change.input = wkcontrol[idx].input;
478                 else
479                     change.input = ICO_SYC_APC_REGULATION_NOCHANGE;
480
481                 (*regulation_cb)(idx, change, regulation_cb_user_data);
482             }
483             control[idx].display = wkcontrol[idx].display;
484             control[idx].sound = wkcontrol[idx].sound;
485             control[idx].input = wkcontrol[idx].input;
486         }
487     }
488     /* send request to AMB                  */
489     request_vehicle_info();
490
491     return ECORE_CALLBACK_RENEW;
492 }
493
494 /*--------------------------------------------------------------------------*/
495 /**
496  * @brief   ico_syc_apc_regulation_init: initialize regulation control
497  *
498  * @param       none
499  * @return      result
500  * @retval      ICO_SYC_EOK     success
501  * @retval      ICO_SYC_EIO     error(D-Bus initialize error)
502  */
503 /*--------------------------------------------------------------------------*/
504 int
505 ico_syc_apc_regulation_init(void)
506 {
507     int     i;
508     DBusError dbus_error;
509
510     apfw_trace("ico_syc_apc_regulation_init: Enter");
511
512     /* get configurations                           */
513     confsys = (Ico_Uxf_Sys_Config *)ico_uxf_getSysConfig();
514
515     if (! confsys) {
516         apfw_trace("ico_syc_apc_regulation_init: Leave(can not read configuration)");
517         return ICO_SYC_EIO;
518     }
519     ncategory = confsys->categoryNum;
520     category = confsys->category;
521
522     memset(vehicle_data, 0, sizeof(vehicle_data));
523     memset(control, 0, sizeof(control));
524     for (i = 0; i <ncategory; i++)  {
525         control[i].display = ICO_SYC_APC_REGULATION_NOREGULATION;
526         control[i].sound = ICO_SYC_APC_REGULATION_NOREGULATION;
527         control[i].input = ICO_SYC_APC_REGULATION_NOREGULATION;
528     }
529
530     /* Reset D-Bus error        */
531     dbus_error_init(&dbus_error);
532
533     /* Get D-Bus connection     */
534     dbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error);
535     if (! dbus_connection){
536         apfw_warn("ico_syc_apc_regulation_init: Leave(ERROR dbus_bus_get)" );
537         return ICO_SYC_EIO;
538     }
539
540     /* send request to AMB                  */
541     request_vehicle_info();
542
543     vehicle_timer = ecore_timer_add(0.1, rule_engine_wake, NULL);
544     if (! vehicle_timer)    {
545         apfw_error("ico_syc_apc_regulation_init: Leave(Can not create Ecore timer)");
546     }
547
548     apfw_trace("ico_syc_apc_regulation_init: Leave(EOK)");
549
550     return ICO_SYC_EOK;
551 }
552
553 /*--------------------------------------------------------------------------*/
554 /**
555  * @brief   ico_syc_apc_regulation_term: terminate regulation control
556  *
557  * @param       none
558  * @return      always ICO_SYC_EOK(success)
559  */
560 /*--------------------------------------------------------------------------*/
561 int
562 ico_syc_apc_regulation_term(void)
563 {
564     apfw_trace("ico_syc_apc_regulation_term: Enter");
565
566     if (! confsys) {
567         apfw_trace("ico_syc_apc_regulation_term: Leave(not initialized)");
568         return ICO_SYC_EOK;
569     }
570     ecore_timer_del(vehicle_timer);
571
572     confsys = NULL;
573
574     apfw_trace("ico_syc_apc_regulation_term: Leave(EOK)");
575     return ICO_SYC_EOK;
576 }
577
578 /*--------------------------------------------------------------------------*/
579 /**
580  * @brief   ico_syc_apc_regulation_listener: set regulation control listener
581  *
582  * @param[in]   func            listener function
583  * @param[in]   user_data       user data
584  * @return      none
585  */
586 /*--------------------------------------------------------------------------*/
587 void
588 ico_syc_apc_regulation_listener(ico_apc_regulation_cb_t func, void *user_data)
589 {
590     int     idx;
591
592     regulation_cb = func;
593     regulation_cb_user_data = user_data;
594
595     if (regulation_cb)  {
596         for (idx = 0; idx < ncategory; idx++) {
597             (*regulation_cb)(idx, control[idx], regulation_cb_user_data);
598         }
599     }
600 }
601
602 /*--------------------------------------------------------------------------*/
603 /**
604  * @brief   ico_syc_apc_regulation_app_visible: get display regulation status
605  *
606  * @param[in]   category    category Id
607  * @return      result
608  * @retval      TRUE        The application of this category can use the display
609  * @retval      FALSE       The application of this category can not use the display
610  */
611 /*--------------------------------------------------------------------------*/
612 int
613 ico_syc_apc_regulation_app_visible(const int category)
614 {
615     if ((category < 0) || (category >= ICO_UXF_CATEGORY_MAX))    {
616         apfw_warn("ico_syc_apc_regulation_app_visible: Illegal category(%d)", category);
617         return TRUE;
618     }
619     if (control[category].display == ICO_SYC_APC_REGULATION_NOREGULATION)   {
620         return TRUE;
621     }
622     return FALSE;
623 }
624
625 /*--------------------------------------------------------------------------*/
626 /**
627  * @brief   ico_syc_apc_regulation_app_sound: get sound reguration status
628  *
629  * @param[in]   category    category Id
630  * @return      result
631  * @retval      TRUE        The application of this category can use the sound output
632  * @retval      FALSE       The application of this category can not use the sound output
633  */
634 /*--------------------------------------------------------------------------*/
635 int
636 ico_syc_apc_regulation_app_sound(const int category)
637 {
638     if ((category < 0) || (category >= ICO_UXF_CATEGORY_MAX))    {
639         apfw_warn("ico_syc_apc_regulation_app_sound: Illegal category(%d)", category);
640         return TRUE;
641     }
642     if (control[category].sound == ICO_SYC_APC_REGULATION_NOREGULATION) {
643         return TRUE;
644     }
645     return FALSE;
646 }
647
648 /*--------------------------------------------------------------------------*/
649 /**
650  * @brief   ico_syc_apc_regulation_app_input: get input switch reguration status
651  *
652  * @param[in]   category    category Id
653  * @return      result
654  * @retval      TRUE        The application of this category is available with an input
655  * @retval      FALSE       The application of this category is not available with an input
656  */
657 /*--------------------------------------------------------------------------*/
658 int
659 ico_syc_apc_regulation_app_input(const int category)
660 {
661     if ((category < 0) || (category >= ICO_UXF_CATEGORY_MAX))    {
662         apfw_warn("ico_syc_apc_regulation_app_input: Illegal category(%d)", category);
663         return TRUE;
664     }
665     if (control[category].input == ICO_SYC_APC_REGULATION_NOREGULATION) {
666         return TRUE;
667     }
668     return FALSE;
669 }
670