Home | History | Annotate | Download | only in host_src
      1 /*----------------------------------------------------------------------------
      2  *
      3  * File:
      4  * eas_hostmm.c
      5  *
      6  * Contents and purpose:
      7  * This file contains the host wrapper functions for stdio, stdlib, etc.
      8  * This is a sample version that reads from a filedescriptor.
      9  * The file locator (EAS_FILE_LOCATOR) handle passed to
     10  * HWOpenFile is the same one that is passed to EAS_OpenFile.
     11  *
     12  * Modify this file to suit the needs of your particular system.
     13  *
     14  * EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within
     15  * a MIDI type 1 file that can be played.
     16  *
     17  * EAS_HW_FILE is a structure to support the file I/O functions. It
     18  * comprises the file descriptor, the file read pointer, and
     19  * the dup flag, which when set, indicates that the file handle has
     20  * been duplicated, and offset and length within the file.
     21  *
     22  * Copyright 2005 Sonic Network Inc.
     23 
     24  * Licensed under the Apache License, Version 2.0 (the "License");
     25  * you may not use this file except in compliance with the License.
     26  * You may obtain a copy of the License at
     27  *
     28  *      http://www.apache.org/licenses/LICENSE-2.0
     29  *
     30  * Unless required by applicable law or agreed to in writing, software
     31  * distributed under the License is distributed on an "AS IS" BASIS,
     32  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     33  * See the License for the specific language governing permissions and
     34  * limitations under the License.
     35  *
     36  *----------------------------------------------------------------------------
     37  * Revision Control:
     38  *   $Revision: 795 $
     39  *   $Date: 2007-08-01 00:14:45 -0700 (Wed, 01 Aug 2007) $
     40  *----------------------------------------------------------------------------
     41 */
     42 
     43 #ifdef _lint
     44 #include "lint_stdlib.h"
     45 #else
     46 #include <stdio.h>
     47 #include <stdlib.h>
     48 #include <string.h>
     49 #include <unistd.h>
     50 #include <sys/types.h>
     51 #include <sys/stat.h>
     52 #include <fcntl.h>
     53 #include <limits.h>
     54 #include <sys/mman.h>
     55 #include <errno.h>
     56 #include <signal.h>
     57 #include <pthread.h>
     58 #include <media/MediaPlayerInterface.h>
     59 #endif
     60 
     61 #include "eas_host.h"
     62 
     63 /* Only for debugging LED, vibrate, and backlight functions */
     64 #include "eas_report.h"
     65 
     66 /* this module requires dynamic memory support */
     67 #ifdef _STATIC_MEMORY
     68 #error "eas_hostmm.c requires the dynamic memory model!\n"
     69 #endif
     70 
     71 #ifndef EAS_MAX_FILE_HANDLES
     72 // 100 max file handles == 3 * (nb tracks(32) + 1 for the segment) + 1 for jet file
     73 //                         3 == 1(playing segment) + 1(prepared segment)
     74 //                              + 1(after end of playing segment, before files closed)
     75 #define EAS_MAX_FILE_HANDLES    100
     76 #endif
     77 
     78 /*
     79  * this structure and the related function are here
     80  * to support the ability to create duplicate handles
     81  * and buffering it in memory. If your system uses
     82  * in-memory resources, you can eliminate the calls
     83  * to malloc and free, the dup flag, and simply track
     84  * the file size and read position.
     85  */
     86 typedef struct eas_hw_file_tag
     87 {
     88     int (*readAt)(void *handle, void *buf, int offset, int size);
     89     int (*size)(void *handle);
     90     int filePos;
     91     void *handle;
     92 } EAS_HW_FILE;
     93 
     94 typedef struct eas_hw_inst_data_tag
     95 {
     96     EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
     97 } EAS_HW_INST_DATA;
     98 
     99 pthread_key_t EAS_sigbuskey;
    100 
    101 /*----------------------------------------------------------------------------
    102  * EAS_HWInit
    103  *
    104  * Initialize host wrapper interface
    105  *
    106  *----------------------------------------------------------------------------
    107 */
    108 EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
    109 {
    110     EAS_HW_FILE *file;
    111     int i;
    112 
    113     /* need to track file opens for duplicate handles */
    114     *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
    115     if (!(*pHWInstData))
    116         return EAS_ERROR_MALLOC_FAILED;
    117 
    118     EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
    119 
    120     file = (*pHWInstData)->files;
    121     for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
    122     {
    123         file->handle = NULL;
    124         file++;
    125     }
    126 
    127 
    128     return EAS_SUCCESS;
    129 }
    130 
    131 /*----------------------------------------------------------------------------
    132  * EAS_HWShutdown
    133  *
    134  * Shut down host wrapper interface
    135  *
    136  *----------------------------------------------------------------------------
    137 */
    138 EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
    139 {
    140 
    141     free(hwInstData);
    142     return EAS_SUCCESS;
    143 }
    144 
    145 /*----------------------------------------------------------------------------
    146  *
    147  * EAS_HWMalloc
    148  *
    149  * Allocates dynamic memory
    150  *
    151  *----------------------------------------------------------------------------
    152 */
    153 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    154 void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
    155 {
    156     /* Since this whole library loves signed sizes, let's not let
    157      * negative or 0 values through */
    158     if (size <= 0)
    159       return NULL;
    160     return malloc((size_t) size);
    161 }
    162 
    163 /*----------------------------------------------------------------------------
    164  *
    165  * EAS_HWFree
    166  *
    167  * Frees dynamic memory
    168  *
    169  *----------------------------------------------------------------------------
    170 */
    171 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    172 void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
    173 {
    174     free(p);
    175 }
    176 
    177 /*----------------------------------------------------------------------------
    178  *
    179  * EAS_HWMemCpy
    180  *
    181  * Copy memory wrapper
    182  *
    183  *----------------------------------------------------------------------------
    184 */
    185 void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
    186 {
    187     if (amount < 0)  {
    188       EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000004 , amount);
    189       exit(255);
    190     }
    191     return memcpy(dest, src, (size_t) amount);
    192 }
    193 
    194 /*----------------------------------------------------------------------------
    195  *
    196  * EAS_HWMemSet
    197  *
    198  * Set memory wrapper
    199  *
    200  *----------------------------------------------------------------------------
    201 */
    202 void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
    203 {
    204     if (amount < 0)  {
    205       EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000005 , amount);
    206       exit(255);
    207     }
    208     return memset(dest, val, (size_t) amount);
    209 }
    210 
    211 /*----------------------------------------------------------------------------
    212  *
    213  * EAS_HWMemCmp
    214  *
    215  * Compare memory wrapper
    216  *
    217  *----------------------------------------------------------------------------
    218 */
    219 EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
    220 {
    221     if (amount < 0) {
    222       EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000006 , amount);
    223       exit(255);
    224     }
    225     return (EAS_I32) memcmp(s1, s2, (size_t) amount);
    226 }
    227 
    228 /*----------------------------------------------------------------------------
    229  *
    230  * EAS_HWOpenFile
    231  *
    232  * Open a file for read or write
    233  *
    234  *----------------------------------------------------------------------------
    235 */
    236 EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
    237 {
    238     EAS_HW_FILE *file;
    239     int fd;
    240     int i, temp;
    241 
    242     /* set return value to NULL */
    243     *pFile = NULL;
    244 
    245     /* only support read mode at this time */
    246     if (mode != EAS_FILE_READ)
    247         return EAS_ERROR_INVALID_FILE_MODE;
    248 
    249     /* find an empty entry in the file table */
    250     file = hwInstData->files;
    251     for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
    252     {
    253         /* is this slot being used? */
    254         if (file->handle == NULL)
    255         {
    256             file->handle = locator->handle;
    257             file->readAt = locator->readAt;
    258             file->size = locator->size;
    259             file->filePos = 0;
    260             *pFile = file;
    261             return EAS_SUCCESS;
    262         }
    263         file++;
    264     }
    265 
    266     /* too many open files */
    267     return EAS_ERROR_MAX_FILES_OPEN;
    268 }
    269 
    270 
    271 /*----------------------------------------------------------------------------
    272  *
    273  * EAS_HWReadFile
    274  *
    275  * Read data from a file
    276  *
    277  *----------------------------------------------------------------------------
    278 */
    279 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    280 EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
    281 {
    282     EAS_I32 count;
    283 
    284     /* make sure we have a valid handle */
    285     if (file->handle == NULL)
    286         return EAS_ERROR_INVALID_HANDLE;
    287 
    288     if (n < 0)
    289       return EAS_EOF;
    290 
    291     /* calculate the bytes to read */
    292     count = file->size(file->handle) - file->filePos;
    293     if (n < count)
    294         count = n;
    295     if (count < 0)
    296       return EAS_EOF;
    297 
    298     /* copy the data to the requested location, and advance the pointer */
    299     if (count) {
    300         count = file->readAt(file->handle, pBuffer, file->filePos, count);
    301     }
    302     file->filePos += count;
    303     *pBytesRead = count;
    304 
    305     /* were n bytes read? */
    306     if (count!= n)
    307         return EAS_EOF;
    308     return EAS_SUCCESS;
    309 }
    310 
    311 /*----------------------------------------------------------------------------
    312  *
    313  * EAS_HWGetByte
    314  *
    315  * Read a byte from a file
    316  *
    317  *----------------------------------------------------------------------------
    318 */
    319 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    320 EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
    321 {
    322     EAS_I32 numread;
    323     return EAS_HWReadFile(hwInstData, file, p, 1, &numread);
    324 }
    325 
    326 /*----------------------------------------------------------------------------
    327  *
    328  * EAS_HWGetWord
    329  *
    330  * Read a 16 bit word from a file
    331  *
    332  *----------------------------------------------------------------------------
    333 */
    334 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    335 EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
    336 {
    337     EAS_RESULT result;
    338     EAS_U8 c1, c2;
    339 
    340     /* read 2 bytes from the file */
    341     if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
    342         return result;
    343     if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
    344         return result;
    345 
    346     /* order them as requested */
    347     if (msbFirst)
    348         *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2;
    349     else
    350         *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1;
    351 
    352     return EAS_SUCCESS;
    353 }
    354 
    355 /*----------------------------------------------------------------------------
    356  *
    357  * EAS_HWGetDWord
    358  *
    359  * Returns the current location in the file
    360  *
    361  *----------------------------------------------------------------------------
    362 */
    363 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    364 EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
    365 {
    366     EAS_RESULT result;
    367     EAS_U8 c1, c2,c3,c4;
    368 
    369     /* read 4 bytes from the file */
    370     if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
    371         return result;
    372     if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
    373         return result;
    374     if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS)
    375         return result;
    376     if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS)
    377         return result;
    378 
    379     /* order them as requested */
    380     if (msbFirst)
    381         *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4;
    382     else
    383         *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1;
    384 
    385     return EAS_SUCCESS;
    386 }
    387 
    388 /*----------------------------------------------------------------------------
    389  *
    390  * EAS_HWFilePos
    391  *
    392  * Returns the current location in the file
    393  *
    394  *----------------------------------------------------------------------------
    395 */
    396 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    397 EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
    398 {
    399 
    400     /* make sure we have a valid handle */
    401     if (file->handle == NULL)
    402         return EAS_ERROR_INVALID_HANDLE;
    403 
    404     *pPosition = file->filePos;
    405     return EAS_SUCCESS;
    406 } /* end EAS_HWFilePos */
    407 
    408 /*----------------------------------------------------------------------------
    409  *
    410  * EAS_HWFileSeek
    411  *
    412  * Seek to a specific location in the file
    413  *
    414  *----------------------------------------------------------------------------
    415 */
    416 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    417 EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
    418 {
    419 
    420     /* make sure we have a valid handle */
    421     if (file->handle == NULL)
    422         return EAS_ERROR_INVALID_HANDLE;
    423 
    424     /* validate new position */
    425     if ((position < 0) || (position > file->size(file->handle)))
    426         return EAS_ERROR_FILE_SEEK;
    427 
    428     /* save new position */
    429     file->filePos = position;
    430     return EAS_SUCCESS;
    431 }
    432 
    433 /*----------------------------------------------------------------------------
    434  *
    435  * EAS_HWFileSeekOfs
    436  *
    437  * Seek forward or back relative to the current position
    438  *
    439  *----------------------------------------------------------------------------
    440 */
    441 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    442 EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
    443 {
    444 
    445     /* make sure we have a valid handle */
    446     if (file->handle == NULL)
    447         return EAS_ERROR_INVALID_HANDLE;
    448 
    449     /* determine the file position */
    450     position += file->filePos;
    451     if ((position < 0) || (position > file->size(file->handle)))
    452         return EAS_ERROR_FILE_SEEK;
    453 
    454     /* save new position */
    455     file->filePos = position;
    456     return EAS_SUCCESS;
    457 }
    458 
    459 
    460 /*----------------------------------------------------------------------------
    461  *
    462  * EAS_HWDupHandle
    463  *
    464  * Duplicate a file handle
    465  *
    466  *----------------------------------------------------------------------------
    467 */
    468 EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile)
    469 {
    470     EAS_HW_FILE *dupFile;
    471     int i;
    472 
    473     /* make sure we have a valid handle */
    474     if (file->handle == NULL)
    475         return EAS_ERROR_INVALID_HANDLE;
    476 
    477     /* find an empty entry in the file table */
    478     dupFile = hwInstData->files;
    479     for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
    480     {
    481         /* is this slot being used? */
    482         if (dupFile->handle == NULL)
    483         {
    484             /* copy info from the handle to be duplicated */
    485             dupFile->handle = file->handle;
    486             dupFile->filePos = file->filePos;
    487             dupFile->readAt = file->readAt;
    488             dupFile->size = file->size;
    489 
    490             *pDupFile = dupFile;
    491             return EAS_SUCCESS;
    492         }
    493         dupFile++;
    494     }
    495 
    496     /* too many open files */
    497     return EAS_ERROR_MAX_FILES_OPEN;
    498 }
    499 
    500 /*----------------------------------------------------------------------------
    501  *
    502  * EAS_HWClose
    503  *
    504  * Wrapper for fclose function
    505  *
    506  *----------------------------------------------------------------------------
    507 */
    508 EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
    509 {
    510     EAS_HW_FILE *file2,*dupFile;
    511     int i;
    512 
    513 
    514     /* make sure we have a valid handle */
    515     if (file1->handle == NULL)
    516         return EAS_ERROR_INVALID_HANDLE;
    517 
    518     file1->handle = NULL;
    519     return EAS_SUCCESS;
    520 }
    521 
    522 /*----------------------------------------------------------------------------
    523  *
    524  * EAS_HWVibrate
    525  *
    526  * Turn on/off vibrate function
    527  *
    528  *----------------------------------------------------------------------------
    529 */
    530 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    531 EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
    532 {
    533     EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000001 , state);
    534     return EAS_SUCCESS;
    535 } /* end EAS_HWVibrate */
    536 
    537 /*----------------------------------------------------------------------------
    538  *
    539  * EAS_HWLED
    540  *
    541  * Turn on/off LED
    542  *
    543  *----------------------------------------------------------------------------
    544 */
    545 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    546 EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
    547 {
    548     EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000002 , state);
    549     return EAS_SUCCESS;
    550 }
    551 
    552 /*----------------------------------------------------------------------------
    553  *
    554  * EAS_HWBackLight
    555  *
    556  * Turn on/off backlight
    557  *
    558  *----------------------------------------------------------------------------
    559 */
    560 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    561 EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
    562 {
    563     EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x1a54b6e8, 0x00000003 , state);
    564     return EAS_SUCCESS;
    565 }
    566 
    567 /*----------------------------------------------------------------------------
    568  *
    569  * EAS_HWYield
    570  *
    571  * This function is called periodically by the EAS library to give the
    572  * host an opportunity to allow other tasks to run. There are two ways to
    573  * use this call:
    574  *
    575  * If you have a multi-tasking OS, you can call the yield function in the
    576  * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
    577  * the EAS library to continue processing when control returns from this
    578  * function.
    579  *
    580  * If tasks run in a single thread by sequential function calls (sometimes
    581  * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
    582  * return to the caller. Be sure to check the number of bytes rendered
    583  * before passing the audio buffer to the codec - it may not be filled.
    584  * The next call to EAS_Render will continue processing until the buffer
    585  * has been filled.
    586  *
    587  *----------------------------------------------------------------------------
    588 */
    589 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    590 EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
    591 {
    592     /* put your code here */
    593     return EAS_FALSE;
    594 }
    595 
    596