Created
June 15, 2011 22:32
-
-
Save ku/1028292 to your computer and use it in GitHub Desktop.
Push Notification(Provider側)をC++で実装する
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Push Notification(Provider側)をObjective-Cで実装する - wirehead virtual machine http://d.hatena.ne.jp/wirehead/20091206 | |
// gcc apn.cpp -o apn -lssl -lcrypto -lstdc++ | |
// ./apn 62c844764111be8222715f26c00708b59143af0cc7d55910cc325caf0162994c 'hello' | |
// | |
#include <netdb.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <openssl/ssl.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <stdint.h> | |
#define appendBytes(p, n) \ | |
memcpy(apn_pointer, p, n); \ | |
apn_pointer += n; | |
int main(int ac, char* av[]) { | |
if (ac < 3) { | |
printf("usage: %s token message\n", av[0]); | |
return -1; | |
} | |
int apnsSocket; | |
struct hostent *apnsHost; | |
struct sockaddr_in apnsAddress; | |
const char dex0 = 0; | |
const char dex32 = 32; | |
// ソケットを用意して、接続する | |
apnsSocket = socket(AF_INET, SOCK_STREAM, 0); | |
int port = 2195; | |
#if 0 | |
const char* host = "gateway.push.apple.com"; | |
#else | |
const char* host = "localhost"; | |
#endif | |
apnsHost = gethostbyname(host); | |
bzero(&apnsAddress, sizeof(struct sockaddr_in)); | |
apnsAddress.sin_family = AF_INET; | |
apnsAddress.sin_port = htons(port); | |
bcopy(apnsHost->h_addr, &(apnsAddress.sin_addr), apnsHost->h_length); | |
int n = connect(apnsSocket, (struct sockaddr *)&apnsAddress, sizeof(struct sockaddr_in)); | |
if (n > 0) { | |
printf("x_X\n"); | |
return 0; | |
} | |
int r = -1; | |
// 送信するデータを作成し、NSMutableDataに詰めていく。 | |
// まずはヘッダ部分 | |
char apnbuffer[256]; | |
char *apn_pointer = apnbuffer; | |
unsigned char command = 1; | |
unsigned short tokenlength = htons(32); | |
memcpy(apn_pointer, &command, 1); | |
apn_pointer += 1; | |
unsigned int expires = htonl(time(NULL)+86400); | |
unsigned int identifier = htonl(0); | |
appendBytes(&identifier, 4); | |
appendBytes(&expires, 4); | |
appendBytes(&tokenlength, 2); // デバイストークンのバイト数 | |
// デバイストークンを16進表記の文字列からバイト列に変換 | |
const char* deviceToken = av[1]; | |
while (*deviceToken) { | |
unsigned char* c; | |
int n = sscanf(deviceToken, "%02x", &c); | |
if (n > 0) { | |
deviceToken += 2; | |
appendBytes(&c, 1); | |
} | |
} | |
char msg[256]; | |
sprintf(msg, "{\"aps\":{\"alert\":\"%s\",\"sound\":\"default\"}}", av[2]); | |
// ペイロードを追加 | |
int msglength = strlen(msg); | |
unsigned short apnsPayloadSize = htons(msglength); | |
appendBytes(&apnsPayloadSize, 2); // 同上 | |
appendBytes(msg, msglength); // ペイロード本体 | |
// APNSサーバへ送信する | |
n = apn_pointer - apnbuffer; | |
printf("write : %d", write(apnsSocket, apnbuffer, n)); | |
// 終了処理 | |
close(apnsSocket); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment