| 2168 | } |
| 2169 | |
| 2170 | static struct command_result *json_disconnect(struct command *cmd, |
| 2171 | const char *buffer, |
| 2172 | const jsmntok_t *obj UNNEEDED, |
| 2173 | const jsmntok_t *params) |
| 2174 | { |
| 2175 | struct node_id *id; |
| 2176 | struct disconnect_command *dc; |
| 2177 | struct peer *peer; |
| 2178 | struct channel *channel; |
| 2179 | bool *force; |
| 2180 | |
| 2181 | if (!param(cmd, buffer, params, |
| 2182 | p_req("id", param_node_id, &id), |
| 2183 | p_opt_def("force", param_bool, &force, false), |
| 2184 | NULL)) |
| 2185 | return command_param_failed(); |
| 2186 | |
| 2187 | peer = peer_by_id(cmd->ld, id); |
| 2188 | if (!peer) { |
| 2189 | return command_fail(cmd, LIGHTNINGD, "Unknown peer"); |
| 2190 | } |
| 2191 | if (peer->connected == PEER_DISCONNECTED) { |
| 2192 | return command_fail(cmd, LIGHTNINGD, "Peer not connected"); |
| 2193 | } |
| 2194 | |
| 2195 | channel = peer_any_active_channel(peer, NULL); |
| 2196 | if (channel && !*force) { |
| 2197 | return command_fail(cmd, LIGHTNINGD, |
| 2198 | "Peer has (at least one) channel in state %s", |
| 2199 | channel_state_name(channel)); |
| 2200 | } |
| 2201 | |
| 2202 | /* If it's not already disconnecting, tell connectd to disconnect */ |
| 2203 | if (peer->connected == PEER_CONNECTED) |
| 2204 | subd_send_msg(peer->ld->connectd, |
| 2205 | take(towire_connectd_discard_peer(NULL, &peer->id, |
| 2206 | peer->connectd_counter))); |
| 2207 | |
| 2208 | /* Connectd tells us when it's finally disconnected */ |
| 2209 | dc = tal(cmd, struct disconnect_command); |
| 2210 | dc->cmd = cmd; |
| 2211 | dc->id = *id; |
| 2212 | list_add_tail(&cmd->ld->disconnect_commands, &dc->list); |
| 2213 | tal_add_destructor(dc, destroy_disconnect_command); |
| 2214 | |
| 2215 | return command_still_pending(cmd); |
| 2216 | } |
| 2217 | |
| 2218 | static const struct json_command disconnect_command = { |
| 2219 | "disconnect", |
nothing calls this directly
no test coverage detected