Changes

2,135 bytes added ,  07:08, 20 June 2017
Add some usage info for svcReplyAndReceive
Line 240: Line 240:  
| Same as above except for read-only buffer. Prior(?) to the kernel version which implemented memory-permission checking for PXI buffers, this was unused and hence triggered a kernelpanic.
 
| Same as above except for read-only buffer. Prior(?) to the kernel version which implemented memory-permission checking for PXI buffers, this was unused and hence triggered a kernelpanic.
 
|}
 
|}
 +
 +
 +
== SVCs ==
 +
 +
=== svcReplyAndReceive ===
 +
 +
'''Signature:'''
 +
Result ReplyAndReceive(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)
 +
 +
In a single operation, sends a IPC reply and waits for a new request. <code>handles</code> should be a pointer to an array of <code>handleCount</code> handles.<sup>TODO: Are only port/session handles supported?</sup>
 +
<code>replyTarget</code> should contain a handle to the session to send the reply to. (This us usually the session from which we received the previous request.)
 +
If <code>replyTarget</code> is 0, no reply and the call will simply wait for an incoming event.<sup>TODO: It doesn't seem like the 0xFFFF0000 command id mentioned in the above sections is necessary, but needs confirmation.</sup>
 +
 +
Upon returning, <code>index</code> will contain an index into <code>handles</code> specifying which object changed state.
 +
If it's a server port endpoint, it means that there is a new incoming connection on that port which should be accepted using svcAcceptSession.
 +
If it's a server session endpoint it means that we received a request from that session and should process and then reply to it by calling svcReplyAndReceive again with <code>replyTarget</code> set to that session's handle.
 +
 +
An example of a server svcReplyAndReceive loop is:
 +
 +
#define MAX_CLIENTS 4
 +
Handle server_port = ...;
 +
s32 requesting_index;
 +
Handle handles[1 + MAX_CLIENTS] = { server_port };
 +
s32 connected_clients = 0;
 +
Handle reply_target = 0;
 +
 +
while (true) {
 +
    Result res = svcReplyAndReceive(&requesting_index, &handles, 1 + connected_clients, reply_target);
 +
 +
    if (res == 0xC920181A) {
 +
        // Session was closed by remote
 +
        // TODO: Handle disconnects
 +
        reply_target = 0;
 +
        continue;
 +
    }
 +
 +
    if (requesting_index == 0) {
 +
        // New connection in server_port
 +
        ASSERT(connected_client < MAX_CLIENTS);
 +
        svcAcceptSession(&handles[1 + connected_clients++], server_port);
 +
        reply_target = 0;
 +
        continue;
 +
    }
 +
 +
    reply_target = handles[requesting_index];
 +
 +
    // Handle command here and write reply to command buffer
 +
}
110

edits