blob: 3e6ec474b764f3b354f74e6243766250c27423e0 [file] [log] [blame]
Jan Tattermuscha7fff862015-02-13 11:08:08 -08001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2015 gRPC authors.
Jan Tattermuscha7fff862015-02-13 11:08:08 -08004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
Jan Tattermuscha7fff862015-02-13 11:08:08 -08008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Jan Tattermuscha7fff862015-02-13 11:08:08 -080010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
Jan Tattermuscha7fff862015-02-13 11:08:08 -080016 *
17 */
18
David Garcia Quintas30bd4eb2015-06-01 21:08:59 -070019#include <grpc/byte_buffer_reader.h>
Jan Tattermusch53398142015-02-24 08:21:57 -080020#include <grpc/grpc.h>
Jan Tattermusch15329232015-03-02 15:32:47 -080021#include <grpc/grpc_security.h>
Craig Tiller5b1c5f22017-04-19 09:52:18 -070022#include <grpc/slice.h>
23#include <grpc/support/alloc.h>
24#include <grpc/support/log.h>
25#include <grpc/support/port_platform.h>
26#include <grpc/support/string_util.h>
Vijay Paic7456902018-02-12 10:28:24 -080027#include <grpc/support/thd_id.h>
Jan Tattermusch94c36532015-01-21 10:36:12 -080028
29#include <string.h>
30
Yuchen Zeng12dfdc32016-04-26 22:05:41 -070031#ifdef GPR_WINDOWS
Jan Tattermusch35e42802015-02-12 10:09:05 -080032#define GPR_EXPORT __declspec(dllexport)
33#define GPR_CALLTYPE __stdcall
34#endif
35
36#ifndef GPR_EXPORT
37#define GPR_EXPORT
38#endif
39
40#ifndef GPR_CALLTYPE
41#define GPR_CALLTYPE
42#endif
43
Craig Tillerbaa14a92017-11-03 09:09:36 -070044grpc_byte_buffer* string_to_byte_buffer(const char* buffer, size_t len) {
Craig Tillerd41a4a72016-10-26 16:16:06 -070045 grpc_slice slice = grpc_slice_from_copied_buffer(buffer, len);
Craig Tillerbaa14a92017-11-03 09:09:36 -070046 grpc_byte_buffer* bb = grpc_raw_byte_buffer_create(&slice, 1);
Craig Tillerd41a4a72016-10-26 16:16:06 -070047 grpc_slice_unref(slice);
Jan Tattermusch94c36532015-01-21 10:36:12 -080048 return bb;
49}
50
Jan Tattermusch337a2dd2015-02-13 15:41:41 -080051/*
52 * Helper to maintain lifetime of batch op inputs and store batch op outputs.
53 */
Jan Tattermusch5bd75d72015-09-08 10:55:20 -070054typedef struct grpcsharp_batch_context {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -080055 grpc_metadata_array send_initial_metadata;
Craig Tillerbaa14a92017-11-03 09:09:36 -070056 grpc_byte_buffer* send_message;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -080057 struct {
58 grpc_metadata_array trailing_metadata;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -080059 } send_status_from_server;
60 grpc_metadata_array recv_initial_metadata;
Craig Tillerbaa14a92017-11-03 09:09:36 -070061 grpc_byte_buffer* recv_message;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -080062 struct {
63 grpc_metadata_array trailing_metadata;
64 grpc_status_code status;
Craig Tiller7c70b6c2017-01-23 07:48:42 -080065 grpc_slice status_details;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -080066 } recv_status_on_client;
67 int recv_close_on_server_cancelled;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -080068} grpcsharp_batch_context;
69
Craig Tillerbaa14a92017-11-03 09:09:36 -070070GPR_EXPORT grpcsharp_batch_context* GPR_CALLTYPE
Craig Tiller5b1c5f22017-04-19 09:52:18 -070071grpcsharp_batch_context_create() {
Craig Tillerbaa14a92017-11-03 09:09:36 -070072 grpcsharp_batch_context* ctx = gpr_malloc(sizeof(grpcsharp_batch_context));
Jan Tattermusch337a2dd2015-02-13 15:41:41 -080073 memset(ctx, 0, sizeof(grpcsharp_batch_context));
74 return ctx;
75}
76
Jan Tattermusch6e901712016-10-21 00:42:37 +020077typedef struct {
Craig Tillerbaa14a92017-11-03 09:09:36 -070078 grpc_call* call;
Jan Tattermusch6e901712016-10-21 00:42:37 +020079 grpc_call_details call_details;
80 grpc_metadata_array request_metadata;
81} grpcsharp_request_call_context;
82
Craig Tillerbaa14a92017-11-03 09:09:36 -070083GPR_EXPORT grpcsharp_request_call_context* GPR_CALLTYPE
Craig Tiller5b1c5f22017-04-19 09:52:18 -070084grpcsharp_request_call_context_create() {
Craig Tillerbaa14a92017-11-03 09:09:36 -070085 grpcsharp_request_call_context* ctx =
Craig Tiller5b1c5f22017-04-19 09:52:18 -070086 gpr_malloc(sizeof(grpcsharp_request_call_context));
Jan Tattermusch6e901712016-10-21 00:42:37 +020087 memset(ctx, 0, sizeof(grpcsharp_request_call_context));
88 return ctx;
89}
90
Jan Tattermuschc0b37212015-03-13 08:35:41 -070091/*
92 * Destroys array->metadata.
93 * The array pointer itself is not freed.
Jan Tattermusch337a2dd2015-02-13 15:41:41 -080094 */
Jan Tattermuschc0b37212015-03-13 08:35:41 -070095void grpcsharp_metadata_array_destroy_metadata_only(
Craig Tillerbaa14a92017-11-03 09:09:36 -070096 grpc_metadata_array* array) {
Jan Tattermuschc0b37212015-03-13 08:35:41 -070097 gpr_free(array->metadata);
98}
99
100/*
101 * Destroys keys, values and array->metadata.
102 * The array pointer itself is not freed.
103 */
104void grpcsharp_metadata_array_destroy_metadata_including_entries(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700105 grpc_metadata_array* array) {
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700106 size_t i;
107 if (array->metadata) {
108 for (i = 0; i < array->count; i++) {
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800109 grpc_slice_unref(array->metadata[i].key);
110 grpc_slice_unref(array->metadata[i].value);
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700111 }
112 }
113 gpr_free(array->metadata);
114}
115
116/*
117 * Fully destroys the metadata array.
118 */
119GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700120grpcsharp_metadata_array_destroy_full(grpc_metadata_array* array) {
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700121 if (!array) {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800122 return;
123 }
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700124 grpcsharp_metadata_array_destroy_metadata_including_entries(array);
125 gpr_free(array);
126}
127
128/*
129 * Creates an empty metadata array with given capacity.
130 * Array can later be destroyed by grpc_metadata_array_destroy_full.
131 */
Craig Tillerbaa14a92017-11-03 09:09:36 -0700132GPR_EXPORT grpc_metadata_array* GPR_CALLTYPE
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700133grpcsharp_metadata_array_create(size_t capacity) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700134 grpc_metadata_array* array =
135 (grpc_metadata_array*)gpr_malloc(sizeof(grpc_metadata_array));
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700136 grpc_metadata_array_init(array);
137 array->capacity = capacity;
138 array->count = 0;
139 if (capacity > 0) {
140 array->metadata =
Craig Tillerbaa14a92017-11-03 09:09:36 -0700141 (grpc_metadata*)gpr_malloc(sizeof(grpc_metadata) * capacity);
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700142 memset(array->metadata, 0, sizeof(grpc_metadata) * capacity);
143 } else {
144 array->metadata = NULL;
145 }
146 return array;
147}
148
149GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700150grpcsharp_metadata_array_add(grpc_metadata_array* array, const char* key,
151 const char* value, size_t value_length) {
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700152 size_t i = array->count;
153 GPR_ASSERT(array->count < array->capacity);
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800154 array->metadata[i].key = grpc_slice_from_copied_string(key);
155 array->metadata[i].value = grpc_slice_from_copied_buffer(value, value_length);
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700156 array->count++;
157}
158
Craig Tiller7536af02015-12-22 13:49:30 -0800159GPR_EXPORT intptr_t GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700160grpcsharp_metadata_array_count(grpc_metadata_array* array) {
Craig Tiller7536af02015-12-22 13:49:30 -0800161 return (intptr_t)array->count;
Jan Tattermuschec50f282015-07-20 19:44:29 -0700162}
163
Craig Tillerbaa14a92017-11-03 09:09:36 -0700164GPR_EXPORT const char* GPR_CALLTYPE grpcsharp_metadata_array_get_key(
165 grpc_metadata_array* array, size_t index, size_t* key_length) {
Jan Tattermuschec50f282015-07-20 19:44:29 -0700166 GPR_ASSERT(index < array->count);
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800167 *key_length = GRPC_SLICE_LENGTH(array->metadata[index].key);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700168 return (char*)GRPC_SLICE_START_PTR(array->metadata[index].key);
Jan Tattermusch77172022015-07-21 18:28:16 -0700169}
170
Craig Tillerbaa14a92017-11-03 09:09:36 -0700171GPR_EXPORT const char* GPR_CALLTYPE grpcsharp_metadata_array_get_value(
172 grpc_metadata_array* array, size_t index, size_t* value_length) {
Jan Tattermusch77172022015-07-21 18:28:16 -0700173 GPR_ASSERT(index < array->count);
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800174 *value_length = GRPC_SLICE_LENGTH(array->metadata[index].value);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700175 return (char*)GRPC_SLICE_START_PTR(array->metadata[index].value);
Jan Tattermuschec50f282015-07-20 19:44:29 -0700176}
177
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700178/* Move contents of metadata array */
Craig Tillerbaa14a92017-11-03 09:09:36 -0700179void grpcsharp_metadata_array_move(grpc_metadata_array* dest,
180 grpc_metadata_array* src) {
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700181 if (!src) {
182 dest->capacity = 0;
183 dest->count = 0;
184 dest->metadata = NULL;
185 return;
186 }
187
188 dest->capacity = src->capacity;
189 dest->count = src->count;
190 dest->metadata = src->metadata;
191
192 src->capacity = 0;
193 src->count = 0;
194 src->metadata = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800195}
196
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700197GPR_EXPORT void GPR_CALLTYPE
Jan Tattermusch1ee85d12017-04-26 10:58:48 +0200198grpcsharp_batch_context_reset(grpcsharp_batch_context* ctx) {
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700199 grpcsharp_metadata_array_destroy_metadata_including_entries(
200 &(ctx->send_initial_metadata));
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800201
202 grpc_byte_buffer_destroy(ctx->send_message);
203
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700204 grpcsharp_metadata_array_destroy_metadata_including_entries(
Jan Tattermuschfa216732015-02-18 11:06:44 -0800205 &(ctx->send_status_from_server.trailing_metadata));
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800206
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700207 grpcsharp_metadata_array_destroy_metadata_only(&(ctx->recv_initial_metadata));
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800208
209 grpc_byte_buffer_destroy(ctx->recv_message);
210
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700211 grpcsharp_metadata_array_destroy_metadata_only(
212 &(ctx->recv_status_on_client.trailing_metadata));
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800213 grpc_slice_unref(ctx->recv_status_on_client.status_details);
Jan Tattermusch1ee85d12017-04-26 10:58:48 +0200214 memset(ctx, 0, sizeof(grpcsharp_batch_context));
215}
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800216
Jan Tattermusch1ee85d12017-04-26 10:58:48 +0200217GPR_EXPORT void GPR_CALLTYPE
218grpcsharp_batch_context_destroy(grpcsharp_batch_context* ctx) {
219 if (!ctx) {
220 return;
221 }
222 grpcsharp_batch_context_reset(ctx);
Jan Tattermusch6e901712016-10-21 00:42:37 +0200223 gpr_free(ctx);
224}
225
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700226GPR_EXPORT void GPR_CALLTYPE
Jan Tattermuschfb6d01a2017-11-28 16:46:41 +0100227grpcsharp_request_call_context_reset(grpcsharp_request_call_context* ctx) {
Jan Tattermuschfa216732015-02-18 11:06:44 -0800228 /* NOTE: ctx->server_rpc_new.call is not destroyed because callback handler is
229 supposed
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800230 to take its ownership. */
231
Jan Tattermusch6e901712016-10-21 00:42:37 +0200232 grpc_call_details_destroy(&(ctx->call_details));
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700233 grpcsharp_metadata_array_destroy_metadata_only(&(ctx->request_metadata));
Jan Tattermuschfb6d01a2017-11-28 16:46:41 +0100234 memset(ctx, 0, sizeof(grpcsharp_request_call_context));
235}
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800236
Jan Tattermuschfb6d01a2017-11-28 16:46:41 +0100237GPR_EXPORT void GPR_CALLTYPE
238grpcsharp_request_call_context_destroy(grpcsharp_request_call_context* ctx) {
239 if (!ctx) {
240 return;
241 }
242 grpcsharp_request_call_context_reset(ctx);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800243 gpr_free(ctx);
244}
245
Craig Tillerbaa14a92017-11-03 09:09:36 -0700246GPR_EXPORT const grpc_metadata_array* GPR_CALLTYPE
Jan Tattermusch77415b62015-07-20 20:18:26 -0700247grpcsharp_batch_context_recv_initial_metadata(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700248 const grpcsharp_batch_context* ctx) {
Jan Tattermuschec50f282015-07-20 19:44:29 -0700249 return &(ctx->recv_initial_metadata);
250}
251
Craig Tiller7536af02015-12-22 13:49:30 -0800252GPR_EXPORT intptr_t GPR_CALLTYPE grpcsharp_batch_context_recv_message_length(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700253 const grpcsharp_batch_context* ctx) {
Jan Tattermusch0d896ef2016-06-21 18:17:27 -0700254 grpc_byte_buffer_reader reader;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800255 if (!ctx->recv_message) {
Jan Tattermuschfa216732015-02-18 11:06:44 -0800256 return -1;
257 }
Alexander Polcyn22220472016-07-13 12:57:41 -0700258
259 GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, ctx->recv_message));
Alexander Polcyn67656532016-09-01 18:50:13 -0700260 intptr_t result = (intptr_t)grpc_byte_buffer_length(reader.buffer_out);
261 grpc_byte_buffer_reader_destroy(&reader);
Alexander Polcyn22220472016-07-13 12:57:41 -0700262
Alexander Polcyn67656532016-09-01 18:50:13 -0700263 return result;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800264}
265
266/*
267 * Copies data from recv_message to a buffer. Fatal error occurs if
268 * buffer is too small.
269 */
Jan Tattermuschfa216732015-02-18 11:06:44 -0800270GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_recv_message_to_buffer(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700271 const grpcsharp_batch_context* ctx, char* buffer, size_t buffer_len) {
David Garcia Quintas30bd4eb2015-06-01 21:08:59 -0700272 grpc_byte_buffer_reader reader;
Craig Tillerd41a4a72016-10-26 16:16:06 -0700273 grpc_slice slice;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800274 size_t offset = 0;
275
Alexander Polcyn22220472016-07-13 12:57:41 -0700276 GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, ctx->recv_message));
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800277
David Garcia Quintas30bd4eb2015-06-01 21:08:59 -0700278 while (grpc_byte_buffer_reader_next(&reader, &slice)) {
Craig Tiller618e67d2016-10-26 21:08:10 -0700279 size_t len = GRPC_SLICE_LENGTH(slice);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800280 GPR_ASSERT(offset + len <= buffer_len);
Craig Tiller618e67d2016-10-26 21:08:10 -0700281 memcpy(buffer + offset, GRPC_SLICE_START_PTR(slice),
282 GRPC_SLICE_LENGTH(slice));
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800283 offset += len;
Craig Tillerd41a4a72016-10-26 16:16:06 -0700284 grpc_slice_unref(slice);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800285 }
Alexander Polcyn67656532016-09-01 18:50:13 -0700286
287 grpc_byte_buffer_reader_destroy(&reader);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800288}
289
290GPR_EXPORT grpc_status_code GPR_CALLTYPE
Jan Tattermuschfa216732015-02-18 11:06:44 -0800291grpcsharp_batch_context_recv_status_on_client_status(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700292 const grpcsharp_batch_context* ctx) {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800293 return ctx->recv_status_on_client.status;
294}
295
Craig Tillerbaa14a92017-11-03 09:09:36 -0700296GPR_EXPORT const char* GPR_CALLTYPE
Jan Tattermuschfa216732015-02-18 11:06:44 -0800297grpcsharp_batch_context_recv_status_on_client_details(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700298 const grpcsharp_batch_context* ctx, size_t* details_length) {
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700299 *details_length =
300 GRPC_SLICE_LENGTH(ctx->recv_status_on_client.status_details);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700301 return (char*)GRPC_SLICE_START_PTR(ctx->recv_status_on_client.status_details);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800302}
303
Craig Tillerbaa14a92017-11-03 09:09:36 -0700304GPR_EXPORT const grpc_metadata_array* GPR_CALLTYPE
Jan Tattermuschec50f282015-07-20 19:44:29 -0700305grpcsharp_batch_context_recv_status_on_client_trailing_metadata(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700306 const grpcsharp_batch_context* ctx) {
Jan Tattermuschec50f282015-07-20 19:44:29 -0700307 return &(ctx->recv_status_on_client.trailing_metadata);
308}
309
Craig Tillerbaa14a92017-11-03 09:09:36 -0700310GPR_EXPORT grpc_call* GPR_CALLTYPE
311grpcsharp_request_call_context_call(const grpcsharp_request_call_context* ctx) {
Jan Tattermusch6e901712016-10-21 00:42:37 +0200312 return ctx->call;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800313}
314
Craig Tillerbaa14a92017-11-03 09:09:36 -0700315GPR_EXPORT const char* GPR_CALLTYPE grpcsharp_request_call_context_method(
316 const grpcsharp_request_call_context* ctx, size_t* method_length) {
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800317 *method_length = GRPC_SLICE_LENGTH(ctx->call_details.method);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700318 return (char*)GRPC_SLICE_START_PTR(ctx->call_details.method);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800319}
320
Craig Tillerbaa14a92017-11-03 09:09:36 -0700321GPR_EXPORT const char* GPR_CALLTYPE grpcsharp_request_call_context_host(
322 const grpcsharp_request_call_context* ctx, size_t* host_length) {
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800323 *host_length = GRPC_SLICE_LENGTH(ctx->call_details.host);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700324 return (char*)GRPC_SLICE_START_PTR(ctx->call_details.host);
Jan Tattermusch77415b62015-07-20 20:18:26 -0700325}
326
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700327GPR_EXPORT gpr_timespec GPR_CALLTYPE grpcsharp_request_call_context_deadline(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700328 const grpcsharp_request_call_context* ctx) {
Jan Tattermusch6e901712016-10-21 00:42:37 +0200329 return ctx->call_details.deadline;
Jan Tattermusch77415b62015-07-20 20:18:26 -0700330}
331
Craig Tillerbaa14a92017-11-03 09:09:36 -0700332GPR_EXPORT const grpc_metadata_array* GPR_CALLTYPE
Jan Tattermusch6e901712016-10-21 00:42:37 +0200333grpcsharp_request_call_context_request_metadata(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700334 const grpcsharp_request_call_context* ctx) {
Jan Tattermusch6e901712016-10-21 00:42:37 +0200335 return &(ctx->request_metadata);
Jan Tattermuschec50f282015-07-20 19:44:29 -0700336}
337
Craig Tiller7536af02015-12-22 13:49:30 -0800338GPR_EXPORT int32_t GPR_CALLTYPE
Jan Tattermusch8c2dd9d2015-05-04 09:20:43 -0700339grpcsharp_batch_context_recv_close_on_server_cancelled(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700340 const grpcsharp_batch_context* ctx) {
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700341 return (int32_t)ctx->recv_close_on_server_cancelled;
Jan Tattermusch8c2dd9d2015-05-04 09:20:43 -0700342}
343
Jan Tattermusch35e42802015-02-12 10:09:05 -0800344/* Init & shutdown */
345
Jan Tattermuscha9edeef2015-02-12 14:29:10 -0800346GPR_EXPORT void GPR_CALLTYPE grpcsharp_init(void) { grpc_init(); }
Jan Tattermusch94c36532015-01-21 10:36:12 -0800347
Jan Tattermuscha9edeef2015-02-12 14:29:10 -0800348GPR_EXPORT void GPR_CALLTYPE grpcsharp_shutdown(void) { grpc_shutdown(); }
Jan Tattermusch94c36532015-01-21 10:36:12 -0800349
Jan Tattermusch35e42802015-02-12 10:09:05 -0800350/* Completion queue */
351
Craig Tillerbaa14a92017-11-03 09:09:36 -0700352GPR_EXPORT grpc_completion_queue* GPR_CALLTYPE
Jan Tattermuschb7462942017-03-08 19:30:21 +0100353grpcsharp_completion_queue_create_async(void) {
Sree Kuchibhotla615e4682017-03-22 12:34:17 -0700354 return grpc_completion_queue_create_for_next(NULL);
Jan Tattermuschb7462942017-03-08 19:30:21 +0100355}
356
Craig Tillerbaa14a92017-11-03 09:09:36 -0700357GPR_EXPORT grpc_completion_queue* GPR_CALLTYPE
Jan Tattermuschb7462942017-03-08 19:30:21 +0100358grpcsharp_completion_queue_create_sync(void) {
Sree Kuchibhotla615e4682017-03-22 12:34:17 -0700359 return grpc_completion_queue_create_for_pluck(NULL);
Jan Tattermusch94c36532015-01-21 10:36:12 -0800360}
361
Jan Tattermuscha9edeef2015-02-12 14:29:10 -0800362GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700363grpcsharp_completion_queue_shutdown(grpc_completion_queue* cq) {
Jan Tattermusch35e42802015-02-12 10:09:05 -0800364 grpc_completion_queue_shutdown(cq);
Jan Tattermusch94c36532015-01-21 10:36:12 -0800365}
366
Jan Tattermuscha9edeef2015-02-12 14:29:10 -0800367GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700368grpcsharp_completion_queue_destroy(grpc_completion_queue* cq) {
Jan Tattermusch35e42802015-02-12 10:09:05 -0800369 grpc_completion_queue_destroy(cq);
Jan Tattermusch94c36532015-01-21 10:36:12 -0800370}
371
Jan Tattermuschd3677482015-06-01 19:27:40 -0700372GPR_EXPORT grpc_event GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700373grpcsharp_completion_queue_next(grpc_completion_queue* cq) {
Nicolas "Pixel" Noble8c597912015-08-07 20:42:22 +0200374 return grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME),
375 NULL);
Jan Tattermuschd3677482015-06-01 19:27:40 -0700376}
Jan Tattermusch94c36532015-01-21 10:36:12 -0800377
Jan Tattermuschd3677482015-06-01 19:27:40 -0700378GPR_EXPORT grpc_event GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700379grpcsharp_completion_queue_pluck(grpc_completion_queue* cq, void* tag) {
Craig Tiller143e7bf2015-07-13 08:41:49 -0700380 return grpc_completion_queue_pluck(cq, tag,
Nicolas "Pixel" Noble8c597912015-08-07 20:42:22 +0200381 gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
Jan Tattermusch94c36532015-01-21 10:36:12 -0800382}
Jan Tattermusch35e42802015-02-12 10:09:05 -0800383
384/* Channel */
385
Craig Tillerbaa14a92017-11-03 09:09:36 -0700386GPR_EXPORT grpc_channel* GPR_CALLTYPE
Craig Tillerd9aed1d2015-07-26 12:55:47 -0700387
Craig Tillerbaa14a92017-11-03 09:09:36 -0700388grpcsharp_insecure_channel_create(const char* target,
389 const grpc_channel_args* args) {
Nicolas "Pixel" Noble9d72b142015-08-08 01:45:38 +0200390 return grpc_insecure_channel_create(target, args, NULL);
Jan Tattermusch35e42802015-02-12 10:09:05 -0800391}
392
Craig Tillerbaa14a92017-11-03 09:09:36 -0700393GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_destroy(grpc_channel* channel) {
Jan Tattermusch35e42802015-02-12 10:09:05 -0800394 grpc_channel_destroy(channel);
395}
396
Craig Tillerbaa14a92017-11-03 09:09:36 -0700397GPR_EXPORT grpc_call* GPR_CALLTYPE grpcsharp_channel_create_call(
398 grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
399 grpc_completion_queue* cq, const char* method, const char* host,
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700400 gpr_timespec deadline) {
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800401 grpc_slice method_slice = grpc_slice_from_copied_string(method);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700402 grpc_slice* host_slice_ptr = NULL;
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800403 grpc_slice host_slice;
404 if (host != NULL) {
405 host_slice = grpc_slice_from_copied_string(host);
406 host_slice_ptr = &host_slice;
407 }
Craig Tillerbaa14a92017-11-03 09:09:36 -0700408 grpc_call* ret =
Jan Tattermusch06eb0572017-06-08 18:21:09 +0200409 grpc_channel_create_call(channel, parent_call, propagation_mask, cq,
410 method_slice, host_slice_ptr, deadline, NULL);
411 grpc_slice_unref(method_slice);
412 if (host != NULL) {
413 grpc_slice_unref(host_slice);
414 }
415 return ret;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800416}
417
Jan Tattermuschd8bbdea2015-07-22 12:51:06 -0700418GPR_EXPORT grpc_connectivity_state GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700419grpcsharp_channel_check_connectivity_state(grpc_channel* channel,
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700420 int32_t try_to_connect) {
Jan Tattermuschd8bbdea2015-07-22 12:51:06 -0700421 return grpc_channel_check_connectivity_state(channel, try_to_connect);
422}
423
424GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_watch_connectivity_state(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700425 grpc_channel* channel, grpc_connectivity_state last_observed_state,
426 gpr_timespec deadline, grpc_completion_queue* cq,
427 grpcsharp_batch_context* ctx) {
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700428 grpc_channel_watch_connectivity_state(channel, last_observed_state, deadline,
429 cq, ctx);
Jan Tattermuschd8bbdea2015-07-22 12:51:06 -0700430}
431
Craig Tillerbaa14a92017-11-03 09:09:36 -0700432GPR_EXPORT char* GPR_CALLTYPE
433grpcsharp_channel_get_target(grpc_channel* channel) {
Jan Tattermuschdead9052015-08-01 21:34:31 -0700434 return grpc_channel_get_target(channel);
Jan Tattermusch35e42802015-02-12 10:09:05 -0800435}
436
Jan Tattermusch15329232015-03-02 15:32:47 -0800437/* Channel args */
438
Craig Tillerbaa14a92017-11-03 09:09:36 -0700439GPR_EXPORT grpc_channel_args* GPR_CALLTYPE
Jan Tattermusch15329232015-03-02 15:32:47 -0800440grpcsharp_channel_args_create(size_t num_args) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700441 grpc_channel_args* args =
442 (grpc_channel_args*)gpr_malloc(sizeof(grpc_channel_args));
Jan Tattermusch15329232015-03-02 15:32:47 -0800443 memset(args, 0, sizeof(grpc_channel_args));
444
445 args->num_args = num_args;
Craig Tillerbaa14a92017-11-03 09:09:36 -0700446 args->args = (grpc_arg*)gpr_malloc(sizeof(grpc_arg) * num_args);
Jan Tattermusch15329232015-03-02 15:32:47 -0800447 memset(args->args, 0, sizeof(grpc_arg) * num_args);
448 return args;
449}
450
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700451GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_args_set_string(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700452 grpc_channel_args* args, size_t index, const char* key, const char* value) {
Jan Tattermusch15329232015-03-02 15:32:47 -0800453 GPR_ASSERT(args);
454 GPR_ASSERT(index < args->num_args);
455 args->args[index].type = GRPC_ARG_STRING;
456 args->args[index].key = gpr_strdup(key);
457 args->args[index].value.string = gpr_strdup(value);
458}
459
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700460GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_args_set_integer(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700461 grpc_channel_args* args, size_t index, const char* key, int value) {
Jan Tattermusch2ddb5a62015-06-08 17:51:36 -0700462 GPR_ASSERT(args);
463 GPR_ASSERT(index < args->num_args);
464 args->args[index].type = GRPC_ARG_INTEGER;
465 args->args[index].key = gpr_strdup(key);
466 args->args[index].value.integer = value;
467}
468
469GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700470grpcsharp_channel_args_destroy(grpc_channel_args* args) {
Jan Tattermusch15329232015-03-02 15:32:47 -0800471 size_t i;
472 if (args) {
473 for (i = 0; i < args->num_args; i++) {
474 gpr_free(args->args[i].key);
475 if (args->args[i].type == GRPC_ARG_STRING) {
476 gpr_free(args->args[i].value.string);
477 }
478 }
479 gpr_free(args->args);
480 gpr_free(args);
481 }
482}
483
Jan Tattermusch35e42802015-02-12 10:09:05 -0800484/* Timespec */
485
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700486GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(gpr_clock_type clock_type) {
487 return gpr_now(clock_type);
488}
Jan Tattermusch35e42802015-02-12 10:09:05 -0800489
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700490GPR_EXPORT gpr_timespec GPR_CALLTYPE
491gprsharp_inf_future(gpr_clock_type clock_type) {
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700492 return gpr_inf_future(clock_type);
493}
494
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700495GPR_EXPORT gpr_timespec GPR_CALLTYPE
496gprsharp_inf_past(gpr_clock_type clock_type) {
Jan Tattermuschf6410f52015-07-22 16:21:57 -0700497 return gpr_inf_past(clock_type);
Jan Tattermusch35e42802015-02-12 10:09:05 -0800498}
499
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700500GPR_EXPORT gpr_timespec GPR_CALLTYPE
501gprsharp_convert_clock_type(gpr_timespec t, gpr_clock_type target_clock) {
Jan Tattermusch7a3ac622015-07-23 18:40:48 -0700502 return gpr_convert_clock_type(t, target_clock);
Jan Tattermusch35e42802015-02-12 10:09:05 -0800503}
504
Craig Tiller7536af02015-12-22 13:49:30 -0800505GPR_EXPORT int32_t GPR_CALLTYPE gprsharp_sizeof_timespec(void) {
Jan Tattermusch35e42802015-02-12 10:09:05 -0800506 return sizeof(gpr_timespec);
507}
508
509/* Call */
510
Craig Tillerbaa14a92017-11-03 09:09:36 -0700511GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_cancel(grpc_call* call) {
Nicolas "Pixel" Noble8c597912015-08-07 20:42:22 +0200512 return grpc_call_cancel(call, NULL);
Jan Tattermusch35e42802015-02-12 10:09:05 -0800513}
514
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700515GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_cancel_with_status(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700516 grpc_call* call, grpc_status_code status, const char* description) {
Nicolas "Pixel" Noble8c597912015-08-07 20:42:22 +0200517 return grpc_call_cancel_with_status(call, status, description, NULL);
Jan Tattermusch35e42802015-02-12 10:09:05 -0800518}
519
Craig Tillerbaa14a92017-11-03 09:09:36 -0700520GPR_EXPORT char* GPR_CALLTYPE grpcsharp_call_get_peer(grpc_call* call) {
Jan Tattermusch062c3292015-07-23 20:28:42 -0700521 return grpc_call_get_peer(call);
522}
523
Craig Tillerbaa14a92017-11-03 09:09:36 -0700524GPR_EXPORT void GPR_CALLTYPE gprsharp_free(void* p) { gpr_free(p); }
Jan Tattermusch062c3292015-07-23 20:28:42 -0700525
Craig Tillerbaa14a92017-11-03 09:09:36 -0700526GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_destroy(grpc_call* call) {
Craig Tillerdd36b152017-03-31 08:27:28 -0700527 grpc_call_unref(call);
Jan Tattermusch35e42802015-02-12 10:09:05 -0800528}
529
Craig Tillerbaa14a92017-11-03 09:09:36 -0700530typedef grpc_call_error (*grpcsharp_call_start_batch_func)(grpc_call* call,
531 const grpc_op* ops,
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200532 size_t nops,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700533 void* tag,
534 void* reserved);
Jan Tattermusch645ae742017-05-22 08:46:26 -0700535
536/* Only for testing */
Craig Tillerbaa14a92017-11-03 09:09:36 -0700537static grpc_call_error grpcsharp_call_start_batch_nop(grpc_call* call,
538 const grpc_op* ops,
539 size_t nops, void* tag,
540 void* reserved) {
Jan Tattermusch645ae742017-05-22 08:46:26 -0700541 return GRPC_CALL_OK;
542}
543
Craig Tillerbaa14a92017-11-03 09:09:36 -0700544static grpc_call_error grpcsharp_call_start_batch_default(grpc_call* call,
545 const grpc_op* ops,
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200546 size_t nops,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700547 void* tag,
548 void* reserved) {
Jan Tattermusch645ae742017-05-22 08:46:26 -0700549 return grpc_call_start_batch(call, ops, nops, tag, reserved);
550}
551
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200552static grpcsharp_call_start_batch_func g_call_start_batch_func =
553 grpcsharp_call_start_batch_default;
Jan Tattermusch645ae742017-05-22 08:46:26 -0700554
Craig Tillerbaa14a92017-11-03 09:09:36 -0700555static grpc_call_error grpcsharp_call_start_batch(grpc_call* call,
556 const grpc_op* ops,
557 size_t nops, void* tag,
558 void* reserved) {
Jan Tattermusch645ae742017-05-22 08:46:26 -0700559 return g_call_start_batch_func(call, ops, nops, tag, reserved);
560}
561
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700562GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_unary(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700563 grpc_call* call, grpcsharp_batch_context* ctx, const char* send_buffer,
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700564 size_t send_buffer_len, uint32_t write_flags,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700565 grpc_metadata_array* initial_metadata, uint32_t initial_metadata_flags) {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800566 /* TODO: don't use magic number */
567 grpc_op ops[6];
David Garcia Quintasa301eaa2016-05-06 16:59:03 -0700568 memset(ops, 0, sizeof(ops));
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800569 ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700570 grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
571 initial_metadata);
572 ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
573 ops[0].data.send_initial_metadata.metadata =
574 ctx->send_initial_metadata.metadata;
Jan Tattermusch43416da2016-11-22 17:28:22 +0100575 ops[0].flags = initial_metadata_flags;
Craig Tiller42758992015-08-18 10:34:32 -0700576 ops[0].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800577
578 ops[1].op = GRPC_OP_SEND_MESSAGE;
579 ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
Mark D. Roth448c1f02017-01-25 10:44:30 -0800580 ops[1].data.send_message.send_message = ctx->send_message;
Jan Tattermuschbff90ac2015-08-06 21:30:26 -0700581 ops[1].flags = write_flags;
Craig Tiller42758992015-08-18 10:34:32 -0700582 ops[1].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800583
584 ops[2].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700585 ops[2].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700586 ops[2].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800587
588 ops[3].op = GRPC_OP_RECV_INITIAL_METADATA;
Mark D. Roth448c1f02017-01-25 10:44:30 -0800589 ops[3].data.recv_initial_metadata.recv_initial_metadata =
590 &(ctx->recv_initial_metadata);
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700591 ops[3].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700592 ops[3].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800593
594 ops[4].op = GRPC_OP_RECV_MESSAGE;
Mark D. Roth448c1f02017-01-25 10:44:30 -0800595 ops[4].data.recv_message.recv_message = &(ctx->recv_message);
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700596 ops[4].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700597 ops[4].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800598
599 ops[5].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
Jan Tattermuschfa216732015-02-18 11:06:44 -0800600 ops[5].data.recv_status_on_client.trailing_metadata =
601 &(ctx->recv_status_on_client.trailing_metadata);
602 ops[5].data.recv_status_on_client.status =
603 &(ctx->recv_status_on_client.status);
Jan Tattermuschfa216732015-02-18 11:06:44 -0800604 ops[5].data.recv_status_on_client.status_details =
605 &(ctx->recv_status_on_client.status_details);
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700606 ops[5].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700607 ops[5].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800608
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200609 return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
610 ctx, NULL);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800611}
612
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700613GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_client_streaming(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700614 grpc_call* call, grpcsharp_batch_context* ctx,
615 grpc_metadata_array* initial_metadata, uint32_t initial_metadata_flags) {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800616 /* TODO: don't use magic number */
617 grpc_op ops[4];
David Garcia Quintasa301eaa2016-05-06 16:59:03 -0700618 memset(ops, 0, sizeof(ops));
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800619 ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700620 grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
621 initial_metadata);
622 ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
623 ops[0].data.send_initial_metadata.metadata =
624 ctx->send_initial_metadata.metadata;
Jan Tattermusch43416da2016-11-22 17:28:22 +0100625 ops[0].flags = initial_metadata_flags;
Craig Tiller42758992015-08-18 10:34:32 -0700626 ops[0].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800627
628 ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
Mark D. Roth448c1f02017-01-25 10:44:30 -0800629 ops[1].data.recv_initial_metadata.recv_initial_metadata =
630 &(ctx->recv_initial_metadata);
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700631 ops[1].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700632 ops[1].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800633
634 ops[2].op = GRPC_OP_RECV_MESSAGE;
Mark D. Roth448c1f02017-01-25 10:44:30 -0800635 ops[2].data.recv_message.recv_message = &(ctx->recv_message);
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700636 ops[2].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700637 ops[2].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800638
639 ops[3].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
Jan Tattermuschfa216732015-02-18 11:06:44 -0800640 ops[3].data.recv_status_on_client.trailing_metadata =
641 &(ctx->recv_status_on_client.trailing_metadata);
642 ops[3].data.recv_status_on_client.status =
643 &(ctx->recv_status_on_client.status);
Jan Tattermuschfa216732015-02-18 11:06:44 -0800644 ops[3].data.recv_status_on_client.status_details =
645 &(ctx->recv_status_on_client.status_details);
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700646 ops[3].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700647 ops[3].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800648
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200649 return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
650 ctx, NULL);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800651}
652
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700653GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_server_streaming(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700654 grpc_call* call, grpcsharp_batch_context* ctx, const char* send_buffer,
Jan Tattermusch43416da2016-11-22 17:28:22 +0100655 size_t send_buffer_len, uint32_t write_flags,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700656 grpc_metadata_array* initial_metadata, uint32_t initial_metadata_flags) {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800657 /* TODO: don't use magic number */
Jan Tattermusch4c25efa2015-08-21 16:07:57 -0700658 grpc_op ops[4];
David Garcia Quintasa301eaa2016-05-06 16:59:03 -0700659 memset(ops, 0, sizeof(ops));
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800660 ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700661 grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
662 initial_metadata);
663 ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
664 ops[0].data.send_initial_metadata.metadata =
665 ctx->send_initial_metadata.metadata;
Jan Tattermusch43416da2016-11-22 17:28:22 +0100666 ops[0].flags = initial_metadata_flags;
Craig Tiller42758992015-08-18 10:34:32 -0700667 ops[0].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800668
669 ops[1].op = GRPC_OP_SEND_MESSAGE;
670 ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
Mark D. Roth448c1f02017-01-25 10:44:30 -0800671 ops[1].data.send_message.send_message = ctx->send_message;
Jan Tattermuschbff90ac2015-08-06 21:30:26 -0700672 ops[1].flags = write_flags;
Craig Tiller42758992015-08-18 10:34:32 -0700673 ops[1].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800674
675 ops[2].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700676 ops[2].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700677 ops[2].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800678
Jan Tattermusch4c25efa2015-08-21 16:07:57 -0700679 ops[3].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
680 ops[3].data.recv_status_on_client.trailing_metadata =
Jan Tattermuschfa216732015-02-18 11:06:44 -0800681 &(ctx->recv_status_on_client.trailing_metadata);
Jan Tattermusch4c25efa2015-08-21 16:07:57 -0700682 ops[3].data.recv_status_on_client.status =
Jan Tattermuschfa216732015-02-18 11:06:44 -0800683 &(ctx->recv_status_on_client.status);
Jan Tattermusch4c25efa2015-08-21 16:07:57 -0700684 ops[3].data.recv_status_on_client.status_details =
Jan Tattermuschfa216732015-02-18 11:06:44 -0800685 &(ctx->recv_status_on_client.status_details);
Jan Tattermusch4c25efa2015-08-21 16:07:57 -0700686 ops[3].flags = 0;
687 ops[3].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800688
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200689 return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
690 ctx, NULL);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800691}
692
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700693GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_duplex_streaming(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700694 grpc_call* call, grpcsharp_batch_context* ctx,
695 grpc_metadata_array* initial_metadata, uint32_t initial_metadata_flags) {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800696 /* TODO: don't use magic number */
Jan Tattermusch4c25efa2015-08-21 16:07:57 -0700697 grpc_op ops[2];
David Garcia Quintasa301eaa2016-05-06 16:59:03 -0700698 memset(ops, 0, sizeof(ops));
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800699 ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
Jan Tattermuschc0b37212015-03-13 08:35:41 -0700700 grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
701 initial_metadata);
702 ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
703 ops[0].data.send_initial_metadata.metadata =
704 ctx->send_initial_metadata.metadata;
Jan Tattermusch43416da2016-11-22 17:28:22 +0100705 ops[0].flags = initial_metadata_flags;
Craig Tiller42758992015-08-18 10:34:32 -0700706 ops[0].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800707
Jan Tattermusch4c25efa2015-08-21 16:07:57 -0700708 ops[1].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
709 ops[1].data.recv_status_on_client.trailing_metadata =
710 &(ctx->recv_status_on_client.trailing_metadata);
711 ops[1].data.recv_status_on_client.status =
712 &(ctx->recv_status_on_client.status);
Jan Tattermusch4c25efa2015-08-21 16:07:57 -0700713 ops[1].data.recv_status_on_client.status_details =
714 &(ctx->recv_status_on_client.status_details);
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700715 ops[1].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700716 ops[1].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800717
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200718 return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
719 ctx, NULL);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800720}
721
Jan Tattermusch4c25efa2015-08-21 16:07:57 -0700722GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_recv_initial_metadata(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700723 grpc_call* call, grpcsharp_batch_context* ctx) {
Jan Tattermusch706a0102015-09-24 18:34:39 -0700724 /* TODO: don't use magic number */
725 grpc_op ops[1];
726 ops[0].op = GRPC_OP_RECV_INITIAL_METADATA;
Mark D. Roth448c1f02017-01-25 10:44:30 -0800727 ops[0].data.recv_initial_metadata.recv_initial_metadata =
728 &(ctx->recv_initial_metadata);
Jan Tattermusch706a0102015-09-24 18:34:39 -0700729 ops[0].flags = 0;
730 ops[0].reserved = NULL;
Jan Tattermusch4c25efa2015-08-21 16:07:57 -0700731
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200732 return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
733 ctx, NULL);
Jan Tattermusch4c25efa2015-08-21 16:07:57 -0700734}
735
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700736GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_message(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700737 grpc_call* call, grpcsharp_batch_context* ctx, const char* send_buffer,
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700738 size_t send_buffer_len, uint32_t write_flags,
739 int32_t send_empty_initial_metadata) {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800740 /* TODO: don't use magic number */
Jan Tattermusch8368b2e2015-08-07 01:18:37 -0700741 grpc_op ops[2];
David Garcia Quintasa301eaa2016-05-06 16:59:03 -0700742 memset(ops, 0, sizeof(ops));
Jan Tattermusch8368b2e2015-08-07 01:18:37 -0700743 size_t nops = send_empty_initial_metadata ? 2 : 1;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800744 ops[0].op = GRPC_OP_SEND_MESSAGE;
745 ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
Mark D. Roth448c1f02017-01-25 10:44:30 -0800746 ops[0].data.send_message.send_message = ctx->send_message;
Jan Tattermuschbff90ac2015-08-06 21:30:26 -0700747 ops[0].flags = write_flags;
Craig Tiller42758992015-08-18 10:34:32 -0700748 ops[0].reserved = NULL;
Jan Tattermusch8368b2e2015-08-07 01:18:37 -0700749 ops[1].op = GRPC_OP_SEND_INITIAL_METADATA;
Jan Tattermusch8368b2e2015-08-07 01:18:37 -0700750 ops[1].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700751 ops[1].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800752
Jan Tattermusch645ae742017-05-22 08:46:26 -0700753 return grpcsharp_call_start_batch(call, ops, nops, ctx, NULL);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800754}
755
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700756GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_close_from_client(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700757 grpc_call* call, grpcsharp_batch_context* ctx) {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800758 /* TODO: don't use magic number */
759 grpc_op ops[1];
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800760 ops[0].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700761 ops[0].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700762 ops[0].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800763
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200764 return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
765 ctx, NULL);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800766}
767
Craig Tillerb256faa2015-07-23 11:28:16 -0700768GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700769 grpc_call* call, grpcsharp_batch_context* ctx, grpc_status_code status_code,
770 const char* status_details, size_t status_details_len,
771 grpc_metadata_array* trailing_metadata, int32_t send_empty_initial_metadata,
772 const char* optional_send_buffer, size_t optional_send_buffer_len,
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700773 uint32_t write_flags) {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800774 /* TODO: don't use magic number */
Jan Tattermusch305ffd42016-05-04 10:26:24 -0700775 grpc_op ops[3];
David Garcia Quintasa301eaa2016-05-06 16:59:03 -0700776 memset(ops, 0, sizeof(ops));
Jan Tattermusch305ffd42016-05-04 10:26:24 -0700777 size_t nops = 1;
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700778 grpc_slice status_details_slice =
779 grpc_slice_from_copied_buffer(status_details, status_details_len);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800780 ops[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER;
781 ops[0].data.send_status_from_server.status = status_code;
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800782 ops[0].data.send_status_from_server.status_details = &status_details_slice;
Craig Tillerb256faa2015-07-23 11:28:16 -0700783 grpcsharp_metadata_array_move(
784 &(ctx->send_status_from_server.trailing_metadata), trailing_metadata);
Jan Tattermuscha0bb0652015-07-20 22:34:19 -0700785 ops[0].data.send_status_from_server.trailing_metadata_count =
786 ctx->send_status_from_server.trailing_metadata.count;
787 ops[0].data.send_status_from_server.trailing_metadata =
788 ctx->send_status_from_server.trailing_metadata.metadata;
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700789 ops[0].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700790 ops[0].reserved = NULL;
Jan Tattermusch305ffd42016-05-04 10:26:24 -0700791 if (optional_send_buffer) {
792 ops[nops].op = GRPC_OP_SEND_MESSAGE;
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700793 ctx->send_message =
794 string_to_byte_buffer(optional_send_buffer, optional_send_buffer_len);
Mark D. Roth448c1f02017-01-25 10:44:30 -0800795 ops[nops].data.send_message.send_message = ctx->send_message;
Jan Tattermusch305ffd42016-05-04 10:26:24 -0700796 ops[nops].flags = write_flags;
797 ops[nops].reserved = NULL;
Carl Mastrangelo5f3a1432017-02-07 08:14:29 -0800798 nops++;
Jan Tattermusch305ffd42016-05-04 10:26:24 -0700799 }
800 if (send_empty_initial_metadata) {
801 ops[nops].op = GRPC_OP_SEND_INITIAL_METADATA;
Jan Tattermusch305ffd42016-05-04 10:26:24 -0700802 ops[nops].flags = 0;
803 ops[nops].reserved = NULL;
804 nops++;
805 }
Jan Tattermusch06eb0572017-06-08 18:21:09 +0200806 grpc_call_error ret = grpcsharp_call_start_batch(call, ops, nops, ctx, NULL);
807 grpc_slice_unref(status_details_slice);
808 return ret;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800809}
810
Jan Tattermuschfa216732015-02-18 11:06:44 -0800811GPR_EXPORT grpc_call_error GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700812grpcsharp_call_recv_message(grpc_call* call, grpcsharp_batch_context* ctx) {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800813 /* TODO: don't use magic number */
814 grpc_op ops[1];
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800815 ops[0].op = GRPC_OP_RECV_MESSAGE;
Mark D. Roth448c1f02017-01-25 10:44:30 -0800816 ops[0].data.recv_message.recv_message = &(ctx->recv_message);
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700817 ops[0].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700818 ops[0].reserved = NULL;
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200819 return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
820 ctx, NULL);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800821}
822
Jan Tattermuschfa216732015-02-18 11:06:44 -0800823GPR_EXPORT grpc_call_error GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700824grpcsharp_call_start_serverside(grpc_call* call, grpcsharp_batch_context* ctx) {
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800825 /* TODO: don't use magic number */
Jan Tattermuschbff90ac2015-08-06 21:30:26 -0700826 grpc_op ops[1];
827 ops[0].op = GRPC_OP_RECV_CLOSE_ON_SERVER;
828 ops[0].data.recv_close_on_server.cancelled =
829 (&ctx->recv_close_on_server_cancelled);
David Garcia Quintasd7e0bea2015-06-15 13:27:17 -0700830 ops[0].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700831 ops[0].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800832
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200833 return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
834 ctx, NULL);
Jan Tattermuschbff90ac2015-08-06 21:30:26 -0700835}
836
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700837GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_initial_metadata(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700838 grpc_call* call, grpcsharp_batch_context* ctx,
839 grpc_metadata_array* initial_metadata) {
Jan Tattermuschbff90ac2015-08-06 21:30:26 -0700840 /* TODO: don't use magic number */
841 grpc_op ops[1];
David Garcia Quintasa301eaa2016-05-06 16:59:03 -0700842 memset(ops, 0, sizeof(ops));
Jan Tattermuschbff90ac2015-08-06 21:30:26 -0700843 ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
844 grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
845 initial_metadata);
846 ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
847 ops[0].data.send_initial_metadata.metadata =
848 ctx->send_initial_metadata.metadata;
Jan Tattermusch5321d492015-08-07 23:21:27 -0700849 ops[0].flags = 0;
Craig Tiller42758992015-08-18 10:34:32 -0700850 ops[0].reserved = NULL;
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800851
Jan Tattermusch254ab4c2017-05-23 18:07:17 +0200852 return grpcsharp_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]),
853 ctx, NULL);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800854}
855
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700856GPR_EXPORT grpc_call_error GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700857grpcsharp_call_set_credentials(grpc_call* call, grpc_call_credentials* creds) {
Jan Tattermusch08dea322015-10-26 17:34:10 -0700858 return grpc_call_set_credentials(call, creds);
Jan Tattermusch74f39e12015-09-23 20:14:56 -0700859}
860
Jan Tattermusch3f8962c2015-02-17 19:20:39 -0800861/* Server */
862
Craig Tillerbaa14a92017-11-03 09:09:36 -0700863GPR_EXPORT grpc_server* GPR_CALLTYPE
864grpcsharp_server_create(const grpc_channel_args* args) {
Jan Tattermusch5ee8e772016-05-24 16:17:10 -0400865 return grpc_server_create(args, NULL);
866}
867
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700868GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_register_completion_queue(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700869 grpc_server* server, grpc_completion_queue* cq) {
Nicolas "Pixel" Noble8c597912015-08-07 20:42:22 +0200870 grpc_server_register_completion_queue(server, cq, NULL);
Jan Tattermusch3f8962c2015-02-17 19:20:39 -0800871}
872
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700873GPR_EXPORT int32_t GPR_CALLTYPE grpcsharp_server_add_insecure_http2_port(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700874 grpc_server* server, const char* addr) {
Craig Tillerc5ae3eb2015-08-03 10:42:22 -0700875 return grpc_server_add_insecure_http2_port(server, addr);
Jan Tattermusch3f8962c2015-02-17 19:20:39 -0800876}
877
Craig Tillerbaa14a92017-11-03 09:09:36 -0700878GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_start(grpc_server* server) {
Jan Tattermusch3f8962c2015-02-17 19:20:39 -0800879 grpc_server_start(server);
880}
881
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700882GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_shutdown_and_notify_callback(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700883 grpc_server* server, grpc_completion_queue* cq,
884 grpcsharp_batch_context* ctx) {
Jan Tattermuschc4e81ad2015-05-29 17:39:07 -0700885 grpc_server_shutdown_and_notify(server, cq, ctx);
886}
887
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700888GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700889grpcsharp_server_cancel_all_calls(grpc_server* server) {
Jan Tattermuschc4e81ad2015-05-29 17:39:07 -0700890 grpc_server_cancel_all_calls(server);
Jan Tattermusch3f8962c2015-02-17 19:20:39 -0800891}
892
Craig Tillerbaa14a92017-11-03 09:09:36 -0700893GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_destroy(grpc_server* server) {
Jan Tattermusch3f8962c2015-02-17 19:20:39 -0800894 grpc_server_destroy(server);
895}
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800896
Jan Tattermuschfa216732015-02-18 11:06:44 -0800897GPR_EXPORT grpc_call_error GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700898grpcsharp_server_request_call(grpc_server* server, grpc_completion_queue* cq,
899 grpcsharp_request_call_context* ctx) {
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700900 return grpc_server_request_call(server, &(ctx->call), &(ctx->call_details),
901 &(ctx->request_metadata), cq, cq, ctx);
Jan Tattermusch337a2dd2015-02-13 15:41:41 -0800902}
Jan Tattermusch50faa8f2015-02-21 17:51:52 -0800903
Jan Tattermusch15329232015-03-02 15:32:47 -0800904/* Security */
905
Craig Tillerbaa14a92017-11-03 09:09:36 -0700906static char* default_pem_root_certs = NULL;
Jan Tattermusch660c15b2016-02-02 06:39:10 -0800907
908static grpc_ssl_roots_override_result override_ssl_roots_handler(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700909 char** pem_root_certs) {
Jan Tattermusch660c15b2016-02-02 06:39:10 -0800910 if (!default_pem_root_certs) {
911 *pem_root_certs = NULL;
912 return GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY;
913 }
914 *pem_root_certs = gpr_strdup(default_pem_root_certs);
915 return GRPC_SSL_ROOTS_OVERRIDE_OK;
916}
917
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700918GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700919grpcsharp_override_default_ssl_roots(const char* pem_root_certs) {
Jan Tattermusch660c15b2016-02-02 06:39:10 -0800920 /*
921 * This currently wastes ~300kB of memory by keeping a copy of roots
922 * in a static variable, but for desktop/server use, the overhead
923 * is negligible. In the future, we might want to change the behavior
924 * for mobile (e.g. Xamarin).
925 */
926 default_pem_root_certs = gpr_strdup(pem_root_certs);
927 grpc_set_ssl_roots_override_callback(override_ssl_roots_handler);
928}
929
Craig Tillerbaa14a92017-11-03 09:09:36 -0700930GPR_EXPORT grpc_channel_credentials* GPR_CALLTYPE
931grpcsharp_ssl_credentials_create(const char* pem_root_certs,
932 const char* key_cert_pair_cert_chain,
933 const char* key_cert_pair_private_key) {
Jan Tattermusch15329232015-03-02 15:32:47 -0800934 grpc_ssl_pem_key_cert_pair key_cert_pair;
935 if (key_cert_pair_cert_chain || key_cert_pair_private_key) {
936 key_cert_pair.cert_chain = key_cert_pair_cert_chain;
937 key_cert_pair.private_key = key_cert_pair_private_key;
Julien Boeufc5b570f2015-08-25 17:47:55 -0700938 return grpc_ssl_credentials_create(pem_root_certs, &key_cert_pair, NULL);
Jan Tattermusch15329232015-03-02 15:32:47 -0800939 } else {
940 GPR_ASSERT(!key_cert_pair_cert_chain);
941 GPR_ASSERT(!key_cert_pair_private_key);
Julien Boeufc5b570f2015-08-25 17:47:55 -0700942 return grpc_ssl_credentials_create(pem_root_certs, NULL, NULL);
Jan Tattermusch15329232015-03-02 15:32:47 -0800943 }
944}
945
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700946GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700947grpcsharp_channel_credentials_release(grpc_channel_credentials* creds) {
Jan Tattermusch08dea322015-10-26 17:34:10 -0700948 grpc_channel_credentials_release(creds);
949}
950
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700951GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700952grpcsharp_call_credentials_release(grpc_call_credentials* creds) {
Jan Tattermusch08dea322015-10-26 17:34:10 -0700953 grpc_call_credentials_release(creds);
Jan Tattermusch15329232015-03-02 15:32:47 -0800954}
955
Craig Tillerbaa14a92017-11-03 09:09:36 -0700956GPR_EXPORT grpc_channel* GPR_CALLTYPE grpcsharp_secure_channel_create(
957 grpc_channel_credentials* creds, const char* target,
958 const grpc_channel_args* args) {
Julien Boeufc5b570f2015-08-25 17:47:55 -0700959 return grpc_secure_channel_create(creds, target, args, NULL);
Jan Tattermusch15329232015-03-02 15:32:47 -0800960}
961
Craig Tillerbaa14a92017-11-03 09:09:36 -0700962GPR_EXPORT grpc_server_credentials* GPR_CALLTYPE
Jan Tattermuschb0829eb2015-03-03 09:30:55 -0800963grpcsharp_ssl_server_credentials_create(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700964 const char* pem_root_certs, const char** key_cert_pair_cert_chain_array,
965 const char** key_cert_pair_private_key_array, size_t num_key_cert_pairs,
Jan Tattermuschd27dfa72015-08-04 18:10:54 -0700966 int force_client_auth) {
Jan Tattermuschb0829eb2015-03-03 09:30:55 -0800967 size_t i;
Craig Tillerbaa14a92017-11-03 09:09:36 -0700968 grpc_server_credentials* creds;
969 grpc_ssl_pem_key_cert_pair* key_cert_pairs =
Jan Tattermuschb0829eb2015-03-03 09:30:55 -0800970 gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair) * num_key_cert_pairs);
971 memset(key_cert_pairs, 0,
972 sizeof(grpc_ssl_pem_key_cert_pair) * num_key_cert_pairs);
973
974 for (i = 0; i < num_key_cert_pairs; i++) {
975 if (key_cert_pair_cert_chain_array[i] ||
976 key_cert_pair_private_key_array[i]) {
977 key_cert_pairs[i].cert_chain = key_cert_pair_cert_chain_array[i];
978 key_cert_pairs[i].private_key = key_cert_pair_private_key_array[i];
979 }
980 }
Deepak Lukosedba4c5f2016-03-25 12:54:25 -0700981 creds = grpc_ssl_server_credentials_create_ex(
982 pem_root_certs, key_cert_pairs, num_key_cert_pairs,
983 force_client_auth
984 ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
985 : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
986 NULL);
Jan Tattermuschb0829eb2015-03-03 09:30:55 -0800987 gpr_free(key_cert_pairs);
988 return creds;
989}
990
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700991GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -0700992grpcsharp_server_credentials_release(grpc_server_credentials* creds) {
Jan Tattermuschb0829eb2015-03-03 09:30:55 -0800993 grpc_server_credentials_release(creds);
994}
995
Craig Tiller5b1c5f22017-04-19 09:52:18 -0700996GPR_EXPORT int32_t GPR_CALLTYPE grpcsharp_server_add_secure_http2_port(
Craig Tillerbaa14a92017-11-03 09:09:36 -0700997 grpc_server* server, const char* addr, grpc_server_credentials* creds) {
Jan Tattermuschb0829eb2015-03-03 09:30:55 -0800998 return grpc_server_add_secure_http2_port(server, addr, creds);
999}
1000
Craig Tillerbaa14a92017-11-03 09:09:36 -07001001GPR_EXPORT grpc_channel_credentials* GPR_CALLTYPE
Craig Tiller5b1c5f22017-04-19 09:52:18 -07001002grpcsharp_composite_channel_credentials_create(
Craig Tillerbaa14a92017-11-03 09:09:36 -07001003 grpc_channel_credentials* channel_creds,
1004 grpc_call_credentials* call_creds) {
Craig Tiller5b1c5f22017-04-19 09:52:18 -07001005 return grpc_composite_channel_credentials_create(channel_creds, call_creds,
1006 NULL);
Jan Tattermusch08dea322015-10-26 17:34:10 -07001007}
1008
Craig Tillerbaa14a92017-11-03 09:09:36 -07001009GPR_EXPORT grpc_call_credentials* GPR_CALLTYPE
1010grpcsharp_composite_call_credentials_create(grpc_call_credentials* creds1,
1011 grpc_call_credentials* creds2) {
Jan Tattermusch08dea322015-10-26 17:34:10 -07001012 return grpc_composite_call_credentials_create(creds1, creds2, NULL);
Jan Tattermusch5bd75d72015-09-08 10:55:20 -07001013}
1014
1015/* Metadata credentials plugin */
1016
1017GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_credentials_notify_from_plugin(
Craig Tillerbaa14a92017-11-03 09:09:36 -07001018 grpc_credentials_plugin_metadata_cb cb, void* user_data,
1019 grpc_metadata_array* metadata, grpc_status_code status,
1020 const char* error_details) {
Jan Tattermuschae4ab4f2016-11-09 22:52:38 +01001021 if (metadata) {
1022 cb(user_data, metadata->metadata, metadata->count, status, error_details);
1023 } else {
1024 cb(user_data, NULL, 0, status, error_details);
1025 }
Jan Tattermusch5bd75d72015-09-08 10:55:20 -07001026}
1027
Craig Tillerbaa14a92017-11-03 09:09:36 -07001028typedef void(GPR_CALLTYPE* grpcsharp_metadata_interceptor_func)(
1029 void* state, const char* service_url, const char* method_name,
1030 grpc_credentials_plugin_metadata_cb cb, void* user_data,
Craig Tiller5b1c5f22017-04-19 09:52:18 -07001031 int32_t is_destroy);
Jan Tattermusch5bd75d72015-09-08 10:55:20 -07001032
Mark D. Roth2caf0212017-09-01 15:04:13 -07001033static int grpcsharp_get_metadata_handler(
Craig Tillerbaa14a92017-11-03 09:09:36 -07001034 void* state, grpc_auth_metadata_context context,
1035 grpc_credentials_plugin_metadata_cb cb, void* user_data,
Mark D. Roth2caf0212017-09-01 15:04:13 -07001036 grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX],
Craig Tillerbaa14a92017-11-03 09:09:36 -07001037 size_t* num_creds_md, grpc_status_code* status,
1038 const char** error_details) {
Jan Tattermusch706a0102015-09-24 18:34:39 -07001039 grpcsharp_metadata_interceptor_func interceptor =
Craig Tiller7536af02015-12-22 13:49:30 -08001040 (grpcsharp_metadata_interceptor_func)(intptr_t)state;
Craig Tiller5b1c5f22017-04-19 09:52:18 -07001041 interceptor(state, context.service_url, context.method_name, cb, user_data,
1042 0);
Mark D. Roth1ff6ee12017-09-06 14:56:18 -07001043 return 0; /* Asynchronous return. */
Jan Tattermusch5bd75d72015-09-08 10:55:20 -07001044}
1045
Craig Tillerbaa14a92017-11-03 09:09:36 -07001046static void grpcsharp_metadata_credentials_destroy_handler(void* state) {
Jan Tattermusch706a0102015-09-24 18:34:39 -07001047 grpcsharp_metadata_interceptor_func interceptor =
Craig Tiller7536af02015-12-22 13:49:30 -08001048 (grpcsharp_metadata_interceptor_func)(intptr_t)state;
Jan Tattermusch189fcf82015-12-02 13:41:12 -08001049 interceptor(state, NULL, NULL, NULL, NULL, 1);
Jan Tattermusch5bd75d72015-09-08 10:55:20 -07001050}
1051
Craig Tillerbaa14a92017-11-03 09:09:36 -07001052GPR_EXPORT grpc_call_credentials* GPR_CALLTYPE
Craig Tiller5b1c5f22017-04-19 09:52:18 -07001053grpcsharp_metadata_credentials_create_from_plugin(
1054 grpcsharp_metadata_interceptor_func metadata_interceptor) {
Jan Tattermusch5bd75d72015-09-08 10:55:20 -07001055 grpc_metadata_credentials_plugin plugin;
1056 plugin.get_metadata = grpcsharp_get_metadata_handler;
1057 plugin.destroy = grpcsharp_metadata_credentials_destroy_handler;
Craig Tillerbaa14a92017-11-03 09:09:36 -07001058 plugin.state = (void*)(intptr_t)metadata_interceptor;
Julien Boeufcaf99352015-11-19 22:00:30 -08001059 plugin.type = "";
Jan Tattermusch5bd75d72015-09-08 10:55:20 -07001060 return grpc_metadata_credentials_create_from_plugin(plugin, NULL);
1061}
1062
Jan Tattermuschc9b03fe2017-02-06 08:45:00 -08001063/* Auth context */
1064
Craig Tillerbaa14a92017-11-03 09:09:36 -07001065GPR_EXPORT grpc_auth_context* GPR_CALLTYPE
1066grpcsharp_call_auth_context(grpc_call* call) {
Jan Tattermuschc9b03fe2017-02-06 08:45:00 -08001067 return grpc_call_auth_context(call);
1068}
1069
Craig Tillerbaa14a92017-11-03 09:09:36 -07001070GPR_EXPORT const char* GPR_CALLTYPE
Craig Tiller5b1c5f22017-04-19 09:52:18 -07001071grpcsharp_auth_context_peer_identity_property_name(
Craig Tillerbaa14a92017-11-03 09:09:36 -07001072 const grpc_auth_context* ctx) {
Jan Tattermuschc9b03fe2017-02-06 08:45:00 -08001073 return grpc_auth_context_peer_identity_property_name(ctx);
1074}
1075
1076GPR_EXPORT grpc_auth_property_iterator GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -07001077grpcsharp_auth_context_property_iterator(const grpc_auth_context* ctx) {
Jan Tattermuschc9b03fe2017-02-06 08:45:00 -08001078 return grpc_auth_context_property_iterator(ctx);
1079}
1080
Craig Tillerbaa14a92017-11-03 09:09:36 -07001081GPR_EXPORT const grpc_auth_property* GPR_CALLTYPE
1082grpcsharp_auth_property_iterator_next(grpc_auth_property_iterator* it) {
Jan Tattermuschc9b03fe2017-02-06 08:45:00 -08001083 return grpc_auth_property_iterator_next(it);
1084}
1085
Craig Tiller5b1c5f22017-04-19 09:52:18 -07001086GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -07001087grpcsharp_auth_context_release(grpc_auth_context* ctx) {
Jan Tattermuschc9b03fe2017-02-06 08:45:00 -08001088 grpc_auth_context_release(ctx);
1089}
1090
Jan Tattermusch53398142015-02-24 08:21:57 -08001091/* Logging */
1092
Craig Tillerbaa14a92017-11-03 09:09:36 -07001093typedef void(GPR_CALLTYPE* grpcsharp_log_func)(const char* file, int32_t line,
Craig Tiller7536af02015-12-22 13:49:30 -08001094 uint64_t thd_id,
Craig Tillerbaa14a92017-11-03 09:09:36 -07001095 const char* severity_string,
1096 const char* msg);
Jan Tattermusch53398142015-02-24 08:21:57 -08001097static grpcsharp_log_func log_func = NULL;
1098
1099/* Redirects gpr_log to log_func callback */
Craig Tillerbaa14a92017-11-03 09:09:36 -07001100static void grpcsharp_log_handler(gpr_log_func_args* args) {
Jan Tattermusch44553b52015-02-25 09:52:18 -08001101 log_func(args->file, args->line, gpr_thd_currentid(),
1102 gpr_log_severity_string(args->severity), args->message);
Jan Tattermusch53398142015-02-24 08:21:57 -08001103}
1104
Jan Tattermusch44553b52015-02-25 09:52:18 -08001105GPR_EXPORT void GPR_CALLTYPE grpcsharp_redirect_log(grpcsharp_log_func func) {
1106 GPR_ASSERT(func);
1107 log_func = func;
1108 gpr_set_log_function(grpcsharp_log_handler);
Jan Tattermusch53398142015-02-24 08:21:57 -08001109}
Jan Tattermusch50faa8f2015-02-21 17:51:52 -08001110
Craig Tillerbaa14a92017-11-03 09:09:36 -07001111typedef void(GPR_CALLTYPE* test_callback_funcptr)(int32_t success);
Jan Tattermuscheb741d12015-06-11 19:09:15 -07001112
Jan Tattermuschc5a6aca2015-08-09 23:41:17 -07001113/* Version info */
Craig Tillerbaa14a92017-11-03 09:09:36 -07001114GPR_EXPORT const char* GPR_CALLTYPE grpcsharp_version_string() {
Jan Tattermuschc5a6aca2015-08-09 23:41:17 -07001115 return grpc_version_string();
1116}
1117
Jan Tattermusch50faa8f2015-02-21 17:51:52 -08001118/* For testing */
1119GPR_EXPORT void GPR_CALLTYPE
Jan Tattermuscheb741d12015-06-11 19:09:15 -07001120grpcsharp_test_callback(test_callback_funcptr callback) {
1121 callback(1);
Jan Tattermusch50faa8f2015-02-21 17:51:52 -08001122}
1123
1124/* For testing */
Craig Tillerbaa14a92017-11-03 09:09:36 -07001125GPR_EXPORT void* GPR_CALLTYPE grpcsharp_test_nop(void* ptr) { return ptr; }
Jan Tattermuschd3677482015-06-01 19:27:40 -07001126
1127/* For testing */
Craig Tiller7536af02015-12-22 13:49:30 -08001128GPR_EXPORT int32_t GPR_CALLTYPE grpcsharp_sizeof_grpc_event(void) {
Jan Tattermuschd3677482015-06-01 19:27:40 -07001129 return sizeof(grpc_event);
1130}
Jan Tattermusch645ae742017-05-22 08:46:26 -07001131
1132/* Override a method for testing */
Jan Tattermusch254ab4c2017-05-23 18:07:17 +02001133GPR_EXPORT void GPR_CALLTYPE
Craig Tillerbaa14a92017-11-03 09:09:36 -07001134grpcsharp_test_override_method(const char* method_name, const char* variant) {
Jan Tattermusch254ab4c2017-05-23 18:07:17 +02001135 if (strcmp("grpcsharp_call_start_batch", method_name) == 0) {
1136 if (strcmp("nop", variant) == 0) {
Jan Tattermusch645ae742017-05-22 08:46:26 -07001137 g_call_start_batch_func = grpcsharp_call_start_batch_nop;
1138 } else {
1139 GPR_ASSERT(0);
1140 }
1141 } else {
1142 GPR_ASSERT(0);
1143 }
1144}