FreeCalypso > hg > themwi-system-sw
diff smpp-trx-sa/tcpconn.c @ 222:9d6e8d99d2b1
smpp-trx-sa: new program
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 03 Aug 2023 21:13:41 -0800 |
parents | |
children | 1bf989f60aa3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smpp-trx-sa/tcpconn.c Thu Aug 03 21:13:41 2023 -0800 @@ -0,0 +1,106 @@ +/* + * This module implements the part of smpp-trx-sa that handles + * the TCP connection to the SMPP server. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> + +extern FILE *logF; + +int tcpsock; + +static u_char rx_buf[0x10000]; +static unsigned rx_accum, rx_pdu_len; +static int rx_body; + +void +open_tcp_conn(server_sin) + struct sockaddr_in *server_sin; +{ + int rc; + + tcpsock = socket(AF_INET, SOCK_STREAM, 0); + if (tcpsock < 0) { + perror("socket(AF_INET, SOCK_STREAM, 0)"); + exit(1); + } + rc = connect(tcpsock, (struct sockaddr *) server_sin, + sizeof(struct sockaddr_in)); + if (rc < 0) { + perror("TCP connect"); + exit(1); + } +} + +static void +got_full_pdu() +{ + unsigned command_id; + + /* prepare for next PDU Rx */ + rx_body = 0; + rx_accum = 0; + /* back to the one we just got */ + command_id = (rx_buf[4] << 24) | (rx_buf[5] << 16) | (rx_buf[6] << 8) | + rx_buf[7]; + if (command_id == 0x15 && rx_pdu_len == 16) { + send_enq_link_resp(rx_buf); + return; + } + log_rx_pdu(rx_buf, rx_pdu_len); + if (command_id == 0x05 || command_id == 0x103) + send_message_resp(rx_buf); +} + +void +tcpsock_select_handler() +{ + unsigned goal; + int cc; + + if (rx_body) + goal = rx_pdu_len; + else + goal = 16; + cc = read(tcpsock, rx_buf + rx_accum, goal - rx_accum); + if (cc < 0) { + perror("read from TCP socket"); + log_fatal_error("error reading from TCP socket"); + exit(1); + } + if (cc == 0) { + log_fatal_error("Server closed TCP connection"); + exit(1); + } + rx_accum += cc; + if (rx_accum < goal) + return; + if (rx_body) { + got_full_pdu(); + return; + } + if (rx_buf[0] || rx_buf[1]) { + log_rx_pdu(rx_buf, 16); + fprintf(logF, "Fatal error: length exceeds limit\n"); + exit(1); + } + rx_pdu_len = (rx_buf[2] << 8) | rx_buf[3]; + if (rx_pdu_len < 16) { + log_rx_pdu(rx_buf, 16); + fprintf(logF, "Fatal error: length below 16\n"); + exit(1); + } + if (rx_pdu_len == 16) { + got_full_pdu(); + return; + } + rx_body = 1; +}