Skip to content

Commit

Permalink
Added tool iphone-apns.
Browse files Browse the repository at this point in the history
  • Loading branch information
Fredrik Eldh committed Oct 28, 2011
1 parent a8bbebe commit 3816459
Show file tree
Hide file tree
Showing 10 changed files with 534 additions and 19 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ config_platform.h
/tools/debugger/start.bat
/tools/debugger/filesystem

/tools/iphone-apns/Certs/

/runtimes/cpp/platforms/sdl/MoRE/filesystem/*
/runtimes/cpp/platforms/android/config_platform.h.saved
/runtimes/java/platforms/javaME/setdirs.bat
Expand Down
43 changes: 24 additions & 19 deletions rules/util.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Copyright (C) 2009 Mobile Sorcery AB
#
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License, version 2, as published by
# the Free Software Foundation.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to the Free
# Software Foundation, 59 Temple Place - Suite 330, Boston, MA
Expand Down Expand Up @@ -53,7 +53,7 @@ def ext(newEnd)
end end
return self[0, doti] + newEnd
end

def getExt
doti = rindex('.')
slashi = rindex('/')
Expand All @@ -63,12 +63,12 @@ def getExt
end
return nil
end

def noExt
doti = rindex('.')
return self[0, doti]
end

# Returns true if self begins with with.
def beginsWith(with)
return false if(self.length < with.length)
Expand All @@ -84,18 +84,23 @@ def endsWith(with)
def sh(cmd)
# Print the command to stdout.
puts cmd
# Open a process.
IO::popen(cmd) do |io|
# Pipe the process's output to our stdout.
while !io.eof?
line = io.gets
puts line
if(HOST == :win32)
success = system(cmd)
raise "Command failed" unless(success)
else
# Open a process.
IO::popen(cmd) do |io|
# Pipe the process's output to our stdout.
while !io.eof?
line = io.gets
puts line
end
# Check the return code
exitCode = Process::waitpid2(io.pid)[1].exitstatus
if(exitCode != 0) then
error "Command failed, code #{exitCode}"
end
if(exitCode != 0)
error "Command failed, code #{exitCode}"
end
end
end
end

Expand Down Expand Up @@ -144,12 +149,12 @@ def sed(script)
class EarlyTime
include Comparable
include Singleton

def <=>(other)
return 0 if(other.instance_of?(EarlyTime))
return -1
end

def to_s
"<EARLY TIME>"
end
Expand All @@ -161,12 +166,12 @@ def to_s
class LateTime
include Comparable
include Singleton

def <=>(other)
return 0 if(other.instance_of?(LateTime))
return 1
end

def to_s
"<LATE TIME>"
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ tlsf-license.txt covers the Two-level Segregate Fit (TLSF) allocator.
yasper-license.txt covers Yasper (Yet Another Smart Process EditoR).

Permission from Andreas J�nsson has kindly been given for the use of Angelcode BMFont and redistribution of its binary files.

iphone-apns was originally written by Oliver Pahl, who has given permission to use and modify the code:
http://blog.toshsoft.de/index.php?/archives/3-Sending-Apple-Push-Notifications-APN-in-C-Updated-Using-CA-Cert.html
141 changes: 141 additions & 0 deletions tools/iphone-apns/Helper/RemoteNotification.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#include "RemoteNotification.h"
#include <stdlib.h>

/* Used internally to send the payload */
int send_payload(const char *deviceTokenHex, const char *payloadBuff, size_t payloadLength);

/* Initialize the Payload with zero values */
void init_payload(Payload *payload)
{
memset(payload, 0, sizeof(Payload));
}

/* Function for sending the Payload */
int send_remote_notification(const char *deviceTokenHex, Payload *payload)
{
char messageBuff[MAXPAYLOAD_SIZE];
char tmpBuff[MAXPAYLOAD_SIZE];
char badgenumBuff[3];

strcpy(messageBuff, "{\"aps\":{");

if(payload->message != NULL)
{
strcat(messageBuff, "\"alert\":");
if(payload->actionKeyCaption != NULL)
{
sprintf(tmpBuff, "{\"body\":\"%s\",\"action-loc-key\":\"%s\"},", payload->message, payload->actionKeyCaption);
strcat(messageBuff, tmpBuff);
}
else
{
sprintf(tmpBuff, "{\"%s\"},", payload->message);
strcat(messageBuff, tmpBuff);
}
}

if(payload->badgeNumber > 99 || payload->badgeNumber < 0)
payload->badgeNumber = 1;

sprintf(badgenumBuff, "%d", payload->badgeNumber);
strcat(messageBuff, "\"badge\":");
strcat(messageBuff, badgenumBuff);

strcat(messageBuff, ",\"sound\":\"");
strcat(messageBuff, payload->soundName == NULL ? "default" : payload->soundName);
strcat(messageBuff, "\"}");

int i = 0;
while(payload->dictKey[i] != NULL && i < 5)
{
sprintf(tmpBuff, "\"%s\":\"%s\"", payload->dictKey[i], payload->dictValue[i]);
strcat(messageBuff, tmpBuff);
if(i < 4 && payload->dictKey[i + 1] != NULL)
{
strcat(messageBuff, ",");
}
i++;
}

strcat(messageBuff, "}");
printf("Sending %s\n", messageBuff);

return send_payload(deviceTokenHex, messageBuff, strlen(messageBuff));
}

