⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_cimd2.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 2 页
字号:
			printf("    Cancel enabled\n");		else if (cancel > INT_MAX)			printf("    Cancel enabled: %ld\n", cancel);		if (tariff_class > INT_MAX)			printf("    Tariff class: %ld\n", tariff_class);		if (service_desc > INT_MAX)			printf("    Service description: %ld\n", service_desc);		if (priority > INT_MAX)			printf("    Priority: %ld\n", priority);	}	if (!dest_addr) {		send_error(out, 53, sequence, "300", "no destination");	} else if (list_len(other_dests) > 0) {		send_error(out, 53, sequence, "301", "too many destinations");	/* TODO: Report many other possible errors here */	} else {		unsigned char buf[TIMESTAMP_MAXLEN];		make_timestamp(buf, time(NULL));		if (logging == LOG_packets)			printf("SND: Submit OK\n");		send_packet(out, 53, sequence,		            21, octstr_get_cstr(dest_addr),			    60, buf,			    0);	}	octstr_destroy(dest_addr);	octstr_destroy(orig_addr);	octstr_destroy(UDH);	octstr_destroy(text);	octstr_destroy(textb);	octstr_destroy(valid_abs);	octstr_destroy(delivery_abs);	list_destroy(other_dests, octstr_destroy_item);}static void handle_enquire(Octstr *packet, Octstr *out, int sequence) {	Octstr *dest_addr = eat_string_parm(packet, 21, 20);	Octstr *timestamp = eat_string_parm(packet, 60, 12);	if (logging == LOG_packets)		printf("RCV: Enquire status, dest='%s', time='%s'\n",			dest_addr ? octstr_get_cstr(dest_addr) : "",			timestamp ? octstr_get_cstr(timestamp) : "");	if (!dest_addr) {		send_error(out, 54, sequence, "400", "no destination");	} else if (!timestamp) {		send_error(out, 54, sequence, "401", "no timestamp");	} else {		if (logging == LOG_packets)			printf("SND: Respond: status unknown\n");		send_packet(out, 54, sequence,			    21, octstr_get_cstr(dest_addr),			    60, octstr_get_cstr(timestamp),			    61, "0",			    0);	}	octstr_destroy(dest_addr);	octstr_destroy(timestamp);}static void handle_delivery_request(Octstr *packet, Octstr *out, int sequence) {	long mode = eat_int_parm(packet, 68, 1);	if (logging == LOG_packets) {		switch (mode) {		case 0: printf("RCV: Delivery request, messages waiting?\n");			break;		case 1: printf("RCV: Delivery request, one message\n");			break;		case 2: printf("RCV: Delivery request, all messages\n");			break;		case INT_MIN:			printf("RCV: Delivery request, no mode\n");			break;		default:			printf("RCV: Delivery request, mode %ld\n", mode);		}	}	if (mode == INT_MIN)		mode = 1;	switch (mode) {	case 0:		if (logging == LOG_packets)			printf("SND: Respond: 0 messages\n");		send_packet(out, 55, sequence,			    66, "0",			    0);		break;	case 1:		send_error(out, 55, sequence, "500", "no messages available");		break;	case 2:		send_error(out, 55, sequence, "500", "no messages available");		break;	default:		send_error(out, 55, sequence, "501", "bad mode");		break;	}}static void handle_cancel(Octstr *packet, Octstr *out, int sequence) {	long mode = eat_int_parm(packet, 59, 1);	Octstr *timestamp = eat_string_parm(packet, 60, 12);	Octstr *destination = eat_string_parm(packet, 21, 20);	if (logging == LOG_packets) {		printf("RCV: Cancel");		if (mode != INT_MIN)			printf(", mode %ld", mode);		if (destination)			printf(", dest '%s'", octstr_get_cstr(destination));		if (timestamp)			printf(", time '%s'", octstr_get_cstr(timestamp));		printf("\n");	}	if (mode < 0 || mode > 2)		send_error(out, 56, sequence, "602", "bad mode");	else {		if (logging == LOG_packets)			printf("SND: OK\n");		send_packet(out, 56, sequence, 0);	}}static void handle_set(Octstr *packet, Octstr *out, int sequence) {	Octstr *pass = eat_string_parm(packet, 11, 32);	if (pass) {		if (logging == LOG_packets)			printf("RCV: Set password to '%s'\n",				octstr_get_cstr(pass));		send_error(out, 58, sequence,			"801", "changing password not allowed");	} else {		if (logging == LOG_packets)			printf("RCV: Set, unknown parameters\n");		send_error(out, 58, sequence, "3", "cannot set");	}}static void handle_get(Octstr *packet, Octstr *out, int sequence) {	long number = eat_int_parm(packet, 500, 3);	if (logging == LOG_packets)		printf("RCV: Get parameter #%ld\n", number);	if (number == INT_MIN) {		send_error(out, 59, sequence, "900", "missing parameter");	} else if (number == 501) {		unsigned char buf[TIMESTAMP_MAXLEN];		make_timestamp(buf, time(NULL));		if (logging == LOG_packets)			printf("SND: OK, SMSC timestamp is '%s'\n", buf);		send_packet(out, 59, sequence,			    501, buf,			    0);	} else {		send_error(out, 59, sequence, "900", "unknown parameter");	}}static void handle_alive(Octstr *packet, Octstr *out, int sequence) {	if (logging == LOG_packets)		printf("RCV: Alive?\n");	if (logging == LOG_packets)		printf("SND: Alive.\n");	send_packet(out, 90, sequence, 0);}static void handle_deliver_response(Octstr *packet, Octstr *out, int sequence) {	awaiting_response = 0;	if (logging == LOG_packets)		printf("RCV: Deliver response\n");	deliveries++;	if (max_deliveries > 0 && deliveries == max_deliveries) {		time_t elapsed = time(NULL) - start_time;		printf("LOG: %ld deliveries in %ld seconds\n",			(long) max_deliveries, (long) elapsed);	}	/* No need to respond to a response */}static void handle_deliver_status_report_response(Octstr *packet, Octstr *out, int sequence) {	awaiting_response = 0;	if (logging == LOG_packets)		printf("RCV: Deliver status report response\n");	/* No need to respond to a response */}static void handle_alive_response(Octstr *packet, Octstr *out, int sequence) {	awaiting_response = 0;	if (logging == LOG_packets)		printf("RCV: Alive.\n");	/* No need to respond to a response */}static void handle_nack(Octstr *packet, Octstr *out, int sequence) {	awaiting_response = 0;	if (logging == LOG_packets)		printf("RCV: NACK\n");	/* TODO: We should retransmit if we get a nack, but there's	 * no record of what request we sent. */}typedef void (*packet_handler)(Octstr *, Octstr *, int);struct {	int opcode;	packet_handler handler;} handlers[] = {	{ 1, handle_login },	{ 2, handle_logout },	{ 3, handle_submit },	{ 4, handle_enquire },	{ 5, handle_delivery_request },	{ 6, handle_cancel },	{ 8, handle_set },	{ 9, handle_get },	{ 40, handle_alive },	{ 70, handle_deliver_response },	{ 73, handle_deliver_status_report_response },	{ 90, handle_alive_response },	{ 99, handle_nack },	{ -1, NULL },};static void parse_packet(Octstr *packet, Octstr *out) {	int opcode, sequence;	int i;	eat_checksum(packet);	opcode = eat_number(packet);	if (opcode < 0 || eat_char(packet, ':') < 0)		return;	sequence = eat_number(packet);	if (sequence < 0)		return;	for (i = 0; handlers[i].opcode >= 0; i++) {		if (handlers[i].opcode == opcode) {			(handlers[i].handler)(packet, out, sequence);			break;		}	}	if (handlers[i].opcode < 0) { /* Loop failed */		if (logging == LOG_packets)			printf("RCV: unknown operation %ld\n",				(long) handlers[i].opcode);		send_error(out, 98, sequence, "1", "unexpected operation");	}}/* Parse the data stream for packets, and send out replies. */static void parse_data(Octstr *in, Octstr *out) {	int stx, etx;	Octstr *packet;	for (;;) {		/* Look for start of packet.  Delete everything up to the start		 * marker.  (CIMD2 section 3.1 says we can ignore any data		 * transmitted between packets.) */		stx = octstr_search_char(in, STX, 0);		if (stx < 0)			octstr_delete(in, 0, octstr_len(in));		else if (stx > 0)			octstr_delete(in, 0, stx);		etx = octstr_search_char(in, ETX, 0);		if (etx < 0)			return;  /* Incomplete packet; wait for more data. */		/* Copy the data between stx and etx */		packet = octstr_copy(in, 1, etx - 1);		/* Then cut the packet (including stx and etx) from inbuffer */		octstr_delete(in, 0, etx + 1);		parse_packet(packet, out);		octstr_destroy(packet);	}}static void random_address(unsigned char *buf, int size) {	int len = random() % size;	while (len--) {		*buf++ = '0' + random() % 10;	}	*buf++ = '\0';}static void random_message(unsigned char *buf, int size) {	int len = random() % size;	while (len--) {		do {			*buf = random() % 256;		} while (*buf == STX || *buf == ETX || *buf == TAB);		buf++;	}	*buf++ = '\0';}static void random_hex(unsigned char *buf, int size) {	int len = random() % size;	/* Make even */	len -= (len % 2);	while (len--) {		int c = random() % 16;		if (c < 10)			*buf++ = c + '0';		else			*buf++ = c - 10 + 'a';	}	*buf++ = '\0';}static void gen_message(Octstr *out) {	static int send_seq = 0;	unsigned char dest[21];	unsigned char orig[21];	unsigned char scts[TIMESTAMP_MAXLEN];	unsigned char message[481];	unsigned char udh[281];	if (awaiting_response == 1)		return;	random_address(dest, sizeof(dest));	random_address(orig, sizeof(orig));	make_timestamp(scts, time(NULL));	random_message(message, sizeof(message));	if (random() % 2 == 0)		random_hex(udh, sizeof(udh));	else		*udh = 0;	if (logging == LOG_packets)		printf("SND: Deliver message (random)\n");	if (*udh) {		send_packet(out, 20, send_seq,			21, dest,			23, orig,			60, scts,			32, udh,			33, message,			0);	} else {		send_packet(out, 20, send_seq,			21, dest,			23, orig,			60, scts,			33, message,			0);	}	send_seq += 2;	if (send_seq > 255)		send_seq = 0;	awaiting_response = 1;}/************************** CIMD 2 specific code ends ************************/static void main_loop(void) {	fd_set readfds, writefds;	int n;	static int reported_outfull = 0;	int interval = -1;	inbuffer = octstr_create("");	outbuffer = octstr_create(intro);	start_time = time(NULL);	for (;;) {		if (octstr_len(outbuffer) < OUTBUFFER_LIMIT) {			interval = gen_data(outbuffer);		} else if (!reported_outfull) {			warning(0, "outbuffer getting full; waiting...");			reported_outfull = 1;		}		FD_ZERO(&readfds);		FD_SET(sockfd, &readfds);		if (octstr_len(outbuffer) > 0) {			FD_ZERO(&writefds);			FD_SET(sockfd, &writefds);			n = select(sockfd+1, &readfds, &writefds, NULL, NULL);		} else {			struct timeval tv;			struct timeval *tvp;			if (interval >= 0) {				tv.tv_sec = 0;				tv.tv_usec = interval;				tvp = &tv;			} else {				tvp = NULL;			}			n = select(sockfd+1, &readfds, NULL, NULL, tvp);		}		if (n < 0) {			if (errno == EINTR) {				warning(errno, "main loop, select");				continue;			}			error(errno, "main loop, select");			sleep(1);			continue;		}		if (n > 0) {			if (FD_ISSET(sockfd, &readfds)) {				read_data(inbuffer, sockfd);				parse_data(inbuffer, outbuffer);			}			if (octstr_len(outbuffer) > 0 &&			    FD_ISSET(sockfd, &writefds)) {				write_data(outbuffer, sockfd);			}			if (octstr_len(outbuffer) < OUTBUFFER_LIMIT) {				reported_outfull = 0;			}		}	}}static struct {	unsigned char *option;	void *location;	int number;} options[] = {	{ "--user", &username, 0 },	{ "--password", &password, 0 },	{ "--port", &port, 1 },	{ "--intro", &intro, 0 },	{ "--activity", &activity, 1 },	{ "--spew", &spew, 1 },	{ "--logging", &logging, 1 },	{ "--checking", &checking, 1 },	{ "--max", &max_deliveries, 1 },	{ NULL, NULL, 0 },};static int wait_for_client(int port) {	struct sockaddr_in sin;	socklen_t addrlen;	int listenfd;	int clientfd;	Octstr *addr;	listenfd = make_server_socket(port, NULL);	if (listenfd < 0) {		fprintf(stderr, "%s: failed to open socket at port %d\n",			progname, port);		exit(1);	}	do {		addrlen = sizeof(sin);		clientfd = accept(listenfd, (struct sockaddr *)&sin, &addrlen);		if (clientfd < 0) {			error(errno, "failed to accept new connection");		}	} while (clientfd < 0);	if (socket_set_blocking(clientfd, 0) < 0) {		panic(0, "failed to make client socket nonblocking");	}    	addr = gw_netaddr_to_octstr(AF_INET, &sin.sin_addr);	info(0, "Accepted client from %s:%d",		octstr_get_cstr(addr), ntohs(sin.sin_port));    	octstr_destroy(addr);	close(listenfd);	return clientfd;}	int main(int argc, char *argv[]) {	int i;	int opt;	gwlib_init();	progname = argv[0];	srandom(0);  /* Make "random" data reproducible */	for (i = 1; i < argc; i++) {		for (opt = 0; options[opt].option; opt++) {			if (strcmp(argv[i], options[opt].option) == 0) {				if (i + 1 >= argc) {					fprintf(stderr, "%s: missing argument to %s",						progname, argv[i]);					exit(2);				}				if (options[opt].number) {					* (int *) options[opt].location = atoi(argv[i+1]);				} else {					* (char **) options[opt].location = argv[i+1];				}				i++;				break;			}		}		if (options[opt].option)			continue;		if (strcmp(argv[i], "--help") == 0) {			usage(stdout);			exit(0);		}		if (argv[i][0] == '-') {			fprintf(stderr, "%s: unknown option %s\n",				progname, argv[i]);			usage(stderr);			exit(2);		}	}	sockfd = wait_for_client(port);	main_loop();	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -