dns: FIX add README_API file and improve sample code

README_API file is added in this patch.

Inline code documentation is improved. More test domains are added.
The README file is also updated to reflect these changes.

Change-Id: Ie670a6559611c6a8d216470e245dbea48369696f
Signed-off-by: Flavio Santes <flavio.santes@intel.com>
diff --git a/samples/net/dns_client/README b/samples/net/dns_client/README
index f3c04e2..bb56936 100644
--- a/samples/net/dns_client/README
+++ b/samples/net/dns_client/README
@@ -1,5 +1,6 @@
 DNS Client Application
 
+
 Requirements
 ------------
 
@@ -11,8 +12,9 @@
 
 * dnsmasq application. The dnsmasq version used in this sample is:
 
-dnsmasq -v
-Dnsmasq version 2.75  Copyright (c) 2000-2015 Simon Kelley
+    dnsmasq -v
+    Dnsmasq version 2.75  Copyright (c) 2000-2015 Simon Kelley
+
 
 Building instructions
 ---------------------
@@ -34,69 +36,104 @@
 
 * Open a terminal window and type:
 
-dnsmasq -d
+    dnsmasq -d
 
 * Connect the USB-UART cable to the Galileo. Open a terminal and run:
 
-  screen /dev/ttyUSB0 115200
+    screen /dev/ttyUSB0 115200
 
 * Connect Galileo to the LAN, Turn on the board.
 
 * The screen terminal window will show:
 
-    WARNING: no console will be available to OS
-    error: no suitable video mode found.
-
     -----------------------------------------
     Domain name: not_a_real_domain_name
-    [fiber:82] DNS Create Query: 0, ID: 1
-    [fiber:85] TX: 0
-    [fiber:88] RX: -5
+    [fiber:89] DNS Query: OK, ID: 0
+    [fiber:92] TX: OK
+    [fiber:97] RX: OK
+    [fiber:102] DNS Response: ERROR <- :)
 
     -----------------------------------------
-    Domain name: oops!
-    [fiber:82] DNS Create Query: 0, ID: 2
-    [fiber:85] TX: 0
-    [fiber:88] RX: 0
-    [fiber:95] DNS response: 2
-
-    -----------------------------------------
-    Domain name: zephyrproject.org
-    [fiber:82] DNS Create Query: 0, ID: 3
-    [fiber:85] TX: 0
-    [fiber:88] RX: 0
+    Domain name: linuxfoundation.org
+    [fiber:89] DNS Query: OK, ID: 1
+    [fiber:92] TX: OK
+    [fiber:97] RX: OK
 
     ****** DNS ANSWER: 0 ******
-    Response: IP address            Size: 4:        140 211 169 8
-    [fiber:95] DNS response: 0
+    Response: IP address            Size: 4:        140 211 169 4
+
+    [fiber:102] DNS Response: OK
 
     -----------------------------------------
-    Domain name: www.google.com
-    [fiber:82] DNS Create Query: 0, ID: 4
-    [fiber:85] TX: 0
-    [fiber:88] RX: 0
+    Domain name: www.linuxfoundation.org
+    [fiber:89] DNS Query: OK, ID: 2
+    [fiber:92] TX: OK
+    [fiber:97] RX: OK
 
     ****** DNS ANSWER: 0 ******
-    Response: IP address            Size: 4:        216 58 192 4
-    [fiber:95] DNS response: 0
+    Response: IP address            Size: 4:        140 211 169 4
+
+    [fiber:102] DNS Response: OK
 
     -----------------------------------------
-    Domain name: mail.yahoo.com
-    [fiber:82] DNS Create Query: 0, ID: 5
-    [fiber:85] TX: 0
-    [fiber:88] RX: 0
+    Domain name: gnu.org
+    [fiber:89] DNS Query: OK, ID: 3
+    [fiber:92] TX: OK
+    [fiber:97] RX: OK
 
     ****** DNS ANSWER: 0 ******
-    Response: CNAME NO IP address           Size: 8:        5 108 111 103 105 110 192 17
-    CNAME: login.yahoo.com
+    Response: IP address            Size: 4:        208 118 235 148
+
+    [fiber:102] DNS Response: OK
+
+    -----------------------------------------
+    Domain name: www.gnu.org
+    [fiber:89] DNS Query: OK, ID: 4
+    [fiber:92] TX: OK
+    [fiber:97] RX: OK
+
+    ****** DNS ANSWER: 0 ******
+    Response: CNAME NO IP address
+    CNAME: wildebeest.gnu.org
+
 
     ****** DNS ANSWER: 1 ******
-    Response: CNAME NO IP address           Size: 35:       9 102 111 45 100 115 45 97 116 115 6 109 101 109 98 101 114 3 103 48 50 8 121 97 104 111 111 100 110 115 3 110 101 116 0
-    CNAME: fo-ds-ats.member.g02.yahoodns.net
+    Response: IP address            Size: 4:        208 118 235 148
 
-    ****** DNS ANSWER: 2 ******
-    Response: IP address            Size: 4:        98 136 189 41
-    [fiber:95] DNS response: 0
+    [fiber:102] DNS Response: OK
 
     -----------------------------------------
-    Bye!
+    Domain name: npr.org
+    [fiber:89] DNS Query: OK, ID: 5
+    [fiber:92] TX: OK
+    [fiber:97] RX: OK
+
+    ****** DNS ANSWER: 0 ******
+    Response: IP address            Size: 4:        216 35 221 76
+
+    [fiber:102] DNS Response: OK
+
+    -----------------------------------------
+    Domain name: www.npr.org
+    [fiber:89] DNS Query: OK, ID: 6
+    [fiber:92] TX: OK
+    [fiber:97] RX: OK
+
+    ****** DNS ANSWER: 0 ******
+    Response: CNAME NO IP address
+    CNAME: www-cdn.npr.org.edgesuite.net
+
+
+    ****** DNS ANSWER: 1 ******
+    Response: CNAME NO IP address
+    CNAME: a1723.g.akamai.net
+
+
+    ****** DNS ANSWER: 2 ******
+    Response: IP address            Size: 4:        63 80 4 192
+
+
+    ****** DNS ANSWER: 3 ******
+    Response: IP address            Size: 4:        63 80 4 161
+
+    [fiber:102] DNS Response: OK
diff --git a/samples/net/dns_client/README_API b/samples/net/dns_client/README_API
new file mode 100644
index 0000000..b02812e
--- /dev/null
+++ b/samples/net/dns_client/README_API
@@ -0,0 +1,23 @@
+DNS Client API
+
+-----------------------------------------------------------------------
+                   THIS API IS STILL WORK IN PROGRESS
+-----------------------------------------------------------------------
+
+The DNS Client API for Zephyr is a collection of C files:
+
+    - dns_pack.h, dns_pack.c:
+        RFC 1035 serialization and deserialization functions
+
+    - dns_utils.h. dns_utils.c:
+	Helper functions
+
+TODO
+
+    - Implement high-level functions to handle the server's response
+    - Remove:
+        * dns_query in src/main.c and handle the Transaction
+          Identifier internally.
+        * dns_response in src/main.c once high-level functions are
+          available.
+
diff --git a/samples/net/dns_client/src/main.c b/samples/net/dns_client/src/main.c
index b7e14f6..e69cf43 100644
--- a/samples/net/dns_client/src/main.c
+++ b/samples/net/dns_client/src/main.c
@@ -27,19 +27,26 @@
 uint8_t stack[STACK_SIZE];
 
 #define BUF_SIZE	1024
-
 uint8_t tx_raw_buf[BUF_SIZE];
 uint8_t rx_raw_buf[BUF_SIZE];
 
-#define SLEEP_TIME 10
+#define SLEEP_TIME	50
 
-char *domains[] = {"not_a_real_domain_name", "oops!",
-		   "zephyrproject.org", "www.google.com",
-		   "mail.yahoo.com", NULL};
+#define RC_STR(rc)	(rc == 0 ? "OK" : "ERROR")
 
+char *domains[] = {"not_a_real_domain_name",
+		   "linuxfoundation.org", "www.linuxfoundation.org",
+		   "gnu.org", "www.gnu.org",
+		   "npr.org", "www.npr.org",
+		   "wikipedia.org", "www.wikipedia.org",
+		   "zephyrproject.org", "www.zephyrproject.org",
+		   NULL};
+
+/* this function creates the DNS query					*/
 int dns_query(struct app_buf_t *buf, char *str, uint16_t id,
 	      enum dns_rr_type qtype);
 
+/* this function parses the DNS server response				*/
 int dns_response(struct app_buf_t *_buf, int *response_type, int src_id);
 
 void fiber(void)
@@ -50,6 +57,9 @@
 	struct app_buf_t rx_buf = APP_BUF_INIT(rx_raw_buf,
 					       sizeof(rx_raw_buf), 0);
 
+	/* If the network is a bit slow, increase rx_timeout and
+	 * tx_retry_timeout in struct netz_ctx_t
+	 */
 	struct netz_ctx_t netz_ctx = NETZ_CTX_INIT;
 
 	int response_type;
