4 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 //#include <Ecore_X.h>
25 #include <utils_i18n.h>
26 #include <system_settings.h>
29 #include "indicator.h"
31 #include "indicator_gui.h"
38 #define SYSTEM_RESUME "system_wakeup"
40 #define TIME_FONT_SIZE_24 ELM_SCALE_SIZE(30)
41 #define TIME_FONT_SIZE_12 ELM_SCALE_SIZE(30)
42 #define AMPM_FONT_SIZE ELM_SCALE_SIZE(29)
44 #define TIME_FONT_COLOR 200, 200, 200, 255
45 #define AMPM_FONT_COLOR 200, 200, 200, 255
46 #define LABEL_STRING "<font_size=%d>%s" \
48 #define LABEL_STRING_FONT "%s</font>"
50 #define BATTERY_TIMER_INTERVAL 3
51 #define BATTERY_TIMER_INTERVAL_CHARGING 30
53 #define CLOCK_STR_LEN 128
56 INDICATOR_CLOCK_MODE_12H = 0,
57 INDICATOR_CLOCK_MODE_24H,
58 INDICATOR_CLOCK_MODE_MAX
61 int clock_mode = INDICATOR_CLOCK_MODE_12H;
63 static const char *colon = ":";
64 static const char *ratio = "∶";
66 static int apm_length = 0;
67 static int apm_position = 0;
68 extern Ecore_Timer *clock_timer;
70 static i18n_udatepg_h _last_generator;
71 static char *_last_locale = NULL;
72 static int battery_charging = 0;
74 static int register_clock_module(void *data);
75 static int unregister_clock_module(void);
76 static int language_changed_cb(void *data);
77 static int region_changed_cb(void *data);
78 static int wake_up_cb(void *data);
79 #ifdef _SUPPORT_SCREEN_READER
80 static int register_clock_tts(void *data,int win_type);
83 #define ICON_PRIORITY INDICATOR_PRIORITY_FIXED8
84 #define MODULE_NAME "clock"
86 static void indicator_get_apm_by_region(char* output, void* data);
87 static void indicator_get_time_by_region(char* output, void* data);
89 static void ICU_set_timezone(const char *timezone);
92 .type = INDICATOR_TXT_ICON,
94 .priority = ICON_PRIORITY,
95 .always_top = EINA_FALSE,
97 .obj_exist = EINA_FALSE,
98 .exist_in_view = EINA_FALSE,
99 .init = register_clock_module,
100 .fini = unregister_clock_module,
101 .lang_changed = NULL,
102 .region_changed = region_changed_cb,
103 .lang_changed = language_changed_cb,
104 .wake_up = wake_up_cb,
109 void cal_delete_last_generator(void)
115 if (_last_generator) {
116 i18n_udatepg_destroy(_last_generator);
117 _last_generator = NULL;
123 static i18n_udatepg_h __cal_get_pattern_generator(const char *locale, int *status)
125 if (!_last_generator || !_last_locale || strcmp(locale, _last_locale)) {
127 cal_delete_last_generator();
129 _last_locale = strdup(locale);
131 int ret = i18n_udatepg_create(locale, &_last_generator);
132 if (ret != I18N_ERROR_NONE) {
133 _E("i18n_udatepg_create failed %d", ret);
134 _last_generator = NULL;
137 return _last_generator;
142 static void set_app_state(void* data)
149 static void indicator_clock_changed_cb(void *data)
151 char time_str[CLOCK_STR_LEN] = {0,};
152 char time_buf[CLOCK_STR_LEN] = {0,};
153 char ampm_buf[CLOCK_STR_LEN] = {0,};
154 char ampm_str[CLOCK_STR_LEN] = {0,};
155 char buf[CLOCK_STR_LEN] = {0,};
156 char result[CLOCK_STR_LEN] = {0,};
157 char icu_apm[CLOCK_STR_LEN] = {0,};
159 struct tm *ts = NULL;
161 struct appdata *ad = NULL;
164 int ampm_size = AMPM_FONT_SIZE;
168 ad = (struct appdata *)data;
170 if (icon_get_update_flag() == 0) return;
174 ts = localtime(&ctime);
176 _E("Fail to get localtime !");
180 if (clock_timer != NULL) {
181 ecore_timer_del(clock_timer);
185 memset(time_str, 0x00, sizeof(time_str));
186 memset(ampm_str, 0x00, sizeof(ampm_str));
187 memset(time_buf, 0x00, sizeof(time_buf));
188 memset(ampm_buf, 0x00, sizeof(ampm_buf));
189 memset(buf, 0x00, sizeof(buf));
191 clock_timer = ecore_timer_add(60 - ts->tm_sec, (void *)indicator_clock_changed_cb, data);
193 _E("Fail to add timer !");
196 indicator_get_apm_by_region(icu_apm,data);
197 indicator_get_time_by_region(time_buf,data);
200 if (clock_mode == INDICATOR_CLOCK_MODE_12H) {
201 char bf1[32] = { 0, };
203 static int pre_hour = 0;
204 const char *region = NULL;
206 int bRegioncheck = 0;
207 char *lang1 = "it_IT";
209 region = vconf_get_str(VCONFKEY_REGIONFORMAT);
212 if (strncmp(region,lang1,strlen(lang1)) == 0) bRegioncheck = 1;
214 if (apm_length>=4 || bRegioncheck==1) {
215 if (ts->tm_hour >= 0 && ts->tm_hour < 12) {
216 snprintf(ampm_buf, sizeof(ampm_buf),"%s","AM");
218 snprintf(ampm_buf, sizeof(ampm_buf),"%s","PM");
221 snprintf(ampm_buf, sizeof(ampm_buf),"%s",icu_apm);
224 strftime(bf1, sizeof(bf1), "%l", ts);
226 strftime(bf1, sizeof(bf1), ":%M", ts);
228 font_size = TIME_FONT_SIZE_12;
231 if ((pre_hour<10 && hour>=10)||(pre_hour>=10 && hour<10)) {
232 box_update_display(&(ad->win));
237 font_size = TIME_FONT_SIZE_24;
240 snprintf(time_str, sizeof(time_str), LABEL_STRING, font_size, time_buf);
241 snprintf(ampm_str, sizeof(ampm_str), LABEL_STRING, ampm_size, ampm_buf);
243 if (clock_mode == INDICATOR_CLOCK_MODE_12H) {
244 if (apm_position == 0) {
245 len = snprintf(buf, sizeof(buf), "%s %s", ampm_str, time_str);
247 len = snprintf(buf, sizeof(buf), "%s %s", time_str, ampm_str);
250 len = snprintf(buf, sizeof(buf), "%s", time_str);
253 snprintf(result, sizeof(result), LABEL_STRING_FONT, buf);
255 _E("Unexpected ERROR!");
259 _D("[CLOCK MODULE] Timer Status : %d Time: %s", clock_timer, result);
260 util_part_text_emit(data, "elm.text.clock", result);
267 static void _clock_format_changed_cb(keynode_t *node, void *data)
269 struct appdata *ad = NULL;
271 i18n_timezone_h timezone;
275 ad = (struct appdata *)data;
277 if (vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224,&mode_24) < 0)
279 ERR("Error getting VCONFKEY_REGIONFORMAT_TIME1224 value");
283 /* Check Time format. If timeformat have invalid value, Set to 12H */
284 if( mode_24==VCONFKEY_TIME_FORMAT_24)
286 if(clock_mode == INDICATOR_CLOCK_MODE_12H)
288 clock_mode = INDICATOR_CLOCK_MODE_24H;
289 box_update_display(&(ad->win));
294 if(clock_mode==INDICATOR_CLOCK_MODE_24H)
296 clock_mode = INDICATOR_CLOCK_MODE_12H;
297 box_update_display(&(ad->win));
301 char *timezone_str = util_get_timezone_str();
303 int ret = i18n_timezone_create(&timezone, timezone_str);
304 if (ret != I18N_ERROR_NONE) {
305 _E("Unable to create timzone handle for %s: %d", timezone_str, ret);
310 ret = i18n_timezone_set_default(timezone);
311 if (ret != I18N_ERROR_NONE) {
312 _E("Unable to set default timzone: %d", ret);
313 i18n_timezone_destroy(timezone);
318 indicator_clock_changed_cb(data);
319 i18n_timezone_destroy(timezone);
325 static void indicator_clock_charging_now_cb(keynode_t *node, void *data)
329 retif(data == NULL, , "Invalid parameter!");
332 vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &status);
334 battery_charging = status;
339 static int language_changed_cb(void *data)
341 const char *pa_lang = vconf_get_str(VCONFKEY_LANGSET);
342 DBG("language_changed_cb %s",pa_lang);
343 indicator_clock_changed_cb(data);
349 static int region_changed_cb(void *data)
351 _clock_format_changed_cb(NULL, data);
357 static int wake_up_cb(void *data)
359 indicator_clock_changed_cb(data);
366 /*static void _time_changed(system_settings_key_e key, void *data)
368 DBG("_time_changed");
369 _clock_format_changed_cb(NULL,data);
374 static void regionformat_changed(keynode_t *node, void *data)
376 DBG("regionformat_changed");
377 _clock_format_changed_cb(NULL,data);
382 static void timezone_int_changed(keynode_t *node, void *data)
384 DBG("timezone_int_changed");
385 _clock_format_changed_cb(NULL,data);
390 static void timezone_id_changed(keynode_t *node, void *data)
392 char *szTimezone = NULL;
393 szTimezone = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
395 DBG("timezone_id_changed %s",szTimezone);
396 _clock_format_changed_cb(NULL,data);
401 static int register_clock_module(void *data)
405 retif(data == NULL, FAIL, "Invalid parameter!");
409 /*ret = system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_TIME_CHANGED, _time_changed, data);
414 ret = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, regionformat_changed, data);
419 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_TIMEZONE_INT, timezone_int_changed, data);
424 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_TIMEZONE_ID, timezone_id_changed, data);
429 ret = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, regionformat_changed, data);
433 _clock_format_changed_cb(NULL, data);
434 indicator_clock_charging_now_cb(NULL,data);
441 static int unregister_clock_module(void)
445 //ret = system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_TIME_CHANGED);
446 ret = ret | vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, regionformat_changed);
447 ret = ret | vconf_ignore_key_changed(VCONFKEY_SETAPPL_TIMEZONE_INT, timezone_int_changed);
448 ret = ret | vconf_ignore_key_changed(VCONFKEY_SETAPPL_TIMEZONE_ID, timezone_id_changed);
449 ret = ret | vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, regionformat_changed);
451 if (clock_timer != NULL) {
452 ecore_timer_del(clock_timer);
456 cal_delete_last_generator();
463 static inline char *_extend_heap(char *buffer, int *sz, int incsz)
468 tmp = realloc(buffer, *sz);
479 static char *_string_replacer(const char *src, const char *pattern, const char *replace)
494 if (!src || !pattern)
497 out_sz = strlen(src);
505 for (state = STATE_START, ptr = src; state != STATE_END; ptr++) {
510 } else if (!isblank(*ptr)) {
518 } else if (*ptr == *pattern) {
525 if (out_idx == out_sz) {
526 tmp = _extend_heap(ret, &out_sz, strlen(replace) + 1);
538 * If there is no space for copying the replacement,
539 * Extend size of the return buffer.
541 if (out_sz - out_idx < strlen(replace) + 1) {
542 tmp = _extend_heap(ret, &out_sz, strlen(replace) + 1);
550 strcpy(ret + out_idx, replace);
551 out_idx += strlen(replace);
555 } else if (*ptr != pattern[idx]) {
558 /* Copy the first matched character */
561 if (out_idx == out_sz) {
562 tmp = _extend_heap(ret, &out_sz, strlen(replace) + 1);
587 void indicator_get_apm_by_region(char* output,void *data)
589 retif(data == NULL, , "Data parameter is NULL");
590 retif(output == NULL, , "output parameter is NULL");
592 i18n_uchar u_custom_skeleton[CLOCK_STR_LEN] = { 0, };
593 i18n_uchar u_timezone[64] = {0,};
594 i18n_uchar u_best_pattern[CLOCK_STR_LEN] = { 0, };
595 i18n_uchar u_formatted[CLOCK_STR_LEN] = { 0, };
597 i18n_udate_format_h formatter;
598 int32_t best_pattern_len, formatted_len;
600 char s_best_pattern[CLOCK_STR_LEN] = { 0, };
601 char s_formatted[CLOCK_STR_LEN] = { 0, };
605 i18n_udatepg_h pattern_generator = NULL;
607 char *locale = vconf_get_str(VCONFKEY_REGIONFORMAT);
610 ERR("[Error] get value of fail.");
614 /* Remove ".UTF-8" in locale */
615 char locale_tmp[32] = {0,};
616 strncpy(locale_tmp, locale, sizeof(locale_tmp)-1);
617 char *p = util_safe_str(locale_tmp, ".UTF-8");
623 i18n_ustring_copy_ua_n(u_custom_skeleton, "hhmm", ARRAY_SIZE(u_custom_skeleton));
625 pattern_generator = __cal_get_pattern_generator (locale_tmp, &status);
626 if (pattern_generator == NULL) {
630 int ret = i18n_udatepg_get_best_pattern(pattern_generator, u_custom_skeleton, i18n_ustring_get_length(u_custom_skeleton),
631 u_best_pattern, (int32_t)ARRAY_SIZE(u_best_pattern), &best_pattern_len);
632 if (ret != I18N_ERROR_NONE) {
633 _E("i18n_udatepg_get_best_pattern failed: %d", ret);
634 i18n_udatepg_destroy(pattern_generator);
637 i18n_udatepg_destroy(pattern_generator);
639 i18n_ustring_copy_au(s_best_pattern, u_best_pattern);
640 i18n_ustring_copy_ua(u_best_pattern, "a");
642 char *timezone_id = util_get_timezone_str();
643 DBG("TimeZone is %s", timezone_id);
645 if (s_best_pattern[0] == 'a') {
653 ret = i18n_ucalendar_get_now(&date);
654 if (ret != I18N_ERROR_NONE) {
655 ERR("i18n_ucalendar_get_now failed: %d", ret);
660 i18n_ustring_copy_ua_n(u_timezone, timezone_id, ARRAY_SIZE(u_timezone));
663 ret = i18n_udate_create(I18N_UDATE_PATTERN, I18N_UDATE_PATTERN, locale_tmp, timezone_id ? u_timezone : NULL, -1,
664 u_best_pattern, -1, &formatter);
665 if (ret != I18N_ERROR_NONE) {
672 ret = i18n_udate_format_date(formatter, date, u_formatted, ARRAY_SIZE(s_formatted), NULL, &formatted_len);
673 if (ret != I18N_ERROR_NONE) {
674 i18n_udate_destroy(formatter);
678 i18n_udate_destroy(formatter);
680 i18n_ustring_copy_au(s_formatted, u_formatted);
681 apm_length = i18n_ustring_get_length(u_formatted);
683 if (strlen(s_formatted) < CLOCK_STR_LEN) {
684 strncpy(output, s_formatted, strlen(s_formatted));
687 strncpy(output, s_formatted, CLOCK_STR_LEN - 1);
695 void indicator_get_time_by_region(char* output,void *data)
697 retif(data == NULL, , "Data parameter is NULL");
698 retif(output == NULL, , "output parameter is NULL");
700 i18n_uchar u_custom_skeleton[CLOCK_STR_LEN] = { 0, };
701 i18n_uchar u_timezone[64] = {0,};
702 i18n_uchar u_best_pattern[CLOCK_STR_LEN] = { 0, };
703 i18n_uchar u_formatted[CLOCK_STR_LEN] = { 0, };
706 i18n_udate_format_h formatter = NULL;
708 char s_best_pattern[CLOCK_STR_LEN] = { 0, };
709 char s_formatted[CLOCK_STR_LEN] = { 0, };
710 char *s_convert_formatted = NULL;
712 char s_time_skeleton[20] = {0,};
713 i18n_udatepg_h pattern_generator = NULL;
715 int32_t best_pattern_len, formatted_len;
717 if (clock_mode == INDICATOR_CLOCK_MODE_12H) {
718 strcpy(s_time_skeleton, "hm");
721 strcpy(s_time_skeleton, "Hm");
723 char *locale = vconf_get_str(VCONFKEY_REGIONFORMAT);
724 if (locale == NULL) {
725 ERR("[Error] get value of fail.");
729 /* Remove ".UTF-8" in locale */
730 char locale_tmp[32] = {0,};
731 strncpy(locale_tmp, locale, sizeof(locale_tmp)-1);
732 char *p = util_safe_str(locale_tmp, ".UTF-8");
738 i18n_ustring_copy_ua_n(u_custom_skeleton, s_time_skeleton, ARRAY_SIZE(u_custom_skeleton));
740 pattern_generator = __cal_get_pattern_generator (locale_tmp, &status);
741 if (pattern_generator == NULL) {
745 int ret = i18n_udatepg_get_best_pattern(pattern_generator, u_custom_skeleton, i18n_ustring_get_length(u_custom_skeleton),
746 u_best_pattern, ARRAY_SIZE(u_best_pattern), &best_pattern_len);
747 if (ret != I18N_ERROR_NONE) {
748 _E("i18n_udatepg_get_best_pattern failed: %d", ret);
749 i18n_udatepg_destroy(pattern_generator);
753 i18n_udatepg_destroy(pattern_generator);
755 char a_best_pattern[64] = {0,};
756 i18n_ustring_copy_au(a_best_pattern, u_best_pattern);
758 char *a_best_pattern_fixed = strtok(a_best_pattern, "a");
759 a_best_pattern_fixed = strtok(a_best_pattern_fixed, " ");
760 if (a_best_pattern_fixed) {
761 i18n_ustring_copy_ua(u_best_pattern, a_best_pattern_fixed);
764 i18n_ustring_copy_au(s_best_pattern, u_best_pattern);
766 DBG("BestPattern is %s", s_best_pattern);
769 ret = i18n_ucalendar_get_now(&date);
770 if (ret != I18N_ERROR_NONE) {
771 ERR("i18n_ucalendar_get_now failed: %d", ret);
775 char* timezone_id = util_get_timezone_str();
776 DBG("TimeZone is %s", timezone_id);
779 i18n_ustring_copy_ua_n(u_timezone, timezone_id, ARRAY_SIZE(u_timezone));
782 ret = i18n_udate_create(I18N_UDATE_PATTERN, I18N_UDATE_PATTERN, locale_tmp, timezone_id ? u_timezone : NULL, -1,
783 u_best_pattern, -1, &formatter);
784 if (ret != I18N_ERROR_NONE) {
791 ret = i18n_udate_format_date(formatter, date, u_formatted, ARRAY_SIZE(s_formatted), NULL, &formatted_len);
792 if (ret != I18N_ERROR_NONE) {
793 i18n_udate_destroy(formatter);
797 i18n_udate_destroy(formatter);
799 i18n_ustring_copy_au(s_formatted, u_formatted);
800 DBG("DATE & TIME is %s %s %d %s", locale_tmp, s_formatted, i18n_ustring_get_length(u_formatted), s_best_pattern);
802 DBG("24H :: Before change %s", s_formatted);
803 s_convert_formatted = _string_replacer(s_formatted, colon, ratio);
804 DBG("24H :: After change %s", s_convert_formatted);
806 if (!s_convert_formatted) {
807 DBG("_string_replacer return NULL");
811 if (strlen(s_convert_formatted) < CLOCK_STR_LEN) {
812 strncpy(output, s_convert_formatted, strlen(s_convert_formatted));
815 strncpy(output, s_convert_formatted, CLOCK_STR_LEN - 1);
818 free(s_convert_formatted);
825 static void ICU_set_timezone(const char *timezone)
829 if (timezone == NULL) {
830 ERR("TIMEZONE is NULL");
834 int ret = i18n_timezone_create(&tmz, timezone);
835 if (ret != I18N_ERROR_NONE) {
836 ERR("Unable to create timezone handle from %s: %d", timezone, ret);
840 ret = i18n_timezone_set_default(tmz);
841 if (ret != I18N_ERROR_NONE) {
842 ERR("Unable to set default timezone to %s: %d", timezone, ret);
845 i18n_timezone_destroy(tmz);
850 #ifdef _SUPPORT_SCREEN_READER
851 static char *_access_info_cb(void *data, Evas_Object *obj)
853 Evas_Object *item = data;
856 char time_buf[128], ampm_buf[128];
857 char buf[CLOCK_STR_LEN];
858 char buf1[CLOCK_STR_LEN];
860 int battery_capa = 0;
863 char strHour[128] = { 0, };
864 char strMin[128] = { 0, };
867 struct tm *ts = NULL;
871 retif(data == NULL,NULL, "Invalid parameter!");
872 char *timezone = util_get_timezone_str();
873 ICU_set_timezone(timezone);
879 ts = localtime(&ctime);
883 memset(time_str, 0x00, sizeof(time_str));
884 memset(time_buf, 0x00, sizeof(time_buf));
885 memset(ampm_buf, 0x00, sizeof(ampm_buf));
886 memset(buf, 0x00, sizeof(buf));
887 memset(buf1, 0x00, sizeof(buf1));
889 if (clock_mode == INDICATOR_CLOCK_MODE_12H) {
890 char bf1[32] = { 0, };
892 if (ts->tm_hour >= 0 && ts->tm_hour < 12)
893 strncpy(ampm_buf, _("IDS_IDLE_OPT_AM_ABB"),sizeof(ampm_buf)-1);
895 strncpy(ampm_buf, _("IDS_IDLE_OPT_PM_ABB"),sizeof(ampm_buf)-1);
897 strftime(bf1, sizeof(bf1), "%l", ts);
899 strftime(bf1, sizeof(bf1), "%M", ts);
903 char bf1[32] = { 0, };
905 strftime(bf1, sizeof(bf1), "%H", ts);
907 strftime(bf1, sizeof(bf1), "%M", ts);
913 strncpy(strHour, _("IDS_COM_BODY_1_HOUR"),sizeof(strHour));
917 snprintf(strHour, sizeof(strHour), _("IDS_COM_POP_PD_HOURS"),hour);
922 strncpy(strMin, _("IDS_COM_BODY_1_MINUTE"),sizeof(strMin));
926 snprintf(strMin, sizeof(strMin), _("IDS_COM_BODY_PD_MINUTES"),minute);
929 if(clock_mode == INDICATOR_CLOCK_MODE_12H)
930 snprintf(time_str, sizeof(time_str), "%s, %s, %s", strHour, strMin,ampm_buf);
932 snprintf(time_str, sizeof(time_str), "%s, %s", strHour, strMin);
935 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, &battery_capa);
940 if (battery_capa < 0)
945 if (battery_capa > 100)
947 snprintf(buf1, sizeof(buf1), _("IDS_IDLE_BODY_PD_PERCENT_OF_BATTERY_POWER_REMAINING"), battery_capa);
949 snprintf(buf, sizeof(buf), "%s, %s, %s", time_str, buf1, _("IDS_IDLE_BODY_STATUS_BAR_ITEM"));
953 if (!tmp) return NULL;
959 static int register_clock_tts(void *data,int win_type)
963 retif(data == NULL, FAIL, "Invalid parameter!");
965 Evas_Object *to = NULL;
966 Evas_Object *ao = NULL;
967 struct appdata *ad = data;
969 to = (Evas_Object *) edje_object_part_object_get(elm_layout_edje_get(ad->win[win_type].layout), "elm.rect.clock.access");
970 ao = util_access_object_register(to, ad->win[win_type].layout);
971 util_access_object_info_cb_set(ao,ELM_ACCESS_INFO,_access_info_cb,data);