Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
179 lines (148 sloc) 5.29 KB
// Copyright © 2017 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.
package ttnsdk
import (
// ClientVersion to use
var ClientVersion = "2.x.x"
// ClientConfig contains the configuration for the API client. Use the NewConfig() or NewCommunityConfig() functions to
// initialize your configuration, otherwise NewClient will panic.
type ClientConfig struct {
initialized bool
Logger log.Interface
// The name of this client
ClientName string
// The version of this client (in the default config, this is the value of ttnsdk.ClientVersion)
ClientVersion string
// TLS Configuration only has to be set if connecting with servers that do not have trusted certificates.
TLSConfig *tls.Config
// Address of the Account Server (in the default config, this is
AccountServerAddress string
// Client ID for the account server (if you registered your client)
AccountServerClientID string
// Client Secret for the account server (if you registered your client)
AccountServerClientSecret string
// Address of the Discovery Server (in the default config, this is
DiscoveryServerAddress string
// Set this to true if the Discovery Server is insecure (not recommended)
DiscoveryServerInsecure bool
// Address of the Handler (optional)
HandlerAddress string
// Timeout for requests (in the default config, this is 10 seconds)
RequestTimeout time.Duration
appID string
appAccessKey string
// NewCommunityConfig creates a new configuration for the API client that is pre-configured for the Public Community Network.
func NewCommunityConfig(clientName string) ClientConfig {
return NewConfig(clientName, "", "")
// NewConfig creates a new configuration for the API client.
func NewConfig(clientName, accountServerAddress, discoveryServerAddress string) ClientConfig {
return ClientConfig{
initialized: true,
Logger: log.Get(),
ClientName: clientName,
ClientVersion: ClientVersion,
AccountServerAddress: accountServerAddress,
AccountServerClientID: clientName,
DiscoveryServerAddress: discoveryServerAddress,
RequestTimeout: 10 * time.Second,
// NewClient creates a new API client from the configuration, using the given Application ID and Application access key.
func (c ClientConfig) NewClient(appID, appAccessKey string) Client {
c.appID = appID
c.appAccessKey = appAccessKey
return newClient(c)
// DialOptions to use when connecting to components
var DialOptions = []grpc.DialOption{
func newClient(config ClientConfig) Client {
if !config.initialized {
panic("ttn-sdk: ClientConfig not initialized. Use ttnsdk.NewConfig or ttnsdk.NewCommunityConfig to generate your configuration")
client := &client{
ClientConfig: config,
transportCredentials: credentials.NewTLS(config.TLSConfig),
if config.AccountServerAddress != "" {
client.account = account.New(config.AccountServerAddress)
return client
// Client interface for The Things Network's API.
type Client interface {
// Close the client and clean up all connections
Close() error
// Subscribe to uplink and events, publish downlink
PubSub() (ApplicationPubSub, error)
// Manage the application
ManageApplication() (ApplicationManager, error)
// Manage devices in the application
ManageDevices() (DeviceManager, error)
// Simulate uplink messages for a device (for testing)
Simulate(devID string) (Simulator, error)
type client struct {
transportCredentials credentials.TransportCredentials
account *account.Account
discovery struct {
conn *grpc.ClientConn
handler struct {
announcement *discovery.Announcement
conn *grpc.ClientConn
mqtt struct {
client mqtt.Client
ctx context.Context
cancel context.CancelFunc
func (c *client) getContext(ctx context.Context) context.Context {
ctx = ttnctx.OutgoingContextWithServiceInfo(ctx, c.ClientConfig.ClientName, c.ClientConfig.ClientVersion, "")
if c.appAccessKey != "" {
ctx = ttnctx.OutgoingContextWithKey(ctx, c.appAccessKey)
return ctx
func (c *client) Close() (closeErr error) {
if err := c.closeHandler(); err != nil {
closeErr = err
if err := c.closeDiscovery(); err != nil && closeErr == nil {
closeErr = err
if err := c.closeMQTT(); err != nil && closeErr == nil {
closeErr = err
You can’t perform that action at this time.