1bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber/*
2bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Copyright 2012, The Android Open Source Project
3bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *
4bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * you may not use this file except in compliance with the License.
6bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * You may obtain a copy of the License at
7bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *
8bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
9bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber *
10bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * Unless required by applicable law or agreed to in writing, software
11bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * See the License for the specific language governing permissions and
14bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber * limitations under the License.
15bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber */
16bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
17bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber//#define LOG_NEBUG 0
18bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#define LOG_TAG "udptest"
19bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <utils/Log.h>
20bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
21bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include "ANetworkSession.h"
22bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
23bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <binder/ProcessState.h>
24bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
25bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/ADebug.h>
26bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/AHandler.h>
27bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/ALooper.h>
28bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/foundation/AMessage.h>
29bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#include <media/stagefright/Utils.h>
30bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
31bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubernamespace android {
32bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
33bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstruct TestHandler : public AHandler {
34bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    TestHandler(const sp<ANetworkSession> &netSession);
35bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
36bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    void startServer(unsigned localPort);
37bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    void startClient(const char *remoteHost, unsigned remotePort);
38bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
39bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberprotected:
40bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    virtual ~TestHandler();
41bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
42bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    virtual void onMessageReceived(const sp<AMessage> &msg);
43bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
44bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberprivate:
45bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    enum {
46bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        kWhatStartServer,
47bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        kWhatStartClient,
48bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        kWhatUDPNotify,
49bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        kWhatSendPacket,
50bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    };
51bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
52bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    sp<ANetworkSession> mNetSession;
53bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
54bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    bool mIsServer;
55bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    bool mConnected;
56bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    int32_t mUDPSession;
57bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    uint32_t mSeqNo;
58bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    double mTotalTimeUs;
59bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    int32_t mCount;
60bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
61bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    void postSendPacket(int64_t delayUs = 0ll);
62bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
63bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(TestHandler);
64bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber};
65bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
66bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberTestHandler::TestHandler(const sp<ANetworkSession> &netSession)
67bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    : mNetSession(netSession),
68bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber      mIsServer(false),
69bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber      mConnected(false),
70bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber      mUDPSession(0),
71bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber      mSeqNo(0),
72bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber      mTotalTimeUs(0.0),
73bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber      mCount(0) {
74bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber}
75bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
76bb197f84c4119651e5face418285688ddaf08ea3Andreas HuberTestHandler::~TestHandler() {
77bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber}
78bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
79bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid TestHandler::startServer(unsigned localPort) {
80bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    sp<AMessage> msg = new AMessage(kWhatStartServer, id());
81bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    msg->setInt32("localPort", localPort);
82bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    msg->post();
83bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber}
84bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
85bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid TestHandler::startClient(const char *remoteHost, unsigned remotePort) {
86bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    sp<AMessage> msg = new AMessage(kWhatStartClient, id());
87bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    msg->setString("remoteHost", remoteHost);
88bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    msg->setInt32("remotePort", remotePort);
89bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    msg->post();
90bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber}
91bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
92bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid TestHandler::onMessageReceived(const sp<AMessage> &msg) {
93bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    switch (msg->what()) {
94bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        case kWhatStartClient:
95bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        {
96bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            AString remoteHost;
97bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            CHECK(msg->findString("remoteHost", &remoteHost));
98bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
99bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            int32_t remotePort;
100bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            CHECK(msg->findInt32("remotePort", &remotePort));
101bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
102bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            sp<AMessage> notify = new AMessage(kWhatUDPNotify, id());
103bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
104bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            CHECK_EQ((status_t)OK,
105bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                     mNetSession->createUDPSession(
106bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                         0 /* localPort */,
107bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                         remoteHost.c_str(),
108bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                         remotePort,
109bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                         notify,
110bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                         &mUDPSession));
111bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
112bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            postSendPacket();
113bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            break;
114bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        }
115bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
116bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        case kWhatStartServer:
117bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        {
118bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            mIsServer = true;
119bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
120bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            int32_t localPort;
121bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            CHECK(msg->findInt32("localPort", &localPort));
122bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
123bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            sp<AMessage> notify = new AMessage(kWhatUDPNotify, id());
124bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
125bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            CHECK_EQ((status_t)OK,
126bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                     mNetSession->createUDPSession(
127bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                         localPort, notify, &mUDPSession));
128bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
129bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            break;
130bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        }
131bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
132bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        case kWhatSendPacket:
133bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        {
134bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            char buffer[12];
135bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            memset(buffer, 0, sizeof(buffer));
136bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
137bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[0] = mSeqNo >> 24;
138bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[1] = (mSeqNo >> 16) & 0xff;
139bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[2] = (mSeqNo >> 8) & 0xff;
140bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[3] = mSeqNo & 0xff;
141bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            ++mSeqNo;
142bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
143bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            int64_t nowUs = ALooper::GetNowUs();
144bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[4] = nowUs >> 56;
145bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[5] = (nowUs >> 48) & 0xff;
146bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[6] = (nowUs >> 40) & 0xff;
147bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[7] = (nowUs >> 32) & 0xff;
148bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[8] = (nowUs >> 24) & 0xff;
149bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[9] = (nowUs >> 16) & 0xff;
150bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[10] = (nowUs >> 8) & 0xff;
151bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            buffer[11] = nowUs & 0xff;
152bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
153bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            CHECK_EQ((status_t)OK,
154bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                     mNetSession->sendRequest(
155bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                         mUDPSession, buffer, sizeof(buffer)));
156bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
157bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            postSendPacket(20000ll);
158bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            break;
159bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        }
160bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
161bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        case kWhatUDPNotify:
162bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        {
163bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            int32_t reason;
164bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            CHECK(msg->findInt32("reason", &reason));
165bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
166bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            switch (reason) {
167bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                case ANetworkSession::kWhatError:
168bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                {
169bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    int32_t sessionID;
170bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    CHECK(msg->findInt32("sessionID", &sessionID));
171bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
172bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    int32_t err;
173bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    CHECK(msg->findInt32("err", &err));
174bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
175bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    AString detail;
176bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    CHECK(msg->findString("detail", &detail));
177bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
178bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    ALOGE("An error occurred in session %d (%d, '%s/%s').",
179bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                          sessionID,
180bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                          err,
181bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                          detail.c_str(),
182bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                          strerror(-err));
183bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
184bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    mNetSession->destroySession(sessionID);
185bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    break;
186bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                }
187bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
188bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                case ANetworkSession::kWhatDatagram:
189bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                {
190bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    int32_t sessionID;
191bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    CHECK(msg->findInt32("sessionID", &sessionID));
192bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
193bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    sp<ABuffer> data;
194bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    CHECK(msg->findBuffer("data", &data));
195bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
196bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    if (mIsServer) {
197bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        if (!mConnected) {
198bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                            AString fromAddr;
199bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                            CHECK(msg->findString("fromAddr", &fromAddr));
200bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
201bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                            int32_t fromPort;
202bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                            CHECK(msg->findInt32("fromPort", &fromPort));
203bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
204bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                            CHECK_EQ((status_t)OK,
205bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                                     mNetSession->connectUDPSession(
206bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                                         mUDPSession, fromAddr.c_str(), fromPort));
207bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
208bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                            mConnected = true;
209bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        }
210bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
211bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        int64_t nowUs = ALooper::GetNowUs();
212bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
213bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        sp<ABuffer> buffer = new ABuffer(data->size() + 8);
214bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        memcpy(buffer->data(), data->data(), data->size());
215bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
216bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        uint8_t *ptr = buffer->data() + data->size();
217bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
218bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        *ptr++ = nowUs >> 56;
219bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        *ptr++ = (nowUs >> 48) & 0xff;
220bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        *ptr++ = (nowUs >> 40) & 0xff;
221bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        *ptr++ = (nowUs >> 32) & 0xff;
222bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        *ptr++ = (nowUs >> 24) & 0xff;
223bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        *ptr++ = (nowUs >> 16) & 0xff;
224bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        *ptr++ = (nowUs >> 8) & 0xff;
225bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        *ptr++ = nowUs & 0xff;
226bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
227bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        CHECK_EQ((status_t)OK,
228bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                                 mNetSession->sendRequest(
229bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                                     mUDPSession, buffer->data(), buffer->size()));
230bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    } else {
231bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        CHECK_EQ(data->size(), 20u);
232bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
233bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        uint32_t seqNo = U32_AT(data->data());
234bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        int64_t t1 = U64_AT(data->data() + 4);
235bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        int64_t t2 = U64_AT(data->data() + 12);
236bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
237bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        int64_t t3;
238bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        CHECK(data->meta()->findInt64("arrivalTimeUs", &t3));
239bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
240bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#if 0
241bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        printf("roundtrip seqNo %u, time = %lld us\n",
242bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                               seqNo, t3 - t1);
243bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#else
244bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        mTotalTimeUs += t3 - t1;
245bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        ++mCount;
246bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        printf("avg. roundtrip time %.2f us\n", mTotalTimeUs / mCount);
247bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber#endif
248bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    }
249bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    break;
250bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                }
251bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
252bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                default:
253bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    TRESPASS();
254bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            }
255bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
256bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            break;
257bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        }
258bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
259bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        default:
260bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            TRESPASS();
261bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    }
262bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber}
263bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
264bb197f84c4119651e5face418285688ddaf08ea3Andreas Hubervoid TestHandler::postSendPacket(int64_t delayUs) {
265bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    (new AMessage(kWhatSendPacket, id()))->post(delayUs);
266bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber}
267bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
268bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber}  // namespace android
269bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
270bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberstatic void usage(const char *me) {
271bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    fprintf(stderr,
272bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            "usage: %s -c host[:port]\tconnect to test server\n"
273bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            "           -l            \tcreate a test server\n",
274bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            me);
275bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber}
276bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
277bb197f84c4119651e5face418285688ddaf08ea3Andreas Huberint main(int argc, char **argv) {
278bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    using namespace android;
279bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
280bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    ProcessState::self()->startThreadPool();
281bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
282bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    int32_t localPort = -1;
283bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    int32_t connectToPort = -1;
284bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    AString connectToHost;
285bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
286bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    int res;
287bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    while ((res = getopt(argc, argv, "hc:l:")) >= 0) {
288bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        switch (res) {
289bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            case 'c':
290bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            {
291bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                const char *colonPos = strrchr(optarg, ':');
292bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
293bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                if (colonPos == NULL) {
294bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    connectToHost = optarg;
295bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    connectToPort = 49152;
296bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                } else {
297bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    connectToHost.setTo(optarg, colonPos - optarg);
298bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
299bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    char *end;
300bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    connectToPort = strtol(colonPos + 1, &end, 10);
301bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
302bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    if (*end != '\0' || end == colonPos + 1
303bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                            || connectToPort < 1 || connectToPort > 65535) {
304bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        fprintf(stderr, "Illegal port specified.\n");
305bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        exit(1);
306bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    }
307bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                }
308bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                break;
309bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            }
310bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
311bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            case 'l':
312bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            {
313bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                char *end;
314bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                localPort = strtol(optarg, &end, 10);
315bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
316bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                if (*end != '\0' || end == optarg
317bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                        || localPort < 1 || localPort > 65535) {
318bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    fprintf(stderr, "Illegal port specified.\n");
319bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                    exit(1);
320bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                }
321bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                break;
322bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            }
323bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
324bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            case '?':
325bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber            case 'h':
326bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                usage(argv[0]);
327bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                exit(1);
328bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        }
329bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    }
330bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
331bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    if (localPort < 0 && connectToPort < 0) {
332bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        fprintf(stderr,
333bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber                "You need to select either client or server mode.\n");
334bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        exit(1);
335bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    }
336bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
337bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    sp<ANetworkSession> netSession = new ANetworkSession;
338bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    netSession->start();
339bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
340bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    sp<ALooper> looper = new ALooper;
341bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
342bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    sp<TestHandler> handler = new TestHandler(netSession);
343bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    looper->registerHandler(handler);
344bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
345bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    if (localPort >= 0) {
346bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        handler->startServer(localPort);
347bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    } else {
348bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber        handler->startClient(connectToHost.c_str(), connectToPort);
349bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    }
350bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
351bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    looper->start(true /* runOnCallingThread */);
352bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
353bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber    return 0;
354bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber}
355bb197f84c4119651e5face418285688ddaf08ea3Andreas Huber
356