1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* a simple test program, connects to ADB server, and opens a track-devices session */
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <netdb.h>
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h>
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <memory.h>
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpanic( const char*  msg )
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr, "PANIC: %s: %s\n", msg, strerror(errno));
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    exit(1);
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunix_write( int  fd, const char*  buf, int  len )
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  result = 0;
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (len > 0) {
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  len2 = write(fd, buf, len);
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (len2 < 0) {
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (errno == EINTR || errno == EAGAIN)
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                continue;
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        result += len2;
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        len -= len2;
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        buf += len2;
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return  result;
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunix_read( int  fd, char*  buf, int  len )
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  result = 0;
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (len > 0) {
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  len2 = read(fd, buf, len);
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (len2 < 0) {
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (errno == EINTR || errno == EAGAIN)
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                continue;
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        result += len2;
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        len -= len2;
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        buf += len2;
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return  result;
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  main( void )
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                  ret, s;
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct sockaddr_in   server;
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char                 buffer[1024];
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char*          request = "track-jdwp";
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                  len;
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset( &server, 0, sizeof(server) );
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    server.sin_family      = AF_INET;
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    server.sin_port        = htons(5037);
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    s = socket( PF_INET, SOCK_STREAM, 0 );
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ret = connect( s, (struct sockaddr*) &server, sizeof(server) );
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (ret < 0) panic( "could not connect to server" );
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* send the request */
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    len = snprintf( buffer, sizeof buffer, "%04x%s", strlen(request), request );
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (unix_write(s, buffer, len) < 0)
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        panic( "could not send request" );
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* read the OKAY answer */
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (unix_read(s, buffer, 4) != 4)
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        panic( "could not read request" );
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf( "server answer: %.*s\n", 4, buffer );
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* now loop */
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (;;) {
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        char  head[5] = "0000";
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (unix_read(s, head, 4) < 0)
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            panic("could not read length");
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( sscanf( head, "%04x", &len ) != 1 )
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            panic("could not decode length");
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (unix_read(s, buffer, len) != len)
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            panic("could not read data");
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf( "received header %.*s (%d bytes):\n%.*s", 4, head, len, len, buffer );
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    close(s);
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
98