• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 #include <stdint.h>
17 #include <arpa/inet.h>
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 
21 #include <utils/StrongPointer.h>
22 
23 #include "audio/Buffer.h"
24 #include "Log.h"
25 #include "audio/AudioProtocol.h"
26 
27 
sendCommand(AudioParam & param)28 bool AudioProtocol::sendCommand(AudioParam& param)
29 {
30     mBuffer[0] = htonl(mCommand);
31     mBuffer[1] = 0;
32     return sendData((char*)mBuffer, 8);
33 }
34 
handleReply(const uint32_t * data,AudioParam * param)35 bool AudioProtocol::handleReply(const uint32_t* data, AudioParam* param)
36 {
37     if (!checkHeaderId(data, mCommand)) {
38         return false;
39     }
40     if (data[1] != 0) { // no endian change for 0
41         LOGE("error in reply %d", ntohl(data[1]));
42         return false;
43     }
44     if (data[2] != 0) {
45         LOGE("payload length %d not zero", ntohl(data[2]));
46         return false;
47     }
48     return true;
49 }
50 
handleReplyHeader(ClientSocket & socket,uint32_t * data,CommandId & id)51 bool AudioProtocol::handleReplyHeader(ClientSocket& socket, uint32_t* data, CommandId& id)
52 {
53     if (!socket.readData((char*)data, REPLY_HEADER_SIZE)) {
54         LOGE("handleReplyHeader cannot read");
55         return false;
56     }
57     uint32_t command = ntohl(data[0]);
58     if ((command & 0xffff0000) != 0x43210000) {
59         LOGE("Wrong header %x %x", command, data[0]);
60         return false;
61     }
62     command = (command & 0xffff) | 0x12340000; // convert to id
63     if (command < ECmdStart) {
64         LOGE("Wrong header %x %x", command, data[0]);
65         return false;
66     }
67     if (command > (ECmdLast - 1)) {
68         LOGE("Wrong header %x %x", command, data[0]);
69         return false;
70     }
71     id = (CommandId)command;
72     LOGD("received reply with command %x", command);
73     return true;
74 }
75 
checkHeaderId(const uint32_t * data,uint32_t command)76 bool AudioProtocol::checkHeaderId(const uint32_t* data, uint32_t command)
77 {
78     if (ntohl(data[0]) != ((command & 0xffff) | 0x43210000)) {
79         LOGE("wrong reply ID 0x%x", ntohl(data[0]));
80         return false;
81     }
82     return true;
83 }
84 
85 
86 /**
87  * param0 u32 data id
88  * param1 sp<Buffer>
89  */
sendCommand(AudioParam & param)90 bool CmdDownload::sendCommand(AudioParam& param)
91 {
92     mBuffer[0] = htonl(ECmdDownload);
93     mBuffer[1] = htonl(4 + param.mBuffer->getSize());
94     mBuffer[2] = htonl(param.mId);
95     if(!sendData((char*)mBuffer, 12)) {
96         return false;
97     }
98     return sendData(param.mBuffer->getData(), param.mBuffer->getSize());
99 }
100 
101 /**
102  * param0 u32 data id
103  * param1 u32 sampling rate
104  * param2 u32 mono / stereo(MSB) | mode
105  * param3 u32 volume
106  * param4 u32 repeat
107  */
sendCommand(AudioParam & param)108 bool CmdStartPlayback::sendCommand(AudioParam& param)
109 {
110     mBuffer[0] = htonl(ECmdStartPlayback);
111     mBuffer[1] = htonl(20);
112     mBuffer[2] = htonl(param.mId);
113     mBuffer[3] = htonl(param.mSamplingF);
114     uint32_t mode = param.mStereo ? 0x80000000 : 0;
115     mode |= param.mMode;
116     mBuffer[4] = htonl(mode);
117     mBuffer[5] = htonl(param.mVolume);
118     mBuffer[6] = htonl(param.mNumberRepetition);
119 
120     return sendData((char*)mBuffer, 28);
121 }
122 
123 
124 /**
125  * param0 u32 sampling rate
126  * param1 u32 mono / stereo(MSB) | mode
127  * param2 u32 volume
128  * param3 u32 samples
129  */
sendCommand(AudioParam & param)130 bool CmdStartRecording::sendCommand(AudioParam& param)
131 {
132     mBuffer[0] = htonl(ECmdStartRecording);
133     mBuffer[1] = htonl(16);
134     mBuffer[2] = htonl(param.mSamplingF);
135     uint32_t mode = param.mStereo ? 0x80000000 : 0;
136     mode |= param.mMode;
137     mBuffer[3] = htonl(mode);
138     mBuffer[4] = htonl(param.mVolume);
139     uint32_t samples = param.mBuffer->getSize() / (param.mStereo ? 4 : 2);
140     mBuffer[5] = htonl(samples);
141 
142     return sendData((char*)mBuffer, 24);
143 }
144 
145 /**
146  * param0 sp<Buffer>
147  */
handleReply(const uint32_t * data,AudioParam * param)148 bool CmdStartRecording::handleReply(const uint32_t* data, AudioParam* param)
149 {
150     if (!checkHeaderId(data, ECmdStartRecording)) {
151         return false;
152     }
153     if (data[1] != 0) { // no endian change for 0
154         LOGE("error in reply %d", ntohl(data[1]));
155         return false;
156     }
157     int len = ntohl(data[2]);
158     if (len > (int)param->mBuffer->getCapacity()) {
159         LOGE("received data %d exceeding buffer capacity %d", len, param->mBuffer->getCapacity());
160         // read and throw away
161         //Buffer tempBuffer(len);
162         //readData(tempBuffer.getData(), len);
163         return false;
164     }
165     if (!readData(param->mBuffer->getData(), len)) {
166         return false;
167     }
168     LOGI("received data %d from device", len);
169     param->mBuffer->setHandled(len);
170     param->mBuffer->setSize(len);
171     return true;
172 }
173 
174 
175 
176 
177