Jul 312012
 

Third and final PHP script for Android GCM. This script is for device registration. After a device has registered itself for GCM, the registration id is sent to the third-party application server for storage.

Also see http://skipstechtalk.net/2012/07/20/my-google-cloud-messaging-gcm-php-script/
and
http://skipstechtalk.net/2012/07/31/my-php-script-for-storing-gcm-user-registration/

<?php
/*
saveRegId.php
 
Script for receiving GCM device registrations. The script 
  expects an HTTP GET with the following parameters:
&phone_name=my_friendly_phone_name. This is edited by the user in 
  the global settings.
&regid=my_gcm_registration_id. This is the registration id that the 
  phone receives when it calls the GCM registration intent
&device_id=my_device_id. Normally this is the IMEI number, but it can 
  be other numbers, depending on the phone and OS. It is easily
  hacked, so it isn't bulletproof. I just use it to try and prevent
  multiple device registrations.
&username=my_username. The same username used to register here
&password=my_password. The same password used to register here
$message_type=gcm or c2dm. All recent versions of PHCA send gcm
 
A working example of this is (all on one line)
https://phc-a.net/saveRegId.php?phone_name=Skips%20phone
  &regid=a1b2c3d4f51234567890abcdef
  &device_id=9ab8c7d6e5f1234567890abcdef
  &username=me
  &password=fluffypants
  &message_type=gcm
*/
$dbuser = 'mydbusername';
$dbname = 'phcadb';
$dbpasswd = 'mydbpassword';
$dbhost = 'my.dbhost.net';
 
$dbh = @mysql_connect($dbhost, $dbuser, $dbpasswd);
$verbose = "";
 
if (!$dbh) {
	echo "Could not connect to MySQL server on " . $dbhost;
	die();
} else {
	$verbose = mysql_real_escape_string($_REQUEST[verbose]);
}
 
if (!@mysql_select_db($dbname, $dbh)) {
	if ($verbose==true) echo "Could not connect to database " . $dbname;
	die();
}
 
 
// store the url, just for debugging purposes.
//$incomingurl = curPageURL();
//$sql = "INSERT INTO incomingsql (sqlx) VALUES ('$incomingurl')";
//$result = query($sql);
 
$salt = GetSalt();
$storedEncryptedPassword = GetStoredEncryptedPassword();
 
$encryptedPassword=hash('sha512', $salt.$_REQUEST[password]);
for($i=0; $i<5000; $i++){
   $encryptedPassword=hash('sha512', $salt.$encryptedPassword);
}
 
if ($storedEncryptedPassword == $encryptedPassword) {
	StoreRegistrationId($verbose);
}
else
{
	header('HTTP/1.0 401 Unauthorized', true, 401);
	die("Bad Username/Password");
}
 
 
function StoreRegistrationId($verbose) {
	$phone_name = mysql_real_escape_string($_REQUEST[phone_name]);
	$regid = mysql_real_escape_string($_REQUEST[regid]);
	$device_id = mysql_real_escape_string($_REQUEST[device_id]);
	$username = mysql_real_escape_string($_REQUEST[username]);
	$password= mysql_real_escape_string($_REQUEST[password]);
	$message_type = mysql_real_escape_string($_REQUEST[message_type]);
 
	// first check to see if we already have this device registered
	if ($verbose==true) echo "Checking if we have seen this device before<br />";
	$sql = "SELECT * FROM userdevices WHERE device_id='$_REQUEST[device_id]'";
	if ($verbose==true) echo "$sql <br />";
	$result = query($sql);
	if (mysql_num_rows($result) == 0) // it's a new device, so INSERT it
	{
		$sql = "INSERT INTO userdevices (
			registration_id, 
			device_id, 
			username, 
			is_sending, 
			message_type, 
			phone_name
			) VALUES (
			'$regid', 
			'$device_id', 
			'$username', 
			1, 
			'$message_type', 
			'$phone_name'
			)";
	}
	else
	{
		// we do have this phone registered already. Check to see if it is with the same user.
		// We don't want people signing up with multiple accounts.
		$row = mysql_fetch_array($result);
		if ($_REQUEST[username] == $row[username])
		{
			$sql = "UPDATE userdevices SET 
			registration_id='$regid', 
			is_sending=1, 
			message_type='$message_type', 
			phone_name='$phone_name' 
			WHERE username = '$username' AND device_id='$device_id'";
		}
		else
		{
			header('HTTP/1.0 550 Unauthorized', true, 550);
			die("This phone is already registered with username '" . $row[username] . "'");
		}
	}
 
	if ($verbose==true) echo "$sql <br />";
	$result = query($sql);
	if (!$result) {
		header('HTTP/1.0 500 Internal Server Error');
		die("Internal Error");
	} else {
		//header("Status: 200");
		//echo "OK<br />";
		// send a test message to the phone to be sure everything is working.
		$url = "https://phc-a.net/send.php?username=".$username."&password=".$password."&varname=".$device_id."&varvalue=".$device_id;
		if ($verbose==true) echo "Sending test message to GCM server. The url is $url<br />";
		$ch = curl_init($url);
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_TIMEOUT, '10');
		$data = curl_exec($ch);
		if(curl_errno($ch) && $verbose==true){
		    echo 'Curl error: ' . curl_error($ch);
		}
		if ($verose==true) print_r(curl_getinfo($ch));
		if ($verbose==true) echo "Execute complete. Here's the data: $data";
		curl_close($ch);
		//exit;
	}
}
 
function curPageURL() {
 $pageURL = 'http';
 if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
 $pageURL .= "://";
 if ($_SERVER["SERVER_PORT"] != "80") {
  $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
 } else {
  $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
 }
 return $pageURL;
}
 
 
function GetSalt() {
	$sql = "SELECT * FROM user WHERE username = '$_REQUEST[username]'";
	$result = query($sql);
	if (mysql_num_rows($result) == 0) // bad username
	{
		header('HTTP/1.0 401 Unauthorized');
		die("Bad Username/Password");
	}
	while ($row = mysql_fetch_assoc($result)) {
	    return $row["salt"];
	}
}
 
function GetStoredEncryptedPassword() {
	$sql = "SELECT * FROM user WHERE username = '$_REQUEST[username]'";
	$result = query($sql);
	if (mysql_num_rows($result) == 0) // bad username, should not happen here
	{
		header('HTTP/1.0 401 Unauthorized');
		die("Bad Username/Password");
	}
	while ($row = mysql_fetch_assoc($result)) {
	    return $row["passwordHash"];
	}
}
 
function query($query) {
if(!($result = mysql_query($query)))
	{
		die ( "MySQL Reports: " . mysql_error());
	}
return $result;
}
?>
 Posted by at 2:48 pm

  7 Responses to “My PHP Script for GCM Device Registration”

  1. [...] PHP script for to store device registration id’s is here: http://skipstechtalk.net/2012/07/31/my-php-script-for-gcm-device-registration/ <?php /* Third-party Application server for the PowerHome Connector for Android C2DM and GCM [...]

  2. Hi,

    I try to follow your tutos but I have a question.
    I would like to know how to get the regid ? Where the phone calls the GCM registration intent ?
    For the client application, I use the google demo app : http://developer.android.com/google/gcm/demo.html

    Thx.

  3. @lesanglier Yes, the registration id comes from the phone after it receives the GCM registration intent. The registration id is part of the response, and that is sent the the application server (this php code).

    I also used the demo app as a starting point.

    Good luck.

    Skip

Leave a Reply