func main() { mylog.Info.Println("MyRouter is alive") c := os.Getenv("MYROUTER_DB") //s, err := sql.Open("postgres", "postgres://*****:*****@server/db?sslmode=require") s, err := sql.Open("postgres", c) checkerror(err) d := dalpsql.NewFactory(s) bll := bllimpl.NewBll(&d) gw := gatewayimpl.New() bro := brokerimpl.New() brokers, err := bll.GetBrokers() checkerror(err) var brokerlist []string for _, value := range brokers { brokerlist = append(brokerlist, value.Endpoint) } ServerAddr, err := net.ResolveUDPAddr("udp", ":1700") checkerror(err) ServerConn, err := net.ListenUDP("udp", ServerAddr) checkerror(err) defer ServerConn.Close() buf := make([]byte, 2048) for { n, addr, err := ServerConn.ReadFromUDP(buf) checkerror(err) packettype, err := semtech.GetPacketType(buf) checkerror(err) switch packettype { case semtech.PushData: pd := new(semtech.PushDataPacket) err := pd.UnmarshalBinary(buf[0:n]) checkerror(err) err = gw.SendPushACK(ServerConn, addr, pd.ProtocolVersion, pd.RandomToken) checkerror(err) fmt.Println("<-PushACK") for _, value := range pd.Payload.RXPK { data, err := base64.StdEncoding.DecodeString(value.Data) checkerror(err) mhdr, err := lora.NewMHDRFromByte(data[0]) if err != nil { if _, ok := err.(*lora.ErrorMTypeValidationFailed); ok { log.Print(err) } else { if _, ok := err.(*lora.ErrorMajorValidationFailed); ok { log.Print(err) } else { checkerror(err) } } } else { if mhdr.IsJoinRequest() { fmt.Println("->JoinRequest") joinrequest, err := lora.NewJoinRequest(data) checkerror(err) fmt.Println(hex.EncodeToString(joinrequest.GetAppEUI())) fmt.Println(hex.EncodeToString(joinrequest.GetDevEUI())) message := &broker.Message{OriginUDPAddrNetwork: addr.Network(), OriginUDPAddrString: addr.String(), ReturnUDPAddrNetwork: ServerAddr.Network(), ReturnUDPAddrString: ServerAddr.String(), Package: value} endpoint, err := bro.FindBrokerOnAppEUI(joinrequest.GetAppEUI(), brokerlist) if err != nil { log.Print(err) } else { responsemessage, err := bro.ForwardMessage(endpoint, message) checkerror(err) txpk, err := json.Marshal(responsemessage.Package) gateway, err := bll.FindGateway(pd.GatewayMAC[:]) checkerror(err) err = gw.SendPullResp(ServerConn, gateway, pd.ProtocolVersion, pd.RandomToken, string(txpk)) checkerror(err) fmt.Println("<-JoinAccept") } } } } case semtech.PullData: pd := new(semtech.PullDataPacket) err := pd.UnmarshalBinary(buf[0:n]) checkerror(err) fmt.Println("->PullData") bll.RefreshGateway(pd.GatewayMAC[:], addr) err = gw.SendPullACK(ServerConn, addr, pd.ProtocolVersion, pd.RandomToken) checkerror(err) fmt.Println("<-PullACK") } } }
// MessageHandler ... func MessageHandler(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() contents, err := ioutil.ReadAll(r.Body) checkerror(err) var message models.Message err = json.Unmarshal(contents, &message) checkerror(err) data, err := base64.StdEncoding.DecodeString(message.Package.Data) checkerror(err) mhdr, err := lora.NewMHDRFromByte(data[0]) checkerror(err) if mhdr.IsJoinRequest() { jr, err := lora.NewJoinRequest(data) if err != nil { checkerror(err) } else { dev, err := b.GetDeviceOnAppEUIDevEUI(hex.EncodeToString(jr.GetAppEUI()), hex.EncodeToString(jr.GetDevEUI())) if err != nil { checkerror(err) } appkey, err := hex.DecodeString(dev.AppKey) if err != nil { checkerror(err) } _, err = lora.NewJoinRequestValidated(appkey, data) if err != nil { if _, ok := err.(*lora.ErrorMICValidationFailed); ok { log.Print(err) w.Write([]byte("{error: \"" + err.Error() + "\"}")) } else { checkerror(err) } } else { nwkaddr, appnonce, err := b.ProcessJoinRequest(hex.EncodeToString(jr.GetAppEUI()), hex.EncodeToString(jr.GetDevEUI()), hex.EncodeToString(jr.GetDevNonce())) if err != nil { log.Print(err) } else { if nwkaddr > 0 { joinaccept, err := lora.NewJoinAccept(appkey, 0, nwkaddr, appnonce) checkerror(err) ja, err := joinaccept.Marshal(appkey) checkerror(err) responsemessage := &models.ResponseMessage{ OriginUDPAddrNetwork: message.OriginUDPAddrNetwork, OriginUDPAddrString: message.OriginUDPAddrString, Package: semtech.TXPK{ Tmst: message.Package.Tmst + 5000000, Freq: message.Package.Freq, RFCh: message.Package.RFCh, Powe: 14, Modu: message.Package.Modu, DatR: message.Package.DatR, CodR: message.Package.CodR, IPol: true, Size: uint16(len(ja) - 4), Data: base64.StdEncoding.EncodeToString(ja)}} msg, err := json.Marshal(responsemessage) checkerror(err) w.Write(msg) } } } } } }