1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <string.h>
16 #include "esp_ping.h"
17
18 #include "lwip/ip_addr.h"
19 typedef struct _ping_option {
20 ip_addr_t ping_target;
21 uint32_t ping_count;
22 uint32_t ping_rcv_timeout;
23 uint32_t ping_delay;
24 uint32_t interface;
25 size_t ping_data_len;
26 uint16_t ping_id;
27 u8_t ping_tos;
28 esp_ping_found_fn ping_res_fn;
29 esp_ping_found ping_res;
30 void *ping_reserve;
31 } ping_option;
32
33 static ping_option ping_option_info[1];
34
esp_ping_set_target(ping_target_id_t opt_id,void * opt_val,uint32_t opt_len)35 esp_err_t esp_ping_set_target(ping_target_id_t opt_id, void *opt_val, uint32_t opt_len)
36 {
37 esp_err_t ret = ESP_OK;
38
39 if (opt_val == NULL) {
40 return ESP_ERR_PING_INVALID_PARAMS;
41 }
42
43 switch (opt_id) {
44 case PING_TARGET_IP_ADDRESS:
45 ipaddr_aton(opt_val, &(ping_option_info->ping_target));
46 break;
47 case PING_TARGET_IP_ADDRESS_COUNT:
48 ESP_PING_CHECK_OPTLEN(opt_len, uint32_t);
49 ping_option_info->ping_count = *(uint32_t *)opt_val;
50 break;
51 case PING_TARGET_IF_INDEX:
52 ESP_PING_CHECK_OPTLEN(opt_len, uint32_t);
53 ping_option_info->interface = *(uint32_t *)opt_val;
54 break;
55 case PING_TARGET_RCV_TIMEO:
56 ESP_PING_CHECK_OPTLEN(opt_len, uint32_t);
57 ping_option_info->ping_rcv_timeout = (*(uint32_t *)opt_val);
58 break;
59 case PING_TARGET_DELAY_TIME:
60 ESP_PING_CHECK_OPTLEN(opt_len, uint32_t);
61 ping_option_info->ping_delay = (*(uint32_t *)opt_val);
62 break;
63 case PING_TARGET_DATA_LEN:
64 ESP_PING_CHECK_OPTLEN(opt_len, size_t);
65 ping_option_info->ping_data_len = (*(size_t *)opt_val);
66 break;
67 case PING_TARGET_ID:
68 ESP_PING_CHECK_OPTLEN(opt_len, uint16_t);
69 ping_option_info->ping_id = *(uint16_t *)opt_val;
70 break;
71 case PING_TARGET_IP_TOS:
72 ESP_PING_CHECK_OPTLEN(opt_len, u8_t);
73 ping_option_info->ping_tos = *(u8_t *)opt_val;
74 break;
75 case PING_TARGET_RES_FN:
76 ping_option_info->ping_res_fn = opt_val;
77 break;
78 case PING_TARGET_RES_RESET:
79 memset(&ping_option_info->ping_res, 0, sizeof(ping_option_info->ping_res));
80 break;
81 default:
82 ret = ESP_ERR_PING_INVALID_PARAMS;
83 break;
84 }
85
86 return ret;
87 }
88
esp_ping_get_target(ping_target_id_t opt_id,void * opt_val,uint32_t opt_len)89 esp_err_t esp_ping_get_target(ping_target_id_t opt_id, void *opt_val, uint32_t opt_len)
90 {
91 esp_err_t ret = ESP_OK;
92
93 if (opt_val == NULL) {
94 return ESP_ERR_PING_INVALID_PARAMS;
95 }
96
97 switch (opt_id) {
98 case PING_TARGET_IP_ADDRESS:
99 ip_addr_copy(*(ip_addr_t*)opt_val, ping_option_info->ping_target);
100 break;
101 case PING_TARGET_IP_ADDRESS_COUNT:
102 ESP_PING_CHECK_OPTLEN(opt_len, uint32_t);
103 *(uint32_t *)opt_val = ping_option_info->ping_count;
104 break;
105 case PING_TARGET_IF_INDEX:
106 ESP_PING_CHECK_OPTLEN(opt_len, uint32_t);
107 *(uint32_t *)opt_val = ping_option_info->interface;
108 break;
109 case PING_TARGET_RCV_TIMEO:
110 ESP_PING_CHECK_OPTLEN(opt_len, uint32_t);
111 *(uint32_t *)opt_val = ping_option_info->ping_rcv_timeout;
112 break;
113 case PING_TARGET_DELAY_TIME:
114 ESP_PING_CHECK_OPTLEN(opt_len, uint32_t);
115 *(uint32_t *)opt_val = ping_option_info->ping_delay;
116 break;
117 case PING_TARGET_DATA_LEN:
118 ESP_PING_CHECK_OPTLEN(opt_len, size_t);
119 *(size_t *)opt_val = ping_option_info->ping_data_len;
120 break;
121 case PING_TARGET_ID:
122 ESP_PING_CHECK_OPTLEN(opt_len, uint16_t);
123 *(uint16_t *)opt_val = ping_option_info->ping_id;
124 break;
125 case PING_TARGET_IP_TOS:
126 ESP_PING_CHECK_OPTLEN(opt_len, uint16_t);
127 *(uint16_t *)opt_val = ping_option_info->ping_tos;
128 break;
129 default:
130 ret = ESP_ERR_PING_INVALID_PARAMS;
131 break;
132 }
133
134 return ret;
135 }
136
esp_ping_result(uint8_t res_val,uint16_t ping_len,uint32_t ping_time)137 esp_err_t esp_ping_result(uint8_t res_val, uint16_t ping_len, uint32_t ping_time)
138 {
139 esp_err_t ret = ESP_OK;
140
141 ping_option_info->ping_res.ping_err = res_val;
142
143 if (res_val != PING_RES_FINISH) {
144 ping_option_info->ping_res.bytes = ping_len;
145 ping_option_info->ping_res.resp_time = ping_time;
146 ping_option_info->ping_res.total_bytes += ping_len;
147 ping_option_info->ping_res.send_count ++;
148
149 if (res_val == PING_RES_TIMEOUT) {
150 ping_option_info->ping_res.timeout_count ++;
151 } else {
152 if (!ping_option_info->ping_res.min_time || (ping_time < ping_option_info->ping_res.min_time)) {
153 ping_option_info->ping_res.min_time = ping_time;
154 }
155
156 if (ping_time > ping_option_info->ping_res.max_time) {
157 ping_option_info->ping_res.max_time = ping_time;
158 }
159
160
161 ping_option_info->ping_res.total_time += ping_time;
162 ping_option_info->ping_res.recv_count ++;
163 }
164 }
165
166 if (ping_option_info->ping_res_fn) {
167 ping_option_info->ping_res_fn(PING_TARGET_RES_FN, &ping_option_info->ping_res);
168 if (res_val == PING_RES_FINISH) {
169 memset(&ping_option_info->ping_res, 0, sizeof(esp_ping_found));
170 }
171 }
172
173 return ret;
174 }
175