📄 rtsp_resp.c
字号:
ADV_SPACE(after); /* * Call the correct parsing routine */ (header_types[ix].parse_routine)(after, info->decode_response, 0); *last_number = ix; return; } } ix++; } if (last_number >= 0 && isspace(*lptr)) { //asdf ADV_SPACE(lptr); (header_types[*last_number].parse_routine)(lptr, info->decode_response, 1); } else rtsp_debug(LOG_DEBUG, "Not processing response header: %s", lptr);}static int rtsp_read_into_buffer (rtsp_client_t *cptr, uint32_t buffer_offset, int wait){ int ret; ret = rtsp_receive_socket(cptr, cptr->m_resp_buffer + buffer_offset, RECV_BUFF_DEFAULT_LEN - buffer_offset, cptr->recv_timeout, wait); if (ret <= 0) return (ret); cptr->m_buffer_len = buffer_offset + ret; cptr->m_resp_buffer[cptr->m_buffer_len] = '\0'; return ret;}int rtsp_bytes_in_buffer (rtsp_client_t *cptr){ return (cptr->m_buffer_len - cptr->m_offset_on);}int rtsp_recv (rtsp_client_t *cptr, char *buffer, uint32_t len){ uint32_t mlen; int copied, result; copied = 0; if (cptr->m_offset_on < cptr->m_buffer_len) { mlen = MIN(len, cptr->m_buffer_len - cptr->m_offset_on); memmove(buffer, &cptr->m_resp_buffer[cptr->m_offset_on], mlen); cptr->m_offset_on += mlen; len -= mlen; copied += mlen; } if (len > 0) { result = rtsp_receive_socket(cptr, buffer + copied, len, 0, 0); if (result >= 0) { copied += result; } } return copied;} static int rtsp_save_and_read (rtsp_client_t *cptr){ int last_on; int ret; cptr->m_buffer_len -= cptr->m_offset_on; if (cptr->m_buffer_len >= RECV_BUFF_DEFAULT_LEN) { return 0; } else if (cptr->m_buffer_len != 0) { memmove(cptr->m_resp_buffer, &cptr->m_resp_buffer[cptr->m_offset_on], cptr->m_buffer_len); last_on = cptr->m_buffer_len; } else { last_on = 0; } cptr->m_offset_on = 0; ret = rtsp_read_into_buffer(cptr, cptr->m_buffer_len, 0); if (ret > 0) { last_on += ret; } return (last_on);}static const char *rtsp_get_next_line (rtsp_client_t *cptr, const char *seperator){ int ret; int last_on; char *sep; /* * If we don't have any data, try to read a buffer full */ if (cptr->m_buffer_len <= 0) { cptr->m_offset_on = 0; ret = rtsp_read_into_buffer(cptr, 0, 1); if (ret <= 0) { return (NULL); } } /* * Look for CR/LF in the buffer. If we find it, NULL terminate at * the CR, then set the buffer values to look past the crlf */ sep = strstr(&cptr->m_resp_buffer[cptr->m_offset_on], seperator); if (sep != NULL) { const char *retval = &cptr->m_resp_buffer[cptr->m_offset_on]; cptr->m_offset_on = sep - cptr->m_resp_buffer; cptr->m_offset_on += strlen(seperator); *sep = '\0'; return (retval); } if (cptr->m_offset_on == 0) { return (NULL); } /* * We don't have a line. So, move the data down in the buffer, then * read into the rest of the buffer */ last_on = rtsp_save_and_read(cptr); if (last_on < 0) return (NULL); /* * Continue searching through the buffer. If we get this far, we've * received like 2K or 4K without a CRLF - most likely a bad response */ sep = strstr(&cptr->m_resp_buffer[last_on], seperator); if (sep != NULL) { const char *retval = &cptr->m_resp_buffer[cptr->m_offset_on]; cptr->m_offset_on = sep - cptr->m_resp_buffer; cptr->m_offset_on += strlen(seperator); *sep = '\0'; return (retval); } return (NULL);}/* * rtsp_parse_response - parse out response headers lines. Figure out * where seperators are, then use them to determine where the body is */static int rtsp_parse_response (rtsp_client_t *info){ const char *seperator; const char *lptr, *p; rtsp_decode_t *decode; int ret, done; int last_header = -1; uint32_t len; decode = info->decode_response; // Figure out what seperator is being used throughout the response ret = rtsp_save_and_read(info); if (ret < 0) { return (RTSP_RESPONSE_RECV_ERROR); } seperator = find_seperator(info->m_resp_buffer); if (seperator == NULL) { rtsp_debug(LOG_INFO, "Could not find seperator in header"); return RTSP_RESPONSE_MALFORM_HEADER; } //rtsp_debug(LOG_DEBUG, "Response buffer:\n%s", info->m_resp_buffer); do { lptr = rtsp_get_next_line(info, seperator); if (lptr == NULL) { rtsp_debug(LOG_INFO, "Couldn't get next line"); return (RTSP_RESPONSE_MALFORM_HEADER); } } while (*lptr == '\0'); rtsp_debug(LOG_DEBUG, lptr); if (strncasecmp(lptr, "RTSP/1.0", strlen("RTSP/1.0")) != 0) { rtsp_debug(LOG_INFO, "RTSP/1.0 not found"); return RTSP_RESPONSE_MALFORM_HEADER; } p = lptr + strlen("RTSP/1.0"); ADV_SPACE(p); memcpy(decode->retcode, p, 3); decode->retcode[3] = '\0'; switch (*p) { case '1': case '2': case '3': case '4': case '5': break; default: rtsp_debug(LOG_INFO, "Bad error code %s", p); return RTSP_RESPONSE_MALFORM_HEADER; } p += 3; ADV_SPACE(p); if (p != '\0') { decode->retresp = strdup(p); } rtsp_debug(LOG_DEBUG, "Decoded status - code %s %s", decode->retcode, decode->retresp); done = 0; do { lptr = rtsp_get_next_line(info, seperator); if (lptr == NULL) { return (RTSP_RESPONSE_MALFORM_HEADER); } if (*lptr == '\0') { done = 1; } else { rtsp_debug(LOG_DEBUG, lptr); rtsp_decode_header(lptr, info, &last_header); } } while (done == 0); if (decode->content_length != 0) { rtsp_debug(LOG_DEBUG, "reading content length %d", decode->content_length); decode->body = malloc(decode->content_length + 1); decode->body[decode->content_length] = '\0'; len = info->m_buffer_len - info->m_offset_on; rtsp_debug(LOG_DEBUG, "Copied %d bytes from buffer", len); if (len < decode->content_length) { // not enough in memory - need to read memcpy(decode->body, &info->m_resp_buffer[info->m_offset_on], len); while (len < decode->content_length) { int left; ret = rtsp_read_into_buffer(info, 0, 1); if (ret <= 0) { rtsp_debug(LOG_DEBUG, "Returned from rtsp_read_into_buffer - error %d", ret); return (-1); } left = decode->content_length - len; if (left < info->m_buffer_len) { // we have more data in the buffer then we need memcpy(decode->body + len, info->m_resp_buffer, left); len += left; info->m_offset_on = left; } else { // exact or less - we're cool memcpy(decode->body + len, info->m_resp_buffer, info->m_buffer_len); len += info->m_buffer_len; info->m_offset_on = info->m_buffer_len; // get ready for next... } } } else { // Plenty in memory - copy it, continue to end... memcpy(decode->body, &info->m_resp_buffer[info->m_offset_on], decode->content_length); info->m_offset_on += decode->content_length; } } else if (decode->close_connection) { // No termination - just deal with what we've got... len = info->m_buffer_len - info->m_offset_on; decode->body = (char *)malloc(len + 1); memcpy(decode->body, &info->m_resp_buffer[info->m_offset_on], len); decode->body[len] = '\0'; } if (decode->body != NULL) rtsp_debug(LOG_DEBUG, "%s", decode->body); return (0);}/* * rtsp_get_response - wait for a complete response. Interesting that * it could be in multiple packets, so deal with that. */int rtsp_get_response (rtsp_client_t *info){ int ret; rtsp_decode_t *decode; int response_okay; while (1) { // In case we didn't get a response that we wanted. if (info->decode_response != NULL) { clear_decode_response(info->decode_response); decode = info->decode_response; } else { decode = info->decode_response = malloc(sizeof(rtsp_decode_t)); if (decode == NULL) { rtsp_debug(LOG_ALERT, "Couldn't create decode response"); return (RTSP_RESPONSE_RECV_ERROR); } } memset(decode, 0, sizeof(rtsp_decode_t)); do { // Parse response. ret = rtsp_parse_response(info); rtsp_debug(LOG_DEBUG, "parsed response - len %d offset %d", info->m_buffer_len, info->m_offset_on); if (ret != 0) { if (info->thread == NULL) rtsp_close_socket(info); rtsp_debug(LOG_ERR, "return code %d from rtsp_parse_response", ret); return (RTSP_RESPONSE_RECV_ERROR); } if (decode->close_connection) { rtsp_debug(LOG_DEBUG, "Response requested connection close"); rtsp_close_socket(info); } response_okay = TRUE; // Okay - we have a good response. - check the cseq, and return // the correct error code. if (info->next_cseq == decode->cseq) { info->next_cseq++; if ((decode->retcode[0] == '4') || (decode->retcode[0] == '5')) { return (RTSP_RESPONSE_BAD); } if (decode->cookie != NULL) { // move cookie to rtsp_client info->cookie = strdup(decode->cookie); } if (decode->retcode[0] == '2') { return (RTSP_RESPONSE_GOOD); } if (decode->retcode[0] == '3') { if (decode->location == NULL) { return (RTSP_RESPONSE_BAD); } if (rtsp_setup_redirect(info) != 0) { return (RTSP_RESPONSE_BAD); } return (RTSP_RESPONSE_REDIRECT); } } else { rtsp_debug(LOG_ERR, "Incorrect cseq in RTSP message - expected %d got %d", info->next_cseq, decode->cseq); } } while (rtsp_bytes_in_buffer(info) > 0); } return (RTSP_RESPONSE_RECV_ERROR);}/* end file rtsp_resp.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -