package localserver // import ( // "bufio" // "encoding/json" // "fmt" // "io" // "log" // "os" // "path/filepath" // "sync/atomic" // "github.com/pion/webrtc/v3" // ) // const ( // UPLOAD_INIT = "upload_init" // UPLOAD = "upload" // UPLOAD_DONE = "upload_done" // DOWNLOAD_INIT = "download_init" // DOWNLOAD = "download" // DOWNLOAD_DONE = "download_done" // HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE_INIT = "hosted_squad_download_file_response_init" // HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE = "hosted_squad_download_file_response" // HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE_END = "hosted_squad_download_file_response_end" // ) // const ( // bufferedAmountLowThreshold uint64 = 512 * 1024 // //maxBufferedAmount uint64 = 1024 * 1024 // ) // type WebrtcCallFileManager struct { // files map[string]*os.File // l *uint32 // } // func NewWebrtcCallFileManager() *WebrtcCallFileManager { // l := uint32(0) // return &WebrtcCallFileManager{ // files: make(map[string]*os.File), // l: &l, // } // } // func (w *WebrtcCallFileManager) HandleCallEvent(from string, squadId string, eventId string, payload map[string]interface{}, data []byte, manager *WebRTCCallManager) (err error) { // done, errCh := make(chan struct{}), make(chan error) // go func() { // // logger.Println("got an event in call file manager", from, eventId, payload) // switch eventId { // case UPLOAD_INIT: // if _, ok := payload["filename"]; !ok { // errCh <- fmt.Errorf("no field filename in payload") // return // } // if _, ok := payload["filename"].(string); !ok { // errCh <- fmt.Errorf("field filename in payload is not a string") // return // } // if err = w.initUpload(squadId, from, payload["filename"].(string)); err != nil { // errCh <- err // return // } // case UPLOAD: // if _, ok := payload["filename"]; !ok { // errCh <- fmt.Errorf("no field filename in payload") // return // } // if _, ok := payload["filename"].(string); !ok { // errCh <- fmt.Errorf("field filename in payload is not a string") // return // } // if err = w.upload(squadId, from, payload["filename"].(string), data); err != nil { // errCh <- err // return // } // case UPLOAD_DONE: // if _, ok := payload["filename"]; !ok { // errCh <- fmt.Errorf("no field filename in payload") // return // } // if _, ok := payload["filename"].(string); !ok { // errCh <- fmt.Errorf("field filename in payload is not a string") // return // } // if _, ok := payload["targets"]; !ok { // errCh <- fmt.Errorf("no field targets in payload") // return // } // if _, ok := payload["targets"].([]interface{}); !ok { // errCh <- fmt.Errorf("field targets in payload is not a string") // return // } // channels := []*DataChannel{} // manager.DataChannelMapMux.RLock() // for _, target := range payload["targets"].([]interface{}) { // if _, ok := manager.DataChannels[target.(string)]; !ok { // manager.DataChannelMapMux.RUnlock() // errCh <- fmt.Errorf("no corresponding datachannel : %s", target.(string)) // return // } // channel := manager.DataChannels[target.(string)] // for { // if atomic.CompareAndSwapUint32(channel.l, 0, 1) { // defer atomic.SwapUint32(channel.l, 0) // break // } // } // channels = append(channels, channel) // } // manager.DataChannelMapMux.RUnlock() // if err = w.uploadDone(squadId, from, payload["filename"].(string), channels); err != nil { // errCh <- err // return // } // case DOWNLOAD: // if _, ok := payload["filename"]; !ok { // errCh <- fmt.Errorf("no field filename in payload") // return // } // if _, ok := payload["filename"].(string); !ok { // errCh <- fmt.Errorf("field filename in payload is not a string") // return // } // if _, ok := payload["peerId"]; !ok { // errCh <- fmt.Errorf("no field peerId in payload") // return // } // if _, ok := payload["peerId"].(string); !ok { // errCh <- fmt.Errorf("field peerId in payload is not a string") // return // } // manager.DataChannelMapMux.RLock() // if _, ok := manager.DataChannels[payload["peerId"].(string)]; !ok { // manager.DataChannelMapMux.RUnlock() // errCh <- fmt.Errorf("no corresponding datachannel") // return // } // channel := manager.DataChannels[payload["peerId"].(string)] // for { // if atomic.CompareAndSwapUint32(channel.l, 0, 1) { // // logger.Println("atomic lock unlocked") // defer atomic.SwapUint32(channel.l, 0) // break // } // } // manager.DataChannelMapMux.RUnlock() // if err = w.download(squadId, from, payload["filename"].(string), channel.DataChannel); err != nil { // errCh <- err // return // } // } // done <- struct{}{} // }() // select { // case <-done: // return nil // case err = <-errCh: // return // } // } // func (w *WebrtcCallFileManager) initUpload(squadId string, from string, fileName string) (err error) { // for { // if atomic.CompareAndSwapUint32(w.l, 0, 1) { // defer atomic.SwapUint32(w.l, 0) // if _, dirErr := os.Stat(filepath.Join(dataPath, dataPath, "data", "squads", squadId)); os.IsNotExist(dirErr) { // if err = os.MkdirAll(filepath.Join(dataPath, dataPath, "data", "squads", squadId), 0700); err != nil { // return // } // } // f, fErr := os.Create(filepath.Join(dataPath, dataPath, "data", "squads", squadId, fileName)) // if err != nil { // return fErr // } // f.Close() // f, fErr = os.OpenFile(filepath.Join(dataPath, dataPath, "data", "squads", squadId, fileName), os.O_APPEND|os.O_WRONLY, 0644) // if err != nil { // return fErr // } // w.files[fileName] = f // break // } else { // continue // } // } // return // } // func (w *WebrtcCallFileManager) upload(squadId string, from string, fileName string, data []byte) (err error) { // for { // if atomic.CompareAndSwapUint32(w.l, 0, 1) { // defer atomic.SwapUint32(w.l, 0) // if _, ok := w.files[fileName]; !ok { // err = fmt.Errorf("no open file with name %s", fileName) // return // } // _, err = w.files[fileName].Write(data) // break // } else { // continue // } // } // return // } // func (w *WebrtcCallFileManager) uploadDone(squadId string, from string, fileName string, channels []*DataChannel) (err error) { // for { // if atomic.CompareAndSwapUint32(w.l, 0, 1) { // defer atomic.SwapUint32(w.l, 0) // if _, ok := w.files[fileName]; !ok { // err = fmt.Errorf("no open file with name %s", fileName) // return // } // err = w.files[fileName].Close() // delete(w.files, fileName) // bsInit, jsonErr := json.Marshal(map[string]interface{}{ // "type": UPLOAD_DONE, // "from": "server", // "payload": map[string]string{ // "path": fileName, // }, // }) // if jsonErr != nil { // return jsonErr // } // for _, channel := range channels { // if err = channel.DataChannel.SendText(string(bsInit)); err != nil { // return // } // } // break // } else { // continue // } // } // return // } // func (w *WebrtcCallFileManager) download(squadId string, dst string, fileName string, channel *webrtc.DataChannel) (err error) { // // logger.Println("got called") // if _, dirErr := os.Stat(filepath.Join(dataPath, dataPath, "data", "squads", squadId, fileName)); os.IsNotExist(dirErr) { // // logger.Println("file does not exist :", filepath.Join(dataPath, "data", "squads", squadId, fileName)) // return // } // f, err := os.Open(filepath.Join(dataPath, dataPath, "data", "squads", squadId, fileName)) // if err != nil { // return // } // defer f.Close() // bsInit, err := json.Marshal(map[string]interface{}{ // "type": HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE_INIT, // "from": "server", // "payload": map[string]string{ // "path": fileName, // }, // }) // if err != nil { // return // } // if err = channel.SendText(string(bsInit)); err != nil { // return // } // r := bufio.NewReader(f) // buf := make([]byte, 0, 30000) // // logger.Println("start reading") // for { // n, readErr := r.Read(buf[:cap(buf)]) // buf = buf[:n] // if n == 0 { // if err == nil { // // logger.Println("n is 0 weird") // break // } // if err == io.EOF { // break // } // log.Fatal(readErr) // } // bs, jsonErr := json.Marshal(map[string]interface{}{ // "type": HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE, // "from": "server", // "payload": map[string]interface{}{ // "path": fileName, // "content": buf, // }, // }) // if jsonErr != nil { // return jsonErr // } // if err = channel.SendText(string(bs)); err != nil { // return // } // } // // logger.Println("stop reading") // bs, err := json.Marshal(map[string]interface{}{ // "type": HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE_END, // "from": "server", // "payload": map[string]string{ // "path": fileName, // }, // }) // if err != nil { // return // } // if err = channel.SendText(string(bs)); err != nil { // return // } // // logger.Println("done") // return // }