Example #1
0
int rtspcl_add_exthds(rtspcl_t *p, char *key, char *data)
{
    int i=0;
    rtspcl_data_t *rtspcld;
    
    if(!p) return -1;
    rtspcld=(rtspcl_data_t *)p;
    if(!rtspcld->exthds){
        if(realloc_memory((void*)&rtspcld->exthds, 17*sizeof(key_data_t),__func__)) return -1;
    }else{
        i=0;
        while(rtspcld->exthds[i].key) {
            if(rtspcld->exthds[i].key[0]==0xff) break;
            i++;
        }
        if(i && i%16==0 && rtspcld->exthds[i].key[0]!=0xff){
            if(realloc_memory((void*)&rtspcld->exthds,(16*((i%16)+1)+1)*sizeof(key_data_t),__func__))
                return -1;
            memset(rtspcld->exthds+16*(i/16),0,17*sizeof(key_data_t));
        }
    }
    if(realloc_memory((void*)&rtspcld->exthds[i].key,strlen(key),__func__)) return -1;
    strcpy((char*)rtspcld->exthds[i].key,key);
    if(realloc_memory((void*)&rtspcld->exthds[i].data,strlen(data),__func__)) return -1;
    strcpy((char*)rtspcld->exthds[i].data,data);
    rtspcld->exthds[i+1].key=NULL;
    return 0;
}
Example #2
0
int raopcl_send_sample(raopcl_t *p, u_int8_t *sample, int count )
{
	int rval=-1;
	u_int16_t len;
        u_int8_t header[] = {
		0x24, 0x00, 0x00, 0x00,
		0xF0, 0xFF, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00,
        };
	const int header_size=sizeof(header);
	raopcl_data_t *raopcld;
	if(!p) return -1;

	raopcld=(raopcl_data_t *)p;
	if(realloc_memory((void**)&raopcld->data, count+header_size+16, __func__)) goto erexit;
	memcpy(raopcld->data,header,header_size);
	len=count+header_size-4;
	raopcld->data[2]=len>>8;
	raopcld->data[3]=len&0xff;
	memcpy(raopcld->data+header_size,sample,count);
	raop_encrypt(raopcld, raopcld->data+header_size, count);
	len=count+header_size;
	raopcld->wblk_remsize=count+header_size;
	raopcld->wblk_wsize=0;
	if(set_fd_event(raopcld->sfd, RAOP_FD_READ|RAOP_FD_WRITE, fd_event_callback,(void*)raopcld)) goto erexit;
	rval=0;
 erexit:
	return rval;
}
Example #3
0
 /**
  * @brief This constructor sets up a basic cleared table of 
  * width/height.
  *
  * @param width [in];  The table width.
  * @param height [in];  The table height.
  */
 CompactCacheTable (int width, int height)
 {
     _width = 0; _height = 0; _data = NULL;
     _minx = 0; _miny = 0;
     _maxx = 0; _maxy = 0;
     realloc_memory(width, height);
 };
Example #4
0
 /**
  * @brief This constructor sets up a basic cleared table of 
  * specified x and y bounds.
  *
  * @param minx [in]; The lower x bound.
  * @param miny [in]; The lower y bound.
  * @param maxx [in]; The upper x bound.
  * @param maxy [in]; The upper y bound.
  */
 CompactCacheTable (int minx, int miny, int maxx, int maxy)
 {
     _width = 0; _height = 0;
     _minx = 0; _miny = 0;
     _maxx = 0; _maxy = 0;
     _data = NULL;
     realloc_memory(minx, miny, maxx, maxy);
 };
