<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en-us" xml:lang="en-us"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="security" content="public" /> <meta name="Robots" content="index,follow" /> <meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' /> <meta name="DC.Type" content="reference" /> <meta name="DC.Title" content="Example: GSKit secure server with asynchronous data receive" /> <meta name="abstract" content="This code example can be used to establish a secure server using Global Secure ToolKit (GSKit) APIs." /> <meta name="description" content="This code example can be used to establish a secure server using Global Secure ToolKit (GSKit) APIs." /> <meta name="DC.Relation" scheme="URI" content="x1ssl.htm" /> <meta name="DC.Relation" scheme="URI" content="cgskit.htm" /> <meta name="DC.Relation" scheme="URI" content="xgskclient.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/createiocompletionport.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/users_14.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/waitforiocompletion.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/destroyiocompletionport.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/bind.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/socket.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/listen.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/close.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/accept.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gsk_environment_open.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_set_buffer.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_set_enum.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gsk_environment_init.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_open.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_set_numeric_value.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_init.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gskstartrecv.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/users_25.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_close.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gsk_environment_close.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_get_numeric_value.htm" /> <meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_write.htm" /> <meta name="DC.Relation" scheme="URI" content="xgskasynch.htm" /> <meta name="DC.Relation" scheme="URI" content="xgskclient.htm" /> <meta name="copyright" content="(C) Copyright IBM Corporation 2001, 2006" /> <meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 2001, 2006" /> <meta name="DC.Format" content="XHTML" /> <meta name="DC.Identifier" content="xgskserver" /> <meta name="DC.Language" content="en-us" /> <!-- All rights reserved. Licensed Materials Property of IBM --> <!-- US Government Users Restricted Rights --> <!-- Use, duplication or disclosure restricted by --> <!-- GSA ADP Schedule Contract with IBM Corp. --> <link rel="stylesheet" type="text/css" href="./ibmdita.css" /> <link rel="stylesheet" type="text/css" href="./ic.css" /> <title>Example: GSKit secure server with asynchronous data receive</title> </head> <body id="xgskserver"><a name="xgskserver"><!-- --></a> <!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script> <h1 class="topictitle1">Example: GSKit secure server with asynchronous data receive</h1> <div><p>This code example can be used to establish a secure server using Global Secure ToolKit (GSKit) APIs.</p> <div class="section"><p>The server opens the socket, prepares the secure environment, accepts and processes connection requests, exchanges data with the client and ends the session. The client also opens a socket, sets up the secure environment, calls the server and requests a secure connection, exchanges data with the server, and closes the session. The following diagram and description shows the server/client flow of events.</p> <div class="note"><span class="notetitle">Note:</span> The following example programs use AF_INET address family, but they can be modified to also use the AF_INET6 address family.</div> </div> <div class="section"><h4 class="sectiontitle">Socket flow of events: Secure server that uses asynchronous data receive</h4><p><br /><img src="rzab6512.gif" alt="GSKit secure server that uses asynchronous data receive" /><br /></p> </div> <div class="section"><p>The following sequence of the socket calls provides a description of the graphic. It also describes the relationship between the server and client examples.</p> </div> <div class="section"> <ol><li>The <span class="apiname">QsoCreateIOCompletionPort()</span> function creates an I/O completion port.</li> <li>The <span class="apiname">pthread_create</span> function creates a worker thread to receive data and to echo it back to the client. The worker thread waits for client requests to arrive on the I/O completion port just created. </li> <li>A call to <span class="apiname">gsk_environment_open()</span> to obtain a handle to an SSL environment.</li> <li>One or more calls to gsk_attribute_set_xxxxx() to set attributes of the SSL environment. At a minimum, either a call to <span class="apiname">gsk_attribute_set_buffer()</span> to set the GSK_OS400_APPLICATION_ID value or to set the GSK_KEYRING_FILE value. Only one of these should be set. It is preferred that you use the GSK_OS400_APPLICATION_ID value. Also ensure you set the type of application (client or server), GSK_SESSION_TYPE, using <span class="apiname">gsk_attribute_set_enum()</span>.</li> <li>A call to <span class="apiname">gsk_environment_init()</span> to initialize this environment for SSL processing and to establish the SSL security information for all SSL sessions that run using this environment.</li> <li>The <span class="apiname">socket</span> function creates a socket descriptor. The server then issues the standard set of socket calls: <span class="apiname">bind()</span>, <span class="apiname">listen()</span>, and <span class="apiname">accept()</span> to enable a server to accept incoming connection requests.</li> <li>The <span class="apiname">gsk_secure_soc_open()</span> function obtains storage for a secure session, sets default values for attributes, and returns a handle that must be saved and used on secure session-related function calls. </li> <li>One or more calls to gsk_attribute_set_xxxxx() to set attributes of the secure session. At a minimum, a call to <span class="apiname">gsk_attribute_set_numeric_value()</span> to associate a specific socket with this secure session.</li> <li>A call to <span class="apiname">gsk_secure_soc_init()</span> to initiate the SSL handshake negotiation of the cryptographic parameters. <div class="note"><span class="notetitle">Note:</span> Typically, a server program must provide a certificate for an SSL handshake to succeed. A server must also have access to the private key that is associated with the server certificate and the key database file where the certificate is stored. In some cases, a client must also provide a certificate during the SSL handshake processing. This occurs if the server to which the client is connecting has enabled client authentication. The <span class="apiname">gsk_attribute_set_buffer</span>(GSK_OS400_APPLICATION_ID) or <span class="apiname">gsk_attribute_set_buffer</span>(GSK_KEYRING_FILE) API calls identify (though in dissimilar ways) the key database file from which the certificate and private key that are used during the handshake are obtained.</div> </li> <li>The <span class="apiname">gsk_secure_soc_startRecv()</span> function initiates an asynchronous receive operation on a secure session. </li> <li>The <span class="apiname">pthread_join</span> synchronizes the server and worker programs. This function waits for the thread to end, detaches the thread, and then returns the threads exit status to the server.</li> <li>The <span class="apiname">gsk_secure_soc_close()</span> function ends the secure session.</li> <li>The <span class="apiname">gsk_environment_close()</span> function closes the SSL environment. </li> <li>The <span class="apiname">close()</span> function ends the listening socket.</li> <li>The <span class="apiname">close()</span> ends the accepted (client connection) socket.</li> <li>The <span class="apiname">QsoDestroyIOCompletionPort()</span> function destroys the completion port.</li> </ol> </div> <div class="section"><h4 class="sectiontitle">Socket flow of events: Worker thread that uses GSKit APIs</h4><ol><li>After the server application creates a worker thread, it waits for server to send it the incoming client request to process client data with the <span class="apiname">gsk_secure_soc_startRecv()</span> call. The <span class="apiname">QsoWaitForIOCompletionPort()</span> function waits on the supplied IO completion port that was specified by the server.</li> <li>As soon as the client request has been received, the <span class="apiname">gsk_attribute_get_numeric_value()</span> function gets the socket descriptor associated with the secure session.</li> <li>The <span class="apiname">gsk_secure_soc_write()</span> function sends the message to the client using the secure session.</li> </ol> </div> <div class="section"><div class="note"><span class="notetitle">Note:</span> By using the code examples, you agree to the terms of the <a href="codedisclaimer.htm">Code license and disclaimer information</a>.</div> <pre>/* GSK Asynchronous Server Program using Application Id*/ /* "IBM grants you a nonexclusive copyright license */ /* to use all programming code examples from which */ /* you can generate similar function tailored to your */ /* own specific needs. */ /* */ /* All sample code is provided by IBM for illustrative*/ /* purposes only. These examples have not been */ /* thoroughly tested under all conditions. IBM, */ /* therefore, cannot guarantee or imply reliability, */ /* serviceability, or function of these programs. */ /* */ /* All programs contained herein are provided to you */ /* "AS IS" without any warranties of any kind. The */ /* implied warranties of non-infringement, */ /* merchantability and fitness for a particular */ /* purpose are expressly disclaimed. " */ /* Assummes that application id is already registered */ /* and a certificate has been associated with the */ /* application id. */ /* No parameters, some comments and many hardcoded */ /* values to keep it short and simple */ /* use following command to create bound program: */ /* CRTBNDC PGM(PROG/GSKSERVa) */ /* SRCFILE(PROG/CSRC) */ /* SRCMBR(GSKSERVa) */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <gskssl.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #define _MULTI_THREADED #include "pthread.h" #include "qsoasync.h" #define Failure 0 #define Success 1 #define TRUE 1 #define FALSE 0 void *workerThread(void *arg); /********************************************************************/ /* Descriptive Name: Master thread will establish a client */ /* connection and hand processing responsibility */ /* to a worker thread. */ /* Note: Due to the thread attribute of this program, spawn() must */ /* be used to invoke. */ /********************************************************************/ int main(void) { gsk_handle my_env_handle=NULL; /* secure environment handle */ gsk_handle my_session_handle=NULL; /* secure session handle */ struct sockaddr_in address; int buf_len, on = 1, rc = 0; int sd = -1, lsd = -1, al = -1, ioCompPort = -1; int successFlag = FALSE; char buff[1024]; pthread_t thr; void *status; Qso_OverlappedIO_t ioStruct; /*********************************************/ /* Issue all of the command in a do/while */ /* loop so that clean up can happen at end */ /*********************************************/ do { /*********************************************/ /* Create an I/O completion port for this */ /* process. */ /*********************************************/ if ((ioCompPort = QsoCreateIOCompletionPort()) < 0) { perror("QsoCreateIOCompletionPort() failed"); break; } /*********************************************/ /* Create a worker thread */ /* to process all client requests. The */ /* worker thread will wait for client */ /* requests to arrive on the I/O completion */ /* port just created. */ /*********************************************/ rc = pthread_create(&thr, NULL, workerThread, &ioCompPort); if (rc < 0) { perror("pthread_create() failed"); break; } /* open a gsk environment */ rc = errno = 0; rc = gsk_environment_open(&my_env_handle); if (rc != GSK_OK) { printf("gsk_environment_open() failed with rc = %d & errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* set the Application ID to use */ rc = errno = 0; rc = gsk_attribute_set_buffer(my_env_handle, GSK_OS400_APPLICATION_ID, "MY_SERVER_APP", 13); if (rc != GSK_OK) { printf("gsk_attribute_set_buffer() failed with rc = %d & errno = %d.\n" ,rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* set this side as the server */ rc = errno = 0; rc = gsk_attribute_set_enum(my_env_handle, GSK_SESSION_TYPE, GSK_SERVER_SESSION); if (rc != GSK_OK) { printf("gsk_attribute_set_enum() failed with rc = %d & errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* by default SSL_V2, SSL_V3, and TLS_V1 are enabled */ /* We will disable SSL_V2 for this example. */ rc = errno = 0; rc = gsk_attribute_set_enum(my_env_handle, GSK_PROTOCOL_SSLV2, GSK_PROTOCOL_SSLV2_OFF); if (rc != GSK_OK) { printf("gsk_attribute_set_enum() failed with rc = %d & errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* set the cipher suite to use. By default our default list */ /* of ciphers is enabled. For this example we will just use one */ rc = errno = 0; rc = gsk_attribute_set_buffer(my_env_handle, GSK_V3_CIPHER_SPECS, "05", /* SSL_RSA_WITH_RC4_128_SHA */ 2); if (rc != GSK_OK) { printf("gsk_attribute_set_buffer() failed with rc = %d & errno = %d.\n" ,rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* Initialize the secure environment */ rc = errno = 0; rc = gsk_environment_init(my_env_handle); if (rc != GSK_OK) { printf("gsk_environment_init() failed with rc = %d & errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* initialize a socket to be used for listening */ lsd = socket(AF_INET, SOCK_STREAM, 0); if (lsd < 0) { perror("socket() failed"); break; } /* set socket so can be reused immediately */ rc = setsockopt(lsd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if (rc < 0) { perror("setsockopt() failed"); break; } /* bind to the local server address */ memset((char *) &address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_port = 13333; address.sin_addr.s_addr = 0; rc = bind(lsd, (struct sockaddr *) &address, sizeof(address)); if (rc < 0) { perror("bind() failed"); break; } /* enable the socket for incoming client connections */ listen(lsd, 5); if (rc < 0) { perror("listen() failed"); break; } /* accept an incoming client connection */ al = sizeof(address); sd = accept(lsd, (struct sockaddr *) &address, &al); if (sd < 0) { perror("accept() failed"); break; } /* open a secure session */ rc = errno = 0; rc = gsk_secure_soc_open(my_env_handle, &my_session_handle); if (rc != GSK_OK) { printf("gsk_secure_soc_open() failed with rc = %d & errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* associate our socket with the secure session */ rc=errno=0; rc = gsk_attribute_set_numeric_value(my_session_handle, GSK_FD, sd); if (rc != GSK_OK) { printf("gsk_attribute_set_numeric_value() failed with rc = %d ", rc); printf("and errno = %d.\n", errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /* initiate the SSL handshake */ rc = errno = 0; rc = gsk_secure_soc_init(my_session_handle); if (rc != GSK_OK) { printf("gsk_secure_soc_init() failed with rc = %d & errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /*********************************************/ /* Issue gsk_secure_soc_startRecv() to */ /* receive client request. */ /* Note: */ /* postFlag == on denoting request should */ /* posted to the I/O completion port, even */ /* if request is immediately available. */ /* Worker thread will process client request.*/ /*********************************************/ /*********************************************/ /* initialize Qso_OverlappedIO_t structure - */ /* reserved fields must be hex 00's. */ /*********************************************/ memset(&ioStruct, '\0', sizeof(ioStruct)); memset((char *) buff, 0, sizeof(buff)); ioStruct.buffer = buff; ioStruct.bufferLength = sizeof(buff); /*********************************************/ /* Store the session handle in the */ /* Qso_OverlappedIO_t descriptorHandle field.*/ /* This area is used to house information */ /* defining the state of the client */ /* connection. Field descriptorHandle is */ /* defined as a (void *) to allow the server */ /* to address more extensive client */ /* connection state if needed. */ /*********************************************/ ioStruct.descriptorHandle = my_session_handle; ioStruct.postFlag = 1; ioStruct.fillBuffer = 0; rc = gsk_secure_soc_startRecv(my_session_handle, ioCompPort, &ioStruct); if (rc != GSK_AS400_ASYNCHRONOUS_RECV) { printf("gsk_secure_soc_startRecv() rc = %d & errno = %d.\n",rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); break; } /*********************************************/ /* This is where the server can loop back */ /* to accept a new connection. */ /*********************************************/ /*********************************************/ /* Wait for worker thread to finish */ /* processing client connection. */ /*********************************************/ rc = pthread_join(thr, &status); /* check status of the worker */ if ( rc == 0 && (rc = __INT(status)) == Success) { printf("Success.\n"); successFlag = TRUE; } else { perror("pthread_join() reported failure"); } } while(FALSE); /* disable the SSL session */ if (my_session_handle != NULL) gsk_secure_soc_close(&my_session_handle); /* disable the SSL environment */ if (my_env_handle != NULL) gsk_environment_close(&my_env_handle); /* close the listening socket */ if (lsd > -1) close(lsd); /* close the accepted socket */ if (sd > -1) close(sd); /* destroy the completion port */ if (ioCompPort > -1) QsoDestroyIOCompletionPort(ioCompPort); if (successFlag) exit(0); else exit(-1); } /********************************************************************/ /* Function Name: workerThread */ /* */ /* Descriptive Name: Process client connection. */ /* */ /* Note: To make the sample more straight forward the main routine */ /* handles all of the clean up although this function can */ /* be made responsible for the clientfd and session_handle. */ /********************************************************************/ void *workerThread(void *arg) { struct timeval waitTime; int ioCompPort = -1, clientfd = -1; Qso_OverlappedIO_t ioStruct; int rc, tID; int amtWritten; gsk_handle client_session_handle = NULL; pthread_t thr; pthread_id_np_t t_id; t_id = pthread_getthreadid_np(); tID = t_id.intId.lo; /*********************************************/ /* I/O completion port is passed to this */ /* routine. */ /*********************************************/ ioCompPort = *(int *)arg; /*********************************************/ /* Wait on the supplied I/O completion port */ /* for a client request. */ /*********************************************/ waitTime.tv_sec = 500; waitTime.tv_usec = 0; rc = QsoWaitForIOCompletion(ioCompPort, &ioStruct, &waitTime); if ((rc == 1) && (ioStruct.returnValue == GSK_OK) && (ioStruct.operationCompleted == GSKSECURESOCSTARTRECV)) /*********************************************/ /* Client request has been received. */ /*********************************************/ ; else { perror("QsoWaitForIOCompletion()/gsk_secure_soc_startRecv() failed"); printf("ioStruct.returnValue = %d.\n", ioStruct.returnValue); return __VOID(Failure); } /* write results to screen */ printf("gsk_secure_soc_startRecv() received %d bytes, here they are:\n", ioStruct.secureDataTransferSize); printf("%s\n",ioStruct.buffer); /*********************************************/ /* Obtain the session handle associated */ /* with the client connection. */ /*********************************************/ client_session_handle = ioStruct.descriptorHandle; /* get the socket associated with the secure session */ rc=errno=0; rc = gsk_attribute_get_numeric_value(client_session_handle, GSK_FD, &clientfd); if (rc != GSK_OK) { printf("gsk_attribute_get_numeric_value() rc = %d & errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); return __VOID(Failure); } /* send the message to the client using the secure session */ amtWritten = 0; rc = gsk_secure_soc_write(client_session_handle, ioStruct.buffer, ioStruct.secureDataTransferSize, &amtWritten); if (amtWritten != ioStruct.secureDataTransferSize) { if (rc != GSK_OK) { printf("gsk_secure_soc_write() rc = %d and errno = %d.\n", rc,errno); printf("rc of %d means %s\n", rc, gsk_strerror(rc)); return __VOID(Failure); } else { printf("gsk_secure_soc_write() did not write all data.\n"); return __VOID(Failure); } } /* write results to screen */ printf("gsk_secure_soc_write() wrote %d bytes...\n", amtWritten); printf("%s\n",ioStruct.buffer); return __VOID(Success); } /* end workerThread */</pre> </div> </div> <div> <div class="familylinks"> <div class="parentlink"><strong>Parent topic:</strong> <a href="x1ssl.htm" title="You can create secure server and clients using either the Global Secure ToolKit (GSKit) APIs or the Secure Sockets Layer (SSL_) APIs.">Examples: Establish secure connections</a></div> </div> <div class="relconcepts"><strong>Related concepts</strong><br /> <div><a href="cgskit.htm" title="Global Secure ToolKit (GSKit) is a set of programmable interfaces that allow an application to be SSL enabled.">Global Secure ToolKit (GSKit) APIs</a></div> </div> <div class="relref"><strong>Related reference</strong><br /> <div><a href="xgskclient.htm" title="This code sample provides an example of a client that uses the GSKit APIs.">Example: Establish a secure client with Global Secure ToolKit (GSKit) APIs</a></div> <div><a href="xgskasynch.htm" title="The gsk_secure_soc_startInit() API allows you to create secure server applications that can handle request asynchronously.">Example: GSKit secure server with asynchronous handshake</a></div> </div> <div class="relinfo"><strong>Related information</strong><br /> <div><a href="../apis/createiocompletionport.htm">QsoCreateIOCompletionPort()</a></div> <div><a href="../apis/users_14.htm">pthread_create</a></div> <div><a href="../apis/waitforiocompletion.htm">QsoWaitForIoCompletionPort()</a></div> <div><a href="../apis/destroyiocompletionport.htm">QsoDestroyIOCompletionPort()</a></div> <div><a href="../apis/bind.htm">bind()</a></div> <div><a href="../apis/socket.htm">socket()</a></div> <div><a href="../apis/listen.htm">listen()</a></div> <div><a href="../apis/close.htm">close()</a></div> <div><a href="../apis/accept.htm">accept()</a></div> <div><a href="../apis/gsk_environment_open.htm">gsk_environment_open()</a></div> <div><a href="../apis/gsk_attribute_set_buffer.htm">gsk_attribute_set_buffer</a></div> <div><a href="../apis/gsk_attribute_set_enum.htm">gsk_attribute_set_enum()</a></div> <div><a href="../apis/gsk_environment_init.htm">gsk_environment_init()</a></div> <div><a href="../apis/gsk_secure_soc_open.htm">gsk_secure_soc_open()</a></div> <div><a href="../apis/gsk_attribute_set_numeric_value.htm">gsk_attribute_set_numeric_value()</a></div> <div><a href="../apis/gsk_secure_soc_init.htm">gsk_secure_soc_init()</a></div> <div><a href="../apis/gskstartrecv.htm">gsk_secure_soc_startRecv()</a></div> <div><a href="../apis/users_25.htm">pthread_join</a></div> <div><a href="../apis/gsk_secure_soc_close.htm">gsk_secure_soc_close()</a></div> <div><a href="../apis/gsk_environment_close.htm">gsk_environment_close()</a></div> <div><a href="../apis/gsk_attribute_get_numeric_value.htm">gsk_attribute_get_numeric_value()</a></div> <div><a href="../apis/gsk_secure_soc_write.htm">gsk_secure_soc_write()</a></div> </div> </div> </body> </html>