khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2018-present Open Networking Foundation |
| 3 | |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
npujar | 1d86a52 | 2019-11-14 17:11:16 +0530 | [diff] [blame] | 16 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 17 | package remote |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 18 | |
| 19 | import ( |
| 20 | "context" |
serkant.uluderya | 8ff291d | 2020-05-20 00:58:00 -0700 | [diff] [blame] | 21 | |
serkant.uluderya | 2ae470f | 2020-01-21 11:13:09 -0800 | [diff] [blame] | 22 | "github.com/opencord/voltha-lib-go/v3/pkg/kafka" |
| 23 | "github.com/opencord/voltha-lib-go/v3/pkg/log" |
| 24 | ic "github.com/opencord/voltha-protos/v3/go/inter_container" |
| 25 | "github.com/opencord/voltha-protos/v3/go/openflow_13" |
| 26 | "github.com/opencord/voltha-protos/v3/go/voltha" |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 27 | ) |
| 28 | |
npujar | 1d86a52 | 2019-11-14 17:11:16 +0530 | [diff] [blame] | 29 | // AdapterProxy represents adapter proxy attributes |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 30 | type AdapterProxy struct { |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 31 | kafka.EndpointManager |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 32 | deviceTopicRegistered bool |
serkant.uluderya | 8ff291d | 2020-05-20 00:58:00 -0700 | [diff] [blame] | 33 | coreTopic string |
npujar | 467fe75 | 2020-01-16 20:17:45 +0530 | [diff] [blame] | 34 | kafkaICProxy kafka.InterContainerProxy |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 35 | } |
| 36 | |
npujar | 1d86a52 | 2019-11-14 17:11:16 +0530 | [diff] [blame] | 37 | // NewAdapterProxy will return adapter proxy instance |
serkant.uluderya | 8ff291d | 2020-05-20 00:58:00 -0700 | [diff] [blame] | 38 | func NewAdapterProxy(kafkaProxy kafka.InterContainerProxy, coreTopic string, endpointManager kafka.EndpointManager) *AdapterProxy { |
Kent Hagerman | a6d0c36 | 2019-07-30 12:50:21 -0400 | [diff] [blame] | 39 | return &AdapterProxy{ |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 40 | EndpointManager: endpointManager, |
Kent Hagerman | a6d0c36 | 2019-07-30 12:50:21 -0400 | [diff] [blame] | 41 | kafkaICProxy: kafkaProxy, |
serkant.uluderya | 8ff291d | 2020-05-20 00:58:00 -0700 | [diff] [blame] | 42 | coreTopic: coreTopic, |
Kent Hagerman | a6d0c36 | 2019-07-30 12:50:21 -0400 | [diff] [blame] | 43 | deviceTopicRegistered: false, |
| 44 | } |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 45 | } |
| 46 | |
serkant.uluderya | 334479d | 2019-04-10 08:26:15 -0700 | [diff] [blame] | 47 | func (ap *AdapterProxy) getCoreTopic() kafka.Topic { |
serkant.uluderya | 8ff291d | 2020-05-20 00:58:00 -0700 | [diff] [blame] | 48 | return kafka.Topic{Name: ap.coreTopic} |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 49 | } |
| 50 | |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 51 | func (ap *AdapterProxy) getAdapterTopic(deviceID string, adapterType string) (*kafka.Topic, error) { |
| 52 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 53 | endpoint, err := ap.GetEndpoint(deviceID, adapterType) |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 54 | if err != nil { |
| 55 | return nil, err |
| 56 | } |
| 57 | |
| 58 | return &kafka.Topic{Name: string(endpoint)}, nil |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 59 | } |
| 60 | |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 61 | func (ap *AdapterProxy) sendRPC(ctx context.Context, rpc string, toTopic *kafka.Topic, replyToTopic *kafka.Topic, |
| 62 | waitForResponse bool, deviceID string, kvArgs ...*kafka.KVArg) (chan *kafka.RpcResponse, error) { |
| 63 | |
| 64 | // Sent the request to kafka |
| 65 | respChnl := ap.kafkaICProxy.InvokeAsyncRPC(ctx, rpc, toTopic, replyToTopic, waitForResponse, deviceID, kvArgs...) |
| 66 | |
| 67 | // Wait for first response which would indicate whether the request was successfully sent to kafka. |
| 68 | firstResponse, ok := <-respChnl |
| 69 | if !ok || firstResponse.MType != kafka.RpcSent { |
Girish Kumar | f56a468 | 2020-03-20 20:07:46 +0000 | [diff] [blame] | 70 | logger.Errorw("failure to request to kafka", log.Fields{"rpc": rpc, "device-id": deviceID, "error": firstResponse.Err}) |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 71 | return nil, firstResponse.Err |
| 72 | } |
| 73 | // return the kafka channel for the caller to wait for the response of the RPC call |
| 74 | return respChnl, nil |
| 75 | } |
| 76 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 77 | // AdoptDevice invokes adopt device rpc |
| 78 | func (ap *AdapterProxy) AdoptDevice(ctx context.Context, device *voltha.Device) (chan *kafka.RpcResponse, error) { |
| 79 | logger.Debugw("AdoptDevice", log.Fields{"device-id": device.Id}) |
khenaidoo | 92e62c5 | 2018-10-03 14:02:54 -0400 | [diff] [blame] | 80 | rpc := "adopt_device" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 81 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 82 | if err != nil { |
| 83 | return nil, err |
| 84 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 85 | args := []*kafka.KVArg{ |
| 86 | {Key: "device", Value: device}, |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 87 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 88 | replyToTopic := ap.getCoreTopic() |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 89 | ap.deviceTopicRegistered = true |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 90 | logger.Debugw("adoptDevice-send-request", log.Fields{"device-id": device.Id, "deviceType": device.Type, "serialNumber": device.SerialNumber}) |
| 91 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | 92e62c5 | 2018-10-03 14:02:54 -0400 | [diff] [blame] | 92 | } |
| 93 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 94 | // DisableDevice invokes disable device rpc |
| 95 | func (ap *AdapterProxy) DisableDevice(ctx context.Context, device *voltha.Device) (chan *kafka.RpcResponse, error) { |
| 96 | logger.Debugw("DisableDevice", log.Fields{"device-id": device.Id}) |
khenaidoo | 92e62c5 | 2018-10-03 14:02:54 -0400 | [diff] [blame] | 97 | rpc := "disable_device" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 98 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 99 | if err != nil { |
| 100 | return nil, err |
| 101 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 102 | args := []*kafka.KVArg{ |
| 103 | {Key: "device", Value: device}, |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 104 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 105 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 106 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 107 | } |
| 108 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 109 | // ReEnableDevice invokes reenable device rpc |
| 110 | func (ap *AdapterProxy) ReEnableDevice(ctx context.Context, device *voltha.Device) (chan *kafka.RpcResponse, error) { |
| 111 | logger.Debugw("ReEnableDevice", log.Fields{"device-id": device.Id}) |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 112 | rpc := "reenable_device" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 113 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 114 | if err != nil { |
| 115 | return nil, err |
| 116 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 117 | args := []*kafka.KVArg{ |
| 118 | {Key: "device", Value: device}, |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 119 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 120 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 121 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 122 | } |
| 123 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 124 | // RebootDevice invokes reboot device rpc |
| 125 | func (ap *AdapterProxy) RebootDevice(ctx context.Context, device *voltha.Device) (chan *kafka.RpcResponse, error) { |
| 126 | logger.Debugw("RebootDevice", log.Fields{"device-id": device.Id}) |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 127 | rpc := "reboot_device" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 128 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 129 | if err != nil { |
| 130 | return nil, err |
| 131 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 132 | args := []*kafka.KVArg{ |
| 133 | {Key: "device", Value: device}, |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 134 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 135 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 136 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 137 | } |
| 138 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 139 | // DeleteDevice invokes delete device rpc |
| 140 | func (ap *AdapterProxy) DeleteDevice(ctx context.Context, device *voltha.Device) (chan *kafka.RpcResponse, error) { |
| 141 | logger.Debugw("DeleteDevice", log.Fields{"device-id": device.Id}) |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 142 | rpc := "delete_device" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 143 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 144 | if err != nil { |
| 145 | return nil, err |
| 146 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 147 | args := []*kafka.KVArg{ |
| 148 | {Key: "device", Value: device}, |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 149 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 150 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 151 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 152 | } |
| 153 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 154 | // GetOfpDeviceInfo invokes get ofp device info rpc |
| 155 | func (ap *AdapterProxy) GetOfpDeviceInfo(ctx context.Context, device *voltha.Device) (chan *kafka.RpcResponse, error) { |
| 156 | logger.Debugw("GetOfpDeviceInfo", log.Fields{"device-id": device.Id}) |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 157 | rpc := "get_ofp_device_info" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 158 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 159 | if err != nil { |
| 160 | return nil, err |
| 161 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 162 | args := []*kafka.KVArg{ |
| 163 | {Key: "device", Value: device}, |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 164 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 165 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 166 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 167 | } |
| 168 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 169 | // GetOfpPortInfo invokes get ofp port info rpc |
| 170 | func (ap *AdapterProxy) GetOfpPortInfo(ctx context.Context, device *voltha.Device, portNo uint32) (chan *kafka.RpcResponse, error) { |
| 171 | logger.Debugw("GetOfpPortInfo", log.Fields{"device-id": device.Id, "port-no": portNo}) |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 172 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 173 | if err != nil { |
| 174 | return nil, err |
| 175 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 176 | args := []*kafka.KVArg{ |
| 177 | {Key: "device", Value: device}, |
| 178 | {Key: "port_no", Value: &ic.IntType{Val: int64(portNo)}}, |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 179 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 180 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 181 | return ap.sendRPC(ctx, "get_ofp_port_info", toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | 4d4802d | 2018-10-04 21:59:49 -0400 | [diff] [blame] | 182 | } |
| 183 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 184 | // ReconcileDevice invokes reconcile device rpc |
| 185 | func (ap *AdapterProxy) ReconcileDevice(ctx context.Context, device *voltha.Device) (chan *kafka.RpcResponse, error) { |
| 186 | logger.Debugw("ReconcileDevice", log.Fields{"device-id": device.Id}) |
Matt Jeanneret | 7cf8e0b | 2020-01-09 11:57:51 -0500 | [diff] [blame] | 187 | rpc := "reconcile_device" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 188 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 189 | if err != nil { |
| 190 | return nil, err |
| 191 | } |
khenaidoo | ba6b6c4 | 2019-08-02 09:11:56 -0400 | [diff] [blame] | 192 | args := []*kafka.KVArg{ |
| 193 | {Key: "device", Value: device}, |
| 194 | } |
khenaidoo | ba6b6c4 | 2019-08-02 09:11:56 -0400 | [diff] [blame] | 195 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 196 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 197 | } |
| 198 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 199 | // DownloadImage invokes download image rpc |
| 200 | func (ap *AdapterProxy) DownloadImage(ctx context.Context, device *voltha.Device, download *voltha.ImageDownload) (chan *kafka.RpcResponse, error) { |
| 201 | logger.Debugw("DownloadImage", log.Fields{"device-id": device.Id, "image": download.Name}) |
khenaidoo | f5a5bfa | 2019-01-23 22:20:29 -0500 | [diff] [blame] | 202 | rpc := "download_image" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 203 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 204 | if err != nil { |
| 205 | return nil, err |
| 206 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 207 | args := []*kafka.KVArg{ |
| 208 | {Key: "device", Value: device}, |
| 209 | {Key: "request", Value: download}, |
khenaidoo | f5a5bfa | 2019-01-23 22:20:29 -0500 | [diff] [blame] | 210 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 211 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 212 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 213 | } |
| 214 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 215 | // GetImageDownloadStatus invokes get image download status rpc |
| 216 | func (ap *AdapterProxy) GetImageDownloadStatus(ctx context.Context, device *voltha.Device, download *voltha.ImageDownload) (chan *kafka.RpcResponse, error) { |
| 217 | logger.Debugw("GetImageDownloadStatus", log.Fields{"device-id": device.Id, "image": download.Name}) |
khenaidoo | f5a5bfa | 2019-01-23 22:20:29 -0500 | [diff] [blame] | 218 | rpc := "get_image_download_status" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 219 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 220 | if err != nil { |
| 221 | return nil, err |
| 222 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 223 | args := []*kafka.KVArg{ |
| 224 | {Key: "device", Value: device}, |
| 225 | {Key: "request", Value: download}, |
khenaidoo | f5a5bfa | 2019-01-23 22:20:29 -0500 | [diff] [blame] | 226 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 227 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 228 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 229 | } |
| 230 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 231 | // CancelImageDownload invokes cancel image download rpc |
| 232 | func (ap *AdapterProxy) CancelImageDownload(ctx context.Context, device *voltha.Device, download *voltha.ImageDownload) (chan *kafka.RpcResponse, error) { |
| 233 | logger.Debugw("CancelImageDownload", log.Fields{"device-id": device.Id, "image": download.Name}) |
khenaidoo | f5a5bfa | 2019-01-23 22:20:29 -0500 | [diff] [blame] | 234 | rpc := "cancel_image_download" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 235 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 236 | if err != nil { |
| 237 | return nil, err |
| 238 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 239 | args := []*kafka.KVArg{ |
| 240 | {Key: "device", Value: device}, |
| 241 | {Key: "request", Value: download}, |
khenaidoo | f5a5bfa | 2019-01-23 22:20:29 -0500 | [diff] [blame] | 242 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 243 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 244 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 245 | } |
| 246 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 247 | // ActivateImageUpdate invokes activate image update rpc |
| 248 | func (ap *AdapterProxy) ActivateImageUpdate(ctx context.Context, device *voltha.Device, download *voltha.ImageDownload) (chan *kafka.RpcResponse, error) { |
| 249 | logger.Debugw("ActivateImageUpdate", log.Fields{"device-id": device.Id, "image": download.Name}) |
khenaidoo | f5a5bfa | 2019-01-23 22:20:29 -0500 | [diff] [blame] | 250 | rpc := "activate_image_update" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 251 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 252 | if err != nil { |
| 253 | return nil, err |
| 254 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 255 | args := []*kafka.KVArg{ |
| 256 | {Key: "device", Value: device}, |
| 257 | {Key: "request", Value: download}, |
khenaidoo | f5a5bfa | 2019-01-23 22:20:29 -0500 | [diff] [blame] | 258 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 259 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 260 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 261 | } |
| 262 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 263 | // RevertImageUpdate invokes revert image update rpc |
| 264 | func (ap *AdapterProxy) RevertImageUpdate(ctx context.Context, device *voltha.Device, download *voltha.ImageDownload) (chan *kafka.RpcResponse, error) { |
| 265 | logger.Debugw("RevertImageUpdate", log.Fields{"device-id": device.Id, "image": download.Name}) |
khenaidoo | f5a5bfa | 2019-01-23 22:20:29 -0500 | [diff] [blame] | 266 | rpc := "revert_image_update" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 267 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 268 | if err != nil { |
| 269 | return nil, err |
| 270 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 271 | args := []*kafka.KVArg{ |
| 272 | {Key: "device", Value: device}, |
| 273 | {Key: "request", Value: download}, |
khenaidoo | f5a5bfa | 2019-01-23 22:20:29 -0500 | [diff] [blame] | 274 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 275 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 276 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 277 | } |
| 278 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 279 | func (ap *AdapterProxy) PacketOut(ctx context.Context, deviceType string, deviceID string, outPort uint32, packet *openflow_13.OfpPacketOut) (chan *kafka.RpcResponse, error) { |
| 280 | logger.Debugw("PacketOut", log.Fields{"device-id": deviceID, "device-type": deviceType, "out-port": outPort}) |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 281 | toTopic, err := ap.getAdapterTopic(deviceID, deviceType) |
| 282 | if err != nil { |
| 283 | return nil, err |
| 284 | } |
khenaidoo | fdbad6e | 2018-11-06 22:26:38 -0500 | [diff] [blame] | 285 | rpc := "receive_packet_out" |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 286 | args := []*kafka.KVArg{ |
| 287 | {Key: "deviceId", Value: &ic.StrType{Val: deviceID}}, |
| 288 | {Key: "outPort", Value: &ic.IntType{Val: int64(outPort)}}, |
| 289 | {Key: "packet", Value: packet}, |
khenaidoo | fdbad6e | 2018-11-06 22:26:38 -0500 | [diff] [blame] | 290 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 291 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 292 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, deviceID, args...) |
khenaidoo | fdbad6e | 2018-11-06 22:26:38 -0500 | [diff] [blame] | 293 | } |
| 294 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 295 | // UpdateFlowsBulk invokes update flows bulk rpc |
| 296 | func (ap *AdapterProxy) UpdateFlowsBulk(ctx context.Context, device *voltha.Device, flows *voltha.Flows, groups *voltha.FlowGroups, flowMetadata *voltha.FlowMetadata) (chan *kafka.RpcResponse, error) { |
| 297 | logger.Debugw("UpdateFlowsBulk", log.Fields{"device-id": device.Id, "flow-count": len(flows.Items), "group-count": len(groups.Items), "flow-metadata": flowMetadata}) |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 298 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 299 | if err != nil { |
| 300 | return nil, err |
| 301 | } |
khenaidoo | 19d7b63 | 2018-10-30 10:49:50 -0400 | [diff] [blame] | 302 | rpc := "update_flows_bulk" |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 303 | args := []*kafka.KVArg{ |
| 304 | {Key: "device", Value: device}, |
| 305 | {Key: "flows", Value: flows}, |
| 306 | {Key: "groups", Value: groups}, |
| 307 | {Key: "flow_metadata", Value: flowMetadata}, |
khenaidoo | 19d7b63 | 2018-10-30 10:49:50 -0400 | [diff] [blame] | 308 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 309 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 310 | return ap.sendRPC(context.TODO(), rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 311 | } |
| 312 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 313 | // UpdateFlowsIncremental invokes update flows incremental rpc |
| 314 | func (ap *AdapterProxy) UpdateFlowsIncremental(ctx context.Context, device *voltha.Device, flowChanges *openflow_13.FlowChanges, groupChanges *openflow_13.FlowGroupChanges, flowMetadata *voltha.FlowMetadata) (chan *kafka.RpcResponse, error) { |
| 315 | logger.Debugw("UpdateFlowsIncremental", |
khenaidoo | 0458db6 | 2019-06-20 08:50:36 -0400 | [diff] [blame] | 316 | log.Fields{ |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 317 | "device-id": device.Id, |
| 318 | "flow-to-add-count": len(flowChanges.ToAdd.Items), |
| 319 | "flow-to-delete-count": len(flowChanges.ToRemove.Items), |
| 320 | "group-to-add-count": len(groupChanges.ToAdd.Items), |
| 321 | "group-to-delete-count": len(groupChanges.ToRemove.Items), |
| 322 | "group-to-update-count": len(groupChanges.ToUpdate.Items), |
khenaidoo | 0458db6 | 2019-06-20 08:50:36 -0400 | [diff] [blame] | 323 | }) |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 324 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 325 | if err != nil { |
| 326 | return nil, err |
| 327 | } |
Matt Jeanneret | b003742 | 2019-03-23 14:36:51 -0400 | [diff] [blame] | 328 | rpc := "update_flows_incrementally" |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 329 | args := []*kafka.KVArg{ |
| 330 | {Key: "device", Value: device}, |
| 331 | {Key: "flow_changes", Value: flowChanges}, |
| 332 | {Key: "group_changes", Value: groupChanges}, |
| 333 | {Key: "flow_metadata", Value: flowMetadata}, |
khenaidoo | 19d7b63 | 2018-10-30 10:49:50 -0400 | [diff] [blame] | 334 | } |
khenaidoo | 54e0ddf | 2019-02-27 16:21:33 -0500 | [diff] [blame] | 335 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 336 | return ap.sendRPC(context.TODO(), rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 337 | } |
| 338 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 339 | // UpdatePmConfigs invokes update pm configs rpc |
| 340 | func (ap *AdapterProxy) UpdatePmConfigs(ctx context.Context, device *voltha.Device, pmConfigs *voltha.PmConfigs) (chan *kafka.RpcResponse, error) { |
| 341 | logger.Debugw("UpdatePmConfigs", log.Fields{"device-id": device.Id, "pm-configs-id": pmConfigs.Id}) |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 342 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 343 | if err != nil { |
| 344 | return nil, err |
| 345 | } |
khenaidoo | b312747 | 2019-07-24 21:04:55 -0400 | [diff] [blame] | 346 | rpc := "Update_pm_config" |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 347 | args := []*kafka.KVArg{ |
| 348 | {Key: "device", Value: device}, |
| 349 | {Key: "pm_configs", Value: pmConfigs}, |
khenaidoo | b312747 | 2019-07-24 21:04:55 -0400 | [diff] [blame] | 350 | } |
khenaidoo | b312747 | 2019-07-24 21:04:55 -0400 | [diff] [blame] | 351 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 352 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
khenaidoo | b920354 | 2018-09-17 22:56:37 -0400 | [diff] [blame] | 353 | } |
| 354 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 355 | // SimulateAlarm invokes simulate alarm rpc |
| 356 | func (ap *AdapterProxy) SimulateAlarm(ctx context.Context, device *voltha.Device, simulateReq *voltha.SimulateAlarmRequest) (chan *kafka.RpcResponse, error) { |
| 357 | logger.Debugw("SimulateAlarm", log.Fields{"device-id": device.Id, "simulate-req-id": simulateReq.Id}) |
serkant.uluderya | 334479d | 2019-04-10 08:26:15 -0700 | [diff] [blame] | 358 | rpc := "simulate_alarm" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 359 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 360 | if err != nil { |
| 361 | return nil, err |
| 362 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 363 | args := []*kafka.KVArg{ |
| 364 | {Key: "device", Value: device}, |
| 365 | {Key: "request", Value: simulateReq}, |
serkant.uluderya | 334479d | 2019-04-10 08:26:15 -0700 | [diff] [blame] | 366 | } |
serkant.uluderya | 334479d | 2019-04-10 08:26:15 -0700 | [diff] [blame] | 367 | replyToTopic := ap.getCoreTopic() |
| 368 | ap.deviceTopicRegistered = true |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 369 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
serkant.uluderya | 334479d | 2019-04-10 08:26:15 -0700 | [diff] [blame] | 370 | } |
kesavand | bc2d162 | 2020-01-21 00:42:01 -0500 | [diff] [blame] | 371 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 372 | func (ap *AdapterProxy) DisablePort(ctx context.Context, device *voltha.Device, port *voltha.Port) (chan *kafka.RpcResponse, error) { |
| 373 | logger.Debugw("DisablePort", log.Fields{"device-id": device.Id, "port-no": port.PortNo}) |
kesavand | bc2d162 | 2020-01-21 00:42:01 -0500 | [diff] [blame] | 374 | rpc := "disable_port" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 375 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 376 | if err != nil { |
| 377 | return nil, err |
| 378 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 379 | args := []*kafka.KVArg{ |
| 380 | {Key: "deviceId", Value: &ic.StrType{Val: device.Id}}, |
| 381 | {Key: "port", Value: port}, |
kesavand | bc2d162 | 2020-01-21 00:42:01 -0500 | [diff] [blame] | 382 | } |
kesavand | bc2d162 | 2020-01-21 00:42:01 -0500 | [diff] [blame] | 383 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 384 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
kesavand | bc2d162 | 2020-01-21 00:42:01 -0500 | [diff] [blame] | 385 | } |
| 386 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 387 | func (ap *AdapterProxy) EnablePort(ctx context.Context, device *voltha.Device, port *voltha.Port) (chan *kafka.RpcResponse, error) { |
| 388 | logger.Debugw("EnablePort", log.Fields{"device-id": device.Id, "port-no": port.PortNo}) |
kesavand | bc2d162 | 2020-01-21 00:42:01 -0500 | [diff] [blame] | 389 | rpc := "enable_port" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 390 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 391 | if err != nil { |
| 392 | return nil, err |
| 393 | } |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 394 | args := []*kafka.KVArg{ |
| 395 | {Key: "deviceId", Value: &ic.StrType{Val: device.Id}}, |
| 396 | {Key: "port", Value: port}, |
kesavand | bc2d162 | 2020-01-21 00:42:01 -0500 | [diff] [blame] | 397 | } |
kesavand | bc2d162 | 2020-01-21 00:42:01 -0500 | [diff] [blame] | 398 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 399 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, args...) |
kesavand | bc2d162 | 2020-01-21 00:42:01 -0500 | [diff] [blame] | 400 | } |
Chaitrashree G S | 543df3e | 2020-02-24 22:36:54 -0500 | [diff] [blame] | 401 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 402 | // ChildDeviceLost invokes child device_lost rpc |
| 403 | func (ap *AdapterProxy) ChildDeviceLost(ctx context.Context, deviceType string, deviceID string, pPortNo uint32, onuID uint32) (chan *kafka.RpcResponse, error) { |
| 404 | logger.Debugw("ChildDeviceLost", log.Fields{"device-id": deviceID, "parent-port-no": pPortNo, "onu-id": onuID}) |
Chaitrashree G S | 543df3e | 2020-02-24 22:36:54 -0500 | [diff] [blame] | 405 | rpc := "child_device_lost" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 406 | toTopic, err := ap.getAdapterTopic(deviceID, deviceType) |
| 407 | if err != nil { |
| 408 | return nil, err |
| 409 | } |
Chaitrashree G S | 543df3e | 2020-02-24 22:36:54 -0500 | [diff] [blame] | 410 | args := []*kafka.KVArg{ |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 411 | {Key: "pDeviceId", Value: &ic.StrType{Val: deviceID}}, |
khenaidoo | 442e7c7 | 2020-03-10 16:13:48 -0400 | [diff] [blame] | 412 | {Key: "pPortNo", Value: &ic.IntType{Val: int64(pPortNo)}}, |
| 413 | {Key: "onuID", Value: &ic.IntType{Val: int64(onuID)}}, |
| 414 | } |
Chaitrashree G S | 543df3e | 2020-02-24 22:36:54 -0500 | [diff] [blame] | 415 | replyToTopic := ap.getCoreTopic() |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 416 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, deviceID, args...) |
Chaitrashree G S | 543df3e | 2020-02-24 22:36:54 -0500 | [diff] [blame] | 417 | } |
onkarkundargi | 8728525 | 2020-01-27 11:34:52 +0530 | [diff] [blame] | 418 | |
Kent Hagerman | 2b21604 | 2020-04-03 18:28:56 -0400 | [diff] [blame] | 419 | func (ap *AdapterProxy) StartOmciTest(ctx context.Context, device *voltha.Device, omcitestrequest *voltha.OmciTestRequest) (chan *kafka.RpcResponse, error) { |
Girish Kumar | f56a468 | 2020-03-20 20:07:46 +0000 | [diff] [blame] | 420 | logger.Debugw("Omci_test_Request_adapter_proxy", log.Fields{"device": device, "omciTestRequest": omcitestrequest}) |
onkarkundargi | 8728525 | 2020-01-27 11:34:52 +0530 | [diff] [blame] | 421 | rpc := "start_omci_test" |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 422 | toTopic, err := ap.getAdapterTopic(device.Id, device.Adapter) |
| 423 | if err != nil { |
| 424 | return nil, err |
| 425 | } |
onkarkundargi | 8728525 | 2020-01-27 11:34:52 +0530 | [diff] [blame] | 426 | // Use a device specific topic as we are the only core handling requests for this device |
| 427 | replyToTopic := ap.getCoreTopic() |
Scott Baker | 432f9be | 2020-03-26 11:56:30 -0700 | [diff] [blame] | 428 | // TODO: Perhaps this should have used omcitestrequest.uuid as the second argument rather |
| 429 | // than including the whole request, which is (deviceid, uuid) |
Matteo Scandolo | d525ae3 | 2020-04-02 17:27:29 -0700 | [diff] [blame] | 430 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, device.Id, |
onkarkundargi | 8728525 | 2020-01-27 11:34:52 +0530 | [diff] [blame] | 431 | &kafka.KVArg{Key: "device", Value: device}, |
| 432 | &kafka.KVArg{Key: "omcitestrequest", Value: omcitestrequest}) |
| 433 | } |
Dinesh Belwalkar | c1129f1 | 2020-02-27 10:41:33 -0800 | [diff] [blame] | 434 | |
| 435 | func (ap *AdapterProxy) GetExtValue(ctx context.Context, pdevice *voltha.Device, cdevice *voltha.Device, id string, valuetype voltha.ValueType_Type) (chan *kafka.RpcResponse, error) { |
| 436 | log.Debugw("GetExtValue", log.Fields{"device-id": pdevice.Id, "onuid": id}) |
| 437 | rpc := "get_ext_value" |
| 438 | toTopic, err := ap.getAdapterTopic(pdevice.Id, pdevice.Adapter) |
| 439 | if err != nil { |
| 440 | return nil, err |
| 441 | } |
| 442 | // Use a device specific topic to send the request. The adapter handling the device creates a device |
| 443 | // specific topic |
| 444 | args := []*kafka.KVArg{ |
| 445 | { |
| 446 | Key: "pDeviceId", |
| 447 | Value: &ic.StrType{Val: pdevice.Id}, |
| 448 | }, |
| 449 | { |
| 450 | Key: "device", |
| 451 | Value: cdevice, |
| 452 | }, |
| 453 | { |
| 454 | Key: "valuetype", |
| 455 | Value: &ic.IntType{Val: int64(valuetype)}, |
| 456 | }} |
| 457 | |
| 458 | replyToTopic := ap.getCoreTopic() |
| 459 | return ap.sendRPC(ctx, rpc, toTopic, &replyToTopic, true, pdevice.Id, args...) |
| 460 | } |