| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "google_apis/gcm/base/mcs_util.h" | 5 #include "google_apis/gcm/base/mcs_util.h" |
| 6 | 6 |
| 7 #include <stddef.h> |
| 8 |
| 7 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 8 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/macros.h" |
| 9 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 10 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 11 #include "base/time/clock.h" | 14 #include "base/time/clock.h" |
| 12 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 13 | 16 |
| 14 namespace gcm { | 17 namespace gcm { |
| 15 | 18 |
| 16 namespace { | 19 namespace { |
| 17 | 20 |
| 18 // Type names corresponding to MCSProtoTags. Useful for identifying what type | 21 // Type names corresponding to MCSProtoTags. Useful for identifying what type |
| (...skipping 25 matching lines...) Expand all Loading... |
| 44 const char kLoginDeviceIdPrefix[] = "android-"; | 47 const char kLoginDeviceIdPrefix[] = "android-"; |
| 45 const char kLoginSettingDefaultName[] = "new_vc"; | 48 const char kLoginSettingDefaultName[] = "new_vc"; |
| 46 const char kLoginSettingDefaultValue[] = "1"; | 49 const char kLoginSettingDefaultValue[] = "1"; |
| 47 | 50 |
| 48 // Maximum amount of time to save an unsent outgoing message for. | 51 // Maximum amount of time to save an unsent outgoing message for. |
| 49 const int kMaxTTLSeconds = 24 * 60 * 60; // 1 day. | 52 const int kMaxTTLSeconds = 24 * 60 * 60; // 1 day. |
| 50 | 53 |
| 51 } // namespace | 54 } // namespace |
| 52 | 55 |
| 53 scoped_ptr<mcs_proto::LoginRequest> BuildLoginRequest( | 56 scoped_ptr<mcs_proto::LoginRequest> BuildLoginRequest( |
| 54 uint64 auth_id, | 57 uint64_t auth_id, |
| 55 uint64 auth_token, | 58 uint64_t auth_token, |
| 56 const std::string& version_string) { | 59 const std::string& version_string) { |
| 57 // Create a hex encoded auth id for the device id field. | 60 // Create a hex encoded auth id for the device id field. |
| 58 std::string auth_id_hex; | 61 std::string auth_id_hex; |
| 59 auth_id_hex = base::StringPrintf("%" PRIx64, auth_id); | 62 auth_id_hex = base::StringPrintf("%" PRIx64, auth_id); |
| 60 | 63 |
| 61 std::string auth_id_str = base::Uint64ToString(auth_id); | 64 std::string auth_id_str = base::Uint64ToString(auth_id); |
| 62 std::string auth_token_str = base::Uint64ToString(auth_token); | 65 std::string auth_token_str = base::Uint64ToString(auth_token); |
| 63 | 66 |
| 64 scoped_ptr<mcs_proto::LoginRequest> login_request( | 67 scoped_ptr<mcs_proto::LoginRequest> login_request( |
| 65 new mcs_proto::LoginRequest()); | 68 new mcs_proto::LoginRequest()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 mcs_proto::SelectiveAck selective_ack; | 102 mcs_proto::SelectiveAck selective_ack; |
| 100 for (size_t i = 0; i < acked_ids.size(); ++i) | 103 for (size_t i = 0; i < acked_ids.size(); ++i) |
| 101 selective_ack.add_id(acked_ids[i]); | 104 selective_ack.add_id(acked_ids[i]); |
| 102 selective_ack_iq->mutable_extension()->set_data( | 105 selective_ack_iq->mutable_extension()->set_data( |
| 103 selective_ack.SerializeAsString()); | 106 selective_ack.SerializeAsString()); |
| 104 return selective_ack_iq.Pass(); | 107 return selective_ack_iq.Pass(); |
| 105 } | 108 } |
| 106 | 109 |
| 107 // Utility method to build a google::protobuf::MessageLite object from a MCS | 110 // Utility method to build a google::protobuf::MessageLite object from a MCS |
| 108 // tag. | 111 // tag. |
| 109 scoped_ptr<google::protobuf::MessageLite> BuildProtobufFromTag(uint8 tag) { | 112 scoped_ptr<google::protobuf::MessageLite> BuildProtobufFromTag(uint8_t tag) { |
| 110 switch(tag) { | 113 switch(tag) { |
| 111 case kHeartbeatPingTag: | 114 case kHeartbeatPingTag: |
| 112 return scoped_ptr<google::protobuf::MessageLite>( | 115 return scoped_ptr<google::protobuf::MessageLite>( |
| 113 new mcs_proto::HeartbeatPing()); | 116 new mcs_proto::HeartbeatPing()); |
| 114 case kHeartbeatAckTag: | 117 case kHeartbeatAckTag: |
| 115 return scoped_ptr<google::protobuf::MessageLite>( | 118 return scoped_ptr<google::protobuf::MessageLite>( |
| 116 new mcs_proto::HeartbeatAck()); | 119 new mcs_proto::HeartbeatAck()); |
| 117 case kLoginRequestTag: | 120 case kLoginRequestTag: |
| 118 return scoped_ptr<google::protobuf::MessageLite>( | 121 return scoped_ptr<google::protobuf::MessageLite>( |
| 119 new mcs_proto::LoginRequest()); | 122 new mcs_proto::LoginRequest()); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 set_persistent_id(persistent_id); | 183 set_persistent_id(persistent_id); |
| 181 return; | 184 return; |
| 182 } else if (protobuf->GetTypeName() == kProtoNames[kDataMessageStanzaTag]) { | 185 } else if (protobuf->GetTypeName() == kProtoNames[kDataMessageStanzaTag]) { |
| 183 reinterpret_cast<mcs_proto::DataMessageStanza*>(protobuf)-> | 186 reinterpret_cast<mcs_proto::DataMessageStanza*>(protobuf)-> |
| 184 set_persistent_id(persistent_id); | 187 set_persistent_id(persistent_id); |
| 185 return; | 188 return; |
| 186 } | 189 } |
| 187 NOTREACHED(); | 190 NOTREACHED(); |
| 188 } | 191 } |
| 189 | 192 |
| 190 uint32 GetLastStreamIdReceived(const google::protobuf::MessageLite& protobuf) { | 193 uint32_t GetLastStreamIdReceived( |
| 194 const google::protobuf::MessageLite& protobuf) { |
| 191 if (protobuf.GetTypeName() == kProtoNames[kIqStanzaTag]) { | 195 if (protobuf.GetTypeName() == kProtoNames[kIqStanzaTag]) { |
| 192 return reinterpret_cast<const mcs_proto::IqStanza*>(&protobuf)-> | 196 return reinterpret_cast<const mcs_proto::IqStanza*>(&protobuf)-> |
| 193 last_stream_id_received(); | 197 last_stream_id_received(); |
| 194 } else if (protobuf.GetTypeName() == kProtoNames[kDataMessageStanzaTag]) { | 198 } else if (protobuf.GetTypeName() == kProtoNames[kDataMessageStanzaTag]) { |
| 195 return reinterpret_cast<const mcs_proto::DataMessageStanza*>(&protobuf)-> | 199 return reinterpret_cast<const mcs_proto::DataMessageStanza*>(&protobuf)-> |
| 196 last_stream_id_received(); | 200 last_stream_id_received(); |
| 197 } else if (protobuf.GetTypeName() == kProtoNames[kHeartbeatPingTag]) { | 201 } else if (protobuf.GetTypeName() == kProtoNames[kHeartbeatPingTag]) { |
| 198 return reinterpret_cast<const mcs_proto::HeartbeatPing*>(&protobuf)-> | 202 return reinterpret_cast<const mcs_proto::HeartbeatPing*>(&protobuf)-> |
| 199 last_stream_id_received(); | 203 last_stream_id_received(); |
| 200 } else if (protobuf.GetTypeName() == kProtoNames[kHeartbeatAckTag]) { | 204 } else if (protobuf.GetTypeName() == kProtoNames[kHeartbeatAckTag]) { |
| 201 return reinterpret_cast<const mcs_proto::HeartbeatAck*>(&protobuf)-> | 205 return reinterpret_cast<const mcs_proto::HeartbeatAck*>(&protobuf)-> |
| 202 last_stream_id_received(); | 206 last_stream_id_received(); |
| 203 } else if (protobuf.GetTypeName() == kProtoNames[kLoginResponseTag]) { | 207 } else if (protobuf.GetTypeName() == kProtoNames[kLoginResponseTag]) { |
| 204 return reinterpret_cast<const mcs_proto::LoginResponse*>(&protobuf)-> | 208 return reinterpret_cast<const mcs_proto::LoginResponse*>(&protobuf)-> |
| 205 last_stream_id_received(); | 209 last_stream_id_received(); |
| 206 } | 210 } |
| 207 // Not all message types have last stream ids. Just return 0. | 211 // Not all message types have last stream ids. Just return 0. |
| 208 return 0; | 212 return 0; |
| 209 } | 213 } |
| 210 | 214 |
| 211 void SetLastStreamIdReceived(uint32 val, | 215 void SetLastStreamIdReceived(uint32_t val, |
| 212 google::protobuf::MessageLite* protobuf) { | 216 google::protobuf::MessageLite* protobuf) { |
| 213 if (protobuf->GetTypeName() == kProtoNames[kIqStanzaTag]) { | 217 if (protobuf->GetTypeName() == kProtoNames[kIqStanzaTag]) { |
| 214 reinterpret_cast<mcs_proto::IqStanza*>(protobuf)-> | 218 reinterpret_cast<mcs_proto::IqStanza*>(protobuf)-> |
| 215 set_last_stream_id_received(val); | 219 set_last_stream_id_received(val); |
| 216 return; | 220 return; |
| 217 } else if (protobuf->GetTypeName() == kProtoNames[kHeartbeatPingTag]) { | 221 } else if (protobuf->GetTypeName() == kProtoNames[kHeartbeatPingTag]) { |
| 218 reinterpret_cast<mcs_proto::HeartbeatPing*>(protobuf)-> | 222 reinterpret_cast<mcs_proto::HeartbeatPing*>(protobuf)-> |
| 219 set_last_stream_id_received(val); | 223 set_last_stream_id_received(val); |
| 220 return; | 224 return; |
| 221 } else if (protobuf->GetTypeName() == kProtoNames[kHeartbeatAckTag]) { | 225 } else if (protobuf->GetTypeName() == kProtoNames[kHeartbeatAckTag]) { |
| 222 reinterpret_cast<mcs_proto::HeartbeatAck*>(protobuf)-> | 226 reinterpret_cast<mcs_proto::HeartbeatAck*>(protobuf)-> |
| 223 set_last_stream_id_received(val); | 227 set_last_stream_id_received(val); |
| 224 return; | 228 return; |
| 225 } else if (protobuf->GetTypeName() == kProtoNames[kDataMessageStanzaTag]) { | 229 } else if (protobuf->GetTypeName() == kProtoNames[kDataMessageStanzaTag]) { |
| 226 reinterpret_cast<mcs_proto::DataMessageStanza*>(protobuf)-> | 230 reinterpret_cast<mcs_proto::DataMessageStanza*>(protobuf)-> |
| 227 set_last_stream_id_received(val); | 231 set_last_stream_id_received(val); |
| 228 return; | 232 return; |
| 229 } else if (protobuf->GetTypeName() == kProtoNames[kLoginResponseTag]) { | 233 } else if (protobuf->GetTypeName() == kProtoNames[kLoginResponseTag]) { |
| 230 reinterpret_cast<mcs_proto::LoginResponse*>(protobuf)-> | 234 reinterpret_cast<mcs_proto::LoginResponse*>(protobuf)-> |
| 231 set_last_stream_id_received(val); | 235 set_last_stream_id_received(val); |
| 232 return; | 236 return; |
| 233 } | 237 } |
| 234 NOTREACHED(); | 238 NOTREACHED(); |
| 235 } | 239 } |
| 236 | 240 |
| 237 bool HasTTLExpired(const google::protobuf::MessageLite& protobuf, | 241 bool HasTTLExpired(const google::protobuf::MessageLite& protobuf, |
| 238 base::Clock* clock) { | 242 base::Clock* clock) { |
| 239 if (protobuf.GetTypeName() != kProtoNames[kDataMessageStanzaTag]) | 243 if (protobuf.GetTypeName() != kProtoNames[kDataMessageStanzaTag]) |
| 240 return false; | 244 return false; |
| 241 uint64 ttl = GetTTL(protobuf); | 245 uint64_t ttl = GetTTL(protobuf); |
| 242 uint64 sent = | 246 uint64_t sent = |
| 243 reinterpret_cast<const mcs_proto::DataMessageStanza*>(&protobuf)->sent(); | 247 reinterpret_cast<const mcs_proto::DataMessageStanza*>(&protobuf)->sent(); |
| 244 DCHECK(sent); | 248 DCHECK(sent); |
| 245 return ttl > 0 && | 249 return ttl > 0 && |
| 246 clock->Now() > | 250 clock->Now() > |
| 247 base::Time::FromInternalValue( | 251 base::Time::FromInternalValue( |
| 248 (sent + ttl) * base::Time::kMicrosecondsPerSecond); | 252 (sent + ttl) * base::Time::kMicrosecondsPerSecond); |
| 249 } | 253 } |
| 250 | 254 |
| 251 int GetTTL(const google::protobuf::MessageLite& protobuf) { | 255 int GetTTL(const google::protobuf::MessageLite& protobuf) { |
| 252 if (protobuf.GetTypeName() != kProtoNames[kDataMessageStanzaTag]) | 256 if (protobuf.GetTypeName() != kProtoNames[kDataMessageStanzaTag]) |
| 253 return 0; | 257 return 0; |
| 254 const mcs_proto::DataMessageStanza* data_message = | 258 const mcs_proto::DataMessageStanza* data_message = |
| 255 reinterpret_cast<const mcs_proto::DataMessageStanza*>(&protobuf); | 259 reinterpret_cast<const mcs_proto::DataMessageStanza*>(&protobuf); |
| 256 if (!data_message->has_ttl()) | 260 if (!data_message->has_ttl()) |
| 257 return kMaxTTLSeconds; | 261 return kMaxTTLSeconds; |
| 258 DCHECK_LE(data_message->ttl(), kMaxTTLSeconds); | 262 DCHECK_LE(data_message->ttl(), kMaxTTLSeconds); |
| 259 return data_message->ttl(); | 263 return data_message->ttl(); |
| 260 } | 264 } |
| 261 | 265 |
| 262 bool IsImmediateAckRequested(const google::protobuf::MessageLite& protobuf) { | 266 bool IsImmediateAckRequested(const google::protobuf::MessageLite& protobuf) { |
| 263 if (protobuf.GetTypeName() != kProtoNames[kDataMessageStanzaTag]) | 267 if (protobuf.GetTypeName() != kProtoNames[kDataMessageStanzaTag]) |
| 264 return false; | 268 return false; |
| 265 const mcs_proto::DataMessageStanza* data_message = | 269 const mcs_proto::DataMessageStanza* data_message = |
| 266 reinterpret_cast<const mcs_proto::DataMessageStanza*>(&protobuf); | 270 reinterpret_cast<const mcs_proto::DataMessageStanza*>(&protobuf); |
| 267 return data_message->has_immediate_ack() && data_message->immediate_ack(); | 271 return data_message->has_immediate_ack() && data_message->immediate_ack(); |
| 268 } | 272 } |
| 269 | 273 |
| 270 } // namespace gcm | 274 } // namespace gcm |
| OLD | NEW |