Example #5
0
int raopcl_connect(raopcl_t *p, char *host,u_int16_t destport)
{
	u_int8_t buf[4+8+16];
	char sid[16];
	char sci[24];
	char *sac=NULL,*key=NULL,*iv=NULL;
	char sdp[1024];
	int rval=-1;
	key_data_t *setup_kd=NULL;
	char *aj, *token, *pc;
	const char delimiters[] = ";";
	u_int8_t rsakey[512];
	int i;
	raopcl_data_t *raopcld;
	if(!p) return -1;

	raopcld=(raopcl_data_t *)p;
	RAND_bytes(buf, sizeof(buf));
	sprintf(sid, "%d", *((u_int32_t*)buf));
	sprintf(sci, "%08x%08x",*((u_int32_t*)(buf+4)),*((u_int32_t*)(buf+8)));
	base64_encode(buf+12,16,&sac);
	if(!(raopcld->rtspcl=rtspcl_open())) goto erexit;
	if(rtspcl_set_useragent(raopcld->rtspcl,"iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)")) goto erexit;
	if(rtspcl_add_exthds(raopcld->rtspcl,"Client-Instance", sci)) goto erexit;
	if(rtspcl_connect(raopcld->rtspcl, host, destport, sid)) goto erexit;

	i=rsa_encrypt(raopcld->key,16,rsakey);
	base64_encode(rsakey,i,&key);
	remove_char_from_string(key,'=');
	base64_encode(raopcld->iv,16,&iv);
	remove_char_from_string(iv,'=');
	sprintf(sdp,
            "v=0\r\n"
            "o=iTunes %s 0 IN IP4 %s\r\n"
            "s=iTunes\r\n"
            "c=IN IP4 %s\r\n"
            "t=0 0\r\n"
            "m=audio 0 RTP/AVP 96\r\n"
            "a=rtpmap:96 AppleLossless\r\n"
            "a=fmtp:96 4096 0 16 40 10 14 2 255 0 0 44100\r\n"
            "a=rsaaeskey:%s\r\n"
            "a=aesiv:%s\r\n",
            sid, rtspcl_local_ip(raopcld->rtspcl), host, key, iv);
	remove_char_from_string(sac,'=');
	if(rtspcl_add_exthds(raopcld->rtspcl, "Apple-Challenge", sac)) goto erexit;
	if(rtspcl_annouce_sdp(raopcld->rtspcl, sdp)) goto erexit;
	if(rtspcl_mark_del_exthds(raopcld->rtspcl, "Apple-Challenge")) goto erexit;
	if(rtspcl_setup(raopcld->rtspcl, &setup_kd)) goto erexit;
	if(!(aj=kd_lookup(setup_kd,"Audio-Jack-Status"))) {
		ERRMSG("%s: Audio-Jack-Status is missing\n",__func__);
		goto erexit;
	}
	
	token=strtok(aj,delimiters);
	while(token){
		if((pc=strstr(token,"="))){
			*pc=0;
			if(!strcmp(token,"type") && !strcmp(pc+1,"digital")){
				raopcld->ajtype=JACK_TYPE_DIGITAL;
			}
		}else{
			if(!strcmp(token,"connected")){
				raopcld->ajstatus=JACK_STATUS_CONNECTED;
			}
		}
		token=strtok(NULL,delimiters);
	}

	if(rtspcl_record(raopcld->rtspcl)) goto erexit;

	// keep host address and port information
	if(realloc_memory((void**)&raopcld->addr,strlen(host)+1,__func__)) goto erexit;
	strcpy(raopcld->addr,host);
	raopcld->rtsp_port=destport;

	if(raopcl_stream_connect(raopcld)) goto erexit;
	
	rval=0;
 erexit:
	if(sac) free(sac);
	if(key) free(key);
	if(iv) free(iv);
	free_kd(setup_kd);
	return rval;
	
	
}
Example #6
0
/*
 * send RTSP request, and get responce if it's needed
 * if this gets a success, *kd is allocated or reallocated (if *kd is not NULL)
 */
