📄 smtp_client.c
字号:
/* On that function we can send data when called by main loop */
if( smtpc_init_done == 0 )
return;
if( smtp_client.state < SMTP_OPEN_REQUESTED)
return;
/* Is there timeout of some sort? */
if(check_timer(smtp_client.tmrhandle) == 0) {
/* Yep */
(void)tcp_abort(smtp_client.sochandle);
smtpc_changestate(SMTP_CLOSED);
/* Make user callback */
smtpc_error();
return;
}
if( smtp_client.state == SMTP_OPEN_REQUESTED) {
/* We are on this state because user has requested connection */
/* but connection is not yet opened. */
/* Try to get TCP stack to accept our connection request */
(void)tcp_abort(smtp_client.sochandle); /* Release old connection */
if(tcp_connect(smtp_client.sochandle, smtp_client.remip, smtp_client.remport, 0) >= 0)
smtpc_changestate(SMTP_CONNECTIONOPEN_SENT);
return;
}
if( tcp_getstate(smtp_client.sochandle) != TCP_STATE_CONNECTED ) {
return;
}
if( tcp_checksend(smtp_client.sochandle) < 0 )
return;
/* It's connected and no unacked data so try to send */
if(smtp_client.state == SMTP_SERVER_READY) {
/* Send HELO */
smtpc_sendhelo();
smtpc_changestate(SMTP_HELO_SENT);
DEBUGOUT("SMTP HELO packet sent\r\n");
return;
}
if(smtp_client.state == SMTP_HELO_ACKED) {
/* Send MAIL FROM */
smtpc_sendmailfrom();
smtpc_changestate(SMTP_MAILFROM_SENT);
DEBUGOUT("SMTP MAIL FROM packet sent\r\n");
return;
}
if(smtp_client.state == SMTP_MAILFROM_ACKED) {
/* Send RCPT TO */
smtpc_sendrcptto();
smtpc_changestate(SMTP_RCPTTO_SENT);
DEBUGOUT("SMTP RCPT TO packet sent\r\n");
return;
}
if(smtp_client.state == SMTP_RCPTTO_ACKED) {
/* Send DATA */
smtpc_senddatareq();
smtpc_changestate(SMTP_DATAREQ_SENT);
DEBUGOUT("SMTP DATA packet sent\r\n");
return;
}
if(smtp_client.state == SMTP_DATAREQ_ACKED) {
/* Send BODY */
smtpc_sendbody();
smtpc_changestate(SMTP_BODY_SENT);
DEBUGOUT("SMTP BODY packet sent\r\n");
return;
}
/* Body is part of plain text so we just make internal state change */
/* when TCP has acked the body packet. This pseudo-state just helps */
/* us to regenerate the body when needed */
if(smtp_client.state == SMTP_BODY_SENT)
smtpc_changestate(SMTP_SENDING_DATA);
if(smtp_client.state == SMTP_SENDING_DATA) {
/* Inform user app that old data is acked now */
smtpc_dataacked();
if (smtpc_senddata() < 0) {
/* End of data, send CRLF.CRLF */
DEBUGOUT("SMTP End of data reached\r\n");
smtpc_senddataend();
smtpc_changestate(SMTP_DATAEND_SENT);
}
return;
}
if(smtp_client.state == SMTP_DATAEND_ACKED) {
/* Send QUIT */
smtpc_sendquit();
smtpc_changestate(SMTP_QUIT_SENT);
DEBUGOUT("SMTP QUIT packet sent\r\n");
return;
}
if(smtp_client.state == SMTP_QUIT_ACKED) {
/* Inform application that data is sent OK */
smtpc_allok();
/* Try to close TCP */
if(tcp_close(smtp_client.sochandle) >= 0) {
smtpc_changestate(SMTP_CLOSED);
DEBUGOUT("SMTP connection closed OK\r\n");
return;
}
/* Close is not accepted by TCP. See if timeout */
if(check_timer(smtp_client.tmrhandle) == 0) {
/* Use brute force */
(void)tcp_abort(smtp_client.sochandle);
smtpc_changestate(SMTP_CLOSED);
DEBUGOUT("SMTP connection closed by ABORT\r\n");
return;
}
/* Keep trying untill timeout */
return;
}
return;
}
void smtpc_sendhelo (void)
{
INT8 i;
UINT8* buf;
/* Fill TCP Tx buffer with "HELO " and use callback function */
/* smtp_getdomain in order to get domain from systems and send */
/* that combined "HELO domainnname" to SMTP server */
buf = &net_buf[TCP_APP_OFFSET];
*buf++ = 'H';
*buf++ = 'E';
*buf++ = 'L';
*buf++ = 'O';
*buf++ = ' ';
i = smtpc_getdomain(buf);
if(i < 0)
return;
buf += i;
/* Insert CRLF */
*buf++ = '\r';
*buf = '\n';
(void)tcp_send(smtp_client.sochandle, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, i + 7);
}
void smtpc_sendmailfrom (void)
{
INT8 i;
UINT8* buf;
/* Fill TCP Tx buffer with "MAIL FROM: <" and use callback function */
/* smtp_getsender in order to get local e-mail address from user and send */
/* that combined "MAIL FROM: <myadr>" to SMTP server */
buf = &net_buf[TCP_APP_OFFSET];
*buf++ = 'M';
*buf++ = 'A';
*buf++ = 'I';
*buf++ = 'L';
*buf++ = ' ';
*buf++ = 'F';
*buf++ = 'R';
*buf++ = 'O';
*buf++ = 'M';
*buf++ = ':';
*buf++ = ' ';
*buf++ = '<';
i = smtpc_getsender(buf);
if(i < 0)
return;
buf += i;
/* Insert >CRLF */
*buf++ = '>';
*buf++ = '\r';
*buf = '\n';
(void)tcp_send(smtp_client.sochandle, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, i + 15);
}
void smtpc_sendrcptto (void)
{
INT8 i;
UINT8* buf;
/* Fill TCP Tx buffer with "RCPT TO: <" and use callback function */
/* smtp_getreceiver in order to get receiver address from user and send */
/* that combined "RCPT To: <rcvadr>" to SMTP server */
buf = &net_buf[TCP_APP_OFFSET];
*buf++ = 'R';
*buf++ = 'C';
*buf++ = 'P';
*buf++ = 'T';
*buf++ = ' ';
*buf++ = 'T';
*buf++ = 'O';
*buf++ = ':';
*buf++ = ' ';
*buf++ = '<';
i = smtpc_getreceiver(buf);
if(i < 0)
return;
buf += i;
/* Insert >CRLF */
*buf++ = '>';
*buf++ = '\r';
*buf = '\n';
(void)tcp_send(smtp_client.sochandle, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, i + 13);
}
void smtpc_senddatareq (void)
{
UINT8* buf;
/* Fill TCP Tx buffer with "DATA" and send to SMTP server */
buf = &net_buf[TCP_APP_OFFSET];
*buf++ = 'D';
*buf++ = 'A';
*buf++ = 'T';
*buf++ = 'A';
/* Insert CRLF */
*buf++ = '\r';
*buf = '\n';
(void)tcp_send(smtp_client.sochandle, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, 6);
}
void smtpc_sendbody (void)
{
UINT8* buf;
INT8 i;
UINT8 j;
/* Fill TCP Tx buffer with RFC 822 body and send to SMTP server */
j = 0;
buf = &net_buf[TCP_APP_OFFSET];
*buf++ = 'T';
*buf++ = 'o';
*buf++ = ':';
*buf++ = ' ';
i = smtpc_getreceiver(buf);
if(i < 0)
return;
buf += i;
j += i;
/* Insert CRLF */
*buf++ = '\r';
*buf++ = '\n';
*buf++ = 'S';
*buf++ = 'u';
*buf++ = 'b';
*buf++ = 'j';
*buf++ = 'e';
*buf++ = 'c';
*buf++ = 't';
*buf++ = ':';
*buf++ = ' ';
i = smtpc_getsubject(buf);
if(i < 0)
return;
buf += i;
j += i;
/* Insert CRLF */
*buf++ = '\r';
*buf++ = '\n';
*buf++ = 'F';
*buf++ = 'r';
*buf++ = 'o';
*buf++ = 'm';
*buf++ = ':';
*buf++ = ' ';
i = smtpc_getsender(buf);
if(i < 0)
return;
buf += i;
j += i;
/* Insert CRLF */
*buf++ = '\r';
*buf++ = '\n';
/* Insert emty row */
*buf++ = '\r';
*buf = '\n';
(void)tcp_send(smtp_client.sochandle, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, j + 27);
}
void smtpc_senddataend (void)
{
UINT8* buf;
/* Fill TCP Tx buffer with CRLF.CRLF and send to SMTP server */
buf = &net_buf[TCP_APP_OFFSET];
*buf++ = '\r';
*buf++ = '\n';
*buf++ = '.';
*buf++ = '\r';
*buf = '\n';
(void)tcp_send(smtp_client.sochandle, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, 5);
}
void smtpc_sendquit (void)
{
UINT8* buf;
/* Fill TCP Tx buffer with "QUIT" and send to SMTP server */
buf = &net_buf[TCP_APP_OFFSET];
*buf++ = 'Q';
*buf++ = 'U';
*buf++ = 'I';
*buf++ = 'T';
/* Insert CRLF */
*buf++ = '\r';
*buf = '\n';
(void)tcp_send(smtp_client.sochandle, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, 6);
}
INT16 smtpc_senddata (void)
{
INT16 len;
/* Use callback smtpc_getdata in order to fill Tx buffer with user data */
/* Normally user callback should return number of bytes assembled but */
/* when end of data is reached no bytes are written but (-1) returned */
len = smtpc_getdata(&net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET);
if(len < 0)
return(-1);
if(len > 0)
tcp_send(smtp_client.sochandle, &net_buf[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, (UINT16)len);
return(len);
}
void smtpc_changestate (UINT8 nstate)
{
init_timer(smtp_client.tmrhandle, SMTPC_TOUT*TIMERTIC);
smtp_client.state = nstate;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -