Push from command line

This commit is contained in:
Deniz Duezgoeren
2019-08-12 11:20:21 +02:00
parent 3a919dcb23
commit f1345eac14
512 changed files with 103288 additions and 1930 deletions
@@ -0,0 +1,188 @@
/*
* Copyright 2019 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "GDTCCTLibrary/Private/GDTCCTNanopbHelpers.h"
#if TARGET_OS_IOS || TARGET_OS_TV
#import <UIKit/UIKit.h>
#elif TARGET_OS_OSX
#import <AppKit/AppKit.h>
#endif // TARGET_OS_IOS || TARGET_OS_TV
#import <GoogleDataTransport/GDTConsoleLogger.h>
#import <nanopb/pb.h>
#import <nanopb/pb_decode.h>
#import <nanopb/pb_encode.h>
#import "GDTCCTLibrary/Private/GDTCCTPrioritizer.h"
#pragma mark - General purpose encoders
pb_bytes_array_t *GDTCCTEncodeString(NSString *string) {
NSData *stringBytes = [string dataUsingEncoding:NSUTF8StringEncoding];
return GDTCCTEncodeData(stringBytes);
}
pb_bytes_array_t *GDTCCTEncodeData(NSData *data) {
pb_bytes_array_t *pbBytes = malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(data.length));
memcpy(pbBytes->bytes, [data bytes], data.length);
pbBytes->size = (pb_size_t)data.length;
return pbBytes;
}
#pragma mark - CCT object constructors
NSData *_Nullable GDTCCTEncodeBatchedLogRequest(gdt_cct_BatchedLogRequest *batchedLogRequest) {
pb_ostream_t sizestream = PB_OSTREAM_SIZING;
// Encode 1 time to determine the size.
if (!pb_encode(&sizestream, gdt_cct_BatchedLogRequest_fields, batchedLogRequest)) {
GDTLogError(GDTMCEGeneralError, @"Error in nanopb encoding for size: %s",
PB_GET_ERROR(&sizestream));
}
// Encode a 2nd time to actually get the bytes from it.
size_t bufferSize = sizestream.bytes_written;
CFMutableDataRef dataRef = CFDataCreateMutable(CFAllocatorGetDefault(), bufferSize);
pb_ostream_t ostream = pb_ostream_from_buffer((void *)CFDataGetBytePtr(dataRef), bufferSize);
if (!pb_encode(&ostream, gdt_cct_BatchedLogRequest_fields, batchedLogRequest)) {
GDTLogError(GDTMCEGeneralError, @"Error in nanopb encoding for bytes: %s",
PB_GET_ERROR(&ostream));
}
CFDataSetLength(dataRef, ostream.bytes_written);
return CFBridgingRelease(dataRef);
}
gdt_cct_BatchedLogRequest GDTCCTConstructBatchedLogRequest(
NSDictionary<NSString *, NSSet<GDTStoredEvent *> *> *logMappingIDToLogSet) {
gdt_cct_BatchedLogRequest batchedLogRequest = gdt_cct_BatchedLogRequest_init_default;
NSUInteger numberOfLogRequests = logMappingIDToLogSet.count;
gdt_cct_LogRequest *logRequests = malloc(sizeof(gdt_cct_LogRequest) * numberOfLogRequests);
__block int i = 0;
[logMappingIDToLogSet enumerateKeysAndObjectsUsingBlock:^(
NSString *_Nonnull logMappingID,
NSSet<GDTStoredEvent *> *_Nonnull logSet, BOOL *_Nonnull stop) {
int32_t logSource = [logMappingID intValue];
gdt_cct_LogRequest logRequest = GDTCCTConstructLogRequest(logSource, logSet);
logRequests[i] = logRequest;
i++;
}];
batchedLogRequest.log_request = logRequests;
batchedLogRequest.log_request_count = (pb_size_t)numberOfLogRequests;
return batchedLogRequest;
}
gdt_cct_LogRequest GDTCCTConstructLogRequest(int32_t logSource,
NSSet<GDTStoredEvent *> *_Nonnull logSet) {
if (logSet.count == 0) {
GDTLogError(GDTMCEGeneralError, @"%@", @"An empty event set can't be serialized to proto.");
gdt_cct_LogRequest logRequest = gdt_cct_LogRequest_init_default;
return logRequest;
}
gdt_cct_LogRequest logRequest = gdt_cct_LogRequest_init_default;
logRequest.log_source = logSource;
logRequest.has_log_source = 1;
logRequest.client_info = GDTCCTConstructClientInfo();
logRequest.has_client_info = 1;
logRequest.log_event = malloc(sizeof(gdt_cct_LogEvent) * logSet.count);
int i = 0;
for (GDTStoredEvent *log in logSet) {
gdt_cct_LogEvent logEvent = GDTCCTConstructLogEvent(log);
logRequest.log_event[i] = logEvent;
i++;
}
logRequest.log_event_count = (pb_size_t)logSet.count;
return logRequest;
}
gdt_cct_LogEvent GDTCCTConstructLogEvent(GDTStoredEvent *event) {
gdt_cct_LogEvent logEvent = gdt_cct_LogEvent_init_default;
logEvent.event_time_ms = event.clockSnapshot.timeMillis;
logEvent.has_event_time_ms = 1;
logEvent.event_uptime_ms = event.clockSnapshot.uptime;
logEvent.has_event_uptime_ms = 1;
logEvent.timezone_offset_seconds = event.clockSnapshot.timezoneOffsetSeconds;
logEvent.has_timezone_offset_seconds = 1;
// TODO: Read network_connection_info from the custom params dict.
NSError *error;
NSData *extensionBytes = [NSData dataWithContentsOfURL:event.dataFuture.fileURL
options:0
error:&error];
if (error) {
GDTLogError(GDTMCEGeneralError, @"There was an error reading extension bytes from disk: %@",
error);
return logEvent;
}
logEvent.source_extension = GDTCCTEncodeData(extensionBytes); // read bytes from the file.
return logEvent;
}
gdt_cct_ClientInfo GDTCCTConstructClientInfo() {
gdt_cct_ClientInfo clientInfo = gdt_cct_ClientInfo_init_default;
clientInfo.client_type = gdt_cct_ClientInfo_ClientType_IOS_FIREBASE;
clientInfo.has_client_type = 1;
#if TARGET_OS_IOS || TARGET_OS_TV
clientInfo.ios_client_info = GDTCCTConstructiOSClientInfo();
clientInfo.has_ios_client_info = 1;
#elif TARGET_OS_OSX
// TODO(mikehaney24): Expand the proto to include macOS client info.
#endif
return clientInfo;
}
gdt_cct_IosClientInfo GDTCCTConstructiOSClientInfo() {
gdt_cct_IosClientInfo iOSClientInfo = gdt_cct_IosClientInfo_init_default;
#if TARGET_OS_IOS || TARGET_OS_TV
UIDevice *device = [UIDevice currentDevice];
NSBundle *bundle = [NSBundle mainBundle];
NSLocale *locale = [NSLocale currentLocale];
iOSClientInfo.os_full_version = GDTCCTEncodeString(device.systemVersion);
NSArray *versionComponents = [device.systemVersion componentsSeparatedByString:@"."];
iOSClientInfo.os_major_version = GDTCCTEncodeString(versionComponents[0]);
NSString *version = [bundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
if (version) {
iOSClientInfo.application_build = GDTCCTEncodeString(version);
}
iOSClientInfo.country = GDTCCTEncodeString([locale objectForKey:NSLocaleCountryCode]);
iOSClientInfo.model = GDTCCTEncodeString(device.model);
NSString *languageCode = bundle.preferredLocalizations.firstObject;
iOSClientInfo.language_code =
languageCode ? GDTCCTEncodeString(languageCode) : GDTCCTEncodeString(@"en");
iOSClientInfo.application_bundle_id = GDTCCTEncodeString(bundle.bundleIdentifier);
#endif
return iOSClientInfo;
}
#pragma mark - CCT Object decoders
gdt_cct_LogResponse GDTCCTDecodeLogResponse(NSData *data, NSError **error) {
gdt_cct_LogResponse response = gdt_cct_LogResponse_init_default;
pb_istream_t istream = pb_istream_from_buffer([data bytes], [data length]);
if (!pb_decode(&istream, gdt_cct_LogResponse_fields, &response)) {
NSString *nanopb_error = [NSString stringWithFormat:@"%s", PB_GET_ERROR(&istream)];
NSDictionary *userInfo = @{@"nanopb error:" : nanopb_error};
if (error != NULL) {
*error = [NSError errorWithDomain:NSURLErrorDomain code:-1 userInfo:userInfo];
}
response = (gdt_cct_LogResponse)gdt_cct_LogResponse_init_default;
}
return response;
}
@@ -0,0 +1,188 @@
/*
* Copyright 2019 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "GDTCCTLibrary/Private/GDTCCTPrioritizer.h"
#import <GoogleDataTransport/GDTEvent.h>
#import <GoogleDataTransport/GDTRegistrar.h>
#import <GoogleDataTransport/GDTStoredEvent.h>
#import <GoogleDataTransport/GDTTargets.h>
const static int64_t kMillisPerDay = 8.64e+7;
@implementation GDTCCTPrioritizer
+ (void)load {
GDTCCTPrioritizer *prioritizer = [GDTCCTPrioritizer sharedInstance];
[[GDTRegistrar sharedInstance] registerPrioritizer:prioritizer target:kGDTTargetCCT];
}
+ (instancetype)sharedInstance {
static GDTCCTPrioritizer *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[GDTCCTPrioritizer alloc] init];
});
return sharedInstance;
}
- (instancetype)init {
self = [super init];
if (self) {
_queue = dispatch_queue_create("com.google.GDTCCTPrioritizer", DISPATCH_QUEUE_SERIAL);
_events = [[NSMutableSet alloc] init];
}
return self;
}
#pragma mark - GDTPrioritizer Protocol
- (void)prioritizeEvent:(GDTStoredEvent *)event {
dispatch_async(_queue, ^{
[self.events addObject:event];
});
}
- (GDTUploadPackage *)uploadPackageWithConditions:(GDTUploadConditions)conditions {
GDTUploadPackage *package = [[GDTUploadPackage alloc] initWithTarget:kGDTTargetCCT];
dispatch_sync(_queue, ^{
NSSet<GDTStoredEvent *> *logEventsThatWillBeSent;
// A high priority event effectively flushes all events to be sent.
if ((conditions & GDTUploadConditionHighPriority) == GDTUploadConditionHighPriority) {
package.events = self.events;
return;
}
// If on wifi, upload logs that are ok to send on wifi.
if ((conditions & GDTUploadConditionWifiData) == GDTUploadConditionWifiData) {
logEventsThatWillBeSent = [self logEventsOkToSendOnWifi];
} else {
logEventsThatWillBeSent = [self logEventsOkToSendOnMobileData];
}
// If it's been > 24h since the last daily upload, upload logs with the daily QoS.
if (self.timeOfLastDailyUpload) {
int64_t millisSinceLastUpload =
[GDTClock snapshot].timeMillis - self.timeOfLastDailyUpload.timeMillis;
if (millisSinceLastUpload > kMillisPerDay) {
logEventsThatWillBeSent =
[logEventsThatWillBeSent setByAddingObjectsFromSet:[self logEventsOkToSendDaily]];
}
} else {
self.timeOfLastDailyUpload = [GDTClock snapshot];
logEventsThatWillBeSent =
[logEventsThatWillBeSent setByAddingObjectsFromSet:[self logEventsOkToSendDaily]];
}
package.events = logEventsThatWillBeSent;
});
return package;
}
#pragma mark - Private helper methods
/** The different possible quality of service specifiers. High values indicate high priority. */
typedef NS_ENUM(NSInteger, GDTCCTQoSTier) {
/** The QoS tier wasn't set, and won't ever be sent. */
GDTCCTQoSDefault = 0,
/** This event is internal telemetry data that should not be sent on its own if possible. */
GDTCCTQoSTelemetry = 1,
/** This event should be sent, but in a batch only roughly once per day. */
GDTCCTQoSDaily = 2,
/** This event should only be uploaded on wifi. */
GDTCCTQoSWifiOnly = 5,
};
/** Converts a GDTEventQoS to a GDTCCTQoS tier.
*
* @param qosTier The GDTEventQoS value.
* @return A static NSNumber that represents the CCT QoS tier.
*/
FOUNDATION_STATIC_INLINE
NSNumber *GDTCCTQosTierFromGDTEventQosTier(GDTEventQoS qosTier) {
switch (qosTier) {
case GDTEventQoSWifiOnly:
return @(GDTCCTQoSWifiOnly);
break;
case GDTEventQoSTelemetry:
// falls through.
case GDTEventQoSDaily:
return @(GDTCCTQoSDaily);
break;
default:
return @(GDTCCTQoSDefault);
break;
}
}
/** Returns a set of logs that are ok to upload whilst on mobile data.
*
* @note This should be called from a thread safe method.
* @return A set of logs that are ok to upload whilst on mobile data.
*/
- (NSSet<GDTStoredEvent *> *)logEventsOkToSendOnMobileData {
return
[self.events objectsPassingTest:^BOOL(GDTStoredEvent *_Nonnull event, BOOL *_Nonnull stop) {
return [GDTCCTQosTierFromGDTEventQosTier(event.qosTier) isEqual:@(GDTCCTQoSDefault)];
}];
}
/** Returns a set of logs that are ok to upload whilst on wifi.
*
* @note This should be called from a thread safe method.
* @return A set of logs that are ok to upload whilst on wifi.
*/
- (NSSet<GDTStoredEvent *> *)logEventsOkToSendOnWifi {
return
[self.events objectsPassingTest:^BOOL(GDTStoredEvent *_Nonnull event, BOOL *_Nonnull stop) {
NSNumber *qosTier = GDTCCTQosTierFromGDTEventQosTier(event.qosTier);
return [qosTier isEqual:@(GDTCCTQoSDefault)] || [qosTier isEqual:@(GDTCCTQoSWifiOnly)] ||
[qosTier isEqual:@(GDTCCTQoSDaily)];
}];
}
/** Returns a set of logs that only should have a single upload attempt per day.
*
* @note This should be called from a thread safe method.
* @return A set of logs that are ok to upload only once per day.
*/
- (NSSet<GDTStoredEvent *> *)logEventsOkToSendDaily {
return
[self.events objectsPassingTest:^BOOL(GDTStoredEvent *_Nonnull event, BOOL *_Nonnull stop) {
return [GDTCCTQosTierFromGDTEventQosTier(event.qosTier) isEqual:@(GDTCCTQoSDaily)];
}];
}
#pragma mark - GDTUploadPackageProtocol
- (void)packageDelivered:(GDTUploadPackage *)package successful:(BOOL)successful {
dispatch_async(_queue, ^{
NSSet<GDTStoredEvent *> *events = [package.events copy];
for (GDTStoredEvent *event in events) {
[self.events removeObject:event];
}
});
}
- (void)packageExpired:(GDTUploadPackage *)package {
[self packageDelivered:package successful:YES];
}
@end
@@ -0,0 +1,206 @@
/*
* Copyright 2019 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "GDTCCTLibrary/Private/GDTCCTUploader.h"
#import <GoogleDataTransport/GDTConsoleLogger.h>
#import <GoogleDataTransport/GDTPlatform.h>
#import <GoogleDataTransport/GDTRegistrar.h>
#import <nanopb/pb.h>
#import <nanopb/pb_decode.h>
#import <nanopb/pb_encode.h>
#import "GDTCCTLibrary/Private/GDTCCTNanopbHelpers.h"
#import "GDTCCTLibrary/Private/GDTCCTPrioritizer.h"
#import "GDTCCTLibrary/Protogen/nanopb/cct.nanopb.h"
@interface GDTCCTUploader ()
// Redeclared as readwrite.
@property(nullable, nonatomic, readwrite) NSURLSessionUploadTask *currentTask;
/** If running in the background, the current background ID. */
@property(nonatomic) GDTBackgroundIdentifier backgroundID;
@end
@implementation GDTCCTUploader
+ (void)load {
GDTCCTUploader *uploader = [GDTCCTUploader sharedInstance];
[[GDTRegistrar sharedInstance] registerUploader:uploader target:kGDTTargetCCT];
}
+ (instancetype)sharedInstance {
static GDTCCTUploader *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[GDTCCTUploader alloc] init];
});
return sharedInstance;
}
- (instancetype)init {
self = [super init];
if (self) {
_uploaderQueue = dispatch_queue_create("com.google.GDTCCTUploader", DISPATCH_QUEUE_SERIAL);
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
_uploaderSession = [NSURLSession sessionWithConfiguration:config];
_backgroundID = GDTBackgroundIdentifierInvalid;
}
return self;
}
- (NSURL *)defaultServerURL {
static NSURL *defaultServerURL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// These strings should be interleaved to construct the real URL. This is just to (hopefully)
// fool github URL scanning bots.
const char *p1 = "hts/frbslgiggolai.o/0clgbth";
const char *p2 = "tp:/ieaeogn.ogepscmvc/o/ac";
const char defaultURL[54] = {
p1[0], p2[0], p1[1], p2[1], p1[2], p2[2], p1[3], p2[3], p1[4], p2[4], p1[5],
p2[5], p1[6], p2[6], p1[7], p2[7], p1[8], p2[8], p1[9], p2[9], p1[10], p2[10],
p1[11], p2[11], p1[12], p2[12], p1[13], p2[13], p1[14], p2[14], p1[15], p2[15], p1[16],
p2[16], p1[17], p2[17], p1[18], p2[18], p1[19], p2[19], p1[20], p2[20], p1[21], p2[21],
p1[22], p2[22], p1[23], p2[23], p1[24], p2[24], p1[25], p2[25], p1[26], '\0'};
defaultServerURL = [NSURL URLWithString:[NSString stringWithUTF8String:defaultURL]];
});
return defaultServerURL;
}
- (void)uploadPackage:(GDTUploadPackage *)package {
dispatch_async(_uploaderQueue, ^{
if (self->_currentTask || self->_currentUploadPackage) {
GDTLogWarning(GDTMCWUploadFailed, @"%@",
@"An upload shouldn't be initiated with another in progress.");
return;
}
NSURL *serverURL = self.serverURL ? self.serverURL : [self defaultServerURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:serverURL];
request.HTTPMethod = @"POST";
id completionHandler =
^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
if (error) {
GDTLogWarning(GDTMCWUploadFailed, @"There was an error uploading events: %@", error);
}
NSError *decodingError;
gdt_cct_LogResponse logResponse = GDTCCTDecodeLogResponse(data, &decodingError);
if (!decodingError && logResponse.has_next_request_wait_millis) {
self->_nextUploadTime =
[GDTClock clockSnapshotInTheFuture:logResponse.next_request_wait_millis];
} else {
// 15 minutes from now.
self->_nextUploadTime = [GDTClock clockSnapshotInTheFuture:15 * 60 * 1000];
}
pb_release(gdt_cct_LogResponse_fields, &logResponse);
[package completeDelivery];
if (self->_backgroundID != GDTBackgroundIdentifierInvalid) {
[[GDTApplication sharedApplication] endBackgroundTask:self->_backgroundID];
self->_backgroundID = GDTBackgroundIdentifierInvalid;
}
self.currentTask = nil;
self.currentUploadPackage = nil;
};
self->_currentUploadPackage = package;
NSData *requestProtoData = [self constructRequestProtoFromPackage:(GDTUploadPackage *)package];
self.currentTask = [self.uploaderSession uploadTaskWithRequest:request
fromData:requestProtoData
completionHandler:completionHandler];
[self.currentTask resume];
});
}
- (BOOL)readyToUploadWithConditions:(GDTUploadConditions)conditions {
__block BOOL result = NO;
dispatch_sync(_uploaderQueue, ^{
if (self->_currentUploadPackage) {
result = NO;
return;
}
if (self->_currentTask) {
result = NO;
return;
}
if ((conditions & GDTUploadConditionHighPriority) == GDTUploadConditionHighPriority) {
result = YES;
return;
} else if (self->_nextUploadTime) {
result = [[GDTClock snapshot] isAfter:self->_nextUploadTime];
return;
}
result = YES;
});
return result;
}
#pragma mark - Private helper methods
/** Constructs data given an upload package.
*
* @param package The upload package used to construct the request proto bytes.
* @return Proto bytes representing a gdt_cct_LogRequest object.
*/
- (nonnull NSData *)constructRequestProtoFromPackage:(GDTUploadPackage *)package {
// Segment the log events by log type.
NSMutableDictionary<NSString *, NSMutableSet<GDTStoredEvent *> *> *logMappingIDToLogSet =
[[NSMutableDictionary alloc] init];
[package.events
enumerateObjectsUsingBlock:^(GDTStoredEvent *_Nonnull event, BOOL *_Nonnull stop) {
NSMutableSet *logSet = logMappingIDToLogSet[event.mappingID];
logSet = logSet ? logSet : [[NSMutableSet alloc] init];
[logSet addObject:event];
logMappingIDToLogSet[event.mappingID] = logSet;
}];
gdt_cct_BatchedLogRequest batchedLogRequest =
GDTCCTConstructBatchedLogRequest(logMappingIDToLogSet);
NSData *data = GDTCCTEncodeBatchedLogRequest(&batchedLogRequest);
pb_release(gdt_cct_BatchedLogRequest_fields, &batchedLogRequest);
return data ? data : [[NSData alloc] init];
}
#pragma mark - GDTUploadPackageProtocol
- (void)packageExpired:(GDTUploadPackage *)package {
dispatch_async(_uploaderQueue, ^{
[self.currentTask cancel];
self.currentTask = nil;
self.currentUploadPackage = nil;
});
}
#pragma mark - GDTLifecycleProtocol
- (void)appWillBackground:(GDTApplication *)app {
_backgroundID = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:self->_backgroundID];
}];
}
- (void)appWillTerminate:(GDTApplication *)application {
dispatch_sync(_uploaderQueue, ^{
[self.currentTask cancel];
[self.currentUploadPackage completeDelivery];
});
}
@end
@@ -0,0 +1,112 @@
/*
* Copyright 2019 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import <GoogleDataTransport/GDTStoredEvent.h>
#import "GDTCCTLibrary/Protogen/nanopb/cct.nanopb.h"
NS_ASSUME_NONNULL_BEGIN
#pragma mark - General purpose encoders
/** Converts an NSString* to a pb_bytes_array_t*.
*
* @note malloc is called in this method. Ensure that pb_release is called on this or the parent.
*
* @param string The string to convert.
* @return A newly allocated array of bytes representing the UTF8 encoding of the string.
*/
pb_bytes_array_t *GDTCCTEncodeString(NSString *string);
/** Converts an NSData to a pb_bytes_array_t*.
*
* @note malloc is called in this method. Ensure that pb_release is called on this or the parent.
*
* @param data The data to convert.
* @return A newly allocated array of bytes with [data bytes] copied into it.
*/
pb_bytes_array_t *GDTCCTEncodeData(NSData *data);
#pragma mark - CCT object constructors
/** Encodes a batched log request.
*
* @note Ensure that pb_release is called on the batchedLogRequest param.
*
* @param batchedLogRequest A pointer to the log batch to encode to bytes.
* @return An NSData object representing the bytes of the log request batch.
*/
FOUNDATION_EXPORT
NSData *GDTCCTEncodeBatchedLogRequest(gdt_cct_BatchedLogRequest *batchedLogRequest);
/** Constructs a gdt_cct_BatchedLogRequest given sets of events segemented by mapping ID.
*
* @note malloc is called in this method. Ensure that pb_release is called on this or the parent.
*
* @param logMappingIDToLogSet A map of mapping IDs to sets of events to convert into a batch.
* @return A newly created gdt_cct_BatchedLogRequest.
*/
FOUNDATION_EXPORT
gdt_cct_BatchedLogRequest GDTCCTConstructBatchedLogRequest(
NSDictionary<NSString *, NSSet<GDTStoredEvent *> *> *logMappingIDToLogSet);
/** Constructs a log request given a log source and a set of events.
*
* @note malloc is called in this method. Ensure that pb_release is called on this or the parent.
* @param logSource The CCT log source to put into the log request.
* @param logSet The set of events to send in this log request.
*/
FOUNDATION_EXPORT
gdt_cct_LogRequest GDTCCTConstructLogRequest(int32_t logSource, NSSet<GDTStoredEvent *> *logSet);
/** Constructs a gdt_cct_LogEvent given a GDTStoredEvent*.
*
* @param event The GDTStoredEvent to convert.
* @return The new gdt_cct_LogEvent object.
*/
FOUNDATION_EXPORT
gdt_cct_LogEvent GDTCCTConstructLogEvent(GDTStoredEvent *event);
/** Constructs a gdt_cct_ClientInfo representing the client device.
*
* @return The new gdt_cct_ClientInfo object.
*/
FOUNDATION_EXPORT
gdt_cct_ClientInfo GDTCCTConstructClientInfo(void);
/** Constructs a gdt_cct_IosClientInfo representing the client device.
*
* @return The new gdt_cct_IosClientInfo object.
*/
FOUNDATION_EXPORT
gdt_cct_IosClientInfo GDTCCTConstructiOSClientInfo(void);
#pragma mark - CCT object decoders
/** Decodes a gdt_cct_LogResponse given proto bytes.
*
* @note malloc is called in this method. Ensure that pb_release is called on the return value.
*
* @param data The proto bytes of the gdt_cct_LogResponse.
* @param error An error that will be populated if something went wrong during decoding.
* @return A newly allocated gdt_cct_LogResponse from the data, if the bytes decoded properly.
*/
FOUNDATION_EXPORT
gdt_cct_LogResponse GDTCCTDecodeLogResponse(NSData *data, NSError **error);
NS_ASSUME_NONNULL_END
@@ -0,0 +1,44 @@
/*
* Copyright 2019 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import <GoogleDataTransport/GDTClock.h>
#import <GoogleDataTransport/GDTPrioritizer.h>
NS_ASSUME_NONNULL_BEGIN
/** Manages the prioritization of events from GoogleDataTransport. */
@interface GDTCCTPrioritizer : NSObject <GDTPrioritizer>
/** The queue on which this prioritizer operates. */
@property(nonatomic) dispatch_queue_t queue;
/** All log events that have been processed by this prioritizer. */
@property(nonatomic) NSMutableSet<GDTStoredEvent *> *events;
/** The most recent attempted upload of daily uploaded logs. */
@property(nonatomic) GDTClock *timeOfLastDailyUpload;
/** Creates and/or returns the singleton instance of this class.
*
* @return The singleton instance of this class.
*/
+ (instancetype)sharedInstance;
NS_ASSUME_NONNULL_END
@end
@@ -0,0 +1,52 @@
/*
* Copyright 2019 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import <GoogleDataTransport/GDTUploader.h>
NS_ASSUME_NONNULL_BEGIN
/** Class capable of uploading events to the CCT backend. */
@interface GDTCCTUploader : NSObject <GDTUploader>
/** The queue on which all CCT uploading will occur. */
@property(nonatomic, readonly) dispatch_queue_t uploaderQueue;
/** The server URL to upload to. Look at .m for the default value. */
@property(nonatomic) NSURL *serverURL;
/** The URL session that will attempt upload. */
@property(nonatomic, readonly) NSURLSession *uploaderSession;
/** The current upload task. */
@property(nullable, nonatomic, readonly) NSURLSessionUploadTask *currentTask;
/** Current upload package. */
@property(nullable, nonatomic) GDTUploadPackage *currentUploadPackage;
/** The next upload time. */
@property(nullable, nonatomic) GDTClock *nextUploadTime;
/** Creates and/or returns the singleton instance of this class.
*
* @return The singleton instance of this class.
*/
+ (instancetype)sharedInstance;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,128 @@
/*
* Copyright 2019 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.9.2 */
#include "cct.nanopb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
const gdt_cct_NetworkConnectionInfo_NetworkType gdt_cct_NetworkConnectionInfo_network_type_default = gdt_cct_NetworkConnectionInfo_NetworkType_NONE;
const gdt_cct_NetworkConnectionInfo_MobileSubtype gdt_cct_NetworkConnectionInfo_mobile_subtype_default = gdt_cct_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE;
const gdt_cct_QosTierConfiguration_QosTier gdt_cct_LogRequest_qos_tier_default = gdt_cct_QosTierConfiguration_QosTier_DEFAULT;
const int32_t gdt_cct_QosTierConfiguration_log_source_default = 0;
const pb_field_t gdt_cct_LogEvent_fields[7] = {
PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, gdt_cct_LogEvent, event_time_ms, event_time_ms, 0),
PB_FIELD( 6, BYTES , OPTIONAL, POINTER , OTHER, gdt_cct_LogEvent, source_extension, event_time_ms, 0),
PB_FIELD( 11, INT32 , OPTIONAL, STATIC , OTHER, gdt_cct_LogEvent, event_code, source_extension, 0),
PB_FIELD( 15, SINT64 , OPTIONAL, STATIC , OTHER, gdt_cct_LogEvent, timezone_offset_seconds, event_code, 0),
PB_FIELD( 17, INT64 , OPTIONAL, STATIC , OTHER, gdt_cct_LogEvent, event_uptime_ms, timezone_offset_seconds, 0),
PB_FIELD( 23, MESSAGE , OPTIONAL, STATIC , OTHER, gdt_cct_LogEvent, network_connection_info, event_uptime_ms, &gdt_cct_NetworkConnectionInfo_fields),
PB_LAST_FIELD
};
const pb_field_t gdt_cct_NetworkConnectionInfo_fields[3] = {
PB_FIELD( 1, ENUM , OPTIONAL, STATIC , FIRST, gdt_cct_NetworkConnectionInfo, network_type, network_type, &gdt_cct_NetworkConnectionInfo_network_type_default),
PB_FIELD( 2, UENUM , OPTIONAL, STATIC , OTHER, gdt_cct_NetworkConnectionInfo, mobile_subtype, network_type, &gdt_cct_NetworkConnectionInfo_mobile_subtype_default),
PB_LAST_FIELD
};
const pb_field_t gdt_cct_IosClientInfo_fields[8] = {
PB_FIELD( 3, BYTES , OPTIONAL, POINTER , FIRST, gdt_cct_IosClientInfo, os_major_version, os_major_version, 0),
PB_FIELD( 4, BYTES , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, os_full_version, os_major_version, 0),
PB_FIELD( 5, BYTES , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, application_build, os_full_version, 0),
PB_FIELD( 6, BYTES , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, country, application_build, 0),
PB_FIELD( 7, BYTES , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, model, country, 0),
PB_FIELD( 8, BYTES , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, language_code, model, 0),
PB_FIELD( 11, BYTES , OPTIONAL, POINTER , OTHER, gdt_cct_IosClientInfo, application_bundle_id, language_code, 0),
PB_LAST_FIELD
};
const pb_field_t gdt_cct_ClientInfo_fields[3] = {
PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, gdt_cct_ClientInfo, client_type, client_type, 0),
PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, gdt_cct_ClientInfo, ios_client_info, client_type, &gdt_cct_IosClientInfo_fields),
PB_LAST_FIELD
};
const pb_field_t gdt_cct_BatchedLogRequest_fields[2] = {
PB_FIELD( 1, MESSAGE , REPEATED, POINTER , FIRST, gdt_cct_BatchedLogRequest, log_request, log_request, &gdt_cct_LogRequest_fields),
PB_LAST_FIELD
};
const pb_field_t gdt_cct_LogRequest_fields[7] = {
PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, gdt_cct_LogRequest, client_info, client_info, &gdt_cct_ClientInfo_fields),
PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, gdt_cct_LogRequest, log_source, client_info, 0),
PB_FIELD( 3, MESSAGE , REPEATED, POINTER , OTHER, gdt_cct_LogRequest, log_event, log_source, &gdt_cct_LogEvent_fields),
PB_FIELD( 4, INT64 , OPTIONAL, STATIC , OTHER, gdt_cct_LogRequest, request_time_ms, log_event, 0),
PB_FIELD( 8, INT64 , OPTIONAL, STATIC , OTHER, gdt_cct_LogRequest, request_uptime_ms, request_time_ms, 0),
PB_FIELD( 9, UENUM , OPTIONAL, STATIC , OTHER, gdt_cct_LogRequest, qos_tier, request_uptime_ms, &gdt_cct_LogRequest_qos_tier_default),
PB_LAST_FIELD
};
const pb_field_t gdt_cct_QosTierConfiguration_fields[3] = {
PB_FIELD( 2, UENUM , OPTIONAL, STATIC , FIRST, gdt_cct_QosTierConfiguration, qos_tier, qos_tier, 0),
PB_FIELD( 3, INT32 , OPTIONAL, STATIC , OTHER, gdt_cct_QosTierConfiguration, log_source, qos_tier, &gdt_cct_QosTierConfiguration_log_source_default),
PB_LAST_FIELD
};
const pb_field_t gdt_cct_QosTiersOverride_fields[3] = {
PB_FIELD( 1, MESSAGE , REPEATED, POINTER , FIRST, gdt_cct_QosTiersOverride, qos_tier_configuration, qos_tier_configuration, &gdt_cct_QosTierConfiguration_fields),
PB_FIELD( 2, INT64 , OPTIONAL, STATIC , OTHER, gdt_cct_QosTiersOverride, qos_tier_fingerprint, qos_tier_configuration, 0),
PB_LAST_FIELD
};
const pb_field_t gdt_cct_LogResponse_fields[3] = {
PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, gdt_cct_LogResponse, next_request_wait_millis, next_request_wait_millis, 0),
PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, gdt_cct_LogResponse, qos_tier, next_request_wait_millis, &gdt_cct_QosTiersOverride_fields),
PB_LAST_FIELD
};
/* Check that field information fits in pb_field_t */
#if !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_32BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
* field descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(gdt_cct_LogEvent, network_connection_info) < 65536 && pb_membersize(gdt_cct_ClientInfo, ios_client_info) < 65536 && pb_membersize(gdt_cct_LogRequest, client_info) < 65536 && pb_membersize(gdt_cct_LogResponse, qos_tier) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_gdt_cct_LogEvent_gdt_cct_NetworkConnectionInfo_gdt_cct_IosClientInfo_gdt_cct_ClientInfo_gdt_cct_BatchedLogRequest_gdt_cct_LogRequest_gdt_cct_QosTierConfiguration_gdt_cct_QosTiersOverride_gdt_cct_LogResponse)
#endif
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_16BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in the default
* 8 bit descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(gdt_cct_LogEvent, network_connection_info) < 256 && pb_membersize(gdt_cct_ClientInfo, ios_client_info) < 256 && pb_membersize(gdt_cct_LogRequest, client_info) < 256 && pb_membersize(gdt_cct_LogResponse, qos_tier) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_gdt_cct_LogEvent_gdt_cct_NetworkConnectionInfo_gdt_cct_IosClientInfo_gdt_cct_ClientInfo_gdt_cct_BatchedLogRequest_gdt_cct_LogRequest_gdt_cct_QosTierConfiguration_gdt_cct_QosTiersOverride_gdt_cct_LogResponse)
#endif
/* @@protoc_insertion_point(eof) */
@@ -0,0 +1,281 @@
/*
* Copyright 2019 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Automatically generated nanopb header */
/* Generated by nanopb-0.3.9.2 */
#ifndef PB_GDT_CCT_CCT_NANOPB_H_INCLUDED
#define PB_GDT_CCT_CCT_NANOPB_H_INCLUDED
#include <nanopb/pb.h>
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
/* Enum definitions */
typedef enum _gdt_cct_NetworkConnectionInfo_NetworkType {
gdt_cct_NetworkConnectionInfo_NetworkType_NONE = -1,
gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE = 0,
gdt_cct_NetworkConnectionInfo_NetworkType_WIFI = 1,
gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_MMS = 2,
gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_SUPL = 3,
gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_DUN = 4,
gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_HIPRI = 5,
gdt_cct_NetworkConnectionInfo_NetworkType_WIMAX = 6,
gdt_cct_NetworkConnectionInfo_NetworkType_BLUETOOTH = 7,
gdt_cct_NetworkConnectionInfo_NetworkType_DUMMY = 8,
gdt_cct_NetworkConnectionInfo_NetworkType_ETHERNET = 9,
gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_FOTA = 10,
gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_IMS = 11,
gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_CBS = 12,
gdt_cct_NetworkConnectionInfo_NetworkType_WIFI_P2P = 13,
gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_IA = 14,
gdt_cct_NetworkConnectionInfo_NetworkType_MOBILE_EMERGENCY = 15,
gdt_cct_NetworkConnectionInfo_NetworkType_PROXY = 16,
gdt_cct_NetworkConnectionInfo_NetworkType_VPN = 17
} gdt_cct_NetworkConnectionInfo_NetworkType;
#define _gdt_cct_NetworkConnectionInfo_NetworkType_MIN gdt_cct_NetworkConnectionInfo_NetworkType_NONE
#define _gdt_cct_NetworkConnectionInfo_NetworkType_MAX gdt_cct_NetworkConnectionInfo_NetworkType_VPN
#define _gdt_cct_NetworkConnectionInfo_NetworkType_ARRAYSIZE ((gdt_cct_NetworkConnectionInfo_NetworkType)(gdt_cct_NetworkConnectionInfo_NetworkType_VPN+1))
typedef enum _gdt_cct_NetworkConnectionInfo_MobileSubtype {
gdt_cct_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE = 0,
gdt_cct_NetworkConnectionInfo_MobileSubtype_GPRS = 1,
gdt_cct_NetworkConnectionInfo_MobileSubtype_EDGE = 2,
gdt_cct_NetworkConnectionInfo_MobileSubtype_UMTS = 3,
gdt_cct_NetworkConnectionInfo_MobileSubtype_CDMA = 4,
gdt_cct_NetworkConnectionInfo_MobileSubtype_EVDO_0 = 5,
gdt_cct_NetworkConnectionInfo_MobileSubtype_EVDO_A = 6,
gdt_cct_NetworkConnectionInfo_MobileSubtype_RTT = 7,
gdt_cct_NetworkConnectionInfo_MobileSubtype_HSDPA = 8,
gdt_cct_NetworkConnectionInfo_MobileSubtype_HSUPA = 9,
gdt_cct_NetworkConnectionInfo_MobileSubtype_HSPA = 10,
gdt_cct_NetworkConnectionInfo_MobileSubtype_IDEN = 11,
gdt_cct_NetworkConnectionInfo_MobileSubtype_EVDO_B = 12,
gdt_cct_NetworkConnectionInfo_MobileSubtype_LTE = 13,
gdt_cct_NetworkConnectionInfo_MobileSubtype_EHRPD = 14,
gdt_cct_NetworkConnectionInfo_MobileSubtype_HSPAP = 15,
gdt_cct_NetworkConnectionInfo_MobileSubtype_GSM = 16,
gdt_cct_NetworkConnectionInfo_MobileSubtype_TD_SCDMA = 17,
gdt_cct_NetworkConnectionInfo_MobileSubtype_IWLAN = 18,
gdt_cct_NetworkConnectionInfo_MobileSubtype_LTE_CA = 19,
gdt_cct_NetworkConnectionInfo_MobileSubtype_COMBINED = 100
} gdt_cct_NetworkConnectionInfo_MobileSubtype;
#define _gdt_cct_NetworkConnectionInfo_MobileSubtype_MIN gdt_cct_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE
#define _gdt_cct_NetworkConnectionInfo_MobileSubtype_MAX gdt_cct_NetworkConnectionInfo_MobileSubtype_COMBINED
#define _gdt_cct_NetworkConnectionInfo_MobileSubtype_ARRAYSIZE ((gdt_cct_NetworkConnectionInfo_MobileSubtype)(gdt_cct_NetworkConnectionInfo_MobileSubtype_COMBINED+1))
typedef enum _gdt_cct_ClientInfo_ClientType {
gdt_cct_ClientInfo_ClientType_CLIENT_UNKNOWN = 0,
gdt_cct_ClientInfo_ClientType_IOS_FIREBASE = 15
} gdt_cct_ClientInfo_ClientType;
#define _gdt_cct_ClientInfo_ClientType_MIN gdt_cct_ClientInfo_ClientType_CLIENT_UNKNOWN
#define _gdt_cct_ClientInfo_ClientType_MAX gdt_cct_ClientInfo_ClientType_IOS_FIREBASE
#define _gdt_cct_ClientInfo_ClientType_ARRAYSIZE ((gdt_cct_ClientInfo_ClientType)(gdt_cct_ClientInfo_ClientType_IOS_FIREBASE+1))
typedef enum _gdt_cct_QosTierConfiguration_QosTier {
gdt_cct_QosTierConfiguration_QosTier_DEFAULT = 0,
gdt_cct_QosTierConfiguration_QosTier_UNMETERED_ONLY = 1,
gdt_cct_QosTierConfiguration_QosTier_UNMETERED_OR_DAILY = 2,
gdt_cct_QosTierConfiguration_QosTier_FAST_IF_RADIO_AWAKE = 3,
gdt_cct_QosTierConfiguration_QosTier_NEVER = 4
} gdt_cct_QosTierConfiguration_QosTier;
#define _gdt_cct_QosTierConfiguration_QosTier_MIN gdt_cct_QosTierConfiguration_QosTier_DEFAULT
#define _gdt_cct_QosTierConfiguration_QosTier_MAX gdt_cct_QosTierConfiguration_QosTier_NEVER
#define _gdt_cct_QosTierConfiguration_QosTier_ARRAYSIZE ((gdt_cct_QosTierConfiguration_QosTier)(gdt_cct_QosTierConfiguration_QosTier_NEVER+1))
/* Struct definitions */
typedef struct _gdt_cct_BatchedLogRequest {
pb_size_t log_request_count;
struct _gdt_cct_LogRequest *log_request;
/* @@protoc_insertion_point(struct:gdt_cct_BatchedLogRequest) */
} gdt_cct_BatchedLogRequest;
typedef struct _gdt_cct_IosClientInfo {
pb_bytes_array_t *os_major_version;
pb_bytes_array_t *os_full_version;
pb_bytes_array_t *application_build;
pb_bytes_array_t *country;
pb_bytes_array_t *model;
pb_bytes_array_t *language_code;
pb_bytes_array_t *application_bundle_id;
/* @@protoc_insertion_point(struct:gdt_cct_IosClientInfo) */
} gdt_cct_IosClientInfo;
typedef struct _gdt_cct_ClientInfo {
bool has_client_type;
gdt_cct_ClientInfo_ClientType client_type;
bool has_ios_client_info;
gdt_cct_IosClientInfo ios_client_info;
/* @@protoc_insertion_point(struct:gdt_cct_ClientInfo) */
} gdt_cct_ClientInfo;
typedef struct _gdt_cct_NetworkConnectionInfo {
bool has_network_type;
gdt_cct_NetworkConnectionInfo_NetworkType network_type;
bool has_mobile_subtype;
gdt_cct_NetworkConnectionInfo_MobileSubtype mobile_subtype;
/* @@protoc_insertion_point(struct:gdt_cct_NetworkConnectionInfo) */
} gdt_cct_NetworkConnectionInfo;
typedef struct _gdt_cct_QosTierConfiguration {
bool has_qos_tier;
gdt_cct_QosTierConfiguration_QosTier qos_tier;
bool has_log_source;
int32_t log_source;
/* @@protoc_insertion_point(struct:gdt_cct_QosTierConfiguration) */
} gdt_cct_QosTierConfiguration;
typedef struct _gdt_cct_QosTiersOverride {
pb_size_t qos_tier_configuration_count;
struct _gdt_cct_QosTierConfiguration *qos_tier_configuration;
bool has_qos_tier_fingerprint;
int64_t qos_tier_fingerprint;
/* @@protoc_insertion_point(struct:gdt_cct_QosTiersOverride) */
} gdt_cct_QosTiersOverride;
typedef struct _gdt_cct_LogEvent {
bool has_event_time_ms;
int64_t event_time_ms;
pb_bytes_array_t *source_extension;
bool has_event_code;
int32_t event_code;
bool has_timezone_offset_seconds;
int64_t timezone_offset_seconds;
bool has_event_uptime_ms;
int64_t event_uptime_ms;
bool has_network_connection_info;
gdt_cct_NetworkConnectionInfo network_connection_info;
/* @@protoc_insertion_point(struct:gdt_cct_LogEvent) */
} gdt_cct_LogEvent;
typedef struct _gdt_cct_LogRequest {
bool has_client_info;
gdt_cct_ClientInfo client_info;
bool has_log_source;
int32_t log_source;
pb_size_t log_event_count;
struct _gdt_cct_LogEvent *log_event;
bool has_request_time_ms;
int64_t request_time_ms;
bool has_request_uptime_ms;
int64_t request_uptime_ms;
bool has_qos_tier;
gdt_cct_QosTierConfiguration_QosTier qos_tier;
/* @@protoc_insertion_point(struct:gdt_cct_LogRequest) */
} gdt_cct_LogRequest;
typedef struct _gdt_cct_LogResponse {
bool has_next_request_wait_millis;
int64_t next_request_wait_millis;
bool has_qos_tier;
gdt_cct_QosTiersOverride qos_tier;
/* @@protoc_insertion_point(struct:gdt_cct_LogResponse) */
} gdt_cct_LogResponse;
/* Default values for struct fields */
extern const gdt_cct_NetworkConnectionInfo_NetworkType gdt_cct_NetworkConnectionInfo_network_type_default;
extern const gdt_cct_NetworkConnectionInfo_MobileSubtype gdt_cct_NetworkConnectionInfo_mobile_subtype_default;
extern const gdt_cct_QosTierConfiguration_QosTier gdt_cct_LogRequest_qos_tier_default;
extern const int32_t gdt_cct_QosTierConfiguration_log_source_default;
/* Initializer values for message structs */
#define gdt_cct_LogEvent_init_default {false, 0, NULL, false, 0, false, 0, false, 0, false, gdt_cct_NetworkConnectionInfo_init_default}
#define gdt_cct_NetworkConnectionInfo_init_default {false, gdt_cct_NetworkConnectionInfo_NetworkType_NONE, false, gdt_cct_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE}
#define gdt_cct_IosClientInfo_init_default {NULL, NULL, NULL, NULL, NULL, NULL, NULL}
#define gdt_cct_ClientInfo_init_default {false, _gdt_cct_ClientInfo_ClientType_MIN, false, gdt_cct_IosClientInfo_init_default}
#define gdt_cct_BatchedLogRequest_init_default {0, NULL}
#define gdt_cct_LogRequest_init_default {false, gdt_cct_ClientInfo_init_default, false, 0, 0, NULL, false, 0, false, 0, false, gdt_cct_QosTierConfiguration_QosTier_DEFAULT}
#define gdt_cct_QosTierConfiguration_init_default {false, _gdt_cct_QosTierConfiguration_QosTier_MIN, false, 0}
#define gdt_cct_QosTiersOverride_init_default {0, NULL, false, 0}
#define gdt_cct_LogResponse_init_default {false, 0, false, gdt_cct_QosTiersOverride_init_default}
#define gdt_cct_LogEvent_init_zero {false, 0, NULL, false, 0, false, 0, false, 0, false, gdt_cct_NetworkConnectionInfo_init_zero}
#define gdt_cct_NetworkConnectionInfo_init_zero {false, _gdt_cct_NetworkConnectionInfo_NetworkType_MIN, false, _gdt_cct_NetworkConnectionInfo_MobileSubtype_MIN}
#define gdt_cct_IosClientInfo_init_zero {NULL, NULL, NULL, NULL, NULL, NULL, NULL}
#define gdt_cct_ClientInfo_init_zero {false, _gdt_cct_ClientInfo_ClientType_MIN, false, gdt_cct_IosClientInfo_init_zero}
#define gdt_cct_BatchedLogRequest_init_zero {0, NULL}
#define gdt_cct_LogRequest_init_zero {false, gdt_cct_ClientInfo_init_zero, false, 0, 0, NULL, false, 0, false, 0, false, _gdt_cct_QosTierConfiguration_QosTier_MIN}
#define gdt_cct_QosTierConfiguration_init_zero {false, _gdt_cct_QosTierConfiguration_QosTier_MIN, false, 0}
#define gdt_cct_QosTiersOverride_init_zero {0, NULL, false, 0}
#define gdt_cct_LogResponse_init_zero {false, 0, false, gdt_cct_QosTiersOverride_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define gdt_cct_BatchedLogRequest_log_request_tag 1
#define gdt_cct_IosClientInfo_os_major_version_tag 3
#define gdt_cct_IosClientInfo_os_full_version_tag 4
#define gdt_cct_IosClientInfo_application_build_tag 5
#define gdt_cct_IosClientInfo_country_tag 6
#define gdt_cct_IosClientInfo_model_tag 7
#define gdt_cct_IosClientInfo_language_code_tag 8
#define gdt_cct_IosClientInfo_application_bundle_id_tag 11
#define gdt_cct_ClientInfo_client_type_tag 1
#define gdt_cct_ClientInfo_ios_client_info_tag 4
#define gdt_cct_NetworkConnectionInfo_network_type_tag 1
#define gdt_cct_NetworkConnectionInfo_mobile_subtype_tag 2
#define gdt_cct_QosTierConfiguration_qos_tier_tag 2
#define gdt_cct_QosTierConfiguration_log_source_tag 3
#define gdt_cct_QosTiersOverride_qos_tier_configuration_tag 1
#define gdt_cct_QosTiersOverride_qos_tier_fingerprint_tag 2
#define gdt_cct_LogEvent_event_time_ms_tag 1
#define gdt_cct_LogEvent_event_code_tag 11
#define gdt_cct_LogEvent_event_uptime_ms_tag 17
#define gdt_cct_LogEvent_source_extension_tag 6
#define gdt_cct_LogEvent_timezone_offset_seconds_tag 15
#define gdt_cct_LogEvent_network_connection_info_tag 23
#define gdt_cct_LogRequest_request_time_ms_tag 4
#define gdt_cct_LogRequest_request_uptime_ms_tag 8
#define gdt_cct_LogRequest_client_info_tag 1
#define gdt_cct_LogRequest_log_source_tag 2
#define gdt_cct_LogRequest_log_event_tag 3
#define gdt_cct_LogRequest_qos_tier_tag 9
#define gdt_cct_LogResponse_next_request_wait_millis_tag 1
#define gdt_cct_LogResponse_qos_tier_tag 3
/* Struct field encoding specification for nanopb */
extern const pb_field_t gdt_cct_LogEvent_fields[7];
extern const pb_field_t gdt_cct_NetworkConnectionInfo_fields[3];
extern const pb_field_t gdt_cct_IosClientInfo_fields[8];
extern const pb_field_t gdt_cct_ClientInfo_fields[3];
extern const pb_field_t gdt_cct_BatchedLogRequest_fields[2];
extern const pb_field_t gdt_cct_LogRequest_fields[7];
extern const pb_field_t gdt_cct_QosTierConfiguration_fields[3];
extern const pb_field_t gdt_cct_QosTiersOverride_fields[3];
extern const pb_field_t gdt_cct_LogResponse_fields[3];
/* Maximum encoded size of messages (where known) */
/* gdt_cct_LogEvent_size depends on runtime parameters */
#define gdt_cct_NetworkConnectionInfo_size 13
/* gdt_cct_IosClientInfo_size depends on runtime parameters */
/* gdt_cct_ClientInfo_size depends on runtime parameters */
/* gdt_cct_BatchedLogRequest_size depends on runtime parameters */
/* gdt_cct_LogRequest_size depends on runtime parameters */
#define gdt_cct_QosTierConfiguration_size 13
/* gdt_cct_QosTiersOverride_size depends on runtime parameters */
/* gdt_cct_LogResponse_size depends on runtime parameters */
/* Message IDs (where set with "msgid" option) */
#ifdef PB_MSGID
#define CCT_MESSAGES \
#endif
/* @@protoc_insertion_point(eof) */
#endif