emNet DNS Client (Sample)
Jump to navigation
Jump to search
| IP_DNS_Client_Sample.c | |
|---|---|
| Requires modifications | No |
| Download | IP_DNS_Client_Sample.c |
This Sample demonstrates how to use emNet to resolve a hostname to an IP address. By default multiple SEGGER hostnames are used.
Code
/*********************************************************************
* (c) SEGGER Microcontroller GmbH *
* The Embedded Experts *
* www.segger.com *
**********************************************************************
-------------------------- END-OF-HEADER -----------------------------
Purpose : Sample program for embOS & emNet
Demonstrates use of the IP stack to resolve a hostname to an
IP addr. IP_ResolveHost() is used instead of gethostbyname()
as gethostbyname() is not thread safe and is therefore not
recommended to be used.
The DNS client will resolve a hostname to its IP addr. using
the DNS server of an interface. The following is a sample of
the output to the terminal window:
<...>
30:033 DNSClient - DNS resolve demonstration
31:033 DNSClient - IP addr. 116.203.153.115 resolved from host name "segger.com".
32:033 DNSClient - IP addr. 194.45.36.135 resolved from host name "blog.segger.com".
33:033 DNSClient - IP addr. 5.104.108.9 resolved from host name "wiki.segger.com".
34:033 DNSClient - IP addr. 89.163.210.194 resolved from host name "forum.segger.com".
35:033 DNSClient - IP addr. 213.202.222.194 resolved from host name "studio.segger.com".
36:033 DNSClient - IP addr. 194.45.36.135 resolved from host name "support.segger.com".
<...>
*/
#include "RTOS.h"
#include "BSP.h"
#include "IP.h"
/*********************************************************************
*
* Configuration
*
**********************************************************************
*/
#define USE_RX_TASK 0 // 0: Packets are read in ISR, 1: Packets are read in a task of its own.
//
// DNS client sample.
//
#define TIMEOUT 10000 // Timeout for DNS request [ms].
//
// Task priorities.
//
enum {
TASK_PRIO_IP_DNSC = 150
,TASK_PRIO_IP_TASK // Priority should be higher than all IP application tasks.
#if USE_RX_TASK
,TASK_PRIO_IP_RX_TASK // Must be the highest priority of all IP related tasks.
#endif
};
//
// Task stack sizes that might not fit for some interfaces (multiples of sizeof(int)).
//
#ifndef APP_TASK_STACK_OVERHEAD
#define APP_TASK_STACK_OVERHEAD 0
#endif
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
//
// List of host names to resolve
//
static const char* _Hosts[] = { "segger.com", "blog.segger.com", "wiki.segger.com", "forum.segger.com", "studio.segger.com", "support.segger.com" };
static IP_HOOK_ON_STATE_CHANGE _StateChangeHook;
static int _IFaceId;
//
// Task stacks and Task-Control-Blocks.
//
static OS_STACKPTR int _IPStack[TASK_STACK_SIZE_IP_TASK/sizeof(int)]; // Stack of the IP_Task.
static OS_TASK _IPTCB; // Task-Control-Block of the IP_Task.
#if USE_RX_TASK
static OS_STACKPTR int _IPRxStack[TASK_STACK_SIZE_IP_RX_TASK/sizeof(int)]; // Stack of the IP_RxTask.
static OS_TASK _IPRxTCB; // Task-Control-Block of the IP_RxTask.
#endif
static OS_STACKPTR int _DNScStack[(1152 + APP_TASK_STACK_OVERHEAD)/sizeof(int)]; // Stack of the DNS client.
static OS_TASK _DNScTCB; // Task-Control-Block of the DNS client.
/*********************************************************************
*
* Prototypes
*
**********************************************************************
*/
#ifdef __cplusplus
extern "C" { /* Make sure we have C-declarations in C++ programs */
#endif
void MainTask(void);
#ifdef __cplusplus
}
#endif
/*********************************************************************
*
* Local functions
*
**********************************************************************
*/
/*********************************************************************
*
* _OnStateChange()
*
* Function description
* Callback that will be notified once the state of an interface
* changes.
*
* Parameters
* IFaceId : Zero-based interface index.
* AdminState: Is this interface enabled ?
* HWState : Is this interface physically ready ?
*/
static void _OnStateChange(unsigned IFaceId, U8 AdminState, U8 HWState) {
//
// Check if this is a disconnect from the peer or a link down.
// In this case call IP_Disconnect() to get into a known state.
//
if (((AdminState == IP_ADMIN_STATE_DOWN) && (HWState == 1)) || // Typical for dial-up connection e.g. PPP when closed from peer. Link up but app. closed.
((AdminState == IP_ADMIN_STATE_UP) && (HWState == 0))) { // Typical for any Ethernet connection e.g. PPPoE. App. opened but link down.
IP_Disconnect(IFaceId); // Disconnect the interface to a clean state.
}
}
/*********************************************************************
*
* _DNScTask()
*
* Function description
* DNS client task that resolves the configured host name to its
* IP addr.
*/
static void _DNScTask(void) {
U32 IPAddr;
int i;
int r;
int NumIFaces;
char ac[16];
U8 IFaceReady;
//
// Make sure that at least one interface is ready before starting the sample.
//
IFaceReady = 0;
NumIFaces = IP_INFO_GetNumInterfaces();
do {
for (i = 0; i < NumIFaces; i++) {
if (IP_IFaceIsReadyEx(_IFaceId) != 0) {
IFaceReady = 1;
break;
}
OS_Delay(100);
}
} while (IFaceReady == 0);
//
// DNS client sample.
//
while (1) {
IP_Logf_Application("DNS resolve demonstration");
for (i = 0; i < (int)SEGGER_COUNTOF(_Hosts); i++) {
OS_Delay(1000); // One check per second is enough.
r = IP_ResolveHost(_Hosts[i], &IPAddr, TIMEOUT); // Resolve host name.
if (r != 0) {
IP_Logf_Application("Could not resolve host addr.");
continue;
}
IP_PrintIPAddr(ac, ntohl(IPAddr), sizeof(ac));
IP_Logf_Application("IP addr. %s resolved from host name \"%s\".", ac, _Hosts[i]);
}
IP_Logf_Application(" "); // newline
OS_Delay(5000);
}
}
/*********************************************************************
*
* Global functions
*
**********************************************************************
*/
/*********************************************************************
*
* MainTask()
*
* Function description
* Main task executed by the RTOS to create further resources and
* running the main application.
*/
void MainTask(void) {
IP_Init();
IP_AddLogFilter(IP_MTYPE_APPLICATION);
_IFaceId = IP_INFO_GetNumInterfaces() - 1; // Get the last registered interface ID as this is most likely the interface we want to use in this sample.
OS_SetPriority(OS_GetTaskID(), TASK_PRIO_IP_TASK); // For now, this task has highest prio except IP management tasks.
OS_CREATETASK(&_IPTCB , "IP_Task" , IP_Task , TASK_PRIO_IP_TASK , _IPStack); // Start the IP_Task.
#if USE_RX_TASK
OS_CREATETASK(&_IPRxTCB, "IP_RxTask", IP_RxTask, TASK_PRIO_IP_RX_TASK, _IPRxStack); // Start the IP_RxTask, optional.
#endif
OS_CREATETASK(&_DNScTCB, "DNSClient", _DNScTask, TASK_PRIO_IP_DNSC , _DNScStack); // Start the DNS client.
IP_AddStateChangeHook(&_StateChangeHook, _OnStateChange); // Register hook to be notified on disconnects.
IP_Connect(_IFaceId); // Connect the interface if necessary.
OS_SetPriority(OS_GetTaskID(), 255); // Now this task has highest prio for real-time application. This is only allowed when this task does not use blocking IP API after this point.
while (IP_IFaceIsReadyEx(_IFaceId) == 0) {
OS_Delay(50);
}
while (1) {
BSP_ToggleLED(1);
OS_Delay(200);
}
}
/*************************** End of file ****************************/