/* * after I've updated the firmware of my AEX, data from AEX doesn't come * when raop_play is not sending data. * 'rsize=GET_BIGENDIAN_INT(buf+0x2c)' this size stops with 330750. * I think '330750/44100=7.5 sec' is data in the AEX bufeer, so add a timer * to check when the AEX buffer data becomes empty. * * from aexcl_play, it goes down but doesn't become zero. * (12/15/2005) */ static int fd_event_callback(void *p, int flags) { int i; u_int8_t buf[256]; raopcl_data_t *raopcld; int rsize; if(!p) return -1; raopcld=(raopcl_data_t *)p; if(flags&RAOP_FD_READ){ return 0; i=read(raopcld->sfd,buf,sizeof(buf)); if(i>0){ rsize=GET_BIGENDIAN_INT(buf+0x2c); raopcld->size_in_aex=rsize; gettimeofday(&raopcld->last_read_tv,NULL); //DBGMSG("%s: read %d bytes, rsize=%d\n", __func__, i,rsize); return 0; } if(i<0) ERRMSG("%s: read error: %s\n", __func__, strerror(errno)); if(i==0) INFMSG("%s: read, disconnected on the other end\n", __func__); return -1; } if(!flags&RAOP_FD_WRITE){ ERRMSG("%s: unknow event flags=%d\n", __func__,flags); return -1; } if(!raopcld->wblk_remsize) { ERRMSG("%s: write is called with remsize=0\n", __func__); return -1; } i=write(raopcld->sfd,raopcld->data+raopcld->wblk_wsize,MIN(4096,raopcld->wblk_remsize)); if(i<0){ ERRMSG("%s: write error: %s\n", __func__, strerror(errno)); return -1; } if(i==0){ INFMSG("%s: write, disconnected on the other end\n", __func__); return -1; } raopcld->wblk_wsize+=i; raopcld->wblk_remsize-=i; if(!raopcld->wblk_remsize) { set_fd_event(raopcld->sfd, RAOP_FD_READ, fd_event_callback,(void*)raopcld); } //DBGMSG("%d bytes are sent, remaining size=%d\n",i,raopcld->wblk_remsize); return 0; }
static int raop_encrypt(raopcl_data_t *raopcld, u_int8_t *data, int size) { u_int8_t *buf; //u_int8_t tmp[16]; int i=0,j; memcpy(raopcld->nv,raopcld->iv,16); while(i+16<=size){ buf=data+i; for(j=0;j<16;j++) buf[j] ^= raopcld->nv[j]; aes_encrypt(&raopcld->ctx, buf, buf); memcpy(raopcld->nv,buf,16); i+=16; } if(i<size){ #if 0 INFMSG("%s: a block less than 16 bytes(%d) is not encrypted\n",__func__, size-i); memset(tmp,0,16); memcpy(tmp,data+i,size-i); for(j=0;j<16;j++) tmp[j] ^= raopcld->nv[j]; aes_encrypt(&raopcld->ctx, tmp, tmp); memcpy(raopcld->nv,tmp,16); memcpy(data+i,tmp,16); i+=16; #endif } return i; }
int tcardIsMount( void ) { char device[256]; char mount_path[256]; FILE *fp; char line[1024]; if (!(fp = fopen("/proc/mounts", "r"))) { ERRMSG("Error opening /proc/mounts (%s)", strerror(errno)); return -1; } int mount = 0; while(fgets(line, sizeof(line), fp)) { line[strlen(line)-1] = '\0'; sscanf(line, "%255s %255s\n", device, mount_path); DBGMSG("dev = %s, mount = %s\n", device, mount_path); if( NULL != strstr(mount_path, TCARD_VOLUME_NAME)) { mount = 1; INFMSG("TCard mount path: '%s'\n", mount_path); break; } } fclose(fp); return mount; }
void RkDispHardwareCursor_Init(ScreenPtr pScreen) { xf86CursorInfoPtr InfoPtr; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; FBDevPtr pMxv = FBDEVPTR(pScrn); pMxv->RkHWC = NULL; int fd; fd = fbdevHWGetFD(pScrn); if (fd <= 0){ ERRMSG("DispHardwareCursor_Init fd error"); return; } if (!(InfoPtr = xf86CreateCursorInfoRec())) { ERRMSG("DispHardwareCursor_Init: xf86CreateCursorInfoRec() failed"); return; } InfoPtr->ShowCursor = ShowCursor; InfoPtr->HideCursor = HideCursor; InfoPtr->SetCursorPosition = SetCursorPosition; InfoPtr->SetCursorColors = SetCursorColors; InfoPtr->LoadCursorImage = LoadCursorImage; InfoPtr->MaxWidth = 32; InfoPtr->MaxHeight = 32; // InfoPtr->RealizeCursor InfoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; if (!xf86InitCursor(pScreen, InfoPtr)) { ERRMSG("DispHardwareCursor_Init: xf86InitCursor(pScreen, InfoPtr) failed"); xf86DestroyCursorInfoRec(InfoPtr); goto err; } pMxv->RkHWC = calloc(1, sizeof(RkDispHWCRec)); if (!pMxv->RkHWC) { ERRMSG("DispHardwareCursor_Init: calloc failed"); xf86DestroyCursorInfoRec(InfoPtr); goto err; } RkDispHWCPtr HWC = pMxv->RkHWC; INFMSG("HWCursor activated"); HWC->hwcursor = InfoPtr; HWC->fb_fd = fd; return; //******************not ok************* err: xf86DestroyCursorInfoRec(InfoPtr); }
int tcardRWTest( void ) { FILE * fp = fopen(TCARD_FILE_NAME, "w"); if( NULL == fp ) { ERRMSG("open '%s'(rw) fail: %s(%d)\n", TCARD_FILE_NAME, strerror(errno), errno); return -1; } if( fwrite(TCARD_TEST_CONTENT, 1, sizeof(TCARD_TEST_CONTENT), fp) != sizeof(TCARD_TEST_CONTENT) ) { ERRMSG("write '%s' fail: %s(%d)\n", TCARD_FILE_NAME, strerror(errno), errno); fclose(fp); return -2; } fclose(fp); fp = fopen(TCARD_FILE_NAME, "r"); if( NULL == fp ) { ERRMSG("open '%s'(ronly) fail: %s(%d)\n", TCARD_FILE_NAME, strerror(errno), errno); return -3; } AT_ASSERT( sizeof(TCARD_TEST_CONTENT) < 128 ); char buf[128]; if( fread(buf, 1, sizeof(TCARD_TEST_CONTENT), fp) != sizeof(TCARD_TEST_CONTENT) ) { ERRMSG("read '%s' fail: %s(%d)\n", TCARD_FILE_NAME, strerror(errno), errno); fclose(fp); return -4; } fclose(fp); unlink(TCARD_FILE_NAME); if( strncmp(buf, TCARD_TEST_CONTENT, sizeof(TCARD_TEST_CONTENT) - 1) ) { ERRMSG("read = %s, dst = %s\n", buf, TCARD_TEST_CONTENT); return -5; } INFMSG("TFlash Card rw OK.\n"); return 0; }
static int main_event_handler() { fd_set rdfds,wrfds; int fdmax=0; int i; struct timeval tout={.tv_sec=MAIN_EVENT_TIMEOUT, .tv_usec=0}; FD_ZERO(&rdfds); FD_ZERO(&wrfds); for(i=0;i<MAX_NUM_OF_FDS;i++){ if(raopld->fds[i].fd<0) continue; if(raopld->fds[i].flags&RAOP_FD_READ) FD_SET(raopld->fds[i].fd, &rdfds); if(raopld->fds[i].flags&RAOP_FD_WRITE) FD_SET(raopld->fds[i].fd, &wrfds); fdmax=(fdmax<raopld->fds[i].fd)?raopld->fds[i].fd:fdmax; } if(raopcl_wait_songdone(raopld->raopcl,0)) raopcl_aexbuf_time(raopld->raopcl, &tout); select(fdmax+1,&rdfds,&wrfds,NULL,&tout); for(i=0;i<MAX_NUM_OF_FDS;i++){ if(raopld->fds[i].fd<0) continue; if((raopld->fds[i].flags&RAOP_FD_READ) && FD_ISSET(raopld->fds[i].fd,&rdfds)){ //DBGMSG("rd event i=%d, flags=%d\n",i,raopld->fds[i].flags); if(raopld->fds[i].cbf && raopld->fds[i].cbf(raopld->fds[i].dp, RAOP_FD_READ)) return -1; } if((raopld->fds[i].flags&RAOP_FD_WRITE) && FD_ISSET(raopld->fds[i].fd,&wrfds)){ //DBGMSG("wr event i=%d, flags=%d\n",i,raopld->fds[i].flags); if(raopld->fds[i].cbf && raopld->fds[i].cbf(raopld->fds[i].dp, RAOP_FD_WRITE)) return -1; } } if(raopcl_wait_songdone(raopld->raopcl,0)){ raopcl_aexbuf_time(raopld->raopcl, &tout); if(!tout.tv_sec && !tout.tv_usec){ // AEX data buffer becomes empty, it means end of playing a song. printf("%s\n",RAOP_SONGDONE); fflush(stdout); raopcl_wait_songdone(raopld->raopcl,-1); // clear wait_songdone } } raopcl_pause_check(raopld->raopcl); return 0; } static int console_command(char *cstr) { int i; char *ps=NULL; if(strstr(cstr,"play")==cstr){ if(raopcl_get_pause(raopld->raopcl)) { raopcl_set_pause(raopld->raopcl,NO_PAUSE); return 0; } for(i=0;i<strlen(cstr);i++) { if(cstr[i]==' ') { ps=cstr+i+1; break; } } if(!ps) return 0; // if there is a new song name, open the song if(!(raopld->auds=auds_open(ps, 0))){ printf("%s\n",RAOP_ERROR); fflush(stdout); return -1; } raopcl_flush_stream(raopld->raopcl); return 0; }else if(!strcmp(cstr,"pause")){ if(raopcl_wait_songdone(raopld->raopcl,0)){ INFMSG("in this period, pause can't work\n"); return -2; } if(raopld->auds) { raopcl_set_pause(raopld->raopcl,OP_PAUSE); } }else if(!strcmp(cstr,"stop")){ if(raopcl_get_pause(raopld->raopcl)) raopcl_set_pause(raopld->raopcl,NO_PAUSE); if(raopld->auds) auds_close(raopld->auds); raopld->auds=NULL; }else if(!strcmp(cstr,"quit")){ return -2; }else if((ps=strstr(cstr,"volume"))){ i=atoi(ps+7); return raopcl_update_volume(raopld->raopcl,i); } return -1; }
int main(int argc, char *argv[]) { char *host=NULL; char *fname=NULL; int port=SERVER_PORT; int rval=-1,i; int size; int volume=100; int encrypt=1; int udp=0; __u8 *buf; int iact=0; struct sigaction act; /* Assign sig_term as our SIGTERM handler */ act.sa_sigaction = sig_action; sigemptyset(&act.sa_mask); // no other signals are blocked act.sa_flags = SA_SIGINFO; // use sa_sigaction instead of sa_handler sigaction(SIGTERM, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGCHLD, &act, NULL); for(i=1;i<argc;i++){ if(!strcmp(argv[i],"-i")){ iact=1; continue; } if(!strcmp(argv[i],"--port")){ port=atoi(argv[++i]); continue; } if(!strcmp(argv[i],"--vol")){ volume=atoi(argv[++i]); continue; } if(!strcmp(argv[i],"-e")){ encrypt=0; continue; } if(!strcmp(argv[i],"--proto")){ udp=!strcmp(argv[++i],"udp"); continue; } if(!strcmp(argv[i],"--help") || !strcmp(argv[i],"-h")) return print_usage(argv); if(!host) {host=argv[i]; continue;} if(!fname) {fname=argv[i]; continue;} INFMSG("raop device %s\n",host); INFMSG("raop stream %s\n",fname); } if(!host) return print_usage(argv); if(!iact && !fname) return print_usage(argv); raopld=(raopld_t*)malloc(sizeof(raopld_t)); if(!raopld) goto erexit; memset(raopld,0,sizeof(raopld_t)); for(i=0;i<MAX_NUM_OF_FDS;i++) raopld->fds[i].fd=-1; raopld->raopcl=raopcl_open(); if(!raopld->raopcl) goto erexit; if(raopcl_connect(raopld->raopcl,host,port,encrypt,udp)) goto erexit; if(raopcl_update_volume(raopld->raopcl,volume)) goto erexit; if (udp) if(raopcl_set_content(raopld->raopcl, "ROAP PLAY", "Via Waveplay", "")) goto erexit; DBGMSG("Connected to Airplay device\n"); if(fname && !(raopld->auds=auds_open(fname,0))) goto erexit; set_fd_event(0,RAOP_FD_READ,console_read,NULL); rval=0; while(!rval && isActivated(host)==1){ if(!raopld->auds){ // if audio data is not opened, just check events rval=main_event_handler(raopld); continue; } switch(raopcl_get_pause(raopld->raopcl)){ case OP_PAUSE: rval=main_event_handler(); continue; case NODATA_PAUSE: if(auds_poll_next_sample(raopld->auds)){ raopcl_set_pause(raopld->raopcl,NO_PAUSE); }else{ rval=main_event_handler(); continue; } case NO_PAUSE: if(!auds_poll_next_sample(raopld->auds)){ // no next data, turn into pause status raopcl_set_pause(raopld->raopcl,NODATA_PAUSE); continue; } if(auds_get_next_sample(raopld->auds, &buf, &size)){ auds_close(raopld->auds); raopld->auds=NULL; raopcl_wait_songdone(raopld->raopcl,1); } if(raopcl_send_sample(raopld->raopcl,buf,size)) break; do{ if((rval=main_event_handler())) break; }while(raopld->auds && raopcl_sample_remsize(raopld->raopcl)); break; default: rval=-1; break; } } rval=raopcl_close(raopld->raopcl); erexit: if(raopld->auds) auds_close(raopld->auds); if(raopld) free(raopld); DBGMSG("Stop streaming. %s Active:%i",host,isActivated(host)); return rval; }