/* 解析SIP消息 */
int sip_message_parse(struct sip_message *msg, const char *data, U32 length)
{
char *line, *saveptr;
char *data_copy;
if (!msg || !data || length == 0)
return -EINVAL;
memset(msg, 0, sizeof(*msg));
/* 复制消息数据 */
data_copy = malloc(length + 1);
if (!data_copy)
return -ENOMEM;
memcpy(data_copy, data, length);
data_copy[length] = '\0';
msg->raw_data = data_copy;
msg->raw_length = length;
/* 解析起始行 */
line = strtok_r(data_copy, "\r\n", &saveptr);
if (!line)
{
free(data_copy);
return -EINVAL;
}
/* 判断消息类型 */
if (strncmp(line, "SIP/2.0", 7) == 0)
{
/* 响应消息 */
msg->type = 1;
if (sscanf(line, "SIP/2.0 %hu", &msg->status_code) == 1)
{
/* 提取原因短语 */
char *reason_start = strchr(line, ' ');
if (reason_start)
{
reason_start = strchr(reason_start + 1, ' ');
if (reason_start)
{
strlcpy(msg->reason_phrase, reason_start + 1,
sizeof(msg->reason_phrase));
}
}
}
}
else
{
/* 请求消息 */
msg->type = 0;
/* 提取方法 */
char method_str[16];
if (sscanf(line, "%15s", method_str) == 1)
{
msg->method = sip_string_to_method(method_str);
}
/* 提取Request-URI */
char *uri_start = strchr(line, ' ');
if (uri_start)
{
char *uri_end = strchr(uri_start + 1, ' ');
if (uri_end)
{
char uri[256];
U32 uri_len = uri_end - uri_start - 1;
if (uri_len < sizeof(uri))
{
strncpy(uri, uri_start + 1, uri_len);
uri[uri_len] = '\0';
sip_uri_parse(&msg->headers.request_uri, uri);
}
}
}
}
/* 解析头部字段 */
while ((line = strtok_r(NULL, "\r\n", &saveptr)) != NULL)
{
if (strlen(line) == 0)
{
break; /* 空行,头部结束 */
}
if (strncasecmp(line, "From:", 5) == 0)
{
char *uri_start = strchr(line, '<');
if (uri_start)
{
char *uri_end = strchr(uri_start + 1, '>');
if (uri_end)
{
char uri[256];
U32 uri_len = uri_end - uri_start - 1;
if (uri_len < sizeof(uri))
{
strncpy(uri, uri_start + 1, uri_len);
uri[uri_len] = '\0';
sip_uri_parse(&msg->headers.from, uri);
}
}
}
}
else if (strncasecmp(line, "To:", 3) == 0)
{
char *uri_start = strchr(line, '<');
if (uri_start)
{
char *uri_end = strchr(uri_start + 1, '>');
if (uri_end)
{
char uri[256];
U32 uri_len = uri_end - uri_start - 1;
if (uri_len < sizeof(uri))
{
strncpy(uri, uri_start + 1, uri_len);
uri[uri_len] = '\0';
sip_uri_parse(&msg->headers.to, uri);
}
}
}
}
else if (strncasecmp(line, "Call-ID:", 8) == 0)
{
char *id_start = line + 8;
while (*id_start == ' ')
id_start++;
strlcpy(msg->headers.call_id, id_start, sizeof(msg->headers.call_id));
}
else if (strncasecmp(line, "CSeq:", 5) == 0)
{
char method_str[16];
if (sscanf(line + 5, "%u %15s", &msg->headers.cseq, method_str) == 2)
{
msg->headers.cseq_method = sip_string_to_method(method_str);
}
}
else if (strncasecmp(line, "Content-Type:", 13) == 0)
{
char *type_start = line + 13;
while (*type_start == ' ')
type_start++;
strlcpy(msg->headers.content_type, type_start,
sizeof(msg->headers.content_type));
}
else if (strncasecmp(line, "Content-Length:", 15) == 0)
{
msg->headers.content_length = strtoul(line + 15, NULL, 10);
}
else if (strncasecmp(line, "Via:", 4) == 0)
{
/* 简化解析Via头 */
char *via_start = line + 4;
while (*via_start == ' ')
via_start++;
/* 提取协议和传输 */
char protocol[32], transport[8], host[64];
U16 port = 5060;
if (sscanf(via_start, "%31[^/]/%*d.%*d/%7[^ ] %63[^:]:%hu",
protocol, transport, host, &port) >= 3)
{
strlcpy(msg->headers.via.protocol, protocol,
sizeof(msg->headers.via.protocol));
strlcpy(msg->headers.via.transport, transport,
sizeof(msg->headers.via.transport));
strlcpy(msg->headers.via.host, host,
sizeof(msg->headers.via.host));
msg->headers.via.port = port;
}
/* 提取branch参数 */
char *branch_start = strstr(via_start, "branch=");
if (branch_start)
{
branch_start += 7;
char *branch_end = strchr(branch_start, ';');
if (!branch_end)
branch_end = strchr(branch_start, ' ');
if (!branch_end)
branch_end = branch_start + strlen(branch_start);
U32 branch_len = branch_end - branch_start;
if (branch_len < sizeof(msg->headers.via.branch))
{
strncpy(msg->headers.via.branch, branch_start, branch_len);
msg->headers.via.branch[branch_len] = '\0';
}
}
}
else if (strncasecmp(line, "WWW-Authenticate: Digest", 24) == 0)
{
char *ptr = line + 24, *key, *value;
while (*ptr != '\r' )
{
// 跳过空格和逗号
while (*ptr == ' ' || *ptr == ',')
ptr++;
// 提取键
key = ptr;
while (*ptr && *ptr != '=')
ptr++;
if (*ptr != '=')
break;
*ptr++ = '\0';
// 提取值
if (*ptr == '"')
{
ptr++;
value = ptr;
while (*ptr && *ptr != '"')
ptr++;
if (*ptr == '"')
*ptr++ = '\0';
}
else
{
value = ptr;
while (*ptr && *ptr != ' ' && *ptr != ',')
ptr++;
if (*ptr)
*ptr++ = '\0';
}
// 保存参数
if (strcmp(key, "realm") == 0)
{
strncpy(msg->headers.auth.realm, value, sizeof(msg->headers.auth.realm) - 1);
}
else if (strcmp(key, "nonce") == 0)
{
strncpy(msg->headers.auth.nonce, value, sizeof(msg->headers.auth.nonce) - 1);
}
else if (strcmp(key, "algorithm") == 0)
{
strncpy(msg->headers.auth.algorithm, value, sizeof(msg->headers.auth.algorithm) - 1);
}
else if (strcmp(key, "qop") == 0)
{
strncpy(msg->headers.auth.qop, value, sizeof(msg->headers.auth.qop) - 1);
}
else if (strcmp(key, "opaque") == 0)
{
strncpy(msg->headers.auth.opaque, value, sizeof(msg->headers.auth.opaque) - 1);
}
else if (strcmp(key, "stale") == 0)
{
msg->headers.auth.stale = (strcmp(value, "true") == 0);
}
}
}
}
/* 解析消息体 */
if (msg->headers.content_length > 0)
{
char *body_start = strstr(data, "\r\n\r\n");
if (body_start)
{
body_start += 4; /* 跳过空行 */
msg->body.content = malloc(msg->headers.content_length + 1);
if (msg->body.content)
{
memcpy(msg->body.content, body_start, msg->headers.content_length);
msg->body.content[msg->headers.content_length] = '\0';
msg->body.length = msg->headers.content_length;
strlcpy(msg->body.type, msg->headers.content_type,
sizeof(msg->body.type));
}
}
}
return 0;
}
这个函数缺少提取to和from的tag的部分请帮我加上