A20 Debian: wi-fi communication problem

Started by vkbidve, February 18, 2015, 08:18:45 AM

Previous topic - Next topic

vkbidve

Hi,

I am working on a networking based project using A20 micro board with Debian wheezy image (downloaded from https://www.olimex.com/wiki/A20-OLinuXino-MICRO#Linux) running on it. I am using two types of wireless USB dongles with it. One is 'MOD-WIFI-R5370-ANT' from Olimex with Realtek 5370 chipset. Another is TP-Link's 'TL-WN721N' with Atheros 9271 chipset. My application involves TCP/IP socket communication in server-client mode. This works quite good with R5370 module (Olimex), but fails with WN721N (TP-LINK) module specifically in client mode!

Initially, the TP-Link modules were not working with A20 board. I figured out the problem from 'dmesg' output, that the debian image was missing the firmware 'htc_9271.fw'. I downloaded the .deb package for it from "https://packages.debian.org/wheezy/firmware-atheros" and installed it with 'dpkg -i'. After that, the 'iw' utility started working fine. Then the module also started working fine in server mode. But in client mode, when the statement in my C code to 'connect' to a host socket is executed, it returns with an error "Invalid Argument"!!!

On the same board and debian image, it works quite fine in server mode. The function calls 'socket', 'bind', 'listen', 'accept', 'read', 'write' work well, but it fails only at 'connect' in client mode.

The same C code in client mode runs well with Olimex R5370 based module. The same C code in client mode, when built for i686 using gcc runs equally well on a Ubuntu 14.04 LTS PC and on a Linux Mint 17 PC, both derived from Debian. So, I suspect the kernel/wireless drivers in the debian image for A20 board.

Can anybody show some light on this issue?


JohnS

Seems to me there's still a small chance it's a non-obvious bug in your code, which someone might find if you'd posted it.

Another possibility is the fw in some again non-obvious respect.

Beyond that, about all I can suggest is to report the problem formally.  Your code is likely to be required.

John

vkbidve

Here is an extract of the client.c file. Sorry, I tried to look for a provision of attachments in the reply composing section, but didn't find any, so had to paste the code here partially.

// SysCall helper function.
// Checks result of a system call and produces error msg in case of errors.
boolean SysCall( const char *syscallName, int lineNbr, int status )
{
char str[256];
if ( pgmName[0] == 0 )
{
readlink("/proc/self/exe", pgmName, 49);
}
if ( status == -1 )
{
sprintf(str, "%s (line %d): System call failed ('%s') - %s.\n",
pgmName,
lineNbr,
syscallName,
strerror( errno ) );
fprintf( stderr, "%s", str );
}
return status != -1;   // True if the system call was successful.
}

static int openSckt( const char   *host,
const char   *service,
unsigned int  scopeId )
{
struct addrinfo *ai;
int              aiErr;
struct addrinfo *aiHead;
struct addrinfo  hints;
sockaddr_in6_t  *pSadrIn6;
int              sckt;

/* Initialize the 'hints' structure for getaddrinfo(3).
**
** Notice that the 'ai_family' field is set to PF_UNSPEC, indicating to
** return only IPv6 address records for the host/service. */

memset( &hints, 0, sizeof( hints ) );
hints.ai_family   = PF_INET6; // IPv6 records only.
hints.ai_socktype = SOCK_STREAM; // Connection-oriented byte stream.
hints.ai_protocol = IPPROTO_TCP; // TCP transport layer protocol only.

// Look up the host/service information.
if ( ( aiErr = getaddrinfo( host,
service,
&hints,
&aiHead ) ) != 0 )
{
fprintf( stderr, "(line %d): ERROR - %s.\n", __LINE__, gai_strerror( aiErr ) );
return INVALID_DESC;
}

/* Go through the list and try to open a connection.  Continue until either
** a connection is established or the entire list is exhausted. */

for ( ai = aiHead,   sckt = INVALID_DESC;
( ai != NULL ) && ( sckt == INVALID_DESC );
ai = ai->ai_next )
{
// IPv6 kluge.  Make sure the scope ID is set.
if ( ai->ai_family == PF_INET6 )
{
pSadrIn6 = (sockaddr_in6_t*) ai->ai_addr;
if ( pSadrIn6->sin6_scope_id == 0 )
{
pSadrIn6->sin6_scope_id = scopeId;
} // End IF the scope ID wasn't set.
} // End IPv6 kluge.

// Create a socket.
if ( !SysCall( "socket", __LINE__, sckt = socket( ai->ai_family, ai->ai_socktype, ai->ai_protocol ) ) )
{
sckt = INVALID_DESC;
continue; // Try the next address record in the list.
}

// Connect to the remote host.
if ( !SysCall( "connect", __LINE__, connect( sckt, ai->ai_addr, ai->ai_addrlen ) ) )
{
(void) close( sckt ); // Could use SysCall() again here, but why?
sckt = INVALID_DESC;
continue; // Try the next address record in the list.
}
} // End FOR each address record returned by getaddrinfo(3).

// Clean up & return.
freeaddrinfo( aiHead );
return sckt;
} // End openSckt()



Still another observation remains unaddressed, as I said in my original post:
QuoteOn the same board and debian image, it works quite fine in server mode. The function calls 'socket', 'bind', 'listen', 'accept', 'read', 'write' work well, but it fails only at 'connect' in client mode.

The same C code in client mode runs well with Olimex R5370 based module. The same C code in client mode, when built for i686 using gcc runs equally well on a Ubuntu 14.04 LTS PC and on a Linux Mint 17 PC, both derived from Debian. So, I suspect the kernel/wireless drivers in the debian image for A20 board.

JohnS

If all else fails you can wait and hope someone posts.

John