📄 rtsp.c
字号:
else { /* too many colons, return */ reason = "too many colons"; npt_acceptable = 0; break; } } else if(tolower(str[i]) == 'h' || tolower(str[i]) == 'm' || tolower(str[i]) == 's' || tolower(str[i]) == 'y'|| tolower(str[i]) == 'd') { if(separated_way == COLON_SEPARATED) { reason = "confusing time separator"; npt_acceptable = 0; break; } separated_way = CHAR_SEPARATED; switch(tolower(str[i])) { case 'y': if(sep_time_filled[YEAR]) { reason = "year already specified"; npt_acceptable = 0; break; } sep_time[YEAR] = value; sep_time_filled[YEAR] = 1; break; case 'd': if(sep_time_filled[DAY]) { reason = "day already specified"; npt_acceptable = 0; break; } sep_time[DAY] = value; sep_time_filled[DAY] = 1; break; case 'h': if(sep_time_filled[HOUR]) { reason = "hour already specified"; npt_acceptable = 0; break; } sep_time[HOUR] = value; sep_time_filled[HOUR] = 1; break; case 'm': if(sep_time_filled[MIN]) { reason = "minute already specified"; npt_acceptable = 0; break; } sep_time[MIN] = value; sep_time_filled[MIN] = 1; break; case 's': if(sep_time_filled[SEC]) { reason = "second already specified"; npt_acceptable = 0; break; } sep_time[SEC] = value; sep_time_filled[SEC] = 1; break; default: break; } value = 0; } else { /* invalid chraracter */ reason = "invalid character"; npt_acceptable = 0; break; } } if(separated_way != CHAR_SEPARATED) { for(j = NUM_COLS - 1; j ; j--) { sep_time[j] = sep_time[j - 1]; /* slide */ } sep_time[0] = value; } else { /* CHAR_SEPARATED */ if(!sep_time_filled[SEC]) { sep_time[0] = value; } else if(value){ /* has some value */ reason = "second already specified"; npt_acceptable = 0; } } if(!npt_acceptable) { if(reason_ret) { *reason_ret = reason; } return NULL; } else { uint64_t sec = 0; npt_time = xmalloc(BUFSIZE_1K + strlen(str_after_dot)); /* hhmmss format */ /* sec = sep_time[SEC] % 60; carry = sep_time[SEC] / 60; min = (sep_time[MIN] + carry) % 60; carry = (sep_time[min] + carry) / 60; hour = (sep_time[YEAR] * 365 + sep_time[DAY]) * 24 + sep_time[HOUR] + carry; snprintf(npt_time,BUFSIZE_1K - 1 + strlen(str_after_dot),"%llu:%d:%d.%s", (long long unsigned int)hour,(int)min,(int)sec,str_after_dot); */ /* sec format */ sec = (((sep_time[YEAR] * 365 + sep_time[DAY]) * 24 + sep_time[HOUR]) * 60 + sep_time[MIN]) * 60 + sep_time[SEC]; snprintf(npt_time,BUFSIZE_1K - 1 + strlen(str_after_dot),"%llu%s", (long long unsigned int)sec,str_after_dot); reason = ""; if(reason_ret) { *reason_ret = reason; } return npt_time; } return NULL;}/* * change dlopts -r option to npt-range string * return value: NULL: str was inacceptable * npt: npt range part (ex. 12.345-67.890) (malloc) */char *rtsp_range_to_npt_range(const char *str,char **reason_ret){ /* npt-range = ( npt-time "-" [ npt-time ] ) | ( "-" npt-time ) npt-time = "now" | npt-sec | npt-hhmmss npt-sec = 1*DIGIT [ "." *DIGIT ] npt-hhmmss = npt-hh ":" npt-mm ":" npt-ss [ "." *DIGIT ] npt-hh = 1*DIGIT ; any positive number npt-mm = 1*2DIGIT ; 0-59 npt-ss = 1*2DIGIT ; 0-59 */ char *npt_range_str = NULL; char *reason = NULL; if(rtsp_npt_range_valid(str,reason_ret)) { /* if str was rfc valid npt range string, return that.*/ npt_range_str = strdup(str); /* to integrate interface, copy it */ reason = ""; if(reason_ret) { *reason_ret = reason; } return npt_range_str; } else { /* not valid, but allocate rfc valid npt string */ char *p = NULL; p = strchr(str,'-'); if(p == NULL) { /* really inacceptable. */ reason = "must use \'-\' to tell range"; if(reason_ret) { *reason_ret = reason; } return NULL; } else if(p == str) { /* "-" npt-time(invalid) */ char *npt_time_str = rtsp_time_to_npt_time(p + 1,reason_ret); if(!npt_time_str) { /* really inacceptable*/ return NULL; } npt_range_str = xmalloc(strlen(npt_time_str) + 2); npt_range_str[0] = '-'; strcpy(npt_range_str + 1,npt_time_str); npt_range_str[strlen(npt_time_str) + 1] = '\0'; free(npt_time_str); return npt_range_str; } else { char *npt_start_time_str = NULL; char *npt_end_time_str = NULL; char *original_start_time_str = NULL; int start_str_len = p - str; if(*(p+1) == '\0') { /* npt-time "-" */ npt_end_time_str = xmalloc(2); npt_end_time_str[0] = '\0'; } else { /* npt-time "-" npt-time */ if(rtsp_npt_time_valid(p + 1,reason_ret)) { /* check end string */ /* end string OK --> direct copy */ npt_end_time_str = strdup(p + 1); } else { /* end string NOT OK */ npt_end_time_str = rtsp_time_to_npt_time(p + 1,reason_ret); if(!npt_end_time_str) { /* really inacceptable */ return NULL; } } } original_start_time_str = xmalloc(start_str_len + 1); strncpy(original_start_time_str,str,start_str_len); original_start_time_str[start_str_len] = '\0'; if(rtsp_npt_time_valid(original_start_time_str,reason_ret)) { /* start string OK --> direct copy */ npt_start_time_str = strdup(original_start_time_str); } else { /* start string NOT OK */ npt_start_time_str = rtsp_time_to_npt_time(original_start_time_str,reason_ret); if(!npt_start_time_str) { /* really inacceptable */ free(original_start_time_str); free(npt_end_time_str); return NULL; } } npt_range_str = xmalloc(strlen(npt_start_time_str) + strlen(npt_end_time_str) + 2); strcpy(npt_range_str,npt_start_time_str); strcat(npt_range_str,"-"); strcat(npt_range_str,npt_end_time_str); npt_range_str[strlen(npt_start_time_str) + strlen(npt_end_time_str) + 1] = '\0'; free(npt_start_time_str); free(npt_end_time_str); free(original_start_time_str); return npt_range_str; } } return NULL;}/* * check if npt-range string is valid. * this function is to only check validity. * return value ... 0: not valid 1: valid * reason_ret ... NULL: no error * error reason string: some error */int rtsp_npt_range_valid(const char *str,char **reason_ret){ char *p = NULL; char *npttime_str = NULL; int valid = 0; char *reason = NULL; p = strchr(str,'-'); if(p == NULL) { /* have to have exactly one '-' */ reason = "must use \'-\' to tell range"; if(reason_ret) { *reason_ret = reason; } return 0; } if(p == str) { /* ( "-" npt-time ) */ valid = rtsp_npt_time_valid(p + 1,reason_ret); return valid; } else { /* 00.23- */ int start_str_len = p - str; if(*(p+1) != '\0') { /* not 00.23- */ if(!rtsp_npt_time_valid(p + 1,reason_ret)) { /* check end string */ return 0; } } /* end string OK */ /* check start string */ npttime_str = xmalloc(start_str_len + 1); strncpy(npttime_str,str,start_str_len); npttime_str[start_str_len] = '\0'; valid = rtsp_npt_time_valid(npttime_str,reason_ret); free(npttime_str); return valid; } return 0;}/* * check if npt-time string is valid. * this function is to only check validity. * return value ... 0: not valid 1: valid * reason_ret ... "": no error some string: error reason * */int rtsp_npt_time_valid(const char *str,char **reason_ret){ int len = strlen(str); int i = 0; int npt_sec_valid = 1; int npt_hhmmss_valid = 1; int met_colon = 0; int mmss_value = 0; char *reason = NULL; if(!strcmp(str,"now")) { /* "now" is valid */ reason = ""; if(reason_ret) { *reason_ret = reason; } return 1; } /* Actually, we can check npt-sec validity and npt-hhmmss at the same time. to do that, change - if(met_colon < 2) { + if((met_colon != 0) && (met_colon < 2)) { I'm not doing this to respect rfc 2326, which wirtes like below. "npt-time = "now" | npt-sec | npt-hhmmss" */ /* check npt-sec validity */ npt_sec_valid = 1; for(i = 0; (i < len) && npt_sec_valid ; i++) { if('0' <= str[i] && str[i] <= '9') { continue; } else if(str[i] == '.') { if((i == 0) || (i == len - 1) || str[i-1] == ':') { /* dot was at the beginning or end of string, or right after colon */ reason = "\'.\' at the beginning or end of string, or right after colon"; npt_sec_valid = 0; break; } i++; for(; i < len ; i++) { if(('0' <= str[i]) && (str[i] <= '9')) { continue; } else { reason = "invalid character after \'.\'"; npt_sec_valid = 0; break; } } } else { /* invalid character found */ reason = "invalid character"; npt_sec_valid = 0; break; } } if(npt_sec_valid) { reason = ""; if(reason_ret) { *reason_ret = reason; } return npt_sec_valid; } /* check npt-hhmmss validity*/ npt_hhmmss_valid = 1; met_colon = 0; mmss_value = 0; for(i = 0 ; (i < len) && npt_hhmmss_valid ; i++) { if('0' <= str[i] && str[i] <= '9') { if(met_colon == 0) { /* npt-hh can be any positive number */ continue; } else { /* npt-mm and npt-ss must be less than 60*/ mmss_value *= 10; mmss_value += str[i] - '0'; if(mmss_value >= 60) { reason = "value more than 59 in mmss"; npt_hhmmss_valid = 0; break; } continue; } } else if(str[i] == '.') { if((i == 0) || (i == len - 1) || (str[i-1] == ':')) { reason = "\'.\' at the beginning or end of string, or right after colon"; npt_hhmmss_valid = 0; break; } i++; for(; i < len ; i++) { if(('0' <= str[i]) && (str[i] <= '9')) { continue; } else { reason = "invalid char after \'.\'"; npt_hhmmss_valid = 0; break; } } } else if(str[i] == ':') { /* have to have 2 colons */ if((i == 0) || (i == len - 1) || (str[i-1] == ':')) { reason = "\':\' at invalid position"; npt_hhmmss_valid = 0; break; } mmss_value = 0; /* reset mmss_value */ if(met_colon < 2) { met_colon++; continue; } else { /* too many colons, return */ reason = "too many colons"; npt_hhmmss_valid = 0; break; } } else { /* invalid chraracter */ reason = "invalid character"; npt_hhmmss_valid = 0; break; } } if(met_colon < 2) { if(reason == NULL) { reason = "there must be exactly 2 or 0colons"; } npt_hhmmss_valid = 0; } if(npt_hhmmss_valid) { reason = ""; if(reason_ret) { *reason_ret = reason; } return npt_hhmmss_valid; } /* invalid */ if(reason_ret) { *reason_ret = reason; } return 0;}/* * receive rtsp header and set rtsp_ctrl * return status code : success * -1 : failure */int rtsp_recv_header(struct stream_t *stream,struct rtsp_header_t *rtsp_hdr){ int ret = 0; ret = rtsp_recv_header_get(stream,rtsp_hdr); if(ret < 0) { return -1; } ret = rtsp_parse_response(stream->stream_ctrl->rtsp_ctrl,rtsp_hdr); if(ret < 0) { return -1; } return rtsp_hdr->status_code;}/* * receive rtsp message from stream->sock. * header is guraranteed to be complete after this function, * body should not be complete. * get header only, have to get body later after this function. * return status code : success * -1 : failure */static int rtsp_recv_header_get(struct stream_t *stream, struct rtsp_header_t *rtsp_hdr){ int ret = 0,i = 0,total = 0; rtsp_hdr->buffer_len = 0; rtsp_hdr->buffer = NULL; total = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -