Thursday, March 26, 2009

Sample Source Code : iPhone OS 3.0 peer to peer bluetooth connectivity

Just saw a sample source code from the apple dev forum to sharing the testing the p2p bluetooth

What you need to do is to create a new project from OpenGL ES Application of iPhone OS 3.0 SDK template called it BluetoothSample
and past the codes as below and test, it should work on 2 iPhone 3G and iPod Touch 2nd gen only.

Then you need to add GameKit framework to build and go

The source is from Travis True

BluetoothSampleAppDelegate.h Select all

// BluetoothSampleAppDelegate.h
// BluetoothSample

#import "EAGLView.h"
#import <GameKit/GameKit.h>

@interface BluetoothSampleAppDelegate : NSObject {
UIWindow *window;
EAGLView *glView;

GKPeerPickerController *picker;
GKSession *session;

int myNumber;
NSData *myData;
UILabel *textView;

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet EAGLView *glView;
@property (nonatomic, retain) GKPeerPickerController *picker;
@property (nonatomic, retain) GKSession *session;

- (void)mySendData;


BluetoothSampleAppDelegate.m Select all

// BluetoothSampleAppDelegate.m
// BluetoothSample

#import "BluetoothSampleAppDelegate.h"

@implementation BluetoothSampleAppDelegate

@synthesize picker;
@synthesize session;
@synthesize window;
@synthesize glView;

- (void)applicationDidFinishLaunching:(UIApplication *)application {

// setup the text view
myNumber = 0;
textView = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 10.0f, 640.0f, 12.0f)];
textView.text = [NSString stringWithFormat:@"myNumber: %i\n", myNumber];
[window addSubview:textView];
[window bringSubviewToFront:textView];

// start the EAGLView
glView.animationInterval = 1.0 / 60.0;
[glView startAnimation];

// allocate the NSData
myData = [[NSData alloc] initWithBytes:&myNumber length:sizeof(int)];

// allocate and setup the peer picker controller
picker = [[GKPeerPickerController alloc] init];
picker.delegate = self;
picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby | GKPeerPickerConnectionTypeOnline;
[picker show];

- (void)applicationWillResignActive:(UIApplication *)application {
glView.animationInterval = 1.0 / 5.0;

- (void)applicationDidBecomeActive:(UIApplication *)application {
glView.animationInterval = 1.0 / 60.0;

- (void)peerPickerController:(GKPeerPickerController *)picker didSelectConnectionType:(GKPeerPickerConnectionType)type {
if(type == GKPeerPickerConnectionTypeOnline) {
[self.picker dismiss];
[self.picker release];
self.picker = nil;
// Display your own UI here.

- (GKSession *) peerPickerController:(GKPeerPickerController *)picker
sessionForConnectionType:(GKPeerPickerConnectionType)type {
session = [[GKSession alloc] initWithSessionID:@"FR" displayName:nil sessionMode:GKSessionModePeer];
session.delegate = self;

return session;

- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state {
switch (state) {
case GKPeerStateConnected:
[self.session setDataReceiveHandler :self withContext:nil];
[self mySendData]; // start off by sending data upon connection

case GKPeerStateDisconnected:

- (void)peerPickerController:(GKPeerPickerController *)picker didConnectToPeer:(NSString *)peerID {
printf("connection was successful! start the game.\n");

- (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker {
printf("connection attempt was canceled\n");

- (void)mySendData {
// allocate the NSData
myData = [[NSData alloc] initWithBytes:&myNumber length:sizeof(int)];
[session sendDataToAllPeers :myData withDataMode:GKSendDataReliable error:nil];
printf("send data: %i\n", myNumber);
textView.text = [NSString stringWithFormat:@"myNumber: %i\n", myNumber];

- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context
// Read the bytes in data and perform an application-specific action, then free the NSData object
[data getBytes:&myNumber length:sizeof(int)];
printf("received data: %i from: %s\n", myNumber, [peer UTF8String]);
textView.text = [NSString stringWithFormat:@"myNumber: %i\n", myNumber];

[self mySendData];

- (void)dealloc
[picker release];
[session release];
[textView release];
[glView release];
[window release];
[super dealloc];


Monday, March 23, 2009

Apple Push Notification Service (APNS)

The Apple Push Notification Service will be launched in this summer and this is one of interesting features of iPhone OS 3.0.

Since the SSL certificate for the APNS for the developer's app is not yet available (update: available now on April 9) in the developer program portal, we need to simulate and test it in our environment at this moment. To prepare for this, we need a client program and a server program (for testing with the client) implementing the TLS communication protocol.

(1) Requirements
The requirement of communication with Apple Push Notification Service (APNS) is described in the "Apple Push Notification Service Programming Guide" and for the developer's view, we need to have a client program to communicate with and send the payload to the APNS

- a "raw" (binary) socket interface which is asynchronous and one-way from developer to APNS
- The binary interface is available through, port 2195
- use TLS (or SSL) to establish a secured communications channel
- The SSL certificate (will be provided from Apple per Application ID from developer portal) is required for these connections
- should present this certificate to APNS at connection time using peer-to-peer authentication.
- should also retain connections with APNS across multiple notifications.

(2) Payload
The maximum size allowed for a notification payload is 256 bytes;
Example of the notification payload

Command : 1 byte (0x00)
Device Token length : 2 bytes (0x00 0x20)
Device Token(binary) : 32 bytes
Payload length : 2 bytes
Payload Content (max 256 bytes): e.g.

"aps" : {
"alert" : {"loc-key":"%@ and %@ have invited you to Dinner","loc-args":["Jenna","Frank"]},
"badge" : 9
"sound" : "happysound.aiff"
"acme1" : "custom property",
"acme2" : 42,
"acme3" : [5,8]

The following example shows the payload message of
{"aps":{"alert":"Message from javacom","badge":9}}
in HexEdit Screen


(3) Pseudocode for this client side program (My iniitial draft for C Code)

Client code for TLS v1 protocol
Needs openssl crypto lib

At first
Initialisation of TLS Context and return SSL Context
SSL_CTX *ctx;
SSL *ssl;

SSL_CTX object is created as a framework to establish TLS/SSL enabled connections
use SSL_CTX_new to create a new context
SSL_CTX should include the tls stuff for SSL certificate handling
use SSL_CTX_set_client_cert_cb(ctx, client_cert_cb) to provide client SSL cert.

socket is created for the APNS
int sock;
struct sockaddr_in server;

connect socket
connect(sock, (struct sockaddr *)&server, sizeof(server))

Then associate the network connection with the object

create a new SSL structure for a connection

connect the SSL object with a socket file descriptor
SSL_set_app_data(ssl, conn);
SSL_set_fd(ssl, sock)

Set ssl to work in client mode (that is to connect)

Then the TLS/SSL handshake is performed
Connect SSL
If connect successful
Compose Payload
sendPayload using SSL_write (this part was given by Apple)

If connect unsuccessful, handle error

If Payload sent or reach maximum retries
Then Shut down the TLS/SSL connection.
Destroy SSL Context
SSL_CTX_free(ctx); ctx = NULL

(4) Other aspects (TO-DOs)
- Keep the definitive count of data items remaining to be downloaded.
- Regularly connect with the feedback web server and fetch the current list of those devices that have repeatedly reported failed-delivery attempts.
- iPhone client program

see update here

Friday, March 20, 2009

3G Tethering & MMS for iPhone OS 3.0 beta

Use this shell command to find out the ipcc file for your country
curl -s -L | grep -i carrier

Then follow these instructions below to amend the bundle contents

Instruction for 3G Tethering is here

Instruction for MMS is here

You can also change the carrier logo, if you modified the png files in the bundle