PHP Code for provisioning and rebooting Grandstreams

Based on the current examples with Bash scripts, Perl and LUA code on the site, I decided to contribute some PHP snippets which provide various functions:

Update: According to my research, the reboot and provisioning methods used for the GXP2120 and GXP2140 should also apply to the GXP2100 and GXP1200 phones.

Reboot for GXP2120 and GXP2140:



	$pass = "admin";
	// generate URLs
	$login_url = "http://" . $ip . "/cgi-bin/dologin";
	$reboot_url = "http://" . $ip . "/cgi-bin/api-sys_operation";

	// curl object
	$ch = curl_init();
		
	// set curl to use cookie file
	$ckfile = tempnam("/tmp", "CURLCOOKIE");
	curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile);
		
	//set the url, number of POST vars, POST data
	curl_setopt($ch, CURLOPT_URL, $login_url);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, "&password=" . $pass);
	curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
		
	// get 'sid' as a string
	$response = curl_exec($ch);
	preg_match('/sid" : "([A-z0-9]*)/', $response, $sid);
	$sid = $sid[1];
		
	// now that we have the sid, send the reboot command
	curl_setopt($ch, CURLOPT_URL, $reboot_url);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, "&request=REBOOT&sid=" . $sid);
	$response = curl_exec($ch);
	curl_close($ch);



Reboot for the GXP2000:



	$pass = "admin";
	// generate URLs
	$login_url = "http://" . $ip . "/dologin.htm";
	$reboot_url = "http://" . $ip . "/rs.htm";

	// curl object
	$ch = curl_init();
	
	// set curl to use cookie file
	$ckfile = tempnam("/tmp", "CURLCOOKIE");
	curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile);
	//set the URL, number of POST vars, POST data
	curl_setopt($ch, CURLOPT_URL, $login_url);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_HEADER, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, "P2=" . $pass . "&Login=Login&gnkey=0b82");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
	curl_setopt($ch, CURLOPT_REFERER, str_replace('dologin', 'login', $login_url));
	curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 ( .NET CLR 3.5.30729)");

	// get 'sid' cookie by logging in
	$response = curl_exec($ch);
	// now that we have the sid cookie, send the reboot command
	curl_setopt($ch, CURLOPT_URL, $reboot_url);
	curl_setopt($ch, CURLOPT_POST, false);
	curl_setopt($ch, CURLOPT_HEADER, 1);
	curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
	$response = curl_exec($ch);
	curl_close($ch);



Provisioning (plain XML) for GXP2120 and GXP2140:

-- This example assumes you have a database with tables named after the configuration parameters. If not, substitute the database part with reading a textfile of params instead or get creative...


	// clear any previous output
	ob_end_clean();

	// set headers for filetype
	header("Content-type: text/xml");
	header("Content-Disposition: \"inline; filename=cfg" . $mac . ".xml");
	// print XML header gxp21xx
	print "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n";
	print "<gs_provision version=\"1\">\r\n";
	print "\t<mac>" . $mac . "</mac>\r\n";
	print "\t<config version=\"1\">\r\n";

	$offset = 7;
	$total_column = ($sth->columnCount() -1);
	$data = $sth->fetch();

	for ($counter = $offset; $counter <= $total_column; $counter ++) {
		$meta = $sth->getColumnMeta($counter);
		// only print configured parameters
		if (strlen($data[$counter]) > 0) {
			$value = str_replace('\r', '', $data[$counter]);
			$value = str_replace('\n', '', $value);
			print "\t\t<" . $meta['name'] . ">" . $value . "</" . $meta['name'] . ">\r\n";
		}
	}
	
	// XML end tags
	print "\t</config>\r\n";
	print "</gs_provision>\r\n";




Provisioning GXP2000:

