/* * cleopatre/application/p1905_managerd/src/p1905_push_button.c * * (C) Copyright 2013 MSsar Semiconductor, Inc. */ #include #include #include #include #include #include #include #include "p1905_managerd.h" #include "libspid.h" #include "label.h" #include "defs.h" #include "path.h" #include "cmdu.h" #define GPIO_DEVICE "/dev/gpio" #define SC_BUT_GPIO_NUM 1 //#define P1905_PUSH_BUTTON_DEBUG #ifdef P1905_PUSH_BUTTON_DEBUG #define debug(...) printf(__VA_ARGS__) #define debug_syslog(...) printf(__VA_ARGS__) #else #define debug(...) #define debug_syslog(format, ...) syslog(LOG_WARNING, format, ##__VA_ARGS__) #endif extern unsigned char p1905_multicast_address[6]; int p1905_push_button_init(struct p1905_managerd_ctx *ctx) { /* Set GPIO info for SC button interruption */ ctx->sc_it.gpioit.enable = 1; ctx->sc_it.gpioit.mask = (1 << SC_BUT_GPIO_NUM); /* Open GPIO device */ if (0 > (ctx->gpio_fd = open (GPIO_DEVICE, O_RDWR))) { syslog (LOG_WARNING, "cannot open gpio device (%s)", strerror (errno)); return -1; } /*register listener for gpio interrupt*/ /* Set GPIO interrupt for SC button */ if (0 > ioctl (ctx->gpio_fd, GPIOIOC_SETIT, (unsigned long *) &ctx->sc_it)) { syslog (LOG_WARNING, "cannot call ioctl for SC interruption (%s)", strerror (errno)); } ctx->pbc_param.is_sc = 0; #ifdef SUPPORT_AP_REGISTRAR ctx->pbc_param.wifi_info.no_need_start_pbc = 0; #endif return 0; } int p1905_push_button_uninit(struct p1905_managerd_ctx *ctx) { ctx->sc_it.gpioit.enable = 0; ctx->sc_it.gpioit.mask = 0; /* Reset GPIO interrupt for SC button */ if (0 > ioctl (ctx->gpio_fd, GPIOIOC_SETIT, (unsigned long *) &ctx->sc_it)) { syslog (LOG_WARNING, "cannot call ioctl for SC interruption (%s)", strerror (errno)); } /* Close GPIO device */ close (ctx->gpio_fd); } int p1905_push_button_process(struct p1905_managerd_ctx *ctx) { unsigned char status[LIBSPID_HPAV_INFO_STATUS_MAX_LEN] = {0}; #ifdef SUPPORT_WIFI unsigned char station_mac_list[WIFI_MAX_STATION_NUM][ETH_ALEN]; unsigned char sta_num = 0; #endif /*send 1905.1 push button event notification to eth port*/ ctx->mid ++; insert_cmdu_txq(p1905_multicast_address, ctx->eth0_mac_addr,\ e_push_button_event_notification, ctx->mid); /* detect connection status. if authenticated, need to send * 1905.1 push button event notification message. Otherwise, it just start * the simple connection process. */ if(LIBSPID_SUCCESS != libspid_config_read_item(LIBSPID_HPAV_INFO_PATH, LIBSPID_HPAV_INFO_LABEL_STATUS, status, LIBSPID_HPAV_INFO_STATUS_MAX_LEN)) { syslog (LOG_WARNING, "libspid config read item failed in p1905.1"); return -1; } if(!strcmp(status, LIBSPID_HPAV_INFO_VALUE_STATUS_AUTHENTICATED)) { /*status is authenticated, need to send push button event notification*/ insert_cmdu_txq(p1905_multicast_address, ctx->plc0_mac_addr, e_push_button_event_notification, ctx->mid); } #ifdef SUPPORT_WIFI if(wifi_utils_success == get_station_mac(station_mac_list, &sta_num)) { if(sta_num > 0) { /* has one or more stations, so need to send PB event notification * in wifi interface */ insert_cmdu_txq(p1905_multicast_address, ctx->wifi0_mac_addr, e_push_button_event_notification, ctx->mid); } } /*trigger WIFI AP push button configuration*/ trigger_wifi_PBC_config(); #endif return 0; } int is_connection_status_authenticated(void) { unsigned char status[LIBSPID_HPAV_INFO_STATUS_MAX_LEN] = {0}; if(LIBSPID_SUCCESS != libspid_config_read_item(LIBSPID_HPAV_INFO_PATH, LIBSPID_HPAV_INFO_LABEL_STATUS, status, LIBSPID_HPAV_INFO_STATUS_MAX_LEN)) { syslog (LOG_WARNING, "libspid config read item failed in p1905.1"); return -1; } if(!strcmp(status, LIBSPID_HPAV_INFO_VALUE_STATUS_AUTHENTICATED)) return 1; else return 0; } int trigger_push_button_config_start(struct p1905_managerd_ctx *ctx) { /* Write SC button GPIO status */ libspid_config_write_item (LIBSPID_HPAV_INFO_PATH, LIBSPID_HPAV_INFO_LABEL_SC_BUTTON, "yes"); /* plc daemon needs to be informed */ if (LIBSPID_SUCCESS != libspid_system_file_update_warn (getpid(), LIBSPID_HPAV_INFO_PATH)) { syslog (LOG_WARNING, "libspid system file update warn failed"); return -1; } return 0; } int is_doing_sc(void) { unsigned char status[10] = {0}; if(LIBSPID_SUCCESS != libspid_config_read_item(LIBSPID_HPAV_INFO_PATH, LIBSPID_HPAV_INFO_LABEL_SC, status, 10)) { syslog (LOG_WARNING, "libspid config read item failed in p1905.1"); return -1; } if(!strcmp(status, LIBSPID_VALUE_BOOLEAN_TRUE)) return 1; else return 0; } int detect_new_device_join(struct p1905_managerd_ctx *ctx) { unsigned char compare[6] = {0}; #ifdef SUPPORT_AP_REGISTRAR unsigned char station_mac_list[WIFI_MAX_STATION_NUM][ETH_ALEN]; unsigned char sta_num = 0; int i = 0, j = 0; #endif /*need to implement WIFI push button status check*/ if(is_doing_sc()) { debug("in simple connect state\n"); return 0; } if(get_station_info(ctx, 2)) { if(memcmp(ctx->pbc_param.info.new_station, compare, 6)) { /*has a new station joined, so send push button join notification*/ ctx->mid ++; insert_cmdu_txq(p1905_multicast_address, ctx->eth0_mac_addr,\ e_push_button_join_notification, ctx->mid); insert_cmdu_txq(p1905_multicast_address, ctx->plc0_mac_addr,\ e_push_button_join_notification, ctx->mid); #ifdef SUPPORT_WIFI insert_cmdu_txq(p1905_multicast_address, ctx->wifi0_mac_addr,\ e_push_button_join_notification, ctx->mid); #endif } } #ifdef SUPPORT_AP_REGISTRAR if(wifi_utils_success == get_station_mac(station_mac_list, &sta_num)) { if(sta_num > ctx->pbc_param.wifi_info.station_num) { if(ctx->pbc_param.wifi_info.station_num == 0) { memcpy(ctx->pbc_param.wifi_info.new_station, &(station_mac_list[0][0]), ETH_ALEN); } else { for(i=0;ipbc_param.wifi_info.station_num;j++) { if(memcmp(&(station_mac_list[i][0]), &(ctx->pbc_param.wifi_info.station_mac_list[j][0]), 6)) { memcpy(ctx->pbc_param.wifi_info.new_station,\ &(station_mac_list[i][0]), ETH_ALEN); } } } } /*send push button event joined notification CMDU*/ ctx->mid ++; insert_cmdu_txq(p1905_multicast_address, ctx->eth0_mac_addr,\ e_push_button_join_notification_wifi, ctx->mid); insert_cmdu_txq(p1905_multicast_address, ctx->plc0_mac_addr,\ e_push_button_join_notification_wifi, ctx->mid); insert_cmdu_txq(p1905_multicast_address, ctx->wifi0_mac_addr,\ e_push_button_join_notification_wifi, ctx->mid); } else { /*no new wifi station joined, set all 0*/ memset(ctx->pbc_param.wifi_info.new_station, 0, ETH_ALEN); } } else { debug_syslog("get wifi station fail in device joined detection\n"); } #endif ctx->pbc_param.is_sc = 0; return 0; }