mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	Wrap the io_callback to ensure that all data is written before asking for more.
Fix the length type for send_sample (restrict to 16bit value) git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/coling@2374 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
		
							parent
							
								
									6510d97315
								
							
						
					
					
						commit
						e596f42f39
					
				
					 2 changed files with 62 additions and 22 deletions
				
			
		| 
						 | 
					@ -93,6 +93,8 @@ struct pa_raop_client {
 | 
				
			||||||
    void* userdata;
 | 
					    void* userdata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint8_t *buffer;
 | 
					    uint8_t *buffer;
 | 
				
			||||||
 | 
					    uint8_t *buffer_index;
 | 
				
			||||||
 | 
					    uint16_t buffer_count;
 | 
				
			||||||
    /*pa_memchunk memchunk;*/
 | 
					    /*pa_memchunk memchunk;*/
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -205,22 +207,51 @@ void pa_raop_client_free(pa_raop_client* c)
 | 
				
			||||||
    pa_xfree(c);
 | 
					    pa_xfree(c);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int remove_char_from_string(char *str, char rc)
 | 
					static inline void rtrimchar(char *str, char rc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int i=0, j=0, len;
 | 
					    char *sp = str + strlen(str) - 1;
 | 
				
			||||||
  int num = 0;
 | 
					    while (sp >= str && *sp == rc) {
 | 
				
			||||||
  len = strlen(str);
 | 
					        *sp = '\0';
 | 
				
			||||||
  while (i<len) {
 | 
					        sp -= 1;
 | 
				
			||||||
      if (str[i] == rc) {
 | 
					    }
 | 
				
			||||||
          for (j=i; j<len; j++)
 | 
					}
 | 
				
			||||||
              str[j] = str[j+1];
 | 
					
 | 
				
			||||||
          len--;
 | 
					static int pa_raop_client_process(pa_raop_client* c)
 | 
				
			||||||
          num++;
 | 
					{
 | 
				
			||||||
      } else {
 | 
					    ssize_t l;
 | 
				
			||||||
          i++;
 | 
					
 | 
				
			||||||
      }
 | 
					    pa_assert(c);
 | 
				
			||||||
  }
 | 
					
 | 
				
			||||||
  return num;
 | 
					    if (!c->buffer_index || !c->buffer_count)
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!pa_iochannel_is_writable(c->io))
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    l = pa_iochannel_write(c->io, c->buffer_index, c->buffer_count);
 | 
				
			||||||
 | 
					    /*pa_log_debug("Wrote %d bytes (from buffer)", (int)l);*/
 | 
				
			||||||
 | 
					    if (l == c->buffer_count) {
 | 
				
			||||||
 | 
					        c->buffer_index = NULL;
 | 
				
			||||||
 | 
					        c->buffer_count = 0;
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    c->buffer_index += l;
 | 
				
			||||||
 | 
					    c->buffer_count -= l;
 | 
				
			||||||
 | 
					    /*pa_log_debug("Sill have %d bytes (in buffer)", c->buffer_count);*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void *userdata)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    pa_raop_client *c = userdata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_assert(c);
 | 
				
			||||||
 | 
					    pa_assert(c->io == io);
 | 
				
			||||||
 | 
					    pa_assert(c->callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pa_raop_client_process(c)) {
 | 
				
			||||||
 | 
					        c->callback(c->io, c->userdata);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata) {
 | 
					static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata) {
 | 
				
			||||||
| 
						 | 
					@ -239,7 +270,7 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    pa_assert(!c->io);
 | 
					    pa_assert(!c->io);
 | 
				
			||||||
    c->io = io;
 | 
					    c->io = io;
 | 
				
			||||||
    pa_iochannel_set_callback(c->io, c->callback, c->userdata);
 | 
					    pa_iochannel_set_callback(c->io, io_callback, c);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void rtsp_cb(pa_rtsp_context *rtsp, pa_rtsp_state state, pa_headerlist* headers, void *userdata)
 | 
					static void rtsp_cb(pa_rtsp_context *rtsp, pa_rtsp_state state, pa_headerlist* headers, void *userdata)
 | 
				
			||||||
| 
						 | 
					@ -268,13 +299,13 @@ static void rtsp_cb(pa_rtsp_context *rtsp, pa_rtsp_state state, pa_headerlist* h
 | 
				
			||||||
            /* Now encrypt our aes_public key to send to the device */
 | 
					            /* Now encrypt our aes_public key to send to the device */
 | 
				
			||||||
            i = rsa_encrypt(c->aes_key, AES_CHUNKSIZE, rsakey);
 | 
					            i = rsa_encrypt(c->aes_key, AES_CHUNKSIZE, rsakey);
 | 
				
			||||||
            pa_base64_encode(rsakey, i, &key);
 | 
					            pa_base64_encode(rsakey, i, &key);
 | 
				
			||||||
            remove_char_from_string(key, '=');
 | 
					            rtrimchar(key, '=');
 | 
				
			||||||
            pa_base64_encode(c->aes_iv, AES_CHUNKSIZE, &iv);
 | 
					            pa_base64_encode(c->aes_iv, AES_CHUNKSIZE, &iv);
 | 
				
			||||||
            remove_char_from_string(iv, '=');
 | 
					            rtrimchar(iv, '=');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            pa_random(&rand_data, sizeof(rand_data));
 | 
					            pa_random(&rand_data, sizeof(rand_data));
 | 
				
			||||||
            pa_base64_encode(&rand_data, AES_CHUNKSIZE, &sac);
 | 
					            pa_base64_encode(&rand_data, AES_CHUNKSIZE, &sac);
 | 
				
			||||||
            remove_char_from_string(sac, '=');
 | 
					            rtrimchar(sac, '=');
 | 
				
			||||||
            pa_rtsp_add_header(c->rtsp, "Apple-Challenge", sac);
 | 
					            pa_rtsp_add_header(c->rtsp, "Apple-Challenge", sac);
 | 
				
			||||||
            sdp = pa_sprintf_malloc(
 | 
					            sdp = pa_sprintf_malloc(
 | 
				
			||||||
                "v=0\r\n"
 | 
					                "v=0\r\n"
 | 
				
			||||||
| 
						 | 
					@ -388,7 +419,7 @@ void pa_raop_client_disconnect(pa_raop_client* c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_raop_client_send_sample(pa_raop_client* c, const uint8_t* buffer, unsigned int count)
 | 
					void pa_raop_client_send_sample(pa_raop_client* c, const uint8_t* buffer, uint16_t count)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ssize_t l;
 | 
					    ssize_t l;
 | 
				
			||||||
    uint16_t len;
 | 
					    uint16_t len;
 | 
				
			||||||
| 
						 | 
					@ -406,7 +437,7 @@ void pa_raop_client_send_sample(pa_raop_client* c, const uint8_t* buffer, unsign
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c->buffer = pa_xrealloc(c->buffer, (count + header_size + 16));
 | 
					    c->buffer = pa_xrealloc(c->buffer, (count + header_size + 16));
 | 
				
			||||||
    memcpy(c->buffer, header, header_size);
 | 
					    memcpy(c->buffer, header, header_size);
 | 
				
			||||||
    len = count + header_size - 4;
 | 
					    len = header_size + count - 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* store the lenght (endian swapped: make this better) */
 | 
					    /* store the lenght (endian swapped: make this better) */
 | 
				
			||||||
    *(c->buffer + 2) = len >> 8;
 | 
					    *(c->buffer + 2) = len >> 8;
 | 
				
			||||||
| 
						 | 
					@ -417,9 +448,18 @@ void pa_raop_client_send_sample(pa_raop_client* c, const uint8_t* buffer, unsign
 | 
				
			||||||
    len = header_size + count;
 | 
					    len = header_size + count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* TODO: move this into a memchunk/memblock and write only in callback */
 | 
					    /* TODO: move this into a memchunk/memblock and write only in callback */
 | 
				
			||||||
 | 
					    /*pa_log_debug("Channel status: %d", pa_iochannel_is_writable(c->io));
 | 
				
			||||||
 | 
					    pa_log_debug("Writing %d bytes", len);*/
 | 
				
			||||||
    l = pa_iochannel_write(c->io, c->buffer, len);
 | 
					    l = pa_iochannel_write(c->io, c->buffer, len);
 | 
				
			||||||
 | 
					    /*pa_log_debug("Wrote %d bytes", (int)l);*/
 | 
				
			||||||
 | 
					    if (l != len) {
 | 
				
			||||||
 | 
					        c->buffer_index = c->buffer + l;
 | 
				
			||||||
 | 
					        c->buffer_count = len - l;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /*pa_log_debug("Sill have %d bytes (in buffer)", c->buffer_count);*/
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_raop_client_set_callback(pa_raop_client* c, pa_iochannel_cb_t callback, void *userdata)
 | 
					void pa_raop_client_set_callback(pa_raop_client* c, pa_iochannel_cb_t callback, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    pa_assert(c);
 | 
					    pa_assert(c);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,7 @@ int pa_raop_client_connect(pa_raop_client* c, pa_mainloop_api *mainloop, const c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_raop_client_disconnect(pa_raop_client* c);
 | 
					void pa_raop_client_disconnect(pa_raop_client* c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_raop_client_send_sample(pa_raop_client* c, const uint8_t* buffer, unsigned int count);
 | 
					void pa_raop_client_send_sample(pa_raop_client* c, const uint8_t* buffer, uint16_t count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_raop_client_set_callback(pa_raop_client* c, pa_iochannel_cb_t callback, void *userdata);
 | 
					void pa_raop_client_set_callback(pa_raop_client* c, pa_iochannel_cb_t callback, void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue