📄 commandlineshell.c
字号:
/* *-------------------------------------------------------------------- * * COPYRIGHT (c) 2002-2004 INTEL CORPORATION. ALL RIGHTS * RESERVED. THIS PROGRAM IS FURNISHED UNDER LICENSE AND MAY * ONLY BE USED OR COPIED IN ACCORDANCE WITH THE TERMS OF THAT * LICENSE. NO PART OF THIS PROGRAM OR PUBLICATION MAY BE * REPRODUCED, TRANSMITTED, TRANSCRIBED, STORED IN A RETRIEVAL * SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER LANGUAGE * IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL, MAGNETIC, * OPTICAL, CHEMICAL, MANUAL, OR OTHERWISE, WITHOUT THE PRIOR * WRITTEN PERMISSION OF INTEL CORPORATION. EXCEPT AS EXPRESSLY * GRANTED IN A LICENSE AGREEMENT, THIS PROGRAM IS FURNISHED "AS-IS" * WITH NO WARRANTY WHATSOEVER, INCLUDING IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON- * INFRINGEMENT. * *-------------------------------------------------------------------- * File Name: CommandLineShell.c * Author: Intel Corporation * */#include "CommandLineShell.h"#include "ILibParsers.h"#include "UPnPControlPointStructs.h"#ifdef WIN32#include "WinSemaphore.h"#include <crtdbg.h>#endif#ifdef _POSIX#include <semaphore.h>#endif#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/time.h>#include <time.h>#include "MmsCp.h"/* #### Begin CARDEA code #### */#define ALLOW_OS_CODE#include "rmupnp/rmlibwmdrmndupnp/include/ms_upnp.h"/* #### End CARDEA code #### *//* Begin PFS code */#include "samples/rmpfs.h"#define MAX_CACHEABLE_URL 4#define PFS_BUF_SIZE (MAX_CACHEABLE_URL * 1024)int buf_first = 0;struct pfs_profile pfs_cardea;RMbool pfs_init = FALSE;/* End PFS code */#ifdef _DEBUG#define DEBUGONLY(x) x#else#define DEBUGONLY(x)#endif#define DEFAULTDELIMITER '/'#define MAX_STR_LEN 1024#define TMP_BUFFER_SIZE 1024#include "MyString.h"#include "http.h"/* Arguments to the browse function, needs to be global or malloced (callback) */static struct MMSCP_BrowseArgs browseArgs;// the hash lists of devices that have been discovered on the network.static void *MS_KnownDevicesTable;// pointers to the control point structs. These are needed for making calls// to the control point functions.static void *MS_ControlPoint;// BEGIN: Shell state variables// the UDNs of the currently selected renderers. They should be empty// strings when no device is selectedstatic char *currMServerUDN;// When browsing through the tree on a media server, this is the stack // symbolizing the current position in the tree. The contents of the // stack are the object ID's of the nodes. Note that the object id: "0" should// always be at the bottom of the stack.static void *currBrowseDirectoryStack;// the most recent results from a browse request. The results come back in a // callback instead of being returned to the calling function, so this // global variable is necessary in order to give the results to the calling // function.struct MMSCP_ResultsList *mostRecentBrowseResults;//the URI of current media serverchar CurrMServerURI[MAX_STR_LEN];// END: Shell state variables./* This buffer should only be used locally */static char tmp_buffer[TMP_BUFFER_SIZE];// some people are upset with querying the pfs layer for cached urls,// so urls are *also* kept track of in MicroAVBrowserstatic RMascii *pfs_cache[MAX_NUMBER_OF_CACHEABLE_URL];/* Pops items off the media server browsing directory stack until only the * root directory is left on the stack. Note that this will free the items * on the stack. */static void popDirectoryStackToRoot(void){ char *temp; while(strcmp("0", ILibPeekStack(&currBrowseDirectoryStack))) { temp = ILibPopStack(&currBrowseDirectoryStack); free(temp); }}/*****************************************************************************************************************************************Callbacks to be used with the MS control point invoke functions. *****************************************************************************************************************************************//*static void MSCP_ResponseSink_ConnectionManager_GetCurrentConnectionInfo(struct UPnPService* Service,int ErrorCode,void *User,int RcsID,int AVTransportID,char* ProtocolInfo,char* PeerConnectionManager,int PeerConnectionID,char* Direction,char* Status){ DEBUGONLY(printf("MSCP_ Invoke Response: ConnectionManager/GetCurrentConnectionInfo[ErrorCode:%d](%d,%d,%s,%s,%d,%s,%s)\r\n",ErrorCode,RcsID,AVTransportID,ProtocolInfo,PeerConnectionManager,PeerConnectionID,Direction,Status);)}*//*static void MSCP_ResponseSink_ConnectionManager_GetProtocolInfo(struct UPnPService* Service,int ErrorCode,void *User,char* Source,char* Sink){ DEBUGONLY(printf("MSCP_ Invoke Response: ConnectionManager/GetProtocolInfo[ErrorCode:%d](%s,%s)\r\n",ErrorCode,Source,Sink);)}*//*static void MSCP_ResponseSink_ConnectionManager_GetCurrentConnectionIDs(struct UPnPService* Service,int ErrorCode,void *User,char* ConnectionIDs){ DEBUGONLY(printf("MSCP_ Invoke Response: ConnectionManager/GetCurrentConnectionIDs[ErrorCode:%d](%s)\r\n",ErrorCode,ConnectionIDs);)}*//*static void MSCP_ResponseSink_ContentDirectory_Browse(struct UPnPService* Service,int ErrorCode,void *User,char* Result,unsigned int NumberReturned,unsigned int TotalMatches,unsigned int UpdateID){ DEBUGONLY(printf("MSCP_ Invoke Response: ContentDirectory/Browse[ErrorCode:%d](%s,%u,%u,%u)\r\n",ErrorCode,Result,NumberReturned,TotalMatches,UpdateID);)}*//*static void MSCP_ResponseSink_ContentDirectory_GetSortCapabilities(struct UPnPService* Service,int ErrorCode,void *User,char* SortCaps){ DEBUGONLY(printf("MSCP_ Invoke Response: ContentDirectory/GetSortCapabilities[ErrorCode:%d](%s)\r\n",ErrorCode,SortCaps);)}*//*static void MSCP_ResponseSink_ContentDirectory_GetSystemUpdateID(struct UPnPService* Service,int ErrorCode,void *User,unsigned int Id){ DEBUGONLY(printf("MSCP_ Invoke Response: ContentDirectory/GetSystemUpdateID[ErrorCode:%d](%u)\r\n",ErrorCode,Id);)}*//*static void MSCP_ResponseSink_ContentDirectory_GetSearchCapabilities(struct UPnPService* Service,int ErrorCode,void *User,char* SearchCaps){ DEBUGONLY(printf("MSCP_ Invoke Response: ContentDirectory/GetSearchCapabilities[ErrorCode:%d](%s)\r\n",ErrorCode,SearchCaps);)}*//*static void MSCP_EventSink_ConnectionManager_SourceProtocolInfo(struct UPnPService* Service,char* SourceProtocolInfo){ DEBUGONLY(printf("MSCP_ Event from %s/ConnectionManager/SourceProtocolInfo: %s\r\n",Service->Parent->FriendlyName,SourceProtocolInfo);)}*//*static void MSCP_EventSink_ConnectionManager_SinkProtocolInfo(struct UPnPService* Service,char* SinkProtocolInfo){ DEBUGONLY(printf("MSCP_ Event from %s/ConnectionManager/SinkProtocolInfo: %s\r\n",Service->Parent->FriendlyName,SinkProtocolInfo);)}*//*static void MSCP_EventSink_ConnectionManager_CurrentConnectionIDs(struct UPnPService* Service,char* CurrentConnectionIDs){ DEBUGONLY(printf("MSCP_ Event from %s/ConnectionManager/CurrentConnectionIDs: %s\r\n",Service->Parent->FriendlyName,CurrentConnectionIDs);)}*//*static void MSCP_EventSink_ContentDirectory_SystemUpdateID(struct UPnPService* Service,unsigned int SystemUpdateID){ DEBUGONLY(printf("MSCP_ Event from %s/ContentDirectory/SystemUpdateID: %u\r\n",Service->Parent->FriendlyName,SystemUpdateID);)}*/static void prompt(){ printf("command> "); fflush(stdout);}static void MSCP_DeviceAddedOrRemoved(struct UPnPDevice *device, int added){ ILibHashTree_Lock(MS_KnownDevicesTable); if(added) { ILibAddEntry( MS_KnownDevicesTable, device->UDN, (int)strlen(device->UDN), device->FriendlyName); } else { ILibDeleteEntry( MS_KnownDevicesTable, device->UDN, (int)strlen(device->UDN)); } ILibHashTree_UnLock(MS_KnownDevicesTable);}static void MSCP_BrowseResponded(void *serviceObj, struct MMSCP_BrowseArgs *args, int errorCode, struct MMSCP_ResultsList *results){ void (*callback)(void); DEBUGONLY(printf("A browse request came back...\n");) DEBUGONLY(printf("Error code: %d\n", errorCode);) if(0 == errorCode) { if(mostRecentBrowseResults != NULL) { printf("ERROR: browse results returned, but"); printf(" mostRecentBrowseResults is not NULL\n"); // prevent memory leaks leave the old results, and // destroy the new results because there might be // other references to the old stuff. MMSCP_DestroyResultsList(results); } else { mostRecentBrowseResults = results; } callback = args->UserObject; if (callback){ callback(); /* Put the prompt back after we have finished the * callback */ prompt(); } }}/*******************************************************************************************************************************************************End of callbacks*******************************************************************************************************************************************************///Identify the delimiter character in a path stringstatic void identifyDelimiter(char * delimiter, char * path){ char * tmp = path; *delimiter = '/'; //default value if(tmp == NULL || strlen(tmp) == 0) return; while('\0' != *tmp && !('\\'== *tmp || '/' == *tmp)) tmp++; if('\0' != *tmp) *delimiter = *tmp;}//do not show "0" for the rootstatic void ignoreRoot(char ** path){ char * tmp = *path; if('0' == *tmp) (*path)++; }static void ignoreParentPath(char ** path, char delimiter){ char * tmp = *path; unsigned int pos = 0, i = 0; if(NULL == tmp) return; while('\0' != *tmp){ if(delimiter == *tmp) pos = i; i++; tmp++; } if(pos == strlen(*path) - 1) return; *path += pos+1;}//change delimiter of the path string that is //ended with '\0'static void changeDelimiter(char * path, char dmt){ char * tmp = path; if(NULL == tmp) return; while(*tmp != '\0') { if(*tmp == '\\' || *tmp == '/') *tmp = dmt; tmp++; }}static struct UPnPDevice *getCurrentMServer(){ struct UPnPDevice *ret; CurrMServerURI[0] = '\0'; if('\0' == currMServerUDN[0]) { printf("No server selected, select one with setms\n"); ret = NULL; } else { ret = MSCP_GetDeviceAtUDN(MS_ControlPoint, currMServerUDN); if(NULL == ret) { printf("The previously selected server has left the network\n"); printf("Please select a new one with setms\n"); currMServerUDN[0] = '\0'; popDirectoryStackToRoot(); } else Utf8ToAnsi(CurrMServerURI, ret->LocationURL, MAX_STR_LEN); } return ret;}/* Presents a list to the user, allows the user to choose * one, and then returns the ID of the device selected. * Parameters: * theILibHashTable: The ILibHashTree that contains the set of items from * which the user should choose. The key should the the ID, * and the value should be a string describing the item. * returns a pointer to the buffer containing the freshly malloc'ed ID string */static char *chooseIDFromTable(void *theILibHashTable){ char *key, *retVal, *tmppath; int keyLength; void *data; char *charData; void *enumerator; int i, numDevices, chosenIndex, attemptsLeft; ILibHashTree_Lock(theILibHashTable); enumerator = ILibHashTree_GetEnumerator(theILibHashTable); printf("Select one of the following:\n"); numDevices = 0; do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -