3.4. Migrating From the Mesh API to the Session API (PiaLocal)

This section describes the changes that are necessary when transitioning from using LocalNetwork with the mesh API to using LocalNetwork with the session API.

Compared to the need to manage both local network and the mesh (with the mesh API), the session API simplifies the implementation of session management and batch process error handling. Example code from the mesh API and session API is provided for each feature so that you can compare them.

Initialization

As with Mesh::Setting, use Session::Setting for initialization.

Code 3-7. Initializing the Mesh API
nn::pia::session::Mesh::Setting setting;

nn::pia::local::UdsNetworkFactory udsFactory;
setting.pNetworkFactory = &udsFactory;
setting.networkTopology = nn::pia::session::NetworkTopology_FullMesh;

nn::pia::session::Mesh::CreateInstance(setting);


Code 3-8. Initializing the Session API
nn::pia::session::Session::Setting setting;

nn::pia::local::UdsNetworkFactory udsFactory;
setting.pNetworkFactory = &udsFactory;
setting.networkTopology = nn::pia::session::NetworkTopology_FullMesh;

nn::pia::session::Session::CreateInstance(setting);

Startup and Cleanup of LocalNetwork

For the mesh API, the application must call the Startup() and Cleanup() functions for LocalNetwork. These functions are called automatically at session startup and cleanup for the session API, so the application need not call them.

Calling APIs for Tasks Like Creating LocalNetwork Networks

For the mesh API, the application needs to create, join, search for, and perform other processes related to the local network. Because the following network creation related APIs are called automatically when they are needed, the application does not need to call them with the session API.

  • CreateNetworkAsync()
  • ConnectNetworkAsync()
  • ScanNetworkAsync()
  • DisconnectNetworkAsync()
  • DestroyNetworkAsync()

Session Startup

Startup and cleanup for the Facade class of the network management modules such as local::LocalFacade are called automatically within the session API. You do not need to call them.

The signature is deselected by default. If it is selected, set the signature key when creating or joining a session.

You do not need to encrypt the signature key because it is encrypted in the SDK's UDS communications layer during local communications.

Code 3-9. Starting the Mesh API
nn::pia::session::Mesh::StartupSetting startupSetting;
startupSetting.bUsingHostMigration = true;
startupSetting.maxSilenceTime = nn::pia::session::NN_PIA_SESSION_MAX_SILENCE_TIME_DEFAULT;
startupSetting.keepAliveSendingInterval = nn::pia::session::NN_PIA_SESSION_KEEP_ALIVE_INTERVAL_DEFAULT;

// Get the player name for the player on the local station.
nn::pia::transport::Station::PlayerName playerName;
Session_GetLocalPlayerName(&playerName);
startupSetting.pPlayerName = &playerName;

// Encryption settings (none).
startupSetting.pCryptoSetting = NULL;

// Signature settings.
char signatureKeyData[] = "sample signature key";
nn::pia::common::SignatureSetting signatureSetting(
    nn::pia::common::SignatureSetting::MODE_HMAC_MD5,
    static_cast<const void*>(signatureKeyData),
    sizeof(signatureKeyData)
);
startupSetting.signatureSetting = signatureSetting;

// Configure station identification information (none).
startupSetting.pToken = NULL;

nn::pia::session::Mesh::GetInstance()->Startup(startupSetting);

 

Code 3-10. Starting the Session API
// Startup settings.
nn::pia::session::Session::StartupSetting startupSetting;
startupSetting.bUsingHostMigration = true; // Host migration setting.
startupSetting.maxSilenceTime = nn::pia::session::NN_PIA_SESSION_MAX_SILENCE_TIME_DEFAULT; // Maximum time without communication.
startupSetting.keepAliveSendingInterval = nn::pia::session::NN_PIA_SESSION_KEEP_ALIVE_INTERVAL_DEFAULT; // Interval for sending the keep-alive signal.

// Get the player name for the player on the local station.
nn::pia::transport::Station::PlayerName playerName;
Session_GetLocalPlayerName(&playerName);
startupSetting.pPlayerName = &playerName;

// Encryption settings (none).
startupSetting.cryptoMode = nn::pia::common::CryptoSetting::MODE_NOTHING;

// Configure identification information (none).
startupSetting.pToken = NULL;

nn::pia::session::Session::GetInstance()->Startup(startupSetting);

Creating a Session

When creating a session with the session API, you must pass an instance of a class that inherits from session::CreateSessionSetting and matches the type of network you are using.

For local communications, you would set it to an instance of the local::UdsCreateSessionSetting class.

For more information about how to configure each of the classes derived from session::CreateSessionSetting, see the API Reference.

Code samples for network creation and session creation when using the mesh API have been omitted. (For code samples, see 6.19.3. Directly Controlling Meshes for Local Communications and 6.19.1. Basic Mesh Network Features.)

Code 3-11. Creating a Session Using the Session API
nn::pia::local::UdsCreateSessionSetting createSessionSetting;
nn::pia::local::UdsCreateNetworkSetting createNetworkSetting;
{
    createNetworkSetting.m_SubId = SUB_ID;
    createNetworkSetting.m_MaxEntry = MAX_ENTRY;
    createNetworkSetting.m_LocalCommunicationId = nn::pia::local::LocalNetwork::GetInstance()->CreateLocalCommunicationId(TITLE_ID);
    memcpy(createNetworkSetting.m_Passphrase, const_cast<char*>(PASSPHRASE), sizeof(PASSPHRASE));
    createNetworkSetting.m_PassphraseLength = sizeof(PASSPHRASE);
}
createSessionSetting.SetLocalCreateNetworkSetting(createNetworkSetting);
result = createSessionSetting.SetSignatureKey(SIGNATURE_KEY_DATA, sizeof(SIGNATURE_KEY_DATA));
PIA_ASSERT(result.IsSuccess());
createSessionSetting.SetMaxParticipants(MAX_ENTRY);
 
// Start the session creation process.
result = nn::pia::session::Session::GetInstance()->CreateSessionAsync(createSessionSetting);
if (result.IsFailure())
{
    // Error handling to use when the creation process fails to start.
}

// Wait for the session creation process to end.
while (true)
{
    nn::pia::common::Scheduler::GetInstance()->Dispatch();

    if (nn::pia::session::Session::GetInstance()->IsCompletedCreateSession())
    {
        result = nn::pia::session::Session::GetInstance()->GetCreateSessionResult();
        if (result.IsFailure())
        {
            // Error handling to use when the creation process fails.
        }
        else
        {
            // Success.
        }
        break;
    }
}

Searching for Sessions

When using the session API, you must pass an instance of a class that inherits from session::SessionSearchCriteria and matches the type of network you are using.

For local communications, you would set it to an instance of the local::LocalSessionSearchCriteria class.

For more information about each of the classes derived from session::SessionSearchCriteria, see the API Reference.

A sample of code for network searches using the mesh API has been omitted. (For a code sample, see 6.19.3. Directly Controlling Meshes for Local Communications.)

Code 3-12. Searching for Sessions With the Session API
nn::pia::local::LocalSessionSearchCriteria criteria;
criteria.SetMaxParticipants(MAX_ENTRY);
criteria.SetSubId(SUB_ID);
criteria.SetLocalCommunicationId(nn::pia::local::LocalNetwork::GetInstance()->CreateLocalCommunicationId(TITLE_ID));
 
// Start the session search process.
result = nn::pia::session::Session::GetInstance()->BrowseSessionAsync(&criteria);
if (result.IsFailure())
{
    // Error handling to use when the search process fails to start.
}

// Wait for the search process to end.
while (true)
{
    nn::pia::common::Scheduler::GetInstance()->Dispatch();

    if (nn::pia::session::Session::GetInstance()->IsCompletedBrowseSession())
    {
        result = nn::pia::session::Session::GetInstance()->GetBrowseSessionResult();
        if (result.IsFailure())
        {
            // Error handling to use when the search process fails.
        }
        else
        {
            // List the sessions.
            nn::pia::session::ISessionInfoList* pSessionInfoList = nn::pia::session::Session::GetInstance()->GetBrowsedSessionInfoList();
            for (nn::pia::session::ISessionInfoList::Iterator it = pSessionInfoList->Begin(); it != pSessionInfoList->End(); ++it)
            {
                PIA_CACHED_PRINTF(
                    "Id=%08X [%02d/%02d] [%s]",
                    (*it)->GetSessionId(),
                    (*it )->GetCurrentParticipants(),
                    (*it)->GetMaxParticipants(),
                    (*it)->IsOpened() ? "Opened" : "Closed"
                );
            }
        }
        break;
    }
}

Joining a Session

When using the session API, you must pass an instance of a class that inherits from session::JoinSessionSetting and matches the type of network you are using.

For local communications, you would set it to an instance of the local::UdsJoinSessionSetting class.

For more information about how to configure each of the classes derived from session::JoinSessionSetting, see the API Reference.

