FreeCalypso > hg > themwi-system-sw
view utils/sip-rx-test.c @ 152:7176dc850d7a
sip-in hold/retr error handling: simply send BYE
Because we know that the SIP state is CONNECTED at the time of any
such error event, we can call initiate_bye() instead of disconnect_sip(),
and thereby get rid of struct gsm_mncc_cause which will never be used
in this scenario anyway.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2022 16:11:21 -0800 |
parents | 5995660dcbac |
children |
line wrap: on
line source
/* * This test program is the next level above sip-udp-dump: it binds * to UDP port 5060, waits for a packet to come in, and when a SIP * packet does arrive (call one of the numbers from BulkVS while this * test program is running, to make BulkVS send SIP INVITE), it does * two things with the captured packet: * * 1) The captured packet is written raw into one file named on the * command line; * * 2) The packet is parsed with parse_incoming_sip_msg(), and the * parsed structure is written out into the other file named on * the command line. * * This program is intended to serve as a unit test for the parsing * function. */ #include <sys/types.h> #include <sys/file.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> #include "../libsip/parse.h" static int sock; static struct sockaddr_in sin; static struct sip_pkt_rx pkt; static void save_raw_packet(filename) char *filename; { int fd; fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666); if (fd < 0) { perror(filename); exit(1); } write(fd, pkt.pkt_buffer, pkt.pkt_length); close(fd); } static void write_parse_output(filename) char *filename; { FILE *of; unsigned n; of = fopen(filename, "w"); if (!of) { perror(filename); exit(1); } switch (pkt.parse_msgtype) { case SIP_MSG_TYPE_REQ: fprintf(of, "Message is a request\n"); fprintf(of, "Method: %s\n", pkt.req_method); fprintf(of, "Request-URI: %s\n", pkt.req_uri); break; case SIP_MSG_TYPE_RESP: fprintf(of, "Message is a response\n"); fprintf(of, "Status code: %u\n", pkt.status_code); fprintf(of, "Status string: %s\n", pkt.status_str); break; default: fprintf(of, "Parsed returned unknown message type %d\n", pkt.parse_msgtype); } fprintf(of, "Number of header fields: %u\n", pkt.num_hdr_fields); for (n = 0; n < pkt.num_hdr_fields; n++) { fprintf(of, "Header field %u:\n", n); fprintf(of, " Field name: %s\n", pkt.hdr_fields[n].field_name); fprintf(of, " Field value: %s\n", pkt.hdr_fields[n].field_value); } fprintf(of, "Message body length: %u\n", pkt.msg_body_len); fclose(of); } main(argc, argv) char **argv; { int rc; socklen_t addrlen; if (argc != 3) { fprintf(stderr, "usage: %s raw-file parsed-file\n", argv[0]); exit(1); } sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { perror("socket"); exit(1); } sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(5060); rc = bind(sock, (struct sockaddr *) &sin, sizeof sin); if (rc < 0) { perror("bind"); exit(1); } addrlen = sizeof sin; rc = recvfrom(sock, pkt.pkt_buffer, MAX_SIP_RX_PACKET, 0, (struct sockaddr *) &sin, &addrlen); if (rc < 0) { perror("recvfrom"); exit(1); } pkt.pkt_length = rc; printf("Rx from %s:%u, %u bytes\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), pkt.pkt_length); save_raw_packet(argv[1]); rc = parse_incoming_sip_msg(&pkt); if (rc < 0) { printf("Parse error: %d\n", rc); exit(0); } write_parse_output(argv[2]); exit(0); }