i want udp recieve data of PC
Answer
1/9/18 3:45 AM
I am now using the sendacceludpandble example to send eight sensor data and PD5 and PD6 values to the PC program using UDP. What I want is to read the data from the PC using UDP and turn on the LED connected to the external port according to a specific message. I need help on how to read certain messages. I did a lot of research and research, but I did not make any small progress.
0 (0 Votes)
RE: i want udp recieve data of PC
Answer
1/9/18 3:09 PM as a reply to jang.

Hello Jang,

to receive UDP messages, you must first open a UDP socket, then bind the socket to a name, which consists of the IP address and the port, and afterwards you can receive messages.

To open a socket and bind a proper name, you can use the following code snippet:

_i16 recvSock = NULL;

void bindSocketToPort(void) {
    SlSockAddrIn_t  LocalAddr;
    _i16 AddrSize = sizeof(SlSockAddrIn_t);
    _i16 Status;

 LocalAddr.sin_family = SL_AF_INET;
    LocalAddr.sin_port = sl_Htons((uint16_t) 6666);
    LocalAddr.sin_addr.s_addr = 0;
    recvSock = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM, 0);
    Status = sl_Bind(recvSock, (SlSockAddr_t *)&LocalAddr, AddrSize);
}

As a first step, the local address is allocated. For the IP address, 0.0.0.0 is used, indicating that the address refers to the chip itself. As the port, you can use any number you want. As an example, 6666 is used here.

Using sl_Socket() with the inputs as seen in the code snippet, will allocate a UDP socket for internet use (SL_AF_INET).

Finally, sl_Bind() binds the socket to the local address. Do note that the socket is global, to be reused in other functions.

Now, messages can be received using the configured socket. I would recommend using a task for that, with the following (minimal) code:

static void wifiUdpReceive(void *param){
    static char Buf[256];
    for(;;){
        sl_Recv(recvSock, Buf, 256, 0);
    }
}

Do note that sl_Recv() will block indefinitely. As such, it would not pose problems when used in a task with the sole purpose of receiving UDP messages. If it used anywhere else where blocking permanently may be an issue, a timeout can be set for the Receiving function as follows:

struct SlTimeval_t timeVal;
    timeVal.tv_sec =  1;             // Seconds
    timeVal.tv_usec = 0;             // Microseconds. 10000 microseconds resolution
    sl_SetSockOpt(recvSock,SL_SOL_SOCKET,SL_SO_RCVTIMEO, (_u8 *)&timeVal, sizeof(timeVal));

Please tell me if this was helpful and feel free to ask further questions.

Kind regards,
Franjo

0 (0 Votes)
RE: i want udp recieve data of PC
Answer
1/10/18 7:20 AM as a reply to Franjo Stjepandic.

I appreciate your help, but I have not done it yet.
If you use the recv or recvfrom function, the program routine is aborted.
I wonder if there is another solution. And is there a way to communicate faster because of the time difference between the two of us? It is imperative to solve this problem.
Is there anything that you should not use with the recv function, or does it satisfy certain conditions?

Sendacceloverudp Raises the portion you added in the example code.

static void wifiUdpSend(void * param1, uint32_t port)
{
    BCDS_UNUSED(param1);
    static uint16_t counter = UINT16_C(0);
    SlSockAddrIn_t Addr;
    uint16_t AddrSize = (uint16_t) ZERO;
    int16_t SockID = (int16_t) ZERO;
    int16_t Status = (int16_t) ZERO;

    /* copies the dummy data to send array , the first array element is the running counter to track the number of packets send so far*/
    bsdBuffer_mau[0] = counter;
    bsdBuffer_mau[1] = 0xAA55;
    bsdBuffer_mau[2] = 0xBB66;
    bsdBuffer_mau[3] = 0xCC77;
    Addr.sin_family = SL_AF_INET;
    Addr.sin_port = sl_Htons((uint16_t) port);
    Addr.sin_addr.s_addr = sl_Htonl(SERVER_IP);
    AddrSize = sizeof(SlSockAddrIn_t);

    SockID = sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, (uint32_t) ZERO); /**<The return value is a positive number if successful; other wise negative*/
    if (SockID < (int16_t) ZERO)
    {
        printf("Error in socket opening\n");
        /* error case*/
        return;
    }

    Status = sl_SendTo(SockID, bsdBuffer_mau, BUFFER_SIZE * sizeof(uint16_t), (uint32_t) ZERO, (SlSockAddr_t *) &Addr, AddrSize);/**<The return value is a number of characters sent;negative if not successful*/
    /*Check if 0 transmitted bytes sent or error condition*/
    if (Status <= (int16_t) ZERO)
    {
        Status = sl_Close(SockID);
        if (Status < 0)
        {
            printf("Error is closing socket after failing to send the Udp data \r\n");
            return;
        }
        printf("Error in sending data \r\n");
        return;
    }
    Status = sl_Close(SockID);
    if (Status < 0)
    {
        printf("Error in closing socket after sending successfully sending the udp data \r\n");
        return;
    }
    counter++;
    printf("UDP sending successful\r\n");

    char Buf[256];

    memset(Buf,0,sizeof(Buf));

    Buf[0] = 'A';

    SlSockAddrIn_t LocalAddr;

    LocalAddr.sin_port = sl_Htons(4444);
    LocalAddr.sin_addr.s_addr = 0;
    LocalAddr.sin_family = SL_AF_INET;

    int16_t recvSock = (int16_t) ZERO;

    printf("before Socket\r\n");

    recvSock = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM,0);

    printf("before bind\r\n");

    sl_Bind(recvSock, (SlSockAddr_t *) &LocalAddr, AddrSize);

    //printf("before listen \r\n");
    //sl_Listen(recvSock, 0);
    printf("before recv \r\n");
    //sl_Recv(recvSock,Buf,256,0);
    sl_RecvFrom(recvSock,Buf,256,0,(SlSockAddr_t *)&LocalAddr,(SlSocklen_t*)&AddrSize);

    printf("g_AddrSize %d",AddrSize);
    printf("Receive Data : %s\n",Buf);

    printf("before close \r\n");
    sl_Close(recvSock);

    return;
}

 

 

0 (0 Votes)
RE: i want udp recieve data of PC
Answer
1/10/18 5:56 PM as a reply to jang.

Hello jang,

as we are located in Europe, communication may be delayed. Unfortunately, we are not able to provide faster responses in the community, but I will keep that in mind and make my answers as detailed and precise as possible.

Maybe there is the possibility to provide direct support. I will clarify this topic and keep you posted.

First of all, you call sl_RecvFrom() instead of sl_Recv(). The first will do anything sl_Recv() would do, but it also stores the information of the source of the UDP message. This basically allows you to make decisions based on the origin of the message. Otherwise, the functions are identical in functionality.

I can see that you have commented out sl_Listen(). I would like to reassure you, that you do not need this function for UDP. This function is only used with TCP, to allow connections to that socket to be made. Since UDP does not use connections, this is not needed.

As for your statement: If you use the recv or recvfrom function, the program routine is aborted. What exactly do you mean by aborted? Does the application simply come to a halt because of the blocking nature of sl_Recv()?

Blocking means that the function will passively wait until any message has arrived at the socket (i.e. a successful receive). As I mentioned before, there will be no timeout, unless it is manually specified (refer to my previous post for that).

If you do not wish for the sending to be stopped as well, I would recommend moving the entire receiving functionality into a separate task. Tasks are essentially what you’d call independent processes or threads on a normal Operating System.

This would allow for sending and receiving messages to be independent of one another. If the receiving function blocks its own task, the rest of the application will remain unaffected and sending will continue. You can find more information on tasks in the FreeRTOS guide in the Learning section.

Please tell me if this was helpful and feel free to ask further questions.

Kind regards,
Franjo

0 (0 Votes)
RE: i want udp recieve data of PC
Answer
1/11/18 12:27 PM as a reply to Franjo Stjepandic.
Thank you for your help.

