The module is 7620a Wireless relay module, support automatic scanning, automatic dialing, support Chinese SSID configuration (need codec module support)
The wireless driver needs to increase the WiFi disconnect and the connection signal sent for Application layer processing events.
This module is for reference only, if you have any questions, you can contact me.
/* * WISP.C * 7620a Wireless Relay module, support automatic redial, support Chinese SSID * author:dxt1107 * mail:[email protected] * 2014.12.04 */#include <stdio .h> #include <stdlib.h> #include <memory.h> #include <arpa/inet.h> #include <unistd.h># Include <bcmnvram.h> #include <shutils.h> #include <ralink.h> #include <bcmutils.h> #include <etioctl.h> #include <bcmparams.h> #include <linux/autoconf.h> #include <signal.h> #include " Encode.h "#define WISP_IFNAME" apcli0 "#define Stat_link_down 0#define stat_link_up 1#define sig_apcli_linkdown SIGUSR2 + //37#define Sig_apcli_linkup SIGUSR2 +//38#define Sig_wisp_debug SIGUSR2 +//39#define Scan_interval 3#define check_network_interval 180#define diagnose_interval 16static int wisp_debug = 0; #define WDBG (Fmt,args ...) if (WI Sp_debug) printf ("dxt1107\033[0;32;32m%s,%d" FMT "\033[m", __func__,__line__,# #args); struct wifi_node_t{struct wifi_ node_t * Next;char Ssid[64];char Bssid[32];char Auth_mode[32];chaR Encrypt_type[32];char w_mode[16];int signal;int Channel;}; typedef enum WIFI_STATUS{STATUS_INIT = 0,status_auth_ok,status_connected_ok,status_internet_ok,}e_wifi_status; struct wifi_node_t * wifi_head = null;struct wifi_node_t g_cur_connect_wifi;static int g_wifi_node_count = 0; E_wifi_status g_wifi_status = status_init;static void Update_wifi_status (E_wifi_status STATUS) {char buf[16] = {0};if (st ATUs < Status_init | | Status > Status_internet_ok) {printf ("Error,invalid status,%d\n", status); return;} G_wifi_status = status;sprintf (buf, "%d", status) Nvram_set ("Wisp_status", buf);} void Show_all_wifi_node (void) {if (!wisp_debug) return;printf ("dxt1107########## #begin show WiFi list###############\ n "); int i = 0;struct wifi_node_t * p = wifi_head;while (p) {i++;p rintf ("%d ssid:%s,bssid:%s,channel:%d,mode:%s,signal:%d \ n ", I, p->ssid,p->bssid,p->channel,p->auth_mode,p->signal);p = P->next;} printf ("dxt1107########## #end Show WiFi list###############\n");} void show_one_wifI_node (struct wifi_node_t * p) {if (!p) return;printf ("dxt1107## #ssid:%s,bssid:%s,channel:%d,mode:%s,signal:%d###\n" , p->ssid,p->bssid,p->channel,p->auth_mode,p->signal);} int Add_wifi_node (struct wifi_node_t * Item) {if (null = = Item) return 0;item->next = null;if (Wifi_head = = NULL) {W Ifi_head = Item;} Else{item->next = Wifi_head->next;wifi_head->next = Item;} G_wifi_node_count ++;return 1;} void Del_wifi_node (struct wifi_node_t * item) {struct wifi_node_t * p = wifi_head;struct wifi_node_t * prev = wifi_head;if (NULL = = Item) return; if (wifi_head = = NULL) {return;} Else{while (P) {if (!strcmp (P->bssid, item->bssid) && P->channel = = Item->channel) {if (NULL = = Prev->next) Wifi_head = null;else {prev->next = P->next;} g_wifi_node_count--; wdbg ("dxt1107bssid:%s,ssid:%s,channel:%d,cur_count:%d\n", P->bssid,p->ssid,p->channel,g_wifi_node_ count); free (p); return;} Prev = P;p = P->next;}}} void Clear_wifi_list (void) {StruCT wifi_node_t * p = wifi_head, * tmp = Null;while (p) {tmp = P->next;free (p);p = tmp;} Wifi_head = Null;g_wifi_node_count = 0;} static voidwisp_signal (int sig) {char signal[] = "XXXX"; int pid;if (sig = = Sig_apcli_linkdown) {wdbg ("dxt1107########## #w ISP link down#############\n "); if (PIDs ("UDHCPC")) {snprintf (signal, sizeof (signal), "-%d", SIGUSR2); Eval ("Killall", Signal, "UDHCPC"); Usleep (9000); }sleep (1); if (PIDs ("UDHCPC")) {eval ("Killall", "-sigterm", "UDHCPC"); Usleep (9000); } unlink ("/tmp/udhcpc");p rintf ("[%d] ssid:%s,channel:%d,change status%d==>%d\n", __line__,g_cur_connect_ Wifi.ssid,g_cur_connect_wifi.channel,g_wifi_status,status_init); Update_wifi_status (STATUS_INIT);} else if (sig = = Sig_apcli_linkup) {wdbg ("dxt1107########## #wisp link up#############\n"); if (G_wifi_status >= status_ CONNECTED_OK) Return;symlink ("/sbin/rc", "/TMP/UDHCPC"); char *wan_hostname = Nvram_safe_get ("Wan_hostname"); char * dhcp_argv[] = {"UDHCPC", "-I", Wisp_ifname, "-P", "/var/run/udhcpc_wan.pid", "-S", "/tmp/udhcpc", Wan_hostname & & *wan_hostname? "-H": NULL, Wan_hostname && *wan_hostname? Wan_hostname:null, NULL}; int dhcpret = 0, Trycount = 3;while (Trycount! = 0) {Dhcpret = _EVAL_UDHCPC (dhcp_argv, NULL, 0, &pid); if (( -3) = = Dhcpret) {trycount-= 1;dprintf ("# # Pull DHCP process fails, retry three times pulled.\n"); Usleep (20 00); } else {break; }}wdbg ("[%d] ssid:%s,channel:%d,change status%d==>%d\n", __line__,g_cur_connect_wifi.ssid,g_cur_connect_ WIFI.CHANNEL,G_WIFI_STATUS,STATUS_AUTH_OK); Update_wifi_status (STATUS_AUTH_OK);} else if (sig = = Sig_wisp_debug) {Wisp_debug = (Wisp_debug = = 1)? 0:1;show_all_wifi_node ();p rintf ("ssid:%s,bssid:%s, Channel:%d,status:%d,count:%d\n ", G_cur_connect_wifi.ssid,g_cur_connect_wifi.bssid,g_cur_connect_wifi.channel,g _wifi_status,g_wifi_node_count);}} void Hex_to_str (unsigned char * str,unsigned char *Hex) {unsigned char *p = hex; unsigned char *p_dst = str; unsigned char tmp[8]={0}; strcpy (P_DST, "0x"); p_dst+=2; while (*p) {memset (tmp,0x0,sizeof (TMP)); sprintf (tmp, "%x", *p); memcpy (p_dst,tmp,2); p_dst+=2; p++; }}void My_trim (char *s) {size_t len = strlen (s); size_t lws;/* trim trailing whitespace */while (len && isspace (s[le N-1])--len;/* trim leading whitespace */if (len) {LWS = STRSPN (S, "\n\r\t\v"); if (LWS) {len-= Lws;memmove (s, S + LWS, l EN);}} S[len] = ' + ';} /* * Function:parse_auth_encrypt * Description: * input:auth_encrypt * output:auth_mode, Encrypt_type * Return:none * author:dxt1107 */void Parse_auth_encrypt (char *auth_encrypt, char * auth_mode, char *encrypt_type) {char *p = NULL;char au TH_ENCRYPT_BUF[64] = {0};strcpy (auth_encrypt_buf,auth_encrypt), if (0 = = memcmp (auth_encrypt_buf, "NONE", 4)) {strcpy ( Auth_mode, "OPEN"); strcpy (Encrypt_type, "NONE");} else if (0 = = memcmp (auth_encrypt_buf, "WEP", 3)) {strCPY (Auth_mode, "Wepauto"); strcpy (Encrypt_type, "WEP"); else {p = strtok (Auth_encrypt_buf, "/"), if (!p) {printf ("Invalid type:%s\n", auth_encrypt); return;} strcpy (Auth_mode, p);p = Strtok (NULL, "/"); if (!p) {return;} strcpy (Encrypt_type, p), if (0 = = memcmp (Auth_mode, "WPA1PSKWPA2PSK", +)) {strcpy (Auth_mode, "Wpa2psk");}}} void Update_wifi_list () {char Channel[8];char Ssid[64];char bssid[32];char Auth_mode[32];char Encrypt_type[32];char A Uth_encrypt[64];char cmd_buf[256] = {0};char Signal[16] = {0};char W_mode[16] = {0};char * conf_ssid = NULL;char * CO Nf_ae = Null;char ssid_buf[128] = {0};struct wifi_node_t * new_node = NULL; FILE *FP = Null;conf_ssid = Nvram_safe_get ("Wisp_ssid"); wdbg ("conf_ssid:%s\n", conf_ssid); conf_ae = Nvram_safe_get ("Wisp_auth_encrypt"); if (!conf_ssid | |!strlen (CONF_SSID) {printf ("Error,wisp_ssid not set."); return;} if (!conf_ae | |!strlen (CONF_AE)) {printf ("Error,auth_encrypt not set."); return;} if (Is_cn_encode (Conf_ssid)) {Hex_to_str (SSID_BUF,CONF_SSID);} else {strcpy (SSID_BUF,CONF_SSID);} Do_system ("Iwpriv" Wisp_ifname "Set Sitesurvey=1", Wisp_debug); sleep (4); sprintf (Cmd_buf, "Iwpriv ra0 Get_site_survey" ); fp = Popen (Cmd_buf, "R"); if (!FP) {return;} if (NULL! = wifi_head) {clear_wifi_list ();} Fgets (Cmd_buf,sizeof (CMD_BUF), FP), Fgets (Cmd_buf,sizeof (CMD_BUF), FP), while (Fgets (cmd_buf,sizeof), FP)) { memset (encrypt_type,0x0,sizeof (Encrypt_type)); Memset (Auth_mode,0x0,sizeof (Auth_mode)); Memset (channel,0x0, sizeof (channel)), Memset (bssid,0x0,sizeof (BSSID)), memset (ssid,0x0,sizeof (SSID)), memset (W_mode,0x0,sizeof (w_mode ); memset (signal,0x0,sizeof (signal)); Memset (Auth_encrypt,0x0,sizeof (Auth_encrypt)); memcpy (channel,cmd_buf,4); My_trim (channel); memcpy (ssid,cmd_buf+4,64); My_trim (SSID); wdbg ("ssid=%s,%s--\n", Ssid_buf,ssid); memcpy (bssid,cmd_buf+69,20); My_trim (BSSID); memcpy (auth_encrypt,cmd_buf+ 89,23); My_trim (Auth_encrypt); memcpy (signal,cmd_buf+112,9); My_trim (signal); memcpy (w_mode,cmd_buf+121,8); My_trim (W_mode); if (strcmp (ssid_bUF,SSID) | | Atoi (channel) <= 0) {continue;} Parse_auth_encrypt (auth_encrypt,auth_mode,encrypt_type); new_node = (struct wifi_node_t *) malloc (sizeof (struct WIFI_ node_t)); if (NULL = = New_node) {printf ("malloc wifi_node error!\n"); continue;} New_node->next = Null;new_node->channel = Atoi (channel); new_node->signal = Atoi (signal); strcpy (new_node- >BSSID,BSSID); strcpy (NEW_NODE->SSID,SSID); strcpy (New_node->auth_mode,auth_mode); strcpy (new_node-> Encrypt_type,encrypt_type); Add_wifi_node (New_node);} Pclose (FP);} void Wisp_init_config (void) {char cmd_buf[128] = {0};d O_system ("Ifconfig" wisp_ifname "Up", Wisp_debug); sprintf (cmd_ BUF, "Iwpriv" Wisp_ifname "set apcliwisppid=%d", 0);d O_system (Cmd_buf, Wisp_debug);d o_system ("Iwpriv" Wisp_ifname "se T apcliauthmode= ", Wisp_debug);d o_system (" Iwpriv "Wisp_ifname" Set apcliencryptype= ", Wisp_debug);d O_system (" Iwpriv "Wisp_ifname" Set channel= ", Wisp_debug);d o_system (" Iwpriv "Wisp_ifname" Set apclienable=1 ", Wisp_debug);Nvram_set ("Wan_ifname", Wisp_ifname);} void Connect_wifi (struct wifi_node_t * wifi_node) {char * Password;char * Ssid;char cmd_buf[128] = {0};d o_system ("Iwpriv "Wisp_ifname" set Apclienable=0 ", 0); sprintf (Cmd_buf," Iwpriv "Wisp_ifname" set apcliwisppid=%d ", 0);d O_system (cmd_buf , wisp_debug); sprintf (Cmd_buf, "Iwpriv" Wisp_ifname "Set channel=%d", Wifi_node->channel);d O_system (Cmd_buf, wisp_ Debug), Sleep (5), SSID = Nvram_safe_get ("Wisp_ssid"), sprintf (Cmd_buf, "Iwpriv" Wisp_ifname "set apclissid= '%s '", SSID); Do_system (Cmd_buf, wisp_debug);p assword = Nvram_safe_get ("Wisp_password"); if (0 = = memcmp (wifi_node->encrypt_type , "WEP", 3)) {sprintf (cmd_buf, "Iwpriv" Wisp_ifname "Set apclidefaultkeyid=%d", 1);d O_system (Cmd_buf, wisp_debug); Sprin TF (Cmd_buf, "Iwpriv" Wisp_ifname "set apclikey1=%s", password);d o_system (Cmd_buf, wisp_debug);} else {sprintf (cmd_buf, "Iwpriv" Wisp_ifname "set apcliwpapsk=%s", password);d o_system (Cmd_buf, wisp_debug);} sprintf (Cmd_buf, "Iwpriv" WIsp_ifname "Set apcliwisppid=%d", Getpid ());d O_system (Cmd_buf, Wisp_debug); sprintf (Cmd_buf, "Iwpriv" Wisp_ifname "set apcliauthmode=%s ", Wifi_node->auth_mode);d O_system (Cmd_buf, Wisp_debug); sprintf (Cmd_buf," Iwpriv "WISP_IFNAME" Set apcliencryptype=%s ", Wifi_node->encrypt_type);d O_system (Cmd_buf, Wisp_debug);d o_system (" Iwpriv "WISP_IFNAME "Set apclienable=1", 0);} Static char ping_domain[][32] ={{"www.baidu.com"},{"www.126.com"},{""},};int check_internet (void) {int I;char read_ BUF[256] = {0};int len = 0; FILE * fp = Null;char cmd_buf[128] = {0};struct Hostent *p = null;for (i = 0;strlen (Ping_domain[i]) > 0;i++) {p = Gethos Tbyname (Ping_domain[i]); if (!p) {wdbg ("Get Host name failed.%s\n", Ping_domain[i]); continue;} sprintf (Cmd_buf, "Ping%s-c 4", Ping_domain[i]); fp = Popen (Cmd_buf, "R"); if (!FP) {continue;} Len = fread (read_buf,1, sizeof (READ_BUF), FP), if (Strstr (read_buf, "+ bytes from") &&!strstr (Read_buf,nvram_sa Fe_get ("Wan_gateway")) {wdbg ("ping success.%s\n", pinG_domain[i]);p close (FP); return 1;} Pclose (FP);} return 0;} /* * Function:update_wifi_info * desc: For page get connection information * author:dxt1107 * date:2014.12.08*/void update_wifi_info (const struct W ifi_node_t * p) {char buf[32] = {0};sprintf (buf, "%d", p->signal), Nvram_set ("Wisp_signal", buf); Nvram_set ("Wisp_ Bssid ", P->bssid); sprintf (buf,"%d ", P->channel); Nvram_set (" Wisp_channel ", buf); wdbg ("wisp_signal:%d,bssid:%s,channel:%d\n", P->signal,p->bssid,p->channel);} void Check_wisp_status (void) {int sleep_ct = 0;int Wifi_count = 0;struct wifi_node_t * P_wifi = Wifi_head;while (P_wifi) {Wifi_count ++;update_wifi_status (status_init); wdbg ("Connecting {%s,%s,%d}..........%d\n", p_wifi->ssid,p_wifi->bssid,p_wifi->channel,wifi_count); memcpy (&g_cur_connect_wifi,p_wifi,sizeof (struct wifi_node_t)); Update_wifi_info (&g_cur_connect_wifi); Connect_wifi (p_wifi); sleep_ct = 0;while (sleep_ct < && g_wifi_status < STATUS_AUTH_OK) {sleep (1); sleep_ CT + +;} if (Status_auth_ok = = G_wifi_status) {wdbg ("{%s,%s,%d} auth ... ok\n", P_wifi->ssid,p_wifi->bssid,p_wifi->channel), sleep_ct); = 0;while (Sleep_ct < &&!nvram_match ("Wan_status", "Connected")) {sleep (1); sleep_ct + +;} if (Nvram_match ("Wan_status", "Connected")) {printf ("[%d] ssid:%s,channel:%d,change status%d==>%d\n", __line__,g_ CUR_CONNECT_WIFI.SSID,G_CUR_CONNECT_WIFI.CHANNEL,STATUS_AUTH_OK,STATUS_CONNECTED_OK); Update_wifi_status (STATUS _CONNECTED_OK); Wdbg ("{%s,%s,%d} connect .... ok\n", p_wifi->ssid,p_wifi->bssid,p_wifi->channel); sleep_ct = 0;; while (Sleep_ct < 2) {if (Check_internet ()) {wdbg ("{%s,%s,%d} connect Internet ... ok\n"), p_wifi->ssid,p _wifi->bssid,p_wifi->channel); Update_wifi_status (STATUS_INTERNET_OK); return;} Sleep (); sleep_ct + +;} Wdbg ("{%s,%s,%d} connect Internet ..... failed\n", P_wifi->ssid,p_wifi->bssid,p_wifi->channel);} Else wdbg ("{%s,%s,%d} lease IP .... failed\n", P_wifi->ssid,p_wifi->bssid,p_w ".Ifi->channel);} P_wifi = P_wifi->next;}} void Check_wifi_list_change (void) {if (strlen (G_CUR_CONNECT_WIFI.SSID) > 0) {wdbg ("##### Current scan result ######## #\n "); Show_all_wifi_node (); Wdbg ("Last time Connect wifi:\n"), Show_one_wifi_node (&g_cur_connect_wifi);d El_wifi_node (&g_cur_connect_ WiFi);}} void Diagnose_network (void) {char *wan_ip = Null;switch (g_wifi_status) {Case status_connected_ok:wan_ip = Nvram_safe_ge T ("wan_ipaddr"), if (NULL = = Wan_ip | | strlen (WAN_IP) < 7) && Nvram_match ("Wan_status", "Connected")) {NVRAM_ Set ("Wan_status", "Disconnected"), Update_wifi_status (status_init);p rintf ("Diagnose network ... success.\n");} Default:break;}} int main (int argc,char *argv[]) {int loop_time = 0;memset (&g_cur_connect_wifi,0x0,sizeof (G_cur_connect_wifi)); Update_wifi_status (Status_init); Nvram_set ("Wan_status", "Disconnected"); Wisp_init_config (); Signal (SIG_APCLI_ Linkdown, wisp_signal); signal (sig_apcli_linkup, wisp_signal); signal (Sig_wisp_debug, wisp_signal);Signal (SIGCHLD, sig_ign); while (1) {wdbg ("loop time:%d,status:%d,count:%d\n", Loop_time, G_wifi_status,g_wifi_node_count); if (STATUS_AUTH_OK <= g_wifi_status) {if (!nvram_match ("Wan_status", "Connected")) {update_wifi_status (STATUS_AUTH_OK);} else {update_wifi_status (STATUS_CONNECTED_OK);}} if (STATUS_CONNECTED_OK <= g_wifi_status) {if (!check_internet ()) {update_wifi_status (STATUS_CONNECTED_OK);} else {update_wifi_status (STATUS_INTERNET_OK); sleep (check_network_interval); continue;}} if (Loop_time > 3) {sleep (10);} if (0 = = loop_time% diagnose_interval) diagnose_network (); if (Loop_time < 3 | | 0 = = (loop_time% scan_interval)) { wdbg ("dxt1107 begin scan ssid........\n"); Update_wifi_list (); if (G_wifi_node_count > 1) {Check_wifi_list_change ();} if ((G_wifi_status < STATUS_CONNECTED_OK && 1 = = G_wifi_node_count) | | g_wifi_node_count > 1) {Update_wifi _status (Status_init); Check_wisp_status ();}} Loop_time++;if (Loop_time > 0xFFFF) loop_time = 1;} return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
7620A Wireless Relay Module (WISP)