@@ -64,41 +74,39 @@
 
 	counter = 0;
 	do {
-		fiber_sleep(300);
-
 		printf("\n-----------------------------------------\n");
 
 		name = domains[counter];
 		if (name == NULL) {
 			counter = 0;
-			break;
+			continue;
 		}
-		counter += 1;
 
 		printf("Domain name: %s\n", name);
 
 		rc = dns_query(&tx_buf, name, counter, DNS_RR_TYPE_A);
-		printf("[%s:%d] DNS Create Query: %d, ID: %d\n",
-		       __func__, __LINE__, rc, counter);
+		printf("[%s:%d] DNS Query: %s, ID: %d\n",
+		       __func__, __LINE__, RC_STR(rc), counter);
 
 		rc = netz_tx(&netz_ctx, &tx_buf);
-		printf("[%s:%d] TX: %d\n", __func__, __LINE__, rc);
+		printf("[%s:%d] TX: %s\n", __func__, __LINE__, RC_STR(rc));
+
+		fiber_sleep(SLEEP_TIME);
 
 		rc = netz_rx(&netz_ctx, &rx_buf);
-		printf("[%s:%d] RX: %d\n", __func__, __LINE__, rc);
+		printf("[%s:%d] RX: %s\n", __func__, __LINE__, RC_STR(rc));
 
-		if (rc != 0) {
-			continue;
+		if (rc == 0) {
+			rc = dns_response(&rx_buf, &response_type, counter);
+			printf("[%s:%d] DNS Response: %s %s\n",
+			       __func__, __LINE__, RC_STR(rc),
+			       (rc != 0 && counter == 0 ? "<- :)" : ""));
 		}
 
-		rc = dns_response(&rx_buf, &response_type, counter);
-		printf("[%s:%d] DNS response: %d\n", __func__, __LINE__, rc);
-
-
+		counter += 1;
+		fiber_sleep(SLEEP_TIME);
 	} while (1);
 
-	printf("Bye!\n");
-
 }
 
 void main(void)
@@ -109,13 +117,18 @@
 			 0, 0, 7, 0);
 }
 
-
+/* Next versions must handle the transaction id internally		*/
 int dns_query(struct app_buf_t *buf, char *str, uint16_t id,
 	      enum dns_rr_type qtype)
 {
 	return dns_msg_pack_query(buf, str, id, qtype);
 }
 
+/* See dns_unpack_answer, and also see:
+ * https://tools.ietf.org/html/rfc1035#section-4.1.2
+ */
+#define DNS_QUERY_POS	0x0c
+
 int dns_response(struct app_buf_t *_buf, int *response_type, int src_id)
 {
 	struct dns_msg_t dns_msg = DNS_MSG_INIT(_buf->buf, _buf->size);
@@ -125,7 +138,7 @@
 
 	rc = dns_unpack_response_header(&dns_msg, src_id);
 	if (rc != 0) {
-		return rc;
+		return -EINVAL;
 	}
 
 	if (dns_header_qdcount(dns_msg.msg) != 1) {
@@ -134,20 +147,18 @@
 
 	rc = dns_unpack_response_query(&dns_msg);
 	if (rc != 0) {
-		return rc;
+		return -EINVAL;
 	}
 
 	i = 0;
-	/* the first dname is at 0x0c bytes */
-	ptr = 0x0c;
+	ptr = DNS_QUERY_POS;
 	while (i < dns_header_ancount(dns_msg.msg)) {
 
 		printf("\n****** DNS ANSWER: %d ******\n", i);
 
 		rc = dns_unpack_answer(&dns_msg, ptr);
 		if (rc != 0) {
-			printf("[%s:%d]\n", __func__, __LINE__);
-			return rc;
+			return -EINVAL;
 		}
 
 		switch (dns_msg.response_type) {
@@ -156,18 +167,16 @@
 			       dns_msg.response_length);
 			print_buf(dns_msg.msg + dns_msg.response_position,
 				  dns_msg.response_length);
+			printf("\n");
 			break;
 
 		case DNS_RESPONSE_CNAME_NO_IP:
-			printf("Response: CNAME NO IP address\t\tSize: %d:\t",
-			       dns_msg.response_length);
-			print_buf(dns_msg.msg + dns_msg.response_position,
-				  dns_msg.response_length);
-			printf("CNAME: ");
+			printf("Response: CNAME NO IP address");
+			printf("\nCNAME: ");
 			dns_print_readable_msg_label(dns_msg.response_position,
 						     dns_msg.msg,
 						     dns_msg.msg_size);
-
+			printf("\n");
 			ptr = dns_msg.response_position;
 
 			break;
@@ -179,9 +188,7 @@
 		}
 
 		dns_msg.answer_offset = dns_msg.answer_offset + 12
-				+ dns_msg.response_length;
-
-
+					+ dns_msg.response_length;
 		++i;
 	}