4. Background Communication

The following library allows your application to automatically carry out wireless communication (background communication) in the background.

  • StreetPass (CEC)
  • SpotPass (BOSS)
  • Presence feature (FRIENDS)

This chapter explains programming procedures and other information necessary to develop applications using each of these libraries.

Effect on Applications of Daemons Running in the Background

The term daemon refers to a resident module running in the background. 3DS includes several daemons performing network functions. The network daemon manager (ndm) serves as a special daemon that integrates these daemons. An NDM library for controlling ndm has been provided in the SDK.

Because the daemons run in a different CPU core than the one in which the application runs, the daemons never directly take up any application CPU time. However, because the application and the daemons both compete for network (wireless communication) access and NAND access, daemon execution does sometimes affect application performance. Applications can stop daemon execution using the NDM library if network and NAND access performance drops to a fatal level.

Note:

SpotPass stops while an application is running unless explicitly instructed otherwise. This does not affect either tasks while sleeping or immediate task execution.

Although daemons can be stopped freely, each plays a specific role and stopping one may limit overall operations. Before you stop a daemon, be sure you understand the possible consequences.

The following table shows the currently known effects of daemons on applications.

Table 4-1. Currently Known Effects of Daemons on Applications

Daemon(nn::ndm::DaemonName)

Effect on the Network

Effect on NAND

nn::ndm::DN_CEC

None. (This daemon does not use infrastructure communication.)

Medium. (When a StreetPass connection is established, there is about 10 KB to 10 MB of NAND access.)

nn::ndm::DN_BOSS

High. (HTTP communications occur when the task executes.)

High. (Data is written to NAND during task execution.)

nn::ndm::DN_NIM

High. (HTTP communications occur when the task executes.)

High. (Data is written to NAND during task execution.)

nn::ndm::DN_FRIENDS

Low. (UDP communications occur when disconnecting.)

Low

Warning:

When controlling daemons, be sure to also read the information in the CTR-SDK API Reference.

4.1. StreetPass

StreetPass communication on the 3DS system represents improvements in features and ease of use over Chance Encounter Communication on the Nintendo DS.

Communication is performed in the background, allowing you to transmit data by simply passing the data without regard to the state of the running application. However, because this also means that an application cannot implement its own wireless communication processes, it may not be possible to build in certain specialized data transmission methods.

Warning:

StreetPass requires that a EULA (End-User License Agreement) be set. To use the CEC library, set the Agree Version to a value of 1.0 or greater from EULA Settings in the Config tool.

Communication via StreetPass cannot be carried out between a development CTR system (debugger or development system) and a retail CTR system.

4.1.1. Overview of Operations

When using StreetPass communication, the communication processes are handled by the StreetPass daemon (a resident process that runs in the background). StreetPass communication can occur if a StreetPass box has been created in the memory region set aside for the 3DS system and if StreetPass data exists in a StreetPass box. The StreetPass daemon automatically handles sending and receiving StreetPass data. The daemon encrypts data before sending it, so there is no need for individual applications to encrypt data.

There are 12 StreetPass boxes available in the system, with one application generally using one box exclusively. You must get the user’s approval before claiming one of the 12 StreetPass boxes to register data for StreetPass. You must get the user’s approval before claiming one of the 12 StreetPass boxes to register data for StreetPass. If all 12 StreetPass box memory slots are already in use, inform the user that the application cannot create its StreetPass settings, and that they must go to the StreetPass management screen in System Settings and delete unneeded StreetPass settings for another application. After the user has opened up at least one of the 12 available memory slots for StreetPass boxes, the application can create a new StreetPass box.

Warning:

When shared use of one system is being made for multiple 3DS Game Cards of the same title, you must be careful with StreetPass that all processes are performed on the same StreetPass box.

Go to the StreetPass management screen in System Settings to check which applications have StreetPass boxes and delete boxes as needed. Deleting a StreetPass box also deletes any notifications in the notification list for that StreetPass box. You must implement your application such that it can continue running even if any data saved in a StreetPass box is deleted.

Within the StreetPass box, there is an inbox and an outbox, each allocated for received data and data to be transmitted.

When a CTR system with StreetPass activated first finds another system in the vicinity that is also activated, the StreetPass boxes in each system’s system memory are scanned. If the two systems both have a box created by the same application (in other words, the StreetPass IDs match), each system begins transmitting only the StreetPass data to be received or sent. If the StreetPass IDs are the same, communication is performed even if the system regions differ. If StreetPass data is being sent from multiple StreetPass boxes, data items are sent (according to size) starting with the smallest. The two systems will not necessarily stay within range of each other long enough to finish sending and receiving all StreetPass data. If the systems are within range for a short period of time, only the smallest data item may be successfully sent. Consequently, keep the size of the StreetPass data as small as possible to increase the chance of successful transmission. StreetPass data items that are part of a group are not sent individually.

You can specify that StreetPass data be receive-only, but note that two systems do not communicate via StreetPass if the boxes are both set to receive-only or send-only. This also applies to units configured to only send StreetPass data. Specifically, if the first registered data is receive-only or send-only, StreetPass exchange never occurs, no matter how much time passes.

The address used by a system for StreetPass communication is regenerated every eight hours and stored in the system’s address list. The interval for StreetPass communication between known communication partners, therefore, is four hours on average and may be up to eight hours. On a development system, you can clear the address list by calling the function to start StreetPass. A similar mechanism to filter addresses cannot be run on a commercial system, so data changes you make may not immediately take effect.

Note:

The system may enter a state while an application is running where StreetPass communication is difficult if connection target settings are registered or there is a surrounding Nintendo Zone. However, even under such conditions, StreetPass communication can be carried out by putting the system into Sleep Mode.

When confirming that StreetPass communication is occurring while an application is running, create an environment where connection target settings are canceled and there is nothing like a Nintendo Zone in the surroundings.

Figure 4-1. Scanning StreetPass Boxes

Application A TitleID=0x0000_0100 Application C TitleID=0x0000_0300 Application D TitleID=0x0000_0400 Application B TitleID=0x0000_0200 User A …… Application F TitleID=0x0000_0600 Application Z TitleID=0x0000_1A00 Application C TitleID=0x0000_0300 Application A TitleID=0x0000_0100 Application E TitleID=0x0000_0400 Even two different applications can StreetPass with each other as long as their StreetPass boxes are registered to the same StreetPass ID.  User B Application X TitleID=0x0000_1800 …… Each application (StreetPass ID) occupies one StreetPass box. You can register up to 12 applications.

4.1.1.1. Conditions Related to StreetPass Communication

This section covers conditions for starting StreetPass communication, connecting with communication peers, sending StreetPass data, destroying StreetPass data, and turning on the notification LED.

Conditions for Starting StreetPass Communication

A search will not be made for peers and StreetPass communication will not start unless all of the following conditions are met.

  • The system is in wireless-enabled mode.
  • StreetPass communication has not been restricted by Parental Controls.
  • The user has agreed to the EULA.
  • A StreetPass box has been set up and there is StreetPass data with a possible send count of 1 or more.

Because the StreetPass daemon also searches for Nintendo Zone, daemon status may show as "scanning" even if the all of these conditions are not met.

Conditions for Connecting with Peers

Connection with a peer cannot be made unless all of the following conditions are met when two systems capable of starting StreetPass communication approach each other.

  • The peer has a StreetPass box with the same StreetPass ID.
  • The StreetPass data for both systems as arranged to be processed combine to form send/receive modes that allow communication.
  • The address used for StreetPass communication with the peer has not been registered in the address filter (a list of addresses of peers with whom StreetPass communication has been performed).
  • The peer has not been registered on the blocked-user list.

Addresses for StreetPass communication are regenerated every eight hours. Up to 255 such addresses can be registered in the address filter saved on a system. If a 256th address is registered, the earliest address in the filter is overwritten. In that case, regardless of the status of the StreetPass box, communication with a peer having the overwritten StreetPass address is impossible. StreetPass communication with this same peer remains impossible for an average of four hours and up to eight hours, even if you create a new StreetPass box.

Conditions for Sending StreetPass Data

After connection with a peer is established, the local host will not send StreetPass data to the peer unless data is exchanged beforehand and all of the following conditions have been met.

  • The peer is a friend and communication settings include a flag for sending data only to friends. Or, the peer is not a friend and communication settings include a flag for sending data to peers other than friends.
  • When StreetPass data has been sent, the data size and count in the peer’s inbox must not exceed the maximum limits allowed.

Even if these conditions are not met, if the send/receive mode is receive-only or send/receive, receipt of StreetPass data from the peer starts as long as the peer meets these conditions.

If send/receive with the peer cannot start because conditions are not met, the address used for StreetPass communication is registered in the address filter at this point. However, the address is not registered if the initial exchange of data conducted beforehand failed.

After data transmission has started, the address for StreetPass communication is registered in the address filter if transmission succeeds. The address is not registered if transmission fails.

Conditions for Destroying Data Received via StreetPass

If either of the following conditions is met, received StreetPass data is destroyed.

  • The StreetPass data signature is incorrect.
  • StreetPass data having the same message ID already exists in the inbox.
Conditions for Turning on the Notification LED

The notification LED illuminates green if StreetPass data has been received in one of the StreetPass boxes and has not been destroyed.

4.1.2. Initialization and Finalization

The application uses the CEC library for StreetPass. Initialize and finalize this library using the nn::cec::Initialize and nn::cec::Finalize functions.

Code 4-1. Initializing and Finalizing
static nn::Result nn::cec::Initialize(nn::fnd::IAllocator& cecAllocFunc);
nn::Result nn::cec::Finalize(); 

Management of memory that the library uses during StreetPass must be performed by the application’s own memory allocator. The library allocates memory from the allocator passed to cecAllocFunc of approximately twice the maximum size of the StreetPass data, for data processing and other purposes.

Calling Initialize after already successfully initializing a StreetPass box returns an nn::cec::MakeResultAlreadyInitialized error indicating that the box is already initialized.

4.1.3. StreetPass Box

Access StreetPass boxes via the nn::cec::MessageBox class.

4.1.3.1. Start Accessing (Opening and Creating)

To start accessing a StreetPass box, first try opening a box to check whether one already exists. If one does exist, simply begin accessing it. If no box exists, create one. After it is created successfully, a StreetPass box is opened.

When a StreetPass box is opened, the StreetPass daemon stops executing. This status continues until the StreetPass box is closed. If the HOME Menu is displayed while a StreetPass box is open, communication via StreetPass does not occur because the daemon is in a stopped state. If the system enters Sleep Mode while the StreetPass box is open, the daemon resumes operations and returns to stopped status when the system wakes up. Even if StreetPass box contents are updated through StreetPass communication carried out during sleep, updated information is not reflected in the opened MessageBox class. The box must be reopened to get the latest information. Because the result of accessing the StreetPass box is rolled back, there is a possibility that the result of processes for creating a StreetPass box or adding or deleting StreetPass data will be lost. We recommend that you close or commit open StreetPass boxes before displaying the HOME Menu or transitioning to Sleep Mode.

Note:

The creation of a StreetPass box and addition or deletion of StreetPass data is not reflected until the StreetPass box is closed or committed. We recommend that access to StreetPass boxes be carried out as an uninterrupted series of operations from open to close.

Warning:

To learn whether real-time StreetPass communication has taken place, use GetCecEvent. (For more information, see 4.1.6. Notifying on Communication Activation.) However, because communication stops each time the StreetPass box is opened, if the box is opened and closed at regular intervals, background communication does not take place.

Code 4-2. Opening and Creating a StreetPass Box
nn::cec::TitleId nn::cec::MakeCecTitleId(bit32 id, bit8 variation = 0x0);
nn::Result nn::cec::MessageBox::OpenMessageBox(const TitleId cecTitleId, 
                                               const u32 privateId);
nn::Result nn::cec::MessageBox::CreateMessageBox(
        const TitleId cecTitleId, const u32 privateId, const char* hmacKey,
        const void* icon, size_t iconSize, const wchar_t* name, size_t nameSize,
        size_t inboxSizeMax = CEC_INBOX_SIZE_DEFAULT, 
        size_t outboxSizeMax = CEC_OUTBOX_SIZE_DEFAULT, 
        size_t inboxMessNumMax = CEC_INBOX_MESSNUM_DEFAULT,
        size_t outboxMessNumMax = CEC_OUTBOX_MESSNUM_DEFAULT,
        size_t messageSizeMax = CEC_MESSSIZEMAX_DEFAULT); 

cecTitleId specifies the Nintendo-assigned value for identifying a game title (the StreetPass ID). The StreetPass ID is generated by calling nn::cec::MakeCecTitleId with a unique 20-bit ID as an argument. This 20-bit ID is assigned by Nintendo. To share StreetPass with multiple titles, specify one of the unique StreetPass IDs as a representative value. The titles will share a single StreetPass box.

privateId specifies the key value required to access a StreetPass box. Developers may choose this value freely. Depending on how this value is generated, access may be restricted to specific save data or to specific game cards.

A StreetPass box may only be opened if these two parameters specify the same values used when creating that StreetPass box. A "no data" error is returned if no StreetPass box exists for the specified StreetPass ID in the cecTitleId value, and a "no access permissions" error is returned if a StreetPass box exists but the privateId value differs.

hmacKey specifies a 32-byte string used to prevent spoofing. Developers may choose this string freely. This value must be identical for both the sending and receiving units. In other words, applications using StreetPass for the same StreetPass ID must specify the same string value.

For the icon parameter, specify the icon to display on the StreetPass management screen, and for iconSize, specify the icon’s size. Icons must be 48×48 pixels in size using the RGB565 PICA native pixel format. You may usually use the game title icon, but for titles in a series, you may use a different icon that makes it clear that this title is part of that series.

For the name parameter, specify the title to display on the StreetPass management screen, and for nameSize, specify its length in bytes. Titles must be strings of up to 64 characters, including the terminating character However, the actual display length is equivalent to 17 characters of the internal fonts at maximum width (in Japan, European, U.S. regions: "%"; in other regions: Japanese hiragana characters, Chinese kanji characters, Hangul characters, and so on). The language of the title can be the same as the language configured in the CTR System settings, or as configured in the language settings of the application itself.

The inboxSizeMax and outboxSizeMax parameters specify the maximum size of the inbox and outbox. The total size of both boxes cannot exceed 1 MB. Unless propagating StreetPass data, the basic rule is to allocate a substantial size for the inbox. If no values are specified for these parameters, the default size is 512 KB.

The inboxMessNumMax and outboxMessNumMax parameters specify the maximum number of messages that can be saved to the inbox and outbox. Specify the value derived by dividing the box capacity by the size of the largest StreetPass message. If no values are specified for these parameters, the default value is 99.

messageSizeMax specifies the maximum size of a StreetPass message. No StreetPass data larger than the specified value may be saved. In general, omit this argument to use the default value of 100 KB. The maximum size of StreetPass data is fixed at 100 KB on the current CTR-SDK, regardless of the value specified for messageSizeMax.

The following table lists errors that can be returned by the nn::cec::MessageBox::OpenMessageBox function, and how to resolve them.

Table 4-2. Errors That May Be Returned by the OpenMessageBox Function and Their Resolution

Error

Cause and Resolution

nn::cec::ResultNoData

No StreetPass box exists. Create a StreetPass box and reopen.

nn::cec::ResultNotAuthorized

The StreetPass box cannot be opened because the privateId values do not match. Data must be deleted when re-creating the StreetPass box.

nn::cec::ResultStateBusy

This error is not returned unless there has been access from multiple threads. The StreetPass box can be opened by waiting awhile and retrying.

Any other errors

If an error not in this table is returned, function execution is treated as having failed. The application must be allowed to advance without using this function. If this function is required for the application to advance, this error may be displayed as a fatal error.

The following table lists errors that can be returned by the nn::cec::MessageBox::CreateMessageBox function, and how to resolve them.

Table 4-3. Errors That May Be Returned by the CreateMessageBox Function and Their Resolution

Error

Cause and Resolution

nn::cec::MakeResultBoxAlreadyExists

A StreetPass box having the same cecTitleId and privateId has already been created.

If the nn::cec::ResultNoData error is returned by the nn::cec::MessageBox::OpenMessageBox function, there is already a StreetPass box that differs only in terms of its cecTitleId.

nn::cec::MakeResultBoxNumFull

There are already twelve StreetPass boxes. A new box cannot be created. Instruct the user to delete an unneeded StreetPass box on the StreetPass Management screen.

nn::cec::ResultStateBusy

This error is not returned unless there has been access from multiple threads. The StreetPass box can be opened by waiting awhile and retrying.

nn::cec::ResultInvalidArgument

An argument has been specified incorrectly.

nn::cec::ResultTooLarge
nn::cec::ResultInvalidData

An icon or name has been specified incorrectly.

Any other errors

If an error not in this table is returned, function execution is treated as having failed. The application must be allowed to advance without using this function. If this function is required in order for the application to advance, this error may be displayed as a fatal error.

4.1.3.2. Setting Related Data

You can change the icon and title displayed on the StreetPass Management screen. Open the StreetPass box and set the new icon and title as related data.

Code 4-3. Setting Related Data
nn::Result nn::cec::MessageBox::SetMessageBoxData(
                        u32 datatype, const void* data, size_t dataSize); 

datatype specifies the type of related data. If setting an icon, use the value nn::cec::BOXDATA_TYPE_ICON, and if setting the title, use the value nn::cec::BOXDATA_TYPE_NAME_1. Specify the starting address of the related data and its size in the data and dataSize parameters.

Icons must be 48×48 pixels in size using the RGB565 PICA native pixel format. You may usually use the game title icon, but for titles in a series, you may use a different icon that makes it clear that this title is part of that series.

Titles must be strings of up to 64 characters, including the string terminator. The actual display length is equivalent to 17 characters of the internal fonts at maximum width (in Japan, European, U.S. regions: "%"; in other regions: Japanese hiragana characters, Chinese kanji characters, Hangul characters, and so on). The language of the title can be the same as the language configured in the CTR System settings, or as configured in the language settings of the application itself.

4.1.3.3. Inbox and Outbox Information

You can get information about the inbox and outbox, such as the capacity or maximum number of messages specified at box creation, the currently used capacity, or the number of messages currently saved.

Code 4-4. Getting Inbox and Outbox Information
u32 nn::cec::MessageBox::GetBoxSizeMax(nn::cec::CecBoxType boxType) const;
u32 nn::cec::MessageBox::GetBoxSize(nn::cec::CecBoxType boxType) const;
u32 nn::cec::MessageBox::GetBoxMessageNumMax(nn::cec::CecBoxType boxType) const;
u32 nn::cec::MessageBox::GetBoxMessageNum(nn::cec::CecBoxType boxType) const; 

All of these functions can be used for either the inbox or outbox, specifying which one by passing an nn::cec::CecBoxType enumerator as an argument. Specify CEC_BOXTYPE_INBOX for the inbox and CEC_BOXTYPE_OUTBOX for the outbox.

Use the GetBoxSizeMax and GetBoxSize functions to get the capacity and used capacity of the specified box.

Use the GetBoxMessageNumMax and GetBoxMessageNum functions to get the maximum number of StreetPass messages and the current number of saved messages for the specified box.

You can scan the data in a StreetPass box by constructing a loop over the number of messages currently saved in it, using the nn::cec::MessageBox class’s GetMessageId functions to get the message ID corresponding to the index.

Code 4-5. Getting a Message ID by Specifying an Index
nn::Result nn::cec::MessageBox::GetMessageId(MessageId* messId, 
                        const CecBoxType boxType, const u32 messIndex); 

Call the ReadMessage function passing the obtained message ID as an argument to get a StreetPass message, and then access that message via the nn::cec::Message class.

Code 4-6. Getting a StreetPass Message
u32 nn::cec::MessageBox::GetMessageSize(const CecBoxType boxType, 
                                            const u32 messIndex) const;
nn::Result nn::cec::MessageBox::ReadMessage(
                nn::cec::Message& cecMessage, void* buf, const size_t bufLen,
                const CecBoxType boxType, const MessageId& messageId); 

cecMessage takes an instance of the nn::cec::Message class.

The buf and bufLen parameters must specify a buffer of the size returned by a call to GetMessageSize, and the size, respectively. This is because the message is first read as a binary array, and then the information is set in the class instance passed in cecMessage.

For more information about accessing StreetPass data via the nn::cec::Message class, see 4.1.4.3. Getting Information.

4.1.3.4. Deleting

StreetPass boxes are a limited resource with only 12 available on the system. Be sure to delete boxes that contain no StreetPass data, or when users are not engaging in StreetPass to allow other applications to create StreetPass boxes.

Code 4-7. Deleting a StreetPass Box
nn::Result nn::cec::MessageBox::DeleteMessageBox();
nn::Result nn::cec::MessageBox::DeleteMessageBox(const TitleId cecTitleId); 

cecTitleId specifies the StreetPass ID of the StreetPass box to delete. If this parameter is omitted, the box currently opened by the nn::cec::MessageBox class is deleted.

Warning:

Do not delete StreetPass boxes other than created by the application.

Only delete StreetPass boxes with the specified StreetPass ID that can no longer be opened because they are broken.

4.1.3.5. Ending Access (Close and Commit)

After access to a StreetPass box has ended, the daemon must be returned to executing status. To restore execution status, call nn::cec::MessageBox::CloseMessageBox to close an open StreetPass box.

Code 4-8. Closing a StreetPass Box
void nn::cec::MessageBox::CloseMessageBox(); 

Changes to a StreetPass box are not written into save memory until they are committed. If an application exits before committing this data, content may rewind to data committed in the past. Call nn::cec::MessageBox::CommitMessageBox to commit, but not that it is also committed when closing the StreetPass box.

Code 4-9. Committing a StreetPass Box
nn::Result nn::cec::MessageBox::CommitMessageBox(); 

4.1.3.6. Relationship With the StreetPass Daemon

When a StreetPass box is opened by an application, the StreetPass daemon stops execution. If this happens during the execution of a daemon process, the process is canceled and any received data may be lost completely. StreetPass boxes can be safely accessed by using the nn::cec::CecControl::GetCecState function to check if the daemon is busy (DAEMON_STATE_BUSY) or communicating (DAEMON_STATE_COMMUNICATING) before opening a StreetPass box.

4.1.3.7. StreetPass-Exclusive Mode (for Debugging Only)

You can set the system to use only StreetPass for background communication by using the following functions. Note that these are only to be used for debugging purposes.

Code 4-10. Switching to StreetPass-Exclusive Mode
static nn::Result nn::cec::CecControl::EnterExclusiveState();
static nn::Result nn::cec::CecControl::LeaveExclusiveState(); 

These functions produce an error when switching to StreetPass-exclusive mode if the system is either already using exclusive background communication or is carrying out local communication.

4.1.4. StreetPass Data

All access to StreetPass data is carried out via the nn::cec::Message class.

4.1.4.1. Creating New Data

To create new StreetPass data, prepare an instance of the nn::cec::Message class and call its NewMessage member function.

Code 4-11. Creating New StreetPass Data
nn::Result nn::cec::Message::NewMessage(TitleId cecTitleId, u32 groupId, 
                        u8 messageTypeFlag, u8 sendMode, 
                        u8 sendCount, u8 propagationCount);
nn::Result nn::cec::Message::NewMessage(TitleId cecTitleId, u32 groupId, 
                        u8 messageTypeFlag, u8 sendMode, 
                        u8 sendCount, u8 propagationCount, 
                        const void* icon, size_t iconSize, 
                        const wchar_t* infoTextData, size_t infoTextSize); 

cecTitleId specifies the StreetPass ID specified when the StreetPass box was opened.

groupId specifies the group number when grouping StreetPass data. Note that the total size for a single group cannot exceed the maximum size for a single transmission (100 KB). Specify 0 for this parameter to not group data and to send messages individually, even if a data group with a number of 0 actually exists.

messageTypeFlag specifies a bitwise OR of flags indicating the recipients of the data. Using a combination of flags, you can restrict the StreetPass data to be sent only to friends or only to non-friends, or allow it to be sent to both. This setting makes it possible to send different StreetPass messages to friends and non-friends and, by registering StreetPass data with different flags in the same group, send additional comments to friends or otherwise control how data is sent. These flags are only considered when data is sent. You cannot make a user’s status as a friend (or not) a condition for receiving data.

Table 4-4. Message Recipient Flags

Flag

Description

Bitwise OR of the following two flags

Set when sending without differentiating between friends and non-friends.

This setting is the default, and it sends to everyone.

MESSAGE_TYPEFLAG_NON_FRIEND

Sends data only to communication partners who are not friends.

Set this flag when sending different comments for friends and non-friends in the StreetPass data for the same group, or in similar situations.

MESSAGE_TYPEFLAG_FRIEND

Sends data only to communication partners who are friends.

Set this flag when adding comments to be sent just to friends included in the same group as StreetPass data to send to everyone, or in similar situations.

Warning:

If you specify only MESSAGE_TYPEFLAG_FRIEND, make sure that the different StreetPass Relay process does not cause any problems for your application's specifications. For more information, see 9. Appendix: StreetPass Relay.

sendMode specifies the transmission mode for controlling StreetPass data transmission. The combination of transmission modes for communication partners controls whether StreetPass data is sent and received during communication.

Table 4-5. Transmission Modes

Transmission Mode

Description

CEC_SENDMODE_RECV

Receive only. Data is received when the communication partner is in send only or send/receive mode.

We recommend not using this setting because it prevents StreetPass communication with peers who are using the same setting.

StreetPass data is registered in the outbox.

CEC_SENDMODE_SEND

Send only. Data is sent when the communication partner is in receive only or send/receive mode.

We recommend not using this setting because it prevents StreetPass communication with peers who are using the same setting.

CEC_SENDMODE_SENDRECV

Send/receive. Data is sent when the communication partner is in receive only mode, received when the communication partner is in send only mode, and sent and received when the communication partner is in send/receive mode.

Specify this mode for one-way communication (only sending or only receiving data), such as when users distribute their own creations, invitations to in-game houses, or similar situations.

CEC_SENDMODE_EXCHANGE

Exchange. Data is sent and received when the communication partner is also in exchange mode. StreetPass communication is not successfully established if either party cannot properly send and receive.

Specify this mode when specific data must be exchanged, such as when swapping in-game pets or engaging in StreetPass matches.

Table 4-6. Transmission in Each of the Transmission Mode Combinations

A (Row)
B (Column)

Receive Only

Send Only

Send/Receive

Exchange

Receive Only

×

A ← B

A ← B

×

Send Only

A → B

×

A → B

×

Send/Receive

A → B

A ← B

A ⇔ B

×

Exchange

×

×

×

A ⇔ B

There is no guarantee that StreetPass data has been successfully sent. Because grouping is performed even if the send/receive mode differs, use the same send/receive mode for data associated with the same group whenever possible, while making sure that the send/receive mode does not include receive only data.

Warning:

When the transmission mode is Exchange, communications are only carried out between systems that are set to the same Exchange mode. If there is a mix of transmission modes set for the same StreetPass box, the probability of StreetPass occurrences will decline.

sendCount specifies the number of times to send a StreetPass message. Specify MESSAGE_SENDCOUNT_UNLIMITED to not limit the number of times a message can be sent. The sendCount value is decremented by 1 every time a message is sent and sending stops when the counter reaches 0. The sendable count decrements at the point data is sent, regardless of whether data received by the receiver has been registered in the inbox. The value decrements when data is sent, and does not decrement when the communication peer is in send only mode, even if the local system is in send/receive mode. This value will also not decrement when the communication peer’s box is full and data cannot be sent, such as after reaching the maximum number of times a message can be received. However, data can still be received from this peer so long as there is room in the local inbox. The sendCount value acts as a limit on the number of times data can be received when in receive only mode (CEC_SENDMOD_RECV), decrementing by 1 every time data is received until reaching 0.

If the same StreetPass data is received, the newer StreetPass data is destroyed. Even if StreetPass data is destroyed, the sendCount of the sender is decremented by one.

There is no guarantee that sent data will actually reach the communication peer. A power loss immediately after StreetPass communication is established and while in the middle of saving data or decrementing the sendCount value can cause an irreconcilable inconsistency between the remaining sendCount value and the number of data items received.

propagationCount specifies the number of times a StreetPass message is propagated. This value is decremented by 1 every time the message is received, and a message with a propagation value of at least 1 is copied to the outbox after receipt. In other words, specify a value of at least 2 to propagate a StreetPass message. Note that received data can be saved in both the inbox and outbox, and that you may receive StreetPass data that you sent yourself, depending on the route through which it is propagated. The library imposes a restriction that either the sendCount or propagationCount parameters must be set to 1 to prevent the risk that a single StreetPass message could multiply exponentially.

If StreetPass data for which a propagation count has been set is received, and the same data already exists in the inbox, the data will not be propagated further because the new data is destroyed. Even if the data is received, and the same data does not already exist in the inbox, it will not be propagated if there is not enough capacity in the outbox. However, if the same data has already been received and copied to the outbox, propagation continues to update the propagation count and possible send count (which must be 1) to match the new data.

Figure 4-2. Propagation With a Propagation Count of 2

3DS A 3DS B 3DS C Outbox Inbox Inbox Outbox Inbox Outbox Propagation count=2 Propagation count=1 Propagation count=1 Propagation count=0 Send Send Copy

The NewMessage function mainly sets the conditions for sending and receiving a message. However, other information such as the data to display in the notification (icon, text) and the actual data to send must also be set. To specify such additional information at the time of message creation, use the overloaded version of NewMessage and specify values for the icon, iconSize, infoTextData, and infoTextSize parameters. The language configured for the description in infoTextData can be the same as the language configured in the CTR System settings, or as configured in the language settings of the application itself. But text for only one language can be configured, so if the settings are different for the sender and receiver, the description could be displayed for the receiver in a language different from the receiver’s configured language.

Use the SetaExHeader function to set the data to display in the notification as extended header information.

Code 4-12. Setting Extended Header Information
nn::Result nn::cec::Message::SetExHeader(
        const u32 exhType, const size_t exhLen, const void* exhBody); 

exhType specifies the type of extended header information.

Table 4-7. Extended Header Types

Type

Description

MESSAGE_EXHEADER_TYPE_ICON

Icon. Its size must be 40×40 pixels using the RGB565 PICA native pixel format.

MESSAGE_EXHEADER_TYPE_INFO

Descriptive text. Up to two lines each having a width equal to 16 characters (in Japan, European, U.S. regions: "%"; in other regions: Japanese hiragana characters, Chinese kanji characters, Hangul characters, and so on) of the internal font at maximum width may be displayed. Maximum length of 128 characters, including newlines and the string terminator. Encoded as UTF16-LE.

The exhBody and exhLen parameters specify the data for the extended header information and its size.

You can set the icon data by calling the SetIcon function and set the descriptive text by calling the SetInfoText function.

Set the data to send in a StreetPass message by calling the SetMessageBody function.

Code 4-13. Setting the Data to Send
nn::Result nn::cec::Message::SetMessageBody(
                        const void* dataBody, const size_t size); 

The dataBody and size parameters specify the data to send and its size. This size must be a multiple of 4.

The total size of the header information, extended header information, and data to send cannot exceed the maximum StreetPass data size specified when creating the StreetPass box (default size of 100 KB). The maximum size of send data is MESSAGE_BODY_SIZE_MAX (96 KB). However, the larger the data size, the later a message is positioned in the StreetPass box sending queue and the longer the time required to send it, which may reduce the chances of successfully transmitting the message.

You do not need to configure receive-only StreetPass data with extended header information and data to send.

You can also call the SetTag function to set an optional 16 bits of data. Use this as convenient, such as for a short message identifier that would be seen when accessing just a message header without reading the data portion.

4.1.4.2. Registering to the Outbox

After a StreetPass message is composed, it must be saved to the outbox using the WriteMessage member function of the nn::cec::MessageBox class.

Code 4-14. Saving a StreetPass Message to a Message Box
nn::Result nn::cec::MessageBox::WriteMessage(const nn::cec::Message& cecMessage,
                        const CecBoxType boxType, MessageId& messageIdOut); 

cecMessage specifies an instance of the nn::cec::Message class representing the created StreetPass data.

boxType usually specifies the outbox (CEC_BOXTYPE_OUTBOX). Applications are not required to perform operations to specify the inbox.

messageIdOut specifies the variable that the message ID is written to after the StreetPass data is saved by a call to this function.

A check for the EULA agreement is made when StreetPass data is saved, so the FS library must be initialized beforehand. The error ResultNotAgreeEula is returned if the user has not agreed to the EULA, or if an icon file has not been set in the application. The error ResultParentalControlCec is returned if StreetPass has been restricted by Parental Controls.

Note:

The maximum size of StreetPass data is fixed at 100 KB. An excessive size error (ResultMessTooLarge) does not occur unless data exceeds 100 KB.

Order of Registering StreetPass Data in the Outbox and Processing It

A list is created in a StreetPass box in the same order that data was registered with the outbox. The data at the start of this list is generally processed first unless its allowable send count is 0, in which case the next data in the list (in order) is processed. The send/receive mode of the data to be processed determines whether it is actually sent and received. If data whose send/receive mode has been set to receive only is included in a group, that data is sent to the communicating peer. Be sure to place data so that groups are formed from data having the same send/receive mode.

If a nonzero group ID is set for the data to be processed and there is other data with the same group in the list, that data is processed together until either the end of the list is reached or the total data size reaches the maximum amount that can be sent in a single transmission. The data from the same group as at start is then moved to the end of the list, and the data at the start of the list is replaced. All data (processed or not) with the same group as this processed data have their sendCount values decremented by 1.

When the group ID for the data to be processed is set to 0, only that data is processed. Any other data with a group ID of 0 is not treated as part of the same group. Only the processed data is appended to the end of the list, and the sendCount value is decremented by 1.

When you register new StreetPass data, it is appended to the end of the list. Any received messages that have propagationCount values of at least 1 after decrementing are appended to the end of the list (added to the outbox), with such messages received from other systems then being sent out at the next opportunity for StreetPass communication.

Figure 4-3. Group Settings and Process Order

Group 1 SendCount=5 60 KByte Group 1 SendCount=5 30 KByte Group 1 SendCount=5 20 KByte Group 0 SendCount=5 10 KByte Group 0 SendCount=5 15 KByte ↓ Start of the list Group 1 SendCount=4 60 KB Group 1 SendCount=4 30 KB Group 1 SendCount=4 20 KB Group 0 SendCount=5 10 KB Group 0 SendCount=5 15 KB This item was in the same group as the data at the start of the list, but this item was not sent because the total group size exceeded the maximum send size. This item's send count is nevertheless decremented because it was part of that group.  Grouped together with the data at the start of the list because they are all in the same group.  Group 0 is not grouped.  ↓ Start of the list Data in the same group as the start of the list is moved to the end of the list.

4.1.4.3. Getting Information

Get required information via the nn::cec::Message class to access received data obtained by scanning the inbox.

Code 4-15. Getting Information
u32 nn::cec::Message::GetBodySize() const;
u32 nn::cec::Message::GetMessageBody(void* dataBody, size_t size) const;
MessageId nn::cec::Message::GetMessageId_Pair(MessageId* messIdPair) const;
u16 nn::cec::Message::GetTag() const; 

Call the GetMessageBody member function to get the sent data in the StreetPass message.

The dataBody and size parameters specify a buffer to store the sent data and the buffer size. Use the GetBodySize function to get the required size of the buffer.

If the StreetPass message transmission mode was set to CEC_SENDMODE_EXCHANGE, access data by getting the message ID of the data sent from the communication partner in the GetMessageId_Pair function.

Use the GetTag function to get the tag information in the StreetPass message.

4.1.4.4. Deleting

Sent or received StreetPass messages are not automatically deleted. The amount of data and number of messages that may be saved in the outbox or inbox is limited. An application must delete StreetPass messages that are no longer needed, such as data to send that has a sendCount value of 0, or received data that has already been applied to the application. Delete messages using the DeleteMessage member function of the nn::cec::MessageBox class. To delete all StreetPass data in the StreetPass box, call the DeleteAllMessages member function of the nn::cec::MessageBox class.

Code 4-16. Deleting a StreetPass Message
nn::Result nn::cec::MessageBox::DeleteMessage(
                const CecBoxType boxType, const MessageId& messageId);
nn::Result nn::cec::MessageBox::DeleteAllMessages(const CecBoxType boxType); 

Specify the ID of the message to delete in the messageId parameter, and the type of message box where the message is saved in the boxType parameter.

If the StreetPass box holds two or more messages, and you want to delete all of them, it is faster to use DeleteAllMessages than to delete them individually using DeleteMessage.

4.1.5. Accessing Header Information

You can use the nn::cec::MessageBox class to access just the header information for a StreetPass box or StreetPass message to extract limited information without having to open the data portion. Note that this class cannot be used to access the data to send, nor the extended header information.

Use the following member functions to get the StreetPass message total size and other information.

Code 4-17. Accessing StreetPass Message Information
u32 nn::cec::MessageBox::GetMessageSize(
                        const CecBoxType boxType, const u32 messIndex) const;
u32 nn::cec::MessageBox::GetMessageBodySize(
                        const CecBoxType boxType, const u32 messIndex) const;
u32 nn::cec::MessageBox::GetMessageGroupId(
                        const CecBoxType boxType, const u32 messIndex) const;
u32 nn::cec::MessageBox::GetMessageSessionId(
                        const CecBoxType boxType, const u32 messIndex) const;
