mcs_util.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
1// Copyright 2013 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 5#include "google_apis/gcm/base/mcs_util.h" 6 7#include "base/format_macros.h" 8#include "base/logging.h" 9#include "base/strings/string_number_conversions.h" 10#include "base/strings/stringprintf.h" 11 12namespace gcm { 13 14namespace { 15 16// Type names corresponding to MCSProtoTags. Useful for identifying what type 17// of MCS protobuf is contained within a google::protobuf::MessageLite object. 18// WARNING: must match the order in MCSProtoTag. 19const char* kProtoNames[] = { 20 "mcs_proto.HeartbeatPing", 21 "mcs_proto.HeartbeatAck", 22 "mcs_proto.LoginRequest", 23 "mcs_proto.LoginResponse", 24 "mcs_proto.Close", 25 "mcs_proto.MessageStanza", 26 "mcs_proto.PresenceStanza", 27 "mcs_proto.IqStanza", 28 "mcs_proto.DataMessageStanza", 29 "mcs_proto.BatchPresenceStanza", 30 "mcs_proto.StreamErrorStanza", 31 "mcs_proto.HttpRequest", 32 "mcs_proto.HttpResponse", 33 "mcs_proto.BindAccountRequest", 34 "mcs_proto.BindAccountResponse", 35 "mcs_proto.TalkMetadata" 36}; 37COMPILE_ASSERT(arraysize(kProtoNames) == kNumProtoTypes, 38 ProtoNamesMustIncludeAllTags); 39 40// TODO(zea): replace these with proper values. 41const char kLoginId[] = "login-1"; 42const char kLoginDomain[] = "mcs.android.com"; 43const char kLoginDeviceIdPrefix[] = "android-"; 44const char kLoginSettingName[] = "new_vc"; 45const char kLoginSettingValue[] = "1"; 46 47} // namespace 48 49scoped_ptr<mcs_proto::LoginRequest> BuildLoginRequest( 50 uint64 auth_id, 51 uint64 auth_token) { 52 // Create a hex encoded auth id for the device id field. 53 std::string auth_id_hex; 54 auth_id_hex = base::StringPrintf("%" PRIx64, auth_id); 55 56 std::string auth_id_str = base::Uint64ToString(auth_id); 57 std::string auth_token_str = base::Uint64ToString(auth_token); 58 59 scoped_ptr<mcs_proto::LoginRequest> login_request( 60 new mcs_proto::LoginRequest()); 61 62 // TODO(zea): set better values. 63 login_request->set_account_id(1000000); 64 login_request->set_adaptive_heartbeat(false); 65 login_request->set_auth_service(mcs_proto::LoginRequest::ANDROID_ID); 66 login_request->set_auth_token(auth_token_str); 67 login_request->set_id(kLoginId); 68 login_request->set_domain(kLoginDomain); 69 login_request->set_device_id(kLoginDeviceIdPrefix + auth_id_hex); 70 login_request->set_network_type(1); 71 login_request->set_resource(auth_id_str); 72 login_request->set_user(auth_id_str); 73 login_request->set_use_rmq2(true); 74 75 login_request->add_setting(); 76 login_request->mutable_setting(0)->set_name(kLoginSettingName); 77 login_request->mutable_setting(0)->set_value(kLoginSettingValue); 78 return login_request.Pass(); 79} 80 81scoped_ptr<mcs_proto::IqStanza> BuildStreamAck() { 82 scoped_ptr<mcs_proto::IqStanza> stream_ack_iq(new mcs_proto::IqStanza()); 83 stream_ack_iq->set_type(mcs_proto::IqStanza::SET); 84 stream_ack_iq->set_id(""); 85 stream_ack_iq->mutable_extension()->set_id(kStreamAck); 86 stream_ack_iq->mutable_extension()->set_data(""); 87 return stream_ack_iq.Pass(); 88} 89 90// Utility method to build a google::protobuf::MessageLite object from a MCS 91// tag. 92scoped_ptr<google::protobuf::MessageLite> BuildProtobufFromTag(uint8 tag) { 93 switch(tag) { 94 case kHeartbeatPingTag: 95 return scoped_ptr<google::protobuf::MessageLite>( 96 new mcs_proto::HeartbeatPing()); 97 case kHeartbeatAckTag: 98 return scoped_ptr<google::protobuf::MessageLite>( 99 new mcs_proto::HeartbeatAck()); 100 case kLoginRequestTag: 101 return scoped_ptr<google::protobuf::MessageLite>( 102 new mcs_proto::LoginRequest()); 103 case kLoginResponseTag: 104 return scoped_ptr<google::protobuf::MessageLite>( 105 new mcs_proto::LoginResponse()); 106 case kCloseTag: 107 return scoped_ptr<google::protobuf::MessageLite>( 108 new mcs_proto::Close()); 109 case kIqStanzaTag: 110 return scoped_ptr<google::protobuf::MessageLite>( 111 new mcs_proto::IqStanza()); 112 case kDataMessageStanzaTag: 113 return scoped_ptr<google::protobuf::MessageLite>( 114 new mcs_proto::DataMessageStanza()); 115 case kStreamErrorStanzaTag: 116 return scoped_ptr<google::protobuf::MessageLite>( 117 new mcs_proto::StreamErrorStanza()); 118 default: 119 return scoped_ptr<google::protobuf::MessageLite>(); 120 } 121} 122 123// Utility method to extract a MCS tag from a google::protobuf::MessageLite 124// object. 125int GetMCSProtoTag(const google::protobuf::MessageLite& message) { 126 const std::string& type_name = message.GetTypeName(); 127 if (type_name == kProtoNames[kHeartbeatPingTag]) { 128 return kHeartbeatPingTag; 129 } else if (type_name == kProtoNames[kHeartbeatAckTag]) { 130 return kHeartbeatAckTag; 131 } else if (type_name == kProtoNames[kLoginRequestTag]) { 132 return kLoginRequestTag; 133 } else if (type_name == kProtoNames[kLoginResponseTag]) { 134 return kLoginResponseTag; 135 } else if (type_name == kProtoNames[kCloseTag]) { 136 return kCloseTag; 137 } else if (type_name == kProtoNames[kIqStanzaTag]) { 138 return kIqStanzaTag; 139 } else if (type_name == kProtoNames[kDataMessageStanzaTag]) { 140 return kDataMessageStanzaTag; 141 } else if (type_name == kProtoNames[kStreamErrorStanzaTag]) { 142 return kStreamErrorStanzaTag; 143 } 144 return -1; 145} 146 147std::string GetPersistentId(const google::protobuf::MessageLite& protobuf) { 148 if (protobuf.GetTypeName() == kProtoNames[kIqStanzaTag]) { 149 return reinterpret_cast<const mcs_proto::IqStanza*>(&protobuf)-> 150 persistent_id(); 151 } else if (protobuf.GetTypeName() == kProtoNames[kDataMessageStanzaTag]) { 152 return reinterpret_cast<const mcs_proto::DataMessageStanza*>(&protobuf)-> 153 persistent_id(); 154 } 155 // Not all message types have persistent ids. Just return empty string; 156 return ""; 157} 158 159void SetPersistentId(const std::string& persistent_id, 160 google::protobuf::MessageLite* protobuf) { 161 if (protobuf->GetTypeName() == kProtoNames[kIqStanzaTag]) { 162 reinterpret_cast<mcs_proto::IqStanza*>(protobuf)-> 163 set_persistent_id(persistent_id); 164 return; 165 } else if (protobuf->GetTypeName() == kProtoNames[kDataMessageStanzaTag]) { 166 reinterpret_cast<mcs_proto::DataMessageStanza*>(protobuf)-> 167 set_persistent_id(persistent_id); 168 return; 169 } 170 NOTREACHED(); 171} 172 173uint32 GetLastStreamIdReceived(const google::protobuf::MessageLite& protobuf) { 174 if (protobuf.GetTypeName() == kProtoNames[kIqStanzaTag]) { 175 return reinterpret_cast<const mcs_proto::IqStanza*>(&protobuf)-> 176 last_stream_id_received(); 177 } else if (protobuf.GetTypeName() == kProtoNames[kDataMessageStanzaTag]) { 178 return reinterpret_cast<const mcs_proto::DataMessageStanza*>(&protobuf)-> 179 last_stream_id_received(); 180 } else if (protobuf.GetTypeName() == kProtoNames[kHeartbeatPingTag]) { 181 return reinterpret_cast<const mcs_proto::HeartbeatPing*>(&protobuf)-> 182 last_stream_id_received(); 183 } else if (protobuf.GetTypeName() == kProtoNames[kHeartbeatAckTag]) { 184 return reinterpret_cast<const mcs_proto::HeartbeatAck*>(&protobuf)-> 185 last_stream_id_received(); 186 } else if (protobuf.GetTypeName() == kProtoNames[kLoginResponseTag]) { 187 return reinterpret_cast<const mcs_proto::LoginResponse*>(&protobuf)-> 188 last_stream_id_received(); 189 } 190 // Not all message types have last stream ids. Just return 0. 191 return 0; 192} 193 194void SetLastStreamIdReceived(uint32 val, 195 google::protobuf::MessageLite* protobuf) { 196 if (protobuf->GetTypeName() == kProtoNames[kIqStanzaTag]) { 197 reinterpret_cast<mcs_proto::IqStanza*>(protobuf)-> 198 set_last_stream_id_received(val); 199 return; 200 } else if (protobuf->GetTypeName() == kProtoNames[kHeartbeatPingTag]) { 201 reinterpret_cast<mcs_proto::HeartbeatPing*>(protobuf)-> 202 set_last_stream_id_received(val); 203 return; 204 } else if (protobuf->GetTypeName() == kProtoNames[kHeartbeatAckTag]) { 205 reinterpret_cast<mcs_proto::HeartbeatAck*>(protobuf)-> 206 set_last_stream_id_received(val); 207 return; 208 } else if (protobuf->GetTypeName() == kProtoNames[kDataMessageStanzaTag]) { 209 reinterpret_cast<mcs_proto::DataMessageStanza*>(protobuf)-> 210 set_last_stream_id_received(val); 211 return; 212 } else if (protobuf->GetTypeName() == kProtoNames[kLoginResponseTag]) { 213 reinterpret_cast<mcs_proto::LoginResponse*>(protobuf)-> 214 set_last_stream_id_received(val); 215 return; 216 } 217 NOTREACHED(); 218} 219 220} // namespace gcm 221