interface SipMessageConfig { targetIp?: string; targetPort?: number; macLocalIp?: string; senderSip?: string; senderIp?: string; receiverSip?: string; receiverIp?: string; } export async function sendSipMessage(config: SipMessageConfig = {}): Promise { // 配置参数(使用默认值或传入的配置) const targetIp = config.targetIp || "192.168.3.3"; // 设备eth1的IP(转发入口) const targetPort = config.targetPort || 5060; // 转发端口 const macLocalIp = config.macLocalIp || "192.168.3.33"; // Mac的本地IP(与Via头部一致) const senderSip = config.senderSip || "3011302"; // 发送方SIP用户 const senderIp = config.senderIp || "192.168.9.57"; // 设备eth0的IP(转发后源IP) const receiverSip = config.receiverSip || "3019901"; // 接收方SIP用户 const receiverIp = config.receiverIp || "192.168.9.4"; // 目标IP // 生成唯一标识 const callId = `${Math.floor(Date.now() / 1000)}`; // 基于时间戳的Call-ID const tag = `${Math.floor(Date.now() % 1000000)}`; // 随机tag const branch = `z9hG4bK${Math.floor(Date.now() / 1000)}`; // Via分支标识 // XML消息体(业务数据) const xmlBody = ` sip:${receiverSip}@${receiverIp}:5060 1 2 13 2 elev appoint /elev/appoint `; // 计算消息体长度(使用字符串长度 + utf8编码估算) const contentLength = new TextEncoder().encode(xmlBody).length; // 构造SIP MESSAGE请求(严格使用\r\n换行) const sipMessage = `MESSAGE sip:${receiverSip}@${receiverIp}:5060 SIP/2.0\r\n` + `Via: SIP/2.0/UDP ${macLocalIp}:5060;rport;branch=${branch}\r\n` + `From: ;tag=${tag}\r\n` + `To: \r\n` + `Call-ID: ${callId}@${macLocalIp}\r\n` + `CSeq: 20 MESSAGE\r\n` + `Content-Type: text/plain\r\n` + `Max-Forwards: 70\r\n` + `User-Agent: DnakeVoip v1.0\r\n` + `Content-Length: ${contentLength}\r\n\r\n` + `${xmlBody}`; return new Promise((resolve, reject) => { try { console.log(`准备发送SIP消息到 ${targetIp}:${targetPort}`); console.log('\n发送的消息内容:'); console.log(sipMessage); resolve(); } catch (error: any) { console.log(`处理失败:${error.message}`); reject(error); } }); } // 使用默认配置的便捷函数 export function sendDefaultSipMessage(): Promise { return sendSipMessage(); } // 使用Node.js原生dgram模块的实现(需要@types/node) export function getSipMessageWithDgram(config: SipMessageConfig = {}): string { const targetIp = config.targetIp || "192.168.3.3"; const macLocalIp = config.macLocalIp || "192.168.3.33"; const senderSip = config.senderSip || "3011302"; const senderIp = config.senderIp || "192.168.9.57"; const receiverSip = config.receiverSip || "3019901"; const receiverIp = config.receiverIp || "192.168.9.4"; const callId = `${Math.floor(Date.now() / 1000)}`; const tag = `${Math.floor(Date.now() % 1000000)}`; const branch = `z9hG4bK${Math.floor(Date.now() / 1000)}`; const xmlBody = ` sip:${receiverSip}@${receiverIp}:5060 1 2 13 2 elev appoint /elev/appoint `; const contentLength = new TextEncoder().encode(xmlBody).length; return `MESSAGE sip:${receiverSip}@${receiverIp}:5060 SIP/2.0\r\n` + `Via: SIP/2.0/UDP ${macLocalIp}:5060;rport;branch=${branch}\r\n` + `From: ;tag=${tag}\r\n` + `To: \r\n` + `Call-ID: ${callId}@${macLocalIp}\r\n` + `CSeq: 20 MESSAGE\r\n` + `Content-Type: text/plain\r\n` + `Max-Forwards: 70\r\n` + `User-Agent: DnakeVoip v1.0\r\n` + `Content-Length: ${contentLength}\r\n\r\n` + `${xmlBody}`; } // sendDefaultSipMessage().catch(console.error);