Browse Source

使用jainsip的方式解析sdp

pull/59/head
panlinlin 4 years ago
parent
commit
421c2f5602
  1. 65
      src/main/java/com/genersoft/iot/vmp/gb28181/sdp/Codec.java
  2. 123
      src/main/java/com/genersoft/iot/vmp/gb28181/sdp/MediaDescription.java
  3. 51
      src/main/java/com/genersoft/iot/vmp/gb28181/sdp/RFC4566_28181.java
  4. 38
      src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SdpLine.java
  5. 230
      src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SdpParser.java
  6. 162
      src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SessionDescription.java
  7. 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
  8. 95
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
  9. 2
      web_src/.postcssrc.js

65
src/main/java/com/genersoft/iot/vmp/gb28181/sdp/Codec.java

@ -1,65 +0,0 @@
/*
This file is part of Peers, a java SIP softphone.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Copyright 2010 Yohann Martineau
*/
package com.genersoft.iot.vmp.gb28181.sdp;
public class Codec {
private int payloadType;
private String name;
public int getPayloadType() {
return payloadType;
}
public void setPayloadType(int payloadType) {
this.payloadType = payloadType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Codec)) {
return false;
}
Codec codec = (Codec)obj;
if (codec.getName() == null) {
return name == null;
}
return codec.getName().equalsIgnoreCase(name);
}
@Override
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append(RFC4566_28181.TYPE_ATTRIBUTE).append(RFC4566_28181.SEPARATOR);
buf.append(RFC4566_28181.ATTR_RTPMAP).append(RFC4566_28181.ATTR_SEPARATOR);
buf.append(payloadType).append(" ").append(name).append("/");
buf.append(9000).append("\r\n");
return buf.toString();
}
}

123
src/main/java/com/genersoft/iot/vmp/gb28181/sdp/MediaDescription.java

@ -1,123 +0,0 @@
/*
This file is part of Peers, a java SIP softphone.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Copyright 2007, 2008, 2009, 2010 Yohann Martineau
*/
package com.genersoft.iot.vmp.gb28181.sdp;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.Hashtable;
import java.util.List;
public class MediaDescription {
private String type;
private InetAddress ipAddress;
// attributes not codec-related
private Hashtable<String, String> attributes;
private int port;
private List<Codec> codecs;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Hashtable<String, String> getAttributes() {
return attributes;
}
public void setAttributes(Hashtable<String, String> attributes) {
this.attributes = attributes;
}
public InetAddress getIpAddress() {
return ipAddress;
}
public void setIpAddress(InetAddress ipAddress) {
this.ipAddress = ipAddress;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public List<Codec> getCodecs() {
return codecs;
}
public void setCodecs(List<Codec> codecs) {
this.codecs = codecs;
}
@Override
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append(RFC4566_28181.TYPE_MEDIA).append(RFC4566_28181.SEPARATOR);
buf.append(type).append(" ").append(port);
buf.append(" RTP/AVP");
if (codecs != null) {
for (Codec codec: codecs) {
buf.append(" ");
buf.append(codec.getPayloadType());
}
buf.append("\r\n");
}
if (ipAddress != null) {
int ipVersion;
if (ipAddress instanceof Inet4Address) {
ipVersion = 4;
} else if (ipAddress instanceof Inet6Address) {
ipVersion = 6;
} else {
throw new RuntimeException("unknown ip version: " + ipAddress);
}
buf.append(RFC4566_28181.TYPE_CONNECTION).append(RFC4566_28181.SEPARATOR);
buf.append("IN IP").append(ipVersion).append(" ");
buf.append(ipAddress.getHostAddress()).append("\r\n");
}
if (codecs != null) {
for (Codec codec: codecs) {
buf.append(codec.toString());
}
}
if (attributes != null) {
for (String attributeName: attributes.keySet()) {
buf.append(RFC4566_28181.TYPE_ATTRIBUTE).append(RFC4566_28181.SEPARATOR);
buf.append(attributeName);
String attributeValue = attributes.get(attributeName);
if (attributeValue != null && !"".equals(attributeValue.trim())) {
buf.append(":").append(attributeValue);
}
buf.append("\r\n");
}
}
return buf.toString();
}
}