u8 nn::cec::MessageBox::GetMessageTypeFlag(
                        const CecBoxType boxType, const u32 messIndex) const;
u8 nn::cec::MessageBox::GetMessageSendMode(
                        const CecBoxType boxType, const u32 messIndex) const;
u8 nn::cec::MessageBox::GetMessageSendCount(
                        const CecBoxType boxType, const u32 messIndex) const;
u8 nn::cec::MessageBox::GetMessagePropagationCount(
                        const CecBoxType boxType, const u32 messIndex) const;
bit16 nn::cec::MessageBox::GetMessageTag(
                        const CecBoxType boxType, const u32 messIndex) const;
nn::fnd::DateTimeParameters nn::cec::MessageBox::GetMessageSendDate(
                        const CecBoxType boxType, const u32 messIndex) const;
nn::fnd::DateTimeParameters nn::cec::MessageBox::GetMessageRecvDate(
                        const CecBoxType boxType, const u32 messIndex) const;
nn::fnd::DateTimeParameters nn::cec::MessageBox::GetMessageCreateDate(
                        const CecBoxType boxType, const u32 messIndex) const;
MessageId nn::cec::MessageBox::GetMessageIdPair(
                        const CecBoxType boxType, const u32 messIndex) const;
nn::Result nn::cec::MessageBox::GetMessageIdPair(
        MessageId* messId, const CecBoxType boxType, const u32 messIndex) const;
MessageId nn::cec::MessageBox::GetMessageId(
                        const CecBoxType boxType, const u32 messIndex) const;
nn::Result nn::cec::MessageBox::GetMessageId(
        MessageId* messId, const CecBoxType boxType, const u32 messIndex) const;
u32 nn::cec::MessageBox::GetMessageIndex(
                        CecBoxType boxType, const MessageId& messId) const;
u32 nn::cec::MessageBox::GetMessageIndex(CecBoxType boxType, u8* messId) const; 

4.1.6. Notifying on Communication Activation

You can receive a notification event indicating that the communication has been activated for StreetPass data. You can also get information about the most recent received data.

Code 4-18. Getting Communication Activation Events and Received Data
nn::Result nn::cec::GetCecEvent(nn::os::Event* event);
nn::Result nn::cec::GetCecInfoBuffer(
                        u32 cecTitleId, u8 pCecInfoBuffer[], size_t size); 

For the nn::os::Event class instance specified in the event parameter, specify an instance that has not been initialized. Note that this event is signaled when the StreetPass box registered by an application that has obtained the event receives StreetPass data, and also when any StreetPass box registered by any other application receives StreetPass data or when StreetPass data was sent. Use this event for immediate notification on the reception of StreetPass data during background StreetPass communication while an application is running.

Call the nn::cec::GetCecInfoBuffer function to get information about the most recent received data. This function stores information about the last StreetPass communication in the buffer specified by the pCecInfoBuffer parameter. In general, call this function passing a value for cecTitleId to determine whether data has been received in the local inbox after detecting communication activation by means of the previously mentioned Event object. You can call this function without stopping the StreetPass daemon process.

The data is stored as a nn::cec::CecNotificationData structure, so specify a buffer large enough to hold this structure in the pCecInfoBuffer and size parameters.

The num member of the nn::cec::CecNotificationData structure stores the number of information items in the structure. The count member stores the number of instances of StreetPass communication activated since the system was last booted. The param member stores information about the StreetPass data stored in the nn::cec::CecNotificationParam structure at position num from the start.

The recvDate member of the nn::cec::CecNotificationParam structure stores the date and time when the StreetPass data was received. The cecTitleId member stores the StreetPass ID, and the messageId member stores the StreetPass data’s message ID.

Note:

The messageId member of the CecNotificationParam structure stores the message ID of the latest StreetPass data received in that StreetPass box. However, even when you receive the grouped StreetPass data, information for only one data item is stored.

You must open the StreetPass box or take some similar action to actually access the received data.

4.1.7. Example of Sending and Receiving StreetPass Data

The following figure shows an example of how data would be sent and received if you passed two other users and multiple applications had registered StreetPass data in StreetPass boxes.

Figure 4-4. Example of Sending and Receiving StreetPass Data

First User to Pass By Second User to Pass By Application B Inbox Outbox Application C Inbox Outbox Application A Inbox Outbox A1 * 2 C1 * 3 Application B Outbox Application D Inbox Outbox Application A Inbox Outbox A1 * 2 B1-a * 2 B1-b * 2 B1-c * 2 Application B Inbox Outbox Application D Inbox Outbox Application A Inbox Outbox A1 D1 * 1 D2 * 2 A1 A1 A1 A1 * 2 B1-a B1-b B1-c B1-a B1-b D2 Inbox B1-a * 0 B1-b * 0 B1-c * 0 B1-a * 2 B1-b * 2 B1-c * 2 B1-a B1-b B1-c D1 * 2 D2 * 2 D1 D3 * 2 D3 * 2 B1-c

The blue lines show how data is sent, the red lines show how data is received, and the yellow boxes indicate the StreetPass data. The transmission mode for all of the StreetPass data is send/receive. Each StreetPass data item is given as a letter followed by: a number that represents a group, a hyphen and a letter that represents different data within the same group, and an asterisk and a number that represents the transmission count. The transmission counts on your system show the values that were registered along with the data. The transmission counts on the other users' systems show the values at the moment they passed by you.

Application A had been registered by both of the users you encountered, so its data was sent and received twice.

Application B had been registered by both of the users you encountered. The first user had a transmission count of 0, however, so data was only sent from your system. Both you and the second user did not have a transmission count of 0, so data was both sent and received.

Application C had been registered only by the first user you encountered, so its data was neither sent nor received.

Data for application D was both sent and received with the second user you encountered, but you each received different data because your next item to send was D1 and the other user's next item to send was D2.

4.1.8. Efficient Settings

Because 3DS communication via StreetPass is handled as a background process, there may be StreetPass opportunities unrelated to the application currently running. However, the StreetPass settings include many items that are complicated and need to be tweaked to efficiently send and receive StreetPass data. This section explains the settings related to sending and receiving data when an opportunity for StreetPass communication arises.

It also describes how to make effective use of the various settings. Features for a variety of purposes are provided by the library. To use these features, developers must constantly keep track of how often data is sent and received and between how many users.

4.1.8.1. Recommended Settings

Consider the normal case, where users select which data to exchange through StreetPass and register the data themselves. We recommend that you use the following settings so that it is easier for users to understand the results of StreetPass and to boost StreetPass transmission activity.

(1) Register only one data item.

You can avoid many of the restrictions inherent in the StreetPass specifications to make it more understandable to users.
If you want to register what seem to be many data items, first consolidate them into one item and register that item. Another way is to use grouping. If you do not use grouping and just register multiple items of data, only one data item ends up being sent and received in any one StreetPass.

(2) Set the transmission mode to Send/Receive.

When the transmission mode is set to Send/Receive, no opportunities will be lost because data is sent and received regardless of the state of either StreetPass inbox. Exchange mode has almost the same conditions for sending and receiving, but StreetPass is not established if there is no free space in either system’s inbox or in some other cases unless both parties succeed in communication. In other words, the party with free space available will miss the opportunity to receive StreetPass data.
When the mode is Send-only or Receive-only, StreetPass will not occur even though two systems set to the same mode encounter one another. When users can select either of these modes, they are likely to tend to choose one mode over the other, resulting in missed opportunities for sending and receiving StreetPass data.

(3) Put no limit on number of times data can be sent.

If StreetPass is always operating, there are no lost opportunities. It is easier for users to understand the StreetPass settings when registered data remain effective until deleted.
When a restriction is set, at some point the number of times that data can be sent will become 0, and the user may be unaware that distribution has ended. Because it is hard for a user to know when distribution has ended, other users will miss opportunities to receive StreetPass data when a user’s transmission count has reached 0.

(4) Send to both friends and non-friends.

If there are no restrictions on who to send data to, no StreetPass opportunities are lost.
While you might consider limiting sending to non-friends to increase opportunities with new people you happen to meet, data would no longer be exchanged with users with whom you have established friendships. Conversely, if you limit sending to only friends, your StreetPass can no longer be carried out with other regular users.

4.1.8.2. Registering Multiple Sets of Data

If you want to send multiple pieces of data to a single other user, we recommend not grouping them but rather packing them together into a single data item. By gathering the data this way instead of grouping, you can eliminate wasteful header information and reduce the overall size of the data.

When registering multiple pieces of data, you must note that only one item of data is sent at a time and that subsequent data items are not sent until the first has been sent. In other words, if the opportunity of StreetPass sending/receiving for the first data item is very low, subsequent data items will end up having to wait a long time for their turns.

The next StreetPass with the same other system will not occur until an average of 4 hours later, and the interval can be as long as 8 hours. For this reason, the second and subsequent data items will not reach that other system in series. If the user has registered multiple data items, the items that reach this other system depend on the items that were first in line on all occasions when the two systems made StreetPass encounters. Chance is a big factor, and the user may have trouble figuring out what’s going on.

4.1.8.3. Using the Send-Target Setting

You can configure the send targets to limit who gets sent the StreetPass data. Combining this setting with grouping, you can send different data to friends and to non-friends.

To provide a specific example, set the data at the start of a group as data to be shared by all send targets, and then add two more data items (one to be sent to friends and the other to be sent to non-friends). StreetPass transmits that first data item first. Configure it in the way that minimizes lost opportunities.

4.1.8.4. Using the Propagation-Count Setting

One interesting aspect of StreetPass is that data registered by a distant user may be received after passing through multiple other users. This occurs when the propagation count for StreetPass data has been set to more than one. However, propagation ceases if data is deleted during its propagation, there is not enough available space in the outbox, or if the same data has already been received. There is also a possibility that data registered by the user may not be sent immediately depending on the send order due to registration of another user's data in the outbox.

You can use propagated data when you only want to disseminate special data inside a certain region, such as special deliveries from limited users such as operators or when applications register data at a low probability.

There is no special setting for data that is being distributed as StreetPass data registered by the user. If grouping is used, you can send it together with data registered by the user.

Note that you need to register dummy data in a CTR system that is waiting for the arrival of propagating data if you are waiting to accept data being propagated without the user registering StreetPass data. For example, if an operator will be using this feature for special deliveries, set the operator side to send-only transmission mode, with a propagation count of 2 or more and a transmission count of 1, and set the side waiting for the propagating data to receive-only, with a propagation count of 1 and a transmission count of 1. This allows the registration of data being propagated to other users from operators and users encountered via StreetPass as an operator.

4.2. SpotPass

SpotPass is the name of a type of communication that uses the feature called BOSS (an acronym for "Background Online Service System"). Applications can use BOSS to handle background communication with Nintendo’s BOSS data servers.

An application uses BOSS by registering a task (which is a set of information describing the communication operations you want to perform) with BOSS and then starting the task. Tasks include data such as execution interval and the execution count (number of remaining times to execute the task). BOSS then runs tasks regularly in the background based on this data.

Note:

The term background in this case refers to Sleep Mode and HOME Menu display. In other words, it refers to states where the application is not running.

Figure 4-5. Downloading Data Using BOSS Features

BOSS Data Server Infrastructure Communication Data (4) Application Download data from the data server. (1) Register the task and start it. Task Task Task Task BOSS automatically connects to and disconnects from the data server.  (2) Wait until task completion. (6) Get data. (5) Notify of task completion. (3) Run tasks at their specified run times. Other operations possible while waiting.

Note:

If the user has not accepted the EULA, tasks registered with BOSS will not run until the EULA has been accepted.

An application can find out whether a new data download task has finished by checking its task status, checking the task’s execution result, or using notifications for newly arrived data events. This data can also be read via BOSS.
The following tasks are currently available.

 

Note:

Data upload tasks and Data Store upload/download tasks require a server environment to be set up. Contact Nintendo (support@noa.com) before using this in a product.

Tasks are generally run in the background, but an application can prompt BOSS to run a registered task at any time. Note that this causes the task to run in the foreground.

In addition, a dedicated task registration function is provided to perform foreground execution of these tasks (for example, registering the tasks and executing immediately while the application is running). This function registers tasks for immediate execution.

The following can be considered basic service examples of the use of BOSS.

  • Regularly distributing notifications and extra data in the background (as NADL tasks)
  • Distributing data that varies by region or company, using Nintendo Zone (as NADL tasks)
  • Performing data exchanges between users in the background (as Data Store upload and download tasks)

4.2.1. Common Processes for All Tasks

This section describes common operations carried out for all task types.

Applications must carry out the following operations when using tasks.

In general, implement applications to follow these steps in the listed order.

4.2.1.1. Initializing the BOSS Library

You must first initialize the BOSS library by calling nn::boss::Initialize before using any BOSS features.

Code 4-19. Initializing the BOSS Library
nn::Result nn::boss::Initialize(void); 

If you call the BOSS library functions before initializing the library, the functions return nn::boss::ResultIpcNotSessionInitialized.

4.2.1.2. Setting Task Properties

Set task properties using three classes. Then call the nn::boss::RegisterTask function, passing in the three configured class instances as arguments, to register one task with the BOSS daemon.

  • Basic information (nn::boss::Task class)
  • Execution policy (nn::boss::TaskPolicy class)
  • Actions (nn::boss::TaskAction class)
Figure 4-6. Configuring Task Properties

taskId execInterval execCount priority taskPermission rootCA clientCert infoAP httpRequestHeader lastModified nn::boss::Task Class nn::boss::TaskPolicy Class nn::boss::TaskAction Class nn::boss::TaskAction Derived Classes If-Modified-Since value assigned to initial HTTP request (If omitted, If-Modified-Since omitted from initial HTTP request.) AP information query settings to add to HTTP request Task ID (string up to 7 characters) Execution interval (in hours) Remaining execution count Execution priority (Nintendo approval required for any non-default value) Execution permissions CA certificate settings for HTTPS Client certificate settings for HTTPS Unique header field to add to HTTP request Different derived class for each task type.  NADL class (nn::boss::NsaDownloadAction) Data upload class (nn::boss::UploadAction) Data store upload class (nn::boss::DataStoreUploadAction) Data store download class (nn::boss::DataStoreDownloadAction)

There are restrictions on the property values that may actually be used by the application.

The following table lists the restrictions that apply when registering NADL tasks.

Table 4-8. Property Value Restrictions When Registering an NADL Task

Property

Restrictions on Valid Values

taskId

Use the task ID from your application to Nintendo.

execInterval

Use a value from 1 hour to 168 hours (one week).

To pass Lotcheck, your application must not use the function version provided for debugging purposes that allows you to set the execution interval in seconds.

execCount

Set an execution count from 1 to 100.

priority

Enter the default value (PRIORITY_MEDIUM).

Contact Nintendo (support@noa.com) if you need to set this to some other value.

taskPermission

Enter the default value (TASK_PERMISSION_IN_PARENTAL_CONTROL).

When resetting properties using the SetProperty function of the nn::boss::TaskPolicy class, always be sure to include TASK_PERMISSION_IN_PARENTAL_CONTROL.

infoAP

On normal tasks, do not set this to a value that provides access point information.

Individual data specific to particular Nintendo Zone locations and retail outlets can be distributed by providing the access point information. If you are using an NADL task that provides access point information, contact Nintendo (support@noa.com) in the early planning stages.

Basic Information (nn::boss::Task class)

The nn::boss::Task class for setting the basic information of a task includes a property for the task ID. Create an instance of the nn::boss::Task class and then call Initialize to set the task ID.

Code 4-20. Initializing the nn::boss::Task Class
class nn::boss::Task
{
    nn::Result Initialize(const char* pTaskId);
} 

The task ID is a string of up to seven characters (not including the string terminator), and it can include uppercase and lowercase alphanumeric characters, the underscore, and the hyphen. This ID must be unique among all tasks belonging to the same application, so specify this value accordingly. Task IDs cannot be changed after they are assigned.

Warning:

Be sure to apply to Nintendo (support@noa.com) for a task ID, and always use that approved task ID. If an unapproved task ID is set, the product will not pass Lotcheck.

Execution Policy (nn::boss::TaskPolicy class)

The nn::boss::TaskPolicy class for setting a task’s execution policy includes properties for the task execution interval and execution count. Create an instance of the nn::boss::TaskPolicy class and then call Initialize to set these properties. These values can be changed after initialization. For more information about changing the execution interval and execution count, see 4.2.1.7. Changing a Task.

Code 4-21. Initializing the nn::boss::TaskPolicy Class
class nn::boss::TaskPolicy
{
    nn::Result Initialize(u32 interval, u32 count);
} 

Specify the execution interval for the interval parameter and the execution count for the count parameter. Interval values are in hours and can be from 1 to 168 (or 7 days). Count values can be from 1 to 100. Do not set UNLIMITED_COUNT as the count value. The count value is decremented every time the task is run. The task is no longer run after this value reaches 0.

Note:

The execution count is decremented whenever communication with the server completes and a response is received, regardless of whether that response indicates success or failure. It is not decremented if the connection is interrupted during task execution.

Warning:

The CTR-SDK also includes the debugging-only function InitializeWithSecInterval, allowing you to set the interval value in seconds. Note that any code setting this value in seconds will not pass Lotcheck.

Set and get all properties using the SetProperty and GetProperty member functions.

Code 4-22. Setting and Getting Property Values
class nn::boss::TaskPolicy
{
    nn::Result SetProperty(PropertyType type, void* pValue, size_t size);
    nn::Result GetProperty(PropertyType type, void* pValue, size_t size);
} 

Specify the property to set or get in the type parameter. Specify a variable storing the property value for pValue, and specify its size in size.

Table 4-9. Valid Property IDs for the nn::boss::TaskPolicy Class

Property ID

Type

Property

TASK_EXEC_INTERVAL

u32

Execution interval (in seconds).

TASK_EXEC_COUNT

u32

Execution count.

TASK_PERMISSION

TaskPermission

See the description following this table.

The TASK_PERMISSION property identifier is accessed to restrict operations when Internet communication with other users ("Online Interaction") is restricted by Parental Controls. If a task has nothing set for this property, the task does not execute if Online Interaction is restricted by Parental Controls.

NADL tasks do not involve the exchange of data between users, so TASK_PERMISSION_IN_PARENTAL_CONTROL is added to the TASK_PERMISSION identifier value by default. Consequently, leaving this value at the default ensures that NADL tasks will be processed even when Online Interaction is restricted by Parental Controls.

Warning:

Any code in which the TASK_PERMISSION property identifier is not set to TASK_PERMISSION_IN_PARENTAL CONTROL in a NADL task will not pass Lotcheck. When you change the TASK_PERMISSION identifier setting, you must include TASK_PERMISSION_IN_PARENTAL_CONTROL.

Although the TASK_PERMISSION property identifier can be used to set actions to perform when the EULA has not been accepted, make sure that tasks registered by the application do not perform actions when the EULA has not been accepted. If you register a task without setting actions, the task is not processed unless the EULA is accepted.

