OpenNSL API Guide and Reference Manual
example_rpc_client.c
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * Copyright © 2017 Broadcom. The term "Broadcom" refers
4  * to Broadcom Limited and/or its subsidiaries.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  *
9  * You may obtain a copy of the License at
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  ***************************************************************************/
19 
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdbool.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <stdlib.h>
26 #include <ctype.h>
27 
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <opennsl/error.h>
33 #include <opennsl/types.h>
34 #include <examples/util.h>
35 #include <cJSON.h>
36 #include <examples/rpc_utils.h>
37 
38 
39 int process_response(char *buffer, int length, int api_id)
40 {
41  char *json;
42  char jsonrpc[JSON_MAX_NODE_LENGTH] = {0};
43  cJSON *root, *json_jsonrpc;
44  cJSON *json_result;
45  cJSON *json_error, *json_code, *json_message;
46  int len = 0;
47 
48 
49  if (0 == length)
50  {
51  printf("no bytes read. error !!\n");
52  return -1;
53  }
54 
55  /* Validating 'length' */
56  if (length > strlen(buffer))
57  {
58  printf("Invalid value for parameter length %d ", len );
59  return -1;
60  }
61 
62  json = strstr(buffer, "\r\n\r\n");
63 
64  if (NULL == json)
65  {
66  /* the http header is not present.
67  assume that the passed buffer is json.
68  if not the validation would fail */
69 
70  json = buffer;
71  }
72 
73  printf("Response message:\n%d:%s\n",length,json);
74 
75  len = strlen(json);
76 
77  /* Parse JSON to a C-JSON root */
78  root = cJSON_Parse(json);
79  JSON_VALIDATE_JSON_POINTER(root, "root", -1);
80 
81  /* Parsing and Validating 'jsonrpc' from JSON buffer */
82  json_jsonrpc = cJSON_GetObjectItem(root, "jsonrpc");
83  JSON_VALIDATE_JSON_POINTER(json_jsonrpc, "jsonrpc", -1);
84  cJSON_Print(json_jsonrpc);
85  JSON_VALIDATE_JSON_AS_STRING(json_jsonrpc, "jsonrpc", -1);
86  /* Copy the string, with a limit on max characters */
87  strncpy (&jsonrpc[0], json_jsonrpc->valuestring, JSON_MAX_NODE_LENGTH - 1);
88  /* Ensure that 'jsonrpc' in the JSON equals "2.0" */
89  JSON_COMPARE_STRINGS_AND_CLEANUP ("jsonrpc", &jsonrpc[0], "2.0");
90 
91  /* Parsing and Validating 'id' from JSON buffer */
92  json_error = cJSON_GetObjectItem(root, "error");
93  if(json_error)
94  {
95  json_code = cJSON_GetObjectItem(json_error, "code");
96  JSON_VALIDATE_JSON_POINTER(json_code, "code", -1);
97  cJSON_Print(json_code);
98  JSON_VALIDATE_JSON_AS_NUMBER(json_code, "code");
99 
100  json_message = cJSON_GetObjectItem(json_error, "message");
101  JSON_VALIDATE_JSON_POINTER(json_message, "message", -1);
102  cJSON_Print(json_message);
103  JSON_VALIDATE_JSON_AS_STRING(json_message, "message", -1);
104 
105  printf("Received FAILURE response,%s(%d), from the server.\n",json_message->valuestring, json_code->valueint);
106  }
107  else
108  {
109  json_result = cJSON_GetObjectItem(root, "result");
110  JSON_VALIDATE_JSON_POINTER(json_result, "result", -1);
111 
112  switch(api_id)
113  {
114  case 1:
115  {
116  cJSON_Print(json_result);
117  JSON_VALIDATE_JSON_AS_NUMBER(json_result, "result");
118 
119  printf("Result:%d.\n", json_result->valueint);
120 
121  break;
122  } /* End of case 1 */
123 
124  case 2:
125  {
126  cJSON *json_btm, *json_ebt, *json_es;
127 
128  json_ebt = cJSON_GetObjectItem(json_result, "enable-buffer-tracking");
129  JSON_VALIDATE_JSON_POINTER(json_ebt, "enable-buffer-tracking", -1);
130  cJSON_Print(json_ebt);
131  JSON_VALIDATE_JSON_AS_NUMBER(json_ebt, "enable-buffer-tracking");
132 
133  json_btm = cJSON_GetObjectItem(json_result, "buffer-tracking-mode");
134  JSON_VALIDATE_JSON_POINTER(json_btm, "buffer-tracking-mode", -1);
135  cJSON_Print(json_btm);
136  JSON_VALIDATE_JSON_AS_STRING(json_btm, "buffer-tracking-mode", -1);
137 
138  json_es = cJSON_GetObjectItem(json_result, "enable-snapshots");
139  JSON_VALIDATE_JSON_POINTER(json_es, "enable-snapshots", -1);
140  cJSON_Print(json_es);
141  JSON_VALIDATE_JSON_AS_NUMBER(json_es, "enable-snapshots");
142 
143  printf("enable-buffer-tracking:%d\nbuffer-tracking-mode:%s\nenable-snapshots:%d.\n", json_ebt->valueint, json_btm->valuestring,json_es->valueint);
144 
145  break;
146  } /* End of case 2 */
147 
148  case 3:
149  {
150  cJSON *json_gport;
151 
152  json_gport = cJSON_GetObjectItem(json_result, "global-port-id");
153  JSON_VALIDATE_JSON_POINTER(json_gport, "global-port-id", -1);
154  cJSON_Print(json_gport);
155  JSON_VALIDATE_JSON_AS_NUMBER(json_gport, "global-port-id");
156 
157  printf("gport:%d.\n", json_gport->valueint);
158 
159  break;
160  } /* End of case 3 */
161 
162  case 4:
163  {
164  cJSON *json_device, *json_revision;
165 
166  json_device = cJSON_GetObjectItem(json_result, "device");
167  JSON_VALIDATE_JSON_POINTER(json_device, "device", -1);
168  cJSON_Print(json_device);
169  JSON_VALIDATE_JSON_AS_NUMBER(json_device, "device");
170 
171  json_revision = cJSON_GetObjectItem(json_result, "revision");
172  JSON_VALIDATE_JSON_POINTER(json_revision, "revision", -1);
173  cJSON_Print(json_revision);
174  JSON_VALIDATE_JSON_AS_NUMBER(json_revision, "revision");
175 
176  printf("Device:%d Revision:%d.\n", json_device->valueint, json_revision->valueint);
177 
178  break;
179  } /* End of case 4 */
180 
181  case 5:
182  {
183  cJSON *json_maxunits;
184 
185  json_maxunits = cJSON_GetObjectItem(json_result, "max-units");
186  JSON_VALIDATE_JSON_POINTER(json_maxunits, "max-units", -1);
187  cJSON_Print(json_maxunits);
188  JSON_VALIDATE_JSON_AS_NUMBER(json_maxunits, "max-units");
189 
190  printf("Max-Units:%d.\n", json_maxunits->valueint);
191 
192  break;
193  } /* End of case 5 */
194  case 6:
195  {
196  cJSON *json_ge, *json_xe, *json_ce, *json_port, *json_cpu, *json_all;
197 
198  json_ge = cJSON_GetObjectItem(json_result, "ge-bmp");
199  JSON_VALIDATE_JSON_POINTER(json_ge, "ge-bmp", -1);
200  cJSON_Print(json_ge);
201  /* JSON_VALIDATE_JSON_AS_ARRAY(json_ge, "ge-bmp");*/
202 
203  json_xe = cJSON_GetObjectItem(json_result, "xe-bmp");
204  JSON_VALIDATE_JSON_POINTER(json_xe, "xe-bmp", -1);
205  cJSON_Print(json_xe);
206  /* JSON_VALIDATE_JSON_AS_ARRAY(json_xe, "xe-bmp");*/
207 
208  json_ce = cJSON_GetObjectItem(json_result, "ce-bmp");
209  JSON_VALIDATE_JSON_POINTER(json_ce, "ce-bmp", -1);
210  cJSON_Print(json_ce);
211  /* JSON_VALIDATE_JSON_AS_ARRAY(json_ce, "ce-bmp");*/
212 
213  json_port = cJSON_GetObjectItem(json_result, "port-bmp");
214  JSON_VALIDATE_JSON_POINTER(json_port, "port-bmp", -1);
215  cJSON_Print(json_port);
216  /* JSON_VALIDATE_JSON_AS_ARRAY(json_port, "port-bmp");*/
217 
218  json_cpu = cJSON_GetObjectItem(json_result, "cpu-bmp");
219  JSON_VALIDATE_JSON_POINTER(json_cpu, "cpu-bmp", -1);
220  cJSON_Print(json_cpu);
221  /* JSON_VALIDATE_JSON_AS_ARRAY(json_cpu, "cpu-bmp");*/
222 
223  json_all = cJSON_GetObjectItem(json_result, "all-bmp");
224  JSON_VALIDATE_JSON_POINTER(json_all, "all-bmp", -1);
225  cJSON_Print(json_all);
226  /* JSON_VALIDATE_JSON_AS_ARRAY(json_all, "all-bmp");*/
227 
228  break;
229  } /* End of case 6 */
230 
231  default:
232  break;
233  } /* End of switch */
234  }
235 
236 
237  if (root != NULL)
238  {
239  cJSON_Delete(root);
240  }
241  return 0;
242 }
243 /* __doxy_func_body_end__ */
244 
245 /******************************************************************
246  * @brief main function for the client
247  *
248  * @param[in] argc, argv
249  *
250  *
251  * @retval none
252  *
253  * @note : The server name can be provided as command line arg
254  *********************************************************************/
255 int main(int argc, char *argv[]){
256  int clientSocket;
257  int temp = 0, choice;
258  struct sockaddr_in serverAddr;
259  socklen_t addr_size;
260  char server[128] = {0};
261  char buffer[1024] = {0};
262 
263  /*---- Create the socket. The three arguments are: ----*/
264  /* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */
265  clientSocket = socket(PF_INET, SOCK_STREAM, 0);
266  if (clientSocket == -1)
267  {
268  printf("failed to create socket \n");
269  exit(0);
270  }
271 
272  /*---- Configure settings of the server address struct ----*/
273  /* Address family = Internet */
274  serverAddr.sin_family = AF_INET;
275  /* Set port number, using htons function to use proper byte order */
276  serverAddr.sin_port = htons(EXAMPLE_CONFIG_PORT);
277 
278  /*If the server hostname is supplied*/
279 
280  if(argc > 1)
281  {
282  /*Use the supplied argument*/
283  strncpy(server, argv[1],(sizeof(server) - 1));
284  printf("Connecting to the server %s, port %d ...\n", server, EXAMPLE_CONFIG_PORT);
285  }
286  else
287  {
288  /*Use the default server name or IP*/
289  strcpy(server, DEF_SERVER);
290  }
291 
292  /* Set IP address to localhost */
293  serverAddr.sin_addr.s_addr = inet_addr(server);
294  /* Set all bits of the padding field to 0 */
295  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
296 
297  /*---- Connect the socket to the server using the address struct ----*/
298  addr_size = sizeof serverAddr;
299  temp = connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
300  if (temp == -1)
301  {
302  printf("failed to connect \n");
303  close(clientSocket);
304  exit(0);
305  }
306 
307  while (1)
308  {
309  printf("\r\nUser menu: Select one of the following JSON-RPC APIs\r\n");
310  printf("1. configure-buffer-tracking\n");
311  printf("2. get-buffer-tracking\n");
312  printf("3. get-global-portid\n");
313  printf("4. get-unit-info\n");
314  printf("5. get-max-units\n");
315  printf("6. get-port-config\n");
316  printf("7. get-gportid\n");
317  printf("0. Quit the application\n");
318 
320  {
321  printf("Invalid option entered. Please re-enter.\n");
322  continue;
323  }
324 
325  switch(choice)
326  {
327  case 1:
328  {
329  char *json_api_template = "{\
330  \"jsonrpc\" : \"2.0\",\
331  \"method\" : \"configure-buffer-tracking\",\
332  \"unit\" : 0,\
333  \"params\" : { \
334  \"enable-buffer-tracking\" : 1,\
335  \"buffer-tracking-mode\" : \"peak\",\
336  \"enable-snapshots\" : 1\
337  },\
338  \"id\" : 1\
339  }";
340  strncpy (buffer, json_api_template, 1023);
341  break;
342  } /* End of case 1 */
343 
344  case 2:
345  {
346  char *json_api_template = "{\
347  \"jsonrpc\" : \"2.0\",\
348  \"method\" : \"get-buffer-tracking\",\
349  \"unit\" : 0,\
350  \"params\" : { },\
351  \"id\" : 2\
352  }";
353  strncpy (buffer, json_api_template, 1023);
354 
355  break;
356  } /* End of case 2 */
357 
358  case 3:
359  {
360  char *json_api_template = "{\
361  \"jsonrpc\" : \"2.0\",\
362  \"method\" : \"get-global-portid\",\
363  \"unit\" : 0,\
364  \"params\" : { \
365  \"local-port\" : 2\
366  },\
367  \"id\" : 3\
368  }";
369  strncpy (buffer, json_api_template, 1023);
370 
371  break;
372  } /* End of case 3 */
373 
374  case 4:
375  {
376  char *json_api_template = "{\
377  \"jsonrpc\" : \"2.0\",\
378  \"method\" : \"get-unit-info\",\
379  \"unit\" : 0,\
380  \"params\" : { },\
381  \"id\" : 4\
382  }";
383  strncpy (buffer, json_api_template, 1023);
384 
385  break;
386  } /* End of case 4 */
387 
388  case 5:
389  {
390  char *json_api_template = "{\
391  \"jsonrpc\" : \"2.0\",\
392  \"method\" : \"get-max-units\",\
393  \"unit\" : 0,\
394  \"params\" : { },\
395  \"id\" : 5\
396  }";
397  strncpy (buffer, json_api_template, 1023);
398 
399  break;
400  } /* End of case 5 */
401 
402  case 6:
403  {
404  char *json_api_template = "{\
405  \"jsonrpc\" : \"2.0\",\
406  \"method\" : \"get-port-config\",\
407  \"unit\" : 0,\
408  \"params\" : { },\
409  \"id\" : 6\
410  }";
411  strncpy (buffer, json_api_template, 1023);
412 
413  break;
414  } /* End of case 6 */
415 
416  case 7:
417  {
418  char *json_api_template = "{\
419  \"jsonrpc\" : \"2.0\",\
420  \"method\" : \"get-gportid\",\
421  \"unit\" : 0,\
422  \"params\" : { \
423  \"local-port\" : 2\
424  },\
425  \"id\" : 7\
426  }";
427  strncpy (buffer, json_api_template, 1023);
428 
429  break;
430  } /* End of case 6 */
431 
432  case 0:
433  {
434  printf("Exiting the application.\n");
435  close(clientSocket);
436  rv = opennsl_driver_exit();
437  exit(rv);
438  }
439  default:
440  continue;
441  } /* End of switch */
442 
443  temp = send(clientSocket, buffer, strlen(buffer), 0);
444  if (0 > temp)
445  {
446  printf("failed to send any data \n");
447  }
448  else
449  {
450  memset(buffer, 0, sizeof(buffer));
451  temp = read (clientSocket, buffer, RPC_MAX_BUFFER_LEN);
452  if (temp < 0)
453  {
454  /* Read error. */
455  perror ("read");
456  printf("Error reading from the socket.\n");
457  break;
458  }
459  else if (temp == 0)
460  {
461  printf("End of file reached.\n");
462  /* End-of-file. */
463  break;
464  }
465  else
466  {
467  /* Data read. */
468  temp = process_response(buffer, temp, choice);
469  if(temp)
470  {
471  printf("Error processing the response.\n");
472  }
473  }
474  }
475  } /* End of while */
476 
477  close(clientSocket);
478  exit(0);
479 }
480 /* __doxy_func_body_end__ */
481