This document contains programming tutorials for the Google AdSense for Audio API. Before you use these tutorials, we recommend that you read the Getting Started Guide to be sure that you have the proper resources and credentials to implement and test the AdSense for Audio API. We also recommend that you read the Developer's Guide to be sure that you understand the technical and business requirements for implementing the AdSense for Audio API.
This tutorial describes how to implement a BroadcasterService operation in C++ by using the gSOAP tools and the OpenSSL toolkit. The gSOAP web services development toolkit includes an open source library that binds Simple Object Access Protocol (SOAP) messages to C++ member functions, which makes it easier for you to create web service clients in C++. The OpenSSL toolkit is an open source cryptography toolkit that helps you implement Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols.
Note: This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/).
In order to get started you will need the following:
We've prepared packages of the gSOAP libraries, executables, and header files for use with this tutorial. If you have already installed gSOAP on your system, be sure that you are using version 2.7.10 or later. The installation packages come in two flavors: one for the Linux® operating system and one for the Windows® operating system with Microsoft® Visual C++® version 8 (Visual Studio® 2005 or later). You can download the packages from the following locations:
After you download the appropriate package, extract the contents to a folder on your hard drive. Each package contains a bin folder (for gSOAP binaries), an import folder (for soapcpp2.exe header files), an include folder (for gSOAP header files), and a lib folder (for gSOAP libraries). You must configure your development environment so that the lib folder is in the library (linker) path and the include folder is in the preprocessor includes path.
We've prepared packages of the OpenSSL toolkit for use with this tutorial. If you have already installed OpenSSL on your system, be sure that you are using version 0.9.8f or later. The installation packages come in two flavors: one for the Linux operating system and one for the Windows operating system with Microsoft Visual C++ version 8 (Visual Studio 2005 or later). You can download the packages from the following locations:
After you download the appropriate package, extract the contents to a folder on your hard drive. Each package contains a bin folder (for OpenSSL binaries), an include folder (for OpenSSL header files), and a lib folder (for OpenSSL libraries). You must configure your development environment so that the lib folder is in the library (linker) path and the include folder is in the preprocessor includes path.
You can access the WSDL file at https://www.google.com/api/afa/v2/BroadcasterService?wsdl. You must use version 2 of the BroadcasterService WSDL file.
First, generate the client-side C++ SOAP stubs by using the following commands (where soapdir is your gSOAP installation folder and BroadcasterServiceV2.wsdl is the AdSense for Audio WSDL file):
soapdir\bin\wsdl2h -o BroadcasterServiceV2.h BroadcasterServiceV2.wsdl
soapdir\bin\soapcpp2 -1 -C -I soapdir\import -i BroadcasterServiceV2.h
This will generate the following files:
Next, you must a correct a problem with the soapC.cpp file that you generated. Open the file, find the function soap_out_SOAP_ENV__Header(), which is near line 9141, and change the following statement:
soap->mustUnderstand = 1;
To this:
soap->mustUnderstand = 0;
Now that you've generated the C++ SOAP stubs, you can create a C++ client program. Your client code needs three pieces of information in order to properly initialize a C++ SOAP stub:
The following code fragment illustrates the initialization sequence:
/** This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "soapBroadcasterServiceV2HttpBindingProxy.h"
#include "BroadcasterServiceV2HttpBinding.nsmap"
#include <stdio.h>
/** Create and return a proxy to the SOAP web service.
*
* Parameters:
*
* url - the URL to the web service
* log_dir - path to directory for log files
* pem_file - path to SSL certificate file
* connect_timeout - TCP connect timeout, in seconds
* io_timeout - TCP send/receive timeout, in seconds
*/
BroadcasterServiceV2HttpBindingProxy *create_proxy(const char *url,
const char *log_dir,
const char *pem_file,
unsigned int connect_timeout,
unsigned int io_timeout)
{
// Initialize the SOAP proxy.
BroadcasterServiceV2HttpBindingProxy *proxy = new BroadcasterServiceV2HttpBindingProxy();
soap_init(proxy);
proxy->soap_endpoint = url;
proxy->recv_timeout = proxy->send_timeout = io_timeout;
proxy->connect_timeout = connect_timeout;
proxy->mustUnderstand = 0;
// Set up SOAP logging.
if(logdir != NULL)
{
// Enable SOAP logging.
// You must add the SOAP_DEBUG symbol as a preprocessor directive to enable logging.
char *buf = (char *)malloc(strlen(log_dir) + 10);
sprintf(buf, "%s/RECV.log", log_dir);
soap_set_recv_logfile(proxy, buf);
sprintf(buf, "%s/SEND.log", logdir);
soap_set_sent_logfile(proxy, buf);
sprintf(buf, "%s/TEST.log", logdir);
soap_set_test_logfile(proxy, buf);
free(buf);
}
else
{
// Disable SOAP logging.
soap_set_recv_logfile(proxy, NULL);
soap_set_sent_logfile(proxy, NULL);
soap_set_test_logfile(proxy, NULL);
}
// Initialize SSL context.
soap_ssl_client_context(proxy,
SOAP_SSL_DEFAULT | SOAP_SSL_SKIP_HOST_CHECK,
NULL,
NULL,
cert_file,
NULL,
NULL);
return(proxy);
}
The corresponding teardown function is:
void destroy_proxy(BroadcasterServiceV2HttpBindingProxy *proxy)
{
soap_end(proxy);
soap_done(proxy);
delete proxy;
}
The C++ class BroadcasterServiceV2HttpBindingProxy, which is declared in the header file soapBroadcasterServiceV2HttpBindingProxy.h, has member functions that correspond to each of the web service operations defined in the AdSense for Audio WSDL file. Each of these member functions accepts two parameters—a request structure and a response structure—and returns an integer status code.
The generated SOAP stub code defines the C++ objects that represent each of these request and response structures. To make a SOAP call, construct the appropriate request and response objects and pass them to one of the member functions. The generated SOAP stub code has a built-in reference-counting mechanism that allows the request and response objects to be cleaned up automatically when they are no longer needed. To make use of this facility, you must create the request and response objects (and any member objects thereof), by using the functions provided for that purpose, which are declared in the generated header soapH.h.
The following example illustrates these concepts with a simple call to the publishAvails operation to publish a single spot. In this example, auth_token is the Google-assigned authentication token that you were issued when you registered as an AdSense for Audio development partner.
/** This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
int publish_avails(BroadcasterServiceV2HttpBindingProxy *proxy,
const char *auth_token,
time_t avails_time,
int partner_station_id,
const char *cart_id,
time_t date_time,
int duration,
const char *industry_code,
int64_t partner_spot_id,
const char *title)
{
// Set authentication token in SOAP header.
proxy->soap_header(auth_token);
// Build request object.
_ns1__publishAvails *request = soap_new__ns1__publishAvails(proxy, -1);
request->avails = soap_new_ns1__ArrayOfAvailList(proxy, -1);
ns1__AvailList *list = soap_new_ns1__AvailList(proxy, -1);
request->avails->AvailList.push_back(list);
list->availsDate = avails_time;
list->partnerStationId = partner_station_id;
list->spots = soap_new_ns1__ArrayOfSpot(proxy, -1);
// Add one spot to the spot array.
ns1__Spot *spot = soap_new_ns1__Spot(proxy, -1);
spot->cart_id = cart_id;
spot->dateTime = date_time;
spot->duration = duration;
spot->industry_code = industry_code;
spot->partnerSpotId = partner_spot_id;
spot->title = title;
// Build response object.
_ns1__publishAvailsResponse *response = soap_new__ns1__publishAvailsResponse(
proxy, -1);
// Make the SOAP call.
int r = proxy->publishAvails(request, response);
// Check for failure.
if(r != SOAP_OK)
{
#ifdef DEBUG
soap_print_fault(proxy, stderr);
soap_print_fault_location(proxy, stderr);
#endif
// Deallocate the objects for this RPC.
soap_destroy(proxy);
return(r);
}
// Decode the claim status.
ns1__AvailClaimStatus *cstatus = response->out;
switch(cstatus->status) {
case ns1__AvailStatus__SUCCESS:
std::cout << "Success." << std::endl;
break;
case ns1__AvailStatus__SUBMITTED:
std::cout << "Request submitted for asynchronous processing." << std::endl;
break;
case ns1__AvailStatus__FAILED:
std::cout << "Request failed." << std::endl;
break;
}
std::cout << "status message: " << cstatus->statusMessage << std::endl;
// Decode the individual avail claims.
ns1__ArrayOfStationAvailClaimStatus *statuses
= cstatus->stationAvailClaimStatuses;
size_t count = statuses->StationAvailClaimStatus.size();
if(count == 1)
{
ns1__StationAvailClaimStatus *status
= statuses->StationAvailClaimStatus[0];
ns1__ArrayOfAvailClaim *claims = status->availClaims;
result->num_statuses = claims->AvailClaim.size();
size_t i = 0;
// Iterate over the claims, printing out the status of each one.
for(std::vector::iterator iter
= claims->AvailClaim.begin();
iter != claims->AvailClaim.end();
++iter, ++i)
{
std::cout << "claim #" << (++i) << std::endl;
ns1__AvailClaim *claim = *iter;
std::cout << "partner spot ID: " << claim->partnerSpotId << std::endl;
std::cout << "claim status: " << claim->claimStatusMessage << std::endl;
}
// Destroy all request and response objects.
soap_destroy(proxy);
return(0);
}
Compilation procedures vary by platform and compiler, so only a general compilation procedure is outlined here.
To build the C++ client, compile the client source files along with the generated source files. You will need to add the include directories of both the gSOAP package and the OpenSSL package to the preprocessor include path. You will also need to define the SOAP_DEBUG symbol as a preprocessor directive if you want to enable SOAP logging. You can do this in Visual Studio by adding SOAP_DEBUG to the list of symbols that are in the Preprocessor Definitions section of the Preprocessor property page for your project.
Link the resulting object files with the gSoap library. On the Linux operating system, this is libgsoapssl++.a. On the Microsoft Windows operating system, it is libgsoapssl++.lib for a release build or libgsoapssl++_d.lib for a debug build.
Doing this produces a standalone executable whose only external dependencies are the C/C++ runtime and the OpenSSL shared libraries (libssl.so and libcrypto.so on the Linux operating system, or libeay32.dll and ssleay32.dll on the Microsoft Windows operating system).