Actions (nn::boss::TaskAction Class)

Use the relevant class derived from nn::boss::TaskAction to set properties related to the operations to be carried out. The following tasks are currently available.

Table 4-10. Task Types for the nn::boss::TaskAction Derived Classes

Derived Class

Task Type

nn::boss::NsaDownloadAction

Nintendo Archive Download (NADL) task

nn::boss::UploadAction

Upload task

nn::boss::DataStoreUploadAction

Data Store upload task

nn::boss::DataStoreDownloadAction

Data Store download task

For more information about using tasks, and the valid property settings to use, see the individual task descriptions.
Upload tasks are provided on an individual basis. For this service, contact support@noa.com.

4.2.1.3. Task Action Settings

Settings can be performed for information provided when connecting to a server and certificates using the nn::boss::TaskAction class, which perform settings specific to task actions.

Code 4-23. Functions for Setting Task Actions
class nn::boss::TaskAction
{
    nn::Result SetApInfo(ApInfoType info);
    nn::Result SetCfgInfo(CfgInfoType info);
    nn::Result AddHeaderField(const char* pLabel, const char* pValue);
    nn::Result SetLastModifiedTime(const char* pLastModifiedTime);
    nn::Result SetRootCa(u32 inCaCertId);
    nn::Result SetClientCert(u32 inClientCertId);
} 

All properties of the nn::boss::TaskAction class can be set and acquired using the SetProperty and GetProperty functions. These functions can be defined in the same way as the nn::boss::TaskPolicy class definition.

Providing Access Point Information

Call the SetApInfo function to specify information to be provided to an access point (AP) for an HTTP query. This allows you to select AP information to be sent from the Nintendo Zone access point to the BOSS data server, when infrastructure communication is occurring via a Nintendo Zone access point using AP information provided in the form of an HTTP request query. The query which is provided can be used only when you need to add changes to the task processing when connecting via the Nintendo Zone. One example would be downloading different data only when connecting to the Nintendo Zone.

Warning:

Items with access point information provided do not pass through Lotcheck. If you are using tasks with access point information provided, be sure to contact support@noa.com early in the product planning process.

Table 4-11. Access Point Information Provided to an HTTP Request

Query

Information Provided

apgroup

Information that can be identified at the access point group level (such as company name).

aparea

Information that can be identified at the access point location level (such as state or prefecture).

ap

Information that can be identified at the access point level.

Specify access point information to provide from the following definitions (select only one).

Table 4-12. Specifying AP Information to Provide to an HTTP Request

Definition

Description

APINFOTYPE_APGROUP

Provide apgroup.

Specify if applying to distribute according to Nintendo Zone operators.

APINFOTYPE_APAREA

Provide aparea.

Specify if applying to distribute according to Nintendo Zone area.

APINFOTYPE_AP

Provide ap.

Specify if applying to distribute according to Nintendo Zone, other than according to Nintendo Zone operator or Nintendo Zone area.

Providing System Settings Information

Call the SetCfgInfo function to specify the provision of System Settings information to an HTTP query. This allows you to provide system information to a query from an HTTP request. This may be used (for example) for downloading different data using the language setting of a system connected to the client server.

Note:

This feature is specific to the BOSS service, using a client server. Providing System Settings information with a BOSS service, using a Nintendo server, has no effect.

If you are considering an independent server using the provided information, consult with Nintendo (support@noa.com).

The definitions listed below are used in specifying system information to be provided. Multiple information items can be granted simultaneously, by setting multiple values using a bitwise OR.

Table 4-13. Specifying System Settings Information to Provide to an HTTP Request

Definition

Description

CFGINFOTYPE_NONE

Do not provide System Settings information.

CFGINFOTYPE_COUNTRY

Provide country code in System Settings information.

CFGINFOTYPE_LANGUAGE

Provide the language code in System Settings information.

Adding an HTTP Request Header

You can include a proprietary HTTP request header in the connection, by calling the AddHeaderField function. To add an HTTP request header, its label must have a maximum length of 32 characters and its value a maximum length of 256 characters. The maximum number of headers allowable is 3.

Specifying Final Update Time at the First Execution

Call the SetLastModifiedTime function to specify the string value to enter in the If-Modified-Since header field for the first time the task is executed. When this specification is not performed, an If-Modified-Since header field is not provided the first time the task is executed. For the second execution and thereafter, an If-Modified-Since header field is provided containing the time of the last update for data acquired during the prior execution (the value in the HTTP response’s Last-Modified field). When executing, if the task does not result in acquiring the data due to its not having been updated (for example, if a "304 Not Modified" status is returned by the server), the execution count is reduced by 1.

In addition, properties setting functions specific to device-internal certificates may also be used. (These functions are inherited from the nn::boss::TaskAction class.)

Code 4-24. Functions for Setting Properties Specific to Device-Internal Certificates
class nn::boss::TaskAction
{
    nn::Result SetRootCa(u32 inCaCertId);
    nn::Result SetClientCert(u32 inClientCertId);
} 

You can configure the settings that determine which certificates embedded in a device are used by using the SetRootCa and SetClientCert functions. Up to three root CA certificates can be set, whereas only one client certificate can be set.

Setting Proprietary Certificates

The functions shown below can be used to set a proprietary certificate when using a proprietary root CA certificate or client certificate to connect when executing a task. There is no need to call them when not using proprietary certificates.

Code 4-25. Setting Proprietary Certificates
nn::Result nn::boss::RegisterPrivateRootCa(
                        const u8* pCertData, size_t certDataSize);
nn::Result nn::boss::RegisterPrivateClientCert(
                        const u8* pCertData, size_t certDataSize,
                        const u8* pPrivateKeyData, size_t privateKeyDataSize); 

A proprietary certificate and a certificate embedded in a device can be used in combination. Only one certificate (either the root CA certificate or the client certificate) can be set as the proprietary certificate. When duplicate settings occur, the last certificate set will be enabled.

To use a proprietary certificate, call the SetPrivateRootCa or SetPrivateClientCert member function from the TaskActionBase class. Only the root CA certificate can be used in combination with a certificate embedded in a device.

Note:

Registering tasks to connect to servers other than the BOSS data server provided by Nintendo is currently not permitted.

4.2.1.4. Registering and Running Tasks

Call nn::boss::RegisterTask with each of the four task property classes as arguments to register a task.

Code 4-26. Registering a Task
nn::Result nn::boss::RegisterTask(nn::boss::Task* pTask,
                                  nn::boss::TaskPolicy* pPolicy,
                                  nn::boss::TaskAction* pAction,
                                  nn::boss::TaskOption* pOption=NULL,
                                  u8 taskStep=DEFAULT_STEP_ID); 
Note:

The pOption and taskStep parameters are for future expansion and are currently unsupported. Do not specify anything for these arguments.

Just registering a task will not cause it to be executed. You must also call the nn::boss::Task class’s Start or StartImmediate member functions to tell the BOSS daemon to run the task.

Code 4-27. Running, Canceling, and Waiting to Finish a Task
class nn::boss::Task
{
    nn::Result Start(void);
    nn::Result StartBgImmediate(void);
    nn::Result StartImmediate(void);
    nn::Result Cancel(void);
    nn::Result WaitFinish(void);
    nn::Result WaitFinish(const nn::fnd::TimeSpan& timeout);
} 

Tasks marked for execution with the Start function are scheduled and run by the BOSS daemon in the background. The daemon automatically handles Internet connections for tasks run in the background. If a connection is lost while a background task is running, the daemon pauses the task. Tasks in a resume state are resumed from the point of interruption the next time an Internet connection can be made.

Tasks begun with the Start function can be halted or removed from the scheduling queue by calling the Cancel function. Call Start again to tell the daemon to add a halted task back into the scheduling queue.

Call StartImmediate to tell the daemon to run a task in the foreground. Tasks marked for execution with the StartImmediate function are run right away. Because such tasks are run in the foreground, the application must handle connecting to the Internet, as the BOSS daemon does not handle these connections. Unlike running with the Start function, tasks run using StartImmediate return an error when the connection is lost while the task is running. Interrupted tasks cannot be resumed.

You can also use StartImmediate to run a task already queued up using the Start function, without having to wait until the execution interval has passed. However, note that this again runs the task in the foreground, and that the application must handle connecting to the Internet.

Note:

While a task is executing, other tasks will not execute (even if the start-execution date of another task has been reached). However, if you execute a task immediately using StartImmediate, tasks executing in the background are stopped and resume after the immediate-execution task is finished.

Warning:

When a task originally started with an instruction from the Start function is executed using the StartImmediate function, the task transitions to the retry state if its original execution is still in progress. This does not cause a problem as BOSS normally does not execute tasks while the application is running. However, when BOSS has been authorized to run while the application is running (this can be set in the NDM library), programmers must take this into consideration. Handle applications of this sort as follows.

  • Cancel the task by calling the Cancel function, and then execute the StartImmediate function.

Call the StartBgImmediate function to tell the daemon to start tasks in the background immediately. Use this function to begin a task’s first scheduled execution immediately. If you call the StartBgImmediate function on a task that was previously scheduled to run as the result of a call to the Start or StartImmediate functions, the task is not run immediately a second time. If you want the task to run immediately every time it is called, use the StartImmediate function instead. If you need to give additional background instruction for immediate execution to a task that has already been scheduled, cancel its execution using the Cancel function, and then call the StartBgImmediate function. Note that calling StartImmediate cancels the execution of other tasks, whereas StartBgImmediate runs the targeted task after any currently running tasks complete.

Call the WaitFinish function to wait for one execution of a task to complete. Use this for the application to wait for task completion in cases, such as: tasks with an execution count of one, or tasks run immediately with StartImmediate. Calling the StartImmediate function cancels execution of other tasks, while the StartBgImmediate function executes the task after other tasks have completed execution. We recommend calling WaitFinish using either a dedicated thread or using the overloaded version and specifying a value for the timeout parameter. When specifying a timeout value, the function returns with ResultWaitFinishTimeout if the task has not completed within the timeout period, passing control back to the application.

The arrival of new data can be used as a method of waiting for task execution to complete. Use nn::boss::GetNewArrivalFlag or nn::boss::RegisterNewArrivalEvent to check newly arrived data. For more information about these functions, see 4.2.2.6. Checking the New Arrival Flag and Waiting for a Data New Arrival Event.

There are also methods of polling task status using nn::boss::GetState and nn::boss::GetStateDetail.

Registering Immediate Execution Tasks

The nn::boss::RegisterImmediateTask function is provided for registering tasks that can only be executed immediately. Always register immediate execution tasks using this function, and execute them in the foreground. The guidelines restrict the number of tasks that can be registered in one application, but immediate execution tasks registered with this function are not counted among those tasks.

Code 4-28. Registering Immediate Execution Tasks
nn::Result nn::boss::RegisterImmediateTask(
        nn::boss::Task* pTask, nn::boss::TaskAction* pAction,
        nn::boss::TaskPolicy* pPolicy=NULL, nn::boss::TaskOption* pOption=NULL,
        u8 taskStep=DEFAULT_STEP_ID); 

For pTask instead of using the nn::boss:Task class, specify its subclass, the nn::boss::FgOnlyTask class. When this class is used, task IDs registered for immediate execution defined in nn::boss::FG_ONLY_TASK_ID are automatically specified. It is not necessary to specify the task ID. Even if execution count and execution intervals have been set in pPolicy, these settings are disabled.

Task execution must occur with the nn::boss::FgOnlyTask::StartImmediate function. Executing a task with any other function returns an error.

The Maximum Number of Tasks That Can Be Registered and Automatic Deletion

The maximum number of tasks that can be registered in BOSS is 127. (Tasks for immediate execution are not included.) This number represents the maximum value of the total number of tasks registered by all applications (including embedded applications). The maximum number of tasks that can be registered by a single application is limited by the CTR Guidelines. If an application attempts to register a new task when the number of registered tasks has already reached the maximum, BOSS automatically deletes a task for which the execution count is 0 and accepts the registration of the new task. This is not just limited to tasks of the application attempting registration. A search is made among all tasks for a task to delete. If there is no task with an execution count of 0, the product of execution counts and execution interval is calculated, the task with the smallest result is deleted, and registration of the new task is accepted.

If an application is not started up for a long time, there is a possibility that its previously registered tasks have been deleted by BOSS using this automatic deletion process. So applications that use BOSS must be able to handle cases where their own tasks have been deleted. You must implement a process that (for example) checks whether an application has any registered tasks when that application starts up and, if tasks are not registered, prompts for user confirmation to register the tasks.

4.2.1.5. Task Information

Use the member functions of the nn::boss::Task class to get information about a task, such as its state or execution result.

Code 4-29. Getting Task Information
class nn::boss::Task
{
    TaskServiceStatus GetServiceStatus(void);
    TaskStateCode     GetState(bool acknowledge=false, 
                               u32* pCount=NULL, u8* pStepID=NULL);
    u32               GetHttpStatusCode(u32* pCount=NULL, u8* pStepID=NULL);
    TaskResultCode    GetResult(u32* pCount=NULL, u8* pStepID=NULL);
    nn::Result        GetStateDetail(TaskStatus* pStatus, 
                                     bool acknowledge=false, u8* pStepID=NULL,
                                     u8 taskStep=CURRENT_STEP_ID);
    nn::Result        GetError(TaskError* pTaskError, u8* pStepID=NULL,
                               u8 taskStep=CURRENT_STEP_ID);
    nn::Result        GetInfo(TaskPolicy* pPolicy, TaskAction* pAction,
                              TaskOption* pOption, u8 taskStep=CURRENT_STEP_ID);
    nn::Result        GetActivePriority(TaskPriority* pPriority);
} 

For the functions above that have a pCount parameter, pass a pointer to a u32 variable instead of NULL to have the function return the execution count for a task. The pStepID parameter cannot be used in the current version.

Warning:

The task execution count and information for tasks acquired returned in pCount can be individually obtained in the library. There is a slight time lag as a result, so information does not necessarily match precisely.

Call the GetServiceStatus function to get the state of the server the task is connecting to (such as SERVICE_AVAILABLE or SERVICE_TERMINATED). The server sends its state when the task runs.

A return value of SERVICE_AVAILABLE indicates that the service is running. A return value of SERVICE_TERMINATED indicates that the service is running. The function returns a value of SERVICE_UNKNOWN when a task has not yet been executed or when a connection attempt fails out in a network error. If the function itself fails, it returns a value of GET_SERVICE_STATUS_ERROR.

Warning:

The system checks whether a service has terminated by checking the response from the server when the task runs to determine whether the response includes a flag indicating that the service has terminated (the service termination flag). This flag is set by the application developer using the BOSS data server.

Call the GetState function to get the state of the task. If the function itself fails, it returns a value of GET_TASK_STATE_ERROR. To ensure that accurate execution results for a task can be obtained, task execution results are stored from the time a task completes execution until the next task executes (in other words, while the status is TASK_WAITING_TIMER). The GetState function returns the execution result of the last task (TASK_DONE, TASK_ERROR, or TASK_RETRY) even though the actual current status is TASK_WAITING_TIMER.

To get the actual current status (rather than the result being stored) call the GetState function while specifying true in the acknowledge parameter. Note that the stored result is released and the actual status (TASK_WAITING_TIMER) can be obtained when the task result is obtained using the GetState function afterward.

Table 4-14. Task States

Definition

Description

TASK_STOPPED

Stopped, and excluded from scheduling.

TASK_WAITING_TIMER

Waiting for the task execution interval to pass.

TASK_WAITING

The task execution interval has passed, but the task is still waiting to run for some reason (such as not being connected to the Internet or because another higher-priority task is running).

TASK_RUNNING

The task is now running.

TASK_PAUSED

Task execution is paused.

TASK_REGISTERED

The state right after registering a task, but before starting it.

TASK_DONE

The task has finished.

TASK_ERROR

An unrecoverable error occurred while the task was running.

TASK_RETRY

Connection was lost during execution and the task is now waiting to retry (resume).

Call the GetHTTPStatusCode function to get the HTTP status code when a task is running. If the function itself fails, it returns a value of U32_CANNOT_GET_DATA.

Call the GetResult function to get the result of a task. If the function itself fails, it returns a value of GET_TASK_RESULT_ERROR. For the return value definitions, see the definition of the TaskResultCode enumerated type in the nn/boss/boss_Const.h file. The return value called during the BOSS library and returned as an error by functions from other libraries becomes a value larger than the value that exists in the TaskResultCode enumerated type UNKNOWN_ERROR + the module ID for the module that generated the error. For the module ID definitions, see nn/Result.h. FS_UNKNOWN_ERROR is returned when an error occurs for file operations at task execution due to any of the following reasons.

  • There is no space available on the SD card.
  • The SD card is write-protected.
  • An SD card is not inserted.
  • A different SD card than the one used at the time the task was registered is inserted, meaning that BOSS storage for writing and reading task data is not available. (BOSS storage is covered in the sections that follow.)
  • The SD card is damaged.

Call the GetStateDetail function to get a task’s state. The difference between this function and the GetState function is that you can use the GetProperty function as an instance of the nn::boss::TaskStatus class returned in the pStatus parameter to get more detailed state information.

Table 4-15. Property IDs Specifiable for the nn::boss::TaskStatus Class

Property ID

Type

Property

TASK_STATE_CODE

TaskStateCode

Task state (same as for GetState).

TASK_RESULT_CODE

TaskResultCode

Execution result (same as for GetResult).

TASK_COMM_ERROR_CODE

u32

Communication error code (same as for GetHttpStatusCode).

TASK_CURRENT_PRIORITY

u32

Current task execution priority.

TASK_EXECUTE_COUNT

u32

Current task execution count.

(It takes some time for this to reflect the most recent value, so we recommend getting the property of the same name from the nn::boss::TaskPolicy class instead.)

TASK_PENDING_TIME

u32

Time in the task execution interval (in seconds).

TASK_START_TIME

s64

Task start time (in seconds, starting from 2000-01-01).

TASK_PROGRESS

u32

Size of downloaded data.

TASK_DATA_SIZE

u32

Total size of the data to download (value of the Content-Length HTTP response field).

TASK_SERVICE_STATUS

TaskServiceStatus

Service availability status.

TASK_SERVICE_TERMINATED

bool

Service-terminated flag.

TASK_LAST_MODIFIED_TIME

char[MAX_LASTMODIFIED_LENGTH]

Last time data to download was modified (value of the Last-Modified HTTP response field).

Call the GetError function to get any error that occurred during task execution. The difference between the GetCommErrorCode and GetResult functions is that you can use the GetProperty function as an instance of the nn::boss::TaskError class, returned in the pTaskError parameter, to get more detailed information.

Table 4-16. Property IDs Specifiable for the nn::boss::TaskError Class

Property ID

Type

Property

TASK_ERROR_RESULT_CODE

TaskResultCode

Task result (only for errors; same as for GetResult).

TASK_ERROR_CODE

bit32

Cause of an error in task execution.

TASK_ERROR_MESSAGE

char[MAX_ERROR_MESSAGE]

Communication error message during task execution.

Call the GetActivePriority function to get a task's current execution priority.

4.2.1.6. Getting a Task List

Call the nn::boss::GetTaskIdList function to get a list of tasks registered by the application.

Code 4-30. Getting a Task List
nn::Result nn::boss::GetTaskIdList(nn::boss::TaskIdList* pTaskIdList); 

For the pTaskIdList parameter, specify a pointer to an instance of the nn::boss:TaskIdList class (generated by the application). An instance is roughly 1 KB in size, so take note of the stack and heap sizes when generating an instance. The nn::boss::TaskIdList class is defined as follows.

Code 4-31. nn::boss::TaskIdList Class
class nn::boss::TaskIdList
{
    explicit TaskIdList(void);
    virtual ~TaskIdList(void);
    u16 GetSize(void);
    char* GetTaskId(u16 index);
} 

Call the GetSize function to get the number of tasks stored in a list. Call the GetTaskId function and specify an index to get the ID of a task stored in a list. The function returns NULL if the specified index is out of bounds.

Note:

The nn::boss::GetStepIdList function is not currently usable.

4.2.1.7. Changing a Task

Call the nn::boss::ReconfigureTask function to change a task’s property settings. You can only change those properties that can be set by the nn::boss::TaskPolicy function. Do not specify a step ID.

Code 4-32. Changing a Task
nn::Result nn::boss::ReconfigureTask(nn::boss::Task* pTask,
                                     nn::boss::TaskPolicy* pPolicy,
                                     u8 taskStep=DEFAULT_STEP_ID); 

Use the nn::boss::Task member functions to change a task’s execution count or execution interval.

Code 4-33. Setting Properties Using the nn::boss::Task Class
class nn::boss::Task
{
    nn::Result UpdateInterval(u32 interval);
    nn::Result UpdateIntervalWithSec(u32 intervalSec);
    nn::Result UpdateCount(u32 count);
    u32 GetInterval(void);
    u32 GetIntervalSec(void);
    u32 GetCount(void);
} 

You can call the UpdateIntervalWithSec function to specify an execution interval in seconds, but note that this function is only for debugging purposes.

4.2.1.8. Unregistering a Task

Call the nn::boss::UnregisterTask function to unregister a task.

Code 4-34. Unregistering a Task
nn::Result nn::boss::UnregisterTask(nn::boss::Task* pTask,
                                    u8 taskStep=DEFAULT_STEP_ID); 

When you unregister a task, the working files created for that task in BOSS storage are deleted. The function returns an error (nn::boss::ResultFileAccess) if it fails to delete the working files (for example, because the SD card was removed), but the task itself will be successfully unregistered. You are not required to handle this error because the working files will still be deleted when the expanded save data is deleted. Although you cannot delete working files directly, you can delete them by reregistering a task with the same task ID and then unregistering it.

Note:

The taskStep parameter cannot be used at present. Do not specify anything for this parameter.

4.2.1.9. Finalizing the BOSS Library

After you finish using BOSS, you must call the nn::boss::Finalize function to finalize the BOSS library.

Code 4-35. Finalizing the BOSS Library
nn::Result nn::boss::Finalize(void); 

4.2.2. Nintendo Archive Download (NADL) Tasks

An NADL task is a BOSS task that downloads data from the BOSS data server via HTTP or HTTPS.

Data must be registered on the BOSS data server for an application to download it. Data registered on the BOSS data server is converted to the proprietary Nintendo Serendipitous (NS) archive format. NS archives can contain multiple data files. Accordingly, you can register multiple data files in a single archive on the BOSS server, so that users can download multiple files (such as application data files and related notifications) by running a single task.

Figure 4-7. Process Flow When Downloading Data Using an NADL Task

Data Boss Data Server BOSS decrypts NS archive, verifies the data, and distributes the NS data.  NS Data 1, NS Data 1 (Extra Data) NS Data 2 (Notification) NS Archive NSA Header NS Data 2 NS Archives can contain multiple files. This sample archive includes extra data and a notification.  Application Expanded Save Data Region NSD BOSS Storage System Expanded Save Data Region NSD BOSS Storage BOSS

For more information about using the BOSS Data Server, see the BOSS Management Tool Operations Manual. The manual can be downloaded from the Help link on the screen that is displayed after you log in to the BOSS Data Server. The manual also includes information about distributed data and operations, so read it before operating the BOSS Data Server.

Following are the primary operations performed with the management tool.

  • Creation of notifications and distributed data
  • Management of the distribution schedule for notifications and distributed data
  • Test distributions during application development
  • Obtaining the distribution log that is sent to users after the actual start

To use the BOSS Data Server, apply to be a "User who Can Access the BOSS Data Server" when applying to use BOSS tasks on the Online title MAnagement System (OMAS). Upon approval of your application, access information for the BOSS Data Server is sent in an email.

4.2.2.1. NS Archives and NS Data

All data included in an NS archive (NS data) is encrypted, signed, and hashed. As a result, BOSS can handle not only NS data decryption, but also data verification to check for tampering or spoofing (to ensure that no invalid data is downloaded).

You can set a new arrival flag for an NS archive. Once this flag is set, applications display an update indicator on their icons after downloading the archive. The new arrival flag is set separately for each application managed using BOSS, and the system checks for the new arrival flag and displays the update indicator accordingly. The system handles all of this, so applications do not need to do anything about this update indicator display.

When the system downloads NS data that includes notifications, it displays the update indicator on the Notifications applet (even if the new arrival flag is OFF, disabled). However, this only applies to the update indicator on the Notifications applet; the update indicator behavior for the application's icon is still controlled by the new arrival flag.

NS data can include the following.

Table 4-17. NS Data Types

Type

Description

Extra data.

Data for various extras used in an application, such as extra items or game levels.

Notifications

Notifications sent via BOSS.

Downloaded contextual banner data.

Data for replacing the text or textures displayed in CTR title banners.

Data Store data

Data downloaded with the Data Store download task.

Each NS data file includes a 32-bit data type designator. The data type consists of two types. The most-significant 16 bits specify the global data type indicating an NS data file, and the least-significant 16 bits specify the private data type. Global data types are shared among all applications and must be specified from the table above. Private data type values can be freely assigned by each application. This private data type is used as a search term when searching NS data, as explained in 4.2.2.6. Checking the New Arrival Flag and Waiting for a Data New Arrival Event. Properly planned private data types allow you to search NS data more efficiently.

Note that NS data is discarded if there is no BOSS storage for the receiving application when the BOSS library distributes the NS data to its various storage locations. For example, this situation applies when the application has never been started, the application has been started before but has never registered BOSS storage, or when the user has deleted the application’s extra data. NS data also includes the unique ID of the target application embedded within it. In the NS data’s unique ID, the unique ID of the application using BOSS is embedded based on the server. For that reason, developers cannot specify an arbitrary unique ID (target) to data. Downloaded NS data is stored in the BOSS storage of the application whose unique ID is embedded within, regardless of which application downloaded the task that was used to download.

Warning:

Be sure to avoid specifying the wrong URL upon task registration or downloading NS data targeting other applications.

Each NS data file is also assigned a serial ID, which must be unique among all NS data for a specific application, and a version number. Both are 32-bit values. Serial IDs are used by applications to specify NS data to read or delete. Versions are used by BOSS when deciding whether to update NS data. When BOSS downloads data with the same serial ID as existing NS data, BOSS then compares version numbers and only updates (that is, overwrites) the NS data if the downloaded data’s version number is newer.

Note:

The serial ID and version for NS data can be set on the BOSS management site. However, because the serial ID and version for Notifications and Data Store data are set automatically, there is nothing the developer can do to set them. For more information, see the manual available on the BOSS management site.

Warning:

Serial IDs in the range from 4294901760 through 4294967295 (0xFFFF0000 through 0xFFFFFFFF) are reserved for the system and are prohibited from use by general applications. Use a value outside of this range (1 through 4294901759 (0xFFFEFFFF)) when setting a serial ID on the BOSS data server's BOSS management website.

NS data includes various properties that can be accessed by the application, such as the data’s serial ID, data type, and size. However, notifications are automatically processed by the system and cannot be directly loaded by applications. Although downloaded contextual banner data is also processed automatically by the system, it can be loaded by applications.

NS archives can contain notifications. You can set the OptOut flag separately for each BOSS storage location to prevent such notifications from being processed and displayed in the Notifications applet.

Figure 4-8. Processing Flow When the OptOut Flag Is Set

Data BOSS Data Server NS Data 1 NS Data 1 (Extra data) NS Data 2 (Notification) NS Archive NSA Header NS Data 2 When downloaded by a task with the OptOut flag set, notifications in the NS archive are discarded.  Application Expanded Save Data Region NSD BOSS Storage System Expanded Save Data Region BOSS Storage BOSS Task OptOut flag set

Call the nn::boss::SetOptoutFlag and nn::boss::GetOptoutFlag functions to set and get the OptOut flag.

Code 4-36. Setting and Getting the OptOut Flag
nn::Result nn::boss::SetOptoutFlag(bool flag);
nn::Result nn::boss::GetOptoutFlag(bool* pFlag); 

Call nn::boss::SetOptoutFlag and pass true for the flag parameter to set the OptOut flag and ignore any notifications that might be included in downloaded NS archives. (BOSS discards any such notifications.) Call the nn::boss::GetOptoutFlag function to get the current setting.

4.2.2.2. BOSS Storage

Extra data and downloaded contextual banner data files are saved to an archive memory region called BOSS storage, which is created in the expanded save data region specified by the application. Although BOSS storage is created in the application’s expanded save data region, applications cannot access it directly. Applications specify to BOSS how much of the expanded save data memory region to use for BOSS storage.

After BOSS storage is full, BOSS automatically deletes data starting from the earliest (the data with the lowest serial ID) so that downloaded data does not exceed the specified storage capacity. You can also specify the maximum number of data files when registering BOSS storage from within the application. When you attempt to save data in excess of the maximum number of data files, BOSS deletes data, starting with the earliest data first, so that the amount of data in storage never exceeds the maximum amount. The maximum number of data files defaults to 2000 unless otherwise specified. Applications must factor this in when specifying the size and number of files for BOSS storage, to accommodate both the size and number of files of downloaded data. In addition, when BOSS storage has been newly created in expanded save data, a maximum value is set for the number of files that can be created in the expanded save data. Because the NS data files in BOSS storage also count toward the total number of files in expanded save data, be sure to set a value that takes the number of instances of NS data being saved in BOSS storage into account when setting the maximum number of files to be created in expanded save data.

Warning:

If even the deletion of earlier data would not free enough memory to store the data to be downloaded, the task is canceled and an error is generated (NSA_ERROR_STORAGE_INSUFFICIENCY ). This can occur in the following scenarios.

  • The size of data to download exceeds the size of BOSS storage.
  • The data to download is a newer version of data already downloaded, and the size of the old and new versions combined exceeds the size of BOSS storage.

This first scenario is obvious, but you need to be careful about the second scenario for data that might be updated to a newer version. When you download a newer version of downloaded data, the new version of the data is first downloaded as a temporary file, the old version is then deleted, and the temporary file is renamed with the official filename. In other words, both the old and new versions temporarily exist in BOSS storage, so their combined size must be less than the size of BOSS storage.

This error does not occur if BOSS storage is greater than double the size of the maximum size of NS data.

Downloaded NS data is saved temporarily to the application's BOSS storage before the different parts of the data are saved to their final destinations. Consequently, notification data is briefly stored in the application's BOSS storage, as shown in Figure 4-7, even though it will ultimately be saved to the system's BOSS storage. If there are already N NS data files in a BOSS storage region and N is its maximum number of data files, notification data downloaded to that region may cause an existing NS data file to be deleted to make room for temporarily saving the new notification data. That temporary data could then be deleted after being saved to its final destination. Consequently, the number of NS data files in that application's BOSS storage is decreased by one (N-1) after downloading new notification data. If your tasks distribute or download notification data, take this behavior into account when configuring your BOSS storage.

Note:

Notifications data that is temporarily saved in BOSS storage is immediately moved to expanded save data on the console. Notifications are not received more than once as long as the task is not removed and re-registered. Previously downloaded data remains on the system and the serial ID and version are compared.

Warning:

If the number of files in expanded save data (including the number of instances of NS data) reaches the maximum value, NS data downloaded after that point cannot be saved, and an error results upon execution of each task.

NS data saved to BOSS storage has a header of 52 bytes added to the front of the file. Consequently, when specifying the size of BOSS storage, be sure to take this into consideration.

BOSS storage is only meant to serve as the BOSS working memory region, and data might be automatically deleted. Consequently, do not leave any data that you want to keep permanently as extra data in BOSS storage as NS data. Instead, we recommend loading this NS data via BOSS and saving a copy as a separate file in the expanded save data region. Also, when a lot of data is being stored in BOSS storage, routines that target all data in BOSS storage become less efficient. We also strongly recommend that you delete data that will no longer be used from BOSS storage. As described above, you can also delete data from BOSS storage if you permanently save the NS data outside BOSS storage.

When an expanded save data region is shared among multiple titles in a series, an application in that series can access downloaded data for any title in the same series.

Developers must submit an application to Nintendo (support@noa.com) to use the BOSS service. In response, Nintendo will provide dedicated URLs for each application. BOSS communication is via the HTTPS protocol using the 3DS system’s built-in CA certificates.

Lotcheck will verify whether applications that use BOSS services register tasks using the settings that were specified in the application to use BOSS services that was submitted to Nintendo.

Warning:

The NS data file serial ID must be unique within the group of files belonging to the same application (or to the same series for series data).

Downloading Notifications Only

Because notifications are stored in the expanded save data of the system, NS data does not accumulate in BOSS storage for applications that download only notifications. However, even in such cases, you must register for BOSS storage for the amount needed to temporarily store notification data. This requirement occurs because hash and signature authentication is carried out after NS data is temporarily stored in BOSS storage. These processes must succeed first, and then NS data is moved into the BOSS storage where it will be temporarily stored. In other words, because the BOSS storage used to store the data is the same as that used to store data for applications that have registered tasks, the NS data remains behind unchanged. In the case of notification data, it is moved to the expanded save data of the system.

60 KB of BOSS storage is required in order to download the maximum amount of notification data (when using 50 KB of attachment data).

Warning:

When using expanded save data only to distribute notifications, check at regular intervals (such as on startup) to make sure that the expanded save data can be mounted normally. Downloaded data is temporarily saved to the expanded save data region, and if the expanded save data is corrupted or deleted, notifications will no longer be received, even if the task still exists.

4.2.2.3. Required Steps to Process an NADL Task

The following figure shows the required steps from registering an NADL task using BOSS through processing the downloaded data.

Figure 4-9. Required Steps to Process an NADL Task

Creating Expanded Save Data Registering BOSS Storage Registering an NADL Task Checking the New Arrival Flag Checking for Downloaded Data Waiting for a Data New Arrival Event Waiting for Task Execution to Complete Checking for New Downloaded Data Processing Downloaded Data When Polling for Task Results When Waiting for Task Execution to Complete Loading Downloaded Data Processing Downloaded Data New Downloaded Data Found No New Downloaded Data Polling Task State

The following table gives an overview of each step.

Table 4-18. Overview of NADL Task Processing

Processing Step

Description

Create Expanded Save Data

The application must first create an expanded save data region before it can register BOSS storage in which to save data downloaded by NADL tasks.

For more information about creating expanded save data regions, see the 3DS Programming Manual: System.

Register BOSS Storage

Register the BOSS storage for saving the data downloaded by an NADL task.

For more information, see 4.2.2.4. Preparing to use BOSS.

Register an NADL Task

Configure the actions for an NADL task and register the task with BOSS.

For more information, see 4.2.2.5. Registering a Nintendo Archive Download (NADL) Task.

Check the New Arrival Flag

Check the new arrival flags managed by the library.

For more information, see 4.2.2.6. Checking the New Arrival Flag and Waiting for a Data New Arrival Event.

Check for Downloaded Data

Get a list of the downloaded data and check whether there is any newly downloaded data. For already-processed data, the application must handle any other operations as necessary: deletion, serial ID recording, setting the data’s status from unread to read, and so on.

For more information, see 4.2.2.7. Checking for Downloaded Data.

Poll Task State

Poll the state of the NADL task to determine whether the state is "completed."

For more information, see 4.2.1.5. Task Information.

Wait for a Data New Arrival Event

Register an event with the library and wait for that event to enter the signaled state.

For more information, see 4.2.2.6. Checking the New Arrival Flag and Waiting for a Data New Arrival Event.

Wait for Task Execution to Complete

Run the NADL task in the foreground and wait for it to complete.

For more information, see 4.2.1.4. Registering and Running Tasks.

Load Downloaded Data

Access the NS data saved in BOSS storage and load it into a buffer allocated by the application.

For more information, see 4.2.2.8. Loading Downloaded Data.

Process Downloaded Data

Process the obtained downloaded data in the application.

4.2.2.4. Preparing to Use BOSS

BOSS storage must already be registered before you can register and run NADL tasks.

Code 4-37. Registering and Unregistering BOSS Storage
nn::Result nn::boss::GetStorageInfo(size_t* pStorageSize=NULL);
nn::Result nn::boss::GetStorageInfo(size_t* pStorageSize, u16* pEntryCount);
nn::Result nn::boss::RegisterStorage(
        bit32 storageId, size_t storageSize, 
        nn::boss::StorageType storageType=nn::boss::USER_EXT_SAVEDATA_STORAGE);
nn::Result nn::boss::RegisterStorage(
        bit32 storageId, size_t storageSize, u16 entryCount, 
        nn::boss::StorageType storageType=nn::boss::USER_EXT_SAVEDATA_STORAGE);
nn::Result nn::boss::UnregisterStorage(void); 

Before registering BOSS storage, check whether BOSS storage has been created by calling nn::boss::GetStorageInfo. If it has not yet been created, the function returns nn::boss::ResultStorageNotFound. For pStorageSize and pEntryCount, specify pointers to variables that store, respectively, the size and maximum number of data files for the BOSS storage.

Call nn::boss:RegisterStorage to create BOSS storage in the expanded save data memory region specified by storageId. This created BOSS storage can store up to an all-files combined total size of storageSize. Use the overloaded version that has an entryCount parameter to specify the maximum number of data files that can be registered to the BOSS storage.

Call nn::boss:UnregisterStorage to unregister BOSS storage. Attempting to register BOSS storage in an expanded save data region to which the application does not have access permission returns an nn::boss::ResultStorageAccessPermission error.

Each application can only register one BOSS storage area. To change the expanded save data region used as BOSS storage by an application, first call nn::boss::UnregisterStorage to unregister, and then call nn::boss::RegisterStorage again to create a new BOSS storage area.

