/** * NOTE: * * HAL_TCP_xxx API reference implementation: wrappers/os/ubuntu/HAL_TCP_linux.c * */ #include "infra_types.h" #include "infra_defs.h" #include "infra_compat.h" #include "wrappers_defs.h" #include "stdarg.h" #include #include #include #include #include #include /*please change it to 0 if you don't want to say the log messages in HAL*/ #define HAL_DEBUG_OUT 0 /** * @brief Deallocate memory block * * @param[in] ptr @n Pointer to a memory block previously allocated with platform_malloc. * @return None. * @see None. * @note None. */ void HAL_Free(void *ptr) { if(ptr) free(ptr); } /** * @brief Get device name from user's system persistent storage * * @param [ou] device_name: array to store device name, max length is IOTX_DEVICE_NAME_LEN * @return the actual length of device name */ int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN + 1]) { memset(device_name,0,IOTX_DEVICE_NAME_LEN + 1); return(snprintf(device_name,IOTX_DEVICE_NAME_LEN,"%s","bdsK8tJTX8CDrhHEr7nv")); } /** * @brief Get device secret from user's system persistent storage * * @param [ou] device_secret: array to store device secret, max length is IOTX_DEVICE_SECRET_LEN * @return the actual length of device secret */ int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN + 1]) { memset(device_secret,0,IOTX_DEVICE_SECRET_LEN + 1); return(snprintf(device_secret,IOTX_DEVICE_SECRET_LEN,"%s","rgZ1navcKLEzyZrbkindRXHLycxDN3X9")); } /** * @brief Get firmware version * * @param [ou] version: array to store firmware version, max length is IOTX_FIRMWARE_VER_LEN * @return the actual length of firmware version */ int HAL_GetFirmwareVersion(char *version) { return (int)0; } /** * @brief Get product key from user's system persistent storage * * @param [ou] product_key: array to store product key, max length is IOTX_PRODUCT_KEY_LEN * @return the actual length of product key */ int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN + 1]) { memset(product_key,0,IOTX_PRODUCT_KEY_LEN + 1); return(snprintf(product_key,IOTX_PRODUCT_KEY_LEN,"%s","a1PtXK86l1v")); } int HAL_GetProductSecret(char product_secret[IOTX_PRODUCT_SECRET_LEN + 1]) { memset(product_secret,0,IOTX_PRODUCT_SECRET_LEN + 1); return(snprintf(product_secret,IOTX_PRODUCT_SECRET_LEN,"%s","Mb5O6TMhbukG2FSt")); } /*The content of the file can't get lost after reboot, please ensure the file is not stored on a RAM file system*/ static char *kvFileName="c:\\iotKv.data"; typedef struct{ int keyLen; int valLen; char *pKey; char *pValue; }kvHeader_t; typedef struct kvNode_s{ struct kvNode_s *pNext; kvHeader_t item; }kvNode_t; static int kv_read_header(HANDLE hFind,kvHeader_t *pHeader) { DWORD readLen; if(ReadFile(hFind,pHeader,2*sizeof(int),&readLen,NULL)==0) return(0); return(readLen); } static int kv_read_item(HANDLE hFind,kvHeader_t *pHeader) { DWORD r1,total=0; ReadFile(hFind,pHeader,2*sizeof(int),&r1,NULL); total += r1; pHeader->pKey = malloc(pHeader->keyLen); pHeader->pValue = malloc(pHeader->valLen); ReadFile(hFind,pHeader->pKey,pHeader->keyLen,&r1,NULL); total += r1; ReadFile(hFind,pHeader->pValue,pHeader->valLen,&r1,NULL); total += r1; return(total); } static void kv_write_item(HANDLE hFile,kvHeader_t *pHeader) { DWORD w1; if(WriteFile(hFile,pHeader,2*sizeof(int),&w1,NULL)==0){ printf("KV write error %d\n\r", (int)GetLastError()); } WriteFile(hFile,pHeader->pKey,pHeader->keyLen,&w1,NULL); WriteFile(hFile,pHeader->pValue,pHeader->valLen,&w1,NULL); } int HAL_Kv_Get(const char *key, void *val, int *buffer_len) { HANDLE hFind; WIN32_FIND_DATA FindFileData; DWORD readLen=0,r1; kvHeader_t header; char keyInFile[32]; int ret = -1; hFind = FindFirstFile(kvFileName, &FindFileData); if (hFind == INVALID_HANDLE_VALUE){ return(-1); } FindClose(hFind); hFind = CreateFileA(kvFileName, GENERIC_READ , 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); while(readLenpNext = pNode; pNode->pNext = NULL; readLen += kv_read_item(hFind,&pNode->item); if(strcmp(key,pNode->item.pKey)==0){ found = 1; free(pNode->item.pValue); pNode->item.pValue = malloc(len); memcpy(pNode->item.pValue,val,len); pNode->item.valLen = len; } pPrevNode = pNode; } if(found==0){ pNode = (kvNode_t *)malloc(sizeof(kvNode_t)); if(pRoot==NULL) pRoot = pNode; if(pPrevNode) pPrevNode->pNext = pNode; pNode->pNext = NULL; pNode->item.keyLen = strlen(key)+1; pNode->item.pKey = malloc(pNode->item.keyLen); pNode->item.pValue = malloc(len); pNode->item.valLen = len; strcpy(pNode->item.pKey,key); memcpy(pNode->item.pValue,val,len); } pNode = pRoot; SetFilePointer(hFind,0,NULL,FILE_BEGIN); SetEndOfFile(hFind); while(pNode){ kv_write_item(hFind, &pNode->item); pNode = pNode->pNext; } CloseHandle(hFind); return (int)0; } /** * @brief Allocates a block of size bytes of memory, returning a pointer to the beginning of the block. * * @param [in] size @n specify block size in bytes. * @return A pointer to the beginning of the block. * @see None. * @note Block value is indeterminate. */ void *HAL_Malloc(uint32_t size) { if(size==0) return(NULL); return malloc(size); } /** * @brief Create a mutex. * * @retval NULL : Initialize mutex failed. * @retval NOT_NULL : The mutex handle. * @see None. * @note None. */ void *HAL_MutexCreate(void) { HANDLE mutex; if (NULL == (mutex = CreateMutex(NULL, FALSE, NULL))) { printf("create mutex error"); } return mutex; } /** * @brief Destroy the specified mutex object, it will release related resource. * * @param [in] mutex @n The specified mutex. * @return None. * @see None. * @note None. */ void HAL_MutexDestroy(void *mutex) { if (0 == CloseHandle(mutex)) { printf("destroy mutex error"); }; } /** * @brief Waits until the specified mutex is in the signaled state. * * @param [in] mutex @n the specified mutex. * @return None. * @see None. * @note None. */ void HAL_MutexLock(void *mutex) { if (WAIT_FAILED == WaitForSingleObject(mutex, INFINITE)) { printf("lock mutex error"); } } /** * @brief Releases ownership of the specified mutex object.. * * @param [in] mutex @n the specified mutex. * @return None. * @see None. * @note None. */ void HAL_MutexUnlock(void *mutex) { ReleaseMutex(mutex); } /** * @brief Writes formatted data to stream. * * @param [in] fmt: @n String that contains the text to be written, it can optionally contain embedded format specifiers that specifies how subsequent arguments are converted for output. * @param [in] ...: @n the variable argument list, for formatted and inserted in the resulting string replacing their respective specifiers. * @return None. * @see None. * @note None. */ void HAL_Printf(const char *fmt, ...) { va_list args; va_start(args, fmt); vprintf(fmt, args); va_end(args); fflush(stdout); } static uint32_t orig_seed = 2; uint32_t HAL_Random(uint32_t region) { orig_seed = 1664525 * orig_seed + 1013904223; return (region > 0) ? (orig_seed % region) : 0; } void HAL_Reboot() { printf("\n\rTo kill and restart the program.\n\r"); return; } /** * @brief create a semaphore * * @return semaphore handle. * @see None. * @note The recommended value of maximum count of the semaphore is 255. */ void *HAL_SemaphoreCreate(void) { return CreateSemaphore(NULL, 0, 1, NULL); } /** * @brief destory a semaphore * * @param[in] sem @n the specified sem. * @return None. * @see None. * @note None. */ void HAL_SemaphoreDestroy(void *sem) { CloseHandle(sem); } /** * @brief signal thread wait on a semaphore * * @param[in] sem @n the specified semaphore. * @return None. * @see None. * @note None. */ void HAL_SemaphorePost(void *sem) { ReleaseSemaphore(sem, 1, NULL); } /** * @brief wait on a semaphore * * @param[in] sem @n the specified semaphore. * @param[in] timeout_ms @n timeout interval in millisecond. If timeout_ms is PLATFORM_WAIT_INFINITE, the function will return only when the semaphore is signaled. * @return @verbatim = 0: The state of the specified object is signaled. = -1: The time-out interval elapsed, and the object's state is nonsignaled. @endverbatim * @see None. * @note None. */ int HAL_SemaphoreWait(void *sem, uint32_t timeout_ms) { uint32_t timeout = timeout_ms; if (timeout == (uint32_t) - 1) { timeout = INFINITE; } return WaitForSingleObject(sem, timeout); } /** * @brief Sleep thread itself. * * @param [in] ms @n the time interval for which execution is to be suspended, in milliseconds. * @return None. * @see None. * @note None. */ void HAL_SleepMs(uint32_t ms) { Sleep(ms); } /** * @brief Writes formatted data to string. * * @param [out] str: @n String that holds written text. * @param [in] len: @n Maximum length of character will be written * @param [in] fmt: @n Format that contains the text to be written, it can optionally contain embedded format specifiers that specifies how subsequent arguments are converted for output. * @param [in] ...: @n the variable argument list, for formatted and inserted in the resulting string replacing their respective specifiers. * @return bytes of character successfully written into string. * @see None. * @note None. */ int HAL_Snprintf(char *str, const int len, const char *fmt, ...) { int ret; va_list args; va_start(args, fmt); ret = _vsnprintf(str, len - 1, fmt, args); va_end(args); return ret; } void HAL_Srandom(uint32_t seed) { orig_seed = seed; } #define MAX_SSL_CONNECTIONS 5 typedef struct{ SSL_METHOD *pMethod; SSL_CTX *pCtx; SSL* pSsl; int fd; }sslConnDef_t; static int openSslInited = 0 ; static sslConnDef_t* connArray[MAX_SSL_CONNECTIONS] = {0}; static void init_open_ssl() { WSADATA wsaData; if(openSslInited) return; WSAStartup(0x202, &wsaData); SSL_library_init(); openSslInited = 1; } int32_t HAL_SSL_Destroy(uintptr_t handle) { int index = (int)handle -1; if(HAL_DEBUG_OUT) printf("Enter HAL_SSL_Destroy\n\r"); if((handle== 0)||(handle>MAX_SSL_CONNECTIONS)) return(0); if(connArray[index]->pSsl){ SSL_shutdown(connArray[index]->pSsl); SSL_free(connArray[index]->pSsl); } if(connArray[index]->pCtx) SSL_CTX_free(connArray[index]->pCtx); if(connArray[index]->fd > 0) closesocket(connArray[index]->fd); free(connArray[index]); connArray[index] = NULL; return(0); } static int tcp_open(const char *host, uint16_t port) { int sockfd,res,err, flag=0; unsigned long nonBlock=1; struct hostent *hp; struct sockaddr_in addrServer; sockfd = socket(AF_INET, SOCK_STREAM, 0); /* socket */ hp = gethostbyname(host); if(hp==NULL) return(-1); memset(&addrServer, 0, sizeof(addrServer)); memcpy(&(addrServer.sin_addr), hp->h_addr, hp->h_length); addrServer.sin_family = AF_INET; addrServer.sin_port = htons((unsigned short)port); printf("connecting to %s", host); ioctlsocket(sockfd,FIONBIO,&nonBlock); while(1){ flag = 0; res = connect(sockfd, (struct sockaddr *)&addrServer, sizeof(struct sockaddr)); if(res==0) break; else{ err = WSAGetLastError(); switch(err){ case(WSAEWOULDBLOCK): printf("tcp_open: WSAEWOULDBLOCK"); Sleep(100); break; case(WSAEISCONN): flag=1; break; default: printf("tcp_open error %d", err); closesocket(sockfd); return(-1); break; } if(flag==1) break; else{ Sleep(100); } } } printf("\n TCP connect successfully!\n"); return sockfd; } uintptr_t HAL_SSL_Establish(const char *host, uint16_t port, const char *ca_crt, uint32_t ca_crt_len) { SSL_METHOD *method; SSL_CTX *ctx; int i,fd=0,err,res; if(HAL_DEBUG_OUT) printf("Enter HAL_SSL_Establish\n\r"); init_open_ssl(); for(i=0;i=MAX_SSL_CONNECTIONS){ printf("Exceed connection limit\n\r"); return(0); } if((fd=tcp_open(host,port))<0){ printf("tcp_open failed\n\r"); return(0); } method = SSLv23_client_method(); ctx = SSL_CTX_new(method); if (ctx == NULL){ closesocket(fd); return(0); } connArray[i] = (sslConnDef_t *)malloc(sizeof(sslConnDef_t)); if(connArray[i] == NULL) goto ErrRet; memset(connArray[i],0,sizeof(sslConnDef_t)); connArray[i]->pMethod = method; connArray[i]->pCtx = ctx; connArray[i]->fd = fd; SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); connArray[i]->pSsl = SSL_new (ctx); SSL_set_fd (connArray[i]->pSsl, fd); SSL_set_connect_state(connArray[i]->pSsl); while(1){ res = SSL_connect (connArray[i]->pSsl); if(res>0) break; if(HAL_DEBUG_OUT) printf("HAL_SSL_Establish: res %d\n", res); err = SSL_get_error(connArray[i]->pSsl, res); if ((err == SSL_ERROR_WANT_WRITE) || (err == SSL_ERROR_WANT_READ)){ Sleep(50); continue; } else{ goto ErrRet; } } printf("HAL_SSL_Establish successfully\n\r"); return(i+1); ErrRet: if(connArray[i]->pSsl) SSL_free(connArray[i]->pSsl); if(connArray[i]->pCtx) SSL_CTX_free(connArray[i]->pCtx); if(fd>0) closesocket(fd); connArray[i] = NULL; printf("HAL_SSL_Establish failed\n\r"); return(0); } int HAL_SSL_Read(uintptr_t handle, char *buf, int len, int timeout_ms) { int res, errCode,index; if((handle== 0)||(handle>MAX_SSL_CONNECTIONS)){ printf("Invalid handle %d\n\r",(int)handle); return(0); } index = (int)handle - 1; while(1){ res = SSL_read(connArray[index]->pSsl,buf,len); if(res>0) break; else{ errCode = SSL_get_error(connArray[index]->pSsl, res); switch(errCode){ case(SSL_ERROR_WANT_CONNECT): case(SSL_ERROR_SYSCALL): case(SSL_ERROR_SSL): printf("HAL_SSL_Read: connection error\n\r"); return(-2); break; case(SSL_ERROR_WANT_READ ): Sleep(100); return(0); break; default: printf("errCode %d\n\r",errCode); return(-1); break; } } } //printf("Rcved %d B from server: %s\n\r",res, buf); return(res); } int HAL_SSL_Write(uintptr_t handle, const char *buf, int len, int timeout_ms) { int res, errCode, index = (int)handle-1; int contFlag, sent=0; unsigned char *pStart = (unsigned char *)buf; if((handle== 0)||(handle>MAX_SSL_CONNECTIONS)) return(0); if(HAL_DEBUG_OUT) printf("HAL_SSL_Write %d,len %d,timeout %d\n\r",(int)handle,len,timeout_ms); while(1){ contFlag = 0; res = SSL_write(connArray[index]->pSsl,pStart,len-sent); if(res > 0){ sent += res; pStart += res; if(sentpSsl, res); switch(errCode){ case(SSL_ERROR_WANT_READ): case(SSL_ERROR_WANT_WRITE): contFlag =1; Sleep(50); break; case(SSL_ERROR_ZERO_RETURN): case(SSL_ERROR_SYSCALL): case(SSL_ERROR_SSL): printf("HAL_SSL_Write: connection error\n\r"); return(-1); break; default: printf("HAL_SSL_Write error, errcode %d\n\r",errCode); contFlag = 1; Sleep(50); break; } } if(contFlag==0) break; else Sleep(100); } return(sent); } int HAL_Sys_Net_Is_Ready() { return (int)1; } /** * @brief create a thread * * @param[out] thread_handle @n The new thread handle, memory allocated before thread created and return it, free it after thread joined or exit. * @param[in] start_routine @n A pointer to the application-defined function to be executed by the thread. This pointer represents the starting address of the thread. * @param[in] arg @n A pointer to a variable to be passed to the start_routine. * @param[in] hal_os_thread_param @n A pointer to stack params. * @param[out] stack_used @n if platform used stack buffer, set stack_used to 1, otherwise set it to 0. * @return @verbatim = 0: on success. = -1: error occur. @endverbatim * @see None. * @note None. */ #define DEFAULT_THREAD_SIZE 4096 int HAL_ThreadCreate( void **thread_handle, void *(*work_routine)(void *), void *arg, hal_os_thread_param_t *hal_os_thread_param, int *stack_used) { SIZE_T stack_size; (void)stack_used; if (!hal_os_thread_param || hal_os_thread_param->stack_size == 0) { stack_size = DEFAULT_THREAD_SIZE; } else { stack_size = hal_os_thread_param->stack_size; } thread_handle = CreateThread(NULL, stack_size, (LPTHREAD_START_ROUTINE)work_routine,arg, 0, NULL); if (thread_handle == NULL) { return -1; } return 0; } void HAL_ThreadDelete(void *thread_handle) { CloseHandle(thread_handle); } typedef struct{ char name[32]; void (*func)(void *); void *user_data; HANDLE tmr; int index; }timer_t; #define HAL_TIMER_SIZE 10 static int timerInited=0; static HANDLE hTimerQueue = NULL; static timer_t* gTimerTable[HAL_TIMER_SIZE]={0}; static void timer_init() { if(timerInited) return; hTimerQueue = CreateTimerQueue(); if (NULL == hTimerQueue){ printf("Failed to create timer queue\n\r"); return; } timerInited = 1; } static void CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired) { timer_t *pTimer = (timer_t *)lpParam; if(HAL_DEBUG_OUT) printf("Timer %s(%d) expired\n\r", pTimer->name,pTimer->index); pTimer->func(pTimer->user_data); } void *HAL_Timer_Create(const char *name, void (*func)(void *), void *user_data) { int i; timer_t *pTimer; timer_init(); for(i=0;i=HAL_TIMER_SIZE){ printf("HAL_Timer_Create failed, increase HAL_TIMER_SIZE\n\r"); return(NULL); } pTimer = (timer_t *)malloc(sizeof(timer_t)); if(pTimer==NULL) return(NULL); memset(pTimer,0,sizeof(timer_t)); pTimer->index = i; pTimer->user_data = user_data; pTimer->func = func; if(name) snprintf(pTimer->name,sizeof(pTimer->name),"%s",name); gTimerTable[i] = pTimer; if(HAL_DEBUG_OUT) printf("Create timer %d %s\n\r",pTimer->index,pTimer->name); return (void*)pTimer; } int HAL_Timer_Delete(void *timer) { timer_t *pTimer = (timer_t *)timer; if(pTimer==NULL) return(-1); if(HAL_DEBUG_OUT) printf("Delete timer %d %s\n\r",pTimer->index,pTimer->name); gTimerTable[pTimer->index] = NULL; free(pTimer); return(0); } int HAL_Timer_Start(void *timer, int ms) { timer_t *pTimer = (timer_t *)timer; if(pTimer==NULL) return(-1); if(HAL_DEBUG_OUT) printf("Start timer %d %s\n\r",pTimer->index,pTimer->name); if (!CreateTimerQueueTimer( &pTimer->tmr, hTimerQueue, (WAITORTIMERCALLBACK)TimerRoutine, (void *)pTimer , ms, 0, 0)){ printf("CreateTimerQueueTimer failed (%d)\n", (int)GetLastError()); return(-1); } return(0); } int HAL_Timer_Stop(void *timer) { timer_t *pTimer = (timer_t *)timer; if(pTimer==NULL) return(-1); if(HAL_DEBUG_OUT) printf("Stop timer %d %s\n\r",pTimer->index,pTimer->name); if(pTimer->index>=HAL_TIMER_SIZE) return(-1); if(pTimer->tmr){ DeleteTimerQueueTimer(hTimerQueue,pTimer->tmr,NULL); pTimer->tmr=NULL; } return (int)0; } int HAL_UDP_close_without_connect(intptr_t sockfd) { if(sockfd>0) closesocket(sockfd); return(0); } intptr_t HAL_UDP_create_without_connect(const char *host, unsigned short port) { SOCKET s = socket(AF_INET, SOCK_DGRAM, 0); struct sockaddr_in service; BOOL flag; int ret,loop; if(HAL_DEBUG_OUT) printf("Create UDP: %s %d\n\r",host,(int)port); if(s==INVALID_SOCKET) return(-1); if(port==0)/*doesn't bind port*/ return(s); service.sin_family = AF_INET; if(host==NULL) service.sin_addr.s_addr = inet_addr("0.0.0.0"); else{ service.sin_addr.s_addr = inet_addr(host); } service.sin_port = htons(port); if(bind(s, (SOCKADDR *) &service, sizeof (service))==SOCKET_ERROR){ closesocket(s); return(-1); } flag = TRUE; ret = setsockopt(s,SOL_SOCKET,SO_BROADCAST,(void *)&flag,sizeof(flag)); if(ret==SOCKET_ERROR){ closesocket(s); printf("Failed to allow UDP socket to send broadcast pkts\n\r"); return -1; } loop = 0; setsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,(void *)&loop,sizeof(loop)); if(ret==SOCKET_ERROR){ closesocket(s); printf("Failed to set IP_MULTICAST_LOOP to false\n\r"); return -1; } return(s); } int HAL_UDP_joinmulticast(intptr_t sockfd, char *p_group) { struct ip_mreq mreq; int ret; memset(&mreq,0,sizeof(struct ip_mreq)); mreq.imr_multiaddr.S_un.S_addr=inet_addr(p_group); //组播源地址 mreq.imr_interface.S_un.S_addr=INADDR_ANY; //本地地址 ret = setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char FAR *)&mreq,sizeof(mreq)); if(ret==SOCKET_ERROR){ printf("Failed to join multicast group\n\r"); return -1; } return(0); } int HAL_UDP_recvfrom(intptr_t sockfd, NetworkAddr *p_remote, unsigned char *p_data, unsigned int datalen, unsigned int timeout_ms) { int ret,errCode; struct sockaddr_in addr; socklen_t addr_len = sizeof(addr); fd_set read_fds; struct timeval timeout = {timeout_ms / 1000, (timeout_ms % 1000) * 1000}; FD_ZERO(&read_fds); FD_SET(sockfd, &read_fds); ret = select(sockfd + 1, &read_fds, NULL, NULL, &timeout); switch(ret){ default: break; case(0): return 0; /* receive timeout */ break; case(SOCKET_ERROR): errCode = WSAGetLastError(); printf("select error %d\n\r",errCode); return(-1); break; } ret = recvfrom(sockfd, (char *)p_data, (int)datalen, 0, (struct sockaddr *)&addr, &addr_len); if(ret<=0) return(-1); if (NULL != p_remote) { p_remote->port = ntohs(addr.sin_port); strcpy((char *)p_remote->addr, inet_ntoa(addr.sin_addr)); } if(HAL_DEBUG_OUT) printf("UDP socket %d rcv %dB\n\r", (int)sockfd, ret); return(ret); } static uint32_t get_subnet_bcast(); int HAL_UDP_sendto(intptr_t sockfd, const NetworkAddr *p_remote, const unsigned char *p_data, unsigned int datalen, unsigned int timeout_ms) { int ret; unsigned long ipAddr; struct hostent *hp; struct sockaddr_in addr; DWORD toVal; //struct timeval timeout = {timeout_ms / 1000, (timeout_ms % 1000) * 1000}; if(HAL_DEBUG_OUT) printf("UDP_sendto %s:%d %d\n\r",p_remote->addr,p_remote->port,datalen); if ((ipAddr=inet_addr((char *)p_remote->addr))==INADDR_NONE) { hp = gethostbyname((char *)p_remote->addr); if (!hp) { printf("can't resolute the host address \n"); return -1; } ipAddr = *(uint32_t *)(hp->h_addr); } if(ipAddr == 0xFFFFFFFF) ipAddr = get_subnet_bcast(); toVal = timeout_ms; ret = setsockopt(sockfd,SOL_SOCKET,SO_SNDTIMEO,(void *)&toVal,sizeof(toVal)); if(ret==SOCKET_ERROR){ printf("Failed to set UDP_send timeout\n\r"); return -1; } addr.sin_addr.s_addr = ipAddr; addr.sin_family = AF_INET; addr.sin_port = htons(p_remote->port); ret = sendto(sockfd, (char *)p_data, (int)datalen, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if(HAL_DEBUG_OUT) printf("UDP socket %d sent %dB\n\r", (int)sockfd, ret); return (ret) > 0 ? ret : -1; } /** * @brief Retrieves the number of milliseconds that have elapsed since the system was boot. * * @return the number of milliseconds. * @see None. * @note None. */ uint64_t HAL_UptimeMs(void) { return (uint64_t)(GetTickCount()); } int HAL_Vsnprintf(char *str, const int len, const char *format, va_list ap) { return vsnprintf(str, len, format, ap); } /*This variable is to define the name of the network interface, you must change it to yours*/ static wchar_t* gIfName = L"\\DEVICE\\TCPIP_{C9E93150-C6B1-4B15-8A2E-C08747261CD2}"; /*The return value will be bigger than zero if it gets the index successfully*/ static DWORD get_interface_index() { MIB_IFTABLE *pIfTable = NULL; MIB_IFROW *pIfRow; DWORD dwSize = 0, ifIndex; int i; if (GetIfTable((MIB_IFTABLE *)&dwSize, &dwSize, 0) != ERROR_INSUFFICIENT_BUFFER){ printf("Failed to get if table at step 1\n\r"); return(0); } pIfTable = (MIB_IFTABLE *) malloc(dwSize); if(pIfTable==NULL) return(0); if (GetIfTable((MIB_IFTABLE *)pIfTable, &dwSize, 0) != NO_ERROR) { free(pIfTable); printf("Failed to get if table\n\r"); return(0); } for (i = 0; i < pIfTable->dwNumEntries; i++) { pIfRow = (MIB_IFROW *) & pIfTable->table[i]; if(wcscmp(pIfRow->wszName,gIfName)==0){ ifIndex = pIfRow->dwIndex; break; } } if(i>=pIfTable->dwNumEntries){ free(pIfTable); printf("Failed to find the network interface \n\r"); return(0); } free(pIfTable); return(ifIndex); } static uint32_t get_subnet_bcast() { DWORD ifIndex; PMIB_IPADDRTABLE pIPAddrTable = NULL; DWORD dwSize = 0; int i; unsigned int net, snBcast; if( (ifIndex=get_interface_index())==0){ printf("Failed to get IP, please check if the WINDOWS_IF_NAME is correct\n\r"); return(0); } if (GetIpAddrTable((MIB_IPADDRTABLE *)&dwSize, &dwSize, 0) != ERROR_INSUFFICIENT_BUFFER){ printf("System doesn't have an ip address yet\n\r"); return(0); } pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize); if(pIPAddrTable==NULL) return(0); if(GetIpAddrTable( pIPAddrTable, &dwSize, 0 )!=NO_ERROR){ printf("Failed to get ip addr table\n\r"); return(0); } for(i=0; i< (int) pIPAddrTable->dwNumEntries; i++){ if(pIPAddrTable->table[i].dwIndex == ifIndex){ net = (unsigned int) pIPAddrTable->table[i].dwAddr & pIPAddrTable->table[i].dwAddr & pIPAddrTable->table[i].dwAddr & pIPAddrTable->table[i].dwMask; snBcast = net | (~pIPAddrTable->table[i].dwMask); //printf("bcast is %X\n\r", snBcast); free(pIPAddrTable); return(snBcast); } } free(pIPAddrTable); return 0; } uint32_t HAL_Wifi_Get_IP(char ip_str[NETWORK_ADDR_LEN], const char *ifname) { DWORD ifIndex; PMIB_IPADDRTABLE pIPAddrTable = NULL; DWORD dwSize = 0; IN_ADDR IPAddr; int i; ip_str[0]=0; if( (ifIndex=get_interface_index())==0){ printf("Failed to get IP, please check if the WINDOWS_IF_NAME is correct\n\r"); return(0); } if (GetIpAddrTable((MIB_IPADDRTABLE *)&dwSize, &dwSize, 0) != ERROR_INSUFFICIENT_BUFFER){ printf("System doesn't have an ip address yet\n\r"); return(0); } pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize); if(pIPAddrTable==NULL) return(0); if(GetIpAddrTable( pIPAddrTable, &dwSize, 0 )!=NO_ERROR){ printf("Failed to get ip addr table\n\r"); return(0); } for(i=0; i< (int) pIPAddrTable->dwNumEntries; i++){ if(pIPAddrTable->table[i].dwIndex == ifIndex){ IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr; snprintf(ip_str,NETWORK_ADDR_LEN,"%s",inet_ntoa(IPAddr)); if(HAL_DEBUG_OUT) printf("WIFI IP address is %s\n\r", ip_str); free(pIPAddrTable); return(IPAddr.S_un.S_addr); } } free(pIPAddrTable); return 0; } char *HAL_Wifi_Get_Mac(char mac_str[HAL_MAC_LEN]) { MIB_IFTABLE *pIfTable = NULL; MIB_IFROW *pIfRow; DWORD dwSize = 0; int i; mac_str[0]=0; if (GetIfTable((MIB_IFTABLE *)&dwSize, &dwSize, 0) != ERROR_INSUFFICIENT_BUFFER){ printf("Failed to get if table at step 1 in HAL_Wifi_Get_Mac\n\r"); return(NULL); } pIfTable = (MIB_IFTABLE *) malloc(dwSize); if(pIfTable==NULL) return(NULL); if (GetIfTable((MIB_IFTABLE *)pIfTable, &dwSize, 0) != NO_ERROR) { free(pIfTable); printf("Failed to get if table (HAL_Wifi_Get_Mac)\n\r"); return(NULL); } for (i = 0; i < pIfTable->dwNumEntries; i++) { pIfRow = (MIB_IFROW *) & pIfTable->table[i]; if(wcscmp(pIfRow->wszName,gIfName)==0){ break; } } if(idwNumEntries){ snprintf(mac_str,HAL_MAC_LEN,"%02X:%02X:%02X:%02X:%02X:%02X", pIfRow->bPhysAddr[0],pIfRow->bPhysAddr[1],pIfRow->bPhysAddr[2], pIfRow->bPhysAddr[3],pIfRow->bPhysAddr[4],pIfRow->bPhysAddr[5]); if(HAL_DEBUG_OUT) printf("WIFI MAC is %s\n\r", mac_str); } free(pIfTable); return (mac_str); }