예제 #1
0
func main() {
	var call = ""
	c, err := eventsocket.Dial("localhost:8021", "ClueCon")
	if err != nil {
		log.Fatal(err)
	}
	c.Send("events json ALL")
	c.Send(fmt.Sprintf("bgapi originate %s 9196 xml default", dest))
	for {
		ev, err := c.ReadEvent()
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("\nNew event")
		ev.PrettyPrint()
		if ev.Get("Answer-State") == "hangup" {
			log.Fatal("Not working")
			break
		}
		if ev.Get("Answer-State") == "answered" {
			fmt.Println("We got the call: ", ev.Get("Unique-Id"))
			call = ev.Get("Unique-Id")
		}
		if ev.Get("Session-Count") >= "1" {
			fmt.Println("Call in progress: ", ev.Get("Session-Count"))
			//time.Sleep(3000 * time.Millisecond)
			fmt.Println("Bye bye: ", call)
			c.SendMsg(eventsocket.MSG{"call-command": "hangup", "hangup-cause": "we're done!"}, call, "")
			break
		}
	}
	fmt.Println("Closing socker")
	c.Close()
}
예제 #2
0
func main() {
	fmt.Println("***** Starting....................***********")
	c, err := eventsocket.Dial("localhost:8021", "ClueCon")
	if err != nil {
		log.Fatal(err)
	}
	c.Send("events plain ALL")

	for {
		ev, err := c.ReadEvent()
		if err != nil {
			log.Fatal(err)
		}
		//fmt.Println("\nNew event")
		//ev.PrettyPrint()
		confClass := ev.Get("Event-Subclass")
		if confClass == "conference::maintenance" {
			callingFunction := ev.Get("Event-Calling-Function")
			//uniqueId := ev.Get("Caller-Unique-ID")

			switch callingFunction {
			case "conference_add_member":
				fmt.Printf("\n=====%s=====\n", callingFunction)
				ev.PrettyPrint()
				fmt.Printf("\n***************\n")
				//handleUseJoinedEvent(ev)
			case "conference_del_member":
				fmt.Printf("\n=====%s=====\n", callingFunction)
				ev.PrettyPrint()
				fmt.Printf("\n***************\n")
			case "conf_api_sub_mute":
				fmt.Printf("\n=====%s=====\n", callingFunction)
				ev.PrettyPrint()
				fmt.Printf("\n***************\n")
			case "conf_api_sub_unmute":
				fmt.Printf("\n=====%s=====\n", callingFunction)
				ev.PrettyPrint()
				fmt.Printf("\n***************\n")
			case "conference_record_thread_run":
				fmt.Printf("\n=====%s=====\n", callingFunction)
				ev.PrettyPrint()
				fmt.Printf("\n***************\n")
				//action := ev.Get("Action")
			case "conference_loop_input":
				fmt.Printf("\n=====%s=====\n", callingFunction)
				ev.PrettyPrint()
				fmt.Printf("\n***************\n")
			default:
				fmt.Printf("\ndefault: %s\n", callingFunction)
			}
		}
	}
	c.Close()
}
예제 #3
0
func handleServer(fsServer server, eventChannel chan eventsocket.Event, messagesChannel chan message, done chan bool, startedGoroutines *int) {

	//create the full server name as well as destinaion and dialplan if needed at some point
	fullServer := fsServer.Host + ":" + strconv.Itoa(fsServer.Port)
	// dest := "sofia/mydomain.com/1000@" + fsServer.Host
	// dialplan := "&socket(" + fsServer.Host + ":9090 async full)"

	//connects to the server
	c, err := eventsocket.Dial(fullServer, fsServer.Password)
	if err != nil {
		log.Fatal(err)
	}

	//at the end it closes the connection to the server
	defer c.Close()

	//set which messages
	c.Send("events json ALL")

	//sends the event
	// c.Send(fmt.Sprintf("bgapi originate %s", dest))
	for {
		ev, err := c.ReadEvent()
		if err != nil {
			log.Fatal(err)
		}

		//checks what to do next with the message
		select {
		case eventChannel <- *ev:
			//sends the event to the channel

		case message := <-messagesChannel:
			if message.Host == fsServer.Host {
				fmt.Println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\nmessage host:\t" + message.Host + "\nserver host:\t" + fsServer.Host + "\nmessage sent:\t" + message.Message + "\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
			}
		case <-done:
			*startedGoroutines--
			fmt.Println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\nCLOSED server " + fsServer.Host + " goroutine, " + strconv.Itoa(*startedGoroutines) + " goroutines left to close\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
			return
		}

		//prints out the event
		fmt.Println("\nNew event")
		ev.PrettyPrint()

		//checks if a hangup happened and returns the function
		if ev.Get("Answer-State") == "hangup" {
			*startedGoroutines--
			// break
			return
		}
	}
}
예제 #4
0
// SetSoftmodemFallback saves the given softmodem fallback setting for a caller id
// to FreeSWITCH's mod_db
func SetSoftmodemFallback(c *eventsocket.Connection, cidnum string, enabled bool) error {
	if !Config.Freeswitch.SoftmodemFallback || cidnum == "" {
		return nil
	}

	var err error
	if c == nil {
		c, err = eventsocket.Dial(Config.Freeswitch.Socket, Config.Freeswitch.Password)
		if err != nil {
			return err
		}
		defer c.Close()
	}

	return FreeSwitchDBInsert(c, modDbFallbackRealm, cidnum, fmt.Sprintf("%d", time.Now().Unix()))
}
예제 #5
0
func (f *Fs_Gateway) Rescan() bool {
	conf, result := config.SetConfig("conf.ini")
	if result == false {
		logger.Debug("load the config file failed")
		return false
	}

	var Fshost, Fsauth, Fsport string
	//var Fsport,Fstime int

	Fshost, result = conf.GetValue("freeswitch", "fshost")
	if result == false {
		return false
	}
	Fsport, result = conf.GetValue("freeswitch", "fsport")
	if result == false {
		return false
	}
	Fsauth, result = conf.GetValue("freeswitch", "fsauth")
	if result == false {
		return false
	}
	//Fstime, err := iniconf.Int("timeout",500)
	c, err := eventsocket.Dial(Fshost+":"+Fsport, Fsauth)
	if err != nil {
		fmt.Println(err)
		//log.Fatal(err)
		return false
	}
	defer c.Close()
	//sofia profile external rescan
	// sofia profile external rescan reloadxml
	//ev, err := c.Send(fmt.Sprintf("bgapi %s", dial_string))
	ev, err := c.Send("bgapi sofia profile external rescan reloadxml")
	if err != nil {
		fmt.Println(err)
		//log.Fatal(err)
		return false
	}
	//	if len(ev.Body) > 0  {
	//		fmt.Println(ev.Body)
	//		return true
	//	}
	fmt.Println(ev.Get("Reply-Text"))
	ev.PrettyPrint()
	return true
}
예제 #6
0
func main() {
	c, err := eventsocket.Dial("localhost:8021", "ClueCon")
	if err != nil {
		log.Fatal(err)
	}
	c.Send("events json ALL")
	c.Send(fmt.Sprintf("bgapi originate %s %s", dest, dialplan))
	for {
		ev, err := c.ReadEvent()
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("\nNew event")
		ev.PrettyPrint()
		if ev.Get("Answer-State") == "hangup" {
			break
		}
	}
	c.Close()
}
예제 #7
0
// GetSoftmodemFallback checks if fallback to SpanDSP's softmodem (no T.38)
// should be enabled for the given callerid number
func GetSoftmodemFallback(c *eventsocket.Connection, cidnum string) (bool, error) {
	if !Config.Freeswitch.SoftmodemFallback || cidnum == "" {
		return false, nil
	}

	var err error
	if c == nil {
		c, err = eventsocket.Dial(Config.Freeswitch.Socket, Config.Freeswitch.Password)
		if err != nil {
			return false, err
		}
		defer c.Close()
	}

	exists, err := FreeSwitchDBExists(c, modDbFallbackRealm, cidnum)
	if err != nil {
		return false, err
	}

	return exists, nil
}
예제 #8
0
func secretaryCallOut(s *Session) {

	c, err := eventsocket.Dial("192.168.36.1:8021", "ClueCon")
	if err != nil {
		fmt.Println("Failed to connect to FreeSWITCH: ", err)
		s.c.Execute("hangup", "", false)
		return
	}

	var uuid string

	{
		ev, err := c.Send("api create_uuid")
		if err != nil {
			fmt.Println("Failed uuid_create: ", err)
			s.c.Execute("hangup", "", false)
			return
		}

		uuid = ev.Body
	}

	s.secretary_uuid = uuid

	cmd := "api originate " +
		fmt.Sprintf(
			"{ignore_early_media=true,"+
				"origination_uuid=%s,"+
				"originate_timeout=60,origination_caller_id_number=83388585,"+
				"origination_caller_id_name='%s'}sofia/gateway/serv36/18874220005",
			uuid,
			s.callername) +
		" &playback(silence_stream://-1)"

	{
		_, err := c.Send(cmd)
		if err != nil {
			fmt.Println("Error calling out: ", err)
			c.Send("api uuid_break " + s.inbound_uuid)
			return
		}
	}

	started := time.Now()
	digit := ""

	for time.Since(started).Seconds() < 60 && digit == "" {

		ev, err := c.Send("api uuid_exists " + s.secretary_uuid)
		if err != nil || ev.Body == "false" {
			break
		}

		digit = playAndGetOneDigit(
			"ivr/ivr-welcome_to_freeswitch.wav",
			c, s.secretary_uuid)
	}

	if digit == "" || digit == "0" {
		c.Send("api uuid_kill " + s.secretary_uuid)
		c.Send("api uuid_break " + s.inbound_uuid)
	} else {
		fmt.Println("inbond_uuid:" + s.inbound_uuid + " sec_uuid:" + s.secretary_uuid)
		c.Send("api uuid_bridge " + s.inbound_uuid +
			" " + s.secretary_uuid)
	}

	c.Close()
}
예제 #9
0
// Connect to FreeSWITCH and originate a txfax
func (t *transmission) start() {

	if t.faxjob.Number == "" {
		t.errorChan <- NewFaxError("Number to dial is empty", false)
		return
	}

	if _, err := os.Stat(t.faxjob.Filename); err != nil {
		t.errorChan <- NewFaxError(err.Error(), false)
		return
	}

	var err error
	t.conn, err = eventsocket.Dial(gofaxlib.Config.Freeswitch.Socket, gofaxlib.Config.Freeswitch.Password)
	if err != nil {
		t.errorChan <- NewFaxError(err.Error(), true)
		return
	}
	defer t.conn.Close()

	// Enable event filter and events
	_, err = t.conn.Send(fmt.Sprintf("filter Unique-ID %v", t.faxjob.UUID))
	if err != nil {
		t.errorChan <- NewFaxError(err.Error(), true)
		return
	}
	_, err = t.conn.Send("event plain CHANNEL_CALLSTATE CUSTOM spandsp::txfaxnegociateresult spandsp::txfaxpageresult spandsp::txfaxresult")
	if err != nil {
		t.errorChan <- NewFaxError(err.Error(), true)
		return
	}

	// Check if T.38 should be disabled
	disableT38 := gofaxlib.Config.Freeswitch.DisableT38
	if disableT38 {
		t.sessionlog.Log("T.38 disabled by configuration")
	} else {
		disableT38, err = gofaxlib.GetSoftmodemFallback(t.conn, t.faxjob.Number)
		if err != nil {
			t.sessionlog.Log(err)
			disableT38 = false
		}
		if disableT38 {
			t.sessionlog.Log(fmt.Sprintf("Softmodem fallback active for destination %s, disabling T.38", t.faxjob.Number))
		}
	}

	// Assemble dialstring
	dsVariablesMap := map[string]string{
		"ignore_early_media":           "true",
		"origination_uuid":             t.faxjob.UUID.String(),
		"origination_caller_id_number": t.faxjob.Cidnum,
		"origination_caller_id_name":   t.faxjob.Cidname,
		"fax_ident":                    t.faxjob.Ident,
		"fax_header":                   t.faxjob.Header,
		"fax_use_ecm":                  strconv.FormatBool(t.faxjob.UseECM),
		"fax_verbose":                  strconv.FormatBool(gofaxlib.Config.Freeswitch.Verbose),
	}

	if disableT38 {
		dsVariablesMap["fax_enable_t38"] = "false"
	} else {
		dsVariablesMap["fax_enable_t38"] = "true"
	}

	dsVariablesPairs := make([]string, len(dsVariablesMap))
	i := 0
	for k, v := range dsVariablesMap {
		dsVariablesPairs[i] = fmt.Sprintf("%v='%v'", k, v)
		i++
	}
	dsVariables := strings.Join(dsVariablesPairs, ",")

	// Try gateways in configured order
	dsGatewaysStrings := make([]string, len(gofaxlib.Config.Freeswitch.Gateway))
	for i, gw := range gofaxlib.Config.Freeswitch.Gateway {
		dsGatewaysStrings[i] = fmt.Sprintf("sofia/gateway/%v/%v", gw, t.faxjob.Number)
	}
	dsGateways := strings.Join(dsGatewaysStrings, "|")

	dialstring := fmt.Sprintf("{%v}%v", dsVariables, dsGateways)
	//t.sessionlog.Log(fmt.Sprintf("%v Dialstring: %v", faxjob.UUID, dialstring))

	// Originate call
	t.sessionlog.Log("Originating channel to", t.faxjob.Number)
	_, err = t.conn.Send(fmt.Sprintf("api originate %v, &txfax(%v)", dialstring, t.faxjob.Filename))
	if err != nil {
		t.conn.Send(fmt.Sprintf("uuid_dump %v", t.faxjob.UUID))
		hangupcause := strings.TrimSpace(err.Error())
		t.sessionlog.Log("Originate failed with hangup cause", hangupcause)
		t.errorChan <- NewFaxError(hangupcause, true)
		return
	}
	t.sessionlog.Log("Originate successful")

	result := gofaxlib.NewFaxResult(t.faxjob.UUID, t.sessionlog)

	es := gofaxlib.NewEventStream(t.conn)
	var pages uint

	// Listen for system signals to be able to kill the channel
	sigchan := make(chan os.Signal, 1)
	signal.Notify(sigchan, syscall.SIGTERM, syscall.SIGINT)

	for {
		select {
		case ev := <-es.Events():
			result.AddEvent(ev)
			if result.Hangupcause != "" {

				// If transmission failed:
				// Check if softmodem fallback should be enabled on the next call
				if gofaxlib.Config.Freeswitch.SoftmodemFallback && !result.Success {
					var activateFallback bool

					if result.NegotiateCount > 1 {
						// Activate fallback if negotiation was repeated
						t.sessionlog.Log(fmt.Sprintf("Fax failed with %d negotiations, enabling softmodem fallback for calls from/to %s.", result.NegotiateCount, t.faxjob.Number))
						activateFallback = true
					} else {
						var badrows uint
						for _, p := range result.PageResults {
							badrows += p.BadRows
						}
						if badrows > 0 {
							// Activate fallback if any bad rows were present
							t.sessionlog.Log(fmt.Sprintf("Fax failed with %d bad rows in %d pages, enabling softmodem fallback for calls from/to %s.", badrows, result.TransferredPages, t.faxjob.Number))
							activateFallback = true
						}
					}

					if activateFallback {
						err = gofaxlib.SetSoftmodemFallback(t.conn, t.faxjob.Number, true)
						if err != nil {
							t.sessionlog.Log(err)
						}
					}

				}

				t.resultChan <- result
				return
			}
			if ev.Get("Event-Subclass") == "spandsp::txfaxnegociateresult" {
				t.resultChan <- result
			} else if result.TransferredPages != pages {
				pages = result.TransferredPages
				t.pageChan <- &result.PageResults[pages-1]
			}
		case err := <-es.Errors():
			t.errorChan <- NewFaxError(err.Error(), true)
			return
		case kill := <-sigchan:
			t.sessionlog.Log(fmt.Sprintf("%v Received signal %v, destroying channel", t.faxjob.UUID, kill))
			t.conn.Send(fmt.Sprintf("api uuid_kill %v", t.faxjob.UUID))
			os.Remove(t.faxjob.Filename)
			t.errorChan <- NewFaxError(fmt.Sprintf("Killed by signal %v", kill), false)
		}
	}

}