📄 sip_msg.c
字号:
intsip_add_passertedid(sip_msg_t sip_msg, char *display_name, char *addr, boolean_t add_aquot){ return (sip_add_name_aspec(sip_msg, display_name, addr, NULL, add_aquot, SIP_PASSERTEDID, NULL));}/* * PPreferredID = "P-Preferred-Identity" HCOLON PPreferredID-value * *(COMMA PPreferredID-value) * PPreferredID-value = name-addr / addr-spec * */intsip_add_ppreferredid(sip_msg_t sip_msg, char *display_name, char *addr, boolean_t add_aquot){ return (sip_add_name_aspec(sip_msg, display_name, addr, NULL, add_aquot, SIP_PPREFERREDID, NULL));}/* * NON OK ACK : MUST contain values for the Call-ID, From, and Request-URI * that are equal to the values of those header fields in the orig request * passed to the transport. The To header field in the ACK MUST equal the To * header field in the response being acknowledged. The ACK MUST contain the * top Via header field of the original request. The CSeq header field in * the ACK MUST contain the same value for the sequence number as was * present in the original request, but the method parameter MUST be equal * to "ACK". */intsip_create_nonOKack(sip_msg_t request, sip_msg_t response, sip_msg_t ack_msg){ int seqno; char *uri; _sip_msg_t *_request; _sip_msg_t *_response; _sip_msg_t *_ack_msg; int ret; if (request == NULL || response == NULL || ack_msg == NULL) return (EINVAL); _request = (_sip_msg_t *)request; _response = (_sip_msg_t *)response; _ack_msg = (_sip_msg_t *)ack_msg; (void) pthread_mutex_lock(&_request->sip_msg_mutex); if (_request->sip_msg_req_res == NULL) { if ((ret = sip_parse_first_line(_request->sip_msg_start_line, &_request->sip_msg_req_res)) != 0) { (void) pthread_mutex_unlock(&_request->sip_msg_mutex); return (ret); } } if (_request->sip_msg_req_res->U.sip_request.sip_request_uri. sip_str_ptr == NULL) { (void) pthread_mutex_unlock(&_request->sip_msg_mutex); return (EINVAL); } uri = (char *)malloc(_request->sip_msg_req_res->U.sip_request. sip_request_uri.sip_str_len + 1); if (uri == NULL) { (void) pthread_mutex_unlock(&_request->sip_msg_mutex); return (EINVAL); } (void) strncpy(uri, _request->sip_msg_req_res->U.sip_request.sip_request_uri. sip_str_ptr, _request->sip_msg_req_res->U.sip_request. sip_request_uri.sip_str_len); uri[_request->sip_msg_req_res->U.sip_request. sip_request_uri.sip_str_len] = '\0'; if ((ret = sip_add_request_line(_ack_msg, ACK, uri)) != 0) { (void) pthread_mutex_unlock(&_request->sip_msg_mutex); return (ret); } free(uri); if ((ret = _sip_find_and_copy_header(_request, _ack_msg, SIP_VIA, NULL)) != 0) { (void) pthread_mutex_unlock(&_request->sip_msg_mutex); return (ret); } (void) _sip_find_and_copy_header(_request, _ack_msg, SIP_MAX_FORWARDS, NULL); (void) pthread_mutex_lock(&_response->sip_msg_mutex); if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_TO, NULL)) != 0) { (void) pthread_mutex_unlock(&_response->sip_msg_mutex); return (ret); } (void) pthread_mutex_unlock(&_response->sip_msg_mutex); if ((ret = _sip_find_and_copy_header(_request, _ack_msg, SIP_FROM, NULL)) != 0) { (void) pthread_mutex_unlock(&_request->sip_msg_mutex); return (ret); } if ((ret = _sip_find_and_copy_header(_request, _ack_msg, SIP_CALL_ID, NULL)) != 0) { (void) pthread_mutex_unlock(&_request->sip_msg_mutex); return (ret); } (void) pthread_mutex_unlock(&_request->sip_msg_mutex); seqno = sip_get_callseq_num(_request, &ret); if (ret != 0) return (ret); if ((ret = sip_add_cseq(_ack_msg, ACK, seqno)) != 0) return (ret); if ((ret = sip_adjust_msgbuf(_ack_msg)) != 0) return (ret); return (0);}/* * This is a 2XX ACK, for others ACK is constructed differently, * esp. the branch id is retained. */intsip_create_OKack(sip_msg_t response, sip_msg_t ack_msg, char *transport, char *sent_by, int sent_by_port, char *via_params){ int seqno; char *uri; sip_parsed_header_t *parsed_header; sip_hdr_value_t *contact_value; _sip_header_t *header; _sip_msg_t *_response; _sip_msg_t *_ack_msg; int ret; if (response == NULL || response == NULL || transport == NULL) return (EINVAL); _response = (_sip_msg_t *)response; _ack_msg = (_sip_msg_t *)ack_msg; /* Get URI from the response, Contact field */ (void) pthread_mutex_lock(&_response->sip_msg_mutex); if ((header = sip_search_for_header(_response, SIP_CONTACT, NULL)) == NULL) { (void) pthread_mutex_unlock(&_response->sip_msg_mutex); return (EINVAL); } if ((ret = sip_parse_cftr_header(header, (void *)&parsed_header)) != 0) { (void) pthread_mutex_unlock(&_response->sip_msg_mutex); return (ret); } contact_value = (sip_hdr_value_t *)parsed_header->value; if (contact_value->cftr_uri.sip_str_ptr == NULL) { (void) pthread_mutex_unlock(&_response->sip_msg_mutex); return (EINVAL); } uri = (char *)malloc(contact_value->cftr_uri.sip_str_len + 1); if (uri == NULL) { (void) pthread_mutex_unlock(&_response->sip_msg_mutex); return (ENOMEM); } (void) strncpy(uri, contact_value->cftr_uri.sip_str_ptr, contact_value->cftr_uri.sip_str_len); uri[contact_value->cftr_uri.sip_str_len] = '\0'; if ((ret = sip_add_request_line(_ack_msg, ACK, uri)) != 0) { (void) pthread_mutex_unlock(&_response->sip_msg_mutex); return (ret); } free(uri); if ((ret = sip_add_via(_ack_msg, transport, sent_by, sent_by_port, via_params)) != 0) { (void) pthread_mutex_unlock(&_response->sip_msg_mutex); return (ret); } if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_TO, NULL)) != 0) { (void) pthread_mutex_unlock(&_response->sip_msg_mutex); return (ret); } if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_FROM, NULL)) != 0) { (void) pthread_mutex_unlock(&_response->sip_msg_mutex); return (ret); } if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_CALL_ID, NULL)) != 0) { (void) pthread_mutex_unlock(&_response->sip_msg_mutex); return (ret); } /* Copy Max-Forward if present */ if (sip_search_for_header(_response, SIP_MAX_FORWARDS, NULL) != NULL) { if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_MAX_FORWARDS, NULL)) != 0) { (void) pthread_mutex_unlock(&_response->sip_msg_mutex); return (ret); } } (void) pthread_mutex_unlock(&_response->sip_msg_mutex); seqno = sip_get_callseq_num(_response, &ret); if (ret != 0) return (ret); if ((ret = sip_add_cseq(_ack_msg, ACK, seqno)) != 0) return (ret); return (0);}/* * Request-Line = Method SP Request-URI SP SIP-Version CRLF */intsip_add_request_line(sip_msg_t sip_request, sip_method_t method, char *request_uri){ _sip_header_t *new_header; int header_size; _sip_msg_t *_sip_request; if (method < INVITE || method >= MAX_SIP_METHODS || request_uri == NULL || sip_request == NULL) { return (EINVAL); } _sip_request = (_sip_msg_t *)sip_request; (void) pthread_mutex_lock(&_sip_request->sip_msg_mutex); if (!sip_ok_to_modify_message(_sip_request)) { (void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex); return (ENOTSUP); } header_size = strlen(sip_methods[method].name) + SIP_SPACE + strlen(request_uri) + SIP_SPACE + strlen(SIP_VERSION) + strlen(SIP_CRLF); new_header = sip_new_header(header_size); if (new_header == NULL) { (void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex); return (ENOMEM); } new_header->sip_hdr_sipmsg = _sip_request; (void) snprintf(new_header->sip_hdr_start, header_size + 1, "%s %s %s%s", sip_methods[method].name, request_uri, SIP_VERSION, SIP_CRLF); new_header->sip_hdr_next = _sip_request->sip_msg_start_line; _sip_request->sip_msg_start_line = new_header; _sip_request->sip_msg_len += header_size; (void) sip_parse_first_line(_sip_request->sip_msg_start_line, &_sip_request->sip_msg_req_res); (void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex); return (0);}/* Clone a message */sip_msg_tsip_clone_msg(sip_msg_t sip_msg){ _sip_msg_t *new_msg; _sip_msg_t *_sip_msg; sip_content_t *sip_content; sip_content_t *msg_content; sip_content_t *new_content = NULL; int len; if (sip_msg == NULL) return (NULL); new_msg = (_sip_msg_t *)sip_new_msg(); if (new_msg == NULL) return (NULL); _sip_msg = (_sip_msg_t *)sip_msg; /* Get start line */ if (sip_copy_start_line(_sip_msg, new_msg) != 0) { sip_free_msg((sip_msg_t)new_msg); return (NULL); } if (sip_copy_all_headers(_sip_msg, new_msg) != 0) { sip_free_msg((sip_msg_t)new_msg); return (NULL); } (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); sip_content = _sip_msg->sip_msg_content; while (sip_content != NULL) { msg_content = calloc(1, sizeof (sip_content_t)); if (msg_content == NULL) { sip_free_msg((sip_msg_t)new_msg); (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); return (NULL); } len = sip_content->sip_content_end - sip_content->sip_content_start; msg_content->sip_content_start = malloc(len + 1); if (msg_content->sip_content_start == NULL) { sip_free_msg((sip_msg_t)new_msg); (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); return (NULL); } (void) strncpy(msg_content->sip_content_start, sip_content->sip_content_start, len); msg_content->sip_content_start[len] = '\0'; msg_content->sip_content_current = msg_content->sip_content_start; msg_content->sip_content_end = msg_content->sip_content_start + len; msg_content->sip_content_allocated = B_TRUE; new_msg->sip_msg_content_len += len; new_msg->sip_msg_len += len; if (new_msg->sip_msg_content == NULL) new_msg->sip_msg_content = msg_content; else new_content->sip_content_next = msg_content; new_content = msg_content; sip_content = sip_content->sip_content_next; } (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); (void) pthread_mutex_lock(&new_msg->sip_msg_mutex); new_msg->sip_msg_buf = sip_msg_to_msgbuf((sip_msg_t)new_msg, NULL); if (new_msg->sip_msg_buf == NULL) { (void) pthread_mutex_unlock(&new_msg->sip_msg_mutex); sip_free_msg((sip_msg_t)new_msg); return (NULL); } new_msg->sip_msg_cannot_be_modified = B_TRUE; (void) pthread_mutex_unlock(&new_msg->sip_msg_mutex); return ((sip_msg_t)new_msg);}/* * returns a comma separated string of all the sent-by values registered by * the UA. */char *sip_sent_by_to_str(int *error){ sent_by_list_t *sb; int sb_len = 0; int slen; char *sb_str; char *p; int count = 0; int cnt = 0; if (error != NULL) *error = 0; (void) pthread_mutex_lock(&sip_sent_by_lock); if (sip_sent_by == NULL) { (void) pthread_mutex_unlock(&sip_sent_by_lock); return (NULL); } sb = sip_sent_by; for (cnt = 0; cnt < sip_sent_by_count; cnt++) { sb_len += strlen(sb->sb_val); sb = sb->sb_next; } /* for the commas */ sb_len += sip_sent_by_count - 1; sb_str = malloc(sb_len + 1); if (sb_str == NULL) { if (error != NULL) *error = ENOMEM; (void) pthread_mutex_unlock(&sip_sent_by_lock); return (NULL); } sb = sip_sent_by; p = sb_str; slen = sb_len + 1; for (cnt = 0; cnt < sip_sent_by_count; cnt++) { if (cnt == 0) { count = snprintf(p, slen, "%s", sb->sb_val); } else { count = snprintf(p, slen, "%c%s", SIP_COMMA, sb->sb_val); } p += count; slen -= count; sb = sb->sb_next; } sb_str[sb_len] = '\0'; (void) pthread_mutex_unlock(&sip_sent_by_lock); return (sb_str);}/* * A comma separated list of sent-by values. */intsip_register_sent_by(char *val){ sent_by_list_t *sb = NULL; sent_by_list_t *sb_tail = NULL; char *str; int count = 0; if (val == NULL) return (EINVAL); str = strtok(val, ","); while (str != NULL) { int slen; char *start = str; char *end = str + strlen(str) - 1; while (isspace(*start)) start++; while (isspace(*end)) end--; if (end <= start) goto err_ret; slen = end - start + 1; sb_tail = (sent_by_list_t *)malloc(sizeof (*sb_tail)); if (sb_tail == NULL) goto err_ret; sb_tail->sb_next = sb_tail->sb_prev = NULL; if ((sb_tail->sb_val = (char *)malloc(slen + 1)) == NULL) { free(sb_tail); goto err_ret; } (void) strncpy(sb_tail->sb_val, start, slen); sb_tail->sb_val[slen] = '\0'; if (sb == NULL) { sb = sb_tail; } else { sb_tail->sb_next = sb; sb->sb_prev = sb_tail; sb = sb_tail; } count++; str = strtok(NULL, ","); } sb_tail = sb; while (sb_tail->sb_next != NULL) sb_tail = sb_tail->sb_next; (void) pthread_mutex_lock(&sip_sent_by_lock); if (sip_sent_by != NULL) { sb_tail->sb_next = sip_sent_by; sip_sent_by->sb_prev = sb_tail; } sip_sent_by = sb; sip_sent_by_count += count; (void) pthread_mutex_unlock(&sip_sent_by_lock); return (0);err_ret: sb_tail = sb; for (; count > 0; count--) { sb = sb_tail->sb_next; free(sb_tail->sb_val); sb_tail->sb_next = NULL; sb_tail->sb_prev = NULL; free(sb_tail); sb_tail = sb; } return (EINVAL);}/* * Given a sent-by value check if it is in the registered list. If no values * have been registered, the check passes. */boolean_tsip_sent_by_registered(const sip_str_t *sb_val){ sent_by_list_t *sb; int count = 0; (void) pthread_mutex_lock(&sip_sent_by_lock); if (sip_sent_by == NULL) { (void) pthread_mutex_unlock(&sip_sent_by_lock); return (B_TRUE); } sb = sip_sent_by; for (count = 0; count < sip_sent_by_count; count++) { if (strncmp(sb->sb_val, sb_val->sip_str_ptr, sb_val->sip_str_len) == 0) { (void) pthread_mutex_unlock(&sip_sent_by_lock); return (B_TRUE); } sb = sb->sb_next; } (void) pthread_mutex_unlock(&sip_sent_by_lock); return (B_FALSE);}/* Un-register sent-by values; 'val' contains a comma separated list */voidsip_unregister_sent_by(char *val){ sent_by_list_t *sb; char *str; int count = 0; (void) pthread_mutex_lock(&sip_sent_by_lock); str = strtok(val, ","); while (str != NULL) { sb = sip_sent_by; for (count = 0; count < sip_sent_by_count; count++) { if (strncmp(sb->sb_val, str, strlen(str)) == 0) { if (sb == sip_sent_by) { if (sb->sb_next !=
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -