RCM4400W Wifi Problem

I can scan and connect to an infrastructure network with and without WEP with no problem. I can then scan and connect to a peer to peer (ad-hoc) network with and without WEP with no problem. I can then scan but cannot connect to an infrastructure network from that point.

Is there anyone out there who can connect from infrastructure to ad-hoc and back to infrastructure? I tried tech support but they could not help me. I had no such problems with the old 3400 module with wifi add-on kit.

Thanks

Hi,
I can try doing this. I suppose you are using the WiFi example files, but tell me the file names you are running just to be sure.

I can’t attach the source file so here is the code. It is a modified version of one of the examples. I modified the TCPconfig.lib to reflect the proper WEP and ip address settings.

/****************************************************************************

WiFiScanAssociate.c

Rabbit Semiconductor, (c) 2007

This code demostrates how to scan WiFi channels for SSID’s using the
ioctl WIFI_SCAN function call. ioctl WIFI_SCAN takes a while to
complete, so it calls a callback function when it is done. The
callback function is specified using an ioctl WIFI_SCANCB function
call.

To run this sample, first configure tcp_config.lib and your TCPCONFIG
mode:

  1.	Edit Lib/tcpip/tcp_config.lib appropriately.

     a. If not using DHCP, set _PRIMARY_STATIC_IP address to an
        address on your network.  Additionally, define
        _PRIMARY_NETMASK, MY_NAMESERVER, and MY_GATEWAY to values
        appropriate to your network.

     b. Set _WIFI_SSID to an appropriate value:

        To connect to a specific BSS, set _WIFI_SSID to the the
        SSID of your access point, as a C-style string.  For example,

           #define _WIFI_SSID "My Access Point"

        Or, use an empty string, "", to to associate with the
        strongest BSS available.

  2. If using DHCP, change the definition of TCPCONFIG below to 5.
     The default value of 1 indicates WiFi with a static IP address.
     (WiFi capability is determined by the board type.)

Compile and run the code. Follow the menu options:

  s - scan for BSS's,
  a - scan and associate
  m - dump MAC state information
  t - dump tx information

Important features to note:

  • ioctl WIFI_SCAN calls do not return data directly, since the scan
    takes a fair amount of time. Instead, callback functions are used.
    The callback function is set with a prior ioctl call:

       wifi_ioctl(IF_WIFI0, WIFI_SCANCB, scan_callback, 0);
       wifi_ioctl(IF_WIFI0, WIFI_SCAN, "0", 0);
    
  • The data passed to the callback function is ephemeral, since another
    scan may occur. Thus, the data needs to be used (or copied)
    during the callback function.

  • While waiting for user input, it is important to keep the network
    alive by regularly calling tcp_tick(NULL).

****************************************************************************/

// TCPCONFIG: 1 - WiFi with static IP; 5 - WiFi with DHCP
//#define _WIFI_WEP_FLAG WIFICONF_WEP_ENABLE
#define TCPCONFIG 1

#use “dcrtcp.lib”

#memmap xmem

#define ESS 0x0001
#define IBSS 0x0002
#define WEP 0x0010
/****************************************************************************
print_macaddress

Routine to print out mac_addr types.

****************************************************************************/
void print_macaddress(far unsigned char *addr)
{
printf(“%02x:%02x:%02x:%02x:%02x:%02x”, addr[0], addr[1], addr[2],
addr[3], addr[4], addr[5]);
}

/****************************************************************************
print_status

Routine to print out status (wln_status type).

****************************************************************************/
void print_status(wifi_status *status)
{
printf("
MAC status:
“);
printf(” state = %d (%s)
“, status->state,
status->state == WLN_ST_STOPPED ? “WLN_ST_STOPPED” :
status->state == WLN_ST_SCANNING ? “WLN_ST_SCANNING” :
status->state == WLN_ST_ASSOC_ESS ? “WLN_ST_ASSOC_ESS” :
status->state == WLN_ST_AUTH_ESS ? “WLN_ST_AUTH_ESS” :
status->state == WLN_ST_JOIN_IBSS ? “WLN_ST_JOIN_IBSS” :
status->state == WLN_ST_START_IBSS ? “WLN_ST_START_IBSS” :
“Unknown/illegal status”);
printf(” ssid = %s
“, status->ssid);
printf(” ssid_len = %d
“, status->ssid_len);
printf(” channel = %d
“, status->channel);
printf(” bss_addr = “);
print_macaddress(status->bss_addr);
printf(”
“);
printf(” bss_caps = %04x
“, status->bss_caps);
printf(” authen = %ld
“, status->authen);
printf(” encrypt = %ld
“, status->encrypt);
printf(” tx_rate = %d
“, status->tx_rate);
printf(” rx_rate = %d
“, status->rx_rate);
printf(” rx_signal = %d
“, status->rx_signal);
printf(” tx_power = %d
", status->tx_power);
}

/****************************************************************************
rxsignal_cmp

qsort comparison, based on rx signal strength.

Inputs:
a, b – far pointers to _wifi_wln_scan_bss, a struct populated by
the ioctl WIFI_SCAN call, including rx_signal (relative
receive signal strength).

Return value: > 0 if a > b
				  < 0 if a < b
				  0   if a == b

****************************************************************************/
int rxsignal_cmp(far _wifi_wln_scan_bss *a, far _wifi_wln_scan_bss *b) {
return b->rx_signal - a->rx_signal;
}

/****************************************************************************
scan_callback

Prints out the sorted results of a BSS scan. Called when ioctl
WIFI_SCAN is complete.

The argument is a pointer to the wifi_scan_data structure generated by
the scan.

We use _f_qsort to sort the data since the data is `far.’ _f_qsort
requires a comparison function, and we use the rxsignal_cmp() function
above.

Inputs:
data – far pointer to wifi_scan_data structure, which contains a
count of the number of responses, and an array of
_wifi_wln_scan_bss structures, with the first `count’
containing valid data for the responses.

***************************************************************************/
root void scan_callback(far wifi_scan_data
data)
{
uint8 i, j;
far _wifi_wln_scan_bss *bss;

bss = data->bss;
// _wifi_macStatus.ssid is the BSS we are currently associated with _or_
// currently trying to associate with.
printf("Current BSS is %*s.

“, _wifi_macStatus.ssid_len,
_wifi_macStatus.ssid);
// Sort results by signal strength. Need to use _f_qsort, since bss is
// far data.
_f_qsort(bss, data->count, sizeof(bss[0]), rxsignal_cmp);
// Print out results
for (i = 0; i < data->count; i++) {
printf(”%X: %16ls ; chan %2d ; rx_signal %d ; MAC “, i, bss[i].ssid,
bss[i].channel, bss[i].rx_signal);
print_macaddress(bss[i].bss_addr);
printf(” caps: %d", bss[i].bss_caps);
printf("
");
}
}

/****************************************************************************
scan_assoc_callback

Much like scan_callback above, this function is called as a result of a
WIFI_SCAN ioctl call (requires registering this function first). The
main difference is that this function gives the user the option of
associating with one of the BSS’s. It uses scan_callback above to sort
and print the scan results.

Inputs:
data – far pointer to wifi_scan_data structure, which contains a
count of the number of responses, and an array of
_wifi_wln_scan_bss structures, with the first `count’
containing valid data for the responses.

***************************************************************************/
root void scan_assoc_callback(far wifi_scan_data
data)
{
char c, ssid[WLN_SSID_SIZE], channel[5];
int ssid_len;
far _wifi_wln_scan_bss *bss;

// Sort and print the scan results
scan_callback(data);
bss = data-&gt;bss;

printf("
Select a new BSS or quit ([0-%x, q to quit)]
“, data->count-1);
while (1) {
tcp_tick(NULL); // While we’re waiting, continue to tick.
if (kbhit()) {
c = getchar();
// Echo the character
printf(”%c
", c);
// Convert character to numeric value.
if (‘0’ <= c && c <= ‘9’) { c = c - ‘0’; }
else if (isxdigit(c)) { c = (tolower(c) - ‘a’ + 10); }
else if (tolower(c) == ‘q’) {
printf("Quitting scan selection
");
break;
}
if (c >= data->count) {
printf("Unlisted option, quitting…
");
break;
}
// c is now the index of the BSS the user opted to associate with
bss = &(data->bss[c]);
ssid_len = bss->ssid_len;
// Need near copy of SSID to call ioctl. ssid will be promoted to
// far for this call, but the results will be in ssid as a near
// variable
_f_memcpy(ssid, bss->ssid, ssid_len);

     ifdown(IF_WIFI0);
     while(ifpending(IF_WIFI0) != IF_DOWN)
     {
     	tcp_tick(NULL);
     }
     printf("

IF is now down
");

     if(bss-&gt;bss_caps &amp; WEP)
     {
  printf("

wep on
“);
wifi_ioctl(IF_WIFI0, WIFI_WEP_FLAG, WIFICONF_WEP_ENABLE, 0);
wifi_ioctl(IF_WIFI0, WIFI_WEP_USEKEY, “0”, 0);
//wifi_ioctl(IF_WIFI0, WIFI_WEP_KEY0, wifikey, sizeof(wifikey));
wifi_ioctl(IF_WIFI0, WIFI_AUTH, WIFICONF_AUTH_ALL, 0);
}
else
{
printf(”
wep off
");
wifi_ioctl(IF_WIFI0, WIFI_WEP_FLAG, WIFICONF_WEP_DISABLE, 0);
wifi_ioctl(IF_WIFI0, WIFI_AUTH, WIFICONF_AUTH_ALL, 0);
}

     if(bss-&gt;bss_caps &amp; ESS)
     {

printf("
infra
“);
wifi_ioctl(IF_WIFI0, WIFI_MODE, WIFICONF_INFRASTRUCT, 0);
sprintf(channel,”%d",bss->channel);
wifi_ioctl(IF_WIFI0, WIFI_OWNCHAN, channel, strlen(channel));
//wifi_ioctl(IF_WIFI0, WIFI_TX_RATE, WIFICONF_RATE_ANY, 0);
wifi_ioctl(IF_WIFI0, WIFI_OWNCHAN, “0”, 0);
}
else
{
printf("
adhoc
“);
wifi_ioctl(IF_WIFI0, WIFI_MODE, WIFICONF_ADHOC, 0);
sprintf(channel,”%d",bss->channel);
wifi_ioctl(IF_WIFI0, WIFI_OWNCHAN, channel, strlen(channel));
//wifi_ioctl(IF_WIFI0, WIFI_TX_RATE, WIFICONF_RATE_1MBPS, 0);
}

     wifi_ioctl(IF_WIFI0, WIFI_SSID, ssid, ssid_len);

		printf("Selected BSS is %.*s.  Wait a bit, then check MAC status

",
ssid_len, ssid);

	/*printf("

bring up 1
“);
ifup(IF_WIFI0);
printf(”
bring up 2
“);
while(ifpending(IF_WIFI0) == IF_COMING_UP)
{
tcp_tick(NULL);
}
printf(”
ready…
"); */

     ifup(IF_WIFI0);
/*while (ifpending(IF_DEFAULT) != IF_UP)
	tcp_tick(NULL);

if(ifpending(IF_DEFAULT) == IF_DOWN)
exit(1); */

  printf("

ready…
");

		break;
	}
}

}

/****************************************************************************
main

Print out a menu, wait for keypresses, while calling tcp_tick.

****************************************************************************/
void main(void)
{
int val0, val1,i, level;
mac_addr mac;
char c;
word waitms, pingit;
longword pingid;
wifi_status status;
int len;
unsigned long int end;

sock_init();

printf("

Menu:
“);
printf(” Press s to scan available BSS’s
“);
printf(” Press a to scan BSS’s and associate
“);
printf(” Press m to print MAC stats
“);
printf(”
");

waitms = _SET_SHORT_TIMEOUT(300);
pingit = 0;

for (;:wink: {
tcp_tick(NULL);
if (kbhit()) {
c = getchar();
if (c == ‘m’) {
wifi_ioctl(IF_WIFI0, WIFI_STATUSGET, &status, 0);
print_status(&status);
}
if (c == ‘s’) {
// Set the callback before requesting scan
wifi_ioctl(IF_WIFI0, WIFI_SCANCB, scan_callback, 0);
wifi_ioctl(IF_WIFI0, WIFI_SCAN, “0”, 0);
printf("Starting scan…
");
}
if (c == ‘a’) {
wifi_ioctl(IF_WIFI0, WIFI_SCANCB, scan_assoc_callback, 0);
wifi_ioctl(IF_WIFI0, WIFI_SCAN, “0”, 0);
printf("Starting scan…
");
}
}
}
}

Hi,
I may be able to try this over the next few days.

By the way, about 90% down in your code there is a for statement that became mangled with an emoticon. I think you were trying to post this statement:
for( ; ; )
but it is coming out as
for(;:wink:

Let me know if I have that wrong.