⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsm0710.c

📁 该源码是针对支持Mux技术的手机Modem的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
					break;			}		}	}	return returnCode;}char *createSymlinkName(int idx) {    if (devSymlinkPrefix == NULL) {        return NULL;    }    char* symLinkName  = malloc(strlen(devSymlinkPrefix)+255);    sprintf(symLinkName, "%s%d", devSymlinkPrefix, idx);    return symLinkName;}int open_pty(char* devname, int idx) {	struct termios options;	int fd = open(devname, O_RDWR | O_NONBLOCK);	char *symLinkName = createSymlinkName(idx);	if (fd != -1) 	{		if (symLinkName) 		{			char* ptsSlaveName = ptsname(fd);	  			// Create symbolic device name, e.g. /dev/mux0			unlink(symLinkName);			if (symlink(ptsSlaveName, symLinkName) != 0) 			{				syslog(LOG_ERR,"Can't create symbolic link %s -> %s. %s (%d).\n", symLinkName, ptsSlaveName, strerror(errno), errno);			}		}		// get the parameters		tcgetattr(fd, &options);		// set raw input		options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);		options.c_iflag &= ~(INLCR | ICRNL | IGNCR);					// set raw output		options.c_oflag &= ~OPOST;		options.c_oflag &= ~OLCUC;		options.c_oflag &= ~ONLRET;		options.c_oflag &= ~ONOCR;		options.c_oflag &= ~OCRNL;		tcsetattr(fd, TCSANOW, &options); 		if (strcmp(devname, "/dev/ptmx") == 0) 		{			// Otherwise programs cannot access the pseudo terminals			grantpt(fd);			unlockpt(fd);		}	}	free(symLinkName);	return fd;}/** * Determine baud rate index for CMUX command */int indexOfBaud(int baudrate) {    int i;    for (i = 0; i < sizeof(baudrates) / sizeof(baudrates[0]); ++i) {        if (baudrates[i] == baudrate)            return i;    }    return 0;}/**  * Set serial port options. Then switch baudrate to zero for a while * and then back up. This is needed to get some modems  * (such as Siemens MC35i) to wake up. */void setAdvancedOptions(int fd, speed_t baud) {    struct termios options;    struct termios options_cpy;    fcntl(fd, F_SETFL, 0);        // get the parameters    tcgetattr(fd, &options);        // Do like minicom: set 0 in speed options    cfsetispeed(&options, 0);    cfsetospeed(&options, 0);        options.c_iflag = IGNBRK;        // Enable the receiver and set local mode and 8N1    options.c_cflag = (CLOCAL | CREAD | CS8 | HUPCL);    // enable hardware flow control (CNEW_RTCCTS)    // options.c_cflag |= CRTSCTS;    // Set speed    options.c_cflag |= baud;        /*      options.c_cflag &= ~PARENB;      options.c_cflag &= ~CSTOPB;      options.c_cflag &= ~CSIZE; // Could this be wrong!?!?!?    */        // set raw input    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);    options.c_iflag &= ~(INLCR | ICRNL | IGNCR);        // set raw output    options.c_oflag &= ~OPOST;    options.c_oflag &= ~OLCUC;    options.c_oflag &= ~ONLRET;    options.c_oflag &= ~ONOCR;    options.c_oflag &= ~OCRNL;        // Set the new options for the port...    options_cpy = options;    tcsetattr(fd, TCSANOW, &options);    options = options_cpy;        // Do like minicom: set speed to 0 and back    options.c_cflag &= ~baud;    tcsetattr(fd, TCSANOW, &options);    options = options_cpy;        sleep(1);        options.c_cflag |= baud;    tcsetattr(fd, TCSANOW, &options);}/* Opens serial port, set's it to 57600bps 8N1 RTS/CTS mode.** PARAMS:* dev - device name* RETURNS :* file descriptor or -1 on error*/int open_serialport(char *dev){	int fd;	if(_debug)		syslog(LOG_DEBUG, "is in %s\n" , __FUNCTION__);	fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);	if (fd != -1)	{		int index = indexOfBaud(baudrate);		if(_debug)			syslog(LOG_DEBUG, "serial opened\n" );		if (index > 0) 		{			// Switch the baud rate to zero and back up to wake up 			// the modem			setAdvancedOptions(fd, baud_bits[index]);		} 		else 		{			struct termios options;			// The old way. Let's not change baud settings			fcntl(fd, F_SETFL, 0);						// get the parameters			tcgetattr(fd, &options);						// Set the baud rates to 57600...			// cfsetispeed(&options, B57600);			// cfsetospeed(&options, B57600);						// Enable the receiver and set local mode...			options.c_cflag |= (CLOCAL | CREAD);						// No parity (8N1):			options.c_cflag &= ~PARENB;			options.c_cflag &= ~CSTOPB;			options.c_cflag &= ~CSIZE;			options.c_cflag |= CS8;						// enable hardware flow control (CNEW_RTCCTS)			// options.c_cflag |= CRTSCTS;						// set raw input			options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);			options.c_iflag &= ~(INLCR | ICRNL | IGNCR);						// set raw output			options.c_oflag &= ~OPOST;			options.c_oflag &= ~OLCUC;			options.c_oflag &= ~ONLRET;			options.c_oflag &= ~ONOCR;			options.c_oflag &= ~OCRNL;						// Set the new options for the port...			tcsetattr(fd, TCSANOW, &options);		}	}	return fd;}// Prints information on a framevoid print_frame(GSM0710_Frame * frame){	if(_debug)	{		syslog(LOG_DEBUG, "is in %s\n" , __FUNCTION__);		syslog(LOG_DEBUG,"Received ");	}    switch((frame->control & ~PF))	{		case SABM:			if(_debug)				syslog(LOG_DEBUG,"SABM ");			break;		case UIH:			if(_debug)				syslog(LOG_DEBUG,"UIH ");			break;		case UA:			if(_debug)				syslog(LOG_DEBUG,"UA ");			break;		case DM:			if(_debug)				syslog(LOG_DEBUG,"DM ");			break;		case DISC:			if(_debug)				syslog(LOG_DEBUG,"DISC ");			break;		case UI:			if(_debug)				syslog(LOG_DEBUG,"UI ");			break;		default:			if(_debug)				syslog(LOG_DEBUG,"unkown (control=%d) ", frame->control);			break;	}	if(_debug)		syslog(LOG_DEBUG," frame for channel %d.\n", frame->channel);	if (frame->data_length > 0)	{		if(_debug)		{			syslog(LOG_DEBUG,"frame->data = %s / size = %d\n",frame->data, frame->data_length);		//fwrite(frame->data, sizeof(char), frame->data_length, stdout);			syslog(LOG_DEBUG,"\n");		}	}}/* Handles commands received from the control channel.*/void handle_command(GSM0710_Frame * frame){#if 1	unsigned char type, signals;	int length = 0, i, type_length, channel, supported = 1;	unsigned char *response;	// struct ussp_operation op;	if(_debug)		syslog(LOG_DEBUG, "is in %s\n" , __FUNCTION__);	if (frame->data_length > 0)	{		type = frame->data[0];  // only a byte long types are handled now		// skip extra bytes		for (i = 0; (frame->data_length > i && (frame->data[i] & EA) == 0); i++);		i++;		type_length = i;		if ((type & CR) == CR)		{			// command not ack			// extract frame length			while (frame->data_length > i)			{				length = (length * 128) + ((frame->data[i] & 254) >> 1);				if ((frame->data[i] & 1) == 1)					break;				i++;			}			i++;			switch((type & ~CR))			{				case C_CLD:					syslog(LOG_INFO,"The mobile station requested mux-mode termination.\n");					if (faultTolerant) {						// Signal restart						restart = 1;					} else {						terminate = 1;						terminateCount = -1;    // don't need to close down channels					}					break;				case C_TEST:	#ifdef DEBUG					if(_debug)						syslog(LOG_DEBUG,"Test command: ");					if(_debug)						syslog(LOG_DEBUG,"frame->data = %s  / frame->data_length = %d\n",frame->data + i, frame->data_length - i);					//fwrite(frame->data + i, sizeof(char), frame->data_length - i, stdout);	#endif					break;				case C_MSC:					if (i + 1 < frame->data_length)					{						channel = ((frame->data[i] & 252) >> 2);						i++;						signals = (frame->data[i]);						// op.op = USSP_MSC;						// op.arg = USSP_RTS;						// op.len = 0;						if(_debug)							syslog(LOG_DEBUG,"Modem status command on channel %d.\n", channel);						if ((signals & S_FC) == S_FC)						{							if(_debug)								syslog(LOG_DEBUG,"No frames allowed.\n");						}						else						{							// op.arg |= USSP_CTS;							if(_debug)								syslog(LOG_DEBUG,"Frames allowed.\n");						}						if ((signals & S_RTC) == S_RTC)						{							// op.arg |= USSP_DSR;							if(_debug)								syslog(LOG_DEBUG,"RTC\n");						}						if ((signals & S_IC) == S_IC)						{							// op.arg |= USSP_RI;							if(_debug)								syslog(LOG_DEBUG,"Ring\n");						}						if ((signals & S_DV) == S_DV)						{							// op.arg |= USSP_DCD;							if(_debug)								syslog(LOG_DEBUG,"DV\n");						}						// if (channel > 0)						//     write(ussp_fd[(channel - 1)], &op, sizeof(op));					}					else					{						syslog(LOG_ERR,"ERROR: Modem status command, but no info. i: %d, len: %d, data-len: %d\n", i, length,						frame->data_length);					}					break;				default:					syslog(LOG_ALERT,"Unknown command (%d) from the control channel.\n", type);					response = malloc(sizeof(char) * (2 + type_length));					response[0] = C_NSC;					// supposes that type length is less than 128					response[1] = EA & ((127 & type_length) << 1);					i = 2;					while (type_length--)					{						response[i] = frame->data[(i - 2)];						i++;					}					write_frame(0, response, i, UIH);					free(response);					supported = 0;					break;			}			if (supported)			{				// acknowledge the command				frame->data[0] = frame->data[0] & ~CR;				write_frame(0, frame->data, frame->data_length, UIH);			}		}		else		{			// received ack for a command			if (COMMAND_IS(C_NSC, type))			{				syslog(LOG_ALERT,"The mobile station didn't support the command sent.\n");			}			else			{				if(_debug)					syslog(LOG_DEBUG,"Command acknowledged by the mobile station.\n");			}		}	}#endif}// shows how to use this programvoid usage(char *_name){	fprintf(stderr,"\nUsage: %s [options] <pty1> <pty2> ...\n",_name);	fprintf(stderr,"  <ptyN>              : pty devices (e.g. /dev/ptya0)\n\n");	fprintf(stderr,"options:\n");	fprintf(stderr,"  -p <serport>        : Serial port device to connect to [/dev/modem]\n");	fprintf(stderr,"  -f <framsize>       : Maximum frame size [32]\n");	fprintf(stderr,"  -d                  : Debug mode, don't fork\n");	fprintf(stderr,"  -m <modem>          : Modem (mc35, mc75, generic, ...)\n");	fprintf(stderr,"  -b <baudrate>       : MUX mode baudrate (0,9600,19200, ...)\n");	fprintf(stderr,"  -P <PIN-code>       : PIN code to fed to the modem\n");	fprintf(stderr,"  -s <symlink-prefix> : Prefix for the symlinks of slave devices (e.g. /dev/mux)\n");	fprintf(stderr,"  -w                  : Wait for deamon startup success/failure\n");	fprintf(stderr,"  -r                  : Restart automatically if the modem stops responding\n");	fprintf(stderr,"  -h                  : Show this help message\n");}/* Extracts and handles frames from the receiver buffer.** PARAMS:* buf - the receiver buffer*/int extract_frames(GSM0710_Buffer * buf){	// version test for Siemens terminals to enable version 2 functions	static char version_test[] = "\x23\x21\x04TEMUXVERSION2\0\0";	int framesExtracted = 0;	GSM0710_Frame *frame;	if(_debug)		syslog(LOG_DEBUG, "is in %s\n" , __FUNCTION__);	while ((frame = gsm0710_buffer_get_frame(buf)))	{		++framesExtracted;		if ((FRAME_IS(UI, frame) || FRAME_IS(UIH, frame)))		{			if(_debug)				syslog(LOG_DEBUG, "is (FRAME_IS(UI, frame) || FRAME_IS(UIH, frame))\n");			if (frame->channel > 0)			{				if(_debug)					syslog(LOG_DEBUG,"frame->channel > 0\n");				// data from logical channel				ussp_send_data(frame->data, frame->data_length, frame->channel - 1);			}			else			{				// control channel command				if(_debug)					syslog(LOG_DEBUG,"control channel command\n");				handle_command(frame);			}		}		else		{			// not an information frame			if(_debug)				syslog(LOG_DEBUG,"not an information frame\n");#ifdef DEBUG			print_frame(frame);#endif                        switch((frame->control & ~PF))			{				case UA:					if(_debug)						syslog(LOG_DEBUG,"is FRAME_IS(UA, frame)\n");					if (cstatus[frame->channel].opened == 1)					{						syslog(LOG_INFO,"Logical channel %d closed.\n", frame->channel);						cstatus[frame->channel].opened = 0;					}					else					{						cstatus[frame->channel].opened = 1;						if (frame->channel == 0)						{							syslog(LOG_INFO,"Control channel opened.\n");							// send version Siemens version test							write_frame(0, version_test, 18, UIH);						}						else						{							syslog(LOG_INFO,"Logical channel %d opened.\n", frame->channel);						}					}					break;				case DM:					if (cstatus[frame->channel].opened)					{						syslog(LOG_INFO,"DM received, so the channel %d was already closed.\n", frame->channel);						cstatus[frame->channel].opened = 0;					}					else					{						if (frame->channel == 0)						{							syslog(LOG_INFO,"Couldn't open control channel.\n->Terminating.\n");							terminate = 1;							terminateCount = -1;    // don't need to close channels						}						else						{							syslog(LOG_INFO,"Logical channel %d couldn't be opened.\n", frame->channel);						}					}					break;				case DISC:					if (cstatus[frame->channel].opened)					{						cstatus[frame->channel].opened = 0;						write_frame(frame->channel, NULL, 0, UA | PF);						if (frame->channel == 0)						{							syslog(LOG_INFO,"Control channel closed.\n");							if (faultTolerant) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -