]> Chaos Git - corbenik/ctrulib.git/commitdiff
Implemented full support for connecting as an UDS spectator.
authoryellows8 <yellows8@users.noreply.github.com>
Wed, 6 Apr 2016 20:26:06 +0000 (16:26 -0400)
committeryellows8 <yellows8@users.noreply.github.com>
Wed, 6 Apr 2016 20:26:06 +0000 (16:26 -0400)
libctru/include/3ds/services/uds.h
libctru/source/services/uds.c

index 84b4445da8147aa19f7ecef02c4cfa57602595dc..28e24956ac08bf4361b7006d32501d1afd08efb6 100644 (file)
@@ -68,6 +68,7 @@ typedef struct {
 typedef struct {
        u32 BindNodeID;
        Handle event;
+       bool spectator;
 } udsBindContext;
 
 /// General NWM input structure used for AP scanning.
@@ -205,8 +206,9 @@ Result udsGetNetworkStructApplicationData(udsNetworkStruct *network, u8 *buf, u3
  * @brief Create a bind.
  * @param bindcontext The output bind context.
  * @param NetworkNodeID This is the NetworkNodeID which this bind can receive data from.
+ * @param spectator False for a regular bind, true for a spectator.
  */
-Result udsBind(udsBindContext *bindcontext, u16 NetworkNodeID);
+Result udsBind(udsBindContext *bindcontext, u16 NetworkNodeID, bool spectator);
 
 /**
  * @brief Remove a bind.
index 70d1a744993cdb903b363b993ea5dfa6bd2bfdd6..cd343976ae8aedb733f0719a9e5c312271e0fee2 100644 (file)
@@ -252,7 +252,7 @@ Result udsCreateNetwork(udsNetworkStruct *network, void* passphrase, size_t pass
        ret = udsipc_BeginHostingNetwork(network, passphrase, passphrase_size);
        if(R_FAILED(ret))return ret;
 
-       ret = udsBind(context, UDS_BROADCAST_NETWORKNODEID);
+       ret = udsBind(context, UDS_BROADCAST_NETWORKNODEID, false);
 
        if(R_FAILED(ret))udsDestroyNetwork();
 
@@ -262,11 +262,15 @@ Result udsCreateNetwork(udsNetworkStruct *network, void* passphrase, size_t pass
 Result udsConnectNetwork(udsNetworkStruct *network, void* passphrase, size_t passphrase_size, udsBindContext *context, u16 recv_NetworkNodeID, udsConnectionType connection_type)
 {
        Result ret=0;
+       bool spectator=false;
+
+       if(connection_type==UDSCONTYPE_Spectator)spectator=true;
+
        //printf("connecting...\n");//Removing these prints caused connecting to fail.
        ret = udsipc_ConnectToNetwork(network, passphrase, passphrase_size, connection_type);
        if(R_FAILED(ret))return ret;
        //printf("bind...\n");
-       ret = udsBind(context, recv_NetworkNodeID);
+       ret = udsBind(context, recv_NetworkNodeID, spectator);
 
        if(R_FAILED(ret))udsDisconnectNetwork();
 
@@ -513,21 +517,32 @@ Result udsScanBeacons(u8 *outbuf, u32 maxsize, udsNetworkScanInfo **networks, u3
        return ret;
 }
 
-Result udsBind(udsBindContext *bindcontext, u16 NetworkNodeID)
+Result udsBind(udsBindContext *bindcontext, u16 NetworkNodeID, bool spectator)
 {
        u32 pos;
 
        memset(bindcontext, 0, sizeof(udsBindContext));
 
-       for(pos=0; pos<UDS_MAXNODES; pos++)
+       if(spectator)
+       {
+               pos = 0;
+               if((bind_allocbitmask & BIT(pos)))return -1;
+       }
+       else
        {
-               if((bind_allocbitmask & BIT(pos)) == 0)break;
+               for(pos=1; pos<UDS_MAXNODES+1; pos++)
+               {
+                       if((bind_allocbitmask & BIT(pos)) == 0)break;
+               }
+               if(pos==UDS_MAXNODES)return -1;
        }
-       if(pos==UDS_MAXNODES)return -1;
 
        bind_allocbitmask |= BIT(pos);
 
-       bindcontext->BindNodeID = (pos+1)<<1;
+       bindcontext->BindNodeID = (pos<<1);
+       if(spectator)bindcontext->BindNodeID |= spectator;
+
+       bindcontext->spectator = spectator;
 
        return udsipc_Bind(bindcontext, 0x2e30, 0xf3, NetworkNodeID);
 }
@@ -535,6 +550,7 @@ Result udsBind(udsBindContext *bindcontext, u16 NetworkNodeID)
 Result udsUnbind(udsBindContext *bindcontext)
 {
        Result ret=0;
+       u32 bitpos = 0;
 
        if(bindcontext->event)
        {
@@ -543,7 +559,8 @@ Result udsUnbind(udsBindContext *bindcontext)
 
        ret = udsipc_Unbind(bindcontext);
 
-       bind_allocbitmask &= ~BIT((bindcontext->BindNodeID>>1) - 1);
+       if(!bindcontext->spectator)bitpos = bindcontext->BindNodeID>>1;
+       bind_allocbitmask &= ~BIT(bitpos);
 
        memset(bindcontext, 0, sizeof(udsBindContext));