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
17
18#ifndef CTSAUDIO_AUDIOPROTOCOL_H
19#define CTSAUDIO_AUDIOPROTOCOL_H
20
21#include <stdint.h>
22
23#include <utils/StrongPointer.h>
24#include "Log.h"
25#include "audio/Buffer.h"
26#include "ClientSocket.h"
27
28#define U32_ENDIAN_SWAP(x) ( ((x) & 0x000000ff)<<24 | ((x) & 0x0000ff00)<<8 | \
29        ((x) & 0x00ff0000)>>8 | ((x) & 0xff000000)>>24 )
30
31class AudioParam {
32public:
33    bool mStereo;
34    uint32_t mSamplingF;
35    uint32_t mMode;
36    uint32_t mNumberRepetition; // only for playback
37    uint32_t mVolume;
38    uint32_t mId;
39    android::sp<Buffer> mBuffer;
40    void* mExtra; // extra data for whatever purpose
41};
42
43class AudioProtocol {
44public:
45    enum CommandId {
46        ECmdStart               = 0x12340001, //not actual command
47        ECmdDownload            = 0x12340001,
48        ECmdStartPlayback       = 0x12340002,
49        ECmdStopPlayback        = 0x12340003,
50        ECmdStartRecording      = 0x12340004,
51        ECmdStopRecording       = 0x12340005,
52        ECmdGetDeviceInfo       = 0x12340006,
53        ECmdLast                = 0x12340007, // not actual command
54    };
55
56    static const uint32_t REPLY_HEADER_SIZE = 12;
57    // up to 5 parameters for command / reply
58    class ProtocolParam {
59    public:
60        void* param[5];
61    };
62
63    virtual ~AudioProtocol() {
64        //LOGD("~AudioProtocol %x", this);
65    };
66
67    /// default implementation, no param, no payload
68    virtual bool sendCommand(AudioParam& param);
69    /// default implementation, no param, no payload
70    virtual bool handleReply(const uint32_t* data, AudioParam* param);
71
72    /**
73     * read header of reply and returns CommandId of reply.
74     * @param socket socket to read
75     * @param data pointer to buffer to store header, it should be uint32_t[3]
76     * @param id types of reply
77     * @return true if everything OK
78     */
79    static bool handleReplyHeader(ClientSocket& socket, uint32_t* data, CommandId& id);
80
81protected:
82    AudioProtocol(ClientSocket& socket, uint32_t command)
83        : mCommand(command),
84          mSocket(socket) {};
85
86    bool sendData(const char* data, int len) {
87        return mSocket.sendData(data, len);
88    };
89
90    bool checkHeaderId(const uint32_t* data, uint32_t command);
91    bool readData(char* data, int len) {
92        return mSocket.readData(data, len);
93    };
94
95protected:
96    int mBuffer[8];
97private:
98    uint32_t mCommand;
99    ClientSocket& mSocket;
100
101};
102
103class CmdDownload: public AudioProtocol {
104public:
105    CmdDownload(ClientSocket& socket)
106        : AudioProtocol(socket, ECmdDownload) {};
107    virtual ~CmdDownload() {};
108    virtual bool sendCommand(AudioParam& param);
109};
110
111
112class CmdStartPlayback: public AudioProtocol {
113public:
114    CmdStartPlayback(ClientSocket& socket)
115        : AudioProtocol(socket, ECmdStartPlayback) {};
116    virtual ~CmdStartPlayback() {};
117    virtual bool sendCommand(AudioParam& param);
118};
119
120class CmdStopPlayback: public AudioProtocol {
121public:
122    CmdStopPlayback(ClientSocket& socket)
123        : AudioProtocol(socket, ECmdStopPlayback) {};
124    virtual ~CmdStopPlayback() {};
125};
126
127class CmdStartRecording: public AudioProtocol {
128public:
129    CmdStartRecording(ClientSocket& socket)
130        : AudioProtocol(socket, ECmdStartRecording) {};
131    virtual ~CmdStartRecording() {};
132
133    virtual bool sendCommand(AudioParam& param);
134
135    virtual bool handleReply(const uint32_t* data, AudioParam* param);
136};
137
138class CmdStopRecording: public AudioProtocol {
139public:
140    CmdStopRecording(ClientSocket& socket)
141        : AudioProtocol(socket, ECmdStopRecording) {};
142    virtual ~CmdStopRecording() {};
143};
144
145class CmdGetDeviceInfo: public AudioProtocol {
146public:
147    CmdGetDeviceInfo(ClientSocket& socket)
148        : AudioProtocol(socket, ECmdGetDeviceInfo) {};
149    virtual ~CmdGetDeviceInfo() {};
150
151    virtual bool handleReply(const uint32_t* data, AudioParam* param);
152};
153
154#endif // CTSAUDIO_AUDIOPROTOCOL_H
155