-- This example assumes you have a database with tables named after the configuration parameters. If not, substitute the database part with reading a textfile of params instead or get creative...


	// clear previous output
	ob_end_clean();
	// set headers for filetype
	header("Content-type: text/plain");
	header("Content-Disposition: \"inline; filename=cfg$mac");
	
	$h_crlf = '0d0a';
	$h_mac = $mac;
	$b_mac  = pack("H12", $h_mac);
	$b_crlf = pack("H4", $h_crlf);

	// huge string of parameters...
	$paramstring = "";

	// get data from db
	$total_column = ($sth->columnCount() -1);
	$data = $sth->fetch();
	for ($counter = 0; $counter <= $total_column; $counter ++) {
		$meta = $sth->getColumnMeta($counter);
		if ($data[$counter]) {
			$paramstring .= $meta['name'] . "=" . trim($data[$counter]) . "&";
		}
	}
	
	// sort of "URLencode" the string
	$paramstring = str_replace(' ','%20',$paramstring);
	$paramstring = str_replace('-','%2D',$paramstring); 
	$paramstring = str_replace('*','%2A',$paramstring); 
	$paramstring = str_replace(',','%2C',$paramstring); 
	$paramstring = str_replace(';','%3B',$paramstring); 

	$paramstring .= 'gnkey=0b82';

	// add an extra byte to make the body even (bytewise)
	if ((strlen($paramstring) % 2) != 0) {
		$paramstring .= "\0";
	}
	// add an extra word ( = two bytes) to make the body even (wordwise)
	if ((strlen($paramstring) % 4) != 0) {
		$paramstring .= "\0\0";
	}

	$d_length = 8 + (strlen($paramstring) / 2);
	
	$b_length = pack("N", $d_length);
	
	$d_checksum = array_sum(unpack("n2", $b_length));
	$d_checksum += array_sum(unpack("n*", $b_mac));
	$d_checksum %= pow(2,16);
	$d_checksum += (6676); // (3338 * 2)
	$d_checksum += array_sum(unpack("n*", $paramstring));
	$d_checksum %= pow(2,16);

	$d_checksum = (65536 - $d_checksum);
	
	$b_checksum = pack("n", $d_checksum);
	
	// output data
	print $b_length;
	print $b_checksum;
	print $b_mac;
	print $b_crlf;
	print $b_crlf;
	print $paramstring;


XML Phonebook (Applies to all models that support the feature):



	ob_end_clean();
	header("Content-type: text/xml");
	header("Content-Disposition: \"inline; filename=phonebook.xml");
	print "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n" .
			"<AddressBook>\r\n";
	foreach ($db->runQuery($query) as $row) {
		$fname = $row['fname'];
		$lname = $row['lname'];
		$pattern = array("'é'", "'è'", "'ë'", "'ê'", "'É'", "'È'", "'Ë'", "'Ê'", 
						"'á'", "'à'", "'ä'", "'â'", "'å'", "'Á'", "'À'", "'Ä'", "'Â'", "'Å'", 
						"'ó'", "'ò'", "'ö'", "'ô'", "'Ó'", "'Ò'", "'Ö'", "'Ô'", 
						"'í'", "'ì'", "'ï'", "'î'", "'Í'", "'Ì'", "'Ï'", "'Î'", 
						"'ú'", "'ù'", "'ü'", "'û'", "'Ú'", "'Ù'", "'Ü'", "'Û'", 
						"'ý'", "'ÿ'", "'Ý'", "'ø'", "'Ø'", "'œ'", "'Œ'", "'Æ'", "'ç'", "'Ç'");
		$replace = array('e', 'e', 'e', 'e', 'E', 'E', 'E', 'E', 
						'a', 'a', 'a', 'a', 'a', 'A', 'A', 'A', 'A', 'A', 
						'o', 'o', 'o', 'o', 'O', 'O', 'O', 'O', 
						'i', 'i', 'i', 'I', 'I', 'I', 'I', 'I', 
						'u', 'u', 'u', 'u', 'U', 'U', 'U', 'U', 
						'y', 'y', 'Y', 'o', 'O', 'a', 'A', 'A', 'c', 'C');
		$fname = preg_replace($pattern, $replace, $fname);
		$lname = preg_replace($pattern, $replace, $lname);
		print "\t  <Contact>\n" .
			  "\t   <LastName>" . $lname . "</LastName>\r\n" . 
			  "\t   <FirstName>" . $fname . "</FirstName>\r\n" . 
			  "\t   <Phone>\n" . 
			  "\t    <phonenumber>" . $row['pnumber'] . "</phonenumber>\r\n" . 
			  "\t    <accountindex>" . $row['accindex'] . "</accountindex>\r\n" . 
			  "\t   </Phone>\r\n" . 
			  "\t  </Contact>\r\n";
	}
	print "</AddressBook>\r\n";

Based on the current examples with Bash scripts, Perl and LUA code on the site, I decided to contribute some PHP snippets which provide various functions:

Update: According to my research, the reboot and provisioning methods used for the GXP2120 and GXP2140 should also apply to the GXP2100 and GXP1200 phones.

Reboot for GXP2120 and GXP2140:



	$pass = "admin";
	// generate URLs
	$login_url = "http://" . $ip . "/cgi-bin/dologin";
	$reboot_url = "http://" . $ip . "/cgi-bin/api-sys_operation";

	// curl object
	$ch = curl_init();
		
	// set curl to use cookie file
	$ckfile = tempnam("/tmp", "CURLCOOKIE");
	curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile);
		
	//set the url, number of POST vars, POST data
	curl_setopt($ch, CURLOPT_URL, $login_url);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, "&password=" . $pass);
	curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
		
	// get 'sid' as a string
	$response = curl_exec($ch);
	preg_match('/sid" : "([A-z0-9]*)/', $response, $sid);
	$sid = $sid[1];
		
	// now that we have the sid, send the reboot command
	curl_setopt($ch, CURLOPT_URL, $reboot_url);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, "&request=REBOOT&sid=" . $sid);
	$response = curl_exec($ch);
	curl_close($ch);



Reboot for the GXP2000:



	$pass = "admin";
	// generate URLs
	$login_url = "http://" . $ip . "/dologin.htm";
	$reboot_url = "http://" . $ip . "/rs.htm";

	// curl object
	$ch = curl_init();
	
	// set curl to use cookie file
	$ckfile = tempnam("/tmp", "CURLCOOKIE");
	curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile);
	//set the URL, number of POST vars, POST data
	curl_setopt($ch, CURLOPT_URL, $login_url);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_HEADER, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, "P2=" . $pass . "&Login=Login&gnkey=0b82");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
	curl_setopt($ch, CURLOPT_REFERER, str_replace('dologin', 'login', $login_url));
	curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 ( .NET CLR 3.5.30729)");

	// get 'sid' cookie by logging in
	$response = curl_exec($ch);
	// now that we have the sid cookie, send the reboot command
	curl_setopt($ch, CURLOPT_URL, $reboot_url);
	curl_setopt($ch, CURLOPT_POST, false);
	curl_setopt($ch, CURLOPT_HEADER, 1);
	curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
	$response = curl_exec($ch);
	curl_close($ch);



Provisioning (plain XML) for GXP2120 and GXP2140:

-- This example assumes you have a database with tables named after the configuration parameters. If not, substitute the database part with reading a textfile of params instead or get creative...


	// clear any previous output
	ob_end_clean();

	// set headers for filetype
	header("Content-type: text/xml");
	header("Content-Disposition: \"inline; filename=cfg" . $mac . ".xml");
	// print XML header gxp21xx
	print "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n";
	print "<gs_provision version=\"1\">\r\n";
	print "\t<mac>" . $mac . "</mac>\r\n";
	print "\t<config version=\"1\">\r\n";

	$offset = 7;
	$total_column = ($sth->columnCount() -1);
	$data = $sth->fetch();

	for ($counter = $offset; $counter <= $total_column; $counter ++) {
		$meta = $sth->getColumnMeta($counter);
		// only print configured parameters
		if (strlen($data[$counter]) > 0) {
			$value = str_replace('\r', '', $data[$counter]);
			$value = str_replace('\n', '', $value);
			print "\t\t<" . $meta['name'] . ">" . $value . "</" . $meta['name'] . ">\r\n";
		}
	}
	
	// XML end tags
	print "\t</config>\r\n";
	print "</gs_provision>\r\n";




Provisioning GXP2000:

-- This example assumes you have a database with tables named after the configuration parameters. If not, substitute the database part with reading a textfile of params instead or get creative...


	// clear previous output
	ob_end_clean();
	// set headers for filetype
	header("Content-type: text/plain");
	header("Content-Disposition: \"inline; filename=cfg$mac");
	
	$h_crlf = '0d0a';
	$h_mac = $mac;
	$b_mac  = pack("H12", $h_mac);
	$b_crlf = pack("H4", $h_crlf);

	// huge string of parameters...
	$paramstring = "";

	// get data from db
	$total_column = ($sth->columnCount() -1);
	$data = $sth->fetch();
	for ($counter = 0; $counter <= $total_column; $counter ++) {
		$meta = $sth->getColumnMeta($counter);
		if ($data[$counter]) {
			$paramstring .= $meta['name'] . "=" . trim($data[$counter]) . "&";
		}
	}
	
	// sort of "URLencode" the string
	$paramstring = str_replace(' ','%20',$paramstring);
	$paramstring = str_replace('-','%2D',$paramstring); 
	$paramstring = str_replace('*','%2A',$paramstring); 
	$paramstring = str_replace(',','%2C',$paramstring); 
	$paramstring = str_replace(';','%3B',$paramstring); 

	$paramstring .= 'gnkey=0b82';

	// add an extra byte to make the body even (bytewise)
	if ((strlen($paramstring) % 2) != 0) {
		$paramstring .= "\0";
	}
	// add an extra word ( = two bytes) to make the body even (wordwise)
	if ((strlen($paramstring) % 4) != 0) {
		$paramstring .= "\0\0";
	}

	$d_length = 8 + (strlen($paramstring) / 2);
	
	$b_length = pack("N", $d_length);
	
	$d_checksum = array_sum(unpack("n2", $b_length));
	$d_checksum += array_sum(unpack("n*", $b_mac));
	$d_checksum %= pow(2,16);
	$d_checksum += (6676); // (3338 * 2)
	$d_checksum += array_sum(unpack("n*", $paramstring));
	$d_checksum %= pow(2,16);

	$d_checksum = (65536 - $d_checksum);
	
	$b_checksum = pack("n", $d_checksum);
	
	// output data
	print $b_length;
	print $b_checksum;
	print $b_mac;
	print $b_crlf;
	print $b_crlf;
	print $paramstring;


XML Phonebook (Applies to all models that support the feature):



	ob_end_clean();
	header("Content-type: text/xml");
	header("Content-Disposition: \"inline; filename=phonebook.xml");
	print "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n" .
			"<AddressBook>\r\n";
	foreach ($db->runQuery($query) as $row) {
		$fname = $row['fname'];
		$lname = $row['lname'];
		$pattern = array("'é'", "'è'", "'ë'", "'ê'", "'É'", "'È'", "'Ë'", "'Ê'", 
						"'á'", "'à'", "'ä'", "'â'", "'å'", "'Á'", "'À'", "'Ä'", "'Â'", "'Å'", 
						"'ó'", "'ò'", "'ö'", "'ô'", "'Ó'", "'Ò'", "'Ö'", "'Ô'", 
						"'í'", "'ì'", "'ï'", "'î'", "'Í'", "'Ì'", "'Ï'", "'Î'", 
						"'ú'", "'ù'", "'ü'", "'û'", "'Ú'", "'Ù'", "'Ü'", "'Û'", 
						"'ý'", "'ÿ'", "'Ý'", "'ø'", "'Ø'", "'œ'", "'Œ'", "'Æ'", "'ç'", "'Ç'");
		$replace = array('e', 'e', 'e', 'e', 'E', 'E', 'E', 'E', 
						'a', 'a', 'a', 'a', 'a', 'A', 'A', 'A', 'A', 'A', 
						'o', 'o', 'o', 'o', 'O', 'O', 'O', 'O', 
						'i', 'i', 'i', 'I', 'I', 'I', 'I', 'I', 
						'u', 'u', 'u', 'u', 'U', 'U', 'U', 'U', 
						'y', 'y', 'Y', 'o', 'O', 'a', 'A', 'A', 'c', 'C');
		$fname = preg_replace($pattern, $replace, $fname);
		$lname = preg_replace($pattern, $replace, $lname);
		print "\t  <Contact>\n" .
			  "\t   <LastName>" . $lname . "</LastName>\r\n" . 
			  "\t   <FirstName>" . $fname . "</FirstName>\r\n" . 
			  "\t   <Phone>\n" . 
			  "\t    <phonenumber>" . $row['pnumber'] . "</phonenumber>\r\n" . 
			  "\t    <accountindex>" . $row['accindex'] . "</accountindex>\r\n" . 
			  "\t   </Phone>\r\n" . 
			  "\t  </Contact>\r\n";
	}
	print "</AddressBook>\r\n";

Created by: pellix, Last modification: Fri 24 of Oct, 2014 (09:38 UTC)
Please update this page with new information, just login and click on the "Edit" or "Discussion" tab. Get a free login here: Register Thanks! - Find us on Google+