mconnect - KDE Connect protocol implementation in Vala/C
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.7 KiB

  1. /* ex:ts=4:sw=4:sts=4:et */
  2. /* -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
  3. /**
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along
  14. * with this program; if not, write to the Free Software Foundation, Inc.,
  15. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  16. *
  17. * AUTHORS
  18. * Maciek Borzecki <maciek.borzecki (at] gmail.com>
  19. */
  20. class Discovery : GLib.Object
  21. {
  22. private Socket socket = null;
  23. public signal void device_found(Device dev);
  24. public Discovery() {
  25. }
  26. ~Discovery() {
  27. debug("cleaning up discovery...");
  28. if (this.socket != null) {
  29. this.socket.close();
  30. }
  31. }
  32. public void listen() throws Error {
  33. this.socket = new Socket(SocketFamily.IPV4,
  34. SocketType.DATAGRAM,
  35. SocketProtocol.UDP);
  36. var sa = new InetSocketAddress(new InetAddress.any(SocketFamily.IPV4),
  37. 1714);
  38. debug("start listening for new devices at: %s:%u",
  39. sa.address.to_string(), sa.port);
  40. try {
  41. socket.bind(sa, false);
  42. } catch (Error e) {
  43. this.socket.close();
  44. this.socket = null;
  45. throw e;
  46. }
  47. var source = socket.create_source(IOCondition.IN);
  48. source.set_callback((s, c) => {
  49. this.incomingPacket();
  50. return true;
  51. });
  52. source.attach(MainContext.default());
  53. }
  54. private void incomingPacket() {
  55. debug("incoming packet");
  56. uint8 buffer[4096];
  57. SocketAddress sa;
  58. InetSocketAddress isa;
  59. try {
  60. ssize_t read = this.socket.receive_from(out sa, buffer);
  61. isa = (InetSocketAddress)sa;
  62. message("got %zd bytes from: %s:%u", read,
  63. isa.address.to_string(), isa.port);
  64. } catch (Error e) {
  65. message("faile to receive packet: %s", e.message);
  66. return;
  67. }
  68. message("message data: %s", (string)buffer);
  69. this.parsePacketFromHost((string) buffer, isa.address);
  70. }
  71. private void parsePacketFromHost(string data, InetAddress host)
  72. {
  73. // expecing an identity packet
  74. var pkt = Packet.new_from_data(data);
  75. if (pkt.pkt_type != Packet.IDENTITY) {
  76. message("unexpected packet type %s from device %s",
  77. pkt.pkt_type, host.to_string());
  78. return;
  79. }
  80. var dev = new Device.from_identity(pkt, host);
  81. debug("connection from device: \'%s\', responds at: %s:%u",
  82. dev.device_name, host.to_string(), dev.tcp_port);
  83. device_found(dev);
  84. }
  85. }