Skip to content

Commit

Permalink
Got the Feedback service working for APNS
Browse files Browse the repository at this point in the history
  • Loading branch information
Erica Sadun authored and Erica Sadun committed Aug 7, 2009
1 parent 01b2d12 commit b7259c6
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 21 deletions.
2 changes: 1 addition & 1 deletion C15-Media/01-Play Audio/ModalMenu.m
Expand Up @@ -57,7 +57,7 @@ +(NSUInteger) menuWithTitle: (NSString *) title view: (UIView *) aView andButto
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title delegate:madelegate cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];

// Set max number of items
int fewerthan = isLandscape() ? 5 : 8;
int fewerthan = isLandscape() ? 8 : 8; // hard coding for this example. This is not a general use case for this class
int count = 1;
for (NSString *title in buttons)
if (count++ < fewerthan) [actionSheet addButtonWithTitle:title];
Expand Down
2 changes: 2 additions & 0 deletions C16-Push/01-PushClient/HelloWorld.xcodeproj/project.pbxproj
Expand Up @@ -165,13 +165,15 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Erica Sadun";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = HelloWorld_Prefix.pch;
INFOPLIST_FILE = "HelloWorld-Info.plist";
PRODUCT_NAME = HelloWorld;
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "A3F26AFC-7F4C-44C6-B7D7-F54FE50F1AFB";
};
name = Debug;
};
Expand Down
2 changes: 1 addition & 1 deletion C16-Push/02-PushUtil/APNSHelper.h
Expand Up @@ -16,5 +16,5 @@

+ (APNSHelper *) sharedInstance;
- (BOOL) push: (NSString *) payload;
- (NSData *) fetchFeedback;
- (NSArray *) fetchFeedback;
@end
49 changes: 39 additions & 10 deletions C16-Push/02-PushUtil/APNSHelper.m
Expand Up @@ -140,7 +140,6 @@ - (BOOL) push: (NSString *) payload
// Perform SSL handshake.
do {result = SSLHandshake(context);} while(result == errSSLWouldBlock);


// Convert string into device token data.
NSMutableData *deviceToken = [NSMutableData data];
unsigned value;
Expand Down Expand Up @@ -190,16 +189,15 @@ - (BOOL) push: (NSString *) payload
}
}

// This is just a guess about how this will work. Not live, can't test.
- (NSData *) fetchFeedback
- (NSArray *) fetchFeedback
{
otSocket socket;
SSLContextRef context;
SecKeychainRef keychain;
SecIdentityRef identity;
SecCertificateRef certificate;
OSStatus result;

// Ensure device token
if (!self.deviceTokenID)
{
Expand Down Expand Up @@ -284,6 +282,14 @@ - (NSData *) fetchFeedback
printf("Error creating identity from certificate\n");
return NO;
}

// Attempt to Disable Verify
result = SSLSetEnableCertVerify(context, NO);
if (result)
{
printf("Error disabling cert verify\n");
return NO;
}

// Set client certificate.
CFArrayRef certificates = CFArrayCreate(NULL, (const void **)&identity, 1, NULL);
Expand All @@ -294,23 +300,46 @@ - (NSData *) fetchFeedback
CFRelease(certificates);
return NO;
}

CFRelease(certificates);

// Perform SSL handshake.
do {result = SSLHandshake(context);} while(result == errSSLWouldBlock);

if (result)
{
cssmPerror("Error", result);
return NO;
}

NSMutableArray *results = [NSMutableArray array];

// 4 big endian bytes for time_t
// 2 big endian bytes for token length (always 0, 32)
// 32 bytes for device token

// Retrieve message from SSL.
size_t processed = 0;
char buffer[38];
NSMutableData *mdata = [NSMutableData data];
do
{
(SSLRead(context, buffer, 38, &processed));
[mdata appendBytes:buffer length:processed];
result = SSLRead(context, buffer, 38, &processed);
if (result) break;

// Recover Date
char *b = buffer;
NSTimeInterval ti = ((unsigned char)b[0] << 24) + ((unsigned char)b[1] << 16) + ((unsigned char)b[2] << 8) + (unsigned char)b[3];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:ti];

// Recover Device ID
NSMutableString *deviceID = [NSMutableString string];
b += 6;
for (int i = 0; i < 32; i++) [deviceID appendFormat:@"%02x", (unsigned char)b[i]];

// Add dictionary to results
[results addObject:[NSDictionary dictionaryWithObject:date forKey:deviceID]];

} while (processed > 0);

return mdata;
return results;
}

- (void) dealloc
Expand Down
1 change: 1 addition & 0 deletions C16-Push/02-PushUtil/doit
@@ -0,0 +1 @@
cp build/Debug/pushutil .
Binary file added C16-Push/02-PushUtil/pushutil
Binary file not shown.
43 changes: 34 additions & 9 deletions C16-Push/02-PushUtil/pushutil.m
Expand Up @@ -364,19 +364,44 @@ int main (int argc, const char * argv[]) {
exit(-1);
}

printf("Preparing to retrieve feedback\n");

[APNSHelper sharedInstance].deviceTokenID = dToken;
[APNSHelper sharedInstance].certificateData = dCert;
NSData *feedbackData = [[APNSHelper sharedInstance] fetchFeedback];
printf("Retrieved %d bytes\n", feedbackData.length);
if (feedbackData.length > 0)
NSArray *resultsArray = [[APNSHelper sharedInstance] fetchFeedback];

if (resultsArray.count == 0)
{
NSString *results = [[NSString alloc] initWithData:feedbackData encoding:NSUTF8StringEncoding];
CFShow(results);
[results release];
printf("No feedback results at this time.\n");
}
exit(1);
else
{

NSString *path = [workingDir() stringByAppendingPathComponent:@"feedback.txt"];
FILE *fp;
if ((fp = fopen([path UTF8String], "a")) == NULL)
{
printf("Cannot open feedback.txt for output\n");
exit(-1);
}

printf("APNS has encountered the following delivery failures:\n\n");
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = @"MM/dd/YY h:mm:ss a";

for (NSDictionary *dict in resultsArray)
{
NSString *deviceid = [[dict allKeys] lastObject];
NSDate *date = [dict objectForKey:deviceid];
NSString *timestamp = [formatter stringFromDate:date];
fprintf(fp, "%s %s\n", [timestamp UTF8String], [deviceid UTF8String]);
printf("TIMESTAMP: %s\n", [timestamp UTF8String]);
printf("DEVICE ID: %s\n\n", [deviceid UTF8String]);
}

fclose(fp);
printf("Wrote %d events to feedback.txt\n", resultsArray.count);
}

exit(1); // successful exit
}

if ([darg caseInsensitiveCompare:@"-undoc"] == NSOrderedSame) // undocumented
Expand Down

0 comments on commit b7259c6

Please sign in to comment.