LwFTP/LWFTP/lwftp_control.c

121 lines
3.2 KiB
C

/*
* lwftp_mod.h
*
* Created on: Feb 14, 2024
* Author: SeungJu Lim
*/
/** Process newly connected PCB
* @param pointer to lwftp session data
* @param pointer to PCB
* @param state of connection
*/
static err_t lwftp_control_connected(void *arg, struct tcp_pcb *tpcb, err_t err) {
lwftp_session_t *s = (lwftp_session_t*) arg;
if (err == ERR_OK) {
LWIP_DEBUGF(LWFTP_STATE, ("lwftp:connected to server\n"));
s->control_state = LWFTP_CONNECTED;
} else {
LWIP_DEBUGF(LWFTP_WARNING,
("lwftp:err in control_connected (%s)\n", lwip_strerr(err)));
}
return err;
}
/** Close control connection
* @param pointer to lwftp session data
* @param result to pass to callback fn (if called)
*/
static void lwftp_control_close(lwftp_session_t *s, int result) {
if (s->data_pcb) {
lwftp_pcb_close(s->data_pcb);
s->data_pcb = NULL;
}
if (s->control_pcb) {
lwftp_pcb_close(s->control_pcb);
s->control_pcb = NULL;
}
s->control_state = LWFTP_CLOSED;
if ((result >= 0) && s->done_fn) {
s->done_fn(s->handle, result);
}
}
/** Process newly connected PCB
* @param pointer to lwftp session data
* @param pointer to PCB
* @param state of connection
*/
static err_t lwftp_control_connected(void *arg, struct tcp_pcb *tpcb, err_t err) {
lwftp_session_t *s = (lwftp_session_t*) arg;
if (err == ERR_OK) {
LWIP_DEBUGF(LWFTP_STATE, ("lwftp: connected to server\n"));
s->control_state = LWFTP_CONNECTED;
} else {
LWIP_DEBUGF(LWFTP_WARNING,
("lwftp: err in control_connected (%s)\n", lwip_strerr(err)));
}
return err;
}
/** Handle control connection error
* @param pointer to lwftp session data
* @param state of connection
*/
static void lwftp_control_err(void *arg, err_t err) {
LWIP_UNUSED_ARG(err);
if (arg != NULL) {
lwftp_session_t *s = (lwftp_session_t*) arg;
int result;
if (s->control_state == LWFTP_CLOSED) {
LWIP_DEBUGF(LWFTP_WARNING,
("lwftp: failed to connect to server (%s)\n", lwip_strerr(err)));
result = LWFTP_RESULT_ERR_CONNECT;
} else {
LWIP_DEBUGF(LWFTP_WARNING, ("lwftp: connection closed by remote host\n"));
result = LWFTP_RESULT_ERR_CLOSED;
}
s->control_pcb = NULL; // No need to de-allocate PCB
lwftp_control_close(s, result);
}
}
/** Handle control connection incoming data
* @param pointer to lwftp session data
* @param pointer to PCB
* @param pointer to incoming pbuf
* @param state of incoming process
*/
static err_t lwftp_control_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
err_t err) {
lwftp_session_t *s = (lwftp_session_t*) arg;
if (err == ERR_OK) {
if (p) {
tcp_recved(tpcb, p->tot_len);
lwftp_control_process(s, tpcb, p);
} else {
LWIP_DEBUGF(LWFTP_WARNING, ("lwftp: connection closed by remote host\n"));
lwftp_control_close(s, LWFTP_RESULT_ERR_CLOSED);
}
} else {
LWIP_DEBUGF(LWFTP_SERIOUS,
("lwftp: failed to receive (%s)\n", lwip_strerr(err)));
lwftp_control_close(s, LWFTP_RESULT_ERR_UNKNOWN);
}
return err;
}
/** Handle control connection acknowledge of sent data
* @param pointer to lwftp session data
* @param pointer to PCB
* @param number of bytes sent
*/
static err_t lwftp_control_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) {
LWIP_DEBUGF(LWFTP_TRACE, ("lwftp: successfully sent %d bytes\n", len));
return ERR_OK;
}