51
src/main/java/com/genersoft/iot/vmp/gb28181/sdp/RFC4566_28181.java

@ -1,51 +0,0 @@
/*
This file is part of Peers, a java SIP softphone.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Copyright 2007, 2008, 2009, 2010 Yohann Martineau
*/
package com.genersoft.iot.vmp.gb28181.sdp;
public class RFC4566_28181 {
public static final char VERSION = '0';
public static final char TYPE_VERSION = 'v';
public static final char TYPE_ORIGIN = 'o';
public static final char TYPE_SUBJECT = 's';
public static final char TYPE_INFO = 'i';
public static final char TYPE_URI = 'u';
public static final char TYPE_EMAIL = 'e';
public static final char TYPE_PHONE = 'p';
public static final char TYPE_CONNECTION = 'c';
public static final char TYPE_BANDWITH = 'b';
public static final char TYPE_TIME = 't';
public static final char TYPE_REPEAT = 'r';
public static final char TYPE_ZONE = 'z';
public static final char TYPE_KEY = 'k';
public static final char TYPE_ATTRIBUTE = 'a';
public static final char TYPE_MEDIA = 'm';
public static final char TYPE_SSRC = 'y';
public static final char TYPE_MEDIA_DES = 'f';
public static final char SEPARATOR = '=';
public static final char ATTR_SEPARATOR = ':';
public static final String MEDIA_AUDIO = "audio";
public static final String ATTR_RTPMAP = "rtpmap";
public static final String ATTR_SENDRECV = "sendrecv";
}

38
src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SdpLine.java