In the original Init function

 
WifiTransmitTimerHandle = xTimerCreate ((char * const) "WifiTransmitTimerHandle", pdMS_TO_TICKS (WIFI_TX_FREQ), TIMER_AUTORELOAD_OFF, NULL, EnqueueAccelDatatoWifi);


In this section, we have replaced it with TIMER_AUTORELOAD_OFF. If you continue to send ASCII code "1", it will be received randomly. For example, if you send 10 times without any rules, there are times when you receive it and sometimes when you send it. Why do you get help?

And when setting TIMER_AUTORELOAD_ON

 
static void EnqueueAccelDatatoWifi (void * pvParameters)
{
    BCDS_UNUSED (pvParameters);

    Retcode_T retVal = CmdProcessor_enqueue (AppCmdProcessorHandle, SendDataOverWifi, NULL, SERVER_PORT);
    if (RETCODE_OK! = retVal)
    {
        printf ("Failed to Enqueue SendDataOverWifi to Application Command Processor \ r \ n");
    }
}

 
We will post the code we used for recieve.

 
char Buf [256];

memset (Buf, 0, sizeof (Buf));


SlSockAddrIn_t LocalAddr;

LocalAddr.sin_port = sl_Htons (SERVER_PORT);
LocalAddr.sin_addr.s_addr = 0; // sl_Htonl (SERVER_RIP);
LocalAddr.sin_family = SL_AF_INET;

    _i16 recvSock = NULL;
    _i16 AddrSize = sizeof (SlSockAddrIn_t);

    printf ("before Socket \ r \ n");

    g_recvSock = sl_Socket (SL_AF_INET, SL_SOCK_DGRAM, 0);

    struct SlTimeval_t timeVal;
     timeVal.tv_sec = 1;
     timeVal.tv_usec = 0;
    sl_SetSockOpt (g_recvSock, SL_SOL_SOCKET, SL_SO_RCVTIMEO, (_u8 *) & timeVal, sizeof (timeVal));

    printf ("before bind \ r \ n");

    sl_Bind (g_recvSock, (SlSockAddr_t *) & LocalAddr, AddrSize);

   

    printf ("before recv \ r \ n");


    // sl_Recv (recvSock, Buf, 256,0);

    Sl_RecvFrom (g_recvSock, Buf, 256,0, (SlSockAddr_t *) & LocalAddr, (SlSocklen_t *) & AddrSize);

    printf ("AddrSize% d \ r \ n", g_AddrSize);
printf ("Receive Data:% s \ n", Buf);


In the function above, the message "Failed to Enqueue SendDataOverWifi to Application Command Processor"
printf ("AddrSize% d \ r \ n", g_AddrSize);
printf ("Receive Data:% s \ n", Buf);


  The buf value is not output.
0 (0 Votes)
RE: i want udp recieve data of PC
Answer
1/11/18 6:19 PM as a reply to jang.

Hello jang,

I do not quite understand the issues you are facing right now.

In this section, we have replaced it with TIMER_AUTORELOAD_OFF. If you continue to send ASCII code "1", it will be received randomly. For example, if you send 10 times without any rules, there are times when you receive it and sometimes when you send it. Why do you get help?

What exactly do you mean by that? Who is sending ASCII code "1"? Did you create a macro for TIMER_AUTORELOAD_OFF that represents pdFALSE, i.e. the value 0?

In the function above, the message "Failed to Enqueue SendDataOverWifi to Application Command Processor"

Do you receive this message in the console? If that is the case, this merely indicates that the Application's Command Processor's Queue is full.

The Command Processor can queue up to 10 functions, which will subsequently be executed one after another. Since the timer enqueues new functions endlessly, the command processor may eventually be filled up, if functions are not executed quickly enough.

Regarding the output you try to produce with Receive Data, the issue here is the fact that you do have a timeout set at one second. If no message is received during that one second, then the content of Buf will be unchanged. Since you set the content to 0 using memset(), the Buf will be interpreted as an empty string.

I recommend that you check if the return value of Sl_RecvFrom() is positive. If the return value is positive, there will be content in Buf and the length will be the function's return value. A negative return value indicates an error. I would recommend to only consider printing something, if there is content.