Warning:

After changing the expanded save data memory region used for BOSS storage, you can no longer access any NS data saved in the previous BOSS storage area.

We recommend creating BOSS storage in one expanded save data region and keeping it there.

Note:

For more information about accessing the expanded save data memory region, see the 3DS Programming Manual: System.

For more information about notification data, see the Applet Specification. For more information about downloaded contextual banner data, see Banner Overview and ctr_makedlexbanner.

Handling the Deletion of Expanded Save Data by Users

Note the possibility that a user may delete expanded save data in System Settings. If such data is deleted, the application must re-create the expanded save data to use BOSS again. An application that uses BOSS must always be able to handle the deletion of expanded save data by users. Applications are required to implement some process for handling this situation. One example for handling this is to check for expanded save data when the application starts, and if none exists, prompt for user confirmation to create expanded save data.

4.2.2.5. Registering a Nintendo Archive Download (NADL) Task

Use the nn::boss::NsaDownloadAction class to set the actions for an NADL task. Create an instance of the class and then call Initialize to set its URL property.

Code 4-38. Initializing the nn::boss::NsaDownloadAction Class
class nn::boss::NsaDownloadAction : public nn::boss::TaskAction
{
    nn::Result Initialize(const char* pUrl);
} 

For pUrl, specify the URL of the NS archive to download. This URL value can be up to 512 characters, including the NULL terminator.

The URL for the NS archive takes the following format.

https://<CDN domain>/<environment ID>/<common parameter>/<BOSS code>/<task ID>/<optional filename>

To distribute NS archives in different languages, you must use a format that contains language information (ISO 639-1 alpha-2).

https://<CDN domain>/<environment ID>/<common parameter>/<BOSS code>/<task ID>/<language information>/<optional filename>

To distribute NS archives in different languages and also to use both simplified and traditional Chinese characters in notifications, you must use a format that contains not only language information but also country information (ISO 3166-1 alpha-2).This is because simplified and traditional Chinese are both defined as Chinese (zh) in ISO 639-1 alpha-2, so the language information alone is not enough for the BOSS data server to determine which character set to use for the distribution.

https://<CDN domain>/<environment ID>/<common parameter>/<BOSS code>/<task ID>/<country information>/<language information>/<optional filename>

 

Warning:

If the user has changed the language setting or country setting in System Settings and tasks are not reregistered, a task that is distributed in different languages will download data in a language different from what is set in System Settings.

Note:

You must apply on OMAS to use the feature to distribute in different languages. If you intend to distribute using both simplified and traditional Chinese characters, indicate that fact in the relevant field on the application form.

Systems set to the China region (mainland China) display notifications using simplified Chinese characters, whereas systems set to the Taiwan region (Taiwan/Hong Kong) display notifications using traditional Chinese characters.

The NsaDownloadAction class inherits from the nn::boss::TaskAction class and also has member functions for setting common task actions.

Table 4-19. Valid Property IDs for the nn::boss::NsaDownloadAction Class

Property ID

Type

Property

ACTION_URL

char[MAX_URL_LENGTH]

Destination URL.

ACTION_HTTP_HEADER

struct httpRequestHeader[MAX_HTTP_HEADER]

Additional HTTP request header.

ACTION_CLIENT_CERT

u32

Built-in client certificate ID.

ACTION_ROOT_CA

u32

Built-in root CA certificate ID.

ACTION_AP_INFO

ApInfoType

AP information added to the HTTP request.

ACTION_CLIENT_CERT_NUM

u32

Number of built-in client certificates to register.

ACTION_ROOT_CA_NUM

u32

Number of built-in root CA certificates to register.


Unique NADL task action settings are described below.

Usable Root CA Certificates

The library automatically registers the NADL task’s root CA certificate, so the application does not need to do this.

The library registers two root CA certificates, specifically a root CA certificate used to connect to the BOSS data server for live distribution to retail products, and a root CA certificate used to connect to the BOSS data server for test distribution. Data for live distribution can only be downloaded from the BOSS data server using the retail (production) hardware. However, an exception is made for the library sample demos, and so data for live distribution can also be downloaded using the development hardware. Data for test distribution can be downloaded using both the development hardware and retail (production) hardware, but only if the DNS setting has been set to 210.128.103.149.

4.2.2.6. Checking the New Arrival Flag and Waiting for a Data New Arrival Event

Use the following functions to check whether any new data has been downloaded.

Code 4-39. Checking for New Data
nn::Result nn::boss::GetNewArrivalFlag(bool* pFlag);
nn::Result nn::boss::RegisterNewArrivalEvent(nn::os::Event* event); 

The nn::boss::GetNewArrivalFlag function returns true in its pFlag parameter if there is new data.

The nn::boss::RegisterNewArrivalEvent function signals the event class passed in its event parameter when new data is downloaded. The application must initialize this event class in advance.

Note:

Any downloaded data is not treated as new data if the NS archive’s new arrival flag is cleared. After downloading such data, the GetNewArrivalFlag function continues to return false, but the event passed to RegisterNewArrivalEvent is signaled.

4.2.2.7. Checking for Downloaded Data

After the task has finished running, the downloaded NS data is saved to the BOSS storage area of the expanded save data region specified in the task. You must first get a list of NS data serial IDs before you can access the NS data saved to BOSS storage.

Code 4-40. Getting a List of NS Data Serial IDs
nn::Result nn::boss::GetNsDataIdList(
                        u32 dataType, nn::boss::NsDataIdList* pNsDataId);
nn::Result nn::boss::GetNewDataNsDataIdList(
                        u32 dataType, nn::boss::NsDataIdList* pNsDataId); 

Call the nn::boss::GetNsDataIdList and nn::boss::GetNewDataNsDataIdList functions to get a list of the NS data files that the application can load. GetNsDataIdList gets a list of all such data in the descending order of the serial IDs, and GetNewDataNsDataIdList gets a list of only unread data.

The update indicator displayed on the application’s icon is cleared after calling either of these functions (that is, the new arrival flag obtained by nn::boss::GetNewArrivalFlag is set to false). Newly downloaded NS data is marked as unread. Call the nn::boss::NsData::SetReadFlag function to mark NS data as either read or unread. NS data is left as unread unless this setting is changed by the application.

Note:

When using the list of serial IDs to determine whether downloaded data must be processed, your application must identify the processed data in some way, such as by always deleting the data after processing, recording the serial IDs of processed data, or setting the processed NS data to read status.

When multiple titles in a series share a single expanded save data region, NS data downloaded via a task registered by a series title can be accessed by other titles in that same series. For more information, see Sharing NS Data.

Because these functions search through all data in BOSS storage, the more data stored in BOSS storage, the more time execution requires. To maintain efficiency of execution, we recommend that you regularly delete data in BOSS storage that is no longer being used.

For each of these functions, specify the NS data search conditions in the dataType parameter, and specify a pointer to an instance of the nn::boss::NsDataIdList class to store the NS data serial ID list in the pNsDataId parameter.

Specify the NS data search conditions as follows.

Specify DATA_TYPE_ALL to include all NS data in the search targets.

Otherwise, specify the search targets using a bitwise OR of the global data type and private data type. This stores on the list only NS data IDs that have a matching global data type and a private data type that results in a match when masked.

The global data types fall into three categories, as shown below.

Table 4-20. NS Data Types

Definition

Description

DATA_TYPE_APPDATA

Extra data.

DATA_TYPE_NEWS

Data displayed in the notification (the application cannot get this data).

DATA_TYPE_EXBANNER

Downloaded contextual banner data.

DATA_TYPE_DATASTORE

Data obtained with a Data Store download task.

The private data type is a 16-bit value and is used as the mask value for NS data (the least-significant 16 bits of the data type). NS data that has even one bit set to 1 that matches the corresponding bit in the specified private data type (in other words, bits where a bitwise AND of the two private data type values is not 0) is included in the list. For example, to include all extra data in the serial ID list, set the dataType parameter to a value of DATA_TYPE_APPDATA | 0x0000FFFF. Applications can use NS data types to get extra data that is sorted into custom categories.

Note:

If BOSS storage cannot be accessed normally—for example, because the SD card has been removed—the nn::boss::GetNsDataIdList function returns an nn::boss::ResultFileAccess error. The application cannot recover from this situation, so you must display the error code to the user. The BOSS sample demo sample_nadl_simple (CTR-SDK 7.1 and later) provides sample implementation of the display of error codes for this error and other unanticipated errors.

To instantiate the nn::boss::NsDataIdList class, you need a u32 array to store the serial IDs. The array must be big enough to contain all the serial IDs that can be obtained in a single search.

The search function returns nn:boss::ResultNsDataListSizeShortage if the array is not big enough to hold all of the serial IDs found in a search. If this happens, you can search again using the same instance (run the same function again) to get a list of serial IDs starting where the previous execution left off.

The search function returns nn::boss::ResultNsDataListUpdated if new NS data is added to BOSS storage while searching. If this happens, first call the Initialize member function of the nn::boss::NsDataIdList class instance to initialize the list, and then search to get the serial ID list starting again from the beginning.

The IsSuccess method on the nn::Result instance returned by the search function returns true after it has listed all NS data files matching the search terms.

Code 4-41. nn::boss::NsDataIdList Class
class nn::boss::NsDataIdList
{
    explicit NsDataIdList(u32* pSerial, u16 size);
    virtual ~NsDataIdList(void);
    void Initialize(void);
    u16 GetSize(void);
    u32 GetNsDataId(u16 index);
} 

You must call Initialize after generating an instance. Call Initialize on an instance that you have already used for a search to reset the search to get the list of serial IDs again from the beginning.

Call GetSize to get the number of serial IDs obtained.

Call GetNsDataId and specify the array index to get a serial ID. The function returns INVALID_SERIAL_ID if the specified index is out of bounds.

Sharing NS Data

When multiple titles in a single series share an expanded save data region, any application in that series can call nn::boss::GetNsDataIdList or nn::boss::GetNewDataNsDataIdList to search the NS data downloaded by any application in that series, and use the nn::boss::NsData class to access that NS data. In other words, NS data downloaded by an NADL task registered by one series title is shared among all titles in that series. NS data for one title in a series is shared among all titles in that series.

Warning:

Consequently, NS data serial IDs must be unique not just among files downloaded by that application but also among all NS data files downloaded by any application in that whole series.

If you do not need to work with NS data downloaded by other titles in a series, you can call the nn::boss::GetOwnNsDataIdList or nn::boss::GetOwnNewDataNsDataIdList functions to search for and list just the NS data downloaded by tasks registered by the calling application.

Code 4-42. Getting a List of NS Data Serial IDs for Just the Calling Application
nn::Result nn::boss::GetOwnNsDataIdList(
                        u32 dataType, nn::boss::NsDataIdList* pNsDataId);
nn::Result nn::boss::GetOwnNewDataNsDataIdList(
                        u32 dataType, nn::boss::NsDataIdList* pNsDataId); 

These two functions differ from nn::boss::GetNsDataIdList and nn::boss::GetNewDataNsDataIdList only in which NS data files they search for. They otherwise operate identically. However, note that these functions incur an increased processing load because they check if an NS data file was downloaded via a task registered by the calling application.

4.2.2.8. Loading Downloaded Data

Access NS data by generating an instance of the nn::boss::NsData class and calling Initialize using the obtained serial ID as an argument.

Code 4-43. nn::boss::NsData Class Initialize and Read Functions
class nn::boss::NsData
{
    nn::Result Initialize(u32 serial);
    nn::Result GetHeaderInfo(HeaderInfoType type, void* pValue, size_t size);
    nn::Result SetReadDataPosition(s64 position, PositionBase base);
    s32 ReadData(u8* pDataBuf, size_t bufLen);
    nn::Result SetReadFlag(bool flag);
    nn::Result GetReadFlag(bool* pFlag);
} 

NS data properties can be obtained from the header information returned by the GetHeaderInfo function. The header information type in the type parameter specifies which header information is obtained. For the pValue and size parameters, specify a variable to hold the header information and its size in bytes (which depends on the data type of the header information).

Table 4-21. Header Information Types

Header Information Type

Type

Description

NSD_TITLEID

s64

Title ID.

NSD_FLAGS

u32

NSD flag (not used).

NSD_DATATYPE

DataType

Data type.

NSD_LENGTH

u32

Data length.

NSD_SERIALID

u32

Serial ID.

NSD_VERSION

u32

Version number.

Call the ReadData function to load (read) the NS data. Specify a read buffer in pDataBuf and its size in bufLen. The function returns the number of bytes read. A return value of 0 indicates that the function has already read all the data. An error occurs and the function returns a negative number if it attempts to read data that does not exist, which could happen if data was automatically deleted to allocate a save region. An error occurs and the function returns NN_BOSS_NSDATA_READ_ERROR_UPDATED if the data is overwritten by new download data while it is being read.

Call the SetReadDataPosition function to specify where in the NS data to read (equivalent to the file system Seek function).

Warning:

Like the file system Seek function, NS data read operations are substantially slower when the read position set by the SetReadDataPosition function is not a multiple of 4 from the start of the file.

Call the SetReadFlag function specifying true for the flag parameter to mark NS data as read. Call the GetReadFlag function to check whether NS data has been read. The function returns a value of true in the pFlag parameter if the NS data is marked as read.

You can also use the following functions to work with NS data.

Code 4-44. Setting and Getting Additional Information, and Deleting Data
class nn::boss::NsData
{
    nn::Result SetAdditionalInfo(u32 info);
    nn::Result GetAdditionalInfo(u32* pInfo);
    nn::Result GetLastUpdated(nn::fnd::DateTime* PTime);
    nn::Result Delete(void);
} 

Call the SetAdditionalInfo and GetAdditionalInfo functions to set and get additional information as a u32 value that applications can freely add to NS data. Note that this additional information is lost when the NS data is overwritten with a new version.

Call the GetLastUpdated function to get the date and time when an NS data file was created. This indicates the last time the NS data was overwritten with a new version.

Call the Delete function to delete NS data from BOSS storage. Even without explicitly calling the Delete function, the BOSS daemon automatically deletes data starting from the earliest (the data with the lowest serial ID) after the storage area is full (that is, after the total size of the NS data exceeds the size specified to the nn::boss::RegisterStorage function) to open up some free space. You can explicitly call the Delete function to get rid of unneeded NS data and keep the BOSS daemon from having to manage that data, thereby improving processing efficiency. Deleted data, for example, is no longer processed when searching NS data to get serial ID lists, making for more efficient searching.

Preventing Duplicate Downloads

BOSS uses the If-Modified-Since HTTP request field to keep from downloading the same NS archive multiple times.

However, the same NS archive is downloaded multiple times if the following conditions are all fulfilled simultaneously.

  • After previously downloading the NS archive, 50 or more other NS archives have been downloaded in the same task.
  • A newer NS archive is registered on the server than the last downloaded NS archive. In other words, the update time of the NS archive on the server is more recent than the LastModifiedTime of the last downloaded NS archive.

There is no need for applications to build in a way to track this information, but each NS archive is assigned its own ID, which is used to control NS archive downloads to prevent downloading duplicates. Each task can only record the last 50 IDs, so distributing an NS archive after a system has downloaded 50 other NS archives can result in an archive being downloaded again. However, so long as the LastModifiedTime of the NS archive is not updated to be more recent than the last downloaded NS archive, the If-Modified-Since field prevents that archive from being downloaded again.

Even when these conditions are not fulfilled during regular use, data write operation errors or other unexpected bugs on the BOSS data server can potentially cause the same NS archive to be downloaded multiple times. Consequently, make sure that such a situation does not cause any fatal errors in your application. For example, an application could keep track of the serial IDs of the data already obtained, and then delete any earlier data if data with the same serial ID is obtained again later.

Warning:

Be cautious when a task has been deleted and re-registered. In general, functionality to prevent multiple receives does not work because previously downloaded information has already been deleted.

To prevent the repeated receipt of notifications, implement programming such that tasks that receive notifications do not need to be deleted. For example, avoid an implementation that deletes and reregisters tasks every time the application starts.

Interrupted Downloads

The download will be interrupted if the user turns the power off, the battery becomes low, or the connection to the access point is lost due to a poor communication environment. Although the system ordinarily tries the download again after 10 minutes, if the communication environment is poor, the system may not always be able to retry before the task is executed again.

Sleep Mode

Although an ongoing download will be interrupted if the system goes into Sleep Mode, the system will resume the download as soon as it finds an access point. After returning from Sleep Mode, if the system connects to the same access point as before it went into Sleep Mode, it continues the download where it left off. If the system was offline before entering Sleep Mode (but was connected during Sleep Mode), it disconnects from the access point but resumes the download the next time that it connects to an access point.

NS Data That Has Been Corrupted or Tampered With

Use the following procedure to check whether NS data has been corrupted or tampered with.

  1. Get the NS data ID with the nn::boss::GetNsDataIdList function.
  2. If an error other than an illegal use error is returned with the nn::boss::NsData::GetHeaderInfo or nn::boss::NsData::ReadData function (which, for the GetHeaderInfo function, is either a ResultInvalidNsDataValue, ResultIpcNotSessionInitialized, or ResultStorageAccessPermission error), NS data can be determined to have been corrupted.

Perform the following when corruption or tampering is detected in NS data.

  1. Delete NS data that has been corrupted or tampered with using the nn::boss::NsData::Delete function.
  2. Notify the user that data has been corrupted and instruct the user to immediately delete the data if a notification has arrived at the same time, or when there has already been advance notice of arrival of data in the application.

As a rule, because of the feature to prevent duplicate downloads, the system cannot download the same archive for the same task again (unless all the right conditions are present), even when NS data is deleted. To download deleted NS data again, first cancel registration for the task using the nn::boss::UnregisterTask function, and then use the nn::boss::RegisterTask function to reregister the task. Note that data downloaded may differ from the data that was deleted if NS data has been updated on the server. Keep this in mind when implementing the re-download process.

4.2.3. NSA List

The NSA list is a feature for retrieving listings of the NS archives on the BOSS data server. You can perform searches by specifying the BOSS code assigned when requesting the use of SpotPass, the task ID, or other attributes. A list of NS archive records matching the conditions is returned.

Note:

For more information about the settings methods for BOSS code and the NSA List, see OMAS Help.

4.2.3.1. NsaList Class

NSA list features are defined in the nn::boss::NsaList class.

Code 4-45. Constructor and Destructor for the NsaList Class
class nn::boss::NsaList
{
    NsaList(const char* nsaListFilePath);
    ~NsaList(void);
} 

The path for storing the retrieved NSA list file is specified in the nsaListFilePath parameter of the constructor. Specify a path within an archive that can be written by the application, as with expanded save data.

4.2.3.2. Getting an NSA Listing

