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;
+}