Home | History | Annotate | Download | only in test_description
      1 #!/usr/bin/python
      2 
      3 # Copyright (C) 2012 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #       http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 
     17 import sys
     18 import numpy as np
     19 import scipy as sp
     20 import socket
     21 import struct
     22 sys.path.append(sys.path[0] + "/processing")
     23 from consts import *
     24 
     25 builtinFunctions = [
     26     "echo", # send back whatever is received
     27     "intsum", # returns int64 + int64
     28 ]
     29 
     30 CMD_HEADER    = 0x0
     31 CMD_TERMINATE = 0x1
     32 CMD_FUNCTION  = 0x2
     33 CMD_AUDIO_MONO = 0x4
     34 CMD_AUDIO_STEREO = 0x5
     35 CMD_INT64 = 0x8
     36 CMD_DOUBLE = 0x9
     37 CMD_RESULT = 0x10
     38 
     39 def echo(inputData, inputTypes):
     40     output = []
     41     print "echo received ", inputData
     42     output.append(RESULT_OK)
     43     output.append(inputData)
     44     output.append(inputTypes)
     45     return output
     46 
     47 def intsum(inputData, inputTypes):
     48     output = []
     49     output.append(RESULT_OK)
     50     sum = inputData[0] + inputData[1]
     51     print "intsum sum is ", sum
     52     outputData = []
     53     outputData.append(sum)
     54     outputTypes = []
     55     outputTypes.append(TYPE_I64)
     56     output.append(outputData)
     57     output.append(outputTypes)
     58     return output
     59 
     60 
     61 class CommandHandler(object):
     62 
     63     def __init__(self, conn):
     64         self.conn = conn
     65     def __del__(self):
     66         self.conn.close()
     67     def run(self):
     68         header = self.readI32()
     69         if header == CMD_TERMINATE:
     70             print "terminate cmd, will exit"
     71             sys.exit(0)
     72         nParam = 0
     73         if header == CMD_HEADER:
     74             nParam = self.readI32()
     75             if nParam < 1:
     76                 protocolError("wrong number of params")
     77             cmdFunction = self.readI32()
     78             if cmdFunction != CMD_FUNCTION:
     79                 protocolError("not function")
     80             nameLen = self.readI32()
     81             self.functionName = self.readRaw(nameLen)
     82             print "Processing function:", self.functionName
     83             inputData = []
     84             inputTypes = []
     85             for i in range(nParam - 1):
     86                 cmd = self.readI32()
     87                 if (cmd == CMD_AUDIO_STEREO) or (cmd == CMD_AUDIO_MONO):
     88                     dataLen = self.readI32()
     89                     data = self.readI16Array(dataLen / 2)
     90                     inputData.append(data)
     91                     if (cmd == CMD_AUDIO_STEREO):
     92                         inputTypes.append(TYPE_STEREO)
     93                     else:
     94                         inputTypes.append(TYPE_MONO)
     95                     print i, "-th input received audio data ", dataLen, cmd
     96                 elif cmd == CMD_INT64:
     97                     i64 = self.readI64()
     98                     inputData.append(i64)
     99                     inputTypes.append(TYPE_I64)
    100                 elif cmd == CMD_DOUBLE:
    101                     val = self.readDouble()
    102                     inputData.append(val)
    103                     inputTypes.append(TYPE_DOUBLE)
    104                 else:
    105                     self.protocolError("unknown command " + str(cmd))
    106             print "inputTypes ", inputTypes
    107             # length 3 list
    108             # output[0]: int, execution result, RESULT_XXX values
    109             # output[1]: output data list
    110             # output[2]: output type list
    111             output = []
    112             if not self.functionName in builtinFunctions:
    113                 mod = __import__(self.functionName)
    114                 output = getattr(mod, self.functionName)(inputData, inputTypes)
    115             else:
    116                 output = globals()[self.functionName](inputData, inputTypes)
    117             nOutputParams = len(output[1])
    118             self.sendI32(CMD_HEADER)
    119             self.sendI32(nOutputParams + 1) # 1 for result
    120             self.sendI32(CMD_RESULT)
    121             self.sendI32(output[0])
    122             outputData = output[1]
    123             outputTypes = output[2]
    124             print "outputTypes ", outputTypes
    125             for i in range(nOutputParams):
    126                 if (outputTypes[i] == TYPE_I64):
    127                     self.sendI32(CMD_INT64)
    128                     self.sendI64(outputData[i])
    129                 elif (outputTypes[i] == TYPE_DOUBLE):
    130                     self.sendI32(CMD_DOUBLE)
    131                     self.sendDouble(outputData[i])
    132                 elif (outputTypes[i] == TYPE_STEREO):
    133                     self.sendI32(CMD_AUDIO_STEREO)
    134                     self.sendI32(len(outputData[i]) * 2)
    135                     self.sendI16Array(outputData[i])
    136                 elif (outputTypes[i] == TYPE_MONO):
    137                     self.sendI32(CMD_AUDIO_MONO)
    138                     self.sendI32(len(outputData[i]) * 2)
    139                     self.sendI16Array(outputData[i])
    140                 else:
    141                     print "unknown type ", outputTypes[i], \
    142                         " returned from funcion ", self.functionName
    143                     sys.exit(1)
    144 
    145     def readRaw(self, length):
    146         result = []
    147         totalRead = 0
    148         while totalRead < length:
    149             raw = self.conn.recv(length - totalRead)
    150             justRead = len(raw)
    151             if justRead == 0: # socket closed
    152                 sys.exit(1)
    153             totalRead += justRead
    154             result.append(raw)
    155         return ''.join(result)
    156 
    157     def readI32(self):
    158         raw = self.readRaw(4)
    159         i32 = struct.unpack("<i", raw)
    160         return i32[0]
    161 
    162     def readI64(self):
    163         raw = self.readRaw(8)
    164         i64 = struct.unpack("<q", raw)
    165         return i64[0]
    166 
    167     def readDouble(self):
    168         raw = self.readRaw(8)
    169         val = struct.unpack("<d", raw)
    170         return val[0]
    171 
    172     def readI16Array(self, length):
    173         raw = self.readRaw(length * 2)
    174         data = np.fromstring(raw, dtype=np.int16)
    175         return data
    176 
    177     def sendI32(self, i32):
    178         raw = struct.pack("<i", i32)
    179         self.sendRaw(raw)
    180 
    181     def sendI64(self, i64):
    182         raw = struct.pack("<q", i64)
    183         self.sendRaw(raw)
    184 
    185     def sendDouble(self, val):
    186         raw = struct.pack("<d", val)
    187         self.sendRaw(raw)
    188 
    189     def sendI16Array(self, arry):
    190         raw = arry.tostring()
    191         self.sendRaw(raw)
    192 
    193     def sendRaw(self, rawString):
    194         totalSent = 0
    195         stringLen = len(rawString)
    196         while totalSent < stringLen:
    197             sent = self.conn.send(rawString[totalSent:])
    198             totalSent += sent
    199 
    200     def protocolError(self, message):
    201         print message
    202         sys.exit(1)
    203 
    204 
    205 if __name__=="__main__":
    206     HOST = "localhost"
    207     PORT = 15010
    208     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    209     s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    210     s.bind((HOST, PORT))
    211     s.listen(1)
    212 
    213     conn, addr = s.accept()
    214     print "client connected"
    215     # close the server socket to allow other instance to run
    216     s.close()
    217     handler = CommandHandler(conn)
    218     while 1:
    219         handler.run()
    220