第 2 章 - Azure RTOS NetX PPPoE 客户端的安装和使用
本章包含与安装、设置和使用 Azure RTOS NetX PPPoE 客户端组件相关的各种问题的说明。
产品分发
NetX 正在由 NetX Duo 取代。 有关 NetX Duo 中此功能的详细信息,请参阅 NetX Duo。 原始 NetX PPPoE 客户端包包含以下文件:
- nx_pppoe_client.h:适用于 NetX 的 PPPoE 客户端的头文件
- nx_pppoe_client.c:适用于 NetX 的 PPPoE 客户端的 C 源文件
- nx_pppoe_client.pdf:适用于 NetX 的 PPPoE 客户端的 PDF 说明
- demo_netx_pppoe_client.c:NetX PPPoE 客户端演示
PPPoE 客户端安装
要使用适用于 NetX 的 PPPoE 客户端,应将前面提到的整个分发包复制到 NetX 所安装在的目录中。 例如,如果 NetX 安装在“\threadx\arm7\green”目录中,则应将 nx_pppoe_client.h 和 nx_pppoe_client.c 文件复制到该目录中。
使用 PPPoE 客户端
使用适用于 NetX 的 PPPoE 客户端非常简单。 总体上,应用程序代码必须先包含 tx_api.h 和 nx_api.h,然后包含 nx_pppoe_client.h,才能分别使用 ThreadX 和 NetX。 包含 nx_pppoe_client.h 之后,应用程序代码就可以进行本指南随后部分所述的 PPPoE 客户端函数调用。 应用程序还必须在生成过程中包含 nx_pppoe_client.c。 此文件必须采用与其他应用程序文件相同的方式来编译,并且其对象窗体必须与该应用程序的文件一起链接。 这就是使用 NetX PPPoE 客户端所需的一切。
小型示例系统
下面的示例演示如何使用 NetX PPPoE 客户端,如图 1.1 所述。 在此示例中,第 50 行引入 PPPoE 客户端包含文件 nx_pppoe_client.h。 接下来,在“thread_0_entry”中的第 238 行创建 PPPoE 客户端。 请注意,应该先创建 IP 实例,然后再创建 PPPoE 客户端。 在第 142-220 行,创建并初始化 IP 实例和 PPP 实例。 在之前的第 75 行,已将 PPPoE 客户端控制块“pppoe_client”定义为全局变量。 send 和 receive 函数在第 238 行进行设置。
通常,PPPoE 模块应与 PPP 模块配合使用。 在此示例中,第 49 行引入 PPP 客户端包含文件 nx_ppp.h。 接下来,在第 164 行创建 PPP 客户端。 第 172 行设置用于发送 PPP 数据包的函数。 第 179-190 行设置 IP 地址,并定义 pap 协议。 第 104-129 行设置 pap 协议的用户名和密码。
PPPoE 会话建立之后, 在第 264 行,应用程序可以调用 nx_pppoe_client_session_get,获取会话信息(服务器 MAC 地址和会话 id)。 在第 283 行,PPP 或应用程序可以调用 nx_pppoe_client_session_packet_send,发送 PPPoE 数据包。
当应用程序不再处理 PPP 流量时,应用程序可以调用 nx_pppoe_client_session_terminate 终止 PPPoE 会话。
请注意,在此示例中,PPPoE 客户端与普通 IP 堆栈同时运行,并共享一个以太网驱动程序。 在第 155 行,传递同一以太网驱动程序以创建普通 IP 实例,并在第 298 行传递该驱动程序以创建 PPPoE 客户端实例。
注意
将 NX_PHYSICAL_HEADER 重新定义为 24,确保有足够的空间可用于填充物理标头。 物理标头:14(以太网标头)+ 6(PPPoE 标头)+ 2(PPP 标头)+ 2(四字节对齐)。
1 /**************************************************************************/
2 /**************************************************************************/
3 /** */
4 /** NetX PPPoE Client stack Component */
5 /** */
6 /** This is a small demo of the high-performance NetX PPPoE Client */
7 /** stack. This demo includes IP instance, PPPoE Client and PPP Client */
8 /** stack. Create one IP instance includes two interfaces to support */
9 /** for normal IP stack and PPPoE Client, PPPoE Client can use the */
10 /** mutex of IP instance to send PPPoE message when share one Ethernet */
11 /** driver. PPPoE Client work with normal IP instance at the same time. */
12 /** */
13 /** Note1: Substitute your Ethernet driver instead of */
14 /** _nx_ram_network_driver before run this demo */
15 /** */
16 /** Note2: Prerequisite for using PPPoE. */
17 /** Redefine NX_PHYSICAL_HEADER to 24 to ensure enough space for filling*/
18 /** in physical header. Physical header:14(Ethernet header) */
19 /** + 6(PPPoE header) + 2(PPP header) + 2(four-byte aligment) */
20 /** */
21 /**************************************************************************/
22 /**************************************************************************/
23
24
25 /*****************************************************************/
26 /* NetX Stack */
27 /*****************************************************************/
28
29 /***************************/
30 /* PPP Client */
31 /***************************/
32
33 /***************************/
34 /* PPPoE Client */
35 /***************************/
36 /***************************/ /***************************/
37 /* Normal Ethernet Type */ /* PPPoE Ethernet Type */
38 /***************************/ /***************************/
39 /***************************/ /***************************/
40 /* Interface 0 */ /* Interface 1 */
41 /***************************/ /***************************/
42
43 /*****************************************************************/
44 /* Ethernet Dirver */
45 /*****************************************************************/
46
47 #include "tx_api.h"
48 #include "nx_api.h"
49 #include "nx_ppp.h"
50 #include "nx_pppoe_client.h"
51
52 /* Defined NX_PPP_PPPOE_ENABLE if use Express Logic's PPP, since PPP module has been modified
to match PPPoE moduler under this definition. */
53 #ifdef NX_PPP_PPPOE_ENABLE
54
55 /* If the driver is not initialized in other module, define NX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE
to initialize the driver in PPPoE module .
56 In this demo, the driver has been initialized in IP module. */
57 #ifndef NX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE
58
59 /* Define the block size. */
60 #define NX_PACKET_POOL_SIZE ((1536 + sizeof(NX_PACKET)) * 30)
61 #define DEMO_STACK_SIZE 2048
62 #define PPPOE_THREAD_SIZE 2048
63
64 /* Define the ThreadX and NetX object control blocks... */
65 TX_THREAD thread_0;
66
67 /* Define the packet pool and IP instance for normal IP instnace. */
68 NX_PACKET_POOL pool_0;
69 NX_IP ip_0;
70
71 /* Define the PPP Client instance. */
72 NX_PPP ppp_client;
73
74 /* Define the PPPoE Client instance. */
75 NX_PPPOE_CLIENT pppoe_client;
76
77 /* Define the counters. */
78 CHAR *pointer;
79 ULONG error_counter;
80
81 /* Define thread prototypes. */
82 void thread_0_entry(ULONG thread_input);
83
84 /***** Substitute your PPP driver entry function here *********/
85 extern void _nx_ppp_driver(NX_IP_DRIVER *driver_req_ptr);
86
87 /***** Substitute your Ethernet driver entry function here *********/
88 extern void _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr);
89
90 /* Define the porting layer function for Express Logic's PPP to simulate TTP's PPP.
91 Functions to be provided by PPP for calling by the PPPoE Stack. */
92 void ppp_client_packet_send(NX_PACKET *packet_ptr);
93 void pppoe_client_packet_receive(NX_PACKET *packet_ptr);
94
95 /* Define main entry point. */
96
97 int main()
98 {
99
100 /* Enter the ThreadX kernel. */
101 tx_kernel_enter();
102 }
103
104 UINT generate_login(CHAR *name, CHAR *password)
105 {
106
107 /* Make a name and password, called "myname" and "mypassword". */
108 name[0] = 'm';
109 name[1] = 'y';
110 name[2] = 'n';
111 name[3] = 'a';
112 name[4] = 'm';
113 name[5] = 'e';
114 name[6] = (CHAR) 0;
115
116 password[0] = 'm';
117 password[1] = 'y';
118 password[2] = 'p';
119 password[3] = 'a';
120 password[4] = 's';
121 password[5] = 's';
122 password[6] = 'w';
123 password[7] = 'o';
124 password[8] = 'r';
125 password[9] = 'd';
126 password[10] = (CHAR) 0;
127
128 return(NX_SUCCESS);
129 }
130
131 /* Define what the initial system looks like. */
132
133 void tx_application_define(void *first_unused_memory)
134 {
135
136 UINT status;
137
138 /* Setup the working pointer. */
139 pointer = (CHAR *) first_unused_memory;
140
141 /* Initialize the NetX system. */
142 nx_system_initialize();
143
144 /* Create a packet pool for normal IP instance. */
145 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool",
146 (1536 + sizeof(NX_PACKET)),
147 pointer, NX_PACKET_POOL_SIZE);
148 pointer = pointer + NX_PACKET_POOL_SIZE;
149
150 /* Check for error. */
151 if (status)
152 error_counter++;
153
154 /* Create an normal IP instance. */
155 status = nx_ip_create(&ip_0, "NetX IP Instance", IP_ADDRESS(192, 168, 100, 44), 0xFFFFFF00UL,
156 &pool_0, _nx_ram_network_driver, pointer, 2048, 1);
157 pointer = pointer + 2048;
158
159 /* Check for error. */
160 if (status)
161 error_counter++;
162
163 /* Create the PPP instance. */
164 status = nx_ppp_create(&ppp_client, "PPP Instance", &ip_0, pointer, 2048, 1,
165 &pool_0, NX_NULL, NX_NULL); pointer = pointer + 2048;
166
167 /* Check for PPP create error. */
168 if (status)
169 error_counter++;
170
171 /* Set the PPP packet send function. */
172 status = nx_ppp_packet_send_set(&ppp_client, ppp_client_packet_send);
173
174 /* Check for PPP packet send function set error. */
175 if (status)
176 error_counter++;
177
178 /* Define IP address. This PPP instance is effectively the client since it doesn't have
any IP addresses. */
179 status = nx_ppp_ip_address_assign(&ppp_client, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0));
180
181 /* Check for PPP IP address assign error. */
182 if (status)
183 error_counter++;
184
185 /* Setup PAP, this PPP instance is effectively the since it generates the name and password
for the peer.. */
186 status = nx_ppp_pap_enable(&ppp_client, generate_login, NX_NULL);
187
188 /* Check for PPP PAP enable error. */
189 if (status)
190 error_counter++;
191
192 /* Attach an interface for PPP. */
193 status = nx_ip_interface_attach(&ip_0, "Second Interface For PPP", IP_ADDRESS(0, 0, 0, 0), 0,
nx_ppp_driver);
194
195 /* Check for error. */
196 if (status)
197 error_counter++;
198
199 /* Enable ARP and supply ARP cache memory for Normal IP Instance. */
200 status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
201 pointer = pointer + 1024;
202
203 /* Check for ARP enable errors. */
204 if (status)
205 error_counter++;
206
207 /* Enable ICMP */
208 status = nx_icmp_enable(&ip_0);
209 if(status)
210 error_counter++;
211
212 /* Enable UDP traffic. */
213 status = nx_udp_enable(&ip_0);
214 if (status)
215 error_counter++;
216
217 /* Enable TCP traffic. */
218 status = nx_tcp_enable(&ip_0);
219 if (status)
220 error_counter++;
221
222 /* Create the main thread. */
223 tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
224 pointer, DEMO_STACK_SIZE,
225 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
226 pointer = pointer + DEMO_STACK_SIZE;
227
228 }
229
230 /* Define the test threads. */
231
232 void thread_0_entry(ULONG thread_input)
233 {
234 UINT status;
235 ULONG ip_status;
236
237 /* Create the PPPoE instance. */
238 status = nx_pppoe_client_create(&pppoe_client, (UCHAR *)"PPPoE Client", &ip_0, 0,
&pool_0, pointer, PPPOE_THREAD_SIZE, 4, _nx_ram_network_driver, pppoe_client_packet_receive);
239 pointer = pointer + PPPOE_THREAD_SIZE;
240 if (status)
241 {
242 error_counter++;
243 return;
244 }
245
246 /* Establish PPPoE Client sessione. */
247 status = nx_pppoe_client_session_connect(&pppoe_client, NX_WAIT_FOREVER);
248 if (status)
249 {
250 error_counter++;
251 return;
252 }
253
254 /* Wait for the link to come up. */
255 status = nx_ip_interface_status_check(&ip_0, 1, NX_IP_ADDRESS_RESOLVED,
&ip_status, NX_WAIT_FOREVER);
256 if (status)
257 {
258 error_counter++;
259 return;
260 }
261
262 /* Get the PPPoE Server physical address and Session ID after establish PPPoE Session. */
263 /*
264 status = nx_pppoe_client_session_get(&pppoe_client, &server_mac_msw,
&server_mac_lsw, &session_id);
265 if (status)
266 error_counter++;
267 */
268 }
269
270 /* PPPoE Client receive function. */
271 void pppoe_client_packet_receive(NX_PACKET *packet_ptr)
272 {
273
274 /* Call PPP Client to receive the PPP data fame. */
275 nx_ppp_packet_receive(&ppp_client, packet_ptr);
276 }
277
278 /* PPP Client send function. */
279 void ppp_client_packet_send(NX_PACKET *packet_ptr)
280 {
281
282 /* Directly Call PPPoE send function to send out the data through PPPoE module. */
283 nx_pppoe_client_session_packet_send(&pppoe_client, packet_ptr);
284 }
285 #endif /* NX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE */
286
287 #endif /* NX_PPP_PPPOE_ENABLE */
图 1.1 与 NetX 配合使用的 PPPoE 客户端示例
配置选项
可通过几个配置选项生成构建适用于 NetX 的 PPPoE 客户端。 以下列表对每个配置选项进行详细说明:
- NX_DISABLE_ERROR_CHECKING:定义后,此选项会删除基本的 PPPoE 客户端错误检查, 通常在调试应用程序完成后使用。
- NX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE:定义后,此选项会启用在 PPPoE 模块中初始化以太网驱动程序的功能, 默认情况下则会禁用该功能。
- NX_PPPOE_CLIENT_THREAD_TIME_SLICE:PPPoE 客户端线程的时间片选项。 默认情况下,此值为 TX_NO_TIME_SLICE。
- NX_PPPOE_CLIENT_PADI_INIT_TIMEOUT:此选项定义初始重新传输 PADI 数据包的等待部分。 默认情况下,此值为 1 秒。
- NX_PPPOE_CLIENT_PADI_COUNT:此选项定义在将连接视为中断之前允许的 PADI 传输停用次数。 默认情况下,此值为 4。
- NX_PPPOE_CLIENT_PADR_INIT_TIMEOUT:此选项定义初始重新传输 PADR 数据包的等待部分。 默认情况下,此值为 1 秒。
- NX_PPPOE_CLIENT_PADR_COUNT:此选项定义在将连接视为中断之前允许的 PADR 传输停用次数。 默认情况下,此值为 4。
- NX_PPPOE_CLIENT_MAX_AC_NAME_SIZE:此选项定义 AC-Name 的最大大小。 默认情况下,此值为 32。
- NX_PPPOE_CLIENT_MAX_AC_COOKIE_SIZE:此选项定义 AC-Cookie 的最大大小。 默认情况下,此值为 32。
- NX_PPPOE_CLIENT_MAX_RELAY_SESSION_ID_SIZE:此选项定义 Relay-Session-Id 的最大大小。默认情况下,此值为 12。
- NX_PPPOE_CLIENT_MIN_PACKET_PAYLOAD_SIZE:指定 PPPoE 客户端的最小数据包有效负载大小。 如果数据包有效负载大小大于此值,则可以避免数据包链接。 默认情况下,此值为 1520(以太网的最大有效负载大小 1500 + 以太网标头 14 + CRC 2 + 四字节对齐 4)。