<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/60254/how-to-support-msg_waitall-flag-for-recv-operation</link><description>Hi 
 We need the recv() be blocking until the full amount of requested data can be returned or the operation was timeout, how to achieve this? 
 I tried flag MSG_WAITALL but failed to compile with error &amp;#39;MSG_WAITALL&amp;#39; undeclared; 
 I also tried flag NRF_MSG_WAITALL</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 20 May 2020 01:19:07 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/60254/how-to-support-msg_waitall-flag-for-recv-operation" /><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/250841?ContentTypeID=1</link><pubDate>Wed, 20 May 2020 01:19:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:11c567ed-0cbc-4a6e-a655-ab3949e60739</guid><dc:creator>Siyou</dc:creator><description>&lt;p&gt;Thank Hakon, the UDP behaves as design, resolved.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/250721?ContentTypeID=1</link><pubDate>Tue, 19 May 2020 12:31:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d32fcbaa-011c-449a-a355-f1ae1602af13</guid><dc:creator>Hakon</dc:creator><description>&lt;p&gt;It&amp;#39;s hard to tell from the documentation, it doesn&amp;#39;t say much about UDP. This is what I found&lt;/p&gt;
&lt;p&gt;&amp;quot;For message-based sockets, such as SOCK_DGRAM and SOCK_SEQPACKET, the entire message shall be read in a single operation. If a message is too long to fit in the supplied buffer, and MSG_PEEK is not set in the &lt;i&gt;flags&lt;/i&gt; argument, the excess bytes shall be discarded.&amp;quot;&lt;/p&gt;
&lt;p&gt;Can you show me the code where you set up the UDP socket?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/250327?ContentTypeID=1</link><pubDate>Mon, 18 May 2020 04:04:06 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a4ee13b9-ac43-43cc-b4da-97fcaa1c5ab4</guid><dc:creator>Siyou</dc:creator><description>&lt;p&gt;Hi Hakon,&lt;/p&gt;
&lt;p&gt;Thanks, the&amp;nbsp;&lt;span&gt;NRF_MSG_WAITALL works with&amp;nbsp;nrf_recv().&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;But for UDP case, it seems that the&amp;nbsp;NRF_MSG_WAITALL&amp;nbsp;has&amp;nbsp;&lt;span class="tran"&gt;no&lt;/span&gt; &lt;span class="tran"&gt;effect&amp;nbsp;&lt;/span&gt;&amp;nbsp;to nrf_recvfrom(), could you confirm whether it is supported on UDP also?&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/247582?ContentTypeID=1</link><pubDate>Thu, 30 Apr 2020 13:28:28 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5eaeb02e-47cb-4ac0-8a63-97bee927b39d</guid><dc:creator>Hakon</dc:creator><description>&lt;p&gt;You should try using the bsdlib socket API, instead of using Zephyr&amp;#39;s socket API. For example, you should replace socket() with nrf_socket(), and recv() with nrf_recv().&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/247181?ContentTypeID=1</link><pubDate>Wed, 29 Apr 2020 01:17:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:35ab00c2-15e9-4521-ba48-7244d1f3d0d5</guid><dc:creator>Siyou</dc:creator><description>&lt;p&gt;First we open socket and connect to the server;&lt;/p&gt;
&lt;p&gt;Second, invoke the&amp;nbsp;do_socket_receive() to receive data from server with timeout.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;
static int do_socket_open(u16_t type, char* url, u16_t dst_port, u16_t src_port)
{
	int err = -EINVAL;
	int client_fd;
	enum net_sock_type sock_type;
	enum net_ip_protocol protocol;
	struct sockaddr_in local_addr;
	int addr_len;
	//int reuse = 1;

	sock_type = type ? SOCK_STREAM : SOCK_DGRAM;
	protocol = type ? IPPROTO_TCP : IPPROTO_UDP;

	LOG_DBG(&amp;quot;%s:%d&amp;quot;, log_strdup(url), dst_port);

	err = modem_info_params_get(&amp;amp;modem_param);
	if (err) {
		LOG_ERR(&amp;quot;Unable to obtain modem parameters (%d)&amp;quot;, err);
		return -1;
	}
	/* Check network connection status by checking local IP address */
	addr_len = strlen(modem_param.network.ip_address.value_string);
	if (addr_len == 0) {
		LOG_ERR(&amp;quot;LTE not connected yet&amp;quot;);
		return -1;
	}
	if (!check_for_ipv4(modem_param.network.ip_address.value_string,
			addr_len)) {
		LOG_ERR(&amp;quot;Invalid local address&amp;quot;);
		return -1;
	}

	if (check_for_ipv4(url, strlen(url))) {
		err = parse_host_by_ipv4(url, dst_port);
	} else {
		err = parse_host_by_name(url, dst_port, sock_type);
	}
	if (err) {
		LOG_ERR(&amp;quot;Parse failed: %d&amp;quot;, err);
		return err;
	}

	client_fd = socket(AF_INET, sock_type, protocol);
	if (client_fd &amp;lt; 0) {
		LOG_ERR(&amp;quot;socket() failed: %d&amp;quot;, -errno);
		return -errno;
	}
/*	err = setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR,
					(const char *)&amp;amp;reuse, sizeof(reuse));
	if (err &amp;lt; 0) {
		close(client_fd);
		LOG_ERR(&amp;quot;setsockopt() error: %d&amp;quot;, -errno);
		return -errno;
	}*/

	sc_client.sock = client_fd;
	sc_client.protocol = protocol;

	LOG_DBG(&amp;quot;Socket opened&amp;quot;);

	local_addr.sin_family = AF_INET;
	local_addr.sin_port = htons(src_port);

	/* NOTE inet_pton() returns 1 as success */
	if (inet_pton(AF_INET, modem_param.network.ip_address.value_string,
		&amp;amp;local_addr.sin_addr.s_addr) != 1) {
		LOG_ERR(&amp;quot;Parse local IP address failed: %d&amp;quot;, -errno);
		return -EINVAL;
	}

	if(protocol == IPPROTO_TCP) {
		err = connect(client_fd, (struct sockaddr *)&amp;amp;sc_client.remote,
				  sizeof(struct sockaddr_in));
		if (err &amp;lt; 0) {
			LOG_ERR(&amp;quot;connect err: %d errno: %d&amp;quot;, err, errno);
			do_socket_close();
			return -errno;
		}
		sc_client.connected = true;
	} else { //UDP use bind() then share the send() and recv()
		err = bind(client_fd, (struct sockaddr *)&amp;amp;local_addr,
			   sizeof(local_addr));
		if (err) {
			LOG_ERR(&amp;quot;bind err: %d errno: %d&amp;quot;, err, errno);
			do_socket_close();
			return -errno;
		}
	}

	sc_client.running = true;
	LOG_INF(&amp;quot;Socket connection service started&amp;quot;);
	return err;
}



