1*621120a2SAndroid Build Coastguard Worker #include <errno.h>
2*621120a2SAndroid Build Coastguard Worker #include <getopt.h>
3*621120a2SAndroid Build Coastguard Worker #include <stdint.h>
4*621120a2SAndroid Build Coastguard Worker #include <stdio.h>
5*621120a2SAndroid Build Coastguard Worker #include <stdlib.h>
6*621120a2SAndroid Build Coastguard Worker #include <string.h>
7*621120a2SAndroid Build Coastguard Worker #include <sys/socket.h>
8*621120a2SAndroid Build Coastguard Worker #include <sys/un.h>
9*621120a2SAndroid Build Coastguard Worker #include <unistd.h>
10*621120a2SAndroid Build Coastguard Worker
11*621120a2SAndroid Build Coastguard Worker #include "wmediumd/api.h"
12*621120a2SAndroid Build Coastguard Worker
print_help(int exit_code)13*621120a2SAndroid Build Coastguard Worker void print_help(int exit_code) {
14*621120a2SAndroid Build Coastguard Worker printf(
15*621120a2SAndroid Build Coastguard Worker "wmediumd_ack_test_client - test client for wmediumd crash that is "
16*621120a2SAndroid Build Coastguard Worker "related with ack\n\n");
17*621120a2SAndroid Build Coastguard Worker printf("Usage: wmediumd_ack_test_client -s PATH\n");
18*621120a2SAndroid Build Coastguard Worker printf(" Options:\n");
19*621120a2SAndroid Build Coastguard Worker printf(" - h : Print help\n");
20*621120a2SAndroid Build Coastguard Worker printf(" - s : Path for unix socket of wmediumd api server\n");
21*621120a2SAndroid Build Coastguard Worker
22*621120a2SAndroid Build Coastguard Worker exit(exit_code);
23*621120a2SAndroid Build Coastguard Worker }
24*621120a2SAndroid Build Coastguard Worker
write_fixed(int sock,void * data,int len)25*621120a2SAndroid Build Coastguard Worker int write_fixed(int sock, void *data, int len) {
26*621120a2SAndroid Build Coastguard Worker int remain = len;
27*621120a2SAndroid Build Coastguard Worker int pos = 0;
28*621120a2SAndroid Build Coastguard Worker
29*621120a2SAndroid Build Coastguard Worker while (remain > 0) {
30*621120a2SAndroid Build Coastguard Worker int actual_written = write(sock, ((char *)data) + pos, remain);
31*621120a2SAndroid Build Coastguard Worker
32*621120a2SAndroid Build Coastguard Worker if (actual_written <= 0) {
33*621120a2SAndroid Build Coastguard Worker return actual_written;
34*621120a2SAndroid Build Coastguard Worker }
35*621120a2SAndroid Build Coastguard Worker
36*621120a2SAndroid Build Coastguard Worker remain -= actual_written;
37*621120a2SAndroid Build Coastguard Worker pos += actual_written;
38*621120a2SAndroid Build Coastguard Worker }
39*621120a2SAndroid Build Coastguard Worker
40*621120a2SAndroid Build Coastguard Worker return pos;
41*621120a2SAndroid Build Coastguard Worker }
42*621120a2SAndroid Build Coastguard Worker
read_fixed(int sock,void * data,int len)43*621120a2SAndroid Build Coastguard Worker int read_fixed(int sock, void *data, int len) {
44*621120a2SAndroid Build Coastguard Worker int remain = len;
45*621120a2SAndroid Build Coastguard Worker int pos = 0;
46*621120a2SAndroid Build Coastguard Worker
47*621120a2SAndroid Build Coastguard Worker while (remain > 0) {
48*621120a2SAndroid Build Coastguard Worker int actual_read = read(sock, ((char *)data) + pos, remain);
49*621120a2SAndroid Build Coastguard Worker
50*621120a2SAndroid Build Coastguard Worker if (actual_read <= 0) {
51*621120a2SAndroid Build Coastguard Worker return actual_read;
52*621120a2SAndroid Build Coastguard Worker }
53*621120a2SAndroid Build Coastguard Worker
54*621120a2SAndroid Build Coastguard Worker remain -= actual_read;
55*621120a2SAndroid Build Coastguard Worker pos += actual_read;
56*621120a2SAndroid Build Coastguard Worker }
57*621120a2SAndroid Build Coastguard Worker
58*621120a2SAndroid Build Coastguard Worker return pos;
59*621120a2SAndroid Build Coastguard Worker }
60*621120a2SAndroid Build Coastguard Worker
wmediumd_send_packet(int sock,uint32_t type,void * data,uint32_t len)61*621120a2SAndroid Build Coastguard Worker int wmediumd_send_packet(int sock, uint32_t type, void *data, uint32_t len) {
62*621120a2SAndroid Build Coastguard Worker struct wmediumd_message_header header;
63*621120a2SAndroid Build Coastguard Worker
64*621120a2SAndroid Build Coastguard Worker header.type = type;
65*621120a2SAndroid Build Coastguard Worker header.data_len = len;
66*621120a2SAndroid Build Coastguard Worker
67*621120a2SAndroid Build Coastguard Worker write_fixed(sock, &header, sizeof(uint32_t) * 2);
68*621120a2SAndroid Build Coastguard Worker
69*621120a2SAndroid Build Coastguard Worker if (len != 0) {
70*621120a2SAndroid Build Coastguard Worker write_fixed(sock, data, len);
71*621120a2SAndroid Build Coastguard Worker }
72*621120a2SAndroid Build Coastguard Worker
73*621120a2SAndroid Build Coastguard Worker return 0;
74*621120a2SAndroid Build Coastguard Worker }
75*621120a2SAndroid Build Coastguard Worker
wmediumd_read_packet(int sock)76*621120a2SAndroid Build Coastguard Worker int wmediumd_read_packet(int sock) {
77*621120a2SAndroid Build Coastguard Worker struct wmediumd_message_header header;
78*621120a2SAndroid Build Coastguard Worker
79*621120a2SAndroid Build Coastguard Worker read_fixed(sock, &header, sizeof(uint32_t) * 2);
80*621120a2SAndroid Build Coastguard Worker
81*621120a2SAndroid Build Coastguard Worker if (header.data_len != 0) {
82*621120a2SAndroid Build Coastguard Worker char buf[4096];
83*621120a2SAndroid Build Coastguard Worker
84*621120a2SAndroid Build Coastguard Worker read_fixed(sock, buf, header.data_len);
85*621120a2SAndroid Build Coastguard Worker }
86*621120a2SAndroid Build Coastguard Worker
87*621120a2SAndroid Build Coastguard Worker return 0;
88*621120a2SAndroid Build Coastguard Worker }
89*621120a2SAndroid Build Coastguard Worker
main(int argc,char ** argv)90*621120a2SAndroid Build Coastguard Worker int main(int argc, char **argv) {
91*621120a2SAndroid Build Coastguard Worker int opt;
92*621120a2SAndroid Build Coastguard Worker char *wmediumd_api_server_path = NULL;
93*621120a2SAndroid Build Coastguard Worker
94*621120a2SAndroid Build Coastguard Worker while ((opt = getopt(argc, argv, "hs:")) != -1) {
95*621120a2SAndroid Build Coastguard Worker switch (opt) {
96*621120a2SAndroid Build Coastguard Worker case ':':
97*621120a2SAndroid Build Coastguard Worker fprintf(stderr,
98*621120a2SAndroid Build Coastguard Worker "error: Option `%c' "
99*621120a2SAndroid Build Coastguard Worker "needs a value\n\n",
100*621120a2SAndroid Build Coastguard Worker optopt);
101*621120a2SAndroid Build Coastguard Worker break;
102*621120a2SAndroid Build Coastguard Worker case 'h':
103*621120a2SAndroid Build Coastguard Worker print_help(0);
104*621120a2SAndroid Build Coastguard Worker break;
105*621120a2SAndroid Build Coastguard Worker case 's':
106*621120a2SAndroid Build Coastguard Worker if (wmediumd_api_server_path != NULL) {
107*621120a2SAndroid Build Coastguard Worker fprintf(stderr,
108*621120a2SAndroid Build Coastguard Worker "error: You must provide just one option for `%c`\n\n",
109*621120a2SAndroid Build Coastguard Worker optopt);
110*621120a2SAndroid Build Coastguard Worker }
111*621120a2SAndroid Build Coastguard Worker
112*621120a2SAndroid Build Coastguard Worker wmediumd_api_server_path = strdup(optarg);
113*621120a2SAndroid Build Coastguard Worker break;
114*621120a2SAndroid Build Coastguard Worker default:
115*621120a2SAndroid Build Coastguard Worker break;
116*621120a2SAndroid Build Coastguard Worker }
117*621120a2SAndroid Build Coastguard Worker }
118*621120a2SAndroid Build Coastguard Worker
119*621120a2SAndroid Build Coastguard Worker if (wmediumd_api_server_path == NULL) {
120*621120a2SAndroid Build Coastguard Worker fprintf(stderr, "error: must specify wmediumd api server path\n\n");
121*621120a2SAndroid Build Coastguard Worker print_help(-1);
122*621120a2SAndroid Build Coastguard Worker }
123*621120a2SAndroid Build Coastguard Worker
124*621120a2SAndroid Build Coastguard Worker int sock = socket(AF_UNIX, SOCK_STREAM, 0);
125*621120a2SAndroid Build Coastguard Worker
126*621120a2SAndroid Build Coastguard Worker struct sockaddr_un addr;
127*621120a2SAndroid Build Coastguard Worker
128*621120a2SAndroid Build Coastguard Worker addr.sun_family = AF_UNIX;
129*621120a2SAndroid Build Coastguard Worker
130*621120a2SAndroid Build Coastguard Worker if (strlen(wmediumd_api_server_path) >= sizeof(addr.sun_path)) {
131*621120a2SAndroid Build Coastguard Worker fprintf(stderr, "error: unix socket path is too long(maximum %zu)\n",
132*621120a2SAndroid Build Coastguard Worker sizeof(addr.sun_path) - 1);
133*621120a2SAndroid Build Coastguard Worker print_help(-1);
134*621120a2SAndroid Build Coastguard Worker }
135*621120a2SAndroid Build Coastguard Worker
136*621120a2SAndroid Build Coastguard Worker strncpy(addr.sun_path, wmediumd_api_server_path,
137*621120a2SAndroid Build Coastguard Worker strlen(wmediumd_api_server_path));
138*621120a2SAndroid Build Coastguard Worker
139*621120a2SAndroid Build Coastguard Worker if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
140*621120a2SAndroid Build Coastguard Worker fprintf(stderr, "Cannot connect to %s\n", wmediumd_api_server_path);
141*621120a2SAndroid Build Coastguard Worker return -1;
142*621120a2SAndroid Build Coastguard Worker }
143*621120a2SAndroid Build Coastguard Worker
144*621120a2SAndroid Build Coastguard Worker struct wmediumd_message_control control_message;
145*621120a2SAndroid Build Coastguard Worker
146*621120a2SAndroid Build Coastguard Worker control_message.flags = WMEDIUMD_CTL_RX_ALL_FRAMES;
147*621120a2SAndroid Build Coastguard Worker
148*621120a2SAndroid Build Coastguard Worker wmediumd_send_packet(sock, WMEDIUMD_MSG_REGISTER, NULL, 0);
149*621120a2SAndroid Build Coastguard Worker wmediumd_read_packet(sock); /* Ack */
150*621120a2SAndroid Build Coastguard Worker wmediumd_send_packet(sock, WMEDIUMD_MSG_SET_CONTROL, &control_message,
151*621120a2SAndroid Build Coastguard Worker sizeof(control_message));
152*621120a2SAndroid Build Coastguard Worker wmediumd_read_packet(sock); /* Ack */
153*621120a2SAndroid Build Coastguard Worker
154*621120a2SAndroid Build Coastguard Worker wmediumd_read_packet(sock);
155*621120a2SAndroid Build Coastguard Worker
156*621120a2SAndroid Build Coastguard Worker /* Send packet while receiving packet from wmediumd */
157*621120a2SAndroid Build Coastguard Worker wmediumd_send_packet(sock, WMEDIUMD_MSG_SET_CONTROL, &control_message,
158*621120a2SAndroid Build Coastguard Worker sizeof(control_message));
159*621120a2SAndroid Build Coastguard Worker wmediumd_read_packet(sock);
160*621120a2SAndroid Build Coastguard Worker
161*621120a2SAndroid Build Coastguard Worker wmediumd_send_packet(sock, WMEDIUMD_MSG_ACK, NULL, 0);
162*621120a2SAndroid Build Coastguard Worker
163*621120a2SAndroid Build Coastguard Worker close(sock);
164*621120a2SAndroid Build Coastguard Worker
165*621120a2SAndroid Build Coastguard Worker free(wmediumd_api_server_path);
166*621120a2SAndroid Build Coastguard Worker
167*621120a2SAndroid Build Coastguard Worker return 0;
168*621120a2SAndroid Build Coastguard Worker }
169