int main(int argc, char *argv[]) { int sock; fd_set readfds; struct timeval tv; int result; lwm2m_context_t * lwm2mH = NULL; int i; connection_t * connList = NULL; int addressFamily = AF_INET6; int opt; command_desc_t commands[] = { {"list", "List registered clients.", NULL, prv_output_clients, NULL}, {"read", "Read from a client.", " read CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri to read such as /3, /3/0/2, /1024/11, /1024/0/1\r\n" "Result will be displayed asynchronously.", prv_read_client, NULL}, {"disc", "Discover resources of a client.", " disc CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri to discover such as /3, /3/0/2, /1024/11, /1024/0/1\r\n" "Result will be displayed asynchronously.", prv_discover_client, NULL}, {"write", "Write to a client.", " write CLIENT# URI DATA\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri to write to such as /3, /3/0/2, /1024/11, /1024/0/1\r\n" " DATA: data to write\r\n" "Result will be displayed asynchronously.", prv_write_client, NULL}, {"time", "Write time-related attributes to a client.", " time CLIENT# URI PMIN PMAX\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri to write attributes to such as /3, /3/0/2, /1024/11, /1024/0/1\r\n" " PMIN: Minimum period\r\n" " PMAX: Maximum period\r\n" "Result will be displayed asynchronously.", prv_time_client, NULL}, {"attr", "Write value-related attributes to a client.", " attr CLIENT# URI LT GT [STEP]\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri to write attributes to such as /3, /3/0/2, /1024/11, /1024/0/1\r\n" " LT: \"Less than\" value\r\n" " GT: \"Greater than\" value\r\n" " STEP: \"Step\" value\r\n" "Result will be displayed asynchronously.", prv_attr_client, NULL}, {"clear", "Clear attributes of a client.", " clear CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri to clear attributes of such as /3, /3/0/2, /1024/11, /1024/0/1\r\n" "Result will be displayed asynchronously.", prv_clear_client, NULL}, {"exec", "Execute a client resource.", " exec CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri of the resource to execute such as /3/0/2\r\n" "Result will be displayed asynchronously.", prv_exec_client, NULL}, {"del", "Delete a client Object instance.", " del CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri of the instance to delete such as /1024/11\r\n" "Result will be displayed asynchronously.", prv_delete_client, NULL}, {"create", "create an Object instance.", " create CLIENT# URI DATA\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri to which create the Object Instance such as /1024, /1024/45 \r\n" " DATA: data to initialize the new Object Instance (0-255 for object 1024) \r\n" "Result will be displayed asynchronously.", prv_create_client, NULL}, {"observe", "Observe from a client.", " observe CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri to observe such as /3, /3/0/2, /1024/11\r\n" "Result will be displayed asynchronously.", prv_observe_client, NULL}, {"cancel", "Cancel an observe.", " cancel CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri on which to cancel an observe such as /3, /3/0/2, /1024/11\r\n" "Result will be displayed asynchronously.", prv_cancel_client, NULL}, {"q", "Quit the server.", NULL, prv_quit, NULL}, COMMAND_END_LIST }; while ((opt = getopt(argc, argv, "4")) != -1) { switch (opt) { case '4': addressFamily = AF_INET; break; default: print_usage(); return 0; } } sock = create_socket(LWM2M_STANDARD_PORT_STR, addressFamily); if (sock < 0) { fprintf(stderr, "Error opening socket: %d\r\n", errno); return -1; } lwm2mH = lwm2m_init(NULL); if (NULL == lwm2mH) { fprintf(stderr, "lwm2m_init() failed\r\n"); return -1; } signal(SIGINT, handle_sigint); for (i = 0 ; commands[i].name != NULL ; i++) { commands[i].userData = (void *)lwm2mH; } fprintf(stdout, "> "); fflush(stdout); lwm2m_set_monitoring_callback(lwm2mH, prv_monitor_callback, lwm2mH); while (0 == g_quit) { FD_ZERO(&readfds); FD_SET(sock, &readfds); FD_SET(STDIN_FILENO, &readfds); tv.tv_sec = 60; tv.tv_usec = 0; result = lwm2m_step(lwm2mH, &(tv.tv_sec)); if (result != 0) { fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result); return -1; } result = select(FD_SETSIZE, &readfds, 0, 0, &tv); if ( result < 0 ) { if (errno != EINTR) { fprintf(stderr, "Error in select(): %d\r\n", errno); } } else if (result > 0) { uint8_t buffer[MAX_PACKET_SIZE]; int numBytes; if (FD_ISSET(sock, &readfds)) { struct sockaddr_storage addr; socklen_t addrLen; addrLen = sizeof(addr); numBytes = recvfrom(sock, buffer, MAX_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrLen); if (numBytes == -1) { fprintf(stderr, "Error in recvfrom(): %d\r\n", errno); } else { char s[INET6_ADDRSTRLEN]; in_port_t port; connection_t * connP; s[0] = 0; if (AF_INET == addr.ss_family) { struct sockaddr_in *saddr = (struct sockaddr_in *)&addr; inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN); port = saddr->sin_port; } else if (AF_INET6 == addr.ss_family) { struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr; inet_ntop(saddr->sin6_family, &saddr->sin6_addr, s, INET6_ADDRSTRLEN); port = saddr->sin6_port; } fprintf(stderr, "%d bytes received from [%s]:%hu\r\n", numBytes, s, ntohs(port)); output_buffer(stderr, buffer, numBytes, 0); connP = connection_find(connList, &addr, addrLen); if (connP == NULL) { connP = connection_new_incoming(connList, sock, (struct sockaddr *)&addr, addrLen); if (connP != NULL) { connList = connP; } } if (connP != NULL) { lwm2m_handle_packet(lwm2mH, buffer, numBytes, connP); } } } else if (FD_ISSET(STDIN_FILENO, &readfds)) { numBytes = read(STDIN_FILENO, buffer, MAX_PACKET_SIZE - 1); if (numBytes > 1) { buffer[numBytes] = 0; handle_command(commands, (char*)buffer); fprintf(stdout, "\r\n"); } if (g_quit == 0) { fprintf(stdout, "> "); fflush(stdout); } else { fprintf(stdout, "\r\n"); } } } } lwm2m_close(lwm2mH); close(sock); connection_free(connList); #ifdef MEMORY_TRACE if (g_quit == 1) { trace_print(0, 1); } #endif return 0; }
int main(int argc, char *argv[]) { int socket; fd_set readfds; struct timeval tv; int result; lwm2m_context_t * lwm2mH = NULL; int i; command_desc_t commands[] = { {"list", "List registered clients.", NULL, prv_output_clients, NULL}, {"read", "Read from a client.", " read CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri to read such as /3, /3//2, /3/0/2, /1024/11, /1024//1\r\n" "Result will be displayed asynchronously.", prv_read_client, NULL}, {"write", "Write to a client.", " write CLIENT# URI DATA\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri to write to such as /3, /3//2, /3/0/2, /1024/11, /1024//1\r\n" " DATA: data to write\r\n" "Result will be displayed asynchronously.", prv_write_client, NULL}, {"exec", "Execute a client resource.", " exec CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri of the resource to execute such as /3/0/2\r\n" "Result will be displayed asynchronously.", prv_exec_client, NULL}, {"del", "Delete a client Object instance.", " del CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri of the instance to delete such as /1024/11\r\n" "Result will be displayed asynchronously.", prv_delete_client, NULL}, {"observe", "Observe from a client.", " observe CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri to observe such as /3, /3/0/2, /1024/11\r\n" "Result will be displayed asynchronously.", prv_observe_client, NULL}, {"cancel", "Cancel an observe.", " cancel CLIENT# URI\r\n" " CLIENT#: client number as returned by command 'list'\r\n" " URI: uri on which to cancel an observe such as /3, /3/0/2, /1024/11\r\n" "Result will be displayed asynchronously.", prv_cancel_client, NULL}, {"quit", "Quit the server.", NULL, prv_quit, NULL}, COMMAND_END_LIST }; socket = get_socket(); if (socket < 0) { fprintf(stderr, "Error opening socket: %d\r\n", errno); return -1; } lwm2mH = lwm2m_init(socket, "testlwm2mserver", 0, NULL, prv_buffer_send); if (NULL == lwm2mH) { fprintf(stderr, "lwm2m_init() failed\r\n"); return -1; } signal(SIGINT, handle_sigint); for (i = 0 ; commands[i].name != NULL ; i++) { commands[i].userData = (void *)lwm2mH; } fprintf(stdout, "> "); fflush(stdout); lwm2m_set_monitoring_callback(lwm2mH, prv_monitor_callback, lwm2mH); while (0 == g_quit) { FD_ZERO(&readfds); FD_SET(socket, &readfds); FD_SET(STDIN_FILENO, &readfds); tv.tv_sec = 60; tv.tv_usec = 0; result = lwm2m_step(lwm2mH, &tv); if (result != 0) { fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result); return -1; } result = select(FD_SETSIZE, &readfds, 0, 0, &tv); if ( result < 0 ) { if (errno != EINTR) { fprintf(stderr, "Error in select(): %d\r\n", errno); } } else if (result > 0) { uint8_t buffer[MAX_PACKET_SIZE]; int numBytes; if (FD_ISSET(socket, &readfds)) { struct sockaddr_storage addr; socklen_t addrLen; addrLen = sizeof(addr); numBytes = recvfrom(socket, buffer, MAX_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrLen); if (numBytes == -1) { fprintf(stderr, "Error in recvfrom(): %d\r\n", errno); } else { char s[INET6_ADDRSTRLEN]; coap_status_t coap_error_code = NO_ERROR; static coap_packet_t message[1]; fprintf(stderr, "%d bytes received from [%s]:%hu\r\n", numBytes, inet_ntop(addr.ss_family, &(((struct sockaddr_in6*)&addr)->sin6_addr), s, INET6_ADDRSTRLEN), ntohs(((struct sockaddr_in6*)&addr)->sin6_port)); prv_output_buffer(stderr, buffer, numBytes); lwm2m_handle_packet(lwm2mH, buffer, numBytes, (uint8_t *)&addr, addrLen); } } else if (FD_ISSET(STDIN_FILENO, &readfds)) { numBytes = read(STDIN_FILENO, buffer, MAX_PACKET_SIZE); if (numBytes > 1) { buffer[numBytes - 1] = 0; handle_command(commands, buffer); } if (g_quit == 0) { fprintf(stdout, "\r\n> "); fflush(stdout); } else { fprintf(stdout, "\r\n"); } } } } lwm2m_close(lwm2mH); close(socket); return 0; }