This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Questions about CC3200 Simplelink

Other Parts Discussed in Thread: CC3200

Hello again!

I'm working with a CC3200 Launchpad, creating something like an "UART/I2C to TCP/IP Converter". The board is in Station mode: there's a TCP server stack, an UDP stack (for something like mDNS) and a HTTP server too (just to inform the IPs for the user). Everything is quite fine, but I have some questions to make it (almost) perfect!

- When the board is in DHCP mode, how can I get the acquired subnet mask? (looks like there's no entry in SL_NETAPP_IPV4_IPACQUIRED_EVENT);

- In scan policy, what's the RSSI range? (maybe -40 to -87 dBm?);

- About scan policy, is it possible to do a new scan when the board is already connected to an AP (and without lose this connection)? If not, can I only read the actual RSSI of the connected AP? (to use in HTML, for example, so the user can move the board to get a better position);

- In station mode, is there a way to access the HTTP server by a hostname? (I don't think so, maybe I need a NetBIOS stack, using that URN field as a hostname...);

- About TCP server socket, how can I know if the client disconnected from the server? (after sl_Accept, my stack waits for anything with sl_Recv function).

Thanks for your attention!

  • Hi Pedro,

    To answer your questions:

    - You can get the subnet mask using the below code:

        _u8 len = sizeof(SlNetCfgIpV4Args_t);
        _u8 dhcpIsOn = 0; // this flag is meaningless on AP/P2P go.
        SlNetCfgIpV4Args_t ipV4 = {0};
    
        sl_NetCfgGet(SL_IPV4_STA_P2P_CL_GET_INFO,&dhcpIsOn,&len,(_u8 *)&ipV4);
    
        UART_PRINT("IP %d.%d.%d.%d MASK %d.%d.%d.%d GW %d.%d.%d.%d DNS %d.%d.%d.%d\n\r",
                SL_IPV4_BYTE(ipV4.ipV4,3),SL_IPV4_BYTE(ipV4.ipV4,2),SL_IPV4_BYTE(ipV4.ipV4,1),SL_IPV4_BYTE(ipV4.ipV4,0),
                SL_IPV4_BYTE(ipV4.ipV4Mask,3),SL_IPV4_BYTE(ipV4.ipV4Mask,2),SL_IPV4_BYTE(ipV4.ipV4Mask,1),SL_IPV4_BYTE(ipV4.ipV4Mask,0),
                SL_IPV4_BYTE(ipV4.ipV4Gateway,3),SL_IPV4_BYTE(ipV4.ipV4Gateway,2),SL_IPV4_BYTE(ipV4.ipV4Gateway,1),SL_IPV4_BYTE(ipV4.ipV4Gateway,0),
                SL_IPV4_BYTE(ipV4.ipV4DnsServer,3),SL_IPV4_BYTE(ipV4.ipV4DnsServer,2),SL_IPV4_BYTE(ipV4.ipV4DnsServer,1),SL_IPV4_BYTE(ipV4.ipV4DnsServer,0));


    - Yes, that is the range for RSSI values.

    - When the CC3200 is already connected to an AP,  you can use the API sl_WlanRxStatGet to get the RSSI values of the connected AP. .

    - You cannot access the HTTP server by hostname when the device starts in station mode. You can only access it using the IP address.

    - You can check sl_Recv to see when the remote device closes the socket. For non blocking sl_Recv, a return code of -11 would return for EAGAIN. If the socket is closed by the remote device, 0 would be returned.

    Regards,
    Raghavendra

  • Hello Raghavendra, thanks (again) for your help!

    - About subnet mask, my bad! Missing a deep read on NWP document... I was looking for mask in "SimpleLinkNetAppEventHandler", but that's ok with a function!

    - About "sl_WlanRxStatGet" for the actual connection, it's ok too. In fact, as NWP said, there are 3 commands to issue... The ideia is to make my HTML page "polling" the rssi information, but I'm afraid it can decrease the WiFi performance... Maybe I can call the three functions each 4 seconds...

    Anyway, if I'm still connected to an AP, can I start a scan and collect information about others APs?

    - About "sl_Recv", the problem with "0" is that there's no sequence for data transfer (in other words, the server can send "n" bytes to client and get no byte as response; the server can send "n" bytes and get "n" bytes from client; the client can send "n" bytes to server...). If we had a command to read socket status, it could be use before a "sl_Recv"/"sl_Send" commands...

    Thanks in advance!

  • Hi Pedro,

    - You can do a scan when the CC3200 is in connected mode.

    - The application should check the status for remote close in a non-blocking sl_Recv for the different sequence that you have defined above. As this gives the correct indication of a remote device closing the socket.
    A no-response will make the sl_Recv return -11, and for rest of the case it will return "n". There is no API to check the status of the socket.

    Regards,
    Raghavendra
  • Hello Raghavendra!

    I've tried to issue a new scan when I'm already connected and didn't work... I'm using "WlanScan" function from "scan_policy" example and it stops in first "sl_WlanPolicySet" command ("make sure the connection policy is not set"). When I'm not connected to an AP, the "WlanScan" function works fine. BTW, about rssi from "sl_WlanGetNetworkList" that I asked before, I think that's not the real range... I've got the signal from a neighbor AP with -97 dBm value... so I think the range is from 0 dBm (excelent signal) to -100 dBm (poor signal).

    About TCP server socket (non blocking), take a look in this piece of my state machine:

    // -------------------------------------------------------------------
    case SR_LISTENING:
        // ** CLIENT SENT SOMETHING? **
        iStatus = sl_Recv(serverSockCli, g_InTcpBuffer, BUF_SIZE, 0);
        if( iStatus < 0 ){
            // error!
            lastError = RECV_ERROR;
            posTcpServer = SR_ERROR;
        }
        else if( iStatus > 0 ){
            // yes
            #ifdef _USE_MY_UART_
            // Send it to UART...
            int i;
            for(i=0;i<iStatus;i++)
                UARTA1put_uc( g_InTcpBuffer[i] );
            #endif
        }
    
        // ** SEND SOMETHING TO CLIENT? **
        #ifdef _USE_MY_UART_
        if( rxFlagUARTA1 ){
            // yes
            rxFlagUARTA1 = 0;
    
            iStatus = sl_Send(serverSockCli, bufferUARTA1_RX, countBufferUARTA1, 0);
            if( iStatus < 0 ){
                // error!
                lastError = SEND_ERROR;
                posTcpServer = SR_ERROR;
            }
        }
        #endif
    break;
    // -------------------------------------------------------------------

    In other words, I'm listening both UART and the client already connected to "serverSockCli" socket. The point is, when the client disconnect, I'm still stuck in this state. I was hopping a negative value from "sl_Recv" (SL_EAGAIN), but this isn't happening...

    Thanks again!

  • Hi Pedro,

    I am able to get the scan working when in connected mode. Please use the standard getting_started_with_wlan_station example. And add the wlanScan function as shown below

    #define WLAN_SCAN_COUNT 20
    Sl_WlanNetworkEntry_t netEntries[WLAN_SCAN_COUNT ];
    
    void wlanScan(void)
    {
        unsigned short ucIndex;
        unsigned char ucpolicyOpt;
        long lRetVal = -1;
    
        union
        {
            unsigned char ucPolicy[4];
            unsigned int uiPolicyLen;
        }policyVal;
    
        //
    	// make sure the connection policy is not set (so no scan is run in the
    	// background)
    	//
    	ucpolicyOpt = SL_CONNECTION_POLICY(0, 0, 0, 0,0);
    	lRetVal = sl_WlanPolicySet(SL_POLICY_CONNECTION , ucpolicyOpt, NULL, 0);
    	if(lRetVal != 0)
    	{
    		GPIO_IF_LedOn(MCU_EXECUTE_FAIL_IND);
    		UART_PRINT("Unable to clear the Connection Policy\n\r");
    		return;
    	}
    
    	//
    	// enable scan
    	//
    	ucpolicyOpt = SL_SCAN_POLICY(1);
    	//
    	// set scan cycle to 10 seconds
    	//
    	policyVal.uiPolicyLen = 10;
    	//
    	// set scan policy - this starts the scan
    	//
    	lRetVal = sl_WlanPolicySet(SL_POLICY_SCAN , ucpolicyOpt,
    							   (unsigned char*)(policyVal.ucPolicy), sizeof(policyVal));
    	if(lRetVal!=0)
    	{
    		GPIO_IF_LedOn(MCU_EXECUTE_FAIL_IND);
    		UART_PRINT("Unable to set the Scan Policy\n\r");
    		return;
    	}
    	MAP_UtilsDelay(8000000);
    	//
    	// get scan results - all 20 entries in one transaction
    	//
    	ucIndex = 0;
    	//
    	// retVal indicates the valid number of entries
    	// The scan results are occupied in netEntries[]
    	//
    	lRetVal = sl_WlanGetNetworkList(ucIndex, (unsigned char)WLAN_SCAN_COUNT,
    									&netEntries[ucIndex]);
    	if(lRetVal==0)
    	{
    		GPIO_IF_LedOn(MCU_EXECUTE_FAIL_IND);
    		UART_PRINT("Unable to retreive the network list\n\r");
    		return;
    	}
    	/* put a break point here and check netEntries[] value for scan ssid list */
    	//
    	// get scan results - 4 transactions of 5 entries
    	//
    	ucIndex = 0;
    	memset(netEntries, 0, sizeof(netEntries));
    
        lRetVal = sl_WlanGetNetworkList(ucIndex,
    									(unsigned char)WLAN_SCAN_COUNT,
    									&netEntries[ucIndex]);
    
        Report("\n\r Scan list\n\r");
        Report("======================\n\r");
    
        for(ucIndex = 0; ucIndex < WLAN_SCAN_COUNT; ucIndex++)
        {
        	Report(" %s \n\r", netEntries[ucIndex].ssid);
        }
    
        Report("Scan complete\n\r");
    
        /* put a break point here and check netEntries[] value for scan ssid list */
    	//
    	// disable scan
    	//
    	ucpolicyOpt = SL_SCAN_POLICY(0);
    	lRetVal = sl_WlanPolicySet(SL_POLICY_SCAN , ucpolicyOpt, NULL, 0);
    	if(lRetVal != 0)
    	{
    		GPIO_IF_LedOn(MCU_EXECUTE_FAIL_IND);
    		UART_PRINT("Unable to Clear the Scan Policy\n\r");
    		return;
    	}
    
    	GPIO_IF_LedOn(MCU_EXECUTE_SUCCESS_IND);
    	UART_PRINT("SUCCESS\n\r");
    }
    
    void WlanStationMode( void *pvParameters )
    {
    
        long lRetVal = -1;
    
        InitializeAppVariables();
    
        //
        // Following function configure the device to default state by cleaning
        // the persistent settings stored in NVMEM (viz. connection profiles &
        // policies, power policy etc)
        //
        // Applications may choose to skip this step if the developer is sure
        // that the device is in its default state at start of applicaton
        //
        // Note that all profiles and persistent settings that were done on the
        // device will be lost
        //
        lRetVal = ConfigureSimpleLinkToDefaultState();
        if(lRetVal < 0)
        {
            if (DEVICE_NOT_IN_STATION_MODE == lRetVal)
            {
                UART_PRINT("Failed to configure the device in its default state\n\r");
            }
    
            LOOP_FOREVER();
        }
    
        UART_PRINT("Device is configured in default state \n\r");
    
        //
        // Assumption is that the device is configured in station mode already
        // and it is in its default state
        //
        lRetVal = sl_Start(0, 0, 0);
        if (lRetVal < 0 || ROLE_STA != lRetVal)
        {
            UART_PRINT("Failed to start the device \n\r");
            LOOP_FOREVER();
        }
    
        UART_PRINT("Device started as STATION \n\r");
    
        //
        //Connecting to WLAN AP
        //
        lRetVal = WlanConnect();
        if(lRetVal < 0)
        {
            UART_PRINT("Failed to establish connection w/ an AP \n\r");
            LOOP_FOREVER();
        }
    
        UART_PRINT("Connection established w/ AP and IP is aquired \n\r");
        UART_PRINT("Pinging...! \n\r");
    
        wlanScan();
        .
        .
    }

    Regarding the TCP server, we will check it and get back to you.

    Regards,
    Raghavendra

  • Hello Raghavendra, thanks for your help!

    Well, everything looks fine now!!

    - TCP Server: the problem is that I was only setting the main socket as non-blocking...  in fact, after a client connection, this new socket must be set as non-blocking too (so in my piece of code above, I must use "sl_SetSockOpt" in "serverSockCli" before use "sl_Recv"). Now, "sl_Recv" works as you told me: "SL_EAGAIN" when there's nothing to receive; "> 0" when there's something; and "= 0", when the client says goodbye!

    - RSSI from scan policy: "antenna_selection" example shows some kind of convertion to percent (just adding 128). At my HTML page, I'm using it with a <meter>!

    - WlanScan function: that was exactly the function I was using. But inside "SimpleLinkHttpServerCallback", right after a POST token... I've learned that we must not call simplelink functions inside a callback! :) Now I'm just setting a flag after POST, and calling "WlanScan" in main function...

    Now I'm just working on that NetBIOS stack, so I can "announce" the hostname for Windows machines... hope find this function in the next SDK! ;)

    Thanks again!!