1 /*
2  * Copyright (c) 2023 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 #include "tcp_server_extra_context.h"
17 
18 #include "context_key.h"
19 #include "event_manager.h"
20 #include "napi_utils.h"
21 #include "netstack_log.h"
22 #include "socket_constant.h"
23 
24 namespace OHOS::NetStack::Socket {
TcpServerSetExtraOptionsContext(napi_env env,EventManager * manager)25 TcpServerSetExtraOptionsContext::TcpServerSetExtraOptionsContext(napi_env env, EventManager *manager)
26     : BaseContext(env, manager)
27 {
28 }
29 
ParseContextKey(napi_value * params)30 void TcpServerSetExtraOptionsContext::ParseContextKey(napi_value *params)
31 {
32     if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_RECEIVE_BUFFER_SIZE)) {
33         options_.SetReceiveBufferSize(NapiUtils::GetUint32Property(GetEnv(), params[0], KEY_RECEIVE_BUFFER_SIZE));
34     }
35 
36     if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_SEND_BUFFER_SIZE)) {
37         options_.SetSendBufferSize(NapiUtils::GetUint32Property(GetEnv(), params[0], KEY_SEND_BUFFER_SIZE));
38     }
39 
40     if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_REUSE_ADDRESS)) {
41         options_.SetReuseAddress(NapiUtils::GetBooleanProperty(GetEnv(), params[0], KEY_REUSE_ADDRESS));
42     }
43 
44     if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_SOCKET_TIMEOUT)) {
45         options_.SetSocketTimeout(NapiUtils::GetUint32Property(GetEnv(), params[0], KEY_SOCKET_TIMEOUT));
46     }
47 
48     if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_KEEP_ALIVE)) {
49         options_.SetKeepAlive(NapiUtils::GetBooleanProperty(GetEnv(), params[0], KEY_KEEP_ALIVE));
50     }
51 
52     if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_OOB_INLINE)) {
53         options_.SetOOBInline(NapiUtils::GetBooleanProperty(GetEnv(), params[0], KEY_OOB_INLINE));
54     }
55 
56     if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_TCP_NO_DELAY)) {
57         options_.SetTCPNoDelay(NapiUtils::GetBooleanProperty(GetEnv(), params[0], KEY_TCP_NO_DELAY));
58     }
59 
60     if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_SOCKET_LINGER)) {
61         napi_value socketLinger = NapiUtils::GetNamedProperty(GetEnv(), params[0], KEY_SOCKET_LINGER);
62         if (NapiUtils::GetValueType(GetEnv(), params[0]) == napi_object) {
63             if (NapiUtils::HasNamedProperty(GetEnv(), socketLinger, KEY_SOCKET_LINGER_ON)) {
64                 options_.socketLinger.SetOn(
65                     NapiUtils::GetBooleanProperty(GetEnv(), socketLinger, KEY_SOCKET_LINGER_ON));
66             }
67             if (NapiUtils::HasNamedProperty(GetEnv(), socketLinger, KEY_SOCKET_LINGER_LINGER)) {
68                 options_.socketLinger.SetLinger(
69                     NapiUtils::GetUint32Property(GetEnv(), socketLinger, KEY_SOCKET_LINGER_LINGER));
70             }
71         }
72     }
73 }
74 
ParseParams(napi_value * params,size_t paramsCount)75 void TcpServerSetExtraOptionsContext::ParseParams(napi_value *params, size_t paramsCount)
76 {
77     bool valid = CheckParamsType(params, paramsCount);
78     if (!valid) {
79         if (paramsCount == PARAM_JUST_CALLBACK) {
80             if (NapiUtils::GetValueType(GetEnv(), params[0]) == napi_function) {
81                 SetCallback(params[0]);
82             }
83             return;
84         }
85         if (paramsCount == PARAM_OPTIONS_AND_CALLBACK) {
86             if (NapiUtils::GetValueType(GetEnv(), params[1]) == napi_function) {
87                 SetCallback(params[1]);
88             }
89             return;
90         }
91         return;
92     }
93 
94     ParseContextKey(params);
95 
96     if (paramsCount == PARAM_OPTIONS_AND_CALLBACK) {
97         SetParseOK(SetCallback(params[1]) == napi_ok);
98         return;
99     }
100     SetParseOK(true);
101 }
102 
GetSocketFd() const103 int TcpServerSetExtraOptionsContext::GetSocketFd() const
104 {
105     return manager_->GetData() ? static_cast<int>(reinterpret_cast<uint64_t>(manager_->GetData())) : -1;
106 }
107 
CheckParamsType(napi_value * params,size_t paramsCount)108 bool TcpServerSetExtraOptionsContext::CheckParamsType(napi_value *params, size_t paramsCount)
109 {
110     if (paramsCount == PARAM_JUST_OPTIONS) {
111         if (NapiUtils::GetValueType(GetEnv(), params[0]) != napi_object) {
112             NETSTACK_LOGE("invalid parameter");
113             SetNeedThrowException(true);
114             SetError(PARSE_ERROR_CODE, PARSE_ERROR_MSG);
115             return false;
116         }
117         return true;
118     }
119 
120     if (paramsCount == PARAM_OPTIONS_AND_CALLBACK) {
121         if (NapiUtils::GetValueType(GetEnv(), params[0]) != napi_object ||
122             NapiUtils::GetValueType(GetEnv(), params[1]) != napi_function) {
123             NETSTACK_LOGE("invalid parameter");
124             SetNeedThrowException(true);
125             SetError(PARSE_ERROR_CODE, PARSE_ERROR_MSG);
126             return false;
127         }
128         return true;
129     }
130     return false;
131 }
132 
GetErrorCode() const133 int32_t TcpServerSetExtraOptionsContext::GetErrorCode() const
134 {
135     if (BaseContext::IsPermissionDenied()) {
136         return PERMISSION_DENIED_CODE;
137     }
138 
139     auto err = BaseContext::GetErrorCode();
140     if (err == PARSE_ERROR_CODE) {
141         return PARSE_ERROR_CODE;
142     }
143     return err + SOCKET_SERVER_ERROR_CODE_BASE;
144 }
145 
GetErrorMessage() const146 std::string TcpServerSetExtraOptionsContext::GetErrorMessage() const
147 {
148     if (BaseContext::IsPermissionDenied()) {
149         return PERMISSION_DENIED_MSG;
150     }
151 
152     auto errCode = BaseContext::GetErrorCode();
153     if (errCode == PARSE_ERROR_CODE) {
154         return PARSE_ERROR_MSG;
155     }
156     char err[MAX_ERR_NUM] = {0};
157     (void)strerror_r(errCode, err, MAX_ERR_NUM);
158     return err;
159 }
160 } // namespace OHOS::NetStack::Socket
161