package com.genersoft.iot.vmp.gb28181.transmit.request.impl;  
 | 
  
 | 
import java.security.NoSuchAlgorithmException;  
 | 
import java.text.ParseException;  
 | 
import java.util.Calendar;  
 | 
import java.util.Locale;  
 | 
  
 | 
import javax.sip.InvalidArgumentException;  
 | 
import javax.sip.RequestEvent;  
 | 
import javax.sip.SipException;  
 | 
import javax.sip.header.AuthorizationHeader;  
 | 
import javax.sip.header.ContactHeader;  
 | 
import javax.sip.header.ExpiresHeader;  
 | 
import javax.sip.header.FromHeader;  
 | 
import javax.sip.header.ViaHeader;  
 | 
import javax.sip.message.Request;  
 | 
import javax.sip.message.Response;  
 | 
  
 | 
import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate;  
 | 
import gov.nist.javax.sip.header.SIPDateHeader;  
 | 
import org.slf4j.Logger;  
 | 
import org.slf4j.LoggerFactory;  
 | 
import org.springframework.util.StringUtils;  
 | 
  
 | 
import com.genersoft.iot.vmp.common.VideoManagerConstants;  
 | 
import com.genersoft.iot.vmp.conf.SipConfig;  
 | 
import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;  
 | 
import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler;  
 | 
import com.genersoft.iot.vmp.gb28181.bean.Device;  
 | 
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;  
 | 
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;  
 | 
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;  
 | 
  
 | 
import gov.nist.javax.sip.address.AddressImpl;  
 | 
import gov.nist.javax.sip.address.SipUri;  
 | 
import gov.nist.javax.sip.header.Expires;  
 | 
  
 | 
/**      
 | 
 * @Description:收到注册请求 处理   
 | 
 * @author: swwheihei  
 | 
 * @date:   2020年5月3日 下午4:47:25       
 | 
 */  
 | 
public class RegisterRequestProcessor extends SIPRequestAbstractProcessor {  
 | 
  
 | 
    private Logger logger = LoggerFactory.getLogger(RegisterRequestProcessor.class);  
 | 
  
 | 
    private SipConfig sipConfig;  
 | 
      
 | 
    private RegisterLogicHandler handler;  
 | 
      
 | 
    private IVideoManagerStorager storager;  
 | 
      
 | 
    private EventPublisher publisher;  
 | 
  
 | 
    /**  
 | 
     * 收到注册请求 处理  
 | 
      * @param evt  
 | 
     */  
 | 
    @Override  
 | 
    public void process(RequestEvent evt) {  
 | 
        try {  
 | 
            logger.info("收到注册请求,开始处理");  
 | 
            Request request = evt.getRequest();  
 | 
  
 | 
            Response response = null;   
 | 
            boolean passwordCorrect = false;  
 | 
            // 注册标志  0:未携带授权头或者密码错误  1:注册成功   2:注销成功  
 | 
            int registerFlag = 0;  
 | 
            Device device = null;  
 | 
            AuthorizationHeader authorhead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);   
 | 
            // 校验密码是否正确  
 | 
            if (authorhead != null) {  
 | 
                passwordCorrect = new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request,  
 | 
                        sipConfig.getSipPassword());  
 | 
            }  
 | 
  