@ -1,38 +0,0 @@
/*
This file is part of Peers, a java SIP softphone.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Copyright 2007, 2008, 2009, 2010 Yohann Martineau
*/
package com.genersoft.iot.vmp.gb28181.sdp;
public class SdpLine {
private char type;
private String value;
public char getType() {
return type;
}
public void setType(char type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

230
src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SdpParser.java

@ -1,230 +0,0 @@
/*
This file is part of Peers, a java SIP softphone.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Copyright 2007, 2008, 2009, 2010 Yohann Martineau
*/
package com.genersoft.iot.vmp.gb28181.sdp;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
public class SdpParser {
public SessionDescription parse(byte[] body) throws IOException {
if (body == null || body.length == 0) {
return null;
}
ByteArrayInputStream in = new ByteArrayInputStream(body);
InputStreamReader inputStreamReader = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(inputStreamReader);
SessionDescription sessionDescription = new SessionDescription();
//version
String line = reader.readLine();
if (line.length() < 3) {
return null;
}
if (line.charAt(0) != RFC4566_28181.TYPE_VERSION
|| line.charAt(1) != RFC4566_28181.SEPARATOR
|| line.charAt(2) != RFC4566_28181.VERSION) {
return null;
}
//origin
line = reader.readLine();
if (line.length() < 3) {
return null;
}
if (line.charAt(0) != RFC4566_28181.TYPE_ORIGIN
|| line.charAt(1) != RFC4566_28181.SEPARATOR) {
return null;
}
line = line.substring(2);
String[] originArr = line.split(" ");
if (originArr == null || originArr.length != 6) {
return null;
}
sessionDescription.setUsername(originArr[0]);
sessionDescription.setId(Long.parseLong(originArr[1]));
sessionDescription.setVersion(Long.parseLong(originArr[2]));
sessionDescription.setIpAddress(InetAddress.getByName(originArr[5]));
//name
line = reader.readLine();
if (line.length() < 3) {
return null;
}
if (line.charAt(0) != RFC4566_28181.TYPE_SUBJECT
|| line.charAt(1) != RFC4566_28181.SEPARATOR) {
return null;
}
sessionDescription.setName(line.substring(2));
//session connection and attributes
Hashtable<String, String> sessionAttributes = new Hashtable<String, String>();
sessionDescription.setAttributes(sessionAttributes);
while ((line = reader.readLine()) != null
&& line.charAt(0) != RFC4566_28181.TYPE_MEDIA) {
if (line.length() > 3
&& line.charAt(0) == RFC4566_28181.TYPE_CONNECTION
&& line.charAt(1) == RFC4566_28181.SEPARATOR) {
String connection = parseConnection(line.substring(2));
if (connection == null) {
continue;
}
sessionDescription.setIpAddress(InetAddress.getByName(connection));
} else if (line.length() > 3
&& line.charAt(0) == RFC4566_28181.TYPE_ATTRIBUTE
&& line.charAt(1) == RFC4566_28181.SEPARATOR) {
String value = line.substring(2);
int pos = value.indexOf(RFC4566_28181.ATTR_SEPARATOR);
if (pos > -1) {
sessionAttributes.put(value.substring(0, pos),
value.substring(pos + 1));
} else {
sessionAttributes.put(value, "");
}
}
}
if (line == null) {
return null;
}
//we are at the first media line
ArrayList<SdpLine> mediaLines = new ArrayList<SdpLine>();
do {
if (line.length() < 2) {
return null;
}
if (line.charAt(1) != RFC4566_28181.SEPARATOR) {
return null;
}
if (line.charAt(0) == RFC4566_28181.TYPE_SSRC) {
sessionDescription.setSsrc(line.length() >=2 ?line.substring(2):"");
}else if (line.charAt(0) == RFC4566_28181.TYPE_MEDIA_DES) {
sessionDescription.setGbMediaDescriptions(line.length() >=2 ?line.substring(2):"");
}else {
SdpLine mediaLine = new SdpLine();
mediaLine.setType(line.charAt(0));
mediaLine.setValue(line.substring(2));
mediaLines.add(mediaLine);
}
}
while ((line = reader.readLine()) != null );
ArrayList<MediaDescription> mediaDescriptions = new ArrayList<MediaDescription>();
sessionDescription.setMediaDescriptions(mediaDescriptions);
for (SdpLine sdpLine : mediaLines) {
MediaDescription mediaDescription;
if (sdpLine.getType() == RFC4566_28181.TYPE_MEDIA) {
String[] mediaArr = sdpLine.getValue().split(" ");
if (mediaArr == null || mediaArr.length < 4) {
return null;
}
mediaDescription = new MediaDescription();
mediaDescription.setType(mediaArr[0]);
//TODO manage port range
mediaDescription.setPort(Integer.parseInt(mediaArr[1]));
mediaDescription.setAttributes(new Hashtable<String, String>());
List<Codec> codecs = new ArrayList<Codec>();
for (int i = 3; i < mediaArr.length; ++i) {
int payloadType = Integer.parseInt(mediaArr[i]);
Codec codec = new Codec();
codec.setPayloadType(payloadType);
codec.setName("unsupported");
codecs.add(codec);
}
mediaDescription.setCodecs(codecs);
mediaDescriptions.add(mediaDescription);
} else {
mediaDescription = mediaDescriptions.get(mediaDescriptions.size() - 1);
String sdpLineValue = sdpLine.getValue();
if (sdpLine.getType() == RFC4566_28181.TYPE_CONNECTION) {
String ipAddress = parseConnection(sdpLineValue);
mediaDescription.setIpAddress(InetAddress.getByName(ipAddress));
} else if (sdpLine.getType() == RFC4566_28181.TYPE_ATTRIBUTE) {
Hashtable<String, String> attributes = mediaDescription.getAttributes();
int pos = sdpLineValue.indexOf(RFC4566_28181.ATTR_SEPARATOR);
if (pos > -1) {
String name = sdpLineValue.substring(0, pos);
String value = sdpLineValue.substring(pos + 1);
pos = value.indexOf(" ");
if (pos > -1) {
int payloadType;
try {
payloadType = Integer.parseInt(value.substring(0, pos));
List<Codec> codecs = mediaDescription.getCodecs();
for (Codec codec: codecs) {
if (codec.getPayloadType() == payloadType) {
value = value.substring(pos + 1);
pos = value.indexOf("/");
if (pos > -1) {
value = value.substring(0, pos);
codec.setName(value);
}
break;
}
}
} catch (NumberFormatException e) {
attributes.put(name, value);
}
} else {
attributes.put(name, value);
}
} else {
attributes.put(sdpLineValue, "");
}
}
}
}
sessionDescription.setMediaDescriptions(mediaDescriptions);
for (MediaDescription description : mediaDescriptions) {
if (description.getIpAddress() == null) {
InetAddress sessionAddress = sessionDescription.getIpAddress();
if (sessionAddress == null) {
return null;
}
description.setIpAddress(sessionAddress);
}
}
return sessionDescription;
}
private String parseConnection(String line) {
String[] connectionArr = line.split(" ");
if (connectionArr == null || connectionArr.length != 3) {
return null;
}
return connectionArr[2];
}
}

162
src/main/java/com/genersoft/iot/vmp/gb28181/sdp/SessionDescription.java

@ -1,162 +0,0 @@
/*
This file is part of Peers, a java SIP softphone.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Copyright 2007, 2008, 2009, 2010 Yohann Martineau
*/
package com.genersoft.iot.vmp.gb28181.sdp;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.Hashtable;
import java.util.List;
public class SessionDescription {
private long id;
private long version;
private String name;
private String username;
private InetAddress ipAddress;
private List<MediaDescription> mediaDescriptions;
private Hashtable<String, String> attributes;
private String ssrc;
private String gbMediaDescriptions;
public SessionDescription() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public InetAddress getIpAddress() {
return ipAddress;
}
public void setIpAddress(InetAddress ipAddress) {
this.ipAddress = ipAddress;
}
public List<MediaDescription> getMediaDescriptions() {
return mediaDescriptions;
}
public void setMediaDescriptions(List<MediaDescription> mediaDescriptions) {
this.mediaDescriptions = mediaDescriptions;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
public Hashtable<String, String> getAttributes() {
return attributes;
}
public void setAttributes(Hashtable<String, String> attributes) {
this.attributes = attributes;
}
public String getSsrc() {
return ssrc;
}
public void setSsrc(String ssrc) {
this.ssrc = ssrc;
}
public String getGbMediaDescriptions() {
return gbMediaDescriptions;
}
public void setGbMediaDescriptions(String gbMediaDescriptions) {
this.gbMediaDescriptions = gbMediaDescriptions;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("v=0\r\n");
buf.append("o=").append(username).append(" ").append(id);
buf.append(" ").append(version);
int ipVersion;
if (ipAddress instanceof Inet4Address) {
ipVersion = 4;
} else if (ipAddress instanceof Inet6Address) {
ipVersion = 6;
} else {
throw new RuntimeException("unknown ip version: " + ipAddress);
}
buf.append(" IN IP").append(ipVersion).append(" ");
String hostAddress = ipAddress.getHostAddress();
buf.append(hostAddress).append("\r\n");
buf.append("s=").append(name).append("\r\n");
buf.append("c=IN IP").append(ipVersion).append(" ");
buf.append(hostAddress).append("\r\n");
buf.append("t=0 0\r\n");
if (attributes != null){
for (String attributeName: attributes.keySet()) {
String attributeValue = attributes.get(attributeName);
buf.append("a=").append(attributeName);
if (attributeValue != null && !"".equals(attributeValue.trim())) {
buf.append(":");
buf.append(attributeValue);
buf.append("\r\n");
}
}
}
if (mediaDescriptions != null){
for (MediaDescription mediaDescription: mediaDescriptions) {
buf.append(mediaDescription.toString());
}
}
if (ssrc != null){
buf.append("y=").append(ssrc).append("\r\n");
}
if (gbMediaDescriptions != null){
buf.append("f=").append(gbMediaDescriptions).append("\r\n");
}
return buf.toString();
}
}

1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java

@ -374,7 +374,6 @@ public class SIPCommander implements ISIPCommander {
if ("TCP-PASSIVE".equals(streamMode)) { // tcp被动模式
content.append("a=setup:passive\r\n");
content.append("a=connection:new\r\n");
} else if ("TCP-ACTIVE".equals(streamMode)) { // tcp主动模式
} else if ("TCP-ACTIVE".equals(streamMode)) { // tcp主动模式
content.append("a=setup:active\r\n");
content.append("a=connection:new\r\n");

95
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java

@ -113,45 +113,84 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
}
// 解析sdp消息, 使用jainsip 自带的sdp解析方式
String contentString = new String(request.getRawContent());
SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(contentString);
// TODO 区分TCP发流还是udp, 当前默认udp
// jainSip不支持y=字段, 移除移除以解析。
int ssrcIndex = contentString.indexOf("y=");
String ssrc = contentString.substring(ssrcIndex + 2, contentString.length())
.replace("\r\n", "").replace("\n", "");
String substring = contentString.substring(0, contentString.indexOf("y="));
SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
// 获取支持的格式
Vector mediaDescriptions = sdp.getMediaDescriptions(true);
// 查看是否支持PS 负载96
String ip = null;
int port = -1;
boolean recvonly = false;
boolean mediaTransmissionTCP = false;
Boolean tcpActive = null;
for (int i = 0; i < mediaDescriptions.size(); i++) {
MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i);
Media media = mediaDescription.getMedia();
Vector mediaFormats = media.getMediaFormats(false);
if (mediaFormats.contains("96")) {
port = media.getMediaPort();
String mediaType = media.getMediaType();
String protocol = media.getProtocol();
// 区分TCP发流还是udp, 当前默认udp
if ("TCP/RTP/AVP".equals(protocol)) {
String setup = mediaDescription.getAttribute("setup");
if (setup != null) {
mediaTransmissionTCP = true;
if ("active".equals(setup)) {
tcpActive = true;
}else if ("passive".equals(setup)) {
tcpActive = false;
}
// for (MediaDescription mediaDescription : mediaDescriptions) {
//
// List<Codec> codecs = mediaDescription.getCodecs();
// for (Codec codec : codecs) {
// if("96".equals(codec.getPayloadType()) || "PS".equals(codec.getName()) || "ps".equals(codec.getName())) {
// // TODO 这里很慢
// ip = mediaDescription.getIpAddress().getHostName();
// port = mediaDescription.getPort();
}
}
// Vector attributes = mediaDescription.getAttributes(false);
// for (Object attributeObj : attributes) {
// Attribute attribute = (Attribute)attributeObj;
// String name = attribute.getName();
// switch (name){
// case "recvonly":
// recvonly = true;
// break;
// case "rtpmap":
// case "connection":
// break;
// case "setup":
// mediaTransmissionTCP = true;
// if ("active".equals(attribute.getValue())) { // tcp主动模式
// tcpActive = true;
// }else if ("passive".equals(attribute.getValue())){ // tcp被动模式
// tcpActive = false;
// }
// break;
//
// }
// }
// if (ip == null || port == -1) { // TODO 没有合适的视频流格式, 可配置是否使用第一个media信息
// if (mediaDescriptions.size() > 0) {
// ip = mediaDescriptions.get(0).getIpAddress().getHostName();
// port = mediaDescriptions.get(0).getPort();
// }
// if ("recvonly".equals(name)) {
// recvonly = true;
// }
//
// if (ip == null || port == -1) {
// response488Ack(evt);
// return;
// String value = attribute.getValue();
// }
//
//
// String ssrc = sdp.getSsrc();
break;
}
}
if (port == -1) {
// 回复不支持的格式
response415Ack(evt); // 不支持的格式,发415
return;
}
String username = sdp.getOrigin().getUsername();
String addressStr = sdp.getOrigin().getAddress();
String sessionName = sdp.getSessionName().getValue();
logger.info("[上级点播]用户:{}, 地址:{}:{}, ssrc:{}", username, addressStr, port, ssrc);
//
// Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, channelId);
// if (device == null) {
@ -277,6 +316,18 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
getServerTransaction(evt).sendResponse(response);
}
/***
* 回复415 不支持的媒体类型
* @param evt
* @throws SipException
* @throws InvalidArgumentException
* @throws ParseException
*/
private void response415Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
Response response = getMessageFactory().createResponse(Response.UNSUPPORTED_MEDIA_TYPE, evt.getRequest());
getServerTransaction(evt).sendResponse(response);
}
/***
* 回复488
* @param evt

2
web_src/.postcssrc.js

@ -7,7 +7,7 @@ module.exports = {
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {},
'postcss-pxtorem': {
rootValue: 24,
rootValue: 16,
propList: ['font-size'] // 只转化font-size
}
}

Loading…
Cancel
Save