Ejemplo n.º 1
0
bool
rtspcl_setup(struct rtspcl_data *rtspcld, struct key_data **kd,
	     int control_port, int ntp_port,
	     GError **error_r)
{
	struct key_data *rkd = NULL, hds;
	const char delimiters[] = ";";
	char *buf = NULL;
	char *token, *pc;
	int rval = false;

	static char transport_key[] = "Transport";

	char transport_value[256];
	snprintf(transport_value, sizeof(transport_value),
		 "RTP/AVP/UDP;unicast;interleaved=0-1;mode=record;control_port=%d;timing_port=%d",
		 control_port, ntp_port);

	hds.key = transport_key;
	hds.data = transport_value;
	hds.next = NULL;
	if (!exec_request(rtspcld, "SETUP", NULL, NULL, 1,
			  &hds, &rkd, error_r))
		return false;

	if (!(rtspcld->session = g_strdup(kd_lookup(rkd, "Session")))) {
		g_set_error_literal(error_r, rtsp_client_quark(), 0,
				    "no session in response");
		goto erexit;
	}
	if (!(rtspcld->transport = kd_lookup(rkd, "Transport"))) {
		g_set_error_literal(error_r, rtsp_client_quark(), 0,
				    "no transport in response");
		goto erexit;
	}
	buf = g_strdup(rtspcld->transport);
	token = strtok(buf, delimiters);
	rtspcld->server_port = 0;
	rtspcld->control_port = 0;
	while (token) {
		if ((pc = strstr(token, "="))) {
			*pc = 0;
			if (!strcmp(token,"server_port")) {
				rtspcld->server_port=atoi(pc + 1);
			}
			if (!strcmp(token,"control_port")) {
				rtspcld->control_port=atoi(pc + 1);
			}
		}
		token = strtok(NULL, delimiters);
	}
	if (rtspcld->server_port == 0) {
		g_set_error_literal(error_r, rtsp_client_quark(), 0,
				    "no server_port in response");
		goto erexit;
	}
	if (rtspcld->control_port == 0) {
		g_set_error_literal(error_r, rtsp_client_quark(), 0,
				    "no control_port in response");
		goto erexit;
	}
	rval = true;
 erexit:
	g_free(buf);

	if (!rval || kd == NULL) {
		free_kd(rkd);
		rkd = NULL;
	}

	if (kd != NULL)
		*kd = rkd;

	return rval;
}
Ejemplo n.º 2
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;
	
	
}
Ejemplo n.º 3
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;
}