wol.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /***************************************************************
  2. * @file wol.c
  3. * @brief
  4. * @author WKJay
  5. * @Version
  6. * @Date 2022-11-16
  7. ***************************************************************/
  8. #include <rtthread.h>
  9. #include <sys/socket.h>
  10. #include <stdio.h>
  11. #include "wol.h"
  12. #define MAGIC_OFFSET 6
  13. #define SOCK_PORT 7
  14. static int do_wol(uint8_t *mac) {
  15. int sock = -1;
  16. int index = 0;
  17. int optval = 1;
  18. struct sockaddr_in server_addr;
  19. uint8_t magic_data[102];
  20. rt_memset(magic_data, 0xff, sizeof(magic_data));
  21. for (index = 0; index < 16; index++) {
  22. rt_memcpy(&magic_data[MAGIC_OFFSET + index * 6], mac, 6);
  23. }
  24. if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
  25. rt_kprintf("create socket error\r\n");
  26. return -1;
  27. }
  28. setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval));
  29. rt_memset(&server_addr, 0, sizeof(struct sockaddr_in));
  30. server_addr.sin_family = AF_INET;
  31. server_addr.sin_port = htons(SOCK_PORT);
  32. server_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  33. if (sendto(sock, magic_data, sizeof(magic_data), 0, (struct sockaddr *)&server_addr,
  34. sizeof(struct sockaddr)) != sizeof(magic_data)) {
  35. rt_kprintf("send wol data failed.\r\n");
  36. return -1;
  37. }
  38. rt_thread_mdelay(1000);
  39. closesocket(sock);
  40. return 0;
  41. }
  42. int wol(uint8_t *mac) { return do_wol(mac); }
  43. int wol_str(char *mac_str) {
  44. int ret = -1;
  45. uint8_t mac[6] = {0};
  46. ret = sscanf(mac_str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mac[0], &mac[1], &mac[2], &mac[3],
  47. &mac[4], &mac[5]);
  48. if (ret == 6) goto next;
  49. ret = sscanf(mac_str, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &mac[0], &mac[1], &mac[2], &mac[3],
  50. &mac[4], &mac[5]);
  51. if (ret == 6) goto next;
  52. ret = sscanf(mac_str, "%hhx %hhx %hhx %hhx %hhx %hhx", &mac[0], &mac[1], &mac[2], &mac[3],
  53. &mac[4], &mac[5]);
  54. if (ret == 6) goto next;
  55. rt_kprintf("invalid mac: %s\r\n", mac);
  56. return -1;
  57. next:
  58. return do_wol(mac);
  59. }
  60. static void wol_wakeup(int argc, char *argv[]) {
  61. if (argc != 2) {
  62. rt_kprintf("invalid arguments,please input:\r\n");
  63. rt_kprintf("wol_wakeup 00:01:02:03:04:05 or\r\n");
  64. rt_kprintf("wol_wakeup 00-01-02-03-04-05 or\r\n");
  65. rt_kprintf("wol_wakeup \"00 01 02 03 04 05\"\r\n");
  66. return;
  67. }
  68. if (wol_str(argv[1]) < 0) {
  69. rt_kprintf("wake %s failed.", argv[1]);
  70. return;
  71. }
  72. return;
  73. }
  74. MSH_CMD_EXPORT(wol_wakeup, Wake on Lan)