static int do_socket_receive(u16_t size, u16_t timeout_ms, bool crc32_enabled)
{
	int ret;
	u8_t data[NET_IPV4_MTU] = {0};
	char hexstr[2*NET_IPV4_MTU+4];
	int sockaddr_len = sizeof(struct sockaddr_in);
	int sock = sc_client.sock;
	struct timeval tmo = {
		.tv_sec = (timeout_ms / 1000),
		.tv_usec = (timeout_ms % 1000) * 1000,
	};
	bool gps_is_active;
	u32_t crc32;

	if (size &amp;gt; sizeof(data)) {
		LOG_ERR(&amp;quot;socket receive err: requested size %d exceeded data buffer(%d)&amp;quot;, size, sizeof(data));
		return -EINVAL;
	}

	gps_is_active = gps_is_running();
	if(gps_is_active) {
		ret = gps_control_stop();
	}

	ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
			&amp;amp;tmo, sizeof(struct timeval));
	if (ret &amp;lt; 0) {
		//do_socket_close(-errno);
		LOG_ERR(&amp;quot;setsockopt() error: %d&amp;quot;, -errno);
		goto error;
	}

	if(sc_client.protocol == IPPROTO_TCP) {
		if(!sc_client.connected) {
			LOG_ERR(&amp;quot;Socket receive error: TCP client has not connected to server&amp;quot;);
			ret = -ENOPROTOOPT;
			goto error;
		}
		ret = recv(sock, data, size, NRF_MSG_WAITALL);
	}
	else {
		ret = recvfrom(sock, data, size, NRF_MSG_WAITALL,
			(struct sockaddr *)&amp;amp;sc_client.remote, &amp;amp;sockaddr_len);
	}

	if (ret &amp;lt; 0) {
		LOG_WRN(&amp;quot;recv() error: %d&amp;quot;, -errno);
		if (errno != EAGAIN &amp;amp;&amp;amp; errno != ETIMEDOUT &amp;amp;&amp;amp; errno != EINVAL) {
			do_socket_close();
			ret = -errno;
			//sprintf(buf, &amp;quot;+MSC: %d\r\n&amp;quot;, -errno);
			//sc_client.callback(buf);
		} else {
			sprintf(buf, &amp;quot;+MSCRECV: 0\r\n&amp;quot;);
			sc_client.callback(buf);
			ret = 0;
		}
	} else if (ret == 0) {
		/**
		 * When a stream socket peer has performed an orderly shutdown,
		 * the return value will be 0 (the traditional &amp;quot;end-of-file&amp;quot;)
		 * The value 0 may also be returned if the requested number of
		 * bytes to receive from a stream socket was 0
		 * In both cases, treat as normal shutdown by remote
		 */
		LOG_WRN(&amp;quot;recv() return 0&amp;quot;);
		sprintf(buf, &amp;quot;+MSCRECV: 0\r\n&amp;quot;);
		sc_client.callback(buf);
	} else {
		data[ret] = &amp;#39;\0&amp;#39;;
		LOG_INF(&amp;quot;MSCRECV: %d, data[%s]&amp;quot;, ret, log_strdup(data));
		if(crc32_enabled) {
			crc32 = crc32_ieee(data, ret);
			LOG_DBG(&amp;quot;CRC32:0x%04X&amp;quot;, crc32);
			sprintf(buf, &amp;quot;+MSCRECV: %d,\&amp;quot;%04X\&amp;quot;,&amp;quot;, ret, crc32);
		}
		else {
			sprintf(buf, &amp;quot;+MSCRECV: %d,\&amp;quot;00000000\&amp;quot;,&amp;quot;, ret);
		}

		int_to_hexstring(data, hexstr, ret, 2*MAX_DATA_SIZE+4);
		sc_client.callback(buf);
		sc_client.callback(hexstr);
		ret = 0;
	}