Finally, while you have made the receiving socket global, I would recommend to only initialize the socket and bind it once. This would be optimal to do in a separate function during initialization. The following code pieces are required for that:

lSockAddrIn_t LocalAddr;

LocalAddr.sin_port = sl_Htons (SERVER_PORT);
LocalAddr.sin_addr.s_addr = 0; // sl_Htonl (SERVER_RIP);
LocalAddr.sin_family = SL_AF_INET;

g_recvSock = sl_Socket (SL_AF_INET, SL_SOCK_DGRAM, 0);

struct SlTimeval_t timeVal;
timeVal.tv_sec = 1;
timeVal.tv_usec = 0;
sl_SetSockOpt (g_recvSock, SL_SOL_SOCKET, SL_SO_RCVTIMEO, (_u8 *) & timeVal, sizeof (timeVal));

sl_Bind (g_recvSock, (SlSockAddr_t *) & LocalAddr, sizeof(SlSockAddrIn_t);

Please tell me if this was helpful, and do not hesitate to ask further questions

Kind regards,
Franjo

0 (0 Votes)
RE: i want udp recieve data of PC
Answer
1/12/18 8:05 AM as a reply to Franjo Stjepandic.

I am grateful for the continued help and I am sorry that the problem is not solved because the communication is not smooth due to the problem of language. I also really want to solve it.

The first question you ask is that if you send an ASCII code or Hex value in UDP on the PC side, it is not a one time send, but a chance one time when you send an arbitrary number of times.
I think it is right to receive ten times if you send 10 times.

Secondly I have a Timer for send and a Timer for recieve respectively.
That is, a total of two timers are used. Because I thought I would separate send and recieve

 

static void WlanEventCallback(WlanConnect_Status_T Event)
{
    switch (Event)
    {
    case WLAN_CONNECTED:
        /* start accelerometer data transmission timer */
        if (NULL != WifiTransmitTimerHandle) //
        {
            if (pdTRUE != xTimerStart(WifiTransmitTimerHandle, (WIFI_TX_FREQ / portTICK_RATE_MS)))
            {
                /* Assertion Reason : Failed to start software timer. Check command queue size of software timer service*/
                printf("Failed to start the Wifi Send timer \r\n");
                assert(false);
            }
            else
            {
                printf("Wifi Send timer started \r\n");
            }
        }

        if (NULL != WifiReceiveTimerHandle) //
        {
                if (pdTRUE != xTimerStart(WifiReceiveTimerHandle, (WIFI_RX_FREQ / portTICK_RATE_MS)))
                {
                    /* Assertion Reason : Failed to start software timer. Check command queue size of software timer service*/
                    printf("Failed to start the Wifi Receive timer \r\n");
                    assert(false);
                }
                else
                {
                    printf("Wifi Receive timer started \r\n");
                }
         }

        printf("XDK Device Connected over WIFI \r\n");
        PrintDeviceIP();
        break;
    case WLAN_DISCONNECTED:
        /* stop Ble timer accelerometer data transmission timer */
        if (NULL != WifiTransmitTimerHandle)
        {
            if (pdTRUE != xTimerStop(WifiTransmitTimerHandle, NUMBER_ZERO))
            {
                /* Assertion Reason: Failed to start software timer. Check command queue size of software timer service. */
                assert(false);
                printf("Failed to stop the Wifi Send timer \r\n");
            }
            else
            {
                printf("Wifi Send Timer stopped \r\n");
            }
        }
        if (NULL != WifiReceiveTimerHandle)
                {
                    if (pdTRUE != xTimerStop(WifiReceiveTimerHandle, NUMBER_ZERO))
                    {
                        /* Assertion Reason: Failed to start software timer. Check command queue size of software timer service. */
                        assert(false);
                        printf("Failed to stop the Wifi Receive timer \r\n");
                    }
                    else
                    {
                        printf("Wifi Receive Timer stopped \r\n");
                    }
                }
if (RETCODE_OK == retval)
    {
    	printf("initalization Clear! \n");

    	retval = wifiConnect();

        initNetwork();

        /* create timer task to get and transmit accel data via BLE for every one second automatically*/
        WifiTransmitTimerHandle = xTimerCreate((char * const ) "WifiTransmitTimerHandle", pdMS_TO_TICKS(WIFI_TX_FREQ), TIMER_AUTORELOAD_ON, NULL, EnqueueAccelDatatoWifi);

        WifiReceiveTimerHandle = xTimerCreate((char * const ) "WifiReceiveTimerHandle", pdMS_TO_TICKS(WIFI_RX_FREQ), TIMER_AUTORELOAD_ON, NULL, EnqueueReceiveDatatoWifi);

 

Third, we will upload the source that we have modified and added from the existing sendacceldataoverudpandble source. It would be nice to have a clear exchange of opinions by sending the entire source, but it is difficult because it is too open to the public.

I have declared a global variable as follows:

int16_t g_SockID = (int16_t) ZERO;
SlSockAddrIn_t  g_Addr;
_i16 g_AddrSize;

_i16 g_recvSock = NULL;
SlSockAddrIn_t g_LocalAddr;
char m_Buf[16];

 

static void initNetwork(void)
{
    memset(m_Buf,0,sizeof(m_Buf));

	g_Addr.sin_family = SL_AF_INET;
	g_Addr.sin_addr.s_addr = sl_Htonl(SERVER_IP);//sl_Htonl(SERVER_IP);//sl_Htonl(SERVER_IP);//
	g_Addr.sin_port = sl_Htons(SERVER_PORT); // SERVER_RIP SERVER_PORT

	g_AddrSize = sizeof(SlSockAddrIn_t);

    g_SockID = sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, (uint32_t) ZERO);

    if (g_SockID < (int16_t) ZERO)
    {
       printf("Error in socket opening1 \r\n");

       // error case
	   BSP_LED_Switch((uint32_t) BSP_XDK_LED_R, (uint32_t) BSP_LED_COMMAND_OFF);
	   BSP_LED_Switch((uint32_t) BSP_XDK_LED_O, (uint32_t) BSP_LED_COMMAND_ON);
	   BSP_LED_Switch((uint32_t) BSP_XDK_LED_Y, (uint32_t) BSP_LED_COMMAND_OFF);

	   return;
    }

   	g_LocalAddr.sin_port = sl_Htons(SERVER_PORT);
   	g_LocalAddr.sin_addr.s_addr = 0; //sl_Htonl(SERVER_RIP);
   	g_LocalAddr.sin_family = SL_AF_INET;

    printf("before Socket\r\n");

    g_recvSock = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM,0);



    struct SlTimeval_t timeVal;
        	timeVal.tv_sec = 0;
        	timeVal.tv_usec = 100;
    sl_SetSockOpt(g_recvSock, SL_SOL_SOCKET, SL_SO_RCVTIMEO, (_u8*)&timeVal, sizeof(timeVal)); // SL_SO_NONBLOCKING  //SL_SO_RCVTIMEO

    printf("before bind\r\n");

    sl_Bind(g_recvSock, (SlSockAddr_t *) &g_LocalAddr, g_AddrSize);
}
static void ReceiveDataOverWifi(void *param1, uint32_t port)
{
	//xTimerStop(WifiReceiveTimerHandle, NUMBER_ZERO);

	_i16 status;
	_i16 result = 0;

	status = sl_RecvFrom(g_recvSock,m_Buf,16,0,(SlSockAddr_t *)&g_LocalAddr,(SlSocklen_t*)&g_AddrSize);

	result += status;

	printf("AddrSize %d \r\n",result);

	if(result == 9)
	{
	    printf("AddrSize %d \r\n",status);
		printf("/////////////////////Receive Data : %s/////////////////////\n",m_Buf);
	}
	//xTimerStart(WifiReceiveTimerHandle, (WIFI_RX_FREQ / portTICK_RATE_MS));
}

 

0 (0 Votes)
RE: i want udp recieve data of PC
Answer
1/12/18 9:24 AM as a reply to jang.

Hello jang,

the only issue I currently see is the fact that you did not use a task, but a timer / command processor combination instead.

All callbacks for timers that you declare will be called within the context of a single task. The same is true for command processors. All functions you send to a command processor are executed by the same task.

That means, sending and receiving still block each other.

I recommend to use the following code for receiving:

static _i16 recvSock = NULL;

static void bindSocketToPort(void) {
    printf("bind\n\r");
   SlSockAddrIn_t  LocalAddr;
   _i16 AddrSize = sizeof(SlSockAddrIn_t);
   _i16 Status;

   LocalAddr.sin_family = SL_AF_INET;
   LocalAddr.sin_port = sl_Htons((uint16_t) 1338);
   LocalAddr.sin_addr.s_addr = 0;
   recvSock = sl_Socket(SL_AF_INET,SL_SOCK_DGRAM, 0);
   Status = sl_Bind(recvSock, (SlSockAddr_t *)&LocalAddr, AddrSize);
}

static void wifiUdpReceive(void *param){
   bindSocketToPort();
    static char Buf[256];
   _i16 Status;

   for(;;){
       printf("Receive\n\r");
       memset(Buf, 0, 256);
       Status = sl_Recv(recvSock, Buf, 256, 0);
       if(Status > 0) {
           printf("/////// Received ///////\n\r");
           printf("Length: %d\n\r", (int) Status);
           Buf[255] = 0;
           printf("Payload: %s\n\r", Buf);
           printf("////////////////////////\n\r");
       } else {
           printf("Sending failed with Status: %d\n\r", (int) Status);
       }

   }
}

static xTaskHandle udpRcv_Handle = NULL;

static void createReceivingTask(void){
   xTaskCreate(wifiUdpReceive,"udpRcv",512,NULL,1,udpRcv_Handle);
}
I tested this with the example SendDataOverUdp , and I can receive and send data at the same time. As a second endpoint for receiving and sending, I use a Raspberry PI, which receives messages on port 37 and sends them from port 38.

If that still does not help, could you please post your email address here, so I can contact you directly to give you the possibility of sending me your project?

Kind regards,
Franjo

 

0 (0 Votes)
RE: i want udp recieve data of PC
Answer
1/12/18 4:42 PM as a reply to Franjo Stjepandic.

Hello Jang,

You asked if it is possible to reduce the reply time and get direct support.

I got new information related to this topic. There is the possibility of premium support. If this is an option for you, feel free to contact support@bosch-connectivity.com.

Kind regards,
Franjo

0 (0 Votes)
RE: i want udp recieve data of PC
Answer
1/15/18 8:58 AM as a reply to Franjo Stjepandic.
Thanks to your help, progress has been made. Thank you.

I have a little problem and I want to solve it, but I need some help.
Although it is a UDP protocol, I have hardly seen data loss when transmitting.
However, there is a loss of data when receiving. Certainly, the reception rate of data is better than before.

However, when the data to be transmitted is received, it is received together.
We see this as the cause of loss of data when receiving.

I wonder if this is just a UDP protocol or whether there is a possibility of improvement.

Thank you for always.
0 (0 Votes)
RE: i want udp recieve data of PC
Answer
1/15/18 5:22 PM as a reply to jang.

Hello jang,

I am not quite sure how you perceive or measure the data loss.

First of all, the data your XDK sends is correct and the messages are sent as intended. Also, you have no loss on transmission, certainly. This leads me to think that the issue is entirely on the server-side now.

I find it strange that the data to be transmitted is received together. What exactly do you mean by that? Is the data broken? Or are messages appended to one another? In general, each UDP message should be standalone, and messages are not usually mixed together. Your server may be doing something wrong, or your code is not building the XDK messages correctly.

What kind of server are you running on your PC?

If you wish to do so, you could post your e-mail address here, so I can contact you for sending your project to me. I would take a look at it to determine if there is anything that still may need to be done in the application.

Kind regards,
Franjo

0 (0 Votes)