/** Actually send an sntp request to a server. * * @param server_addr resolved IP address of the SNTP server */ static void sntp_send_request(ip_addr_t *server_addr) { struct pbuf* p; p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM); if (p != NULL) { struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload; LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n")); /* Initialize request message */ sntp_initialize_request(sntpmsg); /* Send request */ udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT); pbuf_free(p); // [iva2k] fixing memory leak /* Set up receive timeout: try next server or retry on timeout */ sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL); #if SNTP_CHECK_RESPONSE >= 1 /* Save server address to verify it in sntp_recv */ ip_addr_set(&sntp_last_server_address, server_addr); #endif /* SNTP_CHECK_RESPONSE >= 1 */ } else { LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n", (u32_t)SNTP_RETRY_TIMEOUT)); /* Out of memory: set up a timer to send a retry */ sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL); } }
/** Actually send an sntp request to a server. * * @param server_addr resolved IP address of the SNTP server */ void sntp_send_request(ip_addr_t *server_addr) { struct pbuf* p; p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM); if (p != NULL) { struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload; LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n")); /* os_sprintf(deb,"sntp_send_request: Sending request to server\n"); uart0_sendStr(deb);*/ /* initialize request message */ sntp_initialize_request(sntpmsg); /* send request */ udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT); /* os_sprintf(deb,"sntp_send_request: Sent request to server\n"); uart0_sendStr(deb);*/ /* free the pbuf after sending it */ pbuf_free(p); /* os_sprintf(deb,"sntp_send_request: freed request\n"); uart0_sendStr(deb);*/ /* set up receive timeout: try next server or retry on timeout */ sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL); #if SNTP_CHECK_RESPONSE >= 1 /* save server address to verify it in sntp_recv */ ip_addr_set(&sntp_last_server_address, server_addr); #endif /* SNTP_CHECK_RESPONSE >= 1 */ } else { LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, "sntp_send_request: Out of memory, trying again in %"U32_F" ms\n", (u32_t)SNTP_RETRY_TIMEOUT); /* os_sprintf(deb,"sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",(u32_t)SNTP_RETRY_TIMEOUT); uart0_sendStr(deb);*/ /* out of memory: set up a timer to send a retry */ sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL); } /*os_sprintf(deb,"sntp_send_request: finished\n"); uart0_sendStr(deb);*/ }
/** * Send an SNTP request via sockets. * This is a very minimal implementation that does not fully conform * to the SNTPv4 RFC, especially regarding server load and error procesing. */ void sntp_request(void *arg) { int sock; struct sockaddr_in local; struct sockaddr_in to; int tolen; int size; int timeout; struct sntp_msg sntpmsg; ip_addr_t sntp_server_address; LWIP_UNUSED_ARG(arg); /* if we got a valid SNTP server address... */ if (ipaddr_aton(SNTP_SERVER_ADDRESS, &sntp_server_address)) { /* create new socket */ sock = lwip_socket(AF_INET, SOCK_DGRAM, 0); if (sock >= 0) { /* prepare local address */ memset(&local, 0, sizeof(local)); local.sin_family = AF_INET; local.sin_port = PP_HTONS(INADDR_ANY); local.sin_addr.s_addr = PP_HTONL(INADDR_ANY); /* bind to local address */ if (lwip_bind(sock, (struct sockaddr *)&local, sizeof(local)) == 0) { /* set recv timeout */ timeout = SNTP_RECV_TIMEOUT; lwip_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); /* prepare SNTP request */ sntp_initialize_request(&sntpmsg); /* prepare SNTP server address */ memset(&to, 0, sizeof(to)); to.sin_family = AF_INET; to.sin_port = PP_HTONS(SNTP_PORT); inet_addr_from_ipaddr(&to.sin_addr, &sntp_server_address); /* send SNTP request to server */ if (lwip_sendto(sock, &sntpmsg, SNTP_MSG_LEN, 0, (struct sockaddr *)&to, sizeof(to)) >= 0) { /* receive SNTP server response */ tolen = sizeof(to); size = lwip_recvfrom(sock, &sntpmsg, SNTP_MSG_LEN, 0, (struct sockaddr *)&to, (socklen_t *)&tolen); /* if the response size is good */ if (size == SNTP_MSG_LEN) { /* if this is a SNTP response... */ if (((sntpmsg.li_vn_mode & SNTP_MODE_MASK) == SNTP_MODE_SERVER) || ((sntpmsg.li_vn_mode & SNTP_MODE_MASK) == SNTP_MODE_BROADCAST)) { /* do time processing */ sntp_process(sntpmsg.receive_timestamp); } else { LWIP_DEBUGF( SNTP_DEBUG_WARN, ("sntp_request: not response frame code\n")); } } } else { LWIP_DEBUGF( SNTP_DEBUG_WARN, ("sntp_request: not sendto==%i\n", errno)); } } /* close the socket */ closesocket(sock); } } }