Use the Download function to get the NSA listing for a specific BOSS code and task ID. The function is executed in the foreground as an immediate task, so a connection to the Internet must be established using the AC library in advance.
When getting this information, the country and language information set in System Settings is automatically embedded in the query string.

Code 4-46. Function for Getting an NSA List
nn::Result nn::boss::NsaList::Download(
        const char* bossCode, const char* taskId, 
        const nn::boss::NsaList::SearchAttributes* attributes = NULL, 
        u32 waitTimeoutSec = NN_BOSS_NSALIST_WAIT_FINISH_TIMEOUT_DEFAULT_SEC,
        s64 fileSize = NN_BOSS_NSALIST_MAX_SIZE);
nn::Result nn::boss::NsaList::Cancel(void); 

Specify the BOSS code in bossCode and the task ID in taskId.

Specify a download timeout time in seconds in waitTimeoutSec. If this parameter is omitted, nn:: boss::NN_BOSS_NSALIST_WAIT_FINISH_TIMEOUT_DEFAULT_SEC (currently 30 seconds) is specified. The call does not time out if a value of zero is specified.

Search conditions are specified using three attributes (attribute 1 to attribute 3; each attribute has an ASCII string of up to nine characters) in the attributes parameter. NS archive entries are retrieved if the entry attributes are the same as those specified in the call to the Download function. Each attribute is handled by sequence, not by combination. If attribute 1 retrieves the NSA list of the archive called "item," even if "item" is specified in attribute 2 or attribute 3, the archive is not a target for listing unless attribute 1 is not "item." If the NSA list is retrieved with conditions of attribute 1 = "A," attribute 2 = "B," and attribute 3 = "C," all of the conditions are connected by a logical AND, and only the archive that matches the sequences for all attributes is the target for listing. Entries matching these attributes are retrieved, and entries without them (NULL or empty string) are not. However, archive entries that do not specify an attribute that is specified in a Download call are not included in the NS archive list.

A decision, as shown below, is made for each of the three attributes. If the decision in all three cases is to get the archive entry, it is added to the list.

Table 4-22. Decision to Get Based on Specified Attributes

Attribute in Archive

Attribute in Download Call

Get Decision

Not specified

Not specified

Get

Not specified

Specified

Do not get

Specified

Not specified

Get

Specified

Specified

Get if values match

The attributes specified in the Download call are the conditions used to extract data when creating the list. Only one condition can be specified per attribute. To specify more than one condition for a single attribute, the list must be retrieved without that attribute and the content of the list parsed later.

In fileSize, specify the maximum size of the NSA List that is to be created. After creating a blank file of this size, the NSA List feature writes the NS archive list acquired by the file. When omitted, the value for the maximum size of the NSA List saved in nn::boss::NN_BOSS_NSALIST_MAX_SIZE is set automatically.

The NSA List size is calculated using the following formula.

NSA List Size = 54 + 236 * number of NS archives included in the list

Lists including a maximum of 1000 pieces of NS archive information are acquired, so the maximum size of an NSA List is 236,054 bytes. This value can also be set explicitly only if it is not expected that lists with a maximum number of NS archive information will be acquired, or when you want to reduce the capacity of files allocated for NSA lists.

The Download process can be canceled with the Cancel function. Cancel requests are processed asynchronously, so calling this function always succeeds.

4.2.3.3. Checking the Retrieved Results

The GetResult function can be used to confirm whether the NSA list has been retrieved.

Code 4-47. Functions to Check the Retrieval Result
nn::boss::TaskResultCode nn::boss::NsaList::GetResult(void);
u32 nn::boss::NsaList::GetHttpStatusCode(void); 

The value returned by the GetResult function is the execution result from the task used to download the NSA list. A value of TASK_SUCCESS indicates that retrieval of the list has completed.

If GetResult returns HTTP_ERROR_* or SSL_ERROR_*, a communications error has occurred. You can get the HTTP status code returned from the server using the GetHttpStatusCode function. You can also use this to get detailed information on status when an error occurs.

4.2.3.4. Checking Validity and Updates

Use the CheckValidity function to check the validity of the downloaded NSA list. Use the GetDigest function to get a digest value that can be used to confirm updates to the NSA list.

Code 4-48. Functions to Check Validity and Updates
bool nn::boss::NsaList::CheckValidity(void* pWorkBuf, size_t workBufSize);
nn::Result nn::boss::NsaList::GetDigest(u8* pDigestBuf, size_t digestBufSize); 

Specify a working buffer and its size in pWorkBuf and workBufSize. The size of the working buffer must be at least 256 bytes. Also, when the retrieved NSA list is large, processing may be faster if the size allocated for the buffer is larger. When the CheckValidity function returns false, the list content may have been corrupted.

The digest value obtained by the GetDigest function can be used to confirm NSA list updates. The digest value is a 40-character alphanumeric string, so the buffer specified with pDigestBuf and digestBufSize must be at least 41 bytes.

If there have been no updates to the list obtained specifying the same attributes, the digest value will be the same. It can be used to determine whether the entire list has changed, but not whether individual NS archive entries have changed.

4.2.3.5. Parsing the NSA List

The Parse function can be used to parse a retrieved NSA list.

Code 4-49. Function for Parsing an NSA List
nn::boss::NsaList::ParseResult nn::boss::NsaList::Parse(
        u32* pOutParseCount, 
        nn::boss::NsaList::NsaInformation pNsaInformationArray[], 
        u32 nsaInformationArraySize, 
        void* pWorkBuf, size_t workBufSize, u32 nsaFirstPos = 0); 

pNsaInformationArray and nsaInformationArraySize specify an array of NsaInformation structures that store the parsing results and the number of elements in the array. The number of list entries stored in the array is stored in pOutParseCount.

Specify a working buffer used for parsing and its size in pWorkbuf and workBufSize respectively. The size of the working buffer must be at least 256 bytes. Also, when the retrieved NSA list has many elements, processing can be faster if the size allocated for the buffer is larger.

When the return value is zero, all of the list entries have already been parsed. A negative return result indicates that an error has occurred. A positive result indicates that the pNsaInformationArray was too small, and all entries could not be parsed in one call. In this case, the Parse function can be called repeatedly, passing the previous return result in nsaFirstPos to continue parsing.

The NsaInformation structure is defined as follows.

Code 4-50. NsaInformation Structure Definition
struct nn::boss::NsaList::NsaInformation
{
    char fileName[32];
    u32  fileSize;
    u32  updateEpochTime;
    char attribute1[10];
    char attribute2[10];
    char attribute3[10];
    u8   caption[150];
}; 

NS archive information is stored in each of these members.

Table 4-23. Information Stored in Members of the NsaInformation Structure

Member

Stored Information

fileName

Filename.

fileSize

File size.

updateEpochTime

Update time (Number of seconds since 1970/01/01 00:00:00 GMT).

attribute1attribute3

Contents of attributes 1 to 3 set in the archive.

caption

Description (UTF-8 encoded, up to 50 characters).

NS Archive URL

The URL specified for the NADL task has the following structure.

https://npdl.cdn.nintendowifi.net/p01/nsa/(BOSS code)/(Task ID) /(File name)?(query string)

There is an "lm" in the query string parameter. If an archive is retrieved using a NADL task with an update time (the updateEpochTime value) specified in this parameter and the update time is different, a value of 404 (Not Found) is returned. This is specified to avoid producing inconsistencies between the content retrieved in the NSA list and the archive content during the period when the NS archive is being replaced and the contents of the CDN cache and the NS archive are not the same.

Use for Cache Control

The NS archive cache can be controlled easily by comparing the updateEpochTime member content in the NsaInformation structure saved from the previous time it was retrieved with the current value. However, the time measured by the 3DS system can change due to error or user action, so update times must be compared using two updateEpochTime values.

4.2.4. Data Upload Tasks

Data upload tasks are tasks in which data uploads are performed via an HTTP/HTTPS connection to an arbitrary data server.

Figure 4-10. Uploading With a Data Upload Task

Server to receive upload data BOSS Data (4) When the running time comes, BOSS uploads the data to the specified URL (1) Register tasks and data Task (2) BOSS saves data to the BOSS storage (3) Instruct to run the task Data Application Expanded save data region BOSS storage Data Task

Tasks that have already been registered cannot be reused with data upload tasks. When uploading again using a task with the same task ID, the task that has already been registered must first be deleted.

The new task can then be registered. Implement so that the task executes (the start instruction) immediately after registration. If power is interrupted while registering a task, the information for the task and its data become invalid. Tasks that could not begin due to a power interruption can be identified when the nn::boss::Task::GetState function returns TASK_REGISTERED. To re-register a task, first delete the task if it falls under the UnregisterTask function.

Note:

You must contact support@noa.com before using data upload tasks.

4.2.5. Data Store Upload Tasks

Data Store upload tasks are tasks that upload data using the NEX library’s data store features.

Users can be specified, allowing them to view data that has been uploaded. Users can also exchange data among themselves.

A Data Store upload task can use the NEX library data store features, even when the application is not running (such as when it is in Sleep Mode) by communicating via SpotPass.

Figure 4-11. Uploading With a Data Store Upload Task

Data store server BOSS (5) Data Store library uploads the data to the data store server (1) Register the tasks and data Task (2) BOSS saves data to the BOSS storage (3) Instruct to run the task Data Application Expanded save data region BOSS storage Data Task NEX (DataStore library) (4) When the execution time comes, BOSS instructs the Data Store library to upload the data Data

A task that has already been registered cannot be reused for a Data Store upload task. When uploading again using a task with the same task ID, the task that has already been registered must first be deleted.

The new task can then be registered. Implement so that the task executes (the start instruction) immediately after registration. If power is interrupted while registering a task, the information for the task and its data become invalid. Tasks that could not begin due to a power interruption can be identified when the nn::boss::Task::GetState function returns TASK_REGISTERED. To re-register a task, first delete the task if it falls under the UnregisterTask function.

There is a maximum time lag of 20 seconds before data that has been uploaded can be downloaded.

Note:

This feature uses the NEX library, but you do not need to include the NEX library in the application.

For more information about data store features, see the NEX Library documentation.

4.2.6. Data Store Download Tasks

Data Store download tasks are tasks that download data using the NEX library’s data store features.

Because information for the data that has been downloaded is recorded, only that data viewable by the user which has not yet been downloaded is included in the download.

A Data Store download task can use the NEX library Data Store features, even when the application is not running (such as when it is in Sleep Mode) by communicating via SpotPass.

Figure 4-12. Downloading With a Data Store Download Task

Data store server BOSS Data (3) Downloads the data from the Data store server (1) Register tasks and start them Task (4) The downloaded data is passed to BOSS via the Data Store library Application Expanded save data region BOSS storage NSD Task NEX (DataStore library) (2) When the execution time comes, BOSS instructs the Data Store library to download the data (5) BOSS saves the data in NSD format Data

Data that has been downloaded is saved in BOSS storage in NSD format. For this reason, the same function is used for loading data as was used for the data that was downloaded using the NADL task. When BOSS storage is full, data is automatically deleted starting with the earliest data (data with earlier serial numbers). This process is also the same as is used on data downloaded using an NADL task.

By performing notification issue settings when a task is registered, a notification can be posted to the notifications list when new data is downloaded.

Note:

This feature uses the NEX library, but you do not need to include the NEX library in the application.

For more information about data store features, see the NEX Library documentation.

4.3. Presence Feature

With Nintendo DS NITRO-DWC and TWL-DWC, friend-to-friend communications had to be managed by separate implementation into each application. With 3DS, these features are supported by the SDK.

Note:

For more information about the presence features, see the System Application and Applet Specification.

4.3.1. Overview

With 3DS, systems have a shared friend list available to all games from which users can add and remove other users from the HOME Menu by standard system functions. The user does not need to independently implement an interface for management of the friend list by each application.

Also, the user does not need to add other users separately for each application. Other functionality for getting and displaying information such as friends’ Mii characters, status messages, and the title of the game currently being played is now built into the system. Applications can get or set some part of this data by calling the appropriate API function, and information about oneself and one’s friends is automatically synchronized. Because this communication process is executed by daemons running in the background, applications do not need to keep track of detailed information for sending and receiving.

The Join-In feature expands on network functionality. This feature supports inviting friends to join your group while an online game is in progress or to join a friend’s group by virtue of linkage with the NEX library. For more information about using the Join-In function, see the NEX Programming Manual: Server Services.

4.3.2. User Accounts

The presence feature includes individual accounts. Information in those accounts is shared with friends. The account ID is automatically assigned by the system.

4.3.2.1. Types of User IDs

Two types of IDs are used to identify a user of the presence feature: the principal ID and the local friend code. Both IDs are assigned different values each time the system is initialized.

Principal ID

A completely unique ID assigned upon first connection to the friend server. Although the ID will not collide with other IDs, the value is invalid and cannot be used until you connect to the friend server for the first time.

Local friend code

This user ID is used to identify users for the presence features. It is generated based on the system’s unique ID. Although extremely rare, collisions cannot be entirely avoided.

 

There are also two secondary IDs, friend keys and friend codes, that are generated based on these IDs.

Friend key

The concept of this ID is to handle both the principal ID and local friend code. As a rule, this ID uses the local friend code until a principal ID is issued, and then it uses the principal ID from then on.

Friend code

This 12-digit number is generated from the principal ID that is meant to be user-friendly in its format. It is generated based on the principal ID. Because it has a one-to-one correspondence with principal IDs, the two codes can be mutually converted. It includes simple error detection capability.

4.3.2.2. Account Information

The following information can be obtained from friends or made available to friends using the presence feature.

  • Friend key
  • The title of the Currently Playing game
  • Game mode description string
  • Join-in information for the Currently Playing game (for linking with the NEX library)
  • Mii character
  • Screen name (Mii name)
  • System profile information (country and region settings)
  • Friendships
  • Favorite title
  • Status message

Applications can set or get some part of the information in this table. In addition, some items that cannot be directly set or obtained by applications can have their setting configured or checked by the other system features, such as the HOME Menu.

Table 4-24. Setting and Getting Presence Information

Item

Setting/Editing Local Information

Getting/Checking Friend Information

Application

System Features

Application

System Features

Friend code

No

No

No

Yes

Friend key

No

No

Yes

No

The title of the Currently Playing game

No

Yes

No

Yes

Game mode description string

Yes

No

No

Yes

Join-in information about the Currently Playing game

Yes

No

Yes

No

Mii character

No

Yes

Yes

Yes

Screen name (Mii name)

No

Yes

Yes

Yes

System profile information
(Country and region settings)

No

Yes

Yes

No

Friendships

No

Yes

Yes

Yes

Favorite title

No

Yes

No

Yes

Status message

No

Yes

No

Yes

4.3.3. Managing the Friend List

With 3DS, you can add users to and remove users from the friend list by using the Friend List system applet and then saving it on the system.

This friend list can be used in common with all 3DS game titles.

4.3.3.1. Registering Friends on the Friend List

There are three methods of registering another user on the friend list. These methods are described below.

Entering a Friend Code

You can register another party by entering their friend code on the Friend List system applet. When entered, the validity of the friend code is verified by connecting to the friend server. The environment must allow connection to the Internet. The user can check the user’s friend code on the Friend List system applet.

The side entering the friend code for the other party enters a wait state to establish friendship with that other party until the other party adds you to their friend list. Friendship is established after both parties have confirmed registration of each other.

Registering Using Local Communication

You can register another party in your friend list using local communication by selecting Local on the Friend List system applet. Connection to the Internet is not required in this case.

The friendship is established without waiting under this method, because parties are added to each other’s friend lists immediately.

Registering Within an Application

You can also register another party in your friend list within an application by sending and receiving the required registration information.

When performing registration this way, confirmation must be obtained to ensure that both parties consent to friend registration before proceeding.

Note:

For more information about registration within an application, see 4.3.9. Friend Registration. The UI associated with registration must be implemented in the application.

Warning:

Friend registration within an application that is performed via StreetPass or local communication, where it is not possible to identify the other party in advance, is prohibited.

For more information, see the Friend Registration section in 3DS Guidelines: Internet Communication.

4.3.3.2. Friendship Status

Friendships are established when two parties register each other on their friend lists. Friendships transition through the following states, depending on their respective registration status.

Waiting to Establish Friendship

In this state, one party has added another to his or her friend list and is waiting to be added to the other party’s friend list. When the other party adds the first party to the friend list, that fact is registered on the friend server. After the other party adds the first party to his or her friend list, the state changes to friendship established the next time a connection is made to the friend server.

Friendship Established

In this state, both parties have registered the other as a friend. Friendships must be in this status to share information such as connection status and the game title that is currently being played in real-time.

Note:

The friend server maintains a list of users that are registered in each user’s friend list. Two users who are registered on each other’s friend list are treated as being in the friendship established state. As such, friendships that have been established using local communication are not treated as being in the friendship established state until both users have gone online at least once after establishing the friendship. Usually, there is no reason to recognize this status, but it is called local friend status to distinguish it.

Friendship Canceled

This is the state, for example, when you have been removed from the friend list of another party with whom you had established a friendship. Although the other party is not just removed unexpectedly from your own friend list, once this state results, the other party appears as if offline, even if they are actually online. Follow-up access is still possible for information received from the other party before the friendship was canceled. Friendship established status can be restored if the other party registers your friend code again.

4.3.4. Initialization and Finalization

You must initialize the library by first calling nn::friends::Initialize to use API functions in the FRIENDS library. Also, call nn::friends::Finalize to finalize the library when it is not going to be used anymore.

The FRIENDS library has a counter for keeping the initialization count internally. If nn::friends::Initialize has been called multiple times, you must call nn::friends::Finalize the same number of times to completely shut down the library. Use nn::friends::IsInitialized to check whether the library has already been initialized.

Code 4-51. API Functions for Initializing and Finalizing
nn::Result nn::friends::Initialize();
nn::Result nn::friends::Finalize();
bool nn::friends::IsInitialized(); 

4.3.5. Online and Offline

The term online refers to the status when 3DS is connected to the friend server, while offline is used to describe the status when not connected. In online mode, not only can you share information with your friends, such as the title you are currently playing and the game mode, you can also receive the same information from friends who are also online. In offline mode, though you can get some information such as your friends’ names, their Mii characters, and profile information, there is no guarantee that the information is the latest available.

4.3.5.1. Autonomous Connection and Login

There are two methods of putting the 3DS in online mode.

Autonomous Connection

Even without an explicit request from the application, the friend presence daemon autonomously attempts to connect to the friend server and enter online mode if possible. This behavior is managed by the daemon manager and may stop without confirmation, as determined by the daemon manager.

In addition, if you want the application to explicitly stop this behavior, you must instruct the daemon manager to stop execution of the friend presence daemon.

Login

If the application is actively using the presence feature, you can issue a login request to enter online mode regardless of autonomous connection status.

Use nn::friends::Login to issue a login request. If this function succeeds, a connection process runs in the background, and the nn::os::Event object passed in pEvent at the time the process exits enters signal status. Results of asynchronous processing can be obtained using nn::friends::GetLastResponseResult. If a login request is issued and the system is already online, nn::friends::HasLoggedIn returns true.

Note: Do not, however, issue a login request for titles that do not support online play. To issue a login request, you must have already established an Internet connection using the AC (automatic connection) library. For this reason, be sure that login requests are performed only when applications also request an Internet connection.

Even if login is not required, you can cancel a login request by logging out. Again, even without logging out explicitly, login requests are canceled when the FRIENDS library is closed or when an application exits. If autonomous connection is still enabled even after logout, online status will be maintained.

Code 4-52. API Function for Login
nn::Result nn::friends::Login(nn::os::Event* pEvent);
nn::Result nn::friends::Logout();
nn::Result nn::friends::GetLastResponseResult();
bool nn::friends::HasLoggedIn(); 
Code 4-53. Sample Code for Login Process
nn::Result result;
nn::os::Event event(false);

result = nn::friends::Login(&event);
if (result.IsSuccess())
{
    // Generates an asynchronous process if Login succeeds.
    if (event.Wait(nn::fnd::TimeSpan::FromMinutes(2)))
    {
        result = nn::friends::GetLastResponseResult(); 
        if (result.IsSuccess())
        {
            // Login succeeded.
        }
        else
        {
            // Error handling.
        }
    }
    else
    {
        // Request must be canceled because failure of the login process has not been established.
        nn::friends::Logout();
    }
}
else
{
    // Error handling.
} 
event.Finalize(); 
Warning:

Asynchronous processes started by nn::friends::Login processes terminate immediately if online status has been established by autonomous connection. The system takes several seconds to several dozen seconds to transition to online status by asynchronous process. If the user cancels the login request without waiting for this asynchronous process to end, explicitly call nn::friends::Logout to cancel the login request or the process of connecting to the friend server connection will continue to run in the background.

4.3.5.2. Synchronizing Information With the Friend Server and Friends

User information is sent to the friend server while online and then shared with friends via the friend server.

Although local information can be updated even offline, it is not sent immediately to the friend server. Updating local information offline is synchronized by sending the information to the friend server when the system goes online and connects to the friend server.

On the other hand, updates conducted while online are immediately sent to the friend server by a friend presence daemon running in the background. However, because the library restricts the send interval to the friend server to once per 10 seconds at most for any single item, even if information is updated at a shorter interval than this, immediate synchronization with the friend server and friend is impossible. Do not communicate with the friend server at a very high frequency. For more information, see the CTR Guidelines.

Code 4-54. API Functions for Updating Local Information
nn::Result nn::friends::UpdateGameModeDescription(
        const char16 description[nn::friends::MODE_DESCRIPTION_SIZE]); 

The nn::friends::UpdateGameModeDescription function updates the text string describing your own game mode.

The string specified by description is applied to what is displayed on your own friend card. Up to two lines of text having a length equal to 16 characters (in Japan, European, U.S. regions: "%"; in other regions: Japanese hiragana characters, Chinese kanji characters, Hangul characters, and so on) of the internal font at maximum width can be displayed on the friend card. The characters that can be used for this string differ depending on the system region, as shown in the following table. Characters that cannot be displayed are converted to question marks (0xE011).

Table 4-25. Characters Displayable on Friend Cards

Region

Characters That Can Be Displayed

Japan, US, Europe

Characters included in the internal font Japanese and Western characters

China

Characters included in the internal font simplified Chinese characters

South Korea

Characters included in the internal font Hangul characters

Taiwan

Characters included in the internal font traditional Chinese characters

Figure 4-13. Example of Background Communication When the Text String Describing the Local Game Mode Is Updated at a Short Interval

UpdateGameModeDescription(

Some user information is saved on the friend server. Even if your friend is not online at the same time you are, this allows information in effect the last time your friend was online to be obtained from the friend server when you go online. Because the friend information obtained most recently is saved by the 3DS, you can even get friend information when you are offline. However, the friend information obtained when offline may not be the latest information. Information that is meaningless unless both you and your friend are online at the same time, such as the game mode being played, is not saved on the friend server and cannot be obtained unless both you and your friend are online.

  • Information that can be obtained only when both parties are online:
    • The title of the Currently Playing game
    • Game mode description string
    • Join-in information about the Currently Playing game
  • Information that can be obtained at any time:
    • Friend key
    • Mii
    • Screen name (Mii name)
    • System profile information (country and region settings)
    • Friendships
    • Favorite title
    • Status message

For more information about the API functions used to get friend information, see 4.3.6. Getting Friend Information.

4.3.5.3. Private Mode

Local information can be set as private from the Friend List system applet.

There are two disclosure levels.

  • Only the Currently Playing game is kept private.
  • All presence information is kept private.

If you keep all presence information private, you can make it appear to friends that you are offline even though you are online. In other words, information such as your Currently Playing game is not sent to your friends, and your connection status is handled as if you are offline. In addition, because even the friend server will not update your information, settings made the last time you were online with public settings will be used by the friend server for items such as your Mii character and system profile information. Friend information can be obtained in the same way as when presence information has been made public.

4.3.5.4. Getting Local System Information

Use the following functions to get the local system’s own information.

Code 4-55. Functions for Getting the Local System’s Information
nn::friends::PrincipalId nn::friends::GetMyPrincipalId();
bool nn::friends::IsMyPreferenceValid();
nn::Result nn::friends::GetMyPreference(
        bool* pIsPublicMode, bool* pIsShowGameName);
nn::Result nn::friends::GetMyProfile(nn::friends::Profile* pProfile);
nn::Result nn::friends::GetMyPresence(nn::friends::MyPresence* pMyPresence);
nn::Result nn::friends::GetMyScreenName(char16 screenName[SCREEN_NAME_SIZE]);
nn::Result nn::friends::GetMyMii(nn::mii::StoreData* pMiiData); 

If you have never connected to the friend server, INVALID_PRINCIPAL_ID is returned as the principal ID.

If you have never started the friend list (a system applet), the IsMyPreferenceValid function returns false, because you have never touched the friend notification settings. In addition, the default value (true) is stored for the various arguments of the GetMyPreference function.

If you have not created a Personal Mii and you have never started the Friend List system applet, the system profile information obtained by the GetMyProfile function reflects either the settings of the system at initial setup, or the current System Settings.

If you have not used Mii Maker to create a Personal Mii, the GetMyScreenName function returns an empty string starting with NULL (meaning that the second and subsequent characters are undefined). The GetMyMii function returns empty Mii data. You must use the CFL library to determine whether the obtained Mii data is valid and to display the data.

4.3.6. Getting Friend Information

When getting friend information using the FRIENDS library, specify the friend using the friend's friend key or principal ID. You can get friend keys for users registered in your friend list using nn::friends::GetFriendKeyList, or you can specify friend keys and principal IDs obtained externally via other communication.

4.3.6.1. Getting a Friend Key

To get the friend key of a user registered on the friend list, use nn::friends::GetFriendKeyList. This function attempts to get the friend keys for the number of users specified by size in order, beginning from the offset friend in the friend list, and stores them in the buffer pointed to by pFriendKeyList. It returns the number of friend keys actually stored in a buffer pointed to by pNum. If the number of friend keys obtained is less than that specified by size, the values in the buffer for friend keys that could not be stored cannot be guaranteed.

Code 4-56. Function for Getting Friend Keys
nn::Result nn::friends::GetFriendKeyList(
        nn::friends::FriendKey* pFriendKeyList, size_t* pNum,
        size_t offset = 0, size_t size = nn::friends::FRIEND_LIST_SIZE); 

The local friend codes obtained through local communications are scrambled to protect privacy, so they cannot be used as is to specify friends. The FRIENDS library has prepared an API for unscrambling these local friend codes.

Code 4-57. Function for Unscrambling Local Friend Codes
nn::Result nn::friends::UnscrambleLocalFriendCode(
        nn::friends::LocalFriendCode* pLocalFriendCodeList,
        const nn::uds::ScrambledLocalFriendCode* pScrambledLocalFriendCodeList,
        size_t size = 1); 

For pScrambledLocalFriendCodeList and size, specify the list of (scrambled) local friend codes that was obtained through local communications and the number of entries in the list.

The result after unscrambling is stored in pLocalFriendCodeList, so set this parameter to a value large enough to hold the number of entries specified by size. Only the codes for friends can be unscrambled. The local friend codes for users that have not been registered to the friend list are treated as INVALID_LOCAL_FRIEND_CODE.

When implementing your application, note the possibility that friends may have the same local friend code. The unscrambled local friend codes are not unique values, so in extremely rare instances the friend list may contain multiple friends with the same local friend code.

4.3.6.2. Getting Friend Information

Pass a list of friend keys or principal IDs to the API function used to get the friend information. As a result, friend information will be stored in a buffer passed to the first argument of each function in the same number and order as the list of friend keys or principal IDs passed to the function. If the user corresponding to the specified friend key or principal ID is not included in the friend list, invalid data is returned.

Note:

There is no API for getting friend information by specifying a list of local friend codes. Although it is possible to store a local friend code in a friend key and pass that, collisions, while extremely rare, cannot be completely avoided due to the nature of local friend codes. More than one user having the same local friend code could be registered in the friend list. As long as the friend key has been obtained from the friend list, the user in the list can be uniquely identified even if there is more than one user having the same friend code in the list, because there is never more than one user in the list without a principal ID (when there is a collision prior to establishing a friendship, the last-registered user is the one who remains).

Code 4-58. Functions for Getting Friend Information
nn::Result nn::friends::GetFriendPresence(
        nn::friends::FriendPresence* pFriendPresenceList,
        const nn::friends::FriendKey* pFriendKeyList, size_t size = 1);
nn::Result nn::friends::GetFriendPresence(
        nn::friends::FriendPresence* pFriendPresenceList,
        const nn::friends::PrincipalId* pPrincipalIdList, size_t size = 1);
nn::Result nn::friends::GetFriendScreenName(
        char16 (*pScreenNameList)[nn::friends::SCREEN_NAME_SIZE],
        const nn::friends::FriendKey* pFriendKeyList, size_t size = 1,
        bool replaceForeignCharacters = true, u8* pFontRegionList = NULL);
nn::Result nn::friends::GetFriendScreenName(
        char16 (*pScreenNameList)[nn::friends::SCREEN_NAME_SIZE],
        const nn::friends::PrincipalId* pPrincipalIdList, size_t size = 1,
        bool replaceForeignCharacters = true, u8* pFontRegionList = NULL);
nn::Result nn::friends::GetFriendMii(
        nn::mii::StoreData* pMiiDataList,
        const nn::friends::FriendKey* pFriendKeyList, size_t size = 1);
nn::Result nn::friends::GetFriendMii(
        nn::mii::StoreData* pMiiDataList,
        const nn::friends::PrincipalId* pPrincipalIdList, size_t size = 1);
nn::Result nn::friends::GetFriendProfile(
        nn::friends::Profile* pProfileList,
        const nn::friends::FriendKey* pFriendKeyList, size_t size = 1);
nn::Result nn::friends::GetFriendProfile(
        nn::friends::Profile* pProfileList,
        const nn::friends::PrincipalId* pPrincipalIdList, size_t size = 1);
nn::Result nn::friends::GetFriendAttributeFlags(
        bit32* pAttributeFlagsList,
        const nn::friends::FriendKey* pFriendKeyList, size_t size = 1);
nn::Result nn::friends::GetFriendAttributeFlags(
        bit32* pAttributeFlagsList,
        const nn::friends::PrincipalId* pPrincipalIdList, size_t size = 1); 

4.3.7. Notifications

To find changes in connection status with the friend server and updates to friend information without polling, you can get change notifications from the friend presence daemon by specifying the items required by the application. (Note that these notifications are separate from the user-facing messages delivered to the Notifications built-in application.)

4.3.7.1. Types of Notifications

Applications can accept the nine types of notifications listed below. In addition to the types of changes, the friend key of the friend is also notified if notification is related to friends. When a notification arrives, friend information previously obtained by a function call may have become out-of-date. Be sure to refresh this information when convenient for the application.

Table 4-26. Types of Notifications

Definition

Description (including functions that must be called again to refresh the data)

NOTIFICATION_ONLINE

Indicates that the local system came online. An invalid value is stored in the friend key.

NOTIFICATION_OFFLINE

Indicates that the local system went offline. An invalid value is stored in the friend key.

NOTIFICATION_FRIEND_ONLINE

Indicates that a friend has come online.

GetFriendPresence, GetFriendScreenName, GetFriendMii, GetFriendProfile, GetFriendAttributeFlags

NOTIFICATION_FRIEND_PRESENCE

Indicates that the friend’s game mode has changed.

GetFriendPresence

NOTIFICATION_FRIEND_MII

Indicates that the friend’s Mii character has changed.

GetFriendScreenName, GetFriendMii

NOTIFICATION_FRIEND_PROFILE

Indicates that the friend’s profile has changed.

GetFriendProfile

NOTIFICATION_FRIEND_OFFLINE

Indicates that a friend has gone offline.

GetFriendPresence

NOTIFICATION_BECOME_FRIEND

Indicates that a friendship has been established with a user.

GetFriendPresence, GetFriendScreenName, GetFriendMii, GetFriendProfile, GetFriendAttributeFlags

NOTIFICATION_INVITATION

Indicates that the local system has received an invitation from a friend.

GetFriendPresence

4.3.7.2. Notification-Related Functions

Use the following functions to get notifications from the friend presence daemon.

Code 4-59. Notification Functions
nn::Result nn::friends::AttachToEventNotification(nn::os::Event* pEvent);
nn::Result nn::friends::SetNotificationMask(bit32 mask);
u32 nn::friends::GetEventNotification(
        nn::friends::EventNotification* pEventNotificationList,
        size_t size = 1, bool* pHasOverflowed = NULL); 
Event Registration

If you call nn::friends::AttachToEventNotification and pass a pointer to an initialized nn::os::Event object in the pEvent parameter, that event is signaled when a notification occurs.

Setting a Notification Mask

To specify the types of notifications you want to receive, pass a bitwise OR of your desired values of the nn::friends::NotificationMask enumerated type in the mask parameter of the nn::friends::SetNotificationMask function. If the daemon sends notifications of types not enabled by this mask, the nn::os::Event object passed to nn::friends::AttachToEventNotification is not signaled and these notifications are excluded from the notification history you can get with the nn::friends::GetEventNotification function.

Getting Notification Details

Get notification details using the nn::friends::GetEventNotification function. The return value is the number of notifications obtained by the call. Call this function until it returns zero to get all of the notifications accumulated in the daemon’s buffer in the same order the notifications occurred.

Note:

Notifications start accumulating when the FRIENDS library is initialized using nn::friends::Initialize. If you want notifications to start accumulating from zero (that is, to start accumulating only notifications that are newer than the current time), you can exclude all notifications by passing 0 in the mask parameter of the nn::friends::SetNotificationMask function and then delete all notifications received in the past by calling the nn::friends::GetEventNotification function once.

Warning:

The notification history (the daemon’s buffer) stores up to 128 previous notifications, including private notifications sent to the system. If this buffer overflows, the earliest notification in the list is deleted first. If this buffer does overflow and earlier notifications are discarded, your application will no longer be able to track what portions of the friend presence information are out of date. In this case, the application must immediately call the functions to get the local system’s connection status and friend information again.

4.3.8. Error Handling

If a function in the FRIENDS library fails when called to get the error code, call the nn::friends::ResultToErrorCode function, passing the nn::Result object as the result parameter.

Code 4-60. Function for Getting Error Codes
u32 ResultToErrorCode(const nn::Result& result); 

If this function returns zero, there is no need to display the error code. There is also no need to display the error code if the user can continue playing without experiencing any problems, such as when login fails but the application will immediately retry automatically.

Warning:

When converting the content of the nn::Result object into an error code, the nn::friends::ResultToErrorCode function sometimes appends information related to current daemon status. Consequently, when getting an error code, call nn::friends::ResultToErrorCode immediately after receiving a failed result.

4.3.9. Friend Registration

Friend registration within an application can be performed by mutually receiving the information for registration that the nn::friends::GetMyApproachContext function gets, after which both parties pass the received information to the nn::friends::AddFriendWithApproach function.

Code 4-61. Functions Used for Friend Registration Within an Application
nn::Result nn::friends::GetMyApproachContext(
                        nn::friends::ApproachContext* pApproachContext);
nn::Result nn::friends::AddFriendWithApproach(
                        nn::os::Event* pEvent,
                        const nn::friends::ApproachContext& approachContext); 

To use these functions, the FRIENDS library must be initialized. It is not necessary to log in to a friend’s server. In addition, the CFG Library must also be initialized in advance using the nn::cfg::Initialize function.

The nn::friends::ApproachContext structure acquired by the GetMyApproachContext function is already encrypted, so it is not necessary to encrypt the data for sending and receiving on the application side.

Friend registration completes when calling the AddFriendWithApproach function is successful (for example, when the Result returned for the IsSuccess function is true). Asynchronous processing then occurs. Asynchronous processing does not occur for any other Result. When asynchronous processing completes, the event is passed to pEvent and the application is notified of the signaled state. You can get the results of asynchronous processing with the nn::friends::GetLastResponseResult function. Note that library specifications do not support simultaneous handling of multiple instances of asynchronous processing.

Friends registered with this function are local friends, and you cannot get presence information until both parties connect to the Internet and the friend relationship can be established on the friend server. Asynchronous processing merely tests the registration process on the friend server. Even when registration succeeds with both users online, presence information may not be immediately available after asynchronous processing completes.

To display information for friend registration that has been received in the application (the ApproachContext structure), you can get the display name and Mii data using the functions shown below.

Code 4-62. Functions for Getting Information for Friend Registration
nn::Result nn::friends::GetApproachContextScreenName(
                        char16 screenName[nn::friends::SCREEN_NAME_SIZE],
                        const nn::friends::ApproachContext& approachContext,
                        bool replaceForeignCharacters, u8* pFontRegion);
nn::Result nn::friends::GetApproachContextMii(
                        nn::mii::StoreData* pMiiData,
                        const nn::friends::ApproachContext& approachContext); 

The GetApproachContextScreenName function returns the friend display name passed to screenName to the buffer. If true is specified for replaceForeignCharacters at this point, characters that cannot be displayed in the system region standard font (which are included in the display name acquired) are replaced by question marks and acquired in that form. To display these characters in another region without replacing them with question marks, specify false and then pass the pointer to the u8 type variable to pFontRegion. The region with the standard font that can display the characters is returned to pFontRegion by the value set in the nn::friends::FontRegion enumerator.

The GetApproachContextMii function returns the information required for displaying the friend’s Mii to the buffer passed to pMiiData. The separately available Face library is also required in order to handle the Mii information acquired.


CONFIDENTIAL