void *cmsMem_realloc(void *origBuf, UINT32 size) { void *buf; UINT32 origSize, origAllocSize, origAllocFlags; UINT32 allocSize; UINT32 *intBuf; if (origBuf == NULL) { cmsLog_error("cannot take a NULL buffer"); return NULL; } if (size == 0) { cmsMem_free(origBuf); return NULL; } allocSize = REAL_ALLOC_SIZE(size); intBuf = (UINT32 *) (((UINT32) origBuf) - CMS_MEM_HEADER_LENGTH); origAllocFlags = intBuf[0]; origSize = intBuf[1]; /* sanity check the original length */ if (intBuf[1] != (intBuf[2] ^ 0xffffffff)) { cmsLog_error("memory underflow detected, %d %d", intBuf[1], intBuf[2]); cmsAst_assert(0); return NULL; } origAllocSize = REAL_ALLOC_SIZE(origSize); if (allocSize <= origAllocSize) { /* currently, I don't shrink buffers, but could in the future. */ return origBuf; } buf = cmsMem_alloc(allocSize, origAllocFlags); if (buf != NULL) { /* got new buffer, copy orig buffer to new buffer */ memcpy(buf, origBuf, origSize); cmsMem_free(origBuf); } else { /* * We could not allocate a bigger buffer. * Return NULL but leave the original buffer untouched. */ } return buf; }
CmsRet cmsPsp_set(const char *key, const void *buf, UINT32 bufLen) { char *currBuf; SINT32 count; if ((currBuf = cmsMem_alloc(bufLen, 0)) == NULL) { return CMSRET_RESOURCE_EXCEEDED; } /* * Writing to the scratch pad is a non-preemptive time consuming * operation that should be avoided. * Check if the new data is the same as the old data. */ count = devCtl_boardIoctl(BOARD_IOCTL_FLASH_READ, SCRATCH_PAD, (char *) key, 0, (SINT32) bufLen, currBuf); if (count == (SINT32) bufLen) { if (memcmp(currBuf, buf, bufLen) == 0) { cmsMem_free(currBuf); /* set is exactly the same as the orig data, no set needed */ return CMSRET_SUCCESS; } cmsMem_free(currBuf); } return (devCtl_boardIoctl(BOARD_IOCTL_FLASH_WRITE, SCRATCH_PAD, (char *) key, 0, (SINT32) bufLen, (void *) buf)); }
CmsRet cmsUtl_parsePrefixAddress(const char *prefixAddr, char *address, UINT32 *plen) { CmsRet ret = CMSRET_SUCCESS; char *tmpBuf; char *separator; UINT32 len; if (prefixAddr == NULL || address == NULL || plen == NULL) { return CMSRET_INVALID_ARGUMENTS; } cmsLog_debug("prefixAddr=%s", prefixAddr); *address = '\0'; *plen = 128; len = strlen(prefixAddr); if ((tmpBuf = cmsMem_alloc(len+1, 0)) == NULL) { cmsLog_error("alloc of %d bytes failed", len); ret = CMSRET_INTERNAL_ERROR; } else { sprintf(tmpBuf, "%s", prefixAddr); separator = strchr(tmpBuf, '/'); if (separator != NULL) { /* break the string into two strings */ *separator = 0; separator++; while ((isspace(*separator)) && (*separator != 0)) { /* skip white space after comma */ separator++; } *plen = atoi(separator); cmsLog_debug("plen=%d", *plen); } cmsLog_debug("address=%s", tmpBuf); if (strlen(tmpBuf) < BUFLEN_40 && *plen <= 128) { strcpy(address, tmpBuf); } else { ret = CMSRET_INVALID_ARGUMENTS; } cmsMem_free(tmpBuf); } return ret; } /* End of cmsUtl_parsePrefixAddress() */
CmsRet cmsUtl_macStrToNum(const char *macStr, UINT8 *macNum) { char *pToken = NULL; char *pLast = NULL; char *buf; SINT32 i; if (macNum == NULL || macStr == NULL) { cmsLog_error("Invalid macNum/macStr %p/%p", macNum, macStr); return CMSRET_INVALID_ARGUMENTS; } if (cmsUtl_isValidMacAddress(macStr) == FALSE) { return CMSRET_INVALID_PARAM_VALUE; } if ((buf = (char *) cmsMem_alloc(MAC_STR_LEN+1, ALLOC_ZEROIZE)) == NULL) { cmsLog_error("alloc of %d bytes failed", MAC_STR_LEN+1); return CMSRET_RESOURCE_EXCEEDED; } /* need to copy since strtok_r updates string */ strcpy(buf, macStr); /* Mac address has the following format * xx:xx:xx:xx:xx:xx where x is hex number */ pToken = strtok_r(buf, ":", &pLast); macNum[0] = (UINT8) strtol(pToken, (char **)NULL, 16); for (i = 1; i < MAC_ADDR_LEN; i++) { pToken = strtok_r(NULL, ":", &pLast); macNum[i] = (UINT8) strtol(pToken, (char **)NULL, 16); } cmsMem_free(buf); return CMSRET_SUCCESS; }
char *cmsUtl_getDhcpVendorIdsFromAggregateString(const char *aggregateString) { char *vendorIds, *vendorId, *ptr, *savePtr=NULL; char *copy; UINT32 count=0; if (aggregateString == NULL) { return NULL; } vendorIds = cmsMem_alloc(MAX_PORTMAPPING_DHCP_VENDOR_IDS * (DHCP_VENDOR_ID_LEN + 1), ALLOC_ZEROIZE); if (vendorIds == NULL) { cmsLog_error("allocation of vendorIds buffer failed"); return NULL; } copy = cmsMem_strdup(aggregateString); ptr = strtok_r(copy, ",", &savePtr); while ((ptr != NULL) && (count < MAX_PORTMAPPING_DHCP_VENDOR_IDS)) { vendorId = &(vendorIds[count * (DHCP_VENDOR_ID_LEN + 1)]); /* * copy at most DHCP_VENDOR_ID_LEN bytes. Since each chunk in the linear * buffer is DHCP_VENDOR_ID_LEN+1 bytes long and initialized to 0, * we are guaranteed that each vendor id is null terminated. */ strncpy(vendorId, ptr, DHCP_VENDOR_ID_LEN); count++; ptr = strtok_r(NULL, ",", &savePtr); } cmsMem_free(copy); return vendorIds; }
/** Return a pointer to the beginning of the requested flash buffer. * * On DESKTOP_LINUX, this just opens the fake flash file, allocates a buffer, * read contents of fake flash file into buffer, and returns pointer to the * buffer. Persistent flash data is the only thing in the flash file (for now). * If fake flash file is not present, create one and fill it with zeros. */ char *fake_getSharedBlks(int start_block, int num_blocks) { UINT32 bufLen; char *buf=NULL; char path[BUFLEN_1024]; struct stat statbuf; int rc, fd; CmsRet ret; cmsLog_debug("reading block %d through %d", start_block, start_block+num_blocks); if (start_block != 0) { cmsLog_error("cannot handle non-zero start block yet."); return NULL; } if (num_blocks > FAKE_NUM_PSP_FLASH_BLOCKS) { cmsLog_error("requested more blocks than PSP flash blocks, not handled."); return NULL; } /* first allocate the buffer we will need for the read */ bufLen = FAKE_FLASH_BLOCK_SIZE * FAKE_NUM_PSP_FLASH_BLOCKS; if ((buf = cmsMem_alloc(bufLen, ALLOC_ZEROIZE)) == NULL) { cmsLog_error("malloc of %d bytes failed", bufLen); return NULL; } /* form path to the flash file */ if ((ret = cmsUtl_getBaseDir(path, sizeof(path))) != CMSRET_SUCCESS) { cmsLog_error("getBaseDir failed, abort func"); cmsMem_free(buf); return NULL; } else { UINT32 offset; offset = strlen(path); snprintf(&(path[offset]), sizeof(path)-offset, "/%s", FAKE_FLASH_PSP_FILENAME); } cmsLog_debug("checking for flash file at %s", path); if ((rc = stat(path, &statbuf)) < 0) { cmsLog_debug("creating fake flash file and initialize to zeros"); fd = open(path, O_CREAT|O_RDWR, 0644); if (fd < 0) { cmsLog_error("create of flash file %s failed, errno=%d", path, errno); cmsMem_free(buf); return NULL; } /* fill rest of file with zeros */ rc = write(fd, buf, bufLen); cmsLog_debug("filler write returned %d", rc); close(fd); } /* * at this point, we know there is a flash file, so just open it and read it. * Don't bother with offsets for now. Just assume PSP is at the beginning * of the flash. */ fd = open(path, O_RDWR); rc = read(fd, buf, num_blocks * FAKE_FLASH_BLOCK_SIZE); if (rc != num_blocks * FAKE_FLASH_BLOCK_SIZE) { cmsLog_error("unexpected rc %d from read, expected %d", rc, num_blocks * FAKE_FLASH_BLOCK_SIZE); CMSMEM_FREE_BUF_AND_NULL_PTR(buf); } close(fd); return buf; }
/** Free resources used by previous flash read. * */ void fake_retriedKfree(char *pShareBuf) { cmsMem_free(pShareBuf); return; }
CmsRet cmsUtl_parseDNS(const char *inDsnServers, char *outDnsPrimary, char *outDnsSecondary) { CmsRet ret = CMSRET_SUCCESS; char *tmpBuf; char *separator; UINT32 len; if (inDsnServers == NULL) { return CMSRET_INVALID_ARGUMENTS; } cmsLog_debug("entered: DDNSservers=>%s<=", inDsnServers); if (outDnsPrimary) { strcpy(outDnsPrimary, "0.0.0.0"); } if (outDnsSecondary) { strcpy(outDnsSecondary, "0.0.0.0"); } len = strlen(inDsnServers); if ((tmpBuf = cmsMem_alloc(len+1, 0)) == NULL) { cmsLog_error("alloc of %d bytes failed", len); ret = CMSRET_INTERNAL_ERROR; } else { sprintf(tmpBuf, "%s", inDsnServers); separator = strstr(tmpBuf, ","); if (separator != NULL) { /* break the string into two strings */ *separator = 0; separator++; while ((isspace(*separator)) && (*separator != 0)) { /* skip white space after comma */ separator++; } if (outDnsSecondary != NULL) { if (cmsUtl_isValidIpv4Address(separator)) { strcpy(outDnsSecondary, separator); } cmsLog_debug("dnsSecondary=%s", outDnsSecondary); } } if (outDnsPrimary != NULL) { if (cmsUtl_isValidIpv4Address(tmpBuf)) { strcpy(outDnsPrimary, tmpBuf); } cmsLog_debug("dnsPrimary=%s", outDnsPrimary); } cmsMem_free(tmpBuf); } return ret; }
CmsRet oalMsg_init(CmsEntityId eid, void **msgHandle) { CmsMsgHandle *handle; const CmsEntityInfo *eInfo; struct sockaddr_un serverAddr; SINT32 rc; if ((eInfo = cmsEid_getEntityInfo(eid)) == NULL) { cmsLog_error("Invalid eid %d", eid); return CMSRET_INVALID_ARGUMENTS; } if ((handle = (CmsMsgHandle *) cmsMem_alloc(sizeof(CmsMsgHandle), ALLOC_ZEROIZE)) == NULL) { cmsLog_error("could not allocate storage for msg handle"); return CMSRET_RESOURCE_EXCEEDED; } /* store caller's eid */ handle->eid = eid; #ifdef DESKTOP_LINUX /* * Applications may be run without smd on desktop linux, so if we * don't see a socket for smd, don't bother connecting to it. */ { struct stat statbuf; if ((rc = stat(SMD_MESSAGE_ADDR, &statbuf)) < 0) { handle->commFd = CMS_INVALID_FD; handle->standalone = TRUE; *msgHandle = (void *) handle; cmsLog_notice("no smd server socket detected, running in standalone mode."); return CMSRET_SUCCESS; } } #endif /* DESKTOP_LINUX */ /* * Create a unix domain socket. */ handle->commFd = socket(AF_LOCAL, SOCK_STREAM, 0); if (handle->commFd < 0) { cmsLog_error("Could not create socket"); cmsMem_free(handle); return CMSRET_INTERNAL_ERROR; } /* * Set close-on-exec, even though all apps should close their * fd's before fork and exec. */ if ((rc = fcntl(handle->commFd, F_SETFD, FD_CLOEXEC)) != 0) { cmsLog_error("set close-on-exec failed, rc=%d errno=%d", rc, errno); close(handle->commFd); cmsMem_free(handle); return CMSRET_INTERNAL_ERROR; } /* * Connect to smd. */ memset(&serverAddr, 0, sizeof(serverAddr)); serverAddr.sun_family = AF_LOCAL; strncpy(serverAddr.sun_path, SMD_MESSAGE_ADDR, sizeof(serverAddr.sun_path)); rc = connect(handle->commFd, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); if (rc != 0) { cmsLog_error("connect to %s failed, rc=%d errno=%d", SMD_MESSAGE_ADDR, rc, errno); close(handle->commFd); cmsMem_free(handle); return CMSRET_INTERNAL_ERROR; } else { cmsLog_debug("commFd=%d connected to smd", handle->commFd); } /* send a launched message to smd */ { CmsRet ret; CmsMsgHeader launchMsg = EMPTY_MSG_HEADER; launchMsg.type = CMS_MSG_APP_LAUNCHED; launchMsg.src = (eInfo->flags & EIF_MULTIPLE_INSTANCES) ? MAKE_SPECIFIC_EID(getpid(), eid) : eid; launchMsg.dst = EID_SMD; launchMsg.flags_event = 1; if ((ret = oalMsg_send(handle->commFd, &launchMsg)) != CMSRET_SUCCESS) { close(handle->commFd); cmsMem_free(handle); return CMSRET_INTERNAL_ERROR; } else { cmsLog_debug("sent LAUNCHED message to smd"); } } /* successful, set handle pointer */ *msgHandle = (void *) handle; return CMSRET_SUCCESS; }
CmsRet oalMsg_receive(SINT32 fd, CmsMsgHeader **buf, UINT32 *timeout) { CmsMsgHeader *msg; SINT32 rc; CmsRet ret; if (buf == NULL) { cmsLog_error("buf is NULL!"); return CMSRET_INVALID_ARGUMENTS; } else { *buf = NULL; } if (timeout) { if ((ret = waitForDataAvailable(fd, *timeout)) != CMSRET_SUCCESS) { return ret; } } /* * Read just the header in the first read. * Do not try to read more because we might get part of * another message in the TCP socket. */ msg = (CmsMsgHeader *) cmsMem_alloc(sizeof(CmsMsgHeader), ALLOC_ZEROIZE); if (msg == NULL) { cmsLog_error("alloc of msg header failed"); return CMSRET_RESOURCE_EXCEEDED; } rc = read(fd, msg, sizeof(CmsMsgHeader)); if ((rc == 0) || ((rc == -1) && (errno == 131))) /* new 2.6.21 kernel seems to give us this before rc==0 */ { /* broken connection */ cmsMem_free(msg); return CMSRET_DISCONNECTED; } else if (rc < 0 || rc != sizeof(CmsMsgHeader)) { cmsLog_error("bad read, rc=%d errno=%d", rc, errno); cmsMem_free(msg); return CMSRET_INTERNAL_ERROR; } if (msg->dataLength > 0) { SINT32 totalReadSoFar=0; SINT32 totalRemaining=msg->dataLength; char *inBuf; /* there is additional data in the message */ msg = (CmsMsgHeader *) cmsMem_realloc(msg, sizeof(CmsMsgHeader) + msg->dataLength); if (msg == NULL) { cmsLog_error("realloc to %d bytes failed", sizeof(CmsMsgHeader) + msg->dataLength); cmsMem_free(msg); return CMSRET_RESOURCE_EXCEEDED; } inBuf = (char *) (msg + 1); while (totalReadSoFar < msg->dataLength) { cmsLog_debug("reading segment: soFar=%d total=%d", totalReadSoFar, totalRemaining); if (timeout) { if ((ret = waitForDataAvailable(fd, *timeout)) != CMSRET_SUCCESS) { cmsMem_free(msg); return ret; } } rc = read(fd, inBuf, totalRemaining); if (rc <= 0) { cmsLog_error("bad data read, rc=%d errno=%d readSoFar=%d remaining=%d", rc, errno, totalReadSoFar, totalRemaining); cmsMem_free(msg); return CMSRET_INTERNAL_ERROR; } else { inBuf += rc; totalReadSoFar += rc; totalRemaining -= rc; } } } *buf = msg; return CMSRET_SUCCESS; }