diff --git a/libctru/include/3ds/services/httpc.h b/libctru/include/3ds/services/httpc.h index 1f95dcf..6123b34 100644 --- a/libctru/include/3ds/services/httpc.h +++ b/libctru/include/3ds/services/httpc.h @@ -34,9 +34,12 @@ typedef enum { /// Result code returned when a download is pending. #define HTTPC_RESULTCODE_DOWNLOADPENDING 0xd840a02b -// Result code returned when asked about a non-existing header +// Result code returned when asked about a non-existing header. #define HTTPC_RESULTCODE_NOTFOUND 0xd840a028 +// Result code returned when any timeout function times out. +#define HTTPC_RESULTCODE_TIMEDOUT 0xd820a069 + /// Initializes HTTPC. For HTTP GET the sharedmem_size can be zero. The sharedmem contains data which will be later uploaded for HTTP POST. sharedmem_size should be aligned to 0x1000-bytes. Result httpcInit(u32 sharedmem_size); @@ -57,6 +60,12 @@ Result httpcOpenContext(httpcContext *context, HTTPC_RequestMethod method, const */ Result httpcCloseContext(httpcContext *context); +/** + * @brief Cancels a HTTP connection. + * @param context Context to close. + */ +Result httpcCancelConnection(httpcContext *context); + /** * @brief Adds a request header field to a HTTP context. * @param context Context to use. @@ -95,6 +104,15 @@ Result httpcBeginRequest(httpcContext *context); */ Result httpcReceiveData(httpcContext *context, u8* buffer, u32 size); +/** + * @brief Receives data from a HTTP context with a timeout value. + * @param context Context to use. + * @param buffer Buffer to receive data to. + * @param size Size of the buffer. + * @param timeout Maximum time in nanoseconds to wait for a reply. + */ +Result httpcReceiveDataTimeout(httpcContext *context, u8* buffer, u32 size, u64 timeout); + /** * @brief Gets the request state of a HTTP context. * @param context Context to use. @@ -114,9 +132,16 @@ Result httpcGetDownloadSizeState(httpcContext *context, u32* downloadedsize, u32 * @brief Gets the response code of the HTTP context. * @param context Context to get the response code of. * @param out Pointer to write the response code to. - * @param delay Delay to wait for the status code. Not used yet. */ -Result httpcGetResponseStatusCode(httpcContext *context, u32* out, u64 delay); +Result httpcGetResponseStatusCode(httpcContext *context, u32* out); + +/** + * @brief Gets the response code of the HTTP context with a timeout value. + * @param context Context to get the response code of. + * @param out Pointer to write the response code to. + * @param timeout Maximum time in nanoseconds to wait for a reply. + */ +Result httpcGetResponseStatusCodeTimeout(httpcContext *context, u32* out, u64 timeout); /** * @brief Gets a response header field from a HTTP context. diff --git a/libctru/source/services/httpc.c b/libctru/source/services/httpc.c index c4bc3d9..aa954c3 100644 --- a/libctru/source/services/httpc.c +++ b/libctru/source/services/httpc.c @@ -129,6 +129,19 @@ Result httpcCloseContext(httpcContext *context) return ret; } +Result httpcCancelConnection(httpcContext *context) +{ + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=IPC_MakeHeader(0x4,1,0); // 0x40040 + cmdbuf[1]=context->httphandle; + + Result ret=0; + if(R_FAILED(ret=svcSendSyncRequest(__httpc_servhandle)))return ret; + + return cmdbuf[1]; +} + Result httpcDownloadData(httpcContext *context, u8* buffer, u32 size, u32 *downloadedsize) { Result ret=0; @@ -337,6 +350,24 @@ Result httpcReceiveData(httpcContext *context, u8* buffer, u32 size) return cmdbuf[1]; } +Result httpcReceiveDataTimeout(httpcContext *context, u8* buffer, u32 size, u64 timeout) +{ + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=IPC_MakeHeader(0xC,4,2); // 0xC0102 + cmdbuf[1]=context->httphandle; + cmdbuf[2]=size; + cmdbuf[3]=timeout & 0xffffffff; + cmdbuf[4]=(timeout >> 32) & 0xffffffff; + cmdbuf[5]=IPC_Desc_Buffer(size,IPC_BUFFER_W); + cmdbuf[6]=(u32)buffer; + + Result ret=0; + if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret; + + return cmdbuf[1]; +} + Result httpcGetRequestState(httpcContext *context, HTTPC_RequestStatus* out) { u32* cmdbuf=getThreadCommandBuffer(); @@ -388,7 +419,7 @@ Result httpcGetResponseHeader(httpcContext *context, const char* name, char* val return cmdbuf[1]; } -Result httpcGetResponseStatusCode(httpcContext *context, u32* out, u64 delay) +Result httpcGetResponseStatusCode(httpcContext *context, u32* out) { u32* cmdbuf=getThreadCommandBuffer(); @@ -403,6 +434,24 @@ Result httpcGetResponseStatusCode(httpcContext *context, u32* out, u64 delay) return cmdbuf[1]; } + +Result httpcGetResponseStatusCodeTimeout(httpcContext *context, u32* out, u64 timeout) +{ + u32* cmdbuf=getThreadCommandBuffer(); + + cmdbuf[0]=IPC_MakeHeader(0x23,3,0); // 0x2300C0 + cmdbuf[1]=context->httphandle; + cmdbuf[2]=timeout & 0xffffffff; + cmdbuf[3]=(timeout >> 32) & 0xffffffff; + + Result ret=0; + if(R_FAILED(ret=svcSendSyncRequest(context->servhandle)))return ret; + + *out = cmdbuf[2]; + + return cmdbuf[1]; +} + Result httpcAddTrustedRootCA(httpcContext *context, const u8 *cert, u32 certsize) { u32* cmdbuf=getThreadCommandBuffer();