static int exec_request(rtspcl_data_t *rtspcld, char *cmd, char *content_type,
                char *content, int length, int get_response, key_data_t *hds, key_data_t **kd, char* url)
{
    char line[2048];
    char req[1024];
    char reql[128];
    const char delimiters[] = " ";
    char *token,*dp;
    int i,j,dsize,rval,totallength;
    int timeout=5000; // msec unit

    if(!rtspcld) return -1;

    if(url==NULL)
    {
        sprintf(req, "%s %s RTSP/1.0\r\n",cmd,rtspcld->url);
    }
    else
    {
        sprintf(req, "%s %s RTSP/1.0\r\n",cmd,url);
    }
    i=0;
    while( hds && hds[i].key != NULL )
    {
        sprintf(reql,"%s: %s\r\n", hds[i].key, hds[i].data);
        strncat(req,reql,sizeof(req));
        i++;
    }

    if( content_type && content) 
    {
        if(!length)
        {
            sprintf(reql, "Content-Type: %s\r\nContent-Length: %d\r\n",
            content_type, (int)strlen(content));
        }
        else
        {
            sprintf(reql, "Content-Type: %s\r\nContent-Length: %d\r\n",
            content_type, length);
        }
        strncat(req,reql,sizeof(req));
    }
    
    sprintf(reql,"CSeq: %d\r\n",++rtspcld->cseq);
    strncat(req,reql,sizeof(req));
    
    sprintf(reql, "User-Agent: %s\r\n", rtspcld->useragent );
    strncat(req,reql,sizeof(req));

    i=0;
    while(rtspcld->exthds && rtspcld->exthds[i].key)
    {
        if(rtspcld->exthds[i].key[0]==0xff) {i++;continue;}
        sprintf(reql,"%s: %s\r\n", rtspcld->exthds[i].key, rtspcld->exthds[i].data);
        strncat(req,reql,sizeof(req));
        i++;
    }
    
    if( rtspcld->session != NULL )
    {
        sprintf(reql,"Session: %s\r\n",rtspcld->session);
        strncat(req,reql,sizeof(req));
    }
    
    strncat(req,"\r\n",sizeof(req));

    if( content_type && content)
    {
        if(!length)
        {
            strncat(req,content,sizeof(req));
        }
        else
        {
            totallength = strlen(req) + length;
            memcpy(req+strlen(req),content,length);
        }
    }

    if(!length)
    {
        rval=write(rtspcld->fd,req,strlen(req));
        DBGMSG("----> %s : write %s\n",__func__, req);
        if ( rval != strlen(req) )
        {
           ERRMSG("couldn't write request (%d!=%d)\n",(int)rval,(int)strlen(req));
        }
    }
    else
    {
        rval=write(rtspcld->fd,req,totallength);
        DBGMSG("----> %s : write %s\n",__func__,req);
        if ( rval != totallength )
        {
           ERRMSG("couldn't write request (%d!=%d)\n",rval,totallength);
        }
    }

    if( !get_response ) return 0;
    
    if(read_line(rtspcld->fd,line,sizeof(line),timeout,0)<=0)    
    {
        if(get_response==1)
        {
            ERRMSG("%s: response : %s request failed\n",__func__, line);
            return -1;
        }
        else
        {
            return 0;
        }
    }

    token = strtok(line, delimiters);
    token = strtok(NULL, delimiters);
    if(token==NULL || strcmp(token,"200"))
    {
        if(get_response==1)
        {
            ERRMSG("<------ : %s: request failed, error %s\n",__func__,line);
            return -1;
        }
    }
    else
    {
        DBGMSG("<------ : %s: request ok (%s)\n",__func__,token);
    }

    i=0;
    while(read_line(rtspcld->fd,line,sizeof(line),timeout,0)>0){
        DBGMSG("<------ : %s\n",line);
        timeout=1000; // once it started, it shouldn't take a long time
        if(i%16==0){
            if(realloc_memory((void*)kd,(16*(i/16+1)+1)*sizeof(key_data_t),__func__)) return -1;
            memset(*kd+16*(i/16),0,17*sizeof(key_data_t));
        }

        if(i && line[0]==' '){
            for(j=0;j<strlen(line);j++) if(line[j]!=' ') break;
            dsize+=strlen(line+j);
            if(realloc_memory((void*)&(*kd)[i].data,dsize,__func__)) return -1;
            strcat((char*)(*kd)[i].data,line+j);
            continue;
        }

        dp=strstr(line,":");

        if(!dp){
            ERRMSG("%s: Request failed, bad header\n",__func__);
            free_kd(*kd);
            *kd=NULL;
            return -1;
        }

        *dp=0;
        if(realloc_memory((void*)&(*kd)[i].key,strlen(line)+1,__func__)) return -1;
        strcpy((char*)(*kd)[i].key,line);
        dsize=strlen(dp+1)+1;
        if(realloc_memory((void*)&(*kd)[i].data,dsize,__func__)) return -1;
        strcpy((char*)(*kd)[i].data,dp+1);
        i++;

        if ( strcmp( line, "Audio-Latency" ) == 0 )
        {
           alatency=atoi( dp+2 );
           DBGMSG( "saving latency : %d\n", alatency );
        }
    }
    while(read_line(rtspcld->fd,line,sizeof(line),timeout,0)>0)
    {
        //read body
        DBGMSG("<------ : %s\n",line);
    }
    (*kd)[i].key=NULL;
    return 0;
}
Example #7
0
int rtspcl_setup(rtspcl_t *p, key_data_t **kd)
{
    key_data_t *rkd=NULL;
    key_data_t hds[2];
    const char delimiters[] = ";";
    char *buf=NULL;
    char *token,*pc;
    char *temp;
    int rval=-1;
    rtspcl_data_t *rtspcld;

    if(!p) return -1;
    rtspcld=(rtspcl_data_t *)p;
    hds[0].key=(uint8_t*)"Transport";
    hds[0].data=(uint8_t*)"RTP/AVP/UDP;unicast;interleaved=0-1;mode=record;control_port=6001;timing_port=6002";
    hds[1].key=NULL;
    if(exec_request(rtspcld, "SETUP", NULL, NULL, 0, 1, hds, &rkd, NULL)) return -1;
    if(!(temp=kd_lookup(rkd, "Session"))){
        ERRMSG("%s: no session in response\n",__func__);
        goto erexit;
    }
    DBGMSG("<------- : %s: session:%s\n",__func__,temp);
    rtspcld->session = (char *) malloc(100);
    sprintf( rtspcld->session, "%s", trim(temp) );
    if(!(rtspcld->transport=kd_lookup(rkd, "Transport"))){
        ERRMSG("%s: no transport in responce\n",__func__);
        goto erexit;
    }
    if(realloc_memory((void*)&buf,strlen(rtspcld->transport)+1,__func__)) goto erexit;
    strcpy(buf,rtspcld->transport);
    token=strtok(buf,delimiters);
    rtspcld->server_port=0;
    while(token)
    {
        if((pc=strstr(token,"=")))
        {
            *pc=0;
            if(!strcmp(token,"server_port"))
            {
                rtspcld->server_port=atoi(pc+1);
                DBGMSG( "got server port : %d\n", rtspcld->server_port );
            }
            if(!strcmp(token,"control_port"))
            {
                rtspcld->control_port=atoi(pc+1);
                DBGMSG( "got control port : %d\n", rtspcld->control_port );
            }
            if(!strcmp(token,"timing_port"))
            {
                rtspcld->timing_port=atoi(pc+1);
                DBGMSG( "got timing port : %d\n", rtspcld->timing_port );
            }
        }
        token=strtok(NULL,delimiters);
    }
    if(rtspcld->server_port==0){
        ERRMSG("%s: no server_port in response\n",__func__);
        goto erexit;
    }
    rval=0;
 erexit:
    if(buf) free(buf);
    if(rval) {
        free_kd(rkd);
        rkd=NULL;
    }
    *kd=rkd;
    return rval;
}