/*
This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.HLE.modules;
import static jpcsp.HLE.kernel.types.SceKernelErrors.ERROR_NET_RESOLVER_BAD_ID;
import jpcsp.HLE.BufferInfo;
import jpcsp.HLE.BufferInfo.Usage;
import jpcsp.HLE.CheckArgument;
import jpcsp.HLE.HLEFunction;
import jpcsp.HLE.HLEModule;
import jpcsp.HLE.HLEUnimplemented;
import jpcsp.HLE.PspString;
import jpcsp.HLE.SceKernelErrorException;
import jpcsp.HLE.TPointer;
import jpcsp.HLE.TPointer32;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import org.apache.log4j.Logger;
import jpcsp.HLE.kernel.managers.SceUidManager;
import jpcsp.HLE.kernel.types.SceKernelErrors;
import jpcsp.HLE.Modules;
import jpcsp.Processor;
public class sceNetResolver extends HLEModule {
public static Logger log = Modules.getLogger("sceNetResolver");
private static final String uidPurpose = "sceNetResolver-NetResolver";
protected static class ResolverID {
private int id;
private boolean isRunning;
public ResolverID (int id, boolean running) {
this.id = id;
this.isRunning = running;
}
public int getID() {
return id;
}
public boolean getIDStatus () {
return isRunning;
}
public void stop() {
isRunning = false;
}
}
protected HashMap<Integer, ResolverID> RIDs = new HashMap<Integer, ResolverID>();
public int checkRid(int rid) {
if (!RIDs.containsKey(rid)) {
throw new SceKernelErrorException(ERROR_NET_RESOLVER_BAD_ID);
}
return rid;
}
/**
* Initialize the resolver library
*
* @return 0 on success, < 0 on error.
*/
@HLEFunction(nid = 0xF3370E61, version = 150)
public int sceNetResolverInit() {
return 0;
}
/**
* Terminate the resolver library
*
* @return 0 on success, < 0 on error
*/
@HLEFunction(nid = 0x6138194A, version = 150)
public int sceNetResolverTerm() {
return 0;
}
/**
* Create a resolver object
*
* @param rid - Pointer to receive the resolver id
* @param buf - Temporary buffer
* @param buflen - Length of the temporary buffer
*
* @return 0 on success, < 0 on error
*/
@HLEFunction(nid = 0x244172AF, version = 150)
public int sceNetResolverCreate(TPointer32 pRid, TPointer buffer, int bufferLength) {
int newID = SceUidManager.getNewUid(uidPurpose);
ResolverID newRID = new ResolverID(newID, true);
RIDs.put(newID, newRID);
pRid.setValue(newRID.getID());
return 0;
}
/**
* Delete a resolver
*
* @param rid - The resolver to delete
*
* @return 0 on success, < 0 on error
*/
@HLEFunction(nid = 0x94523E09, version = 150)
public int sceNetResolverDelete(@CheckArgument("checkRid") int rid) {
RIDs.remove(rid);
SceUidManager.releaseUid(rid, uidPurpose);
return 0;
}
/**
* Begin a name to address lookup
*
* @param rid - Resolver id
* @param hostname - Name to resolve
* @param addr - Pointer to in_addr structure to receive the address
* @param timeout - Number of seconds before timeout
* @param retry - Number of retires
*
* @return 0 on success, < 0 on error
*/
@HLEFunction(nid = 0x224C5F44, version = 150)
public int sceNetResolverStartNtoA(@CheckArgument("checkRid") int rid, PspString hostname, @BufferInfo(usage=Usage.out) TPointer32 addr, int timeout, int retry) {
try {
InetAddress inetAddress = InetAddress.getByName(hostname.getString());
int resolvedAddress = sceNetInet.bytesToInternetAddress(inetAddress.getAddress());
addr.setValue(resolvedAddress);
if (log.isDebugEnabled()) {
log.debug(String.format("sceNetResolverStartNtoA returning address 0x%08X('%s')", resolvedAddress, sceNetInet.internetAddressToString(resolvedAddress)));
} else if (log.isInfoEnabled()) {
log.info(String.format("sceNetResolverStartNtoA resolved '%s' into '%s'", hostname.getString(), sceNetInet.internetAddressToString(resolvedAddress)));
}
} catch (UnknownHostException e) {
log.error(e);
return SceKernelErrors.ERROR_NET_RESOLVER_INVALID_HOST;
}
return 0;
}
/**
* Begin a address to name lookup
*
* @param rid -Resolver id
* @param addr - Pointer to the address to resolve
* @param hostname - Buffer to receive the name
* @param hostname_len - Length of the buffer
* @param timeout - Number of seconds before timeout
* @param retry - Number of retries
*
* @return 0 on success, < 0 on error
*/
@HLEFunction(nid = 0x629E2FB7, version = 150)
public int sceNetResolverStartAtoN(@CheckArgument("checkRid") int rid, int addr, TPointer hostnameAddr, int hostnameLength, int timeout, int retry) {
try {
byte[] bytes = sceNetInet.internetAddressToBytes(addr);
InetAddress inetAddress = InetAddress.getByAddress(bytes);
String hostName = inetAddress.getHostName();
hostnameAddr.setStringNZ(hostnameLength, hostName);
if (log.isDebugEnabled()) {
log.debug(String.format("sceNetResolverStartAtoN returning host name '%s'", hostName));
}
} catch (UnknownHostException e) {
log.error(e);
return SceKernelErrors.ERROR_NET_RESOLVER_INVALID_HOST;
}
return 0;
}
/**
* Stop a resolver operation
*
* @param rid - Resolver id
*
* @return 0 on success, < 0 on error
*/
@HLEFunction(nid = 0x808F6063, version = 150)
public int sceNetResolverStop(@CheckArgument("checkRid") int rid) {
ResolverID currentRID = RIDs.get(rid);
if (!currentRID.getIDStatus()) {
return SceKernelErrors.ERROR_NET_RESOLVER_ALREADY_STOPPED;
}
currentRID.stop();
return 0;
}
@HLEUnimplemented
@HLEFunction(nid = 0x14C17EF9, version = 150)
public int sceNetResolverStartNtoAAsync() {
return 0;
}
@HLEUnimplemented
@HLEFunction(nid = 0xAAC09184, version = 150)
public int sceNetResolverStartAtoNAsync() {
return 0;
}
@HLEUnimplemented
@HLEFunction(nid = 0x4EE99358, version = 150)
public int sceNetResolverPollAsync() {
return 0;
}
@HLEUnimplemented
@HLEFunction(nid = 0x12748EB9, version = 150)
public int sceNetResolverWaitAsync(Processor processor) {
return 0;
}
}