 | 
            // 未携带授权头或者密码错误 回复401  
 | 
            if (authorhead == null || !passwordCorrect) {  
 | 
                  
 | 
                if (authorhead == null) {  
 | 
                    logger.info("未携带授权头 回复401");  
 | 
                } else if (!passwordCorrect) {  
 | 
                    logger.info("密码错误 回复401");  
 | 
                }  
 | 
                response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request);  
 | 
                new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getSipDomain());  
 | 
            }  
 | 
            // 携带授权头并且密码正确  
 | 
            else if (passwordCorrect) {  
 | 
                response = getMessageFactory().createResponse(Response.OK, request);  
 | 
                // 添加date头  
 | 
                SIPDateHeader dateHeader = new SIPDateHeader();  
 | 
                // 使用自己修改的  
 | 
                WvpSipDate wvpSipDate = new WvpSipDate(Calendar.getInstance(Locale.ENGLISH).getTimeInMillis());  
 | 
                dateHeader.setDate(wvpSipDate);  
 | 
                response.addHeader(dateHeader);  
 | 
  
 | 
                ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME);  
 | 
                // 添加Contact头  
 | 
                response.addHeader(request.getHeader(ContactHeader.NAME));  
 | 
                // 添加Expires头  
 | 
                response.addHeader(request.getExpires());  
 | 
                  
 | 
                // 1.获取到通信地址等信息,保存到Redis  
 | 
                FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME);  
 | 
                ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);  
 | 
                String received = viaHeader.getReceived();  
 | 
                int rPort = viaHeader.getRPort();  
 | 
                // 本地模拟设备 received 为空 rPort 为 -1  
 | 
                // 解析本地地址替代  
 | 
                if (StringUtils.isEmpty(received) || rPort == -1) {  
 | 
                    received = viaHeader.getHost();  
 | 
                    rPort = viaHeader.getPort();  
 | 
                }  
 | 
                //  
 | 
                AddressImpl address = (AddressImpl) fromHeader.getAddress();  
 | 
                SipUri uri = (SipUri) address.getURI();  
 | 
                String deviceId = uri.getUser();  
 | 
                device = new Device();  
 | 
                device.setStreamMode("UDP");  
 | 
                device.setDeviceId(deviceId);  
 | 
                device.setIp(received);  
 | 
                device.setPort(rPort);  
 | 
                device.setHostAddress(received.concat(":").concat(String.valueOf(rPort)));  
 | 
                // 注销成功  
 | 
                if (expiresHeader != null && expiresHeader.getExpires() == 0) {  
 | 
                    registerFlag = 2;  
 | 
                }  
 | 
                // 注册成功  
 | 
                else {  
 | 
                    registerFlag = 1;  
 | 
                    // 判断TCP还是UDP  
 | 
                    boolean isTcp = false;  
 | 
                    ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);  
 | 
                    String transport = reqViaHeader.getTransport();  
 | 
                    if (transport.equals("TCP")) {  
 | 
                        isTcp = true;  
 | 
                    }  
 | 
                    device.setTransport(isTcp ? "TCP" : "UDP");  
 | 
                }  
 | 
            }  
 | 
            getServerTransaction(evt).sendResponse(response);  
 | 
            // 注册成功  
 | 
            // 保存到redis  
 | 
            // 下发catelog查询目录  
 | 
            if (registerFlag == 1 && device != null) {  
 | 
                logger.info("注册成功! deviceId:" + device.getDeviceId());  
 | 
                // boolean exists = storager.exists(device.getDeviceId());  
 | 
                device.setRegisterTimeMillis(System.currentTimeMillis());  
 | 
                storager.updateDevice(device);  
 | 
                publisher.onlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_ONLINE_REGISTER);  
 | 
  
 | 
                // 重新注册更新设备和通道,以免设备替换或更新后信息无法更新  
 | 
                //if (!exists) {  
 | 
                    handler.onRegister(device);  
 | 
                //}  
 | 
            } else if (registerFlag == 2) {  
 | 
                logger.info("注销成功! deviceId:" + device.getDeviceId());  
 | 
                publisher.outlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_OUTLINE_UNREGISTER);  
 | 
            }  
 | 
        } catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) {  
 | 
            e.printStackTrace();  
 | 
        }  
 | 
          
 | 
    }  
 | 
      
 | 
    public void setSipConfig(SipConfig sipConfig) {  
 | 
        this.sipConfig = sipConfig;  
 | 
    }  
 | 
  
 | 
    public void setHandler(RegisterLogicHandler handler) {  
 | 
        this.handler = handler;  
 | 
    }  
 | 
  
 | 
    public void setVideoManagerStorager(IVideoManagerStorager storager) {  
 | 
        this.storager = storager;  
 | 
    }  
 | 
  
 | 
    public void setPublisher(EventPublisher publisher) {  
 | 
        this.publisher = publisher;  
 | 
    }  
 | 
  
 | 
}  
 |