1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef COMMUNICATIONNETSTACK_HTTP_HANDOVER_HANDLER_H 17 #define COMMUNICATIONNETSTACK_HTTP_HANDOVER_HANDLER_H 18 19 #include <map> 20 #include <memory> 21 #include <set> 22 #include <queue> 23 24 #include "curl/curl.h" 25 26 #include "epoller.h" 27 #include "thread_safe_storage.h" 28 #include "timeout_timer.h" 29 #include "manual_reset_event.h" 30 #include "epoll_request_handler.h" 31 #include "request_info.h" 32 #include "request_context.h" 33 34 namespace OHOS::NetStack::HttpOverCurl { 35 struct RequestInfo; 36 typedef void *(*HTTP_HAND_OVER_INIT)(void *user, void (*HMS_NetworkBoost_HandoverEventCallback)(void *), 37 void (*HMS_NetworkBoost_HandoverTimerCallback)(void *, long), const char* stackName); 38 typedef int32_t (*HTTP_HAND_OVER_UNINIT)(void *handle); 39 typedef void (*HTTP_HAND_OVER_QUERY)(void *handle, int32_t *status, int32_t *netId); 40 typedef void (*HTTP_HAND_OVER_ADD)(void *handle, void *userp, int32_t type, int32_t readFlag); 41 typedef void (*HTTP_HAND_OVER_DEL)(void *handle, void *userp, bool isSuccess); 42 typedef int32_t (*HTTP_HAND_OVER_QUERY_REQUEST)(void *handle, void *userp, int32_t *handOverReason, 43 double *flowControlTime, int32_t *readFlag); 44 typedef void (*HTTP_HAND_OVER_REPORT_TIMEOUT)(void *handle); 45 46 void HandoverCallback(void *user); 47 void HandoverTimerCallback(void *user, long timeoutMs); 48 bool CheckSocketTime(void *user, curl_socket_t fd); 49 curl_socket_t OpenSocket(void *user, curlsocktype purpose, struct curl_sockaddr *addr); 50 int CloseSocketCallback(void *user, curl_socket_t fd); 51 52 class HttpHandoverHandler { 53 public: 54 enum { INIT, START, CONTINUE, END, FATAL, TIMEOUT }; 55 explicit HttpHandoverHandler(); 56 ~HttpHandoverHandler(); 57 58 bool IsInitSuccess(); 59 bool TryFlowControl(RequestInfo* requestInfo, int32_t requestType); 60 void HandoverRequestCallback(std::map<CURL *, RequestInfo *> &ongoingRequests, CURLM *multi); 61 void HandoverTimeoutCallback(); 62 void RegisterForPolling(Epoller &poller) const; 63 bool IsItHandoverEvent(FileDescriptor descriptor) const; 64 bool IsItHandoverTimeoutEvent(FileDescriptor descriptor) const; 65 void SetHandoverEvent(); 66 void SetHandoverTimeoutEvent(long timeoutMs); 67 bool ProcessRequestErr(std::map<CURL *, RequestInfo *> &ongoingRequests, CURLM *multi, 68 RequestInfo *requestInfo, CURLMsg *msg); 69 bool Initialize(); 70 void SetCallback(RequestInfo *request); 71 void SetHandoverInfo(RequestInfo *requestInfo); 72 void HandoverQuery(); 73 bool CheckSocketOpentimeLessThanEndTime(curl_socket_t fd); 74 void SetSocketOpenTime(curl_socket_t fd); 75 void EraseFd(curl_socket_t fd); 76 bool RetransRequest(std::map<CURL *, RequestInfo *> &ongoingRequests, CURLM *multi, RequestInfo *request); 77 bool CheckRequestCanRetrans(RequestInfo *request, int32_t requestType, CURLcode result); 78 void UndoneRequestHandle(std::map<CURL *, RequestInfo *> &ongoingRequests, CURLM *multi); 79 int32_t IsRequestRead(CURL *easyHandle); 80 int32_t IsRequestRead(CURL *easyHandle, time_t &recvtime, time_t &sendtime); 81 bool IsNetworkErrorTypeCorrect(CURLcode result); 82 bool ProcessRequestNetError(std::map<CURL *, RequestInfo *> &ongoingRequests, CURLM *multi, 83 RequestInfo *requestInfo, CURLMsg *msg); 84 void AddRequest(RequestInfo *requestInfo, int32_t type); 85 void DelRequest(RequestInfo *requestInfo); 86 int32_t QueryRequest(void *userp, int32_t &handOverReason, double &flowControlTime, int32_t &readFlag); 87 int32_t GetStatus(); 88 void SetStatus(int32_t status); 89 int32_t GetNetId(); 90 void SetNetId(int32_t netId); 91 private: 92 void *netHandoverHandler_ = nullptr; 93 void *httpHandoverManager_ = nullptr; 94 std::unique_ptr<ManualResetEvent> handOverEvent_; 95 std::unique_ptr<HttpOverCurl::TimeoutTimer> handOverTimerEvent_; 96 97 HTTP_HAND_OVER_INIT httpHandoverInit_ = nullptr; 98 HTTP_HAND_OVER_UNINIT httpHandoverUninit_ = nullptr; 99 HTTP_HAND_OVER_QUERY httpHandoverQuery_ = nullptr; 100 HTTP_HAND_OVER_ADD httpHandoverAddRequest_ = nullptr; 101 HTTP_HAND_OVER_DEL httpHandoverDelRequest_ = nullptr; 102 HTTP_HAND_OVER_QUERY_REQUEST httpHandoverQueryRequest_ = nullptr; 103 HTTP_HAND_OVER_REPORT_TIMEOUT httpHandoverReportTimeout_ = nullptr; 104 std::set<RequestInfo *> handoverQueue_; 105 std::map<curl_socket_t, int> socketopentime_; 106 std::map<RequestInfo *, int> requestEndtime_; 107 bool initsuccess_; 108 int endTime_ = 0; 109 int timeoutTime_ = 0; 110 int retrans_ = 0; 111 int32_t status_ = HttpHandoverHandler::INIT; 112 int32_t netId_ = 0; 113 }; 114 115 } // namespace OHOS::NetStack::HttpOverCurl 116 117 #endif // COMMUNICATIONNETSTACK_HTTP_HANOVER_HANDLER_H