signaling_address.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/signaling/signaling_address.h"
  5. #include <string.h>
  6. #include <ostream>
  7. #include "base/check_op.h"
  8. #include "base/notreached.h"
  9. #include "base/strings/string_util.h"
  10. #include "base/strings/stringprintf.h"
  11. #include "remoting/base/name_value_map.h"
  12. #include "remoting/signaling/signaling_id_util.h"
  13. #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
  14. namespace remoting {
  15. namespace {
  16. // FTL ID format:
  17. // user@domain.com/chromoting_ftl_(registration ID)
  18. // The FTL ID is only used local to the program.
  19. constexpr char kFtlResourcePrefix[] = "chromoting_ftl_";
  20. jingle_xmpp::QName GetIdQName(SignalingAddress::Direction direction) {
  21. const char* attribute_name = attribute_name =
  22. (direction == SignalingAddress::FROM) ? "from" : "to";
  23. return jingle_xmpp::QName("", attribute_name);
  24. }
  25. SignalingAddress::Channel GetChannelType(std::string address) {
  26. std::string email;
  27. std::string resource;
  28. bool has_resource = SplitSignalingIdResource(address, &email, &resource);
  29. if (has_resource) {
  30. if (resource.find(kFtlResourcePrefix) == 0) {
  31. return SignalingAddress::Channel::FTL;
  32. }
  33. }
  34. return SignalingAddress::Channel::XMPP;
  35. }
  36. } // namespace
  37. SignalingAddress::SignalingAddress() = default;
  38. SignalingAddress::SignalingAddress(const std::string& address) {
  39. DCHECK(!address.empty());
  40. channel_ = GetChannelType(address);
  41. switch (channel_) {
  42. case Channel::XMPP:
  43. case Channel::FTL:
  44. id_ = NormalizeSignalingId(address);
  45. DCHECK(!id_.empty()) << "Missing signaling ID.";
  46. break;
  47. default:
  48. NOTREACHED();
  49. }
  50. }
  51. bool SignalingAddress::operator==(const SignalingAddress& other) const {
  52. return (other.id_ == id_) && (other.channel_ == channel_);
  53. }
  54. bool SignalingAddress::operator!=(const SignalingAddress& other) const {
  55. return !(*this == other);
  56. }
  57. // static
  58. SignalingAddress SignalingAddress::CreateFtlSignalingAddress(
  59. const std::string& username,
  60. const std::string& registration_id) {
  61. return SignalingAddress(base::StringPrintf("%s/%s%s", username.c_str(),
  62. kFtlResourcePrefix,
  63. registration_id.c_str()));
  64. }
  65. // static
  66. SignalingAddress SignalingAddress::Parse(const jingle_xmpp::XmlElement* iq,
  67. SignalingAddress::Direction direction,
  68. std::string* error) {
  69. std::string id = iq->Attr(GetIdQName(direction));
  70. if (id.empty()) {
  71. return SignalingAddress();
  72. }
  73. return SignalingAddress(id);
  74. }
  75. void SignalingAddress::SetInMessage(jingle_xmpp::XmlElement* iq,
  76. Direction direction) const {
  77. DCHECK(!empty()) << "Signaling Address is empty";
  78. iq->SetAttr(GetIdQName(direction), id_);
  79. }
  80. bool SignalingAddress::GetFtlInfo(std::string* username,
  81. std::string* registration_id) const {
  82. if (channel_ != Channel::FTL) {
  83. return false;
  84. }
  85. std::string resource;
  86. bool has_resource = SplitSignalingIdResource(id_, username, &resource);
  87. DCHECK(has_resource);
  88. size_t ftl_resource_prefix_length = strlen(kFtlResourcePrefix);
  89. DCHECK_LT(ftl_resource_prefix_length, resource.length());
  90. *registration_id = resource.substr(ftl_resource_prefix_length);
  91. return true;
  92. }
  93. } // namespace remoting