Code samples for network connection and session joining when using the mesh API have been omitted. (For code samples, see 6.19.3. Directly Controlling Meshes for Local Communications and 6.19.1. Basic Mesh Network Features.)

Code 3-13. Joining a Session With the Session API
// Get the session information of the session to join from the session search result list.
nn::pia::session::ISessionInfo* pTargetSessionInfo = *it;
// Add the session information to the session join settings.
nn::pia::local::UdsJoinSessionSetting joinSessionSetting;
sessionJoinSessionSetting.SetSessionInfoPtr(pTargetSessionInfo);
result = joinSessionSetting.SetPassphrase(const_cast<char*>(PASSPHRASE), sizeof(PASSPHRASE));
PIA_ASSERT(result.IsSuccess());
result = joinSessionSetting.SetSignatureKey(SIGNATURE_KEY_DATA, sizeof(SIGNATURE_KEY_DATA));
PIA_ASSERT(result.IsSuccess());
// Start the session join process.
result = nn::pia::session::Session::GetInstance()->JoinSessionAsync(&joinSessionSetting);
if (result.IsFailure())
{
    // Error handling to use when the join process fails to start.
}

// Wait for the session join process to complete.
while (true)
{
    nn::pia::common::Scheduler::GetInstance()->Dispatch();

    if (nn::pia::session::Session::GetInstance()->IsCompletedJoinSession())
    {
        result = nn::pia::session::Session::GetInstance()->GetJoinSessionResult();
        if (result.IsFailure())
        {
            // Error handling to use when the join process fails.
        }
        else
        {
            // Success.
        }
        break;
    }
}

Leaving and Destroying Sessions

When using the mesh API, the application needs to determine whether a station can leave the session and whether to destroy the session based on whether that station is the host and whether the host migration feature is enabled. In the session API, the session is automatically destroyed if necessary after the stations leave the session. The application does not need to determine anything. In addition, the LocalNetwork functions DisconnectNetworkAsync() and DestroyNetworkAsync() are automatically called.

Code samples for leaving and destroying sessions and also disconnecting from and destroying networks when using the mesh API have been omitted. (For code samples, see 6.19.3. Directly Controlling Meshes for Local Communications and 6.19.1. Basic Mesh Network Features.)

Code 3-14. Leaving a Session With the Session API
// Start the leave session process.
nn::Result result = nn::pia::session::Session::GetInstance()->LeaveSessionAsync();
if (result.IsFailure())
{
    // Error handling to use when the leave session process fails to start.
}
 
// Wait for the leave process to end.
while (true)
{
    nn::pia::common::Scheduler::GetInstance()->Dispatch();

    if (nn::pia::session::Session::GetInstance()->IsCompletedLeaveSession())
    {
        result = nn::pia::session::Session::GetInstance()->GetLeaveSessionResult();
        if (result.IsFailure())
        {
            // Error handling to use when the leave process fails.
        }
        else
        {
            // Success.
        }
        break;
    }
}

Checking the Network Connection Status

The session API provides a dedicated function for checking the network connection status. This function returns an nn::Result object.

If the station has been disconnected from the mesh, the function returns ResultSessionConnectionIsLost. When this happens, perform a cleanup after calling LeaveSessionAsync.

When disconnected from the network, ResultNetworkConnectionIsLost is returned. When this happens, perform a cleanup.

Code 3-15. Getting the Network Connection Status With the Mesh API
if (! LocalNetwork::IsConnected() && ! LocalNetwork::IsDuringHostMigration())
{
    // Disconnected from the network. Clean up the session and LocalNetwork.
}
 
nn::Result result = nn::pia::transport::Transport::GetInstance()->CheckConnectionError();
if (result.IsFailure())
{
    if (result == nn::pia::ResultNetworkConnectionIsLost())
    {
        // Disconnected from the network. Clean up the session and LocalNetwork.
    }
    else
    {
        // Unexpected state.
    }
}

if (nn::pia::session::Mesh::GetInstance()->CheckConnectionError() == nn::pia::ResultMeshConnectionIsLost())
{
    // Disconnected. Clean up the session.
}
Code 3-16. Getting the Network Connection Status With the Session API
nn::Result result = nn::pia::session::Session::GetInstance()->CheckConnectionError();
if (result.IsFailure())
{
    if (result == nn::pia::ResultSessionConnectionIsLost())
    {
        // Disconnected from the mesh. Perform a cleanup after calling LeaveSessionAsync.
    }
    else if (result == nn::pia::ResultNetworkConnectionIsLost())
    {
        // Disconnected from the network. Perform a cleanup.
    }
}