No developer support is offered for these libraries, and these libraries generally cannot be included in retail products. Contact Nintendo (support@noa.com) if you want to do so.
Limited debugging libraries are available for checking network connectivity, such as socket communication using the wireless module.
Feature |
Library Name |
Namespace |
Description |
---|---|---|---|
Socket Communication |
SOCKET |
|
Library for implementing data transmission to and from a remote host via sockets. |
SSL Communication |
SSL |
|
Helper library for secure communication via SSL. |
HTTP Communication |
HTTP |
|
Library for communication via HTTP. |
The HTTP library conducts socket communications internally, and the process is not affected by the socket API operations of the application.
For example, the application can call functions like nn::socket::Initialize()
and nn::socket::Finalize()
while using the HTTP library without affecting the processing of the HTTP library.
6.1. Socket Communication
The SOCKET library for socket communication handles communication with a remote host via sockets bound to addresses and port numbers. Sockets provide a means for low-level communication between the local machine and remote hosts for transmitting data, waiting for connections from remote hosts, and connecting from the local host to a remote host.
6.1.1. Initializing
Call the nn::socket::Initialize()
function to initialize the SOCKET library.
size_t nn::socket::GetRequiredMemorySize(size_t bufferSizeForSockets, s32 maxSessions); nn::Result nn::socket::Initialize(uptr bufferAddress, size_t bufferSize, s32 bufferSizeForSockets, s32 maxSessions);
The bufferAddress
and bufferSize
parameters specify the starting address of the working memory used by the library and the size of that memory. The starting address of the working memory must be nn::socket::BUFFER_ALIGNMENT
(4,096 bytes) aligned and must be allocated from non-device memory. Call the nn::socket::GetRequiredMemorySize()
function, passing the size of the send/receive buffer to allocate for an entire socket (bufferSizeForSockets
) and the maximum number of sessions (maxSessions
) as arguments, to get the required size of the working memory. The size of the communication buffer (bufferSizeForSockets
) specified here must be a multiple of nn::socket::BUFFER_UNITSIZE_FOR_SOCKETS
(4,096 bytes).
You can use the nn::socket::SetSockOpt()
function to specify the send/receive buffer to assign to each socket. By default, a 16-KB send/receive buffer (8 KB for sending and 8 KB for receiving) is assigned to a single TCP socket, and a 32-KB send/receive buffer is assigned to a single UDP socket. Even if the maximum number of sockets is 1, allocate at least 64 KB with bufferSizeForSockets
.
The maxSessions
argument specifies the number of threads that use sockets (the maximum number of sessions). The library can handle calls to blocking library functions from the specified number of threads. Strictly speaking, the library can handle function calls from more than the specified number of threads (as long as they are not calling blocking library functions), but we do not recommend this approach. Both asynchronous and synchronous library function calls block, until there is a free session, if they exceed the maximum number of sessions. Processing blocks until there is an open session, even when other conditions to unblock have been satisfied, such as when data has finished being received or sent. Note that this may cause processing that is meant to be asynchronous to work synchronously instead. You can check socket states with a single call to the nn::socket::Poll()
function, which allows you to reduce the number of required sessions.
The size of the send/receive buffer assigned by default may be subject to change.
6.1.2. Creating a Socket
Both the remote host and the local host must create sockets before socket communication can occur. Call the nn::socket::Socket()
function to create a socket. The number of sockets that an application can use simultaneously is limited to 16.
The number of sockets that can be used simultaneously may be subject to change.
s32 nn::socket::Socket(s32 af, s32 type, s32 protocol);
af
may only specify PF_INET
.
type
specifies the type of socket to create as either SOCK_STREAM
for stream sockets or SOCK_DGRAM
for datagram sockets. Stream sockets require that the sockets on both sides of the communication establish a connection, whereas datagram sockets allow for one-way sending or receiving of data blocks. Stream sockets also guarantee the order of arrival of data blocks. Datagram sockets do not, but as a consequence transmit faster.
protocol
specifies the protocol the socket uses, but currently only 0
may be specified. A protocol
value of 0 indicates the use of the default protocol for the protocol family and type specified in the af
and type
parameters. The default protocol is TCP for stream sockets and UDP for datagram sockets.
If the return value is 1 or greater, the return value is a socket descriptor for identifying the socket. A value of 0 or less indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
|
Specified protocol family not supported. |
|
Specified protocol is not supported. |
|
No more socket descriptors can be created. |
|
Insufficient memory to allocate working memory. |
|
Specified socket type not supported. |
|
Invalid call. |
|
Local network interface is down. |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
6.1.3. Binding Addresses and Port Numbers
A socket cannot be used for communication unless it is bound to a socket address indicating which address and which port number to use. A freshly created socket does not have a socket address bound to it. Call the nn::socket::Bind()
function to bind a socket address to a socket.
s32 nn::socket::Bind(s32 s, const nn::socket::SockAddrIn* sockAddr);
s
specifies the socket descriptor for the created socket. An error occurs if the specified socket already has a socket address bound to it.
sockAddr
specifies a pointer to the nn::socket::SockAddrIn
structure in which the socket address (address family, port number, address) has been set. Only IPv4 addresses are supported.
A return value of 0 indicates success. A nonzero return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
|
The specified socket descriptor is not valid. |
|
Local network interface is down. |
|
Invalid operation (such as when the socket is already bound). |
|
Specified address family not supported. |
|
Specified socket address already in use. |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
6.1.4. Operating Modes
Call the nn::socket::Fcntl()
function to get or set a socket’s operating mode.
s32 nn::socket::Fcntl(s32 s, s32 cmd, s32 val);
s
specifies the socket descriptor for the socket for which to set or get the operating mode.
cmd
specifies whether to set (F_SETFL
) or get (F_GETFL
) the socket’s operating mode.
val
specifies either 0
or a bitwise OR of the flags to set for the operating mode. This parameter is ignored when the cmd
value is F_GETFL
.
The only flag that may be set is O_NONBLOCK
for non-blocking operation. Sockets that do not have this flag set operate in blocking mode instead. Sockets are set to blocking mode when first created.
When cmd
is F_GETFL
, the return value is a bitwise OR of the operating mode flags that have been set. When cmd
is F_SETFL
, a return value of 0 indicates successful completion. For any cmd
value, a negative return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
|
The specified socket descriptor is not valid. |
|
Local network interface is down. |
|
Invalid process (invalid value specified for |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
6.1.5. Waiting for Connections
Datagram sockets can send and receive data right after a socket address is bound, but stream sockets must establish a connection before data may be transmitted.
The stream socket on the server side creates a queue for connection requests from client-side stream sockets by calling the nn::socket::Listen()
function, and then accepts incoming connection requests by calling the nn::socket::Accept()
function.
s32 nn::socket::Listen(s32 s, s32 backlog); s32 nn::socket::Accept(s32 s, nn::socket::SockAddrIn* sockAddr);
The s
parameter for both functions specifies the socket to use for incoming requests. This socket must have been created as a stream socket, and must have a socket address bound.
backlog
specifies the maximum number of items in the queue used as the socket listening backlog. A value of 0 or a negative number is treated as a value of 1.
sockAddr
specifies a pointer to an nn::socket::SockAddrIn
structure storing the socket address of the socket that received the request.
A return value of 0 for the nn::socket::Listen()
function indicates success. A negative return value indicates an error.
For the nn::socket::Accept()
function, if there is no socket awaiting connection in the queue, processing blocks if the socket used to wait for connections is in synchronous mode. A return value of 1 or greater is the socket descriptor for a newly created socket that has the same address as the socket used to wait for connections. A value of 0 or less indicates an error.
The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
|
The specified socket descriptor is not valid. |
|
Unsupported operation. |
|
Invalid operation. |
|
Insufficient resources. |
|
No socket is waiting for connections. (Non-blocking mode) |
|
Connection attempt canceled. |
EMFILE |
No more socket descriptors can be created. |
|
Insufficient memory to create the listening backlog. |
|
Same as |
ENETDOWN |
Local network interface is down. |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
6.1.6. Connecting to a Remote Host
The client-side stream socket attempts a connection to the server-side stream socket using the nn::socket::Connect()
function, and cannot send or receive data until a connection is established. A call to nn::socket::Connect
by a datagram socket only overwrites the sending target socket address.
s32 nn::socket::Connect(s32 s, const nn::socket::SockAddrIn* sockAddr);
s
specifies the socket descriptor for the socket used for the connection. If this socket has no socket address bound, the function binds the socket to an unused local socket address.
sockAddr
specifies a pointer to an nn::socket::SockAddrIn
structure to which the connection target socket address has been set.
A return value of 0 indicates success. A nonzero return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
EAFNOSUPPORT |
Specified protocol family not supported. |
|
The specified socket descriptor is not valid. |
|
Already attempting to connect in non-blocking mode. |
|
Connection reset by remote host after the local and remote host simultaneously became open. |
|
Connection was reset. |
|
Specified socket is currently changing state. |
|
Invalid process (invalid value specified for |
|
Socket already in use and cannot be used for other processing. |
|
Local network interface is down. |
|
Could not reach the connection target. |
|
Failed to allocate the temporary socket address for the empty socket. |
|
Response from connection target timed out. |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
If the socket specified by s
is a datagram socket, the function only overwrites the socket’s sending target socket address with the socket address set in sockAddr
, with no difference in operation for different operating modes.
If the socket specified by s
is a stream socket and the operating mode is synchronous, the function blocks until a connection is established. If the operating mode is asynchronous, the function returns immediately, and the nn::socket::Poll()
function can be used to check if a connection has been established.
struct nn::socket::PollFd { s32 fd; s32 events; s32 revents; }; s32 nn::socket::Poll(nn::socket::PollFd fds[], u32 nfds, s32 timeout);
The nn::socket::Poll()
function surveys multiple socket descriptors for sockets that can send and receive.
fds
specifies an array of nn::socket::PollFd
structures that contain the socket descriptors and survey conditions. The structure member variable fd
contains a socket descriptor to survey, and the events
member variable contains the survey conditions. The revents
member stores the survey results. Set it to 0
when calling the function.
If a connection could not be established by a call to nn::socket::Connect
, the POLLRDNORM
and POLLWRNORM
flags are set in revents
, and an error is then returned when data is transmitted. The following table lists the flags set for the survey conditions set in events
and for the survey results set in revents
.
Flag |
Description |
---|---|
|
Indicates an ability to receive. |
|
Indicates an ability to receive (for priority data). |
|
Indicates an ability to receive (for highest-priority data). |
|
Indicates an ability to send. |
|
Indicates an ability to send (for priority data). |
|
Indicates that an error occurred. Only set for survey results. |
|
Indicates that the socket was disconnected. Only set for survey results. |
|
Indicates that an invalid socket descriptor was specified. Only set for survey results. |
|
Indicates an ability to receive. Bitwise OR of |
|
Indicates an ability to send. Same as |
nfds
specifies the number of elements in the array specified in fds
.
timeout
specifies the number of milliseconds to wait until timing out when no sockets are found matching the conditions. Specify as a number greater than 0 or as INFTIM
(no timeout).
A call to nn::socket::Poll
blocks until a socket is found that matches the conditions. However, the block is released if the specified timeout period passes with no matching sockets found, if the socket is disconnected, or if an error occurs in the socket.
A return value of 1 or greater is the number of sockets that matched the conditions. A return value of 0 indicates that the function timed out. A negative return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
|
Local network interface is down. |
|
Invalid operation. |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
6.1.7. Receiving Data
You can receive data using the nn::socket::RecvFrom
, nn::socket::Recv
, or nn::socket::Read()
functions. For stream sockets, data cannot be received unless a connection has been established on both the server and client side.
s32 nn::socket::RecvFrom(s32 s, void* buf, s32 len, s32 flags, nn::socket::SockAddrIn* sockFrom); s32 nn::socket::Recv(s32 s, void* buf, s32 len, s32 flags); s32 nn::socket::Read(s32 s, void* buf, s32 len); s32 nn::socket::SockAtMark(s32 s);
s
specifies a socket descriptor for a local socket.
buf
specifies a pointer to a buffer for storing the received data, and len
specifies the size of that buffer in bytes.
flags
specifies flags for any special operations to carry out when receiving. If MSG_DONTWAIT
is specified, the function does not block even if the socket is in synchronous mode. If MSG_PEEK
is specified, data that is received but the state is not changed, and the same data can be received again. If MSG_OOB
is specified, out-of-band data can be received. Check whether the nn::socket::SockAtMark()
function’s return value is 1 to determine whether out-of-band data is included in the receivable data. This function can also be used to check whether the last byte of TCP protocol "urgent data" is at the start of receivable data.
If the sockFrom
parameter specifies a pointer to an nn::socket::SockAddrIn
structure, the socket address of the sender of the data is stored.
If receiving via a stream socket and the operating mode is synchronous, the function blocks until data is received. If the mode is asynchronous or if flags
specifies MSG_DONTWAIT
, only that data that is receivable when the function is called is stored in the buffer, and the function does not block.
If receiving via a datagram socket, all of the data to receive must be received in a single function call. If the data exceeds the size of the receive buffer and MSG_PEEK
is not specified for flags
, any data that does not fit in the buffer is discarded. The maximum amount of data that can be received by a single function call is 1500 bytes.
A return value of 1 or greater is the number of bytes of received data. A return value of 0 when using a stream socket indicates that the remote host has finished sending data. The return value will never be 0 when using a datagram socket. A negative return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
|
The specified socket descriptor is not valid. |
|
No socket is waiting for connections (The non-blocking mode or |
|
Invalid operation. |
|
Unsupported operation. |
|
Specified socket is not connected to the remote host. |
|
Connection was reset. |
|
Process interrupted. |
|
The process timed out. |
|
Local network interface is down. |
|
Same as |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
6.1.8. Sending Data
You can receive data using the nn::socket::SendTo
, nn::socket::Send
, or nn::socket::Write()
functions. For stream sockets, data cannot be sent unless a connection has been established on both the server and client side.
s32 nn::socket::SendTo(s32 s, const void* buf, s32 len, s32 flags, const nn::socket::SockAddrIn* sockTo); s32 nn::socket::Send(s32 s, const void* buf, s32 len, s32 flags); s32 nn::socket::Write(s32 s, const void* buf, s32 len);
s
specifies a socket descriptor for a local socket.
buf
specifies a pointer to a buffer for storing the data to send, and the len
parameter specifies the size of that buffer in bytes.
flags
specifies flags for any special operations to carry out when sending.
If sockTo
specifies a pointer to an nn::socket::SockAddrIn
structure, the function sends the data to the socket address set in the structure.
The function blocks until data sending has completed.
If sending with a datagram socket, the maximum amount of data that can be sent by a single function call is 1500 bytes.
A return value of 0 indicates success. A negative return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
EAFNOSUPPORT |
Specified protocol family not supported. |
|
The specified socket descriptor is not valid. |
|
If in blocking mode, the prior send attempt was blocked. If the socket is a stream socket in non-blocking mode, data to be sent out-of-band cannot be reserved for sending in the internal send buffer. |
|
Connection was reset. |
|
Process interrupted. |
|
Invalid operation. |
|
Unsupported operation. |
|
If the socket is a stream socket, the socket is being used to accept connection requests. If the socket is a datagram socket, the socket address for the communication target to send data to has not been determined. |
|
Data exceeds the size of the internal send buffer. (Datagram sockets only.) |
|
Local network interface is down. |
|
Could not reach the connection target. |
|
Failed to allocate the temporary socket address for the empty socket. Alternatively, failed to allocate the temporary send buffer. |
|
Specified socket is not connected to the remote host. |
|
The process timed out. |
|
Same as |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
6.1.9. Setting Options
Call the nn::socket::SetSockOpt
or nn::socket::GetSockOpt()
functions to set and get socket options, such as internal socket setting values and internal state information.
s32 nn::socket::SetSockOpt(s32 s, s32 level, s32 optname, const void* optval, s32 optlen); s32 nn::socket::GetSockOpt(s32 s, s32 level, int optname, void* optval, int* optlen)
For more information about the values that can be specified for these function parameters, see the header file nn/socket/socket_User.autogen.h
.
A return value of 0 indicates success. A negative return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
|
The specified socket descriptor is not valid. |
|
Invalid operation. |
|
Local network interface is down. |
|
Insufficient memory to allocate working memory. |
|
Unsupported option. |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
6.1.10. Disconnecting a Socket
Call the nn::socket::Shutdown()
function to halt socket communications and disconnect a socket.
s32 nn::socket::Shutdown(s32 s, s32 how);
s
specifies the socket descriptor for the socket to shut down.
how
specifies how to shut down the socket. Specify SHUT_RD
to stop receiving data, SHUT_WR
to stop sending data, and SHUT_RDWR
to stop both sending and receiving.
A return value of 0 indicates success. A negative return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
|
The specified socket descriptor is not valid. |
|
Specified socket is not connected to the remote host. |
|
Invalid operation. |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
6.1.11. Closing a Socket
Only a limited number of sockets may be used at any one time. Close any unneeded sockets by calling the nn::socket::Close()
function.
s32 nn::socket::Close(s32 s);
The s
parameter specifies the socket descriptor for the socket to close.
A socket can no longer be used after it has been closed. If a function blocks after being called using a closed socket, the blocks are released and an error is returned. When closing a stream socket in asynchronous mode, the socket is closed according to the Linger
option setting.
The default behavior for the Close()
function is to return immediately without blocking. Any remaining data to send is then sent in the background, after which the socket releases the resources it was using.
A return value of 0 indicates success. A negative return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
|
The specified socket descriptor is not valid. |
|
Specified socket is not connected to the remote host. |
|
Invalid operation. |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
6.1.12. Finalizing
When no longer using the SOCKET library, call the nn::socket::Finalize()
function to finalize the library.
nn::Result nn::socket::Finalize(void);
This releases any resources in use by the library and destroys any socket descriptors in use.
6.1.13. Utility Functions
The SOCKET library includes various utility functions for purposes such as getting socket addresses, getting network adapter information, getting remote host information via DNS, converting addresses to and from strings and numeric values, and converting numbers to the host byte order and the network byte order.
s32 nn::socket::GetSockName(s32 s, nn::socket::SockAddrIn* sockAddr); s32 nn::socket::GetPeerName(s32 s, nn::socket::SockAddrIn* sockAddr);
The nn::socket::GetSockName()
function gets the local socket address for the socket indicated by the socket descriptor passed in s
and puts it in sockAddr
. The local socket address is the communication source socket address. If no local socket address has been configured using the nn::socket::Bind
or nn::socket::Connect()
functions, this function returns an address of 0.0.0.0
if called on a UDP-protocol socket (a datagram socket), and returns an error if called on a TCP-protocol socket (a stream socket).
The nn::socket::GetPeerName()
function gets the remote socket address for the socket indicated by the socket descriptor passed in s
and puts it in sockAddr
. The remote socket address is the communication target socket address.
A return value of 0 indicates success for either function. A negative return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Library not initialized. |
|
The specified socket descriptor is not valid. |
|
Not connected to remote host or no communication target. (Only for the |
|
Invalid operation. |
|
Local network interface is down. |
EBUSY |
The internal process is busy. There may be a shortage of sessions specified by Initialize() . |
u32 nn::socket::GetHostId(void);
The nn::socket::GetHostId()
function returns the IPv4 address of the local host. A return value of 0 indicates that the network cannot be used. The returned IP address is a 32-bit numeric value in network byte order.
nn::socket::HostEnt* nn::socket::GetHostByName(const char8* name); nn::socket::HostEnt* nn::socket::GetHostByAddr(const void* addr, s32 len, s32 type); s32 nn::socket::GetAddrInfo(const char8* nodeName, const char8* servName, const nn::socket::AddrInfo* hints, nn::socket::AddrInfo** res); void nn::socket::FreeAddrInfo(nn::socket::AddrInfo* head); s32 nn::socket::GetNameInfo(const void* sa, char8* node, s32 nodeLen, char8* service, s32 serviceLen, s32 flags);
The nn::socket::GetHostByName()
and nn::socket::GetHostByAddr()
functions both get information for the specified host. GetHostByName()
searches for a host based on either the host’s name or address string in dot-decimal notation, and GetHostByAddr()
searches based on the host’s address. Processing blocks while searching, and the function may query the DNS server. The actual representation of the structure holding the return value is a buffer internal to the library, so neither of these functions is thread-safe.
nn::socket::GetAddrInfo
gets information for the host found based on hostname and service name. Configure the search parameters using the flags
member of the nn::socket::AddrInfo
structure passed in the hints
parameter. The flags
member stores a bitwise OR of the flags defined by the nn::socket::AddrInfoFlag
enumerators.
Flag |
Description |
---|---|
|
Uses |
|
Gets the canonical name for |
|
|
|
|
Processing blocks while searching, and the function may query the DNS server. The search results structure returned in res
is stored in memory allocated by the library from the allocator specified in the nn::socket::Initialize()
function. Be sure to release this memory when the search results are no longer needed by calling the nn::socket::FreeAddrInfo()
function.
A return value of 0 indicates success for the nn::socket::GetAddrInfo()
function. A negative return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
EAI_BADFLAGS |
The nodeName is either NULL or an empty string even though AI_CANONNAME is specified for hints . |
|
An unrecoverable error has occurred. |
EAI_FAMILY |
The address family specified in hints is not supported. |
|
Failed to allocate memory. |
|
Could not find the specified host. |
EAI_SOCKTYPE |
The socket type, socket protocol, and socket combinations specified in |
EAI_SYSTEM |
A system error occurred. This occurs when this function is called without Initialize is called. |
The nn::socket::GetNameInfo()
function searches for the hostname and service name based on an address. Configure the search parameters by specifying a bitwise OR of the flags defined by the nn::socket::NameInfoFlag
enumerators in the flags
parameter.
Flag |
Description |
---|---|
|
Gets only the node name portion of a fully qualified domain name as the hostname. |
|
Stores the host address in |
|
If the specified host cannot be found, the numeric host address is converted to a string, not replaced, and handled as an error ( |
|
Stores the service (port number) in |
Processing blocks while searching, and the function may query the DNS server.
A return value of 0 indicates success. A negative return value indicates an error. The following table lists the errors that may occur.
Return Value |
Error Description |
---|---|
|
Unsupported protocol family included in the socket address specified in |
|
Invalid buffer size specified in If |
EAI_SYSTEM |
A system error occurred. This occurs when this function is called without Initialize is called. |
s32 nn::socket::InetAtoN(const char* cp, nn::socket::InAddr* inp); char* nn::socket::InetNtoA(nn::socket::InAddr in); s32 nn::socket::InetPtoN(int af, const char* src, void* dst); const char* nn::socket::InetNtoP(int af, const void* src, char* dst, unsigned len);
Call the nn::socket::InetAtoN()
and nn::socket::InetNtoA()
functions to convert an address between a numeric string and the nn::socket::InAddr
structure’s numeric format. These functions can convert IPv4 host addresses. The nn::socket::InetPtoN()
and nn::socket::InetNtoP()
functions previously allowed various values for the af
address family argument, but on the CTR-SDK these functions only take the value AF_INET
for this argument.
These functions can be used even if nn::socket::Initialize
has not been called.
bit32 nn::socket::HtoNl(bit32 v); bit32 nn::socket::NtoHl(bit32 v); bit16 nn::socket::HtoNs(bit16 v); bit16 nn::socket::NtoHs(bit16 v);
Use these functions to convert a numeric value from host byte order to network byte order (HtoN
) and back again (NtoH
). The functions ending in "l
" take 32-bit values, while those ending in "s
" take 16-bit values.
6.2. SSL Communication
The SSL library is a wrapper for SSL communication to help keep communication secure.
6.2.1. Initializing
Call the nn::ssl::Initialize()
function to initialize the SSL library.
nn::Result nn::ssl::Initialize(void);
6.2.2. Generating an Instance of the Connection Class
SSL communication is handled by the nn::ssl::Connection
class, which itself is a wrapper for sockets.
class nn::ssl::Connection { explicit Connection(s32 socket); explicit Connection(); bool AssignSocket(s32 socket); }
Two constructors are available: one that takes a socket descriptor as an argument, and one that does not. For Connection
class instances generated without an argument, you must call the AssignSocket
member function to bind a socket.
6.2.1. Setting the Communication Target
Use the Initialize
member function to set the communication target server to the connection class.
class nn::ssl::Connection { nn::Result Initialize(const char* pServerName, u32 verifyOpt = VERIFY_NONE); }
pServerName
specifies the hostname of the communication target server. When using SSL communication, this hostname is compared against the dnsName/ipAddress
values in the subjectAltName
extended region or the CommonName
of the server certificate, and a communication error occurs if these values do not match. The maximum length of the specifiable hostname string, including the string terminator, is nn::socket::MAXDNAME
bytes.
verifyOpt
specifies any options for server verification during SSL communication. Omit this parameter to use the default server verification. When implementing a server verification option that is not implemented by default, specify in verifyOpt
an enumerator value from the nn::ssl:VerifyOption
enumerated type that specifies this option. To use multiple verification options simultaneously, specify the bitwise OR of these values. This parameter can take the following values.
Value |
Description |
---|---|
|
Verify the certificate’s expiration date. |
|
Use SSL resumption and attempt to reuse the session when connecting to the same host multiple times in a row. |
|
Verifies the EV certificate. Verification succeeds unless the server certificate is linked to an EV certificate. Trusted EV certificates can be set using |
|
Verifies the server certificate, but ignores results and proceeds. Call |
|
Saves all certificate data in the certificate chain when saving the server certificate in the buffer specified by |
Other options not in the table are implemented by default, as defined in the nn::ssl::VerifyOption
enumerated type.
When saving all certificates in the certificate chain, each certificate is saved with the first four bytes indicating the length of the certificate data, followed by the certificate data itself. The data layout starts with the first certificate in the chain (the server certificate) and continues through to the last certificate in the chain (the CA certificate). However, if CA verification fails, the CA certificate cannot be designated and is excluded.
6.2.4. Setting the Certificate and CRL
Use the following function to configure the connection class with the certificate and CRL stores and the client certificate to use in the handshake with the server.
class nn::ssl::Connection { nn::Result SetServerCertStore(nn::ssl::CertStore& certStore); nn::Result SetClientCert(nn::ssl::ClientCert& clientCert); nn::Result SetCRLStore(nn::ssl::CrlStore& crlStore); }
Use the SetServerCertStore()
function to set a server certificate store, use SetCRLStore
to set a CRL store, and use SetClientCert
to set a client certificate.
6.2.4.1. Certificate Store Class
The certificate store class is defined by nn::ssl::CertStore
.
class nn::ssl::CertStore { explicit CertStore(); virtual ~CertStore(void); nn::Result Initialize(void); nn::Result Finalize(void); nn::Result RegisterCert(const u8* pCertData, size_t certDataSize, nn::ssl::CertId* pCertIdCourier=NULL); nn::Result RegisterCert(nn::ssl::InternalCaCert inCaCertName, nn::ssl::CertId* pCertIdCourier=NULL); nn::Result UnRegisterCert(nn::ssl::CertId certId); }
The constructor has no arguments. Generate an instance and call the Initialize()
function.
Call the RegisterCert
member function to register a certificate to the certificate store. pCertData
and certDataSize
specify the certificate data and its size in bytes. Specify nn::ssl::InternalCaCert
as the argument instead to set a certificate stored internally to the certificate store. pCertIdCourier
may be omitted unless you need to unregister an individual certificate. Call the Finalize()
function to unregister all certificates that have not been individually unregistered. Call the RegisterCert
member function multiple times to register multiple certificates to the certificate store.
Use the UnRegisterCert
member function to unregister an individual certificate from the certificate store. Specify the certificate ID obtained in pCertIdCourier
when registering the certificate via RegisterCert
as the value for the certId
argument.
Be sure to call the Finalize()
function when the certificate store is no longer needed.
6.2.4.2. CRL Store Class
The CRL store class is defined by nn::ssl::CrlStore
.
class nn::ssl::CrlStore { explicit CrlStore(); virtual ~CrlStore(void); nn::Result Initialize(void); nn::Result Finalize(void); nn::Result RegisterCrl(const u8* pCrlData, size_t crlDatasize, nn::ssl::CrlId* pCrlIdCourier=NULL); nn::Result RegisterCrl(nn::ssl::InternalCrl inCrlName, nn::ssl::CrlId* pCrlIdCourier=NULL); nn::Result UnRegisterCrl(nn::ssl::CrlId crlId); }
The constructor has no arguments. Generate an instance and call the Initialize()
function.
Call the RegisterCrl
member function to register a CRL to the CRL store. pCrlData
and crlDataSize
specify the CRL data and its size in bytes. Specify nn::ssl::InternalCrl
as the argument instead to set a CRL stored internally to the CRL store. pCrlIdCourier
may be omitted unless you need to unregister an individual CRL. Call the Finalize()
function to unregister all CRLs that have not been individually unregistered. Call the RegisterCrl
member function multiple times to register multiple CRLs to the CRL store.
Use the UnRegisterCrl
member function to unregister an individual CRL from the CRL store. Specify the CRL ID obtained in pCrlIdCourier
when registering the certificate via RegisterCrl
as the value for the crlId
argument.
Be sure to call the Finalize()
function when the CRL store is no longer needed.
6.2.4.3. Client Certificate Class
The client certificate class is defined by nn::ssl::ClientCert
.
class nn::ssl::ClientCert { explicit ClientCert(); virtual ~ClientCert(void); nn::Result Initialize(const u8* pCertData, size_t certDataSize, const u8* pPrivateKeyData, size_t privateKeyDataSize); nn::Result Initialize(nn::ssl::InternalClientCert inClientCertName); nn::Result Finalize(void); }
The constructor has no arguments. Generate an instance and call the Initialize()
function.
pCertData
and certDataSize
specify the client certificate data and its size in bytes. pPrivateKeyData
and privateKeyDataSize
specify the private key data and its size in bytes. Specify nn::ssl::InternalClientCert
instead to use an internal client certificate.
Be sure to call the Finalize()
function when the client certificate is no longer needed.
6.2.5. Handshaking
Call the DoHandshake()
function of the Connection
class to use the configured certificate and CRL stores and client certificate to handshake with the connection target server.
class nn::ssl::Connection { nn::Result SetServerCertBuffer(uptr bufferAddress, size_t bufferSize); nn::Result DoHandshake(void); nn::Result DoHandshake(size_t* pServerCertSize, u32* pServerCertNum = NULL); }
Call the DoHandshake()
function version with arguments when you need information about a server certificate sent from the server. The size of the server certificate in bytes is stored in the variable pointer specified in pServerCertSize
.
Specify the buffer to store the server certificate by calling the SetServerCertBuffer()
function. The buffer specified must be allocated from outside of device memory. The starting address of the buffer specified must be aligned to nn::ssl::Connection::BUFFER_ALIGNMENT
(4,096 bytes), and the size of the buffer must be a multiple of nn::ssl::Connection::BUFFER_UNITSIZE
(4,096 bytes). Calling the DoHandshake()
function version with arguments without specifying a buffer via SetServerCertBuffer
is effectively identical to calling the DoHandshake()
function version that has no arguments.
6.2.6. Transferring Data
After confirming a successful handshake, you can start sending and receiving data via SSL communication.
class nn::ssl::Connection { nn::Result Read(u8* pDataBuf, size_t dataBufSize, size_t* pReadSizeCourier = NULL); nn::Result Peek(u8* pDataBuf, size_t dataBufSize, size_t* pReadSizeCourier = NULL); nn::Result Write(const u8* pDataBuf, size_t dataBufSize, size_t* pWrittenDataSizeCourier = NULL); }
The Read()
and Peek()
member functions both receive data. Peek
does not change the state of data received, and data received this way can be received again. pDataBuf
and dataBufSize
specify a buffer to receive the data and its size in bytes. Specify a pointer to a variable in pReadSizeCourier
for receiving the data size if you need the size in bytes of the received data.
The Write()
member function sends data. pDataBuf
and dataBufSize
specify a buffer to store the data to send and its size in bytes. Specify a pointer to a variable in pWrittenDataSizeCourier
for receiving the data size if you need the size in bytes of the sent data.
6.2.7. Disconnecting
Only a limited number of SSL connections may be used at any one time. Be sure to call the Shutdown
member function on class instances that are no longer needed to disconnect SSL connections and finalize the instances.
class nn::ssl::Connection { nn::Result Shutdown(void); }
6.2.8. Finalizing
6.3. HTTP Communication
The HTTP library handles connecting to the specified URL and communicating over the network via the HTTP protocol. The library also supports the HTTPS protocol.
6.3.1. Initializing
Call the nn::http::Initialize()
function to initialize the HTTP library.
nn::Result nn::http::Initialize(uptr bufferAddress = 0, size_t bufferSize = 0);
You must call this function before using the HTTP library. The function returns nn::http::ResultAlreadyInitialized
if called after the library is already initialized.
Specify bufferAddress
and bufferSize
. The buffer you pass for communications must be allocated from outside of device memory. The starting address of the buffer must be aligned to nn::http::BUFFER_ALIGNMENT
(4,096 bytes), and the size of the buffer must be a multiple of nn::http::BUFFER_UNITSIZE
(4,096 bytes).
6.3.2. Generating an Instance of the Connection Class
Use the nn::http::Connection
class to work with HTTP connections. You must generate one instance of this class for each URL to connect to. The number of connections that can be used at one time by the system as a whole and by the application is limited, so take care when managing connections.
There are two constructor versions: one with arguments and one without. After generating an instance using the constructor with no arguments, you must call the Initialize
member function to configure the URL to connect to, the connection method, and whether to use a default proxy.
class nn::http::Connection { explicit Connection(void); explicit Connection(const char* pUrl, RequestMethod method = REQUEST_METHOD_GET, bool isUseDefaultProxy = true); nn::Result Initialize(const char* pUrl, RequestMethod method = REQUEST_METHOD_GET, bool isUseDefaultProxy = true); }
Specify the URL to connect to in the pUrl
parameter.
Specify the HTTP request method in the method
parameter. Select from one of the following three types.
Definition |
Description |
---|---|
|
|
|
|
|
|
Specify true
for the isUseDefaultProxy
parameter to use the default proxy when connecting. Specify false
to use a different proxy, and configure that separately.
In case of any error occurring during initialization, check the Description
property of the nn::Result
class instance returned by the Initialize()
function.
Description Value |
Cause of Error |
---|---|
|
The system as a whole has no free communications resources. |
|
The specified URL is invalid. |
|
A destination URL has already been specified |
|
No free application-allocated communications resources. |
6.3.3. Configuring Communication
Use these functions to configure various aspects of communication, such as proxy settings, basic verification, or the receive buffer size of the socket used in communication. These settings must be configured before initiating a connection.
class nn::http::Connection { nn::Result SetProxy(const char* pProxyName, u16 port, const char* pUserName, const char* pPassword); nn::Result SetBasicAuthorization(const char* pUserName, const char* pPassword); }
Call the SetProxy()
function to use a proxy other than the default. Specify the proxy URL and port in the pProxyName
and port
parameters, and specify the verification user name and password in the pUserName
and pPassword
parameters.
Call the SetBasicAuthorization()
function if you need to configure basic user verification on connection. Specify the user name and password to use in the pUserName
and pPassword
parameters.
6.3.3.1. Configuring for HTTPS Communication
To use the HTTPS protocol, you must first configure SSL communication settings, such as the CA, CRL, and client certificates.
class nn::http::Connection { nn::Result SetRootCa(const u8* pCertData, size_t certDataSize); nn::Result SetRootCa(nn::http::InternalCaCertId inCaCertName); nn::Result SetRootCaStore(nn::http::CertStore& certStore); nn::Result SetCrl(const u8* pCrlData, size_t crlDataSize); nn::Result SetCrl(nn::http::InternalCrlId inCrlName); nn::Result SetCrlStore(CrlStore& crlStore); nn::Result SetClientCert(const u8* pCertData, size_t certDataSize, const u8* pPrivateKeyData, size_t privateKeyDataSize); nn::Result SetClientCert(nn::http::InternalClientCertId inClientCertName); nn::Result SetClientCert(nn::http::ClientCert& clientCert); nn::Result GetSslError(s32* pResultCodeBuf) const; nn::Result SetVerifyOption(u32 verifyOption); nn::Result DisableVerifyOptionForDebug(u32 excludeVerifyOptions); }
Call the SetRootCa()
function to register a CA certificate. You can register the certificate data directly, or specify nn::http::InternalCaCertId
to use the internal CA certificate included in the system.
If you need to register multiple CA certificates, either call SetRootCa()
multiple times, or call SetRootCaStore()
and specify an instance of the nn::http::CerStore
class as an argument. This allows you to use the same set of CA certificates for multiple connections.
Do not destroy the instance of the nn::http::CertStore
class until you have finished using the set of CA certificates.
class nn::http::CertStore { explicit CertStore(); virtual ~CertStore (void); nn::Result Initialize(void); nn::Result Finalize(void); nn::Result RegisterCert(const u8* pCertData, size_t certDataSize, nn::http::CertId* pCertIdCourier=NULL); nn::Result RegisterCert(nn::http::InternalCaCertId inCaCertName, nn::http::CertId* pCertIdCourier=NULL); nn::Result UnRegisterCert(nn::http::CertId certId); }
Be sure to call the Initialize
member function when using an nn::http::CertStore
class instance. Call the RegisterCert()
function to register a CA certificate. Call the function multiple times to register multiple CA certificates to use them together as a set.
To register an individual CA certificate, call the UnRegisterCert()
function, passing as an argument the value returned in the pCertIdCourier
parameter when you registered the certificate. After you finish using a class instance, you must call the Finalize()
function to destroy the instance.
Call the SetCrl()
function to set a CRL. You can set the CRL data directly, or specify nn::http::InternalCrlId
to use the internal CA certificates included in the system. Note that there are no internal CRLs at present.
Much as for CA certificates, if you need to register multiple CRLs, either call SetCrl()
multiple times, or call SetCrlStore()
and specify an instance of the nn::http::CrlStore
class as an argument. Use the nn::http::CrlStore
class the same way you would use the nn::http::CertStore
class.
class nn::http::CrlStore { explicit CrlStore(); virtual ~CrlStore (void); nn::Result Initialize(void); nn::Result Finalize(void); nn::Result RegisterCrl(const u8* pCrlData, size_t crlDataSize, nn::http::CrlId* pCrlIdCourier=NULL); nn::Result RegisterCrl(nn::http::InternalCrlId inCrlName, nn::http::CrlId* pCrlIdCourier=NULL); nn::Result UnRegisterCrl(nn::http::CrlId crlId); }
Call the SetClientCert()
function to register a client certificate. You can configure the certificate by specifying the certificate data and secret key, by specifying the system’s internal client certificate, or by using an nn::http::ClientCert
class instance to use the same set of client certificates for multiple connections.
When using an nn::http::ClientCert
class instance with multiple connections, do not destroy the instance until you finish using it.
class nn::http::ClientCert { explicit ClientCert(); virtual ~ClientCert (void); nn::Result Initialize(const u8* pCertData, size_t certDataSize, const u8* pPrivateKeyData, size_t privateKeyDataSize); nn::Result Initialize(nn::http::InternalClientCertId inClientCertName); nn::Result Finalize(void); }
The nn::http::ClientCert
class includes two versions of its Initialize()
function, one that allows you to specify the certificate data and secret key, and one that uses the system’s internal client certificate. After you finish using a class instance, you must call the Finalize()
function to destroy the instance.
Call the SetVerifyOption()
function to enable any server verification option that is disabled by default. The options enabled by default are VERIFY_COMMON_NAME
(CommonName
verification), VERIFY_ROOT_CA
(RootCA verification), and VERIFY_SUBJECT_ALT_NAME
(SubjectAlternativeName
verification).
Other options that you can enable in the current SDK version are VERIFY_DATE
(checks for certificate expiration), USE_SESSION_CACHE
(allows for sessions to be resumed), and VERIFY_EV
(EV certificate verification).
You can call the DisableVerifyOptionForDebug()
function to disable all verification options, but note that this is intended only for debugging purposes.
Check for any errors occurring during HTTPS communication by calling the GetSslError()
function and examining the value stored in the pResultCodeBuf
parameter. These error code values are defined by the nn::ssl::ResultCode
class.
6.3.4. Configuring Data to Send
Before initiating a connection and sending data, you must first add a message field header or POST
data. Use the lazy POST
data setting mode to add POST
data after initiating a connection.
class nn::http::Connection { nn::Result AddHeaderField(const char* pLabel, const char* pValue); nn::Result SetPostDataEncoding(nn::http::EncodingType type); nn::Result AddPostDataAscii(const char* pLabel, const char* pValue); nn::Result AddPostDataBinary(const char* pLabel, const void* pValue, size_t valueSize); nn::Result AddPostDataRaw(const void* pValue, size_t valueSize); }
Call the AddHeaderField()
function to add a header to the message field. For example, specify the strings Connection
for the pLabel
parameter and keep-alive
for the pValue
parameter to add a header with the label Connection
and the content keep-alive
.
Call the SetPostDataEncoding()
function to specify the POST
data encoding method, and then call AddPostDataAscii
or another appropriate function to add the data.
Specify a value defined by the nn::http::EncodingType
enumerated type for the type
argument.
Definition |
Description |
---|---|
|
Sends data in URL encoding if all data was added using the |
|
Sends data in URL encoding. Call the |
|
Sends data without encoding it. |
POST
data added using the AddPostDataAscii()
function (ASCII string data) and sent in URL encoding has both labels and data encoded. POST
data that includes binary data or for which the encoding method is specified as multi-part is sent without encoding either the labels or data.
POST
data added using the AddPostDataBinary()
function (binary data) is sent as is, without encoding.
Call the AddPostDataRaw()
function to add multiple POST
data items at the same time, unlike the two functions above. This function only allows you to specify binary POST
data. Calling either the AddPostDataAscii
or AddPostDataBinary()
functions after calling AddPostDataRaw
returns an error with ER_POST_ADDED_ANOTHER
set for the Description
. Calling AddPostDataRaw
a second time discards the data added the first time, adding instead the POST
data specified in this second call.
6.3.4.1. Lazy POST Data Setting Mode
Use the lazy POST
data setting mode to send POST
data after initiating a connection. Note that the SendPostData*()
functions execute synchronously when sending POST
data in this mode, so processing blocks until sending is finished. However, you can impose a timeout by specifying a value for the timeout
parameter of the overloaded version. This causes the function to call Cancel
internally after the timeout period has passed, canceling the connection.
class nn::http::Connection { nn::Result SetLazyPostDataSetting(nn::http::PostDataType dataType); nn::Result NotifyFinishSendPostData(void); nn::Result SendPostDataAscii(const char* pLabel, const char* pValue); nn::Result SendPostDataAscii(const char* pLabel, const char* pValue, const nn::fnd::TimeSpan& timeout); nn::Result SendPostDataBinary( const char* pLabel, const void* pValue, size_t valueSize); nn::Result SendPostDataBinary( const char* pLabel, const void* pValue, size_t valueSize, const nn::fnd::TimeSpan& timeout); nn::Result SendPostDataRaw(const void* pValue, size_t valueSize); nn::Result SendPostDataRaw(const void* pValue, size_t valueSize, const nn::fnd::TimeSpan& timeout); }
Call the SetLazyPostDataSetting()
function to use this mode. The function to call and the sending method used for the POST data differ depending on the value specified for the sending data type specified in dataType
. Specify a value defined by the nn::http::PostDataType
enumerated type for the dataType
parameter.
Definition |
Description |
---|---|
|
Sends data in URL encoding. |
|
Sends data in multi-part format. |
|
Sends data in raw format. |
When sending in URL encoding, you can call either the SendPostDataAscii
or SendPostDataBinary()
functions. Call SendPostDataAscii
to send the data in URL encoding with a format where (label name)=(data content), and call SendPostDataBinary
to send identical but unencoded data.
When sending in multi-part format, you can call either the SendPostDataAscii
or SendPostDataBinary()
functions. Data is sent in chunks, with each chunk starting with boundary data and header fields. Both functions add a header field after the boundary data with the label Content-Disposition: form-data; name=[label]
, but the SendPostDataBinary()
function precedes this header field with another one containing the text Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: binary\r\n
.
When sending data in RAW format. You can only call the SendPostDataRaw()
function. Data is sent in chunks as chunked data.
You must call the NotifyFinishSendPostData()
function after you finish sending all POST data. After calling this function, the system waits to receive an HTTP response.
6.3.5. Opening a Connection
Initiate an HTTP connection to the URL specified in initialization. There are two ways to start a connection. Call either the Connect()
function, which blocks until a connection is established, or the ConnectAsync()
function, which returns immediately. Call the Cancel()
function to cancel a connection.
class nn::http::Connection { nn::Result Connect(void); nn::Result ConnectAsync(void); nn::Result Cancel(void); }
Connect
still blocks even if all HTTP connections available to the system are already in use, whereas ConnectAsync
returns an error immediately.
Call the Cancel()
function to cancel an HTTP connection, with that instance of the Connection
class halting communication.
When a connection is initiated using the nn::http::Connection::Connect
or nn::http::Connection::ConnectAsync()
function, if the WAN cable to the access point is removed while the function is receiving the header information, the function continues to wait forever.
To prevent this situation from occurring, you must implement your program in a way that terminates communication (by calling nn::http::Connection::Cancel
) after a timeout period.
6.3.6. Receiving a Response
After calling Connect
or a similar function to start the connection, call the Read()
function to get the HTTP response message body, GetStatusCode
to get the response status, GetHeaderField
to get a specific message header, and GetHeaderAll
to get all headers. You can impose a timeout by specifying a value for the timeout
parameter of the overloaded version. This causes the function to call Cancel
internally after the timeout period has passed, canceling the connection.
class nn::http::Connection { nn::Result Read(u8* pBodyBuf, size_t bufLen); nn::Result Read(u8* pBodyBuf, size_t bufLen, const nn::fnd::TimeSpan& timeout); nn::Result GetStatusCode(s32* pStatusCodeCourier) const; nn::Result GetStatusCode(s32* pStatusCodeCourier, const nn::fnd::TimeSpan& timeout) const; nn::Result GetHeaderField( const char* pLabel, char* pFieldBuf, size_t bufSize, size_t* pFieldLengthCourier = NULL) const; nn::Result GetHeaderField( const char* pLabel, char* pFieldBuf, size_t bufSize, const nn::fnd::TimeSpan& timeout, size_t* pFieldLengthCourier = NULL) const; nn::Result GetHeaderAll( char* pHeaderBuf, size_t bufSize, size_t* pLengthCourier = NULL) const; nn::Result GetHeaderAll( char* pHeaderBuf, size_t bufSize, const nn::fnd::TimeSpan& timeout, size_t* pLengthCourier = NULL) const; }
When calling the Read()
function, specify the buffer to store the message body in the pBodyBuf
parameter and its size in the bufLen
parameter. If the message body is too big to fit in the buffer, the function stores as much of the body as fits and then returns nn::http::ResultBodyBufShortage
, in which case you can call Read
again to read the remainder of the message body. Any other error returned indicates a failure to receive the HTTP response. However, HTTP status errors for events such as authentication failures are sent with the error message as the message body, so that Read
operates as normal, as a successful connection, returning nn::http::ResultBodyBufShortage
if the message body is too big to fit in the buffer, and returning an instance whose IsSuccess
member returns true
upon reading through to the end of the message body.
When calling the GetStatusCode()
function, specify an s32
variable in the pStatusCodeCourier
parameter to store the response status. Check this response status to find out if any communication errors have occurred. If called when receiving the message header, this function blocks until the header has been fully received. If called after calling Read
, the header has already been fully received, and this function returns immediately.
When calling the GetHeaderField()
function, specify the label of the header field to get in the pLabel
parameter, the buffer to store this data in the pFieldBuf
parameter, and the buffer size in the bufSize
parameter. As long as pFieldBuf
is not NULL
, bufSize
is not 0
, and pFieldLengthCourier
is not NULL
, the size in bytes of the specified label’s header field is stored in the variable specified in pFieldLengthCourier
.
When calling the GetHeaderAll()
function, specify the buffer to store all header fields in the pHeaderBuf
parameter and the buffer size in the bufSize
parameter. As long as pHeaderBuf
is not NULL
, bufSize
is not 0
, and pLengthCourier
is not NULL
, the size in bytes of the buffer required to store all message headers is stored in the variable specified in pLengthCourier
. If called when receiving the message header, these functions block until the header has been fully received. If called after calling Read
, the header has already been fully received, and these functions return immediately.
6.3.7. Getting Connection State and Other Information
The Connection
class includes functions to get the state of the class, the codes of any errors that have occurred, and response reception progress.
class nn::http::Connection { nn::Result GetStatus(nn::http::Status* pStatusBuf) const; nn::Result GetError(nn::http::ResultCode* pResultCodeBuf) const; nn::Result GetProgress(size_t* pReceivedLen, size_t* pContentLen) const; }
When calling the GetStatus()
function, specify a buffer in the pStatusBuf
parameter to store the connection state. The stored value is an nn::http::Status
enumerated type.
When calling the GetError()
function, specify a buffer in pResultCodeBuf
parameter to store the error code. The stored value is an nn::http::ResultCode
enumerated type.
When calling the GetProgress()
function, specify a variable in the pReceivedLen
parameter to store the size in bytes of the message body received so far, and specify a variable in the pContentLen
parameter to store the total length of the message body. This total length is the value of the Content-Length
HTTP response header, so pContentLen
stores 0
if the Content-Length
header is missing.
6.3.8. Closing a Connection
After fully receiving the HTTP response and after the class instance is no longer needed, make sure that you call the Finalize()
function to destroy it. You do not need to call the function for instances that have not been initialized and do not specify a target URL.
class nn::http::Connection { nn::Result Finalize(void); }