static ClRcT
initSocket()
{
    char               *ipaddr;
    in_addr_t           addr_val;
    char               *port;
    uint16_t            port_num;

    CL_FUNC_ENTER();

    //
    // We'll want to get the address where we'll send instrumentation
    // information out of the environment.  Initialize the sockaddr
    // so after we create the socket we can connect it to the address.
    if ((ipaddr = getenv("CL_LOGGING_ADDR")) == 0)
    {
        clOsalPrintf("No value for CL_LOGGING_ADDR\n");
        CL_FUNC_EXIT();
        return CL_RC(0, CL_ERR_INVALID_PARAMETER);
    }
    if ((port = getenv("CL_LOGGING_PORT")) == 0)
    {
        clOsalPrintf("No value for CL_LOGGING_PORT\n");
        CL_FUNC_EXIT();
        return CL_RC(0, CL_ERR_INVALID_PARAMETER);
    }
    addr_val = inet_addr(ipaddr);
    port_num = atoi(port);
    memset(&instaddr, 0, sizeof instaddr);
    instaddr.sin_port = htons(port_num);
    instaddr.sin_addr.s_addr = addr_val;

    sock = socket(PF_INET, SOCK_DGRAM, 0);
    if (sock == -1)
    {
        clOsalPrintf("Failed to open socket");
        return CL_OSAL_ERR_OS_ERROR;
    }
//    if (connect(sock, &instaddr, sizeof addr) != 0)
//    {
//        clOsalPrintf("Failed to connect socket to %s/%s\n", ipaddr, port);
//        close(sock);
//        sock = -1;
//        CL_FUNC_EXIT();
//        return CL_OSAL_ERR_OS_ERROR;
//    }
    CL_FUNC_EXIT();
    return CL_OK;
}
ClUint32T clGetTable ( ClSnmpReqInfoT* reqInfo,
        void* data, 
        ClInt32T* pErrCode)
{
    ClMedOpT        opInfo;
    ClMedVarBindT   *tempVarInfo = NULL;
    ClInt32T        errorCode = CL_OK;
    ClInt32T        retVal = 0;
    ClCharT         oid[CL_SNMP_DISPLAY_STRING_SIZE];

    opInfo.varCount = 1;
    tempVarInfo =
        (ClMedVarBindT *) clHeapCalloc(1,opInfo.varCount * sizeof (ClMedVarBindT));   
    if (tempVarInfo == NULL)
    {
        clLogError("SNM","OPE", "Failed while allocating the varbind.");
        return (CL_RC(CL_CID_SNMP, CL_ERR_NO_MEMORY));
    }
    retVal = 0;
    strcpy(oid, reqInfo->oid);
    /*oid received till this point is that of the table. Add .1.1 to 
      get oid of the first entry in the table
     */
    strcat(oid,".1.1");

    opInfo.varInfo = tempVarInfo;
    opInfo.varInfo[0].pVal = data;
    opInfo.varInfo[0].errId = 0;
    opInfo.varInfo[0].pInst = reqInfo;
    opInfo.opCode = reqInfo->opCode;
    opInfo.varInfo[0].attrId.id = (ClUint8T*)oid;
    opInfo.varInfo[0].attrId.len = (ClUint32T)strlen(oid) + 1;
    opInfo.varInfo[0].len = reqInfo->dataLen;

    errorCode = clMedOperationExecute (gSubAgentInfo.medHdl, &opInfo);

    if ((opInfo.varInfo[0].errId == 0) && (errorCode == 0))
    {
        clHeapFree (tempVarInfo);
        return (CL_OK);
    }
    else
    {
        if (errorCode != CL_OK)
            *pErrCode = errorCode;
        else
            *pErrCode = opInfo.varInfo[0].errId;

        clLogError(CL_LOG_AREA_UNSPECIFIED,CL_LOG_CONTEXT_UNSPECIFIED,
                   "clMedOperationExecute returned error. error code = %x, error id = %d",
                   errorCode, opInfo.varInfo[0].errId);
    }
    clHeapFree (tempVarInfo);
    return (errorCode);
}
ClUint32T clGetTableAttr ( ClSnmpReqInfoT* reqInfo,
        void *data, 
        ClInt32T *pErrCode)
{
    ClMedOpT opInfo;

    ClMedVarBindT *tempVarInfo = NULL;
    ClInt32T errorCode = CL_OK;

    opInfo.varCount = 1;
    tempVarInfo =
        (ClMedVarBindT *) clHeapCalloc(1,opInfo.varCount * sizeof (ClMedVarBindT));
    if (tempVarInfo == NULL)
    {
        clLogError("SNM","OPE", "Failed while allocating the varbind.");
        return (CL_RC(CL_CID_SNMP, CL_ERR_NO_MEMORY));
    }

    opInfo.varInfo = tempVarInfo;
    opInfo.varInfo[0].errId = 0;
    opInfo.varInfo[0].pInst = reqInfo;
    opInfo.opCode = reqInfo->opCode;
    opInfo.varInfo[0].pVal = data;
    opInfo.varInfo[0].len = reqInfo->dataLen;
    opInfo.varInfo[0].attrId.id = (ClUint8T*)reqInfo->oid;
    opInfo.varInfo[0].attrId.len = (ClUint32T)strlen(reqInfo->oid) + 1;
    opInfo.varInfo[0].len = reqInfo->dataLen;

    errorCode = clMedOperationExecute (gSubAgentInfo.medHdl, &opInfo);

    *pErrCode = opInfo.varInfo[0].errId;
    reqInfo->dataLen = opInfo.varInfo[0].len;

    if ((opInfo.varInfo[0].errId == 0) && (errorCode == 0))
    {
        clHeapFree(tempVarInfo);
        return (CL_OK);    
    }
    else
    {
        clHeapFree(tempVarInfo);
        return (errorCode);
    }
}
ClRcT
clInstSetIdentity(const ClNameT *nodeName, const ClNameT *compName)
{
    CL_FUNC_ENTER();
    if (myInstId == 0)
    {
        return CL_RC(0, CL_ERR_NOT_INITIALIZED);
    }
    if (myInstId->nodeName.length == 0)
    {
        memcpy(&myInstId->nodeName, nodeName, sizeof *nodeName);
    }
    if (myInstId->compName.length == 0)
    {
        memcpy(&myInstId->compName, compName, sizeof *compName);
    }
    CL_FUNC_EXIT();
    return CL_OK;
}
ClRcT
clInstInitId()
{
    ClRcT           rc          = CL_OK;
    InstrumentedId *tmpPtr      = 0;

    CL_FUNC_ENTER();
    // check whether the id has been initialized
    if (myInstId != 0)
    {
        CL_FUNC_EXIT();
        return CL_OK;
    }

    if (sock == -1)
    {
        rc = initSocket();
        if (rc != CL_OK)
        {
            clOsalPrintf("failed to initialize instrumentation socket\n");
            return rc;
        }
    }


    // Nope, not initialized, so try to initialize it here.
    // First, try to lock a mutex so that only one thread
    // will be creating the id.
    // Then, try to get our component name, our local node name
    // and then allocate the id and set it from the component
    // and local node name.
    // Finally, unlock and delete the mutex.
    if (!id_mutex)
    {
        if ((rc = clOsalMutexCreateAndLock(&id_mutex)) != CL_OK)
        {
            clOsalPrintf("Failed [0x%x] to create and lock mutex\n", rc);
            CL_FUNC_EXIT();
            return rc;
        }
    }
    else
    {
        // Some other thread must have come through here and set
        // the mutex before us.  We're done.
        CL_FUNC_EXIT();
        return CL_OK;
    }

    if ((tmpPtr = clHeapCalloc(1, sizeof (InstrumentedId))) == 0)
    {
        clOsalPrintf("failed to allocate InstrumentedID\n");
        rc = CL_RC(0, CL_ERR_NO_MEMORY);
        goto breakdown;
    }
    memset(&tmpPtr->compName, 0, sizeof tmpPtr->compName);
    memset(&tmpPtr->nodeName, 0, sizeof tmpPtr->nodeName);
    rc = CL_OK;
    myInstId = tmpPtr;
    tmpPtr = 0;

breakdown:
    clOsalMutexUnlock(id_mutex);
    clOsalMutexDelete(id_mutex);
    id_mutex = 0;

    CL_FUNC_EXIT();
    return rc;
}
ClRcT
clInstSendMessage(int msgType, const char *msg)
{
    char        msgBuf[INST_BUF_SIZE];
    ClRcT       rc = CL_OK;
    int         space;
    char       *ptr = msgBuf;

    CL_FUNC_ENTER();
    if ((rc = clInstInitId()) != CL_OK)
    {
        clOsalPrintf("Failed [0x%x] to initialize Instrumentation id\n", rc);
        CL_FUNC_EXIT();
        return rc;
    }

    //
    // Fill in the msgBuf: msgType,nodeName,compName,msg
    // Check that we have room for the message, formatting it
    // as we go.  Finally, send it over the socket which should
    // already been connected in clInstInitId
    sprintf(msgBuf, "%d", CL_INST_VERSION);
    space = sizeof msgBuf - 1;
    sprintf(msgBuf+1, "%d,", msgType);
    space = sizeof msgBuf - 2;
    ptr += strlen(ptr);
    space = (sizeof msgBuf) - (ptr - msgBuf);
    if (myInstId->nodeName.length == 0)
    {
        strcpy(ptr, "unknown_node,");
    }
    else
    {
        if ((myInstId->nodeName.length + 1) >= space)
        {
            clOsalPrintf("nodeName (%s) too long for remaining space (%d)\n",
                        myInstId->nodeName.value, space);
        }
        else
        {
            strcpy(ptr, myInstId->nodeName.value);
            strcat(ptr, ",");
        }
    }
    ptr += strlen(ptr);
    space = (sizeof msgBuf) - (ptr - msgBuf);

    if (myInstId->compName.length == 0)
    {
        strcat(ptr, "unknown_component,");
    }
    else
    {
        if ((myInstId->compName.length + 1) >= space)
        {
            clOsalPrintf("compName (%s) too long for remaining space (%d)\n",
                        myInstId->compName.value, space);
            return CL_RC(0, CL_ERR_BUFFER_OVERRUN);
        }
        else
        {
            strcpy(ptr, myInstId->compName.value);
            strcat(ptr, ",");
        }
    }
    ptr += strlen(ptr);
    space = (sizeof msgBuf) - (ptr - msgBuf);

    // check that there's enough room for the message in our buffer
    // and if there is then copy it in.
    if (strlen(msg) >= space)
    {
        strncpy(ptr, msg, space - 4);   // room for "..."
        ptr += (space - 4);
        strcpy(ptr, "...");
    }
    else
    {
        strcpy(ptr, msg);
    }
    ptr += strlen(ptr);
    space = (sizeof msgBuf) - (ptr - msgBuf);

    if (sendto(sock, msgBuf, ptr - msgBuf, 0, &instaddr, sizeof instaddr) == -1)
    {
        clOsalPrintf("Failed to send message, sock = %d, errno = %d\n", sock, errno);
        return CL_OSAL_ERR_OS_ERROR;
    }
    CL_FUNC_EXIT();
    return rc;
}