error:
	if(gps_is_active) {
		gps_control_start();
	}
	return ret;
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/247033?ContentTypeID=1</link><pubDate>Tue, 28 Apr 2020 10:21:20 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c2e016d0-5f46-47fd-92b8-120935f76d57</guid><dc:creator>Hakon</dc:creator><description>&lt;p&gt;Is there a chance that I can look at the code. I want to see how you are setting up the sockets.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/247022?ContentTypeID=1</link><pubDate>Tue, 28 Apr 2020 09:45:08 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:f3894ee7-d8d3-469e-9ff6-b77e257fce85</guid><dc:creator>Siyou</dc:creator><description>&lt;p&gt;It&amp;#39;s blocking mode. I said it can be blocked if server did not send any data:&lt;/p&gt;
[quote userid="86436" url="~/f/nordic-q-a/60254/how-to-support-msg_waitall-flag-for-recv-operation/245479"]1, My TCP client recv() could be blocking untill timeout if TCP server did not send any data;[/quote]
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Can you have a try on your side as&amp;nbsp;the previous post? it spends more than 10 days and I just need your confirmation that whether the flag is supported or not.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/246478?ContentTypeID=1</link><pubDate>Fri, 24 Apr 2020 11:23:00 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:0e25a82f-ed6f-482e-8717-0b3f7861e89c</guid><dc:creator>Hakon</dc:creator><description>&lt;p&gt;Is the socket in non-blocking mode?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/246373?ContentTypeID=1</link><pubDate>Fri, 24 Apr 2020 01:27:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e7848fa6-ad89-4dd3-905a-8194b71d693e</guid><dc:creator>Siyou</dc:creator><description>&lt;p&gt;Hi Hakon,&lt;/p&gt;
&lt;p&gt;I cannot agree with you.&lt;/p&gt;
&lt;p&gt;According to&amp;nbsp;&lt;a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html"&gt;https://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;MSG_WAITALL
On SOCK_STREAM sockets this requests that the function block until the full amount of data can be returned. 
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;If your&amp;nbsp;&lt;span&gt;NRF_MSG_WAITALL is&amp;nbsp;the equivalent of MSG_WAITALL, the expected behavior is: block until the full amount of data can be returned, right?&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/246268?ContentTypeID=1</link><pubDate>Thu, 23 Apr 2020 12:50:46 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3b50f30e-6edd-4c26-bf5f-cad725e04f7c</guid><dc:creator>Hakon</dc:creator><description>&lt;p&gt;From what I gather, the NRF_MSG_WAITALL flag just means the recv() will block until it receives &lt;strong&gt;any&lt;/strong&gt; data, whether it&amp;#39;s 1 byte or 1000 bytes. The size parameter just sets the maximum amount of bytes you can receive in a single recv() call, and has nothing to do with the amount of data it takes for recv() to return. Does that make sense?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/246135?ContentTypeID=1</link><pubDate>Thu, 23 Apr 2020 02:54:16 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9f01764f-5352-4e30-9b23-cf890edc35ad</guid><dc:creator>Siyou</dc:creator><description>[quote userid="73166" url="~/f/nordic-q-a/60254/how-to-support-msg_waitall-flag-for-recv-operation/246018"]What do you mean by requested data here?[/quote]
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;ret = recv(sock, data, size, NRF_MSG_WAITALL);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Let me take my code as example, the requested data is the input parameter&amp;nbsp;&lt;strong&gt;size&lt;/strong&gt; of recv()&lt;/p&gt;
&lt;p&gt;When I set the timeout to 10000(10s), size to 10,&amp;nbsp;the recv() is expected could be blocking until either 10s timeout or it received 10 bytes of data. But the actual result is: if the TCP server sent out only 5 bytes of data within 10s, nRF9160 recv() will return the 5 bytes data instead of blocking&amp;nbsp;until timeout.&lt;/p&gt;
&lt;p&gt;That is, the&amp;nbsp;NRF_MSG_WAITALL did not seem to work.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/246018?ContentTypeID=1</link><pubDate>Wed, 22 Apr 2020 11:47:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3f451b42-1391-4b76-98d2-acba032d2947</guid><dc:creator>Hakon</dc:creator><description>[quote user="Siyou"]instead of waiting for the whole requested data untill timeout. [/quote]
&lt;p&gt;&amp;nbsp;What do you mean by requested data here? With NRF_MSG_WAITALL the recv will be blocking until data has been received or it times out.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/245479?ContentTypeID=1</link><pubDate>Mon, 20 Apr 2020 10:00:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:843ea35e-1bf9-4c8b-811e-43f6afca4d8f</guid><dc:creator>Siyou</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;Sorry I cannot&amp;nbsp;find the answer from your link, which flag should I use,&amp;nbsp;&lt;span&gt;&lt;strong&gt;MSG_WAITALL&amp;nbsp;&lt;/strong&gt;or&amp;nbsp;&lt;strong&gt;NRF_MSG_WAITALL&lt;/strong&gt;?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;To obviate misunderstanding, let me explain more about my question:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;1, My TCP client recv() could be blocking untill timeout if TCP server did not send any data;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;2,&amp;nbsp;Conversely, if TCP server sent a part of client requested data before recv() timeout, the client will return the part of data&amp;nbsp;immediately instead of waiting for the whole requested data untill timeout. This is my issue, we need the recv() waiting&amp;nbsp;untill ether it was timeout or the client received the requested&amp;nbsp;complete data.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;SDK: NCS v1.2&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;modem:&amp;nbsp;mfw_nrf9160_1.1.1&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/245473?ContentTypeID=1</link><pubDate>Mon, 20 Apr 2020 09:34:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:3b43ed03-a2c4-42df-8873-b03eb9374a39</guid><dc:creator>Hakon</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;this was &lt;a href="https://github.com/NordicPlayground/fw-nrfconnect-nrf/pull/561"&gt;fixed&lt;/a&gt; a long time ago, so recv should be blocking by default. If it isn&amp;#39;t, you should consider updating your NCS repos, and also upgrading the firmware.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: How to support MSG_WAITALL flag for recv() operation</title><link>https://devzone.nordicsemi.com/thread/245469?ContentTypeID=1</link><pubDate>Mon, 20 Apr 2020 09:22:57 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:bb52c3f0-f09a-4957-81a7-e8a09c127173</guid><dc:creator>Siyou</dc:creator><description>&lt;p&gt;Can anyone from Nordic help to confirm it?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>