ping.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #include "ping.h"
  2. #include "socket.h"
  3. #include "w5500.h"
  4. PINGMSGR PingRequest; // Variable for Ping Request
  5. PINGMSGR PingReply; // Variable for Ping Reply
  6. static uint16_t RandomID = 0x1234;
  7. static uint16_t RandomSeqNum = 0x4321;
  8. uint8_t ping_reply_received = 0;
  9. uint8_t req = 0;
  10. uint8_t rep = 0;
  11. extern void wait_ms(int ms);
  12. uint8_t ping_auto(uint8_t s, uint8_t *addr)
  13. {
  14. uint8_t i;
  15. int32_t len = 0;
  16. uint8_t cnt = 0;
  17. int ret = 0;
  18. for(i = 0; i <= 3; i++) {
  19. uint8_t sr = getSn_SR(s);
  20. //logger("SR: %02X\r\n", sr);
  21. switch(sr)
  22. {
  23. case SOCK_CLOSED:
  24. close(s);
  25. IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); // set ICMP Protocol
  26. if ((ret = socket(s, Sn_MR_IPRAW, 3000, 0)) != s) { // open the SOCKET with IPRAW mode, if fail then Error
  27. //logger( "\r\n socket %d fail %d\r\n", s, ret);
  28. #ifdef PING_DEBUG
  29. return SOCKET_ERROR;
  30. #endif
  31. }
  32. /* Check socket register */
  33. while(getSn_SR(s) != SOCK_IPRAW);
  34. wait_ms(1000); // wait 1000ms
  35. wait_ms(1000); // wait 1000ms
  36. break;
  37. case SOCK_IPRAW:
  38. ping_request(s, addr);
  39. req++;
  40. while(1) {
  41. if ( (len = getSn_RX_RSR(s) ) > 0)
  42. {
  43. ping_reply(s, addr, len);
  44. rep++;
  45. break;
  46. }
  47. else if(cnt > 100)
  48. {
  49. //logger("Request Time out. \r\n");
  50. cnt = 0;
  51. break;
  52. }
  53. else
  54. {
  55. cnt++;
  56. wait_ms(50); // wait 50ms
  57. }
  58. // wait_time for 2 seconds, Break on fail
  59. }
  60. break;
  61. default:
  62. break;
  63. }
  64. #ifdef PING_DEBUG
  65. if(req >= 3)
  66. {
  67. //logger("Ping Request = %d, PING_Reply = %d\r\n", req, rep);
  68. if(rep == req)
  69. return SUCCESS;
  70. else
  71. return REPLY_ERROR;
  72. }
  73. #endif
  74. }
  75. return FUNCTION_ERROR;
  76. }
  77. uint8_t ping_count(uint8_t s, uint16_t pCount, uint8_t *addr)
  78. {
  79. uint16_t rlen, cnt, i;
  80. cnt = 0;
  81. for(i=0; i < pCount + 1; i++) {
  82. if (i != 0) {
  83. /* Output count number */
  84. //logger( "\r\nNo.%d\r\n", (i-1));
  85. }
  86. uint8_t sr = getSn_SR(s);
  87. //logger("SR: %d\r\n", sr);
  88. switch(sr) {
  89. case SOCK_CLOSED:
  90. close(s);
  91. // close the SOCKET
  92. /* Create Socket */
  93. IINCHIP_WRITE(Sn_PROTO(s), IPPROTO_ICMP); // set ICMP Protocol
  94. if (socket(s, Sn_MR_IPRAW, 3000, 0) != s) { // open the SOCKET with IPRAW mode, if fail then Error
  95. //logger( "\r\n socket %d fail r\n", (s));
  96. #ifdef PING_DEBUG
  97. return SOCKET_ERROR;
  98. #endif
  99. }
  100. /* Check socket register */
  101. while(getSn_SR(s) != SOCK_IPRAW);
  102. wait_ms(1000); // wait 1000ms
  103. wait_ms(1000); // wait 1000ms
  104. break;
  105. case SOCK_IPRAW:
  106. ping_request(s, addr);
  107. req++;
  108. while(1) {
  109. if ((rlen = getSn_RX_RSR(s)) > 0) {
  110. ping_reply(s, addr, rlen);
  111. rep++;
  112. if (ping_reply_received) break;
  113. }
  114. /* wait_time for 2 seconds, Break on fail*/
  115. if ( (cnt > 100) ) {
  116. //logger( "\r\nRequest Time out. \r\n") ;
  117. cnt = 0;
  118. break;
  119. } else {
  120. cnt++;
  121. wait_ms(50); // wait 50ms
  122. }
  123. }
  124. break;
  125. default:
  126. break;
  127. }
  128. #ifdef PING_DEBUG
  129. if(req >= pCount)
  130. {
  131. //logger("Ping Request = %d, PING_Reply = %d\r\n", req, rep);
  132. if(rep == req)
  133. return SUCCESS;
  134. else
  135. return REPLY_ERROR;
  136. }
  137. #endif
  138. }
  139. return FUNCTION_ERROR;
  140. }
  141. uint8_t ping_request(uint8_t s, uint8_t *addr)
  142. {
  143. uint16_t i;
  144. //Initailize flag for ping reply
  145. ping_reply_received = 0;
  146. /* make header of the ping-request */
  147. PingRequest.Type = PING_REQUEST; // Ping-Request
  148. PingRequest.Code = CODE_ZERO; // Always '0'
  149. PingRequest.ID = htons(RandomID++); // set ping-request's ID to random integer value
  150. PingRequest.SeqNum =htons(RandomSeqNum++);// set ping-request's sequence number to ramdom integer value
  151. //size = 32; // set Data size
  152. /* Fill in Data[] as size of BIF_LEN (Default = 32)*/
  153. for(i = 0 ; i < BUF_LEN; i++) {
  154. PingRequest.Data[i] = (i) % 8; //'0'~'8' number into ping-request's data
  155. }
  156. /* Do checksum of Ping Request */
  157. PingRequest.CheckSum = 0; // value of checksum before calucating checksum of ping-request packet
  158. PingRequest.CheckSum = htons(checksum((uint8_t*)&PingRequest,sizeof(PingRequest))); // Calculate checksum
  159. /* sendto ping_request to destination */
  160. if (sendto(s,(uint8_t *)&PingRequest, sizeof(PingRequest), addr, 3000) == 0) { // Send Ping-Request to the specified peer.
  161. //logger( "\r\n Fail to send ping-reply packet r\n") ;
  162. } else {
  163. //logger( "Send Ping Request to Destination (") ;
  164. //logger( "%d.%d.%d.%d )", (addr[0]), (addr[1]), (addr[2]), (addr[3])) ;
  165. //logger( " ID:%x SeqNum:%x CheckSum:%x\r\n", htons(PingRequest.ID), htons(PingRequest.SeqNum), htons(PingRequest.CheckSum)) ;
  166. }
  167. return 0;
  168. } // ping request
  169. uint8_t ping_reply(uint8_t s, uint8_t *addr, uint16_t rlen)
  170. {
  171. uint16_t tmp_checksum;
  172. uint16_t len;
  173. uint16_t i;
  174. uint8_t data_buf[128];
  175. uint16_t port = 3000;
  176. PINGMSGR PingReply;
  177. /* receive data from a destination */
  178. len = recvfrom(s, (uint8_t *)data_buf, rlen, addr, &port);
  179. if (data_buf[0] == PING_REPLY) {
  180. PingReply.Type = data_buf[0];
  181. PingReply.Code = data_buf[1];
  182. PingReply.CheckSum = (data_buf[3]<<8) + data_buf[2];
  183. PingReply.ID = (data_buf[5]<<8) + data_buf[4];
  184. PingReply.SeqNum = (data_buf[7]<<8) + data_buf[6];
  185. for(i = 0; i < len - 8 ; ++i) {
  186. PingReply.Data[i] = data_buf[8+i];
  187. }
  188. /* check Checksum of Ping Reply */
  189. tmp_checksum = ~checksum(data_buf, len);
  190. if (tmp_checksum != 0xffff) {
  191. //logger("tmp_checksum = %x\r\n",tmp_checksum);
  192. } else {
  193. /* Output the Destination IP and the size of the Ping Reply Message*/
  194. //logger("Reply from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n",
  195. // (addr[0]), (addr[1]), (addr[2]), (addr[3]), htons(PingReply.ID), htons(PingReply.SeqNum), (rlen+6) );
  196. //logger("\r\n");
  197. /* SET ping_reply_receiver to '1' and go out the while_loop (waitting for ping reply)*/
  198. ping_reply_received =1;
  199. }
  200. } else if (data_buf[0] == PING_REQUEST) {
  201. PingReply.Code = data_buf[1];
  202. PingReply.Type = data_buf[2];
  203. PingReply.CheckSum = (data_buf[3]<<8) + data_buf[2];
  204. PingReply.ID = (data_buf[5]<<8) + data_buf[4];
  205. PingReply.SeqNum = (data_buf[7]<<8) + data_buf[6];
  206. for(i=0; i < len - 8; ++i) {
  207. PingReply.Data[i] = data_buf[8+i];
  208. }
  209. /* check Checksum of Ping Reply */
  210. tmp_checksum = PingReply.CheckSum;
  211. PingReply.CheckSum = 0;
  212. PingReply.CheckSum = htons(checksum((uint8_t*)&PingReply, len));
  213. if (tmp_checksum != PingReply.CheckSum){
  214. //logger( " \n CheckSum is in correct %x shold be %x \n", (tmp_checksum), htons(PingReply.CheckSum));
  215. } else {
  216. //logger( "\r\n Checksum is correct \r\n") ;
  217. }
  218. /* Output the Destination IP and the size of the Ping Reply Message*/
  219. //logger("Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n",
  220. // (addr[0]), (addr[1]), (addr[2]), (addr[3]), (PingReply.ID), (PingReply.SeqNum), (rlen+6) );
  221. /* SET ping_reply_receiver to '1' and go out the while_loop (waitting for ping reply)*/
  222. ping_reply_received = 1;
  223. } else {
  224. //logger(" Unkonwn msg. \n");
  225. }
  226. return 0;
  227. }// ping_reply
  228. uint16_t checksum(uint8_t * data_buf, uint16_t len)
  229. {
  230. uint16_t sum, tsum, i, j;
  231. uint32_t lsum;
  232. j = len >> 1;
  233. lsum = 0;
  234. tsum = 0;
  235. for (i = 0; i < j; ++i) {
  236. tsum = data_buf[i * 2];
  237. tsum = tsum << 8;
  238. tsum += data_buf[i * 2 + 1];
  239. lsum += tsum;
  240. }
  241. if (len % 2)
  242. {
  243. tsum = data_buf[i * 2];
  244. lsum += (tsum << 8);
  245. }
  246. sum = (uint16_t)lsum;
  247. sum = ~(sum + (lsum >> 16));
  248. return sum;
  249. }
  250. uint16_t htons( uint16_t hostshort)
  251. {
  252. #if 1
  253. //#ifdef LITTLE_ENDIAN
  254. uint16_t netshort=0;
  255. netshort = (hostshort & 0xFF) << 8;
  256. netshort |= ((hostshort >> 8)& 0xFF);
  257. return netshort;
  258. #else
  259. return hostshort;
  260. #endif
  261. }