From 9ae79830153d8b9c1562c7f32882cfb46429b742 Mon Sep 17 00:00:00 2001 From: lijie02 Date: Wed, 26 Sep 2018 15:28:14 +0800 Subject: [PATCH] update wifimanager and firmware to newest version(PV1 commit 2e423e6f) --- package/allwinner/wifimanager/demo/Makefile | 3 +- .../wifimanager/demo/wifi_get_netid.c | 2 +- .../demo/wifi_stop_restart_scan_test.c | 4 +- .../allwinner/wifimanager/smartaudio/Makefile | 2 +- .../smartaudio/app_wifi_manager.cpp | 268 +++- package/allwinner/wifimanager/src/Makefile | 8 +- package/allwinner/wifimanager/src/broadlink.c | 890 +++++++++++++ .../wifimanager/src/include/broadlink.h | 43 + .../wifimanager/src/include/network_manager.h | 38 +- .../allwinner/wifimanager/src/include/sdk.h | 213 +++ .../wifimanager/src/include/sdk_errno.h | 19 + .../wifimanager/src/include/wifi_event.h | 5 +- .../wifimanager/src/include/wifi_intf.h | 11 +- .../allwinner/wifimanager/src/libfastcon.a | Bin 0 -> 24018 bytes .../wifimanager/src/network_manager.c | 547 +++----- .../allwinner/wifimanager/src/udhcpc_thread.c | 10 +- package/allwinner/wifimanager/src/wifi.c | 42 +- .../allwinner/wifimanager/src/wifi_event.c | 117 +- .../allwinner/wifimanager/src/wifimanager.c | 1181 ++++++++++------- .../wifimanager/src/wpa_supplicant_conf.c | 144 +- .../allwinner/wifimanager/udhcpc_wlan0.init | 4 +- package/firmware/ap6236/fw_bcm43436b0.bin | Bin 419579 -> 415851 bytes package/libs/libiconv-full/Makefile | 9 +- 23 files changed, 2518 insertions(+), 1042 deletions(-) create mode 100755 package/allwinner/wifimanager/src/broadlink.c create mode 100755 package/allwinner/wifimanager/src/include/broadlink.h create mode 100755 package/allwinner/wifimanager/src/include/sdk.h create mode 100755 package/allwinner/wifimanager/src/include/sdk_errno.h create mode 100755 package/allwinner/wifimanager/src/libfastcon.a mode change 100644 => 100755 package/libs/libiconv-full/Makefile diff --git a/package/allwinner/wifimanager/demo/Makefile b/package/allwinner/wifimanager/demo/Makefile index e984f97c8..2a616247e 100755 --- a/package/allwinner/wifimanager/demo/Makefile +++ b/package/allwinner/wifimanager/demo/Makefile @@ -3,7 +3,8 @@ include $(TINA_BUILD_TOP)/package/netease/Makefile.common include $(TINA_BUILD_TOP)/build/nls.mk target = wifi_connect_ap_test -INCLUDES += -I$(CONFIG_PREFIX)/usr/include \ +MK_PWD = ./ +INCLUDES += -I$(CONFIG_PREFIX)/usr/include -I$(MK_PWD)/softap \ -I ../src/include CPP_SRCS = wifi_connect_ap.cpp diff --git a/package/allwinner/wifimanager/demo/wifi_get_netid.c b/package/allwinner/wifimanager/demo/wifi_get_netid.c index 22dae705e..a8c4dbb7f 100755 --- a/package/allwinner/wifimanager/demo/wifi_get_netid.c +++ b/package/allwinner/wifimanager/demo/wifi_get_netid.c @@ -245,7 +245,7 @@ int main(int argv, char *argc[]){ } - ret = p_wifi_interface->get_netid(argc[1], key_mgmt, net_id, &id_len); + ret = p_wifi_interface->get_netid(argc[1], key_mgmt, net_id); if(ret == 0){ wmg_printf(MSG_INFO,"The netid of your network is %s\n",net_id); wmg_printf(MSG_INFO,"The lenght of netid is %d\n",id_len); diff --git a/package/allwinner/wifimanager/demo/wifi_stop_restart_scan_test.c b/package/allwinner/wifimanager/demo/wifi_stop_restart_scan_test.c index 1d29abeba..833309b52 100755 --- a/package/allwinner/wifimanager/demo/wifi_stop_restart_scan_test.c +++ b/package/allwinner/wifimanager/demo/wifi_stop_restart_scan_test.c @@ -215,7 +215,7 @@ int main(int argv, char *argc[]){ wmg_printf(MSG_INFO,"********************************************\n"); wmg_printf(MSG_INFO,"==================stop scan================!\n"); wmg_printf(MSG_INFO,"********************************************\n"); - p_wifi_interface->stop_scan(); + //p_wifi_interface->stop_scan(); for(i=0;i<10;i++) { usleep(2000000); @@ -223,7 +223,7 @@ int main(int argv, char *argc[]){ wmg_printf(MSG_INFO,"********************************************\n"); wmg_printf(MSG_INFO,"==================restart scan=============!\n"); wmg_printf(MSG_INFO,"********************************************\n"); - p_wifi_interface->restart_scan(); + //p_wifi_interface->restart_scan(); } return 0; diff --git a/package/allwinner/wifimanager/smartaudio/Makefile b/package/allwinner/wifimanager/smartaudio/Makefile index a795c14ca..eebfe1902 100755 --- a/package/allwinner/wifimanager/smartaudio/Makefile +++ b/package/allwinner/wifimanager/smartaudio/Makefile @@ -4,7 +4,7 @@ include $(TINA_BUILD_TOP)/build/nls.mk target = app_wifi_manager MK_PWD = ./ -INCLUDES += -I$(CONFIG_PREFIX)/usr/include -I$(MK_PWD)/softap +INCLUDES += -I$(CONFIG_PREFIX)/usr/include -I$(MK_PWD)/softap -I$(MK_PWD)/../src/include CPP_SRCS = app_wifi_manager.cpp CPP_OBJS := $(CPP_SRCS:.cpp=.o) diff --git a/package/allwinner/wifimanager/smartaudio/app_wifi_manager.cpp b/package/allwinner/wifimanager/smartaudio/app_wifi_manager.cpp index 99c7fcce3..79df815d2 100755 --- a/package/allwinner/wifimanager/smartaudio/app_wifi_manager.cpp +++ b/package/allwinner/wifimanager/smartaudio/app_wifi_manager.cpp @@ -27,11 +27,12 @@ #include - #define PIPE_RET_SIZE 1024 #define WIFI_STATE_JS_KEY "wifi_state" #define WIFI_STATE_RSSI_JS_KEY "wifi_rssi" +#define WIFI_STATE_SSID_JS_KEY "wifi_ssid" +#define WIFI_STATE_MAC_JS_KEY "wifi_mac" #define WIFI_STATE_EVT_JS_KEY "wifi_evt" @@ -42,6 +43,8 @@ #define WLAN_CONFIG_CMD_STR "iwconfig" #define WLAN_RSSI_STR_RRE "Signal level=" +#define WLAN_BSSID_STR_RRE "Access Point: " +#define WLAN_ESSID_STR_RRE "ESSID:\"" #define WIFI_CONF_EVT_TAG 0xf000 @@ -66,6 +69,8 @@ typedef enum { WIFI_STATE_KEY_STATE =0, WIFI_STATE_KEY_RSSI, + WIFI_STATE_KEY_SSID, + WIFI_STATE_KEY_MAC, WIFI_STATE_KEY_CNT, }sWifiStateKeysEnum; @@ -74,6 +79,8 @@ typedef enum { WIFI_EVT_KEY_EVT =0, WIFI_EVT_KEY_RSSI, + WIFI_EVT_KEY_SSID, + WIFI_EVT_KEY_MAC, WIFI_EVT_KEY_CNT, }sWifiEvtKeysEnum; @@ -117,8 +124,9 @@ typedef enum int api_wifi_state_notify(int state); -static char * wifiStateKeys[WIFI_STATE_KEY_CNT] ={WIFI_STATE_JS_KEY,WIFI_STATE_RSSI_JS_KEY}; -static char * wifiEvtKeys[WIFI_STATE_KEY_CNT] ={WIFI_STATE_EVT_JS_KEY,WIFI_STATE_RSSI_JS_KEY}; + +static char * wifiStateKeys[WIFI_STATE_KEY_CNT] ={WIFI_STATE_JS_KEY,WIFI_STATE_RSSI_JS_KEY,WIFI_STATE_SSID_JS_KEY,WIFI_STATE_MAC_JS_KEY}; +static char * wifiEvtKeys[WIFI_STATE_KEY_CNT] ={WIFI_STATE_EVT_JS_KEY,WIFI_STATE_RSSI_JS_KEY,WIFI_STATE_SSID_JS_KEY,WIFI_STATE_MAC_JS_KEY}; @@ -178,14 +186,16 @@ int pipeExcute(const char * cmd,std::vector & recVec ) return 0; } -int get_connected_ap_rssi() +int get_connected_ap_info(int *rssi, std::string &ssid, std::string &mac) { std::string shellCmd = WLAN_CONFIG_CMD_STR; std::vector vectorRes; int status =0; - int rssi = RSSI_INVALID_NUM; std::string out; + if (rssi == NULL) + return -1; + status =pipeExcute(shellCmd.c_str(),vectorRes); if(0 == status) { @@ -196,24 +206,49 @@ int get_connected_ap_rssi() if(pos == std::string::npos) { - LOG_EX(LOG_Debug, "warm: no rssi\r\n"); - status = -1; + LOG_EX(LOG_Debug, "warn: no rssi\r\n"); + *rssi = RSSI_INVALID_NUM; }else { std::string rssiStr = out.substr(pos+strlen(WLAN_RSSI_STR_RRE),4); - LOG_EX(LOG_Debug, "---info: rssiStr is %s \r\n",rssiStr.c_str()); + LOG_EX(LOG_Debug, "---info: rssiStr is %s\r\n",rssiStr.c_str()); - rssi = std::stoi(rssiStr); + *rssi = std::stoi(rssiStr); + } + + pos = out.find(WLAN_BSSID_STR_RRE); + + if(pos == std::string::npos) + { + LOG_EX(LOG_Debug, "warn: no bssid\r\n"); + mac = ""; + }else + { + mac = out.substr(pos+strlen(WLAN_BSSID_STR_RRE),17); + LOG_EX(LOG_Debug, "---info: macStr is %s\r\n", mac.c_str()); + } + + pos = out.find(WLAN_ESSID_STR_RRE); + + if(pos == std::string::npos) + { + LOG_EX(LOG_Debug, "warn: no essid\r\n"); + ssid = ""; + }else + { + std::string ssidStr = out.substr(pos+strlen(WLAN_ESSID_STR_RRE)); + std::size_t pos_end = ssidStr.find("\n"); + ssid = ssidStr.substr(0,pos_end-3); + LOG_EX(LOG_Debug, "---info: essidStr is %s\r\n", ssid.c_str()); } }else { LOG_EX(LOG_Debug, "error: pipe excute error\r\n"); - status = -1; + return -1; } - - return (0 == status)?rssi:RSSI_INVALID_NUM; + return 0; } @@ -309,20 +344,19 @@ char * api_wifi_state_json_get(char * p_key,int res) return p; } -char * api_wifi_state_json_get(char * p_key[],int res[],int size) +char * api_wifi_state_json_get(int state, int rssi, std::string ssid, std::string mac) { cJSON* pRoot = NULL; - char * p=NULL; + char * p=NULL; pRoot=cJSON_CreateObject(); - if(NULL == pRoot) return NULL; + if(NULL == pRoot) + return NULL; - - - for(int i=0;ipMsg); - if(0 == busy_conf) + if(0 == busy_conf || 1 == wifi_off_mode) { busy_conf =1; status = api_wifi_get_cfg_value(pMsg->pMsg,&p_ssid,&p_passwd); @@ -877,9 +934,8 @@ END_DO: break; case CMD_WIFI_AUTO_CONN: { - LOG_EX(LOG_Debug, "====================Get cmd CMD_WIFI_AUTO_CONN==========================\r\n"); - if(1== busy_conf) + if(1== busy_conf || 1 == wifi_off_mode) { audo_code = APP_WIFI_AUTO_BT_CONF_COLLISION; } @@ -956,7 +1012,9 @@ END_DO: if(WIFIMG_WIFI_CONNECTED !=aw_wifi_get_wifi_state() ) { - if(0 != api_wifi_state_notify(APP_WIFI_EVT_NTF_CONNECTING,RSSI_INVALID_NUM)) + std::string ssid = ""; + std::string mac = ""; + if(0 != api_wifi_state_notify(APP_WIFI_EVT_NTF_CONNECTING, RSSI_INVALID_NUM, ssid, mac)) { LOG_EX(LOG_Debug, "Notify the wifi state error!!\r\n"); } @@ -964,8 +1022,11 @@ END_DO: }else { - int rssi = get_connected_ap_rssi(); - if(0 != api_wifi_state_notify(APP_WIFI_EVT_NTF_CONNECTED,rssi)) + int rssi = 0; + std::string ssid = ""; + std::string mac = ""; + get_connected_ap_info(&rssi, ssid, mac); + if(0 != api_wifi_state_notify(APP_WIFI_EVT_NTF_CONNECTED, rssi, ssid, mac)) { LOG_EX(LOG_Debug, "Notify the wifi state error!!\r\n"); } @@ -990,23 +1051,19 @@ END_DO: } case CMD_WIFI_STATE_REQ: { - int stateVal[WIFI_STATE_KEY_CNT] ={0}; - int rssi =0; + int rssi = 0; + std::string ssid = ""; + std::string mac = ""; LOG_EX(LOG_Debug, "====================Get cmd CMD_WIFI_STATE_REQ==========================\r\n"); wifi_state = aw_wifi_get_wifi_state(); if(WIFIMG_WIFI_CONNECTED == wifi_state) { - rssi = get_connected_ap_rssi(); - LOG_EX(LOG_Debug, "---info: rssi is %d\r\n",rssi); + get_connected_ap_info(&rssi, ssid, mac); } - - - stateVal[WIFI_STATE_KEY_STATE] = wifi_state; - stateVal[WIFI_STATE_KEY_RSSI] = rssi; - pStateJson = (uint8_t *)api_wifi_state_json_get(wifiStateKeys,stateVal,WIFI_STATE_KEY_CNT); + pStateJson = (uint8_t *)api_wifi_state_json_get(wifi_state, rssi, ssid, mac); if(NULL != pStateJson) { status = api_wifi_module_cmd_send((1<disconnect_ap(WIFI_CONF_EVT_TAG); + if(0 != status) + { + LOG_EX(LOG_Error, "ERROR:wifi disconnect event 0x%x\n", event); + status = APP_WIFI_CFG_SYS_ERR; + }else + { + LOG_EX(LOG_Debug, "Disconnect the wifi connected ap\r\n"); + status = APP_WIFI_CFG_SUCCESS; + } + } + /* turn off wifi */ + status = aw_wifi_off(p_wifi_interface); + if(status < 0) + { + LOG_EX(LOG_Error, "Turn off wifi failed!\n"); + status = APP_WIFI_CFG_SYS_ERR; + } + else + { + LOG_EX(LOG_Error, "Turn off wifi succeed!\n"); + wifi_off_mode = 1; + p_wifi_interface = NULL; + status = APP_WIFI_CFG_SUCCESS; + } + } + + pResJson = (uint8_t *)api_wifi_res_json_get(status); + if(NULL != pResJson) + { + status = api_wifi_module_cmd_send((1<busCmd, pMsg->pMsg); + break; default: break; } @@ -1141,8 +1308,6 @@ int main(int argv, char *argc[]){ g_pDBusInterfaceName = g_pModInfoTable[MODULE_WIFI].modAliase; - LOG_EX(LOG_Debug, "Start the wifi communication\n"); - //pBus = DBusWithLibuvInit(pLoop, g_pDBusInterfaceName, DBusOnMessage, NULL, NULL, &ret); pBus = DBusWithLibuvInit(pLoop, g_pDBusInterfaceName, NULL, NULL, NULL, &ret); @@ -1152,12 +1317,13 @@ int main(int argv, char *argc[]){ fprintf(stderr, "%s(%d): DBusWithLibuvInit Error: %d\n", g_pDBusInterfaceName, MODULE_PLAYER, ret); return 0; } - + /* init a uv timer to report cur position */ uv_timer_init(pLoop, &timerCurPosMsg); pthread_mutex_init(&ctrl_mutex, NULL); + LOG_EX(LOG_Debug, "Start the wifi communication\n"); uv_thread_t uvSyncThread; uv_thread_create(&uvSyncThread, DBusMsgHandleLoop, NULL); diff --git a/package/allwinner/wifimanager/src/Makefile b/package/allwinner/wifimanager/src/Makefile index 13e4b8856..c891caa57 100755 --- a/package/allwinner/wifimanager/src/Makefile +++ b/package/allwinner/wifimanager/src/Makefile @@ -10,7 +10,7 @@ LIBS += -lpthread -ldl -lrt -liconv local_LDFLAGS := $(BUILD_COMMON_LIB) $(ICONV_LDFLAGS) -liconv SRCS =wifimanager.c wifi_event.c wifi_state_machine.c network_manager.c \ - wifi.c wpa_supplicant_conf.c udhcpc_thread.c tool.c wmg_debug.c + wifi.c wpa_supplicant_conf.c udhcpc_thread.c tool.c wmg_debug.c broadlink.c install: -@mkdir -p $(CONFIG_PREFIX)/usr/lib @@ -19,12 +19,12 @@ install: #libwifimg.so ifeq ($(CONFIG_ARCH), "aarch64") - SRCS += libwpa_client_64.a + SRCS += libwpa_client_64.a libfastcon.a else ifeq ($(CONFIG_SOFT_FLOAT), y) - SRCS += libwpa_client_softft.a + SRCS += libwpa_client_softft.a libfastcon.a else - SRCS += libwpa_client.a + SRCS += libwpa_client.a libfastcon.a endif endif $(target): $(SRCS) diff --git a/package/allwinner/wifimanager/src/broadlink.c b/package/allwinner/wifimanager/src/broadlink.c new file mode 100755 index 000000000..4df4546c9 --- /dev/null +++ b/package/allwinner/wifimanager/src/broadlink.c @@ -0,0 +1,890 @@ +#ifndef PLATFORM_CPU +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PLATFORM_R16) || defined (PLATFORM_CPU) +#include "log.h" +#include "libuv_dbus.h" +//#include "boardlink_iot.h" +#else +#include +#include +//#include +#endif +#include +#include +#include "broadlink.h" +#include "sdk.h" +#include "sdk_errno.h" + + +#define BL_IOT_PROTO (30) +#define BL_MSG_BUF_MAX (1024 * 4) + +static int g_nlSock = -1; +static unsigned char g_MsgSendBuf[BL_MSG_BUF_MAX]; +WL_INFO g_WlInfo; + +void bl_recv_msg_thread(void *pParam) +{ + unsigned char msgBuf[BL_MSG_BUF_MAX]; + unsigned char *pProbeReqPayload = NULL; + struct iovec iov = {msgBuf, BL_MSG_BUF_MAX}; + struct nlmsghdr *pMsgHdr; + struct sockaddr_nl fromAddr; + struct msghdr msgHdr = {&fromAddr, sizeof(fromAddr), &iov, 1, NULL, 0, 0}; + int ret; + int i; + + memset(&fromAddr, 0, sizeof(fromAddr)); + fromAddr.nl_family = AF_NETLINK; + fromAddr.nl_pid = 0; + fromAddr.nl_groups = 0; + + if(0 != bl_create_socket()) + { + LOG_EX(LOG_Error, "Create netlink socket error\n"); + return ; + } + + while(TRUE) + { + int len = recvmsg(g_nlSock, &msgHdr, 0); + + if(len > 0) + { + for(pMsgHdr = (struct nlmsghdr *)msgBuf; + NLMSG_OK(pMsgHdr, len); + pMsgHdr = NLMSG_NEXT(pMsgHdr, len)) + { + if(pMsgHdr->nlmsg_type == NLMSG_DONE) + { + continue; + } + else if(pMsgHdr->nlmsg_type == NLMSG_ERROR) + { + continue; + } + else + { + PBL_IOT_MSG pMsg = (PBL_IOT_MSG)NLMSG_DATA(pMsgHdr); + //LOG_EX(LOG_Debug, "Recv netlink msg type %d\n", pMsg->msgType); + if (MSG_GET_WLAN_INFO == pMsg->msgType) + { + WL_INFO *wlInfo = NULL; + wlInfo = (WL_INFO *)pMsg->msgData; + bl_set_wlan_info(wlInfo); + LOG_EX(LOG_Debug, "SSID %s, Channel %d, dev mac %x:%x:%x:%x:%x:%x, bssid mac %x:%x:%x:%x:%x:%x\n", + wlInfo->ssid, wlInfo->channel, + wlInfo->dev_mac[0], wlInfo->dev_mac[1], wlInfo->dev_mac[2], wlInfo->dev_mac[3], wlInfo->dev_mac[4], wlInfo->dev_mac[5], + wlInfo->bssid[0], wlInfo->bssid[1],wlInfo->bssid[2],wlInfo->bssid[3],wlInfo->bssid[4],wlInfo->bssid[5]); + } + else if (MSG_BYPASS_MODE == pMsg->msgType) + { + LOG_EX(LOG_Debug, "Recv BROADLINK Probe Request! Len %d\n", pMsg->msglen); + sdk_pkt_process(pMsg->msgData, pMsg->msglen); + } + } + } + } + + usleep(1000); + } + //pthread_detach(pthread_self()); +} + +int bl_create_socket(void) +{ + struct sockaddr_nl srcAddr; + + g_nlSock = socket(AF_NETLINK, SOCK_RAW, BL_IOT_PROTO); + + if(g_nlSock == -1) + { + LOG_EX(LOG_Error, "Create netlink socker error: %s\n", strerror(errno)); + return -ERR_CREATE_SOCKET; + } + + memset(&srcAddr, 0, sizeof(srcAddr)); + srcAddr.nl_family = AF_NETLINK; + srcAddr.nl_pid = getpid(); + srcAddr.nl_groups = 0; + + if(bind(g_nlSock, (struct sockaddr*)&srcAddr, sizeof(srcAddr)) < 0) + { + LOG_EX(LOG_Error, "Bind netlink socket failed: %s", strerror(errno)); + close(g_nlSock); + return -ERR_BIND_SOCKET; + } + + return 0; +} + +static int __bl_send_netlink_msg(unsigned char* pData, unsigned int len) +{ + struct iovec iov; + struct sockaddr_nl dstAddr; + struct nlmsghdr* pMsgHdr = (struct nlmsghdr*)g_MsgSendBuf; + struct msghdr msgHdr = {&dstAddr, sizeof(dstAddr), &iov, 1, NULL, 0, 0}; + + memset(&dstAddr, 0, sizeof(struct sockaddr_nl)); + dstAddr.nl_family = AF_NETLINK; + dstAddr.nl_pid = 0; + dstAddr.nl_groups = 0; + + memset(pMsgHdr, 0, BL_MSG_BUF_MAX); + pMsgHdr->nlmsg_len = len; + pMsgHdr->nlmsg_pid = getpid(); + pMsgHdr->nlmsg_flags = 0; + memcpy(NLMSG_DATA(pMsgHdr), pData, len); + + iov.iov_base = pMsgHdr; + iov.iov_len = NLMSG_SPACE(BL_MSG_BUF_MAX); + + return sendmsg(g_nlSock, &msgHdr, 0); +} + +int bl_send_msg(BL_IOT_MSG_TYPE msgType, unsigned char* pData, unsigned int len) +{ + BL_IOT_MSG blMsg; + + memset(&blMsg, 0, sizeof(BL_IOT_MSG)); + blMsg.msgType = msgType; + blMsg.msglen = len; + strcpy(blMsg.msgTags, BL_IOT_MSG_TAGS); + + if(pData && len > 0) + { + memcpy(blMsg.msgData, pData, len); + } + return __bl_send_netlink_msg((unsigned char*)&blMsg, BL_IOT_MSG_LEN(len)); +} + +/** + * __bl_binary_to_string - Transfer binary array to string. + * For example, {0x11,0x22,0x33,0x44} will be transfered to "11223344". + * @binary: Pointer to the binary array. + * @binary_len: Length of the binary array. + * @return: Pointer to the result string. + * + * Remember to free the string space after using the string!! + */ +static char *__bl_binary_to_string(const uint8 *binary, uint16 binary_len) +{ + char *str = NULL; + int str_len = binary_len * 2 + 1; + int i; + + if (NULL == binary || 0 == binary_len) + return NULL; + + str = malloc(str_len); + if (NULL == str) + { + LOG_EX(LOG_Error, "Malloc error!\n"); + return NULL; + } + + memset(str, 0, str_len); + /* Transfer from binary to string */ + for (i=0; i= '0' && string[i*2] <= '9') + (*array)[i] = (string[i*2] - '0') * 0x10; + else if (string[i*2] >= 'a' && string[i*2] <= 'f') + (*array)[i] = (string[i*2] - 'a' + 10) * 0x10; + else + { + free(*array); + *array = NULL; + LOG_EX(LOG_Debug, "Unable to recognize charactor!\n"); + return -1; + } + + if (string[i*2+1] >= '0' && string[i*2+1] <= '9') + (*array)[i] += string[i*2+1] - '0'; + else if (string[i*2+1] >= 'a' && string[i*2+1] <= 'f') + (*array)[i] += string[i*2+1] - 'a' + 10; + else + { + free(*array); + *array = NULL; + LOG_EX(LOG_Debug, "Unable to recognize charactor!\n"); + return -1; + } + } + + return 0; +} + + +static int __bl_dbus_cmd_send(int mask, uint32_t cmd, const char* pContext) +{ + int status =0; + + status = DBusBoardcastCommand(NULL, mask, cmd, pContext); + if(0 != status ) + { + LOG_EX(LOG_Debug, "nevsps bl send module cmd err is %d\r\n",status); + } + + return status; +} + +static int __bl_get_challenge_signature(char * p_txt, uint8 **pp_challenge, uint16 *challenge_len, uint8 **pp_signature, uint16 *signature_len) +{ + cJSON *p_root =NULL; + cJSON *p_challenge_item = NULL; + cJSON *p_signature_item = NULL; + char *p_tmp = NULL; + int ret = 0; + + p_root=cJSON_Parse(p_txt); + if(NULL == p_root) + goto fail; + + /* Get cloud challenge value. */ + p_challenge_item = cJSON_GetObjectItem(p_root, "challenge"); + if(NULL == p_challenge_item) + goto fail; + + p_tmp = p_challenge_item->valuestring; + if(NULL == p_tmp) + goto fail; + + ret = __bl_string_to_binary(p_tmp, pp_challenge, challenge_len); + if (ret) + { + LOG_EX(LOG_Error, "Transfer cloud challenge error!\n"); + goto fail; + } + + /* Get cloud signature value. */ + p_signature_item = cJSON_GetObjectItem(p_root, "signature"); + if(NULL == p_signature_item) + goto fail; + + p_tmp = p_signature_item->valuestring; + if(NULL == p_tmp) + goto fail; + + ret = __bl_string_to_binary(p_tmp, pp_signature, signature_len); + if (ret) + { + LOG_EX(LOG_Error, "Transfer cloud signature error!\n"); + goto fail; + } + + cJSON_Delete(p_root); + + return 0; +fail: + if (*pp_challenge) + { + free(*pp_challenge); + *pp_challenge = NULL; + *challenge_len = 0; + } + if (*pp_signature) + { + free(*pp_signature); + *pp_signature = NULL; + *signature_len = 0; + } + if (p_root) + cJSON_Delete(p_root); + + return -1; +} + +static int __bl_get_shared_key(char * p_txt, uint8 **pp_shared_key, uint16 *shared_key_len) +{ + cJSON *p_root =NULL; + cJSON *p_shared_key_item = NULL; + char *p_tmp = NULL; + int ret = 0; + + p_root=cJSON_Parse(p_txt); + if(NULL == p_root) + goto fail; + + /* Get shared key value. */ + p_shared_key_item = cJSON_GetObjectItem(p_root, "shareKey"); + if(NULL == p_shared_key_item) + goto fail; + + p_tmp = p_shared_key_item->valuestring; + if(NULL == p_tmp) + goto fail; + + ret = __bl_string_to_binary(p_tmp, pp_shared_key, shared_key_len); + if (ret) + { + LOG_EX(LOG_Error, "Transfer shared key error!\n"); + goto fail; + } + + cJSON_Delete(p_root); + + return 0; +fail: + if (*pp_shared_key) + { + free(*pp_shared_key); + *pp_shared_key = NULL; + *shared_key_len = 0; + } + + if (p_root) + cJSON_Delete(p_root); + + return -1; +} + + + +int32 bl_printf(const char* format, ...) +{ + //LOG_EX(level, format, args...) + va_list args; + va_start(args, format); + //vprintf(fmt, args); + IHW_LOG(LOG_Debug, format, args); + va_end(args); + + return 0; +} + +int32 bl_found_device(sdk_product_info_t *product_info) +{ + LOG_EX(LOG_Debug, "Found Broadlink device!\n"); + LOG_EX(LOG_Debug, "verdor id %d!\n", product_info->vendor_id); + LOG_EX(LOG_Debug, "product id %d!\n", product_info->product_id); + LOG_EX(LOG_Debug, "mac %x:%x:%x:%x:%x:%x!\n", product_info->mac[0], product_info->mac[1], product_info->mac[2], product_info->mac[3], product_info->mac[4], product_info->mac[5]); + + if (0 != sdk_user_auth_to_start_config()) + { + LOG_EX(LOG_Debug, "sdk_user_auth_to_start_config failed!\n"); + } + else + { + LOG_EX(LOG_Debug, "sdk_user_auth_to_start_config succeed!\n"); + } + + return 0; +} + +int32 bl_challenge_post(sdk_product_info_t *product_info, uint8 *challenge, uint16 challenge_len) +{ + cJSON* pRoot = NULL; + char *pInfoJson = NULL; + char *dev_info = NULL; + char *dev_id = NULL; + char *challenge_str = NULL; + + LOG_EX(LOG_Debug, "Begin device challenge!\n"); + + pRoot = cJSON_CreateObject(); + if(NULL == pRoot) + { + LOG_EX(LOG_Error, "cJSON_CreateObject error!\n"); + return -1; + } + + /* Add device_info string to json */ + dev_info = __bl_binary_to_string(product_info->device_info, product_info->device_info_len); + if (NULL == dev_info) + { + LOG_EX(LOG_Error, "Transfer device_info error!\n"); + return -1; + } + LOG_EX(LOG_Debug, "add device_info string %s\n", dev_info); + cJSON_AddStringToObject(pRoot, "deviceInfo", dev_info); + free(dev_info); + + /* Add device_id string to json */ + dev_id = __bl_binary_to_string(product_info->device_id, product_info->device_id_len); + if (NULL == dev_id) + { + LOG_EX(LOG_Error, "Transfer device_id error!\n"); + return -1; + } + LOG_EX(LOG_Debug, "add device_id string %s\n", dev_id); + cJSON_AddStringToObject(pRoot, "deviceId", dev_id); + free(dev_id); + + /* Add device challenge string to json */ + challenge_str = __bl_binary_to_string(challenge, challenge_len); + if (NULL == challenge_str) + { + LOG_EX(LOG_Error, "Transfer device challenge error!\n"); + return -1; + } + LOG_EX(LOG_Debug, "add challenge string %s\n", challenge_str); + cJSON_AddStringToObject(pRoot, "challenge", challenge_str); + free(challenge_str); + + pInfoJson = cJSON_Print(pRoot); + if(NULL == pInfoJson) + { + cJSON_Delete(pRoot); + return -1; + } + cJSON_Delete(pRoot); + + LOG_EX(LOG_Debug, "Send device info %s\n", pInfoJson); + __bl_dbus_cmd_send(1<device_info, product_info->device_info_len); + if (NULL == dev_info) + { + LOG_EX(LOG_Error, "Transfer device_info error!\n"); + return -1; + } + LOG_EX(LOG_Debug, "add device_info string %s\n", dev_info); + cJSON_AddStringToObject(pRoot, "deviceInfo", dev_info); + free(dev_info); + + /* Add device_id string to json */ + dev_id = __bl_binary_to_string(product_info->device_id, product_info->device_id_len); + if (NULL == dev_id) + { + LOG_EX(LOG_Error, "Transfer device_id error!\n"); + return -1; + } + LOG_EX(LOG_Debug, "add device_id string %s\n", dev_id); + cJSON_AddStringToObject(pRoot, "deviceId", dev_id); + free(dev_id); + + /* Add device signature string to json */ + signature_str = __bl_binary_to_string(signature, signature_len); + if (NULL == signature_str) + { + LOG_EX(LOG_Error, "Transfer device signature error!\n"); + return -1; + } + LOG_EX(LOG_Debug, "add signature string %s\n", signature_str); + cJSON_AddStringToObject(pRoot, "signature", signature_str); + free(signature_str); + + pSignatureJson = cJSON_Print(pRoot); + if(NULL == pSignatureJson) + { + cJSON_Delete(pRoot); + return -1; + } + cJSON_Delete(pRoot); + + LOG_EX(LOG_Debug, "Send device signature %s\n", pSignatureJson); + __bl_dbus_cmd_send(1<device_info, product_info->device_info_len); + if (NULL == dev_info) + { + LOG_EX(LOG_Error, "Transfer device_info error!\n"); + return -1; + } + LOG_EX(LOG_Debug, "add device_info string %s\n", dev_info); + cJSON_AddStringToObject(pRoot, "deviceInfo", dev_info); + free(dev_info); + + /* Add device_id string to json */ + dev_id = __bl_binary_to_string(product_info->device_id, product_info->device_id_len); + if (NULL == dev_id) + { + LOG_EX(LOG_Error, "Transfer device_id error!\n"); + return -1; + } + LOG_EX(LOG_Debug, "add device_id string %s\n", dev_id); + cJSON_AddStringToObject(pRoot, "deviceId", dev_id); + free(dev_id); + + /* Add device token string to json */ + token_str = __bl_binary_to_string(token, token_len); + if (NULL == token_str) + { + LOG_EX(LOG_Error, "Transfer device token error!\n"); + return -1; + } + LOG_EX(LOG_Debug, "add token string %s\n", token_str); + cJSON_AddStringToObject(pRoot, "tokenInfo", token_str); + free(token_str); + + pTokenJson = cJSON_Print(pRoot); + if(NULL == pTokenJson) + { + cJSON_Delete(pRoot); + return -1; + } + cJSON_Delete(pRoot); + + LOG_EX(LOG_Debug, "Send device token %s\n", pTokenJson); + __bl_dbus_cmd_send(1<channel = g_WlInfo.channel; + memcpy(usrInit->device_mac, g_WlInfo.dev_mac, ETH_ALEN); + memcpy(usrInit->bssid, g_WlInfo.bssid, ETH_ALEN); + + return 0; +} + +int bl_sdk_init() +{ + sdk_user_init_t usrInit; + int ret = 0; + + memset(&usrInit, 0, sizeof(sdk_user_init_t)); + if (0 != bl_get_wlan_info(&usrInit)) + { + LOG_EX(LOG_Error, "Get wlan info error\n"); + return -1; + } + usrInit.send_wlan_type = BL_IOT_MGMT_FRAME_TYPE_ACTION; + usrInit.fastcon_master_id[0]=BL_MASTER_ID_FOR_NETEASE; + usrInit.fastcon_master_id[1]=0; + usrInit.fastcon_master_id[2]=0; + usrInit.fastcon_master_id[3]=0; + usrInit.sdk_config.memset = memset; + usrInit.sdk_config.memcpy = memcpy; + usrInit.sdk_config.memcmp = memcmp; + usrInit.sdk_config.printf = bl_printf; + usrInit.sdk_config.found_device = bl_found_device; + usrInit.sdk_config.challenge_post = bl_challenge_post; + usrInit.sdk_config.signature_post = bl_signature_post; + usrInit.sdk_config.device_token_post = bl_device_token_post; + usrInit.sdk_config.config_result_post = bl_config_result_post; + usrInit.sdk_config.send_raw_pkt = bl_raw_pkt_send; + + if (0 != (ret = sdk_init(&usrInit))) + { + LOG_EX(LOG_Error, "Broadlink sdk init error code %d!\n", ret); + return -1; + } + LOG_EX(LOG_Debug, "Broadlink sdk init OK!\n"); + + return 0; +} + +int bl_event_handle(unsigned int cmd, const char* msg) +{ + uint8 *cloud_challenge = NULL; + uint16 cloud_challenge_len = 0; + uint8 *cloud_signature = NULL; + uint16 cloud_signature_len = 0; + + uint8 *shared_key = NULL; + uint16 shared_key_len = 0; + uint8 ssid[SSID_MAX_LEN] = {0}; + uint8 key_mgmt[KEY_MGMT_LEN] = {0}; + uint8 password[PASSWORD_MAX_LEN] = {0}; + int priority; + + int ret = 0; + + switch(cmd) + { + case CMD_WIFI_BL_CONF: + bl_enable_discovery_mode(); + bl_sdk_init(); + break; + + case CMD_WIFI_BL_CLOUD_CHALLENGE_SIGNATURE: + ret = __bl_get_challenge_signature(msg, &cloud_challenge, &cloud_challenge_len, &cloud_signature, &cloud_signature_len); + if (ret) + { + LOG_EX(LOG_Debug, "__bl_get_challenge_signature failed!\n"); + return -1; + } + + ret = sdk_challenge_and_signature_set(cloud_challenge, cloud_challenge_len, cloud_signature, cloud_signature_len); + if (ret) + LOG_EX(LOG_Error, "sdk_challenge_and_signature_set failed, error code %d!\n", ret); + else + LOG_EX(LOG_Debug, "sdk_challenge_and_signature_set succeed!\n"); + + if (cloud_challenge) + free(cloud_challenge); + + if (cloud_signature) + free(cloud_signature); + + break; + case CMD_WIFI_BL_CLOUD_SHAREDKEY: + ret = __bl_get_shared_key(msg, &shared_key, &shared_key_len); + if (ret) + { + LOG_EX(LOG_Error, "__bl_get_shared_key failed!\n"); + return -1; + } + + /* Get already connected AP's key_mgmt and ssid. */ + wpa_conf_get_apinfo_connected(key_mgmt, &priority); + strncpy(ssid, g_WlInfo.ssid, strlen(g_WlInfo.ssid)); + if (!strcmp(key_mgmt, "WPA-PSK")) + { + /* Get already connected AP's password from wpa_supplicant.conf */ + wpa_conf_get_appwd_connected(priority, password); + } + else + { + // TO BE FIXED + password[0] = '\0'; + } + + ret = sdk_wlan_params_set(shared_key, ssid, strlen(ssid), password, strlen(password)); + if (ret) + LOG_EX(LOG_Debug, "sdk_wlan_params_set failed, error code %d!\n", ret); + else + LOG_EX(LOG_Debug, "sdk_wlan_params_set succeed!\n"); + + if (shared_key) + free(shared_key); + + break; + case CMD_WIFI_BL_DEV_TOKEN_BOUND: + ret = sdk_device_token_bind_success(); + if (ret) + { + LOG_EX(LOG_Debug, "sdk_device_token_bind_success failed, error code %d!\n", ret); + } + else + { + LOG_EX(LOG_Debug, "sdk_device_token_bind_success succeed!\n"); + } + break; + case CMD_WIFI_BL_CONF_ABORT: + bl_disable_discovery_mode(); + break; + default: + break; + } + return ret; +} + +#endif diff --git a/package/allwinner/wifimanager/src/include/broadlink.h b/package/allwinner/wifimanager/src/include/broadlink.h new file mode 100755 index 000000000..09a39a6c3 --- /dev/null +++ b/package/allwinner/wifimanager/src/include/broadlink.h @@ -0,0 +1,43 @@ +#ifndef BROADLINK_IOT_H +#define BROADLINK_IOT_H +#ifndef PLATFORM_CPU +#define BL_IOT_MSG_TAGS ("BLNLINK") +#define BL_IOT_MGMT_FRAME_TYPE_ACTION 2 /* Use action frame to respond to Broadlink device. */ +#define BL_MASTER_ID_FOR_NETEASE 202 +#define BL_MAX_MSG (1024) +#define ETH_ALEN (6) + +typedef enum +{ + MSG_IN_DISCOVERY_MODE = 0, + MSG_OUT_DISCOVERY_MODE, + MSG_GET_WLAN_INFO, + MSG_BYPASS_MODE, +} BL_IOT_MSG_TYPE; + +#pragma pack (push) +#pragma pack (1) +typedef struct +{ + unsigned char msgTags[8]; + unsigned char dstMac[ETH_ALEN]; + unsigned char msgType; + unsigned int msglen; + unsigned char msgData[BL_MAX_MSG]; +} BL_IOT_MSG, *PBL_IOT_MSG; + +typedef struct +{ + unsigned char channel; + unsigned char dev_mac[ETH_ALEN]; + unsigned char bssid[ETH_ALEN]; + unsigned char ssid[32]; +} WL_INFO, *PWL_INFO; +#pragma pack (pop) + +#define BL_IOT_MSG_LEN(len) (sizeof(BL_IOT_MSG) - BL_MAX_MSG + len) + +void bl_recv_msg_thread(void *pParam); +int bl_create_socket(void); +#endif +#endif diff --git a/package/allwinner/wifimanager/src/include/network_manager.h b/package/allwinner/wifimanager/src/include/network_manager.h index 45931d70c..445d38872 100755 --- a/package/allwinner/wifimanager/src/include/network_manager.h +++ b/package/allwinner/wifimanager/src/include/network_manager.h @@ -1,6 +1,5 @@ #ifndef __NETWORK_MANAGER_H #define __NETWORK_MANAGER_H -#include "tool.h" #if __cplusplus extern "C" { @@ -11,39 +10,6 @@ extern "C" { #define KEY_WPA_PSK_INDEX 1 #define KEY_WEP_INDEX 2 -enum wpa_states { - WPA_UNKNOWN = 1024, - WPA_DISCONNECTED, - WPA_INTERFACE_DISABLED, - WPA_INACTIVE, - WPA_SCANNING, - WPA_AUTHENTICATING, - WPA_ASSOCIATING, - WPA_ASSOCIATED, - WPA_4WAY_HANDSHAKE, - WPA_GROUP_HANDSHAKE, - WPA_COMPLETED, -}; - -#define WPA_STA_MAX_SSID 32 -#define WPA_STA_MAX_BSSID 18 -#define WPA_STA_MAX_IP_ADDR 16 -#define WPA_STA_MAX_KEY_MGMT 16 -#define WPA_STA_MAX_MAC_ADDR 18 - -struct wpa_status{ - u32 id; - u8 bssid[WPA_STA_MAX_BSSID]; - u32 freq; - u8 ssid[WPA_STA_MAX_SSID]; - enum wpa_states wpa_state; - u8 ip_address[WPA_STA_MAX_IP_ADDR]; - u8 key_mgmt[WPA_STA_MAX_KEY_MGMT]; - u8 mac_address[WPA_STA_MAX_MAC_ADDR]; -}; - -void shutdown_wifi_scan_thread(); -void restart_wifi_scan_thread(); void start_wifi_scan_thread(void *args); void stop_wifi_scan_thread(); void pause_wifi_scan_thread(); @@ -51,9 +17,7 @@ void resume_wifi_scan_thread(); int update_scan_results(); int get_scan_results_inner(char *results, int *len); int get_key_mgmt(const char *ssid, int key_mgmt_info[]); -struct wpa_status * get_wpa_status(); -void print_wpa_status(struct wpa_status *wpa_sta); -void wpa_status_free(); + #if __cplusplus }; // extern "C" #endif diff --git a/package/allwinner/wifimanager/src/include/sdk.h b/package/allwinner/wifimanager/src/include/sdk.h new file mode 100755 index 000000000..db20bb7ba --- /dev/null +++ b/package/allwinner/wifimanager/src/include/sdk.h @@ -0,0 +1,213 @@ +#ifndef __SDK_H +#define __SDK_H + +/* + * 0. implement all callback's of this SDK + * 1. read wifi probe frame from driver + * 2. feed wifi probe frame to sdk_pkt_process + * 3. this sdk depends on no thirdparty libraries, and there is no internet connection with net. + */ + + +typedef unsigned char uint8; +typedef unsigned short int uint16; +typedef unsigned int uint32; + +typedef char int8; +typedef short int int16; +typedef int int32; + +#define SDK_SUCCESS (0) +#define SDK_FAIL (1) +#define SDK_NULL (0) +#define OUI_LEN (3) +#define OUI_TYPE (0) +#define OUI_TYPE_LEN (1) +#define MAC_LEN (6) +#define SSID_MAX_LEN (64) +#define PASSWORD_MAX_LEN (64) +#define KEY_MGMT_LEN (16) +#define SDK_SHAREDKEY_LEN (32) +#define SDK_FRAME_MAX_LEN (1460) +#define FASTCON_MASTER_ID_LEN (4) + +#define SDK_PACKED __attribute__((packed)) + + +typedef void* (*sdk_memset_t) ( + void* ptr, + int32 value, + uint32 num); +typedef void* (*sdk_memcpy_t) ( + void* dst, + const void* src, + uint32 num); +typedef int32 (*sdk_memcmp_t) ( + const void* ptr1, + const void* ptr2, + uint32 num); +typedef int32 (*sdk_printf_t) ( + const char* format, + ...); + +typedef struct sdk_device_info_t { + uint32 vendor_id; + uint32 product_id; + uint8 mac[MAC_LEN]; + uint8 * device_info; + uint16 device_info_len; + uint8 * device_id; + uint16 device_id_len; +}sdk_product_info_t; + +//发现设备 +typedef int32 (*sdk_found_device_t) (sdk_product_info_t *product_info); +//对应2.1 云端身份校验接口请求 +typedef int32 (*sdk_challenge_post_t)( + sdk_product_info_t *product_info, + uint8 * challenge, + uint16 challenge_len); +//对应2.2 设备身份声明接口请求 +typedef int32 (*sdk_signature_post_t)( + sdk_product_info_t *product_info, + uint8 * signature, + uint16 signature_len); +//sdk将设备控制token传给上层 +typedef int32 (*sdk_device_token_post_t)( + sdk_product_info_t *product_info, + uint8 * token, + uint16 token_len); +//上报配置结果 +//目前只支持失败结果上报。 +//成功的结果是由云端推送上线通知 +//result 0:成功 -1:失败 +typedef int32 (*sdk_config_result_post_t) ( + sdk_product_info_t *product_info, + int8 result); +//发送802.11原始报文接口 +typedef int32 (*sdk_raw_pkt_send_t)( + uint8 * frame, + uint16 frame_len); + + + + +typedef struct { + sdk_memset_t memset; + sdk_memcpy_t memcpy; + sdk_memcmp_t memcmp; + sdk_printf_t printf; + + sdk_found_device_t found_device; + sdk_challenge_post_t challenge_post; + sdk_signature_post_t signature_post; + sdk_device_token_post_t device_token_post; + sdk_config_result_post_t config_result_post; + + sdk_raw_pkt_send_t send_raw_pkt; + +} sdk_config_t; + +typedef struct { + + //gateway信息 + //包括当前路由器信道,gateway mac,bssid + uint8 channel; //cur channel + + //若mac地址为00-11-22-33-44-55,则device_mac[] = {0x00,0x11,0x22,0x33,0x44,0x55}; + uint8 device_mac[MAC_LEN]; + //AP的mac地址,格式等同device_mac + uint8 bssid[MAC_LEN]; + + //由dnakit后台分配,用于区分不同平台,固定4个字节 + uint8 fastcon_master_id[FASTCON_MASTER_ID_LEN]; + + //0:probe req,1:probe rsp,2:action + //报文选择,根据gateway 能力自行设置 + uint8 send_wlan_type; + //回调接口注册 + sdk_config_t sdk_config; +} SDK_PACKED sdk_user_init_t; + +typedef enum { + SDK_STATE_PROBE_DEVICE, + SDK_STATE_LOCK_CHANNEL, + SDK_STATE_CONFIG, + SDK_STATE_CONNECTING, + SDK_STATE_DONE, //Finish + SDK_STATE_FAIL, +} sdk_state_e; + +/** + * @brief 打印sdk编译时间 + * @return 0 打印成功 + * SDK_E_INIT_FAIL sdk未初始化 + */ +extern int32 sdk_version(void); +/** + * @brief 初始化sdk + * @param init + * @return 0 初始化成功 + * SDK_E_INIT_FAIL + */ +extern int32 sdk_init(sdk_user_init_t *init); +/** + * @brief 处理接收的802.11报文 + * @param frame 802.11标准报文格式 + * @param frame_len + * @return sdk_state_e + SDK_E_INIT_FAIL + */ +extern int32 sdk_pkt_process(uint8 *frame, int16 frame_len); +/** + * @brief 发送token bind成功报文 + * @return 0 成功 + * SDK_E_INIT_FAIL + * SDK_E_STATE + */ +extern int32 sdk_device_token_bind_success(void); +/** + * @brief ssid和password信息发送 + * @param sharedkey 二进制数组,云端返回的是十六进制字符串,需要进行转换 + * @param ssid + * @param ssid_len + * @param password + * @param password_len + * @return 0 成功 + * SDK_E_INIT_FAIL + * SDK_E_STATE + * @example 路由器ssid为"ssid",password为"password" + * 代码如下: + * @code + * uint8 ssid[] = "ssid"; + * uint8 password[] = "password"; + * sdk_wlan_params_set(sharedkey,ssid,strlen(ssid),password,strlen(password)); + * @endcode + */ +extern int32 sdk_wlan_params_set(uint8 sharedkey[SDK_SHAREDKEY_LEN],uint8 *ssid,uint16 ssid_len,uint8 *password,uint16 password_len); +/** + * @brief challenge和signature信息发送 + * @param challenge 二进制数组,云端返回的是十六进制字符串,需要进行转换 + * @param challenge_len + * @param signature 二进制数组,云端返回的是十六进制字符串,需要进行转换 + * @param signature_len + * @return 0 成功 + * SDK_E_INIT_FAIL + * SDK_E_STATE + */ +extern int32 sdk_challenge_and_signature_set(uint8 *challenge,uint16 challenge_len, uint8 *signature, uint16 signature_len); +/** + * @brief 用户确认开始配网 + * @return 0 成功 + * SDK_E_INIT_FAIL + * SDK_E_STATE + */ +extern int32 sdk_user_auth_to_start_config(void); +/** + * @brief 清除sdk状态 + * @return 0 成功 + * SDK_E_INIT_FAIL + */ +extern int32 sdk_deinit(void); + +#endif diff --git a/package/allwinner/wifimanager/src/include/sdk_errno.h b/package/allwinner/wifimanager/src/include/sdk_errno.h new file mode 100755 index 000000000..369b79779 --- /dev/null +++ b/package/allwinner/wifimanager/src/include/sdk_errno.h @@ -0,0 +1,19 @@ + +#ifndef __SDK_ERRNO_H +#define __SDK_ERRNO_H + + +#define SDK_E_INIT_FAIL (-1) //SDK初始化失败 +#define SDK_E_INVPARAMS (-2) //参数异常 +#define SDK_E_STATE (-3) //sdk状态异常 + +//only use by sdk_config_result_post_t +#define SDK_E_CONNECT_AP_TIMEOUT (-101) //连接ap超时 +#define SDK_E_PKT_SEND (-102) //发送数据包失败 +#define SDK_E_OVER_RETRY_COUNT (-103) //超过最大重试次数 +#define SDK_E_VERIFY_SIGNATURE (-104) //校验网关端身份失败 +#define SDK_E_SSID_PWD (-105) //ssid和pwd解析异常 +#define SDK_E_MSG_NOT_SUPPORT (-106) //接收到不支持的消息类型 +#define SDK_E_CONFIG_TIMEOUT (-107) //配置超时,超过10分钟配置时间 + +#endif diff --git a/package/allwinner/wifimanager/src/include/wifi_event.h b/package/allwinner/wifimanager/src/include/wifi_event.h index 35c1c4134..c017f46a8 100755 --- a/package/allwinner/wifimanager/src/include/wifi_event.h +++ b/package/allwinner/wifimanager/src/include/wifi_event.h @@ -22,7 +22,7 @@ enum WPA_EVENT{ DRIVER_STATE, EAP_FAILURE, ASSOC_REJECT, - NETWORK_NOT_FOUND, + SSID_TEMP_DISABLED, UNKNOWN, }; @@ -35,11 +35,14 @@ typedef enum{ }tWIFI_EVENT_INNER; void wifi_event_loop(tWifi_event_callback pcb); +void wifi_event_loop_stop(); +void wifi_event_loop_restart(); void start_wifi_on_check_connect_timeout(); void start_check_connect_timeout(); tWIFI_EVENT_INNER get_cur_wifi_event(); int set_cur_wifi_event(tWIFI_EVENT_INNER event); void set_scan_start_flag(); +void set_wifi_off_flag(int value); int get_scan_status(); void reset_assoc_reject_count(); int get_assoc_reject_count(); diff --git a/package/allwinner/wifimanager/src/include/wifi_intf.h b/package/allwinner/wifimanager/src/include/wifi_intf.h index 7db2bbd9a..620d2e9ac 100755 --- a/package/allwinner/wifimanager/src/include/wifi_intf.h +++ b/package/allwinner/wifimanager/src/include/wifi_intf.h @@ -4,6 +4,10 @@ #if __cplusplus extern "C" { #endif + +#include +#include + #define MAX_CALLBCAKS_COUNT 1024 typedef enum { @@ -60,9 +64,7 @@ typedef struct{ int (*remove_all_networks)(void); int (*re_config)(void); int (*list_networks)(char *reply, size_t reply_len, int event_label); - int (*get_netid)(const char *ssid, tKEY_MGMT key_mgmt, char *net_id, int *length); - int (*stop_scan)(); - int (*restart_scan)(); + int (*get_netid)(const char *ssid, tKEY_MGMT key_mgmt, char *net_id); int (*change_ap)(int event_label ); int (*enable_all_network)(void); }aw_wifi_interface_t; @@ -70,6 +72,9 @@ typedef struct{ const aw_wifi_interface_t * aw_wifi_on(tWifi_event_callback pcb, int event_label); int aw_wifi_get_wifi_state(); int aw_wifi_off(const aw_wifi_interface_t *p_wifi_interface_t); +int bl_sdk_init(); +int bl_event_handle(unsigned int cmd, const char* msg); + #if __cplusplus }; // extern "C" diff --git a/package/allwinner/wifimanager/src/libfastcon.a b/package/allwinner/wifimanager/src/libfastcon.a new file mode 100755 index 0000000000000000000000000000000000000000..a479fd75459a238f8006e325ff64e9c05b407483 GIT binary patch literal 24018 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 X2iXqVLhPsP{Ek>c #include +#include +#include +#include + + #include #include "wifi_event.h" #include "network_manager.h" #include "wifi_intf.h" #include "wifi.h" -#include "tool.h" +#include "broadlink.h" + + +#define MAX_SCAN_FAIL_TIME 5 #define WAITING_CLK_COUNTS 50 -#define SSID_LEN 512 #define UTF8_BYTES_MAX 4096 #define UTF8_MULTI_BYTES_MASK 0x80 #define ESCAP_CHAR_ASCII '\\' @@ -24,237 +31,23 @@ /* scan thread */ static pthread_t scan_thread_id; static int scan_running = 0; -static int scan_terminating = 0; static pthread_mutex_t scan_mutex; static pthread_cond_t scan_cond; static int scan_pause = 0; -static int scan_error = 0; -static int do_scan_flag = 1; /* run scan immediately */ static pthread_mutex_t thread_run_mutex; static pthread_cond_t thread_run_cond; -/*stop restart scan*/ -static pthread_mutex_t scan_stop_restart_mutex; -static pthread_cond_t scan_stop_restart_cond; - /* store scan results */ static char scan_results[SCAN_BUF_LEN]; static int scan_results_len = 0; static int scan_completed = 0; -enum wpa_states wpa_supplicant_state_convert(char *str) -{ - if(!strncmp(str,"DISCONNECTED",16)){ - return WPA_DISCONNECTED; - } - if(!strncmp(str,"INTERFACE_DISABLED",22)){ - return WPA_INTERFACE_DISABLED; - } - if(!strncmp(str,"INACTIVE",12)){ - return WPA_INACTIVE; - } - if(!strncmp(str,"SCANNING",12)){ - return WPA_SCANNING; - } - if(!strncmp(str,"AUTHENTICATING",18)){ - return WPA_AUTHENTICATING; - } - if(!strncmp(str,"ASSOCIATED",14)){ - return WPA_ASSOCIATED; - } - if(!strncmp(str,"4WAY_HANDSHAKE",19)){ - return WPA_4WAY_HANDSHAKE; - } - if(!strncmp(str,"GROUP_HANDSHAKE",19)){ - return WPA_GROUP_HANDSHAKE; - } - if(!strncmp(str,"COMPLETED",13)){ - return WPA_COMPLETED; - } - if(!strncmp(str,"DISCONNECTED",16)){ - return WPA_DISCONNECTED; - } - return WPA_UNKNOWN; -} -static const char * wpa_supplicant_state_txt(enum wpa_states state) -{ - switch (state) { - case WPA_DISCONNECTED: - return "DISCONNECTED"; - case WPA_INACTIVE: - return "INACTIVE"; - case WPA_INTERFACE_DISABLED: - return "INTERFACE_DISABLED"; - case WPA_SCANNING: - return "SCANNING"; - case WPA_AUTHENTICATING: - return "AUTHENTICATING"; - case WPA_ASSOCIATING: - return "ASSOCIATING"; - case WPA_ASSOCIATED: - return "ASSOCIATED"; - case WPA_4WAY_HANDSHAKE: - return "4WAY_HANDSHAKE"; - case WPA_GROUP_HANDSHAKE: - return "GROUP_HANDSHAKE"; - case WPA_COMPLETED: - return "COMPLETED"; - default: - return "UNKNOWN"; - } -} -void print_wpa_status(struct wpa_status *wpa_sta) -{ - LOG_EX(LOG_Debug, "obtained wpa_supplicant status,as follow:\n"); - LOG_EX(LOG_Debug, "==============================\n"); - if(wpa_sta->id >= 0) - LOG_EX(LOG_Debug, "id:%d\n",wpa_sta->id); - if(wpa_sta->bssid) - LOG_EX(LOG_Debug, "bssid:%s\n",wpa_sta->bssid); - if(wpa_sta->freq >=0) - LOG_EX(LOG_Debug, "freq:%d\n",wpa_sta->freq); - if(wpa_sta->ssid) - LOG_EX(LOG_Debug, "ssid:%s\n",wpa_sta->ssid); - if(wpa_sta->wpa_state) - LOG_EX(LOG_Debug, "wpa_state:%s\n",wpa_supplicant_state_txt(wpa_sta->wpa_state)); - if(wpa_sta->ip_address) - LOG_EX(LOG_Debug, "ip_address:%s\n",wpa_sta->ip_address); - if(wpa_sta->key_mgmt) - LOG_EX(LOG_Debug, "key_mgmt:%s\n",wpa_sta->key_mgmt); - if(wpa_sta->mac_address) - LOG_EX(LOG_Debug, "mac_address:%s\n",wpa_sta->mac_address); - LOG_EX(LOG_Debug, "==============================\n"); -} -static char *strstr_wpa(const char *src,const char *obj, - const char pre_str[2],int pst_len) -{ - const char *p=src; - int length; - int i=0; - if(src == NULL || obj == NULL || pre_str ==NULL){ - LOG_EX(LOG_Debug, "src or obj or pre_str is NULL"); - return NULL; - } - if(pst_len > strlen(pre_str)){ - LOG_EX(LOG_Debug, "pst_len length is illegal"); - return NULL; - } - length = strlen(obj); - for(;;p++,i++){ - p=strchr(p,*obj); - if(p == NULL){ - LOG_EX(LOG_Debug, "%s is not exist",obj); - return NULL; - } - if(strncmp(p,obj,length) == 0){ - if(i > 1 && *(p-1) != pre_str[0] && *(p-1) != pre_str[1]){ - return (char*)p; - } - } - } -} -static int search_wpa_string(const char *src,const char *obj,int max,char *get_str) -{ - int i=0; - const char *sptr = NULL; - const char *pnext = NULL; - if(obj == NULL || src == NULL){ - wmg_printf(MSG_DEBUG,"src or obj is NULL"); - return 0; - } - if(!strncmp("id=",obj,3)){ - sptr = strstr_wpa(src,obj,"su",2); - }else if(!strncmp("ssid=",obj,5)){ - sptr = strstr_wpa(src,obj,"bb",2); - }else if(!strncmp("address=",obj,8)){ - sptr = strstr_wpa(src,obj,"__",2); - }else{ - sptr = strstr(src, obj); - } +/* broadlink thread */ +static pthread_t broadlink_thread_id; +static int broadlink_thread_running = 0; - if(sptr !=NULL){ - pnext=sptr+strlen(obj); - i=0; - while(1){ - i++; - if(i >max ){ - LOG_EX(LOG_Debug, "Data overflow"); - break; - } - pnext++; - if(*pnext == '\n') - break; - } - strncpy(get_str,sptr+strlen(obj),i); - get_str[i]='\0'; - return 1; - } - return -1; -} -static struct wpa_status *gstatus; - -static struct wpa_status* wpa_status_init() -{ - int i; - if(gstatus == NULL) - gstatus = (struct wpa_status *)wgos_zalloc(sizeof(struct wpa_status)); - if(gstatus == NULL){ - LOG_EX(LOG_Debug, "MALLOC STATUS STRUCT FAILED!\n"); - return NULL; - } - gstatus->id = -1; - gstatus->freq = -1; - for(i = 0;i< WPA_STA_MAX_SSID;i++){ - gstatus->ssid[i] = '\0'; - if(i < WPA_STA_MAX_BSSID) - gstatus->bssid[i] = '\0'; - if(i < WPA_STA_MAX_IP_ADDR) - gstatus->ip_address[i] = '\0'; - if(i < WPA_STA_MAX_KEY_MGMT) - gstatus->key_mgmt[i]='\0'; - if(i < WPA_STA_MAX_MAC_ADDR) - gstatus->mac_address[i]='\0'; - } - gstatus->wpa_state = WPA_UNKNOWN; - return gstatus; -} -void wpa_status_free() -{ - if(gstatus !=NULL) - free(gstatus); -} -struct wpa_status * get_wpa_status() -{ - char reply[4096] = {0}; - char wpa_result[32]; - struct wpa_status *wpa_sta; - wpa_sta = wpa_status_init(); - wifi_command("STATUS", reply, sizeof(reply)); - if(reply !=NULL){ - if(search_wpa_string(reply,"ssid=",32,wpa_result) >0) - strncpy(wpa_sta->ssid,wpa_result,strlen(wpa_result)); - if(search_wpa_string(reply,"id=",4,wpa_result) >0) - wpa_sta->id = atoi(wpa_result); - if(search_wpa_string(reply,"freq=",6,wpa_result) >0) - wpa_sta->freq = atoi(wpa_result); - if(search_wpa_string(reply,"bssid=",18,wpa_result) >0) - strncpy(wpa_sta->bssid,wpa_result,strlen(wpa_result)); - if(search_wpa_string(reply,"key_mgmt=",16,wpa_result) >0) - strncpy(wpa_sta->key_mgmt,wpa_result,strlen(wpa_result)); - if(search_wpa_string(reply,"wpa_state=",32,wpa_result) >0) - wpa_sta->wpa_state = wpa_supplicant_state_convert(wpa_result); - if(search_wpa_string(reply,"address=",18,wpa_result) >0) - strncpy(wpa_sta->mac_address,wpa_result,strlen(wpa_result)); - if(search_wpa_string(reply,"ip_address=",16,wpa_result) >0) - strncpy(wpa_sta->ip_address,wpa_result,strlen(wpa_result)); - } - if(wmg_get_debug_level() >= MSG_DEBUG){ - print_wpa_status(wpa_sta); - } - return wpa_sta; -} int update_scan_results() { @@ -277,72 +70,13 @@ int update_scan_results() return 0; } -int remove_slash_from_scan_results() -{ - char *ptr = NULL; - char *ptr_s = NULL; - char *ftr = NULL; - - ptr_s = scan_results; - while(1) - { - ptr = strchr(ptr_s,'\"'); - if(ptr == NULL) - break; - - ptr_s = ptr; - if((*(ptr-1)) == '\\') - { - ftr = ptr; - ptr -= 1; - while(*ftr != '\0') - *(ptr++) = *(ftr++); - *ptr = '\0'; - continue; //restart new search at ptr_s after removing slash - } - else - ptr_s++; //restart new search at ptr_s++ - } - - ptr_s = scan_results; - while(1) - { - ptr = strchr(ptr_s,'\\'); - if(ptr == NULL) - break; - - ptr_s = ptr; - if((*(ptr-1)) == '\\') - { - ftr = ptr; - ptr -= 1; - while(*ftr != '\0') - *(ptr++) = *(ftr++); - *ptr = '\0'; - continue; //restart new search at ptr_s after removing slash - } - else - ptr_s++; //restart new search at ptr_s++ - } - - return 0; -} - int get_scan_results_inner(char *result, int *len) { int index = 0; char *ptr = NULL; - int ret = 0; pthread_mutex_lock(&scan_mutex); - if(0 != scan_error) - { -// prinf("%s: scan or scan_results ERROR in scan_thread!\n", __func__); - ret = -1; - } - - remove_slash_from_scan_results(); if(*len <= scan_results_len){ strncpy(result, scan_results, *len-1); index = *len -1; @@ -358,7 +92,7 @@ int get_scan_results_inner(char *result, int *len) pthread_mutex_unlock(&scan_mutex); - return ret; + return 0; } int is_network_exist(const char *ssid, tKEY_MGMT key_mgmt) @@ -461,8 +195,10 @@ int get_key_mgmt(const char *ssid, int key_mgmt_info[]) char *ptr = NULL, *pssid_start = NULL, *pssid_end = NULL; char *pst = NULL, *pend = NULL; char *pflag = NULL; - char flag[128], pssid[SSID_LEN + 1]; + char flag[128]; int len = 0, i = 0; + char * pSsidSearch = NULL; + int status=0; LOG_EX(LOG_Debug, "enter get_key_mgmt, ssid %s\n", ssid); @@ -481,47 +217,66 @@ int get_key_mgmt(const char *ssid, int key_mgmt_info[]) } //point second line of scan results - ptr++; - remove_slash_from_scan_results(); - while(1){ + status = utf8BytesExchangeEx(ssid,&pSsidSearch); + if(0 != status) + { + LOG_EX(LOG_Debug, "utf8 exchange err\r\n"); + goto ToOut; + } + + LOG_EX(LOG_Debug, "changed ssid is %s\r\n",pSsidSearch); + + ptr++; + while((pssid_start=strstr(ptr, pSsidSearch)) != NULL){ + pssid_end = pssid_start + strlen(pSsidSearch); + + /* ssid is presuffix of searched network */ + if((*pssid_end != '\n') && (*pssid_end != '\0')){ + pend = strchr(pssid_start, '\n'); + if(pend != NULL){ + ptr = pend+1; + continue; + }else{ + break; + } + } + + /* network ssid is same of searched network */ /* line end */ - pend = strchr(ptr, '\n'); - if (pend != NULL){ + pend = strchr(pssid_start, '\n'); + if(pend != NULL){ *pend = '\0'; } - /* line start */ - pst = ptr; + pst = strrchr(ptr, '\n'); + if(pst != NULL){ + pst++; + }else{ + pst = ptr; + } - /* abstract ssid */ - pssid_start = strrchr(pst, '\t') + 1; - strncpy(pssid, pssid_start, SSID_LEN); - pssid[SSID_LEN] = '\0'; + pflag = pst; + for(i=0; i<3; i++){ + pflag = strchr(pflag, '\t'); + pflag++; + } - /* find ssid in scan results */ - if(strcmp(pssid, ssid) == 0){ - pflag = pst; - for(i=0; i<3; i++){ - pflag = strchr(pflag, '\t'); - pflag++; - } - - len = pssid_start - pflag; - len = len - 1; - strncpy(flag, pflag, len); - flag[len] = '\0'; + len = pssid_start - pflag; + len = len - 1; + strncpy(flag, pflag, len); + flag[len] = '\0'; LOG_EX(LOG_Debug, "ssid %s, flag %s\n", ssid, flag); - if((strstr(flag, "WPA-PSK-") != NULL) - || (strstr(flag, "WPA2-PSK-") != NULL)){ - key_mgmt_info[KEY_WPA_PSK_INDEX] = 1; - }else if(strstr(flag, "WEP") != NULL){ - key_mgmt_info[KEY_WEP_INDEX] = 1; - }else if((strcmp(flag, "[ESS]") == 0) || (strcmp(flag, "[WPS][ESS]") == 0)){ - key_mgmt_info[KEY_NONE_INDEX] = 1; - }else{ - ; - } + + if((strstr(flag, "WPA-PSK-") != NULL) + || (strstr(flag, "WPA2-PSK-") != NULL)){ + key_mgmt_info[KEY_WPA_PSK_INDEX] = 1; + }else if(strstr(flag, "WEP") != NULL){ + key_mgmt_info[KEY_WEP_INDEX] = 1; + }else if((strcmp(flag, "[ESS]") == 0) || (strcmp(flag, "[WPS][ESS]") == 0)){ + key_mgmt_info[KEY_NONE_INDEX] = 1; + }else{ + ; } if(pend != NULL){ @@ -533,6 +288,10 @@ int get_key_mgmt(const char *ssid, int key_mgmt_info[]) } } +ToOut: + free(pSsidSearch); + pSsidSearch = NULL; + pthread_mutex_unlock(&scan_mutex); return 0; @@ -540,46 +299,103 @@ int get_key_mgmt(const char *ssid, int key_mgmt_info[]) } + +double iw_freq2float(const struct iw_freq * in) +{ + int i; + double res = (double)in->m; + + for(i = 0; i < in->e; i++) + res *= 10; + return (res); +} + +static inline int iw_get_ext(int skfd, const char *ifname, int request, struct iwreq * pwrq) +{ + /* Set device name */ + strncpy(pwrq->ifr_name, ifname, IFNAMSIZ); + /* Do the request */ + return(ioctl(skfd, request, pwrq)); +} + +int api_wifi_get_wireless_info(const char *ifname) +{ + int sock; + struct iwreq wrq; + char *mac = NULL; + + memset((char *)&wrq, 0, sizeof(struct iwreq)); + + /* Create a channel to the NET kernel. */ + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) + { + LOG_EX(LOG_Debug, "Open sock error!\n"); + return -1; + } + + /* Get wireless name */ + if(iw_get_ext(sock, ifname, SIOCGIWNAME, &wrq) < 0) + { + LOG_EX(LOG_Debug, "Get wireless name error!\n"); + return -1; + } + LOG_EX(LOG_Debug, "Wireless name %s\n", wrq.u.name); + + /* Get frequency / channel */ + if(iw_get_ext(sock, ifname, SIOCGIWFREQ, &wrq) < 0) + { + LOG_EX(LOG_Debug, "Get wireless frequency error!\n"); + return -1; + } + LOG_EX(LOG_Debug, "Wireless frequency %lf\n", iw_freq2float(&(wrq.u.freq))); + + /* Get AP address */ + if(iw_get_ext(sock, ifname, SIOCGIWAP, &wrq) < 0) + { + LOG_EX(LOG_Debug, "Get wireless ap mac error!\n"); + return -1; + } + mac = (char *)(&(wrq.u.ap_addr)); + LOG_EX(LOG_Debug, "Wireless ap mac %x:%x:%x:%x:%x:%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + +} + + void *wifi_scan_thread(void *args) { int ret = -1, i = 0; + int scan_fail_cnt = 0; char cmd[16] = {0}, reply[16] = {0}; struct timeval now; struct timespec outtime; while(scan_running){ - - pthread_mutex_lock(&scan_stop_restart_mutex); - while(do_scan_flag == 0){ - pthread_cond_wait(&scan_stop_restart_cond, &scan_stop_restart_mutex); - } - if(scan_terminating) - { - pthread_mutex_unlock(&scan_stop_restart_mutex); - continue; - } - pthread_mutex_unlock(&scan_stop_restart_mutex); - pthread_mutex_lock(&scan_mutex); - while(scan_pause == 1){ + if(scan_pause == 1){ pthread_cond_wait(&scan_cond, &scan_mutex); } - /* set scan start flag */ set_scan_start_flag(); - /* scan cmd */ strncpy(cmd, "SCAN", 15); ret = wifi_command(cmd, reply, sizeof(reply)); if(ret){ - scan_error = 1; pthread_mutex_unlock(&scan_mutex); - usleep(5000*1000); + scan_fail_cnt++; + usleep(500*1000); + /* fix PV1-3216, do DISCONNECT to restore driver from continuiously restart */ + if (scan_fail_cnt > MAX_SCAN_FAIL_TIME) + { + stop_connecting(); + scan_fail_cnt = 0; + } continue; } + scan_fail_cnt = 0; for(i=0;i #include -#include "tool.h" + #define IFACE_VALUE_MAX 32 static struct wpa_ctrl *ctrl_conn; static struct wpa_ctrl *monitor_conn; pthread_mutex_t ctrl_mutex; + /* socket pair used to exit from a blocking read */ static int exit_sockets[2]; @@ -479,10 +480,12 @@ int wifi_start_supplicant(int p2p_supported) exit_sockets[0] = exit_sockets[1] = -1; /* start wpa_supplicant */ - strncpy(cmd, "/etc/wifi/wifi start", 511); + strncpy(cmd, "/etc/wifi/wifi restart", 511); cmd[511] = '\0'; system(cmd); + + return 0; } @@ -492,7 +495,7 @@ int wifi_stop_supplicant(int p2p_supported) return 0; } -#define SUPPLICANT_TIMEOUT 3000000 // microseconds +#define SUPPLICANT_TIMEOUT 4000000 // microseconds #define SUPPLICANT_TIMEOUT_STEP 100000 // microseconds int wifi_connect_on_socket_path(const char *path) { @@ -536,8 +539,7 @@ int wifi_connect_on_socket_path(const char *path) int wifi_connect_to_supplicant() { static char path[PATH_MAX]; - if(get_process_state("wpa_supplicant",14) == -1) - return -1; + strncpy(primary_iface, "wlan0", IFACE_VALUE_MAX); if (access(IFACE_DIR, F_OK) == 0) { snprintf(path, sizeof(path), "%s/%s", IFACE_DIR, primary_iface); @@ -558,11 +560,11 @@ int wifi_send_command(const char *cmd, char *reply, size_t *reply_len) ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), reply, reply_len, NULL); LOG_EX(LOG_Debug, "cmd is %s,size is %d,reply len %d\r\n",cmd,strlen(cmd),*reply_len); - + if (ret == -2) { LOG_EX(LOG_Debug, "'%s' command timed out.\n", cmd); /* unblocks the monitor receive socket for termination */ - TEMP_FAILURE_RETRY(write(exit_sockets[0], "T", 1)); + //TEMP_FAILURE_RETRY(write(exit_sockets[0], "T", 1)); return -2; } else if (ret < 0 || strncmp(reply, "FAIL", 4) == 0) { return -1; @@ -606,6 +608,7 @@ int wifi_wait_on_socket(char *buf, size_t buflen) char *match, *match2; if (monitor_conn == NULL) { + sleep(2); return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - connection closed"); } @@ -707,6 +710,25 @@ void wifi_close_supplicant_connection() } } +void wifi_restart_supplicant() +{ + int i; + int ret; + + wifi_event_loop_stop(); + wifi_close_supplicant_connection(); + wifi_start_supplicant(0); + do{ + usleep(300000); + ret = wifi_connect_to_supplicant(); + if(!ret){ + LOG_EX(LOG_Debug, "Connected to wpa_supplicant!\n"); + break; + } + i++; + }while(ret && i<10); + wifi_event_loop_restart(); +} void wifi_clear() { @@ -730,7 +752,11 @@ int wifi_command(char const *cmd, char *reply, size_t reply_len) if ((ret =wifi_send_command(cmd, reply, &reply_len)) != 0) { LOG_EX(LOG_Debug, "wifi_send_command ret is %d %s\r\n",ret, reply); - wifi_clear(); + if (-2 == ret) + wifi_restart_supplicant(); + else + wifi_clear(); + pthread_mutex_unlock(&ctrl_mutex); return -1; } diff --git a/package/allwinner/wifimanager/src/wifi_event.c b/package/allwinner/wifimanager/src/wifi_event.c index 42b26efe6..3400fa9c5 100755 --- a/package/allwinner/wifimanager/src/wifi_event.c +++ b/package/allwinner/wifimanager/src/wifi_event.c @@ -5,14 +5,14 @@ #include #include + #include "wifi.h" #include "wifi_event.h" #include "wifi_state_machine.h" #include "wifi_intf.h" #include "wpa_supplicant_conf.h" -//tWIFI_STATE gwifi_state; -tWIFI_STATE gwifi_state = WIFIMG_WIFI_DISABLED; +tWIFI_STATE gwifi_state; extern char netid_connecting[]; extern int connecting_ap_event_label; extern int disconnect_ap_event_label; @@ -22,8 +22,10 @@ tWifi_event_callback wifi_event_callback[MAX_CALLBCAKS_COUNT] = {NULL}; int wifi_event_callback_index = 0; static pthread_t event_thread_id; +static int event_thread_running; static int wifi_event_inner = AP_DISCONNECTED; static int scan_complete = 0; +static int wifi_off_flag = 0; static int assoc_reject_count = 0; static int authentication_fail_count = 0; @@ -32,7 +34,6 @@ static void handle_event(int event, char * remainder) { char cmd[255] = {0}, reply[16]={0}; int len = NET_ID_LEN+1; tWIFI_MACHINE_STATE state; - static int network_not_found_count = 0; switch (event){ case DISCONNECTED: @@ -60,7 +61,7 @@ static void handle_event(int event, char * remainder) { } } - assoc_reject_count = 0; + //assoc_reject_count = 0; set_wifi_machine_state(L2CONNECTED_STATE); /* start udhcpcd */ @@ -71,18 +72,8 @@ static void handle_event(int event, char * remainder) { scan_complete = 1; break; - case NETWORK_NOT_FOUND: - network_not_found_count++; - LOG_EX(LOG_Debug,"NETWORK NOT FOUND %d times!\n",network_not_found_count); - if(network_not_found_count >= 3){ - sprintf(cmd, "%s", "DISCONNECT"); - wifi_command(cmd, reply, sizeof(reply)); - set_wifi_machine_state(DISCONNECTED_STATE); - set_cur_wifi_event(CONNECT_AP_TIMEOUT); - } - break; case UNKNOWN: - //printf("unknown event!\n"); + //LOG_EX(LOG_Debug, "unknown event!\n"); break; } } @@ -90,8 +81,12 @@ static void handle_event(int event, char * remainder) { static int dispatch_event(const char *event_str, int nread) { int i = 0, event = 0; - char event_name[18]; + char event_name[32]; char cmd[255] = {0}, reply[16]={0}; + char network_id[NET_ID_LEN]={0}; + static char recent_network_id[NET_ID_LEN]={0}; + int network_id_tmp; + char buf_tmp[255]; char *name_start = NULL, *name_end = NULL; char *event_data = NULL; @@ -117,6 +112,11 @@ static int dispatch_event(const char *event_str, int nread) } } + if (!strncmp(event_str, "Selecting BSS network id ", 25)){ + sscanf(event_str, "Selecting BSS network id %d!!!!", &network_id_tmp); + sprintf(recent_network_id, "%d", network_id_tmp); + } + //LOG_EX(LOG_Debug, "EVENT, not care!\n"); return 0; } @@ -124,7 +124,7 @@ static int dispatch_event(const char *event_str, int nread) name_start = (char *)((unsigned long)event_str+11); name_end = strchr(name_start, ' '); if(name_end){ - while((name_start < name_end) && (i < 18)){ + while((name_start < name_end) && (i < 31)){ event_name[i] = *name_start++; i++; } @@ -153,10 +153,10 @@ static int dispatch_event(const char *event_str, int nread) event = DRIVER_STATE; }else if(!strcmp(event_name, "EAP-FAILURE")){ event = EAP_FAILURE; - }else if(!strcmp(event_name, "NETWORK-NOT-FOUND")){ - event = NETWORK_NOT_FOUND; }else if(!strcmp(event_name, "ASSOC-REJECT")){ event = ASSOC_REJECT; + }else if(!strcmp(event_name, "SSID-TEMP-DISABLED")){ + event = SSID_TEMP_DISABLED; }else{ event = UNKNOWN; } @@ -184,22 +184,40 @@ static int dispatch_event(const char *event_str, int nread) LOG_EX(LOG_Debug, "DRIVER_STATE, no care!\n"); return 0; }else if(event == TERMINATING){ - LOG_EX(LOG_Debug, "Wpa supplicant terminated!\n"); - gwifi_state = WIFIMG_WIFI_DISABLED; - call_event_callback_function(WIFIMG_WIFI_OFF_SUCCESS, NULL, 0); - return 1; + if (get_wifi_off_flag()) + { + /* If we turn off wifi, we should update wifimanager status. */ + LOG_EX(LOG_Debug, "Wpa supplicant terminated!\n"); + gwifi_state = WIFIMG_WIFI_DISABLED; + call_event_callback_function(WIFIMG_WIFI_OFF_SUCCESS, NULL, 0); + set_wifi_off_flag(0); + return 1; + } + else + { + /* If we just restart wpa_supplicant, do nothing. */ + return 0; + } }else if(event == EAP_FAILURE){ LOG_EX(LOG_Debug, "EAP FAILURE!\n"); return 0; }else if(event == ASSOC_REJECT){ assoc_reject_count++; if(assoc_reject_count >= MAX_ASSOC_REJECT_COUNT){ + wpa_conf_add_on_priority_list_hdr(recent_network_id); + LOG_EX(LOG_Debug, "Current ap's priority lowered!\n"); /* send disconnect */ sprintf(cmd, "%s", "DISCONNECT"); wifi_command(cmd, reply, sizeof(reply)); } LOG_EX(LOG_Debug, "ASSOC REJECT!\n"); return 0; + }else if(event == SSID_TEMP_DISABLED){ + sscanf(event_str, "CTRL-EVENT-SSID-TEMP-DISABLED id=%d %s", &network_id_tmp, buf_tmp); + sprintf(network_id, "%d", network_id_tmp); + wpa_conf_add_on_priority_list_hdr(network_id); + LOG_EX(LOG_Debug, "Current ap's priority lowered!\n"); + return 0; }else{ handle_event(event, event_data); } @@ -212,8 +230,8 @@ void *event_handle_thread(void* args) char buf[EVENT_BUF_SIZE] = {0}; int nread = 0, ret = 0; - for(;;){ - nread = wifi_wait_for_event(buf, sizeof(buf)); + while(event_thread_running){ + nread = wifi_wait_for_event(buf, sizeof(buf)); if (nread > 0) { ret = dispatch_event(buf, nread); if(ret == 1){ @@ -224,16 +242,43 @@ void *event_handle_thread(void* args) } } + LOG_EX(LOG_Debug, "Wifi event_handle_thread stopped!\n"); pthread_exit(NULL); } void wifi_event_loop(tWifi_event_callback pcb) { + pthread_attr_t attr; /* initial */ wifi_event_inner = AP_DISCONNECTED; - pthread_create(&event_thread_id, NULL, event_handle_thread, NULL); + + /* Set thread attribute PTHREAD_CREATE_DETACHED, otherwise the resources + will not be reclaimed after thread exit. */ + pthread_attr_init (&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + event_thread_running = 1; + pthread_create(&event_thread_id, &attr, event_handle_thread, NULL); } +void wifi_event_loop_stop() +{ + event_thread_running = 0; + usleep(200*1000); +} + +void wifi_event_loop_restart() +{ + pthread_attr_t attr; + + /* Set thread attribute PTHREAD_CREATE_DETACHED, otherwise the resources + will not be reclaimed after thread exit. */ + pthread_attr_init (&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + event_thread_running = 1; + pthread_create(&event_thread_id, &attr, event_handle_thread, NULL); +} + + tWIFI_EVENT_INNER get_cur_wifi_event() { return wifi_event_inner; @@ -286,7 +331,10 @@ void *check_connect_timeout(void *args) call_event_callback_function(WIFIMG_CONNECT_TIMEOUT, NULL, connecting_ap_event_label); } - pthread_exit(NULL); + /* resume scan thread */ + resume_wifi_scan_thread(); + + pthread_exit(NULL); } @@ -323,9 +371,9 @@ void *wifi_on_check_connect_timeout(void *args) event = get_cur_wifi_event(); i++; - } while((state != L2CONNECTED_STATE) && (state != CONNECTED_STATE) && (state != DISCONNECTED_STATE) && (i < 100)); + } while((state != L2CONNECTED_STATE) && (state != CONNECTED_STATE) && (i < 100)); - if((state != L2CONNECTED_STATE) && (state != CONNECTED_STATE) && (state != DISCONNECTED_STATE)){ + if((state != L2CONNECTED_STATE) && (state != CONNECTED_STATE)){ /* send disconnect */ sprintf(cmd, "%s", "DISCONNECT"); wifi_command(cmd, reply, sizeof(reply)); @@ -355,6 +403,17 @@ int get_scan_status() return scan_complete; } +void set_wifi_off_flag(int value) +{ + wifi_off_flag = value; +} + +int get_wifi_off_flag() +{ + return wifi_off_flag; +} + + void reset_assoc_reject_count() { assoc_reject_count = 0; diff --git a/package/allwinner/wifimanager/src/wifimanager.c b/package/allwinner/wifimanager/src/wifimanager.c index f9a92e0e7..b696030a1 100755 --- a/package/allwinner/wifimanager/src/wifimanager.c +++ b/package/allwinner/wifimanager/src/wifimanager.c @@ -2,6 +2,8 @@ #include #include #include +#include + #include "wifi.h" #include "wifi_event.h" @@ -9,9 +11,11 @@ #include "network_manager.h" #include "wpa_supplicant_conf.h" #include "wifi_intf.h" -//#include +#include #include + + #define ENCODE_STYLE_UTF_8 "UTF-8" #define ENCODE_STYLE_GB2312 "GB2312" #define WPA_SSID_LENTH 512 @@ -19,6 +23,7 @@ #define APP_ERR_NULL -1 #define APP_ERR_NOT_MATCH -2 #define APP_ERR_INVALID_PARAMS -3 + extern int is_ip_exist(); typedef enum @@ -26,63 +31,30 @@ typedef enum WIFI_SSID_UTF_8, WIFI_SSID_GBK, }wifi_ssid_encode_e; + char netid_connecting[NET_ID_LEN+1] = {0}; int disconnecting = 0; int connecting_ap_event_label = 0; int disconnect_ap_event_label = 0; -//tWIFI_STATE gwifi_state = WIFIMG_WIFI_DISABLED; -extern tWIFI_STATE gwifi_state; +tWIFI_STATE gwifi_state = WIFIMG_WIFI_DISABLED; static tWIFI_EVENT event_code = WIFIMG_NO_NETWORK_CONNECTING; static int aw_wifi_disconnect_ap(int event_label); -static char wpa_scan_ssid[WPA_SSID_LENTH]; -static char wpa_conf_ssid[WPA_SSID_LENTH]; -static int ssid_contain_chinese = 0; static int aw_wifi_add_event_callback(tWifi_event_callback pcb) { return add_wifi_event_callback_inner(pcb); } -/* -*get wifi connection state with AP -*return value: -*1: connected with AP(connected to network IPv4) -*2: connected with AP(connected to network IPv6) -*0: disconnected with AP -*/ static int aw_wifi_is_ap_connected(char *ssid, int *len) { - int ret = 0; - tWIFI_MACHINE_STATE wifi_machine_state; - if(gwifi_state == WIFIMG_WIFI_DISABLED){ return -1; } - wifi_machine_state = get_wifi_machine_state(); - if(wifi_machine_state != CONNECTED_STATE && wifi_machine_state != DISCONNECTED_STATE){ - LOG_EX(LOG_Debug, "%s: wifi_busing, please try again later!\n", __func__); - return -1; - } - - /* pase scan thread */ - pause_wifi_scan_thread(); - - if( 4 == wpa_conf_is_ap_connected(ssid, len)) - ret = 1; - else if( 6 == wpa_conf_is_ap_connected(ssid, len)) - ret = 2; - else - ret = 0; - - /* resume scan thread */ - resume_wifi_scan_thread(); - - return ret; + return wpa_conf_is_ap_connected(ssid, len); } - static int aw_wifi_scan(int event_label) { int ret = 0; @@ -115,13 +87,8 @@ static int aw_wifi_get_scan_results(char *result, int *len) return -1; } - if(get_scan_results_inner(result, len) != 0) - { - LOG_EX(LOG_Debug, "%s: There is a scan or scan_results error, Please try scan again later!\n", __func__); - return -1; - } - else - return 0; + get_scan_results_inner(result, len); + return 0; } /* check wpa/wpa2 passwd is right */ @@ -149,145 +116,17 @@ int check_wpa_passwd(const char *passwd) return result; } -/* convert app ssid which contain chinese in utf-8 to wpa scan ssid */ -static int ssid_app_to_wpa_scan(const char *app_ssid, char *scan_ssid) -{ - unsigned char h_val = 0, l_val = 0; - int i = 0; - int chinese_in = 0; - - if(!app_ssid || !app_ssid[0]) - { - LOG_EX(LOG_Debug, "Error: app ssid is NULL!\n"); - return -1; - } - - if(!scan_ssid) - { - LOG_EX(LOG_Debug, "Error: wpa ssid buf is NULL\n"); - return -1; - } - - i = 0; - while(app_ssid[i] != '\0') - { - /* ascii code */ - if((unsigned char)app_ssid[i] <= 0x7f) - { - *(scan_ssid++) = app_ssid[i++]; - } - else /* covert to wpa ssid for chinese code */ - { - *(scan_ssid++) = '\\'; - *(scan_ssid++) = 'x'; - h_val = (app_ssid[i] & 0xf0) >> 4; - if((h_val >= 0) && (h_val <= 9)){ - *(scan_ssid++) = h_val + '0'; - }else if((h_val >= 0x0a) && (h_val <= 0x0f)){ - *(scan_ssid++) = h_val + 'a' - 0xa; - } - - l_val = app_ssid[i] & 0x0f; - if((l_val >= 0) && (l_val <= 9)){ - *(scan_ssid++) = l_val + '0'; - }else if((l_val >= 0x0a) && (l_val <= 0x0f)){ - *(scan_ssid++) = l_val + 'a' - 0xa; - } - i++; - chinese_in = 1; - } - } - *scan_ssid = '\0'; - - if(chinese_in == 1){ - return 1; - } - - return 0; -} - -/* convert app ssid which contain chinese in utf-8 to wpa conf ssid */ -static int ssid_app_to_wpa_conf(const char *app_ssid, char *conf_ssid) -{ - unsigned char h_val = 0, l_val = 0; - int i = 0; - int chinese_in = 0; - - if(!app_ssid || !app_ssid[0]) - { - LOG_EX(LOG_Debug, "Error: app ssid is NULL!\n"); - return -1; - } - - if(!conf_ssid) - { - LOG_EX(LOG_Debug, "Error: wpa ssid buf is NULL\n"); - return -1; - } - - i = 0; - while(app_ssid[i] != '\0') - { - h_val = (app_ssid[i] & 0xf0) >> 4; - if((h_val >= 0) && (h_val <= 9)){ - *(conf_ssid++) = h_val + '0'; - }else if((h_val >= 0x0a) && (h_val <= 0x0f)){ - *(conf_ssid++) = h_val + 'a' - 0xa; - } - - l_val = app_ssid[i] & 0x0f; - if((l_val >= 0) && (l_val <= 9)){ - *(conf_ssid++) = l_val + '0'; - }else if((l_val >= 0x0a) && (l_val <= 0x0f)){ - *(conf_ssid++) = l_val + 'a' - 0xa; - } - i++; - } - *conf_ssid = '\0'; - - return 0; -} - -static int connect_command_handle(char *cmd,char *net_id) -{ - int ret; - char reply[REPLY_BUF_SIZE] = {0}; - ret = wifi_command(cmd, reply, sizeof(reply)); - if(ret){ - LOG_EX(LOG_Debug, "%s failed,Remove the information just connected!",cmd); - sprintf(cmd, "REMOVE_NETWORK %s", net_id); - wifi_command(cmd, reply, sizeof(reply)); - sprintf(cmd, "%s", "SAVE_CONFIG"); - wifi_command(cmd, reply, sizeof(reply)); - ret = -1; - }else{ - LOG_EX(LOG_Debug, "%s: %s",cmd,reply); - return 0; - } -} - -static void cancel_saved_conf_handle(char *net_id) -{ - char reply[REPLY_BUF_SIZE] = {0}; - - char cmd[CMD_LEN+1] = {0}; - sprintf(cmd, "REMOVE_NETWORK %s", net_id); - cmd[CMD_LEN] = '\0'; - wifi_command(cmd, reply, sizeof(reply)); - sprintf(cmd, "%s", "SAVE_CONFIG"); - wifi_command(cmd, reply, sizeof(reply)); -} /* connect visiable network */ static int aw_wifi_add_network(const char *ssid, tKEY_MGMT key_mgmt, const char *passwd, int event_label) { int i=0, ret = -1, len = 0, max_prio = -1; char cmd[CMD_LEN+1] = {0}; char reply[REPLY_BUF_SIZE] = {0}, netid1[NET_ID_LEN+1]={0}, netid2[NET_ID_LEN+1] = {0}; - int is_exist = 0; + int is_exist = 0; tWIFI_MACHINE_STATE wifi_machine_state; const char *p_ssid = NULL; - tWIFI_MACHINE_STATE state; - tWIFI_EVENT_INNER event; + tWIFI_MACHINE_STATE state; + tWIFI_EVENT_INNER event; if(gwifi_state == WIFIMG_WIFI_DISABLED){ return -1; @@ -319,28 +158,11 @@ static int aw_wifi_add_network(const char *ssid, tKEY_MGMT key_mgmt, const char /* remove disconnecting flag */ disconnecting = 0; - /* convert app ssid to wpa scan ssid */ - ret = ssid_app_to_wpa_scan(ssid, wpa_scan_ssid); - if(ret < 0){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - }else if(ret > 0){ - ssid_contain_chinese = 1; - }else { - ssid_contain_chinese = 0; - } - - /* has no chinese code */ - if(ssid_contain_chinese == 0){ - p_ssid = ssid; - }else{ - ssid_app_to_wpa_conf(ssid, wpa_conf_ssid); - p_ssid = wpa_conf_ssid; - } + p_ssid = ssid; + /* check already exist or connected */ - len = NET_ID_LEN+1; + len = 3; is_exist = wpa_conf_is_ap_exist(p_ssid, key_mgmt, netid1, &len); /* add network */ @@ -354,14 +176,17 @@ static int aw_wifi_add_network(const char *ssid, tKEY_MGMT key_mgmt, const char goto end; } - /* set network ssid */ - if(ssid_contain_chinese == 0){ - sprintf(cmd, "SET_NETWORK %s ssid \"%s\"", netid2, p_ssid); - }else{ - sprintf(cmd, "SET_NETWORK %s ssid %s", netid2, p_ssid); - } + sprintf(cmd, "SET_NETWORK %s ssid %s", netid2, p_ssid); - if(connect_command_handle(cmd,netid2)){ + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network ssid error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); ret = -1; event_code = WIFIMG_CMD_OR_PARAMS_ERROR; goto end; @@ -371,67 +196,124 @@ static int aw_wifi_add_network(const char *ssid, tKEY_MGMT key_mgmt, const char if (key_mgmt == WIFIMG_NONE){ /* set network no passwd */ sprintf(cmd, "SET_NETWORK %s key_mgmt NONE", netid2); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network key_mgmt error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; } } else if(key_mgmt == WIFIMG_WPA_PSK || key_mgmt == WIFIMG_WPA2_PSK){ /* set network psk passwd */ sprintf(cmd,"SET_NETWORK %s key_mgmt WPA-PSK", netid2); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network key_mgmt WPA-PSK error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } ret = check_wpa_passwd(passwd); if(ret == 0){ LOG_EX(LOG_Debug, "check wpa-psk passwd is error!\n"); - cancel_saved_conf_handle(netid2); + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + cmd[CMD_LEN] = '\0'; + wifi_command(cmd, reply, sizeof(reply)); + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); ret = -1; event_code = WIFIMG_CMD_OR_PARAMS_ERROR; goto end; } sprintf(cmd, "SET_NETWORK %s psk \"%s\"", netid2, passwd); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } - + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network psk error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } } else if(key_mgmt == WIFIMG_WEP){ /* set network key_mgmt none */ - sprintf(cmd, "SET_NETWORK %s key_mgmt NONE", netid2); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } - + sprintf(cmd, "SET_NETWORK %s key_mgmt NONE", netid2); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network key_mgmt none error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } /* set network wep_key0 */ - sprintf(cmd, "SET_NETWORK %s wep_key0 %s", netid2, passwd); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } - + sprintf(cmd, "SET_NETWORK %s wep_key0 %s", netid2, passwd); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + sprintf(cmd, "SET_NETWORK %s wep_key0 \"%s\"", netid2, passwd); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network wep_key0 error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } + } /* set network auth_alg */ - sprintf(cmd, "SET_NETWORK %s auth_alg OPEN SHARED", netid2); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + sprintf(cmd, "SET_NETWORK %s auth_alg OPEN SHARED", netid2); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network auth_alg error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } - } else { + } else { LOG_EX(LOG_Debug, "Error: key mgmt not support!\n"); /* cancel saved in wpa_supplicant.conf */ - cancel_saved_conf_handle(netid2); + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); ret = -1; event_code = WIFIMG_KEY_MGMT_NOT_SUPPORT; goto end; @@ -439,41 +321,67 @@ static int aw_wifi_add_network(const char *ssid, tKEY_MGMT key_mgmt, const char /* set scan_ssid to 1 for network */ sprintf(cmd,"SET_NETWORK %s scan_ssid 1", netid2); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set scan_ssid error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } - - /* get max priority in wpa_supplicant.conf */ + /* get max priority in wpa_supplicant.conf */ max_prio = wpa_conf_get_max_priority(); /* set priority for network */ sprintf(cmd,"SET_NETWORK %s priority %d", netid2, (max_prio+1)); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set priority error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + ret = -1; + goto end; + } /* select network */ sprintf(cmd, "SELECT_NETWORK %s", netid2); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } - + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do select network error!\n"); + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } /* save config */ - sprintf(cmd, "%s", "SAVE_CONFIG"); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } - + sprintf(cmd, "%s", "SAVE_CONFIG"); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do save config error!\n"); + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } /* save netid */ strcpy(netid_connecting, netid2); @@ -488,11 +396,10 @@ static int aw_wifi_add_network(const char *ssid, tKEY_MGMT key_mgmt, const char event = get_cur_wifi_event(); /* password incorrect*/ if ((state == DISCONNECTED_STATE) && (event == PASSWORD_INCORRECT)){ - LOG_EX(LOG_Debug, "wifi_connect_ap_inner: password failed!\n"); + LOG_EX(LOG_Debug, "wifi_connect_ap_inner: password failed!\n"); break; } - if(event == CONNECT_AP_TIMEOUT) - break; + if(get_assoc_reject_count() >= MAX_ASSOC_REJECT_COUNT){ reset_assoc_reject_count(); LOG_EX(LOG_Debug, "aw_wifi_add_network: assoc reject %d times\n", MAX_ASSOC_REJECT_COUNT); @@ -514,7 +421,13 @@ static int aw_wifi_add_network(const char *ssid, tKEY_MGMT key_mgmt, const char wifi_command(cmd, reply, sizeof(reply)); /* cancel saved in wpa_supplicant.conf */ - cancel_saved_conf_handle(netid2); + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + ret = -1; event_code = WIFIMG_NETWORK_NOT_EXIST; goto end; @@ -525,14 +438,20 @@ static int aw_wifi_add_network(const char *ssid, tKEY_MGMT key_mgmt, const char wifi_command(cmd, reply, sizeof(reply)); /* cancel saved in wpa_supplicant.conf */ - cancel_saved_conf_handle(netid2); + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); + ret = -1; event_code = WIFIMG_PASSWORD_FAILED; goto end; }else if(event == OBTAINING_IP_TIMEOUT){ if(is_exist == 1 || is_exist == 3){ - //network is exist or connected - sprintf(cmd, "REMOVE_NETWORK %s", netid1); + //network is exist or connected + sprintf(cmd, "REMOVE_NETWORK %s", netid1); cmd[CMD_LEN] = '\0'; wifi_command(cmd, reply, sizeof(reply)); } @@ -542,13 +461,12 @@ static int aw_wifi_add_network(const char *ssid, tKEY_MGMT key_mgmt, const char wifi_command(cmd, reply, sizeof(reply)); ret = 0; }else{ - event_code = WIFIMG_NETWORK_NOT_EXIST; - cancel_saved_conf_handle(netid2); + ; } }else if(state == L2CONNECTED_STATE || state == CONNECTED_STATE){ /* connect ap l2 */ if(is_exist == 1 || is_exist == 3){ - //network is exist or connected - sprintf(cmd, "REMOVE_NETWORK %s", netid1); + //network is exist or connected + sprintf(cmd, "REMOVE_NETWORK %s", netid1); cmd[CMD_LEN] = '\0'; wifi_command(cmd, reply, sizeof(reply)); } @@ -603,24 +521,36 @@ static int aw_wifi_reconfig(void) static int wifi_connect_ap_inner(const char *ssid, tKEY_MGMT key_mgmt, const char *passwd, int event_label) { int i=0, ret = -1, len = 0, max_prio = -1; - char cmd[CMD_LEN+1] = {0}; - char reply[REPLY_BUF_SIZE] = {0}, netid1[NET_ID_LEN+1]={0}, netid2[NET_ID_LEN+1] = {0}; + int status =0; + char cmd[CMD_LEN+1] = {0}; + char reply[REPLY_BUF_SIZE] = {0}, netid1[NET_ID_LEN+1]={0}, netid2[NET_ID_LEN+1] = {0}; int is_exist = 0; tWIFI_MACHINE_STATE state; - tWIFI_EVENT_INNER event; + tWIFI_EVENT_INNER event; + char * pSsidSearch = NULL; - /* connecting */ - set_wifi_machine_state(CONNECTING_STATE); + /* connecting */ + set_wifi_machine_state(CONNECTING_STATE); - /* set connecting event label */ - connecting_ap_event_label = event_label; + /* set connecting event label */ + connecting_ap_event_label = event_label; - /* remove disconnecting flag */ - disconnecting = 0; + /* remove disconnecting flag */ + disconnecting = 0; - /* check already exist or connected */ - len = NET_ID_LEN+1; - is_exist = wpa_conf_is_ap_exist(ssid, key_mgmt, netid1, &len); + /* check already exist or connected */ + len = NET_ID_LEN+1; + status = utf8BytesExchangeEx(ssid,&pSsidSearch); + if(0 != status) + { + LOG_EX(LOG_Debug, "utf8 exchange err\r\n"); + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } + + LOG_EX(LOG_Debug, "changed ssid is %s\r\n",pSsidSearch); + is_exist = wpa_conf_is_ap_exist(pSsidSearch, key_mgmt, netid1, &len); + LOG_EX(LOG_Debug, "is_exist %d\n", is_exist); /* add network */ strncpy(cmd, "ADD_NETWORK", CMD_LEN); @@ -634,37 +564,51 @@ static int wifi_connect_ap_inner(const char *ssid, tKEY_MGMT key_mgmt, const cha } /* set network ssid */ - if(ssid_contain_chinese == 0){ - sprintf(cmd, "SET_NETWORK %s ssid \"%s\"", netid2, ssid); - }else{ - sprintf(cmd, "SET_NETWORK %s ssid %s", netid2, ssid); + sprintf(cmd, "SET_NETWORK %s ssid \"%s\"", netid2, ssid); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network ssid error!\n"); + + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; } - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } - - /* no passwd */ if (key_mgmt == WIFIMG_NONE){ /* set network no passwd */ sprintf(cmd, "SET_NETWORK %s key_mgmt NONE", netid2); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network key_mgmt error!\n"); + + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + ret = -1; + goto end; + } } else if(key_mgmt == WIFIMG_WPA_PSK || key_mgmt == WIFIMG_WPA2_PSK){ /* set network psk passwd */ sprintf(cmd,"SET_NETWORK %s key_mgmt WPA-PSK", netid2); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network key_mgmt WPA-PSK error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } ret = check_wpa_passwd(passwd); if(ret == 0){ @@ -680,38 +624,68 @@ static int wifi_connect_ap_inner(const char *ssid, tKEY_MGMT key_mgmt, const cha } sprintf(cmd, "SET_NETWORK %s psk \"%s\"", netid2, passwd); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network psk error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } } else if(key_mgmt == WIFIMG_WEP){ /* set network key_mgmt none */ - sprintf(cmd, "SET_NETWORK %s key_mgmt NONE", netid2); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + sprintf(cmd, "SET_NETWORK %s key_mgmt NONE", netid2); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network key_mgmt none error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } /* set network wep_key0 */ - sprintf(cmd, "SET_NETWORK %s wep_key0 %s", netid2, passwd); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + sprintf(cmd, "SET_NETWORK %s wep_key0 %s", netid2, passwd); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + sprintf(cmd, "SET_NETWORK %s wep_key0 \"%s\"", netid2, passwd); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network wep_key0 error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } + } /* set network auth_alg */ - sprintf(cmd, "SET_NETWORK %s auth_alg OPEN SHARED", netid2); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + sprintf(cmd, "SET_NETWORK %s auth_alg OPEN SHARED", netid2); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set network auth_alg error!\n"); + + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + ret = -1; + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; + } + } else { LOG_EX(LOG_Debug, "Error: key mgmt is not support!\n"); @@ -725,38 +699,65 @@ static int wifi_connect_ap_inner(const char *ssid, tKEY_MGMT key_mgmt, const cha } /* get max priority in wpa_supplicant.conf */ - max_prio = wpa_conf_get_max_priority(); - - /* set priority for network */ - sprintf(cmd,"SET_NETWORK %s priority %d", netid2, (max_prio+1)); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; + // max_prio = wpa_conf_get_max_priority(); + // status = wpa_conf_standardize_priority(); + + status =wpa_conf_refresh_list(50); + if(status) + { + LOG_EX(LOG_Debug, "+++++wpa reset priority err:%d\r\n",status); } + /* set priority for network */ + //sprintf(cmd,"SET_NETWORK %s priority %d", netid2, (max_prio+1)); + sprintf(cmd,"SET_NETWORK %s priority %s", netid2, netid2); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do set priority error!\n"); + + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + ret = -1; + goto end; + } /* select network */ sprintf(cmd, "SELECT_NETWORK %s", netid2); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Debug, "do select network error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + ret = -1; + goto end; + } /* save netid */ strcpy(netid_connecting, netid2); + + pause_wifi_scan_thread(); /* reconnect */ sprintf(cmd, "%s", "RECONNECT"); ret = wifi_command(cmd, reply, sizeof(reply)); - if(connect_command_handle(cmd,netid2)){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - } + if(ret){ + LOG_EX(LOG_Debug, "do reconnect network error!\n"); + /* cancel saved in wpa_supplicant.conf */ + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + + event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + ret = -1; + goto end; + } reset_assoc_reject_count(); @@ -772,6 +773,7 @@ static int wifi_connect_ap_inner(const char *ssid, tKEY_MGMT key_mgmt, const cha LOG_EX(LOG_Debug, "wifi_connect_ap_inner: password failed!\n"); break; } + if(get_assoc_reject_count() >= MAX_ASSOC_REJECT_COUNT){ reset_assoc_reject_count(); LOG_EX(LOG_Debug, "wifi_connect_ap_inner: assoc reject %d times\n", MAX_ASSOC_REJECT_COUNT); @@ -793,8 +795,12 @@ static int wifi_connect_ap_inner(const char *ssid, tKEY_MGMT key_mgmt, const cha wifi_command(cmd, reply, sizeof(reply)); /* cancel saved in wpa_supplicant.conf */ - cancel_saved_conf_handle(netid2); + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); ret = -1; LOG_EX(LOG_Debug, "connect ap inner:still connecting!\n"); @@ -807,8 +813,12 @@ static int wifi_connect_ap_inner(const char *ssid, tKEY_MGMT key_mgmt, const cha wifi_command(cmd, reply, sizeof(reply)); /* cancel saved in wpa_supplicant.conf */ - cancel_saved_conf_handle(netid2); + sprintf(cmd, "REMOVE_NETWORK %s", netid2); + wifi_command(cmd, reply, sizeof(reply)); + /* save config */ + sprintf(cmd, "%s", "SAVE_CONFIG"); + wifi_command(cmd, reply, sizeof(reply)); ret = -1; event_code = WIFIMG_PASSWORD_FAILED; @@ -816,8 +826,8 @@ static int wifi_connect_ap_inner(const char *ssid, tKEY_MGMT key_mgmt, const cha goto end; }else if(event == OBTAINING_IP_TIMEOUT){ if(is_exist == 1 || is_exist == 3){ - //network is exist or connected - sprintf(cmd, "REMOVE_NETWORK %s", netid1); + //network is exist or connected + sprintf(cmd, "REMOVE_NETWORK %s", netid1); cmd[CMD_LEN] = '\0'; wifi_command(cmd, reply, sizeof(reply)); } @@ -850,6 +860,11 @@ static int wifi_connect_ap_inner(const char *ssid, tKEY_MGMT key_mgmt, const cha } end: + free(pSsidSearch); + pSsidSearch = NULL; + + resume_wifi_scan_thread(); + //enable all networks in wpa_supplicant.conf wpa_conf_enable_all_networks(); @@ -887,34 +902,14 @@ static int aw_wifi_connect_ap_key_mgmt(const char *ssid, tKEY_MGMT key_mgmt, con goto end; } - /* convert app ssid to wpa scan ssid */ - ret = ssid_app_to_wpa_scan(ssid, wpa_scan_ssid); - if(ret < 0){ - ret = -1; - event_code = WIFIMG_CMD_OR_PARAMS_ERROR; - goto end; - }else if(ret > 0){ - ssid_contain_chinese = 1; - }else { - ssid_contain_chinese = 0; - } - - /* has no chinese code */ - if(ssid_contain_chinese == 0){ - p_ssid = ssid; - }else{ - ssid_app_to_wpa_conf(ssid, wpa_conf_ssid); - p_ssid = wpa_conf_ssid; - } - /* checking network exist at first time */ - get_key_mgmt(wpa_scan_ssid, key); + get_key_mgmt(ssid, key); /* no password */ - if (key_mgmt == WIFIMG_NONE){ + if (key_mgmt == WIFIMG_NONE){ if(key[0] == 0){ update_scan_results(); - get_key_mgmt(wpa_scan_ssid, key); + get_key_mgmt(ssid, key); if(key[0] == 0){ ret = -1; event_code = WIFIMG_NETWORK_NOT_EXIST; @@ -924,7 +919,8 @@ static int aw_wifi_connect_ap_key_mgmt(const char *ssid, tKEY_MGMT key_mgmt, con }else if(key_mgmt == WIFIMG_WPA_PSK || key_mgmt == WIFIMG_WPA2_PSK){ if(key[1] == 0){ update_scan_results(); - get_key_mgmt(wpa_scan_ssid, key); + get_key_mgmt(ssid, key); + if(key[1] == 0){ ret = -1; event_code = WIFIMG_NETWORK_NOT_EXIST; @@ -934,7 +930,7 @@ static int aw_wifi_connect_ap_key_mgmt(const char *ssid, tKEY_MGMT key_mgmt, con }else if(key_mgmt == WIFIMG_WEP){ if(key[2] == 0){ update_scan_results(); - get_key_mgmt(wpa_scan_ssid, key); + get_key_mgmt(ssid, key); if(key[2] == 0){ ret = -1; event_code = WIFIMG_NETWORK_NOT_EXIST; @@ -950,7 +946,13 @@ static int aw_wifi_connect_ap_key_mgmt(const char *ssid, tKEY_MGMT key_mgmt, con /* pause scan thread */ pause_wifi_scan_thread(); - ret = wifi_connect_ap_inner(p_ssid, key_mgmt, passwd, event_label); + /* ensure wifi disconnect */ + state = get_wifi_machine_state(); + if(state == CONNECTED_STATE){ + aw_wifi_disconnect_ap(0x7fffffff); + } + + ret = wifi_connect_ap_inner(ssid, key_mgmt, passwd, event_label); end: if(ret != 0){ @@ -964,60 +966,261 @@ end: } +static int encode_transfor(const char * from_style,const char * to_style,char *in_buf,int in_size,char * out_buf,int * out_size) +{ + int res =0; + iconv_t cid = 0; + size_t encodeSize =0; + char **pin = &in_buf; + char **pout = &out_buf; + + if(NULL == in_buf || NULL == out_buf) return -1; + + memset(out_buf,0x00,*out_size); + + cid = iconv_open(to_style,from_style); + + if(-1 == cid) + { + perror("iconv_open"); + return -1; + } + + encodeSize = iconv(cid, pin, &in_size, pout, out_size); + if(-1 == encodeSize) + { + res = -1; + } + + iconv_close(cid ); + + return 0; + +} +static int buffer_compare(char* buf1,char *buf2,int size,bool isStr) +{ + int i=0; + + if(NULL == buf1 || NULL == buf2) return APP_ERR_NULL; + if(isStr) + { + if(size > strlen(buf1) || size > strlen(buf2) ) + return APP_ERR_INVALID_PARAMS; + } + + for(i=0;i 0){ - ssid_contain_chinese = 1; - }else { - ssid_contain_chinese = 0; - } + memset(key,0x00,4*sizeof(int)); + + p_ssid = ssid; - /* has no chinese code */ - if(ssid_contain_chinese == 0){ - p_ssid = ssid; - }else{ - ssid_app_to_wpa_conf(ssid, wpa_conf_ssid); - p_ssid = wpa_conf_ssid; - } + /* checking network exist at first time */ + get_key_mgmt(p_ssid, key); - /* checking network exist at first time */ - get_key_mgmt(p_ssid, key); - - /* no password */ - if(!passwd || !passwd[0]){ + /* no password */ + if(!passwd || !passwd[0]){ if(key[0] == 0){ update_scan_results(); get_key_mgmt(p_ssid, key); @@ -1031,11 +1234,20 @@ static int aw_wifi_connect_ap(const char *ssid, const char *passwd, int event_la /* pase scan thread */ pause_wifi_scan_thread(); - ret = wifi_connect_ap_inner(p_ssid, WIFIMG_NONE, passwd, event_label); - }else{ + /* ensure disconnected */ + state = get_wifi_machine_state(); + if (state == CONNECTED_STATE){ + aw_wifi_disconnect_ap(0x7fffffff); + } + + ret = wifi_connect_ap_inner(p_ssid, WIFIMG_NONE, passwd, event_label); + }else{ + + if((key[1] == 0) && (key[2] == 0)){ update_scan_results(); - get_key_mgmt(wpa_scan_ssid, key); + get_key_mgmt(p_ssid, key); + if((key[1] == 0) && (key[2] == 0)){ ret = -1; event_code = WIFIMG_NETWORK_NOT_EXIST; @@ -1043,24 +1255,25 @@ static int aw_wifi_connect_ap(const char *ssid, const char *passwd, int event_la } } + /* pause scan thread */ pause_wifi_scan_thread(); /* wpa-psk */ if(key[1] == 1){ /* try WPA-PSK */ - ret = wifi_connect_ap_inner(p_ssid, WIFIMG_WPA_PSK, passwd, event_label); + ret = wifi_connect_ap_inner(p_ssid, WIFIMG_WPA_PSK, passwd, event_label); if(ret == 0){ goto end; } } - /* wep */ - if(key[2] == 1){ - /* try WEP */ - ret = wifi_connect_ap_inner(p_ssid, WIFIMG_WEP, passwd, event_label); - } - } + /* wep */ + if(key[2] == 1){ + /* try WEP */ + ret = wifi_connect_ap_inner(p_ssid, WIFIMG_WEP, passwd, event_label); + } + } end: if(ret != 0){ @@ -1217,7 +1430,6 @@ static int aw_wifi_remove_network(char *ssid, tKEY_MGMT key_mgmt) char cmd[CMD_LEN+1] = {0}; char reply[REPLY_BUF_SIZE] = {0}; char net_id[NET_ID_LEN+1] = {0}; - tWIFI_MACHINE_STATE wifi_machine_state; if(gwifi_state == WIFIMG_WIFI_DISABLED){ return -1; @@ -1228,12 +1440,6 @@ static int aw_wifi_remove_network(char *ssid, tKEY_MGMT key_mgmt) return -1; } - wifi_machine_state = get_wifi_machine_state(); - if(wifi_machine_state != CONNECTED_STATE && wifi_machine_state != DISCONNECTED_STATE){ - wmg_printf(MSG_INFO,"%s: wifi_busing, please try again later!\n", __func__); - return -1; - } - /* pause scan thread */ pause_wifi_scan_thread(); @@ -1274,25 +1480,14 @@ static int aw_wifi_remove_network(char *ssid, tKEY_MGMT key_mgmt) static int aw_wifi_remove_all_networks() { - int ret = -1; - tWIFI_MACHINE_STATE wifi_machine_state; - if(gwifi_state == WIFIMG_WIFI_DISABLED){ return -1; } - wifi_machine_state = get_wifi_machine_state(); - if(wifi_machine_state != CONNECTED_STATE && wifi_machine_state != DISCONNECTED_STATE){ - wmg_printf(MSG_ERROR,"%s: wifi_busing, please try again later!\n", __func__); - return -1; - } - - pause_wifi_scan_thread(); - ret = wpa_conf_remove_all_networks(); - resume_wifi_scan_thread(); - return ret; + wpa_conf_remove_all_networks(); } + static int aw_wifi_enble_all_network() { if(gwifi_state == WIFIMG_WIFI_DISABLED){ @@ -1304,7 +1499,7 @@ static int aw_wifi_enble_all_network() static int aw_wifi_connect_ap_auto(int event_label) { - int i=0, ret = -1, len = 0; + int i=0, ret =0, len = 0; char cmd[CMD_LEN+1] = {0}, reply[REPLY_BUF_SIZE] = {0}; char netid[NET_ID_LEN+1]={0}; tWIFI_MACHINE_STATE wifi_machine_state; @@ -1313,9 +1508,12 @@ static int aw_wifi_connect_ap_auto(int event_label) return -1; } + wpa_conf_enable_all_networks(); + /* pase scan thread */ pause_wifi_scan_thread(); + wifi_machine_state = get_wifi_machine_state(); if(wifi_machine_state == CONNECTED_STATE){ ret = -1; @@ -1343,13 +1541,17 @@ static int aw_wifi_connect_ap_auto(int event_label) disconnecting = 0; connecting_ap_event_label = event_label; + + pause_wifi_scan_thread(); + /* reconnected */ sprintf(cmd, "%s", "RECONNECT"); ret = wifi_command(cmd, reply, sizeof(reply)); if(ret){ - wmg_printf(MSG_ERROR,"do reconnect error!\n"); + LOG_EX(LOG_Debug, "do reconnect error!\n"); ret = -1; event_code = WIFIMG_CMD_OR_PARAMS_ERROR; + goto end; } /* check timeout */ @@ -1360,8 +1562,10 @@ end: call_event_callback_function(event_code, NULL, event_label); } + + /* resume scan thread */ - resume_wifi_scan_thread(); + if(0 != ret)resume_wifi_scan_thread(); return ret; } @@ -1585,46 +1789,28 @@ end: *Ap with certain key_mgmt exists in the .conf file:return is 0, get the *net_id as expectation; *else:return -1 */ -static int aw_wifi_get_netid(const char *ssid, tKEY_MGMT key_mgmt, char *net_id, int *length) +static int aw_wifi_get_netid(const char *ssid, tKEY_MGMT key_mgmt, char *net_id) { - int ret = -1, len = NET_ID_LEN+1; - - if(*length > (NET_ID_LEN+1)) - len = NET_ID_LEN+1; - else - len = *length; + int ret = -1, len = 3; /* pause scan thread */ pause_wifi_scan_thread(); ret = wpa_conf_is_ap_exist(ssid, key_mgmt, net_id, &len); /* resume scan thread */ - resume_wifi_scan_thread(); + resume_wifi_scan_thread(); if(ret == 1 || ret == 3){ - *length = len; return 0; }else{ return -1; } } -static int aw_wifi_stop_scan() -{ - shutdown_wifi_scan_thread(); - return 0; -} - -static int aw_wifi_restart_scan() -{ - restart_wifi_scan_thread(); - return 0; -} - static const aw_wifi_interface_t aw_wifi_interface = { aw_wifi_add_event_callback, aw_wifi_is_ap_connected, aw_wifi_scan, aw_wifi_get_scan_results, - aw_wifi_connect_ap, + aw_wifi_connect_ap_ex, aw_wifi_connect_ap_key_mgmt, aw_wifi_connect_ap_auto, aw_wifi_connect_ap_with_netid, @@ -1637,15 +1823,13 @@ static const aw_wifi_interface_t aw_wifi_interface = { aw_wifi_get_netid, aw_wifi_change_ap, aw_wifi_enble_all_network, - aw_wifi_stop_scan, - aw_wifi_restart_scan }; const aw_wifi_interface_t * aw_wifi_on(tWifi_event_callback pcb, int event_label) { - int i = 0, ret = -1, connected = 0, len = 64; - char ssid[64]; - struct wpa_status * sta; + int i = 0, ret = -1, connected = 0, len = 3; + char netid[4]; + if(gwifi_state != WIFIMG_WIFI_DISABLED){ return NULL; } @@ -1666,7 +1850,6 @@ const aw_wifi_interface_t * aw_wifi_on(tWifi_event_callback pcb, int event_label if(ret < 0){ if(pcb != NULL){ pcb(WIFIMG_WIFI_ON_FAILED, NULL, event_label); - LOG_EX(LOG_Debug, "connect wpa_supplicant failed,please check wifi driver!\n"); } return NULL; } @@ -1680,29 +1863,37 @@ const aw_wifi_interface_t * aw_wifi_on(tWifi_event_callback pcb, int event_label aw_wifi_add_event_callback(pcb); wifi_event_loop(NULL); - sta = get_wpa_status(); + /* check has network info in wpa_supplicant.conf */ - if(sta->wpa_state >= WPA_SCANNING){ + if(wpa_conf_network_info_exist() == 1){ set_wifi_machine_state(CONNECTING_STATE); /* wpa_supplicant already run by other process and connected an ap */ - connected = wpa_conf_is_ap_connected(ssid, &len); - if(connected >= 4){ + connected = wpa_conf_is_ap_connected(netid, &len); + if(connected == 1){ set_wifi_machine_state(CONNECTED_STATE); - set_cur_wifi_event(AP_CONNECTED); - call_event_callback_function(WIFIMG_NETWORK_CONNECTED, NULL, event_label); + set_cur_wifi_event(AP_CONNECTED); ret = 0; }else{ - connecting_ap_event_label = event_label; - start_wifi_on_check_connect_timeout(); + //connecting_ap_event_label = event_label; + //start_wifi_on_check_connect_timeout(); + set_wifi_machine_state(DISCONNECTED_STATE); + set_cur_wifi_event(AP_DISCONNECTED); + ret = 0; } }else{ set_wifi_machine_state(DISCONNECTED_STATE); event_code = WIFIMG_NO_NETWORK_CONNECTING; ret = -1; } + + stop_connecting(); start_wifi_scan_thread(NULL); + start_broadlink_thread(NULL); + + usleep(300*1000); + if(ret != 0){ call_event_callback_function(event_code, NULL, event_label); } @@ -1715,29 +1906,27 @@ int aw_wifi_off(const aw_wifi_interface_t *p_wifi_interface) const aw_wifi_interface_t *p_aw_wifi_intf = &aw_wifi_interface; if(p_aw_wifi_intf != p_wifi_interface){ - call_event_callback_function(WIFIMG_WIFI_OFF_FAILED, NULL, 0); + call_event_callback_function(WIFIMG_WIFI_OFF_FAILED, NULL, 0); return -1; } if(gwifi_state == WIFIMG_WIFI_DISABLED){ return 0; } - wpa_status_free(); - stop_wifi_scan_thread(); + + stop_wifi_scan_thread(); wifi_close_supplicant_connection(); wifi_stop_supplicant(0); - system("/etc/wifi/udhcpc_wlan0 stop"); - while(gwifi_state != WIFIMG_WIFI_DISABLED) - usleep(200*1000); reset_wifi_event_callback(); gwifi_state = WIFIMG_WIFI_DISABLED; + set_wifi_off_flag(1); return 0; } int aw_wifi_get_wifi_state() { int ret = -1, len = 0; - char ssid[64] = {0}; + char netid[4] = {0}; tWIFI_MACHINE_STATE machine_state; int tmp_state; @@ -1751,9 +1940,9 @@ int aw_wifi_get_wifi_state() } /* sync wifi state by wpa_supplicant */ - len = sizeof(ssid); - ret = wpa_conf_is_ap_connected(ssid, &len); - if(ret >= 4){ + len = 3; + ret = aw_wifi_is_ap_connected(netid, &len); + if(ret == 1){ tmp_state = WIFIMG_WIFI_CONNECTED; }else{ tmp_state = WIFIMG_WIFI_DISCONNECTED; diff --git a/package/allwinner/wifimanager/src/wpa_supplicant_conf.c b/package/allwinner/wifimanager/src/wpa_supplicant_conf.c index 4a0fba88b..e7233a4d6 100755 --- a/package/allwinner/wifimanager/src/wpa_supplicant_conf.c +++ b/package/allwinner/wifimanager/src/wpa_supplicant_conf.c @@ -9,6 +9,9 @@ #define WPA_DIASBLE_NETWORK_CMD "DISABLE_NETWORK" #define WPA_INTERNET_RECONNECT_SAVE 1 +static const char SUPP_CONFIG_FILE[] = "/mnt/UDISK/wifi/wpa_supplicant.conf"; + + extern int is_ip_exist(); int wpa_conf_network_info_exist() @@ -62,7 +65,8 @@ int wpa_conf_is_ap_exist(const char *ssid, tKEY_MGMT key_mgmt, char *net_id, int return -1; } - //LOG_EX(LOG_Debug, "List network:%s\r\n",reply) + LOG_EX(LOG_Debug, "List network:%s\r\n",reply); + LOG_EX(LOG_Debug, "Ssid:%s\r\n",ssid); ptr = reply; while((pssid_start=strstr(ptr, ssid)) != NULL){ @@ -186,11 +190,11 @@ int wpa_conf_ssid2netid(char *ssid, tKEY_MGMT key_mgmt, char *net_id, int *len) p_t = strchr(p_s, '\t'); if(p_t){ - int tmp = 0; + int tmp = 0; tmp = p_t - p_s; if(tmp <= NET_ID_LEN){ - strncpy(net_id, p_s, tmp); - net_id[tmp] = '\0'; + strncpy(net_id, p_s, tmp); + net_id[tmp] = '\0'; } } @@ -550,9 +554,7 @@ int wpa_conf_is_ap_connected(char *ssid, int *len) int ret = -1; char cmd[CMD_LEN+1] = {0}; char reply[REPLY_BUF_SIZE] = {0}; - char *p_c=NULL, *p_str = NULL; - char *p_s=NULL, *p_e=NULL, *p=NULL; - int is_ap_connected = 0; + char *p_c=NULL; strncpy(cmd, "LIST_NETWORKS", CMD_LEN); cmd[CMD_LEN] = '\0'; @@ -564,21 +566,15 @@ int wpa_conf_is_ap_connected(char *ssid, int *len) } LOG_EX(LOG_Debug, "----list network:%s\r\n",reply); - p_str = (char *)reply; - while((p_c=strstr(p_str, "[CURRENT]")) != NULL){ - - if(*(p_c + 9) != '\n' && *(p_c + 9) != '\0') - { - p_str = p_c+9; - continue; - } + if ((p_c=strstr(reply, "CURRENT")) != NULL){ + char *p_s=NULL, *p_e=NULL, *p=NULL; p_e = strchr(p_c, '\n'); if(p_e){ *p_e = '\0'; } - p_s = strrchr(p_str, '\n'); + p_s = strrchr(reply, '\n'); p_s++; p = strtok(p_s, "\t"); p = strtok(NULL, "\t"); @@ -587,19 +583,18 @@ int wpa_conf_is_ap_connected(char *ssid, int *len) strncpy(ssid, p, *len-1); ssid[*len-1] = '\0'; *len = strlen(ssid); - is_ap_connected = 1; - break; } } - } + /* check ip exist */ + ret = is_ip_exist(); + if(ret > 0){ + return 1; + } - /* check ip exist */ - ret = is_ip_exist(); - if(ret > 0 && is_ap_connected == 1){ - return ret; - }else{ - return is_ap_connected; + return 0; + } else { + return 0; } } @@ -663,6 +658,7 @@ int wpa_conf_get_ap_connected(char *netid, int *len) LOG_EX(LOG_Debug, "do list networks error!\n"); return -1; } + LOG_EX(LOG_Debug, "%s\n", reply); if ((p_c=strstr(reply, "CURRENT")) != NULL){ char *p_s=NULL, *p_e=NULL, *p=NULL; @@ -689,6 +685,104 @@ int wpa_conf_get_ap_connected(char *netid, int *len) } +int wpa_conf_get_apinfo_connected(char *key_mgmt, int *priority) +{ + int ret = 0; + char cmd[CMD_LEN+1] = {0}; + char reply[REPLY_BUF_SIZE] = {0}; + char netid[NET_ID_LEN+1] = {0}; + int len = NET_ID_LEN+1; + + if (netid == NULL || key_mgmt == NULL || priority == NULL) + return -1; + + if (1 != wpa_conf_get_ap_connected(netid, &len)) + return -1; + + /* Get key_mgmt */ + sprintf(cmd, "GET_NETWORK %s key_mgmt", netid); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Error, "Get network key_mgmt error!\n"); + return -1; + } + strcpy(key_mgmt, reply); + LOG_EX(LOG_Debug, "Get network key_mgmt %s\n", key_mgmt); + + /* Get priority */ + sprintf(cmd, "GET_NETWORK %s priority", netid); + ret = wifi_command(cmd, reply, sizeof(reply)); + if(ret){ + LOG_EX(LOG_Error, "Get network priority error!\n"); + return -1; + } + *priority = atoi(reply); + LOG_EX(LOG_Debug, "Get network priority %d\n", *priority); + + return 0; +} + +int wpa_conf_get_appwd_connected(int priority, char *pwd) +{ + int ret = 0; + int i; + FILE *fp = NULL; + char line[128] = {0}; + char *p_tmp = NULL; + int prio_tmp = 0; + char pwd_tmp[128] = {0}; + + if (pwd == NULL) + return -1; + + fp = fopen(SUPP_CONFIG_FILE, "r"); + if (!fp) { + LOG_EX(LOG_Debug, "Failed to fopen file: %s\n", SUPP_CONFIG_FILE); + return -1; + } + + while (fgets(line, sizeof(line), fp) != NULL) + { + if (!strncmp(line, "network={", 9)) + { + /* If priority does not exist, default to 0. */ + prio_tmp = 0; + while (fgets(line, sizeof(line), fp) != NULL + && strncmp(line, "}", 1)) + { + if ((p_tmp = strstr(line, "priority=")) != NULL) + { + p_tmp += 9; + sscanf(p_tmp, "%d\n", &prio_tmp); + } + if ((p_tmp = strstr(line, "psk=\"")) != NULL) + { + p_tmp += 5; + strncpy(pwd_tmp, p_tmp, strlen(p_tmp)); + } + } + if (prio_tmp == priority) + { + i=0; + while(pwd_tmp[i+1] != '\n') + { + pwd[i] = pwd_tmp[i]; + i++; + } + pwd[i] = '\0'; + LOG_EX(LOG_Debug, "Get network(priority %d) password succeed %s\n", priority, pwd); + fclose(fp); + return 0; + } + } + } + + LOG_EX(LOG_Debug, "Get network(priority %d) password failed!\n", priority); + fclose(fp); + return -1; +} + + int wpa_conf_enable_all_networks() { int ret = -1, len = 0; diff --git a/package/allwinner/wifimanager/udhcpc_wlan0.init b/package/allwinner/wifimanager/udhcpc_wlan0.init index ef308373c..fa56663a9 100755 --- a/package/allwinner/wifimanager/udhcpc_wlan0.init +++ b/package/allwinner/wifimanager/udhcpc_wlan0.init @@ -16,8 +16,8 @@ start_service() { then procd_set_param command $PROG -i wlan0 -h When_you_like_AW -S -T 1 else -# host_name=`cat /mnt/UDISK/bt/bt_config.xml | grep local` - procd_set_param command $PROG -i wlan0 -h "SING-PV2" -S -T 1 + host_name=`cat /mnt/UDISK/bt/bt_config.xml | grep local` + procd_set_param command $PROG -i wlan0 -h "SING-${host_name:32:4}" -S -T 1 fi procd_close_instance } diff --git a/package/firmware/ap6236/fw_bcm43436b0.bin b/package/firmware/ap6236/fw_bcm43436b0.bin index e8f122a38e8ebea4a6e88cb1d415f2a36dc68091..40cffe0acf31f378ef93fcb3431bd5a9ae4cf48a 100755 GIT binary patch delta 122650 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 delta 125282 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

&ooP z1rOn(l9V54(=ezx){~e)_0?gk(rhZcDvoJjdUGMHJFCY=9p{3@(>UBo!pecH4TfWWhfak~ zJJSEeu$OnT<7Gg5p3t~;NttrN*GCQlTxvVeI!1aS)Xl~-th_}NaY(o6)ZTWPQadl@&uUEs) z+dF#0IX&9N(zLfoe78k*QLDPr$*Fo@L71*^N7mAfZ;{>!!|f(Kp7#hUeTTCn)w^xP z_^9j;WBZWmj!0b@-w-tiz>gt_m{z<+V#Sm9sqSquBK=;45krT|E#AN(g};F}fgJ&! zC}P)Q{;QYPDH}860Y5;%D_t}hP|gIaI-l@_g6BG1kB!x~(9Lg?P`?4n|33T)^vv5N zDCDPyf<2HiwuiD;vG3wB97sl|P1UsFZ89+6uNuB&O>B{Uz0w<&*xqb)B^|bbj0k=n z-U2)wLC$fFkplq{fB*=F+wz7+x^)9SPV0yC3;YH)S8!r>*y3>Rdhjw-#U`Mo_F&7~ z=)Dct={7)xxsjOEF)Y89nm3Yg|00=h0-6JEMI16i+}59Y(APGS_>dQ>R>S7SRXE>0 z=;Hdsk(~;H7D{ll=fh_A4&YAuRVz^E@5s zd$HSoU{lV93&tzA^{R~=d6Q*s2^J&KVWKqILOCfZ05 zNhHUiL`TWKGg9$G`$S=_$;1L*Ysa@My{^9LkOv{cia56Fo4 zrvYFITPRzJ6~KogxPbN(SnR{H4lgc&&4Lkgr)gTYn#r{G1L(gaPSN`xkdVkrNDr!y zhb;#ZOC)}K0^9*=dt)M7QI*=TK*KQ?-Pos@SSNvviFot~Yrd$HEI6LB!aqVE$re*I{E=)vvI)j?6r)676 zQ1Drx*6cJzNz=03SdH>}9k=kN;1=&xQMHvEOZRHy=PkBrzugL zH&eN!$V(jU`qOrPJOn*)%9wmV4iuPY1!gG;%(rO!Rx*3)pJ1wa2x_6Ba6=NSeORj4 z&~w911Mta=TaF|F$hEW0jEy}v?)tm-JIuRtmiKq$9N&U`v!zPjM2!XDJ=OH&R%q7t zRM1;n!NNp+lye4H{Jy@&b@6J<{#2F91>)q3C$w#+aPHD-o{%tY6+kFby(LZQ5L+T5 z%4zC0lG^oE=ShbaBDj0;5V&yNk{3AX_HE>1ppNw@f8xK$i7R}bA>sjS5I)PeEx*u2 zmu)Aep@B6K|K<6eI~M{4!l|3|sI;ZrjS)A2sRZ*aw>|?hb&s`NUry_`lYoE~<+?(C zt%#I=#L(442fZlOQHZFs%V{M4om@`SDG3R^S$)>EotYa-^Mt7L{J)W334CEzSxwhc zVouT_A%`h5PC8x}W+{MfX+wqf;mB-u)6vc`UPKmSZmC}{5QC0IRnTVKB^R-Bkvs;b zW1tZ6hU;t;5axX<+%aRm#8-gd4uIcLFAaQ)G~B6-_y2UoQr8n1geS7FQ4em{L%J=m zXn3N|lsOtqhObdwd`s?Va{JJ00E|Qs8@UiWu9QQo-;(8~unj=q_5?&zmr^&@Uc+xc zuFj3M)X;wwkb(L{mQ?Nnmc+zJ+JH?d<47X2S5o*ZnmoqrR0)&uH+?5f z*a1^ONTpU{wqKRJ58NDqx)ey5iL7fS;9^`y-eBc-ApKnu%P63`0N9XQ*_5HE-vA|J z-(qV_WJR^GSPbT0uunPIv^;fKxWNMCx&)w&4u!srKM*YotbPqkD}hC0aUvt-0}*a8 z32cfz55@pa8@%iu#%Enrf}2`_EacbWyw);r4BQ(s64`5Za06-IDjVV_&?gE>P;Mfd z0o51p_^qnFN-)`{6l=QU@?%Om9z#{_dDn3cj(@HF%5}U1$EEOZ2sEf2heR=q4>f_g z*NBM04nf^#VrPv|vrS{V?Yud`%@8^%cLumskC36C@!Qx5x~vjgZ%Lg5IG z_tw(-Lb7|{sJ1z)R7PP7z=RMY1>X;Jt~MkfbpA68B9S$fPiVByF$))zSaLxz#lzaj zCfMoOA`)y0fKRa?h-N|1m|f{pU1;QqKwB=gbxt)Jbd-bhtQY=rHn&jSP7)gMm-CO3 z93W2dymX~X{=`J~c_kf+GvY@zbjD6%@%Rh@>-<4w*3e5kL6t|;(g*y!`Xd_hA=K-8 z%IUxlN%%nXeLg}1W+fQn*-Tuu6KGyDv$-Qkg3C1o=)BG;9YWaeFZFWKt9X_U-TQ}R zaKy_{E%k#K<2y;{7X|*YlS4{Gz4sxu%*bl$wTpznlP78y6rW#ph#Vxw zh+HkkUyfj}mhL(a!&DH@BEcB!1O?pjP9pqQI*-e7++41QUGji$Jo~V^v$pWv$%aI5 zYP>YjQ1LFG2xs`>;fBQjzX7}pH5MATcnNrqDc}mwKVSzEfj@%o64@0yhqHIFY34+B zxj@Ac+XbF{4ZGOAT_i#*s;1pPBGHk5lqXw4bA`B!(%+z(1XP$a6Pv6MITG`}VEPR_ z)AY^5*pfds!q%c9h9=uz;uj-&(>=l%SslMz@Ad<1(Lh6frM2kfr4tkYU?II zKHZexbkOa)$j+Dj$=LRRlR40|0xbwR&3dk6~KB|3ngS=XE_Mv z9uLc&&QP-AZ2o-M6NI#i+%Mf1d!3TA(nXX zcmeDic!K;3A4hU69q}(>)Zdat$5Fxa>P7uM@HZC}K=Vev0qAr9DlfSwuVyswUnB$% zSL0H|PjmCSa$IR3y`cI2>Ii@AqHQP^*UwNKJX7Wn6W~mqg;4_qa)1Fuwk{J|nNsyE z{(Ab?(rf?1GILZ?k3A$d_mqtI|r`m^RR9J>U>c*5Ov7g>*^<_>Ko+} z>SFOVt#V5NJpM&x7|P)f%ate(Mp<8aF$^g>Oc&va%$4T@*mykh2fY%yxUhIQ`;>sE zcnRVrx6LXO5}ElUTDlhm&asi++Dn2%dI8(J!#NCcT!G0=>Z$R#Y62g54JjxrRaE~8 zi5q6D<^r%+x!S0MKy_1I|2L1r-PCW&tDHiAbD4jUe~h_2UJ5`OotyF!czh>G8 zpODZoZQvj*(A9H)s*gMJkPMk0Cowmm*BR;_*dms-T83J7Sn{#f7FTvbZgLJ%eM?@) zfZmh0J4EY3Y`ZBZJ88owL<;EPECHA0R!)jx5=U_BP1(mu$L+(09Li?fY0f?n)CCoE z^F9*pGaI6JCK8ZdpB2xhRnhbNNVXVKLu3CJU2(+)wmfZ^IRdV<2`C;BoBpLONzYTv(JEdK%|54R~u4p@S5R=H?6jinFqvZ&OK3 zt}#F>8zmwA1ojMsGu9D9i_-(g#L()zqI3mk$AR`Mt>x6H;T{?1kuCRq;Ek zsnlbmKH9JBs4_#ZizcPM(NSeVT)WlP!z>=PD$nA>2{;$57xcbou9cvbuPzF$q5}SI zwG!^R&+3s9z<=qHLy+-P8fo1j5;^f$ zV{ulNq{pJ%BMW+WAgTgrKTIuo?hqCdYd1Wee(+XCzG^IA4FHsG0=X`@pLbcLvs!ozxi@=o|B5or4>|2YT~zGG1Ma`&%>wRoHFIXXeqj)@%yIO2 zB;sD!iD|z9Se@M^KWV%1qwJe1Felt7E2?7l*`v65o_r zgAh5PEPI6zJq~W1WWS0HXr;41BhgOX_)dSwDvPFya!!GoQ?Lh zXz}#ayOROa2-T;s<*<)bp{Vo5S-2Oe=SF?ZA}IA|x#*?=!Jl;QW>OQl=n2gNCof`B%km) zZ>w*S_kNx6a4#P#veY*q_#?jSeh#<4As)+MxZ0=zME^~BsOyYd)3>ie)w&InF`1-L z(aO`*0MJr3h-ZA!ccy9R%JnG7QA641L_e_yQhBR}soP)#I>22I~HW^5tc_p0CeB;vc|2q$y9MJ=uem(#Z z^@!;%s-ew?NnH12X2yuP^?yy?^kVO($|XbLpGk+>NJ3nq3oUf8{vDUc{3|8Lu;y>c zQybur3DWo;>2M}?{O8COu@5s5d)KV~&u1xoZ?}tVNw8K%+JeK`K#Qz9$yP zT!#wW0YB>1pfXNJmpA3WhH53?yvjIB(mA~Fu6!Fb`?0C-PRAtIBdM3SW1y%h9?Ft% z>~%m>oXj>>d+jLB_G4zkVQKF=qgu`=15I{~*Hz9bg|Ojv-(1!KHIk;782IHwS@&8r z@%3YXM}*2JT_YG$d4dh-*AWS^R0BTr#iXF6$kw2q!nT0(jG8xx-2$7Lh2KB9v?~o^ zakYHl+Z-gaCv3wv<$QE#meN z_V04K@F*FVGz__Su7CkjvyAc!%Fdh%%2xapiv0BYWl#jwLkI)xn3WzO@g!*zo zIlXt3gp3ZZ)|CiFV6EZq&VxJ&hP0W%^6xqtBF}nMKuzP)5RSFXN{C?*_GAFeI}u)R}BrNY^}@udn&0 zTzG_MtG{qSCA{&WO86K4j^mGv4SE{7#&bGPHI4(HeRM32tv8CTf{B+0yQ^I?k2l(I zFjz0C0D6FKcv5$$>Ns5Yy%7SHZ|iMSSz9UpEL<$ZtLPxXS1)`Ddu{a%M6fkKvc0#a`~~ zqOg;hzN8DL6pgbvj89ku-5t#)+PHCChv_3O{MK<299sB=N_gw(b?8sX_LgqQPd2F~ zu30e~>*Y;OYW#vkj*A3mG#Gc_dK4FjF<}HdPz3fKH6z$3l|SLVk3cepLl%ybt9EDr zC0j3-H%~&zjH4^?kcUneJ)UZ&+rNNU)UjrI2|ed}BQ#a(7(+&|85L?pn|D2kr?XqH zkh~FaMOZv99o&Cd)hqLe6ucr`5|Mg3I4c!?F3+=AyP$WC<^2;N?far~Ai{g|jmVyt z-PLweKG{s_Zps@QWBYjm8!{new}nf|!EAgD=i)eT4_=PGa)R_p_`TBQ4FmcAVvZk} zSA-E2*UPERYRG!=82<2P&O~x=8P3Mm%LAI}_b1@u1+R|g6XZSd&33x}BpD_SZ>C?J zBn4hyK#RnMj4%e>z}yn@mFU()qrW8Mrlr83aa9=yXPuD3C)tfkVCsi>I|c~#av9>4 zUrf>!?^y25-clezc8vt0OL1*S7=d%Kt{9{opO!Zp7e6%b+gUH-DupS~oM zeKt0#>+*Dh;EOS8n`qoAP`Hiv>9kYiK#%+7@C!}y?)N*grtuIho=g)T3Jp35(0E?RBQv2C-)CYm|6@wf8% zls@beXd+Tzm6%k1RO@xMGh`~&wE_5Jv;M*rh0`0JS2-FTt{(zHd}u8_e3k?Tu0s}p z+Y8c=A^G-8A1YcG_J1&2R!Qs5k`ZJs?R}1P8!WqAHhME_#bVVzL+aap1knKSOkpYZ zqw2o6ZA5xuc2HKm><4enznp*Gr}NK|@M%+EOXI?U2^oAi|D+qlneAZYOB3Q$P{^!u z14@XU2|ThO1kR{7(%EY*6fqMA%-9%R0(5X8fckVO;GHSbZVbhdmnWoO8K;2ZaI0T)ln63`TIZ;xG@rL}sNrzp4jIpwU zK6?SvEUB3D?w)lYZ^B;C^xHv*&#hHt&^4Od}FsB9}%LXBrHh zqW}fVRfz)RO819tI-H*%RI{^9JY>!UxRUZ*54`n?%AAsUug|gV-;|j}n*I+f;MYp1 z-f<5unbx-~#63EkZ?+4OVHss1pv$9JW+ivaikH0bH6|dh`^1ueECz`~Scb~@QP>UEJk&wY63U&NPKQbP+bLXl8hNl#vc2~A?(+3BAb$yWjW zE4vr1k>DFzw`k7ibD(6w_Crs9NAyX*0ut=7ONl12gH_zgCk1BF=V8O;YA+#dD3nt+ z1S;-X;^sh>ACxXtQ{V4l&3vYkKL0&Q7wf8M@%QkC2&tx*z9-AnqgjWYN?kjM+2q$1=c3($Omno%s>Bjrj z%HVtnIUDGUmq@hN5m+0lmDoIqt*fPlmq^ICboL}TM2Xea@{~k^aWoQT6)Gcr$G~Bg z*YB-O#+ESBm)rIv_F*m0lTc!Un@-<3bJi;scn-x&?%=S~*}+;W{zxWb+ye^e)F0uY zeWr?T|BoJ^RZ6|am! zaw0nZC)ieK6(qC)>!iI(!i$_@MnTi|>4UFfGr++63*!T4M+p9U2V#nZ%@S3ggkgXa>3@%~WW+25NFhG3@Yh(-gdem*~X79SPK zhnj@`^%IGTzENH5(qO3IN%{gzN}9SKET@p4n`>a4&ZbtCOOx>eQv1==pNYxxWi?;h zLl8DRv-*)U)SqR$Eq9$8?;jb}qm&qTXHRI%n?#r=Obqcbjh=tdSp%+{5!CVFeeN2b z1P4NHf|A%gkcc4G9ox)ul7jNTt7yf~pqKva#ADk@05W`0-%_$(KM3t5mxbozdHl7W zs^+h-0I$*?^6q}+YH|O0!Zk8L z#9}LIw*mM+MS2U~z+qV&11Rr<(eU;)p(k4vDKbeHlfS#Ia{vCeyT>Gee2hjg@>5uu z6b~g8Z5CA#c!C}?X|Q^i!$X>nU`l1rx`TB3WimjN5W8}jyePg7(fBf)9)7K$PhSBW z@EHONt{~9+IeO{}LQd1lY4BAN-LG1m6#LOz;}}CI8sV)Td*9Llp{VSfE{n?WEDw% ziJ}v3$Uiw%NMRsYZ^+*{>8@W%_mM+fh_@dPVRJMquBPMc zpgx6>L?2fH;UGoeS{B4nGK{>FhETuh=1tTX*pV$sHfOBrO<<47Q*`gAZ~r*Q z>@1X-wK#Mz6g;_`* zDPpHkTUAAHFtNJrN5*Vp7JI8EY~?wzXUQJmSBI@CLJoy+6L&y)3Tf`M*bB(a5N;Yf zO8X11gJ)e`F!E?*v8QS@a75G|gl~T#fp?c%Q3iVnlDt&aQmaD=*D)of+Xe^IWCQrF3G)yGz}9nkoJ)Gni5y z0j|Y>#-EqdFDgi=6jZ}!ZCo|ORj(=(i_+P5;HbG!kpZ9}EducP?4S<7xeU1MKROoy zT?WrCmCgoK(cnt5bVdg93UxZ$Xp1%bXGp4|EF>K;y{p}?IgkaG(d~2fXZ#v%p{7Wn zWP1jC*WTHlN11oFpIfah!p>~f6k!Bbw?Z}UDOJ$=N@5zH!NTqHvLoMp*Vg$qORDB& z_j~v2;7`S)txfHNv9}}NduwQ77L%$~bwjY`vzV&d12h0+&DEb+s6v0q_A~VzYp7C* zz3gu7<2|l*_1N?Or$=YiqaLfO{=Yq{T|Ht2ruj%)lpNC*Ws$GevhlF!SS+O7A_jLb z*j^C%g~)``wB?>LvE^THQ1b*8vts(%^Py$s_(Q6Lzrl2QmnXDZ?hRYNkLZ=WM!M;& zXmyiz!%Y)57?KY8J_dEKKCnRj&D--U@5&P!N*zRiACO+G6ZFVnEV=XdzYb1YSE`7y z&lgxp+@$4(CClAoq5mnG2wPNlB*t{x0e^$|vFr}*S&bm2;gwXXCgG9e?{jmdmp}w9 z^yPxZ9oZ}5*(Y|lhq`h#WRX8*txUI6gY#L7*nw);?PIGct0uwSzp8=fXO41)yO|Le zXEByd-9_~^B+y4&Jw#fAcV&WUGp&Y7HBeFH*SKNOowivsU?)1S8_y!DgF%_?rXoN^ zaGKhSWgudxa$Yia4!fymF0Vzpb+!w91j?^JDklN8%c_hvJypUvJrCmq=!yB-1CNt7 zfzA35zw62%{E`^AvNX#N^llAVAg*qt&(uw>>BA7%qoOB z&pu?huJoAVGhn(~<5d+L$^<}SZ2z4EYED5r^YdI9`a7}om)iDNW*7?Qk8aLg;?ABx zDd+FfV3d|TEb)=Kv;Oq>@4y@hq`&`8!qm5%>lEs7olGO8bk21$HcZnJS+WPwAeVdt zE$(ba`&Rgatb>qZ7x>f>;t%a?*>%##eS^Y{9_|QC=s+=dF^X7(ETDZ4Xt-|)2W;pH zt^H+)fgWr&&LX!Ab8F9&CZd0MXrp&8w2g8dY1_;2)-MTpHh0#meGO>82TNDhjMA0< zGnS?{p407;iThk$Mjx)e^F3G+`cBV9=fA<|dr7eT-F-FY-r2n!M=7|`_c!=W+}X!% zTnsz`Kh3QzJ^b9+eP~0x9X;S*s|Ul)t)zWB%pg(jY!807wp{P(&X#s?Ud$b-6t^l3 zzH_2PkVAL&23$hjSwVX)|Jl*Lh~*M)o^)sX+B=Rw$x+$gv4{Yslv`W34Pn}Rzl+uKyBl@^wySO zKlfbb*P*K0+R_uV(Zecv2^q}X*$X)8d~qIZCT^;dxEu8);bV)Cud`qPdYt!lXaDJV z^h!ql{ml3};?K;T4Q=B$7t8eXZ^B~e3Q~MO*QFT@m7?rHkkhB21)TPYe`&=lodH#0=((`;~ec; zPe!;`ws$VA)pUA2>Fs$MBk5c)uhDh&VA9ri&@byjgI0FX`g%B(kEPx>5#zhFiRRoS z?~VH%--e98oa6aQhuOs0{fy0D`UYrgL%Y9(YxNLG|6e;HEPhC64;#hV*-)TfuyH)}YYwcVJrFCevki$o%my zwr&PRNX*&8^$5@dz5x;Grt?Lt)ia1bx#@he?IKX#yZld^d9F5-+eo2a`rt@cuba+M zXn)f=wT+tYl5zc?Q3#gEqY-^||M3x>Lg{};ltvHUC9e`6YPd%Z`n--P7-SAX6pX-L zt)vzA$ZRb;p%OGKlBWGdHU(a;;8w{Yr5xFD#F9VcISo4fP3PNqD}Rw#45d&R3`zK= zGhd;4Mh^S!!uKv13+BTh4e>|Etn|MOG4}tZZVqA~|E7H%(j%h(?#jhudT8OtQ_rh6~aPp!`*!rDH$ouj=!f<@$ zYn3qUd${f?;p73%pFXV;-or0vv%5=q@TYLg@`rQYght1#dM6Kpz%vf(EZuH9j=-P^ zjk&2Efyp9-JF~gr?Zx%ZTGZFL>YD=-QEzTYNbxtH(ZWBt-dT2rj%y>vXV0N4ov~Fg zH~;Kc?>yNi^M=ir{qU*GRy8h9t9O3Z7NdGpmp56}n1i~#xGK;%;nqbJZ(Hx&i84RR zL|ukImmBJxTh7q$+eqa2H`@51%nkQbCN$=t&s<#pO6PqVY^cjbpZq>q=%WjmCv(HF zN%hXzZ4+*#!|#!oCNwg%S&cT&v{7?Aq_i<@bVfULP045I@^&&fDYOmaT_W`Jdgv`_ zZXSYB`GXM6oL8xKzxujs1pIEolFpvo+UWIm_y^p?rjlp;otPV1@Kmm$v`3uKxP2BR zsoC|;3Y0lkzPVvI#&j7ao$+^}vvldvx#mN-*EcAcn^*Yp)|@)lJ5Qg^IquD!68ivc z1M~7hFXM2J!w=@+4#E=t#0K}orNyALGv`&PHBf-_TkDPUNWJsJ2lQA6(GPu(cib>E z#cbR|Iy+u>8keW~9`{Gq^bct&rd7=ZH8wZD>emfGk3=;A>#yF~ z_rbQ^V)xvhr#&(L+*ETzE0z33hhztINV8SZjL?hi+5KSf6n5vKIkgYaigyQPWX-gHNgbar=&f6*H{oZq{Ac=+6au5(Th zNQRHG-ucz3?cdYwM2yVc-ujAb!4KgJ{^8Piua&=ie`sd#g7ALUw;uevO&%8TDlEj6 zt;FbR;d-U7;BMxICsT+q5yPI}Dn54ZrHAK4<2<3>`Fv|%FvMJu*WoNar{uzsY70Jl zuM2$p>u&h;r^eGck8k74rR*E{<^R_5!s zFUoupI6FJ$;kxW~N(kfM2d~SmcXr2Yh1sAQ4`=Js+S}+VH7vydw3ugSi4RBMZ6|k@ zpTtX3?*CKfOPisbm)d#WhH^bW@9LWmx!zd^EnTM~lfRGt=W=MWO6-w)={{fL<5I-G zzn!nY%sE4he2J?uEdG6ciA&F8+=npk9L)3x%9uyPUObsRJedQJ4TTTkW6#4mef0~j}3HOE=KyUtD^Ib@|mrJwGZ}Ukozm`d^NZ_a;=7Cyye3(Co&8F zDZ6eo_pz?|K%PhW@#j1BVVS=If7dREmoN_EhZ<&E{{F|7{qx4~#xd^B_n(&^&BR#&<6+40BDDfGq?P7u665DH6Tu?Z6}$y^g7mic99jH)_Sl)9`-Mi-nP_D+j; z-K-KdzH4(sImSC5W)Xg*!;-CczT_$m0{t~(aGjmcED_Enol^@b1tN1;m1VpT&Y;p;(A@L9_NCm|{!=O{u5);dyX!M$xpeDJZ zF%f$b)0@PGV1cC>lbid%BJ;46eLrWO#pM3J?;k8@X3n(poH=vm%$XT*0=hthxg>Ey ztvl{E4*2Tf>z;6eCmiSr$H*?Xk)d(5?|b3n%9x;gF?vni3v#~YpZT)h45dR3{JAUv}@IF{^1P5!8w!(!wClrZiLs!3)H)I^vNMY{VvPiJ zFFBD|W1i+K4P0{+-qW9TwOnyq>TiXbvLdb3;(|LZE8(=I{$^mM`^ZJ%`_YXOUf(q6M*`SzyO%u?TQnsGo%AyLr0+)+uV9`$Q=5M{MXj zN2i|zn%$9H##_RTUomk5epP#r|#xKFjyH)(Gk}>wb5T%bRaKNH!QPo1K zDSd-!pxLdK)`^lrMM!I%HmgM;(sT(u6=^?Uwei@zBJXyWsT>_EAMs~eO!vNcwfMY+ z1|ik=OlY+@+~PmyAHf4q^6BWbTfE@%mYLS4hoNV??=@mF3fvAXOYLOL)`o~`+*cWA zYIeR`e+=`orG6<2^=dhH#2pz}NZ}U{Zfxdi8`gdL2)KX3J<6P1w?4gE*icHGq-3?Y z1JyOj)8PuhlL1qgZURmPOx-8~Of;QEvwt!M!D;?@5DV{q%I&uc3=AZGIUfwhR)+^a2%U~}9&vMrmc zOmdqtl4@@nTSR;dG;tWMTNau!0&w#{Qf(Q~yYOvoSufVz%|C0)2H4w6^uK`K)T|HJ zH+nGx$pQFPW%$4t^pOQeIWld^Yz)*}&=&V8`v8$z%oGP8yc=wttC%;SKY;ovvjP1G zXuGlx&^Lf~C=Nhh09vM)H&%;NfOaXf0ex-a+#VAi4CIMi#Y zzZz-=NC0`8@hnzI1^2)Hlqfuy;o zTAW9yHCH%+Q!PG2xDV3&k#<eI?*Xz=!ZPmNx#e z0cQYNvY1 zKZ?A+F$zjla-EinKBFI_fggqRb3}s~)naI42nOjcg@)+hMjEiaB-|f(y*$*70K5zS zHu|($ExMhABYnG!b-2RtsPPWpLel) z@EMmo4DEnAOKE41)Q44zPhFoKF5?}`2WzG|@t zu^TWQFIL9svGzN6M&OGedLuNbCCU^TT@B6BWPMSY0V&{ak1v8ywDo0tczhAS3njB; zrB;iV5n2S|7*eUL>V#^s;Dq7qajRVbckehs45ZEw# zw_>jr52J|Pl2+AXx`c694g57(!aBE(moQ1_YB5H_x)@B5FmY~HQniS^7b1xsg-{l9 z><0h!cJ0PDm3U}$kH7Kk2zHX6fOMqMDOBw|Mw0gL1-w2XkAbr5m0{@9^965w+C}S! zW>$+2K+5-(BjD420ot$B0@?*=j}iyw;(&H5ivYa?C|5ZG=nX*Gu-iq0d5Qts$ADuf za0!9YAY>NwU%kQ~aV2HQu^=2_CQdt#^d7k1fGBVVa3FmGd~FCMgxcH-9sZxR1OJn@ z4mSJgo5 z*~~&A{qr0=&R29|Poe|Mv>AxKgKxh?dk|0*zVi#(BY@@tnybwObP&)p+S7ywC{0Tt zJjkraG&=Y@7tq7n6NCpSMVm!%G3Fmq<^md|Jw=Fs`fI7molVq@-Wp%unGFf47XH9XRv;s4s|C~ePn}s$do9ck z$;#X}s>FZXQE$OZO{o&M5jRaah`4e!ht^t~&%ms7_&_v}RpkDz^ zQtkjEGlo@}`&O0s8c?`$5YRb5qm(;O{9VeP$w5+=uaZ?&A@R z#;+0Mcb76W)7x4FW%+$26Q<)T@sxYNayZLQ;4JqZMU{~cxpylu*%UY3ovUO@Xo{Pe z4`=TJUBeLn399TT8<#n|N_>b=oD3Nd+IugQh0qR!-p6tz8o9Q(^?|Vxd|M?pp+rgp zY!~Y&DTxYS3DVmUqH(fEA}&P{337U=!a@Levq|Dm5%b&@6p?peFq=dLrThjy@q%{xLKBfcSC;emcZlrb zA<>u6*!5YyN}QssXnkLacC3YFY?}Y8#J`cFmnR3*_loXCaMzdp9-;LS&V8?noqV-NH6HcI0leHQJwXrb&4()2Lmd`A6!m z*X^%$pHwa8YuzVBf=4Ni#7dV*wzSsJlUiO{m(otadQ|K953E!z>>pTDw2(>q^2w@Y z9kGnQ<7@o{MFdUKiyWmzE{2EwS;GrHhF`Y&7^>I$7;5nUmzR7DFXL|q{#L)?V>p5T zA1vZ;c4wycAuX@;benUJ(A=4nUL`uU@N?Z+*Y^G(k)<{Totv6u`9NSp&Emm0iC!G|KZ?!qCSom{4?` zq#bf+&9>CWru$@6iC3`^Of88`CyuHTFUG@KpXFKM#iEkuQ5fyfyyteCXGzp3#LjLu zfD0`36OC1(q6zoVv&n4OX`a=SO|*w1M|6;-{*zF$K2(VSSp`Z>qPQwyY^L|y_NFz9 zJWP>$=NxTRotFCiP`Js1cvYgNi5f_ye*`0(yhjJ*sXFyE1RSegaW$-#!C0=jz${p4%8Yf+<#GyvcOju-WZ{$`J8`SwugMY#M z+T+s`PA9;yei+-%J{e8o7JuD@2M}-a&rR$R<9;5jz;fz1xG2L(u$f`iaVG#0=Lg(WPX;++pYt9wwNa^(s}pPwrF+4ET_rxp)@K}!4R*0r z2+<@xfC}}kV0D6z`obBgr||!BC$@VO1l$ix0{B4|mL}NFjttKR!i+74( z3#P|l%@JnJx<{HruKy*CNmj0trmHj_|C2OZDTX-JLz+!4oiu;SQvOMrM(Aj*q`6D* z|B&X-0^Ykfn~s_3OBgHnttSFO9s_o)CjwQ8&j6b@5P_=1VZgHi)2BN~_<&yo{666W zo`SsZ63#{0h?bZ0#%814Oqova|aZng?yD*S+Kni>wp$L zj@FX$UnL#^L@Iw3^jBTwuM*P$k;-2sCIVWf%mv;!K+BbbfW`nCt;|L0eSr2W2LTNM z^n!8+5UJUNm8gwXA_`DHWiFsTfZ~*cfJ}f^+Lb#1y8(Pvi9(i6fTCVcP^v^|Ll)GN zxvyj3BQ9Gx2*?l6808Ki256uXwW&%pLjmjpMX^d~fch#20XYHnf~pAJ3eXDW4x0MA z7KJtRt0=hwaXvMX#%8gtnYZuDI)qQa#@9E8jUW4FzzB0h%=xI`WBRfuJI=r9 zg^T-rGxi_e-Y|W-xApn_Cb6F9_hn(;Rib?Z|E@1P(YZgaZ>w)crKoiq>e43s z8}8vdvq<$P_9EuU&_c||?xrQTUQJ`EeGjouYCI;Ab?A;y2UBoXDq-B)j;$RI46DY| zfDu(CMrdBLyyUvK5Ff974qUnh&MkhFbKHVNgSnFIU++dT6BwkU_VODrWi7TFOxBT> z$4*W%vSIv()Z~;44k76fJIAJ6UQMBvy(nc*>N*6TwIQ1UovJ>xd+e zG`iseY=H|f@gl9&Dn*5xl^PX#vz&6$rczoGEg#jyN-uHcEVuM$EB!kyGHhuUMvZ^d zpKWTBwD2qK)N~U>^LhS66dU*O?Vs>!)X#DP8JBz5_;39ro(CMgbVSBgU|e0wxYwP!<#YBicxish2V`O^Mb zDHbC{c1b@;hxrJ_DJ!v!KhdjFM77NG3zjXM_m4Ve$y%Qe9cvCp3um-+lb(#bFm-;U zPoLvx=lC^PXez}Q&1j2VTG}hcNd%ULlD1SSjy2QP5In9Vmo{NAS?U*}(Jd%4>VKLW zf$He|ShM)OLAU*q0k%?f{)bVwQiM>WJVxD05zyk(r`7H}IdNvCF#b=nt2tS16F@h< zH9CFq;-RH}Nob{*-@Mw7T`s6G2Gr7wgQiwO2_ajs*9Cnwd%2KQSz1F;1FkmnF#}mt z>ZE3$ov`y_bA;rOMl=ULY8j4ubpE3Xs2JFW5&D7~ivA3BN z;nuIa1MiCrWaCYPFq_nc60!bj3aQJ&c(c^Lg6)e?9gV|GfmZ@Yg>*JG> z-Xv6x=dLoKR=g0yUc29{1?<4mv+egsny@hSCphr?BW|(L^8skwREp|G|J=lS9NG0L zY1_?6?Wfr57(tV8@G6myjAhT0b@gB@>pC&w2yX8_hHK(t;4-ac87^w3luEIx!5A4= zNEf!PRgHc<@=43^Rul2D@C{K=qo{Pp^(B`r7}0_M9~TdbV|_#az#ypN524I`qfmIPiiKzq#neL6^5D9AoZ=@IIH148Nu5cF{_)17CKtLh9r&jg74oZ@YSW zY&ey$`5D1kmvQJm3?))iSGgh(^HZ&H96t10Sj|+5Wv-|DJ#8|MZFGK7dlmxuZKYE9 zxPtS)@N-_)jX`fA=2_P}vH-1N3ocTjqMQx06qg&I>c{D( z75#03O5rFt^&D?EgvHpqxoB}m3$#kn(M8L-E)ouQ(OOfF4}bxWVyQGQ*VAb7G<3pb z{ZL}M8VKGX;W`O(3I7Gy+mq{dLkHxFtECm3UgoWaT)Lgjj+JDkxCRbtO}N<5x?-#p zKQ~Y#^agz^adh|#iKD|OQB7;(jx~ITYTVLFHcmF;BiSIbm{pQB5v7s63}Z`{fHip% zsJRnXuGWODvKq2^Rf;!d^?HW&vLHQvRRhsUk6+P1gH(@yN#@mipV<(R;jL`ZhR2$$ zuUk}z-RH0kPF>@uF}*?mHcmU)y;Aj$1L8v9xkV-zy;%&!uRn~57Kpyd4gUC)?aXb^ zsPP`_-V3scqmknUX%w-{t`x&$uZZZCBBo(J=9m!3eTYtAHH!o+Z!C*iKNYDt;fh@s z@Ldtegs2Zk+d4FKMrEb4;&!O4bhgRbSr$oZ&Kqb_2%2OB4Ev^>9vUI7mr3IzMxTVq z!dxl-3wXI48mJi4P_?F_|I1}rWil<8?4y;U1c4RGSUI;{mT+?23TzL2hfF^s{HpAs ziXMI=Lu1Vfa-9RbS{Y-G0(=7SYZ5Cn2_sjAP{!=!I@27?crrZJ+zFWb0l$Jql_D)` z&VWj>TSjEc{&ER>;Z5|m1aSP4U5nto* zs26_IVmsj17CSs*t(FCx?AUZbD*@T@w*r5!#*&j3P2x{z+w6#@%@v9w`GZ+k!)EF8 zUu&6&Ct*QNsT32@5o(YgN<@gX8$C1vA^KQ)C|-Ub@*typ1E8^G;^Vi5djnU;Bu%bT z*t;Wws)2})h4erO7aVv(?GQ@9K9-*5C$ka^!Y`^2Zb)ikPD_28*a`vvUhoAr2xO>6 zsyc0esmf1OA#J3Th8Vd=R3UB=j=er8maHCV&5R0hMP_U3iJ3mGLi{Xa+IeD@BIZ0| zsM25=S0PRzoLmPBge-+Hj>~kd=HmGnI7B@9$cF{7!;zKIwCb)$F+NcvpmQh zJ;G^M%c>}{;Y+_OpItmdH-%9an%~ilWqw#GIXOO`oHH)!m(l4#-Tw`n&gvF z0T=mUke#iFtSxqP zq73yy+SnGiIS8TTx;5z)A^{=2QKt}!1#Ob+PNnOs2o)nN66qaf-ZIppwAiW8vJ@R5 z4+!D+5F9`VMFH>x@}yhlR0w}hb(Y$4r0dFe`9IP%sK1uliWF*8g{WzEo4u&I`t3@E zbfzFkuWdParOXZlO6E#({a^Un*P3ZIp&}|#{BN?bN)*2mGl`1ozel>>{wkz@>9Idn zNsJ0{;$H4*q#l*It3A2Hk^7)0J-O~QsPi6jqyH433MxeIz3jgu`&OC#cTe^ZWPcs$ zon&v`MsL5Wh5LjENP>0P;t5LrSkwRce(`3V$((oZA3y_6mytiCYCZjOwo5PqJJ-uLyWtfi^-!~KTJ zM3dh0-#oehdoT4OQg3@wFQ#BWiwIwOFZmLZuX&O$c`_Fw)kn5`D_Z^oJfd+Ig@^2W zLG~|@F6mUi4e2K+y|%$aC*t{h8S@`c46$9FjH#fQOcIOe@1CY`IVvr+&!7o8O@8JW z&scs(BI~x--+nXF zZ88SdUAuWK5YlDPW6rHx1B96}W(bB+f260#&}D?ExXB15*BvBFN!&q%lPI-56%=uU z5mzGjeKKYSl#Jwh65_EkJX67alE9CmP;C-Q8x(>0FQRFi<_%@TQlE?r7xUAB(uJ(( zx*fm%Xei`>%<>SJD-%7~iz@s*F=X&CL>NjRL#~!a+F=dE+U~I1;DPGFDQ>u((3Wt5 zrAdrBPFsxLa6pPlaSLm7^P#0!M?)k&X26I98utB{>N1dAag6492(`l}xzNa`C&Een zeB)p1$zt>pEJiKnc#Do(0NlSNodq9>TyNawei)1-=?)$@RumhUk}Ahk!+c`bR2L zAJim1>HB`^nzwxX2F?(K_Q=p5 zuhV$Iut%tMWLau6!YagDh_Rq!`sk_d85axOR-M|$$T^!`Yn=o(8sd=lsnA($x9 zCn>Zts1PF%qOH_MvG$BxOgLjOsBq$V`*2&V8|yJ#`(t1p=X=JpkvPm$GM@FYTRhv; z>1`0g_PEh-^NUwl>w zeF45xrmSkfSfV7_@5bCI7xrP;BdCC*%os?IC{VUSydVpv&2Ee#i9?&+6=IHTiXQ(2 zRg$XjJ!1^X6xw^P5Yzvs!E2JfA{PXLz8oq;7wRunqG2Q2C6`GOZOByHfBIo&uD(QxYckL?%rc2 zu&(xL=*PiLmikpj=p=yW0`>zuK|6?>plB}`e2Mr2_GVn4h;(d7O--y2!zmx&X@KdD zqdV)#HeDg20Y_mp5=Zp`JQr{S;9i6e*af%?;cuXgrwY3WqYRLc_u(71r3~1e8V%;9 z_31&tqW~Kz1K@=z<)YC|+dj#4pQM*d=a{(|?28fqU&J2-ya@2`g!3kyb1RoVJa^up z4Uuwj1Mzpz!H*Dsm2lp$(`IwIC`4fH8+0tJT>MBdGVcdWPCR%g1eeR|Be4k|!`Hm_ zF!_$qNxyPY1NRYHB#cqY1sOYW%V~%kj^qZ#E8>mYfd+%=b?&jZ$p zUoM^ltP{Unu1Iy_my5>;UlP9@H~O~{zg#2}{zk0Y??VM}N%j!G9QQr962DxoNLz_N zoHBTbA4~Wi;zzp=;ue0L__QJ=ZXqlB?{>GC39jkCshM10Je*c8VV%>;vAZ(s@2^5D z(kOfg`Y1-K!1GZWQOH4j#aR04fbV#|=zm+Hu(3p6nm$musK)wFAF}juF1K*YWcZ+b z-@<23X5H;4q~p9T%VaGVpJIi#Jv~ptpGe2~+Y-(L+>jWVO*s1iyAo{@-qk`3niQ)8wp|96B4Ke#6#r@Utzq*OGm3dn38SxWy_rb?P?Ya-wHl%XE`E))2Xd)Usx*E{Ozw#&R(k4O?Zj zts%VeEpgVoHBxbxX=iD5NQNasDHq4lCIh4_iT|mIWo6E#8>(dzktO}XqCDpc0_Ee6nAxNY_u5Umz3Mc1NF`Fh+9yuhpHPdihD%s;L%ARyQOJ;h zIye8n{1!&bMafeEXjm)1dEwg`BJ$Qy46(;biA5x@Zz2ZKWPeq_t;}=>a4R!a&=Mup zMr?wzk;^WgL;=K6I(I$NY>}TdbCDiSrs5?7ecR;WFHbnB`Je1H5_l8pgPG1!r)Zrc z=Y@~3Ed5`m=?hF69dxETE7e|(MfCp;kxrg4eO0nJsrbf0@cr@02%R(x(|b9*t>!JD z3hJncqQD$IXvV3KV@6oerZgf0amy8RQf8? zh`frvzlEX*BI7CgySQAeLrkL>hasa=eSf1p1hymPR*O5JFq+iBv#uG}A3!m8;rjQ2_1BC2;Ku_O9uwN7~+S ziGShOQadIcQoWID!(zYosc-wAw)2kuvseRohzLNo@^UzoQNE`&TyqDp+#n9fa$be6 z$Cz|Vf41=}AA3n#Dt0Fw#%o_LN+qSPChDK^S|go0bhjsr576quMtT6aNxY6nc!-}U zp5)5c$dw3MJ%NT#LX~~dXLi6P%J82kmWs+of?n?S@idx1&vN*#(FKU^7%>+-W!%v$ z`ZR8B2uVqKf3-4W@~k4`4l7VOWc_|gN4sJ=9;%)4(=EK{~zGAI3-V? zQ4wyGzXvTD1R)T;_Rt$}TS=U^wi%~<2mON#51pn{PfKvl+;)cFoWUZ8F2RZG`n^Z3PpkD?IGTM5v)b5h(tLtCv#Q5*{Uk}2tQ*GXXBGbSwbaP$nsM(cx zUYozLTvUN|cWV}?%FEo5DD^(zzVAAGH_Ps0^}1%tNW=y}Y$=s~1-_0X+kVEbu0Eh? z^8cnGG9n2#_eUCFaY61z(Wbd$gx7YTErz}(%oARL2mH2pZ}Z*WBH3vUg!Nk&y@4s{S zHwawxxGrH@hf!o`?B->%(g_DFYqUsE;Ct23Z;aIs97rkDRdfzh z(joFnOCo8V0)bI3-qRKU`-pl=>&=fo!g`s4UGGNFvjoO1xDE){OO0VBD=tMo{IlkN zuAC0S*FJ)if9Nq9=Y~2)UD4@BT^Wm5115^uQh%WP8c1H1!@13WH+@vAkzx*cm5V5y z>iD2Ez9M8--%kwK=@9#+pk1F%o3@}cQuI;imrJ#VlAD$NEjpn|r!#E|oz67kbf%Bh zfu-0!h5TI|;$b&a$lKL{Ym?_H7XQ{DX(@^p2G3GVF*`MEkol6!|jUak(T#Fi=K zFN;uag4)Gj;;;57C#13>9CF7~_aJbHh3KPAZr@uLImBFf=3yVS1P2b0kk5oo!cR&U zK0Tg}TiB$=;Si~Ixq(b)GN@PNGeT=-2aa2q0Ea`CWW(jefU4=ZMYfU#ai*fW zcvu}R;|a=af<+KBeZ+&mrpM=AEAU7v>r-Wt)~Bg9$axAx}-~XCWM-6ud>-@%?07*MK=# zQY=y3WpefW-(4hhGn+N+>G~Nd~umWM{BpEmfAy!4)IrWNSz@W@5o=EFfJRY9hL47 z<;`BWc_#*PfkM}tE&irVJeG0@FJ~JJ3R7>m%u9D`-Z2-$qcc~W9z#yD9q`br551F+ z)c{8^y8D!_32emiA-_Lf^E*D?I(~aY&k!=Rs)`8XTHLR9U(lB5p05E&VbaVpua@`2_1UGOC%T8zUtB2naieFgHupHk_pSCQLF0 zrAhR_^-ofMVaer?`3(N5RDbEPx zp<9rs%p|}|nlc~tKHziEd#EO^yN^Kus4tW!+_Oo3;v?F}y$!3yhQo$F!Enx{=8@^m zZ<{Zu_)Amkq)U|f7LD^vVvyn(T1_L+Xsnz8CsLL5Lyac0LyT;SLVR+ace+CimGMK2 zcDQ&t#0S*9ag=6E$F@Y01FNnlDdR9>7Bcpd$W~*p*$+M1+!QT~w;ENXZMYXAk>Job z5$oeo@D$nO)6$QbJcHsf!RY6{9b!Qf?~uk!wkNO>ULQIF*WnUPA4W5_XKK!;>!|MG zMxxoJ#_{#aGvo=YIcIv}9XJkxYm!IT719-!nsaKMv6Qg%Tn_Q?Mt`K%;9`p5&}AIr z!$!Uxf{KhqYb9@JZiEMx&Rk-J%x9M>VHWrhNcMxmcuv zA!S;HOmjN<8C=dE5}P(e;9IIGf_mxdtn$gigBpDKV=k?lV`Mk}08l z*GlEEgg$a5D5``$bY&?qs|jzPE8DJQN^rMpjB;2)Ij(_h#Sp)7FTTk;tF`*taIH_)k+ML0bnL#yPedOCUO zz;!Y-lv`6?q%{xlbSb_71?mSc9oXZd0j?jsbcl2pt#u&)(6z@rdGtyCK^INzbnwz4 z9zYZ9tuy{adBmT#d7#TkcUHZUQL+*eZ4if4$-U|a%VyF6OGqK<^s48GK#srXyY7?+ zM5hfW2OMShVA|2=&R|NhC$%Q|%LeF0Fxg7IF-@dJqf&iFyGttYY?|??xWDAylAaoNB?@P{MV8SqBcZ(^V9D8_!Tyw4M%F zI&h%eGqbPm`raVVY)HQ<2)n&K{CLNO>4@=WF%&O#B9VS-y@*7Pmf z%C<4l1-dYI;L;{O_Zc=QAQJ+N-ir8x|LYmnne}hvC!WE@8tohT?Ppl`+4U~t(El7E z>78dV4ppFBLlhqT&k={H$6it`hyaeIb`=~d;!#%jhTU2?6fjF|b|Qo4fJ1~y z8c>+16V%{e6X5SHWn6eoUQHn0YoatTF;1|v%g1X1g4LqdxJBAIzy6mjwXY>oJLkdt zvM!Nq77pxvS?>5+Z1HK9`ke|zJb|Ug+nCD)l9}6P{{^KIKdh%9_gYU2ad*& z5tIyD4&kNsx3)h>)3!@=)l6o6S}jh;^ht}NRL_cxA{Jr-r;P9t!S!Gcob_p)3YUdC z#B705k8Dr~Z~42O9L{wOpR@BxC+=2?K> zgC@;V@td>c%1SFGT5h4BQaEo(>`1Qq^k>-D)WQd*;q0kjL!mUPtJhv4A zqT7nL;}W7Wx~*u6JQYbFm~Q-}lanccziD!;$2~#lBR(+V)7LkO&+wnPnFw75SGovb z5KQ;0XX2yvKF#wMup#ysd687B-K7ktmBC0!tyYvW(a@AFee9|C$6;conULTkpcq-| z3H}Jj?P+~X@CS&e*f_v@K`ese0q+D|TjRHabe{M}#GBH0jzNbm6YD`q-DXoJRyFls zL7#YG%WiE2Nlpw{s2z)PjTpdxtHIE>%fyEizGurRgKHc=@&YXJn@F1liKt7_D1Xhp zFj?~ri_63-l+)AQ86e+ciIGaSpY~;!X<8{h<1Lzyf*{Nv_#aiu;6BwmJmfEnfWT4iEiGyeow zal!vj(S9g8pk=rfg}0%}K{!L|4%Gy<(YsY9mf*PdLS`QJY_spq)7oT^>0)@!_}!?% zpoG!oUE3Ki!%ekRr(Pe`tjA8py|oLO)rgsLA&am+4x!Q?YpKhS9Au-{_cqGlN2XJc zs+@`rWlOvUOajfC|v4n2ZTa5h{ub-1|9PU2S?Ffz>ESfcr z44@5S9DiaFi#I;W-(JMJv3*ValSQm6+uFo`!2gb?n|#0+BdmUh+~PinS9*bJEN@uE zULNRKDvf&!tE2!NXACm;$HCA9>l@ne=^tw`({DHrt0wEm+K}m*c!=*_%OtY)9;rmebl0&~e9j?*k}p zv;Bxm48R=WeZY^q#3)Z{j-Hz351hCD?OZ?FXGJH1xgS`fw>}bfe7}d>Y+Q zrgK&j1_h*@<`xYu@SdN}*v6W`v8|lx7+h1-8uz#s($7$rnU;JfB(m!i z1K(VbWyZs!;C6bkl|__^WS0d^H}FSaX1#`ua*dM#7&Z42_2^O8GF${@99DnCZ|C-; z{e^8LSA7TiMPl-#p24T*lb2Z>+fdIPFGH_uY2YDCSyzlgM}sAz?H^uDA6%gAc9fe{ zCdwO#f>eIU!Dy?_`ad;L&BW&v+lu*11J7K_!o49x8~CQBEOH97d7(y~rnJXEep034 zEjM{dHH&}4c#2Jq*}fPV%jC@IgE3)+IpaLdzSul?0<@wDoO?LB#>A9pAaH)FEe1l5YZwb+}iEm!UdK=gBW6RhKV;K)v&Y~0J zz-U7J-q=&_sTkDmF7lWf7CR%KzJh-3Cq&vfviFngo9J<(c^=|kVB*vda&&iWg_;AP8MpElpSdU&e)jEBAg$AMC5qJsgu z-p5!fu1O;pP2h*IaVjrIW3X8Bex?-Sx;T*?8Jw4}4 z$Y~?)Z>K+v&OqVnzzbR$Y#pyHB-+L_;H4-9J2b{^+WwB0ar$Z5(Sx>>=g(_+Xw=VA z(<irr*>YgRQsP4>2|3w=?wnY5~Pu*+swq+DX50IbJqA?hupnx_?>6`aVso2Jp zK5Eh){eKMp_fhS;Ex7f>aNJ_MPrZSBebn}{j9+&Wchf5c^oO?!uB>Dso!dw5JWH=2 z%hwAokYi_CEK(tORTk+C4c82$_#y4Cr zHSk_aAW{a_@a=laHZ|y8N)S>)Yxpm#n92LP^A(lX0te7@D(||Q^#zow^6@$}TICB? zv+of1*kL|m4I5@UDU1p|DETq$%leLgUUT34@O-=%VlHuhB>3hvupsWnD-QJkO~HSn z|8~LetU>=4eExaRS{7t9&iTB{I#8t3h0ovtYpQpCQ16Wwt#NS%3Q4HvS?k$!|KR!< z>viY4dS0}iEoa}|;ty_MHa2Y+KeK`1Rb+l_BTHn5OSra?O*bCrlU`@z*o0dC=Ic<7 z-mBvWUuPq_8|#dwHgMZjkL`v*gdSG5LAX4RT9(#*wu$)~jib2V8|)c2`Y2!U23s`L zyO6At9jyVA+hKz`{4B#O(~;H^=dX7Sz2lz1BV?0|LrR?A-3=Ka3c)m|>#uJxwD68^ zvPsNZ^Lg5vtf#U4klKZQZ7zA&bTnW>nJ`IxatGi17BlzlT1(m@Isd}<_H>Us>kX0p z4ZuoPO-5tkb?5XW*PZ6Wyyz`lRJyc~FWQU?lU5Y+Gn?5y`ak<^HW&Xt|K)9V)0cox za#)p-fbBck6$1EzU2FmUzqt!HYBf2zwu_zjU4brby7c*%yIG#G)0kQ>Jeui_KaacR zg7C_Fq_x;Nq?TvxVS`xrT7GyBv#`b*UW;(2@*3dc#O8Ue14e%$)W>4ywHiKbFN+J* z3-vOL|BWx&%N}N7wV(g6mwm#h_T}#}vv;vGPyKxFdu)`9y18HP!>SM1FWo6G?lB%0 zxNE(&&2C>jCr2~B$$ZWEWj&w&A=}%Y*VB`8+Uj+eybMF|7x~-gJ@eQg+1UpUu$`=J z2(*me_*;+EKz`pr7Qw?mVw;E>AAH0XQKg@E{Wtr}iyHLX5uK7fkK$19HRq2ipLLXF z0(x8JzZ_*N3Fm=NSz79@$}wDU1-@(t#$X%H0hLUAJ=FYV-MV>>n4Ry?n3!4_-| z?(p-wfNTHM*043QRfcyE>20_Z z$H1l8#r(=K)|)LT=1s>yc!bA%#@4eH_58cf*b(;0HNN6=HnIK1n+9A#60if;f^Rdv z(_P(D!moVJ5}5BT9&#MS|LiWe9cRO4eOfXJAIU$j$hqgPw?eOf?I>BjA=}zDFzJq0 zMDCGTs|9cKU30Fx>wmy!bC7wWwaB^guJ_J~_4B=UCWRFm5aY8W%z6!L-<~mTF2KA2 zBg%E>idwE62ZMCF!6OUUpbiV1hRByL(9_n&=&-_>==L*CKDU5%Z#TEZ5IM7u>H#a) z@~s7Ij44IUFET_9zpz;|fnf1?XS#Ua4|wbFqW1pbDeB!~UR%J-;kW9%a%Ya8nMRLa z$HdHmK%p|O)bIf(*mkz5n4dp^6(OEWzI}p?iut{SO3^>UPJ9IFYf3SFgc!8uJEw0h zSZWKs{~V8$KTG(7C)p6zznE`4iBi73!9O|4RvORqfu~r1R)34nJjMF5Z*K9dQ_K|c z{k1EyYyO4%UT+TrzIS1fw!|1~O~f0-5t|04?JHx z&lXZJPWAUPmPX)rUfL@Y({29dBIoC|hh&OLrkK1ArCs84&R{KgOz?GQu!zVN{KOg7 zePrgU8#bfq^6!xm2Bm%YxIdtK0DjuxwG;0dzGJca{P8-QW1FIGx<<99LWC|B1$frV zqORnjXW7dml2)Z2wb#z%o!M_&7Si8rLQx9C5lTnfp?rW)G ztBSPo#{Sr%{ayUx?&IKJo@Fm}8jR83?$CSBJZD>N+p3vE++8QDH*WC<&M|Y~$(j@p zZL*3-#FwAL)fu~LX#lRy_C7EXcQX_@x7Va)q*y1bIkzrp-gxrUH%1>Kn=n!7tiUJ1e`OS72%U^E-UoT%Krs zbrMnV!5Tb0o^fA~$!hwov}f9t0ylU=TOg0m{;;N(YyxAa}`NwHu1%fv4Nde7b%qY3Y*EAVZJ`wIWB{vH*f)BRgO+qFky z=HbC&n23ZDIo!S2BllQC{Je*d+AzD`1jw`S&6BTm|=vqeMGQ&e=!M#ksG~o^rog~_|>#$xkv25 zc-nmC(K+)_l&>Kk@9#v!qJkOfNxXGxQCDRx&M-s|z3_L@!LsN9|0p`VcxL|pEjU;W zD$c~)qlOrw=Bx$AxLME6f)q~|+IqvM_&|(H4wYhVjK=fHp*IYX6ASs& zFTq8F<@b$M6AI#&N9Px59~l*EKb7AKKY3YOf|W>{%UiYnG2;sUCVzx%T3F$cWg`l< zY6D{EiP!Xu0JY3DF@H`5uuXWK9Xdhz^KP8-iYleX70(MinwA0KIDN7jaI-^lhX+PJ zo|fT!Jg8l~&mUj;%(EHe=cP?nn|QacSht>cL{^u)wAKM$QzxB_-b%pOpl7Uh7cu_>iDd$*~7-uJpXIP*%R0Kak7M9vVk-z`4qJLYIxSY*N~-n=7Z zXD9Vz-s5|gp?q3LBGi!Wm*X8%GU<(eo-d8Fonxnh5i6(Y3C~|GPYlqNCn9Z^lhiqb5`@=2Kh}PUx$4~F&+ur zpw%RJO~!+6xB1wg*}x9(-P&6)5$|zd);1X@;emnvYRFBV^)s}r`TXBM@}rrO=dvMmY!1#N^jH}3%lr6|F~^eodM3%sFRd83#^JS#dP0#)#>KSFRWMS zLnZ4A(%u}`v*gIl=)j^P=YF2@3!4_!>8796mX9Y9eDAXc)`YO3>K8o!7aUf+%>VNX z>&G6d=be6Kku>95er4gtANixdGNtWLwLaFpb4zgNdXe)R{@Sn5^=G;GPrqVu@#sx{ z=T~Mn9^-8)CK5*8=d_41=f8;+uFXHi6hdppWZPUBFHb zQ%tS1r3MiEJxxcAV6&hDJ~crsE8ei(PwjP!w<}}=I?saHqSo0g@o1`#%I=#}>%7ZT z3fbV4M{k+(gUa9ty2ViHzYV4cAESD;WP1K-ZMFfSV@1y6HE0}O**2<^isCo;ZO-vC zUh>P0&Yy@vb81#YXZf@AhSvS?e%cXJf9HjTFwq>inYSP^zt*{@#t?Dn+5Ou5n4km1 z7?EiIYPH6Bw|m21Aa ztF2#aIfgEX@mKdkg_=2@!dtWlW7-_mb6nJO_{uD&`Lf?wFT1_OcW1OUI~>ml8fQV` z&B4RrImWM+7yEU%)CLTfUccJ96i=4s7^kUz*Nu?@g%k3xN)5{U0>wUx_Y9Z2bKsK?fulUTlbgFwAK#Aa`mcqA!ds<3TnbA z=z6fmtEq0o;9)5K9GjpFP}$An`44|g=D0vKb)q`?CZBqdnT$^U{6*HI%@F~~1=Y}? z_T<|xvin$SF~4vTE-#i`u3lvC7#)1|B{nvGUvcNny-QD8k6VYM4IjnL(AuPZlJ8ry z-r&E(*L=n4D>4h>SBylPV{!ju2uoHA_}xoTA=_W)rpvg!_|)pa+^-6JY61;coy}4V z9bMfe_Z7r+LQGxV^n!!sZE_L{0(bN;pjl|=3&yye&+RS0q)m^TQ_v;14aj&nZi{x( z6opElqF768lhygxjDy=1o*xu+;nJYM3#b@n6{B>Ex@L9siV`TKS*v{&yw;9)Z?EG8 z;~kSAhbk|#KB4X1G5H>0i<*j`dz^Q>!n)a$S5LHtD0tucdO$9-Mt~K)5t?(IS>GR2 zpasPQ7k1w9qb+wCar=F%-_|aI@CJ3rYDmSMzvGdNLFJ0=ZEd<#Rr@17C4^k_d#_$I zh+Wt^$fEWFX6GG-?V;+eYvJW5v`#T?c80<99ds7zixSL_U17b9Kl961SaNW5T^7g_ zVz>{&?uzp!kH3nIg-`jst3dgNzkZd)ho8AN5f@-hQa>mO$j!2j^fZ@NL04IvUm;c( z26YY(E@Ba5r#lW0ioKwB`J#4RDofXu`yJB<8PqFTAw?$q4_oD1WWfL6RUv3=!m4?t zF@rKLSOCZIg+(kZF>+O#vU5O~n|%S1%Bo<8&tQwQ^Qz+-!-|LAd&l=QD(Z*Vx@_)} zL$wF5S`A{wUhtA6^XFd|v4KH`8~-f}*n!WYhL!M^A{PEg5x!0UzK*N-TG=Jd6u+fm zh@|YrY~P(2CGU*HD>PlyEw_FsqYA&w)(bzMO@&+3bJ?AD%)-^b2Hr(AUO$c!&anYt z{@?lY*H}dN!Oax00TI6ypUV&Xg!m^4>z|2g*Al$b&N}dO*I2vwFR$wfkCAh9mXS|U zhh8(lJqyz;Mrsm#%@DuWxNWRD^v3+MHfYDw+*r&y+CRA-BY9G9!X&ln`eP6zR7Yz; zZLU!vi5SjfRU=gEoY-#pxy#$+2je ztX+;Vf^GJ~hC|4X@SXm-Ki?-?HCa7c)V0irR<+OWl1te;Wba&dTr;Glo+O^T0r#WM znC)q)8FrZ|52(4t{Fh?fLi$p1xWxZ&R+pR$c+xo6)+WD;`qZ^9IbO=n(#|`6u%-_iFzym(i2YH^p`oy!bS26ao;MJe$t z>YG`oOGA(+wYZ>^+L@o#<=wsoK{IyH5XsMKXYHJe=I$K{X|D^B;M@n)MYlR{?z|%u z^t}Neqod0@=NO`A6dEE&T%hU)7VBLq@ne_9*>)HPUp6AvT+Gjvu&zPv@HF-stRPa= z2s|2Fg1K|zHST?#4G8?Is7nr0?ub_#`3QsqI$a|YJpkSDh3l*bi+1uiue0z$@4ADb z@94bs#_cR`wyj0H@AiS_Ln5jx1V`8BLUJa-AEMZ4Qt{q7vvqvq#<~0xHO62+Tr7Pb zmhzj7k?L-qasxXv@04)c4K|=nfzu0Xc;l9<&QJNC8>~l%KZ^F+ywp`qdu@h3hqbs4 zH$>-Ve&GfSw-q*d4>b+^Zy}vHX=B}Mi&5uZ^Xda%)rh?|SfFMbwgsrp>#eDVZ87Rc z*YLD$pVit!seAEa^6rwoHh)l@Uh+L|F7yk$oHJJyDXzV?wiu*)ZAN&tFx8E_MQ*a0 z<6kV!$?uO^jOK1?05sBx`JZYP%4Mu`QvHi(!_uYt7PHbwYmi!1>^;mh=w#tuTafzE zjlDM7ipjKisdXp#pEp@}`yRJwuVSjoi@a;vKqxCJ?{o_e!kusOhi|c{fj^T%XYFpb zS+6+9VP!qrmOD?e&Ctv-bMex1v9P=HKs~d~?@&MWBLDani|s&#YZ-`J$Uh&z~;A433 zoOMZDejScSr-x(fC<`?D@CMP-s}Ip64CbT&^`#Pnxiu7{4lZg9>7FWs)l0lz8AP$h zCzP>qBX8g-kqA60{Ftq4=3d(cIZtmbim*Lq>$W@s*MDBrmilVW7o436BCQ?OZp9{> zyvQ!0-pRpCLq9>q2N%5u8$Nw3I!7^8-HZ@LN8b|rh3*>Cb6Dq-UNg8yF0`WO%M;41jbEy82ORcvL)+U5ne|2p3j z?g%w)jaC{jvZa{a(#^^^)*h;aLz-@vTRkIl8b&Ut!W^o~hiY9_z^g-B9H9_;a z%~l29yb)7y2oH)=2l}a3`HkBw-rJx)UBo;5&L$gM_*1__S)Qs+F5)YGXAcg|y_*^PNNrfzN_M!hb)+<7)Xb>8(zI3`R{f95`SSid1hZyC({ z79Elw^1mVyPBc^0ZMX7lZB*^noOxlYx0hexI<0419zN=aCG;C|ou}PF7b33nckZyL zwukBlq>&A{)^-`|gzxXL9$j1Nysb;~Rh#N;sDpBz7FnR6ebZF$qV0cREuMZW+j<=4 zq|O({AzHCs)4Wa7z!d~10d1UwC^i~wRdoyTwkX6$7rkfe>KAk=dIj!d%+FG$sbh+L zN~fuvOUOxe8s@w!8ZMHy&QyC}kGFNRug<>=Yw#5i@zFQ?srCOKVQ&H#W%0+4&-2Xe z!RdmCfCvi+qIiIK;2DCh;CMnq`(yezqTV*1m;NP> zZ(eV!!Dh0LX(Zm}HNshJAlKXa^S*z}`{dPDUi-H^4zvDYirmKiH~VG#Ic*!HdO{^% zrl4KyW8-HOxozmNTQYi_23vT8wEeQZvou)w?=1=YE!CyM#}F|SHCSbz5uZEhT%XhJ zd4W!FW|bPqjzu332Pj;zX`MYn+Fs(|xD*4B&XTl!u(AZ_*ds1{yk9(`U4vX_oCHCn|3K<@KMV+bgvsQVRS1txkAv1?5 z-#~6-D)cY-(keNu^YKcfX{Zu)-Duix@9Z;FnF7=R>5d>KdsqtHXCH_?`=($S?{wW~A8crgB^Tj& zsM6)r#uFnnZ7n``mB}rq#O|}F#BR)NT5tn5n&$hpFzc<8bgtIsF8cM7Q6H9!u~?qH zX-b~mXZTh1cJ=ZEqU>4P|GqXOyjgYTo4QY2)_Ip4u^XK0pZR+yVWD#C(%~kJLM6R* zjeJ#|X%hq7jZ0songXh|OY`h+81n3Mj0yLp&{sOGPbgNFE_KBko@-7rj%LJ}E~~d| z_15V`m@ca~Y7g1ZldI~F*gQxs$hgW)U3k~GB@h6sAYojiLpB$aQph^csy`l`BC^~0)> zm!j9il%zU_u%j@cA{)`HYD3ZzOuGCLN>sVVWH{>4!KFkl({%7Db+;HgG%GQ7Xi_SN z`&x8)2A$!G2tf|rdPkSh*F+)2-&hT zftCmwP3Y1)E_tMFys|%&hMmJQA)**PK^u0(nF-M>)YbYXA}xhnRoB~OQ}n*X1x=An zN0+3ghopTIOV%61u@KNnvaX=gC&Mz7^^WDCU2y)=K5cjtOR(1C%GC4%`*h>L0?GOf zIU93XrM0Q)`|Q&VpfCtD%`t$_S)#WFYFw?sk`ZzOdTTH3Wk{nM%`qlOpDMqXH>T4} z^rh#c^-)rZAxc*oW)8uc<{GUoZ-i1;Hs?-;aBNy_7}laBB(2nb4zv5E(YacmE2-(s z>PM*c8=2&Y06&V6)}tU&dHo@~Pjp)oT_1~Hs;L@eLCRVEbaAGSVzek;c{QS#_IG^k zKfbYC`GW6{V(5A?Bf6@p8P&S{_}ZS+0^%KcA2wW>U7;^vVJ&V8vj>Wyp(5yx+otY^ z^XC5j;pG3vD|J3+$5EJ9x5fxit|WymPn zlSPrLM_GMMny|k1z@A7qVhqi=tR^7F@yf$2YOl)8RXXNoJ(ZPJE$De*c{7+Gm^tkj5f%LY$_5x%vDgzUa~ z?Y({^Bu#JKC680?R5YgC&sO8%j2;dT`p^XyQErn>S8U%u(V6@lt$<7D>z0HCdh0BW zwnxt1ZFXPd(uF#!UZM)6D=>A7L^Kao=h}ZZ9zta$Ifv}tMpWP&SL-lY&N;Hsh!G2u zX-->o<8nn~(QBn0Y5L3d(B2q@)fv{feR@YlYAmgT3iNqR%@mXSXC-xnvZYLX6G2&U zzZsThG~X~U3?b_~;flK(wwE3?`V%uyk1YKrH?wqG>)@xkEplChswZWIrB7J3Bf+&~ zpQFUgv_?9T-xVA)e!WqJra`VwnY*thB_m#Wkg0oCuTi*qSxIECl4o`MS>lJ8e%p~)3(r(2CE zO78fU#W#kT*1(5olCM`UGiAd47aYX?8$-7wP}Ww9bQF|nH^c$$*G%&*8I3J8@|cP? zT9CV}$K(?oPHHv9HiLG(U?#j@s}`P8fG$>R^W6%J9kk`og6?~Rv>s;BZ9*AIk(6lK z!b==6L^(ivAt~_`>j!9fT=HU35*lvk^2cEV&rL>qnt^h>@W$4Hf0Y5`A4cc0qsRpR#~*E{oF8!~XwOiiRt%-jZ6!nLHd)nK+q~=wtd|kEe-$Q!Pga zC8`frkqzmqVoXwwN1mKRLTS!;)Wsf%?)n?Nx>^p+I9ztfN}ITsGt45pqu{r|g0ij& zE0?x)Z^_W`HC0`(>gL{|S*fRmTK( zmD%NzEUc5_q(~j+Xd$Lx<>Tx8x?L{m z+TrOyjPbSjhVfQIo{QDfj&4cv#S>MrCH`obE~`H%S}dRHtRG3jRIG5zBiVP% ze%Km_yj|FRt7t>@R;?s&y9^-{ZKxIP-3cwRCusxCQOd8C{9?Tv9pGDk$eNj9z+gEE!)qbqAS74YD*>B$;A6S- z-vS~8PvlqGU+PbVT!EY0!p9*d zErw+cwzb^rsoY#j=53zJ;h?=#%SS$yBZ9j_wzdu2BOa$PRcx>y>g0z*Uq+L+^2c>y+N52cE7F%Vi}DIbN}mc*qUgt{atqjf*O$~PfX`; z)Om&o;lK-ZBOsG-$b3nC8%f__`{R>^v}3nR>I8`J2=k6QyyfGUhL)CL*T$m1qzwsDh35dEQ4P$?&G5T zee;UFmre?aSA1{9oBAm9CXb+Wg7h-aqO_%t_IjCpvr%fxO0gM^HQ-*#%jJA8rQ?{* zrk>!QjD|`+JciL^Hb`lCt8g)+Op<-``7#Y1)A}Vl$qhm2Bak%GcBKXJq-Q#P@BziL zl6h%@t}Nb>-D|j{rLinfnODK%wAk1hVvkLeVq>RD`M*v}0!b*!-PJ0sMc`}d*ed>+ zmUeA&!OF09D`eN(pb*sXU$ry@Cpa`Z`cm^t4N`6!6Wwu5{hugYQO zn5@*s;MO5)sbt)AC(*3kq+j1s8F5RyNnGft-`Y|c1gtZ;96n{%=7@&(Y;+X%HcO=L zm^ZsAqbs?Op0;9_)H62TOHTvkD`k9wo~9!S>^J#2xVe7)NVK1WlwWW1T0ISg%lVr; z(1nil{_3XIbPt8TJ9dF4f+DYiXS&c1a_tSi$At#Sd$04KU8pf4=4o4S5Qj3$ZC^hT zXV}HUsaARKR+zbsDHju)tLn}g?(IsG+LuF^cL7!pkqoE{;;^5f?EeDg{2INbgM;D@ zU+zki4bvYt*?AeO6=)n-m^zZUp&}aPMI>-^HP?I46n0fz1{p>V zy4dr$$}EO$;)KRkk!p4i8U)v-wLHL+b^=;pkO zpxRtgOKS>uG@*kf_E7DAu&~ZR10>0fH}j_9p7!!GtQVx9<-V$BTMLuCsZo-x5W;Ip z=lS|PniJxe9gR>lBrbvsh0oTk_Pyesz+;!?Ag&@+XqMM zHsL&i)LGG%^T#deV9$l+BvhL{!lcX9Ds#*Em>?P?SKyVUAnM0I3Zm`gBM!r~Y3Iwu zP%`wpX(qRP>}75e5k6Bcb{;j>DLRd{11VKKYu&i}7VO4xk1g6fiMwt|G|3#RldUPJ z|6BgGJ%t!@n{0B;LjhYS=ZO2$ba|sp!u1%${DNs`pHlU5jmByw`YqZ}oz+z;Re!GG z=Ynacz*4nK?Rb+xgom&?)`~F4Bm7de4Fn&Iw3nP*$449K5+s7{3BPWn<1##NsA;;y z!+Qgy-S!-VI|L}#+chzX1zXeqw9R^aeWO;K4`jcSEWN@a4H zIco$;t1xSnF=gAbnr~@-_$VrkM~QaRGpd1Q_p)?o(i*7}%OaO}ZW&PEv4wRMTb+Gd zB5!47P367izFUSBG=a4i)*{DcC99I3521a6I@Y^w(Pw{Gpxxx2hjv97Td704XmH>W zmAq{zZ53)L({CAJA`f(KP4Zlk{AGAZ6nSQ90xFk$s*o~1CzMWLRGC}B&xg{kon%ZI z-SQ`_SmNi7!IcMmmD#q}dE{wOhA_O%mzA$>CHSL>L3=w01I@!X3cH5Uc!^c05YKqG z746jYfIY<2EH66ux>{!yMem92D}JIC9nlKXV7L4&2IaMKUyB}6I;Cjh0(Zthrt-S= zpnU?lq=qWIb2!cM{<+E!B91P#vKw;yLR>n?%FDuOeA5Oje;RUkq+M70fprW{= zB51JOr=AavpnmMKnrY+a2s%(6TE_QB&~(G1hA?ytWmp~TZW^sTEax3s)4ff?aqUbz z*<;^}kpUio9~N9^80DJeBr5S;)AK(O-=K?^T;Qo6>KY`Vgz3g?$wsIls{5VeU@7lf?x?Q#Kw1Yw!6H4;-IOgpBdBYTmgc?Fv7C*YMdLsnOGddyJZ3JR)JT z@xLm*xg(w3b#t8=eeoY=m%NDl7U-=>WCr@3HYS%mDeRhUZJp>%u|gNdFxjHHE}Mkk z4OKio8Yy-QmwNGO(R7lZwN8_-Rdm|V5?o5Pxg_LeJ8O4YU01`eMk5B7)!Z6xh@lbk z{%Rf=!gSDok>?@rZw7ahd%a1zFL>-&|e#%k^!i?Vnwzi?bET`aQ_75iV;yI_1$qEZ`| zyV6{-ce}YOGGYQm0lU%8-bu>AiaTbC+8$@RXx3oL%tv;kedOP*Jf|D2l>fNS--@Hx zWfvIrLsaWTU`<^scRrEKPx{kREx2x$p(mh<>&gogHvN{k;|oC~(!o)ep15rjh~fH*vJ2H=V>TsJm*p zr8lhuYG2DM`_Stq>kaHZM1SKimgG|m8fDbY`7^Y*qG|p$aV&`9VX#Z~q%M=q{rzQS zdD+gjS$pM}O$pmh2x+R7c!f0%^8Vd7^QSM-h`>QNH5MU*KouA264jz4$}DZagx!b% z%9xuxKAyIfL(BQBc)G0XeN?6p3^DDch9bKoV+Wh{me0-6rq-Bb{E6Mo`)aq^UMAA6 zx>QWaa2ti%@gR@rOYgAz>ahcb?gwG~n<|fOo@w{XVsu$hlhmvWu{2wd7pN!$e zGHYS z5^sO(^cziH!12J}0DA)$%l^t%;HDvX>=HN+H~{vUpxFT2LHG^zS3ar;!|3Hw# z7L7t$Vk)g>W6MD_CXOW%^>(4y#8GjDND1U`nwY!_`tzAXX;j2{6xt9>^F)C?kJc8? zU72RS-5sYu>%ALn%Nu-+muye!`LUtsBO{fMD+&XK(UFqOZ}8c}X%87ybH{KRo}HlW;Yg_?hjUms52mcJ|GBS+9&CM#~0g@28pfs%2tLLxhrBrcGnI+V-NO+zlI zyQ_xpi$h=LhRX7Wf_qPCc7$Dh(>8N)&jNFrx3V7-q{ahG_fEtWEyd~tGmV4&wj10s zif)s!U$$yA4T_worhQa~F%EH6DYd6cP}^64%9?aRpW+3@i)+QVmRQURAdSbK!zb`gW9Sn3bU8mbhIW!qRPp;`Xl;-3>q%nq3@-r0Aq!1P`!dMS zqHsZ&YTa$yy+;Pir}mDCeW^avVE^flikN;uuQPCjAXHh8G2srt?=U$Xe)V7IlnuB zcIf1%9Ie36s9-)?5@OMqj$n1q1FL&M+s2#Dqe(o1)jdsl@HRIq!^yw%swYn4O{DkP zFDke3PLpVveDOMWpNtv8FY4o3Zk|lL%587(t&{1J(0l4iY^9ON`6Z;aE+xd|WtV#D ztqpPX%>6P?Z@Jmae8+pVPs@zagp6OENk)w&r2jZVo{S;n#}6{el@BwCm1`E! zV5xzJFQS~USxohuEvD1?u|?FI-(N(lLJ_PZT%i*xq9lIahDM$E`4Rr=Vp`c=tA)+9 zH>SQd{nc4hUz;0C=FXY_R_YtGUrl?BFgP*%VKZkeeEqf8=izjH27SeoETfLk63$JQ z@v|B9F2{yjNcSOA-!d9wjGdxm;z&$Pk1o+Yx^yA$%z8C-UfSz3-U14rjz5kxA^@qc zyfbxPs(JbwuN8L9q93|u5E6TQCHW87>Pb5ix?BWfDAvH7I(en=7B3>(4)!;J^~9a@ z2ByRiuY>(yU`7m%)~dpha0D=6_I z8i&0%us8S%nlb(`G(*6GXa-XXd1pNbAOwUA=-2TuXaoY=C=+)BPJ@ zQJ4hnA>c6RBDH@4Zso)`fx{7RkyF0|M}VK8`5U;k6Wf6!otUho5c6xKaRF|NTo&{- zrj?L5#dPx{>NU_C4l&Ne@CEMV#38`3$Xel{4RBBBI(&32u+d4A0NfS!dZgLVm3+!a z)Hh=+?0O(jJqaY!fO|VIA#;HHIB^DWKll^5u^QL}UHmoy4`_tsOW-8Xiv-yN+#kBY zXMvL)d>HBS%1VM78!r;16!zl@$#CS%4H!ycsVB#zH`c8rqa0XI{)GK#L|=T=u1zb+ zL}!GW>|aSHJFy)!Q{XNlC#|Any3nC?z|)|M643%U9lEGLA;2>o*g!h0nnlSB7=(wu zaCp_>z{n8b*MLR9V}Q+0JQX+%SkS)?JPVN!cq#DfuoYkS5%6s2B0`&h-*DouSMkb^ zk>Yz{_YV9C-e-XqIC)$KUI;s3e+T$or~L!q_ng=cya?{7heTRUk$jEey8^#2?4W#r z7dvq);7rg6o{_*=NO6ZD7KSCT6p?%h_yZ>%0ld_SrvWbm7EI>@f9SMd4ZPfGzXf=O z)BY&%N?;M#8Q@jWMS_$7uZGT`DpzOVKrw)x_z?vTdw@j%kAT-g7un^x1}Bi9>k;<= z;E%;O;1>a$4P6BA5^#XIB_cQCr&&cSadwPmiV(AhE34*#79@qV+wTD%aoVo{J}PRa2w*J? zXl@)HHUp!%ao}%(Poh^5Uv>icloOW%pN5^t-g4mY9XOL%fX@PpkNF?)4}@fjh+2Wq zk@#hzeU?9>2e2JR1>aR)#! z9RtI!(Dmr9rvu*w76H5o{HGHy2mZ}LqbHvN{|{LB-2;3Nx=581z<-co9m^(GPLOh^7a0TxX4h_5b>I$|wc{eXq8 z$G!f?0jwdJ4nKo|MPTAf#{xHpF8oXd_H*Jlf&HEMUElzcIWbdsSOG&IbP@Pw zU{RgLuK+lx5t8qLgPr&yun|}UU;z$8l*DM}#oxoc!f!vJ-cqMm@&#Gr7n*^eec^my z1n$VQ4}nFaD!yQ2KCjwH-|eKp4nv(xL0=2(0a}OO&5q%a1N#7jd#1=b<7WODr>X8! zUwLQFRO0xX#y`%dJ9)3oSaCLd%F{PvR+jWB|7J6mIPMmDeM(zas zHpjM)jxl05*|~d626_QDK&?&=Cs4b?FGa}jyR&t)$^zKi<$UxJ@U6)T7ybdx|I2wefM68>-( z4G#GkLA8RF1g9ie--H?tbq;FHK|DKG*nT&Cjk=b>EO@`XgMYS%zTIp(=%4*0Ph46J z!?D6P1@t=xq4DwqG**r-<>9{3*aM891i>&0{$l^jWN0prlNHe_VtBN z3K18nlE)mO%`>{d%VH^siPAj)IKzpD121vnDZrUdJQFy}iF44HjglJKz6<-&2wIeh z)xduPi$cB$7#D&%@PB~+a^ii!Rtcq75Eb)ZL|o3p?tgF><*^*NJ3d{9f4>2*L)Rnh zRp1_=5yk!~a8D;cmm`$)a^lwzuRcyb&0znlGkMwp-*w_d;CRr8BpCwyp_G~7V44cU zS_CEnm;)^0Cy3q$-hc=R^J?HvoQyUAZ-l*|`5c%#@s*EPlD)tp(%->;pA#PfKH!Yp z_rSNDk-l=I@Xk?sUgBrZ(pKDfoNj}xi^!F7G;?~wZ~jPw3QLaD=`vq&j?UtpPtsnz z-H-Iu!bLz50~_f-hfYzcu;et&lUw$jKOg_2qUQIUh`&>NPMqpTqDcz=Ws*$3{0AD& z@1Ldd&97^P#if7#5{C_6ca}EiZGWIs_^uzY$6bAn#_>HxbPmt?5op_4tmmRkNj&{5 z4dl{Kn4}thqPoJ|pXg?JWaI_MV9k+O_yqI?gv|N{DGnVGb^L_g-k+$$0&^e7Pc-Oz z|4SXC7}1uBpP(ClzVO3eXr0vK(IVNwz~z0}!Mr_mkyDeQyFp(IU3d_5UQXTHq4Ogb zXqCL+GXJ)Op5l8i(SX9)rC23%9Xl>{`ixf_@Z)nzsn5pC)W9=KDLZ(X#>=wbHQ~XR zkGo2JHEGl5&Y#0yze<}UjDp&gsFsa|Bl=ol&Q*F`%E-n_llX~T7b{QVW5q{(2P|SP z+Up|V#`@?^&I5~d6qV>Yu*QL9@;k8BX)ji}AYe>m9rmffA_0Zpw}HJ7l=zsHz}~>Z{wv_7 zPW$7)K2H2gS(upKN{*bl4F_L`2Sy$OH+Nu})bTgVX$yIV8~>=BPLm#UD~uz$^}|qM z07Olof}y@oB%}dK1N**E;y2aQsEfZ+D@Mx07&!{1!v1%s+b__+hx(jPzD_$*^9{74 z{+>hjGGbMhkk9{ILdrMugV$+9;h)#(&r-%fw5sCsgc=Fl&WYy$w|C+!V679c0v6E` z$-seKp);t>z#_>7UKhLac@l1ey%-1x`pvL!>coGc=?ZO}Ghz)0L~Y<8BJnM7w3Fx< za4fLM_#c5gLl-pHfV)E%k+J~yCYcT_x`>xBENU!*aCH8fR7+%wDv_m7@1xN@3Vkm0 z(j|olE9lvF>$b+RO7%CKwM)_Wrjw9Na?WUP0)u$o!kzhNY=0zmm5h7hPuey-`qAz;+|x2AP+zC5)z=Z_q%H4JJiIM`R1RU@ zphUQ*2zeAlGSQ;8at3WtEASXVd@cI^P>bqTD;6MoVQ&<{q+U?wT8@-kbNg@F4$$JNkpNK#Zj9I zwOb)Mv0;XmG(AA@8lOc?to9$|my((m8s%L9@kjoWfqBe$q6p6xHKy7NS2l=Dv#3$k z#35r85F{6}i8Af6jO-CME>4@*A4e8QMsdo~fCBN?5qXcH=nSfGF;vanEOHwv zG0i7Rs<5bGyuiSkdCjZS;ITqOXc$U`Asz?)`85OUlCcb*q8w-v^1&VrB)8;FND{YtLxIbnmMJ<*ocW|J1+RSeOu+>jO3@Qd;|tAt(vkS5QBw0; z7CDBf$07Ys+mk{?ik(&?6pv&nY#AQmWmb3MmV8?M8s`DMSWrf4wK3H^HLj>%|AYa7 z@GtUXS2Gv*uTa}p5hV?GyFPf@c2L_Pe%PFQ`ji-5l*#tU6rwDtk2DkI_eTx3qJ~Hu zaNAHHicb_YMzf^2JVHfRuptOhK=si{+Z#{Xn1#(F*f)rqa)H0AGiEpp@l_vtMFP!y zEdGuJJEAPDGb9<3<aO_G`<6W~R4DFvQMo(}wWU339a-l-?bgE~nmLr`&e zGA-I4fbq0ytZ^BnG5Mv8D=?aVP+KSm>J`YpzB|8vA{+E|P2G%^DFinc z<_<#R?LvqV#ku_-wnR}>(@^yr9QR3|RU2%iX2Bfzo2!eSK5S3Ds>Gp`o>f&`Q}b?9 zmM-7G+d55|NiKZCJNU3pQYxS7!?wuT*SXw`b&6;fLCA$^wCFK1- zvqVY_TZ%W2e8J^5B(OaoH>W@kJh4uP*1>q#Xl`shjvQbE!_401fD{9Y$1(Uh1obnDhuD6< zg-60u(_Ev1D^A+7>{^p@Sn%jx$Imop5xO-fiYIL|xwScK?ph3QyU}+KXv@9*SgYn6 z?B7`RGz^XHjFhmHeknK$gw$KhhxoBDudEZ~#GC1urB-DT!SOoJ@?*_@@$Nee8_`xV>% zI<6NlD6t6Ah7=v_KsfO)`oknfP@!D~ zXlWwXv|!`M6<4)2N4E?yIj+$jc1rEF@9FPPe|MNZZtN}ApdnZR^*>Zg(L>FH5 zAS#aRKDq(=bf{%ebD&b7W?kn8TQFmWwqCTGx73XoNRW_Q>NNE5qVnHTTcC#}QJU)l zH>(+@ki@8I=&>FNbA{D&yFT=kI=)7XS1#M*_qgTUQa4+dz;p}u-efuS4OUTAZ$a)? z3|4NbkI}gc-H!84qB;0bm3#o)*PT_f)MY@w*gF@WRo~-jfviAYQ^f;YvL5oG$9!B% z)*&Okp}R?jeD%6q^YzNb$Cea9{5bQL zI#@BLSj@N7aoo+w*2$}D`DaEJJ>ueH<5WSCok>F6kd7kQtiYC)B#X@ir_*q6mzQqNiq1*g>iROunsyi7V{Um=;2iSd*g#Dhav^A;QH&)Bmi zVtgqXb)r^^)Z=dAAlYatw&m~MMvOT7Fp#1(J5*{)tEO)~Trd zrju%#%`GVgdT$%VjbfuxWSsbDOii5QKs(S2DbRcXAty0Sd~9)M>f&xav{8<~9j++uqc4TutLETd{X!NHO4i$27TK<*$Zgc%RAh z!&!SNjsFj*YVGVu2zSZ~={#g9Z_C~&ljN3>@9B`v?vnsxVjr)KUdW6LmH zD=>FSjHy@+;o*^NEUMA_k*xVk&1-Nt@o+o@Zi>}ktGbAb8}-D3t`s+yA-~m4)l$Ab z^vjggRYsHOu9ELlnh0L0OUA?1#4km%iNPN{!g!_Nhm=;WO{jmmdaZKS_8yWb5+Z;% z)vN4ZG3&#{vVSdK&ubFbgwal$&h|GM%+m@Qk)>i1tII^y0yV z7u&Kmk`%#TX~+D1+-i|OA(d(~T&kCj^g5{?wDL9WSU`qcyL0W^L$jDhaJr%WE3>{aW*k-!f|&&IXBNAyEyuX$BlB zA(k9z5?n=ZpJ^7tc9nP@4hKHbn~9VDIK#!m+q2;I`~HuBCcF?3&Vo52{>Afv68W3$ zSyOp^4gat`JKrJ7`d->n#4!$WtWO*Nf>(pnYk#*kZMS}DdC>B!-y5ghS8xSjZUil zmDIFmQBf&UiEor#e$w`1gE?iU`BK3y3{NZ7F;({*x;x^DQ58;FNINRkA$(m7Yt|#7 zidb4A!55(<*b;Mbw1SydVk{@EuT=jO9olmb?NM|p)jQT)Bz&cM)5V~BRESZLU76=yjrRS3Qf?8G|DxGguc6Ek|a zDVaFkg^Oj7K>mDpC-#cGMd6;Y%&%Lqde|1f?=^F{`G*!EmPizkV)c0Kp2H6&_r_Je zkucq|O*0P&oEvzf#mE+a_+RuBb|HLnEUH)*KM>1;B^Q1rmc>dlxl3nOBpLY+o!M)W zEAQ9^GkHHgpbP7p@i2~&-rXTC(1VfwFEJ9*mk|y0rF|Ir9BLx$lVMi`^&8Y9s3GZ$ z%#3H`0o+?dtxI5}6siHdyb>7+hUyD74C(}UPlhi1wC~ACzHoys%upE)PyovsD4b;= z;r$u;!}OehtW9F10*rrwDuU7tWTXXDN2o+7!N?zh2miyA{DMGnXo8G|dpY?24&?=N zvnl`ZZHzz$Ea34w5dIAnGl-Elpmsw&fNC?Ck=LN!gAyKUUI;{(b@=+J|FRSIGo1nT zg!^(4k)hx@j1fMZk*pC|6oi^Fl93A;__Ok5Mh=Vvqw$P*OkiX+Jn!rUCcQxn^V*4w zY?_3xpUlV>xZOx$WFPcPP%2c@SC9=*J)wp{r9xeRs(|VO+Hgdu@oWEYJ>f-%+s?0i zX4i2l@($|jX^dP;#n*z7KUBkLM!p}5$j(67d6l2-#$F9*Gf6{UAEqH6y{sV-BQzv< zf`+Vw-JP-A6vw{xJX)OyvCXvu6Sozs2dWF@?(7@M`?k6X>uH9N#D2j8W8hG(@*_Ri zn2CRn){sl^EDh0+>rh?CX~>6THKZT58?s)KC>rV9@6W1z^fc2ou8YR4;+AqwBt>Cv5bH}tAx)~2g&~&c&dYo z1+M_~Vh7Oaz1ey|IMIb|}>>&veDzlIwS z5|r6XeeL?_a-D2V!?l4uw->AP3)d!KM4ZtV^dCd5MED;NMi>Ce#kZ#{()I{y69+;~V+`|A;sa1|9+YJLpdV&q7A;2QCI5 z5}H~V+mC%N1&Oa-h|m@E;>F|P6QTYEj@1ZJo={lTpS>%06-1xHs~|cLqN^a<1_BE9 zGVna861W{el)eJ{??Jm~c;OdGtWF+!6CU0J#~DaJ7g6ZI>_x&=@Vo_TKhy`H-3+w| z3^pKu(a8BXksb|*VKD;hIjQjeAojLAhJmO8AKVE95203oaVrqbKxP#ppj5d31yv84 zcc5Pe!+p@Lps^u_?nt1~U@X4uW#F6e^JHYnJiM^aD{PAFtwo+kKn;ZY4gqc+TKMf$jDfYy z@R4s%<}kd)S4?Ne;-93mHuBjjUYw3KH$7L=*=ycQ8n8cMbQ=_q;)C%@nff!X zBc90uUHhX!qDb+r6M4=|)*)1w?FYP+U=41M4%a*w;j6TC$F;Y?x=cbsPTAVo`JI_; zLB{BP_5<$2w5DF>H3d?*8{$Ah+L?}H-etsaCI%>`o>`cx}^doj@l3~Swodf>!$=3%$w<2KKF?3P&?sr2OswZ)qHr&?NUc|Lv7johCexqD#g$Ze40fWMJQn~HD?J?}h+P4~w|6}7!+Zh}YYz4YsLJ_Eg8dHL7K-^b zgVT1mjeqnOONhLpH12(gDW*6Ma9#bvDz-UX5%87T(@Y$(r%Ink-2N7O*JnCz;zf>N z1~IJq=V|3?UacmDM`tl#uVK$!;;W{^NBu@iFcpJT6;ajw5gF# zd{rx0hw(S(v0$$&|FU-DpU-3d-o^j2uC3ue&tpdK|NP6oqJ}@6$Nao={$+ozhDXk4 z9Za(0O5d0)V$4lOR;xT2nQtsoYt;?Om}CHn%LO5hs_e?dzKS;<6m*oMRK zRh(a2zXZ0_cWbn`(NbHT`F0E34e{Q^fmUd3#P$G?rBt1$n1mI=iOI#&yZf zu;@~xdg1*&7Ghd~8v0bh)yzbSTxPcrJ$gKslBI)|4WyAiC)SxZnV994-6u!FUqenC zREP#!;8RguR#!FdAmO1L9CUpTGxIO`EAO$E-W}Cvc{Z$C)SDT2ZR$PNDahkr_K8)x zl#P})rqM~q)cPu3`5yE099s{$3S}w!f+E|`PdQt}IyAjpCHP4eBnAqT;ON5pFJe)x z{<6=-lZP!d?FS}SlUPv-f3xp1aZ-kL9ytGB z_B*Yb6e&XNbCu(9Ae^TZ3B8n@m^D>Hwj)80Wn!R%1b-XmRv4Q>$Sn965<7A!@9{p1 za~)hojCA`k(S$5|p9M8r^GFI4`!gcdK0>OA+gSAcyZ2ekX1ad`-CHaracMqlmQiK> zKNB$0O3jJYnW?cUdK?HR>s|73o5Ff=t6q`q!>2kVj0l5-HQ=Q{61lDMZOf$t5JxfC zA>qq$4Wg%seWLlKTz#yxF)c-W%5j6)r^!pO4s%SMZA&V^R^>|!pjU$Y;#cTB7#{PWzC@1(sL755880T7#v1X7MImS?YGr`&Q5OnKhYI_@T z`WRMinWn*jl&lkPqFOShxginF);>jZ21v#^1L7Pnz~RNiI&n*qxI9Y5%a&qKSG?nw zb0`j3;DNDU3>uTd>UgmojCydYs*UONUI{@_M=K_UYEbiT)DdGO=)SB@a?*Y4pmPCT zgY9Ryh9+kmQ#U+!-r{i9IGl^%+yb6IcrZf)!k`+gOkg zZA}S#+klrfHON7x1Y)F?T&o{ULIOjLDM!^CxT919p`3~amKs&f|#W$JNU#8SnD{yIue;Ob;^xMQ`h8B zlUC_nr$fUzrgZH+FJchqiU)QYpg?RIeP7MHe#pi}ol@7@ew`f!yVGil)iV34`ZXj0#n|+!y7hqAbL@sxSpdJC z_~8%PcuB*XE@vTfZ@lNYoJGs?>$!P3>tyt**X1ig(f;xxMLAP0il;y4< zMN9dSDGnh$*&kOl7dd1wdSVOs<3}2kl$}|?QlcR# zRA`enM`jsUisy<_Q!+`hErSQIU@hF!Yx~wpo);Ub88)9JEEen_R4SNdO zL%Qu7^9kF#4N=Kw?aMGG5T?2O=qeW0dtgH_i1*8)p1+}dLQmNGHpt=2><2I}5Vu76 zC7-axHKh7WT{P{Nf=(?Z;ljQt?ECW;t67WA`=5$8fbYujsEy0)-*ggtaC&9#QF4M! z(~#q+hI^p?g!-?jlCU#Oa79|dgrCHf9FM)ZR!~9;B2IhBR zE_RsbI?Qjue8yp(nY97#=}#>wg8lTY6)>g3HQV7jDa)Mh7P;ZXJma^p9}D|PahO;c zp5+bmFqrw0kFW*4=L!GoBkWgZ)^pE~*)nNw;rfqJiRJGe@xQW}A3K6Rle@0NdRG3s zyu&)y!=vw>#;(f;d@l2o>sV91Vjc4dAM_p}iDuo8OYiA00v0bJ>yZtCpcZnHxX2px z-wOKH;e`%T3R3!<^om+rC`d(Xq6g^;?vcZyTrYuCUvNdeQpgi>Sc+VQ+jnxXf*8iH z<**MzPAtYTK^%Ie??c?F0Pj$Mv^V&Ot87GoCH(#MENc31AQKJzxPrcBYW6S4M>#d% z^`pjy?277D*x0y>fWN9|xP*8o8gyfbpz2nhlH!LA)&^T;1HqDET+y?DY7aK1ga~M5 zJ&)hQ0(is*)+cCEeSCo-Y$@&>@S#gnh_w}EDW_8mMIv?w4)P@%*ihdaHFs9rHeYNZ zJ@^sl4y6Y_NJnrl8~@)1HqUqC|BKt28b0R}*4EFA`HIg8u_{T7dPk4sZqg}ppYpw* zunrSmc|<}*r8l5)Ibj?3NP=m%?CCI#aJVg^ZZLg~rY8B(2lkEROS3*{y?vwMh?-GD zjLYnLDGrUA0nLGE9(F=;C<|t58=0l;YTSk-W{G)N137MMi)W}UNE*Fz|Iwj>@U$3H zyA)|#tI#9r*=pX8vv$K*=VCh+YGNL?jG#m&5D2S^$K*vHaz$--KslhpG}|35do#qj z2oe(67{j=OOLjF0X`S+F%Gcm3%qyySF=sxrE@U)jXC~xde#0Q6krO#!11Hf#2tGMZ zJ_h)k@tlttH^v`PCs(sUk)|}0xU8wcb{8C;7TtJ(=k4b_ukPpZxvYcdSa1_k#Ud7M ztN9{404RG^^KWxmz_@kj5QJQQvrIxNo^v6}XOEu6EOWp3#+A>%(aRwP;*NpR5%sPr z2BD2#dEE8^23yj$K!gH80^=rT9Nr#WyFgfBH%sF zLeTYjz|uA!1l&Q@BJ-s6+CgBnUNcCufvzV?$2wfQhY0)uUJs%AZf-1WBB|QKt+9xF zw(nWp-L&tYy4wz+MHWy~qTPLBVoGL;#D{HRF1#|2>G5*xKdoIeyQt%S+_IH1!|QMm zBa%pzx8pV(bu#9&W8Se@gs2FfLJxzQoW=jjXFWV`?|s%L9kUWsSut*iOH!_t87LOzHfgCXZ(X>+ zy{z;9o;!oR_51z)^ZA@P=XuV0&pr1n&v_Q=jhc+882ZIl{-J<{UQ`HB9PPD@?;G%l z7ZnK9UE1{>-ViYAzfhG76{;Z^zRw^(JJ`<)b}U=b8V7`m>e2lh}yr zR*REB8LMC$Yg=i<6b4rDNK9g^t~e)s^&S4Y&Vv0-5mqwzZxr#doeRAy87sQKR*vW0 zc3J6-m{j*h&ZkNbDi`rD@MZFA3SIIpf4~1>jc?UYJgn?*rbphzczx$s&N$^@{z4w2 zB3o^l&I)y{B{1Pp)gXl=3zTXuqT^zyB}2jM*3nB!l`yo7s=t? zcGrhYs&k8F@v`wffY!4&{N;# zTsavEmmaRzwJ?(<_f~DvsD>em_wC@ReK=c-x`$9lF=y)36NJ=0w~0)H9zGf6mS zvd~~@lH^$I3HOpTdYrpUDrY#W@`ESUwJbfW`VIEP&W=I!gD7<7|EI-Fh>4u2CBu?% znFi*iD)~>v;bd1lAab|p?Y+tzcPEn&YtC_Q@PGF418OVTBA26Gz~vmL)$j5X9!aY! znw^A0OUL9R@)HOLmQ8AKFWoWQH`#1GB2TUJNp``^))D#PI$Jth#;h0t_rtvaHy4ge zy`(z8o2cSyiiPu7m_GL&-)H16^*d(3HoIxZ6n;q3Kov%RTa?shePNq&p~)w8>u4Pq z#;WAI4Sec0gqfj$n+>_B;;MkVNqYG`eq1+SC`DymyQbz9bRbN8)YE}G_{0#4cI1TO z>Kf>L9zqQ1vstPqYv{{6cys6RH7xB&?QD@!PY(c>3qqXe5g1@rodUp{#aoXmr5JZ+ zV<%1gimd+@_8FpmeQ?#lxW$->LqCP-3S=R@(nFHE@Q5L}sQ6ZHZr}`zOokqfKdNlN z;>}882PU%lTe+#O4d2TVIc0y~L4OEixDyoB?bugPR)x;;LsyTI9s4G0kN{|?%sSn% zkANvR#2R=!4;}j^KB=92Sjbm(%%Zj1()qYA#E4WhmNm2->-J85P{1WeJho8_v4bH} zCFOSUlRAyTR(qXh{Np|P#4f(K-zEoBs6DNbI(Fe;ajcP;U#b+G1MEo?J+$EdZSl)V z%;?JWtnU3oVRMY6vCfQ=h9&!gGJ8b+ur?8Qy+hE>6}2Tb?g#u%5RsUUX6oNkGg-<$ z7^?3sXjOWEfW`dNt!8U~q@Gs`cJeY0ZbX~TihaBIZteo6pObA6+{%;Q42@V#SjMte z&XkbD-d$0H*&2=_7NY7fZ6rRVQK})>(Pp*=BPIM5Mc16szTE=PD8KM4= z1HzPx3k4tW*Yd7#tIkEYzt49LAt&lEUT345m%zOWHy!Tb+4S@G`9$$%o7w4`DniIl zKOT}_IUZ)(t9}@k$aPhqVIS~ey3vhv$On9c|G_rU^6;3@Az4RlAMoMb*#KtS`0h#n{Q=*v+mxp1Fs{fMFTwcZTtkI&v4x&P23>U?y^W&o-`^r;g*dC^k#&93 zetyMd7m`ElM%>Du*4F*Rq$+u@lYNBMnD%op8djC~fNXROGb(IWB^C2Vu9>D6^L>Z> zvK!)^SW2N3;9ep5-pxamJRc0OHGZc=licPp=>| zzbqivQ70?%uJe_wSDZ{^Vgd>;wBM3PWAe=dY_h+b#oz;gcclH*`a$<9?uCk3If-aH zqJBd~*^)9_VJ*`S!AltHtS*>JdGFWru`u31rWBLw6H-1;bq-X@Zq0TrO z5yNriKW^Sy;Ov;{xN9TCpx;1ick|sQ#NcCrp%|P|n0iTaBKgG?Eu29KwTu%TJGUvg1%GB%eupexEL7cG-=)VpL+V~ z9zIz2h(y2L!&?STR{L5>RDdfwJKCG#L_KIHv+sgtP{mmPhlCGKw{IW)#}!t04(c|Q z(BU6qH8$1Lr#{3Q`tN$g+n8`eI*k2I>$=`sPKSC@#tq(h*PpD@@V9WGoepbvC)H^N zwxS{&H9dQK8XJn4wdwY!FuS_sU?tril2wHj34V5!JRSZeH8$=AXNcCK$zHe`N5(2S zxi)`64`-_WaP#uD{Ax=g~jSdB65hYmZ{#;AG= zAyegJi?*JD9pZ;Tr>xFFSGLi~d-;JAx3!%``Has#Nt|mxu54;cgxth~kWymM8*PcR z*`3VBy9K0Aav?@nf9ox|WBp;DWw=|7;t1YDs#G@0Ss>gf5s{Ag|$?eY;H9nylv zum(lH?HO<7^ZcA;%BwAO@<)(9euQRy#NTK7$otYS$$uPT)Mw>jN2sp!w;slT>Y2@L zIF60v(U17EqqekiTTZDZf(r49j~|(}AjEoBEw*${9&YWNdQ0wJcNRBX1{B3*J6XybNftB3e`-ocq1>U4{* z%_q%*xplotBR;{pw@k$@3F&t_ifq5j|8AIt`;=`4PuBhc`# zlo2q{S0)da=D`3|9=R;vYDjJ<>|Qw91N&58mVapQGw7|!DIJOh*JYS~7!R=sKSPJ& zGAskbtR40|l={&4!*Z)a#NfAvTgUWDef@3{*PtwJCg$0d43*@?yx2@#pYXw*pZR_W zl>1)R9{d2zE0*x%VIKV95`KjL-Bxp1FhsKIm7m(^#u7eu^rQLEK4M%$K7?a3KZTgJ ze}T|^hd)=4$zKC* zbx?ejI-y%M#5wQf_VSXA^r55z?U}kBU0_eY7*VBW+ z%|A+BH#G1#n=ExwAO?xAbO|e*AWg=5&G7Ma3jL)p*xR$Qpwt7QnOZ0iq3K$v6GEzw z=)8p62ReKoADLKC-`90XZJErLyfS%MUH9bIRUUNiGC85HE5cyuLwG

HE6sLk3#8 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

$R`iTFDaZ^U-?^s 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 Bkv{+c diff --git a/package/libs/libiconv-full/Makefile b/package/libs/libiconv-full/Makefile old mode 100644 new mode 100755 index b75a4001d..e39319ef6 --- a/package/libs/libiconv-full/Makefile +++ b/package/libs/libiconv-full/Makefile @@ -49,7 +49,8 @@ define Package/iconv TITLE+= utility endef -TARGET_CFLAGS += $(FPIC) -DUSE_DOS +#TARGET_CFLAGS += $(FPIC) -DUSE_DOS +TARGET_CFLAGS += $(FPIC) CONFIGURE_ARGS += \ --enable-shared \ @@ -66,11 +67,15 @@ endef define Build/InstallDev $(INSTALL_DIR) $(1)/usr/lib/libiconv-full/include + $(INSTALL_DIR) $(1)/usr/include + $(INSTALL_DIR) $(1)/usr/include/libiconv-full $(CP) $(PKG_INSTALL_DIR)/usr/include/iconv.h $(1)/usr/lib/libiconv-full/include/ - + $(CP) $(PKG_INSTALL_DIR)/usr/include/iconv.h $(1)/usr/include/libiconv-full $(INSTALL_DIR) $(1)/usr/lib/libiconv-full/lib $(CP) $(PKG_INSTALL_DIR)/usr/lib/libcharset.{a,so*} $(1)/usr/lib/libiconv-full/lib/ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libiconv.{a,so*} $(1)/usr/lib/libiconv-full/lib/ + $(INSTALL_DIR) $(1)/usr/bin + $(CP) $(PKG_INSTALL_DIR)/usr/bin/iconv $(1)/usr/bin/ endef define Package/libcharset/install