int send_payload(const char *deviceTokenHex, const char *payloadBuff, size_t payloadLength)
{
int rtn = 0;

printf("ssl_connect\n");
SSL_Connection *sslcon = ssl_connect(APPLE_HOST, APPLE_PORT, RSA_CLIENT_CERT, RSA_CLIENT_KEY, CA_CERT_PATH);
if(sslcon == NULL)
{
printf("Could not allocate memory for SSL Connection");
exit(1);
}

printf("ssl_connect successful, sending message...\n");
if (sslcon && deviceTokenHex && payloadBuff && payloadLength)
{
uint8_t command = 0; /* command number */
char binaryMessageBuff[sizeof(uint8_t) + sizeof(uint16_t) + DEVICE_BINARY_SIZE + sizeof(uint16_t) + MAXPAYLOAD_SIZE];

/* message format is, |COMMAND|TOKENLEN|TOKEN|PAYLOADLEN|PAYLOAD| */
char *binaryMessagePt = binaryMessageBuff;
uint16_t networkOrderTokenLength = htons(DEVICE_BINARY_SIZE);
uint16_t networkOrderPayloadLength = htons(payloadLength);

/* command */
*binaryMessagePt++ = command;

/* token length network order */
memcpy(binaryMessagePt, &networkOrderTokenLength, sizeof(uint16_t));
binaryMessagePt += sizeof(uint16_t);

/* Convert the Device Token */
size_t i = 0;
int j = 0;
int tmpi;
char tmp[3];
char deviceTokenBinary[DEVICE_BINARY_SIZE];
while(i < strlen(deviceTokenHex))
{
if(deviceTokenHex[i] == ' ')
{
i++;
}
else
{
tmp[0] = deviceTokenHex[i];
tmp[1] = deviceTokenHex[i + 1];
tmp[2] = '\0';

sscanf(tmp, "%x", &tmpi);
deviceTokenBinary[j] = tmpi;

i += 2;
j++;
}
}

/* device token */
memcpy(binaryMessagePt, deviceTokenBinary, DEVICE_BINARY_SIZE);
binaryMessagePt += DEVICE_BINARY_SIZE;

/* payload length network order */
memcpy(binaryMessagePt, &networkOrderPayloadLength, sizeof(uint16_t));
binaryMessagePt += sizeof(uint16_t);

/* payload */
memcpy(binaryMessagePt, payloadBuff, payloadLength);
binaryMessagePt += payloadLength;
if (SSL_write(sslcon->ssl, binaryMessageBuff, (binaryMessagePt - binaryMessageBuff)) > 0)
rtn = 1;
}
printf("message sent %ssuccessfully\n", rtn ? "un" : "");

ssl_disconnect(sslcon);

return rtn;
}
60 changes: 60 additions & 0 deletions tools/iphone-apns/Helper/RemoteNotification.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef __REMOTE_NOTIFICATION_H
#define __REMOTE_NOTIFICATION_H

#include "SSLHelper.h"

#define CA_CERT_PATH "Certs"

#if defined(IS_DEVELOPMENT_VERSION)
/* Development Certificates */
#define RSA_CLIENT_CERT "Certs/apn-dev-cert.pem"
#define RSA_CLIENT_KEY "Certs/apn-dev-key.pem"

/* Development Connection Infos */
#define APPLE_HOST "gateway.sandbox.push.apple.com"
#define APPLE_PORT 2195

#define APPLE_FEEDBACK_HOST "feedback.sandbox.push.apple.com"
#define APPLE_FEEDBACK_PORT 2196
#else
/* Release Certificates */
#define RSA_CLIENT_CERT "Certs/apn-dis-cert.pem"
#define RSA_CLIENT_KEY "Certs/apn-dis-key.pem"

/* Release Connection Infos */
#define APPLE_HOST "gateway.push.apple.com"
#define APPLE_PORT 2195

#define APPLE_FEEDBACK_HOST "feedback.push.apple.com"
#define APPLE_FEEDBACK_PORT 2196
#endif

#define DEVICE_BINARY_SIZE 32
#define MAXPAYLOAD_SIZE 256


typedef struct {
/* The Message that is displayed to the user */
const char *message;

/* The name of the Sound which will be played back */
const char *soundName;

/* The Number which is plastered over the icon, 0 disables it */
int badgeNumber;

/* The Caption of the Action Key the user needs to press to launch the Application */
const char *actionKeyCaption;

/* Custom Message Dictionary, which is accessible from the Application */
const char* dictKey[5];
const char* dictValue[5];
} Payload;

/* Initialize the payload with zero values */
void init_payload(Payload *payload);

/* Send a Notification to a specified iPhone */
int send_remote_notification(const char *deviceTokenHex, Payload *payload);

#endif
Loading

0 comments on commit 3816459

Please sign in to comment.